From: Ville Syrjala <ville.syrjala@linux.intel.com>
To: intel-gfx@lists.freedesktop.org
Cc: intel-xe@lists.freedesktop.org
Subject: [RFC][PATCH 08/11] drm/i915/prefill: Introduce intel_prefill.c
Date: Wed, 8 Oct 2025 21:25:55 +0300 [thread overview]
Message-ID: <20251008182559.20615-9-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 a new helper thingy to deal with the pipe prefill latency.
We get three potentially useful thigns out of this:
- intel_prefill_vblank_too_short() used for checking the
actual vblank/guardband length
- intel_prefill_min_guardband() to calculate a suitable guardband
size based on some worst case scaling/etc. estimates
- intel_prefill_min_cdclk() used to calculate a minimum cdclk
freqency required for very small vblank lengths (in case the
otherwise compute minimum cdclk doesn't result in fast enough
prefill).
The internal arithmetic is done terms of scanlines using .16
binary fixed point represantion.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
drivers/gpu/drm/i915/Makefile | 1 +
drivers/gpu/drm/i915/display/intel_prefill.c | 167 +++++++++++++++++++
drivers/gpu/drm/i915/display/intel_prefill.h | 48 ++++++
drivers/gpu/drm/xe/Makefile | 1 +
4 files changed, 217 insertions(+)
create mode 100644 drivers/gpu/drm/i915/display/intel_prefill.c
create mode 100644 drivers/gpu/drm/i915/display/intel_prefill.h
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 78a45a6681df..088a6c6cd138 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -351,6 +351,7 @@ i915-y += \
display/intel_panel.o \
display/intel_pfit.o \
display/intel_pps.o \
+ display/intel_prefill.o \
display/intel_qp_tables.o \
display/intel_sdvo.o \
display/intel_snps_hdmi_pll.o \
diff --git a/drivers/gpu/drm/i915/display/intel_prefill.c b/drivers/gpu/drm/i915/display/intel_prefill.c
new file mode 100644
index 000000000000..8b9c14e5c505
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_prefill.c
@@ -0,0 +1,167 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2025 Intel Corporation
+ */
+
+#include <linux/debugfs.h>
+
+#include <drm/drm_print.h>
+
+#include "intel_cdclk.h"
+#include "intel_display_core.h"
+#include "intel_display_types.h"
+#include "intel_prefill.h"
+#include "intel_vdsc.h"
+#include "skl_scaler.h"
+#include "skl_watermark.h"
+
+static unsigned int prefill_usecs_to_lines(const struct intel_crtc_state *crtc_state, unsigned int usecs)
+{
+ const struct drm_display_mode *pipe_mode = &crtc_state->hw.pipe_mode;
+
+ return DIV_ROUND_UP_ULL(mul_u32_u32(pipe_mode->crtc_clock, usecs << 16),
+ pipe_mode->crtc_htotal * 1000);
+}
+
+static void _intel_prefill_init(struct intel_prefill_ctx *ctx,
+ const struct intel_crtc_state *crtc_state)
+{
+ ctx->prefill.fixed = crtc_state->framestart_delay;
+
+ /* 20 usec for translation walks/etc. */
+ ctx->prefill.fixed += prefill_usecs_to_lines(crtc_state, 20);
+
+ ctx->prefill.dsc = intel_vdsc_prefill_lines(crtc_state);
+
+ ctx->prefill.full = 0;
+}
+
+static void intel_prefill_init_nocdclk_worst(struct intel_prefill_ctx *ctx,
+ const struct intel_crtc_state *crtc_state)
+{
+ _intel_prefill_init(ctx, crtc_state);
+
+ ctx->prefill.wm0 = skl_wm0_prefill_lines_worst(crtc_state);
+ ctx->prefill.scaler_1st = skl_scaler_1st_prefill_lines_worst(crtc_state);
+ ctx->prefill.scaler_2nd = skl_scaler_2nd_prefill_lines_worst(crtc_state);
+
+ ctx->adj.scaler_1st = skl_scaler_1st_prefill_adjustment_worst(crtc_state);
+ ctx->adj.scaler_2nd = skl_scaler_2nd_prefill_adjustment_worst(crtc_state);
+}
+
+static void intel_prefill_init_nocdclk(struct intel_prefill_ctx *ctx,
+ const struct intel_crtc_state *crtc_state)
+{
+ _intel_prefill_init(ctx, crtc_state);
+
+ ctx->prefill.wm0 = skl_wm0_prefill_lines(crtc_state);
+ ctx->prefill.scaler_1st = skl_scaler_1st_prefill_lines(crtc_state);
+ ctx->prefill.scaler_2nd = skl_scaler_2nd_prefill_lines(crtc_state);
+
+ ctx->adj.scaler_1st = skl_scaler_1st_prefill_adjustment(crtc_state);
+ ctx->adj.scaler_2nd = skl_scaler_2nd_prefill_adjustment(crtc_state);
+}
+
+static unsigned int prefill_adjust(unsigned int value, unsigned int factor)
+{
+ return DIV_ROUND_UP_ULL(mul_u32_u32(value, factor), 0x10000);
+}
+
+static unsigned int prefill_lines_nocdclk(const struct intel_prefill_ctx *ctx)
+{
+ unsigned int prefill = 0;
+
+ prefill += ctx->prefill.dsc;
+ prefill = prefill_adjust(prefill, ctx->adj.scaler_2nd);
+
+ prefill += ctx->prefill.scaler_2nd;
+ prefill = prefill_adjust(prefill, ctx->adj.scaler_1st);
+
+ prefill += ctx->prefill.scaler_1st;
+ prefill += ctx->prefill.wm0;
+
+ return prefill;
+}
+
+static unsigned int prefill_lines_cdclk(const struct intel_prefill_ctx *ctx)
+{
+ return prefill_adjust(prefill_lines_nocdclk(ctx), ctx->adj.cdclk);
+}
+
+static unsigned int prefill_lines_full(const struct intel_prefill_ctx *ctx)
+{
+ return ctx->prefill.fixed + prefill_lines_cdclk(ctx);
+}
+
+void intel_prefill_init_worst(struct intel_prefill_ctx *ctx,
+ const struct intel_crtc_state *crtc_state)
+{
+ intel_prefill_init_nocdclk_worst(ctx, crtc_state);
+
+ ctx->adj.cdclk = intel_cdclk_prefill_adjustment_worst(crtc_state);
+
+ ctx->prefill.full = prefill_lines_full(ctx);
+}
+
+void intel_prefill_init(struct intel_prefill_ctx *ctx,
+ const struct intel_crtc_state *crtc_state,
+ const struct intel_cdclk_state *cdclk_state)
+{
+ intel_prefill_init_nocdclk(ctx, crtc_state);
+
+ ctx->adj.cdclk = intel_cdclk_prefill_adjustment(crtc_state, cdclk_state);
+
+ ctx->prefill.full = prefill_lines_full(ctx);
+}
+
+static unsigned int prefill_lines_with_latency(const struct intel_prefill_ctx *ctx,
+ const struct intel_crtc_state *crtc_state,
+ unsigned int latency_us)
+{
+ return ctx->prefill.full + prefill_usecs_to_lines(crtc_state, latency_us);
+}
+
+int intel_prefill_min_guardband(const struct intel_prefill_ctx *ctx,
+ const struct intel_crtc_state *crtc_state,
+ unsigned int latency_us)
+{
+ unsigned int prefill = prefill_lines_with_latency(ctx, crtc_state, latency_us);
+
+ return DIV_ROUND_UP(prefill, 0x10000);
+}
+
+static int intel_guardband(const struct intel_crtc_state *crtc_state)
+{
+ const struct drm_display_mode *pipe_mode = &crtc_state->hw.pipe_mode;
+
+ if (crtc_state->vrr.enable)
+ return crtc_state->vrr.guardband;
+ else
+ return pipe_mode->crtc_vblank_end - pipe_mode->crtc_vblank_start;
+}
+
+static int intel_prefill_guardband(const struct intel_crtc_state *crtc_state)
+{
+ return intel_guardband(crtc_state) << 16;
+}
+
+bool intel_prefill_vblank_too_short(const struct intel_prefill_ctx *ctx,
+ const struct intel_crtc_state *crtc_state,
+ unsigned int latency_us)
+{
+ unsigned int guardband = intel_prefill_guardband(crtc_state);
+ unsigned int prefill = prefill_lines_with_latency(ctx, crtc_state, latency_us);
+
+ return guardband < prefill;
+}
+
+int intel_prefill_min_cdclk(const struct intel_prefill_ctx *ctx,
+ const struct intel_crtc_state *crtc_state)
+{
+ unsigned int prefill_unadjusted = prefill_lines_nocdclk(ctx);
+ unsigned int prefill_available = intel_prefill_guardband(crtc_state) -
+ ctx->prefill.fixed;
+
+ return intel_cdclk_min_cdclk_for_prefill(crtc_state, prefill_unadjusted,
+ prefill_available);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_prefill.h b/drivers/gpu/drm/i915/display/intel_prefill.h
new file mode 100644
index 000000000000..0f07660261dc
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_prefill.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2025 Intel Corporation
+ */
+
+#ifndef __INTEL_PREFILL_H__
+#define __INTEL_PREFILL_H__
+
+#include <linux/types.h>
+
+struct intel_cdclk_state;
+struct intel_crtc_state;
+
+struct intel_prefill_ctx {
+ /* .16 scanlines */
+ struct {
+ unsigned int fixed;
+ unsigned int wm0;
+ unsigned int scaler_1st;
+ unsigned int scaler_2nd;
+ unsigned int dsc;
+ unsigned int full;
+ } prefill;
+
+ /* .16 adjustment factors */
+ struct {
+ unsigned int cdclk;
+ unsigned int scaler_1st;
+ unsigned int scaler_2nd;
+ } adj;
+};
+
+void intel_prefill_init_worst(struct intel_prefill_ctx *ctx,
+ const struct intel_crtc_state *crtc_state);
+void intel_prefill_init(struct intel_prefill_ctx *ctx,
+ const struct intel_crtc_state *crtc_state,
+ const struct intel_cdclk_state *cdclk_state);
+
+bool intel_prefill_vblank_too_short(const struct intel_prefill_ctx *ctx,
+ const struct intel_crtc_state *crtc_state,
+ unsigned int latency_us);
+int intel_prefill_min_guardband(const struct intel_prefill_ctx *ctx,
+ const struct intel_crtc_state *crtc_state,
+ unsigned int latency_us);
+int intel_prefill_min_cdclk(const struct intel_prefill_ctx *ctx,
+ const struct intel_crtc_state *crtc_state);
+
+#endif /* __INTEL_PREFILL_H__ */
diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile
index 84321fad3265..1be020cc417d 100644
--- a/drivers/gpu/drm/xe/Makefile
+++ b/drivers/gpu/drm/xe/Makefile
@@ -300,6 +300,7 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \
i915-display/intel_pmdemand.o \
i915-display/intel_pch.o \
i915-display/intel_pps.o \
+ i915-display/intel_prefill.o \
i915-display/intel_psr.o \
i915-display/intel_qp_tables.o \
i915-display/intel_quirks.o \
--
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 ` [RFC][PATCH 02/11] drm/i915/cdclk: Add prefill helpers for CDCLK Ville Syrjala
2025-10-13 16:11 ` 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 ` Ville Syrjala [this message]
2025-10-13 18:42 ` [RFC][PATCH 08/11] drm/i915/prefill: Introduce intel_prefill.c 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-9-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