@@ -2165,7 +2165,8 @@ static void intel_disable_primary_hw_plane(struct drm_plane *plane,
2165
2165
struct drm_i915_private * dev_priv = dev -> dev_private ;
2166
2166
struct intel_crtc * intel_crtc = to_intel_crtc (crtc );
2167
2167
2168
- assert_pipe_enabled (dev_priv , intel_crtc -> pipe );
2168
+ if (WARN_ON (!intel_crtc -> active ))
2169
+ return ;
2169
2170
2170
2171
if (!intel_crtc -> primary_enabled )
2171
2172
return ;
@@ -11737,7 +11738,11 @@ static int
11737
11738
intel_check_primary_plane (struct drm_plane * plane ,
11738
11739
struct intel_plane_state * state )
11739
11740
{
11741
+ struct drm_device * dev = plane -> dev ;
11742
+ struct drm_i915_private * dev_priv = dev -> dev_private ;
11740
11743
struct drm_crtc * crtc = state -> base .crtc ;
11744
+ struct intel_crtc * intel_crtc = to_intel_crtc (crtc );
11745
+ struct intel_plane * intel_plane = to_intel_plane (plane );
11741
11746
struct drm_framebuffer * fb = state -> base .fb ;
11742
11747
struct drm_rect * dest = & state -> dst ;
11743
11748
struct drm_rect * src = & state -> src ;
@@ -11752,10 +11757,40 @@ intel_check_primary_plane(struct drm_plane *plane,
11752
11757
if (ret )
11753
11758
return ret ;
11754
11759
11755
- intel_crtc_wait_for_pending_flips (crtc );
11756
- if (intel_crtc_has_pending_flip (crtc )) {
11757
- DRM_ERROR ("pipe is still busy with an old pageflip\n" );
11758
- return - EBUSY ;
11760
+ if (intel_crtc -> active ) {
11761
+ intel_crtc -> atomic .wait_for_flips = true;
11762
+
11763
+ /*
11764
+ * FBC does not work on some platforms for rotated
11765
+ * planes, so disable it when rotation is not 0 and
11766
+ * update it when rotation is set back to 0.
11767
+ *
11768
+ * FIXME: This is redundant with the fbc update done in
11769
+ * the primary plane enable function except that that
11770
+ * one is done too late. We eventually need to unify
11771
+ * this.
11772
+ */
11773
+ if (intel_crtc -> primary_enabled &&
11774
+ INTEL_INFO (dev )-> gen <= 4 && !IS_G4X (dev ) &&
11775
+ dev_priv -> fbc .plane == intel_crtc -> plane &&
11776
+ intel_plane -> rotation != BIT (DRM_ROTATE_0 )) {
11777
+ intel_crtc -> atomic .disable_fbc = true;
11778
+ }
11779
+
11780
+ if (state -> visible ) {
11781
+ /*
11782
+ * BDW signals flip done immediately if the plane
11783
+ * is disabled, even if the plane enable is already
11784
+ * armed to occur at the next vblank :(
11785
+ */
11786
+ if (IS_BROADWELL (dev ) && !intel_crtc -> primary_enabled )
11787
+ intel_crtc -> atomic .wait_vblank = true;
11788
+ }
11789
+
11790
+ intel_crtc -> atomic .fb_bits |=
11791
+ INTEL_FRONTBUFFER_PRIMARY (intel_crtc -> pipe );
11792
+
11793
+ intel_crtc -> atomic .update_fbc = true;
11759
11794
}
11760
11795
11761
11796
return 0 ;
@@ -11773,18 +11808,6 @@ intel_commit_primary_plane(struct drm_plane *plane,
11773
11808
struct drm_i915_gem_object * obj = intel_fb_obj (fb );
11774
11809
struct intel_plane * intel_plane = to_intel_plane (plane );
11775
11810
struct drm_rect * src = & state -> src ;
11776
- enum pipe pipe = intel_plane -> pipe ;
11777
-
11778
- if (!fb ) {
11779
- /*
11780
- * 'prepare' is never called when plane is being disabled, so
11781
- * we need to handle frontbuffer tracking here
11782
- */
11783
- mutex_lock (& dev -> struct_mutex );
11784
- i915_gem_track_fb (intel_fb_obj (plane -> fb ), NULL ,
11785
- INTEL_FRONTBUFFER_PRIMARY (pipe ));
11786
- mutex_unlock (& dev -> struct_mutex );
11787
- }
11788
11811
11789
11812
plane -> fb = fb ;
11790
11813
crtc -> x = src -> x1 >> 16 ;
@@ -11801,41 +11824,14 @@ intel_commit_primary_plane(struct drm_plane *plane,
11801
11824
intel_plane -> obj = obj ;
11802
11825
11803
11826
if (intel_crtc -> active ) {
11804
- /*
11805
- * FBC does not work on some platforms for rotated
11806
- * planes, so disable it when rotation is not 0 and
11807
- * update it when rotation is set back to 0.
11808
- *
11809
- * FIXME: This is redundant with the fbc update done in
11810
- * the primary plane enable function except that that
11811
- * one is done too late. We eventually need to unify
11812
- * this.
11813
- */
11814
- if (intel_crtc -> primary_enabled &&
11815
- INTEL_INFO (dev )-> gen <= 4 && !IS_G4X (dev ) &&
11816
- dev_priv -> fbc .plane == intel_crtc -> plane &&
11817
- intel_plane -> rotation != BIT (DRM_ROTATE_0 )) {
11818
- intel_fbc_disable (dev );
11819
- }
11820
-
11821
11827
if (state -> visible ) {
11822
- bool was_enabled = intel_crtc -> primary_enabled ;
11823
-
11824
11828
/* FIXME: kill this fastboot hack */
11825
11829
intel_update_pipe_size (intel_crtc );
11826
11830
11827
11831
intel_crtc -> primary_enabled = true;
11828
11832
11829
11833
dev_priv -> display .update_primary_plane (crtc , plane -> fb ,
11830
11834
crtc -> x , crtc -> y );
11831
-
11832
- /*
11833
- * BDW signals flip done immediately if the plane
11834
- * is disabled, even if the plane enable is already
11835
- * armed to occur at the next vblank :(
11836
- */
11837
- if (IS_BROADWELL (dev ) && !was_enabled )
11838
- intel_wait_for_vblank (dev , intel_crtc -> pipe );
11839
11835
} else {
11840
11836
/*
11841
11837
* If clipping results in a non-visible primary plane,
@@ -11846,13 +11842,59 @@ intel_commit_primary_plane(struct drm_plane *plane,
11846
11842
*/
11847
11843
intel_disable_primary_hw_plane (plane , crtc );
11848
11844
}
11845
+ }
11846
+ }
11847
+
11848
+ static void intel_begin_crtc_commit (struct drm_crtc * crtc )
11849
+ {
11850
+ struct drm_device * dev = crtc -> dev ;
11851
+ struct drm_i915_private * dev_priv = dev -> dev_private ;
11852
+ struct intel_crtc * intel_crtc = to_intel_crtc (crtc );
11849
11853
11850
- intel_frontbuffer_flip (dev , INTEL_FRONTBUFFER_PRIMARY (pipe ));
11854
+ if (intel_crtc -> atomic .wait_for_flips )
11855
+ intel_crtc_wait_for_pending_flips (crtc );
11851
11856
11857
+ if (intel_crtc -> atomic .disable_fbc )
11858
+ intel_fbc_disable (dev );
11859
+
11860
+ if (intel_crtc -> atomic .pre_disable_primary )
11861
+ intel_pre_disable_primary (crtc );
11862
+
11863
+ if (intel_crtc -> atomic .update_wm )
11864
+ intel_update_watermarks (crtc );
11865
+
11866
+ intel_runtime_pm_get (dev_priv );
11867
+ }
11868
+
11869
+ static void intel_finish_crtc_commit (struct drm_crtc * crtc )
11870
+ {
11871
+ struct drm_device * dev = crtc -> dev ;
11872
+ struct drm_i915_private * dev_priv = dev -> dev_private ;
11873
+ struct intel_crtc * intel_crtc = to_intel_crtc (crtc );
11874
+ struct drm_plane * p ;
11875
+
11876
+ intel_runtime_pm_put (dev_priv );
11877
+
11878
+ if (intel_crtc -> atomic .wait_vblank )
11879
+ intel_wait_for_vblank (dev , intel_crtc -> pipe );
11880
+
11881
+ intel_frontbuffer_flip (dev , intel_crtc -> atomic .fb_bits );
11882
+
11883
+ if (intel_crtc -> atomic .update_fbc ) {
11852
11884
mutex_lock (& dev -> struct_mutex );
11853
11885
intel_fbc_update (dev );
11854
11886
mutex_unlock (& dev -> struct_mutex );
11855
11887
}
11888
+
11889
+ if (intel_crtc -> atomic .post_enable_primary )
11890
+ intel_post_enable_primary (crtc );
11891
+
11892
+ drm_for_each_legacy_plane (p , & dev -> mode_config .plane_list )
11893
+ if (intel_crtc -> atomic .update_sprite_watermarks & drm_plane_index (p ))
11894
+ intel_update_sprite_watermarks (p , crtc , 0 , 0 , 0 ,
11895
+ false, false);
11896
+
11897
+ memset (& intel_crtc -> atomic , 0 , sizeof (intel_crtc -> atomic ));
11856
11898
}
11857
11899
11858
11900
int
@@ -11863,9 +11905,8 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
11863
11905
uint32_t src_w , uint32_t src_h )
11864
11906
{
11865
11907
struct drm_device * dev = plane -> dev ;
11866
- struct drm_i915_private * dev_priv = dev -> dev_private ;
11867
11908
struct drm_framebuffer * old_fb = plane -> fb ;
11868
- struct intel_plane_state state ;
11909
+ struct intel_plane_state state = {{ 0 }} ;
11869
11910
struct intel_plane * intel_plane = to_intel_plane (plane );
11870
11911
struct intel_crtc * intel_crtc = to_intel_crtc (crtc );
11871
11912
int ret ;
@@ -11903,9 +11944,33 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
11903
11944
return ret ;
11904
11945
}
11905
11946
11906
- intel_runtime_pm_get (dev_priv );
11947
+ if (!state .base .fb ) {
11948
+ unsigned fb_bits = 0 ;
11949
+
11950
+ switch (plane -> type ) {
11951
+ case DRM_PLANE_TYPE_PRIMARY :
11952
+ fb_bits = INTEL_FRONTBUFFER_PRIMARY (intel_plane -> pipe );
11953
+ break ;
11954
+ case DRM_PLANE_TYPE_CURSOR :
11955
+ fb_bits = INTEL_FRONTBUFFER_CURSOR (intel_plane -> pipe );
11956
+ break ;
11957
+ case DRM_PLANE_TYPE_OVERLAY :
11958
+ fb_bits = INTEL_FRONTBUFFER_SPRITE (intel_plane -> pipe );
11959
+ break ;
11960
+ }
11961
+
11962
+ /*
11963
+ * 'prepare' is never called when plane is being disabled, so
11964
+ * we need to handle frontbuffer tracking here
11965
+ */
11966
+ mutex_lock (& dev -> struct_mutex );
11967
+ i915_gem_track_fb (intel_fb_obj (plane -> fb ), NULL , fb_bits );
11968
+ mutex_unlock (& dev -> struct_mutex );
11969
+ }
11970
+
11971
+ intel_begin_crtc_commit (crtc );
11907
11972
intel_plane -> commit_plane (plane , & state );
11908
- intel_runtime_pm_put ( dev_priv );
11973
+ intel_finish_crtc_commit ( crtc );
11909
11974
11910
11975
if (fb != old_fb && old_fb ) {
11911
11976
if (intel_crtc -> active )
@@ -12012,6 +12077,7 @@ intel_check_cursor_plane(struct drm_plane *plane,
12012
12077
struct drm_rect * src = & state -> src ;
12013
12078
const struct drm_rect * clip = & state -> clip ;
12014
12079
struct drm_i915_gem_object * obj = intel_fb_obj (fb );
12080
+ struct intel_crtc * intel_crtc = to_intel_crtc (crtc );
12015
12081
int crtc_w , crtc_h ;
12016
12082
unsigned stride ;
12017
12083
int ret ;
@@ -12027,7 +12093,7 @@ intel_check_cursor_plane(struct drm_plane *plane,
12027
12093
12028
12094
/* if we want to turn off the cursor ignore width and height */
12029
12095
if (!obj )
12030
- return 0 ;
12096
+ goto finish ;
12031
12097
12032
12098
/* Check for which cursor types we support */
12033
12099
crtc_w = drm_rect_width (& state -> orig_dst );
@@ -12054,6 +12120,16 @@ intel_check_cursor_plane(struct drm_plane *plane,
12054
12120
}
12055
12121
mutex_unlock (& dev -> struct_mutex );
12056
12122
12123
+ finish :
12124
+ if (intel_crtc -> active ) {
12125
+ if (intel_crtc -> cursor_width !=
12126
+ drm_rect_width (& state -> orig_dst ))
12127
+ intel_crtc -> atomic .update_wm = true;
12128
+
12129
+ intel_crtc -> atomic .fb_bits |=
12130
+ INTEL_FRONTBUFFER_CURSOR (intel_crtc -> pipe );
12131
+ }
12132
+
12057
12133
return ret ;
12058
12134
}
12059
12135
@@ -12066,9 +12142,6 @@ intel_commit_cursor_plane(struct drm_plane *plane,
12066
12142
struct intel_crtc * intel_crtc = to_intel_crtc (crtc );
12067
12143
struct intel_plane * intel_plane = to_intel_plane (plane );
12068
12144
struct drm_i915_gem_object * obj = intel_fb_obj (state -> base .fb );
12069
- struct drm_i915_gem_object * old_obj = intel_fb_obj (plane -> fb );
12070
- enum pipe pipe = intel_crtc -> pipe ;
12071
- unsigned old_width ;
12072
12145
uint32_t addr ;
12073
12146
12074
12147
plane -> fb = state -> base .fb ;
@@ -12088,17 +12161,6 @@ intel_commit_cursor_plane(struct drm_plane *plane,
12088
12161
if (intel_crtc -> cursor_bo == obj )
12089
12162
goto update ;
12090
12163
12091
- /*
12092
- * 'prepare' is only called when fb != NULL; we still need to update
12093
- * frontbuffer tracking for the 'disable' case here.
12094
- */
12095
- if (!obj ) {
12096
- mutex_lock (& dev -> struct_mutex );
12097
- i915_gem_track_fb (old_obj , NULL ,
12098
- INTEL_FRONTBUFFER_CURSOR (pipe ));
12099
- mutex_unlock (& dev -> struct_mutex );
12100
- }
12101
-
12102
12164
if (!obj )
12103
12165
addr = 0 ;
12104
12166
else if (!INTEL_INFO (dev )-> cursor_needs_physical )
@@ -12109,18 +12171,11 @@ intel_commit_cursor_plane(struct drm_plane *plane,
12109
12171
intel_crtc -> cursor_addr = addr ;
12110
12172
intel_crtc -> cursor_bo = obj ;
12111
12173
update :
12112
- old_width = intel_crtc -> cursor_width ;
12113
-
12114
12174
intel_crtc -> cursor_width = drm_rect_width (& state -> orig_dst );
12115
12175
intel_crtc -> cursor_height = drm_rect_height (& state -> orig_dst );
12116
12176
12117
- if (intel_crtc -> active ) {
12118
- if (old_width != intel_crtc -> cursor_width )
12119
- intel_update_watermarks (crtc );
12177
+ if (intel_crtc -> active )
12120
12178
intel_crtc_update_cursor (crtc , state -> visible );
12121
-
12122
- intel_frontbuffer_flip (dev , INTEL_FRONTBUFFER_CURSOR (pipe ));
12123
- }
12124
12179
}
12125
12180
12126
12181
static const struct drm_plane_funcs intel_cursor_plane_funcs = {
0 commit comments