From f1dc979b6088426698b13e888c65f9c287af48e7 Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Tue, 14 Feb 2023 10:50:17 +0530 Subject: drm/i915/dp: Increase slice_height for DP According VDSC spec 1.2a Section 3.8 Options for Slice implies that 108 lines is an optimal slice height, but any size can be used as long as vertical active integer multiple and maximum vertical slice count requirements are met. Bspec: 49259 --v3 -remove previous fallback code and return slice_height as 2 [Jani] Cc: Jani Nikula Cc: Ankit Nautiyal Cc: Swati Sharma Signed-off-by: Suraj Kandpal Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20230214052017.3312044-1-suraj.kandpal@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 34 ++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 62cbab7402e9..bc7bb4eb4b50 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1415,6 +1415,28 @@ static int intel_dp_sink_dsc_version_minor(struct intel_dp *intel_dp) DP_DSC_MINOR_SHIFT; } +static int intel_dp_get_slice_height(int vactive) +{ + int slice_height; + + /* + * VDSC 1.2a spec in Section 3.8 Options for Slices implies that 108 + * lines is an optimal slice height, but any size can be used as long as + * vertical active integer multiple and maximum vertical slice count + * requirements are met. + */ + for (slice_height = 108; slice_height <= vactive; slice_height += 2) + if (vactive % slice_height == 0) + return slice_height; + + /* + * Highly unlikely we reach here as most of the resolutions will end up + * finding appropriate slice_height in above loop but returning + * slice_height as 2 here as it should work with all resolutions. + */ + return 2; +} + static int intel_dp_dsc_compute_params(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state) { @@ -1433,17 +1455,7 @@ static int intel_dp_dsc_compute_params(struct intel_encoder *encoder, vdsc_cfg->rc_model_size = DSC_RC_MODEL_SIZE_CONST; vdsc_cfg->pic_height = crtc_state->hw.adjusted_mode.crtc_vdisplay; - /* - * Slice Height of 8 works for all currently available panels. So start - * with that if pic_height is an integral multiple of 8. Eventually add - * logic to try multiple slice heights. - */ - if (vdsc_cfg->pic_height % 8 == 0) - vdsc_cfg->slice_height = 8; - else if (vdsc_cfg->pic_height % 4 == 0) - vdsc_cfg->slice_height = 4; - else - vdsc_cfg->slice_height = 2; + vdsc_cfg->slice_height = intel_dp_get_slice_height(vdsc_cfg->pic_height); ret = intel_dsc_compute_params(crtc_state); if (ret) -- cgit From db5d650ff0b5204ba679320ecdbc5e5d7ea80508 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 8 Feb 2023 03:55:01 +0200 Subject: drm/i915: Replace intel_bios_is_lspcon_present() with intel_bios_encoder_is_lspcon() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We always have encoder->devdata available on the platforms that can have LSPCON. So let's start looking there instead of digging it out from vbt.ports[]. And let's rename the function to fit the common pattern for these things. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230208015508.24824-4-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index bc7bb4eb4b50..15a1157f5371 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -4863,7 +4863,7 @@ intel_dp_connector_register(struct drm_connector *connector) if (!ret) drm_dp_cec_register_connector(&intel_dp->aux, connector); - if (!intel_bios_is_lspcon_present(i915, dig_port->base.port)) + if (!intel_bios_encoder_is_lspcon(dig_port->base.devdata)) return ret; /* @@ -5158,9 +5158,12 @@ bool intel_dp_is_port_edp(struct drm_i915_private *dev_priv, enum port port) } static bool -has_gamut_metadata_dip(struct drm_i915_private *i915, enum port port) +has_gamut_metadata_dip(struct intel_encoder *encoder) { - if (intel_bios_is_lspcon_present(i915, port)) + struct drm_i915_private *i915 = to_i915(encoder->base.dev); + enum port port = encoder->port; + + if (intel_bios_encoder_is_lspcon(encoder->devdata)) return false; if (DISPLAY_VER(i915) >= 11) @@ -5195,14 +5198,14 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect drm_connector_attach_max_bpc_property(connector, 6, 12); /* Register HDMI colorspace for case of lspcon */ - if (intel_bios_is_lspcon_present(dev_priv, port)) { + if (intel_bios_encoder_is_lspcon(dp_to_dig_port(intel_dp)->base.devdata)) { drm_connector_attach_content_type_property(connector); intel_attach_hdmi_colorspace_property(connector); } else { intel_attach_dp_colorspace_property(connector); } - if (has_gamut_metadata_dip(dev_priv, port)) + if (has_gamut_metadata_dip(&dp_to_dig_port(intel_dp)->base)) drm_connector_attach_hdr_output_metadata_property(connector); if (HAS_VRR(dev_priv)) -- cgit From 9d4b7af520e542b82a5db210c2053b5dc190eae0 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 8 Feb 2023 03:55:08 +0200 Subject: drm/i915: Use encoder->devdata in eDP init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since we now populate encoder->devdata for all DP capable platforms we can consult it directly during the eDP connector init instead of taking a detour via some global list/array. Unfortunately we can't quite get rid of intel_dp_is_port_edp() since it's still used by the higher level ilk/vlv/chv output setup code. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230208015508.24824-11-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 15a1157f5371..b92e0b0f5369 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -5141,8 +5141,9 @@ intel_dp_hpd_pulse(struct intel_digital_port *dig_port, bool long_hpd) return IRQ_HANDLED; } -/* check the VBT to see whether the eDP is on another port */ -bool intel_dp_is_port_edp(struct drm_i915_private *dev_priv, enum port port) +static bool _intel_dp_is_port_edp(struct drm_i915_private *dev_priv, + const struct intel_bios_encoder_data *devdata, + enum port port) { /* * eDP not supported on g4x. so bail out early just @@ -5154,7 +5155,15 @@ bool intel_dp_is_port_edp(struct drm_i915_private *dev_priv, enum port port) if (DISPLAY_VER(dev_priv) < 9 && port == PORT_A) return true; - return intel_bios_is_port_edp(dev_priv, port); + return devdata && intel_bios_encoder_supports_edp(devdata); +} + +bool intel_dp_is_port_edp(struct drm_i915_private *i915, enum port port) +{ + const struct intel_bios_encoder_data *devdata = + intel_bios_encoder_data_lookup(i915, port); + + return _intel_dp_is_port_edp(i915, devdata, port); } static bool @@ -5427,7 +5436,7 @@ intel_dp_init_connector(struct intel_digital_port *dig_port, intel_dp->DP = intel_de_read(dev_priv, intel_dp->output_reg); intel_dp->attached_connector = intel_connector; - if (intel_dp_is_port_edp(dev_priv, port)) { + if (_intel_dp_is_port_edp(dev_priv, intel_encoder->devdata, port)) { /* * Currently we don't support eDP on TypeC ports, although in * theory it could work on TypeC legacy ports. -- cgit From b3baf0c00cbd2174e9fdc7141ea30adf123c4a8f Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 15 Feb 2023 15:56:16 +0200 Subject: drm/i915: Make backlight setup debugs consistent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's confusing to debug backlight issues when one can't easily even tell what kind of backlight control was selected. Sprinkle uniform debug messages to all the backlight setup functions. Also the one that was already there (ext_pwm) was using drm_info() for some reason. I don't think that's warranted so switch it to drm_dbg_kms() as well. v2: Deal with AUX backlights too (Jani) Move the VLV/CHV initial pipe debug there too (Jani) Cc: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230215135616.30411-1-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index b92e0b0f5369..717be9a9ef5b 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -5256,11 +5256,6 @@ static void intel_edp_backlight_setup(struct intel_dp *intel_dp, if (pipe != PIPE_A && pipe != PIPE_B) pipe = PIPE_A; - - drm_dbg_kms(&i915->drm, - "[CONNECTOR:%d:%s] using pipe %c for initial backlight setup\n", - connector->base.base.id, connector->base.name, - pipe_name(pipe)); } intel_backlight_setup(connector, pipe); -- cgit From 02107ef11b438a2528a113d8a546d4dceb8bcce1 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 16 Feb 2023 02:04:25 +0200 Subject: drm/i915: Use encoder->devdata more MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Switch a lot of the intel_bios_foo() stuff to just accept the devdata (VBT child device info) directly, instead of taking detours via vbt.ports[]. Also unify the function naming scheme. v2: Drop the redundant "encoder" from the dp/hdmi specific functions Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230216000425.32216-1-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 717be9a9ef5b..04ebdb6541a5 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -288,7 +288,7 @@ static int intel_dp_max_common_rate(struct intel_dp *intel_dp) static int intel_dp_max_source_lane_count(struct intel_digital_port *dig_port) { - int vbt_max_lanes = intel_bios_dp_max_lane_count(&dig_port->base); + int vbt_max_lanes = intel_bios_dp_max_lane_count(dig_port->base.devdata); int max_lanes = dig_port->max_lanes; if (vbt_max_lanes) @@ -425,7 +425,7 @@ static int vbt_max_link_rate(struct intel_dp *intel_dp) struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; int max_rate; - max_rate = intel_bios_dp_max_link_rate(encoder); + max_rate = intel_bios_dp_max_link_rate(encoder->devdata); if (intel_dp_is_edp(intel_dp)) { struct intel_connector *connector = intel_dp->attached_connector; -- cgit From 3eb08ea58e5717cf758b9eff6d9604aa3525ab94 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 14 Feb 2023 00:52:50 +0200 Subject: drm/i915: s/PIPECONF/TRANSCONF/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename PIPECONF to TRANSCONF to make it clear what it actually applies to. While the usual convention is to pick the earliers name I think in this case it's more clear to use the later name. Especially as even the register offset is in the wrong range (0x70000 vs. 0x60000) and thus makes it look like this is per-pipe. There is one place in gvt that's doing something with TRANSCONF while iterating with for_each_pipe(). So that might not be doing the right thing for TRANSCODER_EDP, dunno. Not knowing what it does I left it as is to avoid breakage. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230213225258.2127-5-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 04ebdb6541a5..b77bd4565864 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1739,7 +1739,7 @@ bool intel_dp_limited_color_range(const struct intel_crtc_state *crtc_state, * Our YCbCr output is always limited range. * crtc_state->limited_color_range only applies to RGB, * and it must never be set for YCbCr or we risk setting - * some conflicting bits in PIPECONF which will mess up + * some conflicting bits in TRANSCONF which will mess up * the colors on the monitor. */ if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB) -- cgit From 82ea22256b9c1fe3f5a089733969f6539d92d9f0 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 20 Feb 2023 17:17:31 +0200 Subject: drm/i915: Drop useless intel_dp_has_audio() argument MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit intel_dp_has_audio() has no need for the crtc_state, so don't pass it in. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230220151731.6852-2-ville.syrjala@linux.intel.com Reviewed-by: Uma Shankar --- drivers/gpu/drm/i915/display/intel_dp.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index b77bd4565864..d25a93258f8b 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2003,7 +2003,6 @@ intel_dp_drrs_compute_config(struct intel_connector *connector, } static bool intel_dp_has_audio(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { struct drm_i915_private *i915 = to_i915(encoder->base.dev); @@ -2069,7 +2068,7 @@ intel_dp_audio_compute_config(struct intel_encoder *encoder, struct drm_connector *connector = conn_state->connector; pipe_config->sdp_split_enable = - intel_dp_has_audio(encoder, pipe_config, conn_state) && + intel_dp_has_audio(encoder, conn_state) && intel_dp_is_uhbr(pipe_config); drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] SDP split enable: %s\n", @@ -2093,7 +2092,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, pipe_config->has_pch_encoder = true; pipe_config->has_audio = - intel_dp_has_audio(encoder, pipe_config, conn_state) && + intel_dp_has_audio(encoder, conn_state) && intel_audio_compute_config(encoder, pipe_config, conn_state); fixed_mode = intel_panel_fixed_mode(connector, adjusted_mode); -- cgit From fe82b93fc101beb6396193b1713029d18d740e7f Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 20 Feb 2023 18:47:18 +0200 Subject: drm/i915: Get HDR DPCD refresh timeout from VBT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Grab the HDR DPCD refresh timeout (time we need to wait after writing the sourc OUI before the HDR DPCD registers are ready) from the VBT. Windows doesn't even seem to have any default value for this, which is perhaps a bit weird since the VBT value is documented as TGL+ and I thought the HDR backlight stuff might already be used on earlier platforms. To play it safe I left the old hardcoded 30ms default in place. Digging through some internal stuff that seems to have been a number given by the vendor for one particularly slow TCON. Although I did see 50ms mentioned somewhere as well. Let's also include the value in the debug print to ease debugging, and toss in the customary connector id+name as well. The TGL Thinkpad T14 I have sets this to 0 btw. So the delay is now gone on this machine: [CONNECTOR:308:eDP-1] Detected Intel HDR backlight interface version 1 [CONNECTOR:308:eDP-1] Using Intel proprietary eDP backlight controls [CONNECTOR:308:eDP-1] SDR backlight is controlled through PWM [CONNECTOR:308:eDP-1] Using native PCH PWM for backlight control (controller=0) [CONNECTOR:308:eDP-1] Using AUX HDR interface for backlight control (range 0..496) [CONNECTOR:308:eDP-1] Performing OUI wait (0 ms) Cc: Lyude Paul Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230220164718.23117-1-ville.syrjala@linux.intel.com Reviewed-by: Jouni Högander --- drivers/gpu/drm/i915/display/intel_dp.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index d25a93258f8b..aee93b0d810e 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2292,10 +2292,15 @@ intel_edp_init_source_oui(struct intel_dp *intel_dp, bool careful) void intel_dp_wait_source_oui(struct intel_dp *intel_dp) { + struct intel_connector *connector = intel_dp->attached_connector; struct drm_i915_private *i915 = dp_to_i915(intel_dp); - drm_dbg_kms(&i915->drm, "Performing OUI wait\n"); - wait_remaining_ms_from_jiffies(intel_dp->last_oui_write, 30); + drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] Performing OUI wait (%u ms)\n", + connector->base.base.id, connector->base.name, + connector->panel.vbt.backlight.hdr_dpcd_refresh_timeout); + + wait_remaining_ms_from_jiffies(intel_dp->last_oui_write, + connector->panel.vbt.backlight.hdr_dpcd_refresh_timeout); } /* If the device supports it, try to set the power state appropriately */ -- cgit From ce086a32ae21a01e48d202cf85b43815a0eeccfc Mon Sep 17 00:00:00 2001 From: Stanislav Lisovskiy Date: Mon, 6 Mar 2023 10:04:01 +0200 Subject: drm/i915: Ensure DSC has enough BW and stays within HW limits We currently have an issue with some BPPs when using DSC. According to the HW team, the reason is that a single VDSC engine instance has some BW limitations that must be accounted for. So, whenever we approach around 90% of the CDCLK, a second VDSC engine has to be used. This always means using two slices. However, in our current code, the amount of slices is calculated independently of whether we need to enable the second VDSC engine or not. This leads to some logical issues when, according to the pixel clock needs, we need to enable the second VDSC engine. But as we calculated previously that we can only use a single slice, we can't do that and fail. So, we need to fix that so that the number of VDSC engines enabled should depend on the number of slices, and the number of slices should also depend on BW requirements. Lastly, we didn't have BPP limitation for ADLP/MTL/DG2 implemented, which says that DSC output BPPs can only be chosen within the range of 8 to 27 (BSpec 49259). All of this applied together allows us to fix existing FIFO underruns, which we have in many DSC tests. v2: - Replace min with clamp_t(Jani Nikula) - Fix commit message(Swati Sharma) - Added "Closes"(Swati Sharma) BSpec: 49259 HSDES: 18027167222 Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/8231 Signed-off-by: Stanislav Lisovskiy Reviewed-by: Vinod Govindapillai Link: https://patchwork.freedesktop.org/patch/msgid/20230306080401.22552-1-stanislav.lisovskiy@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index aee93b0d810e..8e16745275f6 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -687,6 +687,12 @@ u32 intel_dp_dsc_nearest_valid_bpp(struct drm_i915_private *i915, u32 bpp, u32 p /* From XE_LPD onwards we support from bpc upto uncompressed bpp-1 BPPs */ if (DISPLAY_VER(i915) >= 13) { bits_per_pixel = min(bits_per_pixel, pipe_bpp - 1); + + /* + * According to BSpec, 27 is the max DSC output bpp, + * 8 is the min DSC output bpp + */ + bits_per_pixel = clamp_t(u32, bits_per_pixel, 8, 27); } else { /* Find the nearest match in the array of known BPPs from VESA */ for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) { @@ -771,6 +777,13 @@ u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp, min_slice_count = DIV_ROUND_UP(mode_clock, DP_DSC_MAX_ENC_THROUGHPUT_1); + /* + * Due to some DSC engine BW limitations, we need to enable second + * slice and VDSC engine, whenever we approach close enough to max CDCLK + */ + if (mode_clock >= ((i915->display.cdclk.max_cdclk_freq * 85) / 100)) + min_slice_count = max_t(u8, min_slice_count, 2); + max_slice_width = drm_dp_dsc_sink_max_slice_width(intel_dp->dsc_dpcd); if (max_slice_width < DP_DSC_MIN_SLICE_WIDTH_VALUE) { drm_dbg_kms(&i915->drm, @@ -1597,16 +1610,8 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, * is greater than the maximum Cdclock and if slice count is even * then we need to use 2 VDSC instances. */ - if (adjusted_mode->crtc_clock > dev_priv->display.cdclk.max_cdclk_freq || - pipe_config->bigjoiner_pipes) { - if (pipe_config->dsc.slice_count > 1) { - pipe_config->dsc.dsc_split = true; - } else { - drm_dbg_kms(&dev_priv->drm, - "Cannot split stream to use 2 VDSC instances\n"); - return -EINVAL; - } - } + if (pipe_config->bigjoiner_pipes || pipe_config->dsc.slice_count > 1) + pipe_config->dsc.dsc_split = true; ret = intel_dp_dsc_compute_params(&dig_port->base, pipe_config); if (ret < 0) { -- cgit From 68070b76c4aac9369d7f84d802111ef83a7ff943 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Thu, 23 Feb 2023 17:25:09 +0530 Subject: drm/i915/dp: Don't roundup max bpp, while computing compressed bpp While computing compressed bpp, maximum value of bits_per_pixel is calculated that can be supported with the given link configuration for a given mode. Avoid rounding up of this max bits_per_pixel. Also improve documentation for computing max bits_per_pixel. Signed-off-by: Ankit Nautiyal Reviewed-by: Stanislav Lisovskiy Signed-off-by: Stanislav Lisovskiy Link: https://patchwork.freedesktop.org/patch/msgid/20230223115509.3980226-1-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 8e16745275f6..da1c00ee92fb 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -722,9 +722,19 @@ u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915, * (LinkSymbolClock)* 8 * (TimeSlots / 64) * for SST -> TimeSlots is 64(i.e all TimeSlots that are available) * for MST -> TimeSlots has to be calculated, based on mode requirements + * + * Due to FEC overhead, the available bw is reduced to 97.2261%. + * To support the given mode: + * Bandwidth required should be <= Available link Bandwidth * FEC Overhead + * =>ModeClock * bits_per_pixel <= Available Link Bandwidth * FEC Overhead + * =>bits_per_pixel <= Available link Bandwidth * FEC Overhead / ModeClock + * =>bits_per_pixel <= (NumberOfLanes * LinkSymbolClock) * 8 (TimeSlots / 64) / + * (ModeClock / FEC Overhead) + * =>bits_per_pixel <= (NumberOfLanes * LinkSymbolClock * TimeSlots) / + * (ModeClock / FEC Overhead * 8) */ - bits_per_pixel = DIV_ROUND_UP((link_clock * lane_count) * timeslots, - intel_dp_mode_to_fec_clock(mode_clock) * 8); + bits_per_pixel = ((link_clock * lane_count) * timeslots) / + (intel_dp_mode_to_fec_clock(mode_clock) * 8); drm_dbg_kms(&i915->drm, "Max link bpp is %u for %u timeslots " "total bw %u pixel clock %u\n", -- cgit From 5011f2915b70703a0347f97b8f2ca0b56ab49978 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Thu, 9 Mar 2023 11:58:50 +0530 Subject: drm/i915/dp: Check if DSC supports the given output_format Go with DSC only if the given output_format is supported. v2: Use drm helper to get DSC format support for sink. v3: remove drm_dp_dsc_compute_bpp. Cc: Uma Shankar Signed-off-by: Ankit Nautiyal Reviewed-by: Uma Shankar Signed-off-by: Uma Shankar Link: https://patchwork.freedesktop.org/patch/msgid/20230309062855.393087-3-suraj.kandpal@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'drivers/gpu/drm/i915/display/intel_dp.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index da1c00ee92fb..777d10aedbb1 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1515,6 +1515,31 @@ static int intel_dp_dsc_compute_params(struct intel_encoder *encoder, return drm_dsc_compute_rc_parameters(vdsc_cfg); } +static bool intel_dp_dsc_supports_format(struct intel_dp *intel_dp, + enum intel_output_format output_format) +{ + u8 sink_dsc_format; + + switch (output_format) { + case INTEL_OUTPUT_FORMAT_RGB: + sink_dsc_format = DP_DSC_RGB; + break; + case INTEL_OUTPUT_FORMAT_YCBCR444: + sink_dsc_format = DP_DSC_YCbCr444; + break; + case INTEL_OUTPUT_FORMAT_YCBCR420: + if (min(intel_dp_source_dsc_version_minor(intel_dp), + intel_dp_sink_dsc_version_minor(intel_dp)) < 2) + return false; + sink_dsc_format = DP_DSC_YCbCr420_Native; + break; + default: + return false; + } + + return drm_dp_dsc_sink_supports_format(intel_dp->dsc_dpcd, sink_dsc_format); +} + int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state, @@ -1535,6 +1560,9 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, if (!intel_dp_supports_dsc(intel_dp, pipe_config)) return -EINVAL; + if (!intel_dp_dsc_supports_format(intel_dp, pipe_config->output_format)) + return -EINVAL; + if (compute_pipe_bpp) pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, conn_state->max_requested_bpc); else -- cgit From 9aeabe1988551f797f6e0cba0e7c2d4549cc3a4b Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Thu, 9 Mar 2023 11:58:53 +0530 Subject: drm/i915/dsc: Fill in native_420 field Now that we have laid the groundwork for YUV420 Enablement we fill up native_420 field in vdsc_cfg and add appropriate checks wherever required. ---v2 -adding native_422 field as 0 [Vandita] -filling in second_line_bpg_offset, second_line_offset_adj and nsl_bpg_offset in vds_cfg when native_420 is true ---v3 -adding display version check to solve igt issue --v7 -remove is_pipe_dsc check as its always true for D14 [Jani] --v10 -keep sink capability check [Jani] -move from !(x == y || w == z) to x !=y && w != z [Jani] --v11 -avoid native_420 computation if not gen14 [Uma] --v12 -fix state mismatch issue of compressed_bpp Cc: Uma Shankar Cc: Jani Nikula Signed-off-by: Suraj Kandpal Reviewed-by: Uma Shankar Signed-off-by: Uma Shankar Link: https://patchwork.freedesktop.org/patch/msgid/20230309062855.393087-6-suraj.kandpal@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dp.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 777d10aedbb1..4a909087ea49 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1490,9 +1490,10 @@ static int intel_dp_dsc_compute_params(struct intel_encoder *encoder, vdsc_cfg->dsc_version_minor = min(intel_dp_source_dsc_version_minor(intel_dp), intel_dp_sink_dsc_version_minor(intel_dp)); - - vdsc_cfg->convert_rgb = intel_dp->dsc_dpcd[DP_DSC_DEC_COLOR_FORMAT_CAP - DP_DSC_SUPPORT] & - DP_DSC_RGB; + if (vdsc_cfg->convert_rgb) + vdsc_cfg->convert_rgb = + intel_dp->dsc_dpcd[DP_DSC_DEC_COLOR_FORMAT_CAP - DP_DSC_SUPPORT] & + DP_DSC_RGB; line_buf_depth = drm_dp_dsc_sink_line_buf_depth(intel_dp->dsc_dpcd); if (!line_buf_depth) { @@ -1610,6 +1611,15 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, pipe_config->bigjoiner_pipes, pipe_bpp, timeslots); + /* + * According to DSC 1.2a Section 4.1.1 Table 4.1 the maximum + * supported PPS value can be 63.9375 and with the further + * mention that bpp should be programmed double the target bpp + * restricting our target bpp to be 31.9375 at max + */ + if (pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR420) + dsc_max_output_bpp = min_t(u16, dsc_max_output_bpp, 31 << 4); + if (!dsc_max_output_bpp) { drm_dbg_kms(&dev_priv->drm, "Compressed BPP not supported\n"); -- cgit From d4d17377e01f017fd5a22f68f13e7ab342f97551 Mon Sep 17 00:00:00 2001 From: Swati Sharma Date: Thu, 9 Mar 2023 11:58:55 +0530 Subject: drm/i915/dsc: Add debugfs entry to validate DSC output formats DSC_Output_Format_Sink_Support entry is added to i915_dsc_fec_support_show to depict if sink supports DSC output formats (RGB/YCbCr420/YCbCr444). Also, new debugfs entry is created to enforce output format. This is required because of our driver policy. For ex. if a mode is supported in both RGB and YCbCr420 output formats by the sink, our policy is to try RGB first and fall back to YCbCr420, if mode cannot be shown using RGB. So, to test other output formats like YCbCr420 or YCbCr444, we need a debugfs entry (force_dsc_output_format) to force this output format. v2: -Func name changed to intel_output_format_name() (Jani N) -Return forced o/p format from intel_dp_output_format() (Jani N) v3: -output_format_str[] to remain static (Jani N) Signed-off-by: Swati Sharma Reviewed-by: Uma Shankar Signed-off-by: Uma Shankar Link: https://patchwork.freedesktop.org/patch/msgid/20230309062855.393087-8-suraj.kandpal@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/gpu/drm/i915/display/intel_dp.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 4a909087ea49..f0bace9d98a1 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -76,6 +76,7 @@ #include "intel_tc.h" #include "intel_vdsc.h" #include "intel_vrr.h" +#include "intel_crtc_state_dump.h" /* DP DSC throughput values used for slice count calculations KPixels/s */ #define DP_DSC_PEAK_PIXEL_RATE 2720000 @@ -833,6 +834,9 @@ intel_dp_output_format(struct intel_connector *connector, { struct intel_dp *intel_dp = intel_attached_dp(connector); + if (intel_dp->force_dsc_output_format) + return intel_dp->force_dsc_output_format; + if (!connector->base.ycbcr_420_allowed || !ycbcr_420_output) return INTEL_OUTPUT_FORMAT_RGB; -- cgit From 0ff80028e2702c7c3d78b69705dc47c1ccba8c39 Mon Sep 17 00:00:00 2001 From: Nikita Zhandarovich Date: Tue, 18 Apr 2023 07:04:30 -0700 Subject: drm/i915/dp: prevent potential div-by-zero drm_dp_dsc_sink_max_slice_count() may return 0 if something goes wrong on the part of the DSC sink and its DPCD register. This null value may be later used as a divisor in intel_dsc_compute_params(), which will lead to an error. In the unlikely event that this issue occurs, fix it by testing the return value of drm_dp_dsc_sink_max_slice_count() against zero. Found by Linux Verification Center (linuxtesting.org) with static analysis tool SVACE. Fixes: a4a157777c80 ("drm/i915/dp: Compute DSC pipe config in atomic check") Signed-off-by: Nikita Zhandarovich Reviewed-by: Rodrigo Vivi Signed-off-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20230418140430.69902-1-n.zhandarovich@fintech.ru (cherry picked from commit 51f7008239de011370c5067bbba07f0207f06b72) Signed-off-by: Joonas Lahtinen --- drivers/gpu/drm/i915/display/intel_dp.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/gpu/drm/i915/display/intel_dp.c') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index f0bace9d98a1..529ee22be872 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1601,6 +1601,11 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, pipe_config->dsc.slice_count = drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd, true); + if (!pipe_config->dsc.slice_count) { + drm_dbg_kms(&dev_priv->drm, "Unsupported Slice Count %d\n", + pipe_config->dsc.slice_count); + return -EINVAL; + } } else { u16 dsc_max_output_bpp = 0; u8 dsc_dp_slice_count; -- cgit