diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_fbc.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_fbc.c | 70 |
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 | ||
444 | static void intel_fbc_schedule_activation(struct intel_crtc *crtc) | 446 | static 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 | ||
554 | static int intel_fbc_alloc_cfb(struct intel_crtc *crtc) | 556 | static 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 | */ |
685 | static bool intel_fbc_hw_tracking_covers_screen(struct intel_crtc *crtc) | 687 | static 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 | ||
745 | static bool intel_fbc_can_activate(struct intel_crtc *crtc) | 747 | static 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 | ||
817 | static bool intel_fbc_can_choose(struct intel_crtc *crtc) | 819 | static 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) | |||
851 | static void intel_fbc_get_reg_params(struct intel_crtc *crtc, | 847 | static 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 | ||
911 | static void __intel_fbc_post_update(struct intel_crtc *crtc) | 907 | static 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 | ||
944 | void intel_fbc_post_update(struct intel_crtc *crtc) | 940 | void 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 | ||
1006 | out: | ||
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 | */ |
1160 | void intel_fbc_disable(struct intel_crtc *crtc) | 1157 | void 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 | */ | ||
1228 | static 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; |