drm/i915/dsc: Check if vblank is sufficient for dsc prefill

High refresh rate panels which may have small line times
and vblank sizes, Check if vblank size is sufficient for
dsc prefill latency.

--v2:
- Consider chroma downscaling factor in latency calculation. [Ankit]
- Replace with appropriate function name.

--v3:
- Remove FIXME tag.[Ankit]
- Replace Ycbcr444 to Ycbcr420.[Ankit]
- Correct precision. [Ankit]
- Use some local valiables like linetime_factor and latency to
adjust precision.
- Declare latency to 0 initially to avoid returning any garbage values.
- Account for second scaler downscaling factor as well. [Ankit]

--v4:
- Improvise hscale and vscale calculation. [Ankit]
- Use appropriate name for number of scaler users. [Ankit]
- Update commit message and rebase.
- Add linetime and cdclk prefill adjustment calculation. [Ankit]

--v5:
- Update bspec link in trailer. [Ankit]
- Correct hscale, vscale datatype. [Ankit]
- Use intel_crtc_compute_min_cdclk. [Ankit]

--v6:
- Use cdclk_state->logical.cdclk instead of
intel_crtc_compute_min_cdclk. [Ankit]

--v7:
- Fix linetime calculation. [Ankit]
- Reduce redandancy use of variables. [Ankit]
- Fix typos. [Ankit]
- Update calculation for precision. [Ankit]

--v8:
- Initialise variable to return garbage later. [Ankit]
- Initialise few variables to use at local loop, where
it is used. [Ankit]

Bspec: 70151
Signed-off-by: Mitul Golani <mitulkumar.ajitkumar.golani@intel.com>
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20250120172209.188488-8-mitulkumar.ajitkumar.golani@intel.com
This commit is contained in:
Mitul Golani 2025-01-20 22:52:08 +05:30 committed by Ankit Nautiyal
parent 9159b622ad
commit a9b14af999

View file

@ -2310,6 +2310,37 @@ cdclk_prefill_adjustment(const struct intel_crtc_state *crtc_state)
2 * cdclk_state->logical.cdclk));
}
static int
dsc_prefill_latency(const struct intel_crtc_state *crtc_state)
{
const struct intel_crtc_scaler_state *scaler_state =
&crtc_state->scaler_state;
int linetime = DIV_ROUND_UP(1000 * crtc_state->hw.adjusted_mode.htotal,
crtc_state->hw.adjusted_mode.clock);
int num_scaler_users = hweight32(scaler_state->scaler_users);
int chroma_downscaling_factor =
crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 ? 2 : 1;
u32 dsc_prefill_latency = 0;
if (!crtc_state->dsc.compression_enable || !num_scaler_users)
return dsc_prefill_latency;
dsc_prefill_latency = DIV_ROUND_UP(15 * linetime * chroma_downscaling_factor, 10);
for (int i = 0; i < num_scaler_users; i++) {
u64 hscale_k, vscale_k;
hscale_k = max(1000, mul_u32_u32(scaler_state->scalers[i].hscale, 1000) >> 16);
vscale_k = max(1000, mul_u32_u32(scaler_state->scalers[i].vscale, 1000) >> 16);
dsc_prefill_latency = DIV_ROUND_UP_ULL(dsc_prefill_latency * hscale_k * vscale_k,
1000000);
}
dsc_prefill_latency *= cdclk_prefill_adjustment(crtc_state);
return intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode, dsc_prefill_latency);
}
static int
scaler_prefill_latency(const struct intel_crtc_state *crtc_state)
{
@ -2349,10 +2380,10 @@ skl_is_vblank_too_short(const struct intel_crtc_state *crtc_state,
const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
/* FIXME missing DSC pre-fill time */
return crtc_state->framestart_delay +
intel_usecs_to_scanlines(adjusted_mode, latency) +
scaler_prefill_latency(crtc_state) +
dsc_prefill_latency(crtc_state) +
wm0_lines >
adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vblank_start;
}