Skip to content

Commit

Permalink
drm/radeon/dce2: use 10khz units for audio dto calculation
Browse files Browse the repository at this point in the history
Avoids overflows on DCE2.x devices. Also clarify the calculation
on other asics.

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
  • Loading branch information
Alex Deucher committed May 20, 2013
1 parent fc98603 commit 731da21
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 9 deletions.
7 changes: 3 additions & 4 deletions drivers/gpu/drm/radeon/evergreen_hdmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,19 +154,18 @@ static void evergreen_audio_set_dto(struct drm_encoder *encoder, u32 clock)
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
u32 base_rate = 48000;
u32 base_rate = 24000;

if (!dig || !dig->afmt)
return;

/* 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_DTO0_PHASE, base_rate * 100);
WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100);
WREG32(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL(radeon_crtc->crtc_id));
}

Expand Down
9 changes: 4 additions & 5 deletions drivers/gpu/drm/radeon/r600_hdmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,15 +232,14 @@ void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock)
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;
u32 base_rate = 24000;

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
Expand All @@ -250,13 +249,13 @@ void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock)
/* according to the reg specs, this should DCE3.2 only, but in
* practice it seems to cover DCE3.0 as well.
*/
WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 50);
WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 100);
WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100);
WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */
} else {
/* according to the reg specs, this should be DCE2.0 and DCE3.0 */
WREG32(AUDIO_DTO, AUDIO_DTO_PHASE(base_rate * 50) |
AUDIO_DTO_MODULE(clock * 100));
WREG32(AUDIO_DTO, AUDIO_DTO_PHASE(base_rate / 10) |
AUDIO_DTO_MODULE(clock / 10));
}
}

Expand Down

0 comments on commit 731da21

Please sign in to comment.