From 9d3e1e6cc94f0bd6739c00e29aef148c0b194192 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 4 Jan 2010 18:23:55 -0500 Subject: [PATCH] drm/radeon/kms: update LVDS power sequence Based on r4xx atombios. This might help LVDS resume on some pre-atom laptops. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_legacy_encoders.c | 57 ++++++++++++++--------- 1 files changed, 35 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index eb1af3a..cd4d16c 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c @@ -44,7 +44,7 @@ static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode) struct drm_device *dev = encoder->dev; struct radeon_device *rdev = dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - uint32_t lvds_gen_cntl, lvds_pll_cntl, pixclks_cntl, disp_pwr_man; + u32 lvds_gen_cntl, pixclks_cntl; int panel_pwr_delay = 2000; DRM_DEBUG("\n"); @@ -60,20 +60,8 @@ static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode) switch (mode) { case DRM_MODE_DPMS_ON: - disp_pwr_man = RREG32(RADEON_DISP_PWR_MAN); - disp_pwr_man |= RADEON_AUTO_PWRUP_EN; - WREG32(RADEON_DISP_PWR_MAN, disp_pwr_man); - lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL); - lvds_pll_cntl |= RADEON_LVDS_PLL_EN; - WREG32(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl); - udelay(1000); - - lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL); - lvds_pll_cntl &= ~RADEON_LVDS_PLL_RESET; - WREG32(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl); - lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL); - lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_EN | RADEON_LVDS_DIGON | RADEON_LVDS_BLON); + lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_BLON); lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS); udelay(panel_pwr_delay * 1000); WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); @@ -85,7 +73,7 @@ static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode) WREG32_PLL_P(RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb); lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL); lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS; - lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN | RADEON_LVDS_DIGON); + lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON); udelay(panel_pwr_delay * 1000); WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); @@ -131,14 +119,29 @@ static void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder, struct radeon_device *rdev = dev->dev_private; struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - uint32_t lvds_pll_cntl, lvds_gen_cntl, lvds_ss_gen_cntl; + u32 lvds_pll_cntl, lvds_gen_cntl, lvds_ss_gen_cntl, disp_pwr_man; + int panel_pwr_delay = 2000; DRM_DEBUG("\n"); + if (radeon_encoder->enc_priv) { + if (rdev->is_atom_bios) { + struct radeon_encoder_atom_dig *lvds = radeon_encoder->enc_priv; + panel_pwr_delay = lvds->panel_pwr_delay; + } else { + struct radeon_encoder_lvds *lvds = radeon_encoder->enc_priv; + panel_pwr_delay = lvds->panel_pwr_delay; + } + } + lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL); - lvds_pll_cntl &= ~RADEON_LVDS_PLL_EN; + lvds_pll_cntl &= ~(RADEON_LVDS_PLL_EN | RADEON_LVDS_PLL_RESET); lvds_ss_gen_cntl = RREG32(RADEON_LVDS_SS_GEN_CNTL); + + disp_pwr_man = RREG32(RADEON_DISP_PWR_MAN); + disp_pwr_man |= RADEON_AUTO_PWRUP_EN; + if (rdev->is_atom_bios) { /* LVDS_GEN_CNTL parameters are computed in LVDSEncoderControl * need to call that on resume to set up the reg properly. @@ -158,10 +161,12 @@ static void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder, } else lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL); } - lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS; + lvds_gen_cntl |= (RADEON_LVDS_DISPLAY_DIS | + /*RADEON_LVDS_DIGON | */ + RADEON_LVDS_EN); + lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | - RADEON_LVDS_EN | RADEON_LVDS_RST_FM); if (ASIC_IS_R300(rdev)) @@ -180,9 +185,17 @@ static void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder, lvds_gen_cntl |= RADEON_LVDS_SEL_CRTC2; } - WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); - WREG32(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl); - WREG32(RADEON_LVDS_SS_GEN_CNTL, lvds_ss_gen_cntl); + if (rdev->is_atom_bios) { + WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); + } else { + WREG32(RADEON_LVDS_SS_GEN_CNTL, lvds_ss_gen_cntl); + WREG32(RADEON_DISP_PWR_MAN, disp_pwr_man); + WREG32(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl | RADEON_LVDS_PLL_EN); + udelay(panel_pwr_delay * 1000); + WREG32(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl); + udelay(panel_pwr_delay * 1000); + WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); + } if (rdev->family == CHIP_RV410) WREG32(RADEON_CLOCK_CNTL_INDEX, 0); -- 1.5.6.3