diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2013-04-18 16:50:55 +0200 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2013-04-24 00:03:53 +0200 |
commit | b1f6f47e3e33c4a74534f1301aca241ffabbb3a0 (patch) | |
tree | 22542b1fb96d0cf822c1bdbc4db76fe072260d93 /drivers/gpu/drm/radeon/r600_hdmi.c | |
parent | drm/radeon: clean up audio supported check (diff) | |
download | linux-b1f6f47e3e33c4a74534f1301aca241ffabbb3a0.tar.xz linux-b1f6f47e3e33c4a74534f1301aca241ffabbb3a0.zip |
drm/radeon: clean up audio dto programming
Split into DCE2/3 and DCE4/5 variants. Still todo is to
calculate the DTO dividers properly. Add proper formula
to the comments.
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
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) value, ~HDMI0_AUDIO_TEST_EN); } +void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock) +{ + struct drm_device *dev = encoder->dev; + struct radeon_device *rdev = dev->dev_private; + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; + u32 base_rate = 48000; + + if (!dig || !dig->afmt) + return; + + /* there are two DTOs selected by DCCG_AUDIO_DTO_SELECT. + * doesn't matter which one you use. Just use the first one. + */ + /* XXX: properly calculate this */ + /* XXX two dtos; generally use dto0 for hdmi */ + /* Express [24MHz / target pixel clock] as an exact rational + * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE + * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator + */ + WREG32(DCCG_AUDIO_DTO0_PHASE, (base_rate*50) & 0xffffff); + WREG32(DCCG_AUDIO_DTO0_MODULE, (clock*100) & 0xffffff); + WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */ +} /* * 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 return; offset = dig->afmt->offset; - r600_audio_set_clock(encoder, mode->clock); + r600_audio_set_dto(encoder, mode->clock); WREG32(HDMI0_VBI_PACKET_CONTROL + offset, HDMI0_NULL_SEND); /* send null packets when required */ |