Re: [PATCH 2/3] drm/i915: Fix scanoutpos calculations

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 





On 23.09.13 12:02, ville.syrjala@xxxxxxxxxxxxxxx wrote:
From: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx>

The reported scanout position must be relative to the end of vblank.
Currently we manage to fumble that in a few ways.

First we don't consider the case when vtotal != vbl_end. While that
isn't very common (happens maybe only w/ old panel fitting hardware),
we can fix it easily enough.

The second issue is that on pre-CTG hardware we convert the pixel count
to horizontal/vertical components at the very beginning, and then forget
to adjust the horizontal component to be relative to vbl_end. So instead
we should keep our numbers in the pixel count domain while we're
adjusting the position to be relative to vbl_end. Then when we do the
conversion in the end, both vertical _and_ horizontal components will
come out correct.

Cc: Mario Kleiner <mario.kleiner@xxxxxxxxxxxxxxxx>
Signed-off-by: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx>
---
  drivers/gpu/drm/i915/i915_irq.c | 37 ++++++++++++++++++++++++-------------
  1 file changed, 24 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 697d62c..4f74f0c 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -615,13 +615,7 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
  		/* No obvious pixelcount register. Only query vertical
  		 * scanout position from Display scan line register.
  		 */
-		position = I915_READ(PIPEDSL(pipe));
-
-		/* Decode into vertical scanout position. Don't have
-		 * horizontal scanout position.
-		 */
-		*vpos = position & 0x1fff;
-		*hpos = 0;
+		position = I915_READ(PIPEDSL(pipe)) & 0x1fff;
  	} else {
  		/* Have access to pixelcount since start of frame.
  		 * We can split this into vertical and horizontal
@@ -629,15 +623,32 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
  		 */
  		position = (I915_READ(PIPEFRAMEPIXEL(pipe)) & PIPE_PIXEL_MASK) >> PIPE_PIXEL_SHIFT;

-		*vpos = position / htotal;
-		*hpos = position - (*vpos * htotal);
+		/* convert to pixel counts */
+		vbl_start *= htotal;
+		vbl_end *= htotal;
+		vtotal *= htotal;
  	}

-	in_vbl = *vpos >= vbl_start && *vpos < vbl_end;
+	in_vbl = position >= vbl_start && position < vbl_end;


Carried forward from patch 1/3: position <= vbl_end
Everything else is fine.

Nice improvement :)

Reviewed-by: mario.kleiner.de@xxxxxxxxx


-	/* Inside "upper part" of vblank area? Apply corrective offset: */
-	if (in_vbl && (*vpos >= vbl_start))
-		*vpos = *vpos - vtotal;
+	/*
+	 * While in vblank, position will be negative
+	 * counting up towards 0 at vbl_end. And outside
+	 * vblank, position will be positive counting
+	 * up since vbl_end.
+	 */
+	if (position >= vbl_start)
+		position -= vbl_end;
+	else
+		position += vtotal - vbl_end;
+
+	if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) {
+		*vpos = position;
+		*hpos = 0;
+	} else {
+		*vpos = position / htotal;
+		*hpos = position - (*vpos * htotal);
+	}

  	/* In vblank? */
  	if (in_vbl)

_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/intel-gfx





[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux