diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/evergreen_hdmi.c')
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen_hdmi.c | 54 |
1 files changed, 39 insertions, 15 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index b0e280058b9b..c5acdf0a301a 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c | |||
@@ -32,6 +32,9 @@ | |||
32 | #include "evergreend.h" | 32 | #include "evergreend.h" |
33 | #include "atom.h" | 33 | #include "atom.h" |
34 | 34 | ||
35 | extern void dce6_afmt_write_sad_regs(struct drm_encoder *encoder); | ||
36 | extern void dce6_afmt_select_pin(struct drm_encoder *encoder); | ||
37 | |||
35 | /* | 38 | /* |
36 | * update the N and CTS parameters for a given pixel clock rate | 39 | * update the N and CTS parameters for a given pixel clock rate |
37 | */ | 40 | */ |
@@ -157,22 +160,26 @@ static void evergreen_audio_set_dto(struct drm_encoder *encoder, u32 clock) | |||
157 | if (!dig || !dig->afmt) | 160 | if (!dig || !dig->afmt) |
158 | return; | 161 | return; |
159 | 162 | ||
160 | if (max_ratio >= 8) { | 163 | if (ASIC_IS_DCE6(rdev)) { |
161 | dto_phase = 192 * 1000; | ||
162 | wallclock_ratio = 3; | ||
163 | } else if (max_ratio >= 4) { | ||
164 | dto_phase = 96 * 1000; | ||
165 | wallclock_ratio = 2; | ||
166 | } else if (max_ratio >= 2) { | ||
167 | dto_phase = 48 * 1000; | ||
168 | wallclock_ratio = 1; | ||
169 | } else { | ||
170 | dto_phase = 24 * 1000; | 164 | dto_phase = 24 * 1000; |
171 | wallclock_ratio = 0; | 165 | } else { |
166 | if (max_ratio >= 8) { | ||
167 | dto_phase = 192 * 1000; | ||
168 | wallclock_ratio = 3; | ||
169 | } else if (max_ratio >= 4) { | ||
170 | dto_phase = 96 * 1000; | ||
171 | wallclock_ratio = 2; | ||
172 | } else if (max_ratio >= 2) { | ||
173 | dto_phase = 48 * 1000; | ||
174 | wallclock_ratio = 1; | ||
175 | } else { | ||
176 | dto_phase = 24 * 1000; | ||
177 | wallclock_ratio = 0; | ||
178 | } | ||
179 | dto_cntl = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK; | ||
180 | dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio); | ||
181 | WREG32(DCCG_AUDIO_DTO0_CNTL, dto_cntl); | ||
172 | } | 182 | } |
173 | dto_cntl = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK; | ||
174 | dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio); | ||
175 | WREG32(DCCG_AUDIO_DTO0_CNTL, dto_cntl); | ||
176 | 183 | ||
177 | /* XXX two dtos; generally use dto0 for hdmi */ | 184 | /* XXX two dtos; generally use dto0 for hdmi */ |
178 | /* Express [24MHz / target pixel clock] as an exact rational | 185 | /* Express [24MHz / target pixel clock] as an exact rational |
@@ -266,7 +273,13 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode | |||
266 | AFMT_AUDIO_CHANNEL_ENABLE(0xff)); | 273 | AFMT_AUDIO_CHANNEL_ENABLE(0xff)); |
267 | 274 | ||
268 | /* fglrx sets 0x40 in 0x5f80 here */ | 275 | /* fglrx sets 0x40 in 0x5f80 here */ |
269 | evergreen_hdmi_write_sad_regs(encoder); | 276 | |
277 | if (ASIC_IS_DCE6(rdev)) { | ||
278 | dce6_afmt_select_pin(encoder); | ||
279 | dce6_afmt_write_sad_regs(encoder); | ||
280 | } else { | ||
281 | evergreen_hdmi_write_sad_regs(encoder); | ||
282 | } | ||
270 | 283 | ||
271 | err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode); | 284 | err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode); |
272 | if (err < 0) { | 285 | if (err < 0) { |
@@ -302,6 +315,8 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode | |||
302 | 315 | ||
303 | void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable) | 316 | void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable) |
304 | { | 317 | { |
318 | struct drm_device *dev = encoder->dev; | ||
319 | struct radeon_device *rdev = dev->dev_private; | ||
305 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 320 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
306 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 321 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
307 | 322 | ||
@@ -314,6 +329,15 @@ void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable) | |||
314 | if (!enable && !dig->afmt->enabled) | 329 | if (!enable && !dig->afmt->enabled) |
315 | return; | 330 | return; |
316 | 331 | ||
332 | if (enable) { | ||
333 | if (ASIC_IS_DCE6(rdev)) | ||
334 | dig->afmt->pin = dce6_audio_get_pin(rdev); | ||
335 | else | ||
336 | dig->afmt->pin = r600_audio_get_pin(rdev); | ||
337 | } else { | ||
338 | dig->afmt->pin = NULL; | ||
339 | } | ||
340 | |||
317 | dig->afmt->enabled = enable; | 341 | dig->afmt->enabled = enable; |
318 | 342 | ||
319 | DRM_DEBUG("%sabling HDMI interface @ 0x%04X for encoder 0x%x\n", | 343 | DRM_DEBUG("%sabling HDMI interface @ 0x%04X for encoder 0x%x\n", |