drm/i915: Pass atomic states to fbc update functions.
authorMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Tue, 17 May 2016 13:07:59 +0000 (15:07 +0200)
committerMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Thu, 19 May 2016 12:38:52 +0000 (14:38 +0200)
This is required to let fbc updates run async. It has a lot of
checks whether certain locks are taken, which can be removed when
the relevant states are passed in as pointers.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1463490484-19540-17-git-send-email-maarten.lankhorst@linux.intel.com
Reviewed-by: Patrik Jakobsson <patrik.jakobsson@linux.intel.com>
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_fbc.c

index 11f427f4846659bb0834a6e447fdfab0e90666e5..39493f15843e05305e6392e6ddf72e7fd11d6118 100644 (file)
@@ -4589,7 +4589,7 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state)
                struct intel_plane_state *old_primary_state =
                        to_intel_plane_state(old_pri_state);
 
-               intel_fbc_pre_update(crtc);
+               intel_fbc_pre_update(crtc, pipe_config, primary_state);
 
                if (old_primary_state->visible &&
                    (modeset || !primary_state->visible))
@@ -11169,7 +11169,9 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
        if (obj->base.dma_buf)
                work->old_plane_state[0]->base.fence = intel_get_excl_fence(obj);
 
-       intel_fbc_pre_update(intel_crtc);
+       intel_fbc_pre_update(intel_crtc,
+                            to_intel_crtc_state(new_crtc_state),
+                            to_intel_plane_state(new_state));
 
        schedule_work(&work->mmio_work);
 
@@ -13126,7 +13128,7 @@ static int intel_atomic_commit(struct drm_device *dev,
 
                if (crtc->state->active &&
                    drm_atomic_get_existing_plane_state(state, crtc->primary))
-                       intel_fbc_enable(intel_crtc);
+                       intel_fbc_enable(intel_crtc, pipe_config, to_intel_plane_state(crtc->primary->state));
 
                if (crtc->state->active &&
                    (crtc->state->planes_changed || update_pipe))
index 3eb1f2f01ba36237be7cba5dfde397459139a81d..dae78f410a80d06cd255cf3ee7230ddf75a81e1e 100644 (file)
@@ -1420,11 +1420,15 @@ static inline void intel_fbdev_restore_mode(struct drm_device *dev)
 void intel_fbc_choose_crtc(struct drm_i915_private *dev_priv,
                           struct drm_atomic_state *state);
 bool intel_fbc_is_active(struct drm_i915_private *dev_priv);
-void intel_fbc_pre_update(struct intel_crtc *crtc);
+void intel_fbc_pre_update(struct intel_crtc *crtc,
+                         struct intel_crtc_state *crtc_state,
+                         struct intel_plane_state *plane_state);
 void intel_fbc_post_update(struct intel_crtc *crtc);
 void intel_fbc_init(struct drm_i915_private *dev_priv);
 void intel_fbc_init_pipe_state(struct drm_i915_private *dev_priv);
-void intel_fbc_enable(struct intel_crtc *crtc);
+void intel_fbc_enable(struct intel_crtc *crtc,
+                     struct intel_crtc_state *crtc_state,
+                     struct intel_plane_state *plane_state);
 void intel_fbc_disable(struct intel_crtc *crtc);
 void intel_fbc_global_disable(struct drm_i915_private *dev_priv);
 void intel_fbc_invalidate(struct drm_i915_private *dev_priv,
index 0dea5fbcd8aa83118dcefd3b57752d3d5b61208f..d2b0269b2fe45fb632f50fb1ce49ffe030504538 100644 (file)
@@ -480,10 +480,10 @@ static void intel_fbc_deactivate(struct drm_i915_private *dev_priv)
                intel_fbc_hw_deactivate(dev_priv);
 }
 
-static bool multiple_pipes_ok(struct intel_crtc *crtc)
+static bool multiple_pipes_ok(struct intel_crtc *crtc,
+                             struct intel_plane_state *plane_state)
 {
-       struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
-       struct drm_plane *primary = crtc->base.primary;
+       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        struct intel_fbc *fbc = &dev_priv->fbc;
        enum pipe pipe = crtc->pipe;
 
@@ -491,9 +491,7 @@ static bool multiple_pipes_ok(struct intel_crtc *crtc)
        if (!no_fbc_on_multiple_pipes(dev_priv))
                return true;
 
-       WARN_ON(!drm_modeset_is_locked(&primary->mutex));
-
-       if (to_intel_plane_state(primary->state)->visible)
+       if (plane_state->visible)
                fbc->visible_pipes_mask |= (1 << pipe);
        else
                fbc->visible_pipes_mask &= ~(1 << pipe);
@@ -708,21 +706,16 @@ static bool intel_fbc_hw_tracking_covers_screen(struct intel_crtc *crtc)
        return effective_w <= max_w && effective_h <= max_h;
 }
 
-static void intel_fbc_update_state_cache(struct intel_crtc *crtc)
+static void intel_fbc_update_state_cache(struct intel_crtc *crtc,
+                                        struct intel_crtc_state *crtc_state,
+                                        struct intel_plane_state *plane_state)
 {
        struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
        struct intel_fbc *fbc = &dev_priv->fbc;
        struct intel_fbc_state_cache *cache = &fbc->state_cache;
-       struct intel_crtc_state *crtc_state =
-               to_intel_crtc_state(crtc->base.state);
-       struct intel_plane_state *plane_state =
-               to_intel_plane_state(crtc->base.primary->state);
        struct drm_framebuffer *fb = plane_state->base.fb;
        struct drm_i915_gem_object *obj;
 
-       WARN_ON(!drm_modeset_is_locked(&crtc->base.mutex));
-       WARN_ON(!drm_modeset_is_locked(&crtc->base.primary->mutex));
-
        cache->crtc.mode_flags = crtc_state->base.adjusted_mode.flags;
        if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
                cache->crtc.hsw_bdw_pixel_rate =
@@ -887,7 +880,9 @@ static bool intel_fbc_reg_params_equal(struct intel_fbc_reg_params *params1,
        return memcmp(params1, params2, sizeof(*params1)) == 0;
 }
 
-void intel_fbc_pre_update(struct intel_crtc *crtc)
+void intel_fbc_pre_update(struct intel_crtc *crtc,
+                         struct intel_crtc_state *crtc_state,
+                         struct intel_plane_state *plane_state)
 {
        struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
        struct intel_fbc *fbc = &dev_priv->fbc;
@@ -897,7 +892,7 @@ void intel_fbc_pre_update(struct intel_crtc *crtc)
 
        mutex_lock(&fbc->lock);
 
-       if (!multiple_pipes_ok(crtc)) {
+       if (!multiple_pipes_ok(crtc, plane_state)) {
                fbc->no_fbc_reason = "more than one pipe active";
                goto deactivate;
        }
@@ -905,7 +900,7 @@ void intel_fbc_pre_update(struct intel_crtc *crtc)
        if (!fbc->enabled || fbc->crtc != crtc)
                goto unlock;
 
-       intel_fbc_update_state_cache(crtc);
+       intel_fbc_update_state_cache(crtc, crtc_state, plane_state);
 
 deactivate:
        intel_fbc_deactivate(dev_priv);
@@ -1089,7 +1084,9 @@ out:
  * intel_fbc_enable multiple times for the same pipe without an
  * intel_fbc_disable in the middle, as long as it is deactivated.
  */
-void intel_fbc_enable(struct intel_crtc *crtc)
+void intel_fbc_enable(struct intel_crtc *crtc,
+                     struct intel_crtc_state *crtc_state,
+                     struct intel_plane_state *plane_state)
 {
        struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
        struct intel_fbc *fbc = &dev_priv->fbc;
@@ -1102,19 +1099,19 @@ void intel_fbc_enable(struct intel_crtc *crtc)
        if (fbc->enabled) {
                WARN_ON(fbc->crtc == NULL);
                if (fbc->crtc == crtc) {
-                       WARN_ON(!crtc->config->enable_fbc);
+                       WARN_ON(!crtc_state->enable_fbc);
                        WARN_ON(fbc->active);
                }
                goto out;
        }
 
-       if (!crtc->config->enable_fbc)
+       if (!crtc_state->enable_fbc)
                goto out;
 
        WARN_ON(fbc->active);
        WARN_ON(fbc->crtc != NULL);
 
-       intel_fbc_update_state_cache(crtc);
+       intel_fbc_update_state_cache(crtc, crtc_state, plane_state);
        if (intel_fbc_alloc_cfb(crtc)) {
                fbc->no_fbc_reason = "not enough stolen memory";
                goto out;