aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_fbc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_fbc.c')
-rw-r--r--drivers/gpu/drm/i915/intel_fbc.c70
1 files changed, 45 insertions, 25 deletions
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
index a19944b6dc25..6a7ad3ed1463 100644
--- a/drivers/gpu/drm/i915/intel_fbc.c
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -124,7 +124,9 @@ static void i8xx_fbc_deactivate(struct drm_i915_private *dev_priv)
124 I915_WRITE(FBC_CONTROL, fbc_ctl); 124 I915_WRITE(FBC_CONTROL, fbc_ctl);
125 125
126 /* Wait for compressing bit to clear */ 126 /* Wait for compressing bit to clear */
127 if (wait_for((I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) == 0, 10)) { 127 if (intel_wait_for_register(dev_priv,
128 FBC_STATUS, FBC_STAT_COMPRESSING, 0,
129 10)) {
128 DRM_DEBUG_KMS("FBC idle timed out\n"); 130 DRM_DEBUG_KMS("FBC idle timed out\n");
129 return; 131 return;
130 } 132 }
@@ -390,7 +392,7 @@ static void intel_fbc_work_fn(struct work_struct *__work)
390 struct intel_fbc *fbc = &dev_priv->fbc; 392 struct intel_fbc *fbc = &dev_priv->fbc;
391 struct intel_fbc_work *work = &fbc->work; 393 struct intel_fbc_work *work = &fbc->work;
392 struct intel_crtc *crtc = fbc->crtc; 394 struct intel_crtc *crtc = fbc->crtc;
393 struct drm_vblank_crtc *vblank = &dev_priv->dev->vblank[crtc->pipe]; 395 struct drm_vblank_crtc *vblank = &dev_priv->drm.vblank[crtc->pipe];
394 396
395 if (drm_crtc_vblank_get(&crtc->base)) { 397 if (drm_crtc_vblank_get(&crtc->base)) {
396 DRM_ERROR("vblank not available for FBC on pipe %c\n", 398 DRM_ERROR("vblank not available for FBC on pipe %c\n",
@@ -443,7 +445,7 @@ out:
443 445
444static void intel_fbc_schedule_activation(struct intel_crtc *crtc) 446static void intel_fbc_schedule_activation(struct intel_crtc *crtc)
445{ 447{
446 struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; 448 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
447 struct intel_fbc *fbc = &dev_priv->fbc; 449 struct intel_fbc *fbc = &dev_priv->fbc;
448 struct intel_fbc_work *work = &fbc->work; 450 struct intel_fbc_work *work = &fbc->work;
449 451
@@ -553,7 +555,7 @@ again:
553 555
554static int intel_fbc_alloc_cfb(struct intel_crtc *crtc) 556static int intel_fbc_alloc_cfb(struct intel_crtc *crtc)
555{ 557{
556 struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; 558 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
557 struct intel_fbc *fbc = &dev_priv->fbc; 559 struct intel_fbc *fbc = &dev_priv->fbc;
558 struct drm_mm_node *uninitialized_var(compressed_llb); 560 struct drm_mm_node *uninitialized_var(compressed_llb);
559 int size, fb_cpp, ret; 561 int size, fb_cpp, ret;
@@ -684,7 +686,7 @@ static bool pixel_format_is_valid(struct drm_i915_private *dev_priv,
684 */ 686 */
685static bool intel_fbc_hw_tracking_covers_screen(struct intel_crtc *crtc) 687static bool intel_fbc_hw_tracking_covers_screen(struct intel_crtc *crtc)
686{ 688{
687 struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; 689 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
688 struct intel_fbc *fbc = &dev_priv->fbc; 690 struct intel_fbc *fbc = &dev_priv->fbc;
689 unsigned int effective_w, effective_h, max_w, max_h; 691 unsigned int effective_w, effective_h, max_w, max_h;
690 692
@@ -711,7 +713,7 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc,
711 struct intel_crtc_state *crtc_state, 713 struct intel_crtc_state *crtc_state,
712 struct intel_plane_state *plane_state) 714 struct intel_plane_state *plane_state)
713{ 715{
714 struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; 716 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
715 struct intel_fbc *fbc = &dev_priv->fbc; 717 struct intel_fbc *fbc = &dev_priv->fbc;
716 struct intel_fbc_state_cache *cache = &fbc->state_cache; 718 struct intel_fbc_state_cache *cache = &fbc->state_cache;
717 struct drm_framebuffer *fb = plane_state->base.fb; 719 struct drm_framebuffer *fb = plane_state->base.fb;
@@ -744,7 +746,7 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc,
744 746
745static bool intel_fbc_can_activate(struct intel_crtc *crtc) 747static bool intel_fbc_can_activate(struct intel_crtc *crtc)
746{ 748{
747 struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; 749 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
748 struct intel_fbc *fbc = &dev_priv->fbc; 750 struct intel_fbc *fbc = &dev_priv->fbc;
749 struct intel_fbc_state_cache *cache = &fbc->state_cache; 751 struct intel_fbc_state_cache *cache = &fbc->state_cache;
750 752
@@ -816,22 +818,16 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc)
816 818
817static bool intel_fbc_can_choose(struct intel_crtc *crtc) 819static bool intel_fbc_can_choose(struct intel_crtc *crtc)
818{ 820{
819 struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; 821 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
820 struct intel_fbc *fbc = &dev_priv->fbc; 822 struct intel_fbc *fbc = &dev_priv->fbc;
821 bool enable_by_default = IS_BROADWELL(dev_priv);
822 823
823 if (intel_vgpu_active(dev_priv)) { 824 if (intel_vgpu_active(dev_priv)) {
824 fbc->no_fbc_reason = "VGPU is active"; 825 fbc->no_fbc_reason = "VGPU is active";
825 return false; 826 return false;
826 } 827 }
827 828
828 if (i915.enable_fbc < 0 && !enable_by_default) {
829 fbc->no_fbc_reason = "disabled per chip default";
830 return false;
831 }
832
833 if (!i915.enable_fbc) { 829 if (!i915.enable_fbc) {
834 fbc->no_fbc_reason = "disabled per module param"; 830 fbc->no_fbc_reason = "disabled per module param or by default";
835 return false; 831 return false;
836 } 832 }
837 833
@@ -851,7 +847,7 @@ static bool intel_fbc_can_choose(struct intel_crtc *crtc)
851static void intel_fbc_get_reg_params(struct intel_crtc *crtc, 847static void intel_fbc_get_reg_params(struct intel_crtc *crtc,
852 struct intel_fbc_reg_params *params) 848 struct intel_fbc_reg_params *params)
853{ 849{
854 struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; 850 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
855 struct intel_fbc *fbc = &dev_priv->fbc; 851 struct intel_fbc *fbc = &dev_priv->fbc;
856 struct intel_fbc_state_cache *cache = &fbc->state_cache; 852 struct intel_fbc_state_cache *cache = &fbc->state_cache;
857 853
@@ -884,7 +880,7 @@ void intel_fbc_pre_update(struct intel_crtc *crtc,
884 struct intel_crtc_state *crtc_state, 880 struct intel_crtc_state *crtc_state,
885 struct intel_plane_state *plane_state) 881 struct intel_plane_state *plane_state)
886{ 882{
887 struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; 883 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
888 struct intel_fbc *fbc = &dev_priv->fbc; 884 struct intel_fbc *fbc = &dev_priv->fbc;
889 885
890 if (!fbc_supported(dev_priv)) 886 if (!fbc_supported(dev_priv))
@@ -910,7 +906,7 @@ unlock:
910 906
911static void __intel_fbc_post_update(struct intel_crtc *crtc) 907static void __intel_fbc_post_update(struct intel_crtc *crtc)
912{ 908{
913 struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; 909 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
914 struct intel_fbc *fbc = &dev_priv->fbc; 910 struct intel_fbc *fbc = &dev_priv->fbc;
915 struct intel_fbc_reg_params old_params; 911 struct intel_fbc_reg_params old_params;
916 912
@@ -943,7 +939,7 @@ static void __intel_fbc_post_update(struct intel_crtc *crtc)
943 939
944void intel_fbc_post_update(struct intel_crtc *crtc) 940void intel_fbc_post_update(struct intel_crtc *crtc)
945{ 941{
946 struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; 942 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
947 struct intel_fbc *fbc = &dev_priv->fbc; 943 struct intel_fbc *fbc = &dev_priv->fbc;
948 944
949 if (!fbc_supported(dev_priv)) 945 if (!fbc_supported(dev_priv))
@@ -992,13 +988,13 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv,
992 if (!fbc_supported(dev_priv)) 988 if (!fbc_supported(dev_priv))
993 return; 989 return;
994 990
995 if (origin == ORIGIN_GTT || origin == ORIGIN_FLIP)
996 return;
997
998 mutex_lock(&fbc->lock); 991 mutex_lock(&fbc->lock);
999 992
1000 fbc->busy_bits &= ~frontbuffer_bits; 993 fbc->busy_bits &= ~frontbuffer_bits;
1001 994
995 if (origin == ORIGIN_GTT || origin == ORIGIN_FLIP)
996 goto out;
997
1002 if (!fbc->busy_bits && fbc->enabled && 998 if (!fbc->busy_bits && fbc->enabled &&
1003 (frontbuffer_bits & intel_fbc_get_frontbuffer_bit(fbc))) { 999 (frontbuffer_bits & intel_fbc_get_frontbuffer_bit(fbc))) {
1004 if (fbc->active) 1000 if (fbc->active)
@@ -1007,6 +1003,7 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv,
1007 __intel_fbc_post_update(fbc->crtc); 1003 __intel_fbc_post_update(fbc->crtc);
1008 } 1004 }
1009 1005
1006out:
1010 mutex_unlock(&fbc->lock); 1007 mutex_unlock(&fbc->lock);
1011} 1008}
1012 1009
@@ -1088,7 +1085,7 @@ void intel_fbc_enable(struct intel_crtc *crtc,
1088 struct intel_crtc_state *crtc_state, 1085 struct intel_crtc_state *crtc_state,
1089 struct intel_plane_state *plane_state) 1086 struct intel_plane_state *plane_state)
1090{ 1087{
1091 struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; 1088 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1092 struct intel_fbc *fbc = &dev_priv->fbc; 1089 struct intel_fbc *fbc = &dev_priv->fbc;
1093 1090
1094 if (!fbc_supported(dev_priv)) 1091 if (!fbc_supported(dev_priv))
@@ -1159,7 +1156,7 @@ static void __intel_fbc_disable(struct drm_i915_private *dev_priv)
1159 */ 1156 */
1160void intel_fbc_disable(struct intel_crtc *crtc) 1157void intel_fbc_disable(struct intel_crtc *crtc)
1161{ 1158{
1162 struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; 1159 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1163 struct intel_fbc *fbc = &dev_priv->fbc; 1160 struct intel_fbc *fbc = &dev_priv->fbc;
1164 1161
1165 if (!fbc_supported(dev_priv)) 1162 if (!fbc_supported(dev_priv))
@@ -1213,12 +1210,32 @@ void intel_fbc_init_pipe_state(struct drm_i915_private *dev_priv)
1213 if (!no_fbc_on_multiple_pipes(dev_priv)) 1210 if (!no_fbc_on_multiple_pipes(dev_priv))
1214 return; 1211 return;
1215 1212
1216 for_each_intel_crtc(dev_priv->dev, crtc) 1213 for_each_intel_crtc(&dev_priv->drm, crtc)
1217 if (intel_crtc_active(&crtc->base) && 1214 if (intel_crtc_active(&crtc->base) &&
1218 to_intel_plane_state(crtc->base.primary->state)->visible) 1215 to_intel_plane_state(crtc->base.primary->state)->visible)
1219 dev_priv->fbc.visible_pipes_mask |= (1 << crtc->pipe); 1216 dev_priv->fbc.visible_pipes_mask |= (1 << crtc->pipe);
1220} 1217}
1221 1218
1219/*
1220 * The DDX driver changes its behavior depending on the value it reads from
1221 * i915.enable_fbc, so sanitize it by translating the default value into either
1222 * 0 or 1 in order to allow it to know what's going on.
1223 *
1224 * Notice that this is done at driver initialization and we still allow user
1225 * space to change the value during runtime without sanitizing it again. IGT
1226 * relies on being able to change i915.enable_fbc at runtime.
1227 */
1228static int intel_sanitize_fbc_option(struct drm_i915_private *dev_priv)
1229{
1230 if (i915.enable_fbc >= 0)
1231 return !!i915.enable_fbc;
1232
1233 if (IS_BROADWELL(dev_priv))
1234 return 1;
1235
1236 return 0;
1237}
1238
1222/** 1239/**
1223 * intel_fbc_init - Initialize FBC 1240 * intel_fbc_init - Initialize FBC
1224 * @dev_priv: the i915 device 1241 * @dev_priv: the i915 device
@@ -1236,6 +1253,9 @@ void intel_fbc_init(struct drm_i915_private *dev_priv)
1236 fbc->active = false; 1253 fbc->active = false;
1237 fbc->work.scheduled = false; 1254 fbc->work.scheduled = false;
1238 1255
1256 i915.enable_fbc = intel_sanitize_fbc_option(dev_priv);
1257 DRM_DEBUG_KMS("Sanitized enable_fbc value: %d\n", i915.enable_fbc);
1258
1239 if (!HAS_FBC(dev_priv)) { 1259 if (!HAS_FBC(dev_priv)) {
1240 fbc->no_fbc_reason = "unsupported by this chipset"; 1260 fbc->no_fbc_reason = "unsupported by this chipset";
1241 return; 1261 return;