diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_ddi.c')
| -rw-r--r-- | drivers/gpu/drm/i915/display/intel_ddi.c | 535 | 
1 files changed, 241 insertions, 294 deletions
| diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index bd184325d0c7..1dcfe31e6c6f 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -29,6 +29,7 @@  #include "i915_drv.h"  #include "intel_audio.h" +#include "intel_backlight.h"  #include "intel_combo_phy.h"  #include "intel_connector.h"  #include "intel_crtc.h" @@ -40,6 +41,7 @@  #include "intel_dp_link_training.h"  #include "intel_dp_mst.h"  #include "intel_dpio_phy.h" +#include "intel_drrs.h"  #include "intel_dsi.h"  #include "intel_fdi.h"  #include "intel_fifo_underrun.h" @@ -48,7 +50,6 @@  #include "intel_hdmi.h"  #include "intel_hotplug.h"  #include "intel_lspcon.h" -#include "intel_panel.h"  #include "intel_pps.h"  #include "intel_psr.h"  #include "intel_snps_phy.h" @@ -73,24 +74,27 @@ static const u8 index_to_dp_signal_levels[] = {  };  static int intel_ddi_hdmi_level(struct intel_encoder *encoder, -				const struct intel_crtc_state *crtc_state) +				const struct intel_ddi_buf_trans *trans)  { -	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); -	int n_entries, level, default_entry; +	int level; -	n_entries = intel_ddi_hdmi_num_entries(encoder, crtc_state, &default_entry); -	if (n_entries == 0) -		return 0;  	level = intel_bios_hdmi_level_shift(encoder);  	if (level < 0) -		level = default_entry; - -	if (drm_WARN_ON_ONCE(&dev_priv->drm, level >= n_entries)) -		level = n_entries - 1; +		level = trans->hdmi_default_entry;  	return level;  } +static bool has_buf_trans_select(struct drm_i915_private *i915) +{ +	return DISPLAY_VER(i915) < 10 && !IS_BROXTON(i915); +} + +static bool has_iboost(struct drm_i915_private *i915) +{ +	return DISPLAY_VER(i915) == 9 && !IS_BROXTON(i915); +} +  /*   * Starting with Haswell, DDI port buffers must be programmed with correct   * values in advance. This function programs the correct values for @@ -103,22 +107,22 @@ void hsw_prepare_dp_ddi_buffers(struct intel_encoder *encoder,  	u32 iboost_bit = 0;  	int i, n_entries;  	enum port port = encoder->port; -	const struct intel_ddi_buf_trans *ddi_translations; +	const struct intel_ddi_buf_trans *trans; -	ddi_translations = encoder->get_buf_trans(encoder, crtc_state, &n_entries); -	if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations)) +	trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); +	if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans))  		return;  	/* If we're boosting the current, set bit 31 of trans1 */ -	if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv) && +	if (has_iboost(dev_priv) &&  	    intel_bios_encoder_dp_boost_level(encoder->devdata))  		iboost_bit = DDI_BUF_BALANCE_LEG_ENABLE;  	for (i = 0; i < n_entries; i++) {  		intel_de_write(dev_priv, DDI_BUF_TRANS_LO(port, i), -			       ddi_translations->entries[i].hsw.trans1 | iboost_bit); +			       trans->entries[i].hsw.trans1 | iboost_bit);  		intel_de_write(dev_priv, DDI_BUF_TRANS_HI(port, i), -			       ddi_translations->entries[i].hsw.trans2); +			       trans->entries[i].hsw.trans2);  	}  } @@ -128,31 +132,29 @@ void hsw_prepare_dp_ddi_buffers(struct intel_encoder *encoder,   * HDMI/DVI use cases.   */  static void hsw_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder, -					 const struct intel_crtc_state *crtc_state, -					 int level) +					 const struct intel_crtc_state *crtc_state)  {  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); +	int level = intel_ddi_level(encoder, crtc_state, 0);  	u32 iboost_bit = 0;  	int n_entries;  	enum port port = encoder->port; -	const struct intel_ddi_buf_trans *ddi_translations; +	const struct intel_ddi_buf_trans *trans; -	ddi_translations = encoder->get_buf_trans(encoder, crtc_state, &n_entries); -	if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations)) +	trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); +	if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans))  		return; -	if (drm_WARN_ON_ONCE(&dev_priv->drm, level >= n_entries)) -		level = n_entries - 1;  	/* If we're boosting the current, set bit 31 of trans1 */ -	if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv) && +	if (has_iboost(dev_priv) &&  	    intel_bios_encoder_hdmi_boost_level(encoder->devdata))  		iboost_bit = DDI_BUF_BALANCE_LEG_ENABLE;  	/* Entry 9 is for HDMI: */  	intel_de_write(dev_priv, DDI_BUF_TRANS_LO(port, 9), -		       ddi_translations->entries[level].hsw.trans1 | iboost_bit); +		       trans->entries[level].hsw.trans1 | iboost_bit);  	intel_de_write(dev_priv, DDI_BUF_TRANS_HI(port, 9), -		       ddi_translations->entries[level].hsw.trans2); +		       trans->entries[level].hsw.trans2);  }  void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv, @@ -281,13 +283,14 @@ static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder,  	struct intel_digital_port *dig_port = enc_to_dig_port(encoder);  	enum phy phy = intel_port_to_phy(i915, encoder->port); +	/* DDI_BUF_CTL_ENABLE will be set by intel_ddi_prepare_link_retrain() later */  	intel_dp->DP = dig_port->saved_port_bits | -		DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0); -	intel_dp->DP |= DDI_PORT_WIDTH(crtc_state->lane_count); +		DDI_PORT_WIDTH(crtc_state->lane_count) | +		DDI_BUF_TRANS_SELECT(0);  	if (IS_ALDERLAKE_P(i915) && intel_phy_is_tc(i915, phy)) {  		intel_dp->DP |= ddi_buf_phy_link_rate(crtc_state->port_clock); -		if (dig_port->tc_mode != TC_PORT_TBT_ALT) +		if (!intel_tc_port_in_tbt_alt_mode(dig_port))  			intel_dp->DP |= DDI_BUF_CTL_TC_PHY_OWNERSHIP;  	}  } @@ -407,6 +410,20 @@ static u32 bdw_trans_port_sync_master_select(enum transcoder master_transcoder)  		return master_transcoder + 1;  } +static void +intel_ddi_config_transcoder_dp2(struct intel_encoder *encoder, +				const struct intel_crtc_state *crtc_state) +{ +	struct drm_i915_private *i915 = to_i915(encoder->base.dev); +	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; +	u32 val = 0; + +	if (intel_dp_is_uhbr(crtc_state)) +		val = TRANS_DP2_128B132B_CHANNEL_CODING; + +	intel_de_write(i915, TRANS_DP2_CTL(cpu_transcoder), val); +} +  /*   * Returns the TRANS_DDI_FUNC_CTL value based on CRTC state.   * @@ -488,10 +505,13 @@ intel_ddi_transcoder_func_reg_val_get(struct intel_encoder *encoder,  		if (crtc_state->hdmi_high_tmds_clock_ratio)  			temp |= TRANS_DDI_HIGH_TMDS_CHAR_RATE;  	} else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG)) { -		temp |= TRANS_DDI_MODE_SELECT_FDI; +		temp |= TRANS_DDI_MODE_SELECT_FDI_OR_128B132B;  		temp |= (crtc_state->fdi_lanes - 1) << 1;  	} else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) { -		temp |= TRANS_DDI_MODE_SELECT_DP_MST; +		if (intel_dp_is_uhbr(crtc_state)) +			temp |= TRANS_DDI_MODE_SELECT_FDI_OR_128B132B; +		else +			temp |= TRANS_DDI_MODE_SELECT_DP_MST;  		temp |= DDI_PORT_WIDTH(crtc_state->lane_count);  		if (DISPLAY_VER(dev_priv) >= 12) { @@ -678,8 +698,13 @@ bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)  		ret = false;  		break; -	case TRANS_DDI_MODE_SELECT_FDI: -		ret = type == DRM_MODE_CONNECTOR_VGA; +	case TRANS_DDI_MODE_SELECT_FDI_OR_128B132B: +		if (HAS_DP20(dev_priv)) +			/* 128b/132b */ +			ret = false; +		else +			/* FDI */ +			ret = type == DRM_MODE_CONNECTOR_VGA;  		break;  	default: @@ -766,8 +791,9 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder,  		if ((tmp & port_mask) != ddi_select)  			continue; -		if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == -		    TRANS_DDI_MODE_SELECT_DP_MST) +		if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST || +		    (HAS_DP20(dev_priv) && +		     (tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_FDI_OR_128B132B))  			mst_pipe_mask |= BIT(p);  		*pipe_mask |= BIT(p); @@ -861,8 +887,7 @@ static void intel_ddi_get_power_domains(struct intel_encoder *encoder,  	dig_port = enc_to_dig_port(encoder); -	if (!intel_phy_is_tc(dev_priv, phy) || -	    dig_port->tc_mode != TC_PORT_TBT_ALT) { +	if (!intel_tc_port_in_tbt_alt_mode(dig_port)) {  		drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref);  		dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv,  								   dig_port->ddi_io_power_domain); @@ -947,16 +972,14 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder,  		iboost = intel_bios_encoder_dp_boost_level(encoder->devdata);  	if (iboost == 0) { -		const struct intel_ddi_buf_trans *ddi_translations; +		const struct intel_ddi_buf_trans *trans;  		int n_entries; -		ddi_translations = encoder->get_buf_trans(encoder, crtc_state, &n_entries); -		if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations)) +		trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); +		if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans))  			return; -		if (drm_WARN_ON_ONCE(&dev_priv->drm, level >= n_entries)) -			level = n_entries - 1; -		iboost = ddi_translations->entries[level].hsw.i_boost; +		iboost = trans->entries[level].hsw.i_boost;  	}  	/* Make sure that the requested I_boost is valid */ @@ -971,28 +994,6 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder,  		_skl_ddi_set_iboost(dev_priv, PORT_E, iboost);  } -static void bxt_ddi_vswing_sequence(struct intel_encoder *encoder, -				    const struct intel_crtc_state *crtc_state, -				    int level) -{ -	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); -	const struct intel_ddi_buf_trans *ddi_translations; -	enum port port = encoder->port; -	int n_entries; - -	ddi_translations = encoder->get_buf_trans(encoder, crtc_state, &n_entries); -	if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations)) -		return; -	if (drm_WARN_ON_ONCE(&dev_priv->drm, level >= n_entries)) -		level = n_entries - 1; - -	bxt_ddi_phy_set_signal_level(dev_priv, port, -				     ddi_translations->entries[level].bxt.margin, -				     ddi_translations->entries[level].bxt.scale, -				     ddi_translations->entries[level].bxt.enable, -				     ddi_translations->entries[level].bxt.deemphasis); -} -  static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp,  				   const struct intel_crtc_state *crtc_state)  { @@ -1022,33 +1023,43 @@ static u8 intel_ddi_dp_preemph_max(struct intel_dp *intel_dp)  	return DP_TRAIN_PRE_EMPH_LEVEL_3;  } +static u32 icl_combo_phy_loadgen_select(const struct intel_crtc_state *crtc_state, +					int lane) +{ +	if (crtc_state->port_clock > 600000) +		return 0; + +	if (crtc_state->lane_count == 4) +		return lane >= 1 ? LOADGEN_SELECT : 0; +	else +		return lane == 1 || lane == 2 ? LOADGEN_SELECT : 0; +} +  static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, -					 const struct intel_crtc_state *crtc_state, -					 int level) +					 const struct intel_crtc_state *crtc_state)  {  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); -	const struct intel_ddi_buf_trans *ddi_translations; +	int level = intel_ddi_level(encoder, crtc_state, 0); +	const struct intel_ddi_buf_trans *trans;  	enum phy phy = intel_port_to_phy(dev_priv, encoder->port);  	int n_entries, ln;  	u32 val; -	ddi_translations = encoder->get_buf_trans(encoder, crtc_state, &n_entries); -	if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations)) +	trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); +	if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans))  		return; -	if (drm_WARN_ON_ONCE(&dev_priv->drm, level >= n_entries)) -		level = n_entries - 1;  	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) {  		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);  		val = EDP4K2K_MODE_OVRD_EN | EDP4K2K_MODE_OVRD_OPTIMIZED; -		intel_dp->hobl_active = is_hobl_buf_trans(ddi_translations); +		intel_dp->hobl_active = is_hobl_buf_trans(trans);  		intel_de_rmw(dev_priv, ICL_PORT_CL_DW10(phy), val,  			     intel_dp->hobl_active ? val : 0);  	}  	/* Set PORT_TX_DW5 */ -	val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN0(phy)); +	val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN(0, phy));  	val &= ~(SCALING_MODE_SEL_MASK | RTERM_SELECT_MASK |  		  TAP2_DISABLE | TAP3_DISABLE);  	val |= SCALING_MODE_SEL(0x2); @@ -1057,52 +1068,48 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder,  	intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy), val);  	/* Program PORT_TX_DW2 */ -	val = intel_de_read(dev_priv, ICL_PORT_TX_DW2_LN0(phy)); +	val = intel_de_read(dev_priv, ICL_PORT_TX_DW2_LN(0, phy));  	val &= ~(SWING_SEL_LOWER_MASK | SWING_SEL_UPPER_MASK |  		 RCOMP_SCALAR_MASK); -	val |= SWING_SEL_UPPER(ddi_translations->entries[level].icl.dw2_swing_sel); -	val |= SWING_SEL_LOWER(ddi_translations->entries[level].icl.dw2_swing_sel); +	val |= SWING_SEL_UPPER(trans->entries[level].icl.dw2_swing_sel); +	val |= SWING_SEL_LOWER(trans->entries[level].icl.dw2_swing_sel);  	/* Program Rcomp scalar for every table entry */  	val |= RCOMP_SCALAR(0x98);  	intel_de_write(dev_priv, ICL_PORT_TX_DW2_GRP(phy), val);  	/* Program PORT_TX_DW4 */  	/* We cannot write to GRP. It would overwrite individual loadgen. */ -	for (ln = 0; ln <= 3; ln++) { +	for (ln = 0; ln < 4; ln++) {  		val = intel_de_read(dev_priv, ICL_PORT_TX_DW4_LN(ln, phy));  		val &= ~(POST_CURSOR_1_MASK | POST_CURSOR_2_MASK |  			 CURSOR_COEFF_MASK); -		val |= POST_CURSOR_1(ddi_translations->entries[level].icl.dw4_post_cursor_1); -		val |= POST_CURSOR_2(ddi_translations->entries[level].icl.dw4_post_cursor_2); -		val |= CURSOR_COEFF(ddi_translations->entries[level].icl.dw4_cursor_coeff); +		val |= POST_CURSOR_1(trans->entries[level].icl.dw4_post_cursor_1); +		val |= POST_CURSOR_2(trans->entries[level].icl.dw4_post_cursor_2); +		val |= CURSOR_COEFF(trans->entries[level].icl.dw4_cursor_coeff);  		intel_de_write(dev_priv, ICL_PORT_TX_DW4_LN(ln, phy), val);  	}  	/* Program PORT_TX_DW7 */ -	val = intel_de_read(dev_priv, ICL_PORT_TX_DW7_LN0(phy)); +	val = intel_de_read(dev_priv, ICL_PORT_TX_DW7_LN(0, phy));  	val &= ~N_SCALAR_MASK; -	val |= N_SCALAR(ddi_translations->entries[level].icl.dw7_n_scalar); +	val |= N_SCALAR(trans->entries[level].icl.dw7_n_scalar);  	intel_de_write(dev_priv, ICL_PORT_TX_DW7_GRP(phy), val);  } -static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder, -					      const struct intel_crtc_state *crtc_state, -					      int level) +static void icl_combo_phy_set_signal_levels(struct intel_encoder *encoder, +					    const struct intel_crtc_state *crtc_state)  {  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);  	enum phy phy = intel_port_to_phy(dev_priv, encoder->port); -	int width, rate, ln;  	u32 val; - -	width = crtc_state->lane_count; -	rate = crtc_state->port_clock; +	int ln;  	/*  	 * 1. If port type is eDP or DP,  	 * set PORT_PCS_DW1 cmnkeeper_enable to 1b,  	 * else clear to 0b.  	 */ -	val = intel_de_read(dev_priv, ICL_PORT_PCS_DW1_LN0(phy)); +	val = intel_de_read(dev_priv, ICL_PORT_PCS_DW1_LN(0, phy));  	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))  		val &= ~COMMON_KEEPER_EN;  	else @@ -1111,19 +1118,15 @@ static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder,  	/* 2. Program loadgen select */  	/* -	 * Program PORT_TX_DW4_LN depending on Bit rate and used lanes +	 * Program PORT_TX_DW4 depending on Bit rate and used lanes  	 * <= 6 GHz and 4 lanes (LN0=0, LN1=1, LN2=1, LN3=1)  	 * <= 6 GHz and 1,2 lanes (LN0=0, LN1=1, LN2=1, LN3=0)  	 * > 6 GHz (LN0=0, LN1=0, LN2=0, LN3=0)  	 */ -	for (ln = 0; ln <= 3; ln++) { +	for (ln = 0; ln < 4; ln++) {  		val = intel_de_read(dev_priv, ICL_PORT_TX_DW4_LN(ln, phy));  		val &= ~LOADGEN_SELECT; - -		if ((rate <= 600000 && width == 4 && ln >= 1) || -		    (rate <= 600000 && width < 4 && (ln == 1 || ln == 2))) { -			val |= LOADGEN_SELECT; -		} +		val |= icl_combo_phy_loadgen_select(crtc_state, ln);  		intel_de_write(dev_priv, ICL_PORT_TX_DW4_LN(ln, phy), val);  	} @@ -1133,37 +1136,35 @@ static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder,  	intel_de_write(dev_priv, ICL_PORT_CL_DW5(phy), val);  	/* 4. Clear training enable to change swing values */ -	val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN0(phy)); +	val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN(0, phy));  	val &= ~TX_TRAINING_EN;  	intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy), val);  	/* 5. Program swing and de-emphasis */ -	icl_ddi_combo_vswing_program(encoder, crtc_state, level); +	icl_ddi_combo_vswing_program(encoder, crtc_state);  	/* 6. Set training enable to trigger update */ -	val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN0(phy)); +	val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN(0, phy));  	val |= TX_TRAINING_EN;  	intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy), val);  } -static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder, -					   const struct intel_crtc_state *crtc_state, -					   int level) +static void icl_mg_phy_set_signal_levels(struct intel_encoder *encoder, +					 const struct intel_crtc_state *crtc_state)  {  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);  	enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port); -	const struct intel_ddi_buf_trans *ddi_translations; +	int level = intel_ddi_level(encoder, crtc_state, 0); +	const struct intel_ddi_buf_trans *trans;  	int n_entries, ln;  	u32 val; -	if (enc_to_dig_port(encoder)->tc_mode == TC_PORT_TBT_ALT) +	if (intel_tc_port_in_tbt_alt_mode(enc_to_dig_port(encoder)))  		return; -	ddi_translations = encoder->get_buf_trans(encoder, crtc_state, &n_entries); -	if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations)) +	trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); +	if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans))  		return; -	if (drm_WARN_ON_ONCE(&dev_priv->drm, level >= n_entries)) -		level = n_entries - 1;  	/* Set MG_TX_LINK_PARAMS cri_use_fs32 to 0. */  	for (ln = 0; ln < 2; ln++) { @@ -1181,13 +1182,13 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,  		val = intel_de_read(dev_priv, MG_TX1_SWINGCTRL(ln, tc_port));  		val &= ~CRI_TXDEEMPH_OVERRIDE_17_12_MASK;  		val |= CRI_TXDEEMPH_OVERRIDE_17_12( -			ddi_translations->entries[level].mg.cri_txdeemph_override_17_12); +			trans->entries[level].mg.cri_txdeemph_override_17_12);  		intel_de_write(dev_priv, MG_TX1_SWINGCTRL(ln, tc_port), val);  		val = intel_de_read(dev_priv, MG_TX2_SWINGCTRL(ln, tc_port));  		val &= ~CRI_TXDEEMPH_OVERRIDE_17_12_MASK;  		val |= CRI_TXDEEMPH_OVERRIDE_17_12( -			ddi_translations->entries[level].mg.cri_txdeemph_override_17_12); +			trans->entries[level].mg.cri_txdeemph_override_17_12);  		intel_de_write(dev_priv, MG_TX2_SWINGCTRL(ln, tc_port), val);  	} @@ -1197,9 +1198,9 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,  		val &= ~(CRI_TXDEEMPH_OVERRIDE_11_6_MASK |  			 CRI_TXDEEMPH_OVERRIDE_5_0_MASK);  		val |= CRI_TXDEEMPH_OVERRIDE_5_0( -			ddi_translations->entries[level].mg.cri_txdeemph_override_5_0) | +			trans->entries[level].mg.cri_txdeemph_override_5_0) |  			CRI_TXDEEMPH_OVERRIDE_11_6( -				ddi_translations->entries[level].mg.cri_txdeemph_override_11_6) | +				trans->entries[level].mg.cri_txdeemph_override_11_6) |  			CRI_TXDEEMPH_OVERRIDE_EN;  		intel_de_write(dev_priv, MG_TX1_DRVCTRL(ln, tc_port), val); @@ -1207,9 +1208,9 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,  		val &= ~(CRI_TXDEEMPH_OVERRIDE_11_6_MASK |  			 CRI_TXDEEMPH_OVERRIDE_5_0_MASK);  		val |= CRI_TXDEEMPH_OVERRIDE_5_0( -			ddi_translations->entries[level].mg.cri_txdeemph_override_5_0) | +			trans->entries[level].mg.cri_txdeemph_override_5_0) |  			CRI_TXDEEMPH_OVERRIDE_11_6( -				ddi_translations->entries[level].mg.cri_txdeemph_override_11_6) | +				trans->entries[level].mg.cri_txdeemph_override_11_6) |  			CRI_TXDEEMPH_OVERRIDE_EN;  		intel_de_write(dev_priv, MG_TX2_DRVCTRL(ln, tc_port), val); @@ -1269,45 +1270,29 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,  	}  } -static void icl_ddi_vswing_sequence(struct intel_encoder *encoder, -				    const struct intel_crtc_state *crtc_state, -				    int level) -{ -	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); -	enum phy phy = intel_port_to_phy(dev_priv, encoder->port); - -	if (intel_phy_is_combo(dev_priv, phy)) -		icl_combo_phy_ddi_vswing_sequence(encoder, crtc_state, level); -	else -		icl_mg_phy_ddi_vswing_sequence(encoder, crtc_state, level); -} - -static void -tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder, -				const struct intel_crtc_state *crtc_state, -				int level) +static void tgl_dkl_phy_set_signal_levels(struct intel_encoder *encoder, +					  const struct intel_crtc_state *crtc_state)  {  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);  	enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port); -	const struct intel_ddi_buf_trans *ddi_translations; +	int level = intel_ddi_level(encoder, crtc_state, 0); +	const struct intel_ddi_buf_trans *trans;  	u32 val, dpcnt_mask, dpcnt_val;  	int n_entries, ln; -	if (enc_to_dig_port(encoder)->tc_mode == TC_PORT_TBT_ALT) +	if (intel_tc_port_in_tbt_alt_mode(enc_to_dig_port(encoder)))  		return; -	ddi_translations = encoder->get_buf_trans(encoder, crtc_state, &n_entries); -	if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations)) +	trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); +	if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans))  		return; -	if (drm_WARN_ON_ONCE(&dev_priv->drm, level >= n_entries)) -		level = n_entries - 1;  	dpcnt_mask = (DKL_TX_PRESHOOT_COEFF_MASK |  		      DKL_TX_DE_EMPAHSIS_COEFF_MASK |  		      DKL_TX_VSWING_CONTROL_MASK); -	dpcnt_val = DKL_TX_VSWING_CONTROL(ddi_translations->entries[level].dkl.dkl_vswing_control); -	dpcnt_val |= DKL_TX_DE_EMPHASIS_COEFF(ddi_translations->entries[level].dkl.dkl_de_emphasis_control); -	dpcnt_val |= DKL_TX_PRESHOOT_COEFF(ddi_translations->entries[level].dkl.dkl_preshoot_control); +	dpcnt_val = DKL_TX_VSWING_CONTROL(trans->entries[level].dkl.vswing); +	dpcnt_val |= DKL_TX_DE_EMPHASIS_COEFF(trans->entries[level].dkl.de_emphasis); +	dpcnt_val |= DKL_TX_PRESHOOT_COEFF(trans->entries[level].dkl.preshoot);  	for (ln = 0; ln < 2; ln++) {  		intel_de_write(dev_priv, HIP_INDEX_REG(tc_port), @@ -1329,30 +1314,9 @@ tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder,  		val = intel_de_read(dev_priv, DKL_TX_DPCNTL2(tc_port));  		val &= ~DKL_TX_DP20BITMODE;  		intel_de_write(dev_priv, DKL_TX_DPCNTL2(tc_port), val); - -		if ((intel_crtc_has_dp_encoder(crtc_state) && -		     crtc_state->port_clock == 162000) || -		    (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) && -		     crtc_state->port_clock == 594000)) -			val |= DKL_TX_LOADGEN_SHARING_PMD_DISABLE; -		else -			val &= ~DKL_TX_LOADGEN_SHARING_PMD_DISABLE;  	}  } -static void tgl_ddi_vswing_sequence(struct intel_encoder *encoder, -				    const struct intel_crtc_state *crtc_state, -				    int level) -{ -	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); -	enum phy phy = intel_port_to_phy(dev_priv, encoder->port); - -	if (intel_phy_is_combo(dev_priv, phy)) -		icl_combo_phy_ddi_vswing_sequence(encoder, crtc_state, level); -	else -		tgl_dkl_phy_ddi_vswing_sequence(encoder, crtc_state, level); -} -  static int translate_signal_level(struct intel_dp *intel_dp,  				  u8 signal_levels)  { @@ -1371,65 +1335,63 @@ static int translate_signal_level(struct intel_dp *intel_dp,  	return 0;  } -static int intel_ddi_dp_level(struct intel_dp *intel_dp) +static int intel_ddi_dp_level(struct intel_dp *intel_dp, +			      const struct intel_crtc_state *crtc_state, +			      int lane)  { -	u8 train_set = intel_dp->train_set[0]; -	u8 signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK | -					DP_TRAIN_PRE_EMPHASIS_MASK); - -	return translate_signal_level(intel_dp, signal_levels); -} +	u8 train_set = intel_dp->train_set[lane]; -static void -dg2_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; -	int level = intel_ddi_dp_level(intel_dp); +	if (intel_dp_is_uhbr(crtc_state)) { +		return train_set & DP_TX_FFE_PRESET_VALUE_MASK; +	} else { +		u8 signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK | +						DP_TRAIN_PRE_EMPHASIS_MASK); -	intel_snps_phy_ddi_vswing_sequence(encoder, level); +		return translate_signal_level(intel_dp, signal_levels); +	}  } -static void -tgl_set_signal_levels(struct intel_dp *intel_dp, -		      const struct intel_crtc_state *crtc_state) +int intel_ddi_level(struct intel_encoder *encoder, +		    const struct intel_crtc_state *crtc_state, +		    int lane)  { -	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; -	int level = intel_ddi_dp_level(intel_dp); - -	tgl_ddi_vswing_sequence(encoder, crtc_state, level); -} +	struct drm_i915_private *i915 = to_i915(encoder->base.dev); +	const struct intel_ddi_buf_trans *trans; +	int level, n_entries; -static void -icl_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; -	int level = intel_ddi_dp_level(intel_dp); +	trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); +	if (drm_WARN_ON_ONCE(&i915->drm, !trans)) +		return 0; -	icl_ddi_vswing_sequence(encoder, crtc_state, level); -} +	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) +		level = intel_ddi_hdmi_level(encoder, trans); +	else +		level = intel_ddi_dp_level(enc_to_intel_dp(encoder), crtc_state, +					   lane); -static void -bxt_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; -	int level = intel_ddi_dp_level(intel_dp); +	if (drm_WARN_ON_ONCE(&i915->drm, level >= n_entries)) +		level = n_entries - 1; -	bxt_ddi_vswing_sequence(encoder, crtc_state, level); +	return level;  }  static void -hsw_set_signal_levels(struct intel_dp *intel_dp, +hsw_set_signal_levels(struct intel_encoder *encoder,  		      const struct intel_crtc_state *crtc_state)  { -	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); -	int level = intel_ddi_dp_level(intel_dp); +	struct intel_dp *intel_dp = enc_to_intel_dp(encoder); +	int level = intel_ddi_level(encoder, crtc_state, 0);  	enum port port = encoder->port;  	u32 signal_levels; +	if (has_iboost(dev_priv)) +		skl_ddi_set_iboost(encoder, crtc_state, level); + +	/* HDMI ignores the rest */ +	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) +		return; +  	signal_levels = DDI_BUF_TRANS_SELECT(level);  	drm_dbg_kms(&dev_priv->drm, "Using signal levels %08x\n", @@ -1438,9 +1400,6 @@ hsw_set_signal_levels(struct intel_dp *intel_dp,  	intel_dp->DP &= ~DDI_BUF_EMP_MASK;  	intel_dp->DP |= signal_levels; -	if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv)) -		skl_ddi_set_iboost(encoder, crtc_state, level); -  	intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP);  	intel_de_posting_read(dev_priv, DDI_BUF_CTL(port));  } @@ -2059,7 +2018,7 @@ icl_program_mg_dp_mode(struct intel_digital_port *dig_port,  	u8 width;  	if (!intel_phy_is_tc(dev_priv, phy) || -	    dig_port->tc_mode == TC_PORT_TBT_ALT) +	    intel_tc_port_in_tbt_alt_mode(dig_port))  		return;  	if (DISPLAY_VER(dev_priv) >= 12) { @@ -2084,7 +2043,7 @@ icl_program_mg_dp_mode(struct intel_digital_port *dig_port,  	switch (pin_assignment) {  	case 0x0:  		drm_WARN_ON(&dev_priv->drm, -			    dig_port->tc_mode != TC_PORT_LEGACY); +			    !intel_tc_port_in_legacy_mode(dig_port));  		if (width == 1) {  			ln1 |= MG_DP_MODE_CFG_DP_X1_MODE;  		} else { @@ -2329,15 +2288,19 @@ static void dg2_ddi_pre_enable_dp(struct intel_atomic_state *state,  {  	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); -	enum phy phy = intel_port_to_phy(dev_priv, encoder->port);  	struct intel_digital_port *dig_port = enc_to_dig_port(encoder);  	bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); -	int level = intel_ddi_dp_level(intel_dp);  	intel_dp_set_link_params(intel_dp, crtc_state->port_clock,  				 crtc_state->lane_count);  	/* +	 * We only configure what the register value will be here.  Actual +	 * enabling happens during link training farther down. +	 */ +	intel_ddi_init_dp_buf_reg(encoder, crtc_state); + +	/*  	 * 1. Enable Power Wells  	 *  	 * This was handled at the beginning of intel_atomic_commit_tail(), @@ -2353,8 +2316,7 @@ static void dg2_ddi_pre_enable_dp(struct intel_atomic_state *state,  	intel_ddi_enable_clock(encoder, crtc_state);  	/* 4. Enable IO power */ -	if (!intel_phy_is_tc(dev_priv, phy) || -	    dig_port->tc_mode != TC_PORT_TBT_ALT) +	if (!intel_tc_port_in_tbt_alt_mode(dig_port))  		dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv,  								   dig_port->ddi_io_power_domain); @@ -2374,7 +2336,8 @@ static void dg2_ddi_pre_enable_dp(struct intel_atomic_state *state,  	 */  	intel_ddi_enable_pipe_clock(encoder, crtc_state); -	/* 5.b Not relevant to i915 for now */ +	/* 5.b Configure transcoder for DP 2.0 128b/132b */ +	intel_ddi_config_transcoder_dp2(encoder, crtc_state);  	/*  	 * 5.c Configure TRANS_DDI_FUNC_CTL DDI Select, DDI Mode Select & MST @@ -2391,21 +2354,12 @@ static void dg2_ddi_pre_enable_dp(struct intel_atomic_state *state,  	 */  	/* 5.e Configure voltage swing and related IO settings */ -	intel_snps_phy_ddi_vswing_sequence(encoder, level); - -	/* -	 * 5.f Configure and enable DDI_BUF_CTL -	 * 5.g Wait for DDI_BUF_CTL DDI Idle Status = 0b (Not Idle), timeout -	 *     after 1200 us. -	 * -	 * We only configure what the register value will be here.  Actual -	 * enabling happens during link training farther down. -	 */ -	intel_ddi_init_dp_buf_reg(encoder, crtc_state); +	encoder->set_signal_levels(encoder, crtc_state);  	if (!is_mst)  		intel_dp_set_power(intel_dp, DP_SET_POWER_D0); +	intel_dp_configure_protocol_converter(intel_dp, crtc_state);  	intel_dp_sink_set_decompression_state(intel_dp, crtc_state, true);  	/*  	 * DDI FEC: "anticipates enabling FEC encoding sets the FEC_READY bit @@ -2413,6 +2367,8 @@ static void dg2_ddi_pre_enable_dp(struct intel_atomic_state *state,  	 * training  	 */  	intel_dp_sink_set_fec_ready(intel_dp, crtc_state); +	intel_dp_check_frl_training(intel_dp); +	intel_dp_pcon_dsc_configure(intel_dp, crtc_state);  	/*  	 * 5.h Follow DisplayPort specification training sequence (see notes for @@ -2439,16 +2395,20 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,  {  	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); -	enum phy phy = intel_port_to_phy(dev_priv, encoder->port);  	struct intel_digital_port *dig_port = enc_to_dig_port(encoder);  	bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); -	int level = intel_ddi_dp_level(intel_dp);  	intel_dp_set_link_params(intel_dp,  				 crtc_state->port_clock,  				 crtc_state->lane_count);  	/* +	 * We only configure what the register value will be here.  Actual +	 * enabling happens during link training farther down. +	 */ +	intel_ddi_init_dp_buf_reg(encoder, crtc_state); + +	/*  	 * 1. Enable Power Wells  	 *  	 * This was handled at the beginning of intel_atomic_commit_tail(), @@ -2476,8 +2436,7 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,  	intel_ddi_enable_clock(encoder, crtc_state);  	/* 5. If IO power is controlled through PWR_WELL_CTL, Enable IO Power */ -	if (!intel_phy_is_tc(dev_priv, phy) || -	    dig_port->tc_mode != TC_PORT_TBT_ALT) { +	if (!intel_tc_port_in_tbt_alt_mode(dig_port)) {  		drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref);  		dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv,  								   dig_port->ddi_io_power_domain); @@ -2517,7 +2476,7 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,  	 */  	/* 7.e Configure voltage swing and related IO settings */ -	tgl_ddi_vswing_sequence(encoder, crtc_state, level); +	encoder->set_signal_levels(encoder, crtc_state);  	/*  	 * 7.f Combo PHY: Configure PORT_CL_DW10 Static Power Down to power up @@ -2530,16 +2489,6 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,  	 */  	intel_ddi_mso_configure(crtc_state); -	/* -	 * 7.g Configure and enable DDI_BUF_CTL -	 * 7.h Wait for DDI_BUF_CTL DDI Idle Status = 0b (Not Idle), timeout -	 *     after 500 us. -	 * -	 * We only configure what the register value will be here.  Actual -	 * enabling happens during link training farther down. -	 */ -	intel_ddi_init_dp_buf_reg(encoder, crtc_state); -  	if (!is_mst)  		intel_dp_set_power(intel_dp, DP_SET_POWER_D0); @@ -2582,10 +2531,8 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,  	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);  	enum port port = encoder->port; -	enum phy phy = intel_port_to_phy(dev_priv, port);  	struct intel_digital_port *dig_port = enc_to_dig_port(encoder);  	bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); -	int level = intel_ddi_dp_level(intel_dp);  	if (DISPLAY_VER(dev_priv) < 11)  		drm_WARN_ON(&dev_priv->drm, @@ -2597,12 +2544,17 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,  				 crtc_state->port_clock,  				 crtc_state->lane_count); +	/* +	 * We only configure what the register value will be here.  Actual +	 * enabling happens during link training farther down. +	 */ +	intel_ddi_init_dp_buf_reg(encoder, crtc_state); +  	intel_pps_on(intel_dp);  	intel_ddi_enable_clock(encoder, crtc_state); -	if (!intel_phy_is_tc(dev_priv, phy) || -	    dig_port->tc_mode != TC_PORT_TBT_ALT) { +	if (!intel_tc_port_in_tbt_alt_mode(dig_port)) {  		drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref);  		dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv,  								   dig_port->ddi_io_power_domain); @@ -2610,16 +2562,13 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,  	icl_program_mg_dp_mode(dig_port, crtc_state); -	if (DISPLAY_VER(dev_priv) >= 11) -		icl_ddi_vswing_sequence(encoder, crtc_state, level); -	else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) -		bxt_ddi_vswing_sequence(encoder, crtc_state, level); -	else +	if (has_buf_trans_select(dev_priv))  		hsw_prepare_dp_ddi_buffers(encoder, crtc_state); +	encoder->set_signal_levels(encoder, crtc_state); +  	intel_ddi_power_up_lanes(encoder, crtc_state); -	intel_ddi_init_dp_buf_reg(encoder, crtc_state);  	if (!is_mst)  		intel_dp_set_power(intel_dp, DP_SET_POWER_D0);  	intel_dp_configure_protocol_converter(intel_dp, crtc_state); @@ -2772,7 +2721,6 @@ static void intel_ddi_post_disable_dp(struct intel_atomic_state *state,  	struct intel_dp *intel_dp = &dig_port->dp;  	bool is_mst = intel_crtc_has_type(old_crtc_state,  					  INTEL_OUTPUT_DP_MST); -	enum phy phy = intel_port_to_phy(dev_priv, encoder->port);  	if (!is_mst)  		intel_dp_set_infoframes(encoder, false, @@ -2815,8 +2763,7 @@ static void intel_ddi_post_disable_dp(struct intel_atomic_state *state,  	intel_pps_vdd_on(intel_dp);  	intel_pps_off(intel_dp); -	if (!intel_phy_is_tc(dev_priv, phy) || -	    dig_port->tc_mode != TC_PORT_TBT_ALT) +	if (!intel_tc_port_in_tbt_alt_mode(dig_port))  		intel_display_power_put(dev_priv,  					dig_port->ddi_io_power_domain,  					fetch_and_zero(&dig_port->ddi_io_wakeref)); @@ -2862,7 +2809,7 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state,  	if (!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST)) {  		intel_crtc_vblank_off(old_crtc_state); -		intel_disable_pipe(old_crtc_state); +		intel_disable_transcoder(old_crtc_state);  		intel_vrr_disable(old_crtc_state); @@ -3005,12 +2952,11 @@ static void intel_enable_ddi_dp(struct intel_atomic_state *state,  		intel_dp_stop_link_train(intel_dp, crtc_state);  	intel_edp_backlight_on(crtc_state, conn_state); -	intel_psr_enable(intel_dp, crtc_state, conn_state);  	if (!dig_port->lspcon.active || dig_port->dp.has_hdmi_sink)  		intel_dp_set_infoframes(encoder, true, crtc_state, conn_state); -	intel_edp_drrs_enable(intel_dp, crtc_state); +	intel_drrs_enable(intel_dp, crtc_state);  	if (crtc_state->has_audio)  		intel_audio_codec_enable(encoder, crtc_state, conn_state); @@ -3046,7 +2992,6 @@ static void intel_enable_ddi_hdmi(struct intel_atomic_state *state,  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);  	struct intel_digital_port *dig_port = enc_to_dig_port(encoder);  	struct drm_connector *connector = conn_state->connector; -	int level = intel_ddi_hdmi_level(encoder, crtc_state);  	enum port port = encoder->port;  	if (!intel_hdmi_handle_sink_scrambling(encoder, connector, @@ -3056,19 +3001,10 @@ static void intel_enable_ddi_hdmi(struct intel_atomic_state *state,  			    "[CONNECTOR:%d:%s] Failed to configure sink scrambling/TMDS bit clock ratio\n",  			    connector->base.id, connector->name); -	if (IS_DG2(dev_priv)) -		intel_snps_phy_ddi_vswing_sequence(encoder, U32_MAX); -	else if (DISPLAY_VER(dev_priv) >= 12) -		tgl_ddi_vswing_sequence(encoder, crtc_state, level); -	else if (DISPLAY_VER(dev_priv) == 11) -		icl_ddi_vswing_sequence(encoder, crtc_state, level); -	else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) -		bxt_ddi_vswing_sequence(encoder, crtc_state, level); -	else -		hsw_prepare_hdmi_ddi_buffers(encoder, crtc_state, level); +	if (has_buf_trans_select(dev_priv)) +		hsw_prepare_hdmi_ddi_buffers(encoder, crtc_state); -	if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv)) -		skl_ddi_set_iboost(encoder, crtc_state, level); +	encoder->set_signal_levels(encoder, crtc_state);  	/* Display WA #1143: skl,kbl,cfl */  	if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv)) { @@ -3133,7 +3069,7 @@ static void intel_enable_ddi(struct intel_atomic_state *state,  	intel_vrr_enable(encoder, crtc_state); -	intel_enable_pipe(crtc_state); +	intel_enable_transcoder(crtc_state);  	intel_crtc_vblank_on(crtc_state); @@ -3198,7 +3134,7 @@ static void intel_pre_disable_ddi(struct intel_atomic_state *state,  		return;  	intel_dp = enc_to_intel_dp(encoder); -	intel_edp_drrs_disable(intel_dp, old_crtc_state); +	intel_drrs_disable(intel_dp, old_crtc_state);  	intel_psr_disable(intel_dp, old_crtc_state);  } @@ -3226,11 +3162,10 @@ static void intel_ddi_update_pipe_dp(struct intel_atomic_state *state,  	intel_ddi_set_dp_msa(crtc_state, conn_state); -	intel_psr_update(intel_dp, crtc_state, conn_state);  	intel_dp_set_infoframes(encoder, true, crtc_state, conn_state); -	intel_edp_drrs_update(intel_dp, crtc_state); +	intel_drrs_update(intel_dp, crtc_state); -	intel_panel_update_backlight(state, encoder, crtc_state, conn_state); +	intel_backlight_update(state, encoder, crtc_state, conn_state);  }  void intel_ddi_update_pipe(struct intel_atomic_state *state, @@ -3293,7 +3228,7 @@ intel_ddi_pre_pll_enable(struct intel_atomic_state *state,  						intel_ddi_main_link_aux_domain(dig_port));  	} -	if (is_tc_port && dig_port->tc_mode != TC_PORT_TBT_ALT) +	if (is_tc_port && !intel_tc_port_in_tbt_alt_mode(dig_port))  		/*  		 * Program the lane count for static/dynamic connections on  		 * Type-C ports.  Skip this step for TBT. @@ -3553,9 +3488,6 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder,  		pipe_config->output_types |= BIT(INTEL_OUTPUT_HDMI);  		pipe_config->lane_count = 4;  		break; -	case TRANS_DDI_MODE_SELECT_FDI: -		pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG); -		break;  	case TRANS_DDI_MODE_SELECT_DP_SST:  		if (encoder->type == INTEL_OUTPUT_EDP)  			pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP); @@ -3584,6 +3516,13 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder,  			pipe_config->infoframes.enable |=  				intel_hdmi_infoframes_enabled(encoder, pipe_config);  		break; +	case TRANS_DDI_MODE_SELECT_FDI_OR_128B132B: +		if (!HAS_DP20(dev_priv)) { +			/* FDI */ +			pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG); +			break; +		} +		fallthrough; /* 128b/132b */  	case TRANS_DDI_MODE_SELECT_DP_MST:  		pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST);  		pipe_config->lane_count = @@ -3995,13 +3934,15 @@ static void intel_ddi_encoder_destroy(struct drm_encoder *encoder)  {  	struct drm_i915_private *i915 = to_i915(encoder->dev);  	struct intel_digital_port *dig_port = enc_to_dig_port(to_intel_encoder(encoder)); +	enum phy phy = intel_port_to_phy(i915, dig_port->base.port);  	intel_dp_encoder_flush_work(encoder); +	if (intel_phy_is_tc(i915, phy)) +		intel_tc_port_flush_work(dig_port);  	intel_display_power_flush_work(i915);  	drm_encoder_cleanup(encoder); -	if (dig_port) -		kfree(dig_port->hdcp_port_data.streams); +	kfree(dig_port->hdcp_port_data.streams);  	kfree(dig_port);  } @@ -4022,7 +3963,6 @@ static const struct drm_encoder_funcs intel_ddi_funcs = {  static struct intel_connector *  intel_ddi_init_dp_connector(struct intel_digital_port *dig_port)  { -	struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);  	struct intel_connector *connector;  	enum port port = dig_port->base.port; @@ -4035,17 +3975,6 @@ intel_ddi_init_dp_connector(struct intel_digital_port *dig_port)  	dig_port->dp.set_link_train = intel_ddi_set_link_train;  	dig_port->dp.set_idle_link_train = intel_ddi_set_idle_link_train; -	if (IS_DG2(dev_priv)) -		dig_port->dp.set_signal_levels = dg2_set_signal_levels; -	else if (DISPLAY_VER(dev_priv) >= 12) -		dig_port->dp.set_signal_levels = tgl_set_signal_levels; -	else if (DISPLAY_VER(dev_priv) >= 11) -		dig_port->dp.set_signal_levels = icl_set_signal_levels; -	else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) -		dig_port->dp.set_signal_levels = bxt_set_signal_levels; -	else -		dig_port->dp.set_signal_levels = hsw_set_signal_levels; -  	dig_port->dp.voltage_max = intel_ddi_dp_voltage_max;  	dig_port->dp.preemph_max = intel_ddi_dp_preemph_max; @@ -4421,7 +4350,7 @@ static void intel_ddi_encoder_suspend(struct intel_encoder *encoder)  	if (!intel_phy_is_tc(i915, phy))  		return; -	intel_tc_port_disconnect_phy(dig_port); +	intel_tc_port_flush_work(dig_port);  }  static void intel_ddi_encoder_shutdown(struct intel_encoder *encoder) @@ -4436,7 +4365,7 @@ static void intel_ddi_encoder_shutdown(struct intel_encoder *encoder)  	if (!intel_phy_is_tc(i915, phy))  		return; -	intel_tc_port_disconnect_phy(dig_port); +	intel_tc_port_flush_work(dig_port);  }  #define port_tc_name(port) ((port) - PORT_TC1 + '1') @@ -4617,6 +4546,24 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)  		encoder->get_config = hsw_ddi_get_config;  	} +	if (IS_DG2(dev_priv)) { +		encoder->set_signal_levels = intel_snps_phy_set_signal_levels; +	} else if (DISPLAY_VER(dev_priv) >= 12) { +		if (intel_phy_is_combo(dev_priv, phy)) +			encoder->set_signal_levels = icl_combo_phy_set_signal_levels; +		else +			encoder->set_signal_levels = tgl_dkl_phy_set_signal_levels; +	} else if (DISPLAY_VER(dev_priv) >= 11) { +		if (intel_phy_is_combo(dev_priv, phy)) +			encoder->set_signal_levels = icl_combo_phy_set_signal_levels; +		else +			encoder->set_signal_levels = icl_mg_phy_set_signal_levels; +	} else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { +		encoder->set_signal_levels = bxt_ddi_phy_set_signal_levels; +	} else { +		encoder->set_signal_levels = hsw_set_signal_levels; +	} +  	intel_ddi_buf_trans_init(encoder);  	if (DISPLAY_VER(dev_priv) >= 13) |