@@ -7070,7 +7070,7 @@ static void commit_pipe_pre_planes(struct intel_atomic_state *state,
7070
7070
* During modesets pipe configuration was programmed as the
7071
7071
* CRTC was enabled.
7072
7072
*/
7073
- if (!modeset ) {
7073
+ if (!modeset && ! new_crtc_state -> use_dsb ) {
7074
7074
if (intel_crtc_needs_color_update (new_crtc_state ))
7075
7075
intel_color_commit_arm (NULL , new_crtc_state );
7076
7076
@@ -7172,10 +7172,12 @@ static void intel_pre_update_crtc(struct intel_atomic_state *state,
7172
7172
drm_WARN_ON (& i915 -> drm , !intel_display_power_is_enabled (i915 , POWER_DOMAIN_DC_OFF ));
7173
7173
7174
7174
if (!modeset &&
7175
- intel_crtc_needs_color_update (new_crtc_state ))
7175
+ intel_crtc_needs_color_update (new_crtc_state ) &&
7176
+ !new_crtc_state -> use_dsb )
7176
7177
intel_color_commit_noarm (NULL , new_crtc_state );
7177
7178
7178
- intel_crtc_planes_update_noarm (NULL , state , crtc );
7179
+ if (!new_crtc_state -> use_dsb )
7180
+ intel_crtc_planes_update_noarm (NULL , state , crtc );
7179
7181
}
7180
7182
7181
7183
static void intel_update_crtc (struct intel_atomic_state * state ,
@@ -7186,16 +7188,25 @@ static void intel_update_crtc(struct intel_atomic_state *state,
7186
7188
struct intel_crtc_state * new_crtc_state =
7187
7189
intel_atomic_get_new_crtc_state (state , crtc );
7188
7190
7189
- /* Perform vblank evasion around commit operation */
7190
- intel_pipe_update_start (state , crtc );
7191
+ if (new_crtc_state -> use_dsb ) {
7192
+ intel_crtc_prepare_vblank_event (new_crtc_state , & crtc -> dsb_event );
7193
+
7194
+ intel_dsb_commit (new_crtc_state -> dsb_commit , false);
7195
+ } else {
7196
+ /* Perform vblank evasion around commit operation */
7197
+ intel_pipe_update_start (state , crtc );
7198
+
7199
+ if (new_crtc_state -> dsb_commit )
7200
+ intel_dsb_commit (new_crtc_state -> dsb_commit , false);
7191
7201
7192
- commit_pipe_pre_planes (state , crtc );
7202
+ commit_pipe_pre_planes (state , crtc );
7193
7203
7194
- intel_crtc_planes_update_arm (NULL , state , crtc );
7204
+ intel_crtc_planes_update_arm (NULL , state , crtc );
7195
7205
7196
- commit_pipe_post_planes (state , crtc );
7206
+ commit_pipe_post_planes (state , crtc );
7197
7207
7198
- intel_pipe_update_end (state , crtc );
7208
+ intel_pipe_update_end (state , crtc );
7209
+ }
7199
7210
7200
7211
/*
7201
7212
* VRR/Seamless M/N update may need to update frame timings.
@@ -7520,6 +7531,24 @@ static void intel_atomic_commit_fence_wait(struct intel_atomic_state *intel_stat
7520
7531
}
7521
7532
}
7522
7533
7534
+ static void intel_atomic_dsb_wait_commit (struct intel_crtc_state * crtc_state )
7535
+ {
7536
+ if (crtc_state -> dsb_commit )
7537
+ intel_dsb_wait (crtc_state -> dsb_commit );
7538
+
7539
+ intel_color_wait_commit (crtc_state );
7540
+ }
7541
+
7542
+ static void intel_atomic_dsb_cleanup (struct intel_crtc_state * crtc_state )
7543
+ {
7544
+ if (crtc_state -> dsb_commit ) {
7545
+ intel_dsb_cleanup (crtc_state -> dsb_commit );
7546
+ crtc_state -> dsb_commit = NULL ;
7547
+ }
7548
+
7549
+ intel_color_cleanup_commit (crtc_state );
7550
+ }
7551
+
7523
7552
static void intel_atomic_cleanup_work (struct work_struct * work )
7524
7553
{
7525
7554
struct intel_atomic_state * state =
@@ -7530,7 +7559,7 @@ static void intel_atomic_cleanup_work(struct work_struct *work)
7530
7559
int i ;
7531
7560
7532
7561
for_each_old_intel_crtc_in_state (state , crtc , old_crtc_state , i )
7533
- intel_color_cleanup_commit (old_crtc_state );
7562
+ intel_atomic_dsb_cleanup (old_crtc_state );
7534
7563
7535
7564
drm_atomic_helper_cleanup_planes (& i915 -> drm , & state -> base );
7536
7565
drm_atomic_helper_commit_cleanup_done (& state -> base );
@@ -7586,6 +7615,78 @@ static void intel_atomic_dsb_prepare(struct intel_atomic_state *state,
7586
7615
intel_color_prepare_commit (state , crtc );
7587
7616
}
7588
7617
7618
+ static void intel_atomic_dsb_finish (struct intel_atomic_state * state ,
7619
+ struct intel_crtc * crtc )
7620
+ {
7621
+ const struct intel_crtc_state * old_crtc_state =
7622
+ intel_atomic_get_old_crtc_state (state , crtc );
7623
+ struct intel_crtc_state * new_crtc_state =
7624
+ intel_atomic_get_new_crtc_state (state , crtc );
7625
+
7626
+ if (!new_crtc_state -> hw .active )
7627
+ return ;
7628
+
7629
+ if (state -> base .legacy_cursor_update )
7630
+ return ;
7631
+
7632
+ /* FIXME deal with everything */
7633
+ new_crtc_state -> use_dsb =
7634
+ new_crtc_state -> update_planes &&
7635
+ !new_crtc_state -> vrr .enable &&
7636
+ !new_crtc_state -> do_async_flip &&
7637
+ !new_crtc_state -> has_psr &&
7638
+ !new_crtc_state -> scaler_state .scaler_users &&
7639
+ !old_crtc_state -> scaler_state .scaler_users &&
7640
+ !intel_crtc_needs_modeset (new_crtc_state ) &&
7641
+ !intel_crtc_needs_fastset (new_crtc_state );
7642
+
7643
+ if (!new_crtc_state -> use_dsb && !new_crtc_state -> dsb_color_vblank )
7644
+ return ;
7645
+
7646
+ /*
7647
+ * Rough estimate:
7648
+ * ~64 registers per each plane * 8 planes = 512
7649
+ * Double that for pipe stuff and other overhead.
7650
+ */
7651
+ new_crtc_state -> dsb_commit = intel_dsb_prepare (state , crtc , INTEL_DSB_0 ,
7652
+ new_crtc_state -> use_dsb ? 1024 : 16 );
7653
+ if (!new_crtc_state -> dsb_commit ) {
7654
+ new_crtc_state -> use_dsb = false;
7655
+ intel_color_cleanup_commit (new_crtc_state );
7656
+ return ;
7657
+ }
7658
+
7659
+ if (new_crtc_state -> use_dsb ) {
7660
+ if (intel_crtc_needs_color_update (new_crtc_state ))
7661
+ intel_color_commit_noarm (new_crtc_state -> dsb_commit ,
7662
+ new_crtc_state );
7663
+ intel_crtc_planes_update_noarm (new_crtc_state -> dsb_commit ,
7664
+ state , crtc );
7665
+
7666
+ intel_dsb_vblank_evade (state , new_crtc_state -> dsb_commit );
7667
+
7668
+ if (intel_crtc_needs_color_update (new_crtc_state ))
7669
+ intel_color_commit_arm (new_crtc_state -> dsb_commit ,
7670
+ new_crtc_state );
7671
+ bdw_set_pipe_misc (new_crtc_state -> dsb_commit ,
7672
+ new_crtc_state );
7673
+ intel_crtc_planes_update_arm (new_crtc_state -> dsb_commit ,
7674
+ state , crtc );
7675
+
7676
+ if (!new_crtc_state -> dsb_color_vblank ) {
7677
+ intel_dsb_wait_vblanks (new_crtc_state -> dsb_commit , 1 );
7678
+ intel_dsb_wait_vblank_delay (state , new_crtc_state -> dsb_commit );
7679
+ intel_dsb_interrupt (new_crtc_state -> dsb_commit );
7680
+ }
7681
+ }
7682
+
7683
+ if (new_crtc_state -> dsb_color_vblank )
7684
+ intel_dsb_chain (state , new_crtc_state -> dsb_commit ,
7685
+ new_crtc_state -> dsb_color_vblank , true);
7686
+
7687
+ intel_dsb_finish (new_crtc_state -> dsb_commit );
7688
+ }
7689
+
7589
7690
static void intel_atomic_commit_tail (struct intel_atomic_state * state )
7590
7691
{
7591
7692
struct drm_device * dev = state -> base .dev ;
@@ -7605,6 +7706,9 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
7605
7706
7606
7707
intel_atomic_prepare_plane_clear_colors (state );
7607
7708
7709
+ for_each_new_intel_crtc_in_state (state , crtc , new_crtc_state , i )
7710
+ intel_atomic_dsb_finish (state , crtc );
7711
+
7608
7712
drm_atomic_helper_wait_for_dependencies (& state -> base );
7609
7713
drm_dp_mst_atomic_wait_for_dependencies (& state -> base );
7610
7714
intel_atomic_global_state_wait_for_dependencies (state );
@@ -7718,7 +7822,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
7718
7822
if (new_crtc_state -> do_async_flip )
7719
7823
intel_crtc_disable_flip_done (state , crtc );
7720
7824
7721
- intel_color_wait_commit (new_crtc_state );
7825
+ intel_atomic_dsb_wait_commit (new_crtc_state );
7722
7826
}
7723
7827
7724
7828
/*
@@ -7763,7 +7867,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
7763
7867
* FIXME get rid of this funny new->old swapping
7764
7868
*/
7765
7869
old_crtc_state -> dsb_color_vblank = fetch_and_zero (& new_crtc_state -> dsb_color_vblank );
7766
- old_crtc_state -> dsb_color_commit = fetch_and_zero (& new_crtc_state -> dsb_color_commit );
7870
+ old_crtc_state -> dsb_commit = fetch_and_zero (& new_crtc_state -> dsb_commit );
7767
7871
}
7768
7872
7769
7873
/* Underruns don't always raise interrupts, so check manually */
0 commit comments