Commit 33c3b0d1 authored by Ville Syrjälä's avatar Ville Syrjälä Committed by Jani Nikula

drm/i915: Wait for vblank after enabling the primary plane on BDW

BDW signals the flip done interrupt immediately after the DSPSURF write
when the plane is disabled. This is true even if we've already armed
DSPCNTR to enable the plane at the next vblank. This causes major
problems for our page flip code which relies on the flip done interrupts
happening at vblank time.

So what happens is that we enable the plane, and immediately allow
userspace to submit a page flip. If the plane is still in the process
of being enabled when the page flip is issued, the flip done gets
signalled immediately. Our DSPSURFLIVE check catches this to prevent
premature flip completion, but it also means that we don't get a flip
done interrupt when the plane actually gets enabled, and so the page
flip is never completed.

Work around this by re-introducing blocking vblank waits on BDW
whenever we enable the primary plane.

I removed some of the vblank waits here:
 commit 6304cd91
 Author: Ville Syrjälä <ville.syrjala@linux.intel.com>
 Date:   Fri Apr 25 13:30:12 2014 +0300

    drm/i915: Drop the excessive vblank waits from modeset codepaths

To avoid these blocking vblank waits we should start using the vblank
interrupt instead of the flip done interrupt to complete page flips.
But that's material for another patch.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=79354Tested-by: default avatarGuo Jinxian <jinxianx.guo@intel.com>
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: default avatarJani Nikula <jani.nikula@intel.com>
parent 8525a235
...@@ -2087,6 +2087,7 @@ void intel_flush_primary_plane(struct drm_i915_private *dev_priv, ...@@ -2087,6 +2087,7 @@ void intel_flush_primary_plane(struct drm_i915_private *dev_priv,
static void intel_enable_primary_hw_plane(struct drm_i915_private *dev_priv, static void intel_enable_primary_hw_plane(struct drm_i915_private *dev_priv,
enum plane plane, enum pipe pipe) enum plane plane, enum pipe pipe)
{ {
struct drm_device *dev = dev_priv->dev;
struct intel_crtc *intel_crtc = struct intel_crtc *intel_crtc =
to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
int reg; int reg;
...@@ -2106,6 +2107,14 @@ static void intel_enable_primary_hw_plane(struct drm_i915_private *dev_priv, ...@@ -2106,6 +2107,14 @@ static void intel_enable_primary_hw_plane(struct drm_i915_private *dev_priv,
I915_WRITE(reg, val | DISPLAY_PLANE_ENABLE); I915_WRITE(reg, val | DISPLAY_PLANE_ENABLE);
intel_flush_primary_plane(dev_priv, plane); intel_flush_primary_plane(dev_priv, plane);
/*
* BDW signals flip done immediately if the plane
* is disabled, even if the plane enable is already
* armed to occur at the next vblank :(
*/
if (IS_BROADWELL(dev))
intel_wait_for_vblank(dev, intel_crtc->pipe);
} }
/** /**
......
...@@ -690,6 +690,14 @@ intel_post_enable_primary(struct drm_crtc *crtc) ...@@ -690,6 +690,14 @@ intel_post_enable_primary(struct drm_crtc *crtc)
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
/*
* BDW signals flip done immediately if the plane
* is disabled, even if the plane enable is already
* armed to occur at the next vblank :(
*/
if (IS_BROADWELL(dev))
intel_wait_for_vblank(dev, intel_crtc->pipe);
/* /*
* FIXME IPS should be fine as long as one plane is * FIXME IPS should be fine as long as one plane is
* enabled, but in practice it seems to have problems * enabled, but in practice it seems to have problems
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment