@@ -346,7 +346,10 @@ static enum pipe bigjoiner_master_pipe(const struct intel_crtc_state *crtc_state
346
346
347
347
u8 intel_crtc_bigjoiner_slave_pipes (const struct intel_crtc_state * crtc_state )
348
348
{
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 ;
350
353
}
351
354
352
355
bool 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,
1260
1263
int i ;
1261
1264
1262
1265
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 ))
1267
1268
plane -> enable_flip_done (plane );
1268
1269
}
1269
1270
}
@@ -1279,10 +1280,8 @@ static void intel_crtc_disable_flip_done(struct intel_atomic_state *state,
1279
1280
int i ;
1280
1281
1281
1282
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 ))
1286
1285
plane -> disable_flip_done (plane );
1287
1286
}
1288
1287
}
@@ -7398,7 +7397,7 @@ static void kill_bigjoiner_slave(struct intel_atomic_state *state,
7398
7397
* Correspondingly, support is currently added for primary plane only.
7399
7398
*
7400
7399
* 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.
7402
7401
* Once this check is cleared, flip done interrupt is enabled using
7403
7402
* the intel_crtc_enable_flip_done() function.
7404
7403
*
@@ -7408,7 +7407,65 @@ static void kill_bigjoiner_slave(struct intel_atomic_state *state,
7408
7407
* correspond to the last vblank and have no relation to the actual time when
7409
7408
* the flip done event was sent.
7410
7409
*/
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 )
7412
7469
{
7413
7470
struct drm_i915_private * i915 = to_i915 (state -> base .dev );
7414
7471
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
7419
7476
old_crtc_state = intel_atomic_get_old_crtc_state (state , crtc );
7420
7477
new_crtc_state = intel_atomic_get_new_crtc_state (state , crtc );
7421
7478
7479
+ if (!new_crtc_state -> uapi .async_flip )
7480
+ return 0 ;
7481
+
7422
7482
if (intel_crtc_needs_modeset (new_crtc_state )) {
7423
7483
drm_dbg_kms (& i915 -> drm , "Modeset Required. Async flip not supported\n" );
7424
7484
return - EINVAL ;
@@ -7440,15 +7500,25 @@ static int intel_atomic_check_async(struct intel_atomic_state *state, struct int
7440
7500
continue ;
7441
7501
7442
7502
/*
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.
7448
7506
*/
7449
- if (!plane -> async_flip )
7507
+ if (drm_WARN_ON (& i915 -> drm ,
7508
+ new_crtc_state -> do_async_flip && !plane -> async_flip ))
7450
7509
return - EINVAL ;
7451
7510
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
+
7452
7522
/*
7453
7523
* FIXME: This check is kept generic for all platforms.
7454
7524
* Need to verify this for all gen9 platforms to enable
@@ -7613,6 +7683,12 @@ static int intel_atomic_check(struct drm_device *dev,
7613
7683
if (ret )
7614
7684
goto fail ;
7615
7685
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
+
7616
7692
ret = intel_bigjoiner_add_affected_crtcs (state );
7617
7693
if (ret )
7618
7694
goto fail ;
@@ -7769,11 +7845,9 @@ static int intel_atomic_check(struct drm_device *dev,
7769
7845
7770
7846
for_each_oldnew_intel_crtc_in_state (state , crtc , old_crtc_state ,
7771
7847
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 ;
7777
7851
7778
7852
if (!intel_crtc_needs_modeset (new_crtc_state ) &&
7779
7853
!new_crtc_state -> update_pipe )
@@ -8395,7 +8469,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
8395
8469
intel_dbuf_pre_plane_update (state );
8396
8470
8397
8471
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 )
8399
8473
intel_crtc_enable_flip_done (state , crtc );
8400
8474
}
8401
8475
@@ -8421,7 +8495,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
8421
8495
drm_atomic_helper_wait_for_flip_done (dev , & state -> base );
8422
8496
8423
8497
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 )
8425
8499
intel_crtc_disable_flip_done (state , crtc );
8426
8500
}
8427
8501
0 commit comments