From e8554b61f8a4f0fcf81ed8fea406ea49550d287c Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 8 Jul 2013 09:33:52 -0400 Subject: [PATCH] drm/radeon/dce4: save/restore backlight registers (v2) This may fix problems restoring the backlight on certain APUs after resume from suspend. v2: fix struct naming Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/evergreen.c | 46 +++++++++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/evergreend.h | 9 +++++++ drivers/gpu/drm/radeon/radeon.h | 8 ++++++ 3 files changed, 63 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index e49059d..9e14007 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1186,6 +1186,49 @@ void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev) } } +static void dce4_save_bl_registers(struct radeon_device *rdev) +{ + struct evergreen_bl_state *bl_state = &rdev->config.evergreen.bl_state; + + if (!(rdev->flags & RADEON_IS_MOBILITY)) + return; + + if (ASIC_IS_DCE6(rdev)) + return; + + bl_state->bl_pwm_cntl = RREG32(BL_PWM_CNTL); + bl_state->bl_pwm_cntl2 = RREG32(BL_PWM_CNTL2); + bl_state->bl_period_cntl = RREG32(BL_PWM_PERIOD_CNTL); + bl_state->bl_pwm_ref_div = + (RREG32(LVTMA_PWRSEQ_REF_DIV) & BL_PWM_REF_DIV_MASK) >> BL_PWM_REF_DIV_SHIFT; + +} + +static void dce4_restore_bl_registers(struct radeon_device *rdev) +{ + u32 bl_pwm_cntl, tmp; + struct evergreen_bl_state *bl_state = &rdev->config.evergreen.bl_state; + + if (!(rdev->flags & RADEON_IS_MOBILITY)) + return; + + if (ASIC_IS_DCE6(rdev)) + return; + + bl_pwm_cntl = RREG32(BL_PWM_CNTL) & 0xffff; + if ((bl_pwm_cntl == 0) && bl_state->bl_pwm_cntl) { + WREG32(BL_PWM_CNTL, bl_state->bl_pwm_cntl); + WREG32(BL_PWM_CNTL2, bl_state->bl_pwm_cntl2); + WREG32(BL_PWM_PERIOD_CNTL, bl_state->bl_period_cntl); + tmp = RREG32(LVTMA_PWRSEQ_REF_DIV) & ~BL_PWM_REF_DIV_MASK; + tmp |= BL_PWM_REF_DIV(bl_state->bl_pwm_ref_div); + WREG32(LVTMA_PWRSEQ_REF_DIV, tmp); + } + + tmp = RREG32(BL_PWM_CNTL); + WREG32(BL_PWM_CNTL, tmp | BL_PWM_EN); +} + static bool dce4_is_in_vblank(struct radeon_device *rdev, int crtc) { if (RREG32(EVERGREEN_CRTC_STATUS + crtc_offsets[crtc]) & EVERGREEN_CRTC_V_BLANK) @@ -5270,6 +5313,8 @@ int evergreen_resume(struct radeon_device *rdev) /* init golden registers */ evergreen_init_golden_registers(rdev); + dce4_restore_bl_registers(rdev); + rdev->accel_working = true; r = evergreen_startup(rdev); if (r) { @@ -5284,6 +5329,7 @@ int evergreen_resume(struct radeon_device *rdev) int evergreen_suspend(struct radeon_device *rdev) { + dce4_save_bl_registers(rdev); r600_audio_fini(rdev); radeon_uvd_suspend(rdev); r700_cp_stop(rdev); diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index a7baf67..e68727b 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h @@ -757,6 +757,15 @@ # define PIN3_AUDIO_ENABLED (1 << 27) # define AUDIO_ENABLED (1 << 31) +#define LVTMA_PWRSEQ_REF_DIV 0x6590 +# define BL_PWM_REF_DIV(x) ((x) << 16) +# define BL_PWM_REF_DIV_MASK (0xffff << 16) +# define BL_PWM_REF_DIV_SHIFT 16 + +#define BL_PWM_CNTL 0x659c +# define BL_PWM_EN (1 << 31) +#define BL_PWM_CNTL2 0x65a0 +#define BL_PWM_PERIOD_CNTL 0x65a4 #define GC_USER_SHADER_PIPE_CONFIG 0x8954 #define INACTIVE_QD_PIPES(x) ((x) << 8) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 9b7025d..979762e 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1750,6 +1750,13 @@ struct rv770_asic { unsigned backend_map; }; +struct evergreen_bl_state { + u32 bl_pwm_cntl; + u32 bl_pwm_cntl2; + u32 bl_period_cntl; + u32 bl_pwm_ref_div; +}; + struct evergreen_asic { unsigned num_ses; unsigned max_pipes; @@ -1774,6 +1781,7 @@ struct evergreen_asic { unsigned tiling_group_size; unsigned tile_config; unsigned backend_map; + struct evergreen_bl_state bl_state; }; struct cayman_asic { -- 1.7.7.5