On Mon, Oct 13, 2025 at 06:42:09PM +0000, Shankar, Uma wrote: > > > > -----Original Message----- > > From: Intel-gfx <[email protected]> On Behalf Of Ville > > Syrjala > > Sent: Wednesday, October 8, 2025 11:56 PM > > To: [email protected] > > Cc: [email protected] > > Subject: [RFC][PATCH 08/11] drm/i915/prefill: Introduce intel_prefill.c > > > > From: Ville Syrjälä <[email protected]> > > > > 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. > > Nit: Typo in representation. > > Only thing maybe left is the SDP related latency, which also can be planned > for worst case.
Yeah, though SDP (and PSR) are separate from the pre-fill. So they should be handled by the higher level guardband calculation code, not by intel_prefill. > > Looks Good to me. > Reviewed-by: Uma Shankar <[email protected]> > > > > > Signed-off-by: Ville Syrjälä <[email protected]> > > --- > > 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 > -- Ville Syrjälä Intel
