From: Ville Syrjälä Date: Tue, 11 Mar 2014 10:58:45 +0000 (+0200) Subject: drm/i915: Add a workaround for HSW scanline counter weirdness X-Git-Tag: v3.14-rc8~6^2~3^2~2 X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=commitdiff_plain;h=fcb818231f81e22b2c3a76d7ef416237fa0c7609;p=linux.git drm/i915: Add a workaround for HSW scanline counter weirdness 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 8072bfa6045a264d3913102a35fab125b06603a2 Author: Ville Syrjälä 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: bugzilla1@gmx.com Reviewed-by: Mika Kuoppala Signed-off-by: Ville Syrjälä Signed-off-by: Jani Nikula --- diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 9fec71175571..d4c952d12f3b 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -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