diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_dp.c')
| -rw-r--r-- | drivers/gpu/drm/i915/display/intel_dp.c | 1664 | 
1 files changed, 155 insertions, 1509 deletions
| diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 8c12d5375607..a560468765c0 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -39,6 +39,7 @@  #include <drm/drm_edid.h>  #include <drm/drm_probe_helper.h> +#include "g4x_dp.h"  #include "i915_debugfs.h"  #include "i915_drv.h"  #include "intel_atomic.h" @@ -50,6 +51,7 @@  #include "intel_dp_aux.h"  #include "intel_dp_link_training.h"  #include "intel_dp_mst.h" +#include "intel_dpll.h"  #include "intel_dpio_phy.h"  #include "intel_fifo_underrun.h"  #include "intel_hdcp.h" @@ -81,52 +83,6 @@  #define INTEL_DP_RESOLUTION_STANDARD	(2 << INTEL_DP_RESOLUTION_SHIFT_MASK)  #define INTEL_DP_RESOLUTION_FAILSAFE	(3 << INTEL_DP_RESOLUTION_SHIFT_MASK) -struct dp_link_dpll { -	int clock; -	struct dpll dpll; -}; - -static const struct dp_link_dpll g4x_dpll[] = { -	{ 162000, -		{ .p1 = 2, .p2 = 10, .n = 2, .m1 = 23, .m2 = 8 } }, -	{ 270000, -		{ .p1 = 1, .p2 = 10, .n = 1, .m1 = 14, .m2 = 2 } } -}; - -static const struct dp_link_dpll pch_dpll[] = { -	{ 162000, -		{ .p1 = 2, .p2 = 10, .n = 1, .m1 = 12, .m2 = 9 } }, -	{ 270000, -		{ .p1 = 1, .p2 = 10, .n = 2, .m1 = 14, .m2 = 8 } } -}; - -static const struct dp_link_dpll vlv_dpll[] = { -	{ 162000, -		{ .p1 = 3, .p2 = 2, .n = 5, .m1 = 3, .m2 = 81 } }, -	{ 270000, -		{ .p1 = 2, .p2 = 2, .n = 1, .m1 = 2, .m2 = 27 } } -}; - -/* - * CHV supports eDP 1.4 that have  more link rates. - * Below only provides the fixed rate but exclude variable rate. - */ -static const struct dp_link_dpll chv_dpll[] = { -	/* -	 * CHV requires to program fractional division for m2. -	 * m2 is stored in fixed point format using formula below -	 * (m2_int << 22) | m2_fraction -	 */ -	{ 162000,	/* m2_int = 32, m2_fraction = 1677722 */ -		{ .p1 = 4, .p2 = 2, .n = 1, .m1 = 2, .m2 = 0x819999a } }, -	{ 270000,	/* m2_int = 27, m2_fraction = 0 */ -		{ .p1 = 4, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x6c00000 } }, -}; - -const struct dpll *vlv_get_dpll(struct drm_i915_private *i915) -{ -	return IS_CHERRYVIEW(i915) ? &chv_dpll[0].dpll : &vlv_dpll[0].dpll; -}  /* Constants for DP DSC configurations */  static const u8 valid_dsc_bpp[] = {6, 8, 10, 12, 15}; @@ -150,8 +106,6 @@ bool intel_dp_is_edp(struct intel_dp *intel_dp)  	return dig_port->base.type == INTEL_OUTPUT_EDP;  } -static void intel_dp_link_down(struct intel_encoder *encoder, -			       const struct intel_crtc_state *old_crtc_state);  static void intel_dp_unset_edid(struct intel_dp *intel_dp);  /* update sink rates from dpcd */ @@ -260,8 +214,8 @@ bool intel_dp_can_bigjoiner(struct intel_dp *intel_dp)  	struct intel_encoder *encoder = &intel_dig_port->base;  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); -	return INTEL_GEN(dev_priv) >= 12 || -		(INTEL_GEN(dev_priv) == 11 && +	return DISPLAY_VER(dev_priv) >= 12 || +		(IS_DISPLAY_VER(dev_priv, 11) &&  		 encoder->port != PORT_A);  } @@ -338,10 +292,10 @@ intel_dp_set_source_rates(struct intel_dp *intel_dp)  	drm_WARN_ON(&dev_priv->drm,  		    intel_dp->source_rates || intel_dp->num_source_rates); -	if (INTEL_GEN(dev_priv) >= 10) { +	if (DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv)) {  		source_rates = cnl_rates;  		size = ARRAY_SIZE(cnl_rates); -		if (IS_GEN(dev_priv, 10)) +		if (IS_DISPLAY_VER(dev_priv, 10))  			max_rate = cnl_max_source_rate(intel_dp);  		else if (IS_JSL_EHL(dev_priv))  			max_rate = ehl_max_source_rate(intel_dp); @@ -529,7 +483,7 @@ u32 intel_dp_mode_to_fec_clock(u32 mode_clock)  static int  small_joiner_ram_size_bits(struct drm_i915_private *i915)  { -	if (INTEL_GEN(i915) >= 11) +	if (DISPLAY_VER(i915) >= 11)  		return 7680 * 8;  	else  		return 6144 * 8; @@ -788,10 +742,10 @@ intel_dp_mode_valid(struct drm_connector *connector,  		return MODE_H_ILLEGAL;  	if (intel_dp_is_edp(intel_dp) && fixed_mode) { -		if (mode->hdisplay > fixed_mode->hdisplay) +		if (mode->hdisplay != fixed_mode->hdisplay)  			return MODE_PANEL; -		if (mode->vdisplay > fixed_mode->vdisplay) +		if (mode->vdisplay != fixed_mode->vdisplay)  			return MODE_PANEL;  		target_clock = fixed_mode->clock; @@ -822,7 +776,7 @@ intel_dp_mode_valid(struct drm_connector *connector,  	 * Output bpp is stored in 6.4 format so right shift by 4 to get the  	 * integer value since we support only integer values of bpp.  	 */ -	if ((INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) && +	if (DISPLAY_VER(dev_priv) >= 10 &&  	    drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd)) {  		if (intel_dp_is_edp(intel_dp)) {  			dsc_max_output_bpp = @@ -877,39 +831,6 @@ bool intel_dp_source_supports_hbr3(struct intel_dp *intel_dp)  	return max_rate >= 810000;  } -static void -intel_dp_set_clock(struct intel_encoder *encoder, -		   struct intel_crtc_state *pipe_config) -{ -	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); -	const struct dp_link_dpll *divisor = NULL; -	int i, count = 0; - -	if (IS_G4X(dev_priv)) { -		divisor = g4x_dpll; -		count = ARRAY_SIZE(g4x_dpll); -	} else if (HAS_PCH_SPLIT(dev_priv)) { -		divisor = pch_dpll; -		count = ARRAY_SIZE(pch_dpll); -	} else if (IS_CHERRYVIEW(dev_priv)) { -		divisor = chv_dpll; -		count = ARRAY_SIZE(chv_dpll); -	} else if (IS_VALLEYVIEW(dev_priv)) { -		divisor = vlv_dpll; -		count = ARRAY_SIZE(vlv_dpll); -	} - -	if (divisor && count) { -		for (i = 0; i < count; i++) { -			if (pipe_config->port_clock == divisor[i].clock) { -				pipe_config->dpll = divisor[i].dpll; -				pipe_config->clock_set = true; -				break; -			} -		} -	} -} -  static void snprintf_int_array(char *str, size_t len,  			       const int *array, int nelem)  { @@ -992,10 +913,10 @@ static bool intel_dp_source_supports_fec(struct intel_dp *intel_dp,  	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);  	/* On TGL, FEC is supported on all Pipes */ -	if (INTEL_GEN(dev_priv) >= 12) +	if (DISPLAY_VER(dev_priv) >= 12)  		return true; -	if (IS_GEN(dev_priv, 11) && pipe_config->cpu_transcoder != TRANSCODER_A) +	if (IS_DISPLAY_VER(dev_priv, 11) && pipe_config->cpu_transcoder != TRANSCODER_A)  		return true;  	return false; @@ -1314,7 +1235,7 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,  		return -EINVAL;  	/* Max DSC Input BPC for ICL is 10 and for TGL+ is 12 */ -	if (INTEL_GEN(dev_priv) >= 12) +	if (DISPLAY_VER(dev_priv) >= 12)  		dsc_max_bpc = min_t(u8, 12, conn_state->max_requested_bpc);  	else  		dsc_max_bpc = min_t(u8, 10, @@ -1553,7 +1474,7 @@ static bool intel_dp_port_has_audio(struct drm_i915_private *dev_priv,  {  	if (IS_G4X(dev_priv))  		return false; -	if (INTEL_GEN(dev_priv) < 12 && port == PORT_A) +	if (DISPLAY_VER(dev_priv) < 12 && port == PORT_A)  		return false;  	return true; @@ -1663,12 +1584,10 @@ void intel_dp_compute_psr_vsc_sdp(struct intel_dp *intel_dp,  				  const struct drm_connector_state *conn_state,  				  struct drm_dp_vsc_sdp *vsc)  { -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); -  	vsc->sdp_type = DP_SDP_VSC; -	if (dev_priv->psr.psr2_enabled) { -		if (dev_priv->psr.colorimetry_support && +	if (intel_dp->psr.psr2_enabled) { +		if (intel_dp->psr.colorimetry_support &&  		    intel_dp_needs_vsc_sdp(crtc_state, conn_state)) {  			/* [PSR2, +Colorimetry] */  			intel_dp_compute_vsc_colorimetry(crtc_state, conn_state, @@ -1724,6 +1643,7 @@ intel_dp_drrs_compute_config(struct intel_dp *intel_dp,  {  	struct intel_connector *intel_connector = intel_dp->attached_connector;  	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); +	int pixel_clock;  	if (pipe_config->vrr.enable)  		return; @@ -1742,10 +1662,18 @@ intel_dp_drrs_compute_config(struct intel_dp *intel_dp,  		return;  	pipe_config->has_drrs = true; -	intel_link_compute_m_n(output_bpp, pipe_config->lane_count, -			       intel_connector->panel.downclock_mode->clock, + +	pixel_clock = intel_connector->panel.downclock_mode->clock; +	if (pipe_config->splitter.enable) +		pixel_clock /= pipe_config->splitter.link_count; + +	intel_link_compute_m_n(output_bpp, pipe_config->lane_count, pixel_clock,  			       pipe_config->port_clock, &pipe_config->dp_m2_n2,  			       constant_n, pipe_config->fec_enable); + +	/* FIXME: abstract this better */ +	if (pipe_config->splitter.enable) +		pipe_config->dp_m2_n2.gmch_m *= pipe_config->splitter.link_count;  }  int @@ -1820,6 +1748,26 @@ intel_dp_compute_config(struct intel_encoder *encoder,  		output_bpp = intel_dp_output_bpp(pipe_config->output_format,  						 pipe_config->pipe_bpp); +	if (intel_dp->mso_link_count) { +		int n = intel_dp->mso_link_count; +		int overlap = intel_dp->mso_pixel_overlap; + +		pipe_config->splitter.enable = true; +		pipe_config->splitter.link_count = n; +		pipe_config->splitter.pixel_overlap = overlap; + +		drm_dbg_kms(&dev_priv->drm, "MSO link count %d, pixel overlap %d\n", +			    n, overlap); + +		adjusted_mode->crtc_hdisplay = adjusted_mode->crtc_hdisplay / n + overlap; +		adjusted_mode->crtc_hblank_start = adjusted_mode->crtc_hblank_start / n + overlap; +		adjusted_mode->crtc_hblank_end = adjusted_mode->crtc_hblank_end / n + overlap; +		adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hsync_start / n + overlap; +		adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_end / n + overlap; +		adjusted_mode->crtc_htotal = adjusted_mode->crtc_htotal / n + overlap; +		adjusted_mode->crtc_clock /= n; +	} +  	intel_link_compute_m_n(output_bpp,  			       pipe_config->lane_count,  			       adjusted_mode->crtc_clock, @@ -1827,8 +1775,12 @@ intel_dp_compute_config(struct intel_encoder *encoder,  			       &pipe_config->dp_m_n,  			       constant_n, pipe_config->fec_enable); +	/* FIXME: abstract this better */ +	if (pipe_config->splitter.enable) +		pipe_config->dp_m_n.gmch_m *= pipe_config->splitter.link_count; +  	if (!HAS_DDI(dev_priv)) -		intel_dp_set_clock(encoder, pipe_config); +		g4x_dp_set_clock(encoder, pipe_config);  	intel_vrr_compute_config(pipe_config, conn_state);  	intel_psr_compute_config(intel_dp, pipe_config); @@ -1848,90 +1800,6 @@ void intel_dp_set_link_params(struct intel_dp *intel_dp,  	intel_dp->lane_count = lane_count;  } -static void intel_dp_prepare(struct intel_encoder *encoder, -			     const struct intel_crtc_state *pipe_config) -{ -	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); -	struct intel_dp *intel_dp = enc_to_intel_dp(encoder); -	enum port port = encoder->port; -	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); -	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; - -	intel_dp_set_link_params(intel_dp, -				 pipe_config->port_clock, -				 pipe_config->lane_count); - -	/* -	 * There are four kinds of DP registers: -	 * -	 * 	IBX PCH -	 * 	SNB CPU -	 *	IVB CPU -	 * 	CPT PCH -	 * -	 * IBX PCH and CPU are the same for almost everything, -	 * except that the CPU DP PLL is configured in this -	 * register -	 * -	 * CPT PCH is quite different, having many bits moved -	 * to the TRANS_DP_CTL register instead. That -	 * configuration happens (oddly) in ilk_pch_enable -	 */ - -	/* Preserve the BIOS-computed detected bit. This is -	 * supposed to be read-only. -	 */ -	intel_dp->DP = intel_de_read(dev_priv, intel_dp->output_reg) & DP_DETECTED; - -	/* Handle DP bits in common between all three register formats */ -	intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0; -	intel_dp->DP |= DP_PORT_WIDTH(pipe_config->lane_count); - -	/* Split out the IBX/CPU vs CPT settings */ - -	if (IS_IVYBRIDGE(dev_priv) && port == PORT_A) { -		if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) -			intel_dp->DP |= DP_SYNC_HS_HIGH; -		if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) -			intel_dp->DP |= DP_SYNC_VS_HIGH; -		intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT; - -		if (drm_dp_enhanced_frame_cap(intel_dp->dpcd)) -			intel_dp->DP |= DP_ENHANCED_FRAMING; - -		intel_dp->DP |= DP_PIPE_SEL_IVB(crtc->pipe); -	} else if (HAS_PCH_CPT(dev_priv) && port != PORT_A) { -		u32 trans_dp; - -		intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT; - -		trans_dp = intel_de_read(dev_priv, TRANS_DP_CTL(crtc->pipe)); -		if (drm_dp_enhanced_frame_cap(intel_dp->dpcd)) -			trans_dp |= TRANS_DP_ENH_FRAMING; -		else -			trans_dp &= ~TRANS_DP_ENH_FRAMING; -		intel_de_write(dev_priv, TRANS_DP_CTL(crtc->pipe), trans_dp); -	} else { -		if (IS_G4X(dev_priv) && pipe_config->limited_color_range) -			intel_dp->DP |= DP_COLOR_RANGE_16_235; - -		if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) -			intel_dp->DP |= DP_SYNC_HS_HIGH; -		if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) -			intel_dp->DP |= DP_SYNC_VS_HIGH; -		intel_dp->DP |= DP_LINK_TRAIN_OFF; - -		if (drm_dp_enhanced_frame_cap(intel_dp->dpcd)) -			intel_dp->DP |= DP_ENHANCED_FRAMING; - -		if (IS_CHERRYVIEW(dev_priv)) -			intel_dp->DP |= DP_PIPE_SEL_CHV(crtc->pipe); -		else -			intel_dp->DP |= DP_PIPE_SEL(crtc->pipe); -	} -} - -  /* Enable backlight PWM and backlight PP control. */  void intel_edp_backlight_on(const struct intel_crtc_state *crtc_state,  			    const struct drm_connector_state *conn_state) @@ -1963,89 +1831,6 @@ void intel_edp_backlight_off(const struct drm_connector_state *old_conn_state)  	intel_panel_disable_backlight(old_conn_state);  } -static void assert_dp_port(struct intel_dp *intel_dp, bool state) -{ -	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); -	struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); -	bool cur_state = intel_de_read(dev_priv, intel_dp->output_reg) & DP_PORT_EN; - -	I915_STATE_WARN(cur_state != state, -			"[ENCODER:%d:%s] state assertion failure (expected %s, current %s)\n", -			dig_port->base.base.base.id, dig_port->base.base.name, -			onoff(state), onoff(cur_state)); -} -#define assert_dp_port_disabled(d) assert_dp_port((d), false) - -static void assert_edp_pll(struct drm_i915_private *dev_priv, bool state) -{ -	bool cur_state = intel_de_read(dev_priv, DP_A) & DP_PLL_ENABLE; - -	I915_STATE_WARN(cur_state != state, -			"eDP PLL state assertion failure (expected %s, current %s)\n", -			onoff(state), onoff(cur_state)); -} -#define assert_edp_pll_enabled(d) assert_edp_pll((d), true) -#define assert_edp_pll_disabled(d) assert_edp_pll((d), false) - -static void ilk_edp_pll_on(struct intel_dp *intel_dp, -			   const 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); - -	assert_pipe_disabled(dev_priv, pipe_config->cpu_transcoder); -	assert_dp_port_disabled(intel_dp); -	assert_edp_pll_disabled(dev_priv); - -	drm_dbg_kms(&dev_priv->drm, "enabling eDP PLL for clock %d\n", -		    pipe_config->port_clock); - -	intel_dp->DP &= ~DP_PLL_FREQ_MASK; - -	if (pipe_config->port_clock == 162000) -		intel_dp->DP |= DP_PLL_FREQ_162MHZ; -	else -		intel_dp->DP |= DP_PLL_FREQ_270MHZ; - -	intel_de_write(dev_priv, DP_A, intel_dp->DP); -	intel_de_posting_read(dev_priv, DP_A); -	udelay(500); - -	/* -	 * [DevILK] Work around required when enabling DP PLL -	 * while a pipe is enabled going to FDI: -	 * 1. Wait for the start of vertical blank on the enabled pipe going to FDI -	 * 2. Program DP PLL enable -	 */ -	if (IS_GEN(dev_priv, 5)) -		intel_wait_for_vblank_if_active(dev_priv, !crtc->pipe); - -	intel_dp->DP |= DP_PLL_ENABLE; - -	intel_de_write(dev_priv, DP_A, intel_dp->DP); -	intel_de_posting_read(dev_priv, DP_A); -	udelay(200); -} - -static void ilk_edp_pll_off(struct intel_dp *intel_dp, -			    const struct intel_crtc_state *old_crtc_state) -{ -	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); -	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - -	assert_pipe_disabled(dev_priv, old_crtc_state->cpu_transcoder); -	assert_dp_port_disabled(intel_dp); -	assert_edp_pll_enabled(dev_priv); - -	drm_dbg_kms(&dev_priv->drm, "disabling eDP PLL\n"); - -	intel_dp->DP &= ~DP_PLL_ENABLE; - -	intel_de_write(dev_priv, DP_A, intel_dp->DP); -	intel_de_posting_read(dev_priv, DP_A); -	udelay(200); -} -  static bool downstream_hpd_needs_d0(struct intel_dp *intel_dp)  {  	/* @@ -2148,160 +1933,6 @@ void intel_dp_set_power(struct intel_dp *intel_dp, u8 mode)  			    mode == DP_SET_POWER_D0 ? "D0" : "D3");  } -static bool cpt_dp_port_selected(struct drm_i915_private *dev_priv, -				 enum port port, enum pipe *pipe) -{ -	enum pipe p; - -	for_each_pipe(dev_priv, p) { -		u32 val = intel_de_read(dev_priv, TRANS_DP_CTL(p)); - -		if ((val & TRANS_DP_PORT_SEL_MASK) == TRANS_DP_PORT_SEL(port)) { -			*pipe = p; -			return true; -		} -	} - -	drm_dbg_kms(&dev_priv->drm, "No pipe for DP port %c found\n", -		    port_name(port)); - -	/* must initialize pipe to something for the asserts */ -	*pipe = PIPE_A; - -	return false; -} - -bool intel_dp_port_enabled(struct drm_i915_private *dev_priv, -			   i915_reg_t dp_reg, enum port port, -			   enum pipe *pipe) -{ -	bool ret; -	u32 val; - -	val = intel_de_read(dev_priv, dp_reg); - -	ret = val & DP_PORT_EN; - -	/* asserts want to know the pipe even if the port is disabled */ -	if (IS_IVYBRIDGE(dev_priv) && port == PORT_A) -		*pipe = (val & DP_PIPE_SEL_MASK_IVB) >> DP_PIPE_SEL_SHIFT_IVB; -	else if (HAS_PCH_CPT(dev_priv) && port != PORT_A) -		ret &= cpt_dp_port_selected(dev_priv, port, pipe); -	else if (IS_CHERRYVIEW(dev_priv)) -		*pipe = (val & DP_PIPE_SEL_MASK_CHV) >> DP_PIPE_SEL_SHIFT_CHV; -	else -		*pipe = (val & DP_PIPE_SEL_MASK) >> DP_PIPE_SEL_SHIFT; - -	return ret; -} - -static bool intel_dp_get_hw_state(struct intel_encoder *encoder, -				  enum pipe *pipe) -{ -	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); -	struct intel_dp *intel_dp = enc_to_intel_dp(encoder); -	intel_wakeref_t wakeref; -	bool ret; - -	wakeref = intel_display_power_get_if_enabled(dev_priv, -						     encoder->power_domain); -	if (!wakeref) -		return false; - -	ret = intel_dp_port_enabled(dev_priv, intel_dp->output_reg, -				    encoder->port, pipe); - -	intel_display_power_put(dev_priv, encoder->power_domain, wakeref); - -	return ret; -} - -static void intel_dp_get_config(struct intel_encoder *encoder, -				struct intel_crtc_state *pipe_config) -{ -	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); -	struct intel_dp *intel_dp = enc_to_intel_dp(encoder); -	u32 tmp, flags = 0; -	enum port port = encoder->port; -	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); - -	if (encoder->type == INTEL_OUTPUT_EDP) -		pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP); -	else -		pipe_config->output_types |= BIT(INTEL_OUTPUT_DP); - -	tmp = intel_de_read(dev_priv, intel_dp->output_reg); - -	pipe_config->has_audio = tmp & DP_AUDIO_OUTPUT_ENABLE && port != PORT_A; - -	if (HAS_PCH_CPT(dev_priv) && port != PORT_A) { -		u32 trans_dp = intel_de_read(dev_priv, -					     TRANS_DP_CTL(crtc->pipe)); - -		if (trans_dp & TRANS_DP_HSYNC_ACTIVE_HIGH) -			flags |= DRM_MODE_FLAG_PHSYNC; -		else -			flags |= DRM_MODE_FLAG_NHSYNC; - -		if (trans_dp & TRANS_DP_VSYNC_ACTIVE_HIGH) -			flags |= DRM_MODE_FLAG_PVSYNC; -		else -			flags |= DRM_MODE_FLAG_NVSYNC; -	} else { -		if (tmp & DP_SYNC_HS_HIGH) -			flags |= DRM_MODE_FLAG_PHSYNC; -		else -			flags |= DRM_MODE_FLAG_NHSYNC; - -		if (tmp & DP_SYNC_VS_HIGH) -			flags |= DRM_MODE_FLAG_PVSYNC; -		else -			flags |= DRM_MODE_FLAG_NVSYNC; -	} - -	pipe_config->hw.adjusted_mode.flags |= flags; - -	if (IS_G4X(dev_priv) && tmp & DP_COLOR_RANGE_16_235) -		pipe_config->limited_color_range = true; - -	pipe_config->lane_count = -		((tmp & DP_PORT_WIDTH_MASK) >> DP_PORT_WIDTH_SHIFT) + 1; - -	intel_dp_get_m_n(crtc, pipe_config); - -	if (port == PORT_A) { -		if ((intel_de_read(dev_priv, DP_A) & DP_PLL_FREQ_MASK) == DP_PLL_FREQ_162MHZ) -			pipe_config->port_clock = 162000; -		else -			pipe_config->port_clock = 270000; -	} - -	pipe_config->hw.adjusted_mode.crtc_clock = -		intel_dotclock_calculate(pipe_config->port_clock, -					 &pipe_config->dp_m_n); - -	if (intel_dp_is_edp(intel_dp) && dev_priv->vbt.edp.bpp && -	    pipe_config->pipe_bpp > dev_priv->vbt.edp.bpp) { -		/* -		 * This is a big fat ugly hack. -		 * -		 * Some machines in UEFI boot mode provide us a VBT that has 18 -		 * bpp and 1.62 GHz link bandwidth for eDP, which for reasons -		 * unknown we fail to light up. Yet the same BIOS boots up with -		 * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as -		 * max, not what it tells us to use. -		 * -		 * Note: This will still be broken if the eDP panel is not lit -		 * up by the BIOS, and thus we can't get the mode at module -		 * load. -		 */ -		drm_dbg_kms(&dev_priv->drm, -			    "pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n", -			    pipe_config->pipe_bpp, dev_priv->vbt.edp.bpp); -		dev_priv->vbt.edp.bpp = pipe_config->pipe_bpp; -	} -} -  static bool  intel_dp_get_dpcd(struct intel_dp *intel_dp); @@ -2359,7 +1990,7 @@ bool intel_dp_initial_fastset_check(struct intel_encoder *encoder,  		return false;  	} -	if (CAN_PSR(i915) && intel_dp_is_edp(intel_dp)) { +	if (CAN_PSR(intel_dp)) {  		drm_dbg_kms(&i915->drm, "Forcing full modeset to compute PSR state\n");  		crtc_state->uapi.mode_changed = true;  		return false; @@ -2368,122 +1999,6 @@ bool intel_dp_initial_fastset_check(struct intel_encoder *encoder,  	return true;  } -static void intel_disable_dp(struct intel_atomic_state *state, -			     struct intel_encoder *encoder, -			     const struct intel_crtc_state *old_crtc_state, -			     const struct drm_connector_state *old_conn_state) -{ -	struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - -	intel_dp->link_trained = false; - -	if (old_crtc_state->has_audio) -		intel_audio_codec_disable(encoder, -					  old_crtc_state, old_conn_state); - -	/* Make sure the panel is off before trying to change the mode. But also -	 * ensure that we have vdd while we switch off the panel. */ -	intel_pps_vdd_on(intel_dp); -	intel_edp_backlight_off(old_conn_state); -	intel_dp_set_power(intel_dp, DP_SET_POWER_D3); -	intel_pps_off(intel_dp); -	intel_dp->frl.is_trained = false; -	intel_dp->frl.trained_rate_gbps = 0; -} - -static void g4x_disable_dp(struct intel_atomic_state *state, -			   struct intel_encoder *encoder, -			   const struct intel_crtc_state *old_crtc_state, -			   const struct drm_connector_state *old_conn_state) -{ -	intel_disable_dp(state, encoder, old_crtc_state, old_conn_state); -} - -static void vlv_disable_dp(struct intel_atomic_state *state, -			   struct intel_encoder *encoder, -			   const struct intel_crtc_state *old_crtc_state, -			   const struct drm_connector_state *old_conn_state) -{ -	intel_disable_dp(state, encoder, old_crtc_state, old_conn_state); -} - -static void g4x_post_disable_dp(struct intel_atomic_state *state, -				struct intel_encoder *encoder, -				const struct intel_crtc_state *old_crtc_state, -				const struct drm_connector_state *old_conn_state) -{ -	struct intel_dp *intel_dp = enc_to_intel_dp(encoder); -	enum port port = encoder->port; - -	/* -	 * Bspec does not list a specific disable sequence for g4x DP. -	 * Follow the ilk+ sequence (disable pipe before the port) for -	 * g4x DP as it does not suffer from underruns like the normal -	 * g4x modeset sequence (disable pipe after the port). -	 */ -	intel_dp_link_down(encoder, old_crtc_state); - -	/* Only ilk+ has port A */ -	if (port == PORT_A) -		ilk_edp_pll_off(intel_dp, old_crtc_state); -} - -static void vlv_post_disable_dp(struct intel_atomic_state *state, -				struct intel_encoder *encoder, -				const struct intel_crtc_state *old_crtc_state, -				const struct drm_connector_state *old_conn_state) -{ -	intel_dp_link_down(encoder, old_crtc_state); -} - -static void chv_post_disable_dp(struct intel_atomic_state *state, -				struct intel_encoder *encoder, -				const struct intel_crtc_state *old_crtc_state, -				const struct drm_connector_state *old_conn_state) -{ -	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - -	intel_dp_link_down(encoder, old_crtc_state); - -	vlv_dpio_get(dev_priv); - -	/* Assert data lane reset */ -	chv_data_lane_soft_reset(encoder, old_crtc_state, true); - -	vlv_dpio_put(dev_priv); -} - -static void -cpt_set_link_train(struct intel_dp *intel_dp, -		   const struct intel_crtc_state *crtc_state, -		   u8 dp_train_pat) -{ -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); -	u32 *DP = &intel_dp->DP; - -	*DP &= ~DP_LINK_TRAIN_MASK_CPT; - -	switch (intel_dp_training_pattern_symbol(dp_train_pat)) { -	case DP_TRAINING_PATTERN_DISABLE: -		*DP |= DP_LINK_TRAIN_OFF_CPT; -		break; -	case DP_TRAINING_PATTERN_1: -		*DP |= DP_LINK_TRAIN_PAT_1_CPT; -		break; -	case DP_TRAINING_PATTERN_2: -		*DP |= DP_LINK_TRAIN_PAT_2_CPT; -		break; -	case DP_TRAINING_PATTERN_3: -		drm_dbg_kms(&dev_priv->drm, -			    "TPS3 not supported, using TPS2 instead\n"); -		*DP |= DP_LINK_TRAIN_PAT_2_CPT; -		break; -	} - -	intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP); -	intel_de_posting_read(dev_priv, intel_dp->output_reg); -} -  static void intel_dp_get_pcon_dsc_cap(struct intel_dp *intel_dp)  {  	struct drm_i915_private *i915 = dp_to_i915(intel_dp); @@ -2558,10 +2073,6 @@ static int intel_dp_hdmi_sink_max_frl(struct intel_dp *intel_dp)  static int intel_dp_pcon_start_frl_training(struct intel_dp *intel_dp)  { -#define PCON_EXTENDED_TRAIN_MODE (1 > 0) -#define PCON_CONCURRENT_MODE (1 > 0) -#define PCON_SEQUENTIAL_MODE !PCON_CONCURRENT_MODE -#define PCON_NORMAL_TRAIN_MODE !PCON_EXTENDED_TRAIN_MODE  #define TIMEOUT_FRL_READY_MS 500  #define TIMEOUT_HDMI_LINK_ACTIVE_MS 1000 @@ -2595,10 +2106,12 @@ static int intel_dp_pcon_start_frl_training(struct intel_dp *intel_dp)  		return -ETIMEDOUT;  	max_frl_bw_mask = intel_dp_pcon_set_frl_mask(max_frl_bw); -	ret = drm_dp_pcon_frl_configure_1(&intel_dp->aux, max_frl_bw, PCON_SEQUENTIAL_MODE); +	ret = drm_dp_pcon_frl_configure_1(&intel_dp->aux, max_frl_bw, +					  DP_PCON_ENABLE_SEQUENTIAL_LINK);  	if (ret < 0)  		return ret; -	ret = drm_dp_pcon_frl_configure_2(&intel_dp->aux, max_frl_bw_mask, PCON_NORMAL_TRAIN_MODE); +	ret = drm_dp_pcon_frl_configure_2(&intel_dp->aux, max_frl_bw_mask, +					  DP_PCON_FRL_LINK_TRAIN_NORMAL);  	if (ret < 0)  		return ret;  	ret = drm_dp_pcon_frl_enable(&intel_dp->aux); @@ -2642,15 +2155,20 @@ void intel_dp_check_frl_training(struct intel_dp *intel_dp)  {  	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); -	/* Always go for FRL training if supported */ -	if (!intel_dp_is_hdmi_2_1_sink(intel_dp) || +	/* +	 * Always go for FRL training if: +	 * -PCON supports SRC_CTL_MODE (VESA DP2.0-HDMI2.1 PCON Spec Draft-1 Sec-7) +	 * -sink is HDMI2.1 +	 */ +	if (!(intel_dp->dpcd[2] & DP_PCON_SOURCE_CTL_MODE) || +	    !intel_dp_is_hdmi_2_1_sink(intel_dp) ||  	    intel_dp->frl.is_trained)  		return;  	if (intel_dp_pcon_start_frl_training(intel_dp) < 0) {  		int ret, mode; -		drm_dbg(&dev_priv->drm, "Couldnt set FRL mode, continuing with TMDS mode\n"); +		drm_dbg(&dev_priv->drm, "Couldn't set FRL mode, continuing with TMDS mode\n");  		ret = drm_dp_pcon_reset_frl_config(&intel_dp->aux);  		mode = drm_dp_pcon_hdmi_link_mode(&intel_dp->aux, NULL); @@ -2758,61 +2276,6 @@ intel_dp_pcon_dsc_configure(struct intel_dp *intel_dp,  		drm_dbg_kms(&i915->drm, "Failed to set pcon DSC\n");  } -static void -g4x_set_link_train(struct intel_dp *intel_dp, -		   const struct intel_crtc_state *crtc_state, -		   u8 dp_train_pat) -{ -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); -	u32 *DP = &intel_dp->DP; - -	*DP &= ~DP_LINK_TRAIN_MASK; - -	switch (intel_dp_training_pattern_symbol(dp_train_pat)) { -	case DP_TRAINING_PATTERN_DISABLE: -		*DP |= DP_LINK_TRAIN_OFF; -		break; -	case DP_TRAINING_PATTERN_1: -		*DP |= DP_LINK_TRAIN_PAT_1; -		break; -	case DP_TRAINING_PATTERN_2: -		*DP |= DP_LINK_TRAIN_PAT_2; -		break; -	case DP_TRAINING_PATTERN_3: -		drm_dbg_kms(&dev_priv->drm, -			    "TPS3 not supported, using TPS2 instead\n"); -		*DP |= DP_LINK_TRAIN_PAT_2; -		break; -	} - -	intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP); -	intel_de_posting_read(dev_priv, intel_dp->output_reg); -} - -static void intel_dp_enable_port(struct intel_dp *intel_dp, -				 const struct intel_crtc_state *crtc_state) -{ -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - -	/* enable with pattern 1 (as per spec) */ - -	intel_dp_program_link_training_pattern(intel_dp, crtc_state, -					       DP_TRAINING_PATTERN_1); - -	/* -	 * Magic for VLV/CHV. We _must_ first set up the register -	 * without actually enabling the port, and then do another -	 * write to enable the port. Otherwise link training will -	 * fail when the power sequencer is freshly used for this port. -	 */ -	intel_dp->DP |= DP_PORT_EN; -	if (crtc_state->has_audio) -		intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE; - -	intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP); -	intel_de_posting_read(dev_priv, intel_dp->output_reg); -} -  void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp,  					   const struct intel_crtc_state *crtc_state)  { @@ -2881,592 +2344,6 @@ void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp,  			   enableddisabled(tmp ? true : false));  } -static void intel_enable_dp(struct intel_atomic_state *state, -			    struct intel_encoder *encoder, -			    const struct intel_crtc_state *pipe_config, -			    const struct drm_connector_state *conn_state) -{ -	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); -	struct intel_dp *intel_dp = enc_to_intel_dp(encoder); -	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); -	u32 dp_reg = intel_de_read(dev_priv, intel_dp->output_reg); -	enum pipe pipe = crtc->pipe; -	intel_wakeref_t wakeref; - -	if (drm_WARN_ON(&dev_priv->drm, dp_reg & DP_PORT_EN)) -		return; - -	with_intel_pps_lock(intel_dp, wakeref) { -		if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) -			vlv_pps_init(encoder, pipe_config); - -		intel_dp_enable_port(intel_dp, pipe_config); - -		intel_pps_vdd_on_unlocked(intel_dp); -		intel_pps_on_unlocked(intel_dp); -		intel_pps_vdd_off_unlocked(intel_dp, true); -	} - -	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { -		unsigned int lane_mask = 0x0; - -		if (IS_CHERRYVIEW(dev_priv)) -			lane_mask = intel_dp_unused_lane_mask(pipe_config->lane_count); - -		vlv_wait_port_ready(dev_priv, dp_to_dig_port(intel_dp), -				    lane_mask); -	} - -	intel_dp_set_power(intel_dp, DP_SET_POWER_D0); -	intel_dp_configure_protocol_converter(intel_dp, pipe_config); -	intel_dp_check_frl_training(intel_dp); -	intel_dp_pcon_dsc_configure(intel_dp, pipe_config); -	intel_dp_start_link_train(intel_dp, pipe_config); -	intel_dp_stop_link_train(intel_dp, pipe_config); - -	if (pipe_config->has_audio) { -		drm_dbg(&dev_priv->drm, "Enabling DP audio on pipe %c\n", -			pipe_name(pipe)); -		intel_audio_codec_enable(encoder, pipe_config, conn_state); -	} -} - -static void g4x_enable_dp(struct intel_atomic_state *state, -			  struct intel_encoder *encoder, -			  const struct intel_crtc_state *pipe_config, -			  const struct drm_connector_state *conn_state) -{ -	intel_enable_dp(state, encoder, pipe_config, conn_state); -	intel_edp_backlight_on(pipe_config, conn_state); -} - -static void vlv_enable_dp(struct intel_atomic_state *state, -			  struct intel_encoder *encoder, -			  const struct intel_crtc_state *pipe_config, -			  const struct drm_connector_state *conn_state) -{ -	intel_edp_backlight_on(pipe_config, conn_state); -} - -static void g4x_pre_enable_dp(struct intel_atomic_state *state, -			      struct intel_encoder *encoder, -			      const struct intel_crtc_state *pipe_config, -			      const struct drm_connector_state *conn_state) -{ -	struct intel_dp *intel_dp = enc_to_intel_dp(encoder); -	enum port port = encoder->port; - -	intel_dp_prepare(encoder, pipe_config); - -	/* Only ilk+ has port A */ -	if (port == PORT_A) -		ilk_edp_pll_on(intel_dp, pipe_config); -} - -static void vlv_pre_enable_dp(struct intel_atomic_state *state, -			      struct intel_encoder *encoder, -			      const struct intel_crtc_state *pipe_config, -			      const struct drm_connector_state *conn_state) -{ -	vlv_phy_pre_encoder_enable(encoder, pipe_config); - -	intel_enable_dp(state, encoder, pipe_config, conn_state); -} - -static void vlv_dp_pre_pll_enable(struct intel_atomic_state *state, -				  struct intel_encoder *encoder, -				  const struct intel_crtc_state *pipe_config, -				  const struct drm_connector_state *conn_state) -{ -	intel_dp_prepare(encoder, pipe_config); - -	vlv_phy_pre_pll_enable(encoder, pipe_config); -} - -static void chv_pre_enable_dp(struct intel_atomic_state *state, -			      struct intel_encoder *encoder, -			      const struct intel_crtc_state *pipe_config, -			      const struct drm_connector_state *conn_state) -{ -	chv_phy_pre_encoder_enable(encoder, pipe_config); - -	intel_enable_dp(state, encoder, pipe_config, conn_state); - -	/* Second common lane will stay alive on its own now */ -	chv_phy_release_cl2_override(encoder); -} - -static void chv_dp_pre_pll_enable(struct intel_atomic_state *state, -				  struct intel_encoder *encoder, -				  const struct intel_crtc_state *pipe_config, -				  const struct drm_connector_state *conn_state) -{ -	intel_dp_prepare(encoder, pipe_config); - -	chv_phy_pre_pll_enable(encoder, pipe_config); -} - -static void chv_dp_post_pll_disable(struct intel_atomic_state *state, -				    struct intel_encoder *encoder, -				    const struct intel_crtc_state *old_crtc_state, -				    const struct drm_connector_state *old_conn_state) -{ -	chv_phy_post_pll_disable(encoder, old_crtc_state); -} - -static u8 intel_dp_voltage_max_2(struct intel_dp *intel_dp, -				 const struct intel_crtc_state *crtc_state) -{ -	return DP_TRAIN_VOLTAGE_SWING_LEVEL_2; -} - -static u8 intel_dp_voltage_max_3(struct intel_dp *intel_dp, -				 const struct intel_crtc_state *crtc_state) -{ -	return DP_TRAIN_VOLTAGE_SWING_LEVEL_3; -} - -static u8 intel_dp_preemph_max_2(struct intel_dp *intel_dp) -{ -	return DP_TRAIN_PRE_EMPH_LEVEL_2; -} - -static u8 intel_dp_preemph_max_3(struct intel_dp *intel_dp) -{ -	return DP_TRAIN_PRE_EMPH_LEVEL_3; -} - -static void vlv_set_signal_levels(struct intel_dp *intel_dp, -				  const struct intel_crtc_state *crtc_state) -{ -	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; -	unsigned long demph_reg_value, preemph_reg_value, -		uniqtranscale_reg_value; -	u8 train_set = intel_dp->train_set[0]; - -	switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) { -	case DP_TRAIN_PRE_EMPH_LEVEL_0: -		preemph_reg_value = 0x0004000; -		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) { -		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0: -			demph_reg_value = 0x2B405555; -			uniqtranscale_reg_value = 0x552AB83A; -			break; -		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1: -			demph_reg_value = 0x2B404040; -			uniqtranscale_reg_value = 0x5548B83A; -			break; -		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2: -			demph_reg_value = 0x2B245555; -			uniqtranscale_reg_value = 0x5560B83A; -			break; -		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3: -			demph_reg_value = 0x2B405555; -			uniqtranscale_reg_value = 0x5598DA3A; -			break; -		default: -			return; -		} -		break; -	case DP_TRAIN_PRE_EMPH_LEVEL_1: -		preemph_reg_value = 0x0002000; -		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) { -		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0: -			demph_reg_value = 0x2B404040; -			uniqtranscale_reg_value = 0x5552B83A; -			break; -		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1: -			demph_reg_value = 0x2B404848; -			uniqtranscale_reg_value = 0x5580B83A; -			break; -		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2: -			demph_reg_value = 0x2B404040; -			uniqtranscale_reg_value = 0x55ADDA3A; -			break; -		default: -			return; -		} -		break; -	case DP_TRAIN_PRE_EMPH_LEVEL_2: -		preemph_reg_value = 0x0000000; -		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) { -		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0: -			demph_reg_value = 0x2B305555; -			uniqtranscale_reg_value = 0x5570B83A; -			break; -		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1: -			demph_reg_value = 0x2B2B4040; -			uniqtranscale_reg_value = 0x55ADDA3A; -			break; -		default: -			return; -		} -		break; -	case DP_TRAIN_PRE_EMPH_LEVEL_3: -		preemph_reg_value = 0x0006000; -		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) { -		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0: -			demph_reg_value = 0x1B405555; -			uniqtranscale_reg_value = 0x55ADDA3A; -			break; -		default: -			return; -		} -		break; -	default: -		return; -	} - -	vlv_set_phy_signal_level(encoder, crtc_state, -				 demph_reg_value, preemph_reg_value, -				 uniqtranscale_reg_value, 0); -} - -static void chv_set_signal_levels(struct intel_dp *intel_dp, -				  const struct intel_crtc_state *crtc_state) -{ -	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; -	u32 deemph_reg_value, margin_reg_value; -	bool uniq_trans_scale = false; -	u8 train_set = intel_dp->train_set[0]; - -	switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) { -	case DP_TRAIN_PRE_EMPH_LEVEL_0: -		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) { -		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0: -			deemph_reg_value = 128; -			margin_reg_value = 52; -			break; -		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1: -			deemph_reg_value = 128; -			margin_reg_value = 77; -			break; -		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2: -			deemph_reg_value = 128; -			margin_reg_value = 102; -			break; -		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3: -			deemph_reg_value = 128; -			margin_reg_value = 154; -			uniq_trans_scale = true; -			break; -		default: -			return; -		} -		break; -	case DP_TRAIN_PRE_EMPH_LEVEL_1: -		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) { -		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0: -			deemph_reg_value = 85; -			margin_reg_value = 78; -			break; -		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1: -			deemph_reg_value = 85; -			margin_reg_value = 116; -			break; -		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2: -			deemph_reg_value = 85; -			margin_reg_value = 154; -			break; -		default: -			return; -		} -		break; -	case DP_TRAIN_PRE_EMPH_LEVEL_2: -		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) { -		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0: -			deemph_reg_value = 64; -			margin_reg_value = 104; -			break; -		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1: -			deemph_reg_value = 64; -			margin_reg_value = 154; -			break; -		default: -			return; -		} -		break; -	case DP_TRAIN_PRE_EMPH_LEVEL_3: -		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) { -		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0: -			deemph_reg_value = 43; -			margin_reg_value = 154; -			break; -		default: -			return; -		} -		break; -	default: -		return; -	} - -	chv_set_phy_signal_level(encoder, crtc_state, -				 deemph_reg_value, margin_reg_value, -				 uniq_trans_scale); -} - -static u32 g4x_signal_levels(u8 train_set) -{ -	u32 signal_levels = 0; - -	switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) { -	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0: -	default: -		signal_levels |= DP_VOLTAGE_0_4; -		break; -	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1: -		signal_levels |= DP_VOLTAGE_0_6; -		break; -	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2: -		signal_levels |= DP_VOLTAGE_0_8; -		break; -	case DP_TRAIN_VOLTAGE_SWING_LEVEL_3: -		signal_levels |= DP_VOLTAGE_1_2; -		break; -	} -	switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) { -	case DP_TRAIN_PRE_EMPH_LEVEL_0: -	default: -		signal_levels |= DP_PRE_EMPHASIS_0; -		break; -	case DP_TRAIN_PRE_EMPH_LEVEL_1: -		signal_levels |= DP_PRE_EMPHASIS_3_5; -		break; -	case DP_TRAIN_PRE_EMPH_LEVEL_2: -		signal_levels |= DP_PRE_EMPHASIS_6; -		break; -	case DP_TRAIN_PRE_EMPH_LEVEL_3: -		signal_levels |= DP_PRE_EMPHASIS_9_5; -		break; -	} -	return signal_levels; -} - -static void -g4x_set_signal_levels(struct intel_dp *intel_dp, -		      const struct intel_crtc_state *crtc_state) -{ -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); -	u8 train_set = intel_dp->train_set[0]; -	u32 signal_levels; - -	signal_levels = g4x_signal_levels(train_set); - -	drm_dbg_kms(&dev_priv->drm, "Using signal levels %08x\n", -		    signal_levels); - -	intel_dp->DP &= ~(DP_VOLTAGE_MASK | DP_PRE_EMPHASIS_MASK); -	intel_dp->DP |= signal_levels; - -	intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP); -	intel_de_posting_read(dev_priv, intel_dp->output_reg); -} - -/* SNB CPU eDP voltage swing and pre-emphasis control */ -static u32 snb_cpu_edp_signal_levels(u8 train_set) -{ -	u8 signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK | -					DP_TRAIN_PRE_EMPHASIS_MASK); - -	switch (signal_levels) { -	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0: -	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0: -		return EDP_LINK_TRAIN_400_600MV_0DB_SNB_B; -	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1: -		return EDP_LINK_TRAIN_400MV_3_5DB_SNB_B; -	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2: -	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2: -		return EDP_LINK_TRAIN_400_600MV_6DB_SNB_B; -	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1: -	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1: -		return EDP_LINK_TRAIN_600_800MV_3_5DB_SNB_B; -	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0: -	case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0: -		return EDP_LINK_TRAIN_800_1200MV_0DB_SNB_B; -	default: -		DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:" -			      "0x%x\n", signal_levels); -		return EDP_LINK_TRAIN_400_600MV_0DB_SNB_B; -	} -} - -static void -snb_cpu_edp_set_signal_levels(struct intel_dp *intel_dp, -			      const struct intel_crtc_state *crtc_state) -{ -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); -	u8 train_set = intel_dp->train_set[0]; -	u32 signal_levels; - -	signal_levels = snb_cpu_edp_signal_levels(train_set); - -	drm_dbg_kms(&dev_priv->drm, "Using signal levels %08x\n", -		    signal_levels); - -	intel_dp->DP &= ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB; -	intel_dp->DP |= signal_levels; - -	intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP); -	intel_de_posting_read(dev_priv, intel_dp->output_reg); -} - -/* IVB CPU eDP voltage swing and pre-emphasis control */ -static u32 ivb_cpu_edp_signal_levels(u8 train_set) -{ -	u8 signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK | -					DP_TRAIN_PRE_EMPHASIS_MASK); - -	switch (signal_levels) { -	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0: -		return EDP_LINK_TRAIN_400MV_0DB_IVB; -	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1: -		return EDP_LINK_TRAIN_400MV_3_5DB_IVB; -	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2: -	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2: -		return EDP_LINK_TRAIN_400MV_6DB_IVB; - -	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0: -		return EDP_LINK_TRAIN_600MV_0DB_IVB; -	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1: -		return EDP_LINK_TRAIN_600MV_3_5DB_IVB; - -	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0: -		return EDP_LINK_TRAIN_800MV_0DB_IVB; -	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1: -		return EDP_LINK_TRAIN_800MV_3_5DB_IVB; - -	default: -		DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:" -			      "0x%x\n", signal_levels); -		return EDP_LINK_TRAIN_500MV_0DB_IVB; -	} -} - -static void -ivb_cpu_edp_set_signal_levels(struct intel_dp *intel_dp, -			      const struct intel_crtc_state *crtc_state) -{ -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); -	u8 train_set = intel_dp->train_set[0]; -	u32 signal_levels; - -	signal_levels = ivb_cpu_edp_signal_levels(train_set); - -	drm_dbg_kms(&dev_priv->drm, "Using signal levels %08x\n", -		    signal_levels); - -	intel_dp->DP &= ~EDP_LINK_TRAIN_VOL_EMP_MASK_IVB; -	intel_dp->DP |= signal_levels; - -	intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP); -	intel_de_posting_read(dev_priv, intel_dp->output_reg); -} - -static char dp_training_pattern_name(u8 train_pat) -{ -	switch (train_pat) { -	case DP_TRAINING_PATTERN_1: -	case DP_TRAINING_PATTERN_2: -	case DP_TRAINING_PATTERN_3: -		return '0' + train_pat; -	case DP_TRAINING_PATTERN_4: -		return '4'; -	default: -		MISSING_CASE(train_pat); -		return '?'; -	} -} - -void -intel_dp_program_link_training_pattern(struct intel_dp *intel_dp, -				       const struct intel_crtc_state *crtc_state, -				       u8 dp_train_pat) -{ -	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; -	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); -	u8 train_pat = intel_dp_training_pattern_symbol(dp_train_pat); - -	if (train_pat != DP_TRAINING_PATTERN_DISABLE) -		drm_dbg_kms(&dev_priv->drm, -			    "[ENCODER:%d:%s] Using DP training pattern TPS%c\n", -			    encoder->base.base.id, encoder->base.name, -			    dp_training_pattern_name(train_pat)); - -	intel_dp->set_link_train(intel_dp, crtc_state, dp_train_pat); -} - -static void -intel_dp_link_down(struct intel_encoder *encoder, -		   const struct intel_crtc_state *old_crtc_state) -{ -	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); -	struct intel_dp *intel_dp = enc_to_intel_dp(encoder); -	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); -	enum port port = encoder->port; -	u32 DP = intel_dp->DP; - -	if (drm_WARN_ON(&dev_priv->drm, -			(intel_de_read(dev_priv, intel_dp->output_reg) & -			 DP_PORT_EN) == 0)) -		return; - -	drm_dbg_kms(&dev_priv->drm, "\n"); - -	if ((IS_IVYBRIDGE(dev_priv) && port == PORT_A) || -	    (HAS_PCH_CPT(dev_priv) && port != PORT_A)) { -		DP &= ~DP_LINK_TRAIN_MASK_CPT; -		DP |= DP_LINK_TRAIN_PAT_IDLE_CPT; -	} else { -		DP &= ~DP_LINK_TRAIN_MASK; -		DP |= DP_LINK_TRAIN_PAT_IDLE; -	} -	intel_de_write(dev_priv, intel_dp->output_reg, DP); -	intel_de_posting_read(dev_priv, intel_dp->output_reg); - -	DP &= ~(DP_PORT_EN | DP_AUDIO_OUTPUT_ENABLE); -	intel_de_write(dev_priv, intel_dp->output_reg, DP); -	intel_de_posting_read(dev_priv, intel_dp->output_reg); - -	/* -	 * HW workaround for IBX, we need to move the port -	 * to transcoder A after disabling it to allow the -	 * matching HDMI port to be enabled on transcoder A. -	 */ -	if (HAS_PCH_IBX(dev_priv) && crtc->pipe == PIPE_B && port != PORT_A) { -		/* -		 * We get CPU/PCH FIFO underruns on the other pipe when -		 * doing the workaround. Sweep them under the rug. -		 */ -		intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, false); -		intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false); - -		/* always enable with pattern 1 (as per spec) */ -		DP &= ~(DP_PIPE_SEL_MASK | DP_LINK_TRAIN_MASK); -		DP |= DP_PORT_EN | DP_PIPE_SEL(PIPE_A) | -			DP_LINK_TRAIN_PAT_1; -		intel_de_write(dev_priv, intel_dp->output_reg, DP); -		intel_de_posting_read(dev_priv, intel_dp->output_reg); - -		DP &= ~DP_PORT_EN; -		intel_de_write(dev_priv, intel_dp->output_reg, DP); -		intel_de_posting_read(dev_priv, intel_dp->output_reg); - -		intel_wait_for_vblank_if_active(dev_priv, PIPE_A); -		intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true); -		intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true); -	} - -	msleep(intel_dp->pps.panel_power_down_delay); - -	intel_dp->DP = DP; - -	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { -		intel_wakeref_t wakeref; - -		with_intel_pps_lock(intel_dp, wakeref) -			intel_dp->pps.active_pipe = INVALID_PIPE; -	} -}  bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp)  { @@ -3517,6 +2394,64 @@ static void intel_dp_get_dsc_sink_cap(struct intel_dp *intel_dp)  	}  } +static void intel_edp_mso_mode_fixup(struct intel_connector *connector, +				     struct drm_display_mode *mode) +{ +	struct intel_dp *intel_dp = intel_attached_dp(connector); +	struct drm_i915_private *i915 = to_i915(connector->base.dev); +	int n = intel_dp->mso_link_count; +	int overlap = intel_dp->mso_pixel_overlap; + +	if (!mode || !n) +		return; + +	mode->hdisplay = (mode->hdisplay - overlap) * n; +	mode->hsync_start = (mode->hsync_start - overlap) * n; +	mode->hsync_end = (mode->hsync_end - overlap) * n; +	mode->htotal = (mode->htotal - overlap) * n; +	mode->clock *= n; + +	drm_mode_set_name(mode); + +	drm_dbg_kms(&i915->drm, +		    "[CONNECTOR:%d:%s] using generated MSO mode: ", +		    connector->base.base.id, connector->base.name); +	drm_mode_debug_printmodeline(mode); +} + +static void intel_edp_mso_init(struct intel_dp *intel_dp) +{ +	struct drm_i915_private *i915 = dp_to_i915(intel_dp); +	u8 mso; + +	if (intel_dp->edp_dpcd[0] < DP_EDP_14) +		return; + +	if (drm_dp_dpcd_readb(&intel_dp->aux, DP_EDP_MSO_LINK_CAPABILITIES, &mso) != 1) { +		drm_err(&i915->drm, "Failed to read MSO cap\n"); +		return; +	} + +	/* Valid configurations are SST or MSO 2x1, 2x2, 4x1 */ +	mso &= DP_EDP_MSO_NUMBER_OF_LINKS_MASK; +	if (mso % 2 || mso > drm_dp_max_lane_count(intel_dp->dpcd)) { +		drm_err(&i915->drm, "Invalid MSO link count cap %u\n", mso); +		mso = 0; +	} + +	if (mso) { +		drm_dbg_kms(&i915->drm, "Sink MSO %ux%u configuration\n", +			    mso, drm_dp_max_lane_count(intel_dp->dpcd) / mso); +		if (!HAS_MSO(i915)) { +			drm_err(&i915->drm, "No source MSO support, disabling\n"); +			mso = 0; +		} +	} + +	intel_dp->mso_link_count = mso; +	intel_dp->mso_pixel_overlap = 0; /* FIXME: read from DisplayID v2.0 */ +} +  static bool  intel_edp_init_dpcd(struct intel_dp *intel_dp)  { @@ -3591,7 +2526,7 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp)  	intel_dp_set_common_rates(intel_dp);  	/* Read the eDP DSC DPCD registers */ -	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) +	if (DISPLAY_VER(dev_priv) >= 10)  		intel_dp_get_dsc_sink_cap(intel_dp);  	/* @@ -3600,6 +2535,8 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp)  	 */  	intel_edp_init_source_oui(intel_dp, true); +	intel_edp_mso_init(intel_dp); +  	return true;  } @@ -3619,9 +2556,7 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)  {  	int ret; -	intel_dp_lttpr_init(intel_dp); - -	if (drm_dp_read_dpcd_caps(&intel_dp->aux, intel_dp->dpcd)) +	if (intel_dp_init_lttpr_and_dprx_caps(intel_dp) < 0)  		return false;  	/* @@ -4770,7 +3705,7 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,  			to_intel_crtc_state(crtc->base.state);  		/* retrain on the MST master transcoder */ -		if (INTEL_GEN(dev_priv) >= 12 && +		if (DISPLAY_VER(dev_priv) >= 12 &&  		    intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) &&  		    !intel_dp_mst_is_master_trans(crtc_state))  			continue; @@ -4874,7 +3809,7 @@ static int intel_dp_do_phy_test(struct intel_encoder *encoder,  			to_intel_crtc_state(crtc->base.state);  		/* test on the MST master transcoder */ -		if (INTEL_GEN(dev_priv) >= 12 && +		if (DISPLAY_VER(dev_priv) >= 12 &&  		    intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) &&  		    !intel_dp_mst_is_master_trans(crtc_state))  			continue; @@ -4910,64 +3845,6 @@ void intel_dp_phy_test(struct intel_encoder *encoder)  		 "Acquiring modeset locks failed with %i\n", ret);  } -/* - * If display is now connected check links status, - * there has been known issues of link loss triggering - * long pulse. - * - * Some sinks (eg. ASUS PB287Q) seem to perform some - * weird HPD ping pong during modesets. So we can apparently - * end up with HPD going low during a modeset, and then - * going back up soon after. And once that happens we must - * retrain the link to get a picture. That's in case no - * userspace component reacted to intermittent HPD dip. - */ -static enum intel_hotplug_state -intel_dp_hotplug(struct intel_encoder *encoder, -		 struct intel_connector *connector) -{ -	struct intel_dp *intel_dp = enc_to_intel_dp(encoder); -	struct drm_modeset_acquire_ctx ctx; -	enum intel_hotplug_state state; -	int ret; - -	if (intel_dp->compliance.test_active && -	    intel_dp->compliance.test_type == DP_TEST_LINK_PHY_TEST_PATTERN) { -		intel_dp_phy_test(encoder); -		/* just do the PHY test and nothing else */ -		return INTEL_HOTPLUG_UNCHANGED; -	} - -	state = intel_encoder_hotplug(encoder, connector); - -	drm_modeset_acquire_init(&ctx, 0); - -	for (;;) { -		ret = intel_dp_retrain_link(encoder, &ctx); - -		if (ret == -EDEADLK) { -			drm_modeset_backoff(&ctx); -			continue; -		} - -		break; -	} - -	drm_modeset_drop_locks(&ctx); -	drm_modeset_acquire_fini(&ctx); -	drm_WARN(encoder->base.dev, ret, -		 "Acquiring modeset locks failed with %i\n", ret); - -	/* -	 * Keeping it consistent with intel_ddi_hotplug() and -	 * intel_hdmi_hotplug(). -	 */ -	if (state == INTEL_HOTPLUG_UNCHANGED && !connector->hotplug_retries) -		state = INTEL_HOTPLUG_RETRY; - -	return state; -} -  static void intel_dp_check_device_service_irq(struct intel_dp *intel_dp)  {  	struct drm_i915_private *i915 = dp_to_i915(intel_dp); @@ -5149,68 +4026,6 @@ edp_detect(struct intel_dp *intel_dp)  	return connector_status_connected;  } -static bool ibx_digital_port_connected(struct intel_encoder *encoder) -{ -	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); -	u32 bit = dev_priv->hotplug.pch_hpd[encoder->hpd_pin]; - -	return intel_de_read(dev_priv, SDEISR) & bit; -} - -static bool g4x_digital_port_connected(struct intel_encoder *encoder) -{ -	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); -	u32 bit; - -	switch (encoder->hpd_pin) { -	case HPD_PORT_B: -		bit = PORTB_HOTPLUG_LIVE_STATUS_G4X; -		break; -	case HPD_PORT_C: -		bit = PORTC_HOTPLUG_LIVE_STATUS_G4X; -		break; -	case HPD_PORT_D: -		bit = PORTD_HOTPLUG_LIVE_STATUS_G4X; -		break; -	default: -		MISSING_CASE(encoder->hpd_pin); -		return false; -	} - -	return intel_de_read(dev_priv, PORT_HOTPLUG_STAT) & bit; -} - -static bool gm45_digital_port_connected(struct intel_encoder *encoder) -{ -	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); -	u32 bit; - -	switch (encoder->hpd_pin) { -	case HPD_PORT_B: -		bit = PORTB_HOTPLUG_LIVE_STATUS_GM45; -		break; -	case HPD_PORT_C: -		bit = PORTC_HOTPLUG_LIVE_STATUS_GM45; -		break; -	case HPD_PORT_D: -		bit = PORTD_HOTPLUG_LIVE_STATUS_GM45; -		break; -	default: -		MISSING_CASE(encoder->hpd_pin); -		return false; -	} - -	return intel_de_read(dev_priv, PORT_HOTPLUG_STAT) & bit; -} - -static bool ilk_digital_port_connected(struct intel_encoder *encoder) -{ -	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); -	u32 bit = dev_priv->hotplug.hpd[encoder->hpd_pin]; - -	return intel_de_read(dev_priv, DEISR) & bit; -} -  /*   * intel_digital_port_connected - is the specified port connected?   * @encoder: intel_encoder @@ -5307,7 +4122,7 @@ intel_dp_update_420(struct intel_dp *intel_dp)  	 * ILK doesn't seem capable of DP YCbCr output. The  	 * displayed image is severly corrupted. SNB+ is fine.  	 */ -	if (IS_GEN(i915, 5)) +	if (IS_IRONLAKE(i915))  		return;  	is_branch = drm_dp_is_branch(intel_dp->dpcd); @@ -5325,7 +4140,7 @@ intel_dp_update_420(struct intel_dp *intel_dp)  								 DP_DS_HDMI_BT709_RGB_YCBCR_CONV |  								 DP_DS_HDMI_BT2020_RGB_YCBCR_CONV); -	if (INTEL_GEN(i915) >= 11) { +	if (DISPLAY_VER(i915) >= 11) {  		/* Let PCON convert from RGB->YCbCr if possible */  		if (is_branch && rgb_to_ycbcr && ycbcr_444_to_420) {  			intel_dp->dfp.rgb_to_ycbcr = true; @@ -5443,7 +4258,7 @@ intel_dp_detect(struct drm_connector *connector,  	}  	/* Read DP Sink DSC Cap DPCD regs for DP v1.4 */ -	if (INTEL_GEN(dev_priv) >= 11) +	if (DISPLAY_VER(dev_priv) >= 11)  		intel_dp_get_dsc_sink_cap(intel_dp);  	intel_dp_configure_mst(intel_dp); @@ -5548,19 +4363,18 @@ static int intel_dp_get_modes(struct drm_connector *connector)  {  	struct intel_connector *intel_connector = to_intel_connector(connector);  	struct edid *edid; +	int num_modes = 0;  	edid = intel_connector->detect_edid;  	if (edid) { -		int ret = intel_connector_update_modes(connector, edid); +		num_modes = intel_connector_update_modes(connector, edid);  		if (intel_vrr_is_capable(connector))  			drm_connector_set_vrr_capable_property(connector,  							       true); -		if (ret) -			return ret;  	} -	/* if eDP has no EDID, fall back to fixed mode */ +	/* Also add fixed mode, which may or may not be present in EDID */  	if (intel_dp_is_edp(intel_attached_dp(intel_connector)) &&  	    intel_connector->panel.fixed_mode) {  		struct drm_display_mode *mode; @@ -5569,10 +4383,13 @@ static int intel_dp_get_modes(struct drm_connector *connector)  					  intel_connector->panel.fixed_mode);  		if (mode) {  			drm_mode_probed_add(connector, mode); -			return 1; +			num_modes++;  		}  	} +	if (num_modes) +		return num_modes; +  	if (!edid) {  		struct intel_dp *intel_dp = intel_attached_dp(intel_connector);  		struct drm_display_mode *mode; @@ -5582,11 +4399,11 @@ static int intel_dp_get_modes(struct drm_connector *connector)  					      intel_dp->downstream_ports);  		if (mode) {  			drm_mode_probed_add(connector, mode); -			return 1; +			num_modes++;  		}  	} -	return 0; +	return num_modes;  }  static int @@ -5650,14 +4467,6 @@ void intel_dp_encoder_flush_work(struct drm_encoder *encoder)  	intel_dp_aux_fini(intel_dp);  } -static void intel_dp_encoder_destroy(struct drm_encoder *encoder) -{ -	intel_dp_encoder_flush_work(encoder); - -	drm_encoder_cleanup(encoder); -	kfree(enc_to_dig_port(to_intel_encoder(encoder))); -} -  void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder)  {  	struct intel_dp *intel_dp = enc_to_intel_dp(intel_encoder); @@ -5672,39 +4481,6 @@ void intel_dp_encoder_shutdown(struct intel_encoder *intel_encoder)  	intel_pps_wait_power_cycle(intel_dp);  } -static enum pipe vlv_active_pipe(struct intel_dp *intel_dp) -{ -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); -	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; -	enum pipe pipe; - -	if (intel_dp_port_enabled(dev_priv, intel_dp->output_reg, -				  encoder->port, &pipe)) -		return pipe; - -	return INVALID_PIPE; -} - -void intel_dp_encoder_reset(struct drm_encoder *encoder) -{ -	struct drm_i915_private *dev_priv = to_i915(encoder->dev); -	struct intel_dp *intel_dp = enc_to_intel_dp(to_intel_encoder(encoder)); - -	if (!HAS_DDI(dev_priv)) -		intel_dp->DP = intel_de_read(dev_priv, intel_dp->output_reg); - -	intel_dp->reset_link_params = true; - -	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { -		intel_wakeref_t wakeref; - -		with_intel_pps_lock(intel_dp, wakeref) -			intel_dp->pps.active_pipe = vlv_active_pipe(intel_dp); -	} - -	intel_pps_encoder_reset(intel_dp); -} -  static int intel_modeset_tile_group(struct intel_atomic_state *state,  				    int tile_group_id)  { @@ -5828,7 +4604,7 @@ static int intel_dp_connector_atomic_check(struct drm_connector *conn,  	 * We don't enable port sync on BDW due to missing w/as and  	 * due to not having adjusted the modeset sequence appropriately.  	 */ -	if (INTEL_GEN(dev_priv) < 9) +	if (DISPLAY_VER(dev_priv) < 9)  		return 0;  	if (!intel_connector_needs_modeset(state, conn)) @@ -5862,11 +4638,6 @@ static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs =  	.atomic_check = intel_dp_connector_atomic_check,  }; -static const struct drm_encoder_funcs intel_dp_enc_funcs = { -	.reset = intel_dp_encoder_reset, -	.destroy = intel_dp_encoder_destroy, -}; -  enum irqreturn  intel_dp_hpd_pulse(struct intel_digital_port *dig_port, bool long_hpd)  { @@ -5916,10 +4687,10 @@ bool intel_dp_is_port_edp(struct drm_i915_private *dev_priv, enum port port)  	 * eDP not supported on g4x. so bail out early just  	 * for a bit extra safety in case the VBT is bonkers.  	 */ -	if (INTEL_GEN(dev_priv) < 5) +	if (DISPLAY_VER(dev_priv) < 5)  		return false; -	if (INTEL_GEN(dev_priv) < 9 && port == PORT_A) +	if (DISPLAY_VER(dev_priv) < 9 && port == PORT_A)  		return true;  	return intel_bios_is_port_edp(dev_priv, port); @@ -5940,7 +4711,7 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect  	intel_attach_broadcast_rgb_property(connector);  	if (HAS_GMCH(dev_priv))  		drm_connector_attach_max_bpc_property(connector, 6, 10); -	else if (INTEL_GEN(dev_priv) >= 5) +	else if (DISPLAY_VER(dev_priv) >= 5)  		drm_connector_attach_max_bpc_property(connector, 6, 12);  	/* Register HDMI colorspace for case of lspcon */ @@ -5951,7 +4722,7 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect  		intel_attach_dp_colorspace_property(connector);  	} -	if (IS_GEMINILAKE(dev_priv) || INTEL_GEN(dev_priv) >= 11) +	if (IS_GEMINILAKE(dev_priv) || DISPLAY_VER(dev_priv) >= 11)  		drm_object_attach_property(&connector->base,  					   connector->dev->mode_config.hdr_output_metadata_property,  					   0); @@ -6032,7 +4803,7 @@ static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv,  		return;  	} -	if (INTEL_GEN(dev_priv) >= 8 && !IS_CHERRYVIEW(dev_priv)) { +	if (DISPLAY_VER(dev_priv) >= 8 && !IS_CHERRYVIEW(dev_priv)) {  		switch (index) {  		case DRRS_HIGH_RR:  			intel_dp_set_m_n(crtc_state, M1_N1); @@ -6045,7 +4816,7 @@ static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv,  			drm_err(&dev_priv->drm,  				"Unsupported refreshrate type\n");  		} -	} else if (INTEL_GEN(dev_priv) > 6) { +	} else if (DISPLAY_VER(dev_priv) > 6) {  		i915_reg_t reg = PIPECONF(crtc_state->cpu_transcoder);  		u32 val; @@ -6373,7 +5144,7 @@ intel_dp_drrs_init(struct intel_connector *connector,  	INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_edp_drrs_downclock_work);  	mutex_init(&dev_priv->drrs.mutex); -	if (INTEL_GEN(dev_priv) <= 6) { +	if (DISPLAY_VER(dev_priv) <= 6) {  		drm_dbg_kms(&dev_priv->drm,  			    "DRRS supported for Gen7 and above\n");  		return NULL; @@ -6459,6 +5230,10 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,  	if (fixed_mode)  		downclock_mode = intel_dp_drrs_init(intel_connector, fixed_mode); +	/* multiply the mode clock and horizontal timings for MSO */ +	intel_edp_mso_mode_fixup(intel_connector, fixed_mode); +	intel_edp_mso_mode_fixup(intel_connector, downclock_mode); +  	/* fallback to VBT if available for eDP */  	if (!fixed_mode)  		fixed_mode = intel_panel_vbt_fixed_mode(intel_connector); @@ -6641,6 +5416,8 @@ intel_dp_init_connector(struct intel_digital_port *dig_port,  	intel_dp->frl.is_trained = false;  	intel_dp->frl.trained_rate_gbps = 0; +	intel_psr_init(intel_dp); +  	return true;  fail: @@ -6649,137 +5426,6 @@ fail:  	return false;  } -bool intel_dp_init(struct drm_i915_private *dev_priv, -		   i915_reg_t output_reg, -		   enum port port) -{ -	struct intel_digital_port *dig_port; -	struct intel_encoder *intel_encoder; -	struct drm_encoder *encoder; -	struct intel_connector *intel_connector; - -	dig_port = kzalloc(sizeof(*dig_port), GFP_KERNEL); -	if (!dig_port) -		return false; - -	intel_connector = intel_connector_alloc(); -	if (!intel_connector) -		goto err_connector_alloc; - -	intel_encoder = &dig_port->base; -	encoder = &intel_encoder->base; - -	mutex_init(&dig_port->hdcp_mutex); - -	if (drm_encoder_init(&dev_priv->drm, &intel_encoder->base, -			     &intel_dp_enc_funcs, DRM_MODE_ENCODER_TMDS, -			     "DP %c", port_name(port))) -		goto err_encoder_init; - -	intel_encoder->hotplug = intel_dp_hotplug; -	intel_encoder->compute_config = intel_dp_compute_config; -	intel_encoder->get_hw_state = intel_dp_get_hw_state; -	intel_encoder->get_config = intel_dp_get_config; -	intel_encoder->sync_state = intel_dp_sync_state; -	intel_encoder->initial_fastset_check = intel_dp_initial_fastset_check; -	intel_encoder->update_pipe = intel_panel_update_backlight; -	intel_encoder->suspend = intel_dp_encoder_suspend; -	intel_encoder->shutdown = intel_dp_encoder_shutdown; -	if (IS_CHERRYVIEW(dev_priv)) { -		intel_encoder->pre_pll_enable = chv_dp_pre_pll_enable; -		intel_encoder->pre_enable = chv_pre_enable_dp; -		intel_encoder->enable = vlv_enable_dp; -		intel_encoder->disable = vlv_disable_dp; -		intel_encoder->post_disable = chv_post_disable_dp; -		intel_encoder->post_pll_disable = chv_dp_post_pll_disable; -	} else if (IS_VALLEYVIEW(dev_priv)) { -		intel_encoder->pre_pll_enable = vlv_dp_pre_pll_enable; -		intel_encoder->pre_enable = vlv_pre_enable_dp; -		intel_encoder->enable = vlv_enable_dp; -		intel_encoder->disable = vlv_disable_dp; -		intel_encoder->post_disable = vlv_post_disable_dp; -	} else { -		intel_encoder->pre_enable = g4x_pre_enable_dp; -		intel_encoder->enable = g4x_enable_dp; -		intel_encoder->disable = g4x_disable_dp; -		intel_encoder->post_disable = g4x_post_disable_dp; -	} - -	if ((IS_IVYBRIDGE(dev_priv) && port == PORT_A) || -	    (HAS_PCH_CPT(dev_priv) && port != PORT_A)) -		dig_port->dp.set_link_train = cpt_set_link_train; -	else -		dig_port->dp.set_link_train = g4x_set_link_train; - -	if (IS_CHERRYVIEW(dev_priv)) -		dig_port->dp.set_signal_levels = chv_set_signal_levels; -	else if (IS_VALLEYVIEW(dev_priv)) -		dig_port->dp.set_signal_levels = vlv_set_signal_levels; -	else if (IS_IVYBRIDGE(dev_priv) && port == PORT_A) -		dig_port->dp.set_signal_levels = ivb_cpu_edp_set_signal_levels; -	else if (IS_GEN(dev_priv, 6) && port == PORT_A) -		dig_port->dp.set_signal_levels = snb_cpu_edp_set_signal_levels; -	else -		dig_port->dp.set_signal_levels = g4x_set_signal_levels; - -	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv) || -	    (HAS_PCH_SPLIT(dev_priv) && port != PORT_A)) { -		dig_port->dp.preemph_max = intel_dp_preemph_max_3; -		dig_port->dp.voltage_max = intel_dp_voltage_max_3; -	} else { -		dig_port->dp.preemph_max = intel_dp_preemph_max_2; -		dig_port->dp.voltage_max = intel_dp_voltage_max_2; -	} - -	dig_port->dp.output_reg = output_reg; -	dig_port->max_lanes = 4; - -	intel_encoder->type = INTEL_OUTPUT_DP; -	intel_encoder->power_domain = intel_port_to_power_domain(port); -	if (IS_CHERRYVIEW(dev_priv)) { -		if (port == PORT_D) -			intel_encoder->pipe_mask = BIT(PIPE_C); -		else -			intel_encoder->pipe_mask = BIT(PIPE_A) | BIT(PIPE_B); -	} else { -		intel_encoder->pipe_mask = ~0; -	} -	intel_encoder->cloneable = 0; -	intel_encoder->port = port; -	intel_encoder->hpd_pin = intel_hpd_pin_default(dev_priv, port); - -	dig_port->hpd_pulse = intel_dp_hpd_pulse; - -	if (HAS_GMCH(dev_priv)) { -		if (IS_GM45(dev_priv)) -			dig_port->connected = gm45_digital_port_connected; -		else -			dig_port->connected = g4x_digital_port_connected; -	} else { -		if (port == PORT_A) -			dig_port->connected = ilk_digital_port_connected; -		else -			dig_port->connected = ibx_digital_port_connected; -	} - -	if (port != PORT_A) -		intel_infoframe_init(dig_port); - -	dig_port->aux_ch = intel_bios_port_aux_ch(dev_priv, port); -	if (!intel_dp_init_connector(dig_port, intel_connector)) -		goto err_init_connector; - -	return true; - -err_init_connector: -	drm_encoder_cleanup(encoder); -err_encoder_init: -	kfree(intel_connector); -err_connector_alloc: -	kfree(dig_port); -	return false; -} -  void intel_dp_mst_suspend(struct drm_i915_private *dev_priv)  {  	struct intel_encoder *encoder; | 
