@@ -2240,14 +2240,6 @@ static void intel_enable_primary_hw_plane(struct drm_plane *plane,
2240
2240
2241
2241
dev_priv -> display .update_primary_plane (crtc , plane -> fb ,
2242
2242
crtc -> x , crtc -> y );
2243
-
2244
- /*
2245
- * BDW signals flip done immediately if the plane
2246
- * is disabled, even if the plane enable is already
2247
- * armed to occur at the next vblank :(
2248
- */
2249
- if (IS_BROADWELL (dev ))
2250
- intel_wait_for_vblank (dev , intel_crtc -> pipe );
2251
2243
}
2252
2244
2253
2245
static bool need_vtd_wa (struct drm_device * dev )
@@ -4742,45 +4734,134 @@ static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable)
4742
4734
*/
4743
4735
}
4744
4736
4745
- static void intel_crtc_enable_planes (struct drm_crtc * crtc )
4737
+ /**
4738
+ * intel_post_enable_primary - Perform operations after enabling primary plane
4739
+ * @crtc: the CRTC whose primary plane was just enabled
4740
+ *
4741
+ * Performs potentially sleeping operations that must be done after the primary
4742
+ * plane is enabled, such as updating FBC and IPS. Note that this may be
4743
+ * called due to an explicit primary plane update, or due to an implicit
4744
+ * re-enable that is caused when a sprite plane is updated to no longer
4745
+ * completely hide the primary plane.
4746
+ */
4747
+ static void
4748
+ intel_post_enable_primary (struct drm_crtc * crtc )
4746
4749
{
4747
4750
struct drm_device * dev = crtc -> dev ;
4751
+ struct drm_i915_private * dev_priv = dev -> dev_private ;
4748
4752
struct intel_crtc * intel_crtc = to_intel_crtc (crtc );
4749
4753
int pipe = intel_crtc -> pipe ;
4750
4754
4751
- intel_enable_primary_hw_plane (crtc -> primary , crtc );
4752
- intel_enable_sprite_planes (crtc );
4753
- intel_crtc_update_cursor (crtc , true);
4754
- intel_crtc_dpms_overlay (intel_crtc , true);
4755
+ /*
4756
+ * BDW signals flip done immediately if the plane
4757
+ * is disabled, even if the plane enable is already
4758
+ * armed to occur at the next vblank :(
4759
+ */
4760
+ if (IS_BROADWELL (dev ))
4761
+ intel_wait_for_vblank (dev , pipe );
4755
4762
4763
+ /*
4764
+ * FIXME IPS should be fine as long as one plane is
4765
+ * enabled, but in practice it seems to have problems
4766
+ * when going from primary only to sprite only and vice
4767
+ * versa.
4768
+ */
4756
4769
hsw_enable_ips (intel_crtc );
4757
4770
4758
4771
mutex_lock (& dev -> struct_mutex );
4759
4772
intel_fbc_update (dev );
4760
4773
mutex_unlock (& dev -> struct_mutex );
4761
4774
4762
4775
/*
4763
- * FIXME: Once we grow proper nuclear flip support out of this we need
4764
- * to compute the mask of flip planes precisely. For the time being
4765
- * consider this a flip from a NULL plane.
4776
+ * Gen2 reports pipe underruns whenever all planes are disabled.
4777
+ * So don't enable underrun reporting before at least some planes
4778
+ * are enabled.
4779
+ * FIXME: Need to fix the logic to work when we turn off all planes
4780
+ * but leave the pipe running.
4766
4781
*/
4767
- intel_frontbuffer_flip (dev , INTEL_FRONTBUFFER_ALL_MASK (pipe ));
4782
+ if (IS_GEN2 (dev ))
4783
+ intel_set_cpu_fifo_underrun_reporting (dev_priv , pipe , true);
4784
+
4785
+ /* Underruns don't raise interrupts, so check manually. */
4786
+ if (HAS_GMCH_DISPLAY (dev ))
4787
+ i9xx_check_fifo_underruns (dev_priv );
4768
4788
}
4769
4789
4770
- static void intel_crtc_disable_planes (struct drm_crtc * crtc )
4790
+ /**
4791
+ * intel_pre_disable_primary - Perform operations before disabling primary plane
4792
+ * @crtc: the CRTC whose primary plane is to be disabled
4793
+ *
4794
+ * Performs potentially sleeping operations that must be done before the
4795
+ * primary plane is disabled, such as updating FBC and IPS. Note that this may
4796
+ * be called due to an explicit primary plane update, or due to an implicit
4797
+ * disable that is caused when a sprite plane completely hides the primary
4798
+ * plane.
4799
+ */
4800
+ static void
4801
+ intel_pre_disable_primary (struct drm_crtc * crtc )
4771
4802
{
4772
4803
struct drm_device * dev = crtc -> dev ;
4773
4804
struct drm_i915_private * dev_priv = dev -> dev_private ;
4774
4805
struct intel_crtc * intel_crtc = to_intel_crtc (crtc );
4775
- struct intel_plane * intel_plane ;
4776
4806
int pipe = intel_crtc -> pipe ;
4777
4807
4778
- intel_crtc_wait_for_pending_flips (crtc );
4808
+ /*
4809
+ * Gen2 reports pipe underruns whenever all planes are disabled.
4810
+ * So diasble underrun reporting before all the planes get disabled.
4811
+ * FIXME: Need to fix the logic to work when we turn off all planes
4812
+ * but leave the pipe running.
4813
+ */
4814
+ if (IS_GEN2 (dev ))
4815
+ intel_set_cpu_fifo_underrun_reporting (dev_priv , pipe , false);
4816
+
4817
+ /*
4818
+ * Vblank time updates from the shadow to live plane control register
4819
+ * are blocked if the memory self-refresh mode is active at that
4820
+ * moment. So to make sure the plane gets truly disabled, disable
4821
+ * first the self-refresh mode. The self-refresh enable bit in turn
4822
+ * will be checked/applied by the HW only at the next frame start
4823
+ * event which is after the vblank start event, so we need to have a
4824
+ * wait-for-vblank between disabling the plane and the pipe.
4825
+ */
4826
+ if (HAS_GMCH_DISPLAY (dev ))
4827
+ intel_set_memory_cxsr (dev_priv , false);
4779
4828
4829
+ mutex_lock (& dev -> struct_mutex );
4780
4830
if (dev_priv -> fbc .crtc == intel_crtc )
4781
4831
intel_fbc_disable (dev );
4832
+ mutex_unlock (& dev -> struct_mutex );
4782
4833
4834
+ /*
4835
+ * FIXME IPS should be fine as long as one plane is
4836
+ * enabled, but in practice it seems to have problems
4837
+ * when going from primary only to sprite only and vice
4838
+ * versa.
4839
+ */
4783
4840
hsw_disable_ips (intel_crtc );
4841
+ }
4842
+
4843
+ static void intel_crtc_enable_planes (struct drm_crtc * crtc )
4844
+ {
4845
+ struct intel_crtc * intel_crtc = to_intel_crtc (crtc );
4846
+
4847
+ intel_enable_primary_hw_plane (crtc -> primary , crtc );
4848
+ intel_enable_sprite_planes (crtc );
4849
+ intel_crtc_update_cursor (crtc , true);
4850
+ intel_crtc_dpms_overlay (intel_crtc , true);
4851
+
4852
+ intel_post_enable_primary (crtc );
4853
+ }
4854
+
4855
+ static void intel_crtc_disable_planes (struct drm_crtc * crtc )
4856
+ {
4857
+ struct drm_device * dev = crtc -> dev ;
4858
+ struct intel_crtc * intel_crtc = to_intel_crtc (crtc );
4859
+ struct intel_plane * intel_plane ;
4860
+ int pipe = intel_crtc -> pipe ;
4861
+
4862
+ intel_crtc_wait_for_pending_flips (crtc );
4863
+
4864
+ intel_pre_disable_primary (crtc );
4784
4865
4785
4866
intel_crtc_dpms_overlay (intel_crtc , false);
4786
4867
for_each_intel_plane (dev , intel_plane ) {
@@ -5839,9 +5920,6 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
5839
5920
encoder -> enable (encoder );
5840
5921
5841
5922
intel_crtc_enable_planes (crtc );
5842
-
5843
- /* Underruns don't raise interrupts, so check manually. */
5844
- i9xx_check_fifo_underruns (dev_priv );
5845
5923
}
5846
5924
5847
5925
static void i9xx_set_pll_dividers (struct intel_crtc * crtc )
@@ -5900,19 +5978,6 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
5900
5978
encoder -> enable (encoder );
5901
5979
5902
5980
intel_crtc_enable_planes (crtc );
5903
-
5904
- /*
5905
- * Gen2 reports pipe underruns whenever all planes are disabled.
5906
- * So don't enable underrun reporting before at least some planes
5907
- * are enabled.
5908
- * FIXME: Need to fix the logic to work when we turn off all planes
5909
- * but leave the pipe running.
5910
- */
5911
- if (IS_GEN2 (dev ))
5912
- intel_set_cpu_fifo_underrun_reporting (dev_priv , pipe , true);
5913
-
5914
- /* Underruns don't raise interrupts, so check manually. */
5915
- i9xx_check_fifo_underruns (dev_priv );
5916
5981
}
5917
5982
5918
5983
static void i9xx_pfit_disable (struct intel_crtc * crtc )
@@ -5941,25 +6006,6 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
5941
6006
if (!intel_crtc -> active )
5942
6007
return ;
5943
6008
5944
- /*
5945
- * Gen2 reports pipe underruns whenever all planes are disabled.
5946
- * So diasble underrun reporting before all the planes get disabled.
5947
- * FIXME: Need to fix the logic to work when we turn off all planes
5948
- * but leave the pipe running.
5949
- */
5950
- if (IS_GEN2 (dev ))
5951
- intel_set_cpu_fifo_underrun_reporting (dev_priv , pipe , false);
5952
-
5953
- /*
5954
- * Vblank time updates from the shadow to live plane control register
5955
- * are blocked if the memory self-refresh mode is active at that
5956
- * moment. So to make sure the plane gets truly disabled, disable
5957
- * first the self-refresh mode. The self-refresh enable bit in turn
5958
- * will be checked/applied by the HW only at the next frame start
5959
- * event which is after the vblank start event, so we need to have a
5960
- * wait-for-vblank between disabling the plane and the pipe.
5961
- */
5962
- intel_set_memory_cxsr (dev_priv , false);
5963
6009
intel_crtc_disable_planes (crtc );
5964
6010
5965
6011
/*
@@ -12908,7 +12954,7 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
12908
12954
plane_state = to_intel_plane_state (primary -> state );
12909
12955
if (ret == 0 && !was_visible && plane_state -> visible ) {
12910
12956
WARN_ON (!intel_crtc -> active );
12911
- intel_enable_primary_hw_plane ( set -> crtc -> primary , set -> crtc );
12957
+ intel_post_enable_primary ( set -> crtc );
12912
12958
}
12913
12959
12914
12960
/*
0 commit comments