drm/radeon/kms: pageflipping cleanup for avivo+
Avoid touching the flip setup regs while acceleration is running. Set them at modeset rather than during pageflip. Touching these regs while acceleration is active caused hangs on pre-avivo chips. These chips do not seem to be affected, but better safe than sorry, plus it avoids repeatedly reprogramming the regs every flip. Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
beb4727411
commit
fb9674bd2c
3 changed files with 20 additions and 22 deletions
|
@ -1009,6 +1009,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
|
||||||
uint64_t fb_location;
|
uint64_t fb_location;
|
||||||
uint32_t fb_format, fb_pitch_pixels, tiling_flags;
|
uint32_t fb_format, fb_pitch_pixels, tiling_flags;
|
||||||
u32 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_NONE);
|
u32 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_NONE);
|
||||||
|
u32 tmp;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
/* no fb bound */
|
/* 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,
|
WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
|
||||||
(crtc->mode.hdisplay << 16) | crtc->mode.vdisplay);
|
(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) {
|
if (!atomic && fb && fb != crtc->fb) {
|
||||||
radeon_fb = to_radeon_framebuffer(fb);
|
radeon_fb = to_radeon_framebuffer(fb);
|
||||||
rbo = gem_to_radeon_bo(radeon_fb->obj);
|
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;
|
uint64_t fb_location;
|
||||||
uint32_t fb_format, fb_pitch_pixels, tiling_flags;
|
uint32_t fb_format, fb_pitch_pixels, tiling_flags;
|
||||||
u32 fb_swap = R600_D1GRPH_SWAP_ENDIAN_NONE;
|
u32 fb_swap = R600_D1GRPH_SWAP_ENDIAN_NONE;
|
||||||
|
u32 tmp;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
/* no fb bound */
|
/* 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,
|
WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
|
||||||
(crtc->mode.hdisplay << 16) | crtc->mode.vdisplay);
|
(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) {
|
if (!atomic && fb && fb != crtc->fb) {
|
||||||
radeon_fb = to_radeon_framebuffer(fb);
|
radeon_fb = to_radeon_framebuffer(fb);
|
||||||
rbo = gem_to_radeon_bo(radeon_fb->obj);
|
rbo = gem_to_radeon_bo(radeon_fb->obj);
|
||||||
|
|
|
@ -43,17 +43,6 @@ static void evergreen_pcie_gen2_enable(struct radeon_device *rdev);
|
||||||
|
|
||||||
void evergreen_pre_page_flip(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 */
|
/* enable the pflip int */
|
||||||
radeon_irq_kms_pflip_irq_get(rdev, crtc);
|
radeon_irq_kms_pflip_irq_get(rdev, crtc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,17 +48,6 @@ int rs600_mc_wait_for_idle(struct radeon_device *rdev);
|
||||||
|
|
||||||
void rs600_pre_page_flip(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 */
|
/* enable the pflip int */
|
||||||
radeon_irq_kms_pflip_irq_get(rdev, crtc);
|
radeon_irq_kms_pflip_irq_get(rdev, crtc);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue