diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/r600_hdmi.c')
-rw-r--r-- | drivers/gpu/drm/radeon/r600_hdmi.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 95397b215701..62721bfabe77 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c | |||
@@ -226,6 +226,30 @@ static void r600_hdmi_audio_workaround(struct drm_encoder *encoder) | |||
226 | value, ~HDMI0_AUDIO_TEST_EN); | 226 | value, ~HDMI0_AUDIO_TEST_EN); |
227 | } | 227 | } |
228 | 228 | ||
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 = 48000; | ||
236 | |||
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: properly calculate this */ | ||
244 | /* XXX two dtos; generally use dto0 for hdmi */ | ||
245 | /* Express [24MHz / target pixel clock] as an exact rational | ||
246 | * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE | ||
247 | * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator | ||
248 | */ | ||
249 | WREG32(DCCG_AUDIO_DTO0_PHASE, (base_rate*50) & 0xffffff); | ||
250 | WREG32(DCCG_AUDIO_DTO0_MODULE, (clock*100) & 0xffffff); | ||
251 | WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */ | ||
252 | } | ||
229 | 253 | ||
230 | /* | 254 | /* |
231 | * update the info frames with the data from the current display mode | 255 | * update the info frames with the data from the current display mode |
@@ -246,7 +270,7 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod | |||
246 | return; | 270 | return; |
247 | offset = dig->afmt->offset; | 271 | offset = dig->afmt->offset; |
248 | 272 | ||
249 | r600_audio_set_clock(encoder, mode->clock); | 273 | r600_audio_set_dto(encoder, mode->clock); |
250 | 274 | ||
251 | WREG32(HDMI0_VBI_PACKET_CONTROL + offset, | 275 | WREG32(HDMI0_VBI_PACKET_CONTROL + offset, |
252 | HDMI0_NULL_SEND); /* send null packets when required */ | 276 | HDMI0_NULL_SEND); /* send null packets when required */ |