From: Ville Syrjala <ville.syrjala@linux.intel.com>
To: intel-gfx@lists.freedesktop.org
Cc: intel-xe@lists.freedesktop.org
Subject: [RFC][PATCH 02/11] drm/i915/cdclk: Add prefill helpers for CDCLK
Date: Wed, 8 Oct 2025 21:25:49 +0300 [thread overview]
Message-ID: <20251008182559.20615-3-ville.syrjala@linux.intel.com> (raw)
In-Reply-To: <20251008182559.20615-1-ville.syrjala@linux.intel.com>
From: Ville Syrjälä <ville.syrjala@linux.intel.com>
Add helpers to compute the CDCLKl adjustment factor for prefill
calculations. The adjustment factor is always <= 1.0. That is,
a faster that strictly necessary CDCLK speeds up the pipe prefill.
intel_cdclk_prefill_adjustment_worst() gives out a worst case estimate,
meant to be used during guardband sizing. We can actually do better
than 1.0 here because the absolute minimum CDCLK is limited by the
dotclock. This will still allow planes, pfit, etc. to be changed any
which way without having to resize the guardband yet again.
intel_cdclk_prefill_adjustment() gives out a potentially more optimal
value, purely based on the final minimum CDCLK (also considering
planes/pfit/etc.) for the current pipe. We can't actually check against
the current CDCLK frequency as that might be much higher due to some
other pipe, and said other pipe might later reduce the CDCLK below
what the current pipe would find acceptable (given which WM levels
are enabled). Ie. we don't consider any global constraints (other
pipes, dbuf bandwidth, etc) on the mimimum CDCLK frequency here.
The returned numbers are in .16 binary fixed point.
TODO: the intel_cdclk_prefill_adjustment_worst() approach here
can result in guardband changes for DRRS. But I'm thinking
that is fine since M/N changes will always happen on the
legacy timing generator so guardband doesn't actually matter.
May need to think about this a bit more though...
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
drivers/gpu/drm/i915/display/intel_cdclk.c | 87 +++++++++++++++++++++-
drivers/gpu/drm/i915/display/intel_cdclk.h | 4 +
2 files changed, 89 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
index b54b1006aeb0..598593eafdf5 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -2791,16 +2791,20 @@ static int intel_cdclk_guardband(struct intel_display *display)
return 90;
}
-static int intel_pixel_rate_to_cdclk(const struct intel_crtc_state *crtc_state)
+static int _intel_pixel_rate_to_cdclk(const struct intel_crtc_state *crtc_state, int pixel_rate)
{
struct intel_display *display = to_intel_display(crtc_state);
int ppc = intel_cdclk_ppc(display, crtc_state->double_wide);
int guardband = intel_cdclk_guardband(display);
- int pixel_rate = crtc_state->pixel_rate;
return DIV_ROUND_UP(pixel_rate * 100, guardband * ppc);
}
+static int intel_pixel_rate_to_cdclk(const struct intel_crtc_state *crtc_state)
+{
+ return _intel_pixel_rate_to_cdclk(crtc_state, crtc_state->pixel_rate);
+}
+
static int intel_planes_min_cdclk(const struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
@@ -3917,3 +3921,82 @@ void intel_cdclk_read_hw(struct intel_display *display)
cdclk_state->actual = display->cdclk.hw;
cdclk_state->logical = display->cdclk.hw;
}
+
+static int calc_cdclk(const struct intel_crtc_state *crtc_state, int min_cdclk)
+{
+ struct intel_display *display = to_intel_display(crtc_state);
+
+ if (DISPLAY_VER(display) >= 10 || display->platform.broxton) {
+ return bxt_calc_cdclk(display, min_cdclk);
+ } else if (DISPLAY_VER(display) == 9) {
+ int vco;
+
+ vco = display->cdclk.skl_preferred_vco_freq;
+ if (vco == 0)
+ vco = 8100000;
+
+ return skl_calc_cdclk(min_cdclk, vco);
+ } else if (display->platform.broadwell) {
+ return bdw_calc_cdclk(min_cdclk);
+ } else if (display->platform.cherryview || display->platform.valleyview) {
+ return vlv_calc_cdclk(display, min_cdclk);
+ } else {
+ return display->cdclk.max_cdclk_freq;
+ }
+}
+
+static unsigned int _intel_cdclk_prefill_adj(const struct intel_crtc_state *crtc_state,
+ int clock, int min_cdclk)
+{
+ struct intel_display *display = to_intel_display(crtc_state);
+ int ppc = intel_cdclk_ppc(display, crtc_state->double_wide);
+ int cdclk = calc_cdclk(crtc_state, min_cdclk);
+
+ return min(0x10000, DIV_ROUND_UP_ULL((u64)clock << 16, ppc * cdclk));
+}
+
+unsigned int intel_cdclk_prefill_adjustment(const struct intel_crtc_state *crtc_state,
+ const struct intel_cdclk_state *cdclk_state)
+{
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ int clock = crtc_state->hw.pipe_mode.crtc_clock;
+ int min_cdclk;
+
+ /*
+ * Only consider the current pipe's minimum cdclk here as a safe
+ * lower bound. This must *not* be based on the actual/logical cdclk
+ * frequency here as that may get reduced later due to eg. a modeset
+ * on a different pipe, and that would completely invalidate the
+ * guardband length checks we did on this pipe previously. That
+ * could lead to prefill exceeding the guardband which would result
+ * in underruns.
+ */
+ min_cdclk = intel_cdclk_min_cdclk(cdclk_state, crtc->pipe);
+
+ return _intel_cdclk_prefill_adj(crtc_state, clock, min_cdclk);
+}
+
+unsigned int intel_cdclk_prefill_adjustment_worst(const struct intel_crtc_state *crtc_state)
+{
+ int clock = crtc_state->hw.pipe_mode.crtc_clock;
+ int min_cdclk;
+
+ /*
+ * FIXME could perhaps consider a few more of the factors
+ * that go into cdclk_state->min_cdclk[] here. Namely anything
+ * that only changes during full modesets.
+ *
+ * Should perhaps just cache those into a crtc_state->min_cdclk
+ * at .compute_config() time. Then we could also skip recomputing
+ * those parts during intel_cdclk_atomic_check().
+ *
+ * FIXME this assumes 1:1 scaling, but the other _worst() stuff
+ * assumes max downscaling, so the final result will be
+ * unrealistically bad. Figure out where the actual maximum value
+ * lies and use that to compute a more realistic worst case
+ * estimate...
+ */
+ min_cdclk = _intel_pixel_rate_to_cdclk(crtc_state, clock);
+
+ return _intel_cdclk_prefill_adj(crtc_state, clock, min_cdclk);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.h b/drivers/gpu/drm/i915/display/intel_cdclk.h
index cacee598af0e..d97f725a0160 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.h
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.h
@@ -69,4 +69,8 @@ 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);
+unsigned int intel_cdclk_prefill_adjustment(const struct intel_crtc_state *crtc_state,
+ const struct intel_cdclk_state *cdclk_state);
+unsigned int intel_cdclk_prefill_adjustment_worst(const struct intel_crtc_state *crtc_state);
+
#endif /* __INTEL_CDCLK_H__ */
--
2.49.1
next prev parent reply other threads:[~2025-10-08 18:26 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-10-08 18:25 [RFC][PATCH 00/11] drm/i915/prefill: Introduce helpers for prefill latency calculations Ville Syrjala
2025-10-08 18:25 ` [RFC][PATCH 01/11] drm/i915: Reject modes with linetime > 64 usec Ville Syrjala
2025-10-13 15:15 ` Shankar, Uma
2025-10-08 18:25 ` Ville Syrjala [this message]
2025-10-13 16:11 ` [RFC][PATCH 02/11] drm/i915/cdclk: Add prefill helpers for CDCLK Shankar, Uma
2025-10-08 18:25 ` [RFC][PATCH 03/11] drm/i915/cdclk: Add intel_cdclk_min_cdclk_for_prefill() Ville Syrjala
2025-10-13 16:25 ` Shankar, Uma
2025-10-08 18:25 ` [RFC][PATCH 04/11] drm/i915/dsc: Add prefill helper for DSC Ville Syrjala
2025-10-13 16:26 ` Shankar, Uma
2025-10-08 18:25 ` [RFC][PATCH 05/11] drm/i915/scaler: Add scaler prefill helpers Ville Syrjala
2025-10-13 17:56 ` Shankar, Uma
2025-10-08 18:25 ` [RFC][PATCH 06/11] drm/i195/wm: Add WM0 " Ville Syrjala
2025-10-13 18:30 ` Shankar, Uma
2025-10-13 21:49 ` Ville Syrjälä
2025-10-08 18:25 ` [RFC][PATCH 07/11] drm/i915: Introduce intel_compute_global_watermarks_late() Ville Syrjala
2025-10-13 18:36 ` Shankar, Uma
2025-10-13 20:35 ` Ville Syrjälä
2025-10-08 18:25 ` [RFC][PATCH 08/11] drm/i915/prefill: Introduce intel_prefill.c Ville Syrjala
2025-10-13 18:42 ` Shankar, Uma
2025-10-13 21:37 ` Ville Syrjälä
2025-10-08 18:25 ` [RFC][PATCH 09/11] drm/i915/wm: Use intel_prefill Ville Syrjala
2025-10-13 18:43 ` Shankar, Uma
2025-10-08 18:25 ` [RFC][PATCH 10/11] drm/i915/prefill: Print the prefill details Ville Syrjala
2025-10-13 18:45 ` Shankar, Uma
2025-10-08 18:25 ` [RFC][PATCH 11/11] drm/i915/prefill: Also print out the worst case estimates Ville Syrjala
2025-10-13 18:47 ` Shankar, Uma
2025-10-08 19:10 ` ✗ CI.checkpatch: warning for drm/i915/prefill: Introduce helpers for prefill latency calculations Patchwork
2025-10-08 19:11 ` ✓ CI.KUnit: success " Patchwork
2025-10-08 19:26 ` ✗ CI.checksparse: warning " Patchwork
2025-10-08 19:58 ` ✓ Xe.CI.BAT: success " Patchwork
2025-10-08 23:13 ` ✗ Xe.CI.Full: failure " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251008182559.20615-3-ville.syrjala@linux.intel.com \
--to=ville.syrjala@linux.intel.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=intel-xe@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox