Skip to content

Commit

Permalink
drm/radeon: update wait_for_vblank for r1xx-r4xx
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 f9df7ea commit 2b48b96
Showing 1 changed file with 53 additions and 24 deletions.
77 changes: 53 additions & 24 deletions drivers/gpu/drm/radeon/r100.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,38 @@ MODULE_FIRMWARE(FIRMWARE_R520);
* and others in some cases.
*/

static bool r100_is_in_vblank(struct radeon_device *rdev, int crtc)
{
if (crtc == 0) {
if (RREG32(RADEON_CRTC_STATUS) & RADEON_CRTC_VBLANK_CUR)
return true;
else
return false;
} else {
if (RREG32(RADEON_CRTC2_STATUS) & RADEON_CRTC2_VBLANK_CUR)
return true;
else
return false;
}
}

static bool r100_is_counter_moving(struct radeon_device *rdev, int crtc)
{
u32 vline1, vline2;

if (crtc == 0) {
vline1 = (RREG32(RADEON_CRTC_VLINE_CRNT_VLINE) >> 16) & RADEON_CRTC_V_TOTAL;
vline2 = (RREG32(RADEON_CRTC_VLINE_CRNT_VLINE) >> 16) & RADEON_CRTC_V_TOTAL;
} else {
vline1 = (RREG32(RADEON_CRTC2_VLINE_CRNT_VLINE) >> 16) & RADEON_CRTC_V_TOTAL;
vline2 = (RREG32(RADEON_CRTC2_VLINE_CRNT_VLINE) >> 16) & RADEON_CRTC_V_TOTAL;
}
if (vline1 != vline2)
return true;
else
return false;
}

/**
* r100_wait_for_vblank - vblank wait asic callback.
*
Expand All @@ -79,36 +111,33 @@ MODULE_FIRMWARE(FIRMWARE_R520);
*/
void r100_wait_for_vblank(struct radeon_device *rdev, int crtc)
{
int i;
unsigned i = 0;

if (crtc >= rdev->num_crtc)
return;

if (crtc == 0) {
if (RREG32(RADEON_CRTC_GEN_CNTL) & RADEON_CRTC_EN) {
for (i = 0; i < rdev->usec_timeout; i++) {
if (!(RREG32(RADEON_CRTC_STATUS) & RADEON_CRTC_VBLANK_CUR))
break;
udelay(1);
}
for (i = 0; i < rdev->usec_timeout; i++) {
if (RREG32(RADEON_CRTC_STATUS) & RADEON_CRTC_VBLANK_CUR)
break;
udelay(1);
}
}
if (!(RREG32(RADEON_CRTC_GEN_CNTL) & RADEON_CRTC_EN))
return;
} else {
if (RREG32(RADEON_CRTC2_GEN_CNTL) & RADEON_CRTC2_EN) {
for (i = 0; i < rdev->usec_timeout; i++) {
if (!(RREG32(RADEON_CRTC2_STATUS) & RADEON_CRTC2_VBLANK_CUR))
break;
udelay(1);
}
for (i = 0; i < rdev->usec_timeout; i++) {
if (RREG32(RADEON_CRTC2_STATUS) & RADEON_CRTC2_VBLANK_CUR)
break;
udelay(1);
}
if (!(RREG32(RADEON_CRTC2_GEN_CNTL) & RADEON_CRTC2_EN))
return;
}

/* depending on when we hit vblank, we may be close to active; if so,
* wait for another frame.
*/
while (r100_is_in_vblank(rdev, crtc)) {
if (i++ % 100 == 0) {
if (!r100_is_counter_moving(rdev, crtc))
break;
}
}

while (!r100_is_in_vblank(rdev, crtc)) {
if (i++ % 100 == 0) {
if (!r100_is_counter_moving(rdev, crtc))
break;
}
}
}
Expand Down

0 comments on commit 2b48b96

Please sign in to comment.