Skip to content

Commit

Permalink
drm/radeon: update wait_for_vblank for evergreen+
Browse files Browse the repository at this point in the history
Properly wait for the next vblank region.  The previous
code didn't always wait long enough depending on the timing.

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
  • Loading branch information
Alex Deucher committed Apr 22, 2013
1 parent bea5497 commit 10257a6
Showing 1 changed file with 36 additions and 8 deletions.
44 changes: 36 additions & 8 deletions drivers/gpu/drm/radeon/evergreen.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,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.
*
Expand All @@ -326,21 +347,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;
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;
udelay(1);
}
}
}
Expand Down

0 comments on commit 10257a6

Please sign in to comment.