From: Ville Syrjälä <[email protected]> Now that the scaler assignment has been moved to an earlier point we can start to use the actual scale factors in the prefill vs. vblank length check.
Reviewed-by: Luca Coelho <[email protected]> Signed-off-by: Ville Syrjälä <[email protected]> --- drivers/gpu/drm/i915/display/skl_scaler.c | 77 ++++++++++++++++++++--- 1 file changed, 67 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c index e8a8facdc300..53436c731cf1 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.c +++ b/drivers/gpu/drm/i915/display/skl_scaler.c @@ -978,22 +978,79 @@ void adl_scaler_ecc_unmask(const struct intel_crtc_state *crtc_state) intel_de_write(display, XELPD_DISPLAY_ERR_FATAL_MASK, 0); } +static unsigned int skl_scaler_scale(const struct intel_crtc_state *crtc_state, int i) +{ + const struct intel_crtc_scaler_state *scaler_state = + &crtc_state->scaler_state; + + return DIV_ROUND_UP_ULL(mul_u32_u32(scaler_state->scalers[i].hscale, + scaler_state->scalers[i].vscale), + 0x10000); +} + +static unsigned int skl_scaler_downscale(const struct intel_crtc_state *crtc_state, int i) +{ + return max(0x10000, skl_scaler_scale(crtc_state, i)); +} + +static unsigned int skl_plane_scaler_downscale(const struct intel_crtc_state *crtc_state) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + const struct intel_crtc_scaler_state *scaler_state = + &crtc_state->scaler_state; + unsigned int scale = 0x10000; + int i; + + for (i = 0; i < crtc->num_scalers; i++) { + /* ignore pfit */ + if (i == scaler_state->scaler_id) + continue; + + if (!scaler_state->scalers[i].in_use) + continue; + + scale = max(scale, skl_scaler_downscale(crtc_state, i)); + } + + return scale; +} + +static unsigned int skl_pipe_scaler_downscale(const struct intel_crtc_state *crtc_state) +{ + const struct intel_crtc_scaler_state *scaler_state = + &crtc_state->scaler_state; + + if (!crtc_state->pch_pfit.enabled) + return 0x10000; + + return skl_scaler_downscale(crtc_state, scaler_state->scaler_id); +} + unsigned int skl_scaler_1st_prefill_adjustment(const struct intel_crtc_state *crtc_state) { - /* - * FIXME don't have scalers assigned yet - * so can't look up the scale factors - */ - return 0x10000; + const struct intel_crtc_scaler_state *scaler_state = + &crtc_state->scaler_state; + int num_scalers = hweight32(scaler_state->scaler_users); + + if (num_scalers < 1) + return 0x10000; + + if (num_scalers == 1 && crtc_state->pch_pfit.enabled) + return skl_pipe_scaler_downscale(crtc_state); + else + return skl_plane_scaler_downscale(crtc_state); } unsigned int skl_scaler_2nd_prefill_adjustment(const struct intel_crtc_state *crtc_state) { - /* - * FIXME don't have scalers assigned yet - * so can't look up the scale factors - */ - return 0x10000; + const struct intel_crtc_scaler_state *scaler_state = + &crtc_state->scaler_state; + int num_scalers = hweight32(scaler_state->scaler_users); + + if (num_scalers < 2) + return 0x10000; + + return skl_pipe_scaler_downscale(crtc_state); } unsigned int skl_scaler_1st_prefill_lines(const struct intel_crtc_state *crtc_state) -- 2.49.1
