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

Commit 75fa0b08 authored by Mario Kleiner's avatar Mario Kleiner Committed by Dave Airlie
Browse files

drm/radeon: Modify radeon_pm_in_vbl to use radeon_get_crtc_scanoutpos()



radeon_pm_in_vbl() didn't report in vblank status accurately. Make
it a wrapper around radeon_get_crtc_scanoutpos() which corrects for
biases, so it reports accurately.

radeon_pm_in_vbl() will only report in_vbl if all active crtc's
are currently inside vblank.

agd5f: use rdev->num_crtc rather than hardcoding the crtc count

Signed-off-by: default avatarMario Kleiner <mario.kleiner@tuebingen.mpg.de>
Signed-off-by: default avatarAlex Deucher <alexdeucher@gmail.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 6383cf7d
Loading
Loading
Loading
Loading
+9 −61
Original line number Diff line number Diff line
@@ -712,73 +712,21 @@ void radeon_pm_compute_clocks(struct radeon_device *rdev)

static bool radeon_pm_in_vbl(struct radeon_device *rdev)
{
	u32 stat_crtc = 0, vbl = 0, position = 0;
	int  crtc, vpos, hpos, vbl_status;
	bool in_vbl = true;

	if (ASIC_IS_DCE4(rdev)) {
		if (rdev->pm.active_crtcs & (1 << 0)) {
			vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
				     EVERGREEN_CRTC0_REGISTER_OFFSET) & 0xfff;
			position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
					  EVERGREEN_CRTC0_REGISTER_OFFSET) & 0xfff;
		}
		if (rdev->pm.active_crtcs & (1 << 1)) {
			vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
				     EVERGREEN_CRTC1_REGISTER_OFFSET) & 0xfff;
			position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
					  EVERGREEN_CRTC1_REGISTER_OFFSET) & 0xfff;
		}
		if (rdev->pm.active_crtcs & (1 << 2)) {
			vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
				     EVERGREEN_CRTC2_REGISTER_OFFSET) & 0xfff;
			position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
					  EVERGREEN_CRTC2_REGISTER_OFFSET) & 0xfff;
		}
		if (rdev->pm.active_crtcs & (1 << 3)) {
			vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
				     EVERGREEN_CRTC3_REGISTER_OFFSET) & 0xfff;
			position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
					  EVERGREEN_CRTC3_REGISTER_OFFSET) & 0xfff;
		}
		if (rdev->pm.active_crtcs & (1 << 4)) {
			vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
				     EVERGREEN_CRTC4_REGISTER_OFFSET) & 0xfff;
			position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
					  EVERGREEN_CRTC4_REGISTER_OFFSET) & 0xfff;
		}
		if (rdev->pm.active_crtcs & (1 << 5)) {
			vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
				     EVERGREEN_CRTC5_REGISTER_OFFSET) & 0xfff;
			position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
					  EVERGREEN_CRTC5_REGISTER_OFFSET) & 0xfff;
		}
	} else if (ASIC_IS_AVIVO(rdev)) {
		if (rdev->pm.active_crtcs & (1 << 0)) {
			vbl = RREG32(AVIVO_D1CRTC_V_BLANK_START_END) & 0xfff;
			position = RREG32(AVIVO_D1CRTC_STATUS_POSITION) & 0xfff;
		}
		if (rdev->pm.active_crtcs & (1 << 1)) {
			vbl = RREG32(AVIVO_D2CRTC_V_BLANK_START_END) & 0xfff;
			position = RREG32(AVIVO_D2CRTC_STATUS_POSITION) & 0xfff;
		}
		if (position < vbl && position > 1)
			in_vbl = false;
	} else {
		if (rdev->pm.active_crtcs & (1 << 0)) {
			stat_crtc = RREG32(RADEON_CRTC_STATUS);
			if (!(stat_crtc & 1))
				in_vbl = false;
		}
		if (rdev->pm.active_crtcs & (1 << 1)) {
			stat_crtc = RREG32(RADEON_CRTC2_STATUS);
			if (!(stat_crtc & 1))
	/* Iterate over all active crtc's. All crtc's must be in vblank,
	 * otherwise return in_vbl == false.
	 */
	for (crtc = 0; (crtc < rdev->num_crtc) && in_vbl; crtc++) {
		if (rdev->pm.active_crtcs & (1 << crtc)) {
			vbl_status = radeon_get_crtc_scanoutpos(rdev, crtc, &vpos, &hpos);
			if ((vbl_status & RADEON_SCANOUTPOS_VALID) &&
			    !(vbl_status & RADEON_SCANOUTPOS_INVBL))
				in_vbl = false;
		}
	}

	if (position < vbl && position > 1)
		in_vbl = false;

	return in_vbl;
}