From 47460ea9129088a2b6f46d4869b9df8765a6c051 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Sun, 27 Mar 2011 16:22:27 -0400 Subject: [PATCH] drm/radeon/kms: fix pageflipping hangs on r6xx+ Fullscreen Adobe Flash seems to cause hangs on r6xx+ asics. Avoid touching the flip setup regs while acceleration is running. Set them at modeset rather than during pageflip. For reference see: c640e8ca172c6a5c45abe8e2e8353900a84427fa for previous asics. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=35697 Signed-off-by: Alex Deucher Cc: stable@kernel.org --- drivers/gpu/drm/radeon/atombios_crtc.c | 20 ++++++++++++++++++++ drivers/gpu/drm/radeon/evergreen.c | 11 ----------- drivers/gpu/drm/radeon/rs600.c | 11 ----------- 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 10e41af..b41ec59 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -1009,6 +1009,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, uint64_t fb_location; uint32_t fb_format, fb_pitch_pixels, tiling_flags; u32 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_NONE); + u32 tmp; int r; /* no fb bound */ @@ -1137,6 +1138,15 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset, (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay); + /* pageflip setup */ + /* make sure flip is at vb rather than hb */ + tmp = RREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset); + tmp &= ~EVERGREEN_GRPH_SURFACE_UPDATE_H_RETRACE_EN; + WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp); + + /* set pageflip to happen anywhere in vblank interval */ + WREG32(EVERGREEN_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0); + if (!atomic && fb && fb != crtc->fb) { radeon_fb = to_radeon_framebuffer(fb); rbo = gem_to_radeon_bo(radeon_fb->obj); @@ -1167,6 +1177,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, uint64_t fb_location; uint32_t fb_format, fb_pitch_pixels, tiling_flags; u32 fb_swap = R600_D1GRPH_SWAP_ENDIAN_NONE; + u32 tmp; int r; /* no fb bound */ @@ -1294,6 +1305,15 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset, (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay); + /* pageflip setup */ + /* make sure flip is at vb rather than hb */ + tmp = RREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset); + tmp &= ~AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN; + WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp); + + /* set pageflip to happen anywhere in vblank interval */ + WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0); + if (!atomic && fb && fb != crtc->fb) { radeon_fb = to_radeon_framebuffer(fb); rbo = gem_to_radeon_bo(radeon_fb->obj); diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index a242e17..ccb988a 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -62,17 +62,6 @@ void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc) void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc) { - struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc]; - u32 tmp; - - /* make sure flip is at vb rather than hb */ - tmp = RREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset); - tmp &= ~EVERGREEN_GRPH_SURFACE_UPDATE_H_RETRACE_EN; - WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp); - - /* set pageflip to happen anywhere in vblank interval */ - WREG32(EVERGREEN_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0); - /* enable the pflip int */ radeon_irq_kms_pflip_irq_get(rdev, crtc); } diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 6493332..c888648 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -67,17 +67,6 @@ void avivo_wait_for_vblank(struct radeon_device *rdev, int crtc) void rs600_pre_page_flip(struct radeon_device *rdev, int crtc) { - struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc]; - u32 tmp; - - /* make sure flip is at vb rather than hb */ - tmp = RREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset); - tmp &= ~AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN; - WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp); - - /* set pageflip to happen anywhere in vblank interval */ - WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0); - /* enable the pflip int */ radeon_irq_kms_pflip_irq_get(rdev, crtc); } -- 1.7.1.1