From: Ville Syrjälä <[email protected]>

Currently we compute the min_cdclk for each pipe during
intel_cdclk_atomic_check(). But that is too late for the
pipe prefill vs. vblank length checks (done during
intel_compute_global_watermarks).

We can't just reorder these things due to other dependencies,
so instead pull only the per-crtc minimum cdclk calculation
ahead. We should have enough information for that as soon
as we've computed the min cdclk for the planes.

Signed-off-by: Ville Syrjälä <[email protected]>
---
 drivers/gpu/drm/i915/display/intel_cdclk.c         | 8 ++++----
 drivers/gpu/drm/i915/display/intel_cdclk.h         | 2 ++
 drivers/gpu/drm/i915/display/intel_display.c       | 3 +++
 drivers/gpu/drm/i915/display/intel_display_types.h | 2 ++
 drivers/gpu/drm/i915/display/intel_modeset_setup.c | 5 +++++
 5 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c 
b/drivers/gpu/drm/i915/display/intel_cdclk.c
index ed64fac7897d..af918e0e72ef 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -2829,7 +2829,7 @@ static int intel_planes_min_cdclk(const struct 
intel_crtc_state *crtc_state)
        return min_cdclk;
 }
 
-static int intel_crtc_compute_min_cdclk(const struct intel_crtc_state 
*crtc_state)
+int intel_crtc_min_cdclk(const struct intel_crtc_state *crtc_state)
 {
        int min_cdclk;
 
@@ -3302,8 +3302,8 @@ static int intel_crtcs_calc_min_cdclk(struct 
intel_atomic_state *state,
        for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
                                            new_crtc_state, i) {
                ret = intel_cdclk_update_crtc_min_cdclk(state, crtc,
-                                                       
intel_crtc_compute_min_cdclk(old_crtc_state),
-                                                       
intel_crtc_compute_min_cdclk(new_crtc_state),
+                                                       
old_crtc_state->min_cdclk,
+                                                       
new_crtc_state->min_cdclk,
                                                        need_cdclk_calc);
                if (ret)
                        return ret;
@@ -3523,7 +3523,7 @@ void intel_cdclk_update_hw_state(struct intel_display 
*display)
                if (crtc_state->hw.active)
                        cdclk_state->active_pipes |= BIT(pipe);
 
-               cdclk_state->min_cdclk[pipe] = 
intel_crtc_compute_min_cdclk(crtc_state);
+               cdclk_state->min_cdclk[pipe] = crtc_state->min_cdclk;
                cdclk_state->min_voltage_level[pipe] = 
crtc_state->min_voltage_level;
        }
 
diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.h 
b/drivers/gpu/drm/i915/display/intel_cdclk.h
index d9d7a8b3a48a..bad2da8d45d2 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.h
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.h
@@ -69,4 +69,6 @@ bool intel_cdclk_pmdemand_needs_update(struct 
intel_atomic_state *state);
 void intel_cdclk_force_min_cdclk(struct intel_cdclk_state *cdclk_state, int 
force_min_cdclk);
 void intel_cdclk_read_hw(struct intel_display *display);
 
+int intel_crtc_min_cdclk(const struct intel_crtc_state *crtc_state);
+
 #endif /* __INTEL_CDCLK_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index d5b2612d4ec2..539017018884 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -6443,6 +6443,9 @@ int intel_atomic_check(struct drm_device *dev,
        if (ret)
                goto fail;
 
+       for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i)
+               new_crtc_state->min_cdclk = 
intel_crtc_min_cdclk(new_crtc_state);
+
        ret = intel_compute_global_watermarks(state);
        if (ret)
                goto fail;
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index f77d120733fd..203dd38a9ec4 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1192,6 +1192,8 @@ struct intel_crtc_state {
 
        struct intel_crtc_wm_state wm;
 
+       int min_cdclk;
+
        int plane_min_cdclk[I915_MAX_PLANES];
 
        /* for packed/planar CbCr */
diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c 
b/drivers/gpu/drm/i915/display/intel_modeset_setup.c
index d5c432b613ce..0dcb0597879a 100644
--- a/drivers/gpu/drm/i915/display/intel_modeset_setup.c
+++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.c
@@ -865,6 +865,11 @@ static void intel_modeset_readout_hw_state(struct 
intel_display *display)
                                    crtc_state->plane_min_cdclk[plane->id]);
                }
 
+               crtc_state->min_cdclk = intel_crtc_min_cdclk(crtc_state);
+
+               drm_dbg_kms(display->drm, "[CRTC:%d:%s] min_cdclk %d kHz\n",
+                           crtc->base.base.id, crtc->base.name, 
crtc_state->min_cdclk);
+
                intel_pmdemand_update_port_clock(display, pmdemand_state, pipe,
                                                 crtc_state->port_clock);
        }
-- 
2.49.1

Reply via email to