diff mbox series

[01/23] drm/i915/dp: Fix dsc bpp calculations, v2.

Message ID 20190920114235.22411-1-maarten.lankhorst@linux.intel.com (mailing list archive)
State New, archived
Headers show
Series [01/23] drm/i915/dp: Fix dsc bpp calculations, v2. | expand

Commit Message

Maarten Lankhorst Sept. 20, 2019, 11:42 a.m. UTC
There was a integer wraparound when mode_clock became too high,
and we didn't correct for the FEC overhead factor when dividing,
with the calculations breaking at HBR3.

As a result our calculated bpp was way too high, and the link width
limitation never came into effect.

Print out the resulting bpp calcululations as a sanity check, just
in case we ever have to debug it later on again.

We also used the wrong factor for FEC. While bspec mentions 2.4%,
all the calculations use 1/0.972261, and the same ratio should be
applied to data M/N as well, so use it there when FEC is enabled.

Make sure we don't break hw readout, and read out FEC enable state
and correct the DDI clock readout for the new values.

Together with the next commit, this causes FEC to work correctly
with big joiner, while also having the correct refresh rate
reported in kms_setmode.basic.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Fixes: d9218c8f6cf4 ("drm/i915/dp: Add helpers for Compressed BPP and Slice Count for DSC")
Cc: <stable@vger.kernel.org> # v5.0+
Cc: Manasi Navare <manasi.d.navare@intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c     |  19 +-
 drivers/gpu/drm/i915/display/intel_display.c |   1 +
 drivers/gpu/drm/i915/display/intel_dp.c      | 195 ++++++++++---------
 drivers/gpu/drm/i915/display/intel_dp.h      |   6 +-
 4 files changed, 128 insertions(+), 93 deletions(-)

Comments

Ville Syrjälä Sept. 20, 2019, 4:38 p.m. UTC | #1
On Fri, Sep 20, 2019 at 01:42:13PM +0200, Maarten Lankhorst wrote:
> There was a integer wraparound when mode_clock became too high,
> and we didn't correct for the FEC overhead factor when dividing,
> with the calculations breaking at HBR3.
> 
> As a result our calculated bpp was way too high, and the link width
> limitation never came into effect.
> 
> Print out the resulting bpp calcululations as a sanity check, just
> in case we ever have to debug it later on again.
> 
> We also used the wrong factor for FEC. While bspec mentions 2.4%,
> all the calculations use 1/0.972261, and the same ratio should be
> applied to data M/N as well, so use it there when FEC is enabled.
> 
> Make sure we don't break hw readout, and read out FEC enable state
> and correct the DDI clock readout for the new values.
> 
> Together with the next commit, this causes FEC to work correctly
> with big joiner, while also having the correct refresh rate
> reported in kms_setmode.basic.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Fixes: d9218c8f6cf4 ("drm/i915/dp: Add helpers for Compressed BPP and Slice Count for DSC")
> Cc: <stable@vger.kernel.org> # v5.0+
> Cc: Manasi Navare <manasi.d.navare@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c     |  19 +-
>  drivers/gpu/drm/i915/display/intel_display.c |   1 +
>  drivers/gpu/drm/i915/display/intel_dp.c      | 195 ++++++++++---------
>  drivers/gpu/drm/i915/display/intel_dp.h      |   6 +-
>  4 files changed, 128 insertions(+), 93 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 3e6394139964..1b59b852874b 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -1479,6 +1479,10 @@ static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
>  	if (pipe_config->pixel_multiplier)
>  		dotclock /= pipe_config->pixel_multiplier;
>  
> +	/* fec adds overhead to the data M/N values, correct for it */
> +	if (pipe_config->fec_enable)
> +		dotclock = intel_dp_fec_to_mode_clock(dotclock);
> +
>  	pipe_config->base.adjusted_mode.crtc_clock = dotclock;
>  }
>  
> @@ -4031,7 +4035,9 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>  	case TRANS_DDI_MODE_SELECT_FDI:
>  		pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG);
>  		break;
> -	case TRANS_DDI_MODE_SELECT_DP_SST:
> +	case TRANS_DDI_MODE_SELECT_DP_SST: {
> +		struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
> +
>  		if (encoder->type == INTEL_OUTPUT_EDP)
>  			pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP);
>  		else
> @@ -4039,7 +4045,18 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>  		pipe_config->lane_count =
>  			((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
>  		intel_dp_get_m_n(intel_crtc, pipe_config);
> +
> +		if (INTEL_GEN(dev_priv) >= 11) {
> +			pipe_config->fec_enable =
> +				I915_READ(intel_dp->regs.dp_tp_ctl) &
> +					  DP_TP_CTL_FEC_ENABLE;

Side note: That looks broken for the init/resume readout.
I knew there was a reason I didn't quite like the idea of
intel_dp->regs...

> +			DRM_DEBUG_KMS("[ENCODER:%d:%s] Fec status: %u\n",
> +				      encoder->base.base.id, encoder->base.name,
> +				      pipe_config->fec_enable);
> +		}
> +
>  		break;
> +	}
>  	case TRANS_DDI_MODE_SELECT_DP_MST:
>  		pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST);
>  		pipe_config->lane_count =
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index e0033d99f6e3..7996864e6f7c 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -12773,6 +12773,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>  	PIPE_CONF_CHECK_BOOL(hdmi_scrambling);
>  	PIPE_CONF_CHECK_BOOL(hdmi_high_tmds_clock_ratio);
>  	PIPE_CONF_CHECK_BOOL(has_infoframe);
> +	PIPE_CONF_CHECK_BOOL(fec_enable);
>  
>  	PIPE_CONF_CHECK_BOOL_INCOMPLETE(has_audio);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index ccaf9f00b747..4dfb78dc7fa2 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -76,8 +76,8 @@
>  #define DP_DSC_MAX_ENC_THROUGHPUT_0		340000
>  #define DP_DSC_MAX_ENC_THROUGHPUT_1		400000
>  
> -/* DP DSC FEC Overhead factor = (100 - 2.4)/100 */
> -#define DP_DSC_FEC_OVERHEAD_FACTOR		976
> +/* DP DSC FEC Overhead factor = 1/(0.972261) */
> +#define DP_DSC_FEC_OVERHEAD_FACTOR		972261
>  
>  /* Compliance test status bits  */
>  #define INTEL_DP_RESOLUTION_SHIFT_MASK	0
> @@ -492,6 +492,104 @@ int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
>  	return 0;
>  }
>  
> +static inline u32 intel_dp_mode_to_fec_clock(u32 mode_clock)
> +{
> +	return div_u64(mul_u32_u32(mode_clock, 1000000U),
> +		       DP_DSC_FEC_OVERHEAD_FACTOR);
> +}
> +
> +u32 intel_dp_fec_to_mode_clock(u32 fec_clock)
> +{
> +	return div_u64(mul_u32_u32(fec_clock,
> +				   DP_DSC_FEC_OVERHEAD_FACTOR),
> +		       1000000U);
> +}
> +
> +static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
> +				       u32 mode_clock, u32 mode_hdisplay)
> +{
> +	u32 bits_per_pixel, max_bpp_small_joiner_ram;
> +	int i;
> +
> +	/*
> +	 * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
> +	 * (LinkSymbolClock)* 8 * (TimeSlotsPerMTP)
> +	 * for SST -> TimeSlotsPerMTP is 1,
> +	 * for MST -> TimeSlotsPerMTP has to be calculated
> +	 */
> +	bits_per_pixel = (link_clock * lane_count * 8) /
> +			 intel_dp_mode_to_fec_clock(mode_clock);
> +	DRM_DEBUG_KMS("Max link bpp: %u\n", bits_per_pixel);
> +
> +	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
> +	max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER / mode_hdisplay;
> +	DRM_DEBUG_KMS("Max small joiner bpp: %u\n", max_bpp_small_joiner_ram);
> +
> +	/*
> +	 * Greatest allowed DSC BPP = MIN (output BPP from available Link BW
> +	 * check, output bpp from small joiner RAM check)
> +	 */
> +	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
> +
> +	/* Error out if the max bpp is less than smallest allowed valid bpp */
> +	if (bits_per_pixel < valid_dsc_bpp[0]) {
> +		DRM_DEBUG_KMS("Unsupported BPP %u, min %u\n",
> +			      bits_per_pixel, valid_dsc_bpp[0]);
> +		return 0;
> +	}
> +
> +	/* Find the nearest match in the array of known BPPs from VESA */
> +	for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) {
> +		if (bits_per_pixel < valid_dsc_bpp[i + 1])
> +			break;
> +	}
> +	bits_per_pixel = valid_dsc_bpp[i];
> +
> +	/*
> +	 * Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
> +	 * fractional part is 0
> +	 */
> +	return bits_per_pixel << 4;
> +}
> +
> +static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
> +				       int mode_clock, int mode_hdisplay)
> +{
> +	u8 min_slice_count, i;
> +	int max_slice_width;
> +
> +	if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE)
> +		min_slice_count = DIV_ROUND_UP(mode_clock,
> +					       DP_DSC_MAX_ENC_THROUGHPUT_0);
> +	else
> +		min_slice_count = DIV_ROUND_UP(mode_clock,
> +					       DP_DSC_MAX_ENC_THROUGHPUT_1);
> +
> +	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_DEBUG_KMS("Unsupported slice width %d by DP DSC Sink device\n",
> +			      max_slice_width);
> +		return 0;
> +	}
> +	/* Also take into account max slice width */
> +	min_slice_count = min_t(u8, min_slice_count,
> +				DIV_ROUND_UP(mode_hdisplay,
> +					     max_slice_width));
> +
> +	/* Find the closest match to the valid slice count values */
> +	for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
> +		if (valid_dsc_slicecount[i] >
> +		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
> +						    false))
> +			break;
> +		if (min_slice_count  <= valid_dsc_slicecount[i])
> +			return valid_dsc_slicecount[i];
> +	}
> +
> +	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
> +	return 0;
> +}
> +
>  static enum drm_mode_status
>  intel_dp_mode_valid(struct drm_connector *connector,
>  		    struct drm_display_mode *mode)
> @@ -2182,6 +2280,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>  	bool constant_n = drm_dp_has_quirk(&intel_dp->desc,
>  					   DP_DPCD_QUIRK_CONSTANT_N);
>  	int ret = 0, output_bpp;
> +	u32 data_clock;
>  
>  	if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv) && port != PORT_A)
>  		pipe_config->has_pch_encoder = true;
> @@ -2244,9 +2343,14 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>  	else
>  		output_bpp = intel_dp_output_bpp(pipe_config, pipe_config->pipe_bpp);
>  
> +	if (pipe_config->fec_enable)
> +		data_clock = intel_dp_mode_to_fec_clock(adjusted_mode->crtc_clock);
> +	else
> +		data_clock = adjusted_mode->crtc_clock;

This looks wrong to me. The link M/N are used the regenerate the
stream clock from the link symbol clock. AFAICS the only effect FEC
should have is that the overhead may require us to bump the LS clock
a bit higher. But the M/N is stil computed simply as the ratio
between LS clock and stream clock.

The data M/N do need to account for FEC. I guess that's the problem
you're trying to address here?

> +
>  	intel_link_compute_m_n(output_bpp,
>  			       pipe_config->lane_count,
> -			       adjusted_mode->crtc_clock,
> +			       data_clock,
>  			       pipe_config->port_clock,
>  			       &pipe_config->dp_m_n,
>  			       constant_n);
> @@ -4363,91 +4467,6 @@ intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *sink_irq_vector)
>  		DP_DPRX_ESI_LEN;
>  }
>  
> -u16 intel_dp_dsc_get_output_bpp(int link_clock, u8 lane_count,
> -				int mode_clock, int mode_hdisplay)
> -{
> -	u16 bits_per_pixel, max_bpp_small_joiner_ram;
> -	int i;
> -
> -	/*
> -	 * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
> -	 * (LinkSymbolClock)* 8 * ((100-FECOverhead)/100)*(TimeSlotsPerMTP)
> -	 * FECOverhead = 2.4%, for SST -> TimeSlotsPerMTP is 1,
> -	 * for MST -> TimeSlotsPerMTP has to be calculated
> -	 */
> -	bits_per_pixel = (link_clock * lane_count * 8 *
> -			  DP_DSC_FEC_OVERHEAD_FACTOR) /
> -		mode_clock;
> -
> -	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
> -	max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER /
> -		mode_hdisplay;
> -
> -	/*
> -	 * Greatest allowed DSC BPP = MIN (output BPP from avaialble Link BW
> -	 * check, output bpp from small joiner RAM check)
> -	 */
> -	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
> -
> -	/* Error out if the max bpp is less than smallest allowed valid bpp */
> -	if (bits_per_pixel < valid_dsc_bpp[0]) {
> -		DRM_DEBUG_KMS("Unsupported BPP %d\n", bits_per_pixel);
> -		return 0;
> -	}
> -
> -	/* Find the nearest match in the array of known BPPs from VESA */
> -	for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) {
> -		if (bits_per_pixel < valid_dsc_bpp[i + 1])
> -			break;
> -	}
> -	bits_per_pixel = valid_dsc_bpp[i];
> -
> -	/*
> -	 * Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
> -	 * fractional part is 0
> -	 */
> -	return bits_per_pixel << 4;
> -}
> -
> -u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
> -				int mode_clock,
> -				int mode_hdisplay)
> -{
> -	u8 min_slice_count, i;
> -	int max_slice_width;
> -
> -	if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE)
> -		min_slice_count = DIV_ROUND_UP(mode_clock,
> -					       DP_DSC_MAX_ENC_THROUGHPUT_0);
> -	else
> -		min_slice_count = DIV_ROUND_UP(mode_clock,
> -					       DP_DSC_MAX_ENC_THROUGHPUT_1);
> -
> -	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_DEBUG_KMS("Unsupported slice width %d by DP DSC Sink device\n",
> -			      max_slice_width);
> -		return 0;
> -	}
> -	/* Also take into account max slice width */
> -	min_slice_count = min_t(u8, min_slice_count,
> -				DIV_ROUND_UP(mode_hdisplay,
> -					     max_slice_width));
> -
> -	/* Find the closest match to the valid slice count values */
> -	for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
> -		if (valid_dsc_slicecount[i] >
> -		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
> -						    false))
> -			break;
> -		if (min_slice_count  <= valid_dsc_slicecount[i])
> -			return valid_dsc_slicecount[i];
> -	}
> -
> -	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
> -	return 0;
> -}
> -
>  static void
>  intel_pixel_encoding_setup_vsc(struct intel_dp *intel_dp,
>  			       const struct intel_crtc_state *crtc_state)
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
> index e01d1f89409d..e9f11e698697 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.h
> +++ b/drivers/gpu/drm/i915/display/intel_dp.h
> @@ -103,10 +103,6 @@ bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
>  bool intel_dp_source_supports_hbr3(struct intel_dp *intel_dp);
>  bool
>  intel_dp_get_link_status(struct intel_dp *intel_dp, u8 *link_status);
> -u16 intel_dp_dsc_get_output_bpp(int link_clock, u8 lane_count,
> -				int mode_clock, int mode_hdisplay);
> -u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp, int mode_clock,
> -				int mode_hdisplay);
>  
>  bool intel_dp_read_dpcd(struct intel_dp *intel_dp);
>  bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp);
> @@ -119,4 +115,6 @@ static inline unsigned int intel_dp_unused_lane_mask(int lane_count)
>  	return ~((1 << lane_count) - 1) & 0xf;
>  }
>  
> +u32 intel_dp_fec_to_mode_clock(u32 fec_clock);
> +
>  #endif /* __INTEL_DP_H__ */
> -- 
> 2.20.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Sasha Levin Sept. 21, 2019, 12:06 p.m. UTC | #2
Hi,

[This is an automated email]

This commit has been processed because it contains a "Fixes:" tag,
fixing commit: d9218c8f6cf4 drm/i915/dp: Add helpers for Compressed BPP and Slice Count for DSC.

The bot has tested the following trees: v5.2.16.

v5.2.16: Failed to apply! Possible dependencies:
    3c053a96ef5f ("drm/i915/dp: Program VSC Header and DB for Pixel Encoding/Colorimetry Format")
    7afc7f816870 ("drm/i915: Drop the _INCOMPLETE for has_infoframe")
    8e9d645c6831 ("drm/i915/dp: Add a config function for YCBCR420 outputs")


NOTE: The patch will not be queued to stable trees until it is upstream.

How should we proceed with this patch?

--
Thanks,
Sasha
Maarten Lankhorst Sept. 23, 2019, 10:43 a.m. UTC | #3
Op 21-09-2019 om 17:22 schreef Patchwork:
> == Series Details ==
>
> Series: series starting with [01/23] drm/i915/dp: Fix dsc bpp calculations, v2.
> URL   : https://patchwork.freedesktop.org/series/66998/
> State : failure
>
> == Summary ==
>
> CI Bug Log - changes from CI_DRM_6928_full -> Patchwork_14476_full
> ====================================================
>
> Summary
> -------
>
>   **FAILURE**
>
>   Serious unknown changes coming with Patchwork_14476_full absolutely need to be
>   verified manually.
>   
>   If you think the reported changes have nothing to do with the changes
>   introduced in Patchwork_14476_full, please notify your bug team to allow them
>   to document this new failure mode, which will reduce false positives in CI.
>
>   
>
> Possible new issues
> -------------------
>
>   Here are the unknown changes that may have been introduced in Patchwork_14476_full:
>
> ### IGT changes ###
>
> #### Possible regressions ####
>
>   * igt@kms_plane_lowres@pipe-a-tiling-x:
>     - shard-snb:          [PASS][1] -> [FAIL][2] +3 similar issues
>    [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-snb6/igt@kms_plane_lowres@pipe-a-tiling-x.html
>    [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-snb2/igt@kms_plane_lowres@pipe-a-tiling-x.html
>
>   * igt@kms_plane_lowres@pipe-a-tiling-yf:
>     - shard-skl:          [PASS][3] -> [FAIL][4] +11 similar issues
>    [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-skl7/igt@kms_plane_lowres@pipe-a-tiling-yf.html
>    [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-skl8/igt@kms_plane_lowres@pipe-a-tiling-yf.html
>
>   * igt@kms_plane_lowres@pipe-b-tiling-x:
>     - shard-glk:          [PASS][5] -> [FAIL][6] +11 similar issues
>    [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-glk2/igt@kms_plane_lowres@pipe-b-tiling-x.html
>    [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-glk2/igt@kms_plane_lowres@pipe-b-tiling-x.html
>     - shard-apl:          [PASS][7] -> [FAIL][8] +8 similar issues
>    [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-apl4/igt@kms_plane_lowres@pipe-b-tiling-x.html
>    [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-apl4/igt@kms_plane_lowres@pipe-b-tiling-x.html
>
>   * igt@kms_plane_lowres@pipe-b-tiling-y:
>     - shard-iclb:         NOTRUN -> [FAIL][9]
>    [9]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb5/igt@kms_plane_lowres@pipe-b-tiling-y.html
>
>   * igt@kms_plane_lowres@pipe-c-tiling-none:
>     - shard-iclb:         [PASS][10] -> [FAIL][11] +10 similar issues
>    [10]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb4/igt@kms_plane_lowres@pipe-c-tiling-none.html
>    [11]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb5/igt@kms_plane_lowres@pipe-c-tiling-none.html
>     - shard-hsw:          [PASS][12] -> [FAIL][13] +5 similar issues
>    [12]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-hsw5/igt@kms_plane_lowres@pipe-c-tiling-none.html
>    [13]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-hsw4/igt@kms_plane_lowres@pipe-c-tiling-none.html
>
>   * igt@kms_plane_lowres@pipe-c-tiling-y:
>     - shard-apl:          NOTRUN -> [FAIL][14]
>    [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-apl6/igt@kms_plane_lowres@pipe-c-tiling-y.html
>
>   * igt@kms_plane_lowres@pipe-c-tiling-yf:
>     - shard-kbl:          [PASS][15] -> [FAIL][16] +11 similar issues
>    [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-kbl1/igt@kms_plane_lowres@pipe-c-tiling-yf.html
>    [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-kbl3/igt@kms_plane_lowres@pipe-c-tiling-yf.html
kms_plane_lowres is failing because of the debugfs changes to i915_display_info, rest of tests pass. Needs some fixes to igt. :)
>   
> Known issues
> ------------
>
>   Here are the changes found in Patchwork_14476_full that come from known issues:
>
> ### IGT changes ###
>
> #### Issues hit ####
>
>   * igt@gem_ctx_shared@exec-single-timeline-bsd:
>     - shard-iclb:         [PASS][17] -> [SKIP][18] ([fdo#110841])
>    [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb6/igt@gem_ctx_shared@exec-single-timeline-bsd.html
>    [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb1/igt@gem_ctx_shared@exec-single-timeline-bsd.html
>
>   * igt@gem_exec_schedule@preempt-queue-bsd1:
>     - shard-iclb:         [PASS][19] -> [SKIP][20] ([fdo#109276]) +37 similar issues
>    [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb4/igt@gem_exec_schedule@preempt-queue-bsd1.html
>    [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb5/igt@gem_exec_schedule@preempt-queue-bsd1.html
>
>   * igt@gem_exec_schedule@reorder-wide-bsd:
>     - shard-iclb:         [PASS][21] -> [SKIP][22] ([fdo#111325]) +6 similar issues
>    [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb3/igt@gem_exec_schedule@reorder-wide-bsd.html
>    [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb2/igt@gem_exec_schedule@reorder-wide-bsd.html
>
>   * igt@kms_cursor_crc@pipe-b-cursor-64x21-offscreen:
>     - shard-apl:          [PASS][23] -> [INCOMPLETE][24] ([fdo#103927]) +3 similar issues
>    [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-apl1/igt@kms_cursor_crc@pipe-b-cursor-64x21-offscreen.html
>    [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-apl6/igt@kms_cursor_crc@pipe-b-cursor-64x21-offscreen.html
>
>   * igt@kms_cursor_legacy@2x-long-cursor-vs-flip-legacy:
>     - shard-hsw:          [PASS][25] -> [FAIL][26] ([fdo#105767])
>    [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-hsw5/igt@kms_cursor_legacy@2x-long-cursor-vs-flip-legacy.html
>    [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-hsw4/igt@kms_cursor_legacy@2x-long-cursor-vs-flip-legacy.html
>
>   * igt@kms_frontbuffer_tracking@fbc-1p-primscrn-shrfb-plflip-blt:
>     - shard-iclb:         [PASS][27] -> [FAIL][28] ([fdo#103167]) +4 similar issues
>    [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb4/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-shrfb-plflip-blt.html
>    [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb5/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-shrfb-plflip-blt.html
>
>   * igt@kms_plane@pixel-format-pipe-a-planes:
>     - shard-iclb:         [PASS][29] -> [DMESG-FAIL][30] ([fdo#107724]) +5 similar issues
>    [29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb3/igt@kms_plane@pixel-format-pipe-a-planes.html
>    [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb2/igt@kms_plane@pixel-format-pipe-a-planes.html
>
>   * igt@kms_plane_scaling@pipe-b-scaler-with-rotation:
>     - shard-iclb:         [PASS][31] -> [DMESG-WARN][32] ([fdo#107724]) +7 similar issues
>    [31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb6/igt@kms_plane_scaling@pipe-b-scaler-with-rotation.html
>    [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb3/igt@kms_plane_scaling@pipe-b-scaler-with-rotation.html
>
>   * igt@kms_psr@psr2_sprite_plane_move:
>     - shard-iclb:         [PASS][33] -> [SKIP][34] ([fdo#109441]) +4 similar issues
>    [33]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb2/igt@kms_psr@psr2_sprite_plane_move.html
>    [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb3/igt@kms_psr@psr2_sprite_plane_move.html
>
>   * igt@kms_rotation_crc@bad-pixel-format:
>     - shard-iclb:         [PASS][35] -> [DMESG-WARN][36] ([fdo#107724] / [fdo#108336])
>    [35]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb4/igt@kms_rotation_crc@bad-pixel-format.html
>    [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb5/igt@kms_rotation_crc@bad-pixel-format.html
>
>   * igt@kms_vblank@pipe-b-ts-continuation-suspend:
>     - shard-apl:          [PASS][37] -> [DMESG-WARN][38] ([fdo#108566]) +3 similar issues
>    [37]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-apl8/igt@kms_vblank@pipe-b-ts-continuation-suspend.html
>    [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-apl3/igt@kms_vblank@pipe-b-ts-continuation-suspend.html
>
>   * igt@kms_vblank@pipe-c-query-forked-hang:
>     - shard-hsw:          [PASS][39] -> [INCOMPLETE][40] ([fdo#103540])
>    [39]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-hsw5/igt@kms_vblank@pipe-c-query-forked-hang.html
>    [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-hsw6/igt@kms_vblank@pipe-c-query-forked-hang.html
>
>   
> #### Possible fixes ####
>
>   * igt@gem_exec_schedule@independent-bsd2:
>     - shard-iclb:         [SKIP][41] ([fdo#109276]) -> [PASS][42] +14 similar issues
>    [41]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb3/igt@gem_exec_schedule@independent-bsd2.html
>    [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb2/igt@gem_exec_schedule@independent-bsd2.html
>
>   * igt@gem_exec_schedule@preemptive-hang-bsd:
>     - shard-iclb:         [SKIP][43] ([fdo#111325]) -> [PASS][44] +7 similar issues
>    [43]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb1/igt@gem_exec_schedule@preemptive-hang-bsd.html
>    [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb5/igt@gem_exec_schedule@preemptive-hang-bsd.html
>
>   * igt@gem_tiled_swapping@non-threaded:
>     - shard-glk:          [DMESG-WARN][45] ([fdo#108686]) -> [PASS][46]
>    [45]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-glk4/igt@gem_tiled_swapping@non-threaded.html
>    [46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-glk4/igt@gem_tiled_swapping@non-threaded.html
>
>   * igt@i915_suspend@sysfs-reader:
>     - shard-apl:          [DMESG-WARN][47] ([fdo#108566]) -> [PASS][48] +4 similar issues
>    [47]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-apl1/igt@i915_suspend@sysfs-reader.html
>    [48]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-apl2/igt@i915_suspend@sysfs-reader.html
>
>   * igt@kms_cursor_crc@pipe-c-cursor-suspend:
>     - shard-skl:          [INCOMPLETE][49] ([fdo#110741]) -> [PASS][50]
>    [49]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-skl6/igt@kms_cursor_crc@pipe-c-cursor-suspend.html
>    [50]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-skl7/igt@kms_cursor_crc@pipe-c-cursor-suspend.html
>
>   * igt@kms_flip@flip-vs-dpms-interruptible:
>     - shard-iclb:         [INCOMPLETE][51] ([fdo#107713]) -> [PASS][52]
>    [51]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb1/igt@kms_flip@flip-vs-dpms-interruptible.html
>    [52]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb5/igt@kms_flip@flip-vs-dpms-interruptible.html
>
>   * igt@kms_flip@flip-vs-suspend-interruptible:
>     - shard-snb:          [DMESG-WARN][53] ([fdo#102365]) -> [PASS][54]
>    [53]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-snb4/igt@kms_flip@flip-vs-suspend-interruptible.html
>    [54]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-snb2/igt@kms_flip@flip-vs-suspend-interruptible.html
>
>   * igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-indfb-draw-pwrite:
>     - shard-iclb:         [FAIL][55] ([fdo#103167]) -> [PASS][56] +2 similar issues
>    [55]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb1/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-indfb-draw-pwrite.html
>    [56]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb6/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-indfb-draw-pwrite.html
>
>   * igt@kms_frontbuffer_tracking@psr-suspend:
>     - shard-skl:          [INCOMPLETE][57] ([fdo#104108] / [fdo#106978]) -> [PASS][58]
>    [57]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-skl9/igt@kms_frontbuffer_tracking@psr-suspend.html
>    [58]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-skl1/igt@kms_frontbuffer_tracking@psr-suspend.html
>
>   * igt@kms_plane_cursor@pipe-a-primary-size-128:
>     - shard-kbl:          [DMESG-WARN][59] ([fdo#103558] / [fdo#105602]) -> [PASS][60] +37 similar issues
>    [59]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-kbl6/igt@kms_plane_cursor@pipe-a-primary-size-128.html
>    [60]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-kbl4/igt@kms_plane_cursor@pipe-a-primary-size-128.html
>
>   * igt@kms_psr@psr2_sprite_mmap_gtt:
>     - shard-iclb:         [SKIP][61] ([fdo#109441]) -> [PASS][62] +3 similar issues
>    [61]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb1/igt@kms_psr@psr2_sprite_mmap_gtt.html
>    [62]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb2/igt@kms_psr@psr2_sprite_mmap_gtt.html
>
>   * igt@kms_setmode@basic:
>     - shard-apl:          [FAIL][63] ([fdo#99912]) -> [PASS][64]
>    [63]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-apl3/igt@kms_setmode@basic.html
>    [64]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-apl6/igt@kms_setmode@basic.html
>     - shard-hsw:          [FAIL][65] ([fdo#99912]) -> [PASS][66]
>    [65]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-hsw6/igt@kms_setmode@basic.html
>    [66]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-hsw6/igt@kms_setmode@basic.html
>
>   * igt@kms_vblank@pipe-a-ts-continuation-suspend:
>     - shard-apl:          [INCOMPLETE][67] ([fdo#103927]) -> [PASS][68] +2 similar issues
>    [67]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-apl4/igt@kms_vblank@pipe-a-ts-continuation-suspend.html
>    [68]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-apl8/igt@kms_vblank@pipe-a-ts-continuation-suspend.html
>
>   * igt@perf@blocking:
>     - shard-skl:          [FAIL][69] ([fdo#110728]) -> [PASS][70] +1 similar issue
>    [69]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-skl7/igt@perf@blocking.html
>    [70]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-skl3/igt@perf@blocking.html
>
>   
> #### Warnings ####
>
>   * igt@gem_ctx_isolation@vcs1-nonpriv:
>     - shard-iclb:         [FAIL][71] ([fdo#111329]) -> [SKIP][72] ([fdo#109276])
>    [71]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb4/igt@gem_ctx_isolation@vcs1-nonpriv.html
>    [72]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb8/igt@gem_ctx_isolation@vcs1-nonpriv.html
>
>   * igt@gem_mocs_settings@mocs-isolation-bsd2:
>     - shard-iclb:         [FAIL][73] ([fdo#111330]) -> [SKIP][74] ([fdo#109276]) +1 similar issue
>    [73]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb4/igt@gem_mocs_settings@mocs-isolation-bsd2.html
>    [74]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb5/igt@gem_mocs_settings@mocs-isolation-bsd2.html
>
>   * igt@kms_busy@extended-pageflip-modeset-hang-oldfb-render-d:
>     - shard-kbl:          [SKIP][75] ([fdo#105602] / [fdo#109271] / [fdo#109278]) -> [SKIP][76] ([fdo#109271] / [fdo#109278]) +3 similar issues
>    [75]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-kbl6/igt@kms_busy@extended-pageflip-modeset-hang-oldfb-render-d.html
>    [76]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-kbl4/igt@kms_busy@extended-pageflip-modeset-hang-oldfb-render-d.html
>
>   * igt@kms_flip@flip-vs-suspend-interruptible:
>     - shard-apl:          [DMESG-WARN][77] ([fdo#108566]) -> [INCOMPLETE][78] ([fdo#103927])
>    [77]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-apl3/igt@kms_flip@flip-vs-suspend-interruptible.html
>    [78]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-apl2/igt@kms_flip@flip-vs-suspend-interruptible.html
>
>   * igt@kms_panel_fitting@legacy:
>     - shard-kbl:          [SKIP][79] ([fdo#105602] / [fdo#109271]) -> [SKIP][80] ([fdo#109271]) +30 similar issues
>    [79]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-kbl6/igt@kms_panel_fitting@legacy.html
>    [80]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-kbl4/igt@kms_panel_fitting@legacy.html
>
>   
>   [fdo#102365]: https://bugs.freedesktop.org/show_bug.cgi?id=102365
>   [fdo#103167]: https://bugs.freedesktop.org/show_bug.cgi?id=103167
>   [fdo#103540]: https://bugs.freedesktop.org/show_bug.cgi?id=103540
>   [fdo#103558]: https://bugs.freedesktop.org/show_bug.cgi?id=103558
>   [fdo#103927]: https://bugs.freedesktop.org/show_bug.cgi?id=103927
>   [fdo#104108]: https://bugs.freedesktop.org/show_bug.cgi?id=104108
>   [fdo#105602]: https://bugs.freedesktop.org/show_bug.cgi?id=105602
>   [fdo#105767]: https://bugs.freedesktop.org/show_bug.cgi?id=105767
>   [fdo#106978]: https://bugs.freedesktop.org/show_bug.cgi?id=106978
>   [fdo#107713]: https://bugs.freedesktop.org/show_bug.cgi?id=107713
>   [fdo#107724]: https://bugs.freedesktop.org/show_bug.cgi?id=107724
>   [fdo#108336]: https://bugs.freedesktop.org/show_bug.cgi?id=108336
>   [fdo#108566]: https://bugs.freedesktop.org/show_bug.cgi?id=108566
>   [fdo#108686]: https://bugs.freedesktop.org/show_bug.cgi?id=108686
>   [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
>   [fdo#109276]: https://bugs.freedesktop.org/show_bug.cgi?id=109276
>   [fdo#109278]: https://bugs.freedesktop.org/show_bug.cgi?id=109278
>   [fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
>   [fdo#110728]: https://bugs.freedesktop.org/show_bug.cgi?id=110728
>   [fdo#110741]: https://bugs.freedesktop.org/show_bug.cgi?id=110741
>   [fdo#110841]: https://bugs.freedesktop.org/show_bug.cgi?id=110841
>   [fdo#111325]: https://bugs.freedesktop.org/show_bug.cgi?id=111325
>   [fdo#111329]: https://bugs.freedesktop.org/show_bug.cgi?id=111329
>   [fdo#111330]: https://bugs.freedesktop.org/show_bug.cgi?id=111330
>   [fdo#99912]: https://bugs.freedesktop.org/show_bug.cgi?id=99912
>
>
> Participating hosts (9 -> 9)
> ------------------------------
>
>   No changes in participating hosts
>
>
> Build changes
> -------------
>
>   * CI: CI-20190529 -> None
>   * Linux: CI_DRM_6928 -> Patchwork_14476
>
>   CI-20190529: 20190529
>   CI_DRM_6928: 74bb5b031ca11c7036f7be21f42a73a057fc8da8 @ git://anongit.freedesktop.org/gfx-ci/linux
>   IGT_5194: 531d3d02d5e7a2a84d61b92b28fa01b822afc399 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
>   Patchwork_14476: 4fc8d6917d9641566f066833c6cd4a367858864a @ git://anongit.freedesktop.org/gfx-ci/linux
>   piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit
>
> == Logs ==
>
> For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 3e6394139964..1b59b852874b 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -1479,6 +1479,10 @@  static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
 	if (pipe_config->pixel_multiplier)
 		dotclock /= pipe_config->pixel_multiplier;
 
+	/* fec adds overhead to the data M/N values, correct for it */
+	if (pipe_config->fec_enable)
+		dotclock = intel_dp_fec_to_mode_clock(dotclock);
+
 	pipe_config->base.adjusted_mode.crtc_clock = dotclock;
 }
 
@@ -4031,7 +4035,9 @@  void intel_ddi_get_config(struct intel_encoder *encoder,
 	case TRANS_DDI_MODE_SELECT_FDI:
 		pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG);
 		break;
-	case TRANS_DDI_MODE_SELECT_DP_SST:
+	case TRANS_DDI_MODE_SELECT_DP_SST: {
+		struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+
 		if (encoder->type == INTEL_OUTPUT_EDP)
 			pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP);
 		else
@@ -4039,7 +4045,18 @@  void intel_ddi_get_config(struct intel_encoder *encoder,
 		pipe_config->lane_count =
 			((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
 		intel_dp_get_m_n(intel_crtc, pipe_config);
+
+		if (INTEL_GEN(dev_priv) >= 11) {
+			pipe_config->fec_enable =
+				I915_READ(intel_dp->regs.dp_tp_ctl) &
+					  DP_TP_CTL_FEC_ENABLE;
+			DRM_DEBUG_KMS("[ENCODER:%d:%s] Fec status: %u\n",
+				      encoder->base.base.id, encoder->base.name,
+				      pipe_config->fec_enable);
+		}
+
 		break;
+	}
 	case TRANS_DDI_MODE_SELECT_DP_MST:
 		pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST);
 		pipe_config->lane_count =
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index e0033d99f6e3..7996864e6f7c 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -12773,6 +12773,7 @@  intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 	PIPE_CONF_CHECK_BOOL(hdmi_scrambling);
 	PIPE_CONF_CHECK_BOOL(hdmi_high_tmds_clock_ratio);
 	PIPE_CONF_CHECK_BOOL(has_infoframe);
+	PIPE_CONF_CHECK_BOOL(fec_enable);
 
 	PIPE_CONF_CHECK_BOOL_INCOMPLETE(has_audio);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index ccaf9f00b747..4dfb78dc7fa2 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -76,8 +76,8 @@ 
 #define DP_DSC_MAX_ENC_THROUGHPUT_0		340000
 #define DP_DSC_MAX_ENC_THROUGHPUT_1		400000
 
-/* DP DSC FEC Overhead factor = (100 - 2.4)/100 */
-#define DP_DSC_FEC_OVERHEAD_FACTOR		976
+/* DP DSC FEC Overhead factor = 1/(0.972261) */
+#define DP_DSC_FEC_OVERHEAD_FACTOR		972261
 
 /* Compliance test status bits  */
 #define INTEL_DP_RESOLUTION_SHIFT_MASK	0
@@ -492,6 +492,104 @@  int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
 	return 0;
 }
 
+static inline u32 intel_dp_mode_to_fec_clock(u32 mode_clock)
+{
+	return div_u64(mul_u32_u32(mode_clock, 1000000U),
+		       DP_DSC_FEC_OVERHEAD_FACTOR);
+}
+
+u32 intel_dp_fec_to_mode_clock(u32 fec_clock)
+{
+	return div_u64(mul_u32_u32(fec_clock,
+				   DP_DSC_FEC_OVERHEAD_FACTOR),
+		       1000000U);
+}
+
+static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
+				       u32 mode_clock, u32 mode_hdisplay)
+{
+	u32 bits_per_pixel, max_bpp_small_joiner_ram;
+	int i;
+
+	/*
+	 * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
+	 * (LinkSymbolClock)* 8 * (TimeSlotsPerMTP)
+	 * for SST -> TimeSlotsPerMTP is 1,
+	 * for MST -> TimeSlotsPerMTP has to be calculated
+	 */
+	bits_per_pixel = (link_clock * lane_count * 8) /
+			 intel_dp_mode_to_fec_clock(mode_clock);
+	DRM_DEBUG_KMS("Max link bpp: %u\n", bits_per_pixel);
+
+	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
+	max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER / mode_hdisplay;
+	DRM_DEBUG_KMS("Max small joiner bpp: %u\n", max_bpp_small_joiner_ram);
+
+	/*
+	 * Greatest allowed DSC BPP = MIN (output BPP from available Link BW
+	 * check, output bpp from small joiner RAM check)
+	 */
+	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
+
+	/* Error out if the max bpp is less than smallest allowed valid bpp */
+	if (bits_per_pixel < valid_dsc_bpp[0]) {
+		DRM_DEBUG_KMS("Unsupported BPP %u, min %u\n",
+			      bits_per_pixel, valid_dsc_bpp[0]);
+		return 0;
+	}
+
+	/* Find the nearest match in the array of known BPPs from VESA */
+	for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) {
+		if (bits_per_pixel < valid_dsc_bpp[i + 1])
+			break;
+	}
+	bits_per_pixel = valid_dsc_bpp[i];
+
+	/*
+	 * Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
+	 * fractional part is 0
+	 */
+	return bits_per_pixel << 4;
+}
+
+static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
+				       int mode_clock, int mode_hdisplay)
+{
+	u8 min_slice_count, i;
+	int max_slice_width;
+
+	if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE)
+		min_slice_count = DIV_ROUND_UP(mode_clock,
+					       DP_DSC_MAX_ENC_THROUGHPUT_0);
+	else
+		min_slice_count = DIV_ROUND_UP(mode_clock,
+					       DP_DSC_MAX_ENC_THROUGHPUT_1);
+
+	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_DEBUG_KMS("Unsupported slice width %d by DP DSC Sink device\n",
+			      max_slice_width);
+		return 0;
+	}
+	/* Also take into account max slice width */
+	min_slice_count = min_t(u8, min_slice_count,
+				DIV_ROUND_UP(mode_hdisplay,
+					     max_slice_width));
+
+	/* Find the closest match to the valid slice count values */
+	for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
+		if (valid_dsc_slicecount[i] >
+		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
+						    false))
+			break;
+		if (min_slice_count  <= valid_dsc_slicecount[i])
+			return valid_dsc_slicecount[i];
+	}
+
+	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
+	return 0;
+}
+
 static enum drm_mode_status
 intel_dp_mode_valid(struct drm_connector *connector,
 		    struct drm_display_mode *mode)
@@ -2182,6 +2280,7 @@  intel_dp_compute_config(struct intel_encoder *encoder,
 	bool constant_n = drm_dp_has_quirk(&intel_dp->desc,
 					   DP_DPCD_QUIRK_CONSTANT_N);
 	int ret = 0, output_bpp;
+	u32 data_clock;
 
 	if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv) && port != PORT_A)
 		pipe_config->has_pch_encoder = true;
@@ -2244,9 +2343,14 @@  intel_dp_compute_config(struct intel_encoder *encoder,
 	else
 		output_bpp = intel_dp_output_bpp(pipe_config, pipe_config->pipe_bpp);
 
+	if (pipe_config->fec_enable)
+		data_clock = intel_dp_mode_to_fec_clock(adjusted_mode->crtc_clock);
+	else
+		data_clock = adjusted_mode->crtc_clock;
+
 	intel_link_compute_m_n(output_bpp,
 			       pipe_config->lane_count,
-			       adjusted_mode->crtc_clock,
+			       data_clock,
 			       pipe_config->port_clock,
 			       &pipe_config->dp_m_n,
 			       constant_n);
@@ -4363,91 +4467,6 @@  intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *sink_irq_vector)
 		DP_DPRX_ESI_LEN;
 }
 
-u16 intel_dp_dsc_get_output_bpp(int link_clock, u8 lane_count,
-				int mode_clock, int mode_hdisplay)
-{
-	u16 bits_per_pixel, max_bpp_small_joiner_ram;
-	int i;
-
-	/*
-	 * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
-	 * (LinkSymbolClock)* 8 * ((100-FECOverhead)/100)*(TimeSlotsPerMTP)
-	 * FECOverhead = 2.4%, for SST -> TimeSlotsPerMTP is 1,
-	 * for MST -> TimeSlotsPerMTP has to be calculated
-	 */
-	bits_per_pixel = (link_clock * lane_count * 8 *
-			  DP_DSC_FEC_OVERHEAD_FACTOR) /
-		mode_clock;
-
-	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
-	max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER /
-		mode_hdisplay;
-
-	/*
-	 * Greatest allowed DSC BPP = MIN (output BPP from avaialble Link BW
-	 * check, output bpp from small joiner RAM check)
-	 */
-	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
-
-	/* Error out if the max bpp is less than smallest allowed valid bpp */
-	if (bits_per_pixel < valid_dsc_bpp[0]) {
-		DRM_DEBUG_KMS("Unsupported BPP %d\n", bits_per_pixel);
-		return 0;
-	}
-
-	/* Find the nearest match in the array of known BPPs from VESA */
-	for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) {
-		if (bits_per_pixel < valid_dsc_bpp[i + 1])
-			break;
-	}
-	bits_per_pixel = valid_dsc_bpp[i];
-
-	/*
-	 * Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
-	 * fractional part is 0
-	 */
-	return bits_per_pixel << 4;
-}
-
-u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
-				int mode_clock,
-				int mode_hdisplay)
-{
-	u8 min_slice_count, i;
-	int max_slice_width;
-
-	if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE)
-		min_slice_count = DIV_ROUND_UP(mode_clock,
-					       DP_DSC_MAX_ENC_THROUGHPUT_0);
-	else
-		min_slice_count = DIV_ROUND_UP(mode_clock,
-					       DP_DSC_MAX_ENC_THROUGHPUT_1);
-
-	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_DEBUG_KMS("Unsupported slice width %d by DP DSC Sink device\n",
-			      max_slice_width);
-		return 0;
-	}
-	/* Also take into account max slice width */
-	min_slice_count = min_t(u8, min_slice_count,
-				DIV_ROUND_UP(mode_hdisplay,
-					     max_slice_width));
-
-	/* Find the closest match to the valid slice count values */
-	for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
-		if (valid_dsc_slicecount[i] >
-		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
-						    false))
-			break;
-		if (min_slice_count  <= valid_dsc_slicecount[i])
-			return valid_dsc_slicecount[i];
-	}
-
-	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
-	return 0;
-}
-
 static void
 intel_pixel_encoding_setup_vsc(struct intel_dp *intel_dp,
 			       const struct intel_crtc_state *crtc_state)
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index e01d1f89409d..e9f11e698697 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -103,10 +103,6 @@  bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
 bool intel_dp_source_supports_hbr3(struct intel_dp *intel_dp);
 bool
 intel_dp_get_link_status(struct intel_dp *intel_dp, u8 *link_status);
-u16 intel_dp_dsc_get_output_bpp(int link_clock, u8 lane_count,
-				int mode_clock, int mode_hdisplay);
-u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp, int mode_clock,
-				int mode_hdisplay);
 
 bool intel_dp_read_dpcd(struct intel_dp *intel_dp);
 bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp);
@@ -119,4 +115,6 @@  static inline unsigned int intel_dp_unused_lane_mask(int lane_count)
 	return ~((1 << lane_count) - 1) & 0xf;
 }
 
+u32 intel_dp_fec_to_mode_clock(u32 fec_clock);
+
 #endif /* __INTEL_DP_H__ */