summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
authorVille Syrjälä2017-02-17 16:01:59 +0100
committerVille Syrjälä2017-03-02 15:40:43 +0100
commita5509abda48ecfc133fac6268e83fc1a93dba039 (patch)
treeda63b261b52e7afde3486db2be969b11550fded7 /drivers/gpu/drm/i915/intel_display.c
parentdrm/i915/glk: Fix DSI enable I/O sequence (diff)
downloadkernel-qcow2-linux-a5509abda48ecfc133fac6268e83fc1a93dba039.tar.gz
kernel-qcow2-linux-a5509abda48ecfc133fac6268e83fc1a93dba039.tar.xz
kernel-qcow2-linux-a5509abda48ecfc133fac6268e83fc1a93dba039.zip
drm/i915: Fix legacy cursor vs. watermarks for ILK-BDW
In order to make cursor updates actually safe wrt. watermark programming we have to clear the legacy_cursor_update flag in the atomic state. That will cause the regular atomic update path to do the necessary vblank wait after the plane update if needed, otherwise the vblank wait would be skipped and we'd feed the optimal watermarks to the hardware before the plane update has actually happened. To make the slow vs. fast path determination in intel_legacy_cursor_update() a little simpler we can ignore the actual visibility of the plane (which can only get computed once we've already chosen out path) and instead we simply check whether the fb is being set or cleared by the user. This means a fully clipped but logically visible cursor will be considered visible as far as watermark programming is concerned. We can do that for the cursor since it's a fixed size plane and the clipped size doesn't play a role in the watermark computation. This should fix underruns that can occur when the cursor gets enable/disabled or the size gets changed. Hopefully it's good enough that only pure cursor movement and flips go through unthrottled. Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Uwe Kleine-König <uwe@kleine-koenig.org> Reported-by: Uwe Kleine-König <uwe@kleine-koenig.org> Fixes: f79f26921ee1 ("drm/i915: Add a cursor hack to allow converting legacy page flip to atomic, v3.") Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170217150159.11683-1-ville.syrjala@linux.intel.com Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Tested-by: Rafael Ristovski <rafael.ristovski@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 9d8c08c4b105..9908bba5b3d3 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12955,6 +12955,17 @@ static int intel_atomic_commit(struct drm_device *dev,
struct drm_i915_private *dev_priv = to_i915(dev);
int ret = 0;
+ /*
+ * The intel_legacy_cursor_update() fast path takes care
+ * of avoiding the vblank waits for simple cursor
+ * movement and flips. For cursor on/off and size changes,
+ * we want to perform the vblank waits so that watermark
+ * updates happen during the correct frames. Gen9+ have
+ * double buffered watermarks and so shouldn't need this.
+ */
+ if (INTEL_GEN(dev_priv) < 9)
+ state->legacy_cursor_update = false;
+
ret = drm_atomic_helper_setup_commit(state, nonblock);
if (ret)
return ret;
@@ -13389,8 +13400,7 @@ intel_legacy_cursor_update(struct drm_plane *plane,
old_plane_state->src_h != src_h ||
old_plane_state->crtc_w != crtc_w ||
old_plane_state->crtc_h != crtc_h ||
- !old_plane_state->visible ||
- old_plane_state->fb->modifier != fb->modifier)
+ !old_plane_state->fb != !fb)
goto slow;
new_plane_state = intel_plane_duplicate_state(plane);
@@ -13413,10 +13423,6 @@ intel_legacy_cursor_update(struct drm_plane *plane,
if (ret)
goto out_free;
- /* Visibility changed, must take slowpath. */
- if (!new_plane_state->visible)
- goto slow_free;
-
ret = mutex_lock_interruptible(&dev_priv->drm.struct_mutex);
if (ret)
goto out_free;
@@ -13456,9 +13462,12 @@ intel_legacy_cursor_update(struct drm_plane *plane,
new_plane_state->fb = old_fb;
to_intel_plane_state(new_plane_state)->vma = old_vma;
- intel_plane->update_plane(plane,
- to_intel_crtc_state(crtc->state),
- to_intel_plane_state(plane->state));
+ if (plane->state->visible)
+ intel_plane->update_plane(plane,
+ to_intel_crtc_state(crtc->state),
+ to_intel_plane_state(plane->state));
+ else
+ intel_plane->disable_plane(plane, crtc);
intel_cleanup_plane_fb(plane, new_plane_state);
@@ -13468,8 +13477,6 @@ out_free:
intel_plane_destroy_state(plane, new_plane_state);
return ret;
-slow_free:
- intel_plane_destroy_state(plane, new_plane_state);
slow:
return drm_atomic_helper_update_plane(plane, crtc, fb,
crtc_x, crtc_y, crtc_w, crtc_h,