aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/radeon/Makefile2
-rw-r--r--drivers/gpu/drm/radeon/r600.c5
-rw-r--r--drivers/gpu/drm/radeon/r600_audio.c267
-rw-r--r--drivers/gpu/drm/radeon/r600_hdmi.c506
-rw-r--r--drivers/gpu/drm/radeon/r600_reg.h74
-rw-r--r--drivers/gpu/drm/radeon/radeon.h24
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_encoders.c16
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h3
9 files changed, 895 insertions, 6 deletions
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index feb52eee4314..b5f5fe75e6af 100644
--- a/drivers/gpu/drm/radeon/Makefile
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -49,7 +49,7 @@ radeon-y += radeon_device.o radeon_kms.o \
49 radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o \ 49 radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o \
50 rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \ 50 rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \
51 r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \ 51 r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \
52 r600_blit_kms.o radeon_pm.o atombios_dp.o 52 r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o
53 53
54radeon-$(CONFIG_COMPAT) += radeon_ioc32.o 54radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
55 55
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index e145faac9904..5c6058c6ddde 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2067,6 +2067,10 @@ int r600_init(struct radeon_device *rdev)
2067 rdev->accel_working = false; 2067 rdev->accel_working = false;
2068 } 2068 }
2069 } 2069 }
2070
2071 r = r600_audio_init(rdev);
2072 if (r)
2073 return r; /* TODO error handling */
2070 return 0; 2074 return 0;
2071} 2075}
2072 2076
@@ -2075,6 +2079,7 @@ void r600_fini(struct radeon_device *rdev)
2075 /* Suspend operations */ 2079 /* Suspend operations */
2076 r600_suspend(rdev); 2080 r600_suspend(rdev);
2077 2081
2082 r600_audio_fini(rdev);
2078 r600_blit_fini(rdev); 2083 r600_blit_fini(rdev);
2079 r600_irq_fini(rdev); 2084 r600_irq_fini(rdev);
2080 radeon_irq_kms_fini(rdev); 2085 radeon_irq_kms_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/r600_audio.c b/drivers/gpu/drm/radeon/r600_audio.c
new file mode 100644
index 000000000000..99e2c3891a7d
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r600_audio.c
@@ -0,0 +1,267 @@
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.h"
28#include "radeon_reg.h"
29#include "atom.h"
30
31#define AUDIO_TIMER_INTERVALL 100 /* 1/10 sekund should be enough */
32
33/*
34 * check if the chipset is supported
35 */
36static int r600_audio_chipset_supported(struct radeon_device *rdev)
37{
38 return rdev->family >= CHIP_R600
39 || rdev->family == CHIP_RS600
40 || rdev->family == CHIP_RS690
41 || rdev->family == CHIP_RS740;
42}
43
44/*
45 * current number of channels
46 */
47static int r600_audio_channels(struct radeon_device *rdev)
48{
49 return (RREG32(R600_AUDIO_RATE_BPS_CHANNEL) & 0x7) + 1;
50}
51
52/*
53 * current bits per sample
54 */
55static int r600_audio_bits_per_sample(struct radeon_device *rdev)
56{
57 uint32_t value = (RREG32(R600_AUDIO_RATE_BPS_CHANNEL) & 0xF0) >> 4;
58 switch (value) {
59 case 0x0: return 8;
60 case 0x1: return 16;
61 case 0x2: return 20;
62 case 0x3: return 24;
63 case 0x4: return 32;
64 }
65
66 DRM_ERROR("Unknown bits per sample 0x%x using 16 instead.\n", (int)value);
67
68 return 16;
69}
70
71/*
72 * current sampling rate in HZ
73 */
74static int r600_audio_rate(struct radeon_device *rdev)
75{
76 uint32_t value = RREG32(R600_AUDIO_RATE_BPS_CHANNEL);
77 uint32_t result;
78
79 if (value & 0x4000)
80 result = 44100;
81 else
82 result = 48000;
83
84 result *= ((value >> 11) & 0x7) + 1;
85 result /= ((value >> 8) & 0x7) + 1;
86
87 return result;
88}
89
90/*
91 * iec 60958 status bits
92 */
93static uint8_t r600_audio_status_bits(struct radeon_device *rdev)
94{
95 return RREG32(R600_AUDIO_STATUS_BITS) & 0xff;
96}
97
98/*
99 * iec 60958 category code
100 */
101static uint8_t r600_audio_category_code(struct radeon_device *rdev)
102{
103 return (RREG32(R600_AUDIO_STATUS_BITS) >> 8) & 0xff;
104}
105
106/*
107 * update all hdmi interfaces with current audio parameters
108 */
109static void r600_audio_update_hdmi(unsigned long param)
110{
111 struct radeon_device *rdev = (struct radeon_device *)param;
112 struct drm_device *dev = rdev->ddev;
113
114 int channels = r600_audio_channels(rdev);
115 int rate = r600_audio_rate(rdev);
116 int bps = r600_audio_bits_per_sample(rdev);
117 uint8_t status_bits = r600_audio_status_bits(rdev);
118 uint8_t category_code = r600_audio_category_code(rdev);
119
120 struct drm_encoder *encoder;
121 int changes = 0;
122
123 changes |= channels != rdev->audio_channels;
124 changes |= rate != rdev->audio_rate;
125 changes |= bps != rdev->audio_bits_per_sample;
126 changes |= status_bits != rdev->audio_status_bits;
127 changes |= category_code != rdev->audio_category_code;
128
129 if (changes) {
130 rdev->audio_channels = channels;
131 rdev->audio_rate = rate;
132 rdev->audio_bits_per_sample = bps;
133 rdev->audio_status_bits = status_bits;
134 rdev->audio_category_code = category_code;
135 }
136
137 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
138 if (changes || r600_hdmi_buffer_status_changed(encoder))
139 r600_hdmi_update_audio_settings(
140 encoder, channels,
141 rate, bps, status_bits,
142 category_code);
143 }
144
145 mod_timer(&rdev->audio_timer,
146 jiffies + msecs_to_jiffies(AUDIO_TIMER_INTERVALL));
147}
148
149/*
150 * initialize the audio vars and register the update timer
151 */
152int r600_audio_init(struct radeon_device *rdev)
153{
154 if (!r600_audio_chipset_supported(rdev))
155 return 0;
156
157 DRM_INFO("%s audio support", radeon_audio ? "Enabling" : "Disabling");
158 WREG32_P(R600_AUDIO_ENABLE, radeon_audio ? 0x81000000 : 0x0, ~0x81000000);
159
160 rdev->audio_channels = -1;
161 rdev->audio_rate = -1;
162 rdev->audio_bits_per_sample = -1;
163 rdev->audio_status_bits = 0;
164 rdev->audio_category_code = 0;
165
166 setup_timer(
167 &rdev->audio_timer,
168 r600_audio_update_hdmi,
169 (unsigned long)rdev);
170
171 mod_timer(&rdev->audio_timer, jiffies + 1);
172
173 return 0;
174}
175
176/*
177 * determin how the encoders and audio interface is wired together
178 */
179int r600_audio_tmds_index(struct drm_encoder *encoder)
180{
181 struct drm_device *dev = encoder->dev;
182 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
183 struct drm_encoder *other;
184
185 switch (radeon_encoder->encoder_id) {
186 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
187 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
188 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
189 return 0;
190
191 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
192 /* special case check if an TMDS1 is present */
193 list_for_each_entry(other, &dev->mode_config.encoder_list, head) {
194 if (to_radeon_encoder(other)->encoder_id ==
195 ENCODER_OBJECT_ID_INTERNAL_TMDS1)
196 return 1;
197 }
198 return 0;
199
200 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
201 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
202 return 1;
203
204 default:
205 DRM_ERROR("Unsupported encoder type 0x%02X\n",
206 radeon_encoder->encoder_id);
207 return -1;
208 }
209}
210
211/*
212 * atach the audio codec to the clock source of the encoder
213 */
214void r600_audio_set_clock(struct drm_encoder *encoder, int clock)
215{
216 struct drm_device *dev = encoder->dev;
217 struct radeon_device *rdev = dev->dev_private;
218 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
219 int base_rate = 48000;
220
221 switch (radeon_encoder->encoder_id) {
222 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
223 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
224 WREG32_P(R600_AUDIO_TIMING, 0, ~0x301);
225 break;
226
227 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
228 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
229 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
230 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
231 WREG32_P(R600_AUDIO_TIMING, 0x100, ~0x301);
232 break;
233
234 default:
235 DRM_ERROR("Unsupported encoder type 0x%02X\n",
236 radeon_encoder->encoder_id);
237 return;
238 }
239
240 switch (r600_audio_tmds_index(encoder)) {
241 case 0:
242 WREG32(R600_AUDIO_PLL1_MUL, base_rate*50);
243 WREG32(R600_AUDIO_PLL1_DIV, clock*100);
244 WREG32(R600_AUDIO_CLK_SRCSEL, 0);
245 break;
246
247 case 1:
248 WREG32(R600_AUDIO_PLL2_MUL, base_rate*50);
249 WREG32(R600_AUDIO_PLL2_DIV, clock*100);
250 WREG32(R600_AUDIO_CLK_SRCSEL, 1);
251 break;
252 }
253}
254
255/*
256 * release the audio timer
257 * TODO: How to do this correctly on SMP systems?
258 */
259void r600_audio_fini(struct radeon_device *rdev)
260{
261 if (!r600_audio_chipset_supported(rdev))
262 return;
263
264 WREG32_P(R600_AUDIO_ENABLE, 0x0, ~0x81000000);
265
266 del_timer(&rdev->audio_timer);
267}
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c
new file mode 100644
index 000000000000..fcc949df0e5d
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r600_hdmi.c
@@ -0,0 +1,506 @@
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 "atom.h"
30
31/*
32 * HDMI color format
33 */
34enum r600_hdmi_color_format {
35 RGB = 0,
36 YCC_422 = 1,
37 YCC_444 = 2
38};
39
40/*
41 * IEC60958 status bits
42 */
43enum r600_hdmi_iec_status_bits {
44 AUDIO_STATUS_DIG_ENABLE = 0x01,
45 AUDIO_STATUS_V = 0x02,
46 AUDIO_STATUS_VCFG = 0x04,
47 AUDIO_STATUS_EMPHASIS = 0x08,
48 AUDIO_STATUS_COPYRIGHT = 0x10,
49 AUDIO_STATUS_NONAUDIO = 0x20,
50 AUDIO_STATUS_PROFESSIONAL = 0x40,
51 AUDIO_STATUS_LEVEL = 0x80
52};
53
54struct {
55 uint32_t Clock;
56
57 int N_32kHz;
58 int CTS_32kHz;
59
60 int N_44_1kHz;
61 int CTS_44_1kHz;
62
63 int N_48kHz;
64 int CTS_48kHz;
65
66} r600_hdmi_ACR[] = {
67 /* 32kHz 44.1kHz 48kHz */
68 /* Clock N CTS N CTS N CTS */
69 { 25174, 4576, 28125, 7007, 31250, 6864, 28125 }, /* 25,20/1.001 MHz */
70 { 25200, 4096, 25200, 6272, 28000, 6144, 25200 }, /* 25.20 MHz */
71 { 27000, 4096, 27000, 6272, 30000, 6144, 27000 }, /* 27.00 MHz */
72 { 27027, 4096, 27027, 6272, 30030, 6144, 27027 }, /* 27.00*1.001 MHz */
73 { 54000, 4096, 54000, 6272, 60000, 6144, 54000 }, /* 54.00 MHz */
74 { 54054, 4096, 54054, 6272, 60060, 6144, 54054 }, /* 54.00*1.001 MHz */
75 { 74175, 11648, 210937, 17836, 234375, 11648, 140625 }, /* 74.25/1.001 MHz */
76 { 74250, 4096, 74250, 6272, 82500, 6144, 74250 }, /* 74.25 MHz */
77 { 148351, 11648, 421875, 8918, 234375, 5824, 140625 }, /* 148.50/1.001 MHz */
78 { 148500, 4096, 148500, 6272, 165000, 6144, 148500 }, /* 148.50 MHz */
79 { 0, 4096, 0, 6272, 0, 6144, 0 } /* Other */
80};
81
82/*
83 * calculate CTS value if it's not found in the table
84 */
85static void r600_hdmi_calc_CTS(uint32_t clock, int *CTS, int N, int freq)
86{
87 if (*CTS == 0)
88 *CTS = clock*N/(128*freq)*1000;
89 DRM_DEBUG("Using ACR timing N=%d CTS=%d for frequency %d\n",
90 N, *CTS, freq);
91}
92
93/*
94 * update the N and CTS parameters for a given pixel clock rate
95 */
96static void r600_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t clock)
97{
98 struct drm_device *dev = encoder->dev;
99 struct radeon_device *rdev = dev->dev_private;
100 uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
101 int CTS;
102 int N;
103 int i;
104
105 for (i = 0; r600_hdmi_ACR[i].Clock != clock && r600_hdmi_ACR[i].Clock != 0; i++);
106
107 CTS = r600_hdmi_ACR[i].CTS_32kHz;
108 N = r600_hdmi_ACR[i].N_32kHz;
109 r600_hdmi_calc_CTS(clock, &CTS, N, 32000);
110 WREG32(offset+R600_HDMI_32kHz_CTS, CTS << 12);
111 WREG32(offset+R600_HDMI_32kHz_N, N);
112
113 CTS = r600_hdmi_ACR[i].CTS_44_1kHz;
114 N = r600_hdmi_ACR[i].N_44_1kHz;
115 r600_hdmi_calc_CTS(clock, &CTS, N, 44100);
116 WREG32(offset+R600_HDMI_44_1kHz_CTS, CTS << 12);
117 WREG32(offset+R600_HDMI_44_1kHz_N, N);
118
119 CTS = r600_hdmi_ACR[i].CTS_48kHz;
120 N = r600_hdmi_ACR[i].N_48kHz;
121 r600_hdmi_calc_CTS(clock, &CTS, N, 48000);
122 WREG32(offset+R600_HDMI_48kHz_CTS, CTS << 12);
123 WREG32(offset+R600_HDMI_48kHz_N, N);
124}
125
126/*
127 * calculate the crc for a given info frame
128 */
129static void r600_hdmi_infoframe_checksum(uint8_t packetType,
130 uint8_t versionNumber,
131 uint8_t length,
132 uint8_t *frame)
133{
134 int i;
135 frame[0] = packetType + versionNumber + length;
136 for (i = 1; i <= length; i++)
137 frame[0] += frame[i];
138 frame[0] = 0x100 - frame[0];
139}
140
141/*
142 * build a HDMI Video Info Frame
143 */
144static void r600_hdmi_videoinfoframe(
145 struct drm_encoder *encoder,
146 enum r600_hdmi_color_format color_format,
147 int active_information_present,
148 uint8_t active_format_aspect_ratio,
149 uint8_t scan_information,
150 uint8_t colorimetry,
151 uint8_t ex_colorimetry,
152 uint8_t quantization,
153 int ITC,
154 uint8_t picture_aspect_ratio,
155 uint8_t video_format_identification,
156 uint8_t pixel_repetition,
157 uint8_t non_uniform_picture_scaling,
158 uint8_t bar_info_data_valid,
159 uint16_t top_bar,
160 uint16_t bottom_bar,
161 uint16_t left_bar,
162 uint16_t right_bar
163)
164{
165 struct drm_device *dev = encoder->dev;
166 struct radeon_device *rdev = dev->dev_private;
167 uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
168
169 uint8_t frame[14];
170
171 frame[0x0] = 0;
172 frame[0x1] =
173 (scan_information & 0x3) |
174 ((bar_info_data_valid & 0x3) << 2) |
175 ((active_information_present & 0x1) << 4) |
176 ((color_format & 0x3) << 5);
177 frame[0x2] =
178 (active_format_aspect_ratio & 0xF) |
179 ((picture_aspect_ratio & 0x3) << 4) |
180 ((colorimetry & 0x3) << 6);
181 frame[0x3] =
182 (non_uniform_picture_scaling & 0x3) |
183 ((quantization & 0x3) << 2) |
184 ((ex_colorimetry & 0x7) << 4) |
185 ((ITC & 0x1) << 7);
186 frame[0x4] = (video_format_identification & 0x7F);
187 frame[0x5] = (pixel_repetition & 0xF);
188 frame[0x6] = (top_bar & 0xFF);
189 frame[0x7] = (top_bar >> 8);
190 frame[0x8] = (bottom_bar & 0xFF);
191 frame[0x9] = (bottom_bar >> 8);
192 frame[0xA] = (left_bar & 0xFF);
193 frame[0xB] = (left_bar >> 8);
194 frame[0xC] = (right_bar & 0xFF);
195 frame[0xD] = (right_bar >> 8);
196
197 r600_hdmi_infoframe_checksum(0x82, 0x02, 0x0D, frame);
198
199 WREG32(offset+R600_HDMI_VIDEOINFOFRAME_0,
200 frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));
201 WREG32(offset+R600_HDMI_VIDEOINFOFRAME_1,
202 frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x7] << 24));
203 WREG32(offset+R600_HDMI_VIDEOINFOFRAME_2,
204 frame[0x8] | (frame[0x9] << 8) | (frame[0xA] << 16) | (frame[0xB] << 24));
205 WREG32(offset+R600_HDMI_VIDEOINFOFRAME_3,
206 frame[0xC] | (frame[0xD] << 8));
207}
208
209/*
210 * build a Audio Info Frame
211 */
212static void r600_hdmi_audioinfoframe(
213 struct drm_encoder *encoder,
214 uint8_t channel_count,
215 uint8_t coding_type,
216 uint8_t sample_size,
217 uint8_t sample_frequency,
218 uint8_t format,
219 uint8_t channel_allocation,
220 uint8_t level_shift,
221 int downmix_inhibit
222)
223{
224 struct drm_device *dev = encoder->dev;
225 struct radeon_device *rdev = dev->dev_private;
226 uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
227
228 uint8_t frame[11];
229
230 frame[0x0] = 0;
231 frame[0x1] = (channel_count & 0x7) | ((coding_type & 0xF) << 4);
232 frame[0x2] = (sample_size & 0x3) | ((sample_frequency & 0x7) << 2);
233 frame[0x3] = format;
234 frame[0x4] = channel_allocation;
235 frame[0x5] = ((level_shift & 0xF) << 3) | ((downmix_inhibit & 0x1) << 7);
236 frame[0x6] = 0;
237 frame[0x7] = 0;
238 frame[0x8] = 0;
239 frame[0x9] = 0;
240 frame[0xA] = 0;
241
242 r600_hdmi_infoframe_checksum(0x84, 0x01, 0x0A, frame);
243
244 WREG32(offset+R600_HDMI_AUDIOINFOFRAME_0,
245 frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));
246 WREG32(offset+R600_HDMI_AUDIOINFOFRAME_1,
247 frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x8] << 24));
248}
249
250/*
251 * test if audio buffer is filled enough to start playing
252 */
253static int r600_hdmi_is_audio_buffer_filled(struct drm_encoder *encoder)
254{
255 struct drm_device *dev = encoder->dev;
256 struct radeon_device *rdev = dev->dev_private;
257 uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
258
259 return (RREG32(offset+R600_HDMI_STATUS) & 0x10) != 0;
260}
261
262/*
263 * have buffer status changed since last call?
264 */
265int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder)
266{
267 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
268 int status, result;
269
270 if (!radeon_encoder->hdmi_offset)
271 return 0;
272
273 status = r600_hdmi_is_audio_buffer_filled(encoder);
274 result = radeon_encoder->hdmi_buffer_status != status;
275 radeon_encoder->hdmi_buffer_status = status;
276
277 return result;
278}
279
280/*
281 * write the audio workaround status to the hardware
282 */
283void r600_hdmi_audio_workaround(struct drm_encoder *encoder)
284{
285 struct drm_device *dev = encoder->dev;
286 struct radeon_device *rdev = dev->dev_private;
287 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
288 uint32_t offset = radeon_encoder->hdmi_offset;
289
290 if (!offset)
291 return;
292
293 if (r600_hdmi_is_audio_buffer_filled(encoder)) {
294 /* disable audio workaround and start delivering of audio frames */
295 WREG32_P(offset+R600_HDMI_CNTL, 0x00000001, ~0x00001001);
296
297 } else if (radeon_encoder->hdmi_audio_workaround) {
298 /* enable audio workaround and start delivering of audio frames */
299 WREG32_P(offset+R600_HDMI_CNTL, 0x00001001, ~0x00001001);
300
301 } else {
302 /* disable audio workaround and stop delivering of audio frames */
303 WREG32_P(offset+R600_HDMI_CNTL, 0x00000000, ~0x00001001);
304 }
305}
306
307
308/*
309 * update the info frames with the data from the current display mode
310 */
311void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode)
312{
313 struct drm_device *dev = encoder->dev;
314 struct radeon_device *rdev = dev->dev_private;
315 uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
316
317 if (!offset)
318 return;
319
320 r600_audio_set_clock(encoder, mode->clock);
321
322 WREG32(offset+R600_HDMI_UNKNOWN_0, 0x1000);
323 WREG32(offset+R600_HDMI_UNKNOWN_1, 0x0);
324 WREG32(offset+R600_HDMI_UNKNOWN_2, 0x1000);
325
326 r600_hdmi_update_ACR(encoder, mode->clock);
327
328 WREG32(offset+R600_HDMI_VIDEOCNTL, 0x13);
329
330 WREG32(offset+R600_HDMI_VERSION, 0x202);
331
332 r600_hdmi_videoinfoframe(encoder, RGB, 0, 0, 0, 0,
333 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
334
335 /* it's unknown what these bits do excatly, but it's indeed quite usefull for debugging */
336 WREG32(offset+R600_HDMI_AUDIO_DEBUG_0, 0x00FFFFFF);
337 WREG32(offset+R600_HDMI_AUDIO_DEBUG_1, 0x007FFFFF);
338 WREG32(offset+R600_HDMI_AUDIO_DEBUG_2, 0x00000001);
339 WREG32(offset+R600_HDMI_AUDIO_DEBUG_3, 0x00000001);
340
341 r600_hdmi_audio_workaround(encoder);
342
343 /* audio packets per line, does anyone know how to calc this ? */
344 WREG32_P(offset+R600_HDMI_CNTL, 0x00040000, ~0x001F0000);
345
346 /* update? reset? don't realy know */
347 WREG32_P(offset+R600_HDMI_CNTL, 0x14000000, ~0x14000000);
348}
349
350/*
351 * update settings with current parameters from audio engine
352 */
353void r600_hdmi_update_audio_settings(struct drm_encoder *encoder,
354 int channels,
355 int rate,
356 int bps,
357 uint8_t status_bits,
358 uint8_t category_code)
359{
360 struct drm_device *dev = encoder->dev;
361 struct radeon_device *rdev = dev->dev_private;
362 uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
363
364 uint32_t iec;
365
366 if (!offset)
367 return;
368
369 DRM_DEBUG("%s with %d channels, %d Hz sampling rate, %d bits per sample,\n",
370 r600_hdmi_is_audio_buffer_filled(encoder) ? "playing" : "stopped",
371 channels, rate, bps);
372 DRM_DEBUG("0x%02X IEC60958 status bits and 0x%02X category code\n",
373 (int)status_bits, (int)category_code);
374
375 iec = 0;
376 if (status_bits & AUDIO_STATUS_PROFESSIONAL)
377 iec |= 1 << 0;
378 if (status_bits & AUDIO_STATUS_NONAUDIO)
379 iec |= 1 << 1;
380 if (status_bits & AUDIO_STATUS_COPYRIGHT)
381 iec |= 1 << 2;
382 if (status_bits & AUDIO_STATUS_EMPHASIS)
383 iec |= 1 << 3;
384
385 iec |= category_code << 8;
386
387 switch (rate) {
388 case 32000: iec |= 0x3 << 24; break;
389 case 44100: iec |= 0x0 << 24; break;
390 case 88200: iec |= 0x8 << 24; break;
391 case 176400: iec |= 0xc << 24; break;
392 case 48000: iec |= 0x2 << 24; break;
393 case 96000: iec |= 0xa << 24; break;
394 case 192000: iec |= 0xe << 24; break;
395 }
396
397 WREG32(offset+R600_HDMI_IEC60958_1, iec);
398
399 iec = 0;
400 switch (bps) {
401 case 16: iec |= 0x2; break;
402 case 20: iec |= 0x3; break;
403 case 24: iec |= 0xb; break;
404 }
405 if (status_bits & AUDIO_STATUS_V)
406 iec |= 0x5 << 16;
407
408 WREG32_P(offset+R600_HDMI_IEC60958_2, iec, ~0x5000f);
409
410 /* 0x021 or 0x031 sets the audio frame length */
411 WREG32(offset+R600_HDMI_AUDIOCNTL, 0x31);
412 r600_hdmi_audioinfoframe(encoder, channels-1, 0, 0, 0, 0, 0, 0, 0);
413
414 r600_hdmi_audio_workaround(encoder);
415
416 /* update? reset? don't realy know */
417 WREG32_P(offset+R600_HDMI_CNTL, 0x04000000, ~0x04000000);
418}
419
420/*
421 * enable/disable the HDMI engine
422 */
423void r600_hdmi_enable(struct drm_encoder *encoder, int enable)
424{
425 struct drm_device *dev = encoder->dev;
426 struct radeon_device *rdev = dev->dev_private;
427 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
428 uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
429
430 if (!offset)
431 return;
432
433 DRM_DEBUG("%s HDMI interface @ 0x%04X\n", enable ? "Enabling" : "Disabling", offset);
434
435 /* some version of atombios ignore the enable HDMI flag
436 * so enabling/disabling HDMI was moved here for TMDS1+2 */
437 switch (radeon_encoder->encoder_id) {
438 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
439 WREG32_P(AVIVO_TMDSA_CNTL, enable ? 0x4 : 0x0, ~0x4);
440 WREG32(offset+R600_HDMI_ENABLE, enable ? 0x101 : 0x0);
441 break;
442
443 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
444 WREG32_P(AVIVO_LVTMA_CNTL, enable ? 0x4 : 0x0, ~0x4);
445 WREG32(offset+R600_HDMI_ENABLE, enable ? 0x105 : 0x0);
446 break;
447
448 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
449 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
450 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
451 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
452 /* This part is doubtfull in my opinion */
453 WREG32(offset+R600_HDMI_ENABLE, enable ? 0x110 : 0x0);
454 break;
455
456 default:
457 DRM_ERROR("unknown HDMI output type\n");
458 break;
459 }
460}
461
462/*
463 * determin at which register offset the HDMI encoder is
464 */
465void r600_hdmi_init(struct drm_encoder *encoder)
466{
467 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
468
469 switch (radeon_encoder->encoder_id) {
470 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
471 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
472 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
473 radeon_encoder->hdmi_offset = R600_HDMI_TMDS1;
474 break;
475
476 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
477 switch (r600_audio_tmds_index(encoder)) {
478 case 0:
479 radeon_encoder->hdmi_offset = R600_HDMI_TMDS1;
480 break;
481 case 1:
482 radeon_encoder->hdmi_offset = R600_HDMI_TMDS2;
483 break;
484 default:
485 radeon_encoder->hdmi_offset = 0;
486 break;
487 }
488 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
489 radeon_encoder->hdmi_offset = R600_HDMI_TMDS2;
490 break;
491
492 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
493 radeon_encoder->hdmi_offset = R600_HDMI_DIG;
494 break;
495
496 default:
497 radeon_encoder->hdmi_offset = 0;
498 break;
499 }
500
501 DRM_DEBUG("using HDMI engine at offset 0x%04X for encoder 0x%x\n",
502 radeon_encoder->hdmi_offset, radeon_encoder->encoder_id);
503
504 /* TODO: make this configureable */
505 radeon_encoder->hdmi_audio_workaround = 0;
506}
diff --git a/drivers/gpu/drm/radeon/r600_reg.h b/drivers/gpu/drm/radeon/r600_reg.h
index e2d1f5f33f7e..d0e28ffdeda9 100644
--- a/drivers/gpu/drm/radeon/r600_reg.h
+++ b/drivers/gpu/drm/radeon/r600_reg.h
@@ -110,5 +110,79 @@
110#define R600_BIOS_6_SCRATCH 0x173c 110#define R600_BIOS_6_SCRATCH 0x173c
111#define R600_BIOS_7_SCRATCH 0x1740 111#define R600_BIOS_7_SCRATCH 0x1740
112 112
113/* Audio, these regs were reverse enginered,
114 * so the chance is high that the naming is wrong
115 * R6xx+ ??? */
116
117/* Audio clocks */
118#define R600_AUDIO_PLL1_MUL 0x0514
119#define R600_AUDIO_PLL1_DIV 0x0518
120#define R600_AUDIO_PLL2_MUL 0x0524
121#define R600_AUDIO_PLL2_DIV 0x0528
122#define R600_AUDIO_CLK_SRCSEL 0x0534
123
124/* Audio general */
125#define R600_AUDIO_ENABLE 0x7300
126#define R600_AUDIO_TIMING 0x7344
127
128/* Audio params */
129#define R600_AUDIO_VENDOR_ID 0x7380
130#define R600_AUDIO_REVISION_ID 0x7384
131#define R600_AUDIO_ROOT_NODE_COUNT 0x7388
132#define R600_AUDIO_NID1_NODE_COUNT 0x738c
133#define R600_AUDIO_NID1_TYPE 0x7390
134#define R600_AUDIO_SUPPORTED_SIZE_RATE 0x7394
135#define R600_AUDIO_SUPPORTED_CODEC 0x7398
136#define R600_AUDIO_SUPPORTED_POWER_STATES 0x739c
137#define R600_AUDIO_NID2_CAPS 0x73a0
138#define R600_AUDIO_NID3_CAPS 0x73a4
139#define R600_AUDIO_NID3_PIN_CAPS 0x73a8
140
141/* Audio conn list */
142#define R600_AUDIO_CONN_LIST_LEN 0x73ac
143#define R600_AUDIO_CONN_LIST 0x73b0
144
145/* Audio verbs */
146#define R600_AUDIO_RATE_BPS_CHANNEL 0x73c0
147#define R600_AUDIO_PLAYING 0x73c4
148#define R600_AUDIO_IMPLEMENTATION_ID 0x73c8
149#define R600_AUDIO_CONFIG_DEFAULT 0x73cc
150#define R600_AUDIO_PIN_SENSE 0x73d0
151#define R600_AUDIO_PIN_WIDGET_CNTL 0x73d4
152#define R600_AUDIO_STATUS_BITS 0x73d8
153
154/* HDMI base register addresses */
155#define R600_HDMI_TMDS1 0x7400
156#define R600_HDMI_TMDS2 0x7700
157#define R600_HDMI_DIG 0x7800
158
159/* HDMI registers */
160#define R600_HDMI_ENABLE 0x00
161#define R600_HDMI_STATUS 0x04
162#define R600_HDMI_CNTL 0x08
163#define R600_HDMI_UNKNOWN_0 0x0C
164#define R600_HDMI_AUDIOCNTL 0x10
165#define R600_HDMI_VIDEOCNTL 0x14
166#define R600_HDMI_VERSION 0x18
167#define R600_HDMI_UNKNOWN_1 0x28
168#define R600_HDMI_VIDEOINFOFRAME_0 0x54
169#define R600_HDMI_VIDEOINFOFRAME_1 0x58
170#define R600_HDMI_VIDEOINFOFRAME_2 0x5c
171#define R600_HDMI_VIDEOINFOFRAME_3 0x60
172#define R600_HDMI_32kHz_CTS 0xac
173#define R600_HDMI_32kHz_N 0xb0
174#define R600_HDMI_44_1kHz_CTS 0xb4
175#define R600_HDMI_44_1kHz_N 0xb8
176#define R600_HDMI_48kHz_CTS 0xbc
177#define R600_HDMI_48kHz_N 0xc0
178#define R600_HDMI_AUDIOINFOFRAME_0 0xcc
179#define R600_HDMI_AUDIOINFOFRAME_1 0xd0
180#define R600_HDMI_IEC60958_1 0xd4
181#define R600_HDMI_IEC60958_2 0xd8
182#define R600_HDMI_UNKNOWN_2 0xdc
183#define R600_HDMI_AUDIO_DEBUG_0 0xe0
184#define R600_HDMI_AUDIO_DEBUG_1 0xe4
185#define R600_HDMI_AUDIO_DEBUG_2 0xe8
186#define R600_HDMI_AUDIO_DEBUG_3 0xec
113 187
114#endif 188#endif
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index e3c494097f67..cd650fd3964e 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -89,6 +89,7 @@ extern int radeon_testing;
89extern int radeon_connector_table; 89extern int radeon_connector_table;
90extern int radeon_tv; 90extern int radeon_tv;
91extern int radeon_new_pll; 91extern int radeon_new_pll;
92extern int radeon_audio;
92 93
93/* 94/*
94 * Copy from radeon_drv.h so we don't have to include both and have conflicting 95 * Copy from radeon_drv.h so we don't have to include both and have conflicting
@@ -814,6 +815,14 @@ struct radeon_device {
814 struct r600_ih ih; /* r6/700 interrupt ring */ 815 struct r600_ih ih; /* r6/700 interrupt ring */
815 struct workqueue_struct *wq; 816 struct workqueue_struct *wq;
816 struct work_struct hotplug_work; 817 struct work_struct hotplug_work;
818
819 /* audio stuff */
820 struct timer_list audio_timer;
821 int audio_channels;
822 int audio_rate;
823 int audio_bits_per_sample;
824 uint8_t audio_status_bits;
825 uint8_t audio_category_code;
817}; 826};
818 827
819int radeon_device_init(struct radeon_device *rdev, 828int radeon_device_init(struct radeon_device *rdev,
@@ -1147,6 +1156,21 @@ extern void r600_irq_fini(struct radeon_device *rdev);
1147extern void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size); 1156extern void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size);
1148extern int r600_irq_set(struct radeon_device *rdev); 1157extern int r600_irq_set(struct radeon_device *rdev);
1149 1158
1159extern int r600_audio_init(struct radeon_device *rdev);
1160extern int r600_audio_tmds_index(struct drm_encoder *encoder);
1161extern void r600_audio_set_clock(struct drm_encoder *encoder, int clock);
1162extern void r600_audio_fini(struct radeon_device *rdev);
1163extern void r600_hdmi_init(struct drm_encoder *encoder);
1164extern void r600_hdmi_enable(struct drm_encoder *encoder, int enable);
1165extern void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode);
1166extern int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder);
1167extern void r600_hdmi_update_audio_settings(struct drm_encoder *encoder,
1168 int channels,
1169 int rate,
1170 int bps,
1171 uint8_t status_bits,
1172 uint8_t category_code);
1173
1150#include "radeon_object.h" 1174#include "radeon_object.h"
1151 1175
1152#endif 1176#endif
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index c5c45e626d74..dbd56ef82f9c 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -87,6 +87,7 @@ int radeon_testing = 0;
87int radeon_connector_table = 0; 87int radeon_connector_table = 0;
88int radeon_tv = 1; 88int radeon_tv = 1;
89int radeon_new_pll = 1; 89int radeon_new_pll = 1;
90int radeon_audio = 1;
90 91
91MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); 92MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers");
92module_param_named(no_wb, radeon_no_wb, int, 0444); 93module_param_named(no_wb, radeon_no_wb, int, 0444);
@@ -124,6 +125,9 @@ module_param_named(tv, radeon_tv, int, 0444);
124MODULE_PARM_DESC(new_pll, "Select new PLL code for AVIVO chips"); 125MODULE_PARM_DESC(new_pll, "Select new PLL code for AVIVO chips");
125module_param_named(new_pll, radeon_new_pll, int, 0444); 126module_param_named(new_pll, radeon_new_pll, int, 0444);
126 127
128MODULE_PARM_DESC(audio, "Audio enable (0 = disable)");
129module_param_named(audio, radeon_audio, int, 0444);
130
127static int radeon_suspend(struct drm_device *dev, pm_message_t state) 131static int radeon_suspend(struct drm_device *dev, pm_message_t state)
128{ 132{
129 drm_radeon_private_t *dev_priv = dev->dev_private; 133 drm_radeon_private_t *dev_priv = dev->dev_private;
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c
index b4f23ec93201..0d1d908e5225 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -438,6 +438,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
438 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 438 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
439 union lvds_encoder_control args; 439 union lvds_encoder_control args;
440 int index = 0; 440 int index = 0;
441 int hdmi_detected = 0;
441 uint8_t frev, crev; 442 uint8_t frev, crev;
442 struct radeon_encoder_atom_dig *dig; 443 struct radeon_encoder_atom_dig *dig;
443 struct drm_connector *connector; 444 struct drm_connector *connector;
@@ -458,6 +459,9 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
458 if (!radeon_connector->con_priv) 459 if (!radeon_connector->con_priv)
459 return; 460 return;
460 461
462 if (drm_detect_hdmi_monitor(radeon_connector->edid))
463 hdmi_detected = 1;
464
461 dig_connector = radeon_connector->con_priv; 465 dig_connector = radeon_connector->con_priv;
462 466
463 memset(&args, 0, sizeof(args)); 467 memset(&args, 0, sizeof(args));
@@ -487,7 +491,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
487 case 1: 491 case 1:
488 args.v1.ucMisc = 0; 492 args.v1.ucMisc = 0;
489 args.v1.ucAction = action; 493 args.v1.ucAction = action;
490 if (drm_detect_hdmi_monitor(radeon_connector->edid)) 494 if (hdmi_detected)
491 args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; 495 args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
492 args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); 496 args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
493 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { 497 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
@@ -512,7 +516,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
512 if (dig->coherent_mode) 516 if (dig->coherent_mode)
513 args.v2.ucMisc |= PANEL_ENCODER_MISC_COHERENT; 517 args.v2.ucMisc |= PANEL_ENCODER_MISC_COHERENT;
514 } 518 }
515 if (drm_detect_hdmi_monitor(radeon_connector->edid)) 519 if (hdmi_detected)
516 args.v2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; 520 args.v2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
517 args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); 521 args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
518 args.v2.ucTruncate = 0; 522 args.v2.ucTruncate = 0;
@@ -552,7 +556,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
552 } 556 }
553 557
554 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 558 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
555 559 r600_hdmi_enable(encoder, hdmi_detected);
556} 560}
557 561
558int 562int
@@ -893,7 +897,6 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
893 } 897 }
894 898
895 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 899 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
896
897} 900}
898 901
899static void 902static void
@@ -1162,7 +1165,6 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder)
1162 } 1165 }
1163 1166
1164 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 1167 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
1165
1166} 1168}
1167 1169
1168static void 1170static void
@@ -1265,6 +1267,8 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
1265 break; 1267 break;
1266 } 1268 }
1267 atombios_apply_encoder_quirks(encoder, adjusted_mode); 1269 atombios_apply_encoder_quirks(encoder, adjusted_mode);
1270
1271 r600_hdmi_setmode(encoder, adjusted_mode);
1268} 1272}
1269 1273
1270static bool 1274static bool
@@ -1510,4 +1514,6 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su
1510 drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); 1514 drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs);
1511 break; 1515 break;
1512 } 1516 }
1517
1518 r600_hdmi_init(encoder);
1513} 1519}
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 44d4b652ea12..3dcbe130c422 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -334,6 +334,9 @@ struct radeon_encoder {
334 enum radeon_rmx_type rmx_type; 334 enum radeon_rmx_type rmx_type;
335 struct drm_display_mode native_mode; 335 struct drm_display_mode native_mode;
336 void *enc_priv; 336 void *enc_priv;
337 int hdmi_offset;
338 int hdmi_audio_workaround;
339 int hdmi_buffer_status;
337}; 340};
338 341
339struct radeon_connector_atom_dig { 342struct radeon_connector_atom_dig {