On Thu, Apr 13, 2023 at 02:24:40PM -0700, Radhakrishna Sripada wrote: > From: José Roberto de Souza <jose.souza@xxxxxxxxx> > > The differences between MTL and TGL DP sequences are big enough to > MTL have its own functions. > > Also it is much easier to follow MTL sequences against spec with > its own functions. > > One change worthy to mention is the move of > 'intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain)'. > This call is not necessary for MTL but we have _put() counter part in > intel_ddi_post_disable_dp() that needs to balanced. > We could add a display version check on it but instead here it is > moving it to intel_ddi_pre_enable_dp() so it is executed for all > platforms in a single place and this will not cause any harm in MTL > and newer platforms. > > v2: > - Fix logic to wait for buf idle. > - Use the right register to wait for ddi active.(RK) > v3: > - Increase wait timeout for ddi buf active (Mika) > v4: > - Increase idle timeout for ddi buf idle (Mika) > v5: use rmw in mtl_disable_ddi_buf. Donot clear > link training mask(Imre) > > BSpec: 65448 65505 > Cc: Matt Roper <matthew.d.roper@xxxxxxxxx> > Cc: Satyeshwar Singh <satyeshwar.singh@xxxxxxxxx> > Cc: Clint Taylor <clinton.a.taylor@xxxxxxxxx> > Cc: Ankit Nautiyal <ankit.k.nautiyal@xxxxxxxxx> > Cc: Imre Deak <imre.deak@xxxxxxxxx> > Signed-off-by: Radhakrishna Sripada <radhakrishna.sripada@xxxxxxxxx> > Signed-off-by: José Roberto de Souza <jose.souza@xxxxxxxxx> > Signed-off-by: Mika Kahola <mika.kahola@xxxxxxxxx> Reviewed-by: Imre Deak <imre.deak@xxxxxxxxx> > --- > .../gpu/drm/i915/display/intel_cx0_phy_regs.h | 8 + > drivers/gpu/drm/i915/display/intel_ddi.c | 344 +++++++++++++++++- > drivers/gpu/drm/i915/i915_reg.h | 5 + > 3 files changed, 345 insertions(+), 12 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h b/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h > index 9cfa7f508c90..fe2e3edef69b 100644 > --- a/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h > +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h > @@ -59,8 +59,16 @@ > _XELPDP_PORT_BUF_CTL1_LN0_B, \ > _XELPDP_PORT_BUF_CTL1_LN0_USBC1, \ > _XELPDP_PORT_BUF_CTL1_LN0_USBC2)) > +#define XELPDP_PORT_BUF_D2D_LINK_ENABLE REG_BIT(29) > +#define XELPDP_PORT_BUF_D2D_LINK_STATE REG_BIT(28) > #define XELPDP_PORT_BUF_SOC_PHY_READY REG_BIT(24) > +#define XELPDP_PORT_BUF_PORT_DATA_WIDTH_MASK REG_GENMASK(19, 18) > +#define XELPDP_PORT_BUF_PORT_DATA_10BIT REG_FIELD_PREP(XELPDP_PORT_BUF_PORT_DATA_WIDTH_MASK, 0) > +#define XELPDP_PORT_BUF_PORT_DATA_20BIT REG_FIELD_PREP(XELPDP_PORT_BUF_PORT_DATA_WIDTH_MASK, 1) > +#define XELPDP_PORT_BUF_PORT_DATA_40BIT REG_FIELD_PREP(XELPDP_PORT_BUF_PORT_DATA_WIDTH_MASK, 2) > #define XELPDP_PORT_REVERSAL REG_BIT(16) > +#define XELPDP_PORT_BUF_IO_SELECT_TBT REG_BIT(11) > +#define XELPDP_PORT_BUF_PHY_IDLE REG_BIT(7) > #define XELPDP_TC_PHY_OWNERSHIP REG_BIT(6) > #define XELPDP_TCSS_POWER_REQUEST REG_BIT(5) > #define XELPDP_TCSS_POWER_STATE REG_BIT(4) > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c > index 21a86cb7b2dc..c0283829823f 100644 > --- a/drivers/gpu/drm/i915/display/intel_ddi.c > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c > @@ -40,6 +40,7 @@ > #include "intel_connector.h" > #include "intel_crtc.h" > #include "intel_cx0_phy.h" > +#include "intel_cx0_phy_regs.h" > #include "intel_ddi.h" > #include "intel_ddi_buf_trans.h" > #include "intel_de.h" > @@ -169,6 +170,18 @@ static void hsw_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder, > trans->entries[level].hsw.trans2); > } > > +static void mtl_wait_ddi_buf_idle(struct drm_i915_private *i915, enum port port) > +{ > + int ret; > + > + /* FIXME: find out why Bspec's 100us timeout is too short */ > + ret = wait_for_us((intel_de_read(i915, XELPDP_PORT_BUF_CTL1(port)) & > + XELPDP_PORT_BUF_PHY_IDLE), 10000); > + if (ret) > + drm_err(&i915->drm, "Timeout waiting for DDI BUF %c to get idle\n", > + port_name(port)); > +} > + > void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv, > enum port port) > { > @@ -196,7 +209,9 @@ static void intel_wait_ddi_buf_active(struct drm_i915_private *dev_priv, > return; > } > > - if (IS_DG2(dev_priv)) { > + if (DISPLAY_VER(dev_priv) >= 14) { > + timeout_us = 10000; > + } else if (IS_DG2(dev_priv)) { > timeout_us = 1200; > } else if (DISPLAY_VER(dev_priv) >= 12) { > if (intel_phy_is_tc(dev_priv, phy)) > @@ -207,8 +222,12 @@ static void intel_wait_ddi_buf_active(struct drm_i915_private *dev_priv, > timeout_us = 500; > } > > - ret = _wait_for(!(intel_de_read(dev_priv, DDI_BUF_CTL(port)) & > - DDI_BUF_IS_IDLE), timeout_us, 10, 10); > + if (DISPLAY_VER(dev_priv) >= 14) > + ret = _wait_for(!(intel_de_read(dev_priv, XELPDP_PORT_BUF_CTL1(port)) & XELPDP_PORT_BUF_PHY_IDLE), > + timeout_us, 10, 10); > + else > + ret = _wait_for(!(intel_de_read(dev_priv, DDI_BUF_CTL(port)) & DDI_BUF_IS_IDLE), > + timeout_us, 10, 10); > > if (ret) > drm_err(&dev_priv->drm, "Timeout waiting for DDI BUF %c to get active\n", > @@ -313,6 +332,13 @@ static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder, > DDI_PORT_WIDTH(crtc_state->lane_count) | > DDI_BUF_TRANS_SELECT(0); > > + if (DISPLAY_VER(i915) >= 14) { > + if (intel_dp_is_uhbr(crtc_state)) > + intel_dp->DP |= DDI_BUF_PORT_DATA_40BIT; > + else > + intel_dp->DP |= DDI_BUF_PORT_DATA_10BIT; > + } > + > if (IS_ALDERLAKE_P(i915) && intel_phy_is_tc(i915, phy)) { > intel_dp->DP |= ddi_buf_phy_link_rate(crtc_state->port_clock); > if (!intel_tc_port_in_tbt_alt_mode(dig_port)) > @@ -2309,6 +2335,179 @@ static void intel_ddi_mso_configure(const struct intel_crtc_state *crtc_state) > OVERLAP_PIXELS_MASK, dss1); > } > > +static u8 mtl_get_port_width(u8 lane_count) > +{ > + switch (lane_count) { > + case 1: > + return 0; > + case 2: > + return 1; > + case 3: > + return 4; > + case 4: > + return 3; > + default: > + MISSING_CASE(lane_count); > + return 4; > + } > +} > + > +static void > +mtl_ddi_enable_d2d(struct intel_encoder *encoder) > +{ > + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); > + enum port port = encoder->port; > + > + intel_de_rmw(dev_priv, XELPDP_PORT_BUF_CTL1(port), 0, > + XELPDP_PORT_BUF_D2D_LINK_ENABLE); > + > + if (wait_for_us((intel_de_read(dev_priv, XELPDP_PORT_BUF_CTL1(port)) & > + XELPDP_PORT_BUF_D2D_LINK_STATE), 100)) { > + drm_err(&dev_priv->drm, "Timeout waiting for D2D Link enable for PORT_BUF_CTL %c\n", > + port_name(port)); > + } > +} > + > +static void mtl_port_buf_ctl_program(struct intel_encoder *encoder, > + const struct intel_crtc_state *crtc_state) > +{ > + struct drm_i915_private *i915 = to_i915(encoder->base.dev); > + struct intel_digital_port *dig_port = enc_to_dig_port(encoder); > + enum port port = encoder->port; > + u32 val; > + > + val = intel_de_read(i915, XELPDP_PORT_BUF_CTL1(port)); > + val &= ~XELPDP_PORT_WIDTH_MASK; > + val |= XELPDP_PORT_WIDTH(mtl_get_port_width(crtc_state->lane_count)); > + > + val &= ~XELPDP_PORT_BUF_PORT_DATA_WIDTH_MASK; > + if (intel_dp_is_uhbr(crtc_state)) > + val |= XELPDP_PORT_BUF_PORT_DATA_40BIT; > + else > + val |= XELPDP_PORT_BUF_PORT_DATA_10BIT; > + > + if (dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL) > + val |= XELPDP_PORT_REVERSAL; > + > + intel_de_write(i915, XELPDP_PORT_BUF_CTL1(port), val); > +} > + > +static void mtl_port_buf_ctl_io_selection(struct intel_encoder *encoder) > +{ > + struct drm_i915_private *i915 = to_i915(encoder->base.dev); > + struct intel_digital_port *dig_port = enc_to_dig_port(encoder); > + u32 val; > + > + val = intel_tc_port_in_tbt_alt_mode(dig_port) ? > + XELPDP_PORT_BUF_IO_SELECT_TBT : 0; > + intel_de_rmw(i915, XELPDP_PORT_BUF_CTL1(encoder->port), > + XELPDP_PORT_BUF_IO_SELECT_TBT, val); > +} > + > +static void mtl_ddi_pre_enable_dp(struct intel_atomic_state *state, > + struct intel_encoder *encoder, > + const struct intel_crtc_state *crtc_state, > + const struct drm_connector_state *conn_state) > +{ > + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); > + bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); > + > + 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(), > + * before we called down into this function. > + */ > + > + /* 2. PMdemand was already set */ > + > + /* 3. Select Thunderbolt */ > + mtl_port_buf_ctl_io_selection(encoder); > + > + /* 4. Enable Panel Power if PPS is required */ > + intel_pps_on(intel_dp); > + > + /* 5. Enable the port PLL */ > + intel_ddi_enable_clock(encoder, crtc_state); > + > + /* > + * 6.a Configure Transcoder Clock Select to direct the Port clock to the > + * Transcoder. > + */ > + intel_ddi_enable_transcoder_clock(encoder, crtc_state); > + > + /* > + * 6.b If DP v2.0/128b mode - Configure TRANS_DP2_CTL register settings. > + */ > + intel_ddi_config_transcoder_dp2(encoder, crtc_state); > + > + /* > + * 6.c Configure TRANS_DDI_FUNC_CTL DDI Select, DDI Mode Select & MST > + * Transport Select > + */ > + intel_ddi_config_transcoder_func(encoder, crtc_state); > + > + /* > + * 6.e Program CoG/MSO configuration bits in DSS_CTL1 if selected. > + */ > + intel_ddi_mso_configure(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 > + * in the FEC_CONFIGURATION register to 1 before initiating link > + * 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); > + > + /* > + * 6. The rest of the below are substeps under the bspec's "Enable and > + * Train Display Port" step. Note that steps that are specific to > + * MST will be handled by intel_mst_pre_enable_dp() before/after it > + * calls into this function. Also intel_mst_pre_enable_dp() only calls > + * us when active_mst_links==0, so any steps designated for "single > + * stream or multi-stream master transcoder" can just be performed > + * unconditionally here. > + * > + * mtl_ddi_prepare_link_retrain() that is called by > + * intel_dp_start_link_train() will execute steps: 6.d, 6.f, 6.g, 6.h, > + * 6.i and 6.j > + * > + * 6.k Follow DisplayPort specification training sequence (see notes for > + * failure handling) > + * 6.m If DisplayPort multi-stream - Set DP_TP_CTL link training to Idle > + * Pattern, wait for 5 idle patterns (DP_TP_STATUS Min_Idles_Sent) > + * (timeout after 800 us) > + */ > + intel_dp_start_link_train(intel_dp, crtc_state); > + > + /* 6.n Set DP_TP_CTL link training to Normal */ > + if (!is_trans_port_sync_mode(crtc_state)) > + intel_dp_stop_link_train(intel_dp, crtc_state); > + > + /* 6.o Configure and enable FEC if needed */ > + intel_ddi_enable_fec(encoder, crtc_state); > + > + intel_dsc_dp_pps_write(encoder, crtc_state); > +} > + > static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, > struct intel_encoder *encoder, > const struct intel_crtc_state *crtc_state, > @@ -2523,7 +2722,9 @@ static void intel_ddi_pre_enable_dp(struct intel_atomic_state *state, > intel_dp_128b132b_sdp_crc16(enc_to_intel_dp(encoder), > crtc_state); > > - if (DISPLAY_VER(dev_priv) >= 12) > + if (DISPLAY_VER(dev_priv) >= 14) > + mtl_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state); > + else if (DISPLAY_VER(dev_priv) >= 12) > tgl_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state); > else > hsw_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state); > @@ -2604,8 +2805,50 @@ static void intel_ddi_pre_enable(struct intel_atomic_state *state, > } > } > > -static void intel_disable_ddi_buf(struct intel_encoder *encoder, > - const struct intel_crtc_state *crtc_state) > +static void > +mtl_ddi_disable_d2d_link(struct intel_encoder *encoder) > +{ > + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); > + enum port port = encoder->port; > + > + intel_de_rmw(dev_priv, XELPDP_PORT_BUF_CTL1(port), > + XELPDP_PORT_BUF_D2D_LINK_ENABLE, 0); > + > + if (wait_for_us(!(intel_de_read(dev_priv, XELPDP_PORT_BUF_CTL1(port)) & > + XELPDP_PORT_BUF_D2D_LINK_STATE), 100)) > + drm_err(&dev_priv->drm, "Timeout waiting for D2D Link disable for PORT_BUF_CTL %c\n", > + port_name(port)); > +} > + > +static void mtl_disable_ddi_buf(struct intel_encoder *encoder, > + const struct intel_crtc_state *crtc_state) > +{ > + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); > + enum port port = encoder->port; > + u32 val; > + > + /* 3.b Clear DDI_CTL_DE Enable to 0. */ > + val = intel_de_read(dev_priv, DDI_BUF_CTL(port)); > + if (val & DDI_BUF_CTL_ENABLE) { > + val &= ~DDI_BUF_CTL_ENABLE; > + intel_de_write(dev_priv, DDI_BUF_CTL(port), val); > + > + /* 3.c Poll for PORT_BUF_CTL Idle Status == 1, timeout after 100us */ > + mtl_wait_ddi_buf_idle(dev_priv, port); > + } > + > + /* 3.d Disable D2D Link */ > + mtl_ddi_disable_d2d_link(encoder); > + > + /* 3.e Disable DP_TP_CTL */ > + if (intel_crtc_has_dp_encoder(crtc_state)) { > + intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), > + DP_TP_CTL_ENABLE, 0); > + } > +} > + > +static void disable_ddi_buf(struct intel_encoder *encoder, > + const struct intel_crtc_state *crtc_state) > { > struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); > enum port port = encoder->port; > @@ -2630,6 +2873,21 @@ static void intel_disable_ddi_buf(struct intel_encoder *encoder, > intel_wait_ddi_buf_idle(dev_priv, port); > } > > +static void intel_disable_ddi_buf(struct intel_encoder *encoder, > + const struct intel_crtc_state *crtc_state) > +{ > + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); > + > + if (DISPLAY_VER(dev_priv) >= 14) { > + mtl_disable_ddi_buf(encoder, crtc_state); > + > + /* 3.f Disable DP_TP_CTL FEC Enable if it is needed */ > + intel_ddi_disable_fec_state(encoder, crtc_state); > + } else { > + disable_ddi_buf(encoder, crtc_state); > + } > +} > + > static void intel_ddi_post_disable_dp(struct intel_atomic_state *state, > struct intel_encoder *encoder, > const struct intel_crtc_state *old_crtc_state, > @@ -2638,6 +2896,7 @@ static void intel_ddi_post_disable_dp(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 intel_dp *intel_dp = &dig_port->dp; > + intel_wakeref_t wakeref; > bool is_mst = intel_crtc_has_type(old_crtc_state, > INTEL_OUTPUT_DP_MST); > > @@ -2677,12 +2936,19 @@ 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_tc_port_in_tbt_alt_mode(dig_port)) > + wakeref = fetch_and_zero(&dig_port->ddi_io_wakeref); > + > + if (wakeref) > intel_display_power_put(dev_priv, > dig_port->ddi_io_power_domain, > - fetch_and_zero(&dig_port->ddi_io_wakeref)); > + wakeref); > > intel_ddi_disable_clock(encoder); > + > + /* De-select Thunderbolt */ > + if (DISPLAY_VER(dev_priv) >= 14) > + intel_de_rmw(dev_priv, XELPDP_PORT_BUF_CTL1(encoder->port), > + XELPDP_PORT_BUF_IO_SELECT_TBT, 0); > } > > static void intel_ddi_post_disable_hdmi(struct intel_atomic_state *state, > @@ -2693,6 +2959,7 @@ static void intel_ddi_post_disable_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 intel_hdmi *intel_hdmi = &dig_port->hdmi; > + intel_wakeref_t wakeref; > > dig_port->set_infoframes(encoder, false, > old_crtc_state, old_conn_state); > @@ -2705,9 +2972,11 @@ static void intel_ddi_post_disable_hdmi(struct intel_atomic_state *state, > if (DISPLAY_VER(dev_priv) >= 12) > intel_ddi_disable_transcoder_clock(old_crtc_state); > > - intel_display_power_put(dev_priv, > - dig_port->ddi_io_power_domain, > - fetch_and_zero(&dig_port->ddi_io_wakeref)); > + wakeref = fetch_and_zero(&dig_port->ddi_io_wakeref); > + if (wakeref) > + intel_display_power_put(dev_priv, > + dig_port->ddi_io_power_domain, > + wakeref); > > intel_ddi_disable_clock(encoder); > > @@ -3104,6 +3373,53 @@ static void adlp_tbt_to_dp_alt_switch_wa(struct intel_encoder *encoder) > intel_dkl_phy_rmw(i915, DKL_PCS_DW5(tc_port, ln), DKL_PCS_DW5_CORE_SOFTRESET, 0); > } > > +static void mtl_ddi_prepare_link_retrain(struct intel_dp *intel_dp, > + const struct intel_crtc_state *crtc_state) > +{ > + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); > + struct intel_encoder *encoder = &dig_port->base; > + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); > + enum port port = encoder->port; > + u32 dp_tp_ctl; > + > + /* > + * TODO: To train with only a different voltage swing entry is not > + * necessary disable and enable port > + */ > + dp_tp_ctl = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state)); > + if (dp_tp_ctl & DP_TP_CTL_ENABLE) > + mtl_disable_ddi_buf(encoder, crtc_state); > + > + /* 6.d Configure and enable DP_TP_CTL with link training pattern 1 selected */ > + dp_tp_ctl = DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_PAT1; > + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) { > + dp_tp_ctl |= DP_TP_CTL_MODE_MST; > + } else { > + dp_tp_ctl |= DP_TP_CTL_MODE_SST; > + if (drm_dp_enhanced_frame_cap(intel_dp->dpcd)) > + dp_tp_ctl |= DP_TP_CTL_ENHANCED_FRAME_ENABLE; > + } > + intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), dp_tp_ctl); > + intel_de_posting_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state)); > + > + /* 6.f Enable D2D Link */ > + mtl_ddi_enable_d2d(encoder); > + > + /* 6.g Configure voltage swing and related IO settings */ > + encoder->set_signal_levels(encoder, crtc_state); > + > + /* 6.h Configure PORT_BUF_CTL1 */ > + mtl_port_buf_ctl_program(encoder, crtc_state); > + > + /* 6.i Configure and enable DDI_CTL_DE to start sending valid data to port slice */ > + intel_dp->DP |= DDI_BUF_CTL_ENABLE; > + intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP); > + intel_de_posting_read(dev_priv, DDI_BUF_CTL(port)); > + > + /* 6.j Poll for PORT_BUF_CTL Idle Status == 0, timeout after 100 us */ > + intel_wait_ddi_buf_active(dev_priv, port); > +} > + > static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp, > const struct intel_crtc_state *crtc_state) > { > @@ -3871,6 +4187,7 @@ 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 *i915 = to_i915(dig_port->base.base.dev); > struct intel_connector *connector; > enum port port = dig_port->base.port; > > @@ -3879,7 +4196,10 @@ intel_ddi_init_dp_connector(struct intel_digital_port *dig_port) > return NULL; > > dig_port->dp.output_reg = DDI_BUF_CTL(port); > - dig_port->dp.prepare_link_retrain = intel_ddi_prepare_link_retrain; > + if (DISPLAY_VER(i915) >= 14) > + dig_port->dp.prepare_link_retrain = mtl_ddi_prepare_link_retrain; > + else > + dig_port->dp.prepare_link_retrain = intel_ddi_prepare_link_retrain; > dig_port->dp.set_link_train = intel_ddi_set_link_train; > dig_port->dp.set_idle_link_train = intel_ddi_set_idle_link_train; > > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index 531c0ea68c05..df29ab301326 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -5655,11 +5655,16 @@ enum skl_power_gate { > /* DDI Buffer Control */ > #define _DDI_BUF_CTL_A 0x64000 > #define _DDI_BUF_CTL_B 0x64100 > +/* Known as DDI_CTL_DE in MTL+ */ > #define DDI_BUF_CTL(port) _MMIO_PORT(port, _DDI_BUF_CTL_A, _DDI_BUF_CTL_B) > #define DDI_BUF_CTL_ENABLE (1 << 31) > #define DDI_BUF_TRANS_SELECT(n) ((n) << 24) > #define DDI_BUF_EMP_MASK (0xf << 24) > #define DDI_BUF_PHY_LINK_RATE(r) ((r) << 20) > +#define DDI_BUF_PORT_DATA_MASK REG_GENMASK(19, 18) > +#define DDI_BUF_PORT_DATA_10BIT REG_FIELD_PREP(DDI_BUF_PORT_DATA_MASK, 0) > +#define DDI_BUF_PORT_DATA_20BIT REG_FIELD_PREP(DDI_BUF_PORT_DATA_MASK, 1) > +#define DDI_BUF_PORT_DATA_40BIT REG_FIELD_PREP(DDI_BUF_PORT_DATA_MASK, 2) > #define DDI_BUF_PORT_REVERSAL (1 << 16) > #define DDI_BUF_IS_IDLE (1 << 7) > #define DDI_BUF_CTL_TC_PHY_OWNERSHIP REG_BIT(6) > -- > 2.34.1 >