Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bea5497b authored by Alex Deucher's avatar Alex Deucher
Browse files

drm/radeon: update wait_for_vblank for r5xx-r7xx



Properly wait for the next vblank region.  The previous
code didn't always wait long enough depending on the timing.

Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
parent 2b48b968
Loading
Loading
Loading
Loading
+44 −8
Original line number Original line Diff line number Diff line
@@ -52,23 +52,59 @@ static const u32 crtc_offsets[2] =
	AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL
	AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL
};
};


static bool avivo_is_in_vblank(struct radeon_device *rdev, int crtc)
{
	if (RREG32(AVIVO_D1CRTC_STATUS + crtc_offsets[crtc]) & AVIVO_D1CRTC_V_BLANK)
		return true;
	else
		return false;
}

static bool avivo_is_counter_moving(struct radeon_device *rdev, int crtc)
{
	u32 pos1, pos2;

	pos1 = RREG32(AVIVO_D1CRTC_STATUS_POSITION + crtc_offsets[crtc]);
	pos2 = RREG32(AVIVO_D1CRTC_STATUS_POSITION + crtc_offsets[crtc]);

	if (pos1 != pos2)
		return true;
	else
		return false;
}

/**
 * avivo_wait_for_vblank - vblank wait asic callback.
 *
 * @rdev: radeon_device pointer
 * @crtc: crtc to wait for vblank on
 *
 * Wait for vblank on the requested crtc (r5xx-r7xx).
 */
void avivo_wait_for_vblank(struct radeon_device *rdev, int crtc)
void avivo_wait_for_vblank(struct radeon_device *rdev, int crtc)
{
{
	int i;
	unsigned i = 0;


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


	if (RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[crtc]) & AVIVO_CRTC_EN) {
	if (!(RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[crtc]) & AVIVO_CRTC_EN))
		for (i = 0; i < rdev->usec_timeout; i++) {
		return;
			if (!(RREG32(AVIVO_D1CRTC_STATUS + crtc_offsets[crtc]) & AVIVO_D1CRTC_V_BLANK))

	/* depending on when we hit vblank, we may be close to active; if so,
	 * wait for another frame.
	 */
	while (avivo_is_in_vblank(rdev, crtc)) {
		if (i++ % 100 == 0) {
			if (!avivo_is_counter_moving(rdev, crtc))
				break;
				break;
			udelay(1);
		}
		}
		for (i = 0; i < rdev->usec_timeout; i++) {
	}
			if (RREG32(AVIVO_D1CRTC_STATUS + crtc_offsets[crtc]) & AVIVO_D1CRTC_V_BLANK)

	while (!avivo_is_in_vblank(rdev, crtc)) {
		if (i++ % 100 == 0) {
			if (!avivo_is_counter_moving(rdev, crtc))
				break;
				break;
			udelay(1);
		}
		}
	}
	}
}
}