On all dual CRTC GPUs the CRTC_CRT_ON in the RADEON_CRTC_EXT_CNTL register controls the CRTC of the primary DAC. Therefore it is set in the DAC DMPS function. This is different for GPU's with a single CRTC but a primary and a TV DAC: here it controls the single CRTC no matter where it is routed. Therefore we set it here. This avoids an elaborate on/off state tracking since both primary_dac_dpms() and tv_dac_dpms() functions would have to touch this bit. On single CRTC GPUs with just one DAC it's irrelevant where this bit is handled. Signed-off-by: Egbert Eich <eich@xxxxxxx> --- drivers/gpu/drm/radeon/radeon_legacy_crtc.c | 15 +++++++++++++-- drivers/gpu/drm/radeon/radeon_legacy_encoders.c | 7 +++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 5677a42..6857cb4 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c @@ -295,6 +295,7 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct drm_device *dev = crtc->dev; struct radeon_device *rdev = dev->dev_private; + uint32_t crtc_ext_cntl = 0; uint32_t mask; if (radeon_crtc->crtc_id) @@ -307,6 +308,16 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) RADEON_CRTC_VSYNC_DIS | RADEON_CRTC_HSYNC_DIS); + /* + * On all dual CRTC GPUs this bit controls the CRTC of the primary DAC. + * Therefore it is set in the DAC DMPS function. + * This is different for GPU's with a single CRTC but a primary and a + * TV DAC: here it controls the single CRTC no matter where it is + * routed. Therefore we set it here. + */ + if (rdev->flags & RADEON_SINGLE_CRTC) + crtc_ext_cntl = RADEON_CRTC_CRT_ON; + switch (mode) { case DRM_MODE_DPMS_ON: radeon_crtc->enabled = true; @@ -317,7 +328,7 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) else { WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_EN, ~(RADEON_CRTC_EN | RADEON_CRTC_DISP_REQ_EN_B)); - WREG32_P(RADEON_CRTC_EXT_CNTL, 0, ~mask); + WREG32_P(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl, ~(mask | crtc_ext_cntl)); } drm_vblank_post_modeset(dev, radeon_crtc->crtc_id); radeon_crtc_load_lut(crtc); @@ -331,7 +342,7 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) else { WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~(RADEON_CRTC_EN | RADEON_CRTC_DISP_REQ_EN_B)); - WREG32_P(RADEON_CRTC_EXT_CNTL, mask, ~mask); + WREG32_P(RADEON_CRTC_EXT_CNTL, mask, ~(mask | crtc_ext_cntl)); } radeon_crtc->enabled = false; /* adjust pm to dpms changes AFTER disabling crtcs */ diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index c05b42a..500d3da 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c @@ -534,7 +534,9 @@ static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode break; } - WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); + /* handled in radeon_crtc_dpms() */ + if (!rdev->flags & RADEON_SINGLE_CRTC) + WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); WREG32(RADEON_DAC_CNTL, dac_cntl); WREG32(RADEON_DAC_MACRO_CNTL, dac_macro_cntl); @@ -1095,7 +1097,8 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) } else { if (is_tv) WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl); - else + /* handled in radeon_crtc_dpms() */ + else if (!rdev->flags & RADEON_SINGLE_CRTC) WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); } -- 1.7.6.3 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel