From patchwork Thu Jun 16 04:22:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankit Nautiyal X-Patchwork-Id: 12883309 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 42721C43334 for ; Thu, 16 Jun 2022 04:21:20 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 98C27113CFE; Thu, 16 Jun 2022 04:21:19 +0000 (UTC) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by gabe.freedesktop.org (Postfix) with ESMTPS id 1F6D3113D1B for ; Thu, 16 Jun 2022 04:21:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1655353278; x=1686889278; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=KQYqAuU2hLEVzi1mkaGd5I20Fu0boxATwEPb7BwsJ88=; b=FaOebCq6bbofxGtYw6qW42v5KSFbYZHlJskxhvsNMF9xvquKiS77oVvN xXIZ96/GSmNMgLYdiuroMim6YFlKe+cvaLVY1kX6GLahVmP7BqTpQajl3 fvIEQLZQ7ph1hq48m7RLkEDq9G0gK9vseYZ7n2wWHd4dQFQSmN0cTwOC+ h2imk290n3sTjee8TdHCj3oIIalLijX6rdfC5HzgU3NsnXqXG1jCkdSss VvVkTQmFECKgskxi6T7RJzA95xG3xSeGcZ+4PGf2QIGf09Wxwu5RU6Q3v /ya45HqsRheyVu6IaUKt3EfmptakWp1/awqRNnCgxAiKuvKFwraOBRjJX g==; X-IronPort-AV: E=McAfee;i="6400,9594,10379"; a="279219509" X-IronPort-AV: E=Sophos;i="5.91,304,1647327600"; d="scan'208";a="279219509" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jun 2022 21:21:18 -0700 X-IronPort-AV: E=Sophos;i="5.91,304,1647327600"; d="scan'208";a="911993770" Received: from srr4-3-linux-103-aknautiy.iind.intel.com ([10.223.34.160]) by fmsmga005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jun 2022 21:21:15 -0700 From: Ankit Nautiyal To: intel-gfx@lists.freedesktop.org Date: Thu, 16 Jun 2022 09:52:45 +0530 Message-Id: <20220616042247.324969-2-ankit.k.nautiyal@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220616042247.324969-1-ankit.k.nautiyal@intel.com> References: <20220616042247.324969-1-ankit.k.nautiyal@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [RFC PATCH 1/3] drm/i915/dp: Rename helper to calculate dsc output bpp 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: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Currently we the required dsc output bpp is set to be the largest compressed bpp supported for max, lane, rate, and bpp. The helper intel_dp_dsc_get_output_bpp gets the maximum supported compressed bpp taking into account link configuration, input bpp, bigjoiner considerations etc. This patch appends 'max' suffix to the function, and also avoid unnecessary left shifting by 4, which we are anyway shifting back later. Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_dp.c | 49 +++++++++++-------------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 2fac76bcf06d..eb00fdf5a3ad 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -660,11 +660,11 @@ small_joiner_ram_size_bits(struct drm_i915_private *i915) return 6144 * 8; } -static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915, - u32 link_clock, u32 lane_count, - u32 mode_clock, u32 mode_hdisplay, - bool bigjoiner, - u32 pipe_bpp) +static u16 intel_dp_dsc_get_output_bpp_max(struct drm_i915_private *i915, + u32 link_clock, u32 lane_count, + u32 mode_clock, u32 mode_hdisplay, + bool bigjoiner, + u32 pipe_bpp) { u32 bits_per_pixel, max_bpp_small_joiner_ram; int i; @@ -718,11 +718,7 @@ static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915, bits_per_pixel = valid_dsc_bpp[i]; } - /* - * Compressed BPP in U6.4 format so multiply by 16, for Gen 11, - * fractional part is 0 - */ - return bits_per_pixel << 4; + return bits_per_pixel; } static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp, @@ -1016,13 +1012,13 @@ intel_dp_mode_valid(struct drm_connector *_connector, true); } else if (drm_dp_sink_supports_fec(intel_dp->fec_capable)) { dsc_max_output_bpp = - intel_dp_dsc_get_output_bpp(dev_priv, - max_link_clock, - max_lanes, - target_clock, - mode->hdisplay, - bigjoiner, - pipe_bpp) >> 4; + intel_dp_dsc_get_output_bpp_max(dev_priv, + max_link_clock, + max_lanes, + target_clock, + mode->hdisplay, + bigjoiner, + pipe_bpp); dsc_slice_count = intel_dp_dsc_get_slice_count(intel_dp, target_clock, @@ -1465,13 +1461,13 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, u8 dsc_dp_slice_count; dsc_max_output_bpp = - intel_dp_dsc_get_output_bpp(dev_priv, - pipe_config->port_clock, - pipe_config->lane_count, - adjusted_mode->crtc_clock, - adjusted_mode->crtc_hdisplay, - pipe_config->bigjoiner_pipes, - pipe_bpp); + intel_dp_dsc_get_output_bpp_max(dev_priv, + pipe_config->port_clock, + pipe_config->lane_count, + adjusted_mode->crtc_clock, + adjusted_mode->crtc_hdisplay, + pipe_config->bigjoiner_pipes, + pipe_bpp); dsc_dp_slice_count = intel_dp_dsc_get_slice_count(intel_dp, adjusted_mode->crtc_clock, @@ -1482,9 +1478,8 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, "Compressed BPP/Slice Count not supported\n"); return -EINVAL; } - pipe_config->dsc.compressed_bpp = min_t(u16, - dsc_max_output_bpp >> 4, - pipe_config->pipe_bpp); + pipe_config->dsc.compressed_bpp = min_t(u16, dsc_max_output_bpp, + pipe_config->pipe_bpp); pipe_config->dsc.slice_count = dsc_dp_slice_count; } From patchwork Thu Jun 16 04:22:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankit Nautiyal X-Patchwork-Id: 12883310 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 399DEC43334 for ; Thu, 16 Jun 2022 04:21:24 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A2B74113D1B; Thu, 16 Jun 2022 04:21:23 +0000 (UTC) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by gabe.freedesktop.org (Postfix) with ESMTPS id 543B6113D1B for ; Thu, 16 Jun 2022 04:21:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1655353280; x=1686889280; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=VMd8WBuLNouVQj+NtH+yZtotnV7r0kUzl01ob3CwJG4=; b=fyduJAK7BLbn9E00nrv68jUTxQDmyKjh8CKcZnsDRj9rfJdgz+t8+QLj imZvOOo9iYBNgSGGS27RYl1SiFx6opBKZt+qivigtJ/aDcJZ4SoSmNMVs 48O7yuxBrdApJ6MDPmXp39Hk5P4sj9Fke4hM5FWgUU6UrJb8Pr5qnEdWy 6RJeS8Jr3e4u4kKYzbHlulc3e2jmOuBAM8UrNBGD+xxvXng36XiQB91TA zu85h8cRvx4AiaIqM/TC5Jr5JZL3x/i8xb7mqCtWEHQB3cjII/XT3zbNl RRhoHJsAiMIeCIZ3m9XDrGCh/boTAFMLSUSz54XLlv4detazMThfEYFqt Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10379"; a="279219518" X-IronPort-AV: E=Sophos;i="5.91,304,1647327600"; d="scan'208";a="279219518" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jun 2022 21:21:20 -0700 X-IronPort-AV: E=Sophos;i="5.91,304,1647327600"; d="scan'208";a="911993791" Received: from srr4-3-linux-103-aknautiy.iind.intel.com ([10.223.34.160]) by fmsmga005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jun 2022 21:21:18 -0700 From: Ankit Nautiyal To: intel-gfx@lists.freedesktop.org Date: Thu, 16 Jun 2022 09:52:46 +0530 Message-Id: <20220616042247.324969-3-ankit.k.nautiyal@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220616042247.324969-1-ankit.k.nautiyal@intel.com> References: <20220616042247.324969-1-ankit.k.nautiyal@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [RFC PATCH 2/3] drm/i915/dp: Rename helper to get max pipe bpp with DSC 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: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" The helper intel_dp_dsc_compute_bpp gives the maximum pipe bpp that is allowed with DSC. Renaming the function to reflect the same. Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_dp.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index eb00fdf5a3ad..d0c63888dfff 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -115,7 +115,7 @@ bool intel_dp_is_edp(struct intel_dp *intel_dp) } static void intel_dp_unset_edid(struct intel_dp *intel_dp); -static int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc); +static int intel_dp_dsc_get_bpp_max(struct intel_dp *intel_dp, u8 dsc_max_bpc); /* Is link rate UHBR and thus 128b/132b? */ bool intel_dp_is_uhbr(const struct intel_crtc_state *crtc_state) @@ -1002,7 +1002,7 @@ intel_dp_mode_valid(struct drm_connector *_connector, * TBD pass the connector BPC, * for now U8_MAX so that max BPC on that platform would be picked */ - int pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, U8_MAX); + int pipe_bpp_max = intel_dp_dsc_get_bpp_max(intel_dp, U8_MAX); if (intel_dp_is_edp(intel_dp)) { dsc_max_output_bpp = @@ -1018,7 +1018,7 @@ intel_dp_mode_valid(struct drm_connector *_connector, target_clock, mode->hdisplay, bigjoiner, - pipe_bpp); + pipe_bpp_max); dsc_slice_count = intel_dp_dsc_get_slice_count(intel_dp, target_clock, @@ -1323,7 +1323,7 @@ intel_dp_compute_link_config_wide(struct intel_dp *intel_dp, return -EINVAL; } -static int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 max_req_bpc) +static int intel_dp_dsc_get_bpp_max(struct intel_dp *intel_dp, u8 max_req_bpc) { struct drm_i915_private *i915 = dp_to_i915(intel_dp); int i, num_bpc; @@ -1422,7 +1422,7 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; - int pipe_bpp; + int pipe_bpp_max; int ret; pipe_config->fec_enable = !intel_dp_is_edp(intel_dp) && @@ -1431,10 +1431,10 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, if (!intel_dp_supports_dsc(intel_dp, pipe_config)) return -EINVAL; - pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, conn_state->max_requested_bpc); + pipe_bpp_max = intel_dp_dsc_get_bpp_max(intel_dp, conn_state->max_requested_bpc); /* Min Input BPC for ICL+ is 8 */ - if (pipe_bpp < 8 * 3) { + if (pipe_bpp_max < 8 * 3) { drm_dbg_kms(&dev_priv->drm, "No DSC support for less than 8bpc\n"); return -EINVAL; @@ -1445,7 +1445,7 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, * Optimize this later for the minimum possible link rate/lane count * with DSC enabled for the requested mode. */ - pipe_config->pipe_bpp = pipe_bpp; + pipe_config->pipe_bpp = pipe_bpp_max; pipe_config->port_clock = limits->max_rate; pipe_config->lane_count = limits->max_lane_count; @@ -1467,7 +1467,7 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, adjusted_mode->crtc_clock, adjusted_mode->crtc_hdisplay, pipe_config->bigjoiner_pipes, - pipe_bpp); + pipe_bpp_max); dsc_dp_slice_count = intel_dp_dsc_get_slice_count(intel_dp, adjusted_mode->crtc_clock, @@ -1486,7 +1486,7 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, /* As of today we support DSC for only RGB */ if (intel_dp->force_dsc_bpp) { if (intel_dp->force_dsc_bpp >= 8 && - intel_dp->force_dsc_bpp < pipe_bpp) { + intel_dp->force_dsc_bpp < pipe_bpp_max) { drm_dbg_kms(&dev_priv->drm, "DSC BPP forced to %d", intel_dp->force_dsc_bpp); From patchwork Thu Jun 16 04:22:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankit Nautiyal X-Patchwork-Id: 12883311 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 88447C433EF for ; Thu, 16 Jun 2022 04:21:25 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 05D1F113D1C; Thu, 16 Jun 2022 04:21:25 +0000 (UTC) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by gabe.freedesktop.org (Postfix) with ESMTPS id C12D3113D1C for ; Thu, 16 Jun 2022 04:21:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1655353282; x=1686889282; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=gL3M/n+jDFH9RpExm9hhDmdCSI/h6jAU2qoAyB3QtVQ=; b=n1pv5+4aBED0Y5fM6ELa/EHBWXrvAX0XTB18WsSYunZf0XM5K/rdaIBO g4MKLqKtJYgkSkVbmWjwkjokfq/2iERmtPi1tOk6dVaFGTXNGLLj9cHuu o5MT5U/W9ZE0wsk43lFxPwXQQMSitklSwfVX6AoEa8zrBv8et0jz9PlcV UQsDXNRWKhQmi861Y/aWPxxrgnb8qJRcoLf8SRpjuhpvlt6ASaILr0ico 6lYhDpAbnDYyA1dv5yx0d/98//81U9648k+hxCy35u3kCxvTHDx6qTvcD QEU+/iLT/Oi6+MfxBPdOThScYNTtHLk7G1HGqSb+EWMIcada5tUa8dioS Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10379"; a="279219528" X-IronPort-AV: E=Sophos;i="5.91,304,1647327600"; d="scan'208";a="279219528" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jun 2022 21:21:22 -0700 X-IronPort-AV: E=Sophos;i="5.91,304,1647327600"; d="scan'208";a="911993816" Received: from srr4-3-linux-103-aknautiy.iind.intel.com ([10.223.34.160]) by fmsmga005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jun 2022 21:21:20 -0700 From: Ankit Nautiyal To: intel-gfx@lists.freedesktop.org Date: Thu, 16 Jun 2022 09:52:47 +0530 Message-Id: <20220616042247.324969-4-ankit.k.nautiyal@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220616042247.324969-1-ankit.k.nautiyal@intel.com> References: <20220616042247.324969-1-ankit.k.nautiyal@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [RFC PATCH 3/3] drm/i915/dp: Get optimal link config to have best compressed bpp 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: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Currently, we take the max lane, rate and pipe bpp, to get the maximum compressed bpp possible. We then set the output bpp to this value. This patch provides support to have max bpp, min rate and min lanes, that can support the min compressed bpp. This patch also takes care of the validation case where bpp is forced via debugfs. Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_dp.c | 220 ++++++++++++++++++++---- 1 file changed, 182 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index d0c63888dfff..4d06f245110f 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1413,6 +1413,173 @@ static int intel_dp_dsc_compute_params(struct intel_encoder *encoder, return drm_dsc_compute_rc_parameters(vdsc_cfg); } +static bool is_dsc_bw_sufficient(int link_rate, int lane_count, int compressed_bpp, + const struct drm_display_mode *adjusted_mode) +{ + int mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock, compressed_bpp); + int link_avail = intel_dp_max_data_rate(link_rate, lane_count); + + return mode_rate <= link_avail; +} + +static int dsc_compute_link_config(struct intel_dp *intel_dp, + struct intel_crtc_state *pipe_config, + struct link_config_limits *limits, + int pipe_bpp, + u16 compressed_bpp) +{ + const struct drm_display_mode *adjusted_mode = + &pipe_config->hw.adjusted_mode; + int link_rate, lane_count; + int dsc_max_bpp; + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + int i; + + for (i = 0; i < intel_dp->num_common_rates; i++) { + link_rate = intel_dp_common_rate(intel_dp, i); + if (link_rate < limits->min_rate || link_rate > limits->max_rate) + continue; + + for (lane_count = limits->min_lane_count; + lane_count <= limits->max_lane_count; + lane_count <<= 1) { + dsc_max_bpp = intel_dp_dsc_get_output_bpp_max(dev_priv, + link_rate, + lane_count, + adjusted_mode->crtc_clock, + adjusted_mode->crtc_hdisplay, + pipe_config->bigjoiner_pipes, + pipe_bpp); + if (compressed_bpp > dsc_max_bpp) + continue; + + if (!is_dsc_bw_sufficient(link_rate, lane_count, + compressed_bpp, adjusted_mode)) + continue; + + pipe_config->lane_count = lane_count; + pipe_config->port_clock = link_rate; + + return 0; + } + } + + return -EINVAL; +} + +static int _dsc_compute_compressed_bpp(struct intel_dp *intel_dp, + struct intel_crtc_state *pipe_config, + struct link_config_limits *limits, + int pipe_bpp) +{ + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + u16 compressed_bpp; + int dsc_min_bpp, dsc_max_bpp; + int ret; + + dsc_min_bpp = 8; + if (DISPLAY_VER(dev_priv) <= 12) + dsc_max_bpp = 23; + else + dsc_max_bpp = 27; + + for (compressed_bpp = dsc_max_bpp; + compressed_bpp >= dsc_min_bpp; + compressed_bpp--) { + ret = dsc_compute_link_config(intel_dp, + pipe_config, + limits, + pipe_bpp, + compressed_bpp); + if (ret == 0) { + pipe_config->dsc.compressed_bpp = compressed_bpp; + return 0; + } + } + + return -EINVAL; +} + +static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp, + struct intel_crtc_state *pipe_config, + struct link_config_limits *limits, + int pipe_bpp) +{ + int ret; + + if (intel_dp->force_dsc_bpp) { + u16 compressed_bpp = intel_dp->force_dsc_bpp; + + ret = dsc_compute_link_config(intel_dp, + pipe_config, + limits, + pipe_bpp, + compressed_bpp); + if (ret == 0) + pipe_config->dsc.compressed_bpp = compressed_bpp; + + return ret; + } + + return _dsc_compute_compressed_bpp(intel_dp, pipe_config, limits, pipe_bpp); +} + +static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp, + struct intel_crtc_state *pipe_config, + struct drm_connector_state *conn_state, + struct link_config_limits *limits) +{ + struct drm_i915_private *i915 = dp_to_i915(intel_dp); + u8 dsc_bpc[3] = {0}; + u8 dsc_max_bpc, dsc_max_bpp; + u8 max_req_bpc = conn_state->max_requested_bpc; + int i, bpp, ret; + int num_bpc = drm_dp_dsc_sink_supported_input_bpcs(intel_dp->dsc_dpcd, + dsc_bpc); + + if (intel_dp->force_dsc_bpp) { + /* As of today we support DSC for only RGB */ + if (intel_dp->force_dsc_bpp < 8) + return -EINVAL; + } + + /* Max DSC Input BPC for ICL is 10 and for TGL+ is 12 */ + if (DISPLAY_VER(i915) >= 12) + dsc_max_bpc = min_t(u8, 12, limits->max_bpp); + else + dsc_max_bpc = min_t(u8, 10, max_req_bpc); + + dsc_max_bpp = min(dsc_max_bpc * 3, limits->max_bpp); + + /* + * Get the maximum DSC bpc that will be supported by any valid + * link configuration and compressed bpp. + */ + for (i = 0; i < num_bpc; i++) { + bpp = dsc_bpc[i] * 3; + + if (bpp < limits->min_bpp) + continue; + + if (bpp > limits->max_bpp) + break; + + ret = dsc_compute_compressed_bpp(intel_dp, pipe_config, + limits, bpp); + if (ret == 0) { + pipe_config->pipe_bpp = bpp; + + return 0; + } + } + + if (intel_dp->force_dsc_bpp) + drm_dbg_kms(&i915->drm, "Invalid DSC BPP %d for given mode", + intel_dp->force_dsc_bpp); + + return -EINVAL; +} + static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state, @@ -1440,16 +1607,11 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, return -EINVAL; } - /* - * For now enable DSC for max bpp, max link rate, max lane count. - * Optimize this later for the minimum possible link rate/lane count - * with DSC enabled for the requested mode. - */ - pipe_config->pipe_bpp = pipe_bpp_max; - pipe_config->port_clock = limits->max_rate; - pipe_config->lane_count = limits->max_lane_count; - if (intel_dp_is_edp(intel_dp)) { + pipe_config->pipe_bpp = pipe_bpp_max; + pipe_config->port_clock = limits->max_rate; + pipe_config->lane_count = limits->max_lane_count; + pipe_config->dsc.compressed_bpp = min_t(u16, drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) >> 4, pipe_config->pipe_bpp); @@ -1457,46 +1619,28 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd, true); } else { - u16 dsc_max_output_bpp; u8 dsc_dp_slice_count; - dsc_max_output_bpp = - intel_dp_dsc_get_output_bpp_max(dev_priv, - pipe_config->port_clock, - pipe_config->lane_count, - adjusted_mode->crtc_clock, - adjusted_mode->crtc_hdisplay, - pipe_config->bigjoiner_pipes, - pipe_bpp_max); + ret = intel_dp_dsc_compute_pipe_bpp(intel_dp, pipe_config, + conn_state, limits); + if (ret < 0) { + drm_dbg_kms(&dev_priv->drm, + "Cannot support mode with DSC with any link config\n"); + return ret; + } + dsc_dp_slice_count = intel_dp_dsc_get_slice_count(intel_dp, adjusted_mode->crtc_clock, adjusted_mode->crtc_hdisplay, pipe_config->bigjoiner_pipes); - if (!dsc_max_output_bpp || !dsc_dp_slice_count) { + if (!dsc_dp_slice_count) { drm_dbg_kms(&dev_priv->drm, - "Compressed BPP/Slice Count not supported\n"); + "Slice Count not supported\n"); return -EINVAL; } - pipe_config->dsc.compressed_bpp = min_t(u16, dsc_max_output_bpp, - pipe_config->pipe_bpp); - pipe_config->dsc.slice_count = dsc_dp_slice_count; - } - /* As of today we support DSC for only RGB */ - if (intel_dp->force_dsc_bpp) { - if (intel_dp->force_dsc_bpp >= 8 && - intel_dp->force_dsc_bpp < pipe_bpp_max) { - drm_dbg_kms(&dev_priv->drm, - "DSC BPP forced to %d", - intel_dp->force_dsc_bpp); - pipe_config->dsc.compressed_bpp = - intel_dp->force_dsc_bpp; - } else { - drm_dbg_kms(&dev_priv->drm, - "Invalid DSC BPP %d", - intel_dp->force_dsc_bpp); - } + pipe_config->dsc.slice_count = dsc_dp_slice_count; } /*