[PATCH 2/7] hmm
Chris Wilson
chris at chris-wilson.co.uk
Wed Jun 7 19:28:30 UTC 2017
---
drivers/gpu/drm/i915/intel_display.c | 123 +++++++++++++++++++----------------
drivers/gpu/drm/i915/intel_drv.h | 1 +
2 files changed, 68 insertions(+), 56 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 85ac32549e85..9398c1dec473 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12752,22 +12752,36 @@ static int intel_atomic_check(struct drm_device *dev,
}
static int intel_atomic_prepare_commit(struct drm_device *dev,
- struct drm_atomic_state *state)
+ struct intel_atomic_state *state)
{
struct drm_i915_private *dev_priv = to_i915(dev);
struct drm_crtc_state *crtc_state;
- struct drm_crtc *crtc;
+ struct drm_crtc *drm_crtc;
int i, ret;
- for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
- if (state->legacy_cursor_update)
+ for_each_new_crtc_in_state(&state->base, drm_crtc, crtc_state, i) {
+ struct intel_crtc *crtc = to_intel_crtc(drm_crtc);
+ int err = 0;
+
+ if (crtc->last_commit) {
+ err = i915_sw_fence_await_completion(&state->commit_ready,
+ &crtc->last_commit->hw_done,
+ GFP_KERNEL);
+ drm_crtc_commit_put(crtc->last_commit);
+ }
+ crtc->last_commit = state->base.crtcs[i].commit;
+ drm_crtc_commit_get(crtc->last_commit);
+ if (err)
+ return err;
+
+ if (state->base.legacy_cursor_update)
continue;
- ret = intel_crtc_wait_for_pending_flips(crtc);
+ ret = intel_crtc_wait_for_pending_flips(drm_crtc);
if (ret)
return ret;
- if (atomic_read(&to_intel_crtc(crtc)->unpin_work_count) >= 2)
+ if (atomic_read(&crtc->unpin_work_count) >= 2)
flush_workqueue(dev_priv->wq);
}
@@ -12775,7 +12789,7 @@ static int intel_atomic_prepare_commit(struct drm_device *dev,
if (ret)
return ret;
- ret = drm_atomic_helper_prepare_planes(dev, state);
+ ret = drm_atomic_helper_prepare_planes(dev, &state->base);
mutex_unlock(&dev->struct_mutex);
return ret;
@@ -12989,6 +13003,18 @@ static void intel_atomic_helper_free_state_worker(struct work_struct *work)
intel_atomic_helper_free_state(dev_priv);
}
+static void intel_atomic_track_fbs(struct drm_atomic_state *state)
+{
+ struct drm_plane_state *old_plane_state, *new_plane_state;
+ struct drm_plane *plane;
+ int i;
+
+ for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i)
+ i915_gem_track_fb(intel_fb_obj(old_plane_state->fb),
+ intel_fb_obj(new_plane_state->fb),
+ to_intel_plane(plane)->frontbuffer_bit);
+}
+
static void intel_atomic_commit_tail(struct drm_atomic_state *state)
{
struct drm_device *dev = state->dev;
@@ -13002,7 +13028,38 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
unsigned crtc_vblank_mask = 0;
int i;
- drm_atomic_helper_wait_for_dependencies(state);
+ /*
+ * 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.
+ *
+ * Do this after drm_atomic_helper_setup_commit() and
+ * intel_atomic_prepare_commit() because we still want
+ * to skip the flip and fb cleanup waits. Although that
+ * does risk yanking the mapping from under the display
+ * engine.
+ *
+ * FIXME doing watermarks and fb cleanup from a vblank worker
+ * (assuming we had any) would solve these problems.
+ */
+ if (INTEL_GEN(dev_priv) < 9)
+ state->legacy_cursor_update = false;
+
+ drm_atomic_helper_swap_state(state, false);
+ dev_priv->wm.distrust_bios_wm = false;
+ intel_shared_dpll_swap_state(state);
+ intel_atomic_track_fbs(state);
+
+ if (intel_state->modeset) {
+ memcpy(dev_priv->min_pixclk, intel_state->min_pixclk,
+ sizeof(intel_state->min_pixclk));
+ dev_priv->active_crtcs = intel_state->active_crtcs;
+ dev_priv->cdclk.logical = intel_state->cdclk.logical;
+ dev_priv->cdclk.actual = intel_state->cdclk.actual;
+ }
if (intel_state->modeset)
intel_display_power_get(dev_priv, POWER_DOMAIN_MODESET);
@@ -13192,18 +13249,6 @@ intel_atomic_commit_ready(struct i915_sw_fence *fence,
return NOTIFY_DONE;
}
-static void intel_atomic_track_fbs(struct drm_atomic_state *state)
-{
- struct drm_plane_state *old_plane_state, *new_plane_state;
- struct drm_plane *plane;
- int i;
-
- for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i)
- i915_gem_track_fb(intel_fb_obj(old_plane_state->fb),
- intel_fb_obj(new_plane_state->fb),
- to_intel_plane(plane)->frontbuffer_bit);
-}
-
/**
* intel_atomic_commit - commit validated state object
* @dev: DRM device
@@ -13221,8 +13266,7 @@ static int intel_atomic_commit(struct drm_device *dev,
bool nonblock)
{
struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
- struct drm_i915_private *dev_priv = to_i915(dev);
- int ret = 0;
+ int ret;
ret = drm_atomic_helper_setup_commit(state, nonblock);
if (ret)
@@ -13232,46 +13276,13 @@ static int intel_atomic_commit(struct drm_device *dev,
i915_sw_fence_init(&intel_state->commit_ready,
intel_atomic_commit_ready);
- ret = intel_atomic_prepare_commit(dev, state);
+ ret = intel_atomic_prepare_commit(dev, intel_state);
if (ret) {
DRM_DEBUG_ATOMIC("Preparing state failed with %i\n", ret);
i915_sw_fence_commit(&intel_state->commit_ready);
return ret;
}
- /*
- * 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.
- *
- * Do this after drm_atomic_helper_setup_commit() and
- * intel_atomic_prepare_commit() because we still want
- * to skip the flip and fb cleanup waits. Although that
- * does risk yanking the mapping from under the display
- * engine.
- *
- * FIXME doing watermarks and fb cleanup from a vblank worker
- * (assuming we had any) would solve these problems.
- */
- if (INTEL_GEN(dev_priv) < 9)
- state->legacy_cursor_update = false;
-
- drm_atomic_helper_swap_state(state, true);
- dev_priv->wm.distrust_bios_wm = false;
- intel_shared_dpll_swap_state(state);
- intel_atomic_track_fbs(state);
-
- if (intel_state->modeset) {
- memcpy(dev_priv->min_pixclk, intel_state->min_pixclk,
- sizeof(intel_state->min_pixclk));
- dev_priv->active_crtcs = intel_state->active_crtcs;
- dev_priv->cdclk.logical = intel_state->cdclk.logical;
- dev_priv->cdclk.actual = intel_state->cdclk.actual;
- }
-
drm_atomic_state_get(state);
INIT_WORK(&state->commit_work,
nonblock ? intel_atomic_commit_work : NULL);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 83dd40905821..13044d95b166 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -808,6 +808,7 @@ struct intel_crtc {
int adjusted_y;
struct intel_crtc_state *config;
+ struct drm_crtc_commit *last_commit;
/* global reset count when the last flip was submitted */
unsigned int reset_count;
--
2.11.0
More information about the Intel-gfx-trybot
mailing list