1379bc100SJani Nikula /* 2379bc100SJani Nikula * Copyright © 2012 Intel Corporation 3379bc100SJani Nikula * 4379bc100SJani Nikula * Permission is hereby granted, free of charge, to any person obtaining a 5379bc100SJani Nikula * copy of this software and associated documentation files (the "Software"), 6379bc100SJani Nikula * to deal in the Software without restriction, including without limitation 7379bc100SJani Nikula * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8379bc100SJani Nikula * and/or sell copies of the Software, and to permit persons to whom the 9379bc100SJani Nikula * Software is furnished to do so, subject to the following conditions: 10379bc100SJani Nikula * 11379bc100SJani Nikula * The above copyright notice and this permission notice (including the next 12379bc100SJani Nikula * paragraph) shall be included in all copies or substantial portions of the 13379bc100SJani Nikula * Software. 14379bc100SJani Nikula * 15379bc100SJani Nikula * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16379bc100SJani Nikula * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17379bc100SJani Nikula * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18379bc100SJani Nikula * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19379bc100SJani Nikula * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20379bc100SJani Nikula * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21379bc100SJani Nikula * IN THE SOFTWARE. 22379bc100SJani Nikula * 23379bc100SJani Nikula * Authors: 24379bc100SJani Nikula * Eugeni Dodonov <eugeni.dodonov@intel.com> 25379bc100SJani Nikula * 26379bc100SJani Nikula */ 27379bc100SJani Nikula 28707c3a7dSLucas De Marchi #include <linux/string_helpers.h> 29707c3a7dSLucas De Marchi 30644edf52SThomas Zimmermann #include <drm/display/drm_scdc_helper.h> 316306d8dbSHans de Goede #include <drm/drm_privacy_screen_consumer.h> 32379bc100SJani Nikula 33379bc100SJani Nikula #include "i915_drv.h" 34801543b2SJani Nikula #include "i915_reg.h" 35379bc100SJani Nikula #include "intel_audio.h" 36b43edc50SJani Nikula #include "intel_audio_regs.h" 376cc42fbeSJani Nikula #include "intel_backlight.h" 38379bc100SJani Nikula #include "intel_combo_phy.h" 39d0864ee4SMatt Roper #include "intel_combo_phy_regs.h" 40379bc100SJani Nikula #include "intel_connector.h" 417c53e628SJani Nikula #include "intel_crtc.h" 4251390cc0SRadhakrishna Sripada #include "intel_cx0_phy.h" 4323ef6194SJosé Roberto de Souza #include "intel_cx0_phy_regs.h" 44379bc100SJani Nikula #include "intel_ddi.h" 4599092a97SDave Airlie #include "intel_ddi_buf_trans.h" 467785ae0bSVille Syrjälä #include "intel_de.h" 47979e1b32SImre Deak #include "intel_display_power.h" 481d455f8dSJani Nikula #include "intel_display_types.h" 4989cb0ba4SImre Deak #include "intel_dkl_phy.h" 50d69813c7SImre Deak #include "intel_dkl_phy_regs.h" 51379bc100SJani Nikula #include "intel_dp.h" 52bb45217fSVille Syrjälä #include "intel_dp_aux.h" 53379bc100SJani Nikula #include "intel_dp_link_training.h" 54dcb38f79SDave Airlie #include "intel_dp_mst.h" 55379bc100SJani Nikula #include "intel_dpio_phy.h" 56379bc100SJani Nikula #include "intel_dsi.h" 57dcb38f79SDave Airlie #include "intel_fdi.h" 58379bc100SJani Nikula #include "intel_fifo_underrun.h" 59379bc100SJani Nikula #include "intel_gmbus.h" 60379bc100SJani Nikula #include "intel_hdcp.h" 61379bc100SJani Nikula #include "intel_hdmi.h" 62379bc100SJani Nikula #include "intel_hotplug.h" 6303120fefSJani Nikula #include "intel_hti.h" 64379bc100SJani Nikula #include "intel_lspcon.h" 65589ebefdSImre Deak #include "intel_mg_phy_regs.h" 6660ded7ccSImre Deak #include "intel_modeset_lock.h" 67abad6805SJani Nikula #include "intel_pps.h" 68379bc100SJani Nikula #include "intel_psr.h" 690c82118bSJani Nikula #include "intel_quirks.h" 70865b73eaSMatt Roper #include "intel_snps_phy.h" 71bc85328fSImre Deak #include "intel_tc.h" 72379bc100SJani Nikula #include "intel_vdsc.h" 73c3f05948SJani Nikula #include "intel_vdsc_regs.h" 74714b1cdbSDave Airlie #include "skl_scaler.h" 7546d12f91SDave Airlie #include "skl_universal_plane.h" 76379bc100SJani Nikula 77379bc100SJani Nikula static const u8 index_to_dp_signal_levels[] = { 78379bc100SJani Nikula [0] = DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0, 79379bc100SJani Nikula [1] = DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1, 80379bc100SJani Nikula [2] = DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2, 81379bc100SJani Nikula [3] = DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_3, 82379bc100SJani Nikula [4] = DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0, 83379bc100SJani Nikula [5] = DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1, 84379bc100SJani Nikula [6] = DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2, 85379bc100SJani Nikula [7] = DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0, 86379bc100SJani Nikula [8] = DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1, 87379bc100SJani Nikula [9] = DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0, 88379bc100SJani Nikula }; 89379bc100SJani Nikula 90a621860aSVille Syrjälä static int intel_ddi_hdmi_level(struct intel_encoder *encoder, 913e022c1fSVille Syrjälä const struct intel_ddi_buf_trans *trans) 92379bc100SJani Nikula { 933e022c1fSVille Syrjälä int level; 94379bc100SJani Nikula 9502107ef1SVille Syrjälä level = intel_bios_hdmi_level_shift(encoder->devdata); 960aed3bdeSJani Nikula if (level < 0) 973e022c1fSVille Syrjälä level = trans->hdmi_default_entry; 98379bc100SJani Nikula 99379bc100SJani Nikula return level; 100379bc100SJani Nikula } 101379bc100SJani Nikula 1025bafd85dSVille Syrjälä static bool has_buf_trans_select(struct drm_i915_private *i915) 1035bafd85dSVille Syrjälä { 1045bafd85dSVille Syrjälä return DISPLAY_VER(i915) < 10 && !IS_BROXTON(i915); 1055bafd85dSVille Syrjälä } 1065bafd85dSVille Syrjälä 107f820693bSVille Syrjälä static bool has_iboost(struct drm_i915_private *i915) 108f820693bSVille Syrjälä { 109f820693bSVille Syrjälä return DISPLAY_VER(i915) == 9 && !IS_BROXTON(i915); 110f820693bSVille Syrjälä } 111f820693bSVille Syrjälä 112379bc100SJani Nikula /* 113379bc100SJani Nikula * Starting with Haswell, DDI port buffers must be programmed with correct 114379bc100SJani Nikula * values in advance. This function programs the correct values for 115379bc100SJani Nikula * DP/eDP/FDI use cases. 116379bc100SJani Nikula */ 117266152aeSVille Syrjälä void hsw_prepare_dp_ddi_buffers(struct intel_encoder *encoder, 118379bc100SJani Nikula const struct intel_crtc_state *crtc_state) 119379bc100SJani Nikula { 120379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 121379bc100SJani Nikula u32 iboost_bit = 0; 122379bc100SJani Nikula int i, n_entries; 123379bc100SJani Nikula enum port port = encoder->port; 124e505d764SVille Syrjälä const struct intel_ddi_buf_trans *trans; 125379bc100SJani Nikula 126e505d764SVille Syrjälä trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); 127e505d764SVille Syrjälä if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) 128d6b10b1aSVille Syrjälä return; 129379bc100SJani Nikula 130379bc100SJani Nikula /* If we're boosting the current, set bit 31 of trans1 */ 131f820693bSVille Syrjälä if (has_iboost(dev_priv) && 13202107ef1SVille Syrjälä intel_bios_dp_boost_level(encoder->devdata)) 133379bc100SJani Nikula iboost_bit = DDI_BUF_BALANCE_LEG_ENABLE; 134379bc100SJani Nikula 135379bc100SJani Nikula for (i = 0; i < n_entries; i++) { 136f7960e7fSJani Nikula intel_de_write(dev_priv, DDI_BUF_TRANS_LO(port, i), 137e505d764SVille Syrjälä trans->entries[i].hsw.trans1 | iboost_bit); 138f7960e7fSJani Nikula intel_de_write(dev_priv, DDI_BUF_TRANS_HI(port, i), 139e505d764SVille Syrjälä trans->entries[i].hsw.trans2); 140379bc100SJani Nikula } 141379bc100SJani Nikula } 142379bc100SJani Nikula 143379bc100SJani Nikula /* 144379bc100SJani Nikula * Starting with Haswell, DDI port buffers must be programmed with correct 145379bc100SJani Nikula * values in advance. This function programs the correct values for 146379bc100SJani Nikula * HDMI/DVI use cases. 147379bc100SJani Nikula */ 148266152aeSVille Syrjälä static void hsw_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder, 149e722ab8bSVille Syrjälä const struct intel_crtc_state *crtc_state) 150379bc100SJani Nikula { 151379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 152d0920a45SVille Syrjälä int level = intel_ddi_level(encoder, crtc_state, 0); 153379bc100SJani Nikula u32 iboost_bit = 0; 154379bc100SJani Nikula int n_entries; 155379bc100SJani Nikula enum port port = encoder->port; 156e505d764SVille Syrjälä const struct intel_ddi_buf_trans *trans; 157379bc100SJani Nikula 158e505d764SVille Syrjälä trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); 159e505d764SVille Syrjälä if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) 160379bc100SJani Nikula return; 161379bc100SJani Nikula 162379bc100SJani Nikula /* If we're boosting the current, set bit 31 of trans1 */ 163f820693bSVille Syrjälä if (has_iboost(dev_priv) && 16402107ef1SVille Syrjälä intel_bios_hdmi_boost_level(encoder->devdata)) 165379bc100SJani Nikula iboost_bit = DDI_BUF_BALANCE_LEG_ENABLE; 166379bc100SJani Nikula 167379bc100SJani Nikula /* Entry 9 is for HDMI: */ 168f7960e7fSJani Nikula intel_de_write(dev_priv, DDI_BUF_TRANS_LO(port, 9), 169e505d764SVille Syrjälä trans->entries[level].hsw.trans1 | iboost_bit); 170f7960e7fSJani Nikula intel_de_write(dev_priv, DDI_BUF_TRANS_HI(port, 9), 171e505d764SVille Syrjälä trans->entries[level].hsw.trans2); 172379bc100SJani Nikula } 173379bc100SJani Nikula 17423ef6194SJosé Roberto de Souza static void mtl_wait_ddi_buf_idle(struct drm_i915_private *i915, enum port port) 17523ef6194SJosé Roberto de Souza { 17623ef6194SJosé Roberto de Souza int ret; 17723ef6194SJosé Roberto de Souza 17823ef6194SJosé Roberto de Souza /* FIXME: find out why Bspec's 100us timeout is too short */ 17923ef6194SJosé Roberto de Souza ret = wait_for_us((intel_de_read(i915, XELPDP_PORT_BUF_CTL1(port)) & 18023ef6194SJosé Roberto de Souza XELPDP_PORT_BUF_PHY_IDLE), 10000); 18123ef6194SJosé Roberto de Souza if (ret) 18223ef6194SJosé Roberto de Souza drm_err(&i915->drm, "Timeout waiting for DDI BUF %c to get idle\n", 18323ef6194SJosé Roberto de Souza port_name(port)); 18423ef6194SJosé Roberto de Souza } 18523ef6194SJosé Roberto de Souza 186dcb38f79SDave Airlie void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv, 187379bc100SJani Nikula enum port port) 188379bc100SJani Nikula { 1895a2ad99bSManasi Navare if (IS_BROXTON(dev_priv)) { 1905a2ad99bSManasi Navare udelay(16); 191379bc100SJani Nikula return; 192379bc100SJani Nikula } 1935a2ad99bSManasi Navare 1945a2ad99bSManasi Navare if (wait_for_us((intel_de_read(dev_priv, DDI_BUF_CTL(port)) & 1955a2ad99bSManasi Navare DDI_BUF_IS_IDLE), 8)) 1965a2ad99bSManasi Navare drm_err(&dev_priv->drm, "Timeout waiting for DDI BUF %c to get idle\n", 19747bdb1caSJani Nikula port_name(port)); 198379bc100SJani Nikula } 199379bc100SJani Nikula 200e828da30SManasi Navare static void intel_wait_ddi_buf_active(struct drm_i915_private *dev_priv, 201e828da30SManasi Navare enum port port) 202e828da30SManasi Navare { 2035add4575SAnkit Nautiyal enum phy phy = intel_port_to_phy(dev_priv, port); 2045add4575SAnkit Nautiyal int timeout_us; 205f82f2563SMatt Roper int ret; 206f82f2563SMatt Roper 207e828da30SManasi Navare /* Wait > 518 usecs for DDI_BUF_CTL to be non idle */ 208ad314fecSVille Syrjälä if (DISPLAY_VER(dev_priv) < 10) { 209e828da30SManasi Navare usleep_range(518, 1000); 210e828da30SManasi Navare return; 211e828da30SManasi Navare } 212e828da30SManasi Navare 21323ef6194SJosé Roberto de Souza if (DISPLAY_VER(dev_priv) >= 14) { 21423ef6194SJosé Roberto de Souza timeout_us = 10000; 21523ef6194SJosé Roberto de Souza } else if (IS_DG2(dev_priv)) { 2165add4575SAnkit Nautiyal timeout_us = 1200; 2175add4575SAnkit Nautiyal } else if (DISPLAY_VER(dev_priv) >= 12) { 2185add4575SAnkit Nautiyal if (intel_phy_is_tc(dev_priv, phy)) 2195add4575SAnkit Nautiyal timeout_us = 3000; 2205add4575SAnkit Nautiyal else 2215add4575SAnkit Nautiyal timeout_us = 1000; 2225add4575SAnkit Nautiyal } else { 2235add4575SAnkit Nautiyal timeout_us = 500; 2245add4575SAnkit Nautiyal } 2255add4575SAnkit Nautiyal 22623ef6194SJosé Roberto de Souza if (DISPLAY_VER(dev_priv) >= 14) 22723ef6194SJosé Roberto de Souza ret = _wait_for(!(intel_de_read(dev_priv, XELPDP_PORT_BUF_CTL1(port)) & XELPDP_PORT_BUF_PHY_IDLE), 22823ef6194SJosé Roberto de Souza timeout_us, 10, 10); 22923ef6194SJosé Roberto de Souza else 23023ef6194SJosé Roberto de Souza ret = _wait_for(!(intel_de_read(dev_priv, DDI_BUF_CTL(port)) & DDI_BUF_IS_IDLE), 23123ef6194SJosé Roberto de Souza timeout_us, 10, 10); 232f82f2563SMatt Roper 233f82f2563SMatt Roper if (ret) 234e828da30SManasi Navare drm_err(&dev_priv->drm, "Timeout waiting for DDI BUF %c to get active\n", 235e828da30SManasi Navare port_name(port)); 236e828da30SManasi Navare } 237e828da30SManasi Navare 238ad952982SVille Syrjälä static u32 hsw_pll_to_ddi_pll_sel(const struct intel_shared_dpll *pll) 239379bc100SJani Nikula { 240379bc100SJani Nikula switch (pll->info->id) { 241379bc100SJani Nikula case DPLL_ID_WRPLL1: 242379bc100SJani Nikula return PORT_CLK_SEL_WRPLL1; 243379bc100SJani Nikula case DPLL_ID_WRPLL2: 244379bc100SJani Nikula return PORT_CLK_SEL_WRPLL2; 245379bc100SJani Nikula case DPLL_ID_SPLL: 246379bc100SJani Nikula return PORT_CLK_SEL_SPLL; 247379bc100SJani Nikula case DPLL_ID_LCPLL_810: 248379bc100SJani Nikula return PORT_CLK_SEL_LCPLL_810; 249379bc100SJani Nikula case DPLL_ID_LCPLL_1350: 250379bc100SJani Nikula return PORT_CLK_SEL_LCPLL_1350; 251379bc100SJani Nikula case DPLL_ID_LCPLL_2700: 252379bc100SJani Nikula return PORT_CLK_SEL_LCPLL_2700; 253379bc100SJani Nikula default: 254379bc100SJani Nikula MISSING_CASE(pll->info->id); 255379bc100SJani Nikula return PORT_CLK_SEL_NONE; 256379bc100SJani Nikula } 257379bc100SJani Nikula } 258379bc100SJani Nikula 259379bc100SJani Nikula static u32 icl_pll_to_ddi_clk_sel(struct intel_encoder *encoder, 260379bc100SJani Nikula const struct intel_crtc_state *crtc_state) 261379bc100SJani Nikula { 262379bc100SJani Nikula const struct intel_shared_dpll *pll = crtc_state->shared_dpll; 263379bc100SJani Nikula int clock = crtc_state->port_clock; 264379bc100SJani Nikula const enum intel_dpll_id id = pll->info->id; 265379bc100SJani Nikula 266379bc100SJani Nikula switch (id) { 267379bc100SJani Nikula default: 268379bc100SJani Nikula /* 269379bc100SJani Nikula * DPLL_ID_ICL_DPLL0 and DPLL_ID_ICL_DPLL1 should not be used 270379bc100SJani Nikula * here, so do warn if this get passed in 271379bc100SJani Nikula */ 272379bc100SJani Nikula MISSING_CASE(id); 273379bc100SJani Nikula return DDI_CLK_SEL_NONE; 274379bc100SJani Nikula case DPLL_ID_ICL_TBTPLL: 275379bc100SJani Nikula switch (clock) { 276379bc100SJani Nikula case 162000: 277379bc100SJani Nikula return DDI_CLK_SEL_TBT_162; 278379bc100SJani Nikula case 270000: 279379bc100SJani Nikula return DDI_CLK_SEL_TBT_270; 280379bc100SJani Nikula case 540000: 281379bc100SJani Nikula return DDI_CLK_SEL_TBT_540; 282379bc100SJani Nikula case 810000: 283379bc100SJani Nikula return DDI_CLK_SEL_TBT_810; 284379bc100SJani Nikula default: 285379bc100SJani Nikula MISSING_CASE(clock); 286379bc100SJani Nikula return DDI_CLK_SEL_NONE; 287379bc100SJani Nikula } 288379bc100SJani Nikula case DPLL_ID_ICL_MGPLL1: 289379bc100SJani Nikula case DPLL_ID_ICL_MGPLL2: 290379bc100SJani Nikula case DPLL_ID_ICL_MGPLL3: 291379bc100SJani Nikula case DPLL_ID_ICL_MGPLL4: 2926677c3b1SJosé Roberto de Souza case DPLL_ID_TGL_MGPLL5: 2936677c3b1SJosé Roberto de Souza case DPLL_ID_TGL_MGPLL6: 294379bc100SJani Nikula return DDI_CLK_SEL_MG; 295379bc100SJani Nikula } 296379bc100SJani Nikula } 297379bc100SJani Nikula 298414002f1SImre Deak static u32 ddi_buf_phy_link_rate(int port_clock) 299414002f1SImre Deak { 300414002f1SImre Deak switch (port_clock) { 301414002f1SImre Deak case 162000: 302414002f1SImre Deak return DDI_BUF_PHY_LINK_RATE(0); 303414002f1SImre Deak case 216000: 304414002f1SImre Deak return DDI_BUF_PHY_LINK_RATE(4); 305414002f1SImre Deak case 243000: 306414002f1SImre Deak return DDI_BUF_PHY_LINK_RATE(5); 307414002f1SImre Deak case 270000: 308414002f1SImre Deak return DDI_BUF_PHY_LINK_RATE(1); 309414002f1SImre Deak case 324000: 310414002f1SImre Deak return DDI_BUF_PHY_LINK_RATE(6); 311414002f1SImre Deak case 432000: 312414002f1SImre Deak return DDI_BUF_PHY_LINK_RATE(7); 313414002f1SImre Deak case 540000: 314414002f1SImre Deak return DDI_BUF_PHY_LINK_RATE(2); 315414002f1SImre Deak case 810000: 316414002f1SImre Deak return DDI_BUF_PHY_LINK_RATE(3); 317414002f1SImre Deak default: 318414002f1SImre Deak MISSING_CASE(port_clock); 319414002f1SImre Deak return DDI_BUF_PHY_LINK_RATE(0); 320414002f1SImre Deak } 321414002f1SImre Deak } 322414002f1SImre Deak 323a621860aSVille Syrjälä static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder, 324a621860aSVille Syrjälä const struct intel_crtc_state *crtc_state) 325379bc100SJani Nikula { 32655ce306cSJosé Roberto de Souza struct drm_i915_private *i915 = to_i915(encoder->base.dev); 327b7d02c3aSVille Syrjälä struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 3287801f3b7SLucas De Marchi struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 32955ce306cSJosé Roberto de Souza enum phy phy = intel_port_to_phy(i915, encoder->port); 330379bc100SJani Nikula 3319f620f1dSVille Syrjälä /* DDI_BUF_CTL_ENABLE will be set by intel_ddi_prepare_link_retrain() later */ 3327801f3b7SLucas De Marchi intel_dp->DP = dig_port->saved_port_bits | 3339f620f1dSVille Syrjälä DDI_PORT_WIDTH(crtc_state->lane_count) | 3349f620f1dSVille Syrjälä DDI_BUF_TRANS_SELECT(0); 33555ce306cSJosé Roberto de Souza 33623ef6194SJosé Roberto de Souza if (DISPLAY_VER(i915) >= 14) { 33723ef6194SJosé Roberto de Souza if (intel_dp_is_uhbr(crtc_state)) 33823ef6194SJosé Roberto de Souza intel_dp->DP |= DDI_BUF_PORT_DATA_40BIT; 33923ef6194SJosé Roberto de Souza else 34023ef6194SJosé Roberto de Souza intel_dp->DP |= DDI_BUF_PORT_DATA_10BIT; 34123ef6194SJosé Roberto de Souza } 34223ef6194SJosé Roberto de Souza 343414002f1SImre Deak if (IS_ALDERLAKE_P(i915) && intel_phy_is_tc(i915, phy)) { 344414002f1SImre Deak intel_dp->DP |= ddi_buf_phy_link_rate(crtc_state->port_clock); 34511a89708SImre Deak if (!intel_tc_port_in_tbt_alt_mode(dig_port)) 34655ce306cSJosé Roberto de Souza intel_dp->DP |= DDI_BUF_CTL_TC_PHY_OWNERSHIP; 347379bc100SJani Nikula } 348414002f1SImre Deak } 349379bc100SJani Nikula 350379bc100SJani Nikula static int icl_calc_tbt_pll_link(struct drm_i915_private *dev_priv, 351379bc100SJani Nikula enum port port) 352379bc100SJani Nikula { 353f7960e7fSJani Nikula u32 val = intel_de_read(dev_priv, DDI_CLK_SEL(port)) & DDI_CLK_SEL_MASK; 354379bc100SJani Nikula 355379bc100SJani Nikula switch (val) { 356379bc100SJani Nikula case DDI_CLK_SEL_NONE: 357379bc100SJani Nikula return 0; 358379bc100SJani Nikula case DDI_CLK_SEL_TBT_162: 359379bc100SJani Nikula return 162000; 360379bc100SJani Nikula case DDI_CLK_SEL_TBT_270: 361379bc100SJani Nikula return 270000; 362379bc100SJani Nikula case DDI_CLK_SEL_TBT_540: 363379bc100SJani Nikula return 540000; 364379bc100SJani Nikula case DDI_CLK_SEL_TBT_810: 365379bc100SJani Nikula return 810000; 366379bc100SJani Nikula default: 367379bc100SJani Nikula MISSING_CASE(val); 368379bc100SJani Nikula return 0; 369379bc100SJani Nikula } 370379bc100SJani Nikula } 371379bc100SJani Nikula 372623411c2SVille Syrjälä static void ddi_dotclock_get(struct intel_crtc_state *pipe_config) 373623411c2SVille Syrjälä { 374623411c2SVille Syrjälä /* CRT dotclock is determined via other means */ 375623411c2SVille Syrjälä if (pipe_config->has_pch_encoder) 376623411c2SVille Syrjälä return; 377623411c2SVille Syrjälä 378623411c2SVille Syrjälä pipe_config->hw.adjusted_mode.crtc_clock = 379623411c2SVille Syrjälä intel_crtc_dotclock(pipe_config); 380379bc100SJani Nikula } 381379bc100SJani Nikula 3820c06fa15SGwan-gyeong Mun void intel_ddi_set_dp_msa(const struct intel_crtc_state *crtc_state, 3830c06fa15SGwan-gyeong Mun const struct drm_connector_state *conn_state) 384379bc100SJani Nikula { 3852225f3c6SMaarten Lankhorst struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 386379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 387379bc100SJani Nikula enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; 388379bc100SJani Nikula u32 temp; 389379bc100SJani Nikula 390379bc100SJani Nikula if (!intel_crtc_has_dp_encoder(crtc_state)) 391379bc100SJani Nikula return; 392379bc100SJani Nikula 3931de143ccSPankaj Bharadiya drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder)); 394379bc100SJani Nikula 3953e706dffSVille Syrjälä temp = DP_MSA_MISC_SYNC_CLOCK; 396379bc100SJani Nikula 397379bc100SJani Nikula switch (crtc_state->pipe_bpp) { 398379bc100SJani Nikula case 18: 3993e706dffSVille Syrjälä temp |= DP_MSA_MISC_6_BPC; 400379bc100SJani Nikula break; 401379bc100SJani Nikula case 24: 4023e706dffSVille Syrjälä temp |= DP_MSA_MISC_8_BPC; 403379bc100SJani Nikula break; 404379bc100SJani Nikula case 30: 4053e706dffSVille Syrjälä temp |= DP_MSA_MISC_10_BPC; 406379bc100SJani Nikula break; 407379bc100SJani Nikula case 36: 4083e706dffSVille Syrjälä temp |= DP_MSA_MISC_12_BPC; 409379bc100SJani Nikula break; 410379bc100SJani Nikula default: 411379bc100SJani Nikula MISSING_CASE(crtc_state->pipe_bpp); 412379bc100SJani Nikula break; 413379bc100SJani Nikula } 414379bc100SJani Nikula 415cae154fcSVille Syrjälä /* nonsense combination */ 4161de143ccSPankaj Bharadiya drm_WARN_ON(&dev_priv->drm, crtc_state->limited_color_range && 417cae154fcSVille Syrjälä crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB); 418cae154fcSVille Syrjälä 419cae154fcSVille Syrjälä if (crtc_state->limited_color_range) 4203e706dffSVille Syrjälä temp |= DP_MSA_MISC_COLOR_CEA_RGB; 421cae154fcSVille Syrjälä 422379bc100SJani Nikula /* 423379bc100SJani Nikula * As per DP 1.2 spec section 2.3.4.3 while sending 424379bc100SJani Nikula * YCBCR 444 signals we should program MSA MISC1/0 fields with 425646d3dc8SVille Syrjälä * colorspace information. 426379bc100SJani Nikula */ 427379bc100SJani Nikula if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR444) 4283e706dffSVille Syrjälä temp |= DP_MSA_MISC_COLOR_YCBCR_444_BT709; 429646d3dc8SVille Syrjälä 430379bc100SJani Nikula /* 431379bc100SJani Nikula * As per DP 1.4a spec section 2.2.4.3 [MSA Field for Indication 432379bc100SJani Nikula * of Color Encoding Format and Content Color Gamut] while sending 4330c06fa15SGwan-gyeong Mun * YCBCR 420, HDR BT.2020 signals we should program MSA MISC1 fields 4340c06fa15SGwan-gyeong Mun * which indicate VSC SDP for the Pixel Encoding/Colorimetry Format. 435379bc100SJani Nikula */ 436bd8c9ccaSGwan-gyeong Mun if (intel_dp_needs_vsc_sdp(crtc_state, conn_state)) 4373e706dffSVille Syrjälä temp |= DP_MSA_MISC_COLOR_VSC_SDP; 4380c06fa15SGwan-gyeong Mun 439f7960e7fSJani Nikula intel_de_write(dev_priv, TRANS_MSA_MISC(cpu_transcoder), temp); 440379bc100SJani Nikula } 441379bc100SJani Nikula 442dc5b8ed5SVille Syrjälä static u32 bdw_trans_port_sync_master_select(enum transcoder master_transcoder) 443dc5b8ed5SVille Syrjälä { 444dc5b8ed5SVille Syrjälä if (master_transcoder == TRANSCODER_EDP) 445dc5b8ed5SVille Syrjälä return 0; 446dc5b8ed5SVille Syrjälä else 447dc5b8ed5SVille Syrjälä return master_transcoder + 1; 448dc5b8ed5SVille Syrjälä } 449dc5b8ed5SVille Syrjälä 45079ac2b1bSJani Nikula static void 45179ac2b1bSJani Nikula intel_ddi_config_transcoder_dp2(struct intel_encoder *encoder, 45279ac2b1bSJani Nikula const struct intel_crtc_state *crtc_state) 45379ac2b1bSJani Nikula { 45479ac2b1bSJani Nikula struct drm_i915_private *i915 = to_i915(encoder->base.dev); 45579ac2b1bSJani Nikula enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; 45679ac2b1bSJani Nikula u32 val = 0; 45779ac2b1bSJani Nikula 45879ac2b1bSJani Nikula if (intel_dp_is_uhbr(crtc_state)) 45979ac2b1bSJani Nikula val = TRANS_DP2_128B132B_CHANNEL_CODING; 46079ac2b1bSJani Nikula 46179ac2b1bSJani Nikula intel_de_write(i915, TRANS_DP2_CTL(cpu_transcoder), val); 46279ac2b1bSJani Nikula } 46379ac2b1bSJani Nikula 46499389390SJosé Roberto de Souza /* 46599389390SJosé Roberto de Souza * Returns the TRANS_DDI_FUNC_CTL value based on CRTC state. 46699389390SJosé Roberto de Souza * 46799389390SJosé Roberto de Souza * Only intended to be used by intel_ddi_enable_transcoder_func() and 46899389390SJosé Roberto de Souza * intel_ddi_config_transcoder_func(). 46999389390SJosé Roberto de Souza */ 47099389390SJosé Roberto de Souza static u32 471eed22a46SVille Syrjälä intel_ddi_transcoder_func_reg_val_get(struct intel_encoder *encoder, 472eed22a46SVille Syrjälä const struct intel_crtc_state *crtc_state) 473379bc100SJani Nikula { 4742225f3c6SMaarten Lankhorst struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 475379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 476379bc100SJani Nikula enum pipe pipe = crtc->pipe; 477379bc100SJani Nikula enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; 478379bc100SJani Nikula enum port port = encoder->port; 479379bc100SJani Nikula u32 temp; 480379bc100SJani Nikula 481379bc100SJani Nikula /* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */ 482379bc100SJani Nikula temp = TRANS_DDI_FUNC_ENABLE; 483005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 12) 484df16b636SMahesh Kumar temp |= TGL_TRANS_DDI_SELECT_PORT(port); 485df16b636SMahesh Kumar else 486379bc100SJani Nikula temp |= TRANS_DDI_SELECT_PORT(port); 487379bc100SJani Nikula 488379bc100SJani Nikula switch (crtc_state->pipe_bpp) { 48904514c14SJani Nikula default: 49004514c14SJani Nikula MISSING_CASE(crtc_state->pipe_bpp); 49104514c14SJani Nikula fallthrough; 492379bc100SJani Nikula case 18: 493379bc100SJani Nikula temp |= TRANS_DDI_BPC_6; 494379bc100SJani Nikula break; 495379bc100SJani Nikula case 24: 496379bc100SJani Nikula temp |= TRANS_DDI_BPC_8; 497379bc100SJani Nikula break; 498379bc100SJani Nikula case 30: 499379bc100SJani Nikula temp |= TRANS_DDI_BPC_10; 500379bc100SJani Nikula break; 501379bc100SJani Nikula case 36: 502379bc100SJani Nikula temp |= TRANS_DDI_BPC_12; 503379bc100SJani Nikula break; 504379bc100SJani Nikula } 505379bc100SJani Nikula 5061326a92cSMaarten Lankhorst if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC) 507379bc100SJani Nikula temp |= TRANS_DDI_PVSYNC; 5081326a92cSMaarten Lankhorst if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC) 509379bc100SJani Nikula temp |= TRANS_DDI_PHSYNC; 510379bc100SJani Nikula 511379bc100SJani Nikula if (cpu_transcoder == TRANSCODER_EDP) { 512379bc100SJani Nikula switch (pipe) { 51304514c14SJani Nikula default: 51404514c14SJani Nikula MISSING_CASE(pipe); 51504514c14SJani Nikula fallthrough; 516379bc100SJani Nikula case PIPE_A: 517379bc100SJani Nikula /* On Haswell, can only use the always-on power well for 518379bc100SJani Nikula * eDP when not using the panel fitter, and when not 519379bc100SJani Nikula * using motion blur mitigation (which we don't 520379bc100SJani Nikula * support). */ 521379bc100SJani Nikula if (crtc_state->pch_pfit.force_thru) 522379bc100SJani Nikula temp |= TRANS_DDI_EDP_INPUT_A_ONOFF; 523379bc100SJani Nikula else 524379bc100SJani Nikula temp |= TRANS_DDI_EDP_INPUT_A_ON; 525379bc100SJani Nikula break; 526379bc100SJani Nikula case PIPE_B: 527379bc100SJani Nikula temp |= TRANS_DDI_EDP_INPUT_B_ONOFF; 528379bc100SJani Nikula break; 529379bc100SJani Nikula case PIPE_C: 530379bc100SJani Nikula temp |= TRANS_DDI_EDP_INPUT_C_ONOFF; 531379bc100SJani Nikula break; 532379bc100SJani Nikula } 533379bc100SJani Nikula } 534379bc100SJani Nikula 535379bc100SJani Nikula if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { 536379bc100SJani Nikula if (crtc_state->has_hdmi_sink) 537379bc100SJani Nikula temp |= TRANS_DDI_MODE_SELECT_HDMI; 538379bc100SJani Nikula else 539379bc100SJani Nikula temp |= TRANS_DDI_MODE_SELECT_DVI; 540379bc100SJani Nikula 541379bc100SJani Nikula if (crtc_state->hdmi_scrambling) 542379bc100SJani Nikula temp |= TRANS_DDI_HDMI_SCRAMBLING; 543379bc100SJani Nikula if (crtc_state->hdmi_high_tmds_clock_ratio) 544379bc100SJani Nikula temp |= TRANS_DDI_HIGH_TMDS_CHAR_RATE; 545b66a8abaSAnkit Nautiyal if (DISPLAY_VER(dev_priv) >= 14) 546b66a8abaSAnkit Nautiyal temp |= TRANS_DDI_PORT_WIDTH(crtc_state->lane_count); 547379bc100SJani Nikula } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG)) { 5487bb97db8SJani Nikula temp |= TRANS_DDI_MODE_SELECT_FDI_OR_128B132B; 549379bc100SJani Nikula temp |= (crtc_state->fdi_lanes - 1) << 1; 550379bc100SJani Nikula } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) { 55165213594SJani Nikula if (intel_dp_is_uhbr(crtc_state)) 55265213594SJani Nikula temp |= TRANS_DDI_MODE_SELECT_FDI_OR_128B132B; 55365213594SJani Nikula else 554379bc100SJani Nikula temp |= TRANS_DDI_MODE_SELECT_DP_MST; 555379bc100SJani Nikula temp |= DDI_PORT_WIDTH(crtc_state->lane_count); 556b3545e08SLucas De Marchi 557005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 12) { 5586671c367SJosé Roberto de Souza enum transcoder master; 5596671c367SJosé Roberto de Souza 5606671c367SJosé Roberto de Souza master = crtc_state->mst_master_transcoder; 5611de143ccSPankaj Bharadiya drm_WARN_ON(&dev_priv->drm, 5621de143ccSPankaj Bharadiya master == INVALID_TRANSCODER); 5636671c367SJosé Roberto de Souza temp |= TRANS_DDI_MST_TRANSPORT_SELECT(master); 5646671c367SJosé Roberto de Souza } 565379bc100SJani Nikula } else { 566379bc100SJani Nikula temp |= TRANS_DDI_MODE_SELECT_DP_SST; 567379bc100SJani Nikula temp |= DDI_PORT_WIDTH(crtc_state->lane_count); 568379bc100SJani Nikula } 569379bc100SJani Nikula 57093e7e61eSLucas De Marchi if (IS_DISPLAY_VER(dev_priv, 8, 10) && 571dc5b8ed5SVille Syrjälä crtc_state->master_transcoder != INVALID_TRANSCODER) { 572dc5b8ed5SVille Syrjälä u8 master_select = 573dc5b8ed5SVille Syrjälä bdw_trans_port_sync_master_select(crtc_state->master_transcoder); 574dc5b8ed5SVille Syrjälä 575dc5b8ed5SVille Syrjälä temp |= TRANS_DDI_PORT_SYNC_ENABLE | 576dc5b8ed5SVille Syrjälä TRANS_DDI_PORT_SYNC_MASTER_SELECT(master_select); 577dc5b8ed5SVille Syrjälä } 578dc5b8ed5SVille Syrjälä 57999389390SJosé Roberto de Souza return temp; 58099389390SJosé Roberto de Souza } 58199389390SJosé Roberto de Souza 582eed22a46SVille Syrjälä void intel_ddi_enable_transcoder_func(struct intel_encoder *encoder, 583eed22a46SVille Syrjälä const struct intel_crtc_state *crtc_state) 58499389390SJosé Roberto de Souza { 5852225f3c6SMaarten Lankhorst struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 58699389390SJosé Roberto de Souza struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 58799389390SJosé Roberto de Souza enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; 58899389390SJosé Roberto de Souza 589005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 11) { 590589a4cd6SVille Syrjälä enum transcoder master_transcoder = crtc_state->master_transcoder; 591589a4cd6SVille Syrjälä u32 ctl2 = 0; 592589a4cd6SVille Syrjälä 593589a4cd6SVille Syrjälä if (master_transcoder != INVALID_TRANSCODER) { 594dc5b8ed5SVille Syrjälä u8 master_select = 595dc5b8ed5SVille Syrjälä bdw_trans_port_sync_master_select(master_transcoder); 596589a4cd6SVille Syrjälä 597589a4cd6SVille Syrjälä ctl2 |= PORT_SYNC_MODE_ENABLE | 598d4d7d9caSVille Syrjälä PORT_SYNC_MODE_MASTER_SELECT(master_select); 599589a4cd6SVille Syrjälä } 600589a4cd6SVille Syrjälä 601589a4cd6SVille Syrjälä intel_de_write(dev_priv, 602589a4cd6SVille Syrjälä TRANS_DDI_FUNC_CTL2(cpu_transcoder), ctl2); 603589a4cd6SVille Syrjälä } 604589a4cd6SVille Syrjälä 605580fbdc5SImre Deak intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder), 606580fbdc5SImre Deak intel_ddi_transcoder_func_reg_val_get(encoder, 607580fbdc5SImre Deak crtc_state)); 60899389390SJosé Roberto de Souza } 60999389390SJosé Roberto de Souza 61099389390SJosé Roberto de Souza /* 61199389390SJosé Roberto de Souza * Same as intel_ddi_enable_transcoder_func(), but it does not set the enable 61299389390SJosé Roberto de Souza * bit. 61399389390SJosé Roberto de Souza */ 61499389390SJosé Roberto de Souza static void 615eed22a46SVille Syrjälä intel_ddi_config_transcoder_func(struct intel_encoder *encoder, 616eed22a46SVille Syrjälä const struct intel_crtc_state *crtc_state) 61799389390SJosé Roberto de Souza { 6182225f3c6SMaarten Lankhorst struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 61999389390SJosé Roberto de Souza struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 62099389390SJosé Roberto de Souza enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; 621589a4cd6SVille Syrjälä u32 ctl; 62299389390SJosé Roberto de Souza 623eed22a46SVille Syrjälä ctl = intel_ddi_transcoder_func_reg_val_get(encoder, crtc_state); 624589a4cd6SVille Syrjälä ctl &= ~TRANS_DDI_FUNC_ENABLE; 625589a4cd6SVille Syrjälä intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder), ctl); 626379bc100SJani Nikula } 627379bc100SJani Nikula 628379bc100SJani Nikula void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state) 629379bc100SJani Nikula { 6302225f3c6SMaarten Lankhorst struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 631379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 632379bc100SJani Nikula enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; 633589a4cd6SVille Syrjälä u32 ctl; 634c59053dcSJosé Roberto de Souza 635005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 11) 636589a4cd6SVille Syrjälä intel_de_write(dev_priv, 637589a4cd6SVille Syrjälä TRANS_DDI_FUNC_CTL2(cpu_transcoder), 0); 638589a4cd6SVille Syrjälä 639589a4cd6SVille Syrjälä ctl = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder)); 640dc5b8ed5SVille Syrjälä 6411cfcdbf3SSean Paul drm_WARN_ON(crtc->base.dev, ctl & TRANS_DDI_HDCP_SIGNALLING); 6421cfcdbf3SSean Paul 643589a4cd6SVille Syrjälä ctl &= ~TRANS_DDI_FUNC_ENABLE; 644379bc100SJani Nikula 64593e7e61eSLucas De Marchi if (IS_DISPLAY_VER(dev_priv, 8, 10)) 646dc5b8ed5SVille Syrjälä ctl &= ~(TRANS_DDI_PORT_SYNC_ENABLE | 647dc5b8ed5SVille Syrjälä TRANS_DDI_PORT_SYNC_MASTER_SELECT_MASK); 648dc5b8ed5SVille Syrjälä 649005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 12) { 650919e4f07SJosé Roberto de Souza if (!intel_dp_mst_is_master_trans(crtc_state)) { 651589a4cd6SVille Syrjälä ctl &= ~(TGL_TRANS_DDI_PORT_MASK | 652919e4f07SJosé Roberto de Souza TRANS_DDI_MODE_SELECT_MASK); 653919e4f07SJosé Roberto de Souza } 654df16b636SMahesh Kumar } else { 655589a4cd6SVille Syrjälä ctl &= ~(TRANS_DDI_PORT_MASK | TRANS_DDI_MODE_SELECT_MASK); 656df16b636SMahesh Kumar } 657dc5b8ed5SVille Syrjälä 658589a4cd6SVille Syrjälä intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder), ctl); 659379bc100SJani Nikula 6600c82118bSJani Nikula if (intel_has_quirk(dev_priv, QUIRK_INCREASE_DDI_DISABLED_TIME) && 661379bc100SJani Nikula intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { 66247bdb1caSJani Nikula drm_dbg_kms(&dev_priv->drm, 66347bdb1caSJani Nikula "Quirk Increase DDI disabled time\n"); 664379bc100SJani Nikula /* Quirk time at 100ms for reliable operation */ 665379bc100SJani Nikula msleep(100); 666379bc100SJani Nikula } 667379bc100SJani Nikula } 668379bc100SJani Nikula 6691a67a168SAnshuman Gupta int intel_ddi_toggle_hdcp_bits(struct intel_encoder *intel_encoder, 6700b9c9290SSean Paul enum transcoder cpu_transcoder, 6711a67a168SAnshuman Gupta bool enable, u32 hdcp_mask) 672379bc100SJani Nikula { 673379bc100SJani Nikula struct drm_device *dev = intel_encoder->base.dev; 674379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(dev); 675379bc100SJani Nikula intel_wakeref_t wakeref; 676379bc100SJani Nikula int ret = 0; 677379bc100SJani Nikula 678379bc100SJani Nikula wakeref = intel_display_power_get_if_enabled(dev_priv, 679379bc100SJani Nikula intel_encoder->power_domain); 6801de143ccSPankaj Bharadiya if (drm_WARN_ON(dev, !wakeref)) 681379bc100SJani Nikula return -ENXIO; 682379bc100SJani Nikula 6838910d8b7SAndrzej Hajda intel_de_rmw(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder), 6848910d8b7SAndrzej Hajda hdcp_mask, enable ? hdcp_mask : 0); 685379bc100SJani Nikula intel_display_power_put(dev_priv, intel_encoder->power_domain, wakeref); 686379bc100SJani Nikula return ret; 687379bc100SJani Nikula } 688379bc100SJani Nikula 689379bc100SJani Nikula bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector) 690379bc100SJani Nikula { 691379bc100SJani Nikula struct drm_device *dev = intel_connector->base.dev; 692379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(dev); 693fa7edcd2SVille Syrjälä struct intel_encoder *encoder = intel_attached_encoder(intel_connector); 694379bc100SJani Nikula int type = intel_connector->base.connector_type; 695379bc100SJani Nikula enum port port = encoder->port; 696379bc100SJani Nikula enum transcoder cpu_transcoder; 697379bc100SJani Nikula intel_wakeref_t wakeref; 698379bc100SJani Nikula enum pipe pipe = 0; 699379bc100SJani Nikula u32 tmp; 700379bc100SJani Nikula bool ret; 701379bc100SJani Nikula 702379bc100SJani Nikula wakeref = intel_display_power_get_if_enabled(dev_priv, 703379bc100SJani Nikula encoder->power_domain); 704379bc100SJani Nikula if (!wakeref) 705379bc100SJani Nikula return false; 706379bc100SJani Nikula 707379bc100SJani Nikula if (!encoder->get_hw_state(encoder, &pipe)) { 708379bc100SJani Nikula ret = false; 709379bc100SJani Nikula goto out; 710379bc100SJani Nikula } 711379bc100SJani Nikula 71210cf8e75SVille Syrjälä if (HAS_TRANSCODER(dev_priv, TRANSCODER_EDP) && port == PORT_A) 713379bc100SJani Nikula cpu_transcoder = TRANSCODER_EDP; 714379bc100SJani Nikula else 715379bc100SJani Nikula cpu_transcoder = (enum transcoder) pipe; 716379bc100SJani Nikula 717f7960e7fSJani Nikula tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder)); 718379bc100SJani Nikula 719379bc100SJani Nikula switch (tmp & TRANS_DDI_MODE_SELECT_MASK) { 720379bc100SJani Nikula case TRANS_DDI_MODE_SELECT_HDMI: 721379bc100SJani Nikula case TRANS_DDI_MODE_SELECT_DVI: 722379bc100SJani Nikula ret = type == DRM_MODE_CONNECTOR_HDMIA; 723379bc100SJani Nikula break; 724379bc100SJani Nikula 725379bc100SJani Nikula case TRANS_DDI_MODE_SELECT_DP_SST: 726379bc100SJani Nikula ret = type == DRM_MODE_CONNECTOR_eDP || 727379bc100SJani Nikula type == DRM_MODE_CONNECTOR_DisplayPort; 728379bc100SJani Nikula break; 729379bc100SJani Nikula 730379bc100SJani Nikula case TRANS_DDI_MODE_SELECT_DP_MST: 731379bc100SJani Nikula /* if the transcoder is in MST state then 732379bc100SJani Nikula * connector isn't connected */ 733379bc100SJani Nikula ret = false; 734379bc100SJani Nikula break; 735379bc100SJani Nikula 7367bb97db8SJani Nikula case TRANS_DDI_MODE_SELECT_FDI_OR_128B132B: 73765213594SJani Nikula if (HAS_DP20(dev_priv)) 73865213594SJani Nikula /* 128b/132b */ 73965213594SJani Nikula ret = false; 74065213594SJani Nikula else 74165213594SJani Nikula /* FDI */ 742379bc100SJani Nikula ret = type == DRM_MODE_CONNECTOR_VGA; 743379bc100SJani Nikula break; 744379bc100SJani Nikula 745379bc100SJani Nikula default: 746379bc100SJani Nikula ret = false; 747379bc100SJani Nikula break; 748379bc100SJani Nikula } 749379bc100SJani Nikula 750379bc100SJani Nikula out: 751379bc100SJani Nikula intel_display_power_put(dev_priv, encoder->power_domain, wakeref); 752379bc100SJani Nikula 753379bc100SJani Nikula return ret; 754379bc100SJani Nikula } 755379bc100SJani Nikula 756379bc100SJani Nikula static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, 757379bc100SJani Nikula u8 *pipe_mask, bool *is_dp_mst) 758379bc100SJani Nikula { 759379bc100SJani Nikula struct drm_device *dev = encoder->base.dev; 760379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(dev); 761379bc100SJani Nikula enum port port = encoder->port; 762379bc100SJani Nikula intel_wakeref_t wakeref; 763379bc100SJani Nikula enum pipe p; 764379bc100SJani Nikula u32 tmp; 765379bc100SJani Nikula u8 mst_pipe_mask; 766379bc100SJani Nikula 767379bc100SJani Nikula *pipe_mask = 0; 768379bc100SJani Nikula *is_dp_mst = false; 769379bc100SJani Nikula 770379bc100SJani Nikula wakeref = intel_display_power_get_if_enabled(dev_priv, 771379bc100SJani Nikula encoder->power_domain); 772379bc100SJani Nikula if (!wakeref) 773379bc100SJani Nikula return; 774379bc100SJani Nikula 775f7960e7fSJani Nikula tmp = intel_de_read(dev_priv, DDI_BUF_CTL(port)); 776379bc100SJani Nikula if (!(tmp & DDI_BUF_CTL_ENABLE)) 777379bc100SJani Nikula goto out; 778379bc100SJani Nikula 77910cf8e75SVille Syrjälä if (HAS_TRANSCODER(dev_priv, TRANSCODER_EDP) && port == PORT_A) { 780f7960e7fSJani Nikula tmp = intel_de_read(dev_priv, 781f7960e7fSJani Nikula TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)); 782379bc100SJani Nikula 783379bc100SJani Nikula switch (tmp & TRANS_DDI_EDP_INPUT_MASK) { 784379bc100SJani Nikula default: 785379bc100SJani Nikula MISSING_CASE(tmp & TRANS_DDI_EDP_INPUT_MASK); 786df561f66SGustavo A. R. Silva fallthrough; 787379bc100SJani Nikula case TRANS_DDI_EDP_INPUT_A_ON: 788379bc100SJani Nikula case TRANS_DDI_EDP_INPUT_A_ONOFF: 789379bc100SJani Nikula *pipe_mask = BIT(PIPE_A); 790379bc100SJani Nikula break; 791379bc100SJani Nikula case TRANS_DDI_EDP_INPUT_B_ONOFF: 792379bc100SJani Nikula *pipe_mask = BIT(PIPE_B); 793379bc100SJani Nikula break; 794379bc100SJani Nikula case TRANS_DDI_EDP_INPUT_C_ONOFF: 795379bc100SJani Nikula *pipe_mask = BIT(PIPE_C); 796379bc100SJani Nikula break; 797379bc100SJani Nikula } 798379bc100SJani Nikula 799379bc100SJani Nikula goto out; 800379bc100SJani Nikula } 801379bc100SJani Nikula 802379bc100SJani Nikula mst_pipe_mask = 0; 803379bc100SJani Nikula for_each_pipe(dev_priv, p) { 804379bc100SJani Nikula enum transcoder cpu_transcoder = (enum transcoder)p; 805df16b636SMahesh Kumar unsigned int port_mask, ddi_select; 8066aa3bef1SJosé Roberto de Souza intel_wakeref_t trans_wakeref; 8076aa3bef1SJosé Roberto de Souza 8086aa3bef1SJosé Roberto de Souza trans_wakeref = intel_display_power_get_if_enabled(dev_priv, 8096aa3bef1SJosé Roberto de Souza POWER_DOMAIN_TRANSCODER(cpu_transcoder)); 8106aa3bef1SJosé Roberto de Souza if (!trans_wakeref) 8116aa3bef1SJosé Roberto de Souza continue; 812df16b636SMahesh Kumar 813005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 12) { 814df16b636SMahesh Kumar port_mask = TGL_TRANS_DDI_PORT_MASK; 815df16b636SMahesh Kumar ddi_select = TGL_TRANS_DDI_SELECT_PORT(port); 816df16b636SMahesh Kumar } else { 817df16b636SMahesh Kumar port_mask = TRANS_DDI_PORT_MASK; 818df16b636SMahesh Kumar ddi_select = TRANS_DDI_SELECT_PORT(port); 819df16b636SMahesh Kumar } 820379bc100SJani Nikula 821f7960e7fSJani Nikula tmp = intel_de_read(dev_priv, 822f7960e7fSJani Nikula TRANS_DDI_FUNC_CTL(cpu_transcoder)); 8236aa3bef1SJosé Roberto de Souza intel_display_power_put(dev_priv, POWER_DOMAIN_TRANSCODER(cpu_transcoder), 8246aa3bef1SJosé Roberto de Souza trans_wakeref); 825379bc100SJani Nikula 826df16b636SMahesh Kumar if ((tmp & port_mask) != ddi_select) 827379bc100SJani Nikula continue; 828379bc100SJani Nikula 82965213594SJani Nikula if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST || 83065213594SJani Nikula (HAS_DP20(dev_priv) && 83165213594SJani Nikula (tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_FDI_OR_128B132B)) 832379bc100SJani Nikula mst_pipe_mask |= BIT(p); 833379bc100SJani Nikula 834379bc100SJani Nikula *pipe_mask |= BIT(p); 835379bc100SJani Nikula } 836379bc100SJani Nikula 837379bc100SJani Nikula if (!*pipe_mask) 83847bdb1caSJani Nikula drm_dbg_kms(&dev_priv->drm, 83947bdb1caSJani Nikula "No pipe for [ENCODER:%d:%s] found\n", 84066a990ddSVille Syrjälä encoder->base.base.id, encoder->base.name); 841379bc100SJani Nikula 842379bc100SJani Nikula if (!mst_pipe_mask && hweight8(*pipe_mask) > 1) { 84347bdb1caSJani Nikula drm_dbg_kms(&dev_priv->drm, 84447bdb1caSJani Nikula "Multiple pipes for [ENCODER:%d:%s] (pipe_mask %02x)\n", 84566a990ddSVille Syrjälä encoder->base.base.id, encoder->base.name, 84666a990ddSVille Syrjälä *pipe_mask); 847379bc100SJani Nikula *pipe_mask = BIT(ffs(*pipe_mask) - 1); 848379bc100SJani Nikula } 849379bc100SJani Nikula 850379bc100SJani Nikula if (mst_pipe_mask && mst_pipe_mask != *pipe_mask) 85147bdb1caSJani Nikula drm_dbg_kms(&dev_priv->drm, 85247bdb1caSJani Nikula "Conflicting MST and non-MST state for [ENCODER:%d:%s] (pipe_mask %02x mst_pipe_mask %02x)\n", 85366a990ddSVille Syrjälä encoder->base.base.id, encoder->base.name, 85466a990ddSVille Syrjälä *pipe_mask, mst_pipe_mask); 855379bc100SJani Nikula else 856379bc100SJani Nikula *is_dp_mst = mst_pipe_mask; 857379bc100SJani Nikula 858379bc100SJani Nikula out: 8592446e1d6SMatt Roper if (*pipe_mask && (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))) { 860f7960e7fSJani Nikula tmp = intel_de_read(dev_priv, BXT_PHY_CTL(port)); 861379bc100SJani Nikula if ((tmp & (BXT_PHY_CMNLANE_POWERDOWN_ACK | 862379bc100SJani Nikula BXT_PHY_LANE_POWERDOWN_ACK | 863379bc100SJani Nikula BXT_PHY_LANE_ENABLED)) != BXT_PHY_LANE_ENABLED) 86447bdb1caSJani Nikula drm_err(&dev_priv->drm, 86547bdb1caSJani Nikula "[ENCODER:%d:%s] enabled but PHY powered down? (PHY_CTL %08x)\n", 86647bdb1caSJani Nikula encoder->base.base.id, encoder->base.name, tmp); 867379bc100SJani Nikula } 868379bc100SJani Nikula 869379bc100SJani Nikula intel_display_power_put(dev_priv, encoder->power_domain, wakeref); 870379bc100SJani Nikula } 871379bc100SJani Nikula 872379bc100SJani Nikula bool intel_ddi_get_hw_state(struct intel_encoder *encoder, 873379bc100SJani Nikula enum pipe *pipe) 874379bc100SJani Nikula { 875379bc100SJani Nikula u8 pipe_mask; 876379bc100SJani Nikula bool is_mst; 877379bc100SJani Nikula 878379bc100SJani Nikula intel_ddi_get_encoder_pipes(encoder, &pipe_mask, &is_mst); 879379bc100SJani Nikula 880379bc100SJani Nikula if (is_mst || !pipe_mask) 881379bc100SJani Nikula return false; 882379bc100SJani Nikula 883379bc100SJani Nikula *pipe = ffs(pipe_mask) - 1; 884379bc100SJani Nikula 885379bc100SJani Nikula return true; 886379bc100SJani Nikula } 887379bc100SJani Nikula 88881b55ef1SJani Nikula static enum intel_display_power_domain 889637c7aa2SImre Deak intel_ddi_main_link_aux_domain(struct intel_digital_port *dig_port, 890637c7aa2SImre Deak const struct intel_crtc_state *crtc_state) 891379bc100SJani Nikula { 892f645cbdaSImre Deak struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 893637c7aa2SImre Deak enum phy phy = intel_port_to_phy(i915, dig_port->base.port); 894f645cbdaSImre Deak 895637c7aa2SImre Deak /* 896637c7aa2SImre Deak * ICL+ HW requires corresponding AUX IOs to be powered up for PSR with 897379bc100SJani Nikula * DC states enabled at the same time, while for driver initiated AUX 898379bc100SJani Nikula * transfers we need the same AUX IOs to be powered but with DC states 899637c7aa2SImre Deak * disabled. Accordingly use the AUX_IO_<port> power domain here which 900637c7aa2SImre Deak * leaves DC states enabled. 901637c7aa2SImre Deak * 902637c7aa2SImre Deak * Before MTL TypeC PHYs (in all TypeC modes and both DP/HDMI) also require 903637c7aa2SImre Deak * AUX IO to be enabled, but all these require DC_OFF to be enabled as 904637c7aa2SImre Deak * well, so we can acquire a wider AUX_<port> power domain reference 905637c7aa2SImre Deak * instead of a specific AUX_IO_<port> reference without powering up any 906637c7aa2SImre Deak * extra wells. 907379bc100SJani Nikula */ 908f645cbdaSImre Deak if (intel_encoder_can_psr(&dig_port->base)) 909f645cbdaSImre Deak return intel_display_power_aux_io_domain(i915, dig_port->aux_ch); 9101acefacaSImre Deak else if (DISPLAY_VER(i915) < 14 && 9111acefacaSImre Deak (intel_crtc_has_dp_encoder(crtc_state) || 9121acefacaSImre Deak intel_phy_is_tc(i915, phy))) 913b2e00dd3SImre Deak return intel_aux_power_domain(dig_port); 914637c7aa2SImre Deak else 915637c7aa2SImre Deak return POWER_DOMAIN_INVALID; 916637c7aa2SImre Deak } 917637c7aa2SImre Deak 918637c7aa2SImre Deak static void 919637c7aa2SImre Deak main_link_aux_power_domain_get(struct intel_digital_port *dig_port, 920637c7aa2SImre Deak const struct intel_crtc_state *crtc_state) 921637c7aa2SImre Deak { 922637c7aa2SImre Deak struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 923637c7aa2SImre Deak enum intel_display_power_domain domain = 924637c7aa2SImre Deak intel_ddi_main_link_aux_domain(dig_port, crtc_state); 925637c7aa2SImre Deak 926637c7aa2SImre Deak drm_WARN_ON(&i915->drm, dig_port->aux_wakeref); 927637c7aa2SImre Deak 928637c7aa2SImre Deak if (domain == POWER_DOMAIN_INVALID) 929637c7aa2SImre Deak return; 930637c7aa2SImre Deak 931637c7aa2SImre Deak dig_port->aux_wakeref = intel_display_power_get(i915, domain); 932637c7aa2SImre Deak } 933637c7aa2SImre Deak 934637c7aa2SImre Deak static void 935637c7aa2SImre Deak main_link_aux_power_domain_put(struct intel_digital_port *dig_port, 936637c7aa2SImre Deak const struct intel_crtc_state *crtc_state) 937637c7aa2SImre Deak { 938637c7aa2SImre Deak struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 939637c7aa2SImre Deak enum intel_display_power_domain domain = 940637c7aa2SImre Deak intel_ddi_main_link_aux_domain(dig_port, crtc_state); 941637c7aa2SImre Deak intel_wakeref_t wf; 942637c7aa2SImre Deak 943637c7aa2SImre Deak wf = fetch_and_zero(&dig_port->aux_wakeref); 944637c7aa2SImre Deak if (!wf) 945637c7aa2SImre Deak return; 946637c7aa2SImre Deak 947637c7aa2SImre Deak intel_display_power_put(i915, domain, wf); 948379bc100SJani Nikula } 949379bc100SJani Nikula 950379bc100SJani Nikula static void intel_ddi_get_power_domains(struct intel_encoder *encoder, 951379bc100SJani Nikula struct intel_crtc_state *crtc_state) 952379bc100SJani Nikula { 953379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 954379bc100SJani Nikula struct intel_digital_port *dig_port; 955379bc100SJani Nikula 956379bc100SJani Nikula /* 957379bc100SJani Nikula * TODO: Add support for MST encoders. Atm, the following should never 958379bc100SJani Nikula * happen since fake-MST encoders don't set their get_power_domains() 959379bc100SJani Nikula * hook. 960379bc100SJani Nikula */ 9611de143ccSPankaj Bharadiya if (drm_WARN_ON(&dev_priv->drm, 9621de143ccSPankaj Bharadiya intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST))) 963379bc100SJani Nikula return; 964379bc100SJani Nikula 965b7d02c3aSVille Syrjälä dig_port = enc_to_dig_port(encoder); 966f77a2db2SImre Deak 96711a89708SImre Deak if (!intel_tc_port_in_tbt_alt_mode(dig_port)) { 968a4550977SImre Deak drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref); 969a4550977SImre Deak dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv, 970f77a2db2SImre Deak dig_port->ddi_io_power_domain); 971a4550977SImre Deak } 972379bc100SJani Nikula 973637c7aa2SImre Deak main_link_aux_power_domain_get(dig_port, crtc_state); 974162e68e1SImre Deak } 975379bc100SJani Nikula 97655a4679eSVille Syrjälä void intel_ddi_enable_transcoder_clock(struct intel_encoder *encoder, 97702a715c3SVille Syrjälä const struct intel_crtc_state *crtc_state) 978379bc100SJani Nikula { 9792225f3c6SMaarten Lankhorst struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 980379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 981379bc100SJani Nikula enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; 982ed2615a8SMatt Roper enum phy phy = intel_port_to_phy(dev_priv, encoder->port); 983ed2615a8SMatt Roper u32 val; 984379bc100SJani Nikula 98548630a31SVille Syrjälä if (cpu_transcoder == TRANSCODER_EDP) 98648630a31SVille Syrjälä return; 98748630a31SVille Syrjälä 988ed2615a8SMatt Roper if (DISPLAY_VER(dev_priv) >= 13) 989ed2615a8SMatt Roper val = TGL_TRANS_CLK_SEL_PORT(phy); 990ed2615a8SMatt Roper else if (DISPLAY_VER(dev_priv) >= 12) 991ed2615a8SMatt Roper val = TGL_TRANS_CLK_SEL_PORT(encoder->port); 992df16b636SMahesh Kumar else 993ed2615a8SMatt Roper val = TRANS_CLK_SEL_PORT(encoder->port); 994ed2615a8SMatt Roper 995ed2615a8SMatt Roper intel_de_write(dev_priv, TRANS_CLK_SEL(cpu_transcoder), val); 996379bc100SJani Nikula } 997379bc100SJani Nikula 99855a4679eSVille Syrjälä void intel_ddi_disable_transcoder_clock(const struct intel_crtc_state *crtc_state) 999379bc100SJani Nikula { 10002225f3c6SMaarten Lankhorst struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); 1001379bc100SJani Nikula enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; 100248630a31SVille Syrjälä u32 val; 1003379bc100SJani Nikula 100448630a31SVille Syrjälä if (cpu_transcoder == TRANSCODER_EDP) 100548630a31SVille Syrjälä return; 100648630a31SVille Syrjälä 1007005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 12) 100848630a31SVille Syrjälä val = TGL_TRANS_CLK_SEL_DISABLED; 1009df16b636SMahesh Kumar else 101048630a31SVille Syrjälä val = TRANS_CLK_SEL_DISABLED; 101148630a31SVille Syrjälä 101248630a31SVille Syrjälä intel_de_write(dev_priv, TRANS_CLK_SEL(cpu_transcoder), val); 1013df16b636SMahesh Kumar } 1014379bc100SJani Nikula 1015379bc100SJani Nikula static void _skl_ddi_set_iboost(struct drm_i915_private *dev_priv, 1016379bc100SJani Nikula enum port port, u8 iboost) 1017379bc100SJani Nikula { 1018379bc100SJani Nikula u32 tmp; 1019379bc100SJani Nikula 1020f7960e7fSJani Nikula tmp = intel_de_read(dev_priv, DISPIO_CR_TX_BMU_CR0); 1021379bc100SJani Nikula tmp &= ~(BALANCE_LEG_MASK(port) | BALANCE_LEG_DISABLE(port)); 1022379bc100SJani Nikula if (iboost) 1023379bc100SJani Nikula tmp |= iboost << BALANCE_LEG_SHIFT(port); 1024379bc100SJani Nikula else 1025379bc100SJani Nikula tmp |= BALANCE_LEG_DISABLE(port); 1026f7960e7fSJani Nikula intel_de_write(dev_priv, DISPIO_CR_TX_BMU_CR0, tmp); 1027379bc100SJani Nikula } 1028379bc100SJani Nikula 1029379bc100SJani Nikula static void skl_ddi_set_iboost(struct intel_encoder *encoder, 1030a621860aSVille Syrjälä const struct intel_crtc_state *crtc_state, 1031a621860aSVille Syrjälä int level) 1032379bc100SJani Nikula { 10337801f3b7SLucas De Marchi struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 1034379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 1035379bc100SJani Nikula u8 iboost; 1036379bc100SJani Nikula 1037a621860aSVille Syrjälä if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) 103802107ef1SVille Syrjälä iboost = intel_bios_hdmi_boost_level(encoder->devdata); 1039379bc100SJani Nikula else 104002107ef1SVille Syrjälä iboost = intel_bios_dp_boost_level(encoder->devdata); 1041379bc100SJani Nikula 1042379bc100SJani Nikula if (iboost == 0) { 1043e505d764SVille Syrjälä const struct intel_ddi_buf_trans *trans; 1044379bc100SJani Nikula int n_entries; 1045379bc100SJani Nikula 1046e505d764SVille Syrjälä trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); 1047e505d764SVille Syrjälä if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) 1048379bc100SJani Nikula return; 1049379bc100SJani Nikula 1050e505d764SVille Syrjälä iboost = trans->entries[level].hsw.i_boost; 1051379bc100SJani Nikula } 1052379bc100SJani Nikula 1053379bc100SJani Nikula /* Make sure that the requested I_boost is valid */ 1054379bc100SJani Nikula if (iboost && iboost != 0x1 && iboost != 0x3 && iboost != 0x7) { 105547bdb1caSJani Nikula drm_err(&dev_priv->drm, "Invalid I_boost value %u\n", iboost); 1056379bc100SJani Nikula return; 1057379bc100SJani Nikula } 1058379bc100SJani Nikula 1059f0e86e05SJosé Roberto de Souza _skl_ddi_set_iboost(dev_priv, encoder->port, iboost); 1060379bc100SJani Nikula 1061f0e86e05SJosé Roberto de Souza if (encoder->port == PORT_A && dig_port->max_lanes == 4) 1062379bc100SJani Nikula _skl_ddi_set_iboost(dev_priv, PORT_E, iboost); 1063379bc100SJani Nikula } 1064379bc100SJani Nikula 1065a621860aSVille Syrjälä static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp, 1066a621860aSVille Syrjälä const struct intel_crtc_state *crtc_state) 1067379bc100SJani Nikula { 106853de0a20SVille Syrjälä struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; 1069379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 1070379bc100SJani Nikula int n_entries; 1071379bc100SJani Nikula 1072c40a253bSVille Syrjälä encoder->get_buf_trans(encoder, crtc_state, &n_entries); 1073379bc100SJani Nikula 10741de143ccSPankaj Bharadiya if (drm_WARN_ON(&dev_priv->drm, n_entries < 1)) 1075379bc100SJani Nikula n_entries = 1; 10761de143ccSPankaj Bharadiya if (drm_WARN_ON(&dev_priv->drm, 10771de143ccSPankaj Bharadiya n_entries > ARRAY_SIZE(index_to_dp_signal_levels))) 1078379bc100SJani Nikula n_entries = ARRAY_SIZE(index_to_dp_signal_levels); 1079379bc100SJani Nikula 1080379bc100SJani Nikula return index_to_dp_signal_levels[n_entries - 1] & 1081379bc100SJani Nikula DP_TRAIN_VOLTAGE_SWING_MASK; 1082379bc100SJani Nikula } 1083379bc100SJani Nikula 1084379bc100SJani Nikula /* 1085379bc100SJani Nikula * We assume that the full set of pre-emphasis values can be 1086379bc100SJani Nikula * used on all DDI platforms. Should that change we need to 1087379bc100SJani Nikula * rethink this code. 1088379bc100SJani Nikula */ 108953de0a20SVille Syrjälä static u8 intel_ddi_dp_preemph_max(struct intel_dp *intel_dp) 1090379bc100SJani Nikula { 1091379bc100SJani Nikula return DP_TRAIN_PRE_EMPH_LEVEL_3; 1092379bc100SJani Nikula } 1093379bc100SJani Nikula 10945e7fe4d9SVille Syrjälä static u32 icl_combo_phy_loadgen_select(const struct intel_crtc_state *crtc_state, 10955e7fe4d9SVille Syrjälä int lane) 10965e7fe4d9SVille Syrjälä { 10975e7fe4d9SVille Syrjälä if (crtc_state->port_clock > 600000) 10985e7fe4d9SVille Syrjälä return 0; 10995e7fe4d9SVille Syrjälä 11005e7fe4d9SVille Syrjälä if (crtc_state->lane_count == 4) 11015e7fe4d9SVille Syrjälä return lane >= 1 ? LOADGEN_SELECT : 0; 11025e7fe4d9SVille Syrjälä else 11035e7fe4d9SVille Syrjälä return lane == 1 || lane == 2 ? LOADGEN_SELECT : 0; 11045e7fe4d9SVille Syrjälä } 11055e7fe4d9SVille Syrjälä 1106a8143150SJosé Roberto de Souza static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, 1107193299adSVille Syrjälä const struct intel_crtc_state *crtc_state) 1108379bc100SJani Nikula { 1109a8143150SJosé Roberto de Souza struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 1110e505d764SVille Syrjälä const struct intel_ddi_buf_trans *trans; 1111f0e86e05SJosé Roberto de Souza enum phy phy = intel_port_to_phy(dev_priv, encoder->port); 1112a621860aSVille Syrjälä int n_entries, ln; 1113a621860aSVille Syrjälä u32 val; 1114379bc100SJani Nikula 1115e505d764SVille Syrjälä trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); 1116e505d764SVille Syrjälä if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) 111785da0292SVille Syrjälä return; 1118379bc100SJani Nikula 1119a621860aSVille Syrjälä if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) { 112081619f4aSJosé Roberto de Souza struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 112181619f4aSJosé Roberto de Souza 112281619f4aSJosé Roberto de Souza val = EDP4K2K_MODE_OVRD_EN | EDP4K2K_MODE_OVRD_OPTIMIZED; 1123e505d764SVille Syrjälä intel_dp->hobl_active = is_hobl_buf_trans(trans); 112481619f4aSJosé Roberto de Souza intel_de_rmw(dev_priv, ICL_PORT_CL_DW10(phy), val, 112581619f4aSJosé Roberto de Souza intel_dp->hobl_active ? val : 0); 112681619f4aSJosé Roberto de Souza } 112781619f4aSJosé Roberto de Souza 1128379bc100SJani Nikula /* Set PORT_TX_DW5 */ 1129e6908588SVille Syrjälä val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN(0, phy)); 1130379bc100SJani Nikula val &= ~(SCALING_MODE_SEL_MASK | RTERM_SELECT_MASK | 1131379bc100SJani Nikula TAP2_DISABLE | TAP3_DISABLE); 1132379bc100SJani Nikula val |= SCALING_MODE_SEL(0x2); 1133379bc100SJani Nikula val |= RTERM_SELECT(0x6); 1134379bc100SJani Nikula val |= TAP3_DISABLE; 1135f7960e7fSJani Nikula intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy), val); 1136379bc100SJani Nikula 1137379bc100SJani Nikula /* Program PORT_TX_DW2 */ 1138f20ca899SVille Syrjälä for (ln = 0; ln < 4; ln++) { 113931e914a2SVille Syrjälä int level = intel_ddi_level(encoder, crtc_state, ln); 114031e914a2SVille Syrjälä 1141c1d53cbdSVille Syrjälä intel_de_rmw(dev_priv, ICL_PORT_TX_DW2_LN(ln, phy), 1142c1d53cbdSVille Syrjälä SWING_SEL_UPPER_MASK | SWING_SEL_LOWER_MASK | RCOMP_SCALAR_MASK, 1143c1d53cbdSVille Syrjälä SWING_SEL_UPPER(trans->entries[level].icl.dw2_swing_sel) | 1144c1d53cbdSVille Syrjälä SWING_SEL_LOWER(trans->entries[level].icl.dw2_swing_sel) | 1145c1d53cbdSVille Syrjälä RCOMP_SCALAR(0x98)); 1146f20ca899SVille Syrjälä } 1147379bc100SJani Nikula 1148379bc100SJani Nikula /* Program PORT_TX_DW4 */ 1149379bc100SJani Nikula /* We cannot write to GRP. It would overwrite individual loadgen. */ 1150a1f01768SVille Syrjälä for (ln = 0; ln < 4; ln++) { 115131e914a2SVille Syrjälä int level = intel_ddi_level(encoder, crtc_state, ln); 115231e914a2SVille Syrjälä 1153c1d53cbdSVille Syrjälä intel_de_rmw(dev_priv, ICL_PORT_TX_DW4_LN(ln, phy), 1154c1d53cbdSVille Syrjälä POST_CURSOR_1_MASK | POST_CURSOR_2_MASK | CURSOR_COEFF_MASK, 1155c1d53cbdSVille Syrjälä POST_CURSOR_1(trans->entries[level].icl.dw4_post_cursor_1) | 1156c1d53cbdSVille Syrjälä POST_CURSOR_2(trans->entries[level].icl.dw4_post_cursor_2) | 1157c1d53cbdSVille Syrjälä CURSOR_COEFF(trans->entries[level].icl.dw4_cursor_coeff)); 1158379bc100SJani Nikula } 1159379bc100SJani Nikula 1160379bc100SJani Nikula /* Program PORT_TX_DW7 */ 1161f20ca899SVille Syrjälä for (ln = 0; ln < 4; ln++) { 116231e914a2SVille Syrjälä int level = intel_ddi_level(encoder, crtc_state, ln); 116331e914a2SVille Syrjälä 1164c1d53cbdSVille Syrjälä intel_de_rmw(dev_priv, ICL_PORT_TX_DW7_LN(ln, phy), 1165c1d53cbdSVille Syrjälä N_SCALAR_MASK, 1166c1d53cbdSVille Syrjälä N_SCALAR(trans->entries[level].icl.dw7_n_scalar)); 1167f20ca899SVille Syrjälä } 1168379bc100SJani Nikula } 1169379bc100SJani Nikula 1170193299adSVille Syrjälä static void icl_combo_phy_set_signal_levels(struct intel_encoder *encoder, 1171193299adSVille Syrjälä const struct intel_crtc_state *crtc_state) 1172379bc100SJani Nikula { 1173379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 1174dc867bc7SMatt Roper enum phy phy = intel_port_to_phy(dev_priv, encoder->port); 1175379bc100SJani Nikula u32 val; 11765e7fe4d9SVille Syrjälä int ln; 1177379bc100SJani Nikula 1178379bc100SJani Nikula /* 1179379bc100SJani Nikula * 1. If port type is eDP or DP, 1180379bc100SJani Nikula * set PORT_PCS_DW1 cmnkeeper_enable to 1b, 1181379bc100SJani Nikula * else clear to 0b. 1182379bc100SJani Nikula */ 1183e6908588SVille Syrjälä val = intel_de_read(dev_priv, ICL_PORT_PCS_DW1_LN(0, phy)); 1184a621860aSVille Syrjälä if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) 1185379bc100SJani Nikula val &= ~COMMON_KEEPER_EN; 1186379bc100SJani Nikula else 1187379bc100SJani Nikula val |= COMMON_KEEPER_EN; 1188f7960e7fSJani Nikula intel_de_write(dev_priv, ICL_PORT_PCS_DW1_GRP(phy), val); 1189379bc100SJani Nikula 1190379bc100SJani Nikula /* 2. Program loadgen select */ 1191379bc100SJani Nikula /* 1192e6908588SVille Syrjälä * Program PORT_TX_DW4 depending on Bit rate and used lanes 1193379bc100SJani Nikula * <= 6 GHz and 4 lanes (LN0=0, LN1=1, LN2=1, LN3=1) 1194379bc100SJani Nikula * <= 6 GHz and 1,2 lanes (LN0=0, LN1=1, LN2=1, LN3=0) 1195379bc100SJani Nikula * > 6 GHz (LN0=0, LN1=0, LN2=0, LN3=0) 1196379bc100SJani Nikula */ 1197a1f01768SVille Syrjälä for (ln = 0; ln < 4; ln++) { 1198c1d53cbdSVille Syrjälä intel_de_rmw(dev_priv, ICL_PORT_TX_DW4_LN(ln, phy), 1199c1d53cbdSVille Syrjälä LOADGEN_SELECT, 1200c1d53cbdSVille Syrjälä icl_combo_phy_loadgen_select(crtc_state, ln)); 1201379bc100SJani Nikula } 1202379bc100SJani Nikula 1203379bc100SJani Nikula /* 3. Set PORT_CL_DW5 SUS Clock Config to 11b */ 1204c1d53cbdSVille Syrjälä intel_de_rmw(dev_priv, ICL_PORT_CL_DW5(phy), 1205c1d53cbdSVille Syrjälä 0, SUS_CLOCK_CONFIG); 1206379bc100SJani Nikula 1207379bc100SJani Nikula /* 4. Clear training enable to change swing values */ 1208e6908588SVille Syrjälä val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN(0, phy)); 1209379bc100SJani Nikula val &= ~TX_TRAINING_EN; 1210f7960e7fSJani Nikula intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy), val); 1211379bc100SJani Nikula 1212379bc100SJani Nikula /* 5. Program swing and de-emphasis */ 1213193299adSVille Syrjälä icl_ddi_combo_vswing_program(encoder, crtc_state); 1214379bc100SJani Nikula 1215379bc100SJani Nikula /* 6. Set training enable to trigger update */ 1216e6908588SVille Syrjälä val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN(0, phy)); 1217379bc100SJani Nikula val |= TX_TRAINING_EN; 1218f7960e7fSJani Nikula intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy), val); 1219379bc100SJani Nikula } 1220379bc100SJani Nikula 1221193299adSVille Syrjälä static void icl_mg_phy_set_signal_levels(struct intel_encoder *encoder, 1222193299adSVille Syrjälä const struct intel_crtc_state *crtc_state) 1223379bc100SJani Nikula { 1224379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 1225f21e8b80SJosé Roberto de Souza enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port); 1226e505d764SVille Syrjälä const struct intel_ddi_buf_trans *trans; 1227a621860aSVille Syrjälä int n_entries, ln; 1228379bc100SJani Nikula 122911a89708SImre Deak if (intel_tc_port_in_tbt_alt_mode(enc_to_dig_port(encoder))) 1230f8c6b615SVille Syrjälä return; 1231f8c6b615SVille Syrjälä 1232e505d764SVille Syrjälä trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); 1233e505d764SVille Syrjälä if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) 123485da0292SVille Syrjälä return; 1235379bc100SJani Nikula 1236379bc100SJani Nikula for (ln = 0; ln < 2; ln++) { 1237d4e0f163SVille Syrjälä intel_de_rmw(dev_priv, MG_TX1_LINK_PARAMS(ln, tc_port), 1238d4e0f163SVille Syrjälä CRI_USE_FS32, 0); 1239d4e0f163SVille Syrjälä intel_de_rmw(dev_priv, MG_TX2_LINK_PARAMS(ln, tc_port), 1240d4e0f163SVille Syrjälä CRI_USE_FS32, 0); 1241379bc100SJani Nikula } 1242379bc100SJani Nikula 1243379bc100SJani Nikula /* Program MG_TX_SWINGCTRL with values from vswing table */ 1244379bc100SJani Nikula for (ln = 0; ln < 2; ln++) { 1245305448e5SVille Syrjälä int level; 1246305448e5SVille Syrjälä 1247305448e5SVille Syrjälä level = intel_ddi_level(encoder, crtc_state, 2*ln+0); 1248305448e5SVille Syrjälä 1249d4e0f163SVille Syrjälä intel_de_rmw(dev_priv, MG_TX1_SWINGCTRL(ln, tc_port), 1250d4e0f163SVille Syrjälä CRI_TXDEEMPH_OVERRIDE_17_12_MASK, 1251d4e0f163SVille Syrjälä CRI_TXDEEMPH_OVERRIDE_17_12(trans->entries[level].mg.cri_txdeemph_override_17_12)); 1252379bc100SJani Nikula 1253305448e5SVille Syrjälä level = intel_ddi_level(encoder, crtc_state, 2*ln+1); 1254305448e5SVille Syrjälä 1255d4e0f163SVille Syrjälä intel_de_rmw(dev_priv, MG_TX2_SWINGCTRL(ln, tc_port), 1256d4e0f163SVille Syrjälä CRI_TXDEEMPH_OVERRIDE_17_12_MASK, 1257d4e0f163SVille Syrjälä CRI_TXDEEMPH_OVERRIDE_17_12(trans->entries[level].mg.cri_txdeemph_override_17_12)); 1258379bc100SJani Nikula } 1259379bc100SJani Nikula 1260379bc100SJani Nikula /* Program MG_TX_DRVCTRL with values from vswing table */ 1261379bc100SJani Nikula for (ln = 0; ln < 2; ln++) { 1262305448e5SVille Syrjälä int level; 1263305448e5SVille Syrjälä 1264305448e5SVille Syrjälä level = intel_ddi_level(encoder, crtc_state, 2*ln+0); 1265305448e5SVille Syrjälä 1266d4e0f163SVille Syrjälä intel_de_rmw(dev_priv, MG_TX1_DRVCTRL(ln, tc_port), 1267d4e0f163SVille Syrjälä CRI_TXDEEMPH_OVERRIDE_11_6_MASK | 1268d4e0f163SVille Syrjälä CRI_TXDEEMPH_OVERRIDE_5_0_MASK, 1269d4e0f163SVille Syrjälä CRI_TXDEEMPH_OVERRIDE_11_6(trans->entries[level].mg.cri_txdeemph_override_11_6) | 1270d4e0f163SVille Syrjälä CRI_TXDEEMPH_OVERRIDE_5_0(trans->entries[level].mg.cri_txdeemph_override_5_0) | 1271d4e0f163SVille Syrjälä CRI_TXDEEMPH_OVERRIDE_EN); 1272379bc100SJani Nikula 1273305448e5SVille Syrjälä level = intel_ddi_level(encoder, crtc_state, 2*ln+1); 1274305448e5SVille Syrjälä 1275d4e0f163SVille Syrjälä intel_de_rmw(dev_priv, MG_TX2_DRVCTRL(ln, tc_port), 1276d4e0f163SVille Syrjälä CRI_TXDEEMPH_OVERRIDE_11_6_MASK | 1277d4e0f163SVille Syrjälä CRI_TXDEEMPH_OVERRIDE_5_0_MASK, 1278d4e0f163SVille Syrjälä CRI_TXDEEMPH_OVERRIDE_11_6(trans->entries[level].mg.cri_txdeemph_override_11_6) | 1279d4e0f163SVille Syrjälä CRI_TXDEEMPH_OVERRIDE_5_0(trans->entries[level].mg.cri_txdeemph_override_5_0) | 1280d4e0f163SVille Syrjälä CRI_TXDEEMPH_OVERRIDE_EN); 1281379bc100SJani Nikula 1282379bc100SJani Nikula /* FIXME: Program CRI_LOADGEN_SEL after the spec is updated */ 1283379bc100SJani Nikula } 1284379bc100SJani Nikula 1285379bc100SJani Nikula /* 1286379bc100SJani Nikula * Program MG_CLKHUB<LN, port being used> with value from frequency table 1287379bc100SJani Nikula * In case of Legacy mode on MG PHY, both TX1 and TX2 enabled so use the 1288379bc100SJani Nikula * values from table for which TX1 and TX2 enabled. 1289379bc100SJani Nikula */ 1290379bc100SJani Nikula for (ln = 0; ln < 2; ln++) { 1291d4e0f163SVille Syrjälä intel_de_rmw(dev_priv, MG_CLKHUB(ln, tc_port), 1292d4e0f163SVille Syrjälä CFG_LOW_RATE_LKREN_EN, 1293d4e0f163SVille Syrjälä crtc_state->port_clock < 300000 ? CFG_LOW_RATE_LKREN_EN : 0); 1294379bc100SJani Nikula } 1295379bc100SJani Nikula 1296379bc100SJani Nikula /* Program the MG_TX_DCC<LN, port being used> based on the link frequency */ 1297379bc100SJani Nikula for (ln = 0; ln < 2; ln++) { 1298d4e0f163SVille Syrjälä intel_de_rmw(dev_priv, MG_TX1_DCC(ln, tc_port), 1299d4e0f163SVille Syrjälä CFG_AMI_CK_DIV_OVERRIDE_VAL_MASK | 1300d4e0f163SVille Syrjälä CFG_AMI_CK_DIV_OVERRIDE_EN, 1301d4e0f163SVille Syrjälä crtc_state->port_clock > 500000 ? 1302d4e0f163SVille Syrjälä CFG_AMI_CK_DIV_OVERRIDE_VAL(1) | 1303d4e0f163SVille Syrjälä CFG_AMI_CK_DIV_OVERRIDE_EN : 0); 1304379bc100SJani Nikula 1305d4e0f163SVille Syrjälä intel_de_rmw(dev_priv, MG_TX2_DCC(ln, tc_port), 1306d4e0f163SVille Syrjälä CFG_AMI_CK_DIV_OVERRIDE_VAL_MASK | 1307d4e0f163SVille Syrjälä CFG_AMI_CK_DIV_OVERRIDE_EN, 1308d4e0f163SVille Syrjälä crtc_state->port_clock > 500000 ? 1309d4e0f163SVille Syrjälä CFG_AMI_CK_DIV_OVERRIDE_VAL(1) | 1310d4e0f163SVille Syrjälä CFG_AMI_CK_DIV_OVERRIDE_EN : 0); 1311379bc100SJani Nikula } 1312379bc100SJani Nikula 1313379bc100SJani Nikula /* Program MG_TX_PISO_READLOAD with values from vswing table */ 1314379bc100SJani Nikula for (ln = 0; ln < 2; ln++) { 1315d4e0f163SVille Syrjälä intel_de_rmw(dev_priv, MG_TX1_PISO_READLOAD(ln, tc_port), 1316d4e0f163SVille Syrjälä 0, CRI_CALCINIT); 1317d4e0f163SVille Syrjälä intel_de_rmw(dev_priv, MG_TX2_PISO_READLOAD(ln, tc_port), 1318d4e0f163SVille Syrjälä 0, CRI_CALCINIT); 1319379bc100SJani Nikula } 1320379bc100SJani Nikula } 1321379bc100SJani Nikula 1322193299adSVille Syrjälä static void tgl_dkl_phy_set_signal_levels(struct intel_encoder *encoder, 1323193299adSVille Syrjälä const struct intel_crtc_state *crtc_state) 1324978c3e53SClinton A Taylor { 1325978c3e53SClinton A Taylor struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 1326978c3e53SClinton A Taylor enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port); 1327e505d764SVille Syrjälä const struct intel_ddi_buf_trans *trans; 1328a621860aSVille Syrjälä int n_entries, ln; 1329978c3e53SClinton A Taylor 133011a89708SImre Deak if (intel_tc_port_in_tbt_alt_mode(enc_to_dig_port(encoder))) 1331f8c6b615SVille Syrjälä return; 1332f8c6b615SVille Syrjälä 1333e505d764SVille Syrjälä trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); 1334e505d764SVille Syrjälä if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) 133585da0292SVille Syrjälä return; 1336978c3e53SClinton A Taylor 1337978c3e53SClinton A Taylor for (ln = 0; ln < 2; ln++) { 1338a905ced6SVille Syrjälä int level; 1339a905ced6SVille Syrjälä 1340b8ed5533SImre Deak intel_dkl_phy_write(dev_priv, DKL_TX_PMD_LANE_SUS(tc_port, ln), 0); 13412d69c42eSJosé Roberto de Souza 1342a905ced6SVille Syrjälä level = intel_ddi_level(encoder, crtc_state, 2*ln+0); 1343a905ced6SVille Syrjälä 1344b8ed5533SImre Deak intel_dkl_phy_rmw(dev_priv, DKL_TX_DPCNTL0(tc_port, ln), 1345c86e1873SVille Syrjälä DKL_TX_PRESHOOT_COEFF_MASK | 1346a905ced6SVille Syrjälä DKL_TX_DE_EMPAHSIS_COEFF_MASK | 1347c86e1873SVille Syrjälä DKL_TX_VSWING_CONTROL_MASK, 1348c86e1873SVille Syrjälä DKL_TX_PRESHOOT_COEFF(trans->entries[level].dkl.preshoot) | 1349a905ced6SVille Syrjälä DKL_TX_DE_EMPHASIS_COEFF(trans->entries[level].dkl.de_emphasis) | 1350c86e1873SVille Syrjälä DKL_TX_VSWING_CONTROL(trans->entries[level].dkl.vswing)); 1351978c3e53SClinton A Taylor 1352a905ced6SVille Syrjälä level = intel_ddi_level(encoder, crtc_state, 2*ln+1); 1353a905ced6SVille Syrjälä 1354b8ed5533SImre Deak intel_dkl_phy_rmw(dev_priv, DKL_TX_DPCNTL1(tc_port, ln), 1355c86e1873SVille Syrjälä DKL_TX_PRESHOOT_COEFF_MASK | 1356a905ced6SVille Syrjälä DKL_TX_DE_EMPAHSIS_COEFF_MASK | 1357c86e1873SVille Syrjälä DKL_TX_VSWING_CONTROL_MASK, 1358c86e1873SVille Syrjälä DKL_TX_PRESHOOT_COEFF(trans->entries[level].dkl.preshoot) | 1359a905ced6SVille Syrjälä DKL_TX_DE_EMPHASIS_COEFF(trans->entries[level].dkl.de_emphasis) | 1360c86e1873SVille Syrjälä DKL_TX_VSWING_CONTROL(trans->entries[level].dkl.vswing)); 1361978c3e53SClinton A Taylor 1362b8ed5533SImre Deak intel_dkl_phy_rmw(dev_priv, DKL_TX_DPCNTL2(tc_port, ln), 1363c86e1873SVille Syrjälä DKL_TX_DP20BITMODE, 0); 13645ff59dddSJosé Roberto de Souza 13655ff59dddSJosé Roberto de Souza if (IS_ALDERLAKE_P(dev_priv)) { 13665ff59dddSJosé Roberto de Souza u32 val; 13675ff59dddSJosé Roberto de Souza 13685ff59dddSJosé Roberto de Souza if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { 13695ff59dddSJosé Roberto de Souza if (ln == 0) { 13705ff59dddSJosé Roberto de Souza val = DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1(0); 13715ff59dddSJosé Roberto de Souza val |= DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2(2); 13725ff59dddSJosé Roberto de Souza } else { 13735ff59dddSJosé Roberto de Souza val = DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1(3); 13745ff59dddSJosé Roberto de Souza val |= DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2(3); 13755ff59dddSJosé Roberto de Souza } 13765ff59dddSJosé Roberto de Souza } else { 13775ff59dddSJosé Roberto de Souza val = DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1(0); 13785ff59dddSJosé Roberto de Souza val |= DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2(0); 13795ff59dddSJosé Roberto de Souza } 13805ff59dddSJosé Roberto de Souza 1381b8ed5533SImre Deak intel_dkl_phy_rmw(dev_priv, DKL_TX_DPCNTL2(tc_port, ln), 13825ff59dddSJosé Roberto de Souza DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1_MASK | 13835ff59dddSJosé Roberto de Souza DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2_MASK, 13845ff59dddSJosé Roberto de Souza val); 13855ff59dddSJosé Roberto de Souza } 1386978c3e53SClinton A Taylor } 1387978c3e53SClinton A Taylor } 1388978c3e53SClinton A Taylor 1389a621860aSVille Syrjälä static int translate_signal_level(struct intel_dp *intel_dp, 1390a621860aSVille Syrjälä u8 signal_levels) 1391379bc100SJani Nikula { 13928b4f2137SPankaj Bharadiya struct drm_i915_private *i915 = dp_to_i915(intel_dp); 1393379bc100SJani Nikula int i; 1394379bc100SJani Nikula 1395379bc100SJani Nikula for (i = 0; i < ARRAY_SIZE(index_to_dp_signal_levels); i++) { 1396379bc100SJani Nikula if (index_to_dp_signal_levels[i] == signal_levels) 1397379bc100SJani Nikula return i; 1398379bc100SJani Nikula } 1399379bc100SJani Nikula 14008b4f2137SPankaj Bharadiya drm_WARN(&i915->drm, 1, 14018b4f2137SPankaj Bharadiya "Unsupported voltage swing/pre-emphasis level: 0x%x\n", 1402379bc100SJani Nikula signal_levels); 1403379bc100SJani Nikula 1404379bc100SJani Nikula return 0; 1405379bc100SJani Nikula } 1406379bc100SJani Nikula 14075c31e9d0SJani Nikula static int intel_ddi_dp_level(struct intel_dp *intel_dp, 14085c31e9d0SJani Nikula const struct intel_crtc_state *crtc_state, 14095c31e9d0SJani Nikula int lane) 1410379bc100SJani Nikula { 1411d0920a45SVille Syrjälä u8 train_set = intel_dp->train_set[lane]; 14125c31e9d0SJani Nikula 14135c31e9d0SJani Nikula if (intel_dp_is_uhbr(crtc_state)) { 14145c31e9d0SJani Nikula return train_set & DP_TX_FFE_PRESET_VALUE_MASK; 14155c31e9d0SJani Nikula } else { 1416a621860aSVille Syrjälä u8 signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK | 1417379bc100SJani Nikula DP_TRAIN_PRE_EMPHASIS_MASK); 1418379bc100SJani Nikula 14198b4f2137SPankaj Bharadiya return translate_signal_level(intel_dp, signal_levels); 1420379bc100SJani Nikula } 14215c31e9d0SJani Nikula } 1422379bc100SJani Nikula 1423193299adSVille Syrjälä int intel_ddi_level(struct intel_encoder *encoder, 1424d0920a45SVille Syrjälä const struct intel_crtc_state *crtc_state, 1425d0920a45SVille Syrjälä int lane) 1426a046a0daSMatt Roper { 14272c63e0f9SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 14282c63e0f9SVille Syrjälä const struct intel_ddi_buf_trans *trans; 14292c63e0f9SVille Syrjälä int level, n_entries; 14302c63e0f9SVille Syrjälä 14312c63e0f9SVille Syrjälä trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); 14322c63e0f9SVille Syrjälä if (drm_WARN_ON_ONCE(&i915->drm, !trans)) 14332c63e0f9SVille Syrjälä return 0; 14342c63e0f9SVille Syrjälä 1435e722ab8bSVille Syrjälä if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) 14363e022c1fSVille Syrjälä level = intel_ddi_hdmi_level(encoder, trans); 1437e722ab8bSVille Syrjälä else 14385c31e9d0SJani Nikula level = intel_ddi_dp_level(enc_to_intel_dp(encoder), crtc_state, 14395c31e9d0SJani Nikula lane); 14402c63e0f9SVille Syrjälä 14412c63e0f9SVille Syrjälä if (drm_WARN_ON_ONCE(&i915->drm, level >= n_entries)) 14422c63e0f9SVille Syrjälä level = n_entries - 1; 14432c63e0f9SVille Syrjälä 14442c63e0f9SVille Syrjälä return level; 1445e722ab8bSVille Syrjälä } 1446e722ab8bSVille Syrjälä 1447e722ab8bSVille Syrjälä static void 1448e722ab8bSVille Syrjälä hsw_set_signal_levels(struct intel_encoder *encoder, 1449a621860aSVille Syrjälä const struct intel_crtc_state *crtc_state) 1450fb83f72cSVille Syrjälä { 1451fb83f72cSVille Syrjälä struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 1452e722ab8bSVille Syrjälä struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 1453d0920a45SVille Syrjälä int level = intel_ddi_level(encoder, crtc_state, 0); 1454fb83f72cSVille Syrjälä enum port port = encoder->port; 1455fb83f72cSVille Syrjälä u32 signal_levels; 1456fb83f72cSVille Syrjälä 1457e722ab8bSVille Syrjälä if (has_iboost(dev_priv)) 1458e722ab8bSVille Syrjälä skl_ddi_set_iboost(encoder, crtc_state, level); 1459e722ab8bSVille Syrjälä 1460e722ab8bSVille Syrjälä /* HDMI ignores the rest */ 1461e722ab8bSVille Syrjälä if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) 1462e722ab8bSVille Syrjälä return; 1463e722ab8bSVille Syrjälä 1464fb83f72cSVille Syrjälä signal_levels = DDI_BUF_TRANS_SELECT(level); 1465fb83f72cSVille Syrjälä 1466fb83f72cSVille Syrjälä drm_dbg_kms(&dev_priv->drm, "Using signal levels %08x\n", 1467fb83f72cSVille Syrjälä signal_levels); 1468fb83f72cSVille Syrjälä 1469fb83f72cSVille Syrjälä intel_dp->DP &= ~DDI_BUF_EMP_MASK; 1470fb83f72cSVille Syrjälä intel_dp->DP |= signal_levels; 1471fb83f72cSVille Syrjälä 1472fb83f72cSVille Syrjälä intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP); 1473fb83f72cSVille Syrjälä intel_de_posting_read(dev_priv, DDI_BUF_CTL(port)); 1474379bc100SJani Nikula } 1475379bc100SJani Nikula 14764da27d5dSLucas De Marchi static void _icl_ddi_enable_clock(struct drm_i915_private *i915, i915_reg_t reg, 14779c6a5c35SVille Syrjälä u32 clk_sel_mask, u32 clk_sel, u32 clk_off) 14789c6a5c35SVille Syrjälä { 147936d225f3SJani Nikula mutex_lock(&i915->display.dpll.lock); 14809c6a5c35SVille Syrjälä 14819c6a5c35SVille Syrjälä intel_de_rmw(i915, reg, clk_sel_mask, clk_sel); 14829c6a5c35SVille Syrjälä 14839c6a5c35SVille Syrjälä /* 14849c6a5c35SVille Syrjälä * "This step and the step before must be 14859c6a5c35SVille Syrjälä * done with separate register writes." 14869c6a5c35SVille Syrjälä */ 14879c6a5c35SVille Syrjälä intel_de_rmw(i915, reg, clk_off, 0); 14889c6a5c35SVille Syrjälä 148936d225f3SJani Nikula mutex_unlock(&i915->display.dpll.lock); 14909c6a5c35SVille Syrjälä } 14919c6a5c35SVille Syrjälä 14924da27d5dSLucas De Marchi static void _icl_ddi_disable_clock(struct drm_i915_private *i915, i915_reg_t reg, 14939c6a5c35SVille Syrjälä u32 clk_off) 14949c6a5c35SVille Syrjälä { 149536d225f3SJani Nikula mutex_lock(&i915->display.dpll.lock); 14969c6a5c35SVille Syrjälä 14979c6a5c35SVille Syrjälä intel_de_rmw(i915, reg, 0, clk_off); 14989c6a5c35SVille Syrjälä 149936d225f3SJani Nikula mutex_unlock(&i915->display.dpll.lock); 15009c6a5c35SVille Syrjälä } 15019c6a5c35SVille Syrjälä 15024da27d5dSLucas De Marchi static bool _icl_ddi_is_clock_enabled(struct drm_i915_private *i915, i915_reg_t reg, 15030fbd8694SVille Syrjälä u32 clk_off) 15040fbd8694SVille Syrjälä { 15050fbd8694SVille Syrjälä return !(intel_de_read(i915, reg) & clk_off); 15060fbd8694SVille Syrjälä } 15070fbd8694SVille Syrjälä 1508351221ffSVille Syrjälä static struct intel_shared_dpll * 15094da27d5dSLucas De Marchi _icl_ddi_get_pll(struct drm_i915_private *i915, i915_reg_t reg, 1510351221ffSVille Syrjälä u32 clk_sel_mask, u32 clk_sel_shift) 1511351221ffSVille Syrjälä { 1512351221ffSVille Syrjälä enum intel_dpll_id id; 1513351221ffSVille Syrjälä 1514351221ffSVille Syrjälä id = (intel_de_read(i915, reg) & clk_sel_mask) >> clk_sel_shift; 1515351221ffSVille Syrjälä 1516351221ffSVille Syrjälä return intel_get_shared_dpll_by_id(i915, id); 1517351221ffSVille Syrjälä } 1518351221ffSVille Syrjälä 151940b316d4SVille Syrjälä static void adls_ddi_enable_clock(struct intel_encoder *encoder, 152040b316d4SVille Syrjälä const struct intel_crtc_state *crtc_state) 152140b316d4SVille Syrjälä { 152240b316d4SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 152340b316d4SVille Syrjälä const struct intel_shared_dpll *pll = crtc_state->shared_dpll; 152440b316d4SVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 152540b316d4SVille Syrjälä 152640b316d4SVille Syrjälä if (drm_WARN_ON(&i915->drm, !pll)) 152740b316d4SVille Syrjälä return; 152840b316d4SVille Syrjälä 15294da27d5dSLucas De Marchi _icl_ddi_enable_clock(i915, ADLS_DPCLKA_CFGCR(phy), 153040b316d4SVille Syrjälä ADLS_DPCLKA_CFGCR_DDI_CLK_SEL_MASK(phy), 153140b316d4SVille Syrjälä pll->info->id << ADLS_DPCLKA_CFGCR_DDI_SHIFT(phy), 153240b316d4SVille Syrjälä ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); 153340b316d4SVille Syrjälä } 153440b316d4SVille Syrjälä 153540b316d4SVille Syrjälä static void adls_ddi_disable_clock(struct intel_encoder *encoder) 153640b316d4SVille Syrjälä { 153740b316d4SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 153840b316d4SVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 153940b316d4SVille Syrjälä 15404da27d5dSLucas De Marchi _icl_ddi_disable_clock(i915, ADLS_DPCLKA_CFGCR(phy), 154140b316d4SVille Syrjälä ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); 154240b316d4SVille Syrjälä } 154340b316d4SVille Syrjälä 15440fbd8694SVille Syrjälä static bool adls_ddi_is_clock_enabled(struct intel_encoder *encoder) 15450fbd8694SVille Syrjälä { 15460fbd8694SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 15470fbd8694SVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 15480fbd8694SVille Syrjälä 15494da27d5dSLucas De Marchi return _icl_ddi_is_clock_enabled(i915, ADLS_DPCLKA_CFGCR(phy), 15500fbd8694SVille Syrjälä ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); 15510fbd8694SVille Syrjälä } 15520fbd8694SVille Syrjälä 1553351221ffSVille Syrjälä static struct intel_shared_dpll *adls_ddi_get_pll(struct intel_encoder *encoder) 1554351221ffSVille Syrjälä { 1555351221ffSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 1556351221ffSVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 1557351221ffSVille Syrjälä 15584da27d5dSLucas De Marchi return _icl_ddi_get_pll(i915, ADLS_DPCLKA_CFGCR(phy), 1559351221ffSVille Syrjälä ADLS_DPCLKA_CFGCR_DDI_CLK_SEL_MASK(phy), 1560351221ffSVille Syrjälä ADLS_DPCLKA_CFGCR_DDI_SHIFT(phy)); 1561351221ffSVille Syrjälä } 1562351221ffSVille Syrjälä 156340b316d4SVille Syrjälä static void rkl_ddi_enable_clock(struct intel_encoder *encoder, 156440b316d4SVille Syrjälä const struct intel_crtc_state *crtc_state) 156540b316d4SVille Syrjälä { 156640b316d4SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 156740b316d4SVille Syrjälä const struct intel_shared_dpll *pll = crtc_state->shared_dpll; 156840b316d4SVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 156940b316d4SVille Syrjälä 157040b316d4SVille Syrjälä if (drm_WARN_ON(&i915->drm, !pll)) 157140b316d4SVille Syrjälä return; 157240b316d4SVille Syrjälä 15734da27d5dSLucas De Marchi _icl_ddi_enable_clock(i915, ICL_DPCLKA_CFGCR0, 157440b316d4SVille Syrjälä RKL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy), 157540b316d4SVille Syrjälä RKL_DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, phy), 157640b316d4SVille Syrjälä RKL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); 157740b316d4SVille Syrjälä } 157840b316d4SVille Syrjälä 157940b316d4SVille Syrjälä static void rkl_ddi_disable_clock(struct intel_encoder *encoder) 158040b316d4SVille Syrjälä { 158140b316d4SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 158240b316d4SVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 158340b316d4SVille Syrjälä 15844da27d5dSLucas De Marchi _icl_ddi_disable_clock(i915, ICL_DPCLKA_CFGCR0, 158540b316d4SVille Syrjälä RKL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); 158640b316d4SVille Syrjälä } 158740b316d4SVille Syrjälä 15880fbd8694SVille Syrjälä static bool rkl_ddi_is_clock_enabled(struct intel_encoder *encoder) 15890fbd8694SVille Syrjälä { 15900fbd8694SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 15910fbd8694SVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 15920fbd8694SVille Syrjälä 15934da27d5dSLucas De Marchi return _icl_ddi_is_clock_enabled(i915, ICL_DPCLKA_CFGCR0, 15940fbd8694SVille Syrjälä RKL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); 15950fbd8694SVille Syrjälä } 15960fbd8694SVille Syrjälä 1597351221ffSVille Syrjälä static struct intel_shared_dpll *rkl_ddi_get_pll(struct intel_encoder *encoder) 1598351221ffSVille Syrjälä { 1599351221ffSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 1600351221ffSVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 1601351221ffSVille Syrjälä 16024da27d5dSLucas De Marchi return _icl_ddi_get_pll(i915, ICL_DPCLKA_CFGCR0, 1603351221ffSVille Syrjälä RKL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy), 1604351221ffSVille Syrjälä RKL_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(phy)); 1605351221ffSVille Syrjälä } 1606351221ffSVille Syrjälä 160735bb6b1aSVille Syrjälä static void dg1_ddi_enable_clock(struct intel_encoder *encoder, 160811ffe972SLucas De Marchi const struct intel_crtc_state *crtc_state) 160911ffe972SLucas De Marchi { 161097a24a70SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 16119c6a5c35SVille Syrjälä const struct intel_shared_dpll *pll = crtc_state->shared_dpll; 161297a24a70SVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 161311ffe972SLucas De Marchi 161497a24a70SVille Syrjälä if (drm_WARN_ON(&i915->drm, !pll)) 1615f67a008eSVille Syrjälä return; 1616f67a008eSVille Syrjälä 161711ffe972SLucas De Marchi /* 161811ffe972SLucas De Marchi * If we fail this, something went very wrong: first 2 PLLs should be 161911ffe972SLucas De Marchi * used by first 2 phys and last 2 PLLs by last phys 162011ffe972SLucas De Marchi */ 162197a24a70SVille Syrjälä if (drm_WARN_ON(&i915->drm, 162211ffe972SLucas De Marchi (pll->info->id < DPLL_ID_DG1_DPLL2 && phy >= PHY_C) || 162311ffe972SLucas De Marchi (pll->info->id >= DPLL_ID_DG1_DPLL2 && phy < PHY_C))) 162411ffe972SLucas De Marchi return; 162511ffe972SLucas De Marchi 16264da27d5dSLucas De Marchi _icl_ddi_enable_clock(i915, DG1_DPCLKA_CFGCR0(phy), 16277815ed88SVille Syrjälä DG1_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy), 16289c6a5c35SVille Syrjälä DG1_DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, phy), 16299c6a5c35SVille Syrjälä DG1_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); 163011ffe972SLucas De Marchi } 163111ffe972SLucas De Marchi 163235bb6b1aSVille Syrjälä static void dg1_ddi_disable_clock(struct intel_encoder *encoder) 163335bb6b1aSVille Syrjälä { 163497a24a70SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 163597a24a70SVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 163635bb6b1aSVille Syrjälä 16374da27d5dSLucas De Marchi _icl_ddi_disable_clock(i915, DG1_DPCLKA_CFGCR0(phy), 16389c6a5c35SVille Syrjälä DG1_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); 163935bb6b1aSVille Syrjälä } 164035bb6b1aSVille Syrjälä 16410fbd8694SVille Syrjälä static bool dg1_ddi_is_clock_enabled(struct intel_encoder *encoder) 16420fbd8694SVille Syrjälä { 16430fbd8694SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 16440fbd8694SVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 16450fbd8694SVille Syrjälä 16464da27d5dSLucas De Marchi return _icl_ddi_is_clock_enabled(i915, DG1_DPCLKA_CFGCR0(phy), 16470fbd8694SVille Syrjälä DG1_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); 16480fbd8694SVille Syrjälä } 16490fbd8694SVille Syrjälä 1650351221ffSVille Syrjälä static struct intel_shared_dpll *dg1_ddi_get_pll(struct intel_encoder *encoder) 1651351221ffSVille Syrjälä { 1652351221ffSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 1653351221ffSVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 16543352d86dSJosé Roberto de Souza enum intel_dpll_id id; 16553352d86dSJosé Roberto de Souza u32 val; 1656351221ffSVille Syrjälä 16573352d86dSJosé Roberto de Souza val = intel_de_read(i915, DG1_DPCLKA_CFGCR0(phy)); 16583352d86dSJosé Roberto de Souza val &= DG1_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy); 16593352d86dSJosé Roberto de Souza val >>= DG1_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(phy); 16603352d86dSJosé Roberto de Souza id = val; 16613352d86dSJosé Roberto de Souza 16623352d86dSJosé Roberto de Souza /* 16633352d86dSJosé Roberto de Souza * _DG1_DPCLKA0_CFGCR0 maps between DPLL 0 and 1 with one bit for phy A 16643352d86dSJosé Roberto de Souza * and B while _DG1_DPCLKA1_CFGCR0 maps between DPLL 2 and 3 with one 16653352d86dSJosé Roberto de Souza * bit for phy C and D. 16663352d86dSJosé Roberto de Souza */ 16673352d86dSJosé Roberto de Souza if (phy >= PHY_C) 16683352d86dSJosé Roberto de Souza id += DPLL_ID_DG1_DPLL2; 16693352d86dSJosé Roberto de Souza 16703352d86dSJosé Roberto de Souza return intel_get_shared_dpll_by_id(i915, id); 1671351221ffSVille Syrjälä } 1672351221ffSVille Syrjälä 167336ecb0ecSVille Syrjälä static void icl_ddi_combo_enable_clock(struct intel_encoder *encoder, 1674379bc100SJani Nikula const struct intel_crtc_state *crtc_state) 1675379bc100SJani Nikula { 167697a24a70SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 16779c6a5c35SVille Syrjälä const struct intel_shared_dpll *pll = crtc_state->shared_dpll; 167897a24a70SVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 1679cd803bb4SMatt Roper 168097a24a70SVille Syrjälä if (drm_WARN_ON(&i915->drm, !pll)) 1681f67a008eSVille Syrjälä return; 1682f67a008eSVille Syrjälä 16834da27d5dSLucas De Marchi _icl_ddi_enable_clock(i915, ICL_DPCLKA_CFGCR0, 168440b316d4SVille Syrjälä ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy), 168540b316d4SVille Syrjälä ICL_DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, phy), 168640b316d4SVille Syrjälä ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); 1687379bc100SJani Nikula } 1688379bc100SJani Nikula 168936ecb0ecSVille Syrjälä static void icl_ddi_combo_disable_clock(struct intel_encoder *encoder) 1690379bc100SJani Nikula { 169197a24a70SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 169297a24a70SVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 1693379bc100SJani Nikula 16944da27d5dSLucas De Marchi _icl_ddi_disable_clock(i915, ICL_DPCLKA_CFGCR0, 169540b316d4SVille Syrjälä ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); 1696379bc100SJani Nikula } 1697379bc100SJani Nikula 16980fbd8694SVille Syrjälä static bool icl_ddi_combo_is_clock_enabled(struct intel_encoder *encoder) 16990fbd8694SVille Syrjälä { 17000fbd8694SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 17010fbd8694SVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 17020fbd8694SVille Syrjälä 17034da27d5dSLucas De Marchi return _icl_ddi_is_clock_enabled(i915, ICL_DPCLKA_CFGCR0, 17040fbd8694SVille Syrjälä ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); 17050fbd8694SVille Syrjälä } 17060fbd8694SVille Syrjälä 1707351221ffSVille Syrjälä struct intel_shared_dpll *icl_ddi_combo_get_pll(struct intel_encoder *encoder) 1708351221ffSVille Syrjälä { 1709351221ffSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 1710351221ffSVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 1711351221ffSVille Syrjälä 17124da27d5dSLucas De Marchi return _icl_ddi_get_pll(i915, ICL_DPCLKA_CFGCR0, 1713351221ffSVille Syrjälä ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy), 1714351221ffSVille Syrjälä ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(phy)); 1715351221ffSVille Syrjälä } 1716351221ffSVille Syrjälä 171736ecb0ecSVille Syrjälä static void jsl_ddi_tc_enable_clock(struct intel_encoder *encoder, 1718379bc100SJani Nikula const struct intel_crtc_state *crtc_state) 1719379bc100SJani Nikula { 172036ecb0ecSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 1721379bc100SJani Nikula const struct intel_shared_dpll *pll = crtc_state->shared_dpll; 172236ecb0ecSVille Syrjälä enum port port = encoder->port; 1723379bc100SJani Nikula 172436ecb0ecSVille Syrjälä if (drm_WARN_ON(&i915->drm, !pll)) 1725379bc100SJani Nikula return; 1726379bc100SJani Nikula 1727c2052d6eSJosé Roberto de Souza /* 172836ecb0ecSVille Syrjälä * "For DDIC and DDID, program DDI_CLK_SEL to map the MG clock to the port. 172936ecb0ecSVille Syrjälä * MG does not exist, but the programming is required to ungate DDIC and DDID." 1730c2052d6eSJosé Roberto de Souza */ 173136ecb0ecSVille Syrjälä intel_de_write(i915, DDI_CLK_SEL(port), DDI_CLK_SEL_MG); 173236ecb0ecSVille Syrjälä 173336ecb0ecSVille Syrjälä icl_ddi_combo_enable_clock(encoder, crtc_state); 1734379bc100SJani Nikula } 1735379bc100SJani Nikula 173636ecb0ecSVille Syrjälä static void jsl_ddi_tc_disable_clock(struct intel_encoder *encoder) 1737379bc100SJani Nikula { 173836ecb0ecSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 1739379bc100SJani Nikula enum port port = encoder->port; 1740379bc100SJani Nikula 174136ecb0ecSVille Syrjälä icl_ddi_combo_disable_clock(encoder); 174236ecb0ecSVille Syrjälä 174336ecb0ecSVille Syrjälä intel_de_write(i915, DDI_CLK_SEL(port), DDI_CLK_SEL_NONE); 1744379bc100SJani Nikula } 174536ecb0ecSVille Syrjälä 17460fbd8694SVille Syrjälä static bool jsl_ddi_tc_is_clock_enabled(struct intel_encoder *encoder) 17470fbd8694SVille Syrjälä { 17480fbd8694SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 17490fbd8694SVille Syrjälä enum port port = encoder->port; 17500fbd8694SVille Syrjälä u32 tmp; 17510fbd8694SVille Syrjälä 17520fbd8694SVille Syrjälä tmp = intel_de_read(i915, DDI_CLK_SEL(port)); 17530fbd8694SVille Syrjälä 17540fbd8694SVille Syrjälä if ((tmp & DDI_CLK_SEL_MASK) == DDI_CLK_SEL_NONE) 17550fbd8694SVille Syrjälä return false; 17560fbd8694SVille Syrjälä 17570fbd8694SVille Syrjälä return icl_ddi_combo_is_clock_enabled(encoder); 17580fbd8694SVille Syrjälä } 17590fbd8694SVille Syrjälä 176036ecb0ecSVille Syrjälä static void icl_ddi_tc_enable_clock(struct intel_encoder *encoder, 176136ecb0ecSVille Syrjälä const struct intel_crtc_state *crtc_state) 176236ecb0ecSVille Syrjälä { 176336ecb0ecSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 176436ecb0ecSVille Syrjälä const struct intel_shared_dpll *pll = crtc_state->shared_dpll; 176536ecb0ecSVille Syrjälä enum tc_port tc_port = intel_port_to_tc(i915, encoder->port); 176636ecb0ecSVille Syrjälä enum port port = encoder->port; 176736ecb0ecSVille Syrjälä 176836ecb0ecSVille Syrjälä if (drm_WARN_ON(&i915->drm, !pll)) 176936ecb0ecSVille Syrjälä return; 177036ecb0ecSVille Syrjälä 177136ecb0ecSVille Syrjälä intel_de_write(i915, DDI_CLK_SEL(port), 177236ecb0ecSVille Syrjälä icl_pll_to_ddi_clk_sel(encoder, crtc_state)); 177336ecb0ecSVille Syrjälä 177436d225f3SJani Nikula mutex_lock(&i915->display.dpll.lock); 177536ecb0ecSVille Syrjälä 177636ecb0ecSVille Syrjälä intel_de_rmw(i915, ICL_DPCLKA_CFGCR0, 177736ecb0ecSVille Syrjälä ICL_DPCLKA_CFGCR0_TC_CLK_OFF(tc_port), 0); 177836ecb0ecSVille Syrjälä 177936d225f3SJani Nikula mutex_unlock(&i915->display.dpll.lock); 178036ecb0ecSVille Syrjälä } 178136ecb0ecSVille Syrjälä 178236ecb0ecSVille Syrjälä static void icl_ddi_tc_disable_clock(struct intel_encoder *encoder) 178336ecb0ecSVille Syrjälä { 178436ecb0ecSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 178536ecb0ecSVille Syrjälä enum tc_port tc_port = intel_port_to_tc(i915, encoder->port); 178636ecb0ecSVille Syrjälä enum port port = encoder->port; 178736ecb0ecSVille Syrjälä 178836d225f3SJani Nikula mutex_lock(&i915->display.dpll.lock); 178936ecb0ecSVille Syrjälä 179036ecb0ecSVille Syrjälä intel_de_rmw(i915, ICL_DPCLKA_CFGCR0, 179136ecb0ecSVille Syrjälä 0, ICL_DPCLKA_CFGCR0_TC_CLK_OFF(tc_port)); 179236ecb0ecSVille Syrjälä 179336d225f3SJani Nikula mutex_unlock(&i915->display.dpll.lock); 179436ecb0ecSVille Syrjälä 179536ecb0ecSVille Syrjälä intel_de_write(i915, DDI_CLK_SEL(port), DDI_CLK_SEL_NONE); 1796379bc100SJani Nikula } 1797379bc100SJani Nikula 17980fbd8694SVille Syrjälä static bool icl_ddi_tc_is_clock_enabled(struct intel_encoder *encoder) 17990fbd8694SVille Syrjälä { 18000fbd8694SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 18010fbd8694SVille Syrjälä enum tc_port tc_port = intel_port_to_tc(i915, encoder->port); 18020fbd8694SVille Syrjälä enum port port = encoder->port; 18030fbd8694SVille Syrjälä u32 tmp; 18040fbd8694SVille Syrjälä 18050fbd8694SVille Syrjälä tmp = intel_de_read(i915, DDI_CLK_SEL(port)); 18060fbd8694SVille Syrjälä 18070fbd8694SVille Syrjälä if ((tmp & DDI_CLK_SEL_MASK) == DDI_CLK_SEL_NONE) 18080fbd8694SVille Syrjälä return false; 18090fbd8694SVille Syrjälä 18100fbd8694SVille Syrjälä tmp = intel_de_read(i915, ICL_DPCLKA_CFGCR0); 18110fbd8694SVille Syrjälä 18120fbd8694SVille Syrjälä return !(tmp & ICL_DPCLKA_CFGCR0_TC_CLK_OFF(tc_port)); 18130fbd8694SVille Syrjälä } 18140fbd8694SVille Syrjälä 1815351221ffSVille Syrjälä static struct intel_shared_dpll *icl_ddi_tc_get_pll(struct intel_encoder *encoder) 1816351221ffSVille Syrjälä { 1817351221ffSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 1818351221ffSVille Syrjälä enum tc_port tc_port = intel_port_to_tc(i915, encoder->port); 1819351221ffSVille Syrjälä enum port port = encoder->port; 1820351221ffSVille Syrjälä enum intel_dpll_id id; 1821351221ffSVille Syrjälä u32 tmp; 1822351221ffSVille Syrjälä 1823351221ffSVille Syrjälä tmp = intel_de_read(i915, DDI_CLK_SEL(port)); 1824351221ffSVille Syrjälä 1825351221ffSVille Syrjälä switch (tmp & DDI_CLK_SEL_MASK) { 1826351221ffSVille Syrjälä case DDI_CLK_SEL_TBT_162: 1827351221ffSVille Syrjälä case DDI_CLK_SEL_TBT_270: 1828351221ffSVille Syrjälä case DDI_CLK_SEL_TBT_540: 1829351221ffSVille Syrjälä case DDI_CLK_SEL_TBT_810: 1830351221ffSVille Syrjälä id = DPLL_ID_ICL_TBTPLL; 1831351221ffSVille Syrjälä break; 1832351221ffSVille Syrjälä case DDI_CLK_SEL_MG: 1833351221ffSVille Syrjälä id = icl_tc_port_to_pll_id(tc_port); 1834351221ffSVille Syrjälä break; 1835351221ffSVille Syrjälä default: 1836351221ffSVille Syrjälä MISSING_CASE(tmp); 1837351221ffSVille Syrjälä fallthrough; 1838351221ffSVille Syrjälä case DDI_CLK_SEL_NONE: 1839351221ffSVille Syrjälä return NULL; 1840351221ffSVille Syrjälä } 1841351221ffSVille Syrjälä 1842351221ffSVille Syrjälä return intel_get_shared_dpll_by_id(i915, id); 1843351221ffSVille Syrjälä } 1844351221ffSVille Syrjälä 1845351221ffSVille Syrjälä static struct intel_shared_dpll *bxt_ddi_get_pll(struct intel_encoder *encoder) 1846351221ffSVille Syrjälä { 1847351221ffSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 1848351221ffSVille Syrjälä enum intel_dpll_id id; 1849351221ffSVille Syrjälä 1850351221ffSVille Syrjälä switch (encoder->port) { 1851351221ffSVille Syrjälä case PORT_A: 1852351221ffSVille Syrjälä id = DPLL_ID_SKL_DPLL0; 1853351221ffSVille Syrjälä break; 1854351221ffSVille Syrjälä case PORT_B: 1855351221ffSVille Syrjälä id = DPLL_ID_SKL_DPLL1; 1856351221ffSVille Syrjälä break; 1857351221ffSVille Syrjälä case PORT_C: 1858351221ffSVille Syrjälä id = DPLL_ID_SKL_DPLL2; 1859351221ffSVille Syrjälä break; 1860351221ffSVille Syrjälä default: 1861351221ffSVille Syrjälä MISSING_CASE(encoder->port); 1862351221ffSVille Syrjälä return NULL; 1863351221ffSVille Syrjälä } 1864351221ffSVille Syrjälä 1865351221ffSVille Syrjälä return intel_get_shared_dpll_by_id(i915, id); 1866351221ffSVille Syrjälä } 1867351221ffSVille Syrjälä 186838e31f1aSVille Syrjälä static void skl_ddi_enable_clock(struct intel_encoder *encoder, 186938e31f1aSVille Syrjälä const struct intel_crtc_state *crtc_state) 187038e31f1aSVille Syrjälä { 187138e31f1aSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 187238e31f1aSVille Syrjälä const struct intel_shared_dpll *pll = crtc_state->shared_dpll; 187338e31f1aSVille Syrjälä enum port port = encoder->port; 187438e31f1aSVille Syrjälä 187538e31f1aSVille Syrjälä if (drm_WARN_ON(&i915->drm, !pll)) 187638e31f1aSVille Syrjälä return; 187738e31f1aSVille Syrjälä 187836d225f3SJani Nikula mutex_lock(&i915->display.dpll.lock); 187938e31f1aSVille Syrjälä 18807815ed88SVille Syrjälä intel_de_rmw(i915, DPLL_CTRL2, 18817815ed88SVille Syrjälä DPLL_CTRL2_DDI_CLK_OFF(port) | 18827815ed88SVille Syrjälä DPLL_CTRL2_DDI_CLK_SEL_MASK(port), 18837815ed88SVille Syrjälä DPLL_CTRL2_DDI_CLK_SEL(pll->info->id, port) | 188438e31f1aSVille Syrjälä DPLL_CTRL2_DDI_SEL_OVERRIDE(port)); 188538e31f1aSVille Syrjälä 188636d225f3SJani Nikula mutex_unlock(&i915->display.dpll.lock); 188738e31f1aSVille Syrjälä } 188838e31f1aSVille Syrjälä 188938e31f1aSVille Syrjälä static void skl_ddi_disable_clock(struct intel_encoder *encoder) 189038e31f1aSVille Syrjälä { 189138e31f1aSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 189238e31f1aSVille Syrjälä enum port port = encoder->port; 189338e31f1aSVille Syrjälä 189436d225f3SJani Nikula mutex_lock(&i915->display.dpll.lock); 1895be317ca0SVille Syrjälä 18967815ed88SVille Syrjälä intel_de_rmw(i915, DPLL_CTRL2, 18977815ed88SVille Syrjälä 0, DPLL_CTRL2_DDI_CLK_OFF(port)); 1898be317ca0SVille Syrjälä 189936d225f3SJani Nikula mutex_unlock(&i915->display.dpll.lock); 190038e31f1aSVille Syrjälä } 190138e31f1aSVille Syrjälä 19020fbd8694SVille Syrjälä static bool skl_ddi_is_clock_enabled(struct intel_encoder *encoder) 19030fbd8694SVille Syrjälä { 19040fbd8694SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 19050fbd8694SVille Syrjälä enum port port = encoder->port; 19060fbd8694SVille Syrjälä 19070fbd8694SVille Syrjälä /* 19080fbd8694SVille Syrjälä * FIXME Not sure if the override affects both 19090fbd8694SVille Syrjälä * the PLL selection and the CLK_OFF bit. 19100fbd8694SVille Syrjälä */ 19110fbd8694SVille Syrjälä return !(intel_de_read(i915, DPLL_CTRL2) & DPLL_CTRL2_DDI_CLK_OFF(port)); 19120fbd8694SVille Syrjälä } 19130fbd8694SVille Syrjälä 1914351221ffSVille Syrjälä static struct intel_shared_dpll *skl_ddi_get_pll(struct intel_encoder *encoder) 1915351221ffSVille Syrjälä { 1916351221ffSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 1917351221ffSVille Syrjälä enum port port = encoder->port; 1918351221ffSVille Syrjälä enum intel_dpll_id id; 1919351221ffSVille Syrjälä u32 tmp; 1920351221ffSVille Syrjälä 1921351221ffSVille Syrjälä tmp = intel_de_read(i915, DPLL_CTRL2); 1922351221ffSVille Syrjälä 1923351221ffSVille Syrjälä /* 1924351221ffSVille Syrjälä * FIXME Not sure if the override affects both 1925351221ffSVille Syrjälä * the PLL selection and the CLK_OFF bit. 1926351221ffSVille Syrjälä */ 1927351221ffSVille Syrjälä if ((tmp & DPLL_CTRL2_DDI_SEL_OVERRIDE(port)) == 0) 1928351221ffSVille Syrjälä return NULL; 1929351221ffSVille Syrjälä 1930351221ffSVille Syrjälä id = (tmp & DPLL_CTRL2_DDI_CLK_SEL_MASK(port)) >> 1931351221ffSVille Syrjälä DPLL_CTRL2_DDI_CLK_SEL_SHIFT(port); 1932351221ffSVille Syrjälä 1933351221ffSVille Syrjälä return intel_get_shared_dpll_by_id(i915, id); 1934351221ffSVille Syrjälä } 1935351221ffSVille Syrjälä 1936d135368dSVille Syrjälä void hsw_ddi_enable_clock(struct intel_encoder *encoder, 1937d135368dSVille Syrjälä const struct intel_crtc_state *crtc_state) 1938d135368dSVille Syrjälä { 1939d135368dSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 1940d135368dSVille Syrjälä const struct intel_shared_dpll *pll = crtc_state->shared_dpll; 1941d135368dSVille Syrjälä enum port port = encoder->port; 1942d135368dSVille Syrjälä 1943d135368dSVille Syrjälä if (drm_WARN_ON(&i915->drm, !pll)) 1944d135368dSVille Syrjälä return; 1945d135368dSVille Syrjälä 1946d135368dSVille Syrjälä intel_de_write(i915, PORT_CLK_SEL(port), hsw_pll_to_ddi_pll_sel(pll)); 1947d135368dSVille Syrjälä } 1948d135368dSVille Syrjälä 1949d135368dSVille Syrjälä void hsw_ddi_disable_clock(struct intel_encoder *encoder) 1950d135368dSVille Syrjälä { 1951d135368dSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 1952d135368dSVille Syrjälä enum port port = encoder->port; 1953d135368dSVille Syrjälä 1954d135368dSVille Syrjälä intel_de_write(i915, PORT_CLK_SEL(port), PORT_CLK_SEL_NONE); 1955d135368dSVille Syrjälä } 1956d135368dSVille Syrjälä 19570fbd8694SVille Syrjälä bool hsw_ddi_is_clock_enabled(struct intel_encoder *encoder) 19580fbd8694SVille Syrjälä { 19590fbd8694SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 19600fbd8694SVille Syrjälä enum port port = encoder->port; 19610fbd8694SVille Syrjälä 19620fbd8694SVille Syrjälä return intel_de_read(i915, PORT_CLK_SEL(port)) != PORT_CLK_SEL_NONE; 19630fbd8694SVille Syrjälä } 19640fbd8694SVille Syrjälä 1965351221ffSVille Syrjälä static struct intel_shared_dpll *hsw_ddi_get_pll(struct intel_encoder *encoder) 1966351221ffSVille Syrjälä { 1967351221ffSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 1968351221ffSVille Syrjälä enum port port = encoder->port; 1969351221ffSVille Syrjälä enum intel_dpll_id id; 1970351221ffSVille Syrjälä u32 tmp; 1971351221ffSVille Syrjälä 1972351221ffSVille Syrjälä tmp = intel_de_read(i915, PORT_CLK_SEL(port)); 1973351221ffSVille Syrjälä 1974351221ffSVille Syrjälä switch (tmp & PORT_CLK_SEL_MASK) { 1975351221ffSVille Syrjälä case PORT_CLK_SEL_WRPLL1: 1976351221ffSVille Syrjälä id = DPLL_ID_WRPLL1; 1977351221ffSVille Syrjälä break; 1978351221ffSVille Syrjälä case PORT_CLK_SEL_WRPLL2: 1979351221ffSVille Syrjälä id = DPLL_ID_WRPLL2; 1980351221ffSVille Syrjälä break; 1981351221ffSVille Syrjälä case PORT_CLK_SEL_SPLL: 1982351221ffSVille Syrjälä id = DPLL_ID_SPLL; 1983351221ffSVille Syrjälä break; 1984351221ffSVille Syrjälä case PORT_CLK_SEL_LCPLL_810: 1985351221ffSVille Syrjälä id = DPLL_ID_LCPLL_810; 1986351221ffSVille Syrjälä break; 1987351221ffSVille Syrjälä case PORT_CLK_SEL_LCPLL_1350: 1988351221ffSVille Syrjälä id = DPLL_ID_LCPLL_1350; 1989351221ffSVille Syrjälä break; 1990351221ffSVille Syrjälä case PORT_CLK_SEL_LCPLL_2700: 1991351221ffSVille Syrjälä id = DPLL_ID_LCPLL_2700; 1992351221ffSVille Syrjälä break; 1993351221ffSVille Syrjälä default: 1994351221ffSVille Syrjälä MISSING_CASE(tmp); 1995351221ffSVille Syrjälä fallthrough; 1996351221ffSVille Syrjälä case PORT_CLK_SEL_NONE: 1997351221ffSVille Syrjälä return NULL; 1998351221ffSVille Syrjälä } 1999351221ffSVille Syrjälä 2000351221ffSVille Syrjälä return intel_get_shared_dpll_by_id(i915, id); 2001351221ffSVille Syrjälä } 2002351221ffSVille Syrjälä 2003c133df69SVille Syrjälä void intel_ddi_enable_clock(struct intel_encoder *encoder, 2004c133df69SVille Syrjälä const struct intel_crtc_state *crtc_state) 2005c133df69SVille Syrjälä { 2006c133df69SVille Syrjälä if (encoder->enable_clock) 2007c133df69SVille Syrjälä encoder->enable_clock(encoder, crtc_state); 2008c133df69SVille Syrjälä } 2009c133df69SVille Syrjälä 2010d39ef5d5SVille Syrjälä void intel_ddi_disable_clock(struct intel_encoder *encoder) 2011c133df69SVille Syrjälä { 2012c133df69SVille Syrjälä if (encoder->disable_clock) 2013c133df69SVille Syrjälä encoder->disable_clock(encoder); 2014c133df69SVille Syrjälä } 2015c133df69SVille Syrjälä 2016aaca50efSVille Syrjälä void intel_ddi_sanitize_encoder_pll_mapping(struct intel_encoder *encoder) 2017dc1ddac6SVille Syrjälä { 201897a24a70SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 2019dc1ddac6SVille Syrjälä u32 port_mask; 2020dc1ddac6SVille Syrjälä bool ddi_clk_needed; 2021dc1ddac6SVille Syrjälä 2022dc1ddac6SVille Syrjälä /* 2023dc1ddac6SVille Syrjälä * In case of DP MST, we sanitize the primary encoder only, not the 2024dc1ddac6SVille Syrjälä * virtual ones. 2025dc1ddac6SVille Syrjälä */ 2026dc1ddac6SVille Syrjälä if (encoder->type == INTEL_OUTPUT_DP_MST) 2027dc1ddac6SVille Syrjälä return; 2028dc1ddac6SVille Syrjälä 2029dc1ddac6SVille Syrjälä if (!encoder->base.crtc && intel_encoder_is_dp(encoder)) { 2030dc1ddac6SVille Syrjälä u8 pipe_mask; 2031dc1ddac6SVille Syrjälä bool is_mst; 2032dc1ddac6SVille Syrjälä 2033dc1ddac6SVille Syrjälä intel_ddi_get_encoder_pipes(encoder, &pipe_mask, &is_mst); 2034dc1ddac6SVille Syrjälä /* 2035dc1ddac6SVille Syrjälä * In the unlikely case that BIOS enables DP in MST mode, just 2036dc1ddac6SVille Syrjälä * warn since our MST HW readout is incomplete. 2037dc1ddac6SVille Syrjälä */ 203897a24a70SVille Syrjälä if (drm_WARN_ON(&i915->drm, is_mst)) 2039dc1ddac6SVille Syrjälä return; 2040dc1ddac6SVille Syrjälä } 2041dc1ddac6SVille Syrjälä 2042dc1ddac6SVille Syrjälä port_mask = BIT(encoder->port); 2043dc1ddac6SVille Syrjälä ddi_clk_needed = encoder->base.crtc; 2044dc1ddac6SVille Syrjälä 2045dc1ddac6SVille Syrjälä if (encoder->type == INTEL_OUTPUT_DSI) { 2046dc1ddac6SVille Syrjälä struct intel_encoder *other_encoder; 2047dc1ddac6SVille Syrjälä 2048dc1ddac6SVille Syrjälä port_mask = intel_dsi_encoder_ports(encoder); 2049dc1ddac6SVille Syrjälä /* 2050dc1ddac6SVille Syrjälä * Sanity check that we haven't incorrectly registered another 2051dc1ddac6SVille Syrjälä * encoder using any of the ports of this DSI encoder. 2052dc1ddac6SVille Syrjälä */ 205397a24a70SVille Syrjälä for_each_intel_encoder(&i915->drm, other_encoder) { 2054dc1ddac6SVille Syrjälä if (other_encoder == encoder) 2055dc1ddac6SVille Syrjälä continue; 2056dc1ddac6SVille Syrjälä 205797a24a70SVille Syrjälä if (drm_WARN_ON(&i915->drm, 2058dc1ddac6SVille Syrjälä port_mask & BIT(other_encoder->port))) 2059dc1ddac6SVille Syrjälä return; 2060dc1ddac6SVille Syrjälä } 2061dc1ddac6SVille Syrjälä /* 2062dc1ddac6SVille Syrjälä * For DSI we keep the ddi clocks gated 2063dc1ddac6SVille Syrjälä * except during enable/disable sequence. 2064dc1ddac6SVille Syrjälä */ 2065dc1ddac6SVille Syrjälä ddi_clk_needed = false; 2066dc1ddac6SVille Syrjälä } 2067dc1ddac6SVille Syrjälä 2068f82f2563SMatt Roper if (ddi_clk_needed || !encoder->is_clock_enabled || 20690fbd8694SVille Syrjälä !encoder->is_clock_enabled(encoder)) 20700fbd8694SVille Syrjälä return; 20710fbd8694SVille Syrjälä 20720fbd8694SVille Syrjälä drm_notice(&i915->drm, 20730fbd8694SVille Syrjälä "[ENCODER:%d:%s] is disabled/in DSI mode with an ungated DDI clock, gate it\n", 20740fbd8694SVille Syrjälä encoder->base.base.id, encoder->base.name); 20750fbd8694SVille Syrjälä 2076dc1ddac6SVille Syrjälä encoder->disable_clock(encoder); 2077dc1ddac6SVille Syrjälä } 2078dc1ddac6SVille Syrjälä 20798aaf5cbdSJosé Roberto de Souza static void 20807801f3b7SLucas De Marchi icl_program_mg_dp_mode(struct intel_digital_port *dig_port, 20813b51be4eSClinton A Taylor const struct intel_crtc_state *crtc_state) 2082379bc100SJani Nikula { 20837801f3b7SLucas De Marchi struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); 20847801f3b7SLucas De Marchi enum tc_port tc_port = intel_port_to_tc(dev_priv, dig_port->base.port); 20855b6a9ba9SVille Syrjälä enum phy phy = intel_port_to_phy(dev_priv, dig_port->base.port); 20863b51be4eSClinton A Taylor u32 ln0, ln1, pin_assignment; 20873b51be4eSClinton A Taylor u8 width; 2088379bc100SJani Nikula 20895b6a9ba9SVille Syrjälä if (!intel_phy_is_tc(dev_priv, phy) || 209011a89708SImre Deak intel_tc_port_in_tbt_alt_mode(dig_port)) 2091379bc100SJani Nikula return; 2092379bc100SJani Nikula 2093005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 12) { 2094b8ed5533SImre Deak ln0 = intel_dkl_phy_read(dev_priv, DKL_DP_MODE(tc_port, 0)); 2095b8ed5533SImre Deak ln1 = intel_dkl_phy_read(dev_priv, DKL_DP_MODE(tc_port, 1)); 2096978c3e53SClinton A Taylor } else { 2097f7960e7fSJani Nikula ln0 = intel_de_read(dev_priv, MG_DP_MODE(0, tc_port)); 2098f7960e7fSJani Nikula ln1 = intel_de_read(dev_priv, MG_DP_MODE(1, tc_port)); 2099978c3e53SClinton A Taylor } 2100379bc100SJani Nikula 21014f72a8eeSKhaled Almahallawy ln0 &= ~(MG_DP_MODE_CFG_DP_X1_MODE | MG_DP_MODE_CFG_DP_X2_MODE); 2102379bc100SJani Nikula ln1 &= ~(MG_DP_MODE_CFG_DP_X1_MODE | MG_DP_MODE_CFG_DP_X2_MODE); 2103379bc100SJani Nikula 21043b51be4eSClinton A Taylor /* DPPATC */ 21057801f3b7SLucas De Marchi pin_assignment = intel_tc_port_get_pin_assignment_mask(dig_port); 21063b51be4eSClinton A Taylor width = crtc_state->lane_count; 2107379bc100SJani Nikula 21083b51be4eSClinton A Taylor switch (pin_assignment) { 21093b51be4eSClinton A Taylor case 0x0: 21101de143ccSPankaj Bharadiya drm_WARN_ON(&dev_priv->drm, 211111a89708SImre Deak !intel_tc_port_in_legacy_mode(dig_port)); 21123b51be4eSClinton A Taylor if (width == 1) { 2113379bc100SJani Nikula ln1 |= MG_DP_MODE_CFG_DP_X1_MODE; 21143b51be4eSClinton A Taylor } else { 21153b51be4eSClinton A Taylor ln0 |= MG_DP_MODE_CFG_DP_X2_MODE; 21163b51be4eSClinton A Taylor ln1 |= MG_DP_MODE_CFG_DP_X2_MODE; 2117379bc100SJani Nikula } 2118379bc100SJani Nikula break; 21193b51be4eSClinton A Taylor case 0x1: 21203b51be4eSClinton A Taylor if (width == 4) { 21213b51be4eSClinton A Taylor ln0 |= MG_DP_MODE_CFG_DP_X2_MODE; 21223b51be4eSClinton A Taylor ln1 |= MG_DP_MODE_CFG_DP_X2_MODE; 21233b51be4eSClinton A Taylor } 2124379bc100SJani Nikula break; 21253b51be4eSClinton A Taylor case 0x2: 21263b51be4eSClinton A Taylor if (width == 2) { 21273b51be4eSClinton A Taylor ln0 |= MG_DP_MODE_CFG_DP_X2_MODE; 21283b51be4eSClinton A Taylor ln1 |= MG_DP_MODE_CFG_DP_X2_MODE; 21293b51be4eSClinton A Taylor } 21303b51be4eSClinton A Taylor break; 21313b51be4eSClinton A Taylor case 0x3: 21323b51be4eSClinton A Taylor case 0x5: 21333b51be4eSClinton A Taylor if (width == 1) { 21343b51be4eSClinton A Taylor ln0 |= MG_DP_MODE_CFG_DP_X1_MODE; 21353b51be4eSClinton A Taylor ln1 |= MG_DP_MODE_CFG_DP_X1_MODE; 21363b51be4eSClinton A Taylor } else { 21373b51be4eSClinton A Taylor ln0 |= MG_DP_MODE_CFG_DP_X2_MODE; 21383b51be4eSClinton A Taylor ln1 |= MG_DP_MODE_CFG_DP_X2_MODE; 21393b51be4eSClinton A Taylor } 21403b51be4eSClinton A Taylor break; 21413b51be4eSClinton A Taylor case 0x4: 21423b51be4eSClinton A Taylor case 0x6: 21433b51be4eSClinton A Taylor if (width == 1) { 21443b51be4eSClinton A Taylor ln0 |= MG_DP_MODE_CFG_DP_X1_MODE; 21453b51be4eSClinton A Taylor ln1 |= MG_DP_MODE_CFG_DP_X1_MODE; 21463b51be4eSClinton A Taylor } else { 21473b51be4eSClinton A Taylor ln0 |= MG_DP_MODE_CFG_DP_X2_MODE; 21483b51be4eSClinton A Taylor ln1 |= MG_DP_MODE_CFG_DP_X2_MODE; 21493b51be4eSClinton A Taylor } 21503b51be4eSClinton A Taylor break; 2151379bc100SJani Nikula default: 21523b51be4eSClinton A Taylor MISSING_CASE(pin_assignment); 2153379bc100SJani Nikula } 2154379bc100SJani Nikula 2155005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 12) { 2156b8ed5533SImre Deak intel_dkl_phy_write(dev_priv, DKL_DP_MODE(tc_port, 0), ln0); 2157b8ed5533SImre Deak intel_dkl_phy_write(dev_priv, DKL_DP_MODE(tc_port, 1), ln1); 2158978c3e53SClinton A Taylor } else { 2159f7960e7fSJani Nikula intel_de_write(dev_priv, MG_DP_MODE(0, tc_port), ln0); 2160f7960e7fSJani Nikula intel_de_write(dev_priv, MG_DP_MODE(1, tc_port), ln1); 2161379bc100SJani Nikula } 2162978c3e53SClinton A Taylor } 2163379bc100SJani Nikula 2164ef79fafeSVille Syrjälä static enum transcoder 2165ef79fafeSVille Syrjälä tgl_dp_tp_transcoder(const struct intel_crtc_state *crtc_state) 2166ef79fafeSVille Syrjälä { 2167ef79fafeSVille Syrjälä if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) 2168ef79fafeSVille Syrjälä return crtc_state->mst_master_transcoder; 2169ef79fafeSVille Syrjälä else 2170ef79fafeSVille Syrjälä return crtc_state->cpu_transcoder; 2171ef79fafeSVille Syrjälä } 2172ef79fafeSVille Syrjälä 2173ef79fafeSVille Syrjälä i915_reg_t dp_tp_ctl_reg(struct intel_encoder *encoder, 2174ef79fafeSVille Syrjälä const struct intel_crtc_state *crtc_state) 2175ef79fafeSVille Syrjälä { 2176ef79fafeSVille Syrjälä struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 2177ef79fafeSVille Syrjälä 2178005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 12) 2179ef79fafeSVille Syrjälä return TGL_DP_TP_CTL(tgl_dp_tp_transcoder(crtc_state)); 2180ef79fafeSVille Syrjälä else 2181ef79fafeSVille Syrjälä return DP_TP_CTL(encoder->port); 2182ef79fafeSVille Syrjälä } 2183ef79fafeSVille Syrjälä 2184ef79fafeSVille Syrjälä i915_reg_t dp_tp_status_reg(struct intel_encoder *encoder, 2185ef79fafeSVille Syrjälä const struct intel_crtc_state *crtc_state) 2186ef79fafeSVille Syrjälä { 2187ef79fafeSVille Syrjälä struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 2188ef79fafeSVille Syrjälä 2189005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 12) 2190ef79fafeSVille Syrjälä return TGL_DP_TP_STATUS(tgl_dp_tp_transcoder(crtc_state)); 2191ef79fafeSVille Syrjälä else 2192ef79fafeSVille Syrjälä return DP_TP_STATUS(encoder->port); 2193ef79fafeSVille Syrjälä } 2194ef79fafeSVille Syrjälä 21951639406aSManasi Navare static void intel_dp_sink_set_msa_timing_par_ignore_state(struct intel_dp *intel_dp, 21961639406aSManasi Navare const struct intel_crtc_state *crtc_state, 21971639406aSManasi Navare bool enable) 21981639406aSManasi Navare { 21991639406aSManasi Navare struct drm_i915_private *i915 = dp_to_i915(intel_dp); 22001639406aSManasi Navare 22011639406aSManasi Navare if (!crtc_state->vrr.enable) 22021639406aSManasi Navare return; 22031639406aSManasi Navare 22041639406aSManasi Navare if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_DOWNSPREAD_CTRL, 22051639406aSManasi Navare enable ? DP_MSA_TIMING_PAR_IGNORE_EN : 0) <= 0) 22061639406aSManasi Navare drm_dbg_kms(&i915->drm, 22070868b1ceSVille Syrjälä "Failed to %s MSA_TIMING_PAR_IGNORE in the sink\n", 2208707c3a7dSLucas De Marchi str_enable_disable(enable)); 22091639406aSManasi Navare } 22101639406aSManasi Navare 2211379bc100SJani Nikula static void intel_dp_sink_set_fec_ready(struct intel_dp *intel_dp, 2212379bc100SJani Nikula const struct intel_crtc_state *crtc_state) 2213379bc100SJani Nikula { 221447bdb1caSJani Nikula struct drm_i915_private *i915 = dp_to_i915(intel_dp); 221547bdb1caSJani Nikula 2216379bc100SJani Nikula if (!crtc_state->fec_enable) 2217379bc100SJani Nikula return; 2218379bc100SJani Nikula 2219379bc100SJani Nikula if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_FEC_CONFIGURATION, DP_FEC_READY) <= 0) 222047bdb1caSJani Nikula drm_dbg_kms(&i915->drm, 222147bdb1caSJani Nikula "Failed to set FEC_READY in the sink\n"); 2222379bc100SJani Nikula } 2223379bc100SJani Nikula 2224379bc100SJani Nikula static void intel_ddi_enable_fec(struct intel_encoder *encoder, 2225379bc100SJani Nikula const struct intel_crtc_state *crtc_state) 2226379bc100SJani Nikula { 2227379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 2228379bc100SJani Nikula 2229379bc100SJani Nikula if (!crtc_state->fec_enable) 2230379bc100SJani Nikula return; 2231379bc100SJani Nikula 22328910d8b7SAndrzej Hajda intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), 22338910d8b7SAndrzej Hajda 0, DP_TP_CTL_FEC_ENABLE); 2234379bc100SJani Nikula } 2235379bc100SJani Nikula 2236379bc100SJani Nikula static void intel_ddi_disable_fec_state(struct intel_encoder *encoder, 2237379bc100SJani Nikula const struct intel_crtc_state *crtc_state) 2238379bc100SJani Nikula { 2239379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 2240379bc100SJani Nikula 2241379bc100SJani Nikula if (!crtc_state->fec_enable) 2242379bc100SJani Nikula return; 2243379bc100SJani Nikula 22448910d8b7SAndrzej Hajda intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), 22458910d8b7SAndrzej Hajda DP_TP_CTL_FEC_ENABLE, 0); 2246ef79fafeSVille Syrjälä intel_de_posting_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state)); 2247379bc100SJani Nikula } 2248379bc100SJani Nikula 22495cdf706fSVille Syrjälä static void intel_ddi_power_up_lanes(struct intel_encoder *encoder, 22505cdf706fSVille Syrjälä const struct intel_crtc_state *crtc_state) 22515cdf706fSVille Syrjälä { 22525cdf706fSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 22535cdf706fSVille Syrjälä struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 22545cdf706fSVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 22555cdf706fSVille Syrjälä 22565cdf706fSVille Syrjälä if (intel_phy_is_combo(i915, phy)) { 22575cdf706fSVille Syrjälä bool lane_reversal = 22585cdf706fSVille Syrjälä dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL; 22595cdf706fSVille Syrjälä 22605cdf706fSVille Syrjälä intel_combo_phy_power_up_lanes(i915, phy, false, 22615cdf706fSVille Syrjälä crtc_state->lane_count, 22625cdf706fSVille Syrjälä lane_reversal); 22635cdf706fSVille Syrjälä } 22645cdf706fSVille Syrjälä } 22655cdf706fSVille Syrjälä 2266f6864b27SJani Nikula /* Splitter enable for eDP MSO is limited to certain pipes. */ 2267f6864b27SJani Nikula static u8 intel_ddi_splitter_pipe_mask(struct drm_i915_private *i915) 2268f6864b27SJani Nikula { 2269f6864b27SJani Nikula if (IS_ALDERLAKE_P(i915)) 2270f6864b27SJani Nikula return BIT(PIPE_A) | BIT(PIPE_B); 2271f6864b27SJani Nikula else 2272f6864b27SJani Nikula return BIT(PIPE_A); 2273f6864b27SJani Nikula } 2274f6864b27SJani Nikula 22755b616a29SJani Nikula static void intel_ddi_mso_get_config(struct intel_encoder *encoder, 22765b616a29SJani Nikula struct intel_crtc_state *pipe_config) 22775b616a29SJani Nikula { 22785b616a29SJani Nikula struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); 22795b616a29SJani Nikula struct drm_i915_private *i915 = to_i915(crtc->base.dev); 22805b616a29SJani Nikula enum pipe pipe = crtc->pipe; 22815b616a29SJani Nikula u32 dss1; 22825b616a29SJani Nikula 22835b616a29SJani Nikula if (!HAS_MSO(i915)) 22845b616a29SJani Nikula return; 22855b616a29SJani Nikula 22865b616a29SJani Nikula dss1 = intel_de_read(i915, ICL_PIPE_DSS_CTL1(pipe)); 22875b616a29SJani Nikula 22885b616a29SJani Nikula pipe_config->splitter.enable = dss1 & SPLITTER_ENABLE; 22895b616a29SJani Nikula if (!pipe_config->splitter.enable) 22905b616a29SJani Nikula return; 22915b616a29SJani Nikula 2292f6864b27SJani Nikula if (drm_WARN_ON(&i915->drm, !(intel_ddi_splitter_pipe_mask(i915) & BIT(pipe)))) { 22935b616a29SJani Nikula pipe_config->splitter.enable = false; 22945b616a29SJani Nikula return; 22955b616a29SJani Nikula } 22965b616a29SJani Nikula 22975b616a29SJani Nikula switch (dss1 & SPLITTER_CONFIGURATION_MASK) { 22985b616a29SJani Nikula default: 22995b616a29SJani Nikula drm_WARN(&i915->drm, true, 23005b616a29SJani Nikula "Invalid splitter configuration, dss1=0x%08x\n", dss1); 23015b616a29SJani Nikula fallthrough; 23025b616a29SJani Nikula case SPLITTER_CONFIGURATION_2_SEGMENT: 23035b616a29SJani Nikula pipe_config->splitter.link_count = 2; 23045b616a29SJani Nikula break; 23055b616a29SJani Nikula case SPLITTER_CONFIGURATION_4_SEGMENT: 23065b616a29SJani Nikula pipe_config->splitter.link_count = 4; 23075b616a29SJani Nikula break; 23085b616a29SJani Nikula } 23095b616a29SJani Nikula 23105b616a29SJani Nikula pipe_config->splitter.pixel_overlap = REG_FIELD_GET(OVERLAP_PIXELS_MASK, dss1); 23115b616a29SJani Nikula } 23125b616a29SJani Nikula 2313bc71194eSJani Nikula static void intel_ddi_mso_configure(const struct intel_crtc_state *crtc_state) 2314bc71194eSJani Nikula { 2315bc71194eSJani Nikula struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 2316bc71194eSJani Nikula struct drm_i915_private *i915 = to_i915(crtc->base.dev); 2317bc71194eSJani Nikula enum pipe pipe = crtc->pipe; 2318bc71194eSJani Nikula u32 dss1 = 0; 2319bc71194eSJani Nikula 2320bc71194eSJani Nikula if (!HAS_MSO(i915)) 2321bc71194eSJani Nikula return; 2322bc71194eSJani Nikula 2323bc71194eSJani Nikula if (crtc_state->splitter.enable) { 2324bc71194eSJani Nikula dss1 |= SPLITTER_ENABLE; 2325bc71194eSJani Nikula dss1 |= OVERLAP_PIXELS(crtc_state->splitter.pixel_overlap); 2326bc71194eSJani Nikula if (crtc_state->splitter.link_count == 2) 2327bc71194eSJani Nikula dss1 |= SPLITTER_CONFIGURATION_2_SEGMENT; 2328bc71194eSJani Nikula else 2329bc71194eSJani Nikula dss1 |= SPLITTER_CONFIGURATION_4_SEGMENT; 2330bc71194eSJani Nikula } 2331bc71194eSJani Nikula 2332bc71194eSJani Nikula intel_de_rmw(i915, ICL_PIPE_DSS_CTL1(pipe), 2333bc71194eSJani Nikula SPLITTER_ENABLE | SPLITTER_CONFIGURATION_MASK | 2334bc71194eSJani Nikula OVERLAP_PIXELS_MASK, dss1); 2335bc71194eSJani Nikula } 2336bc71194eSJani Nikula 233723ef6194SJosé Roberto de Souza static u8 mtl_get_port_width(u8 lane_count) 233823ef6194SJosé Roberto de Souza { 233923ef6194SJosé Roberto de Souza switch (lane_count) { 234023ef6194SJosé Roberto de Souza case 1: 234123ef6194SJosé Roberto de Souza return 0; 234223ef6194SJosé Roberto de Souza case 2: 234323ef6194SJosé Roberto de Souza return 1; 234423ef6194SJosé Roberto de Souza case 3: 234523ef6194SJosé Roberto de Souza return 4; 234623ef6194SJosé Roberto de Souza case 4: 234723ef6194SJosé Roberto de Souza return 3; 234823ef6194SJosé Roberto de Souza default: 234923ef6194SJosé Roberto de Souza MISSING_CASE(lane_count); 235023ef6194SJosé Roberto de Souza return 4; 235123ef6194SJosé Roberto de Souza } 235223ef6194SJosé Roberto de Souza } 235323ef6194SJosé Roberto de Souza 235423ef6194SJosé Roberto de Souza static void 235523ef6194SJosé Roberto de Souza mtl_ddi_enable_d2d(struct intel_encoder *encoder) 235623ef6194SJosé Roberto de Souza { 235723ef6194SJosé Roberto de Souza struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 235823ef6194SJosé Roberto de Souza enum port port = encoder->port; 235923ef6194SJosé Roberto de Souza 236023ef6194SJosé Roberto de Souza intel_de_rmw(dev_priv, XELPDP_PORT_BUF_CTL1(port), 0, 236123ef6194SJosé Roberto de Souza XELPDP_PORT_BUF_D2D_LINK_ENABLE); 236223ef6194SJosé Roberto de Souza 236323ef6194SJosé Roberto de Souza if (wait_for_us((intel_de_read(dev_priv, XELPDP_PORT_BUF_CTL1(port)) & 236423ef6194SJosé Roberto de Souza XELPDP_PORT_BUF_D2D_LINK_STATE), 100)) { 236523ef6194SJosé Roberto de Souza drm_err(&dev_priv->drm, "Timeout waiting for D2D Link enable for PORT_BUF_CTL %c\n", 236623ef6194SJosé Roberto de Souza port_name(port)); 236723ef6194SJosé Roberto de Souza } 236823ef6194SJosé Roberto de Souza } 236923ef6194SJosé Roberto de Souza 237023ef6194SJosé Roberto de Souza static void mtl_port_buf_ctl_program(struct intel_encoder *encoder, 237123ef6194SJosé Roberto de Souza const struct intel_crtc_state *crtc_state) 237223ef6194SJosé Roberto de Souza { 237323ef6194SJosé Roberto de Souza struct drm_i915_private *i915 = to_i915(encoder->base.dev); 237423ef6194SJosé Roberto de Souza struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 237523ef6194SJosé Roberto de Souza enum port port = encoder->port; 237623ef6194SJosé Roberto de Souza u32 val; 237723ef6194SJosé Roberto de Souza 237823ef6194SJosé Roberto de Souza val = intel_de_read(i915, XELPDP_PORT_BUF_CTL1(port)); 237923ef6194SJosé Roberto de Souza val &= ~XELPDP_PORT_WIDTH_MASK; 238023ef6194SJosé Roberto de Souza val |= XELPDP_PORT_WIDTH(mtl_get_port_width(crtc_state->lane_count)); 238123ef6194SJosé Roberto de Souza 238223ef6194SJosé Roberto de Souza val &= ~XELPDP_PORT_BUF_PORT_DATA_WIDTH_MASK; 238323ef6194SJosé Roberto de Souza if (intel_dp_is_uhbr(crtc_state)) 238423ef6194SJosé Roberto de Souza val |= XELPDP_PORT_BUF_PORT_DATA_40BIT; 238523ef6194SJosé Roberto de Souza else 238623ef6194SJosé Roberto de Souza val |= XELPDP_PORT_BUF_PORT_DATA_10BIT; 238723ef6194SJosé Roberto de Souza 238823ef6194SJosé Roberto de Souza if (dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL) 238923ef6194SJosé Roberto de Souza val |= XELPDP_PORT_REVERSAL; 239023ef6194SJosé Roberto de Souza 239123ef6194SJosé Roberto de Souza intel_de_write(i915, XELPDP_PORT_BUF_CTL1(port), val); 239223ef6194SJosé Roberto de Souza } 239323ef6194SJosé Roberto de Souza 239423ef6194SJosé Roberto de Souza static void mtl_port_buf_ctl_io_selection(struct intel_encoder *encoder) 239523ef6194SJosé Roberto de Souza { 239623ef6194SJosé Roberto de Souza struct drm_i915_private *i915 = to_i915(encoder->base.dev); 239723ef6194SJosé Roberto de Souza struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 239823ef6194SJosé Roberto de Souza u32 val; 239923ef6194SJosé Roberto de Souza 240023ef6194SJosé Roberto de Souza val = intel_tc_port_in_tbt_alt_mode(dig_port) ? 240123ef6194SJosé Roberto de Souza XELPDP_PORT_BUF_IO_SELECT_TBT : 0; 240223ef6194SJosé Roberto de Souza intel_de_rmw(i915, XELPDP_PORT_BUF_CTL1(encoder->port), 240323ef6194SJosé Roberto de Souza XELPDP_PORT_BUF_IO_SELECT_TBT, val); 240423ef6194SJosé Roberto de Souza } 240523ef6194SJosé Roberto de Souza 240623ef6194SJosé Roberto de Souza static void mtl_ddi_pre_enable_dp(struct intel_atomic_state *state, 240723ef6194SJosé Roberto de Souza struct intel_encoder *encoder, 240823ef6194SJosé Roberto de Souza const struct intel_crtc_state *crtc_state, 240923ef6194SJosé Roberto de Souza const struct drm_connector_state *conn_state) 241023ef6194SJosé Roberto de Souza { 241123ef6194SJosé Roberto de Souza struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 241223ef6194SJosé Roberto de Souza bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); 241323ef6194SJosé Roberto de Souza 241423ef6194SJosé Roberto de Souza intel_dp_set_link_params(intel_dp, 241523ef6194SJosé Roberto de Souza crtc_state->port_clock, 241623ef6194SJosé Roberto de Souza crtc_state->lane_count); 241723ef6194SJosé Roberto de Souza 241823ef6194SJosé Roberto de Souza /* 241923ef6194SJosé Roberto de Souza * We only configure what the register value will be here. Actual 242023ef6194SJosé Roberto de Souza * enabling happens during link training farther down. 242123ef6194SJosé Roberto de Souza */ 242223ef6194SJosé Roberto de Souza intel_ddi_init_dp_buf_reg(encoder, crtc_state); 242323ef6194SJosé Roberto de Souza 242423ef6194SJosé Roberto de Souza /* 242523ef6194SJosé Roberto de Souza * 1. Enable Power Wells 242623ef6194SJosé Roberto de Souza * 242723ef6194SJosé Roberto de Souza * This was handled at the beginning of intel_atomic_commit_tail(), 242823ef6194SJosé Roberto de Souza * before we called down into this function. 242923ef6194SJosé Roberto de Souza */ 243023ef6194SJosé Roberto de Souza 243123ef6194SJosé Roberto de Souza /* 2. PMdemand was already set */ 243223ef6194SJosé Roberto de Souza 243323ef6194SJosé Roberto de Souza /* 3. Select Thunderbolt */ 243423ef6194SJosé Roberto de Souza mtl_port_buf_ctl_io_selection(encoder); 243523ef6194SJosé Roberto de Souza 243623ef6194SJosé Roberto de Souza /* 4. Enable Panel Power if PPS is required */ 243723ef6194SJosé Roberto de Souza intel_pps_on(intel_dp); 243823ef6194SJosé Roberto de Souza 243923ef6194SJosé Roberto de Souza /* 5. Enable the port PLL */ 244023ef6194SJosé Roberto de Souza intel_ddi_enable_clock(encoder, crtc_state); 244123ef6194SJosé Roberto de Souza 244223ef6194SJosé Roberto de Souza /* 244323ef6194SJosé Roberto de Souza * 6.a Configure Transcoder Clock Select to direct the Port clock to the 244423ef6194SJosé Roberto de Souza * Transcoder. 244523ef6194SJosé Roberto de Souza */ 244623ef6194SJosé Roberto de Souza intel_ddi_enable_transcoder_clock(encoder, crtc_state); 244723ef6194SJosé Roberto de Souza 244823ef6194SJosé Roberto de Souza /* 244923ef6194SJosé Roberto de Souza * 6.b If DP v2.0/128b mode - Configure TRANS_DP2_CTL register settings. 245023ef6194SJosé Roberto de Souza */ 245123ef6194SJosé Roberto de Souza intel_ddi_config_transcoder_dp2(encoder, crtc_state); 245223ef6194SJosé Roberto de Souza 245323ef6194SJosé Roberto de Souza /* 245423ef6194SJosé Roberto de Souza * 6.c Configure TRANS_DDI_FUNC_CTL DDI Select, DDI Mode Select & MST 245523ef6194SJosé Roberto de Souza * Transport Select 245623ef6194SJosé Roberto de Souza */ 245723ef6194SJosé Roberto de Souza intel_ddi_config_transcoder_func(encoder, crtc_state); 245823ef6194SJosé Roberto de Souza 245923ef6194SJosé Roberto de Souza /* 246023ef6194SJosé Roberto de Souza * 6.e Program CoG/MSO configuration bits in DSS_CTL1 if selected. 246123ef6194SJosé Roberto de Souza */ 246223ef6194SJosé Roberto de Souza intel_ddi_mso_configure(crtc_state); 246323ef6194SJosé Roberto de Souza 246423ef6194SJosé Roberto de Souza if (!is_mst) 246523ef6194SJosé Roberto de Souza intel_dp_set_power(intel_dp, DP_SET_POWER_D0); 246623ef6194SJosé Roberto de Souza 246723ef6194SJosé Roberto de Souza intel_dp_configure_protocol_converter(intel_dp, crtc_state); 246823ef6194SJosé Roberto de Souza intel_dp_sink_set_decompression_state(intel_dp, crtc_state, true); 246923ef6194SJosé Roberto de Souza /* 247023ef6194SJosé Roberto de Souza * DDI FEC: "anticipates enabling FEC encoding sets the FEC_READY bit 247123ef6194SJosé Roberto de Souza * in the FEC_CONFIGURATION register to 1 before initiating link 247223ef6194SJosé Roberto de Souza * training 247323ef6194SJosé Roberto de Souza */ 247423ef6194SJosé Roberto de Souza intel_dp_sink_set_fec_ready(intel_dp, crtc_state); 247523ef6194SJosé Roberto de Souza 247623ef6194SJosé Roberto de Souza intel_dp_check_frl_training(intel_dp); 247723ef6194SJosé Roberto de Souza intel_dp_pcon_dsc_configure(intel_dp, crtc_state); 247823ef6194SJosé Roberto de Souza 247923ef6194SJosé Roberto de Souza /* 248023ef6194SJosé Roberto de Souza * 6. The rest of the below are substeps under the bspec's "Enable and 248123ef6194SJosé Roberto de Souza * Train Display Port" step. Note that steps that are specific to 248223ef6194SJosé Roberto de Souza * MST will be handled by intel_mst_pre_enable_dp() before/after it 248323ef6194SJosé Roberto de Souza * calls into this function. Also intel_mst_pre_enable_dp() only calls 248423ef6194SJosé Roberto de Souza * us when active_mst_links==0, so any steps designated for "single 248523ef6194SJosé Roberto de Souza * stream or multi-stream master transcoder" can just be performed 248623ef6194SJosé Roberto de Souza * unconditionally here. 248723ef6194SJosé Roberto de Souza * 248823ef6194SJosé Roberto de Souza * mtl_ddi_prepare_link_retrain() that is called by 248923ef6194SJosé Roberto de Souza * intel_dp_start_link_train() will execute steps: 6.d, 6.f, 6.g, 6.h, 249023ef6194SJosé Roberto de Souza * 6.i and 6.j 249123ef6194SJosé Roberto de Souza * 249223ef6194SJosé Roberto de Souza * 6.k Follow DisplayPort specification training sequence (see notes for 249323ef6194SJosé Roberto de Souza * failure handling) 249423ef6194SJosé Roberto de Souza * 6.m If DisplayPort multi-stream - Set DP_TP_CTL link training to Idle 249523ef6194SJosé Roberto de Souza * Pattern, wait for 5 idle patterns (DP_TP_STATUS Min_Idles_Sent) 249623ef6194SJosé Roberto de Souza * (timeout after 800 us) 249723ef6194SJosé Roberto de Souza */ 249823ef6194SJosé Roberto de Souza intel_dp_start_link_train(intel_dp, crtc_state); 249923ef6194SJosé Roberto de Souza 250023ef6194SJosé Roberto de Souza /* 6.n Set DP_TP_CTL link training to Normal */ 250123ef6194SJosé Roberto de Souza if (!is_trans_port_sync_mode(crtc_state)) 250223ef6194SJosé Roberto de Souza intel_dp_stop_link_train(intel_dp, crtc_state); 250323ef6194SJosé Roberto de Souza 250423ef6194SJosé Roberto de Souza /* 6.o Configure and enable FEC if needed */ 250523ef6194SJosé Roberto de Souza intel_ddi_enable_fec(encoder, crtc_state); 250623ef6194SJosé Roberto de Souza 250723ef6194SJosé Roberto de Souza intel_dsc_dp_pps_write(encoder, crtc_state); 250823ef6194SJosé Roberto de Souza } 250923ef6194SJosé Roberto de Souza 2510ede9771dSVille Syrjälä static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, 2511ede9771dSVille Syrjälä struct intel_encoder *encoder, 251299389390SJosé Roberto de Souza const struct intel_crtc_state *crtc_state, 251399389390SJosé Roberto de Souza const struct drm_connector_state *conn_state) 251499389390SJosé Roberto de Souza { 2515b7d02c3aSVille Syrjälä struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 251699389390SJosé Roberto de Souza struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 2517b7d02c3aSVille Syrjälä struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 251899389390SJosé Roberto de Souza bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); 251999389390SJosé Roberto de Souza 2520a621860aSVille Syrjälä intel_dp_set_link_params(intel_dp, 2521a621860aSVille Syrjälä crtc_state->port_clock, 2522a621860aSVille Syrjälä crtc_state->lane_count); 252399389390SJosé Roberto de Souza 25245e19c0b0SMatt Roper /* 25259f620f1dSVille Syrjälä * We only configure what the register value will be here. Actual 25269f620f1dSVille Syrjälä * enabling happens during link training farther down. 25279f620f1dSVille Syrjälä */ 25289f620f1dSVille Syrjälä intel_ddi_init_dp_buf_reg(encoder, crtc_state); 25299f620f1dSVille Syrjälä 25309f620f1dSVille Syrjälä /* 25315e19c0b0SMatt Roper * 1. Enable Power Wells 25325e19c0b0SMatt Roper * 25335e19c0b0SMatt Roper * This was handled at the beginning of intel_atomic_commit_tail(), 25345e19c0b0SMatt Roper * before we called down into this function. 25355e19c0b0SMatt Roper */ 253699389390SJosé Roberto de Souza 25375e19c0b0SMatt Roper /* 2. Enable Panel Power if PPS is required */ 2538eb46f498SJani Nikula intel_pps_on(intel_dp); 253999389390SJosé Roberto de Souza 254099389390SJosé Roberto de Souza /* 25415e19c0b0SMatt Roper * 3. For non-TBT Type-C ports, set FIA lane count 25425e19c0b0SMatt Roper * (DFLEXDPSP.DPX4TXLATC) 25435e19c0b0SMatt Roper * 25445e19c0b0SMatt Roper * This was done before tgl_ddi_pre_enable_dp by 25451e98f88cSLucas De Marchi * hsw_crtc_enable()->intel_encoders_pre_pll_enable(). 254699389390SJosé Roberto de Souza */ 254799389390SJosé Roberto de Souza 25485e19c0b0SMatt Roper /* 25495e19c0b0SMatt Roper * 4. Enable the port PLL. 25505e19c0b0SMatt Roper * 25515e19c0b0SMatt Roper * The PLL enabling itself was already done before this function by 25521e98f88cSLucas De Marchi * hsw_crtc_enable()->intel_enable_shared_dpll(). We need only 25535e19c0b0SMatt Roper * configure the PLL to port mapping here. 25545e19c0b0SMatt Roper */ 2555c133df69SVille Syrjälä intel_ddi_enable_clock(encoder, crtc_state); 25566171e58bSClinton A Taylor 25575e19c0b0SMatt Roper /* 5. If IO power is controlled through PWR_WELL_CTL, Enable IO Power */ 255811a89708SImre Deak if (!intel_tc_port_in_tbt_alt_mode(dig_port)) { 2559a4550977SImre Deak drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref); 2560a4550977SImre Deak dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv, 256199389390SJosé Roberto de Souza dig_port->ddi_io_power_domain); 2562a4550977SImre Deak } 256399389390SJosé Roberto de Souza 25645e19c0b0SMatt Roper /* 6. Program DP_MODE */ 25653b51be4eSClinton A Taylor icl_program_mg_dp_mode(dig_port, crtc_state); 256699389390SJosé Roberto de Souza 256799389390SJosé Roberto de Souza /* 25685e19c0b0SMatt Roper * 7. The rest of the below are substeps under the bspec's "Enable and 25695e19c0b0SMatt Roper * Train Display Port" step. Note that steps that are specific to 25705e19c0b0SMatt Roper * MST will be handled by intel_mst_pre_enable_dp() before/after it 25715e19c0b0SMatt Roper * calls into this function. Also intel_mst_pre_enable_dp() only calls 25725e19c0b0SMatt Roper * us when active_mst_links==0, so any steps designated for "single 25735e19c0b0SMatt Roper * stream or multi-stream master transcoder" can just be performed 25745e19c0b0SMatt Roper * unconditionally here. 25755e19c0b0SMatt Roper */ 25765e19c0b0SMatt Roper 25775e19c0b0SMatt Roper /* 25785e19c0b0SMatt Roper * 7.a Configure Transcoder Clock Select to direct the Port clock to the 25795e19c0b0SMatt Roper * Transcoder. 258099389390SJosé Roberto de Souza */ 258155a4679eSVille Syrjälä intel_ddi_enable_transcoder_clock(encoder, crtc_state); 258299389390SJosé Roberto de Souza 2583fe6959a6SVille Syrjälä if (HAS_DP20(dev_priv)) 2584fe6959a6SVille Syrjälä intel_ddi_config_transcoder_dp2(encoder, crtc_state); 2585fe6959a6SVille Syrjälä 25865e19c0b0SMatt Roper /* 25875e19c0b0SMatt Roper * 7.b Configure TRANS_DDI_FUNC_CTL DDI Select, DDI Mode Select & MST 25885e19c0b0SMatt Roper * Transport Select 25895e19c0b0SMatt Roper */ 2590eed22a46SVille Syrjälä intel_ddi_config_transcoder_func(encoder, crtc_state); 259199389390SJosé Roberto de Souza 25925e19c0b0SMatt Roper /* 25935e19c0b0SMatt Roper * 7.c Configure & enable DP_TP_CTL with link training pattern 1 25945e19c0b0SMatt Roper * selected 25955e19c0b0SMatt Roper * 25965e19c0b0SMatt Roper * This will be handled by the intel_dp_start_link_train() farther 25975e19c0b0SMatt Roper * down this function. 25985e19c0b0SMatt Roper */ 25995e19c0b0SMatt Roper 26005e19c0b0SMatt Roper /* 7.e Configure voltage swing and related IO settings */ 2601e722ab8bSVille Syrjälä encoder->set_signal_levels(encoder, crtc_state); 260299389390SJosé Roberto de Souza 26035e19c0b0SMatt Roper /* 26045e19c0b0SMatt Roper * 7.f Combo PHY: Configure PORT_CL_DW10 Static Power Down to power up 26055e19c0b0SMatt Roper * the used lanes of the DDI. 26065e19c0b0SMatt Roper */ 26075cdf706fSVille Syrjälä intel_ddi_power_up_lanes(encoder, crtc_state); 260899389390SJosé Roberto de Souza 26095e19c0b0SMatt Roper /* 2610bc71194eSJani Nikula * 7.g Program CoG/MSO configuration bits in DSS_CTL1 if selected. 2611bc71194eSJani Nikula */ 2612bc71194eSJani Nikula intel_ddi_mso_configure(crtc_state); 2613bc71194eSJani Nikula 261499389390SJosé Roberto de Souza if (!is_mst) 26150e634efdSVille Syrjälä intel_dp_set_power(intel_dp, DP_SET_POWER_D0); 261699389390SJosé Roberto de Souza 2617522508b6SAnkit Nautiyal intel_dp_configure_protocol_converter(intel_dp, crtc_state); 261899389390SJosé Roberto de Souza intel_dp_sink_set_decompression_state(intel_dp, crtc_state, true); 261999389390SJosé Roberto de Souza /* 262099389390SJosé Roberto de Souza * DDI FEC: "anticipates enabling FEC encoding sets the FEC_READY bit 262199389390SJosé Roberto de Souza * in the FEC_CONFIGURATION register to 1 before initiating link 262299389390SJosé Roberto de Souza * training 262399389390SJosé Roberto de Souza */ 262499389390SJosé Roberto de Souza intel_dp_sink_set_fec_ready(intel_dp, crtc_state); 26255e19c0b0SMatt Roper 26264f3dd47aSAnkit Nautiyal intel_dp_check_frl_training(intel_dp); 262710fec80bSAnkit Nautiyal intel_dp_pcon_dsc_configure(intel_dp, crtc_state); 26284f3dd47aSAnkit Nautiyal 26295e19c0b0SMatt Roper /* 26305e19c0b0SMatt Roper * 7.i Follow DisplayPort specification training sequence (see notes for 26315e19c0b0SMatt Roper * failure handling) 26325e19c0b0SMatt Roper * 7.j If DisplayPort multi-stream - Set DP_TP_CTL link training to Idle 26335e19c0b0SMatt Roper * Pattern, wait for 5 idle patterns (DP_TP_STATUS Min_Idles_Sent) 26345e19c0b0SMatt Roper * (timeout after 800 us) 26355e19c0b0SMatt Roper */ 2636a621860aSVille Syrjälä intel_dp_start_link_train(intel_dp, crtc_state); 263799389390SJosé Roberto de Souza 26385e19c0b0SMatt Roper /* 7.k Set DP_TP_CTL link training to Normal */ 2639eadf6f91SManasi Navare if (!is_trans_port_sync_mode(crtc_state)) 2640a621860aSVille Syrjälä intel_dp_stop_link_train(intel_dp, crtc_state); 264199389390SJosé Roberto de Souza 26425e19c0b0SMatt Roper /* 7.l Configure and enable FEC if needed */ 264399389390SJosé Roberto de Souza intel_ddi_enable_fec(encoder, crtc_state); 26443126977dSVille Syrjälä 26453126977dSVille Syrjälä intel_dsc_dp_pps_write(encoder, crtc_state); 264699389390SJosé Roberto de Souza } 264799389390SJosé Roberto de Souza 2648ede9771dSVille Syrjälä static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, 2649ede9771dSVille Syrjälä struct intel_encoder *encoder, 2650379bc100SJani Nikula const struct intel_crtc_state *crtc_state, 2651379bc100SJani Nikula const struct drm_connector_state *conn_state) 2652379bc100SJani Nikula { 2653b7d02c3aSVille Syrjälä struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 2654379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 2655379bc100SJani Nikula enum port port = encoder->port; 2656b7d02c3aSVille Syrjälä struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 2657379bc100SJani Nikula bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); 2658379bc100SJani Nikula 2659005e9537SMatt Roper if (DISPLAY_VER(dev_priv) < 11) 26601de143ccSPankaj Bharadiya drm_WARN_ON(&dev_priv->drm, 26611de143ccSPankaj Bharadiya is_mst && (port == PORT_A || port == PORT_E)); 2662542dfab5SJosé Roberto de Souza else 26631de143ccSPankaj Bharadiya drm_WARN_ON(&dev_priv->drm, is_mst && port == PORT_A); 2664379bc100SJani Nikula 2665a621860aSVille Syrjälä intel_dp_set_link_params(intel_dp, 2666a621860aSVille Syrjälä crtc_state->port_clock, 2667a621860aSVille Syrjälä crtc_state->lane_count); 2668379bc100SJani Nikula 26699f620f1dSVille Syrjälä /* 26709f620f1dSVille Syrjälä * We only configure what the register value will be here. Actual 26719f620f1dSVille Syrjälä * enabling happens during link training farther down. 26729f620f1dSVille Syrjälä */ 26739f620f1dSVille Syrjälä intel_ddi_init_dp_buf_reg(encoder, crtc_state); 26749f620f1dSVille Syrjälä 2675eb46f498SJani Nikula intel_pps_on(intel_dp); 2676379bc100SJani Nikula 2677c133df69SVille Syrjälä intel_ddi_enable_clock(encoder, crtc_state); 2678379bc100SJani Nikula 267911a89708SImre Deak if (!intel_tc_port_in_tbt_alt_mode(dig_port)) { 2680a4550977SImre Deak drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref); 2681a4550977SImre Deak dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv, 26823b2ed431SImre Deak dig_port->ddi_io_power_domain); 2683a4550977SImre Deak } 2684379bc100SJani Nikula 26853b51be4eSClinton A Taylor icl_program_mg_dp_mode(dig_port, crtc_state); 2686379bc100SJani Nikula 26875bafd85dSVille Syrjälä if (has_buf_trans_select(dev_priv)) 2688266152aeSVille Syrjälä hsw_prepare_dp_ddi_buffers(encoder, crtc_state); 2689379bc100SJani Nikula 2690e722ab8bSVille Syrjälä encoder->set_signal_levels(encoder, crtc_state); 2691e722ab8bSVille Syrjälä 26925cdf706fSVille Syrjälä intel_ddi_power_up_lanes(encoder, crtc_state); 2693379bc100SJani Nikula 2694379bc100SJani Nikula if (!is_mst) 26950e634efdSVille Syrjälä intel_dp_set_power(intel_dp, DP_SET_POWER_D0); 2696522508b6SAnkit Nautiyal intel_dp_configure_protocol_converter(intel_dp, crtc_state); 2697379bc100SJani Nikula intel_dp_sink_set_decompression_state(intel_dp, crtc_state, 2698379bc100SJani Nikula true); 2699379bc100SJani Nikula intel_dp_sink_set_fec_ready(intel_dp, crtc_state); 2700a621860aSVille Syrjälä intel_dp_start_link_train(intel_dp, crtc_state); 2701005e9537SMatt Roper if ((port != PORT_A || DISPLAY_VER(dev_priv) >= 9) && 2702eadf6f91SManasi Navare !is_trans_port_sync_mode(crtc_state)) 2703a621860aSVille Syrjälä intel_dp_stop_link_train(intel_dp, crtc_state); 2704379bc100SJani Nikula 2705379bc100SJani Nikula intel_ddi_enable_fec(encoder, crtc_state); 2706379bc100SJani Nikula 2707379bc100SJani Nikula if (!is_mst) 270855a4679eSVille Syrjälä intel_ddi_enable_transcoder_clock(encoder, crtc_state); 2709379bc100SJani Nikula 27103126977dSVille Syrjälä intel_dsc_dp_pps_write(encoder, crtc_state); 2711379bc100SJani Nikula } 2712379bc100SJani Nikula 2713ede9771dSVille Syrjälä static void intel_ddi_pre_enable_dp(struct intel_atomic_state *state, 2714ede9771dSVille Syrjälä struct intel_encoder *encoder, 271599389390SJosé Roberto de Souza const struct intel_crtc_state *crtc_state, 271699389390SJosé Roberto de Souza const struct drm_connector_state *conn_state) 271799389390SJosé Roberto de Souza { 271899389390SJosé Roberto de Souza struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 271999389390SJosé Roberto de Souza 27201a324a40SArun R Murthy if (HAS_DP20(dev_priv)) 27211a324a40SArun R Murthy intel_dp_128b132b_sdp_crc16(enc_to_intel_dp(encoder), 27221a324a40SArun R Murthy crtc_state); 27231a324a40SArun R Murthy 272423ef6194SJosé Roberto de Souza if (DISPLAY_VER(dev_priv) >= 14) 272523ef6194SJosé Roberto de Souza mtl_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state); 272623ef6194SJosé Roberto de Souza else if (DISPLAY_VER(dev_priv) >= 12) 2727ede9771dSVille Syrjälä tgl_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state); 272899389390SJosé Roberto de Souza else 2729ede9771dSVille Syrjälä hsw_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state); 27300c06fa15SGwan-gyeong Mun 2731bd8c9ccaSGwan-gyeong Mun /* MST will call a setting of MSA after an allocating of Virtual Channel 2732bd8c9ccaSGwan-gyeong Mun * from MST encoder pre_enable callback. 2733bd8c9ccaSGwan-gyeong Mun */ 27348de5df3bSVille Syrjälä if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) 27350c06fa15SGwan-gyeong Mun intel_ddi_set_dp_msa(crtc_state, conn_state); 27361fc1e8d4SJosé Roberto de Souza } 273799389390SJosé Roberto de Souza 2738ede9771dSVille Syrjälä static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state, 2739ede9771dSVille Syrjälä struct intel_encoder *encoder, 2740379bc100SJani Nikula const struct intel_crtc_state *crtc_state, 2741379bc100SJani Nikula const struct drm_connector_state *conn_state) 2742379bc100SJani Nikula { 27430ba7ffeaSLucas De Marchi struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 27440ba7ffeaSLucas De Marchi struct intel_hdmi *intel_hdmi = &dig_port->hdmi; 2745379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 2746379bc100SJani Nikula 2747379bc100SJani Nikula intel_dp_dual_mode_set_tmds_output(intel_hdmi, true); 2748c133df69SVille Syrjälä intel_ddi_enable_clock(encoder, crtc_state); 2749379bc100SJani Nikula 2750a4550977SImre Deak drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref); 2751a4550977SImre Deak dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv, 2752a4550977SImre Deak dig_port->ddi_io_power_domain); 2753379bc100SJani Nikula 27543b51be4eSClinton A Taylor icl_program_mg_dp_mode(dig_port, crtc_state); 2755379bc100SJani Nikula 275655a4679eSVille Syrjälä intel_ddi_enable_transcoder_clock(encoder, crtc_state); 2757379bc100SJani Nikula 27580ba7ffeaSLucas De Marchi dig_port->set_infoframes(encoder, 2759379bc100SJani Nikula crtc_state->has_infoframe, 2760379bc100SJani Nikula crtc_state, conn_state); 2761379bc100SJani Nikula } 2762379bc100SJani Nikula 2763ede9771dSVille Syrjälä static void intel_ddi_pre_enable(struct intel_atomic_state *state, 2764ede9771dSVille Syrjälä struct intel_encoder *encoder, 2765379bc100SJani Nikula const struct intel_crtc_state *crtc_state, 2766379bc100SJani Nikula const struct drm_connector_state *conn_state) 2767379bc100SJani Nikula { 27682225f3c6SMaarten Lankhorst struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 2769379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 2770379bc100SJani Nikula enum pipe pipe = crtc->pipe; 2771379bc100SJani Nikula 2772379bc100SJani Nikula /* 2773379bc100SJani Nikula * When called from DP MST code: 2774379bc100SJani Nikula * - conn_state will be NULL 2775379bc100SJani Nikula * - encoder will be the main encoder (ie. mst->primary) 2776379bc100SJani Nikula * - the main connector associated with this port 2777379bc100SJani Nikula * won't be active or linked to a crtc 2778379bc100SJani Nikula * - crtc_state will be the state of the first stream to 2779379bc100SJani Nikula * be activated on this port, and it may not be the same 2780379bc100SJani Nikula * stream that will be deactivated last, but each stream 2781379bc100SJani Nikula * should have a state that is identical when it comes to 2782379bc100SJani Nikula * the DP link parameteres 2783379bc100SJani Nikula */ 2784379bc100SJani Nikula 27851de143ccSPankaj Bharadiya drm_WARN_ON(&dev_priv->drm, crtc_state->has_pch_encoder); 2786379bc100SJani Nikula 2787379bc100SJani Nikula intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); 2788379bc100SJani Nikula 2789379bc100SJani Nikula if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { 2790ede9771dSVille Syrjälä intel_ddi_pre_enable_hdmi(state, encoder, crtc_state, 2791ede9771dSVille Syrjälä conn_state); 2792379bc100SJani Nikula } else { 2793f7af425dSVille Syrjälä struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 2794379bc100SJani Nikula 2795ede9771dSVille Syrjälä intel_ddi_pre_enable_dp(state, encoder, crtc_state, 2796ede9771dSVille Syrjälä conn_state); 2797379bc100SJani Nikula 2798f7af425dSVille Syrjälä /* FIXME precompute everything properly */ 27990ea02bb8SJosé Roberto de Souza /* FIXME how do we turn infoframes off again? */ 28007ffa2f27SJani Nikula if (dig_port->lspcon.active && intel_dp_has_hdmi_sink(&dig_port->dp)) 2801379bc100SJani Nikula dig_port->set_infoframes(encoder, 2802379bc100SJani Nikula crtc_state->has_infoframe, 2803379bc100SJani Nikula crtc_state, conn_state); 2804379bc100SJani Nikula } 2805379bc100SJani Nikula } 2806379bc100SJani Nikula 280723ef6194SJosé Roberto de Souza static void 280823ef6194SJosé Roberto de Souza mtl_ddi_disable_d2d_link(struct intel_encoder *encoder) 280923ef6194SJosé Roberto de Souza { 281023ef6194SJosé Roberto de Souza struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 281123ef6194SJosé Roberto de Souza enum port port = encoder->port; 281223ef6194SJosé Roberto de Souza 281323ef6194SJosé Roberto de Souza intel_de_rmw(dev_priv, XELPDP_PORT_BUF_CTL1(port), 281423ef6194SJosé Roberto de Souza XELPDP_PORT_BUF_D2D_LINK_ENABLE, 0); 281523ef6194SJosé Roberto de Souza 281623ef6194SJosé Roberto de Souza if (wait_for_us(!(intel_de_read(dev_priv, XELPDP_PORT_BUF_CTL1(port)) & 281723ef6194SJosé Roberto de Souza XELPDP_PORT_BUF_D2D_LINK_STATE), 100)) 281823ef6194SJosé Roberto de Souza drm_err(&dev_priv->drm, "Timeout waiting for D2D Link disable for PORT_BUF_CTL %c\n", 281923ef6194SJosé Roberto de Souza port_name(port)); 282023ef6194SJosé Roberto de Souza } 282123ef6194SJosé Roberto de Souza 282223ef6194SJosé Roberto de Souza static void mtl_disable_ddi_buf(struct intel_encoder *encoder, 282323ef6194SJosé Roberto de Souza const struct intel_crtc_state *crtc_state) 282423ef6194SJosé Roberto de Souza { 282523ef6194SJosé Roberto de Souza struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 282623ef6194SJosé Roberto de Souza enum port port = encoder->port; 282723ef6194SJosé Roberto de Souza u32 val; 282823ef6194SJosé Roberto de Souza 282923ef6194SJosé Roberto de Souza /* 3.b Clear DDI_CTL_DE Enable to 0. */ 283023ef6194SJosé Roberto de Souza val = intel_de_read(dev_priv, DDI_BUF_CTL(port)); 283123ef6194SJosé Roberto de Souza if (val & DDI_BUF_CTL_ENABLE) { 283223ef6194SJosé Roberto de Souza val &= ~DDI_BUF_CTL_ENABLE; 283323ef6194SJosé Roberto de Souza intel_de_write(dev_priv, DDI_BUF_CTL(port), val); 283423ef6194SJosé Roberto de Souza 283523ef6194SJosé Roberto de Souza /* 3.c Poll for PORT_BUF_CTL Idle Status == 1, timeout after 100us */ 283623ef6194SJosé Roberto de Souza mtl_wait_ddi_buf_idle(dev_priv, port); 283723ef6194SJosé Roberto de Souza } 283823ef6194SJosé Roberto de Souza 283923ef6194SJosé Roberto de Souza /* 3.d Disable D2D Link */ 284023ef6194SJosé Roberto de Souza mtl_ddi_disable_d2d_link(encoder); 284123ef6194SJosé Roberto de Souza 284223ef6194SJosé Roberto de Souza /* 3.e Disable DP_TP_CTL */ 284323ef6194SJosé Roberto de Souza if (intel_crtc_has_dp_encoder(crtc_state)) { 284423ef6194SJosé Roberto de Souza intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), 284523ef6194SJosé Roberto de Souza DP_TP_CTL_ENABLE, 0); 284623ef6194SJosé Roberto de Souza } 284723ef6194SJosé Roberto de Souza } 284823ef6194SJosé Roberto de Souza 284923ef6194SJosé Roberto de Souza static void disable_ddi_buf(struct intel_encoder *encoder, 2850379bc100SJani Nikula const struct intel_crtc_state *crtc_state) 2851379bc100SJani Nikula { 2852379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 2853379bc100SJani Nikula enum port port = encoder->port; 2854379bc100SJani Nikula bool wait = false; 2855379bc100SJani Nikula u32 val; 2856379bc100SJani Nikula 2857f7960e7fSJani Nikula val = intel_de_read(dev_priv, DDI_BUF_CTL(port)); 2858379bc100SJani Nikula if (val & DDI_BUF_CTL_ENABLE) { 2859379bc100SJani Nikula val &= ~DDI_BUF_CTL_ENABLE; 2860f7960e7fSJani Nikula intel_de_write(dev_priv, DDI_BUF_CTL(port), val); 2861379bc100SJani Nikula wait = true; 2862379bc100SJani Nikula } 2863379bc100SJani Nikula 28648910d8b7SAndrzej Hajda if (intel_crtc_has_dp_encoder(crtc_state)) 28658910d8b7SAndrzej Hajda intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), 28668c042949SVille Syrjälä DP_TP_CTL_ENABLE, 0); 2867379bc100SJani Nikula 2868379bc100SJani Nikula /* Disable FEC in DP Sink */ 2869379bc100SJani Nikula intel_ddi_disable_fec_state(encoder, crtc_state); 2870379bc100SJani Nikula 2871379bc100SJani Nikula if (wait) 2872379bc100SJani Nikula intel_wait_ddi_buf_idle(dev_priv, port); 2873379bc100SJani Nikula } 2874379bc100SJani Nikula 287523ef6194SJosé Roberto de Souza static void intel_disable_ddi_buf(struct intel_encoder *encoder, 287623ef6194SJosé Roberto de Souza const struct intel_crtc_state *crtc_state) 287723ef6194SJosé Roberto de Souza { 287823ef6194SJosé Roberto de Souza struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 287923ef6194SJosé Roberto de Souza 288023ef6194SJosé Roberto de Souza if (DISPLAY_VER(dev_priv) >= 14) { 288123ef6194SJosé Roberto de Souza mtl_disable_ddi_buf(encoder, crtc_state); 288223ef6194SJosé Roberto de Souza 288323ef6194SJosé Roberto de Souza /* 3.f Disable DP_TP_CTL FEC Enable if it is needed */ 288423ef6194SJosé Roberto de Souza intel_ddi_disable_fec_state(encoder, crtc_state); 288523ef6194SJosé Roberto de Souza } else { 288623ef6194SJosé Roberto de Souza disable_ddi_buf(encoder, crtc_state); 288723ef6194SJosé Roberto de Souza } 288823ef6194SJosé Roberto de Souza } 288923ef6194SJosé Roberto de Souza 2890ede9771dSVille Syrjälä static void intel_ddi_post_disable_dp(struct intel_atomic_state *state, 2891ede9771dSVille Syrjälä struct intel_encoder *encoder, 2892379bc100SJani Nikula const struct intel_crtc_state *old_crtc_state, 2893379bc100SJani Nikula const struct drm_connector_state *old_conn_state) 2894379bc100SJani Nikula { 2895379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 2896b7d02c3aSVille Syrjälä struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 2897379bc100SJani Nikula struct intel_dp *intel_dp = &dig_port->dp; 289823ef6194SJosé Roberto de Souza intel_wakeref_t wakeref; 2899379bc100SJani Nikula bool is_mst = intel_crtc_has_type(old_crtc_state, 2900379bc100SJani Nikula INTEL_OUTPUT_DP_MST); 2901379bc100SJani Nikula 2902c980216dSImre Deak if (!is_mst) 2903c980216dSImre Deak intel_dp_set_infoframes(encoder, false, 2904c980216dSImre Deak old_crtc_state, old_conn_state); 2905fa37a213SGwan-gyeong Mun 2906379bc100SJani Nikula /* 2907379bc100SJani Nikula * Power down sink before disabling the port, otherwise we end 2908379bc100SJani Nikula * up getting interrupts from the sink on detecting link loss. 2909379bc100SJani Nikula */ 29100e634efdSVille Syrjälä intel_dp_set_power(intel_dp, DP_SET_POWER_D3); 291178eaaba3SJosé Roberto de Souza 2912005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 12) { 2913c59053dcSJosé Roberto de Souza if (is_mst) { 2914c59053dcSJosé Roberto de Souza enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder; 2915c59053dcSJosé Roberto de Souza 29168910d8b7SAndrzej Hajda intel_de_rmw(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder), 29178910d8b7SAndrzej Hajda TGL_TRANS_DDI_PORT_MASK | TRANS_DDI_MODE_SELECT_MASK, 29188910d8b7SAndrzej Hajda 0); 2919c59053dcSJosé Roberto de Souza } 2920c59053dcSJosé Roberto de Souza } else { 2921c59053dcSJosé Roberto de Souza if (!is_mst) 292255a4679eSVille Syrjälä intel_ddi_disable_transcoder_clock(old_crtc_state); 2923c59053dcSJosé Roberto de Souza } 2924379bc100SJani Nikula 2925379bc100SJani Nikula intel_disable_ddi_buf(encoder, old_crtc_state); 2926379bc100SJani Nikula 29273ca8f191SJosé Roberto de Souza /* 29283ca8f191SJosé Roberto de Souza * From TGL spec: "If single stream or multi-stream master transcoder: 29293ca8f191SJosé Roberto de Souza * Configure Transcoder Clock select to direct no clock to the 29303ca8f191SJosé Roberto de Souza * transcoder" 29313ca8f191SJosé Roberto de Souza */ 2932005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 12) 293355a4679eSVille Syrjälä intel_ddi_disable_transcoder_clock(old_crtc_state); 29343ca8f191SJosé Roberto de Souza 2935eb46f498SJani Nikula intel_pps_vdd_on(intel_dp); 2936eb46f498SJani Nikula intel_pps_off(intel_dp); 2937379bc100SJani Nikula 293823ef6194SJosé Roberto de Souza wakeref = fetch_and_zero(&dig_port->ddi_io_wakeref); 293923ef6194SJosé Roberto de Souza 294023ef6194SJosé Roberto de Souza if (wakeref) 2941a4550977SImre Deak intel_display_power_put(dev_priv, 2942a4550977SImre Deak dig_port->ddi_io_power_domain, 294323ef6194SJosé Roberto de Souza wakeref); 2944379bc100SJani Nikula 2945c133df69SVille Syrjälä intel_ddi_disable_clock(encoder); 294623ef6194SJosé Roberto de Souza 294723ef6194SJosé Roberto de Souza /* De-select Thunderbolt */ 294823ef6194SJosé Roberto de Souza if (DISPLAY_VER(dev_priv) >= 14) 294923ef6194SJosé Roberto de Souza intel_de_rmw(dev_priv, XELPDP_PORT_BUF_CTL1(encoder->port), 295023ef6194SJosé Roberto de Souza XELPDP_PORT_BUF_IO_SELECT_TBT, 0); 2951379bc100SJani Nikula } 2952379bc100SJani Nikula 2953ede9771dSVille Syrjälä static void intel_ddi_post_disable_hdmi(struct intel_atomic_state *state, 2954ede9771dSVille Syrjälä struct intel_encoder *encoder, 2955379bc100SJani Nikula const struct intel_crtc_state *old_crtc_state, 2956379bc100SJani Nikula const struct drm_connector_state *old_conn_state) 2957379bc100SJani Nikula { 2958379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 2959b7d02c3aSVille Syrjälä struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 2960379bc100SJani Nikula struct intel_hdmi *intel_hdmi = &dig_port->hdmi; 296123ef6194SJosé Roberto de Souza intel_wakeref_t wakeref; 2962379bc100SJani Nikula 2963379bc100SJani Nikula dig_port->set_infoframes(encoder, false, 2964379bc100SJani Nikula old_crtc_state, old_conn_state); 2965379bc100SJani Nikula 2966c1949189SImre Deak if (DISPLAY_VER(dev_priv) < 12) 296755a4679eSVille Syrjälä intel_ddi_disable_transcoder_clock(old_crtc_state); 2968379bc100SJani Nikula 2969379bc100SJani Nikula intel_disable_ddi_buf(encoder, old_crtc_state); 2970379bc100SJani Nikula 2971c1949189SImre Deak if (DISPLAY_VER(dev_priv) >= 12) 297255a4679eSVille Syrjälä intel_ddi_disable_transcoder_clock(old_crtc_state); 2973c1949189SImre Deak 297423ef6194SJosé Roberto de Souza wakeref = fetch_and_zero(&dig_port->ddi_io_wakeref); 297523ef6194SJosé Roberto de Souza if (wakeref) 2976a4550977SImre Deak intel_display_power_put(dev_priv, 2977a4550977SImre Deak dig_port->ddi_io_power_domain, 297823ef6194SJosé Roberto de Souza wakeref); 2979379bc100SJani Nikula 2980c133df69SVille Syrjälä intel_ddi_disable_clock(encoder); 2981379bc100SJani Nikula 2982379bc100SJani Nikula intel_dp_dual_mode_set_tmds_output(intel_hdmi, false); 2983379bc100SJani Nikula } 2984379bc100SJani Nikula 2985ede9771dSVille Syrjälä static void intel_ddi_post_disable(struct intel_atomic_state *state, 2986ede9771dSVille Syrjälä struct intel_encoder *encoder, 2987379bc100SJani Nikula const struct intel_crtc_state *old_crtc_state, 2988379bc100SJani Nikula const struct drm_connector_state *old_conn_state) 2989379bc100SJani Nikula { 2990379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 2991a6e7a006SVille Syrjälä struct intel_crtc *slave_crtc; 2992379bc100SJani Nikula 29937829c92bSVille Syrjälä if (!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST)) { 2994773b4b54SVille Syrjälä intel_crtc_vblank_off(old_crtc_state); 2995773b4b54SVille Syrjälä 29960504d0acSVille Syrjälä intel_disable_transcoder(old_crtc_state); 29970504d0acSVille Syrjälä 2998773b4b54SVille Syrjälä intel_ddi_disable_transcoder_func(old_crtc_state); 2999773b4b54SVille Syrjälä 3000773b4b54SVille Syrjälä intel_dsc_disable(old_crtc_state); 3001773b4b54SVille Syrjälä 3002005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 9) 3003f6df4d46SLucas De Marchi skl_scaler_disable(old_crtc_state); 3004773b4b54SVille Syrjälä else 30059eae5e27SLucas De Marchi ilk_pfit_disable(old_crtc_state); 30067829c92bSVille Syrjälä } 3007773b4b54SVille Syrjälä 3008a6e7a006SVille Syrjälä for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, slave_crtc, 3009a6e7a006SVille Syrjälä intel_crtc_bigjoiner_slave_pipes(old_crtc_state)) { 30104e3cdb45SManasi Navare const struct intel_crtc_state *old_slave_crtc_state = 3011f2e19b58SVille Syrjälä intel_atomic_get_old_crtc_state(state, slave_crtc); 30124e3cdb45SManasi Navare 30134e3cdb45SManasi Navare intel_crtc_vblank_off(old_slave_crtc_state); 30144e3cdb45SManasi Navare 30154e3cdb45SManasi Navare intel_dsc_disable(old_slave_crtc_state); 30164e3cdb45SManasi Navare skl_scaler_disable(old_slave_crtc_state); 30174e3cdb45SManasi Navare } 30184e3cdb45SManasi Navare 3019379bc100SJani Nikula /* 3020379bc100SJani Nikula * When called from DP MST code: 3021379bc100SJani Nikula * - old_conn_state will be NULL 3022379bc100SJani Nikula * - encoder will be the main encoder (ie. mst->primary) 3023379bc100SJani Nikula * - the main connector associated with this port 3024379bc100SJani Nikula * won't be active or linked to a crtc 3025379bc100SJani Nikula * - old_crtc_state will be the state of the last stream to 3026379bc100SJani Nikula * be deactivated on this port, and it may not be the same 3027379bc100SJani Nikula * stream that was activated last, but each stream 3028379bc100SJani Nikula * should have a state that is identical when it comes to 3029379bc100SJani Nikula * the DP link parameteres 3030379bc100SJani Nikula */ 3031379bc100SJani Nikula 3032379bc100SJani Nikula if (intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_HDMI)) 3033ede9771dSVille Syrjälä intel_ddi_post_disable_hdmi(state, encoder, old_crtc_state, 3034ede9771dSVille Syrjälä old_conn_state); 3035379bc100SJani Nikula else 3036ede9771dSVille Syrjälä intel_ddi_post_disable_dp(state, encoder, old_crtc_state, 3037ede9771dSVille Syrjälä old_conn_state); 3038b108bdd0SImre Deak } 3039b108bdd0SImre Deak 3040b108bdd0SImre Deak static void intel_ddi_post_pll_disable(struct intel_atomic_state *state, 3041b108bdd0SImre Deak struct intel_encoder *encoder, 3042b108bdd0SImre Deak const struct intel_crtc_state *old_crtc_state, 3043b108bdd0SImre Deak const struct drm_connector_state *old_conn_state) 3044b108bdd0SImre Deak { 3045b108bdd0SImre Deak struct drm_i915_private *i915 = to_i915(encoder->base.dev); 3046b108bdd0SImre Deak struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 3047b108bdd0SImre Deak enum phy phy = intel_port_to_phy(i915, encoder->port); 3048b108bdd0SImre Deak bool is_tc_port = intel_phy_is_tc(i915, phy); 3049379bc100SJani Nikula 3050637c7aa2SImre Deak main_link_aux_power_domain_put(dig_port, old_crtc_state); 305117bef9baSVille Syrjälä 305217bef9baSVille Syrjälä if (is_tc_port) 305317bef9baSVille Syrjälä intel_tc_port_put_link(dig_port); 3054379bc100SJani Nikula } 3055379bc100SJani Nikula 3056d82a855aSVille Syrjälä static void trans_port_sync_stop_link_train(struct intel_atomic_state *state, 3057d82a855aSVille Syrjälä struct intel_encoder *encoder, 3058d82a855aSVille Syrjälä const struct intel_crtc_state *crtc_state) 3059d82a855aSVille Syrjälä { 3060d82a855aSVille Syrjälä const struct drm_connector_state *conn_state; 3061d82a855aSVille Syrjälä struct drm_connector *conn; 3062d82a855aSVille Syrjälä int i; 3063d82a855aSVille Syrjälä 3064d82a855aSVille Syrjälä if (!crtc_state->sync_mode_slaves_mask) 3065d82a855aSVille Syrjälä return; 3066d82a855aSVille Syrjälä 3067d82a855aSVille Syrjälä for_each_new_connector_in_state(&state->base, conn, conn_state, i) { 3068d82a855aSVille Syrjälä struct intel_encoder *slave_encoder = 3069d82a855aSVille Syrjälä to_intel_encoder(conn_state->best_encoder); 3070d82a855aSVille Syrjälä struct intel_crtc *slave_crtc = to_intel_crtc(conn_state->crtc); 3071d82a855aSVille Syrjälä const struct intel_crtc_state *slave_crtc_state; 3072d82a855aSVille Syrjälä 3073d82a855aSVille Syrjälä if (!slave_crtc) 3074d82a855aSVille Syrjälä continue; 3075d82a855aSVille Syrjälä 3076d82a855aSVille Syrjälä slave_crtc_state = 3077d82a855aSVille Syrjälä intel_atomic_get_new_crtc_state(state, slave_crtc); 3078d82a855aSVille Syrjälä 3079d82a855aSVille Syrjälä if (slave_crtc_state->master_transcoder != 3080d82a855aSVille Syrjälä crtc_state->cpu_transcoder) 3081d82a855aSVille Syrjälä continue; 3082d82a855aSVille Syrjälä 3083a621860aSVille Syrjälä intel_dp_stop_link_train(enc_to_intel_dp(slave_encoder), 3084a621860aSVille Syrjälä slave_crtc_state); 3085d82a855aSVille Syrjälä } 3086d82a855aSVille Syrjälä 3087d82a855aSVille Syrjälä usleep_range(200, 400); 3088d82a855aSVille Syrjälä 3089a621860aSVille Syrjälä intel_dp_stop_link_train(enc_to_intel_dp(encoder), 3090a621860aSVille Syrjälä crtc_state); 3091d82a855aSVille Syrjälä } 3092d82a855aSVille Syrjälä 3093ede9771dSVille Syrjälä static void intel_enable_ddi_dp(struct intel_atomic_state *state, 3094ede9771dSVille Syrjälä struct intel_encoder *encoder, 3095379bc100SJani Nikula const struct intel_crtc_state *crtc_state, 3096379bc100SJani Nikula const struct drm_connector_state *conn_state) 3097379bc100SJani Nikula { 3098379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 3099b7d02c3aSVille Syrjälä struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 3100998cc864SUma Shankar struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 3101379bc100SJani Nikula enum port port = encoder->port; 3102379bc100SJani Nikula 3103005e9537SMatt Roper if (port == PORT_A && DISPLAY_VER(dev_priv) < 9) 3104a621860aSVille Syrjälä intel_dp_stop_link_train(intel_dp, crtc_state); 3105379bc100SJani Nikula 31066306d8dbSHans de Goede drm_connector_update_privacy_screen(conn_state); 3107379bc100SJani Nikula intel_edp_backlight_on(crtc_state, conn_state); 3108998cc864SUma Shankar 31097ffa2f27SJani Nikula if (!dig_port->lspcon.active || intel_dp_has_hdmi_sink(&dig_port->dp)) 31101bf3657cSGwan-gyeong Mun intel_dp_set_infoframes(encoder, true, crtc_state, conn_state); 3111998cc864SUma Shankar 3112379bc100SJani Nikula intel_audio_codec_enable(encoder, crtc_state, conn_state); 3113d82a855aSVille Syrjälä 3114d82a855aSVille Syrjälä trans_port_sync_stop_link_train(state, encoder, crtc_state); 3115379bc100SJani Nikula } 3116379bc100SJani Nikula 3117379bc100SJani Nikula static i915_reg_t 3118379bc100SJani Nikula gen9_chicken_trans_reg_by_port(struct drm_i915_private *dev_priv, 3119379bc100SJani Nikula enum port port) 3120379bc100SJani Nikula { 312112c4d4c1SVille Syrjälä static const enum transcoder trans[] = { 312212c4d4c1SVille Syrjälä [PORT_A] = TRANSCODER_EDP, 312312c4d4c1SVille Syrjälä [PORT_B] = TRANSCODER_A, 312412c4d4c1SVille Syrjälä [PORT_C] = TRANSCODER_B, 312512c4d4c1SVille Syrjälä [PORT_D] = TRANSCODER_C, 312612c4d4c1SVille Syrjälä [PORT_E] = TRANSCODER_A, 3127379bc100SJani Nikula }; 3128379bc100SJani Nikula 3129005e9537SMatt Roper drm_WARN_ON(&dev_priv->drm, DISPLAY_VER(dev_priv) < 9); 3130379bc100SJani Nikula 31311de143ccSPankaj Bharadiya if (drm_WARN_ON(&dev_priv->drm, port < PORT_A || port > PORT_E)) 3132379bc100SJani Nikula port = PORT_A; 3133379bc100SJani Nikula 313412c4d4c1SVille Syrjälä return CHICKEN_TRANS(trans[port]); 3135379bc100SJani Nikula } 3136379bc100SJani Nikula 3137ede9771dSVille Syrjälä static void intel_enable_ddi_hdmi(struct intel_atomic_state *state, 3138ede9771dSVille Syrjälä struct intel_encoder *encoder, 3139379bc100SJani Nikula const struct intel_crtc_state *crtc_state, 3140379bc100SJani Nikula const struct drm_connector_state *conn_state) 3141379bc100SJani Nikula { 3142379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 3143b7d02c3aSVille Syrjälä struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 3144379bc100SJani Nikula struct drm_connector *connector = conn_state->connector; 3145379bc100SJani Nikula enum port port = encoder->port; 3146e99ba962SImre Deak enum phy phy = intel_port_to_phy(dev_priv, port); 3147e99ba962SImre Deak u32 buf_ctl; 3148379bc100SJani Nikula 3149379bc100SJani Nikula if (!intel_hdmi_handle_sink_scrambling(encoder, connector, 3150379bc100SJani Nikula crtc_state->hdmi_high_tmds_clock_ratio, 3151379bc100SJani Nikula crtc_state->hdmi_scrambling)) 315247bdb1caSJani Nikula drm_dbg_kms(&dev_priv->drm, 315347bdb1caSJani Nikula "[CONNECTOR:%d:%s] Failed to configure sink scrambling/TMDS bit clock ratio\n", 3154379bc100SJani Nikula connector->base.id, connector->name); 3155379bc100SJani Nikula 31565bafd85dSVille Syrjälä if (has_buf_trans_select(dev_priv)) 3157e722ab8bSVille Syrjälä hsw_prepare_hdmi_ddi_buffers(encoder, crtc_state); 3158c9b69041SVille Syrjälä 3159b66a8abaSAnkit Nautiyal /* e. Enable D2D Link for C10/C20 Phy */ 3160b66a8abaSAnkit Nautiyal if (DISPLAY_VER(dev_priv) >= 14) 3161b66a8abaSAnkit Nautiyal mtl_ddi_enable_d2d(encoder); 3162b66a8abaSAnkit Nautiyal 3163e722ab8bSVille Syrjälä encoder->set_signal_levels(encoder, crtc_state); 3164c9b69041SVille Syrjälä 3165379bc100SJani Nikula /* Display WA #1143: skl,kbl,cfl */ 316693e7e61eSLucas De Marchi if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv)) { 3167379bc100SJani Nikula /* 3168379bc100SJani Nikula * For some reason these chicken bits have been 3169379bc100SJani Nikula * stuffed into a transcoder register, event though 3170379bc100SJani Nikula * the bits affect a specific DDI port rather than 3171379bc100SJani Nikula * a specific transcoder. 3172379bc100SJani Nikula */ 3173379bc100SJani Nikula i915_reg_t reg = gen9_chicken_trans_reg_by_port(dev_priv, port); 3174379bc100SJani Nikula u32 val; 3175379bc100SJani Nikula 3176f7960e7fSJani Nikula val = intel_de_read(dev_priv, reg); 3177379bc100SJani Nikula 3178379bc100SJani Nikula if (port == PORT_E) 3179379bc100SJani Nikula val |= DDIE_TRAINING_OVERRIDE_ENABLE | 3180379bc100SJani Nikula DDIE_TRAINING_OVERRIDE_VALUE; 3181379bc100SJani Nikula else 3182379bc100SJani Nikula val |= DDI_TRAINING_OVERRIDE_ENABLE | 3183379bc100SJani Nikula DDI_TRAINING_OVERRIDE_VALUE; 3184379bc100SJani Nikula 3185f7960e7fSJani Nikula intel_de_write(dev_priv, reg, val); 3186f7960e7fSJani Nikula intel_de_posting_read(dev_priv, reg); 3187379bc100SJani Nikula 3188379bc100SJani Nikula udelay(1); 3189379bc100SJani Nikula 3190379bc100SJani Nikula if (port == PORT_E) 3191379bc100SJani Nikula val &= ~(DDIE_TRAINING_OVERRIDE_ENABLE | 3192379bc100SJani Nikula DDIE_TRAINING_OVERRIDE_VALUE); 3193379bc100SJani Nikula else 3194379bc100SJani Nikula val &= ~(DDI_TRAINING_OVERRIDE_ENABLE | 3195379bc100SJani Nikula DDI_TRAINING_OVERRIDE_VALUE); 3196379bc100SJani Nikula 3197f7960e7fSJani Nikula intel_de_write(dev_priv, reg, val); 3198379bc100SJani Nikula } 3199379bc100SJani Nikula 32001e0cb7beSVille Syrjälä intel_ddi_power_up_lanes(encoder, crtc_state); 32011e0cb7beSVille Syrjälä 3202379bc100SJani Nikula /* In HDMI/DVI mode, the port width, and swing/emphasis values 3203379bc100SJani Nikula * are ignored so nothing special needs to be done besides 3204379bc100SJani Nikula * enabling the port. 3205414002f1SImre Deak * 3206414002f1SImre Deak * On ADL_P the PHY link rate and lane count must be programmed but 3207414002f1SImre Deak * these are both 0 for HDMI. 3208b66a8abaSAnkit Nautiyal * 3209b66a8abaSAnkit Nautiyal * But MTL onwards HDMI2.1 is supported and in TMDS mode this 3210b66a8abaSAnkit Nautiyal * is filled with lane count, already set in the crtc_state. 3211b66a8abaSAnkit Nautiyal * The same is required to be filled in PORT_BUF_CTL for C10/20 Phy. 3212379bc100SJani Nikula */ 3213e99ba962SImre Deak buf_ctl = dig_port->saved_port_bits | DDI_BUF_CTL_ENABLE; 3214b66a8abaSAnkit Nautiyal if (DISPLAY_VER(dev_priv) >= 14) { 3215b66a8abaSAnkit Nautiyal u8 lane_count = mtl_get_port_width(crtc_state->lane_count); 3216b66a8abaSAnkit Nautiyal u32 port_buf = 0; 3217b66a8abaSAnkit Nautiyal 3218b66a8abaSAnkit Nautiyal port_buf |= XELPDP_PORT_WIDTH(lane_count); 3219b66a8abaSAnkit Nautiyal 3220b66a8abaSAnkit Nautiyal if (dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL) 3221b66a8abaSAnkit Nautiyal port_buf |= XELPDP_PORT_REVERSAL; 3222b66a8abaSAnkit Nautiyal 3223b66a8abaSAnkit Nautiyal intel_de_rmw(dev_priv, XELPDP_PORT_BUF_CTL1(port), 3224b66a8abaSAnkit Nautiyal XELPDP_PORT_WIDTH_MASK | XELPDP_PORT_REVERSAL, port_buf); 3225b66a8abaSAnkit Nautiyal 3226b66a8abaSAnkit Nautiyal buf_ctl |= DDI_PORT_WIDTH(lane_count); 3227b66a8abaSAnkit Nautiyal } else if (IS_ALDERLAKE_P(dev_priv) && intel_phy_is_tc(dev_priv, phy)) { 3228e99ba962SImre Deak drm_WARN_ON(&dev_priv->drm, !intel_tc_port_in_legacy_mode(dig_port)); 3229e99ba962SImre Deak buf_ctl |= DDI_BUF_CTL_TC_PHY_OWNERSHIP; 3230e99ba962SImre Deak } 3231b66a8abaSAnkit Nautiyal 3232e99ba962SImre Deak intel_de_write(dev_priv, DDI_BUF_CTL(port), buf_ctl); 3233379bc100SJani Nikula 323465e75edaSAnkit Nautiyal intel_wait_ddi_buf_active(dev_priv, port); 323565e75edaSAnkit Nautiyal 3236379bc100SJani Nikula intel_audio_codec_enable(encoder, crtc_state, conn_state); 3237379bc100SJani Nikula } 3238379bc100SJani Nikula 3239ede9771dSVille Syrjälä static void intel_enable_ddi(struct intel_atomic_state *state, 3240ede9771dSVille Syrjälä struct intel_encoder *encoder, 3241379bc100SJani Nikula const struct intel_crtc_state *crtc_state, 3242379bc100SJani Nikula const struct drm_connector_state *conn_state) 3243379bc100SJani Nikula { 32448b4f2137SPankaj Bharadiya drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder); 324521fd23acSJani Nikula 3246df529053SVille Syrjälä if (!intel_crtc_is_bigjoiner_slave(crtc_state)) 3247eed22a46SVille Syrjälä intel_ddi_enable_transcoder_func(encoder, crtc_state); 32487c2fedd7SVille Syrjälä 32498853750dSVinod Govindapillai /* Enable/Disable DP2.0 SDP split config before transcoder */ 32508853750dSVinod Govindapillai intel_audio_sdp_split_update(encoder, crtc_state); 32518853750dSVinod Govindapillai 32528c66081bSVille Syrjälä intel_enable_transcoder(crtc_state); 325321fd23acSJani Nikula 325421fd23acSJani Nikula intel_crtc_vblank_on(crtc_state); 325521fd23acSJani Nikula 3256379bc100SJani Nikula if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) 3257ede9771dSVille Syrjälä intel_enable_ddi_hdmi(state, encoder, crtc_state, conn_state); 3258379bc100SJani Nikula else 3259ede9771dSVille Syrjälä intel_enable_ddi_dp(state, encoder, crtc_state, conn_state); 3260379bc100SJani Nikula 3261379bc100SJani Nikula /* Enable hdcp if it's desired */ 3262379bc100SJani Nikula if (conn_state->content_protection == 3263379bc100SJani Nikula DRM_MODE_CONTENT_PROTECTION_DESIRED) 32644c4279a8SSuraj Kandpal intel_hdcp_enable(state, encoder, crtc_state, conn_state); 3265379bc100SJani Nikula } 3266379bc100SJani Nikula 3267ede9771dSVille Syrjälä static void intel_disable_ddi_dp(struct intel_atomic_state *state, 3268ede9771dSVille Syrjälä struct intel_encoder *encoder, 3269379bc100SJani Nikula const struct intel_crtc_state *old_crtc_state, 3270379bc100SJani Nikula const struct drm_connector_state *old_conn_state) 3271379bc100SJani Nikula { 3272b7d02c3aSVille Syrjälä struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 3273379bc100SJani Nikula 3274379bc100SJani Nikula intel_dp->link_trained = false; 3275379bc100SJani Nikula 3276179db7c1SJani Nikula intel_audio_codec_disable(encoder, old_crtc_state, old_conn_state); 3277f28c5950SVille Syrjälä 3278f28c5950SVille Syrjälä intel_psr_disable(intel_dp, old_crtc_state); 3279379bc100SJani Nikula intel_edp_backlight_off(old_conn_state); 3280379bc100SJani Nikula /* Disable the decompression in DP Sink */ 3281379bc100SJani Nikula intel_dp_sink_set_decompression_state(intel_dp, old_crtc_state, 3282379bc100SJani Nikula false); 32831639406aSManasi Navare /* Disable Ignore_MSA bit in DP Sink */ 32841639406aSManasi Navare intel_dp_sink_set_msa_timing_par_ignore_state(intel_dp, old_crtc_state, 32851639406aSManasi Navare false); 3286379bc100SJani Nikula } 3287379bc100SJani Nikula 3288ede9771dSVille Syrjälä static void intel_disable_ddi_hdmi(struct intel_atomic_state *state, 3289ede9771dSVille Syrjälä struct intel_encoder *encoder, 3290379bc100SJani Nikula const struct intel_crtc_state *old_crtc_state, 3291379bc100SJani Nikula const struct drm_connector_state *old_conn_state) 3292379bc100SJani Nikula { 329347bdb1caSJani Nikula struct drm_i915_private *i915 = to_i915(encoder->base.dev); 3294379bc100SJani Nikula struct drm_connector *connector = old_conn_state->connector; 3295379bc100SJani Nikula 3296179db7c1SJani Nikula intel_audio_codec_disable(encoder, old_crtc_state, old_conn_state); 3297f28c5950SVille Syrjälä 3298379bc100SJani Nikula if (!intel_hdmi_handle_sink_scrambling(encoder, connector, 3299379bc100SJani Nikula false, false)) 330047bdb1caSJani Nikula drm_dbg_kms(&i915->drm, 330147bdb1caSJani Nikula "[CONNECTOR:%d:%s] Failed to reset sink scrambling/TMDS bit clock ratio\n", 3302379bc100SJani Nikula connector->base.id, connector->name); 3303379bc100SJani Nikula } 3304379bc100SJani Nikula 3305ede9771dSVille Syrjälä static void intel_disable_ddi(struct intel_atomic_state *state, 3306ede9771dSVille Syrjälä struct intel_encoder *encoder, 3307379bc100SJani Nikula const struct intel_crtc_state *old_crtc_state, 3308379bc100SJani Nikula const struct drm_connector_state *old_conn_state) 3309379bc100SJani Nikula { 3310c598c335SImre Deak intel_tc_port_link_cancel_reset_work(enc_to_dig_port(encoder)); 3311c598c335SImre Deak 3312379bc100SJani Nikula intel_hdcp_disable(to_intel_connector(old_conn_state->connector)); 3313379bc100SJani Nikula 3314379bc100SJani Nikula if (intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_HDMI)) 3315ede9771dSVille Syrjälä intel_disable_ddi_hdmi(state, encoder, old_crtc_state, 3316ede9771dSVille Syrjälä old_conn_state); 3317379bc100SJani Nikula else 3318ede9771dSVille Syrjälä intel_disable_ddi_dp(state, encoder, old_crtc_state, 3319ede9771dSVille Syrjälä old_conn_state); 3320379bc100SJani Nikula } 3321379bc100SJani Nikula 3322ede9771dSVille Syrjälä static void intel_ddi_update_pipe_dp(struct intel_atomic_state *state, 3323ede9771dSVille Syrjälä struct intel_encoder *encoder, 3324379bc100SJani Nikula const struct intel_crtc_state *crtc_state, 3325379bc100SJani Nikula const struct drm_connector_state *conn_state) 3326379bc100SJani Nikula { 33270c06fa15SGwan-gyeong Mun intel_ddi_set_dp_msa(crtc_state, conn_state); 3328379bc100SJani Nikula 332976d45d06SGwan-gyeong Mun intel_dp_set_infoframes(encoder, true, crtc_state, conn_state); 3330379bc100SJani Nikula 3331c0a52f8bSJani Nikula intel_backlight_update(state, encoder, crtc_state, conn_state); 33326306d8dbSHans de Goede drm_connector_update_privacy_screen(conn_state); 3333379bc100SJani Nikula } 3334379bc100SJani Nikula 3335f1c7a36bSSean Paul void intel_ddi_update_pipe(struct intel_atomic_state *state, 3336ede9771dSVille Syrjälä struct intel_encoder *encoder, 3337379bc100SJani Nikula const struct intel_crtc_state *crtc_state, 3338379bc100SJani Nikula const struct drm_connector_state *conn_state) 3339379bc100SJani Nikula { 3340d456512cSRamalingam C 3341f1c7a36bSSean Paul if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) && 3342f1c7a36bSSean Paul !intel_encoder_is_mst(encoder)) 3343ede9771dSVille Syrjälä intel_ddi_update_pipe_dp(state, encoder, crtc_state, 3344ede9771dSVille Syrjälä conn_state); 3345379bc100SJani Nikula 3346ede9771dSVille Syrjälä intel_hdcp_update_pipe(state, encoder, crtc_state, conn_state); 3347379bc100SJani Nikula } 3348379bc100SJani Nikula 334927ac123bSImre Deak void intel_ddi_update_active_dpll(struct intel_atomic_state *state, 335027ac123bSImre Deak struct intel_encoder *encoder, 335127ac123bSImre Deak struct intel_crtc *crtc) 335227ac123bSImre Deak { 335327ac123bSImre Deak struct drm_i915_private *i915 = to_i915(encoder->base.dev); 335427ac123bSImre Deak struct intel_crtc_state *crtc_state = 335527ac123bSImre Deak intel_atomic_get_new_crtc_state(state, crtc); 335627ac123bSImre Deak struct intel_crtc *slave_crtc; 335727ac123bSImre Deak enum phy phy = intel_port_to_phy(i915, encoder->port); 335827ac123bSImre Deak 335962618c7fSMika Kahola /* FIXME: Add MTL pll_mgr */ 336062618c7fSMika Kahola if (DISPLAY_VER(i915) >= 14 || !intel_phy_is_tc(i915, phy)) 336127ac123bSImre Deak return; 336227ac123bSImre Deak 336327ac123bSImre Deak intel_update_active_dpll(state, crtc, encoder); 336427ac123bSImre Deak for_each_intel_crtc_in_pipe_mask(&i915->drm, slave_crtc, 336527ac123bSImre Deak intel_crtc_bigjoiner_slave_pipes(crtc_state)) 336627ac123bSImre Deak intel_update_active_dpll(state, slave_crtc, encoder); 336727ac123bSImre Deak } 336827ac123bSImre Deak 3369379bc100SJani Nikula static void 3370ede9771dSVille Syrjälä intel_ddi_pre_pll_enable(struct intel_atomic_state *state, 3371ede9771dSVille Syrjälä struct intel_encoder *encoder, 3372379bc100SJani Nikula const struct intel_crtc_state *crtc_state, 3373379bc100SJani Nikula const struct drm_connector_state *conn_state) 3374379bc100SJani Nikula { 3375379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 3376b7d02c3aSVille Syrjälä struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 3377d8fe2ab6SMatt Roper enum phy phy = intel_port_to_phy(dev_priv, encoder->port); 3378d8fe2ab6SMatt Roper bool is_tc_port = intel_phy_is_tc(dev_priv, phy); 3379379bc100SJani Nikula 33800f752b21SImre Deak if (is_tc_port) { 33810f752b21SImre Deak struct intel_crtc *master_crtc = 33820f752b21SImre Deak to_intel_crtc(crtc_state->uapi.crtc); 33830f752b21SImre Deak 338424a7bfe0SImre Deak intel_tc_port_get_link(dig_port, crtc_state->lane_count); 338527ac123bSImre Deak intel_ddi_update_active_dpll(state, encoder, master_crtc); 33860f752b21SImre Deak } 33870f752b21SImre Deak 3388637c7aa2SImre Deak main_link_aux_power_domain_get(dig_port, crtc_state); 3389379bc100SJani Nikula 339011a89708SImre Deak if (is_tc_port && !intel_tc_port_in_tbt_alt_mode(dig_port)) 33919d44dcb9SLucas De Marchi /* 33929d44dcb9SLucas De Marchi * Program the lane count for static/dynamic connections on 33939d44dcb9SLucas De Marchi * Type-C ports. Skip this step for TBT. 33949d44dcb9SLucas De Marchi */ 33959d44dcb9SLucas De Marchi intel_tc_port_set_fia_lane_count(dig_port, crtc_state->lane_count); 33962446e1d6SMatt Roper else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) 3397379bc100SJani Nikula bxt_ddi_phy_set_lane_optim_mask(encoder, 3398379bc100SJani Nikula crtc_state->lane_lat_optim_mask); 3399379bc100SJani Nikula } 3400379bc100SJani Nikula 340155223c3bSImre Deak static void adlp_tbt_to_dp_alt_switch_wa(struct intel_encoder *encoder) 340255223c3bSImre Deak { 340355223c3bSImre Deak struct drm_i915_private *i915 = to_i915(encoder->base.dev); 340455223c3bSImre Deak enum tc_port tc_port = intel_port_to_tc(i915, encoder->port); 340555223c3bSImre Deak int ln; 340655223c3bSImre Deak 340789cb0ba4SImre Deak for (ln = 0; ln < 2; ln++) 3408b8ed5533SImre Deak intel_dkl_phy_rmw(i915, DKL_PCS_DW5(tc_port, ln), DKL_PCS_DW5_CORE_SOFTRESET, 0); 340955223c3bSImre Deak } 341055223c3bSImre Deak 341123ef6194SJosé Roberto de Souza static void mtl_ddi_prepare_link_retrain(struct intel_dp *intel_dp, 341223ef6194SJosé Roberto de Souza const struct intel_crtc_state *crtc_state) 341323ef6194SJosé Roberto de Souza { 341423ef6194SJosé Roberto de Souza struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); 341523ef6194SJosé Roberto de Souza struct intel_encoder *encoder = &dig_port->base; 341623ef6194SJosé Roberto de Souza struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 341723ef6194SJosé Roberto de Souza enum port port = encoder->port; 341823ef6194SJosé Roberto de Souza u32 dp_tp_ctl; 341923ef6194SJosé Roberto de Souza 342023ef6194SJosé Roberto de Souza /* 342123ef6194SJosé Roberto de Souza * TODO: To train with only a different voltage swing entry is not 342223ef6194SJosé Roberto de Souza * necessary disable and enable port 342323ef6194SJosé Roberto de Souza */ 342423ef6194SJosé Roberto de Souza dp_tp_ctl = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state)); 342523ef6194SJosé Roberto de Souza if (dp_tp_ctl & DP_TP_CTL_ENABLE) 342623ef6194SJosé Roberto de Souza mtl_disable_ddi_buf(encoder, crtc_state); 342723ef6194SJosé Roberto de Souza 342823ef6194SJosé Roberto de Souza /* 6.d Configure and enable DP_TP_CTL with link training pattern 1 selected */ 342923ef6194SJosé Roberto de Souza dp_tp_ctl = DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_PAT1; 343023ef6194SJosé Roberto de Souza if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) { 343123ef6194SJosé Roberto de Souza dp_tp_ctl |= DP_TP_CTL_MODE_MST; 343223ef6194SJosé Roberto de Souza } else { 343323ef6194SJosé Roberto de Souza dp_tp_ctl |= DP_TP_CTL_MODE_SST; 343423ef6194SJosé Roberto de Souza if (drm_dp_enhanced_frame_cap(intel_dp->dpcd)) 343523ef6194SJosé Roberto de Souza dp_tp_ctl |= DP_TP_CTL_ENHANCED_FRAME_ENABLE; 343623ef6194SJosé Roberto de Souza } 343723ef6194SJosé Roberto de Souza intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), dp_tp_ctl); 343823ef6194SJosé Roberto de Souza intel_de_posting_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state)); 343923ef6194SJosé Roberto de Souza 344023ef6194SJosé Roberto de Souza /* 6.f Enable D2D Link */ 344123ef6194SJosé Roberto de Souza mtl_ddi_enable_d2d(encoder); 344223ef6194SJosé Roberto de Souza 344323ef6194SJosé Roberto de Souza /* 6.g Configure voltage swing and related IO settings */ 344423ef6194SJosé Roberto de Souza encoder->set_signal_levels(encoder, crtc_state); 344523ef6194SJosé Roberto de Souza 344623ef6194SJosé Roberto de Souza /* 6.h Configure PORT_BUF_CTL1 */ 344723ef6194SJosé Roberto de Souza mtl_port_buf_ctl_program(encoder, crtc_state); 344823ef6194SJosé Roberto de Souza 344923ef6194SJosé Roberto de Souza /* 6.i Configure and enable DDI_CTL_DE to start sending valid data to port slice */ 345023ef6194SJosé Roberto de Souza intel_dp->DP |= DDI_BUF_CTL_ENABLE; 345123ef6194SJosé Roberto de Souza intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP); 345223ef6194SJosé Roberto de Souza intel_de_posting_read(dev_priv, DDI_BUF_CTL(port)); 345323ef6194SJosé Roberto de Souza 345423ef6194SJosé Roberto de Souza /* 6.j Poll for PORT_BUF_CTL Idle Status == 0, timeout after 100 us */ 345523ef6194SJosé Roberto de Souza intel_wait_ddi_buf_active(dev_priv, port); 345623ef6194SJosé Roberto de Souza } 345723ef6194SJosé Roberto de Souza 3458a621860aSVille Syrjälä static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp, 3459a621860aSVille Syrjälä const struct intel_crtc_state *crtc_state) 3460379bc100SJani Nikula { 346155223c3bSImre Deak struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); 346255223c3bSImre Deak struct intel_encoder *encoder = &dig_port->base; 3463ef79fafeSVille Syrjälä struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 3464ef79fafeSVille Syrjälä enum port port = encoder->port; 346535ac28a8SLucas De Marchi u32 dp_tp_ctl, ddi_buf_ctl; 3466379bc100SJani Nikula bool wait = false; 3467379bc100SJani Nikula 3468ef79fafeSVille Syrjälä dp_tp_ctl = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state)); 346935ac28a8SLucas De Marchi 347035ac28a8SLucas De Marchi if (dp_tp_ctl & DP_TP_CTL_ENABLE) { 3471f7960e7fSJani Nikula ddi_buf_ctl = intel_de_read(dev_priv, DDI_BUF_CTL(port)); 347235ac28a8SLucas De Marchi if (ddi_buf_ctl & DDI_BUF_CTL_ENABLE) { 3473f7960e7fSJani Nikula intel_de_write(dev_priv, DDI_BUF_CTL(port), 347435ac28a8SLucas De Marchi ddi_buf_ctl & ~DDI_BUF_CTL_ENABLE); 3475379bc100SJani Nikula wait = true; 3476379bc100SJani Nikula } 3477379bc100SJani Nikula 34788c042949SVille Syrjälä dp_tp_ctl &= ~DP_TP_CTL_ENABLE; 3479ef79fafeSVille Syrjälä intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), dp_tp_ctl); 3480ef79fafeSVille Syrjälä intel_de_posting_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state)); 3481379bc100SJani Nikula 3482379bc100SJani Nikula if (wait) 3483379bc100SJani Nikula intel_wait_ddi_buf_idle(dev_priv, port); 3484379bc100SJani Nikula } 3485379bc100SJani Nikula 3486963501bdSImre Deak dp_tp_ctl = DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_PAT1; 3487a621860aSVille Syrjälä if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) { 348835ac28a8SLucas De Marchi dp_tp_ctl |= DP_TP_CTL_MODE_MST; 3489a621860aSVille Syrjälä } else { 349035ac28a8SLucas De Marchi dp_tp_ctl |= DP_TP_CTL_MODE_SST; 3491379bc100SJani Nikula if (drm_dp_enhanced_frame_cap(intel_dp->dpcd)) 349235ac28a8SLucas De Marchi dp_tp_ctl |= DP_TP_CTL_ENHANCED_FRAME_ENABLE; 3493379bc100SJani Nikula } 3494ef79fafeSVille Syrjälä intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), dp_tp_ctl); 3495ef79fafeSVille Syrjälä intel_de_posting_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state)); 3496379bc100SJani Nikula 349755223c3bSImre Deak if (IS_ALDERLAKE_P(dev_priv) && 349855223c3bSImre Deak (intel_tc_port_in_dp_alt_mode(dig_port) || intel_tc_port_in_legacy_mode(dig_port))) 349955223c3bSImre Deak adlp_tbt_to_dp_alt_switch_wa(encoder); 350055223c3bSImre Deak 3501379bc100SJani Nikula intel_dp->DP |= DDI_BUF_CTL_ENABLE; 3502f7960e7fSJani Nikula intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP); 3503f7960e7fSJani Nikula intel_de_posting_read(dev_priv, DDI_BUF_CTL(port)); 3504379bc100SJani Nikula 3505e828da30SManasi Navare intel_wait_ddi_buf_active(dev_priv, port); 3506379bc100SJani Nikula } 3507379bc100SJani Nikula 3508eee3f911SVille Syrjälä static void intel_ddi_set_link_train(struct intel_dp *intel_dp, 3509a621860aSVille Syrjälä const struct intel_crtc_state *crtc_state, 3510eee3f911SVille Syrjälä u8 dp_train_pat) 3511eee3f911SVille Syrjälä { 3512ef79fafeSVille Syrjälä struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; 3513ef79fafeSVille Syrjälä struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 3514eee3f911SVille Syrjälä u32 temp; 3515eee3f911SVille Syrjälä 3516ef79fafeSVille Syrjälä temp = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state)); 3517eee3f911SVille Syrjälä 3518eee3f911SVille Syrjälä temp &= ~DP_TP_CTL_LINK_TRAIN_MASK; 35196777a855SImre Deak switch (intel_dp_training_pattern_symbol(dp_train_pat)) { 3520eee3f911SVille Syrjälä case DP_TRAINING_PATTERN_DISABLE: 3521eee3f911SVille Syrjälä temp |= DP_TP_CTL_LINK_TRAIN_NORMAL; 3522eee3f911SVille Syrjälä break; 3523eee3f911SVille Syrjälä case DP_TRAINING_PATTERN_1: 3524eee3f911SVille Syrjälä temp |= DP_TP_CTL_LINK_TRAIN_PAT1; 3525eee3f911SVille Syrjälä break; 3526eee3f911SVille Syrjälä case DP_TRAINING_PATTERN_2: 3527eee3f911SVille Syrjälä temp |= DP_TP_CTL_LINK_TRAIN_PAT2; 3528eee3f911SVille Syrjälä break; 3529eee3f911SVille Syrjälä case DP_TRAINING_PATTERN_3: 3530eee3f911SVille Syrjälä temp |= DP_TP_CTL_LINK_TRAIN_PAT3; 3531eee3f911SVille Syrjälä break; 3532eee3f911SVille Syrjälä case DP_TRAINING_PATTERN_4: 3533eee3f911SVille Syrjälä temp |= DP_TP_CTL_LINK_TRAIN_PAT4; 3534eee3f911SVille Syrjälä break; 3535eee3f911SVille Syrjälä } 3536eee3f911SVille Syrjälä 3537ef79fafeSVille Syrjälä intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), temp); 3538eee3f911SVille Syrjälä } 3539eee3f911SVille Syrjälä 3540a621860aSVille Syrjälä static void intel_ddi_set_idle_link_train(struct intel_dp *intel_dp, 3541a621860aSVille Syrjälä const struct intel_crtc_state *crtc_state) 35428fdda385SVille Syrjälä { 35438fdda385SVille Syrjälä struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; 35448fdda385SVille Syrjälä struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 35458fdda385SVille Syrjälä enum port port = encoder->port; 35468fdda385SVille Syrjälä 35478910d8b7SAndrzej Hajda intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), 35488910d8b7SAndrzej Hajda DP_TP_CTL_LINK_TRAIN_MASK, DP_TP_CTL_LINK_TRAIN_IDLE); 35498fdda385SVille Syrjälä 35508fdda385SVille Syrjälä /* 35518fdda385SVille Syrjälä * Until TGL on PORT_A we can have only eDP in SST mode. There the only 35528fdda385SVille Syrjälä * reason we need to set idle transmission mode is to work around a HW 35538fdda385SVille Syrjälä * issue where we enable the pipe while not in idle link-training mode. 35548fdda385SVille Syrjälä * In this case there is requirement to wait for a minimum number of 35558fdda385SVille Syrjälä * idle patterns to be sent. 35568fdda385SVille Syrjälä */ 3557005e9537SMatt Roper if (port == PORT_A && DISPLAY_VER(dev_priv) < 12) 35588fdda385SVille Syrjälä return; 35598fdda385SVille Syrjälä 3560ef79fafeSVille Syrjälä if (intel_de_wait_for_set(dev_priv, 3561ef79fafeSVille Syrjälä dp_tp_status_reg(encoder, crtc_state), 35628fdda385SVille Syrjälä DP_TP_STATUS_IDLE_DONE, 1)) 35638fdda385SVille Syrjälä drm_err(&dev_priv->drm, 35648fdda385SVille Syrjälä "Timed out waiting for DP idle patterns\n"); 35658fdda385SVille Syrjälä } 35668fdda385SVille Syrjälä 3567379bc100SJani Nikula static bool intel_ddi_is_audio_enabled(struct drm_i915_private *dev_priv, 3568379bc100SJani Nikula enum transcoder cpu_transcoder) 3569379bc100SJani Nikula { 3570379bc100SJani Nikula if (cpu_transcoder == TRANSCODER_EDP) 3571379bc100SJani Nikula return false; 3572379bc100SJani Nikula 3573615a7724SAnshuman Gupta if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO_MMIO)) 3574379bc100SJani Nikula return false; 3575379bc100SJani Nikula 3576f7960e7fSJani Nikula return intel_de_read(dev_priv, HSW_AUD_PIN_ELD_CP_VLD) & 3577379bc100SJani Nikula AUDIO_OUTPUT_ENABLE(cpu_transcoder); 3578379bc100SJani Nikula } 3579379bc100SJani Nikula 3580379bc100SJani Nikula void intel_ddi_compute_min_voltage_level(struct drm_i915_private *dev_priv, 3581379bc100SJani Nikula struct intel_crtc_state *crtc_state) 3582379bc100SJani Nikula { 3583005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 12 && crtc_state->port_clock > 594000) 35840fde0b1dSMatt Roper crtc_state->min_voltage_level = 2; 358524ea098bSTejas Upadhyay else if (IS_JSL_EHL(dev_priv) && crtc_state->port_clock > 594000) 35869d5fd37eSMatt Roper crtc_state->min_voltage_level = 3; 3587005e9537SMatt Roper else if (DISPLAY_VER(dev_priv) >= 11 && crtc_state->port_clock > 594000) 3588379bc100SJani Nikula crtc_state->min_voltage_level = 1; 3589379bc100SJani Nikula } 3590379bc100SJani Nikula 3591dc5b8ed5SVille Syrjälä static enum transcoder bdw_transcoder_master_readout(struct drm_i915_private *dev_priv, 359202d8ea47SVille Syrjälä enum transcoder cpu_transcoder) 359302d8ea47SVille Syrjälä { 3594dc5b8ed5SVille Syrjälä u32 master_select; 359502d8ea47SVille Syrjälä 3596005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 11) { 3597dc5b8ed5SVille Syrjälä u32 ctl2 = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL2(cpu_transcoder)); 359802d8ea47SVille Syrjälä 359902d8ea47SVille Syrjälä if ((ctl2 & PORT_SYNC_MODE_ENABLE) == 0) 360002d8ea47SVille Syrjälä return INVALID_TRANSCODER; 360102d8ea47SVille Syrjälä 3602d4d7d9caSVille Syrjälä master_select = REG_FIELD_GET(PORT_SYNC_MODE_MASTER_SELECT_MASK, ctl2); 3603dc5b8ed5SVille Syrjälä } else { 3604dc5b8ed5SVille Syrjälä u32 ctl = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder)); 3605dc5b8ed5SVille Syrjälä 3606dc5b8ed5SVille Syrjälä if ((ctl & TRANS_DDI_PORT_SYNC_ENABLE) == 0) 3607dc5b8ed5SVille Syrjälä return INVALID_TRANSCODER; 3608dc5b8ed5SVille Syrjälä 3609dc5b8ed5SVille Syrjälä master_select = REG_FIELD_GET(TRANS_DDI_PORT_SYNC_MASTER_SELECT_MASK, ctl); 3610dc5b8ed5SVille Syrjälä } 361102d8ea47SVille Syrjälä 361202d8ea47SVille Syrjälä if (master_select == 0) 361302d8ea47SVille Syrjälä return TRANSCODER_EDP; 361402d8ea47SVille Syrjälä else 361502d8ea47SVille Syrjälä return master_select - 1; 361602d8ea47SVille Syrjälä } 361702d8ea47SVille Syrjälä 3618dc5b8ed5SVille Syrjälä static void bdw_get_trans_port_sync_config(struct intel_crtc_state *crtc_state) 361902d8ea47SVille Syrjälä { 362002d8ea47SVille Syrjälä struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); 362102d8ea47SVille Syrjälä u32 transcoders = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | 362202d8ea47SVille Syrjälä BIT(TRANSCODER_C) | BIT(TRANSCODER_D); 362302d8ea47SVille Syrjälä enum transcoder cpu_transcoder; 362402d8ea47SVille Syrjälä 362502d8ea47SVille Syrjälä crtc_state->master_transcoder = 3626dc5b8ed5SVille Syrjälä bdw_transcoder_master_readout(dev_priv, crtc_state->cpu_transcoder); 362702d8ea47SVille Syrjälä 362802d8ea47SVille Syrjälä for_each_cpu_transcoder_masked(dev_priv, cpu_transcoder, transcoders) { 362902d8ea47SVille Syrjälä enum intel_display_power_domain power_domain; 363002d8ea47SVille Syrjälä intel_wakeref_t trans_wakeref; 363102d8ea47SVille Syrjälä 363202d8ea47SVille Syrjälä power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder); 363302d8ea47SVille Syrjälä trans_wakeref = intel_display_power_get_if_enabled(dev_priv, 363402d8ea47SVille Syrjälä power_domain); 363502d8ea47SVille Syrjälä 363602d8ea47SVille Syrjälä if (!trans_wakeref) 363702d8ea47SVille Syrjälä continue; 363802d8ea47SVille Syrjälä 3639dc5b8ed5SVille Syrjälä if (bdw_transcoder_master_readout(dev_priv, cpu_transcoder) == 364002d8ea47SVille Syrjälä crtc_state->cpu_transcoder) 364102d8ea47SVille Syrjälä crtc_state->sync_mode_slaves_mask |= BIT(cpu_transcoder); 364202d8ea47SVille Syrjälä 364302d8ea47SVille Syrjälä intel_display_power_put(dev_priv, power_domain, trans_wakeref); 364402d8ea47SVille Syrjälä } 364502d8ea47SVille Syrjälä 364602d8ea47SVille Syrjälä drm_WARN_ON(&dev_priv->drm, 364702d8ea47SVille Syrjälä crtc_state->master_transcoder != INVALID_TRANSCODER && 364802d8ea47SVille Syrjälä crtc_state->sync_mode_slaves_mask); 364902d8ea47SVille Syrjälä } 365002d8ea47SVille Syrjälä 36510385eceaSManasi Navare static void intel_ddi_read_func_ctl(struct intel_encoder *encoder, 3652379bc100SJani Nikula struct intel_crtc_state *pipe_config) 3653379bc100SJani Nikula { 3654379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 3655f15f01a7SVille Syrjälä struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); 3656379bc100SJani Nikula enum transcoder cpu_transcoder = pipe_config->cpu_transcoder; 3657a44289b9SUma Shankar struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 3658379bc100SJani Nikula u32 temp, flags = 0; 3659379bc100SJani Nikula 3660f7960e7fSJani Nikula temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder)); 3661379bc100SJani Nikula if (temp & TRANS_DDI_PHSYNC) 3662379bc100SJani Nikula flags |= DRM_MODE_FLAG_PHSYNC; 3663379bc100SJani Nikula else 3664379bc100SJani Nikula flags |= DRM_MODE_FLAG_NHSYNC; 3665379bc100SJani Nikula if (temp & TRANS_DDI_PVSYNC) 3666379bc100SJani Nikula flags |= DRM_MODE_FLAG_PVSYNC; 3667379bc100SJani Nikula else 3668379bc100SJani Nikula flags |= DRM_MODE_FLAG_NVSYNC; 3669379bc100SJani Nikula 36701326a92cSMaarten Lankhorst pipe_config->hw.adjusted_mode.flags |= flags; 3671379bc100SJani Nikula 3672379bc100SJani Nikula switch (temp & TRANS_DDI_BPC_MASK) { 3673379bc100SJani Nikula case TRANS_DDI_BPC_6: 3674379bc100SJani Nikula pipe_config->pipe_bpp = 18; 3675379bc100SJani Nikula break; 3676379bc100SJani Nikula case TRANS_DDI_BPC_8: 3677379bc100SJani Nikula pipe_config->pipe_bpp = 24; 3678379bc100SJani Nikula break; 3679379bc100SJani Nikula case TRANS_DDI_BPC_10: 3680379bc100SJani Nikula pipe_config->pipe_bpp = 30; 3681379bc100SJani Nikula break; 3682379bc100SJani Nikula case TRANS_DDI_BPC_12: 3683379bc100SJani Nikula pipe_config->pipe_bpp = 36; 3684379bc100SJani Nikula break; 3685379bc100SJani Nikula default: 3686379bc100SJani Nikula break; 3687379bc100SJani Nikula } 3688379bc100SJani Nikula 3689379bc100SJani Nikula switch (temp & TRANS_DDI_MODE_SELECT_MASK) { 3690379bc100SJani Nikula case TRANS_DDI_MODE_SELECT_HDMI: 3691379bc100SJani Nikula pipe_config->has_hdmi_sink = true; 3692379bc100SJani Nikula 3693379bc100SJani Nikula pipe_config->infoframes.enable |= 3694379bc100SJani Nikula intel_hdmi_infoframes_enabled(encoder, pipe_config); 3695379bc100SJani Nikula 3696379bc100SJani Nikula if (pipe_config->infoframes.enable) 3697379bc100SJani Nikula pipe_config->has_infoframe = true; 3698379bc100SJani Nikula 3699379bc100SJani Nikula if (temp & TRANS_DDI_HDMI_SCRAMBLING) 3700379bc100SJani Nikula pipe_config->hdmi_scrambling = true; 3701379bc100SJani Nikula if (temp & TRANS_DDI_HIGH_TMDS_CHAR_RATE) 3702379bc100SJani Nikula pipe_config->hdmi_high_tmds_clock_ratio = true; 3703df561f66SGustavo A. R. Silva fallthrough; 3704379bc100SJani Nikula case TRANS_DDI_MODE_SELECT_DVI: 3705379bc100SJani Nikula pipe_config->output_types |= BIT(INTEL_OUTPUT_HDMI); 3706b66a8abaSAnkit Nautiyal if (DISPLAY_VER(dev_priv) >= 14) 3707b66a8abaSAnkit Nautiyal pipe_config->lane_count = 3708b66a8abaSAnkit Nautiyal ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1; 3709b66a8abaSAnkit Nautiyal else 3710379bc100SJani Nikula pipe_config->lane_count = 4; 3711379bc100SJani Nikula break; 3712379bc100SJani Nikula case TRANS_DDI_MODE_SELECT_DP_SST: 3713379bc100SJani Nikula if (encoder->type == INTEL_OUTPUT_EDP) 3714379bc100SJani Nikula pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP); 3715379bc100SJani Nikula else 3716379bc100SJani Nikula pipe_config->output_types |= BIT(INTEL_OUTPUT_DP); 3717379bc100SJani Nikula pipe_config->lane_count = 3718379bc100SJani Nikula ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1; 37196149cb68SVille Syrjälä 37205cd06644SVille Syrjälä intel_cpu_transcoder_get_m1_n1(crtc, cpu_transcoder, 37215cd06644SVille Syrjälä &pipe_config->dp_m_n); 37225cd06644SVille Syrjälä intel_cpu_transcoder_get_m2_n2(crtc, cpu_transcoder, 37236149cb68SVille Syrjälä &pipe_config->dp_m2_n2); 37248aa940c8SMaarten Lankhorst 3725005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 11) { 3726ef79fafeSVille Syrjälä i915_reg_t dp_tp_ctl = dp_tp_ctl_reg(encoder, pipe_config); 37278aa940c8SMaarten Lankhorst 37288aa940c8SMaarten Lankhorst pipe_config->fec_enable = 3729f7960e7fSJani Nikula intel_de_read(dev_priv, dp_tp_ctl) & DP_TP_CTL_FEC_ENABLE; 37308aa940c8SMaarten Lankhorst 373147bdb1caSJani Nikula drm_dbg_kms(&dev_priv->drm, 373247bdb1caSJani Nikula "[ENCODER:%d:%s] Fec status: %u\n", 37338aa940c8SMaarten Lankhorst encoder->base.base.id, encoder->base.name, 37348aa940c8SMaarten Lankhorst pipe_config->fec_enable); 37358aa940c8SMaarten Lankhorst } 37368aa940c8SMaarten Lankhorst 37377ffa2f27SJani Nikula if (dig_port->lspcon.active && intel_dp_has_hdmi_sink(&dig_port->dp)) 3738a44289b9SUma Shankar pipe_config->infoframes.enable |= 3739a44289b9SUma Shankar intel_lspcon_infoframes_enabled(encoder, pipe_config); 3740a44289b9SUma Shankar else 3741dee66f3eSGwan-gyeong Mun pipe_config->infoframes.enable |= 3742dee66f3eSGwan-gyeong Mun intel_hdmi_infoframes_enabled(encoder, pipe_config); 3743379bc100SJani Nikula break; 374465213594SJani Nikula case TRANS_DDI_MODE_SELECT_FDI_OR_128B132B: 374565213594SJani Nikula if (!HAS_DP20(dev_priv)) { 374665213594SJani Nikula /* FDI */ 374765213594SJani Nikula pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG); 374865213594SJani Nikula break; 374965213594SJani Nikula } 375065213594SJani Nikula fallthrough; /* 128b/132b */ 3751379bc100SJani Nikula case TRANS_DDI_MODE_SELECT_DP_MST: 3752379bc100SJani Nikula pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST); 3753379bc100SJani Nikula pipe_config->lane_count = 3754379bc100SJani Nikula ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1; 37556671c367SJosé Roberto de Souza 3756005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 12) 37576671c367SJosé Roberto de Souza pipe_config->mst_master_transcoder = 37586671c367SJosé Roberto de Souza REG_FIELD_GET(TRANS_DDI_MST_TRANSPORT_SELECT_MASK, temp); 37596671c367SJosé Roberto de Souza 37605cd06644SVille Syrjälä intel_cpu_transcoder_get_m1_n1(crtc, cpu_transcoder, 37615cd06644SVille Syrjälä &pipe_config->dp_m_n); 3762dee66f3eSGwan-gyeong Mun 3763dee66f3eSGwan-gyeong Mun pipe_config->infoframes.enable |= 3764dee66f3eSGwan-gyeong Mun intel_hdmi_infoframes_enabled(encoder, pipe_config); 3765379bc100SJani Nikula break; 3766379bc100SJani Nikula default: 3767379bc100SJani Nikula break; 3768379bc100SJani Nikula } 37690385eceaSManasi Navare } 37700385eceaSManasi Navare 3771351221ffSVille Syrjälä static void intel_ddi_get_config(struct intel_encoder *encoder, 37720385eceaSManasi Navare struct intel_crtc_state *pipe_config) 37730385eceaSManasi Navare { 37740385eceaSManasi Navare struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 37750385eceaSManasi Navare enum transcoder cpu_transcoder = pipe_config->cpu_transcoder; 37760385eceaSManasi Navare 37770385eceaSManasi Navare /* XXX: DSI transcoder paranoia */ 37780385eceaSManasi Navare if (drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder))) 37790385eceaSManasi Navare return; 37800385eceaSManasi Navare 37810385eceaSManasi Navare intel_ddi_read_func_ctl(encoder, pipe_config); 3782379bc100SJani Nikula 37835b616a29SJani Nikula intel_ddi_mso_get_config(encoder, pipe_config); 37845b616a29SJani Nikula 3785379bc100SJani Nikula pipe_config->has_audio = 3786379bc100SJani Nikula intel_ddi_is_audio_enabled(dev_priv, cpu_transcoder); 3787379bc100SJani Nikula 3788822e5ae7SVille Syrjälä if (encoder->type == INTEL_OUTPUT_EDP) 3789822e5ae7SVille Syrjälä intel_edp_fixup_vbt_bpp(encoder, pipe_config->pipe_bpp); 3790379bc100SJani Nikula 3791351221ffSVille Syrjälä ddi_dotclock_get(pipe_config); 3792379bc100SJani Nikula 37932446e1d6SMatt Roper if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) 3794379bc100SJani Nikula pipe_config->lane_lat_optim_mask = 3795379bc100SJani Nikula bxt_ddi_phy_get_lane_lat_optim_mask(encoder); 3796379bc100SJani Nikula 3797379bc100SJani Nikula intel_ddi_compute_min_voltage_level(dev_priv, pipe_config); 3798379bc100SJani Nikula 3799379bc100SJani Nikula intel_hdmi_read_gcp_infoframe(encoder, pipe_config); 3800379bc100SJani Nikula 3801379bc100SJani Nikula intel_read_infoframe(encoder, pipe_config, 3802379bc100SJani Nikula HDMI_INFOFRAME_TYPE_AVI, 3803379bc100SJani Nikula &pipe_config->infoframes.avi); 3804379bc100SJani Nikula intel_read_infoframe(encoder, pipe_config, 3805379bc100SJani Nikula HDMI_INFOFRAME_TYPE_SPD, 3806379bc100SJani Nikula &pipe_config->infoframes.spd); 3807379bc100SJani Nikula intel_read_infoframe(encoder, pipe_config, 3808379bc100SJani Nikula HDMI_INFOFRAME_TYPE_VENDOR, 3809379bc100SJani Nikula &pipe_config->infoframes.hdmi); 3810379bc100SJani Nikula intel_read_infoframe(encoder, pipe_config, 3811379bc100SJani Nikula HDMI_INFOFRAME_TYPE_DRM, 3812379bc100SJani Nikula &pipe_config->infoframes.drm); 381302d8ea47SVille Syrjälä 3814005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 8) 3815dc5b8ed5SVille Syrjälä bdw_get_trans_port_sync_config(pipe_config); 3816dee66f3eSGwan-gyeong Mun 3817dee66f3eSGwan-gyeong Mun intel_read_dp_sdp(encoder, pipe_config, HDMI_PACKET_TYPE_GAMUT_METADATA); 38182c3928e4SGwan-gyeong Mun intel_read_dp_sdp(encoder, pipe_config, DP_SDP_VSC); 381978b772e1SJosé Roberto de Souza 382078b772e1SJosé Roberto de Souza intel_psr_get_config(encoder, pipe_config); 382161a60df6SVille Syrjälä 382261a60df6SVille Syrjälä intel_audio_codec_get_config(encoder, pipe_config); 3823379bc100SJani Nikula } 3824379bc100SJani Nikula 3825351221ffSVille Syrjälä void intel_ddi_get_clock(struct intel_encoder *encoder, 3826351221ffSVille Syrjälä struct intel_crtc_state *crtc_state, 3827351221ffSVille Syrjälä struct intel_shared_dpll *pll) 3828351221ffSVille Syrjälä { 3829351221ffSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 3830351221ffSVille Syrjälä enum icl_port_dpll_id port_dpll_id = ICL_PORT_DPLL_DEFAULT; 3831351221ffSVille Syrjälä struct icl_port_dpll *port_dpll = &crtc_state->icl_port_dplls[port_dpll_id]; 3832351221ffSVille Syrjälä bool pll_active; 3833351221ffSVille Syrjälä 3834086877a1SVille Syrjälä if (drm_WARN_ON(&i915->drm, !pll)) 3835086877a1SVille Syrjälä return; 3836086877a1SVille Syrjälä 3837351221ffSVille Syrjälä port_dpll->pll = pll; 3838351221ffSVille Syrjälä pll_active = intel_dpll_get_hw_state(i915, pll, &port_dpll->hw_state); 3839351221ffSVille Syrjälä drm_WARN_ON(&i915->drm, !pll_active); 3840351221ffSVille Syrjälä 3841351221ffSVille Syrjälä icl_set_active_port_dpll(crtc_state, port_dpll_id); 3842351221ffSVille Syrjälä 3843351221ffSVille Syrjälä crtc_state->port_clock = intel_dpll_get_freq(i915, crtc_state->shared_dpll, 3844351221ffSVille Syrjälä &crtc_state->dpll_hw_state); 3845351221ffSVille Syrjälä } 3846351221ffSVille Syrjälä 384751390cc0SRadhakrishna Sripada static void mtl_ddi_get_config(struct intel_encoder *encoder, 384851390cc0SRadhakrishna Sripada struct intel_crtc_state *crtc_state) 384951390cc0SRadhakrishna Sripada { 385051390cc0SRadhakrishna Sripada struct drm_i915_private *i915 = to_i915(encoder->base.dev); 385151390cc0SRadhakrishna Sripada enum phy phy = intel_port_to_phy(i915, encoder->port); 38527dee06bcSMika Kahola struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 385351390cc0SRadhakrishna Sripada 38547dee06bcSMika Kahola if (intel_tc_port_in_tbt_alt_mode(dig_port)) { 38557dee06bcSMika Kahola crtc_state->port_clock = intel_mtl_tbt_calc_port_clock(encoder); 38567dee06bcSMika Kahola } else if (intel_is_c10phy(i915, phy)) { 385751390cc0SRadhakrishna Sripada intel_c10pll_readout_hw_state(encoder, &crtc_state->cx0pll_state.c10); 385851390cc0SRadhakrishna Sripada intel_c10pll_dump_hw_state(i915, &crtc_state->cx0pll_state.c10); 3859f1f9e627SMika Kahola crtc_state->port_clock = intel_c10pll_calc_port_clock(encoder, &crtc_state->cx0pll_state.c10); 3860929f527aSMika Kahola } else { 3861929f527aSMika Kahola intel_c20pll_readout_hw_state(encoder, &crtc_state->cx0pll_state.c20); 3862f968a253SMika Kahola intel_c20pll_dump_hw_state(i915, &crtc_state->cx0pll_state.c20); 3863f1f9e627SMika Kahola crtc_state->port_clock = intel_c20pll_calc_port_clock(encoder, &crtc_state->cx0pll_state.c20); 3864929f527aSMika Kahola } 3865929f527aSMika Kahola 386651390cc0SRadhakrishna Sripada intel_ddi_get_config(encoder, crtc_state); 386751390cc0SRadhakrishna Sripada } 386851390cc0SRadhakrishna Sripada 3869865b73eaSMatt Roper static void dg2_ddi_get_config(struct intel_encoder *encoder, 3870865b73eaSMatt Roper struct intel_crtc_state *crtc_state) 3871865b73eaSMatt Roper { 3872865b73eaSMatt Roper intel_mpllb_readout_hw_state(encoder, &crtc_state->mpllb_state); 3873865b73eaSMatt Roper crtc_state->port_clock = intel_mpllb_calc_port_clock(encoder, &crtc_state->mpllb_state); 3874865b73eaSMatt Roper 3875865b73eaSMatt Roper intel_ddi_get_config(encoder, crtc_state); 3876865b73eaSMatt Roper } 3877865b73eaSMatt Roper 3878351221ffSVille Syrjälä static void adls_ddi_get_config(struct intel_encoder *encoder, 3879351221ffSVille Syrjälä struct intel_crtc_state *crtc_state) 3880351221ffSVille Syrjälä { 3881351221ffSVille Syrjälä intel_ddi_get_clock(encoder, crtc_state, adls_ddi_get_pll(encoder)); 3882351221ffSVille Syrjälä intel_ddi_get_config(encoder, crtc_state); 3883351221ffSVille Syrjälä } 3884351221ffSVille Syrjälä 3885351221ffSVille Syrjälä static void rkl_ddi_get_config(struct intel_encoder *encoder, 3886351221ffSVille Syrjälä struct intel_crtc_state *crtc_state) 3887351221ffSVille Syrjälä { 3888351221ffSVille Syrjälä intel_ddi_get_clock(encoder, crtc_state, rkl_ddi_get_pll(encoder)); 3889351221ffSVille Syrjälä intel_ddi_get_config(encoder, crtc_state); 3890351221ffSVille Syrjälä } 3891351221ffSVille Syrjälä 3892351221ffSVille Syrjälä static void dg1_ddi_get_config(struct intel_encoder *encoder, 3893351221ffSVille Syrjälä struct intel_crtc_state *crtc_state) 3894351221ffSVille Syrjälä { 3895351221ffSVille Syrjälä intel_ddi_get_clock(encoder, crtc_state, dg1_ddi_get_pll(encoder)); 3896351221ffSVille Syrjälä intel_ddi_get_config(encoder, crtc_state); 3897351221ffSVille Syrjälä } 3898351221ffSVille Syrjälä 3899351221ffSVille Syrjälä static void icl_ddi_combo_get_config(struct intel_encoder *encoder, 3900351221ffSVille Syrjälä struct intel_crtc_state *crtc_state) 3901351221ffSVille Syrjälä { 3902351221ffSVille Syrjälä intel_ddi_get_clock(encoder, crtc_state, icl_ddi_combo_get_pll(encoder)); 3903351221ffSVille Syrjälä intel_ddi_get_config(encoder, crtc_state); 3904351221ffSVille Syrjälä } 3905351221ffSVille Syrjälä 39067c1da068SImre Deak static bool icl_ddi_tc_pll_is_tbt(const struct intel_shared_dpll *pll) 39077c1da068SImre Deak { 39087c1da068SImre Deak return pll->info->id == DPLL_ID_ICL_TBTPLL; 39097c1da068SImre Deak } 39107c1da068SImre Deak 39117c1da068SImre Deak static enum icl_port_dpll_id 39127c1da068SImre Deak icl_ddi_tc_port_pll_type(struct intel_encoder *encoder, 39137c1da068SImre Deak const struct intel_crtc_state *crtc_state) 39147c1da068SImre Deak { 39157c1da068SImre Deak struct drm_i915_private *i915 = to_i915(encoder->base.dev); 39167c1da068SImre Deak const struct intel_shared_dpll *pll = crtc_state->shared_dpll; 39177c1da068SImre Deak 39187c1da068SImre Deak if (drm_WARN_ON(&i915->drm, !pll)) 39197c1da068SImre Deak return ICL_PORT_DPLL_DEFAULT; 39207c1da068SImre Deak 39217c1da068SImre Deak if (icl_ddi_tc_pll_is_tbt(pll)) 39227c1da068SImre Deak return ICL_PORT_DPLL_DEFAULT; 39237c1da068SImre Deak else 39247c1da068SImre Deak return ICL_PORT_DPLL_MG_PHY; 39257c1da068SImre Deak } 39267c1da068SImre Deak 39277c1da068SImre Deak enum icl_port_dpll_id 39287c1da068SImre Deak intel_ddi_port_pll_type(struct intel_encoder *encoder, 39297c1da068SImre Deak const struct intel_crtc_state *crtc_state) 39307c1da068SImre Deak { 39317c1da068SImre Deak if (!encoder->port_pll_type) 39327c1da068SImre Deak return ICL_PORT_DPLL_DEFAULT; 39337c1da068SImre Deak 39347c1da068SImre Deak return encoder->port_pll_type(encoder, crtc_state); 39357c1da068SImre Deak } 39367c1da068SImre Deak 3937086877a1SVille Syrjälä static void icl_ddi_tc_get_clock(struct intel_encoder *encoder, 3938086877a1SVille Syrjälä struct intel_crtc_state *crtc_state, 3939086877a1SVille Syrjälä struct intel_shared_dpll *pll) 3940351221ffSVille Syrjälä { 3941351221ffSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 3942351221ffSVille Syrjälä enum icl_port_dpll_id port_dpll_id; 3943351221ffSVille Syrjälä struct icl_port_dpll *port_dpll; 3944351221ffSVille Syrjälä bool pll_active; 3945351221ffSVille Syrjälä 3946086877a1SVille Syrjälä if (drm_WARN_ON(&i915->drm, !pll)) 3947086877a1SVille Syrjälä return; 3948351221ffSVille Syrjälä 39497c1da068SImre Deak if (icl_ddi_tc_pll_is_tbt(pll)) 3950351221ffSVille Syrjälä port_dpll_id = ICL_PORT_DPLL_DEFAULT; 3951351221ffSVille Syrjälä else 3952351221ffSVille Syrjälä port_dpll_id = ICL_PORT_DPLL_MG_PHY; 3953351221ffSVille Syrjälä 3954351221ffSVille Syrjälä port_dpll = &crtc_state->icl_port_dplls[port_dpll_id]; 3955351221ffSVille Syrjälä 3956351221ffSVille Syrjälä port_dpll->pll = pll; 3957351221ffSVille Syrjälä pll_active = intel_dpll_get_hw_state(i915, pll, &port_dpll->hw_state); 3958351221ffSVille Syrjälä drm_WARN_ON(&i915->drm, !pll_active); 3959351221ffSVille Syrjälä 3960351221ffSVille Syrjälä icl_set_active_port_dpll(crtc_state, port_dpll_id); 3961351221ffSVille Syrjälä 39627c1da068SImre Deak if (icl_ddi_tc_pll_is_tbt(crtc_state->shared_dpll)) 3963351221ffSVille Syrjälä crtc_state->port_clock = icl_calc_tbt_pll_link(i915, encoder->port); 3964351221ffSVille Syrjälä else 3965351221ffSVille Syrjälä crtc_state->port_clock = intel_dpll_get_freq(i915, crtc_state->shared_dpll, 3966351221ffSVille Syrjälä &crtc_state->dpll_hw_state); 3967086877a1SVille Syrjälä } 3968351221ffSVille Syrjälä 3969086877a1SVille Syrjälä static void icl_ddi_tc_get_config(struct intel_encoder *encoder, 3970086877a1SVille Syrjälä struct intel_crtc_state *crtc_state) 3971086877a1SVille Syrjälä { 3972086877a1SVille Syrjälä icl_ddi_tc_get_clock(encoder, crtc_state, icl_ddi_tc_get_pll(encoder)); 3973351221ffSVille Syrjälä intel_ddi_get_config(encoder, crtc_state); 3974351221ffSVille Syrjälä } 3975351221ffSVille Syrjälä 3976351221ffSVille Syrjälä static void bxt_ddi_get_config(struct intel_encoder *encoder, 3977351221ffSVille Syrjälä struct intel_crtc_state *crtc_state) 3978351221ffSVille Syrjälä { 3979351221ffSVille Syrjälä intel_ddi_get_clock(encoder, crtc_state, bxt_ddi_get_pll(encoder)); 3980351221ffSVille Syrjälä intel_ddi_get_config(encoder, crtc_state); 3981351221ffSVille Syrjälä } 3982351221ffSVille Syrjälä 3983351221ffSVille Syrjälä static void skl_ddi_get_config(struct intel_encoder *encoder, 3984351221ffSVille Syrjälä struct intel_crtc_state *crtc_state) 3985351221ffSVille Syrjälä { 3986351221ffSVille Syrjälä intel_ddi_get_clock(encoder, crtc_state, skl_ddi_get_pll(encoder)); 3987351221ffSVille Syrjälä intel_ddi_get_config(encoder, crtc_state); 3988351221ffSVille Syrjälä } 3989351221ffSVille Syrjälä 3990351221ffSVille Syrjälä void hsw_ddi_get_config(struct intel_encoder *encoder, 3991351221ffSVille Syrjälä struct intel_crtc_state *crtc_state) 3992351221ffSVille Syrjälä { 3993351221ffSVille Syrjälä intel_ddi_get_clock(encoder, crtc_state, hsw_ddi_get_pll(encoder)); 3994351221ffSVille Syrjälä intel_ddi_get_config(encoder, crtc_state); 3995351221ffSVille Syrjälä } 3996351221ffSVille Syrjälä 3997f9e76a6eSImre Deak static void intel_ddi_sync_state(struct intel_encoder *encoder, 3998f9e76a6eSImre Deak const struct intel_crtc_state *crtc_state) 3999f9e76a6eSImre Deak { 40007194dc99SImre Deak struct drm_i915_private *i915 = to_i915(encoder->base.dev); 40017194dc99SImre Deak enum phy phy = intel_port_to_phy(i915, encoder->port); 40027194dc99SImre Deak 40037194dc99SImre Deak if (intel_phy_is_tc(i915, phy)) 40042a4d292fSImre Deak intel_tc_port_sanitize_mode(enc_to_dig_port(encoder), 40052a4d292fSImre Deak crtc_state); 40067194dc99SImre Deak 40077194dc99SImre Deak if (crtc_state && intel_crtc_has_dp_encoder(crtc_state)) 4008f9e76a6eSImre Deak intel_dp_sync_state(encoder, crtc_state); 4009f9e76a6eSImre Deak } 4010f9e76a6eSImre Deak 4011b671d6efSImre Deak static bool intel_ddi_initial_fastset_check(struct intel_encoder *encoder, 4012b671d6efSImre Deak struct intel_crtc_state *crtc_state) 4013b671d6efSImre Deak { 4014eddb4afcSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 4015eddb4afcSVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 4016eddb4afcSVille Syrjälä bool fastset = true; 4017b671d6efSImre Deak 4018eddb4afcSVille Syrjälä if (intel_phy_is_tc(i915, phy)) { 4019eddb4afcSVille Syrjälä drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] Forcing full modeset to compute TC port DPLLs\n", 4020eddb4afcSVille Syrjälä encoder->base.base.id, encoder->base.name); 4021eddb4afcSVille Syrjälä crtc_state->uapi.mode_changed = true; 4022eddb4afcSVille Syrjälä fastset = false; 4023eddb4afcSVille Syrjälä } 4024eddb4afcSVille Syrjälä 4025eddb4afcSVille Syrjälä if (intel_crtc_has_dp_encoder(crtc_state) && 4026eddb4afcSVille Syrjälä !intel_dp_initial_fastset_check(encoder, crtc_state)) 4027eddb4afcSVille Syrjälä fastset = false; 4028eddb4afcSVille Syrjälä 4029eddb4afcSVille Syrjälä return fastset; 4030b671d6efSImre Deak } 4031b671d6efSImre Deak 4032379bc100SJani Nikula static enum intel_output_type 4033379bc100SJani Nikula intel_ddi_compute_output_type(struct intel_encoder *encoder, 4034379bc100SJani Nikula struct intel_crtc_state *crtc_state, 4035379bc100SJani Nikula struct drm_connector_state *conn_state) 4036379bc100SJani Nikula { 4037379bc100SJani Nikula switch (conn_state->connector->connector_type) { 4038379bc100SJani Nikula case DRM_MODE_CONNECTOR_HDMIA: 4039379bc100SJani Nikula return INTEL_OUTPUT_HDMI; 4040379bc100SJani Nikula case DRM_MODE_CONNECTOR_eDP: 4041379bc100SJani Nikula return INTEL_OUTPUT_EDP; 4042379bc100SJani Nikula case DRM_MODE_CONNECTOR_DisplayPort: 4043379bc100SJani Nikula return INTEL_OUTPUT_DP; 4044379bc100SJani Nikula default: 4045379bc100SJani Nikula MISSING_CASE(conn_state->connector->connector_type); 4046379bc100SJani Nikula return INTEL_OUTPUT_UNUSED; 4047379bc100SJani Nikula } 4048379bc100SJani Nikula } 4049379bc100SJani Nikula 4050379bc100SJani Nikula static int intel_ddi_compute_config(struct intel_encoder *encoder, 4051379bc100SJani Nikula struct intel_crtc_state *pipe_config, 4052379bc100SJani Nikula struct drm_connector_state *conn_state) 4053379bc100SJani Nikula { 40542225f3c6SMaarten Lankhorst struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); 4055379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 4056379bc100SJani Nikula enum port port = encoder->port; 4057379bc100SJani Nikula int ret; 4058379bc100SJani Nikula 405910cf8e75SVille Syrjälä if (HAS_TRANSCODER(dev_priv, TRANSCODER_EDP) && port == PORT_A) 4060379bc100SJani Nikula pipe_config->cpu_transcoder = TRANSCODER_EDP; 4061379bc100SJani Nikula 4062bdacf087SAnshuman Gupta if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_HDMI)) { 406334682d60SVille Syrjälä pipe_config->has_hdmi_sink = 406434682d60SVille Syrjälä intel_hdmi_compute_has_hdmi_sink(encoder, pipe_config, conn_state); 406534682d60SVille Syrjälä 4066379bc100SJani Nikula ret = intel_hdmi_compute_config(encoder, pipe_config, conn_state); 4067bdacf087SAnshuman Gupta } else { 4068379bc100SJani Nikula ret = intel_dp_compute_config(encoder, pipe_config, conn_state); 4069bdacf087SAnshuman Gupta } 4070bdacf087SAnshuman Gupta 4071379bc100SJani Nikula if (ret) 4072379bc100SJani Nikula return ret; 4073379bc100SJani Nikula 4074379bc100SJani Nikula if (IS_HASWELL(dev_priv) && crtc->pipe == PIPE_A && 4075379bc100SJani Nikula pipe_config->cpu_transcoder == TRANSCODER_EDP) 4076379bc100SJani Nikula pipe_config->pch_pfit.force_thru = 4077379bc100SJani Nikula pipe_config->pch_pfit.enabled || 4078379bc100SJani Nikula pipe_config->crc_enabled; 4079379bc100SJani Nikula 40802446e1d6SMatt Roper if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) 4081379bc100SJani Nikula pipe_config->lane_lat_optim_mask = 4082379bc100SJani Nikula bxt_ddi_phy_calc_lane_lat_optim_mask(pipe_config->lane_count); 4083379bc100SJani Nikula 4084379bc100SJani Nikula intel_ddi_compute_min_voltage_level(dev_priv, pipe_config); 4085379bc100SJani Nikula 4086379bc100SJani Nikula return 0; 4087379bc100SJani Nikula } 4088379bc100SJani Nikula 4089b50a1aa6SManasi Navare static bool mode_equal(const struct drm_display_mode *mode1, 4090b50a1aa6SManasi Navare const struct drm_display_mode *mode2) 4091b50a1aa6SManasi Navare { 4092b50a1aa6SManasi Navare return drm_mode_match(mode1, mode2, 4093b50a1aa6SManasi Navare DRM_MODE_MATCH_TIMINGS | 4094b50a1aa6SManasi Navare DRM_MODE_MATCH_FLAGS | 4095b50a1aa6SManasi Navare DRM_MODE_MATCH_3D_FLAGS) && 4096b50a1aa6SManasi Navare mode1->clock == mode2->clock; /* we want an exact match */ 4097b50a1aa6SManasi Navare } 4098b50a1aa6SManasi Navare 4099b50a1aa6SManasi Navare static bool m_n_equal(const struct intel_link_m_n *m_n_1, 4100b50a1aa6SManasi Navare const struct intel_link_m_n *m_n_2) 4101b50a1aa6SManasi Navare { 4102b50a1aa6SManasi Navare return m_n_1->tu == m_n_2->tu && 41035f721a5dSVille Syrjälä m_n_1->data_m == m_n_2->data_m && 41045f721a5dSVille Syrjälä m_n_1->data_n == m_n_2->data_n && 4105b50a1aa6SManasi Navare m_n_1->link_m == m_n_2->link_m && 4106b50a1aa6SManasi Navare m_n_1->link_n == m_n_2->link_n; 4107b50a1aa6SManasi Navare } 4108b50a1aa6SManasi Navare 4109b50a1aa6SManasi Navare static bool crtcs_port_sync_compatible(const struct intel_crtc_state *crtc_state1, 4110b50a1aa6SManasi Navare const struct intel_crtc_state *crtc_state2) 4111b50a1aa6SManasi Navare { 4112b50a1aa6SManasi Navare return crtc_state1->hw.active && crtc_state2->hw.active && 4113b50a1aa6SManasi Navare crtc_state1->output_types == crtc_state2->output_types && 4114b50a1aa6SManasi Navare crtc_state1->output_format == crtc_state2->output_format && 4115b50a1aa6SManasi Navare crtc_state1->lane_count == crtc_state2->lane_count && 4116b50a1aa6SManasi Navare crtc_state1->port_clock == crtc_state2->port_clock && 4117b50a1aa6SManasi Navare mode_equal(&crtc_state1->hw.adjusted_mode, 4118b50a1aa6SManasi Navare &crtc_state2->hw.adjusted_mode) && 4119b50a1aa6SManasi Navare m_n_equal(&crtc_state1->dp_m_n, &crtc_state2->dp_m_n); 4120b50a1aa6SManasi Navare } 4121b50a1aa6SManasi Navare 4122b50a1aa6SManasi Navare static u8 4123b50a1aa6SManasi Navare intel_ddi_port_sync_transcoders(const struct intel_crtc_state *ref_crtc_state, 4124b50a1aa6SManasi Navare int tile_group_id) 4125b50a1aa6SManasi Navare { 4126b50a1aa6SManasi Navare struct drm_connector *connector; 4127b50a1aa6SManasi Navare const struct drm_connector_state *conn_state; 4128b50a1aa6SManasi Navare struct drm_i915_private *dev_priv = to_i915(ref_crtc_state->uapi.crtc->dev); 4129b50a1aa6SManasi Navare struct intel_atomic_state *state = 4130b50a1aa6SManasi Navare to_intel_atomic_state(ref_crtc_state->uapi.state); 4131b50a1aa6SManasi Navare u8 transcoders = 0; 4132b50a1aa6SManasi Navare int i; 4133b50a1aa6SManasi Navare 4134dc5b8ed5SVille Syrjälä /* 4135dc5b8ed5SVille Syrjälä * We don't enable port sync on BDW due to missing w/as and 4136dc5b8ed5SVille Syrjälä * due to not having adjusted the modeset sequence appropriately. 4137dc5b8ed5SVille Syrjälä */ 4138005e9537SMatt Roper if (DISPLAY_VER(dev_priv) < 9) 4139b50a1aa6SManasi Navare return 0; 4140b50a1aa6SManasi Navare 4141b50a1aa6SManasi Navare if (!intel_crtc_has_type(ref_crtc_state, INTEL_OUTPUT_DP)) 4142b50a1aa6SManasi Navare return 0; 4143b50a1aa6SManasi Navare 4144b50a1aa6SManasi Navare for_each_new_connector_in_state(&state->base, connector, conn_state, i) { 4145b50a1aa6SManasi Navare struct intel_crtc *crtc = to_intel_crtc(conn_state->crtc); 4146b50a1aa6SManasi Navare const struct intel_crtc_state *crtc_state; 4147b50a1aa6SManasi Navare 4148b50a1aa6SManasi Navare if (!crtc) 4149b50a1aa6SManasi Navare continue; 4150b50a1aa6SManasi Navare 4151b50a1aa6SManasi Navare if (!connector->has_tile || 4152b50a1aa6SManasi Navare connector->tile_group->id != 4153b50a1aa6SManasi Navare tile_group_id) 4154b50a1aa6SManasi Navare continue; 4155b50a1aa6SManasi Navare crtc_state = intel_atomic_get_new_crtc_state(state, 4156b50a1aa6SManasi Navare crtc); 4157b50a1aa6SManasi Navare if (!crtcs_port_sync_compatible(ref_crtc_state, 4158b50a1aa6SManasi Navare crtc_state)) 4159b50a1aa6SManasi Navare continue; 4160b50a1aa6SManasi Navare transcoders |= BIT(crtc_state->cpu_transcoder); 4161b50a1aa6SManasi Navare } 4162b50a1aa6SManasi Navare 4163b50a1aa6SManasi Navare return transcoders; 4164b50a1aa6SManasi Navare } 4165b50a1aa6SManasi Navare 4166b50a1aa6SManasi Navare static int intel_ddi_compute_config_late(struct intel_encoder *encoder, 4167b50a1aa6SManasi Navare struct intel_crtc_state *crtc_state, 4168b50a1aa6SManasi Navare struct drm_connector_state *conn_state) 4169b50a1aa6SManasi Navare { 417047bdb1caSJani Nikula struct drm_i915_private *i915 = to_i915(encoder->base.dev); 4171b50a1aa6SManasi Navare struct drm_connector *connector = conn_state->connector; 4172b50a1aa6SManasi Navare u8 port_sync_transcoders = 0; 4173b50a1aa6SManasi Navare 417447bdb1caSJani Nikula drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] [CRTC:%d:%s]", 4175b50a1aa6SManasi Navare encoder->base.base.id, encoder->base.name, 4176b50a1aa6SManasi Navare crtc_state->uapi.crtc->base.id, crtc_state->uapi.crtc->name); 4177b50a1aa6SManasi Navare 4178b50a1aa6SManasi Navare if (connector->has_tile) 4179b50a1aa6SManasi Navare port_sync_transcoders = intel_ddi_port_sync_transcoders(crtc_state, 4180b50a1aa6SManasi Navare connector->tile_group->id); 4181b50a1aa6SManasi Navare 4182b50a1aa6SManasi Navare /* 4183b50a1aa6SManasi Navare * EDP Transcoders cannot be ensalved 4184b50a1aa6SManasi Navare * make them a master always when present 4185b50a1aa6SManasi Navare */ 4186b50a1aa6SManasi Navare if (port_sync_transcoders & BIT(TRANSCODER_EDP)) 4187b50a1aa6SManasi Navare crtc_state->master_transcoder = TRANSCODER_EDP; 4188b50a1aa6SManasi Navare else 4189b50a1aa6SManasi Navare crtc_state->master_transcoder = ffs(port_sync_transcoders) - 1; 4190b50a1aa6SManasi Navare 4191b50a1aa6SManasi Navare if (crtc_state->master_transcoder == crtc_state->cpu_transcoder) { 4192b50a1aa6SManasi Navare crtc_state->master_transcoder = INVALID_TRANSCODER; 4193b50a1aa6SManasi Navare crtc_state->sync_mode_slaves_mask = 4194b50a1aa6SManasi Navare port_sync_transcoders & ~BIT(crtc_state->cpu_transcoder); 4195b50a1aa6SManasi Navare } 4196b50a1aa6SManasi Navare 4197b50a1aa6SManasi Navare return 0; 4198b50a1aa6SManasi Navare } 4199b50a1aa6SManasi Navare 4200379bc100SJani Nikula static void intel_ddi_encoder_destroy(struct drm_encoder *encoder) 4201379bc100SJani Nikula { 42024a300e65SImre Deak struct drm_i915_private *i915 = to_i915(encoder->dev); 4203b7d02c3aSVille Syrjälä struct intel_digital_port *dig_port = enc_to_dig_port(to_intel_encoder(encoder)); 42043e0abc76SImre Deak enum phy phy = intel_port_to_phy(i915, dig_port->base.port); 4205379bc100SJani Nikula 4206379bc100SJani Nikula intel_dp_encoder_flush_work(encoder); 42073e0abc76SImre Deak if (intel_phy_is_tc(i915, phy)) 4208c5879999SImre Deak intel_tc_port_cleanup(dig_port); 42094a300e65SImre Deak intel_display_power_flush_work(i915); 4210379bc100SJani Nikula 4211379bc100SJani Nikula drm_encoder_cleanup(encoder); 4212a6c6eac9SAnshuman Gupta kfree(dig_port->hdcp_port_data.streams); 4213379bc100SJani Nikula kfree(dig_port); 4214379bc100SJani Nikula } 4215379bc100SJani Nikula 4216764f6729SVille Syrjälä static void intel_ddi_encoder_reset(struct drm_encoder *encoder) 4217764f6729SVille Syrjälä { 4218a82796a2SImre Deak struct drm_i915_private *i915 = to_i915(encoder->dev); 4219764f6729SVille Syrjälä struct intel_dp *intel_dp = enc_to_intel_dp(to_intel_encoder(encoder)); 4220a82796a2SImre Deak struct intel_digital_port *dig_port = enc_to_dig_port(to_intel_encoder(encoder)); 4221a82796a2SImre Deak enum phy phy = intel_port_to_phy(i915, dig_port->base.port); 4222764f6729SVille Syrjälä 4223764f6729SVille Syrjälä intel_dp->reset_link_params = true; 4224764f6729SVille Syrjälä 4225764f6729SVille Syrjälä intel_pps_encoder_reset(intel_dp); 4226a82796a2SImre Deak 4227a82796a2SImre Deak if (intel_phy_is_tc(i915, phy)) 4228a82796a2SImre Deak intel_tc_port_init_mode(dig_port); 4229764f6729SVille Syrjälä } 4230764f6729SVille Syrjälä 4231c598c335SImre Deak static int intel_ddi_encoder_late_register(struct drm_encoder *_encoder) 4232c598c335SImre Deak { 4233c598c335SImre Deak struct intel_encoder *encoder = to_intel_encoder(_encoder); 4234c598c335SImre Deak 4235c598c335SImre Deak intel_tc_port_link_reset(enc_to_dig_port(encoder)); 4236c598c335SImre Deak 4237c598c335SImre Deak return 0; 4238c598c335SImre Deak } 4239c598c335SImre Deak 4240379bc100SJani Nikula static const struct drm_encoder_funcs intel_ddi_funcs = { 4241764f6729SVille Syrjälä .reset = intel_ddi_encoder_reset, 4242379bc100SJani Nikula .destroy = intel_ddi_encoder_destroy, 4243c598c335SImre Deak .late_register = intel_ddi_encoder_late_register, 4244379bc100SJani Nikula }; 4245379bc100SJani Nikula 4246379bc100SJani Nikula static struct intel_connector * 42477801f3b7SLucas De Marchi intel_ddi_init_dp_connector(struct intel_digital_port *dig_port) 4248379bc100SJani Nikula { 424923ef6194SJosé Roberto de Souza struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 4250379bc100SJani Nikula struct intel_connector *connector; 42517801f3b7SLucas De Marchi enum port port = dig_port->base.port; 4252379bc100SJani Nikula 4253379bc100SJani Nikula connector = intel_connector_alloc(); 4254379bc100SJani Nikula if (!connector) 4255379bc100SJani Nikula return NULL; 4256379bc100SJani Nikula 42577801f3b7SLucas De Marchi dig_port->dp.output_reg = DDI_BUF_CTL(port); 425823ef6194SJosé Roberto de Souza if (DISPLAY_VER(i915) >= 14) 425923ef6194SJosé Roberto de Souza dig_port->dp.prepare_link_retrain = mtl_ddi_prepare_link_retrain; 426023ef6194SJosé Roberto de Souza else 42617801f3b7SLucas De Marchi dig_port->dp.prepare_link_retrain = intel_ddi_prepare_link_retrain; 42627801f3b7SLucas De Marchi dig_port->dp.set_link_train = intel_ddi_set_link_train; 42637801f3b7SLucas De Marchi dig_port->dp.set_idle_link_train = intel_ddi_set_idle_link_train; 4264eee3f911SVille Syrjälä 42657801f3b7SLucas De Marchi dig_port->dp.voltage_max = intel_ddi_dp_voltage_max; 42667801f3b7SLucas De Marchi dig_port->dp.preemph_max = intel_ddi_dp_preemph_max; 426753de0a20SVille Syrjälä 42687801f3b7SLucas De Marchi if (!intel_dp_init_connector(dig_port, connector)) { 4269379bc100SJani Nikula kfree(connector); 4270379bc100SJani Nikula return NULL; 4271379bc100SJani Nikula } 4272379bc100SJani Nikula 42736306d8dbSHans de Goede if (dig_port->base.type == INTEL_OUTPUT_EDP) { 42746306d8dbSHans de Goede struct drm_device *dev = dig_port->base.base.dev; 42756306d8dbSHans de Goede struct drm_privacy_screen *privacy_screen; 42766306d8dbSHans de Goede 42776306d8dbSHans de Goede privacy_screen = drm_privacy_screen_get(dev->dev, NULL); 42786306d8dbSHans de Goede if (!IS_ERR(privacy_screen)) { 42796306d8dbSHans de Goede drm_connector_attach_privacy_screen_provider(&connector->base, 42806306d8dbSHans de Goede privacy_screen); 42816306d8dbSHans de Goede } else if (PTR_ERR(privacy_screen) != -ENODEV) { 42826306d8dbSHans de Goede drm_warn(dev, "Error getting privacy-screen\n"); 42836306d8dbSHans de Goede } 42846306d8dbSHans de Goede } 42856306d8dbSHans de Goede 4286379bc100SJani Nikula return connector; 4287379bc100SJani Nikula } 4288379bc100SJani Nikula 4289379bc100SJani Nikula static int modeset_pipe(struct drm_crtc *crtc, 4290379bc100SJani Nikula struct drm_modeset_acquire_ctx *ctx) 4291379bc100SJani Nikula { 4292379bc100SJani Nikula struct drm_atomic_state *state; 4293379bc100SJani Nikula struct drm_crtc_state *crtc_state; 4294379bc100SJani Nikula int ret; 4295379bc100SJani Nikula 4296379bc100SJani Nikula state = drm_atomic_state_alloc(crtc->dev); 4297379bc100SJani Nikula if (!state) 4298379bc100SJani Nikula return -ENOMEM; 4299379bc100SJani Nikula 4300379bc100SJani Nikula state->acquire_ctx = ctx; 430176ec6927SVille Syrjälä to_intel_atomic_state(state)->internal = true; 4302379bc100SJani Nikula 4303379bc100SJani Nikula crtc_state = drm_atomic_get_crtc_state(state, crtc); 4304379bc100SJani Nikula if (IS_ERR(crtc_state)) { 4305379bc100SJani Nikula ret = PTR_ERR(crtc_state); 4306379bc100SJani Nikula goto out; 4307379bc100SJani Nikula } 4308379bc100SJani Nikula 4309379bc100SJani Nikula crtc_state->connectors_changed = true; 4310379bc100SJani Nikula 4311379bc100SJani Nikula ret = drm_atomic_commit(state); 4312379bc100SJani Nikula out: 4313379bc100SJani Nikula drm_atomic_state_put(state); 4314379bc100SJani Nikula 4315379bc100SJani Nikula return ret; 4316379bc100SJani Nikula } 4317379bc100SJani Nikula 4318379bc100SJani Nikula static int intel_hdmi_reset_link(struct intel_encoder *encoder, 4319379bc100SJani Nikula struct drm_modeset_acquire_ctx *ctx) 4320379bc100SJani Nikula { 4321379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 4322b7d02c3aSVille Syrjälä struct intel_hdmi *hdmi = enc_to_intel_hdmi(encoder); 4323379bc100SJani Nikula struct intel_connector *connector = hdmi->attached_connector; 4324379bc100SJani Nikula struct i2c_adapter *adapter = 4325379bc100SJani Nikula intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus); 4326379bc100SJani Nikula struct drm_connector_state *conn_state; 4327379bc100SJani Nikula struct intel_crtc_state *crtc_state; 4328379bc100SJani Nikula struct intel_crtc *crtc; 4329379bc100SJani Nikula u8 config; 4330379bc100SJani Nikula int ret; 4331379bc100SJani Nikula 4332379bc100SJani Nikula if (!connector || connector->base.status != connector_status_connected) 4333379bc100SJani Nikula return 0; 4334379bc100SJani Nikula 4335379bc100SJani Nikula ret = drm_modeset_lock(&dev_priv->drm.mode_config.connection_mutex, 4336379bc100SJani Nikula ctx); 4337379bc100SJani Nikula if (ret) 4338379bc100SJani Nikula return ret; 4339379bc100SJani Nikula 4340379bc100SJani Nikula conn_state = connector->base.state; 4341379bc100SJani Nikula 4342379bc100SJani Nikula crtc = to_intel_crtc(conn_state->crtc); 4343379bc100SJani Nikula if (!crtc) 4344379bc100SJani Nikula return 0; 4345379bc100SJani Nikula 4346379bc100SJani Nikula ret = drm_modeset_lock(&crtc->base.mutex, ctx); 4347379bc100SJani Nikula if (ret) 4348379bc100SJani Nikula return ret; 4349379bc100SJani Nikula 4350379bc100SJani Nikula crtc_state = to_intel_crtc_state(crtc->base.state); 4351379bc100SJani Nikula 43521de143ccSPankaj Bharadiya drm_WARN_ON(&dev_priv->drm, 43531de143ccSPankaj Bharadiya !intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)); 4354379bc100SJani Nikula 43551326a92cSMaarten Lankhorst if (!crtc_state->hw.active) 4356379bc100SJani Nikula return 0; 4357379bc100SJani Nikula 4358379bc100SJani Nikula if (!crtc_state->hdmi_high_tmds_clock_ratio && 4359379bc100SJani Nikula !crtc_state->hdmi_scrambling) 4360379bc100SJani Nikula return 0; 4361379bc100SJani Nikula 4362379bc100SJani Nikula if (conn_state->commit && 4363379bc100SJani Nikula !try_wait_for_completion(&conn_state->commit->hw_done)) 4364379bc100SJani Nikula return 0; 4365379bc100SJani Nikula 4366379bc100SJani Nikula ret = drm_scdc_readb(adapter, SCDC_TMDS_CONFIG, &config); 4367379bc100SJani Nikula if (ret < 0) { 43685d844091SVille Syrjälä drm_err(&dev_priv->drm, "[CONNECTOR:%d:%s] Failed to read TMDS config: %d\n", 43695d844091SVille Syrjälä connector->base.base.id, connector->base.name, ret); 4370379bc100SJani Nikula return 0; 4371379bc100SJani Nikula } 4372379bc100SJani Nikula 4373379bc100SJani Nikula if (!!(config & SCDC_TMDS_BIT_CLOCK_RATIO_BY_40) == 4374379bc100SJani Nikula crtc_state->hdmi_high_tmds_clock_ratio && 4375379bc100SJani Nikula !!(config & SCDC_SCRAMBLING_ENABLE) == 4376379bc100SJani Nikula crtc_state->hdmi_scrambling) 4377379bc100SJani Nikula return 0; 4378379bc100SJani Nikula 4379379bc100SJani Nikula /* 4380379bc100SJani Nikula * HDMI 2.0 says that one should not send scrambled data 4381379bc100SJani Nikula * prior to configuring the sink scrambling, and that 4382379bc100SJani Nikula * TMDS clock/data transmission should be suspended when 4383379bc100SJani Nikula * changing the TMDS clock rate in the sink. So let's 4384379bc100SJani Nikula * just do a full modeset here, even though some sinks 4385379bc100SJani Nikula * would be perfectly happy if were to just reconfigure 4386379bc100SJani Nikula * the SCDC settings on the fly. 4387379bc100SJani Nikula */ 4388379bc100SJani Nikula return modeset_pipe(&crtc->base, ctx); 4389379bc100SJani Nikula } 4390379bc100SJani Nikula 43913944709dSImre Deak static enum intel_hotplug_state 43923944709dSImre Deak intel_ddi_hotplug(struct intel_encoder *encoder, 43938c8919c7SImre Deak struct intel_connector *connector) 4394379bc100SJani Nikula { 4395b4df5405SImre Deak struct drm_i915_private *i915 = to_i915(encoder->base.dev); 4396b7d02c3aSVille Syrjälä struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 4397699390f7SVille Syrjälä struct intel_dp *intel_dp = &dig_port->dp; 4398b4df5405SImre Deak enum phy phy = intel_port_to_phy(i915, encoder->port); 4399b4df5405SImre Deak bool is_tc = intel_phy_is_tc(i915, phy); 4400379bc100SJani Nikula struct drm_modeset_acquire_ctx ctx; 44013944709dSImre Deak enum intel_hotplug_state state; 4402379bc100SJani Nikula int ret; 4403379bc100SJani Nikula 4404699390f7SVille Syrjälä if (intel_dp->compliance.test_active && 4405699390f7SVille Syrjälä intel_dp->compliance.test_type == DP_TEST_LINK_PHY_TEST_PATTERN) { 4406699390f7SVille Syrjälä intel_dp_phy_test(encoder); 4407699390f7SVille Syrjälä /* just do the PHY test and nothing else */ 4408699390f7SVille Syrjälä return INTEL_HOTPLUG_UNCHANGED; 4409699390f7SVille Syrjälä } 4410699390f7SVille Syrjälä 44118c8919c7SImre Deak state = intel_encoder_hotplug(encoder, connector); 4412379bc100SJani Nikula 4413c598c335SImre Deak if (!intel_tc_port_link_reset(dig_port)) { 441460ded7ccSImre Deak intel_modeset_lock_ctx_retry(&ctx, NULL, 0, ret) { 4415379bc100SJani Nikula if (connector->base.connector_type == DRM_MODE_CONNECTOR_HDMIA) 4416379bc100SJani Nikula ret = intel_hdmi_reset_link(encoder, &ctx); 4417379bc100SJani Nikula else 4418379bc100SJani Nikula ret = intel_dp_retrain_link(encoder, &ctx); 4419379bc100SJani Nikula } 4420379bc100SJani Nikula 442160ded7ccSImre Deak drm_WARN_ON(encoder->base.dev, ret); 4422c598c335SImre Deak } 4423379bc100SJani Nikula 4424bb80c925SJosé Roberto de Souza /* 4425bb80c925SJosé Roberto de Souza * Unpowered type-c dongles can take some time to boot and be 4426bb80c925SJosé Roberto de Souza * responsible, so here giving some time to those dongles to power up 4427bb80c925SJosé Roberto de Souza * and then retrying the probe. 4428bb80c925SJosé Roberto de Souza * 4429bb80c925SJosé Roberto de Souza * On many platforms the HDMI live state signal is known to be 4430bb80c925SJosé Roberto de Souza * unreliable, so we can't use it to detect if a sink is connected or 4431bb80c925SJosé Roberto de Souza * not. Instead we detect if it's connected based on whether we can 4432bb80c925SJosé Roberto de Souza * read the EDID or not. That in turn has a problem during disconnect, 4433bb80c925SJosé Roberto de Souza * since the HPD interrupt may be raised before the DDC lines get 4434bb80c925SJosé Roberto de Souza * disconnected (due to how the required length of DDC vs. HPD 4435bb80c925SJosé Roberto de Souza * connector pins are specified) and so we'll still be able to get a 4436bb80c925SJosé Roberto de Souza * valid EDID. To solve this schedule another detection cycle if this 4437bb80c925SJosé Roberto de Souza * time around we didn't detect any change in the sink's connection 4438bb80c925SJosé Roberto de Souza * status. 4439b4df5405SImre Deak * 4440b4df5405SImre Deak * Type-c connectors which get their HPD signal deasserted then 4441b4df5405SImre Deak * reasserted, without unplugging/replugging the sink from the 4442b4df5405SImre Deak * connector, introduce a delay until the AUX channel communication 4443b4df5405SImre Deak * becomes functional. Retry the detection for 5 seconds on type-c 4444b4df5405SImre Deak * connectors to account for this delay. 4445bb80c925SJosé Roberto de Souza */ 4446b4df5405SImre Deak if (state == INTEL_HOTPLUG_UNCHANGED && 4447b4df5405SImre Deak connector->hotplug_retries < (is_tc ? 5 : 1) && 4448bb80c925SJosé Roberto de Souza !dig_port->dp.is_mst) 4449bb80c925SJosé Roberto de Souza state = INTEL_HOTPLUG_RETRY; 4450bb80c925SJosé Roberto de Souza 44513944709dSImre Deak return state; 4452379bc100SJani Nikula } 4453379bc100SJani Nikula 4454edc0e09cSVille Syrjälä static bool lpt_digital_port_connected(struct intel_encoder *encoder) 4455edc0e09cSVille Syrjälä { 4456edc0e09cSVille Syrjälä struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 44575a4dd6f0SJani Nikula u32 bit = dev_priv->display.hotplug.pch_hpd[encoder->hpd_pin]; 4458edc0e09cSVille Syrjälä 4459edc0e09cSVille Syrjälä return intel_de_read(dev_priv, SDEISR) & bit; 4460edc0e09cSVille Syrjälä } 4461edc0e09cSVille Syrjälä 4462edc0e09cSVille Syrjälä static bool hsw_digital_port_connected(struct intel_encoder *encoder) 4463edc0e09cSVille Syrjälä { 4464edc0e09cSVille Syrjälä struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 44655a4dd6f0SJani Nikula u32 bit = dev_priv->display.hotplug.hpd[encoder->hpd_pin]; 4466edc0e09cSVille Syrjälä 4467c7e8a3d6SVille Syrjälä return intel_de_read(dev_priv, DEISR) & bit; 4468edc0e09cSVille Syrjälä } 4469edc0e09cSVille Syrjälä 4470edc0e09cSVille Syrjälä static bool bdw_digital_port_connected(struct intel_encoder *encoder) 4471edc0e09cSVille Syrjälä { 4472edc0e09cSVille Syrjälä struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 44735a4dd6f0SJani Nikula u32 bit = dev_priv->display.hotplug.hpd[encoder->hpd_pin]; 4474edc0e09cSVille Syrjälä 4475edc0e09cSVille Syrjälä return intel_de_read(dev_priv, GEN8_DE_PORT_ISR) & bit; 4476edc0e09cSVille Syrjälä } 4477edc0e09cSVille Syrjälä 4478379bc100SJani Nikula static struct intel_connector * 44797801f3b7SLucas De Marchi intel_ddi_init_hdmi_connector(struct intel_digital_port *dig_port) 4480379bc100SJani Nikula { 4481379bc100SJani Nikula struct intel_connector *connector; 44827801f3b7SLucas De Marchi enum port port = dig_port->base.port; 4483379bc100SJani Nikula 4484379bc100SJani Nikula connector = intel_connector_alloc(); 4485379bc100SJani Nikula if (!connector) 4486379bc100SJani Nikula return NULL; 4487379bc100SJani Nikula 44887801f3b7SLucas De Marchi dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port); 44897801f3b7SLucas De Marchi intel_hdmi_init_connector(dig_port, connector); 4490379bc100SJani Nikula 4491379bc100SJani Nikula return connector; 4492379bc100SJani Nikula } 4493379bc100SJani Nikula 44947801f3b7SLucas De Marchi static bool intel_ddi_a_force_4_lanes(struct intel_digital_port *dig_port) 4495379bc100SJani Nikula { 44967801f3b7SLucas De Marchi struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); 4497379bc100SJani Nikula 44987801f3b7SLucas De Marchi if (dig_port->base.port != PORT_A) 4499379bc100SJani Nikula return false; 4500379bc100SJani Nikula 45017801f3b7SLucas De Marchi if (dig_port->saved_port_bits & DDI_A_4_LANES) 4502379bc100SJani Nikula return false; 4503379bc100SJani Nikula 4504379bc100SJani Nikula /* Broxton/Geminilake: Bspec says that DDI_A_4_LANES is the only 4505379bc100SJani Nikula * supported configuration 4506379bc100SJani Nikula */ 45072446e1d6SMatt Roper if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) 4508379bc100SJani Nikula return true; 4509379bc100SJani Nikula 4510379bc100SJani Nikula return false; 4511379bc100SJani Nikula } 4512379bc100SJani Nikula 4513379bc100SJani Nikula static int 45147801f3b7SLucas De Marchi intel_ddi_max_lanes(struct intel_digital_port *dig_port) 4515379bc100SJani Nikula { 45167801f3b7SLucas De Marchi struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); 45177801f3b7SLucas De Marchi enum port port = dig_port->base.port; 4518379bc100SJani Nikula int max_lanes = 4; 4519379bc100SJani Nikula 4520005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 11) 4521379bc100SJani Nikula return max_lanes; 4522379bc100SJani Nikula 4523379bc100SJani Nikula if (port == PORT_A || port == PORT_E) { 4524f7960e7fSJani Nikula if (intel_de_read(dev_priv, DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES) 4525379bc100SJani Nikula max_lanes = port == PORT_A ? 4 : 0; 4526379bc100SJani Nikula else 4527379bc100SJani Nikula /* Both A and E share 2 lanes */ 4528379bc100SJani Nikula max_lanes = 2; 4529379bc100SJani Nikula } 4530379bc100SJani Nikula 4531379bc100SJani Nikula /* 4532379bc100SJani Nikula * Some BIOS might fail to set this bit on port A if eDP 4533379bc100SJani Nikula * wasn't lit up at boot. Force this bit set when needed 4534379bc100SJani Nikula * so we use the proper lane count for our calculations. 4535379bc100SJani Nikula */ 45367801f3b7SLucas De Marchi if (intel_ddi_a_force_4_lanes(dig_port)) { 453747bdb1caSJani Nikula drm_dbg_kms(&dev_priv->drm, 453847bdb1caSJani Nikula "Forcing DDI_A_4_LANES for port A\n"); 45397801f3b7SLucas De Marchi dig_port->saved_port_bits |= DDI_A_4_LANES; 4540379bc100SJani Nikula max_lanes = 4; 4541379bc100SJani Nikula } 4542379bc100SJani Nikula 4543379bc100SJani Nikula return max_lanes; 4544379bc100SJani Nikula } 4545379bc100SJani Nikula 4546ed2615a8SMatt Roper static enum hpd_pin xelpd_hpd_pin(struct drm_i915_private *dev_priv, 4547ed2615a8SMatt Roper enum port port) 4548ed2615a8SMatt Roper { 4549ed2615a8SMatt Roper if (port >= PORT_D_XELPD) 4550ed2615a8SMatt Roper return HPD_PORT_D + port - PORT_D_XELPD; 4551ed2615a8SMatt Roper else if (port >= PORT_TC1) 4552ed2615a8SMatt Roper return HPD_PORT_TC1 + port - PORT_TC1; 4553ed2615a8SMatt Roper else 4554ed2615a8SMatt Roper return HPD_PORT_A + port - PORT_A; 4555ed2615a8SMatt Roper } 4556ed2615a8SMatt Roper 4557229f31e2SLucas De Marchi static enum hpd_pin dg1_hpd_pin(struct drm_i915_private *dev_priv, 4558229f31e2SLucas De Marchi enum port port) 4559229f31e2SLucas De Marchi { 45601d8ca002SVille Syrjälä if (port >= PORT_TC1) 45611d8ca002SVille Syrjälä return HPD_PORT_C + port - PORT_TC1; 4562229f31e2SLucas De Marchi else 4563229f31e2SLucas De Marchi return HPD_PORT_A + port - PORT_A; 4564229f31e2SLucas De Marchi } 4565229f31e2SLucas De Marchi 4566da51e4baSVille Syrjälä static enum hpd_pin tgl_hpd_pin(struct drm_i915_private *dev_priv, 4567da51e4baSVille Syrjälä enum port port) 4568da51e4baSVille Syrjälä { 45691d8ca002SVille Syrjälä if (port >= PORT_TC1) 45701d8ca002SVille Syrjälä return HPD_PORT_TC1 + port - PORT_TC1; 4571da51e4baSVille Syrjälä else 4572da51e4baSVille Syrjälä return HPD_PORT_A + port - PORT_A; 4573da51e4baSVille Syrjälä } 4574da51e4baSVille Syrjälä 4575da51e4baSVille Syrjälä static enum hpd_pin rkl_hpd_pin(struct drm_i915_private *dev_priv, 4576da51e4baSVille Syrjälä enum port port) 4577da51e4baSVille Syrjälä { 4578da51e4baSVille Syrjälä if (HAS_PCH_TGP(dev_priv)) 4579da51e4baSVille Syrjälä return tgl_hpd_pin(dev_priv, port); 4580da51e4baSVille Syrjälä 45811d8ca002SVille Syrjälä if (port >= PORT_TC1) 45821d8ca002SVille Syrjälä return HPD_PORT_C + port - PORT_TC1; 4583da51e4baSVille Syrjälä else 4584da51e4baSVille Syrjälä return HPD_PORT_A + port - PORT_A; 4585da51e4baSVille Syrjälä } 4586da51e4baSVille Syrjälä 4587da51e4baSVille Syrjälä static enum hpd_pin icl_hpd_pin(struct drm_i915_private *dev_priv, 4588da51e4baSVille Syrjälä enum port port) 4589da51e4baSVille Syrjälä { 4590da51e4baSVille Syrjälä if (port >= PORT_C) 4591da51e4baSVille Syrjälä return HPD_PORT_TC1 + port - PORT_C; 4592da51e4baSVille Syrjälä else 4593da51e4baSVille Syrjälä return HPD_PORT_A + port - PORT_A; 4594da51e4baSVille Syrjälä } 4595da51e4baSVille Syrjälä 4596da51e4baSVille Syrjälä static enum hpd_pin ehl_hpd_pin(struct drm_i915_private *dev_priv, 4597da51e4baSVille Syrjälä enum port port) 4598da51e4baSVille Syrjälä { 4599da51e4baSVille Syrjälä if (port == PORT_D) 4600da51e4baSVille Syrjälä return HPD_PORT_A; 4601da51e4baSVille Syrjälä 4602f24d1d45SVille Syrjälä if (HAS_PCH_TGP(dev_priv)) 4603da51e4baSVille Syrjälä return icl_hpd_pin(dev_priv, port); 4604da51e4baSVille Syrjälä 4605da51e4baSVille Syrjälä return HPD_PORT_A + port - PORT_A; 4606da51e4baSVille Syrjälä } 4607da51e4baSVille Syrjälä 4608c8455098SLyude Paul static enum hpd_pin skl_hpd_pin(struct drm_i915_private *dev_priv, enum port port) 4609c8455098SLyude Paul { 4610c8455098SLyude Paul if (HAS_PCH_TGP(dev_priv)) 4611c8455098SLyude Paul return icl_hpd_pin(dev_priv, port); 4612c8455098SLyude Paul 4613c8455098SLyude Paul return HPD_PORT_A + port - PORT_A; 4614c8455098SLyude Paul } 4615c8455098SLyude Paul 461636ecb0ecSVille Syrjälä static bool intel_ddi_is_tc(struct drm_i915_private *i915, enum port port) 461736ecb0ecSVille Syrjälä { 4618005e9537SMatt Roper if (DISPLAY_VER(i915) >= 12) 461936ecb0ecSVille Syrjälä return port >= PORT_TC1; 4620005e9537SMatt Roper else if (DISPLAY_VER(i915) >= 11) 462136ecb0ecSVille Syrjälä return port >= PORT_C; 462236ecb0ecSVille Syrjälä else 462336ecb0ecSVille Syrjälä return false; 462436ecb0ecSVille Syrjälä } 462536ecb0ecSVille Syrjälä 4626151ec347SImre Deak static void intel_ddi_encoder_suspend(struct intel_encoder *encoder) 4627151ec347SImre Deak { 4628151ec347SImre Deak intel_dp_encoder_suspend(encoder); 4629b61fad5fSImre Deak } 4630151ec347SImre Deak 4631b61fad5fSImre Deak static void intel_ddi_tc_encoder_suspend_complete(struct intel_encoder *encoder) 4632b61fad5fSImre Deak { 4633b61fad5fSImre Deak struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 4634b61fad5fSImre Deak struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); 4635151ec347SImre Deak 4636c598c335SImre Deak intel_tc_port_suspend(dig_port); 4637151ec347SImre Deak } 4638151ec347SImre Deak 4639151ec347SImre Deak static void intel_ddi_encoder_shutdown(struct intel_encoder *encoder) 4640151ec347SImre Deak { 4641151ec347SImre Deak intel_dp_encoder_shutdown(encoder); 464249c55f7bSVille Syrjälä intel_hdmi_encoder_shutdown(encoder); 4643b61fad5fSImre Deak } 4644151ec347SImre Deak 4645b61fad5fSImre Deak static void intel_ddi_tc_encoder_shutdown_complete(struct intel_encoder *encoder) 4646b61fad5fSImre Deak { 4647b61fad5fSImre Deak struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 4648b61fad5fSImre Deak struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); 4649151ec347SImre Deak 4650c5879999SImre Deak intel_tc_port_cleanup(dig_port); 4651151ec347SImre Deak } 4652151ec347SImre Deak 465383566d13SVille Syrjälä #define port_tc_name(port) ((port) - PORT_TC1 + '1') 465483566d13SVille Syrjälä #define tc_port_name(tc_port) ((tc_port) - TC_PORT_1 + '1') 465583566d13SVille Syrjälä 4656379bc100SJani Nikula void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) 4657379bc100SJani Nikula { 46587801f3b7SLucas De Marchi struct intel_digital_port *dig_port; 465970dfbc29SLucas De Marchi struct intel_encoder *encoder; 466045c0673aSJani Nikula const struct intel_bios_encoder_data *devdata; 4661f542d671SKai-Heng Feng bool init_hdmi, init_dp; 4662d8fe2ab6SMatt Roper enum phy phy = intel_port_to_phy(dev_priv, port); 4663379bc100SJani Nikula 4664*679df6f1SVille Syrjälä if (!assert_port_valid(dev_priv, port)) 4665*679df6f1SVille Syrjälä return; 4666*679df6f1SVille Syrjälä 4667ddff9a60SMatt Roper /* 4668ddff9a60SMatt Roper * On platforms with HTI (aka HDPORT), if it's enabled at boot it may 4669ddff9a60SMatt Roper * have taken over some of the PHYs and made them unavailable to the 4670ddff9a60SMatt Roper * driver. In that case we should skip initializing the corresponding 4671ddff9a60SMatt Roper * outputs. 4672ddff9a60SMatt Roper */ 467303120fefSJani Nikula if (intel_hti_uses_phy(dev_priv, phy)) { 4674ddff9a60SMatt Roper drm_dbg_kms(&dev_priv->drm, "PORT %c / PHY %c reserved by HTI\n", 4675ddff9a60SMatt Roper port_name(port), phy_name(phy)); 4676ddff9a60SMatt Roper return; 4677ddff9a60SMatt Roper } 4678ddff9a60SMatt Roper 467945c0673aSJani Nikula devdata = intel_bios_encoder_data_lookup(dev_priv, port); 468045c0673aSJani Nikula if (!devdata) { 468145c0673aSJani Nikula drm_dbg_kms(&dev_priv->drm, 468245c0673aSJani Nikula "VBT says port %c is not present\n", 468345c0673aSJani Nikula port_name(port)); 468445c0673aSJani Nikula return; 468545c0673aSJani Nikula } 468645c0673aSJani Nikula 468745c0673aSJani Nikula init_hdmi = intel_bios_encoder_supports_dvi(devdata) || 468845c0673aSJani Nikula intel_bios_encoder_supports_hdmi(devdata); 468945c0673aSJani Nikula init_dp = intel_bios_encoder_supports_dp(devdata); 4690379bc100SJani Nikula 4691db5d650fSVille Syrjälä if (intel_bios_encoder_is_lspcon(devdata)) { 4692379bc100SJani Nikula /* 4693379bc100SJani Nikula * Lspcon device needs to be driven with DP connector 4694379bc100SJani Nikula * with special detection sequence. So make sure DP 4695379bc100SJani Nikula * is initialized before lspcon. 4696379bc100SJani Nikula */ 4697379bc100SJani Nikula init_dp = true; 4698379bc100SJani Nikula init_hdmi = false; 469947bdb1caSJani Nikula drm_dbg_kms(&dev_priv->drm, "VBT says port %c has lspcon\n", 470047bdb1caSJani Nikula port_name(port)); 4701379bc100SJani Nikula } 4702379bc100SJani Nikula 4703379bc100SJani Nikula if (!init_dp && !init_hdmi) { 470447bdb1caSJani Nikula drm_dbg_kms(&dev_priv->drm, 470547bdb1caSJani Nikula "VBT says port %c is not DVI/HDMI/DP compatible, respect it\n", 4706379bc100SJani Nikula port_name(port)); 4707379bc100SJani Nikula return; 4708379bc100SJani Nikula } 4709379bc100SJani Nikula 4710b4eb76d8SMatt Roper if (intel_phy_is_snps(dev_priv, phy) && 47113a7e2d58SJani Nikula dev_priv->display.snps.phy_failed_calibration & BIT(phy)) { 4712b4eb76d8SMatt Roper drm_dbg_kms(&dev_priv->drm, 471382c362f2SLucas De Marchi "SNPS PHY %c failed to calibrate, proceeding anyway\n", 4714b4eb76d8SMatt Roper phy_name(phy)); 4715b4eb76d8SMatt Roper } 4716b4eb76d8SMatt Roper 47177801f3b7SLucas De Marchi dig_port = kzalloc(sizeof(*dig_port), GFP_KERNEL); 47187801f3b7SLucas De Marchi if (!dig_port) 4719379bc100SJani Nikula return; 4720379bc100SJani Nikula 47217801f3b7SLucas De Marchi encoder = &dig_port->base; 4722c0a950d1SJani Nikula encoder->devdata = devdata; 4723379bc100SJani Nikula 4724ed2615a8SMatt Roper if (DISPLAY_VER(dev_priv) >= 13 && port >= PORT_D_XELPD) { 4725ed2615a8SMatt Roper drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs, 4726ed2615a8SMatt Roper DRM_MODE_ENCODER_TMDS, 4727ed2615a8SMatt Roper "DDI %c/PHY %c", 4728ed2615a8SMatt Roper port_name(port - PORT_D_XELPD + PORT_D), 4729ed2615a8SMatt Roper phy_name(phy)); 4730ed2615a8SMatt Roper } else if (DISPLAY_VER(dev_priv) >= 12) { 47312d709a5aSVille Syrjälä enum tc_port tc_port = intel_port_to_tc(dev_priv, port); 47322d709a5aSVille Syrjälä 473370dfbc29SLucas De Marchi drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs, 47342d709a5aSVille Syrjälä DRM_MODE_ENCODER_TMDS, 47352d709a5aSVille Syrjälä "DDI %s%c/PHY %s%c", 47362d709a5aSVille Syrjälä port >= PORT_TC1 ? "TC" : "", 473783566d13SVille Syrjälä port >= PORT_TC1 ? port_tc_name(port) : port_name(port), 47382d709a5aSVille Syrjälä tc_port != TC_PORT_NONE ? "TC" : "", 473983566d13SVille Syrjälä tc_port != TC_PORT_NONE ? tc_port_name(tc_port) : phy_name(phy)); 4740005e9537SMatt Roper } else if (DISPLAY_VER(dev_priv) >= 11) { 47412d709a5aSVille Syrjälä enum tc_port tc_port = intel_port_to_tc(dev_priv, port); 47422d709a5aSVille Syrjälä 47432d709a5aSVille Syrjälä drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs, 47442d709a5aSVille Syrjälä DRM_MODE_ENCODER_TMDS, 47452d709a5aSVille Syrjälä "DDI %c%s/PHY %s%c", 47462d709a5aSVille Syrjälä port_name(port), 47472d709a5aSVille Syrjälä port >= PORT_C ? " (TC)" : "", 47482d709a5aSVille Syrjälä tc_port != TC_PORT_NONE ? "TC" : "", 474983566d13SVille Syrjälä tc_port != TC_PORT_NONE ? tc_port_name(tc_port) : phy_name(phy)); 47502d709a5aSVille Syrjälä } else { 47512d709a5aSVille Syrjälä drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs, 47522d709a5aSVille Syrjälä DRM_MODE_ENCODER_TMDS, 47532d709a5aSVille Syrjälä "DDI %c/PHY %c", port_name(port), phy_name(phy)); 47542d709a5aSVille Syrjälä } 4755379bc100SJani Nikula 475636e5e704SSean Paul mutex_init(&dig_port->hdcp_mutex); 475736e5e704SSean Paul dig_port->num_hdcp_streams = 0; 475836e5e704SSean Paul 475970dfbc29SLucas De Marchi encoder->hotplug = intel_ddi_hotplug; 476070dfbc29SLucas De Marchi encoder->compute_output_type = intel_ddi_compute_output_type; 476170dfbc29SLucas De Marchi encoder->compute_config = intel_ddi_compute_config; 4762b50a1aa6SManasi Navare encoder->compute_config_late = intel_ddi_compute_config_late; 476370dfbc29SLucas De Marchi encoder->enable = intel_enable_ddi; 476470dfbc29SLucas De Marchi encoder->pre_pll_enable = intel_ddi_pre_pll_enable; 476570dfbc29SLucas De Marchi encoder->pre_enable = intel_ddi_pre_enable; 476670dfbc29SLucas De Marchi encoder->disable = intel_disable_ddi; 4767b108bdd0SImre Deak encoder->post_pll_disable = intel_ddi_post_pll_disable; 476870dfbc29SLucas De Marchi encoder->post_disable = intel_ddi_post_disable; 476970dfbc29SLucas De Marchi encoder->update_pipe = intel_ddi_update_pipe; 477070dfbc29SLucas De Marchi encoder->get_hw_state = intel_ddi_get_hw_state; 4771f9e76a6eSImre Deak encoder->sync_state = intel_ddi_sync_state; 4772b671d6efSImre Deak encoder->initial_fastset_check = intel_ddi_initial_fastset_check; 4773151ec347SImre Deak encoder->suspend = intel_ddi_encoder_suspend; 4774151ec347SImre Deak encoder->shutdown = intel_ddi_encoder_shutdown; 477570dfbc29SLucas De Marchi encoder->get_power_domains = intel_ddi_get_power_domains; 477670dfbc29SLucas De Marchi 477770dfbc29SLucas De Marchi encoder->type = INTEL_OUTPUT_DDI; 4778979e1b32SImre Deak encoder->power_domain = intel_display_power_ddi_lanes_domain(dev_priv, port); 477970dfbc29SLucas De Marchi encoder->port = port; 478070dfbc29SLucas De Marchi encoder->cloneable = 0; 478170dfbc29SLucas De Marchi encoder->pipe_mask = ~0; 4782da51e4baSVille Syrjälä 478351390cc0SRadhakrishna Sripada if (DISPLAY_VER(dev_priv) >= 14) { 478473fc3abcSMika Kahola encoder->enable_clock = intel_mtl_pll_enable; 478573fc3abcSMika Kahola encoder->disable_clock = intel_mtl_pll_disable; 47866f0423b0SMika Kahola encoder->port_pll_type = intel_mtl_port_pll_type; 478751390cc0SRadhakrishna Sripada encoder->get_config = mtl_ddi_get_config; 478851390cc0SRadhakrishna Sripada } else if (IS_DG2(dev_priv)) { 4789f82f2563SMatt Roper encoder->enable_clock = intel_mpllb_enable; 4790f82f2563SMatt Roper encoder->disable_clock = intel_mpllb_disable; 4791865b73eaSMatt Roper encoder->get_config = dg2_ddi_get_config; 4792865b73eaSMatt Roper } else if (IS_ALDERLAKE_S(dev_priv)) { 479340b316d4SVille Syrjälä encoder->enable_clock = adls_ddi_enable_clock; 479440b316d4SVille Syrjälä encoder->disable_clock = adls_ddi_disable_clock; 47950fbd8694SVille Syrjälä encoder->is_clock_enabled = adls_ddi_is_clock_enabled; 4796351221ffSVille Syrjälä encoder->get_config = adls_ddi_get_config; 479740b316d4SVille Syrjälä } else if (IS_ROCKETLAKE(dev_priv)) { 479840b316d4SVille Syrjälä encoder->enable_clock = rkl_ddi_enable_clock; 479940b316d4SVille Syrjälä encoder->disable_clock = rkl_ddi_disable_clock; 48000fbd8694SVille Syrjälä encoder->is_clock_enabled = rkl_ddi_is_clock_enabled; 4801351221ffSVille Syrjälä encoder->get_config = rkl_ddi_get_config; 480236ecb0ecSVille Syrjälä } else if (IS_DG1(dev_priv)) { 480335bb6b1aSVille Syrjälä encoder->enable_clock = dg1_ddi_enable_clock; 480435bb6b1aSVille Syrjälä encoder->disable_clock = dg1_ddi_disable_clock; 48050fbd8694SVille Syrjälä encoder->is_clock_enabled = dg1_ddi_is_clock_enabled; 4806351221ffSVille Syrjälä encoder->get_config = dg1_ddi_get_config; 480736ecb0ecSVille Syrjälä } else if (IS_JSL_EHL(dev_priv)) { 480836ecb0ecSVille Syrjälä if (intel_ddi_is_tc(dev_priv, port)) { 480936ecb0ecSVille Syrjälä encoder->enable_clock = jsl_ddi_tc_enable_clock; 481036ecb0ecSVille Syrjälä encoder->disable_clock = jsl_ddi_tc_disable_clock; 48110fbd8694SVille Syrjälä encoder->is_clock_enabled = jsl_ddi_tc_is_clock_enabled; 48127c1da068SImre Deak encoder->port_pll_type = icl_ddi_tc_port_pll_type; 4813351221ffSVille Syrjälä encoder->get_config = icl_ddi_combo_get_config; 481436ecb0ecSVille Syrjälä } else { 481536ecb0ecSVille Syrjälä encoder->enable_clock = icl_ddi_combo_enable_clock; 481636ecb0ecSVille Syrjälä encoder->disable_clock = icl_ddi_combo_disable_clock; 48170fbd8694SVille Syrjälä encoder->is_clock_enabled = icl_ddi_combo_is_clock_enabled; 4818351221ffSVille Syrjälä encoder->get_config = icl_ddi_combo_get_config; 481936ecb0ecSVille Syrjälä } 4820005e9537SMatt Roper } else if (DISPLAY_VER(dev_priv) >= 11) { 482136ecb0ecSVille Syrjälä if (intel_ddi_is_tc(dev_priv, port)) { 482236ecb0ecSVille Syrjälä encoder->enable_clock = icl_ddi_tc_enable_clock; 482336ecb0ecSVille Syrjälä encoder->disable_clock = icl_ddi_tc_disable_clock; 48240fbd8694SVille Syrjälä encoder->is_clock_enabled = icl_ddi_tc_is_clock_enabled; 48257c1da068SImre Deak encoder->port_pll_type = icl_ddi_tc_port_pll_type; 4826351221ffSVille Syrjälä encoder->get_config = icl_ddi_tc_get_config; 482736ecb0ecSVille Syrjälä } else { 482836ecb0ecSVille Syrjälä encoder->enable_clock = icl_ddi_combo_enable_clock; 482936ecb0ecSVille Syrjälä encoder->disable_clock = icl_ddi_combo_disable_clock; 48300fbd8694SVille Syrjälä encoder->is_clock_enabled = icl_ddi_combo_is_clock_enabled; 4831351221ffSVille Syrjälä encoder->get_config = icl_ddi_combo_get_config; 483236ecb0ecSVille Syrjälä } 48332446e1d6SMatt Roper } else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { 4834351221ffSVille Syrjälä /* BXT/GLK have fixed PLL->port mapping */ 4835351221ffSVille Syrjälä encoder->get_config = bxt_ddi_get_config; 483693e7e61eSLucas De Marchi } else if (DISPLAY_VER(dev_priv) == 9) { 483738e31f1aSVille Syrjälä encoder->enable_clock = skl_ddi_enable_clock; 483838e31f1aSVille Syrjälä encoder->disable_clock = skl_ddi_disable_clock; 48390fbd8694SVille Syrjälä encoder->is_clock_enabled = skl_ddi_is_clock_enabled; 4840351221ffSVille Syrjälä encoder->get_config = skl_ddi_get_config; 484138e31f1aSVille Syrjälä } else if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) { 4842d135368dSVille Syrjälä encoder->enable_clock = hsw_ddi_enable_clock; 4843d135368dSVille Syrjälä encoder->disable_clock = hsw_ddi_disable_clock; 48440fbd8694SVille Syrjälä encoder->is_clock_enabled = hsw_ddi_is_clock_enabled; 4845351221ffSVille Syrjälä encoder->get_config = hsw_ddi_get_config; 4846d135368dSVille Syrjälä } 4847d135368dSVille Syrjälä 4848ea8af87aSMika Kahola if (DISPLAY_VER(dev_priv) >= 14) { 4849ea8af87aSMika Kahola encoder->set_signal_levels = intel_cx0_phy_set_signal_levels; 4850ea8af87aSMika Kahola } else if (IS_DG2(dev_priv)) { 4851193299adSVille Syrjälä encoder->set_signal_levels = intel_snps_phy_set_signal_levels; 4852193299adSVille Syrjälä } else if (DISPLAY_VER(dev_priv) >= 12) { 4853193299adSVille Syrjälä if (intel_phy_is_combo(dev_priv, phy)) 4854193299adSVille Syrjälä encoder->set_signal_levels = icl_combo_phy_set_signal_levels; 4855e722ab8bSVille Syrjälä else 4856193299adSVille Syrjälä encoder->set_signal_levels = tgl_dkl_phy_set_signal_levels; 4857193299adSVille Syrjälä } else if (DISPLAY_VER(dev_priv) >= 11) { 4858193299adSVille Syrjälä if (intel_phy_is_combo(dev_priv, phy)) 4859193299adSVille Syrjälä encoder->set_signal_levels = icl_combo_phy_set_signal_levels; 4860193299adSVille Syrjälä else 4861193299adSVille Syrjälä encoder->set_signal_levels = icl_mg_phy_set_signal_levels; 4862193299adSVille Syrjälä } else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { 48635f5ada0bSVille Syrjälä encoder->set_signal_levels = bxt_ddi_phy_set_signal_levels; 4864193299adSVille Syrjälä } else { 4865e722ab8bSVille Syrjälä encoder->set_signal_levels = hsw_set_signal_levels; 4866193299adSVille Syrjälä } 4867e722ab8bSVille Syrjälä 4868c40a253bSVille Syrjälä intel_ddi_buf_trans_init(encoder); 4869c40a253bSVille Syrjälä 4870ed2615a8SMatt Roper if (DISPLAY_VER(dev_priv) >= 13) 4871ed2615a8SMatt Roper encoder->hpd_pin = xelpd_hpd_pin(dev_priv, port); 4872ed2615a8SMatt Roper else if (IS_DG1(dev_priv)) 4873229f31e2SLucas De Marchi encoder->hpd_pin = dg1_hpd_pin(dev_priv, port); 4874229f31e2SLucas De Marchi else if (IS_ROCKETLAKE(dev_priv)) 4875da51e4baSVille Syrjälä encoder->hpd_pin = rkl_hpd_pin(dev_priv, port); 4876005e9537SMatt Roper else if (DISPLAY_VER(dev_priv) >= 12) 4877da51e4baSVille Syrjälä encoder->hpd_pin = tgl_hpd_pin(dev_priv, port); 487824ea098bSTejas Upadhyay else if (IS_JSL_EHL(dev_priv)) 4879da51e4baSVille Syrjälä encoder->hpd_pin = ehl_hpd_pin(dev_priv, port); 488093e7e61eSLucas De Marchi else if (DISPLAY_VER(dev_priv) == 11) 4881da51e4baSVille Syrjälä encoder->hpd_pin = icl_hpd_pin(dev_priv, port); 488293e7e61eSLucas De Marchi else if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv)) 4883c8455098SLyude Paul encoder->hpd_pin = skl_hpd_pin(dev_priv, port); 4884da51e4baSVille Syrjälä else 488503c7e4f1SVille Syrjälä encoder->hpd_pin = intel_hpd_pin_default(dev_priv, port); 4886379bc100SJani Nikula 4887005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 11) 48887801f3b7SLucas De Marchi dig_port->saved_port_bits = 48897801f3b7SLucas De Marchi intel_de_read(dev_priv, DDI_BUF_CTL(port)) 48907801f3b7SLucas De Marchi & DDI_BUF_PORT_REVERSAL; 4891379bc100SJani Nikula else 48927801f3b7SLucas De Marchi dig_port->saved_port_bits = 48937801f3b7SLucas De Marchi intel_de_read(dev_priv, DDI_BUF_CTL(port)) 48947801f3b7SLucas De Marchi & (DDI_BUF_PORT_REVERSAL | DDI_A_4_LANES); 489570dfbc29SLucas De Marchi 48965f42196dSVille Syrjälä if (intel_bios_encoder_lane_reversal(devdata)) 4897aaab24bbSUma Shankar dig_port->saved_port_bits |= DDI_BUF_PORT_REVERSAL; 4898aaab24bbSUma Shankar 48997801f3b7SLucas De Marchi dig_port->dp.output_reg = INVALID_MMIO_REG; 49007801f3b7SLucas De Marchi dig_port->max_lanes = intel_ddi_max_lanes(dig_port); 4901bb45217fSVille Syrjälä dig_port->aux_ch = intel_dp_aux_ch(encoder); 4902379bc100SJani Nikula 4903d8fe2ab6SMatt Roper if (intel_phy_is_tc(dev_priv, phy)) { 4904c5faae5aSJani Nikula bool is_legacy = 4905f08fbe6aSJani Nikula !intel_bios_encoder_supports_typec_usb(devdata) && 4906f08fbe6aSJani Nikula !intel_bios_encoder_supports_tbt(devdata); 4907379bc100SJani Nikula 490840a55b84SImre Deak if (!is_legacy && init_hdmi) { 490940a55b84SImre Deak is_legacy = !init_dp; 491040a55b84SImre Deak 491140a55b84SImre Deak drm_dbg_kms(&dev_priv->drm, 491240a55b84SImre Deak "VBT says port %c is non-legacy TC and has HDMI (with DP: %s), assume it's %s\n", 491340a55b84SImre Deak port_name(port), 491440a55b84SImre Deak str_yes_no(init_dp), 491540a55b84SImre Deak is_legacy ? "legacy" : "non-legacy"); 491640a55b84SImre Deak } 491740a55b84SImre Deak 4918b61fad5fSImre Deak encoder->suspend_complete = intel_ddi_tc_encoder_suspend_complete; 4919b61fad5fSImre Deak encoder->shutdown_complete = intel_ddi_tc_encoder_shutdown_complete; 4920b61fad5fSImre Deak 4921c5879999SImre Deak if (intel_tc_port_init(dig_port, is_legacy) < 0) 4922c5879999SImre Deak goto err; 4923ab7bc4e1SImre Deak } 4924ab7bc4e1SImre Deak 49251de143ccSPankaj Bharadiya drm_WARN_ON(&dev_priv->drm, port > PORT_I); 4926979e1b32SImre Deak dig_port->ddi_io_power_domain = intel_display_power_ddi_io_domain(dev_priv, port); 4927379bc100SJani Nikula 4928005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 11) { 4929edc0e09cSVille Syrjälä if (intel_phy_is_tc(dev_priv, phy)) 49307801f3b7SLucas De Marchi dig_port->connected = intel_tc_port_connected; 4931edc0e09cSVille Syrjälä else 49327801f3b7SLucas De Marchi dig_port->connected = lpt_digital_port_connected; 4933dded35acSVille Syrjälä } else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { 4934dded35acSVille Syrjälä dig_port->connected = bdw_digital_port_connected; 4935dded35acSVille Syrjälä } else if (DISPLAY_VER(dev_priv) == 9) { 4936dded35acSVille Syrjälä dig_port->connected = lpt_digital_port_connected; 4937dded35acSVille Syrjälä } else if (IS_BROADWELL(dev_priv)) { 4938dded35acSVille Syrjälä if (port == PORT_A) 49397801f3b7SLucas De Marchi dig_port->connected = bdw_digital_port_connected; 4940edc0e09cSVille Syrjälä else 49417801f3b7SLucas De Marchi dig_port->connected = lpt_digital_port_connected; 4942dded35acSVille Syrjälä } else if (IS_HASWELL(dev_priv)) { 4943c7e8a3d6SVille Syrjälä if (port == PORT_A) 49447801f3b7SLucas De Marchi dig_port->connected = hsw_digital_port_connected; 4945edc0e09cSVille Syrjälä else 49467801f3b7SLucas De Marchi dig_port->connected = lpt_digital_port_connected; 4947edc0e09cSVille Syrjälä } 4948edc0e09cSVille Syrjälä 49497801f3b7SLucas De Marchi intel_infoframe_init(dig_port); 4950379bc100SJani Nikula 4951a98ffd6eSVille Syrjälä if (init_dp) { 4952a98ffd6eSVille Syrjälä if (!intel_ddi_init_dp_connector(dig_port)) 4953a98ffd6eSVille Syrjälä goto err; 4954a98ffd6eSVille Syrjälä 4955a98ffd6eSVille Syrjälä dig_port->hpd_pulse = intel_dp_hpd_pulse; 4956a98ffd6eSVille Syrjälä 4957a98ffd6eSVille Syrjälä if (dig_port->dp.mso_link_count) 4958a98ffd6eSVille Syrjälä encoder->pipe_mask = intel_ddi_splitter_pipe_mask(dev_priv); 4959a98ffd6eSVille Syrjälä } 4960a98ffd6eSVille Syrjälä 4961a98ffd6eSVille Syrjälä /* 4962a98ffd6eSVille Syrjälä * In theory we don't need the encoder->type check, 4963a98ffd6eSVille Syrjälä * but leave it just in case we have some really bad VBTs... 4964a98ffd6eSVille Syrjälä */ 4965a98ffd6eSVille Syrjälä if (encoder->type != INTEL_OUTPUT_EDP && init_hdmi) { 4966a98ffd6eSVille Syrjälä if (!intel_ddi_init_hdmi_connector(dig_port)) 4967a98ffd6eSVille Syrjälä goto err; 4968a98ffd6eSVille Syrjälä } 4969a98ffd6eSVille Syrjälä 4970379bc100SJani Nikula return; 4971379bc100SJani Nikula 4972379bc100SJani Nikula err: 497370dfbc29SLucas De Marchi drm_encoder_cleanup(&encoder->base); 49747801f3b7SLucas De Marchi kfree(dig_port); 4975379bc100SJani Nikula } 4976