> -----Original Message-----
> From: Jani Nikula <[email protected]>
> Sent: 15 June 2026 19:07
> To: Srinivas, Vidya <[email protected]>;
> [email protected]
> Cc: [email protected]; Shankar, Uma <[email protected]>;
> Vidya Srinivas <[email protected]>; Srinivas,
> Vidya <[email protected]>; Lin, Charlton <[email protected]>
> Subject: Re: [PATCH] [RFC] drm/i915/display: Fix PPC-granularity and limit 2nd
> scaler to 1:1
>
> On Mon, 08 Jun 2026, Vidya Srinivas <[email protected]> wrote:
> > From: Vidya Srinivas <[email protected]>
> >
> > The existing icl_plane_min_cdclk() uses a simple pixel_rate/PPC
> > calculation that does not account for the pipeline granularity
> > adjustment when horizontal downscaling is active. The effective
> > pixels-per-clock throughput is reduced due to integer pipeline
> > granularity, requiring a higher CDCLK than the current one computes.
> > This causes FIFO underruns on multi-pipe configurations near max CDCLK.
> >
> > Additionally, limit second scaler to 1:1 (no horizontal or vertical
> > downscaling) on DISPLAY_VER > 14
> >
> > Also apply CDCLK PLL disable/enable WA for DISPLAY_VER 30
> >
> > Signed-off-by: Vidya Srinivas <[email protected]>
> > Signed-off-by: Charlton Lin <[email protected]>
>
> If you're sending a patch from you, why is Charlton's Signed-off-by here? Who
> is the author? Did you inted to add Co-developed-by: Charlton?
Apologies for clubbing two. Charlton identified the scaler. Since it was RFC
patch we combined
and sent for feedback. Sorry about that. If the patch content is relevant we
will split and send it.
Thank you so much.
Regards
Vidya
>
> BR,
> Jani.
>
>
>
> > ---
> > drivers/gpu/drm/i915/display/intel_cdclk.c | 3 +-
> > drivers/gpu/drm/i915/display/skl_scaler.c | 4 +-
> > .../drm/i915/display/skl_universal_plane.c | 58 +++++++++++++++++--
> > 3 files changed, 57 insertions(+), 8 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c
> > b/drivers/gpu/drm/i915/display/intel_cdclk.c
> > index 189ae2d3cfc9..f724227c3726 100644
> > --- a/drivers/gpu/drm/i915/display/intel_cdclk.c
> > +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
> > @@ -2149,7 +2149,8 @@ static bool
> > cdclk_compute_crawl_and_squash_midpoint(struct intel_display *displa
> >
> > static bool pll_enable_wa_needed(struct intel_display *display) {
> > - return (DISPLAY_VERx100(display) == 2000 ||
> > + return (DISPLAY_VERx100(display) == 3000 ||
> > + DISPLAY_VERx100(display) == 2000 ||
> > DISPLAY_VERx100(display) == 1400 ||
> > display->platform.dg2) &&
> > display->cdclk.hw.vco > 0;
> > diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c
> > b/drivers/gpu/drm/i915/display/skl_scaler.c
> > index 7994b983d509..3673b52de4da 100644
> > --- a/drivers/gpu/drm/i915/display/skl_scaler.c
> > +++ b/drivers/gpu/drm/i915/display/skl_scaler.c
> > @@ -382,8 +382,10 @@ calculate_max_scale(struct intel_crtc *crtc,
> >
> > if (scaler_id == 0)
> > *max_vscale = 0x30000 - 1;
> > - else
> > + else {
> > + *max_hscale = 0x10000;
> > *max_vscale = 0x10000;
> > + }
> > } else if (DISPLAY_VER(display) >= 10 || !is_yuv_semiplanar) {
> > *max_hscale = 0x30000 - 1;
> > *max_vscale = 0x30000 - 1;
> > diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c
> > b/drivers/gpu/drm/i915/display/skl_universal_plane.c
> > index ad4bfff6903d..c49f330c4878 100644
> > --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
> > +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
> > @@ -264,12 +264,58 @@ bool icl_is_hdr_plane(struct intel_display
> > *display, enum plane_id plane_id) }
> >
> > static int icl_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
> > - const struct intel_plane_state *plane_state)
> > -{
> > - unsigned int pixel_rate = intel_plane_pixel_rate(crtc_state,
> plane_state);
> > -
> > - /* two pixels per clock */
> > - return DIV_ROUND_UP(pixel_rate, 2);
> > + const struct intel_plane_state *plane_state) {
> > + struct intel_display *display = to_intel_display(crtc_state);
> > + unsigned int pixel_rate = intel_plane_pixel_rate(crtc_state,
> > +plane_state);
> > +
> > + if (DISPLAY_VER(display) >= 30) {
> > + unsigned int src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
> > + unsigned int dst_w = drm_rect_width(&plane_state->uapi.dst);
> > + unsigned int src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
> > + unsigned int dst_h = drm_rect_height(&plane_state->uapi.dst);
> > + const unsigned int ppc = 2;
> > +
> > + /*
> > + * "Resolution Support" PPC-granularity:
> > + * Hscale_PPC = (src_w / dst_w) * PPC
> > + * int_part = floor(Hscale_PPC)
> > + * frac = Hscale_PPC - int_part
> > + * adjusted_frac = frac > 0 ? 1/ROUNDUP(1/frac) : 0
> > + * H_down = int_part/PPC + adjusted_frac
> > + * min_cdclk = crtc_clock * H_down * V_down / PPC
> > + */
> > + if (dst_w && dst_h && src_w > dst_w) {
> > + unsigned int hscale_ppc = src_w * ppc;
> > + unsigned int int_part = hscale_ppc / dst_w;
> > + unsigned int frac_num = hscale_ppc % dst_w;
> > + unsigned int v_num = max(src_h, dst_h);
> > + u64 num;
> > +
> > + if (frac_num) {
> > + unsigned int recip_ceil = DIV_ROUND_UP(dst_w, frac_num);
> > + /* H_down = (int_part * recip_ceil + ppc) / (ppc *
> > recip_ceil) */
> > + unsigned int h_num = int_part * recip_ceil + ppc;
> > + unsigned int h_den = ppc * recip_ceil;
> > +
> > + num = mul_u32_u32(crtc_state->pixel_rate, h_num);
> > + num *= v_num;
> > + return DIV_ROUND_UP_ULL(num,
> > + (u64)h_den * ppc * dst_h);
> > + }
> > +
> > + /* frac == 0: H_down = int_part / ppc exactly */
> > + num = mul_u32_u32(crtc_state->pixel_rate, int_part);
> > + num *= v_num;
> > + return DIV_ROUND_UP_ULL(num, (u64)ppc * ppc * dst_h);
> > + }
> > +
> > + /* No horizontal downscale */
> > + return DIV_ROUND_UP(pixel_rate, ppc);
> > + }
> > +
> > + /* two pixels per clock */
> > + return DIV_ROUND_UP(pixel_rate, 2);
> > }
> >
> > static void
>
> --
> Jani Nikula, Intel