From patchwork Mon May 22 23:07:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vinod Govindapillai X-Patchwork-Id: 13251213 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 620DBC77B73 for ; Mon, 22 May 2023 23:08:34 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id BA4F310E3B2; Mon, 22 May 2023 23:08:33 +0000 (UTC) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by gabe.freedesktop.org (Postfix) with ESMTPS id A37AA10E3B2 for ; Mon, 22 May 2023 23:08:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1684796910; x=1716332910; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=7oYac8rA3P8ThyL289V2x2h6M2jTXbbKqKR1ssIxEpo=; b=dATxjHCYXkAMPNCQ/kBjrirdLza1gsH9+BtqpTkKHjHldmv79X/SQHVy wA7TrN2psP4hoPuziZaBWwcLAYRMNWD+sZzrMpMTw3DhBopdfcBsigakz a8V5nEqOZUFXLGNP6pZmDzYRsrA7/HCH2XMW2k7BCwFB5CLbLJClQl4PP /Np1nNy7JS+dOWwg2Fzq+hp5w7OPmD8RRtgT/Xo3SunJu3Qz8KZ1oVD3c nc6oiXsVhWaDpyUr8lXC1UlQBLi8X8OkjgrcpBK1ND8hx/nhgVcZWxogf 1WqB42wtz6ARtTXRxLZ1ni/CE3OJX8v2bQwyUdqXvZlPnFS82b6RJEbCo Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10718"; a="353093864" X-IronPort-AV: E=Sophos;i="6.00,184,1681196400"; d="scan'208";a="353093864" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 May 2023 16:08:30 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10718"; a="773542636" X-IronPort-AV: E=Sophos;i="6.00,184,1681196400"; d="scan'208";a="773542636" Received: from cavram-mobl1.ger.corp.intel.com (HELO vgovind2-mobl3.intel.com) ([10.251.220.199]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 May 2023 16:08:27 -0700 From: Vinod Govindapillai To: intel-gfx@lists.freedesktop.org Date: Tue, 23 May 2023 02:07:56 +0300 Message-Id: <20230522230759.153112-5-vinod.govindapillai@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230522230759.153112-1-vinod.govindapillai@intel.com> References: <20230522230759.153112-1-vinod.govindapillai@intel.com> MIME-Version: 1.0 Organization: Intel Finland Oy - BIC 0357606-4 - Westendinkatu 7, 02160 Espoo Subject: [Intel-gfx] [PATCH v6 4/7] drm/i915: extract intel_bw_check_qgv_points() X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ville.syrjala@intel.com Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Extract intel_bw_check_qgv_points() from intel_bw_atomic_check to facilitate future platform variations in handling SAGV configurations. Signed-off-by: Vinod Govindapillai Reviewed-by: Stanislav Lisovskiy --- drivers/gpu/drm/i915/display/intel_bw.c | 235 +++++++++++++----------- 1 file changed, 130 insertions(+), 105 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index db117638d23b..d83aafd0cc2b 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -803,6 +803,128 @@ intel_atomic_get_bw_state(struct intel_atomic_state *state) return to_intel_bw_state(bw_state); } +static int icl_find_qgv_points(struct drm_i915_private *i915, + unsigned int data_rate, + unsigned int num_active_planes, + const struct intel_bw_state *old_bw_state, + struct intel_bw_state *new_bw_state) +{ + unsigned int max_bw_point = 0; + unsigned int max_bw = 0; + unsigned int num_psf_gv_points = i915->display.bw.max[0].num_psf_gv_points; + unsigned int num_qgv_points = i915->display.bw.max[0].num_qgv_points; + u16 psf_points = 0; + u16 qgv_points = 0; + int i; + int ret; + + ret = intel_atomic_lock_global_state(&new_bw_state->base); + if (ret) + return ret; + + for (i = 0; i < num_qgv_points; i++) { + unsigned int max_data_rate; + + if (DISPLAY_VER(i915) > 11) + max_data_rate = tgl_max_bw(i915, num_active_planes, i); + else + max_data_rate = icl_max_bw(i915, num_active_planes, i); + /* + * We need to know which qgv point gives us + * maximum bandwidth in order to disable SAGV + * if we find that we exceed SAGV block time + * with watermarks. By that moment we already + * have those, as it is calculated earlier in + * intel_atomic_check, + */ + if (max_data_rate > max_bw) { + max_bw_point = i; + max_bw = max_data_rate; + } + if (max_data_rate >= data_rate) + qgv_points |= BIT(i); + + drm_dbg_kms(&i915->drm, "QGV point %d: max bw %d required %d\n", + i, max_data_rate, data_rate); + } + + for (i = 0; i < num_psf_gv_points; i++) { + unsigned int max_data_rate = adl_psf_bw(i915, i); + + if (max_data_rate >= data_rate) + psf_points |= BIT(i); + + drm_dbg_kms(&i915->drm, "PSF GV point %d: max bw %d" + " required %d\n", + i, max_data_rate, data_rate); + } + + /* + * BSpec states that we always should have at least one allowed point + * left, so if we couldn't - simply reject the configuration for obvious + * reasons. + */ + if (qgv_points == 0) { + drm_dbg_kms(&i915->drm, "No QGV points provide sufficient memory" + " bandwidth %d for display configuration(%d active planes).\n", + data_rate, num_active_planes); + return -EINVAL; + } + + if (num_psf_gv_points > 0 && psf_points == 0) { + drm_dbg_kms(&i915->drm, "No PSF GV points provide sufficient memory" + " bandwidth %d for display configuration(%d active planes).\n", + data_rate, num_active_planes); + return -EINVAL; + } + + /* + * Leave only single point with highest bandwidth, if + * we can't enable SAGV due to the increased memory latency it may + * cause. + */ + if (!intel_can_enable_sagv(i915, new_bw_state)) { + qgv_points = BIT(max_bw_point); + drm_dbg_kms(&i915->drm, "No SAGV, using single QGV point %d\n", + max_bw_point); + } + + /* + * We store the ones which need to be masked as that is what PCode + * actually accepts as a parameter. + */ + new_bw_state->qgv_points_mask = + ~(ICL_PCODE_REQ_QGV_PT(qgv_points) | + ADLS_PCODE_REQ_PSF_PT(psf_points)) & + icl_qgv_points_mask(i915); + + /* + * If the actual mask had changed we need to make sure that + * the commits are serialized(in case this is a nomodeset, nonblocking) + */ + if (new_bw_state->qgv_points_mask != old_bw_state->qgv_points_mask) { + ret = intel_atomic_serialize_global_state(&new_bw_state->base); + if (ret) + return ret; + } + + return 0; +} + +static int intel_bw_check_qgv_points(struct drm_i915_private *i915, + const struct intel_bw_state *old_bw_state, + struct intel_bw_state *new_bw_state) +{ + unsigned int data_rate = intel_bw_data_rate(i915, new_bw_state); + unsigned int num_active_planes = + intel_bw_num_active_planes(i915, new_bw_state); + + data_rate = DIV_ROUND_UP(data_rate, 1000); + + return icl_find_qgv_points(i915, data_rate, num_active_planes, + old_bw_state, new_bw_state); +} + static bool intel_bw_state_changed(struct drm_i915_private *i915, const struct intel_bw_state *old_bw_state, const struct intel_bw_state *new_bw_state) @@ -1049,20 +1171,14 @@ static int intel_bw_check_data_rate(struct intel_atomic_state *state, bool *chan int intel_bw_atomic_check(struct intel_atomic_state *state) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); - const struct intel_bw_state *old_bw_state; - struct intel_bw_state *new_bw_state; - unsigned int data_rate; - unsigned int num_active_planes; - int i, ret; - u16 qgv_points = 0, psf_points = 0; - unsigned int max_bw_point = 0, max_bw = 0; - unsigned int num_qgv_points = dev_priv->display.bw.max[0].num_qgv_points; - unsigned int num_psf_gv_points = dev_priv->display.bw.max[0].num_psf_gv_points; bool changed = false; + struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_bw_state *new_bw_state; + const struct intel_bw_state *old_bw_state; + int ret; /* FIXME earlier gens need some checks too */ - if (DISPLAY_VER(dev_priv) < 11) + if (DISPLAY_VER(i915) < 11) return 0; ret = intel_bw_check_data_rate(state, &changed); @@ -1073,8 +1189,8 @@ int intel_bw_atomic_check(struct intel_atomic_state *state) new_bw_state = intel_atomic_get_new_bw_state(state); if (new_bw_state && - intel_can_enable_sagv(dev_priv, old_bw_state) != - intel_can_enable_sagv(dev_priv, new_bw_state)) + intel_can_enable_sagv(i915, old_bw_state) != + intel_can_enable_sagv(i915, new_bw_state)) changed = true; /* @@ -1084,101 +1200,10 @@ int intel_bw_atomic_check(struct intel_atomic_state *state) if (!changed) return 0; - ret = intel_atomic_lock_global_state(&new_bw_state->base); + ret = intel_bw_check_qgv_points(i915, old_bw_state, new_bw_state); if (ret) return ret; - data_rate = intel_bw_data_rate(dev_priv, new_bw_state); - data_rate = DIV_ROUND_UP(data_rate, 1000); - - num_active_planes = intel_bw_num_active_planes(dev_priv, new_bw_state); - - for (i = 0; i < num_qgv_points; i++) { - unsigned int max_data_rate; - - if (DISPLAY_VER(dev_priv) > 11) - max_data_rate = tgl_max_bw(dev_priv, num_active_planes, i); - else - max_data_rate = icl_max_bw(dev_priv, num_active_planes, i); - /* - * We need to know which qgv point gives us - * maximum bandwidth in order to disable SAGV - * if we find that we exceed SAGV block time - * with watermarks. By that moment we already - * have those, as it is calculated earlier in - * intel_atomic_check, - */ - if (max_data_rate > max_bw) { - max_bw_point = i; - max_bw = max_data_rate; - } - if (max_data_rate >= data_rate) - qgv_points |= BIT(i); - - drm_dbg_kms(&dev_priv->drm, "QGV point %d: max bw %d required %d\n", - i, max_data_rate, data_rate); - } - - for (i = 0; i < num_psf_gv_points; i++) { - unsigned int max_data_rate = adl_psf_bw(dev_priv, i); - - if (max_data_rate >= data_rate) - psf_points |= BIT(i); - - drm_dbg_kms(&dev_priv->drm, "PSF GV point %d: max bw %d" - " required %d\n", - i, max_data_rate, data_rate); - } - - /* - * BSpec states that we always should have at least one allowed point - * left, so if we couldn't - simply reject the configuration for obvious - * reasons. - */ - if (qgv_points == 0) { - drm_dbg_kms(&dev_priv->drm, "No QGV points provide sufficient memory" - " bandwidth %d for display configuration(%d active planes).\n", - data_rate, num_active_planes); - return -EINVAL; - } - - if (num_psf_gv_points > 0 && psf_points == 0) { - drm_dbg_kms(&dev_priv->drm, "No PSF GV points provide sufficient memory" - " bandwidth %d for display configuration(%d active planes).\n", - data_rate, num_active_planes); - return -EINVAL; - } - - /* - * Leave only single point with highest bandwidth, if - * we can't enable SAGV due to the increased memory latency it may - * cause. - */ - if (!intel_can_enable_sagv(dev_priv, new_bw_state)) { - qgv_points = BIT(max_bw_point); - drm_dbg_kms(&dev_priv->drm, "No SAGV, using single QGV point %d\n", - max_bw_point); - } - - /* - * We store the ones which need to be masked as that is what PCode - * actually accepts as a parameter. - */ - new_bw_state->qgv_points_mask = - ~(ICL_PCODE_REQ_QGV_PT(qgv_points) | - ADLS_PCODE_REQ_PSF_PT(psf_points)) & - icl_qgv_points_mask(dev_priv); - - /* - * If the actual mask had changed we need to make sure that - * the commits are serialized(in case this is a nomodeset, nonblocking) - */ - if (new_bw_state->qgv_points_mask != old_bw_state->qgv_points_mask) { - ret = intel_atomic_serialize_global_state(&new_bw_state->base); - if (ret) - return ret; - } - return 0; }