---
drivers/gpu/drm/radeon/atombios_crtc.c | 2 ++
drivers/gpu/drm/radeon/evergreen_hdmi.c | 9 +++++----
drivers/gpu/drm/radeon/r600_hdmi.c | 16 +++++++++-------
drivers/gpu/drm/radeon/radeon_mode.h | 1 +
4 files changed, 17 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index bf87f6d..3a6059f 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -1027,6 +1027,8 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
radeon_compute_pll_legacy(pll, radeon_crtc->adjusted_clock, &pll_clock,
&fb_div, &frac_fb_div, &ref_div, &post_div);
+ radeon_crtc->pll_clock = pll_clock * 10; /* convert to khz units */
+
atombios_crtc_program_ss(rdev, ATOM_DISABLE, radeon_crtc->pll_id,
radeon_crtc->crtc_id, &radeon_crtc->ss);
diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c
index 6787365..0d55870 100644
--- a/drivers/gpu/drm/radeon/evergreen_hdmi.c
+++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c
@@ -225,7 +225,7 @@ static void evergreen_hdmi_update_avi_infoframe(struct drm_encoder *encoder,
frame[0xC] | (frame[0xD] << 8) | (header[1] << 24));
}
-static void evergreen_audio_set_dto(struct drm_encoder *encoder, u32 clock)
+static void evergreen_audio_set_dto(struct drm_encoder *encoder)
{
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
@@ -233,9 +233,10 @@ static void evergreen_audio_set_dto(struct drm_encoder *encoder, u32 clock)
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
u32 base_rate = 24000;
- u32 max_ratio = clock / base_rate;
+ u32 max_ratio = radeon_crtc->pll_clock / base_rate;
u32 dto_phase;
- u32 dto_modulo = clock;
+ /* need to use the exact pll clock here to keep audio rate correct */
+ u32 dto_modulo = radeon_crtc->pll_clock;
u32 wallclock_ratio;
u32 dto_cntl;
@@ -296,7 +297,7 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode
return;
offset = dig->afmt->offset;
- evergreen_audio_set_dto(encoder, mode->clock);
+ evergreen_audio_set_dto(encoder);
WREG32(HDMI_VBI_PACKET_CONTROL + offset,
HDMI_NULL_SEND); /* send null packets when required */
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c
index 21f2b74..b8c444e 100644
--- a/drivers/gpu/drm/radeon/r600_hdmi.c
+++ b/drivers/gpu/drm/radeon/r600_hdmi.c
@@ -219,16 +219,18 @@ 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)
+static void r600_audio_set_dto(struct drm_encoder *encoder)
{
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;
+ struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
u32 base_rate = 24000;
- u32 max_ratio = clock / base_rate;
+ u32 max_ratio = radeon_crtc->pll_clock / base_rate;
u32 dto_phase;
- u32 dto_modulo = clock;
+ /* need to use the exact pll clock here to keep audio rate correct */
+ u32 dto_modulo = radeon_crtc->pll_clock;
u32 wallclock_ratio;
u32 dto_cntl;
@@ -279,17 +281,17 @@ void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock)
*/
if (dig->dig_encoder == 0) {
WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 100);
- WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100);
+ WREG32(DCCG_AUDIO_DTO0_MODULE, dto_modulo * 100);
WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */
} else {
WREG32(DCCG_AUDIO_DTO1_PHASE, base_rate * 100);
- WREG32(DCCG_AUDIO_DTO1_MODULE, clock * 100);
+ WREG32(DCCG_AUDIO_DTO1_MODULE, dto_modulo * 100);
WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */
}
} else {
/* according to the reg specs, this should be DCE2.0 and DCE3.0/3.1 */
WREG32(AUDIO_DTO, AUDIO_DTO_PHASE(base_rate / 10) |
- AUDIO_DTO_MODULE(clock / 10));
+ AUDIO_DTO_MODULE(dto_modulo / 10));
}
}
@@ -420,7 +422,7 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod
return;
offset = dig->afmt->offset;
- r600_audio_set_dto(encoder, mode->clock);
+ r600_audio_set_dto(encoder);
WREG32(HDMI0_VBI_PACKET_CONTROL + offset,
HDMI0_NULL_SEND); /* send null packets when required */
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 8b4e712..5b5339b 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -341,6 +341,7 @@ struct radeon_crtc {
u32 wm_low;
u32 wm_high;
struct drm_display_mode hw_mode;
+ u32 pll_clock; /* actual clock generated by the pll */
};
struct radeon_encoder_primary_dac {