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

Reply via email to