@@ -7070,7 +7070,7 @@ static void commit_pipe_pre_planes(struct intel_atomic_state *state,
70707070 * During modesets pipe configuration was programmed as the
70717071 * CRTC was enabled.
70727072 */
7073- if (!modeset ) {
7073+ if (!modeset && ! new_crtc_state -> use_dsb ) {
70747074 if (intel_crtc_needs_color_update (new_crtc_state ))
70757075 intel_color_commit_arm (NULL , new_crtc_state );
70767076
@@ -7172,10 +7172,12 @@ static void intel_pre_update_crtc(struct intel_atomic_state *state,
71727172 drm_WARN_ON (& i915 -> drm , !intel_display_power_is_enabled (i915 , POWER_DOMAIN_DC_OFF ));
71737173
71747174 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 )
71767177 intel_color_commit_noarm (NULL , new_crtc_state );
71777178
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 );
71797181}
71807182
71817183static void intel_update_crtc (struct intel_atomic_state * state ,
@@ -7186,16 +7188,25 @@ static void intel_update_crtc(struct intel_atomic_state *state,
71867188 struct intel_crtc_state * new_crtc_state =
71877189 intel_atomic_get_new_crtc_state (state , crtc );
71887190
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);
71917201
7192- commit_pipe_pre_planes (state , crtc );
7202+ commit_pipe_pre_planes (state , crtc );
71937203
7194- intel_crtc_planes_update_arm (NULL , state , crtc );
7204+ intel_crtc_planes_update_arm (NULL , state , crtc );
71957205
7196- commit_pipe_post_planes (state , crtc );
7206+ commit_pipe_post_planes (state , crtc );
71977207
7198- intel_pipe_update_end (state , crtc );
7208+ intel_pipe_update_end (state , crtc );
7209+ }
71997210
72007211 /*
72017212 * 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
75207531 }
75217532}
75227533
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+
75237552static void intel_atomic_cleanup_work (struct work_struct * work )
75247553{
75257554 struct intel_atomic_state * state =
@@ -7530,7 +7559,7 @@ static void intel_atomic_cleanup_work(struct work_struct *work)
75307559 int i ;
75317560
75327561 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 );
75347563
75357564 drm_atomic_helper_cleanup_planes (& i915 -> drm , & state -> base );
75367565 drm_atomic_helper_commit_cleanup_done (& state -> base );
@@ -7586,6 +7615,78 @@ static void intel_atomic_dsb_prepare(struct intel_atomic_state *state,
75867615 intel_color_prepare_commit (state , crtc );
75877616}
75887617
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+
75897690static void intel_atomic_commit_tail (struct intel_atomic_state * state )
75907691{
75917692 struct drm_device * dev = state -> base .dev ;
@@ -7605,6 +7706,9 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
76057706
76067707 intel_atomic_prepare_plane_clear_colors (state );
76077708
7709+ for_each_new_intel_crtc_in_state (state , crtc , new_crtc_state , i )
7710+ intel_atomic_dsb_finish (state , crtc );
7711+
76087712 drm_atomic_helper_wait_for_dependencies (& state -> base );
76097713 drm_dp_mst_atomic_wait_for_dependencies (& state -> base );
76107714 intel_atomic_global_state_wait_for_dependencies (state );
@@ -7718,7 +7822,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
77187822 if (new_crtc_state -> do_async_flip )
77197823 intel_crtc_disable_flip_done (state , crtc );
77207824
7721- intel_color_wait_commit (new_crtc_state );
7825+ intel_atomic_dsb_wait_commit (new_crtc_state );
77227826 }
77237827
77247828 /*
@@ -7763,7 +7867,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
77637867 * FIXME get rid of this funny new->old swapping
77647868 */
77657869 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 );
77677871 }
77687872
77697873 /* Underruns don't always raise interrupts, so check manually */
0 commit comments