From patchwork Fri Apr 28 11:32:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [01/16] drm/i915/dp: Remove extra logs for printing DSC info From: Ankit Nautiyal X-Patchwork-Id: 534635 Message-Id: <20230428113242.635892-2-ankit.k.nautiyal@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Date: Fri, 28 Apr 2023 17:02:27 +0530 DSC compressed bpp and slice counts are already getting printed at the end of dsc compute config. Remove extra logs. Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_dp.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 80d95cec8f9d..93aebd3683a4 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1576,9 +1576,6 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, pipe_config->pipe_bpp); } pipe_config->dsc.slice_count = dsc_dp_slice_count; - drm_dbg_kms(&dev_priv->drm, "DSC: compressed bpp %d slice count %d\n", - pipe_config->dsc.compressed_bpp, - pipe_config->dsc.slice_count); } /* * VDSC engine operates at 1 Pixel per clock, so if peak pixel rate From patchwork Fri Apr 28 11:32:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [02/16] drm/i915/dp: Avoid forcing DSC BPC for MST case From: Ankit Nautiyal X-Patchwork-Id: 534636 Message-Id: <20230428113242.635892-3-ankit.k.nautiyal@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Date: Fri, 28 Apr 2023 17:02:28 +0530 For MST the bpc is hardcoded to 8, and pipe bpp to 24. So avoid forcing DSC bpc for MST case. Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_dp.c | 11 +++++------ drivers/gpu/drm/i915/display/intel_dp_mst.c | 8 ++++++++ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 93aebd3683a4..3d828ea0894d 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1500,14 +1500,13 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, if (!intel_dp_supports_dsc(intel_dp, pipe_config)) return -EINVAL; - if (compute_pipe_bpp) + if (intel_dp->force_dsc_bpc && compute_pipe_bpp) { + pipe_bpp = intel_dp->force_dsc_bpc * 3; + drm_dbg_kms(&dev_priv->drm, "Input DSC BPP forced to %d\n", pipe_bpp); + } else if (compute_pipe_bpp) { pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, conn_state->max_requested_bpc); - else + } else { pipe_bpp = pipe_config->pipe_bpp; - - if (intel_dp->force_dsc_bpc) { - pipe_bpp = intel_dp->force_dsc_bpc * 3; - drm_dbg_kms(&dev_priv->drm, "Input DSC BPP forced to %d", pipe_bpp); } /* Min Input BPC for ICL+ is 8 */ diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 8b0e4defa3f1..9be04c60cced 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -325,6 +325,14 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder, /* enable compression if the mode doesn't fit available BW */ drm_dbg_kms(&dev_priv->drm, "Force DSC en = %d\n", intel_dp->force_dsc_en); if (ret || intel_dp->force_dsc_en) { + if (intel_dp->force_dsc_bpc) { + /* + * FIXME: As bpc is hardcoed to 8 bpc as mentioned above, + * Avoid force BPC for now. + */ + drm_dbg_kms(&dev_priv->drm, "Cannot Force BPC for MST\n"); + return -EINVAL; + } /* * Try to get at least some timeslots and then see, if * we can fit there with DSC. From patchwork Fri Apr 28 11:32:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [03/16] drm/i915/dp: Do not check for min DSC BPC for MST case From: Ankit Nautiyal X-Patchwork-Id: 534637 Message-Id: <20230428113242.635892-4-ankit.k.nautiyal@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Date: Fri, 28 Apr 2023 17:02:29 +0530 For DSC the min BPC is 8 for ICL+ and so the min pipe_bpp is 24. Check this condition for cases only where pipe_bpp is to be computed. For MST case the pipe_bpp is already computed (hardcoded to be 24), and this check is not required. Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_dp.c | 46 ++++++++++++++++--------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 3d828ea0894d..d061fc3fa402 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1480,6 +1480,13 @@ static int intel_dp_dsc_compute_params(struct intel_encoder *encoder, return drm_dsc_compute_rc_parameters(vdsc_cfg); } +static +bool is_dsc_pipe_bpp_sufficient(struct drm_i915_private *i915, int pipe_bpp) +{ + /* Min Input BPC for ICL+ is 8 */ + return (pipe_bpp < 8 * 3); +} + int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state, @@ -1491,7 +1498,6 @@ 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 ret; pipe_config->fec_enable = !intel_dp_is_edp(intel_dp) && @@ -1501,27 +1507,35 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, return -EINVAL; if (intel_dp->force_dsc_bpc && compute_pipe_bpp) { - pipe_bpp = intel_dp->force_dsc_bpc * 3; - drm_dbg_kms(&dev_priv->drm, "Input DSC BPP forced to %d\n", pipe_bpp); - } else if (compute_pipe_bpp) { - pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, conn_state->max_requested_bpc); - } else { - pipe_bpp = pipe_config->pipe_bpp; - } + int forced_bpc = intel_dp->force_dsc_bpc; + int forced_bpp = forced_bpc * 3; - /* Min Input BPC for ICL+ is 8 */ - if (pipe_bpp < 8 * 3) { - drm_dbg_kms(&dev_priv->drm, - "No DSC support for less than 8bpc\n"); - return -EINVAL; + /* Min Input BPC for ICL+ is 8 */ + if (forced_bpc < 8) { + drm_dbg_kms(&dev_priv->drm, + "Cannot force dsc bpc:%d, due to dsc bpc limits\n", + intel_dp->force_dsc_bpc); + return -EINVAL; + } + pipe_config->pipe_bpp = forced_bpp; + drm_dbg_kms(&dev_priv->drm, "Input DSC BPP forced to %d\n", + pipe_config->pipe_bpp); + } else if (compute_pipe_bpp) { + int pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, + conn_state->max_requested_bpc); + if (!is_dsc_pipe_bpp_sufficient(dev_priv, pipe_bpp)) { + drm_dbg_kms(&dev_priv->drm, + "No DSC support for less than 8bpc\n"); + return -EINVAL; + } + pipe_config->pipe_bpp = pipe_bpp; } /* - * For now enable DSC for max bpp, max link rate, max lane count. + * For now enable DSC for 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; pipe_config->port_clock = limits->max_rate; pipe_config->lane_count = limits->max_lane_count; @@ -1544,7 +1558,7 @@ 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_config->pipe_bpp, timeslots); if (!dsc_max_output_bpp) { drm_dbg_kms(&dev_priv->drm, From patchwork Fri Apr 28 11:32:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [04/16] drm/i915/dp: Check if dsc forced bpc is in allowed limits From: Ankit Nautiyal X-Patchwork-Id: 534638 Message-Id: <20230428113242.635892-5-ankit.k.nautiyal@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Date: Fri, 28 Apr 2023 17:02:30 +0530 Add a check to use force DSC bpc only if it, along with the corresponding bpp are within allowed limits. Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_dp.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index d061fc3fa402..354dbd1d3164 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1510,19 +1510,20 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, int forced_bpc = intel_dp->force_dsc_bpc; int forced_bpp = forced_bpc * 3; - /* Min Input BPC for ICL+ is 8 */ - if (forced_bpc < 8) { + if (forced_bpc < 8 || /* Min Input BPC for ICL+ is 8 */ + forced_bpc > conn_state->max_requested_bpc || + forced_bpp < limits->min_bpp || + forced_bpp > limits->max_bpp) { drm_dbg_kms(&dev_priv->drm, - "Cannot force dsc bpc:%d, due to dsc bpc limits\n", + "Cannot force dsc bpc:%d, due to bpc/bpp limits\n", intel_dp->force_dsc_bpc); return -EINVAL; } pipe_config->pipe_bpp = forced_bpp; - drm_dbg_kms(&dev_priv->drm, "Input DSC BPP forced to %d\n", - pipe_config->pipe_bpp); + drm_dbg_kms(&dev_priv->drm, "Input DSC BPP forced to %d\n", pipe_config->pipe_bpp); } else if (compute_pipe_bpp) { - int pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, - conn_state->max_requested_bpc); + int pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, conn_state->max_requested_bpc); + if (!is_dsc_pipe_bpp_sufficient(dev_priv, pipe_bpp)) { drm_dbg_kms(&dev_priv->drm, "No DSC support for less than 8bpc\n"); @@ -1530,7 +1531,6 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, } pipe_config->pipe_bpp = pipe_bpp; } - /* * For now enable DSC for max link rate, max lane count. * Optimize this later for the minimum possible link rate/lane count From patchwork Fri Apr 28 11:32:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [05/16] drm/i915/dp: Avoid left shift of DSC output bpp by 4 From: Ankit Nautiyal X-Patchwork-Id: 534639 Message-Id: <20230428113242.635892-6-ankit.k.nautiyal@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Date: Fri, 28 Apr 2023 17:02:31 +0530 To make way for fractional bpp support, avoid left shifting the output_bpp by 4 in helper intel_dp_dsc_get_output_bpp. Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_dp.c | 10 +++------- drivers/gpu/drm/i915/display/intel_dp_mst.c | 2 +- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 354dbd1d3164..c52e9979f0a4 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -749,11 +749,7 @@ u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915, bits_per_pixel = intel_dp_dsc_nearest_valid_bpp(i915, bits_per_pixel, pipe_bpp); - /* - * 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; } u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp, @@ -1050,7 +1046,7 @@ intel_dp_mode_valid(struct drm_connector *_connector, target_clock, mode->hdisplay, bigjoiner, - pipe_bpp, 64) >> 4; + pipe_bpp, 64); dsc_slice_count = intel_dp_dsc_get_slice_count(intel_dp, target_clock, @@ -1585,7 +1581,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, */ if (compute_pipe_bpp) { pipe_config->dsc.compressed_bpp = min_t(u16, - dsc_max_output_bpp >> 4, + dsc_max_output_bpp, pipe_config->pipe_bpp); } pipe_config->dsc.slice_count = dsc_dp_slice_count; diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 9be04c60cced..5b65e4c2c78f 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -921,7 +921,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector, target_clock, mode->hdisplay, bigjoiner, - pipe_bpp, 64) >> 4; + pipe_bpp, 64); dsc_slice_count = intel_dp_dsc_get_slice_count(intel_dp, target_clock, From patchwork Fri Apr 28 11:32:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [06/16] drm/i915/dp: Rename helpers to get DSC max pipe_bpp/output_bpp From: Ankit Nautiyal X-Patchwork-Id: 534640 Message-Id: <20230428113242.635892-7-ankit.k.nautiyal@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Date: Fri, 28 Apr 2023 17:02:32 +0530 Currently 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. Similarly, the helper intel_dp_dsc_compute_bpp gives the maximum pipe bpp that is allowed with DSC. Rename the functions to reflect that these return max DSC input and output bpps. Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_dp.c | 48 ++++++++++----------- drivers/gpu/drm/i915/display/intel_dp.h | 14 +++--- drivers/gpu/drm/i915/display/intel_dp_mst.c | 16 +++---- 3 files changed, 39 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index c52e9979f0a4..c0b96cfb7528 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -702,12 +702,12 @@ u32 intel_dp_dsc_nearest_valid_bpp(struct drm_i915_private *i915, u32 bpp, u32 p return bits_per_pixel; } -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, - u32 timeslots) +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 timeslots) { u32 bits_per_pixel, max_bpp_small_joiner_ram; @@ -1030,7 +1030,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 = intel_dp_dsc_get_bpp_max(intel_dp, U8_MAX); if (intel_dp_is_edp(intel_dp)) { dsc_max_output_bpp = @@ -1040,13 +1040,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, 64); + intel_dp_dsc_get_output_bpp_max(dev_priv, + max_link_clock, + max_lanes, + target_clock, + mode->hdisplay, + bigjoiner, + pipe_bpp, 64); dsc_slice_count = intel_dp_dsc_get_slice_count(intel_dp, target_clock, @@ -1375,7 +1375,7 @@ intel_dp_compute_link_config_wide(struct intel_dp *intel_dp, return -EINVAL; } -int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 max_req_bpc) +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; @@ -1518,7 +1518,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, pipe_config->pipe_bpp = forced_bpp; drm_dbg_kms(&dev_priv->drm, "Input DSC BPP forced to %d\n", pipe_config->pipe_bpp); } else if (compute_pipe_bpp) { - int pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, conn_state->max_requested_bpc); + int pipe_bpp = intel_dp_dsc_get_bpp_max(intel_dp, conn_state->max_requested_bpc); if (!is_dsc_pipe_bpp_sufficient(dev_priv, pipe_bpp)) { drm_dbg_kms(&dev_priv->drm, @@ -1548,14 +1548,14 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, if (compute_pipe_bpp) { 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_config->pipe_bpp, - timeslots); + 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_config->pipe_bpp, + timeslots); if (!dsc_max_output_bpp) { drm_dbg_kms(&dev_priv->drm, "Compressed BPP not supported\n"); diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index ef39e4f7a329..7cb8227a4d1e 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -102,13 +102,13 @@ void intel_read_dp_sdp(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state, unsigned int type); bool intel_digital_port_connected(struct intel_encoder *encoder); -int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc); -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, - u32 timeslots); +int intel_dp_dsc_get_bpp_max(struct intel_dp *intel_dp, u8 dsc_max_bpc); +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 timeslots); u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp, int mode_clock, int mode_hdisplay, bool bigjoiner); diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 5b65e4c2c78f..df19691776ca 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -911,17 +911,17 @@ intel_dp_mst_mode_valid_ctx(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 = intel_dp_dsc_get_bpp_max(intel_dp, U8_MAX); 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, 64); + intel_dp_dsc_get_output_bpp_max(dev_priv, + max_link_clock, + max_lanes, + target_clock, + mode->hdisplay, + bigjoiner, + pipe_bpp, 64); dsc_slice_count = intel_dp_dsc_get_slice_count(intel_dp, target_clock, From patchwork Fri Apr 28 11:32:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [07/16] drm/i915/dp: Get optimal link config to have best compressed bpp From: Ankit Nautiyal X-Patchwork-Id: 534642 Message-Id: <20230428113242.635892-8-ankit.k.nautiyal@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Date: Fri, 28 Apr 2023 17:02:33 +0530 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. v2: -Avoid ending up with compressed bpp, same as pipe bpp. (Stan) -Fix the checks for limits->max/min_bpp while iterating over list of valid DSC bpcs. (Stan) v3: -Refactor the code to have pipe bpp/compressed bpp computation and slice count calculation separately for different cases. Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_dp.c | 278 ++++++++++++++++++++---- 1 file changed, 232 insertions(+), 46 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index c0b96cfb7528..885d2f75ddbf 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1476,6 +1476,195 @@ 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, 64); + 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 u16 dsc_max_sink_compressed_bppx16(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE], + struct intel_crtc_state *pipe_config, + int bpc) +{ + u16 max_bppx16 = dsc_dpcd[DP_DSC_MAX_BITS_PER_PIXEL_LOW - DP_DSC_SUPPORT] | + (dsc_dpcd[DP_DSC_MAX_BITS_PER_PIXEL_HI - DP_DSC_SUPPORT] & + DP_DSC_MAX_BITS_PER_PIXEL_HI_MASK << DP_DSC_MAX_BITS_PER_PIXEL_HI_SHIFT); + + if (max_bppx16) + return max_bppx16; + /* + * If support not given in DPCD 67h, 68h use the Maximum Allowed bit rate + * values as given in spec Table 2-157 DP v2.0 + */ + switch (pipe_config->output_format) { + case INTEL_OUTPUT_FORMAT_RGB: + case INTEL_OUTPUT_FORMAT_YCBCR444: + return (3 * bpc) << 4; + case INTEL_OUTPUT_FORMAT_YCBCR420: + return (3 * (bpc / 2)) << 4; + default: + MISSING_CASE(pipe_config->output_format); + break; + } + + return 0; +} + +static u16 dsc_min_compressed_bppx16(struct intel_crtc_state *pipe_config) +{ + switch (pipe_config->output_format) { + case INTEL_OUTPUT_FORMAT_RGB: + case INTEL_OUTPUT_FORMAT_YCBCR444: + return 8 << 4; + case INTEL_OUTPUT_FORMAT_YCBCR420: + return 6 << 4; + default: + MISSING_CASE(pipe_config->output_format); + break; + } + + return 0; +} + +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_src_max_bpp, dsc_sink_max_bpp, dsc_max_bpp; + int ret; + + dsc_min_bpp = max(dsc_min_compressed_bppx16(pipe_config) >> 4, 8); + if (DISPLAY_VER(dev_priv) <= 12) + dsc_src_max_bpp = 23; + else + dsc_src_max_bpp = 27; + dsc_sink_max_bpp = dsc_max_sink_compressed_bppx16(intel_dp->dsc_dpcd, + pipe_config, pipe_bpp / 3) >> 4; + + dsc_max_bpp = dsc_sink_max_bpp ? min(dsc_sink_max_bpp, dsc_src_max_bpp) : dsc_src_max_bpp; + + /* Compressed BPP should be less than the Input DSC bpp */ + dsc_max_bpp = min(dsc_max_bpp, pipe_bpp - 1); + + 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 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 dsc_min_bpc, dsc_min_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); + + /* 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, max_req_bpc); + else + dsc_max_bpc = min_t(u8, 10, max_req_bpc); + + dsc_max_bpp = min(dsc_max_bpc * 3, limits->max_bpp); + + /* Min DSC Input BPC for ICL+ is 8 */ + dsc_min_bpc = 8; + dsc_min_bpp = max(dsc_min_bpc * 3, limits->min_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 < dsc_min_bpp) + break; + + if (bpp > dsc_max_bpp) + continue; + + ret = dsc_compute_compressed_bpp(intel_dp, pipe_config, + limits, bpp); + if (ret == 0) { + pipe_config->pipe_bpp = bpp; + + return 0; + } + } + + return -EINVAL; +} + static bool is_dsc_pipe_bpp_sufficient(struct drm_i915_private *i915, int pipe_bpp) { @@ -1502,6 +1691,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, if (!intel_dp_supports_dsc(intel_dp, pipe_config)) return -EINVAL; + /* Compute DSC input BPP and output/compressed BPP */ if (intel_dp->force_dsc_bpc && compute_pipe_bpp) { int forced_bpc = intel_dp->force_dsc_bpc; int forced_bpp = forced_bpc * 3; @@ -1515,53 +1705,61 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, intel_dp->force_dsc_bpc); return -EINVAL; } + if (dsc_compute_compressed_bpp(intel_dp, pipe_config, + limits, forced_bpp)) { + drm_dbg_kms(&dev_priv->drm, + "Compressed BPP not supported with forced bpc = %d\n", + intel_dp->force_dsc_bpc); + return -EINVAL; + } + pipe_config->pipe_bpp = forced_bpp; drm_dbg_kms(&dev_priv->drm, "Input DSC BPP forced to %d\n", pipe_config->pipe_bpp); } else if (compute_pipe_bpp) { + /* + * compute pipe bpp is set to false for DP MST DSC case + * and compressed_bpp is calculated same time once + * vpci timeslots are allocated, because overall bpp + * calculation procedure is bit different for MST case. + */ int pipe_bpp = intel_dp_dsc_get_bpp_max(intel_dp, conn_state->max_requested_bpc); - if (!is_dsc_pipe_bpp_sufficient(dev_priv, pipe_bpp)) { - drm_dbg_kms(&dev_priv->drm, - "No DSC support for less than 8bpc\n"); - return -EINVAL; + if (intel_dp_is_edp(intel_dp)) { + /* For eDP use max bpp that can be supported with DSC. */ + pipe_bpp = intel_dp_dsc_get_bpp_max(intel_dp, + conn_state->max_requested_bpc); + if (!is_dsc_pipe_bpp_sufficient(dev_priv, pipe_bpp)) { + drm_dbg_kms(&dev_priv->drm, + "No DSC support for less than 8bpc\n"); + return -EINVAL; + } + pipe_config->pipe_bpp = pipe_bpp; + 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); + } else { + /* + * For DP compute the optimal pipe bpp, link rate and + * num lanes with DSC. + */ + ret = intel_dp_dsc_compute_pipe_bpp(intel_dp, pipe_config, + conn_state, limits); + if (ret) { + drm_dbg_kms(&dev_priv->drm, + "No Valid pipe bpp for given mode\n"); + return ret; + } } - pipe_config->pipe_bpp = pipe_bpp; } - /* - * For now enable DSC for 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->port_clock = limits->max_rate; - pipe_config->lane_count = limits->max_lane_count; - + /* Calculate Slice count */ if (intel_dp_is_edp(intel_dp)) { - pipe_config->dsc.compressed_bpp = - min_t(u16, drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) >> 4, - pipe_config->pipe_bpp); pipe_config->dsc.slice_count = drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd, true); } else { - u16 dsc_max_output_bpp = 0; u8 dsc_dp_slice_count; - - if (compute_pipe_bpp) { - 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_config->pipe_bpp, - timeslots); - if (!dsc_max_output_bpp) { - drm_dbg_kms(&dev_priv->drm, - "Compressed BPP not supported\n"); - return -EINVAL; - } - } dsc_dp_slice_count = intel_dp_dsc_get_slice_count(intel_dp, adjusted_mode->crtc_clock, @@ -1572,18 +1770,6 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, "Compressed Slice Count not supported\n"); return -EINVAL; } - - /* - * compute pipe bpp is set to false for DP MST DSC case - * and compressed_bpp is calculated same time once - * vpci timeslots are allocated, because overall bpp - * calculation procedure is bit different for MST case. - */ - if (compute_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 Fri Apr 28 11:32:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [08/16] drm/i915/display: Store compressed bpp in U6.4 format From: Ankit Nautiyal X-Patchwork-Id: 534641 Message-Id: <20230428113242.635892-9-ankit.k.nautiyal@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Date: Fri, 28 Apr 2023 17:02:34 +0530 DSC parameter bits_per_pixel is stored in U6.4 format. The 4 bits represent the fractional part of the bpp. Currently we use compressed_bpp member of dsc structure to store only the integral part of the bits_per_pixel. To store the full bits_per_pixel along with the fractional part, compressed_bpp is changed to store bpp in U6.4 formats. Intergral part is retrieved by simply right shifting the member compressed_bpp by 4. Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/icl_dsi.c | 10 ++++---- drivers/gpu/drm/i915/display/intel_audio.c | 2 +- drivers/gpu/drm/i915/display/intel_bios.c | 2 +- .../drm/i915/display/intel_display_types.h | 16 +++++++++++- drivers/gpu/drm/i915/display/intel_dp.c | 25 +++++++++++-------- drivers/gpu/drm/i915/display/intel_vdsc.c | 4 +-- 6 files changed, 38 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c index ae14c794c4bc..f387450c4be2 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -343,7 +343,7 @@ static int afe_clk(struct intel_encoder *encoder, int bpp; if (crtc_state->dsc.compression_enable) - bpp = crtc_state->dsc.compressed_bpp; + bpp = dsc_integral_compressed_bpp(crtc_state->dsc.compressed_bpp); else bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format); @@ -903,7 +903,7 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder, * compressed and non-compressed bpp. */ if (crtc_state->dsc.compression_enable) { - mul = crtc_state->dsc.compressed_bpp; + mul = dsc_integral_compressed_bpp(crtc_state->dsc.compressed_bpp); div = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format); } @@ -927,7 +927,7 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder, int bpp, line_time_us, byte_clk_period_ns; if (crtc_state->dsc.compression_enable) - bpp = crtc_state->dsc.compressed_bpp; + bpp = dsc_integral_compressed_bpp(crtc_state->dsc.compressed_bpp); else bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format); @@ -1500,8 +1500,8 @@ static void gen11_dsi_get_timings(struct intel_encoder *encoder, struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; - if (pipe_config->dsc.compressed_bpp) { - int div = pipe_config->dsc.compressed_bpp; + if (dsc_integral_compressed_bpp(pipe_config->dsc.compressed_bpp)) { + int div = dsc_integral_compressed_bpp(pipe_config->dsc.compressed_bpp); int mul = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format); adjusted_mode->crtc_htotal = diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c index 626c47e96a6d..a73cf477b5e6 100644 --- a/drivers/gpu/drm/i915/display/intel_audio.c +++ b/drivers/gpu/drm/i915/display/intel_audio.c @@ -517,7 +517,7 @@ static unsigned int calc_hblank_early_prog(struct intel_encoder *encoder, h_active = crtc_state->hw.adjusted_mode.crtc_hdisplay; h_total = crtc_state->hw.adjusted_mode.crtc_htotal; pixel_clk = crtc_state->hw.adjusted_mode.crtc_clock; - vdsc_bpp = crtc_state->dsc.compressed_bpp; + vdsc_bpp = dsc_integral_compressed_bpp(crtc_state->dsc.compressed_bpp); cdclk = i915->display.cdclk.hw.cdclk; /* fec= 0.972261, using rounding multiplier of 1000000 */ fec_coeff = 972261; diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index 78abe34c7a42..75343bca8750 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -3482,7 +3482,7 @@ static void fill_dsc(struct intel_crtc_state *crtc_state, crtc_state->pipe_bpp = bpc * 3; crtc_state->dsc.compressed_bpp = min(crtc_state->pipe_bpp, - VBT_DSC_MAX_BPP(dsc->max_bpp)); + VBT_DSC_MAX_BPP(dsc->max_bpp)) << 4; /* * FIXME: This is ugly, and slice count should take DSC engine diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 32e8b2fc3cc6..e879a9483148 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1283,7 +1283,7 @@ struct intel_crtc_state { struct { bool compression_enable; bool dsc_split; - u16 compressed_bpp; + u16 compressed_bpp; /* U6.4 format (first 4 bits for fractional part) */ u8 slice_count; struct drm_dsc_config config; } dsc; @@ -2062,4 +2062,18 @@ to_intel_frontbuffer(struct drm_framebuffer *fb) return fb ? to_intel_framebuffer(fb)->frontbuffer : NULL; } +/* Returns integral part of the compressed bpp given in U6.4 format */ +static inline int +dsc_integral_compressed_bpp(u16 compressed_bpp) +{ + return compressed_bpp >> 4; +} + +/* Returns fractional part of the compressed bpp given in U6.4 format */ +static inline int +dsc_fractional_compressed_bpp(u16 compressed_bpp) +{ + return ((compressed_bpp & 0xF) * 10000 / 16); +} + #endif /* __INTEL_DISPLAY_TYPES_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 885d2f75ddbf..ce7bffbdad9e 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1606,7 +1606,7 @@ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp, pipe_bpp, compressed_bpp); if (ret == 0) { - pipe_config->dsc.compressed_bpp = compressed_bpp; + pipe_config->dsc.compressed_bpp = compressed_bpp << 4; return 0; } } @@ -1737,8 +1737,8 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, 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); + min_t(u16, drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd), + pipe_config->pipe_bpp << 4); } else { /* * For DP compute the optimal pipe bpp, link rate and @@ -1792,17 +1792,19 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, if (ret < 0) { drm_dbg_kms(&dev_priv->drm, "Cannot compute valid DSC parameters for Input Bpp = %d " - "Compressed BPP = %d\n", + "Compressed BPP = %d.%d\n", pipe_config->pipe_bpp, - pipe_config->dsc.compressed_bpp); + dsc_integral_compressed_bpp(pipe_config->dsc.compressed_bpp), + dsc_fractional_compressed_bpp(pipe_config->dsc.compressed_bpp)); return ret; } pipe_config->dsc.compression_enable = true; drm_dbg_kms(&dev_priv->drm, "DP DSC computed with Input Bpp = %d " - "Compressed Bpp = %d Slice Count = %d\n", + "Compressed Bpp = %d.%d Slice Count = %d\n", pipe_config->pipe_bpp, - pipe_config->dsc.compressed_bpp, + dsc_integral_compressed_bpp(pipe_config->dsc.compressed_bpp), + dsc_fractional_compressed_bpp(pipe_config->dsc.compressed_bpp), pipe_config->dsc.slice_count); return 0; @@ -1881,15 +1883,16 @@ intel_dp_compute_link_config(struct intel_encoder *encoder, if (pipe_config->dsc.compression_enable) { drm_dbg_kms(&i915->drm, - "DP lane count %d clock %d Input bpp %d Compressed bpp %d\n", + "DP lane count %d clock %d Input bpp %d Compressed bpp %d.%d\n", pipe_config->lane_count, pipe_config->port_clock, pipe_config->pipe_bpp, - pipe_config->dsc.compressed_bpp); + dsc_integral_compressed_bpp(pipe_config->dsc.compressed_bpp), + dsc_fractional_compressed_bpp(pipe_config->dsc.compressed_bpp)); drm_dbg_kms(&i915->drm, "DP link rate required %i available %i\n", intel_dp_link_required(adjusted_mode->crtc_clock, - pipe_config->dsc.compressed_bpp), + dsc_integral_compressed_bpp(pipe_config->dsc.compressed_bpp)), intel_dp_max_data_rate(pipe_config->port_clock, pipe_config->lane_count)); } else { @@ -2315,7 +2318,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, intel_dp_limited_color_range(pipe_config, conn_state); if (pipe_config->dsc.compression_enable) - output_bpp = pipe_config->dsc.compressed_bpp; + output_bpp = dsc_integral_compressed_bpp(pipe_config->dsc.compressed_bpp); else output_bpp = intel_dp_output_bpp(pipe_config->output_format, pipe_config->pipe_bpp); diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c index 207b2a648d32..ed5c85229414 100644 --- a/drivers/gpu/drm/i915/display/intel_vdsc.c +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c @@ -452,7 +452,7 @@ int intel_dsc_compute_params(struct intel_crtc_state *pipe_config) struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct drm_dsc_config *vdsc_cfg = &pipe_config->dsc.config; - u16 compressed_bpp = pipe_config->dsc.compressed_bpp; + u16 compressed_bpp = dsc_integral_compressed_bpp(pipe_config->dsc.compressed_bpp); const struct rc_parameters *rc_params; struct rc_parameters *rc = NULL; u8 i = 0; @@ -1210,7 +1210,7 @@ void intel_dsc_get_config(struct intel_crtc_state *crtc_state) val = intel_de_read(dev_priv, ICL_DSC0_PICTURE_PARAMETER_SET_1(pipe)); vdsc_cfg->bits_per_pixel = val; - crtc_state->dsc.compressed_bpp = vdsc_cfg->bits_per_pixel >> 4; + crtc_state->dsc.compressed_bpp = vdsc_cfg->bits_per_pixel; out: intel_display_power_put(dev_priv, power_domain, wakeref); } From patchwork Fri Apr 28 11:32:35 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [09/16] drm/i915/display: Consider fractional vdsc bpp while computing m_n values From: Ankit Nautiyal X-Patchwork-Id: 534643 Message-Id: <20230428113242.635892-10-ankit.k.nautiyal@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Date: Fri, 28 Apr 2023 17:02:35 +0530 MTL+ supports fractional compressed bits_per_pixel, with precision of 1/16. This compressed bpp is stored in U6.4 format. Accommodate this precision while computing m_n values. Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_display.c | 6 +++++- drivers/gpu/drm/i915/display/intel_display.h | 2 +- drivers/gpu/drm/i915/display/intel_dp.c | 7 ++++--- drivers/gpu/drm/i915/display/intel_dp_mst.c | 6 ++++-- drivers/gpu/drm/i915/display/intel_fdi.c | 2 +- 5 files changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 734e8e613f8e..9912930890d0 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2748,10 +2748,14 @@ void intel_link_compute_m_n(u16 bits_per_pixel, int nlanes, int pixel_clock, int link_clock, struct intel_link_m_n *m_n, - bool fec_enable) + bool fec_enable, + bool is_dsc_fractional_bpp) { u32 data_clock = bits_per_pixel * pixel_clock; + if (is_dsc_fractional_bpp) + data_clock = DIV_ROUND_UP(bits_per_pixel * pixel_clock, 16); + if (fec_enable) data_clock = intel_dp_mode_to_fec_clock(data_clock); diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index ef73730f32b0..3c2016edad18 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -514,7 +514,7 @@ u8 intel_calc_active_pipes(struct intel_atomic_state *state, void intel_link_compute_m_n(u16 bpp, int nlanes, int pixel_clock, int link_clock, struct intel_link_m_n *m_n, - bool fec_enable); + bool fec_enable, bool is_dsc_fractional_bpp); u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv, u32 pixel_format, u64 modifier); enum drm_mode_status diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index ce7bffbdad9e..3d08acb4505a 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2178,7 +2178,7 @@ intel_dp_drrs_compute_config(struct intel_connector *connector, intel_link_compute_m_n(output_bpp, pipe_config->lane_count, pixel_clock, pipe_config->port_clock, &pipe_config->dp_m2_n2, - pipe_config->fec_enable); + pipe_config->fec_enable, false); /* FIXME: abstract this better */ if (pipe_config->splitter.enable) @@ -2318,7 +2318,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, intel_dp_limited_color_range(pipe_config, conn_state); if (pipe_config->dsc.compression_enable) - output_bpp = dsc_integral_compressed_bpp(pipe_config->dsc.compressed_bpp); + output_bpp = pipe_config->dsc.compressed_bpp; else output_bpp = intel_dp_output_bpp(pipe_config->output_format, pipe_config->pipe_bpp); @@ -2350,7 +2350,8 @@ intel_dp_compute_config(struct intel_encoder *encoder, adjusted_mode->crtc_clock, pipe_config->port_clock, &pipe_config->dp_m_n, - pipe_config->fec_enable); + pipe_config->fec_enable, + pipe_config->dsc.compression_enable); /* FIXME: abstract this better */ if (pipe_config->splitter.enable) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index df19691776ca..67d6e261eb68 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -143,7 +143,8 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder, adjusted_mode->crtc_clock, crtc_state->port_clock, &crtc_state->dp_m_n, - crtc_state->fec_enable); + crtc_state->fec_enable, + false); crtc_state->dp_m_n.tu = slots; return 0; @@ -237,7 +238,8 @@ static int intel_dp_dsc_mst_compute_link_config(struct intel_encoder *encoder, adjusted_mode->crtc_clock, crtc_state->port_clock, &crtc_state->dp_m_n, - crtc_state->fec_enable); + crtc_state->fec_enable, + crtc_state->dsc.compression_enable); crtc_state->dp_m_n.tu = slots; return 0; diff --git a/drivers/gpu/drm/i915/display/intel_fdi.c b/drivers/gpu/drm/i915/display/intel_fdi.c index 063f1da4f229..5ab6c2e983d5 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.c +++ b/drivers/gpu/drm/i915/display/intel_fdi.c @@ -257,7 +257,7 @@ int ilk_fdi_compute_config(struct intel_crtc *crtc, pipe_config->fdi_lanes = lane; intel_link_compute_m_n(pipe_config->pipe_bpp, lane, fdi_dotclock, - link_bw, &pipe_config->fdi_m_n, false); + link_bw, &pipe_config->fdi_m_n, false, false); ret = ilk_check_fdi_lanes(dev, crtc->pipe, pipe_config); if (ret == -EDEADLK) From patchwork Fri Apr 28 11:32:36 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [10/16] drm/i915/audio : Consider fractional vdsc bpp while computing tu_data From: Ankit Nautiyal X-Patchwork-Id: 534644 Message-Id: <20230428113242.635892-11-ankit.k.nautiyal@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Date: Fri, 28 Apr 2023 17:02:36 +0530 MTL+ supports fractional compressed bits_per_pixel, with precision of 1/16. This compressed bpp is stored in U6.4 format. Accommodate the precision during calculation of transfer unit data for hblank_early calculation. v2: -Fixed tu_data calculation while dealing with U6.4 format. (Stan) Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_audio.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c index a73cf477b5e6..30d75f637793 100644 --- a/drivers/gpu/drm/i915/display/intel_audio.c +++ b/drivers/gpu/drm/i915/display/intel_audio.c @@ -510,14 +510,14 @@ static unsigned int calc_hblank_early_prog(struct intel_encoder *encoder, unsigned int link_clks_available, link_clks_required; unsigned int tu_data, tu_line, link_clks_active; unsigned int h_active, h_total, hblank_delta, pixel_clk; - unsigned int fec_coeff, cdclk, vdsc_bpp; + unsigned int fec_coeff, cdclk, vdsc_bppx16; unsigned int link_clk, lanes; unsigned int hblank_rise; h_active = crtc_state->hw.adjusted_mode.crtc_hdisplay; h_total = crtc_state->hw.adjusted_mode.crtc_htotal; pixel_clk = crtc_state->hw.adjusted_mode.crtc_clock; - vdsc_bpp = dsc_integral_compressed_bpp(crtc_state->dsc.compressed_bpp); + vdsc_bppx16 = crtc_state->dsc.compressed_bpp; cdclk = i915->display.cdclk.hw.cdclk; /* fec= 0.972261, using rounding multiplier of 1000000 */ fec_coeff = 972261; @@ -525,10 +525,10 @@ static unsigned int calc_hblank_early_prog(struct intel_encoder *encoder, lanes = crtc_state->lane_count; drm_dbg_kms(&i915->drm, "h_active = %u link_clk = %u :" - "lanes = %u vdsc_bpp = %u cdclk = %u\n", - h_active, link_clk, lanes, vdsc_bpp, cdclk); + "lanes = %u vdsc_bppx16 = %u cdclk = %u\n", + h_active, link_clk, lanes, vdsc_bppx16, cdclk); - if (WARN_ON(!link_clk || !pixel_clk || !lanes || !vdsc_bpp || !cdclk)) + if (WARN_ON(!link_clk || !pixel_clk || !lanes || !vdsc_bppx16 || !cdclk)) return 0; link_clks_available = (h_total - h_active) * link_clk / pixel_clk - 28; @@ -540,8 +540,8 @@ static unsigned int calc_hblank_early_prog(struct intel_encoder *encoder, hblank_delta = DIV64_U64_ROUND_UP(mul_u32_u32(5 * (link_clk + cdclk), pixel_clk), mul_u32_u32(link_clk, cdclk)); - tu_data = div64_u64(mul_u32_u32(pixel_clk * vdsc_bpp * 8, 1000000), - mul_u32_u32(link_clk * lanes, fec_coeff)); + tu_data = div64_u64(mul_u32_u32(pixel_clk * vdsc_bppx16 * 8, 1000000), + mul_u32_u32(link_clk * lanes * 16, fec_coeff)); tu_line = div64_u64(h_active * mul_u32_u32(link_clk, fec_coeff), mul_u32_u32(64 * pixel_clk, 1000000)); link_clks_active = (tu_line - 1) * 64 + tu_data; From patchwork Fri Apr 28 11:32:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [11/16] drm/display/dp: Fix the DP DSC Receiver cap size From: Ankit Nautiyal X-Patchwork-Id: 534645 Message-Id: <20230428113242.635892-12-ankit.k.nautiyal@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Date: Fri, 28 Apr 2023 17:02:37 +0530 DP DSC Receiver Capabilities are exposed via DPCD 60h-6Fh. Fix the DSC RECEIVER CAP SIZE accordingly. Fixes: ffddc4363c28 ("drm/dp: Add DP DSC DPCD receiver capability size define and missing SHIFT") Cc: Anusha Srivatsa Cc: Manasi Navare Cc: # v5.0+ Reported-by: kernel test robot Signed-off-by: Ankit Nautiyal --- include/drm/display/drm_dp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h index 632376c291db..bdc05593f462 100644 --- a/include/drm/display/drm_dp.h +++ b/include/drm/display/drm_dp.h @@ -1532,7 +1532,7 @@ enum drm_dp_phy { #define DP_BRANCH_OUI_HEADER_SIZE 0xc #define DP_RECEIVER_CAP_SIZE 0xf -#define DP_DSC_RECEIVER_CAP_SIZE 0xf +#define DP_DSC_RECEIVER_CAP_SIZE 0x10 /* DSC Capabilities 0x60 through 0x6F */ #define EDP_PSR_RECEIVER_CAP_SIZE 2 #define EDP_DISPLAY_CTL_CAP_SIZE 3 #define DP_LTTPR_COMMON_CAP_SIZE 8 From patchwork Fri Apr 28 11:32:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [12/16] drm/display/dp: Add helper function to get DSC bpp prescision From: Ankit Nautiyal X-Patchwork-Id: 534646 Message-Id: <20230428113242.635892-13-ankit.k.nautiyal@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Date: Fri, 28 Apr 2023 17:02:38 +0530 Add helper to get the DSC bits_per_pixel precision for the DP sink. Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/display/drm_dp_helper.c | 27 +++++++++++++++++++++++++ include/drm/display/drm_dp_helper.h | 1 + 2 files changed, 28 insertions(+) diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c index 16565a0a5da6..db3288af4032 100644 --- a/drivers/gpu/drm/display/drm_dp_helper.c +++ b/drivers/gpu/drm/display/drm_dp_helper.c @@ -2323,6 +2323,33 @@ int drm_dp_read_desc(struct drm_dp_aux *aux, struct drm_dp_desc *desc, } EXPORT_SYMBOL(drm_dp_read_desc); +/** + * drm_dp_dsc_sink_bpp_incr() - Get bits per pixel increment + * @dsc_dpcd: DSC capabilities from DPCD + * + * Returns the bpp precision supported by the DP sink. + */ +u8 drm_dp_dsc_sink_bpp_incr(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]) +{ + u8 bpp_increment_dpcd = dsc_dpcd[DP_DSC_BITS_PER_PIXEL_INC - DP_DSC_SUPPORT]; + + switch (bpp_increment_dpcd) { + case DP_DSC_BITS_PER_PIXEL_1_16: + return 16; + case DP_DSC_BITS_PER_PIXEL_1_8: + return 8; + case DP_DSC_BITS_PER_PIXEL_1_4: + return 4; + case DP_DSC_BITS_PER_PIXEL_1_2: + return 2; + case DP_DSC_BITS_PER_PIXEL_1_1: + return 1; + } + + return 0; +} +EXPORT_SYMBOL(drm_dp_dsc_sink_bpp_incr); + /** * drm_dp_dsc_sink_max_slice_count() - Get the max slice count * supported by the DSC sink. diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h index ab55453f2d2c..0a0306b2e829 100644 --- a/include/drm/display/drm_dp_helper.h +++ b/include/drm/display/drm_dp_helper.h @@ -164,6 +164,7 @@ drm_dp_is_branch(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) } /* DP/eDP DSC support */ +u8 drm_dp_dsc_sink_bpp_incr(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]); u8 drm_dp_dsc_sink_max_slice_count(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE], bool is_edp); u8 drm_dp_dsc_sink_line_buf_depth(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]); From patchwork Fri Apr 28 11:32:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [13/16] drm/i915/dsc/mtl: Add support for fractional bpp From: Ankit Nautiyal X-Patchwork-Id: 534649 Message-Id: <20230428113242.635892-14-ankit.k.nautiyal@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Date: Fri, 28 Apr 2023 17:02:39 +0530 From: Vandita Kulkarni Consider the fractional bpp while reading the qp values. Signed-off-by: Vandita Kulkarni Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_qp_tables.c | 3 --- drivers/gpu/drm/i915/display/intel_vdsc.c | 12 +++++++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_qp_tables.c b/drivers/gpu/drm/i915/display/intel_qp_tables.c index 6f8e4ec5c0fb..a0094287dc81 100644 --- a/drivers/gpu/drm/i915/display/intel_qp_tables.c +++ b/drivers/gpu/drm/i915/display/intel_qp_tables.c @@ -21,9 +21,6 @@ * These qp tables are as per the C model * and it has the rows pointing to bpps which increment * in steps of 0.5 - * We do not support fractional bpps as of today, - * hence we would skip the fractional bpps during - * our references for qp calclulations. */ static const u8 rc_range_minqp444_8bpc[DSC_NUM_BUF_RANGES][RC_RANGE_QP444_8BPC_MAX_NUM_BPP] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c index ed5c85229414..3e39f682b19f 100644 --- a/drivers/gpu/drm/i915/display/intel_vdsc.c +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c @@ -378,6 +378,7 @@ calculate_rc_params(struct rc_parameters *rc, { int bpc = vdsc_cfg->bits_per_component; int bpp = vdsc_cfg->bits_per_pixel >> 4; + int fractional_bits = vdsc_cfg->bits_per_pixel & 0xf; static const s8 ofs_und6[] = { 0, -2, -2, -4, -6, -6, -8, -8, -8, -10, -10, -12, -12, -12, -12 }; @@ -418,7 +419,13 @@ calculate_rc_params(struct rc_parameters *rc, rc->rc_quant_incr_limit0 = 11 + qp_bpc_modifier; rc->rc_quant_incr_limit1 = 11 + qp_bpc_modifier; - bpp_i = (2 * (bpp - 6)); + /* + * QP table rows have values in increment of 0.5. + * So 6.0 bpp to 6.4375 will have index 0, 6.5 to 6.9375 will have index 1, + * and so on. + * 0.5 represented as 0x8 in U6.4 format. + */ + bpp_i = ((bpp - 6) + (fractional_bits < 0x8 ? 0 : 1)); for (buf_i = 0; buf_i < DSC_NUM_BUF_RANGES; buf_i++) { /* Read range_minqp and range_max_qp from qp tables */ rc->rc_range_params[buf_i].range_min_qp = @@ -466,8 +473,7 @@ int intel_dsc_compute_params(struct intel_crtc_state *pipe_config) /* Gen 11 does not support VBR */ vdsc_cfg->vbr_enable = false; - /* Gen 11 only supports integral values of bpp */ - vdsc_cfg->bits_per_pixel = compressed_bpp << 4; + vdsc_cfg->bits_per_pixel = pipe_config->dsc.compressed_bpp; vdsc_cfg->bits_per_component = pipe_config->pipe_bpp / 3; for (i = 0; i < DSC_NUM_BUF_RANGES - 1; i++) { From patchwork Fri Apr 28 11:32:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [14/16] drm/i915/dp: Iterate over output bpp with fractional step size From: Ankit Nautiyal X-Patchwork-Id: 534648 Message-Id: <20230428113242.635892-15-ankit.k.nautiyal@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Date: Fri, 28 Apr 2023 17:02:40 +0530 This patch adds support to iterate over compressed output bpp as per the fractional step, supported by DP sink. v2: -Avoid ending up with compressed bpp, same as pipe bpp. (Stan) Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_dp.c | 47 +++++++++++++++---------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 3d08acb4505a..8dede5969af5 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1476,10 +1476,11 @@ 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, +static bool is_dsc_bw_sufficient(int link_rate, int lane_count, int compressed_bppx16, const struct drm_display_mode *adjusted_mode) { - int mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock, compressed_bpp); + int mode_rate = DIV_ROUND_UP(intel_dp_link_required(adjusted_mode->crtc_clock, + compressed_bppx16), 16); int link_avail = intel_dp_max_data_rate(link_rate, lane_count); return mode_rate <= link_avail; @@ -1489,7 +1490,7 @@ 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) + u16 compressed_bppx16) { const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; @@ -1513,11 +1514,11 @@ static int dsc_compute_link_config(struct intel_dp *intel_dp, adjusted_mode->crtc_hdisplay, pipe_config->bigjoiner_pipes, pipe_bpp, 64); - if (compressed_bpp > dsc_max_bpp) + if (compressed_bppx16 > dsc_max_bpp << 16) continue; if (!is_dsc_bw_sufficient(link_rate, lane_count, - compressed_bpp, adjusted_mode)) + compressed_bppx16, adjusted_mode)) continue; pipe_config->lane_count = lane_count; @@ -1580,33 +1581,41 @@ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp, int pipe_bpp) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - u16 compressed_bpp; - int dsc_min_bpp, dsc_src_max_bpp, dsc_sink_max_bpp, dsc_max_bpp; + u16 compressed_bppx16; + int dsc_min_bppx16, dsc_src_max_bppx16, dsc_sink_max_bppx16, dsc_max_bppx16; + u8 bppx16_incr = drm_dp_dsc_sink_bpp_incr(intel_dp->dsc_dpcd); + u8 bppx16_step; int ret; - dsc_min_bpp = max(dsc_min_compressed_bppx16(pipe_config) >> 4, 8); + if (DISPLAY_VER(dev_priv) < 14 || bppx16_incr <= 1) + bppx16_step = 16; + else + bppx16_step = 16 / bppx16_incr; + + dsc_min_bppx16 = max((int)dsc_min_compressed_bppx16(pipe_config), 8 << 4); if (DISPLAY_VER(dev_priv) <= 12) - dsc_src_max_bpp = 23; + dsc_src_max_bppx16 = 23 << 4; else - dsc_src_max_bpp = 27; - dsc_sink_max_bpp = dsc_max_sink_compressed_bppx16(intel_dp->dsc_dpcd, - pipe_config, pipe_bpp / 3) >> 4; + dsc_src_max_bppx16 = 27 << 4; + dsc_sink_max_bppx16 = dsc_max_sink_compressed_bppx16(intel_dp->dsc_dpcd, + pipe_config, pipe_bpp / 3); - dsc_max_bpp = dsc_sink_max_bpp ? min(dsc_sink_max_bpp, dsc_src_max_bpp) : dsc_src_max_bpp; + dsc_max_bppx16 = dsc_sink_max_bppx16 ? + min(dsc_sink_max_bppx16, dsc_src_max_bppx16) : dsc_src_max_bppx16; /* Compressed BPP should be less than the Input DSC bpp */ - dsc_max_bpp = min(dsc_max_bpp, pipe_bpp - 1); + dsc_max_bppx16 = min(dsc_max_bppx16, (pipe_bpp << 4) - bppx16_step); - for (compressed_bpp = dsc_max_bpp; - compressed_bpp >= dsc_min_bpp; - compressed_bpp--) { + for (compressed_bppx16 = dsc_max_bppx16; + compressed_bppx16 >= dsc_min_bppx16; + compressed_bppx16 -= bppx16_step) { ret = dsc_compute_link_config(intel_dp, pipe_config, limits, pipe_bpp, - compressed_bpp); + compressed_bppx16); if (ret == 0) { - pipe_config->dsc.compressed_bpp = compressed_bpp << 4; + pipe_config->dsc.compressed_bpp = compressed_bppx16; return 0; } } From patchwork Fri Apr 28 11:32:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [15/16] drm/i915/dsc: Add debugfs entry to validate DSC fractional bpp From: Ankit Nautiyal X-Patchwork-Id: 534647 Message-Id: <20230428113242.635892-16-ankit.k.nautiyal@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Date: Fri, 28 Apr 2023 17:02:41 +0530 From: Swati Sharma DSC_Sink_BPP_Precision entry is added to i915_dsc_fec_support_show to depict sink's precision. Also, new debugfs entry is created to enforce fractional bpp. If Force_DSC_Fractional_BPP_en is set then while iterating over output bpp with fractional step size we will continue if output_bpp is computed as integer. With this approach, we will be able to validate DSC with fractional bpp. Signed-off-by: Swati Sharma Signed-off-by: Ankit Nautiyal --- .../drm/i915/display/intel_display_debugfs.c | 84 +++++++++++++++++++ .../drm/i915/display/intel_display_types.h | 1 + 2 files changed, 85 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index 7bcd90384a46..2b36ec812293 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -1772,6 +1772,8 @@ static int i915_dsc_fec_support_show(struct seq_file *m, void *data) str_yes_no(drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd))); seq_printf(m, "Force_DSC_Enable: %s\n", str_yes_no(intel_dp->force_dsc_en)); + seq_printf(m, "DSC_Sink_BPP_Precision: %d\n", + drm_dp_dsc_sink_bpp_incr(intel_dp->dsc_dpcd)); if (!intel_dp_is_edp(intel_dp)) seq_printf(m, "FEC_Sink_Support: %s\n", str_yes_no(drm_dp_sink_supports_fec(intel_dp->fec_capable))); @@ -1895,6 +1897,85 @@ static const struct file_operations i915_dsc_bpc_fops = { .write = i915_dsc_bpc_write }; +static int i915_dsc_fractional_bpp_show(struct seq_file *m, void *data) +{ + struct drm_connector *connector = m->private; + struct drm_device *dev = connector->dev; + struct drm_crtc *crtc; + struct intel_dp *intel_dp; + struct intel_crtc_state *crtc_state; + struct intel_encoder *encoder = intel_attached_encoder(to_intel_connector(connector)); + int ret; + + if (!encoder) + return -ENODEV; + + ret = drm_modeset_lock_single_interruptible(&dev->mode_config.connection_mutex); + if (ret) + return ret; + + crtc = connector->state->crtc; + if (connector->status != connector_status_connected || !crtc) { + ret = -ENODEV; + goto out; + } + + intel_dp = intel_attached_dp(to_intel_connector(connector)); + crtc_state = to_intel_crtc_state(crtc->state); + seq_printf(m, "Force_DSC_Fractional_BPP_Enable: %s\n", + str_yes_no(intel_dp->force_dsc_fractional_bpp_en)); + +out: drm_modeset_unlock(&dev->mode_config.connection_mutex); + + return ret; +} + +static ssize_t i915_dsc_fractional_bpp_write(struct file *file, + const char __user *ubuf, + size_t len, loff_t *offp) +{ + struct drm_connector *connector = + ((struct seq_file *)file->private_data)->private; + struct intel_encoder *encoder = intel_attached_encoder(to_intel_connector(connector)); + struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + bool dsc_fractional_bpp_enable = false; + int ret; + + if (len == 0) + return 0; + + drm_dbg(&i915->drm, + "Copied %zu bytes from user to force fractional bpp for DSC\n", len); + + ret = kstrtobool_from_user(ubuf, len, &dsc_fractional_bpp_enable); + if (ret < 0) + return ret; + + drm_dbg(&i915->drm, "Got %s for DSC Fractional BPP Enable\n", + (dsc_fractional_bpp_enable) ? "true" : "false"); + intel_dp->force_dsc_fractional_bpp_en = dsc_fractional_bpp_enable; + + *offp += len; + + return len; +} + +static int i915_dsc_fractional_bpp_open(struct inode *inode, + struct file *file) +{ + return single_open(file, i915_dsc_fractional_bpp_show, inode->i_private); +} + +static const struct file_operations i915_dsc_fractional_bpp_fops = { + .owner = THIS_MODULE, + .open = i915_dsc_fractional_bpp_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = i915_dsc_fractional_bpp_write +}; + /* * Returns the Current CRTC's bpc. * Example usage: cat /sys/kernel/debug/dri/0/crtc-0/i915_current_bpc @@ -1966,6 +2047,9 @@ void intel_connector_debugfs_add(struct intel_connector *intel_connector) debugfs_create_file("i915_dsc_bpc", 0644, root, connector, &i915_dsc_bpc_fops); + + debugfs_create_file("i915_dsc_fractional_bpp", 0644, root, + connector, &i915_dsc_fractional_bpp_fops); } if (connector->connector_type == DRM_MODE_CONNECTOR_DSI || diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index e879a9483148..1c5930d78749 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1737,6 +1737,7 @@ struct intel_dp { /* Display stream compression testing */ bool force_dsc_en; + bool force_dsc_fractional_bpp_en; int force_dsc_bpc; bool hobl_failed; From patchwork Fri Apr 28 11:32:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [16/16] drm/i915/dsc: Allow DSC only with fractional bpp when forced from debugfs From: Ankit Nautiyal X-Patchwork-Id: 534650 Message-Id: <20230428113242.635892-17-ankit.k.nautiyal@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Date: Fri, 28 Apr 2023 17:02:42 +0530 From: Swati Sharma If force_dsc_fractional_bpp_en is set through debugfs allow DSC iff compressed bpp is fractional. Continue if we computed compressed bpp is computed as integer. Signed-off-by: Swati Sharma --- drivers/gpu/drm/i915/display/intel_dp.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 8dede5969af5..48ade9077352 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1609,6 +1609,9 @@ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp, for (compressed_bppx16 = dsc_max_bppx16; compressed_bppx16 >= dsc_min_bppx16; compressed_bppx16 -= bppx16_step) { + if (intel_dp->force_dsc_fractional_bpp_en && + (compressed_bppx16 % 16 == 0)) + continue; ret = dsc_compute_link_config(intel_dp, pipe_config, limits, @@ -1705,6 +1708,9 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, int forced_bpc = intel_dp->force_dsc_bpc; int forced_bpp = forced_bpc * 3; + if (intel_dp->force_dsc_fractional_bpp_en) + drm_dbg_kms(&dev_priv->drm, + "Forcing DSC fractional bpp\n"); if (forced_bpc < 8 || /* Min Input BPC for ICL+ is 8 */ forced_bpc > conn_state->max_requested_bpc || forced_bpp < limits->min_bpp ||