From bd5b8bb252bea95666852671ef8e448ead9b6b70 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 26 Oct 2012 10:03:47 -0400 Subject: [PATCH] drm/radeon: further fixes for evergreen_mc_stop/resume (v2) Take the crtc hw lock when updating the crtc registers. This forces updates to be atomic rather than double buffered. v2: disable the hw cursor and icon May fix: https://bugs.freedesktop.org/show_bug.cgi?id=56139 Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/evergreen.c | 17 +++++++++++++++++ drivers/gpu/drm/radeon/evergreen_reg.h | 9 +++++++++ 2 files changed, 26 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 14313ad..b839ff0 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1308,6 +1308,18 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav crtc_enabled = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]) & EVERGREEN_CRTC_MASTER_EN; if (crtc_enabled) { save->crtc_enabled[i] = true; + /* disable the cursor */ + WREG32(EVERGREEN_CUR_UPDATE + crtc_offsets[i], EVERGREEN_CURSOR_UPDATE_LOCK); + tmp = RREG32(EVERGREEN_CUR_CONTROL + crtc_offsets[i]) & ~EVERGREEN_CURSOR_EN; + WREG32(EVERGREEN_CUR_CONTROL + crtc_offsets[i], tmp); + WREG32(EVERGREEN_CUR_UPDATE + crtc_offsets[i], 0); + /* disable the icon */ + WREG32(EVERGREEN_ICON_UPDATE + crtc_offsets[i], EVERGREEN_ICON_UPDATE_LOCK); + tmp = RREG32(EVERGREEN_ICON_CONTROL + crtc_offsets[i]) & ~EVERGREEN_ICON_EN; + WREG32(EVERGREEN_ICON_CONTROL + crtc_offsets[i], tmp); + WREG32(EVERGREEN_ICON_UPDATE + crtc_offsets[i], 0); + /* disable memory requests, but leave timing enabled */ + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1); if (ASIC_IS_DCE6(rdev)) { tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]); if (!(tmp & EVERGREEN_CRTC_BLANK_DATA_EN)) { @@ -1323,6 +1335,7 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp); } } + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0); /* wait for the next frame */ frame_count = radeon_get_vblank_counter(rdev, i); for (j = 0; j < rdev->usec_timeout; j++) { @@ -1352,6 +1365,7 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s /* update crtc base addresses */ for (i = 0; i < rdev->num_crtc; i++) { + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1); WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i], upper_32_bits(rdev->mc.vram_start)); WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i], @@ -1360,6 +1374,7 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s (u32)rdev->mc.vram_start); WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + crtc_offsets[i], (u32)rdev->mc.vram_start); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0); } WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(rdev->mc.vram_start)); WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start); @@ -1373,6 +1388,7 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s for (i = 0; i < rdev->num_crtc; i++) { if (save->crtc_enabled) { + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1); if (ASIC_IS_DCE6(rdev)) { tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]); tmp |= EVERGREEN_CRTC_BLANK_DATA_EN; @@ -1382,6 +1398,7 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s tmp &= ~EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE; WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp); } + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0); /* wait for the next frame */ frame_count = radeon_get_vblank_counter(rdev, i); for (j = 0; j < rdev->usec_timeout; j++) { diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h b/drivers/gpu/drm/radeon/evergreen_reg.h index 034f4c2..9fc8527 100644 --- a/drivers/gpu/drm/radeon/evergreen_reg.h +++ b/drivers/gpu/drm/radeon/evergreen_reg.h @@ -178,6 +178,15 @@ # define EVERGREEN_CURSOR_UPDATE_LOCK (1 << 16) # define EVERGREEN_CURSOR_DISABLE_MULTIPLE_UPDATE (1 << 24) +#define EVERGREEN_ICON_CONTROL 0x69bc +# define EVERGREEN_ICON_EN (1 << 0) + +#define EVERGREEN_ICON_UPDATE 0x69d8 +# define EVERGREEN_ICON_UPDATE_PENDING (1 << 0) +# define EVERGREEN_ICON_UPDATE_TAKEN (1 << 1) +# define EVERGREEN_ICON_UPDATE_LOCK (1 << 16) +# define EVERGREEN_ICON_DISABLE_MULTIPLE_UPDATE (1 << 24) + /* LUT blocks at 0x69e0, 0x75e0, 0x101e0, 0x10de0, 0x119e0, 0x125e0 */ #define EVERGREEN_DC_LUT_RW_MODE 0x69e0 #define EVERGREEN_DC_LUT_RW_INDEX 0x69e4 -- 1.7.7.5