@@ -2534,7 +2534,8 @@ intel_set_cdclk_pre_plane_update(struct intel_atomic_state *state)
25342534 intel_atomic_get_old_cdclk_state (state );
25352535 const struct intel_cdclk_state * new_cdclk_state =
25362536 intel_atomic_get_new_cdclk_state (state );
2537- enum pipe pipe = new_cdclk_state -> pipe ;
2537+ struct intel_cdclk_config cdclk_config ;
2538+ enum pipe pipe ;
25382539
25392540 if (!intel_cdclk_changed (& old_cdclk_state -> actual ,
25402541 & new_cdclk_state -> actual ))
@@ -2543,12 +2544,25 @@ intel_set_cdclk_pre_plane_update(struct intel_atomic_state *state)
25432544 if (IS_DG2 (i915 ))
25442545 intel_cdclk_pcode_pre_notify (state );
25452546
2546- if (pipe == INVALID_PIPE ||
2547- old_cdclk_state -> actual .cdclk <= new_cdclk_state -> actual .cdclk ) {
2548- drm_WARN_ON (& i915 -> drm , !new_cdclk_state -> base .changed );
2547+ if (new_cdclk_state -> disable_pipes ) {
2548+ cdclk_config = new_cdclk_state -> actual ;
2549+ pipe = INVALID_PIPE ;
2550+ } else {
2551+ if (new_cdclk_state -> actual .cdclk >= old_cdclk_state -> actual .cdclk ) {
2552+ cdclk_config = new_cdclk_state -> actual ;
2553+ pipe = new_cdclk_state -> pipe ;
2554+ } else {
2555+ cdclk_config = old_cdclk_state -> actual ;
2556+ pipe = INVALID_PIPE ;
2557+ }
25492558
2550- intel_set_cdclk (i915 , & new_cdclk_state -> actual , pipe );
2559+ cdclk_config .voltage_level = max (new_cdclk_state -> actual .voltage_level ,
2560+ old_cdclk_state -> actual .voltage_level );
25512561 }
2562+
2563+ drm_WARN_ON (& i915 -> drm , !new_cdclk_state -> base .changed );
2564+
2565+ intel_set_cdclk (i915 , & cdclk_config , pipe );
25522566}
25532567
25542568/**
@@ -2566,7 +2580,7 @@ intel_set_cdclk_post_plane_update(struct intel_atomic_state *state)
25662580 intel_atomic_get_old_cdclk_state (state );
25672581 const struct intel_cdclk_state * new_cdclk_state =
25682582 intel_atomic_get_new_cdclk_state (state );
2569- enum pipe pipe = new_cdclk_state -> pipe ;
2583+ enum pipe pipe ;
25702584
25712585 if (!intel_cdclk_changed (& old_cdclk_state -> actual ,
25722586 & new_cdclk_state -> actual ))
@@ -2575,12 +2589,15 @@ intel_set_cdclk_post_plane_update(struct intel_atomic_state *state)
25752589 if (IS_DG2 (i915 ))
25762590 intel_cdclk_pcode_post_notify (state );
25772591
2578- if (pipe != INVALID_PIPE &&
2579- old_cdclk_state -> actual .cdclk > new_cdclk_state -> actual .cdclk ) {
2580- drm_WARN_ON (& i915 -> drm , !new_cdclk_state -> base .changed );
2592+ if (!new_cdclk_state -> disable_pipes &&
2593+ new_cdclk_state -> actual .cdclk < old_cdclk_state -> actual .cdclk )
2594+ pipe = new_cdclk_state -> pipe ;
2595+ else
2596+ pipe = INVALID_PIPE ;
2597+
2598+ drm_WARN_ON (& i915 -> drm , !new_cdclk_state -> base .changed );
25812599
2582- intel_set_cdclk (i915 , & new_cdclk_state -> actual , pipe );
2583- }
2600+ intel_set_cdclk (i915 , & new_cdclk_state -> actual , pipe );
25842601}
25852602
25862603static int intel_pixel_rate_to_cdclk (const struct intel_crtc_state * crtc_state )
@@ -3058,6 +3075,7 @@ static struct intel_global_state *intel_cdclk_duplicate_state(struct intel_globa
30583075 return NULL ;
30593076
30603077 cdclk_state -> pipe = INVALID_PIPE ;
3078+ cdclk_state -> disable_pipes = false;
30613079
30623080 return & cdclk_state -> base ;
30633081}
@@ -3236,6 +3254,8 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state)
32363254 if (ret )
32373255 return ret ;
32383256
3257+ new_cdclk_state -> disable_pipes = true;
3258+
32393259 drm_dbg_kms (& dev_priv -> drm ,
32403260 "Modeset required for cdclk change\n" );
32413261 }
0 commit comments