Daniel, Ville,
i tested Ville's patch series for the scanoutpos improvements on a
GMA-950, on top of airlied's current drm-next branch.
There's one issue: The variable "position" in i915_get_crtc_scanoutpos()
must be turned from a u32 into a int, otherwise funny sign errors happen
and we end up with *vpos being off by multiple million scanlines and
timestamps being off by over 60 seconds.
Other than that looks good. Execution time is now better:
Before uncore.lock addition: 3-4 usecs execution time for the scanoutpos
query on my machine. After uncore.lock addition (3.12.0-rc3) 9-20 usecs,
sometimes repetition of the timing loop triggered. After Ville's patches
down to typically 3-8 usecs, occassionally spiking to almost 20 usecs.
I'll make my patches for the realtime kernel + increased accuracy on top
of drm-next + Ville's patches.
thanks,
-mario
On 09/23/2013 12:02 PM, 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;
- /* 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