Skip to content

Commit

Permalink
drm/i915: Add a workaround for HSW scanline counter weirdness
Browse files Browse the repository at this point in the history
On HSW the scanline counter seems to behave differently depending on
the output type. eDP on port A does what you would expect an the normal
+1 fixup is sufficient to cover it. But on HDMI outputs we seem to need
a +2 fixup. Just assume we always need the +2 fixup and accept the
slight inaccuracy on eDP.

This fixes a regression introduced in:
 commit 8072bfa
 Author: Ville Syrjälä <[email protected]>
 Date:   Mon Oct 28 21:22:52 2013 +0200

    drm/radeon: Move the early vblank IRQ fixup to radeon_get_crtc_scanoutpos()

That commit removed the heuristic that tried to fix up the timestamps
for vblank interrupts that fire a bit too early. Since then the vblank
timestamp code would treat some vblank interrupts as spurious since the
scanline counter would indicate that vblank_start wasn't reached yet.
That in turn lead to incorrect vblank event sequence numbers being
reported to userspace, which lead to unsteady framerate in applications
such as XBMC which uses them for timing purposes.

v2: Remember to call ilk_pipe_in_vblank_locked() on HSW too (Mika)

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=75725
Tested-by: [email protected]
Reviewed-by: Mika Kuoppala <[email protected]>
Signed-off-by: Ville Syrjälä <[email protected]>
Signed-off-by: Jani Nikula <[email protected]>
  • Loading branch information
vsyrjala authored and jnikula committed Mar 12, 2014
1 parent 24bd9bf commit fcb8182
Showing 1 changed file with 22 additions and 1 deletion.
23 changes: 22 additions & 1 deletion drivers/gpu/drm/i915/i915_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -702,7 +702,28 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
else
position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3;

if (HAS_PCH_SPLIT(dev)) {
if (HAS_DDI(dev)) {
/*
* On HSW HDMI outputs there seems to be a 2 line
* difference, whereas eDP has the normal 1 line
* difference that earlier platforms have. External
* DP is unknown. For now just check for the 2 line
* difference case on all output types on HSW+.
*
* This might misinterpret the scanline counter being
* one line too far along on eDP, but that's less
* dangerous than the alternative since that would lead
* the vblank timestamp code astray when it sees a
* scanline count before vblank_start during a vblank
* interrupt.
*/
in_vbl = ilk_pipe_in_vblank_locked(dev, pipe);
if ((in_vbl && (position == vbl_start - 2 ||
position == vbl_start - 1)) ||
(!in_vbl && (position == vbl_end - 2 ||
position == vbl_end - 1)))
position = (position + 2) % vtotal;
} else if (HAS_PCH_SPLIT(dev)) {
/*
* The scanline counter increments at the leading edge
* of hsync, ie. it completely misses the active portion
Expand Down

0 comments on commit fcb8182

Please sign in to comment.