@@ -346,7 +346,10 @@ static enum pipe bigjoiner_master_pipe(const struct intel_crtc_state *crtc_state
346346
347347u8 intel_crtc_bigjoiner_slave_pipes (const struct intel_crtc_state * crtc_state )
348348{
349- return crtc_state -> bigjoiner_pipes & ~BIT (bigjoiner_master_pipe (crtc_state ));
349+ if (crtc_state -> bigjoiner_pipes )
350+ return crtc_state -> bigjoiner_pipes & ~BIT (bigjoiner_master_pipe (crtc_state ));
351+ else
352+ return 0 ;
350353}
351354
352355bool intel_crtc_is_bigjoiner_slave (const struct intel_crtc_state * crtc_state )
@@ -1260,10 +1263,8 @@ static void intel_crtc_enable_flip_done(struct intel_atomic_state *state,
12601263 int i ;
12611264
12621265 for_each_new_intel_plane_in_state (state , plane , plane_state , i ) {
1263- if (plane -> enable_flip_done &&
1264- plane -> pipe == crtc -> pipe &&
1265- update_planes & BIT (plane -> id ) &&
1266- plane_state -> do_async_flip )
1266+ if (plane -> pipe == crtc -> pipe &&
1267+ update_planes & BIT (plane -> id ))
12671268 plane -> enable_flip_done (plane );
12681269 }
12691270}
@@ -1279,10 +1280,8 @@ static void intel_crtc_disable_flip_done(struct intel_atomic_state *state,
12791280 int i ;
12801281
12811282 for_each_new_intel_plane_in_state (state , plane , plane_state , i ) {
1282- if (plane -> disable_flip_done &&
1283- plane -> pipe == crtc -> pipe &&
1284- update_planes & BIT (plane -> id ) &&
1285- plane_state -> do_async_flip )
1283+ if (plane -> pipe == crtc -> pipe &&
1284+ update_planes & BIT (plane -> id ))
12861285 plane -> disable_flip_done (plane );
12871286 }
12881287}
@@ -7398,7 +7397,7 @@ static void kill_bigjoiner_slave(struct intel_atomic_state *state,
73987397 * Correspondingly, support is currently added for primary plane only.
73997398 *
74007399 * Async flip can only change the plane surface address, so anything else
7401- * changing is rejected from the intel_atomic_check_async () function.
7400+ * changing is rejected from the intel_async_flip_check_hw () function.
74027401 * Once this check is cleared, flip done interrupt is enabled using
74037402 * the intel_crtc_enable_flip_done() function.
74047403 *
@@ -7408,7 +7407,65 @@ static void kill_bigjoiner_slave(struct intel_atomic_state *state,
74087407 * correspond to the last vblank and have no relation to the actual time when
74097408 * the flip done event was sent.
74107409 */
7411- static int intel_atomic_check_async (struct intel_atomic_state * state , struct intel_crtc * crtc )
7410+ static int intel_async_flip_check_uapi (struct intel_atomic_state * state ,
7411+ struct intel_crtc * crtc )
7412+ {
7413+ struct drm_i915_private * i915 = to_i915 (state -> base .dev );
7414+ const struct intel_crtc_state * new_crtc_state =
7415+ intel_atomic_get_new_crtc_state (state , crtc );
7416+ const struct intel_plane_state * old_plane_state ;
7417+ struct intel_plane_state * new_plane_state ;
7418+ struct intel_plane * plane ;
7419+ int i ;
7420+
7421+ if (!new_crtc_state -> uapi .async_flip )
7422+ return 0 ;
7423+
7424+ if (!new_crtc_state -> uapi .active ) {
7425+ drm_dbg_kms (& i915 -> drm ,
7426+ "[CRTC:%d:%s] not active\n" ,
7427+ crtc -> base .base .id , crtc -> base .name );
7428+ return - EINVAL ;
7429+ }
7430+
7431+ if (intel_crtc_needs_modeset (new_crtc_state )) {
7432+ drm_dbg_kms (& i915 -> drm ,
7433+ "[CRTC:%d:%s] modeset required\n" ,
7434+ crtc -> base .base .id , crtc -> base .name );
7435+ return - EINVAL ;
7436+ }
7437+
7438+ for_each_oldnew_intel_plane_in_state (state , plane , old_plane_state ,
7439+ new_plane_state , i ) {
7440+ if (plane -> pipe != crtc -> pipe )
7441+ continue ;
7442+
7443+ /*
7444+ * TODO: Async flip is only supported through the page flip IOCTL
7445+ * as of now. So support currently added for primary plane only.
7446+ * Support for other planes on platforms on which supports
7447+ * this(vlv/chv and icl+) should be added when async flip is
7448+ * enabled in the atomic IOCTL path.
7449+ */
7450+ if (!plane -> async_flip ) {
7451+ drm_dbg_kms (& i915 -> drm ,
7452+ "[PLANE:%d:%s] async flip not supported\n" ,
7453+ plane -> base .base .id , plane -> base .name );
7454+ return - EINVAL ;
7455+ }
7456+
7457+ if (!old_plane_state -> uapi .fb || !new_plane_state -> uapi .fb ) {
7458+ drm_dbg_kms (& i915 -> drm ,
7459+ "[PLANE:%d:%s] no old or new framebuffer\n" ,
7460+ plane -> base .base .id , plane -> base .name );
7461+ return - EINVAL ;
7462+ }
7463+ }
7464+
7465+ return 0 ;
7466+ }
7467+
7468+ static int intel_async_flip_check_hw (struct intel_atomic_state * state , struct intel_crtc * crtc )
74127469{
74137470 struct drm_i915_private * i915 = to_i915 (state -> base .dev );
74147471 const struct intel_crtc_state * old_crtc_state , * new_crtc_state ;
@@ -7419,6 +7476,9 @@ static int intel_atomic_check_async(struct intel_atomic_state *state, struct int
74197476 old_crtc_state = intel_atomic_get_old_crtc_state (state , crtc );
74207477 new_crtc_state = intel_atomic_get_new_crtc_state (state , crtc );
74217478
7479+ if (!new_crtc_state -> uapi .async_flip )
7480+ return 0 ;
7481+
74227482 if (intel_crtc_needs_modeset (new_crtc_state )) {
74237483 drm_dbg_kms (& i915 -> drm , "Modeset Required. Async flip not supported\n" );
74247484 return - EINVAL ;
@@ -7440,15 +7500,25 @@ static int intel_atomic_check_async(struct intel_atomic_state *state, struct int
74407500 continue ;
74417501
74427502 /*
7443- * TODO: Async flip is only supported through the page flip IOCTL
7444- * as of now. So support currently added for primary plane only.
7445- * Support for other planes on platforms on which supports
7446- * this(vlv/chv and icl+) should be added when async flip is
7447- * enabled in the atomic IOCTL path.
7503+ * Only async flip capable planes should be in the state
7504+ * if we're really about to ask the hardware to perform
7505+ * an async flip. We should never get this far otherwise.
74487506 */
7449- if (!plane -> async_flip )
7507+ if (drm_WARN_ON (& i915 -> drm ,
7508+ new_crtc_state -> do_async_flip && !plane -> async_flip ))
74507509 return - EINVAL ;
74517510
7511+ /*
7512+ * Only check async flip capable planes other planes
7513+ * may be involved in the initial commit due to
7514+ * the wm0/ddb optimization.
7515+ *
7516+ * TODO maybe should track which planes actually
7517+ * were requested to do the async flip...
7518+ */
7519+ if (!plane -> async_flip )
7520+ continue ;
7521+
74527522 /*
74537523 * FIXME: This check is kept generic for all platforms.
74547524 * Need to verify this for all gen9 platforms to enable
@@ -7613,6 +7683,12 @@ static int intel_atomic_check(struct drm_device *dev,
76137683 if (ret )
76147684 goto fail ;
76157685
7686+ for_each_new_intel_crtc_in_state (state , crtc , new_crtc_state , i ) {
7687+ ret = intel_async_flip_check_uapi (state , crtc );
7688+ if (ret )
7689+ return ret ;
7690+ }
7691+
76167692 ret = intel_bigjoiner_add_affected_crtcs (state );
76177693 if (ret )
76187694 goto fail ;
@@ -7769,11 +7845,9 @@ static int intel_atomic_check(struct drm_device *dev,
77697845
77707846 for_each_oldnew_intel_crtc_in_state (state , crtc , old_crtc_state ,
77717847 new_crtc_state , i ) {
7772- if (new_crtc_state -> uapi .async_flip ) {
7773- ret = intel_atomic_check_async (state , crtc );
7774- if (ret )
7775- goto fail ;
7776- }
7848+ ret = intel_async_flip_check_hw (state , crtc );
7849+ if (ret )
7850+ goto fail ;
77777851
77787852 if (!intel_crtc_needs_modeset (new_crtc_state ) &&
77797853 !new_crtc_state -> update_pipe )
@@ -8395,7 +8469,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
83958469 intel_dbuf_pre_plane_update (state );
83968470
83978471 for_each_new_intel_crtc_in_state (state , crtc , new_crtc_state , i ) {
8398- if (new_crtc_state -> uapi . async_flip )
8472+ if (new_crtc_state -> do_async_flip )
83998473 intel_crtc_enable_flip_done (state , crtc );
84008474 }
84018475
@@ -8421,7 +8495,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
84218495 drm_atomic_helper_wait_for_flip_done (dev , & state -> base );
84228496
84238497 for_each_new_intel_crtc_in_state (state , crtc , new_crtc_state , i ) {
8424- if (new_crtc_state -> uapi . async_flip )
8498+ if (new_crtc_state -> do_async_flip )
84258499 intel_crtc_disable_flip_done (state , crtc );
84268500 }
84278501
0 commit comments