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>

authored by Alex Deucher and committed by Dave Airlie fb9674bd beb47274

+20 -22
+20
drivers/gpu/drm/radeon/atombios_crtc.c
··· 1009 1009 uint64_t fb_location; 1010 1010 uint32_t fb_format, fb_pitch_pixels, tiling_flags; 1011 1011 u32 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_NONE); 1012 + u32 tmp; 1012 1013 int r; 1013 1014 1014 1015 /* no fb bound */ ··· 1138 1137 WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset, 1139 1138 (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay); 1140 1139 1140 + /* pageflip setup */ 1141 + /* make sure flip is at vb rather than hb */ 1142 + tmp = RREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset); 1143 + tmp &= ~EVERGREEN_GRPH_SURFACE_UPDATE_H_RETRACE_EN; 1144 + WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp); 1145 + 1146 + /* set pageflip to happen anywhere in vblank interval */ 1147 + WREG32(EVERGREEN_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0); 1148 + 1141 1149 if (!atomic && fb && fb != crtc->fb) { 1142 1150 radeon_fb = to_radeon_framebuffer(fb); 1143 1151 rbo = gem_to_radeon_bo(radeon_fb->obj); ··· 1177 1167 uint64_t fb_location; 1178 1168 uint32_t fb_format, fb_pitch_pixels, tiling_flags; 1179 1169 u32 fb_swap = R600_D1GRPH_SWAP_ENDIAN_NONE; 1170 + u32 tmp; 1180 1171 int r; 1181 1172 1182 1173 /* no fb bound */ ··· 1304 1293 (x << 16) | y); 1305 1294 WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset, 1306 1295 (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay); 1296 + 1297 + /* pageflip setup */ 1298 + /* make sure flip is at vb rather than hb */ 1299 + tmp = RREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset); 1300 + tmp &= ~AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN; 1301 + WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp); 1302 + 1303 + /* set pageflip to happen anywhere in vblank interval */ 1304 + WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0); 1307 1305 1308 1306 if (!atomic && fb && fb != crtc->fb) { 1309 1307 radeon_fb = to_radeon_framebuffer(fb);
-11
drivers/gpu/drm/radeon/evergreen.c
··· 43 43 44 44 void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc) 45 45 { 46 - struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc]; 47 - u32 tmp; 48 - 49 - /* make sure flip is at vb rather than hb */ 50 - tmp = RREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset); 51 - tmp &= ~EVERGREEN_GRPH_SURFACE_UPDATE_H_RETRACE_EN; 52 - WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp); 53 - 54 - /* set pageflip to happen anywhere in vblank interval */ 55 - WREG32(EVERGREEN_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0); 56 - 57 46 /* enable the pflip int */ 58 47 radeon_irq_kms_pflip_irq_get(rdev, crtc); 59 48 }
-11
drivers/gpu/drm/radeon/rs600.c
··· 48 48 49 49 void rs600_pre_page_flip(struct radeon_device *rdev, int crtc) 50 50 { 51 - struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc]; 52 - u32 tmp; 53 - 54 - /* make sure flip is at vb rather than hb */ 55 - tmp = RREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset); 56 - tmp &= ~AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN; 57 - WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp); 58 - 59 - /* set pageflip to happen anywhere in vblank interval */ 60 - WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0); 61 - 62 51 /* enable the pflip int */ 63 52 radeon_irq_kms_pflip_irq_get(rdev, crtc); 64 53 }