diff options
author | Jonathan Gray <jsg@jsg.id.au> | 2013-07-01 13:38:28 +1000 |
---|---|---|
committer | Jonathan Gray <jsg@jsg.id.au> | 2013-08-12 10:43:56 +1000 |
commit | dbd71ca06819d49696aa6f6dbcb82a0e614b548d (patch) | |
tree | 4b290a77b70d68d61bc7c870d67d8c68f9421322 | |
parent | 9618f65d4eba2b90518f16e1191fe9ab7226b4eb (diff) |
drm/radeon: update wait_for_vblank for evergreen+, from 3.8.13
-rw-r--r-- | sys/dev/pci/drm/radeon/evergreen.c | 44 |
1 files changed, 36 insertions, 8 deletions
diff --git a/sys/dev/pci/drm/radeon/evergreen.c b/sys/dev/pci/drm/radeon/evergreen.c index f4ce232e251..b9ba135b35d 100644 --- a/sys/dev/pci/drm/radeon/evergreen.c +++ b/sys/dev/pci/drm/radeon/evergreen.c @@ -111,6 +111,27 @@ void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev) } } +static bool dce4_is_in_vblank(struct radeon_device *rdev, int crtc) +{ + if (RREG32(EVERGREEN_CRTC_STATUS + crtc_offsets[crtc]) & EVERGREEN_CRTC_V_BLANK) + return true; + else + return false; +} + +static bool dce4_is_counter_moving(struct radeon_device *rdev, int crtc) +{ + u32 pos1, pos2; + + pos1 = RREG32(EVERGREEN_CRTC_STATUS_POSITION + crtc_offsets[crtc]); + pos2 = RREG32(EVERGREEN_CRTC_STATUS_POSITION + crtc_offsets[crtc]); + + if (pos1 != pos2) + return true; + else + return false; +} + /** * dce4_wait_for_vblank - vblank wait asic callback. * @@ -121,21 +142,28 @@ void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev) */ void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc) { - int i; + unsigned i = 0; if (crtc >= rdev->num_crtc) return; - if (RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[crtc]) & EVERGREEN_CRTC_MASTER_EN) { - for (i = 0; i < rdev->usec_timeout; i++) { - if (!(RREG32(EVERGREEN_CRTC_STATUS + crtc_offsets[crtc]) & EVERGREEN_CRTC_V_BLANK)) + if (!(RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[crtc]) & EVERGREEN_CRTC_MASTER_EN)) + return; + + /* depending on when we hit vblank, we may be close to active; if so, + * wait for another frame. + */ + while (dce4_is_in_vblank(rdev, crtc)) { + if (i++ % 100 == 0) { + if (!dce4_is_counter_moving(rdev, crtc)) break; - DRM_UDELAY(1); } - for (i = 0; i < rdev->usec_timeout; i++) { - if (RREG32(EVERGREEN_CRTC_STATUS + crtc_offsets[crtc]) & EVERGREEN_CRTC_V_BLANK) + } + + while (!dce4_is_in_vblank(rdev, crtc)) { + if (i++ % 100 == 0) { + if (!dce4_is_counter_moving(rdev, crtc)) break; - DRM_UDELAY(1); } } } |