diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_ddi.c')
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_ddi.c | 216 |
1 files changed, 60 insertions, 156 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index cab505277595..9e6fa59eabba 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -25,24 +25,27 @@ * */ +#include <linux/string_helpers.h> + +#include <drm/display/drm_scdc_helper.h> #include <drm/drm_privacy_screen_consumer.h> -#include <drm/drm_scdc_helper.h> #include "i915_drv.h" #include "intel_audio.h" #include "intel_backlight.h" #include "intel_combo_phy.h" +#include "intel_combo_phy_regs.h" #include "intel_connector.h" #include "intel_crtc.h" #include "intel_ddi.h" #include "intel_ddi_buf_trans.h" #include "intel_de.h" +#include "intel_display_power.h" #include "intel_display_types.h" #include "intel_dp.h" #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" @@ -56,6 +59,7 @@ #include "intel_snps_phy.h" #include "intel_sprite.h" #include "intel_tc.h" +#include "intel_tc_phy_regs.h" #include "intel_vdsc.h" #include "intel_vrr.h" #include "skl_scaler.h" @@ -2150,7 +2154,7 @@ static void intel_dp_sink_set_msa_timing_par_ignore_state(struct intel_dp *intel enable ? DP_MSA_TIMING_PAR_IGNORE_EN : 0) <= 0) drm_dbg_kms(&i915->drm, "Failed to %s MSA_TIMING_PAR_IGNORE in the sink\n", - enabledisable(enable)); + str_enable_disable(enable)); } static void intel_dp_sink_set_fec_ready(struct intel_dp *intel_dp, @@ -2287,116 +2291,6 @@ static void intel_ddi_mso_configure(const struct intel_crtc_state *crtc_state) OVERLAP_PIXELS_MASK, dss1); } -static void dg2_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); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - struct intel_digital_port *dig_port = enc_to_dig_port(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. Enable Panel Power if PPS is required */ - intel_pps_on(intel_dp); - - /* - * 3. Enable the port PLL. - */ - intel_ddi_enable_clock(encoder, crtc_state); - - /* 4. Enable IO power */ - 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); - - /* - * 5. 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. - */ - - /* - * 5.a Configure Transcoder Clock Select to direct the Port clock to the - * Transcoder. - */ - intel_ddi_enable_pipe_clock(encoder, crtc_state); - - /* 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 - * Transport Select - */ - intel_ddi_config_transcoder_func(encoder, crtc_state); - - /* - * 5.d Configure & enable DP_TP_CTL with link training pattern 1 - * selected - * - * This will be handled by the intel_dp_start_link_train() farther - * down this function. - */ - - /* 5.e Configure voltage swing and related IO settings */ - 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 - * 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); - - /* - * 5.h Follow DisplayPort specification training sequence (see notes for - * failure handling) - * 5.i 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); - - /* 5.j 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); - - /* 5.k Configure and enable FEC if needed */ - intel_ddi_enable_fec(encoder, crtc_state); - - intel_dsc_dp_pps_write(encoder, crtc_state); - - intel_dsc_enable(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, @@ -2470,6 +2364,9 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, */ intel_ddi_enable_pipe_clock(encoder, crtc_state); + if (HAS_DP20(dev_priv)) + intel_ddi_config_transcoder_dp2(encoder, crtc_state); + /* * 7.b Configure TRANS_DDI_FUNC_CTL DDI Select, DDI Mode Select & MST * Transport Select @@ -2530,9 +2427,6 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, intel_ddi_enable_fec(encoder, crtc_state); intel_dsc_dp_pps_write(encoder, crtc_state); - - if (!crtc_state->bigjoiner) - intel_dsc_enable(crtc_state); } static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, @@ -2598,9 +2492,6 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, intel_ddi_enable_pipe_clock(encoder, crtc_state); intel_dsc_dp_pps_write(encoder, crtc_state); - - if (!crtc_state->bigjoiner) - intel_dsc_enable(crtc_state); } static void intel_ddi_pre_enable_dp(struct intel_atomic_state *state, @@ -2610,9 +2501,7 @@ static void intel_ddi_pre_enable_dp(struct intel_atomic_state *state, { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - if (IS_DG2(dev_priv)) - dg2_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state); - else if (DISPLAY_VER(dev_priv) >= 12) + 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); @@ -2620,11 +2509,8 @@ static void intel_ddi_pre_enable_dp(struct intel_atomic_state *state, /* MST will call a setting of MSA after an allocating of Virtual Channel * from MST encoder pre_enable callback. */ - if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) { + if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) intel_ddi_set_dp_msa(crtc_state, conn_state); - - intel_dp_set_m_n(crtc_state, M1_N1); - } } static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state, @@ -2819,6 +2705,7 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state, struct intel_digital_port *dig_port = enc_to_dig_port(encoder); enum phy phy = intel_port_to_phy(dev_priv, encoder->port); bool is_tc_port = intel_phy_is_tc(dev_priv, phy); + struct intel_crtc *slave_crtc; if (!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST)) { intel_crtc_vblank_off(old_crtc_state); @@ -2837,9 +2724,8 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state, ilk_pfit_disable(old_crtc_state); } - if (old_crtc_state->bigjoiner_linked_crtc) { - struct intel_crtc *slave_crtc = - old_crtc_state->bigjoiner_linked_crtc; + for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, slave_crtc, + intel_crtc_bigjoiner_slave_pipes(old_crtc_state)) { const struct intel_crtc_state *old_slave_crtc_state = intel_atomic_get_old_crtc_state(state, slave_crtc); @@ -2934,10 +2820,7 @@ static void intel_enable_ddi_dp(struct intel_atomic_state *state, if (!dig_port->lspcon.active || dig_port->dp.has_hdmi_sink) intel_dp_set_infoframes(encoder, true, crtc_state, conn_state); - intel_drrs_enable(intel_dp, crtc_state); - - if (crtc_state->has_audio) - intel_audio_codec_enable(encoder, crtc_state, conn_state); + intel_audio_codec_enable(encoder, crtc_state, conn_state); trans_port_sync_stop_link_train(state, encoder, crtc_state); } @@ -3031,8 +2914,7 @@ static void intel_enable_ddi_hdmi(struct intel_atomic_state *state, intel_de_write(dev_priv, DDI_BUF_CTL(port), dig_port->saved_port_bits | DDI_BUF_CTL_ENABLE); - if (crtc_state->has_audio) - intel_audio_codec_enable(encoder, crtc_state, conn_state); + intel_audio_codec_enable(encoder, crtc_state, conn_state); } static void intel_enable_ddi(struct intel_atomic_state *state, @@ -3042,7 +2924,7 @@ static void intel_enable_ddi(struct intel_atomic_state *state, { drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder); - if (!crtc_state->bigjoiner_slave) + if (!intel_crtc_is_bigjoiner_slave(crtc_state)) intel_ddi_enable_transcoder_func(encoder, crtc_state); intel_vrr_enable(encoder, crtc_state); @@ -3073,11 +2955,8 @@ static void intel_disable_ddi_dp(struct intel_atomic_state *state, intel_dp->link_trained = false; - if (old_crtc_state->has_audio) - intel_audio_codec_disable(encoder, - old_crtc_state, old_conn_state); + intel_audio_codec_disable(encoder, old_crtc_state, old_conn_state); - intel_drrs_disable(intel_dp, old_crtc_state); intel_psr_disable(intel_dp, old_crtc_state); intel_edp_backlight_off(old_conn_state); /* Disable the decompression in DP Sink */ @@ -3096,9 +2975,7 @@ static void intel_disable_ddi_hdmi(struct intel_atomic_state *state, struct drm_i915_private *i915 = to_i915(encoder->base.dev); struct drm_connector *connector = old_conn_state->connector; - if (old_crtc_state->has_audio) - intel_audio_codec_disable(encoder, - old_crtc_state, old_conn_state); + intel_audio_codec_disable(encoder, old_crtc_state, old_conn_state); if (!intel_hdmi_handle_sink_scrambling(encoder, connector, false, false)) @@ -3127,12 +3004,9 @@ static void intel_ddi_update_pipe_dp(struct intel_atomic_state *state, const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - intel_ddi_set_dp_msa(crtc_state, conn_state); intel_dp_set_infoframes(encoder, true, crtc_state, conn_state); - intel_drrs_update(intel_dp, crtc_state); intel_backlight_update(state, encoder, crtc_state, conn_state); drm_connector_update_privacy_screen(conn_state); @@ -3157,6 +3031,7 @@ intel_ddi_update_prepare(struct intel_atomic_state *state, struct intel_encoder *encoder, struct intel_crtc *crtc) { + struct drm_i915_private *i915 = to_i915(state->base.dev); struct intel_crtc_state *crtc_state = crtc ? intel_atomic_get_new_crtc_state(state, crtc) : NULL; int required_lanes = crtc_state ? crtc_state->lane_count : 1; @@ -3166,11 +3041,12 @@ intel_ddi_update_prepare(struct intel_atomic_state *state, intel_tc_port_get_link(enc_to_dig_port(encoder), required_lanes); if (crtc_state && crtc_state->hw.active) { - struct intel_crtc *slave_crtc = crtc_state->bigjoiner_linked_crtc; + struct intel_crtc *slave_crtc; intel_update_active_dpll(state, crtc, encoder); - if (slave_crtc) + for_each_intel_crtc_in_pipe_mask(&i915->drm, slave_crtc, + intel_crtc_bigjoiner_slave_pipes(crtc_state)) intel_update_active_dpll(state, slave_crtc, encoder); } } @@ -3215,10 +3091,23 @@ intel_ddi_pre_pll_enable(struct intel_atomic_state *state, crtc_state->lane_lat_optim_mask); } +static void adlp_tbt_to_dp_alt_switch_wa(struct intel_encoder *encoder) +{ + struct drm_i915_private *i915 = to_i915(encoder->base.dev); + enum tc_port tc_port = intel_port_to_tc(i915, encoder->port); + int ln; + + for (ln = 0; ln < 2; ln++) { + intel_de_write(i915, HIP_INDEX_REG(tc_port), HIP_INDEX_VAL(tc_port, ln)); + intel_de_rmw(i915, DKL_PCS_DW5(tc_port), DKL_PCS_DW5_CORE_SOFTRESET, 0); + } +} + static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { - struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; + 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, ddi_buf_ctl; @@ -3254,6 +3143,10 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp, 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)); + if (IS_ALDERLAKE_P(dev_priv) && + (intel_tc_port_in_dp_alt_mode(dig_port) || intel_tc_port_in_legacy_mode(dig_port))) + adlp_tbt_to_dp_alt_switch_wa(encoder); + 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)); @@ -3471,7 +3364,11 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder, pipe_config->output_types |= BIT(INTEL_OUTPUT_DP); pipe_config->lane_count = ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1; - intel_dp_get_m_n(crtc, pipe_config); + + intel_cpu_transcoder_get_m1_n1(crtc, cpu_transcoder, + &pipe_config->dp_m_n); + intel_cpu_transcoder_get_m2_n2(crtc, cpu_transcoder, + &pipe_config->dp_m2_n2); if (DISPLAY_VER(dev_priv) >= 11) { i915_reg_t dp_tp_ctl = dp_tp_ctl_reg(encoder, pipe_config); @@ -3508,7 +3405,8 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder, pipe_config->mst_master_transcoder = REG_FIELD_GET(TRANS_DDI_MST_TRANSPORT_SELECT_MASK, temp); - intel_dp_get_m_n(crtc, pipe_config); + intel_cpu_transcoder_get_m1_n1(crtc, cpu_transcoder, + &pipe_config->dp_m_n); pipe_config->infoframes.enable |= intel_hdmi_infoframes_enabled(encoder, pipe_config); @@ -3797,8 +3695,8 @@ static bool m_n_equal(const struct intel_link_m_n *m_n_1, const struct intel_link_m_n *m_n_2) { return m_n_1->tu == m_n_2->tu && - m_n_1->gmch_m == m_n_2->gmch_m && - m_n_1->gmch_n == m_n_2->gmch_n && + m_n_1->data_m == m_n_2->data_m && + m_n_1->data_n == m_n_2->data_n && m_n_1->link_m == m_n_2->link_m && m_n_1->link_n == m_n_2->link_n; } @@ -4400,6 +4298,13 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) return; } + if (intel_phy_is_snps(dev_priv, phy) && + dev_priv->snps_phy_failed_calibration & BIT(phy)) { + drm_dbg_kms(&dev_priv->drm, + "SNPS PHY %c failed to calibrate, proceeding anyway\n", + phy_name(phy)); + } + dig_port = kzalloc(sizeof(*dig_port), GFP_KERNEL); if (!dig_port) return; @@ -4460,7 +4365,7 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) encoder->get_power_domains = intel_ddi_get_power_domains; encoder->type = INTEL_OUTPUT_DDI; - encoder->power_domain = intel_port_to_power_domain(port); + encoder->power_domain = intel_display_power_ddi_lanes_domain(dev_priv, port); encoder->port = port; encoder->cloneable = 0; encoder->pipe_mask = ~0; @@ -4588,8 +4493,7 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) } drm_WARN_ON(&dev_priv->drm, port > PORT_I); - dig_port->ddi_io_power_domain = POWER_DOMAIN_PORT_DDI_A_IO + - port - PORT_A; + dig_port->ddi_io_power_domain = intel_display_power_ddi_io_domain(dev_priv, port); if (init_dp) { if (!intel_ddi_init_dp_connector(dig_port)) |