Commit 81ffbbed authored by Felix Kuehling's avatar Felix Kuehling Committed by Dave Airlie

drm/radeon: fix deferred page-flip detection logic on Avivo-based ASICs

This fixes page-flip-related flickering observed on Iconia Tab W500.

The update_pending status returned by radeon_page_flip is very accurate on
Avivo-based ASICs when vpos is negative.

Experiments were conducted on several ASIC generations ranging from RS690
to Cayman where the page flip was artificially timed to occur at a specific
vpos. With negative vpos, overriding update_pending always lead to
flickering.

The same experiment on RV380 and RV410 showed that update_pending is not
accurate with negative vpos. In most cases update_pending == 1 is returned
although the flip would complete before the start of the next frame.
Therefore I left the behaviour unchanged for pre-AVIVO ASICs for
performance reasons, although this may result in flickering in rare cases.

This change also makes the logic a little easier to understand.
Signed-off-by: default avatarFelix Kuehling <Felix.Kuehling@amd.com>
Reviewed-by: default avatarMario Kleiner <mario.kleiner@tuebingen.mpg.de>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 884a53ef
...@@ -303,8 +303,17 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id) ...@@ -303,8 +303,17 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
if (update_pending && if (update_pending &&
(DRM_SCANOUTPOS_VALID & radeon_get_crtc_scanoutpos(rdev->ddev, crtc_id, (DRM_SCANOUTPOS_VALID & radeon_get_crtc_scanoutpos(rdev->ddev, crtc_id,
&vpos, &hpos)) && &vpos, &hpos)) &&
(vpos >=0) && ((vpos >= (99 * rdev->mode_info.crtcs[crtc_id]->base.hwmode.crtc_vdisplay)/100) ||
(vpos < (99 * rdev->mode_info.crtcs[crtc_id]->base.hwmode.crtc_vdisplay)/100)) { (vpos < 0 && !ASIC_IS_AVIVO(rdev)))) {
/* crtc didn't flip in this target vblank interval,
* but flip is pending in crtc. Based on the current
* scanout position we know that the current frame is
* (nearly) complete and the flip will (likely)
* complete before the start of the next frame.
*/
update_pending = 0;
}
if (update_pending) {
/* crtc didn't flip in this target vblank interval, /* crtc didn't flip in this target vblank interval,
* but flip is pending in crtc. It will complete it * but flip is pending in crtc. It will complete it
* in next vblank interval, so complete the flip at * in next vblank interval, so complete the flip at
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment