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

Commit 10257a6d authored by Alex Deucher's avatar Alex Deucher
Browse files

drm/radeon: update wait_for_vblank for evergreen+



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 bea5497b
Loading
Loading
Loading
Loading
+36 −8
Original line number Diff line number Diff line
@@ -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.
 *
@@ -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);
		}
	}
}