Commit 2099deff authored by Maarten Lankhorst's avatar Maarten Lankhorst

drm/i915: Pass atomic states to fbc update functions.

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: default avatarMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1463490484-19540-17-git-send-email-maarten.lankhorst@linux.intel.comReviewed-by: default avatarPatrik Jakobsson <patrik.jakobsson@linux.intel.com>
parent ee7171af
...@@ -4589,7 +4589,7 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state) ...@@ -4589,7 +4589,7 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state)
struct intel_plane_state *old_primary_state = struct intel_plane_state *old_primary_state =
to_intel_plane_state(old_pri_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 && if (old_primary_state->visible &&
(modeset || !primary_state->visible)) (modeset || !primary_state->visible))
...@@ -11169,7 +11169,9 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, ...@@ -11169,7 +11169,9 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
if (obj->base.dma_buf) if (obj->base.dma_buf)
work->old_plane_state[0]->base.fence = intel_get_excl_fence(obj); 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); schedule_work(&work->mmio_work);
...@@ -13126,7 +13128,7 @@ static int intel_atomic_commit(struct drm_device *dev, ...@@ -13126,7 +13128,7 @@ static int intel_atomic_commit(struct drm_device *dev,
if (crtc->state->active && if (crtc->state->active &&
drm_atomic_get_existing_plane_state(state, crtc->primary)) 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 && if (crtc->state->active &&
(crtc->state->planes_changed || update_pipe)) (crtc->state->planes_changed || update_pipe))
......
...@@ -1420,11 +1420,15 @@ static inline void intel_fbdev_restore_mode(struct drm_device *dev) ...@@ -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, void intel_fbc_choose_crtc(struct drm_i915_private *dev_priv,
struct drm_atomic_state *state); struct drm_atomic_state *state);
bool intel_fbc_is_active(struct drm_i915_private *dev_priv); 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_post_update(struct intel_crtc *crtc);
void intel_fbc_init(struct drm_i915_private *dev_priv); 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_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_disable(struct intel_crtc *crtc);
void intel_fbc_global_disable(struct drm_i915_private *dev_priv); void intel_fbc_global_disable(struct drm_i915_private *dev_priv);
void intel_fbc_invalidate(struct drm_i915_private *dev_priv, void intel_fbc_invalidate(struct drm_i915_private *dev_priv,
......
...@@ -480,10 +480,10 @@ static void intel_fbc_deactivate(struct drm_i915_private *dev_priv) ...@@ -480,10 +480,10 @@ static void intel_fbc_deactivate(struct drm_i915_private *dev_priv)
intel_fbc_hw_deactivate(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_i915_private *dev_priv = to_i915(crtc->base.dev);
struct drm_plane *primary = crtc->base.primary;
struct intel_fbc *fbc = &dev_priv->fbc; struct intel_fbc *fbc = &dev_priv->fbc;
enum pipe pipe = crtc->pipe; enum pipe pipe = crtc->pipe;
...@@ -491,9 +491,7 @@ static bool multiple_pipes_ok(struct intel_crtc *crtc) ...@@ -491,9 +491,7 @@ static bool multiple_pipes_ok(struct intel_crtc *crtc)
if (!no_fbc_on_multiple_pipes(dev_priv)) if (!no_fbc_on_multiple_pipes(dev_priv))
return true; return true;
WARN_ON(!drm_modeset_is_locked(&primary->mutex)); if (plane_state->visible)
if (to_intel_plane_state(primary->state)->visible)
fbc->visible_pipes_mask |= (1 << pipe); fbc->visible_pipes_mask |= (1 << pipe);
else else
fbc->visible_pipes_mask &= ~(1 << pipe); fbc->visible_pipes_mask &= ~(1 << pipe);
...@@ -708,21 +706,16 @@ static bool intel_fbc_hw_tracking_covers_screen(struct intel_crtc *crtc) ...@@ -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; 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 drm_i915_private *dev_priv = crtc->base.dev->dev_private;
struct intel_fbc *fbc = &dev_priv->fbc; struct intel_fbc *fbc = &dev_priv->fbc;
struct intel_fbc_state_cache *cache = &fbc->state_cache; 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_framebuffer *fb = plane_state->base.fb;
struct drm_i915_gem_object *obj; 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; cache->crtc.mode_flags = crtc_state->base.adjusted_mode.flags;
if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
cache->crtc.hsw_bdw_pixel_rate = cache->crtc.hsw_bdw_pixel_rate =
...@@ -887,7 +880,9 @@ static bool intel_fbc_reg_params_equal(struct intel_fbc_reg_params *params1, ...@@ -887,7 +880,9 @@ static bool intel_fbc_reg_params_equal(struct intel_fbc_reg_params *params1,
return memcmp(params1, params2, sizeof(*params1)) == 0; 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 drm_i915_private *dev_priv = crtc->base.dev->dev_private;
struct intel_fbc *fbc = &dev_priv->fbc; struct intel_fbc *fbc = &dev_priv->fbc;
...@@ -897,7 +892,7 @@ void intel_fbc_pre_update(struct intel_crtc *crtc) ...@@ -897,7 +892,7 @@ void intel_fbc_pre_update(struct intel_crtc *crtc)
mutex_lock(&fbc->lock); 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"; fbc->no_fbc_reason = "more than one pipe active";
goto deactivate; goto deactivate;
} }
...@@ -905,7 +900,7 @@ void intel_fbc_pre_update(struct intel_crtc *crtc) ...@@ -905,7 +900,7 @@ void intel_fbc_pre_update(struct intel_crtc *crtc)
if (!fbc->enabled || fbc->crtc != crtc) if (!fbc->enabled || fbc->crtc != crtc)
goto unlock; goto unlock;
intel_fbc_update_state_cache(crtc); intel_fbc_update_state_cache(crtc, crtc_state, plane_state);
deactivate: deactivate:
intel_fbc_deactivate(dev_priv); intel_fbc_deactivate(dev_priv);
...@@ -1089,7 +1084,9 @@ void intel_fbc_choose_crtc(struct drm_i915_private *dev_priv, ...@@ -1089,7 +1084,9 @@ void intel_fbc_choose_crtc(struct drm_i915_private *dev_priv,
* intel_fbc_enable multiple times for the same pipe without an * intel_fbc_enable multiple times for the same pipe without an
* intel_fbc_disable in the middle, as long as it is deactivated. * 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 drm_i915_private *dev_priv = crtc->base.dev->dev_private;
struct intel_fbc *fbc = &dev_priv->fbc; struct intel_fbc *fbc = &dev_priv->fbc;
...@@ -1102,19 +1099,19 @@ void intel_fbc_enable(struct intel_crtc *crtc) ...@@ -1102,19 +1099,19 @@ void intel_fbc_enable(struct intel_crtc *crtc)
if (fbc->enabled) { if (fbc->enabled) {
WARN_ON(fbc->crtc == NULL); WARN_ON(fbc->crtc == NULL);
if (fbc->crtc == crtc) { if (fbc->crtc == crtc) {
WARN_ON(!crtc->config->enable_fbc); WARN_ON(!crtc_state->enable_fbc);
WARN_ON(fbc->active); WARN_ON(fbc->active);
} }
goto out; goto out;
} }
if (!crtc->config->enable_fbc) if (!crtc_state->enable_fbc)
goto out; goto out;
WARN_ON(fbc->active); WARN_ON(fbc->active);
WARN_ON(fbc->crtc != NULL); 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)) { if (intel_fbc_alloc_cfb(crtc)) {
fbc->no_fbc_reason = "not enough stolen memory"; fbc->no_fbc_reason = "not enough stolen memory";
goto out; goto out;
......
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