diff options
author | Maarten Lankhorst <maarten.lankhorst@linux.intel.com> | 2016-05-17 09:07:59 -0400 |
---|---|---|
committer | Maarten Lankhorst <maarten.lankhorst@linux.intel.com> | 2016-05-19 08:38:52 -0400 |
commit | 2099deffef4404f949ba1b68d2b17e0608190bc2 (patch) | |
tree | a31eea885229c31643680d8dacb388ba52dc029c | |
parent | ee7171af72c39c18b7d7571419a4ac6ca30aea66 (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.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_fbc.c | 39 |
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) | |||
1420 | void intel_fbc_choose_crtc(struct drm_i915_private *dev_priv, | 1420 | void intel_fbc_choose_crtc(struct drm_i915_private *dev_priv, |
1421 | struct drm_atomic_state *state); | 1421 | struct drm_atomic_state *state); |
1422 | bool intel_fbc_is_active(struct drm_i915_private *dev_priv); | 1422 | bool intel_fbc_is_active(struct drm_i915_private *dev_priv); |
1423 | void intel_fbc_pre_update(struct intel_crtc *crtc); | 1423 | void intel_fbc_pre_update(struct intel_crtc *crtc, |
1424 | struct intel_crtc_state *crtc_state, | ||
1425 | struct intel_plane_state *plane_state); | ||
1424 | void intel_fbc_post_update(struct intel_crtc *crtc); | 1426 | void intel_fbc_post_update(struct intel_crtc *crtc); |
1425 | void intel_fbc_init(struct drm_i915_private *dev_priv); | 1427 | void intel_fbc_init(struct drm_i915_private *dev_priv); |
1426 | void intel_fbc_init_pipe_state(struct drm_i915_private *dev_priv); | 1428 | void intel_fbc_init_pipe_state(struct drm_i915_private *dev_priv); |
1427 | void intel_fbc_enable(struct intel_crtc *crtc); | 1429 | void intel_fbc_enable(struct intel_crtc *crtc, |
1430 | struct intel_crtc_state *crtc_state, | ||
1431 | struct intel_plane_state *plane_state); | ||
1428 | void intel_fbc_disable(struct intel_crtc *crtc); | 1432 | void intel_fbc_disable(struct intel_crtc *crtc); |
1429 | void intel_fbc_global_disable(struct drm_i915_private *dev_priv); | 1433 | void intel_fbc_global_disable(struct drm_i915_private *dev_priv); |
1430 | void intel_fbc_invalidate(struct drm_i915_private *dev_priv, | 1434 | void 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 | ||
483 | static bool multiple_pipes_ok(struct intel_crtc *crtc) | 483 | static 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 | ||
711 | static void intel_fbc_update_state_cache(struct intel_crtc *crtc) | 709 | static 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 | ||
890 | void intel_fbc_pre_update(struct intel_crtc *crtc) | 883 | void 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 | ||
910 | deactivate: | 905 | deactivate: |
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 | */ |
1092 | void intel_fbc_enable(struct intel_crtc *crtc) | 1087 | void 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; |