aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaarten Lankhorst <maarten.lankhorst@linux.intel.com>2016-05-17 09:07:59 -0400
committerMaarten Lankhorst <maarten.lankhorst@linux.intel.com>2016-05-19 08:38:52 -0400
commit2099deffef4404f949ba1b68d2b17e0608190bc2 (patch)
treea31eea885229c31643680d8dacb388ba52dc029c
parentee7171af72c39c18b7d7571419a4ac6ca30aea66 (diff)
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: 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>
-rw-r--r--drivers/gpu/drm/i915/intel_display.c8
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h8
-rw-r--r--drivers/gpu/drm/i915/intel_fbc.c39
3 files changed, 29 insertions, 26 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 11f427f48466..39493f15843e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4589,7 +4589,7 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state)
4589 struct intel_plane_state *old_primary_state = 4589 struct intel_plane_state *old_primary_state =
4590 to_intel_plane_state(old_pri_state); 4590 to_intel_plane_state(old_pri_state);
4591 4591
4592 intel_fbc_pre_update(crtc); 4592 intel_fbc_pre_update(crtc, pipe_config, primary_state);
4593 4593
4594 if (old_primary_state->visible && 4594 if (old_primary_state->visible &&
4595 (modeset || !primary_state->visible)) 4595 (modeset || !primary_state->visible))
@@ -11169,7 +11169,9 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
11169 if (obj->base.dma_buf) 11169 if (obj->base.dma_buf)
11170 work->old_plane_state[0]->base.fence = intel_get_excl_fence(obj); 11170 work->old_plane_state[0]->base.fence = intel_get_excl_fence(obj);
11171 11171
11172 intel_fbc_pre_update(intel_crtc); 11172 intel_fbc_pre_update(intel_crtc,
11173 to_intel_crtc_state(new_crtc_state),
11174 to_intel_plane_state(new_state));
11173 11175
11174 schedule_work(&work->mmio_work); 11176 schedule_work(&work->mmio_work);
11175 11177
@@ -13126,7 +13128,7 @@ static int intel_atomic_commit(struct drm_device *dev,
13126 13128
13127 if (crtc->state->active && 13129 if (crtc->state->active &&
13128 drm_atomic_get_existing_plane_state(state, crtc->primary)) 13130 drm_atomic_get_existing_plane_state(state, crtc->primary))
13129 intel_fbc_enable(intel_crtc); 13131 intel_fbc_enable(intel_crtc, pipe_config, to_intel_plane_state(crtc->primary->state));
13130 13132
13131 if (crtc->state->active && 13133 if (crtc->state->active &&
13132 (crtc->state->planes_changed || update_pipe)) 13134 (crtc->state->planes_changed || update_pipe))
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 3eb1f2f01ba3..dae78f410a80 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1420,11 +1420,15 @@ static inline void intel_fbdev_restore_mode(struct drm_device *dev)
1420void intel_fbc_choose_crtc(struct drm_i915_private *dev_priv, 1420void intel_fbc_choose_crtc(struct drm_i915_private *dev_priv,
1421 struct drm_atomic_state *state); 1421 struct drm_atomic_state *state);
1422bool intel_fbc_is_active(struct drm_i915_private *dev_priv); 1422bool intel_fbc_is_active(struct drm_i915_private *dev_priv);
1423void intel_fbc_pre_update(struct intel_crtc *crtc); 1423void intel_fbc_pre_update(struct intel_crtc *crtc,
1424 struct intel_crtc_state *crtc_state,
1425 struct intel_plane_state *plane_state);
1424void intel_fbc_post_update(struct intel_crtc *crtc); 1426void intel_fbc_post_update(struct intel_crtc *crtc);
1425void intel_fbc_init(struct drm_i915_private *dev_priv); 1427void intel_fbc_init(struct drm_i915_private *dev_priv);
1426void intel_fbc_init_pipe_state(struct drm_i915_private *dev_priv); 1428void intel_fbc_init_pipe_state(struct drm_i915_private *dev_priv);
1427void intel_fbc_enable(struct intel_crtc *crtc); 1429void intel_fbc_enable(struct intel_crtc *crtc,
1430 struct intel_crtc_state *crtc_state,
1431 struct intel_plane_state *plane_state);
1428void intel_fbc_disable(struct intel_crtc *crtc); 1432void intel_fbc_disable(struct intel_crtc *crtc);
1429void intel_fbc_global_disable(struct drm_i915_private *dev_priv); 1433void intel_fbc_global_disable(struct drm_i915_private *dev_priv);
1430void intel_fbc_invalidate(struct drm_i915_private *dev_priv, 1434void intel_fbc_invalidate(struct drm_i915_private *dev_priv,
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
index 0dea5fbcd8aa..d2b0269b2fe4 100644
--- a/drivers/gpu/drm/i915/intel_fbc.c
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -480,10 +480,10 @@ static void intel_fbc_deactivate(struct drm_i915_private *dev_priv)
480 intel_fbc_hw_deactivate(dev_priv); 480 intel_fbc_hw_deactivate(dev_priv);
481} 481}
482 482
483static bool multiple_pipes_ok(struct intel_crtc *crtc) 483static bool multiple_pipes_ok(struct intel_crtc *crtc,
484 struct intel_plane_state *plane_state)
484{ 485{
485 struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; 486 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
486 struct drm_plane *primary = crtc->base.primary;
487 struct intel_fbc *fbc = &dev_priv->fbc; 487 struct intel_fbc *fbc = &dev_priv->fbc;
488 enum pipe pipe = crtc->pipe; 488 enum pipe pipe = crtc->pipe;
489 489
@@ -491,9 +491,7 @@ static bool multiple_pipes_ok(struct intel_crtc *crtc)
491 if (!no_fbc_on_multiple_pipes(dev_priv)) 491 if (!no_fbc_on_multiple_pipes(dev_priv))
492 return true; 492 return true;
493 493
494 WARN_ON(!drm_modeset_is_locked(&primary->mutex)); 494 if (plane_state->visible)
495
496 if (to_intel_plane_state(primary->state)->visible)
497 fbc->visible_pipes_mask |= (1 << pipe); 495 fbc->visible_pipes_mask |= (1 << pipe);
498 else 496 else
499 fbc->visible_pipes_mask &= ~(1 << pipe); 497 fbc->visible_pipes_mask &= ~(1 << pipe);
@@ -708,21 +706,16 @@ static bool intel_fbc_hw_tracking_covers_screen(struct intel_crtc *crtc)
708 return effective_w <= max_w && effective_h <= max_h; 706 return effective_w <= max_w && effective_h <= max_h;
709} 707}
710 708
711static void intel_fbc_update_state_cache(struct intel_crtc *crtc) 709static void intel_fbc_update_state_cache(struct intel_crtc *crtc,
710 struct intel_crtc_state *crtc_state,
711 struct intel_plane_state *plane_state)
712{ 712{
713 struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; 713 struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
714 struct intel_fbc *fbc = &dev_priv->fbc; 714 struct intel_fbc *fbc = &dev_priv->fbc;
715 struct intel_fbc_state_cache *cache = &fbc->state_cache; 715 struct intel_fbc_state_cache *cache = &fbc->state_cache;
716 struct intel_crtc_state *crtc_state =
717 to_intel_crtc_state(crtc->base.state);
718 struct intel_plane_state *plane_state =
719 to_intel_plane_state(crtc->base.primary->state);
720 struct drm_framebuffer *fb = plane_state->base.fb; 716 struct drm_framebuffer *fb = plane_state->base.fb;
721 struct drm_i915_gem_object *obj; 717 struct drm_i915_gem_object *obj;
722 718
723 WARN_ON(!drm_modeset_is_locked(&crtc->base.mutex));
724 WARN_ON(!drm_modeset_is_locked(&crtc->base.primary->mutex));
725
726 cache->crtc.mode_flags = crtc_state->base.adjusted_mode.flags; 719 cache->crtc.mode_flags = crtc_state->base.adjusted_mode.flags;
727 if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) 720 if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
728 cache->crtc.hsw_bdw_pixel_rate = 721 cache->crtc.hsw_bdw_pixel_rate =
@@ -887,7 +880,9 @@ static bool intel_fbc_reg_params_equal(struct intel_fbc_reg_params *params1,
887 return memcmp(params1, params2, sizeof(*params1)) == 0; 880 return memcmp(params1, params2, sizeof(*params1)) == 0;
888} 881}
889 882
890void intel_fbc_pre_update(struct intel_crtc *crtc) 883void intel_fbc_pre_update(struct intel_crtc *crtc,
884 struct intel_crtc_state *crtc_state,
885 struct intel_plane_state *plane_state)
891{ 886{
892 struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; 887 struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
893 struct intel_fbc *fbc = &dev_priv->fbc; 888 struct intel_fbc *fbc = &dev_priv->fbc;
@@ -897,7 +892,7 @@ void intel_fbc_pre_update(struct intel_crtc *crtc)
897 892
898 mutex_lock(&fbc->lock); 893 mutex_lock(&fbc->lock);
899 894
900 if (!multiple_pipes_ok(crtc)) { 895 if (!multiple_pipes_ok(crtc, plane_state)) {
901 fbc->no_fbc_reason = "more than one pipe active"; 896 fbc->no_fbc_reason = "more than one pipe active";
902 goto deactivate; 897 goto deactivate;
903 } 898 }
@@ -905,7 +900,7 @@ void intel_fbc_pre_update(struct intel_crtc *crtc)
905 if (!fbc->enabled || fbc->crtc != crtc) 900 if (!fbc->enabled || fbc->crtc != crtc)
906 goto unlock; 901 goto unlock;
907 902
908 intel_fbc_update_state_cache(crtc); 903 intel_fbc_update_state_cache(crtc, crtc_state, plane_state);
909 904
910deactivate: 905deactivate:
911 intel_fbc_deactivate(dev_priv); 906 intel_fbc_deactivate(dev_priv);
@@ -1089,7 +1084,9 @@ out:
1089 * intel_fbc_enable multiple times for the same pipe without an 1084 * intel_fbc_enable multiple times for the same pipe without an
1090 * intel_fbc_disable in the middle, as long as it is deactivated. 1085 * intel_fbc_disable in the middle, as long as it is deactivated.
1091 */ 1086 */
1092void intel_fbc_enable(struct intel_crtc *crtc) 1087void intel_fbc_enable(struct intel_crtc *crtc,
1088 struct intel_crtc_state *crtc_state,
1089 struct intel_plane_state *plane_state)
1093{ 1090{
1094 struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; 1091 struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
1095 struct intel_fbc *fbc = &dev_priv->fbc; 1092 struct intel_fbc *fbc = &dev_priv->fbc;
@@ -1102,19 +1099,19 @@ void intel_fbc_enable(struct intel_crtc *crtc)
1102 if (fbc->enabled) { 1099 if (fbc->enabled) {
1103 WARN_ON(fbc->crtc == NULL); 1100 WARN_ON(fbc->crtc == NULL);
1104 if (fbc->crtc == crtc) { 1101 if (fbc->crtc == crtc) {
1105 WARN_ON(!crtc->config->enable_fbc); 1102 WARN_ON(!crtc_state->enable_fbc);
1106 WARN_ON(fbc->active); 1103 WARN_ON(fbc->active);
1107 } 1104 }
1108 goto out; 1105 goto out;
1109 } 1106 }
1110 1107
1111 if (!crtc->config->enable_fbc) 1108 if (!crtc_state->enable_fbc)
1112 goto out; 1109 goto out;
1113 1110
1114 WARN_ON(fbc->active); 1111 WARN_ON(fbc->active);
1115 WARN_ON(fbc->crtc != NULL); 1112 WARN_ON(fbc->crtc != NULL);
1116 1113
1117 intel_fbc_update_state_cache(crtc); 1114 intel_fbc_update_state_cache(crtc, crtc_state, plane_state);
1118 if (intel_fbc_alloc_cfb(crtc)) { 1115 if (intel_fbc_alloc_cfb(crtc)) {
1119 fbc->no_fbc_reason = "not enough stolen memory"; 1116 fbc->no_fbc_reason = "not enough stolen memory";
1120 goto out; 1117 goto out;