From cbacc79db6ac932f7ac86ff01086302bfb79e5d0 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Thu, 4 Oct 2018 16:15:58 -0700 Subject: [PATCH] drm/i915: transition WMs ask for Selected Result Blocks The transition watermarks ask for Selected Result Blocks (the real value), not Result Blocks (the integer value). Given how ceilings are applied in both the non-transition and the transition watermarks calculations, we can get away with assuming that Selected Result Blocks is actually Result Blocks minus 1 without any rounding errors. Reviewed-by: Matt Roper Signed-off-by: Paulo Zanoni Link: https://patchwork.freedesktop.org/patch/msgid/20181004231600.14101-5-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/intel_pm.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 43fb1f8..8bd4558 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4871,7 +4871,7 @@ static void skl_compute_transition_wm(struct intel_crtc_state *cstate, const struct drm_i915_private *dev_priv = to_i915(dev); uint16_t trans_min, trans_y_tile_min; const uint16_t trans_amount = 10; /* This is configurable amount */ - uint16_t trans_offset_b, res_blocks; + uint16_t wm0_sel_res_b, trans_offset_b, res_blocks; if (!cstate->base.active) goto exit; @@ -4890,13 +4890,25 @@ static void skl_compute_transition_wm(struct intel_crtc_state *cstate, trans_offset_b = trans_min + trans_amount; + /* + * The spec asks for Selected Result Blocks for wm0 (the real value), + * not Result Blocks (the integer value). Pay attention to the capital + * letters. The value wm_l0->plane_res_b is actually Result Blocks, but + * since Result Blocks is the ceiling of Selected Result Blocks plus 1, + * and since we later will have to get the ceiling of the sum in the + * transition watermarks calculation, we can just pretend Selected + * Result Blocks is Result Blocks minus 1 and it should work for the + * current platforms. + */ + wm0_sel_res_b = wm_l0->plane_res_b - 1; + if (wp->y_tiled) { trans_y_tile_min = (uint16_t) mul_round_up_u32_fixed16(2, wp->y_tile_minimum); - res_blocks = max(wm_l0->plane_res_b, trans_y_tile_min) + + res_blocks = max(wm0_sel_res_b, trans_y_tile_min) + trans_offset_b; } else { - res_blocks = wm_l0->plane_res_b + trans_offset_b; + res_blocks = wm0_sel_res_b + trans_offset_b; /* WA BUG:1938466 add one block for non y-tile planes */ if (IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_A0)) -- 2.7.4