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" 66abad6805SJani Nikula #include "intel_pps.h" 67379bc100SJani Nikula #include "intel_psr.h" 680c82118bSJani Nikula #include "intel_quirks.h" 69865b73eaSMatt Roper #include "intel_snps_phy.h" 70bc85328fSImre Deak #include "intel_tc.h" 71379bc100SJani Nikula #include "intel_vdsc.h" 72c3f05948SJani Nikula #include "intel_vdsc_regs.h" 73714b1cdbSDave Airlie #include "skl_scaler.h" 7446d12f91SDave Airlie #include "skl_universal_plane.h" 75379bc100SJani Nikula 76379bc100SJani Nikula static const u8 index_to_dp_signal_levels[] = { 77379bc100SJani Nikula [0] = DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0, 78379bc100SJani Nikula [1] = DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1, 79379bc100SJani Nikula [2] = DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2, 80379bc100SJani Nikula [3] = DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_3, 81379bc100SJani Nikula [4] = DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0, 82379bc100SJani Nikula [5] = DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1, 83379bc100SJani Nikula [6] = DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2, 84379bc100SJani Nikula [7] = DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0, 85379bc100SJani Nikula [8] = DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1, 86379bc100SJani Nikula [9] = DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0, 87379bc100SJani Nikula }; 88379bc100SJani Nikula 89a621860aSVille Syrjälä static int intel_ddi_hdmi_level(struct intel_encoder *encoder, 903e022c1fSVille Syrjälä const struct intel_ddi_buf_trans *trans) 91379bc100SJani Nikula { 923e022c1fSVille Syrjälä int level; 93379bc100SJani Nikula 9402107ef1SVille Syrjälä level = intel_bios_hdmi_level_shift(encoder->devdata); 950aed3bdeSJani Nikula if (level < 0) 963e022c1fSVille Syrjälä level = trans->hdmi_default_entry; 97379bc100SJani Nikula 98379bc100SJani Nikula return level; 99379bc100SJani Nikula } 100379bc100SJani Nikula 1015bafd85dSVille Syrjälä static bool has_buf_trans_select(struct drm_i915_private *i915) 1025bafd85dSVille Syrjälä { 1035bafd85dSVille Syrjälä return DISPLAY_VER(i915) < 10 && !IS_BROXTON(i915); 1045bafd85dSVille Syrjälä } 1055bafd85dSVille Syrjälä 106f820693bSVille Syrjälä static bool has_iboost(struct drm_i915_private *i915) 107f820693bSVille Syrjälä { 108f820693bSVille Syrjälä return DISPLAY_VER(i915) == 9 && !IS_BROXTON(i915); 109f820693bSVille Syrjälä } 110f820693bSVille Syrjälä 111379bc100SJani Nikula /* 112379bc100SJani Nikula * Starting with Haswell, DDI port buffers must be programmed with correct 113379bc100SJani Nikula * values in advance. This function programs the correct values for 114379bc100SJani Nikula * DP/eDP/FDI use cases. 115379bc100SJani Nikula */ 116266152aeSVille Syrjälä void hsw_prepare_dp_ddi_buffers(struct intel_encoder *encoder, 117379bc100SJani Nikula const struct intel_crtc_state *crtc_state) 118379bc100SJani Nikula { 119379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 120379bc100SJani Nikula u32 iboost_bit = 0; 121379bc100SJani Nikula int i, n_entries; 122379bc100SJani Nikula enum port port = encoder->port; 123e505d764SVille Syrjälä const struct intel_ddi_buf_trans *trans; 124379bc100SJani Nikula 125e505d764SVille Syrjälä trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); 126e505d764SVille Syrjälä if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) 127d6b10b1aSVille Syrjälä return; 128379bc100SJani Nikula 129379bc100SJani Nikula /* If we're boosting the current, set bit 31 of trans1 */ 130f820693bSVille Syrjälä if (has_iboost(dev_priv) && 13102107ef1SVille Syrjälä intel_bios_dp_boost_level(encoder->devdata)) 132379bc100SJani Nikula iboost_bit = DDI_BUF_BALANCE_LEG_ENABLE; 133379bc100SJani Nikula 134379bc100SJani Nikula for (i = 0; i < n_entries; i++) { 135f7960e7fSJani Nikula intel_de_write(dev_priv, DDI_BUF_TRANS_LO(port, i), 136e505d764SVille Syrjälä trans->entries[i].hsw.trans1 | iboost_bit); 137f7960e7fSJani Nikula intel_de_write(dev_priv, DDI_BUF_TRANS_HI(port, i), 138e505d764SVille Syrjälä trans->entries[i].hsw.trans2); 139379bc100SJani Nikula } 140379bc100SJani Nikula } 141379bc100SJani Nikula 142379bc100SJani Nikula /* 143379bc100SJani Nikula * Starting with Haswell, DDI port buffers must be programmed with correct 144379bc100SJani Nikula * values in advance. This function programs the correct values for 145379bc100SJani Nikula * HDMI/DVI use cases. 146379bc100SJani Nikula */ 147266152aeSVille Syrjälä static void hsw_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder, 148e722ab8bSVille Syrjälä const struct intel_crtc_state *crtc_state) 149379bc100SJani Nikula { 150379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 151d0920a45SVille Syrjälä int level = intel_ddi_level(encoder, crtc_state, 0); 152379bc100SJani Nikula u32 iboost_bit = 0; 153379bc100SJani Nikula int n_entries; 154379bc100SJani Nikula enum port port = encoder->port; 155e505d764SVille Syrjälä const struct intel_ddi_buf_trans *trans; 156379bc100SJani Nikula 157e505d764SVille Syrjälä trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); 158e505d764SVille Syrjälä if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) 159379bc100SJani Nikula return; 160379bc100SJani Nikula 161379bc100SJani Nikula /* If we're boosting the current, set bit 31 of trans1 */ 162f820693bSVille Syrjälä if (has_iboost(dev_priv) && 16302107ef1SVille Syrjälä intel_bios_hdmi_boost_level(encoder->devdata)) 164379bc100SJani Nikula iboost_bit = DDI_BUF_BALANCE_LEG_ENABLE; 165379bc100SJani Nikula 166379bc100SJani Nikula /* Entry 9 is for HDMI: */ 167f7960e7fSJani Nikula intel_de_write(dev_priv, DDI_BUF_TRANS_LO(port, 9), 168e505d764SVille Syrjälä trans->entries[level].hsw.trans1 | iboost_bit); 169f7960e7fSJani Nikula intel_de_write(dev_priv, DDI_BUF_TRANS_HI(port, 9), 170e505d764SVille Syrjälä trans->entries[level].hsw.trans2); 171379bc100SJani Nikula } 172379bc100SJani Nikula 17323ef6194SJosé Roberto de Souza static void mtl_wait_ddi_buf_idle(struct drm_i915_private *i915, enum port port) 17423ef6194SJosé Roberto de Souza { 17523ef6194SJosé Roberto de Souza int ret; 17623ef6194SJosé Roberto de Souza 17723ef6194SJosé Roberto de Souza /* FIXME: find out why Bspec's 100us timeout is too short */ 17823ef6194SJosé Roberto de Souza ret = wait_for_us((intel_de_read(i915, XELPDP_PORT_BUF_CTL1(port)) & 17923ef6194SJosé Roberto de Souza XELPDP_PORT_BUF_PHY_IDLE), 10000); 18023ef6194SJosé Roberto de Souza if (ret) 18123ef6194SJosé Roberto de Souza drm_err(&i915->drm, "Timeout waiting for DDI BUF %c to get idle\n", 18223ef6194SJosé Roberto de Souza port_name(port)); 18323ef6194SJosé Roberto de Souza } 18423ef6194SJosé Roberto de Souza 185dcb38f79SDave Airlie void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv, 186379bc100SJani Nikula enum port port) 187379bc100SJani Nikula { 1885a2ad99bSManasi Navare if (IS_BROXTON(dev_priv)) { 1895a2ad99bSManasi Navare udelay(16); 190379bc100SJani Nikula return; 191379bc100SJani Nikula } 1925a2ad99bSManasi Navare 1935a2ad99bSManasi Navare if (wait_for_us((intel_de_read(dev_priv, DDI_BUF_CTL(port)) & 1945a2ad99bSManasi Navare DDI_BUF_IS_IDLE), 8)) 1955a2ad99bSManasi Navare drm_err(&dev_priv->drm, "Timeout waiting for DDI BUF %c to get idle\n", 19647bdb1caSJani Nikula port_name(port)); 197379bc100SJani Nikula } 198379bc100SJani Nikula 199e828da30SManasi Navare static void intel_wait_ddi_buf_active(struct drm_i915_private *dev_priv, 200e828da30SManasi Navare enum port port) 201e828da30SManasi Navare { 2025add4575SAnkit Nautiyal enum phy phy = intel_port_to_phy(dev_priv, port); 2035add4575SAnkit Nautiyal int timeout_us; 204f82f2563SMatt Roper int ret; 205f82f2563SMatt Roper 206e828da30SManasi Navare /* Wait > 518 usecs for DDI_BUF_CTL to be non idle */ 207ad314fecSVille Syrjälä if (DISPLAY_VER(dev_priv) < 10) { 208e828da30SManasi Navare usleep_range(518, 1000); 209e828da30SManasi Navare return; 210e828da30SManasi Navare } 211e828da30SManasi Navare 21223ef6194SJosé Roberto de Souza if (DISPLAY_VER(dev_priv) >= 14) { 21323ef6194SJosé Roberto de Souza timeout_us = 10000; 21423ef6194SJosé Roberto de Souza } else if (IS_DG2(dev_priv)) { 2155add4575SAnkit Nautiyal timeout_us = 1200; 2165add4575SAnkit Nautiyal } else if (DISPLAY_VER(dev_priv) >= 12) { 2175add4575SAnkit Nautiyal if (intel_phy_is_tc(dev_priv, phy)) 2185add4575SAnkit Nautiyal timeout_us = 3000; 2195add4575SAnkit Nautiyal else 2205add4575SAnkit Nautiyal timeout_us = 1000; 2215add4575SAnkit Nautiyal } else { 2225add4575SAnkit Nautiyal timeout_us = 500; 2235add4575SAnkit Nautiyal } 2245add4575SAnkit Nautiyal 22523ef6194SJosé Roberto de Souza if (DISPLAY_VER(dev_priv) >= 14) 22623ef6194SJosé Roberto de Souza ret = _wait_for(!(intel_de_read(dev_priv, XELPDP_PORT_BUF_CTL1(port)) & XELPDP_PORT_BUF_PHY_IDLE), 22723ef6194SJosé Roberto de Souza timeout_us, 10, 10); 22823ef6194SJosé Roberto de Souza else 22923ef6194SJosé Roberto de Souza ret = _wait_for(!(intel_de_read(dev_priv, DDI_BUF_CTL(port)) & DDI_BUF_IS_IDLE), 23023ef6194SJosé Roberto de Souza timeout_us, 10, 10); 231f82f2563SMatt Roper 232f82f2563SMatt Roper if (ret) 233e828da30SManasi Navare drm_err(&dev_priv->drm, "Timeout waiting for DDI BUF %c to get active\n", 234e828da30SManasi Navare port_name(port)); 235e828da30SManasi Navare } 236e828da30SManasi Navare 237ad952982SVille Syrjälä static u32 hsw_pll_to_ddi_pll_sel(const struct intel_shared_dpll *pll) 238379bc100SJani Nikula { 239379bc100SJani Nikula switch (pll->info->id) { 240379bc100SJani Nikula case DPLL_ID_WRPLL1: 241379bc100SJani Nikula return PORT_CLK_SEL_WRPLL1; 242379bc100SJani Nikula case DPLL_ID_WRPLL2: 243379bc100SJani Nikula return PORT_CLK_SEL_WRPLL2; 244379bc100SJani Nikula case DPLL_ID_SPLL: 245379bc100SJani Nikula return PORT_CLK_SEL_SPLL; 246379bc100SJani Nikula case DPLL_ID_LCPLL_810: 247379bc100SJani Nikula return PORT_CLK_SEL_LCPLL_810; 248379bc100SJani Nikula case DPLL_ID_LCPLL_1350: 249379bc100SJani Nikula return PORT_CLK_SEL_LCPLL_1350; 250379bc100SJani Nikula case DPLL_ID_LCPLL_2700: 251379bc100SJani Nikula return PORT_CLK_SEL_LCPLL_2700; 252379bc100SJani Nikula default: 253379bc100SJani Nikula MISSING_CASE(pll->info->id); 254379bc100SJani Nikula return PORT_CLK_SEL_NONE; 255379bc100SJani Nikula } 256379bc100SJani Nikula } 257379bc100SJani Nikula 258379bc100SJani Nikula static u32 icl_pll_to_ddi_clk_sel(struct intel_encoder *encoder, 259379bc100SJani Nikula const struct intel_crtc_state *crtc_state) 260379bc100SJani Nikula { 261379bc100SJani Nikula const struct intel_shared_dpll *pll = crtc_state->shared_dpll; 262379bc100SJani Nikula int clock = crtc_state->port_clock; 263379bc100SJani Nikula const enum intel_dpll_id id = pll->info->id; 264379bc100SJani Nikula 265379bc100SJani Nikula switch (id) { 266379bc100SJani Nikula default: 267379bc100SJani Nikula /* 268379bc100SJani Nikula * DPLL_ID_ICL_DPLL0 and DPLL_ID_ICL_DPLL1 should not be used 269379bc100SJani Nikula * here, so do warn if this get passed in 270379bc100SJani Nikula */ 271379bc100SJani Nikula MISSING_CASE(id); 272379bc100SJani Nikula return DDI_CLK_SEL_NONE; 273379bc100SJani Nikula case DPLL_ID_ICL_TBTPLL: 274379bc100SJani Nikula switch (clock) { 275379bc100SJani Nikula case 162000: 276379bc100SJani Nikula return DDI_CLK_SEL_TBT_162; 277379bc100SJani Nikula case 270000: 278379bc100SJani Nikula return DDI_CLK_SEL_TBT_270; 279379bc100SJani Nikula case 540000: 280379bc100SJani Nikula return DDI_CLK_SEL_TBT_540; 281379bc100SJani Nikula case 810000: 282379bc100SJani Nikula return DDI_CLK_SEL_TBT_810; 283379bc100SJani Nikula default: 284379bc100SJani Nikula MISSING_CASE(clock); 285379bc100SJani Nikula return DDI_CLK_SEL_NONE; 286379bc100SJani Nikula } 287379bc100SJani Nikula case DPLL_ID_ICL_MGPLL1: 288379bc100SJani Nikula case DPLL_ID_ICL_MGPLL2: 289379bc100SJani Nikula case DPLL_ID_ICL_MGPLL3: 290379bc100SJani Nikula case DPLL_ID_ICL_MGPLL4: 2916677c3b1SJosé Roberto de Souza case DPLL_ID_TGL_MGPLL5: 2926677c3b1SJosé Roberto de Souza case DPLL_ID_TGL_MGPLL6: 293379bc100SJani Nikula return DDI_CLK_SEL_MG; 294379bc100SJani Nikula } 295379bc100SJani Nikula } 296379bc100SJani Nikula 297414002f1SImre Deak static u32 ddi_buf_phy_link_rate(int port_clock) 298414002f1SImre Deak { 299414002f1SImre Deak switch (port_clock) { 300414002f1SImre Deak case 162000: 301414002f1SImre Deak return DDI_BUF_PHY_LINK_RATE(0); 302414002f1SImre Deak case 216000: 303414002f1SImre Deak return DDI_BUF_PHY_LINK_RATE(4); 304414002f1SImre Deak case 243000: 305414002f1SImre Deak return DDI_BUF_PHY_LINK_RATE(5); 306414002f1SImre Deak case 270000: 307414002f1SImre Deak return DDI_BUF_PHY_LINK_RATE(1); 308414002f1SImre Deak case 324000: 309414002f1SImre Deak return DDI_BUF_PHY_LINK_RATE(6); 310414002f1SImre Deak case 432000: 311414002f1SImre Deak return DDI_BUF_PHY_LINK_RATE(7); 312414002f1SImre Deak case 540000: 313414002f1SImre Deak return DDI_BUF_PHY_LINK_RATE(2); 314414002f1SImre Deak case 810000: 315414002f1SImre Deak return DDI_BUF_PHY_LINK_RATE(3); 316414002f1SImre Deak default: 317414002f1SImre Deak MISSING_CASE(port_clock); 318414002f1SImre Deak return DDI_BUF_PHY_LINK_RATE(0); 319414002f1SImre Deak } 320414002f1SImre Deak } 321414002f1SImre Deak 322a621860aSVille Syrjälä static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder, 323a621860aSVille Syrjälä const struct intel_crtc_state *crtc_state) 324379bc100SJani Nikula { 32555ce306cSJosé Roberto de Souza struct drm_i915_private *i915 = to_i915(encoder->base.dev); 326b7d02c3aSVille Syrjälä struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 3277801f3b7SLucas De Marchi struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 32855ce306cSJosé Roberto de Souza enum phy phy = intel_port_to_phy(i915, encoder->port); 329379bc100SJani Nikula 3309f620f1dSVille Syrjälä /* DDI_BUF_CTL_ENABLE will be set by intel_ddi_prepare_link_retrain() later */ 3317801f3b7SLucas De Marchi intel_dp->DP = dig_port->saved_port_bits | 3329f620f1dSVille Syrjälä DDI_PORT_WIDTH(crtc_state->lane_count) | 3339f620f1dSVille Syrjälä DDI_BUF_TRANS_SELECT(0); 33455ce306cSJosé Roberto de Souza 33523ef6194SJosé Roberto de Souza if (DISPLAY_VER(i915) >= 14) { 33623ef6194SJosé Roberto de Souza if (intel_dp_is_uhbr(crtc_state)) 33723ef6194SJosé Roberto de Souza intel_dp->DP |= DDI_BUF_PORT_DATA_40BIT; 33823ef6194SJosé Roberto de Souza else 33923ef6194SJosé Roberto de Souza intel_dp->DP |= DDI_BUF_PORT_DATA_10BIT; 34023ef6194SJosé Roberto de Souza } 34123ef6194SJosé Roberto de Souza 342414002f1SImre Deak if (IS_ALDERLAKE_P(i915) && intel_phy_is_tc(i915, phy)) { 343414002f1SImre Deak intel_dp->DP |= ddi_buf_phy_link_rate(crtc_state->port_clock); 34411a89708SImre Deak if (!intel_tc_port_in_tbt_alt_mode(dig_port)) 34555ce306cSJosé Roberto de Souza intel_dp->DP |= DDI_BUF_CTL_TC_PHY_OWNERSHIP; 346379bc100SJani Nikula } 347414002f1SImre Deak } 348379bc100SJani Nikula 349379bc100SJani Nikula static int icl_calc_tbt_pll_link(struct drm_i915_private *dev_priv, 350379bc100SJani Nikula enum port port) 351379bc100SJani Nikula { 352f7960e7fSJani Nikula u32 val = intel_de_read(dev_priv, DDI_CLK_SEL(port)) & DDI_CLK_SEL_MASK; 353379bc100SJani Nikula 354379bc100SJani Nikula switch (val) { 355379bc100SJani Nikula case DDI_CLK_SEL_NONE: 356379bc100SJani Nikula return 0; 357379bc100SJani Nikula case DDI_CLK_SEL_TBT_162: 358379bc100SJani Nikula return 162000; 359379bc100SJani Nikula case DDI_CLK_SEL_TBT_270: 360379bc100SJani Nikula return 270000; 361379bc100SJani Nikula case DDI_CLK_SEL_TBT_540: 362379bc100SJani Nikula return 540000; 363379bc100SJani Nikula case DDI_CLK_SEL_TBT_810: 364379bc100SJani Nikula return 810000; 365379bc100SJani Nikula default: 366379bc100SJani Nikula MISSING_CASE(val); 367379bc100SJani Nikula return 0; 368379bc100SJani Nikula } 369379bc100SJani Nikula } 370379bc100SJani Nikula 371623411c2SVille Syrjälä static void ddi_dotclock_get(struct intel_crtc_state *pipe_config) 372623411c2SVille Syrjälä { 373623411c2SVille Syrjälä /* CRT dotclock is determined via other means */ 374623411c2SVille Syrjälä if (pipe_config->has_pch_encoder) 375623411c2SVille Syrjälä return; 376623411c2SVille Syrjälä 377623411c2SVille Syrjälä pipe_config->hw.adjusted_mode.crtc_clock = 378623411c2SVille Syrjälä intel_crtc_dotclock(pipe_config); 379379bc100SJani Nikula } 380379bc100SJani Nikula 3810c06fa15SGwan-gyeong Mun void intel_ddi_set_dp_msa(const struct intel_crtc_state *crtc_state, 3820c06fa15SGwan-gyeong Mun const struct drm_connector_state *conn_state) 383379bc100SJani Nikula { 3842225f3c6SMaarten Lankhorst struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 385379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 386379bc100SJani Nikula enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; 387379bc100SJani Nikula u32 temp; 388379bc100SJani Nikula 389379bc100SJani Nikula if (!intel_crtc_has_dp_encoder(crtc_state)) 390379bc100SJani Nikula return; 391379bc100SJani Nikula 3921de143ccSPankaj Bharadiya drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder)); 393379bc100SJani Nikula 3943e706dffSVille Syrjälä temp = DP_MSA_MISC_SYNC_CLOCK; 395379bc100SJani Nikula 396379bc100SJani Nikula switch (crtc_state->pipe_bpp) { 397379bc100SJani Nikula case 18: 3983e706dffSVille Syrjälä temp |= DP_MSA_MISC_6_BPC; 399379bc100SJani Nikula break; 400379bc100SJani Nikula case 24: 4013e706dffSVille Syrjälä temp |= DP_MSA_MISC_8_BPC; 402379bc100SJani Nikula break; 403379bc100SJani Nikula case 30: 4043e706dffSVille Syrjälä temp |= DP_MSA_MISC_10_BPC; 405379bc100SJani Nikula break; 406379bc100SJani Nikula case 36: 4073e706dffSVille Syrjälä temp |= DP_MSA_MISC_12_BPC; 408379bc100SJani Nikula break; 409379bc100SJani Nikula default: 410379bc100SJani Nikula MISSING_CASE(crtc_state->pipe_bpp); 411379bc100SJani Nikula break; 412379bc100SJani Nikula } 413379bc100SJani Nikula 414cae154fcSVille Syrjälä /* nonsense combination */ 4151de143ccSPankaj Bharadiya drm_WARN_ON(&dev_priv->drm, crtc_state->limited_color_range && 416cae154fcSVille Syrjälä crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB); 417cae154fcSVille Syrjälä 418cae154fcSVille Syrjälä if (crtc_state->limited_color_range) 4193e706dffSVille Syrjälä temp |= DP_MSA_MISC_COLOR_CEA_RGB; 420cae154fcSVille Syrjälä 421379bc100SJani Nikula /* 422379bc100SJani Nikula * As per DP 1.2 spec section 2.3.4.3 while sending 423379bc100SJani Nikula * YCBCR 444 signals we should program MSA MISC1/0 fields with 424646d3dc8SVille Syrjälä * colorspace information. 425379bc100SJani Nikula */ 426379bc100SJani Nikula if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR444) 4273e706dffSVille Syrjälä temp |= DP_MSA_MISC_COLOR_YCBCR_444_BT709; 428646d3dc8SVille Syrjälä 429379bc100SJani Nikula /* 430379bc100SJani Nikula * As per DP 1.4a spec section 2.2.4.3 [MSA Field for Indication 431379bc100SJani Nikula * of Color Encoding Format and Content Color Gamut] while sending 4320c06fa15SGwan-gyeong Mun * YCBCR 420, HDR BT.2020 signals we should program MSA MISC1 fields 4330c06fa15SGwan-gyeong Mun * which indicate VSC SDP for the Pixel Encoding/Colorimetry Format. 434379bc100SJani Nikula */ 435bd8c9ccaSGwan-gyeong Mun if (intel_dp_needs_vsc_sdp(crtc_state, conn_state)) 4363e706dffSVille Syrjälä temp |= DP_MSA_MISC_COLOR_VSC_SDP; 4370c06fa15SGwan-gyeong Mun 438f7960e7fSJani Nikula intel_de_write(dev_priv, TRANS_MSA_MISC(cpu_transcoder), temp); 439379bc100SJani Nikula } 440379bc100SJani Nikula 441dc5b8ed5SVille Syrjälä static u32 bdw_trans_port_sync_master_select(enum transcoder master_transcoder) 442dc5b8ed5SVille Syrjälä { 443dc5b8ed5SVille Syrjälä if (master_transcoder == TRANSCODER_EDP) 444dc5b8ed5SVille Syrjälä return 0; 445dc5b8ed5SVille Syrjälä else 446dc5b8ed5SVille Syrjälä return master_transcoder + 1; 447dc5b8ed5SVille Syrjälä } 448dc5b8ed5SVille Syrjälä 44979ac2b1bSJani Nikula static void 45079ac2b1bSJani Nikula intel_ddi_config_transcoder_dp2(struct intel_encoder *encoder, 45179ac2b1bSJani Nikula const struct intel_crtc_state *crtc_state) 45279ac2b1bSJani Nikula { 45379ac2b1bSJani Nikula struct drm_i915_private *i915 = to_i915(encoder->base.dev); 45479ac2b1bSJani Nikula enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; 45579ac2b1bSJani Nikula u32 val = 0; 45679ac2b1bSJani Nikula 45779ac2b1bSJani Nikula if (intel_dp_is_uhbr(crtc_state)) 45879ac2b1bSJani Nikula val = TRANS_DP2_128B132B_CHANNEL_CODING; 45979ac2b1bSJani Nikula 46079ac2b1bSJani Nikula intel_de_write(i915, TRANS_DP2_CTL(cpu_transcoder), val); 46179ac2b1bSJani Nikula } 46279ac2b1bSJani Nikula 46399389390SJosé Roberto de Souza /* 46499389390SJosé Roberto de Souza * Returns the TRANS_DDI_FUNC_CTL value based on CRTC state. 46599389390SJosé Roberto de Souza * 46699389390SJosé Roberto de Souza * Only intended to be used by intel_ddi_enable_transcoder_func() and 46799389390SJosé Roberto de Souza * intel_ddi_config_transcoder_func(). 46899389390SJosé Roberto de Souza */ 46999389390SJosé Roberto de Souza static u32 470eed22a46SVille Syrjälä intel_ddi_transcoder_func_reg_val_get(struct intel_encoder *encoder, 471eed22a46SVille Syrjälä const struct intel_crtc_state *crtc_state) 472379bc100SJani Nikula { 4732225f3c6SMaarten Lankhorst struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 474379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 475379bc100SJani Nikula enum pipe pipe = crtc->pipe; 476379bc100SJani Nikula enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; 477379bc100SJani Nikula enum port port = encoder->port; 478379bc100SJani Nikula u32 temp; 479379bc100SJani Nikula 480379bc100SJani Nikula /* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */ 481379bc100SJani Nikula temp = TRANS_DDI_FUNC_ENABLE; 482005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 12) 483df16b636SMahesh Kumar temp |= TGL_TRANS_DDI_SELECT_PORT(port); 484df16b636SMahesh Kumar else 485379bc100SJani Nikula temp |= TRANS_DDI_SELECT_PORT(port); 486379bc100SJani Nikula 487379bc100SJani Nikula switch (crtc_state->pipe_bpp) { 48804514c14SJani Nikula default: 48904514c14SJani Nikula MISSING_CASE(crtc_state->pipe_bpp); 49004514c14SJani Nikula fallthrough; 491379bc100SJani Nikula case 18: 492379bc100SJani Nikula temp |= TRANS_DDI_BPC_6; 493379bc100SJani Nikula break; 494379bc100SJani Nikula case 24: 495379bc100SJani Nikula temp |= TRANS_DDI_BPC_8; 496379bc100SJani Nikula break; 497379bc100SJani Nikula case 30: 498379bc100SJani Nikula temp |= TRANS_DDI_BPC_10; 499379bc100SJani Nikula break; 500379bc100SJani Nikula case 36: 501379bc100SJani Nikula temp |= TRANS_DDI_BPC_12; 502379bc100SJani Nikula break; 503379bc100SJani Nikula } 504379bc100SJani Nikula 5051326a92cSMaarten Lankhorst if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC) 506379bc100SJani Nikula temp |= TRANS_DDI_PVSYNC; 5071326a92cSMaarten Lankhorst if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC) 508379bc100SJani Nikula temp |= TRANS_DDI_PHSYNC; 509379bc100SJani Nikula 510379bc100SJani Nikula if (cpu_transcoder == TRANSCODER_EDP) { 511379bc100SJani Nikula switch (pipe) { 51204514c14SJani Nikula default: 51304514c14SJani Nikula MISSING_CASE(pipe); 51404514c14SJani Nikula fallthrough; 515379bc100SJani Nikula case PIPE_A: 516379bc100SJani Nikula /* On Haswell, can only use the always-on power well for 517379bc100SJani Nikula * eDP when not using the panel fitter, and when not 518379bc100SJani Nikula * using motion blur mitigation (which we don't 519379bc100SJani Nikula * support). */ 520379bc100SJani Nikula if (crtc_state->pch_pfit.force_thru) 521379bc100SJani Nikula temp |= TRANS_DDI_EDP_INPUT_A_ONOFF; 522379bc100SJani Nikula else 523379bc100SJani Nikula temp |= TRANS_DDI_EDP_INPUT_A_ON; 524379bc100SJani Nikula break; 525379bc100SJani Nikula case PIPE_B: 526379bc100SJani Nikula temp |= TRANS_DDI_EDP_INPUT_B_ONOFF; 527379bc100SJani Nikula break; 528379bc100SJani Nikula case PIPE_C: 529379bc100SJani Nikula temp |= TRANS_DDI_EDP_INPUT_C_ONOFF; 530379bc100SJani Nikula break; 531379bc100SJani Nikula } 532379bc100SJani Nikula } 533379bc100SJani Nikula 534379bc100SJani Nikula if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { 535379bc100SJani Nikula if (crtc_state->has_hdmi_sink) 536379bc100SJani Nikula temp |= TRANS_DDI_MODE_SELECT_HDMI; 537379bc100SJani Nikula else 538379bc100SJani Nikula temp |= TRANS_DDI_MODE_SELECT_DVI; 539379bc100SJani Nikula 540379bc100SJani Nikula if (crtc_state->hdmi_scrambling) 541379bc100SJani Nikula temp |= TRANS_DDI_HDMI_SCRAMBLING; 542379bc100SJani Nikula if (crtc_state->hdmi_high_tmds_clock_ratio) 543379bc100SJani Nikula temp |= TRANS_DDI_HIGH_TMDS_CHAR_RATE; 544b66a8abaSAnkit Nautiyal if (DISPLAY_VER(dev_priv) >= 14) 545b66a8abaSAnkit Nautiyal temp |= TRANS_DDI_PORT_WIDTH(crtc_state->lane_count); 546379bc100SJani Nikula } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG)) { 5477bb97db8SJani Nikula temp |= TRANS_DDI_MODE_SELECT_FDI_OR_128B132B; 548379bc100SJani Nikula temp |= (crtc_state->fdi_lanes - 1) << 1; 549379bc100SJani Nikula } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) { 55065213594SJani Nikula if (intel_dp_is_uhbr(crtc_state)) 55165213594SJani Nikula temp |= TRANS_DDI_MODE_SELECT_FDI_OR_128B132B; 55265213594SJani Nikula else 553379bc100SJani Nikula temp |= TRANS_DDI_MODE_SELECT_DP_MST; 554379bc100SJani Nikula temp |= DDI_PORT_WIDTH(crtc_state->lane_count); 555b3545e08SLucas De Marchi 556005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 12) { 5576671c367SJosé Roberto de Souza enum transcoder master; 5586671c367SJosé Roberto de Souza 5596671c367SJosé Roberto de Souza master = crtc_state->mst_master_transcoder; 5601de143ccSPankaj Bharadiya drm_WARN_ON(&dev_priv->drm, 5611de143ccSPankaj Bharadiya master == INVALID_TRANSCODER); 5626671c367SJosé Roberto de Souza temp |= TRANS_DDI_MST_TRANSPORT_SELECT(master); 5636671c367SJosé Roberto de Souza } 564379bc100SJani Nikula } else { 565379bc100SJani Nikula temp |= TRANS_DDI_MODE_SELECT_DP_SST; 566379bc100SJani Nikula temp |= DDI_PORT_WIDTH(crtc_state->lane_count); 567379bc100SJani Nikula } 568379bc100SJani Nikula 56993e7e61eSLucas De Marchi if (IS_DISPLAY_VER(dev_priv, 8, 10) && 570dc5b8ed5SVille Syrjälä crtc_state->master_transcoder != INVALID_TRANSCODER) { 571dc5b8ed5SVille Syrjälä u8 master_select = 572dc5b8ed5SVille Syrjälä bdw_trans_port_sync_master_select(crtc_state->master_transcoder); 573dc5b8ed5SVille Syrjälä 574dc5b8ed5SVille Syrjälä temp |= TRANS_DDI_PORT_SYNC_ENABLE | 575dc5b8ed5SVille Syrjälä TRANS_DDI_PORT_SYNC_MASTER_SELECT(master_select); 576dc5b8ed5SVille Syrjälä } 577dc5b8ed5SVille Syrjälä 57899389390SJosé Roberto de Souza return temp; 57999389390SJosé Roberto de Souza } 58099389390SJosé Roberto de Souza 581eed22a46SVille Syrjälä void intel_ddi_enable_transcoder_func(struct intel_encoder *encoder, 582eed22a46SVille Syrjälä const struct intel_crtc_state *crtc_state) 58399389390SJosé Roberto de Souza { 5842225f3c6SMaarten Lankhorst struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 58599389390SJosé Roberto de Souza struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 58699389390SJosé Roberto de Souza enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; 58799389390SJosé Roberto de Souza 588005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 11) { 589589a4cd6SVille Syrjälä enum transcoder master_transcoder = crtc_state->master_transcoder; 590589a4cd6SVille Syrjälä u32 ctl2 = 0; 591589a4cd6SVille Syrjälä 592589a4cd6SVille Syrjälä if (master_transcoder != INVALID_TRANSCODER) { 593dc5b8ed5SVille Syrjälä u8 master_select = 594dc5b8ed5SVille Syrjälä bdw_trans_port_sync_master_select(master_transcoder); 595589a4cd6SVille Syrjälä 596589a4cd6SVille Syrjälä ctl2 |= PORT_SYNC_MODE_ENABLE | 597d4d7d9caSVille Syrjälä PORT_SYNC_MODE_MASTER_SELECT(master_select); 598589a4cd6SVille Syrjälä } 599589a4cd6SVille Syrjälä 600589a4cd6SVille Syrjälä intel_de_write(dev_priv, 601589a4cd6SVille Syrjälä TRANS_DDI_FUNC_CTL2(cpu_transcoder), ctl2); 602589a4cd6SVille Syrjälä } 603589a4cd6SVille Syrjälä 604580fbdc5SImre Deak intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder), 605580fbdc5SImre Deak intel_ddi_transcoder_func_reg_val_get(encoder, 606580fbdc5SImre Deak crtc_state)); 60799389390SJosé Roberto de Souza } 60899389390SJosé Roberto de Souza 60999389390SJosé Roberto de Souza /* 61099389390SJosé Roberto de Souza * Same as intel_ddi_enable_transcoder_func(), but it does not set the enable 61199389390SJosé Roberto de Souza * bit. 61299389390SJosé Roberto de Souza */ 61399389390SJosé Roberto de Souza static void 614eed22a46SVille Syrjälä intel_ddi_config_transcoder_func(struct intel_encoder *encoder, 615eed22a46SVille Syrjälä const struct intel_crtc_state *crtc_state) 61699389390SJosé Roberto de Souza { 6172225f3c6SMaarten Lankhorst struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 61899389390SJosé Roberto de Souza struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 61999389390SJosé Roberto de Souza enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; 620589a4cd6SVille Syrjälä u32 ctl; 62199389390SJosé Roberto de Souza 622eed22a46SVille Syrjälä ctl = intel_ddi_transcoder_func_reg_val_get(encoder, crtc_state); 623589a4cd6SVille Syrjälä ctl &= ~TRANS_DDI_FUNC_ENABLE; 624589a4cd6SVille Syrjälä intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder), ctl); 625379bc100SJani Nikula } 626379bc100SJani Nikula 627379bc100SJani Nikula void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state) 628379bc100SJani Nikula { 6292225f3c6SMaarten Lankhorst struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 630379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 631379bc100SJani Nikula enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; 632589a4cd6SVille Syrjälä u32 ctl; 633c59053dcSJosé Roberto de Souza 634005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 11) 635589a4cd6SVille Syrjälä intel_de_write(dev_priv, 636589a4cd6SVille Syrjälä TRANS_DDI_FUNC_CTL2(cpu_transcoder), 0); 637589a4cd6SVille Syrjälä 638589a4cd6SVille Syrjälä ctl = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder)); 639dc5b8ed5SVille Syrjälä 6401cfcdbf3SSean Paul drm_WARN_ON(crtc->base.dev, ctl & TRANS_DDI_HDCP_SIGNALLING); 6411cfcdbf3SSean Paul 642589a4cd6SVille Syrjälä ctl &= ~TRANS_DDI_FUNC_ENABLE; 643379bc100SJani Nikula 64493e7e61eSLucas De Marchi if (IS_DISPLAY_VER(dev_priv, 8, 10)) 645dc5b8ed5SVille Syrjälä ctl &= ~(TRANS_DDI_PORT_SYNC_ENABLE | 646dc5b8ed5SVille Syrjälä TRANS_DDI_PORT_SYNC_MASTER_SELECT_MASK); 647dc5b8ed5SVille Syrjälä 648005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 12) { 649919e4f07SJosé Roberto de Souza if (!intel_dp_mst_is_master_trans(crtc_state)) { 650589a4cd6SVille Syrjälä ctl &= ~(TGL_TRANS_DDI_PORT_MASK | 651919e4f07SJosé Roberto de Souza TRANS_DDI_MODE_SELECT_MASK); 652919e4f07SJosé Roberto de Souza } 653df16b636SMahesh Kumar } else { 654589a4cd6SVille Syrjälä ctl &= ~(TRANS_DDI_PORT_MASK | TRANS_DDI_MODE_SELECT_MASK); 655df16b636SMahesh Kumar } 656dc5b8ed5SVille Syrjälä 657589a4cd6SVille Syrjälä intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder), ctl); 658379bc100SJani Nikula 6590c82118bSJani Nikula if (intel_has_quirk(dev_priv, QUIRK_INCREASE_DDI_DISABLED_TIME) && 660379bc100SJani Nikula intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { 66147bdb1caSJani Nikula drm_dbg_kms(&dev_priv->drm, 66247bdb1caSJani Nikula "Quirk Increase DDI disabled time\n"); 663379bc100SJani Nikula /* Quirk time at 100ms for reliable operation */ 664379bc100SJani Nikula msleep(100); 665379bc100SJani Nikula } 666379bc100SJani Nikula } 667379bc100SJani Nikula 6681a67a168SAnshuman Gupta int intel_ddi_toggle_hdcp_bits(struct intel_encoder *intel_encoder, 6690b9c9290SSean Paul enum transcoder cpu_transcoder, 6701a67a168SAnshuman Gupta bool enable, u32 hdcp_mask) 671379bc100SJani Nikula { 672379bc100SJani Nikula struct drm_device *dev = intel_encoder->base.dev; 673379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(dev); 674379bc100SJani Nikula intel_wakeref_t wakeref; 675379bc100SJani Nikula int ret = 0; 676379bc100SJani Nikula 677379bc100SJani Nikula wakeref = intel_display_power_get_if_enabled(dev_priv, 678379bc100SJani Nikula intel_encoder->power_domain); 6791de143ccSPankaj Bharadiya if (drm_WARN_ON(dev, !wakeref)) 680379bc100SJani Nikula return -ENXIO; 681379bc100SJani Nikula 6828910d8b7SAndrzej Hajda intel_de_rmw(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder), 6838910d8b7SAndrzej Hajda hdcp_mask, enable ? hdcp_mask : 0); 684379bc100SJani Nikula intel_display_power_put(dev_priv, intel_encoder->power_domain, wakeref); 685379bc100SJani Nikula return ret; 686379bc100SJani Nikula } 687379bc100SJani Nikula 688379bc100SJani Nikula bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector) 689379bc100SJani Nikula { 690379bc100SJani Nikula struct drm_device *dev = intel_connector->base.dev; 691379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(dev); 692fa7edcd2SVille Syrjälä struct intel_encoder *encoder = intel_attached_encoder(intel_connector); 693379bc100SJani Nikula int type = intel_connector->base.connector_type; 694379bc100SJani Nikula enum port port = encoder->port; 695379bc100SJani Nikula enum transcoder cpu_transcoder; 696379bc100SJani Nikula intel_wakeref_t wakeref; 697379bc100SJani Nikula enum pipe pipe = 0; 698379bc100SJani Nikula u32 tmp; 699379bc100SJani Nikula bool ret; 700379bc100SJani Nikula 701379bc100SJani Nikula wakeref = intel_display_power_get_if_enabled(dev_priv, 702379bc100SJani Nikula encoder->power_domain); 703379bc100SJani Nikula if (!wakeref) 704379bc100SJani Nikula return false; 705379bc100SJani Nikula 706379bc100SJani Nikula if (!encoder->get_hw_state(encoder, &pipe)) { 707379bc100SJani Nikula ret = false; 708379bc100SJani Nikula goto out; 709379bc100SJani Nikula } 710379bc100SJani Nikula 71110cf8e75SVille Syrjälä if (HAS_TRANSCODER(dev_priv, TRANSCODER_EDP) && port == PORT_A) 712379bc100SJani Nikula cpu_transcoder = TRANSCODER_EDP; 713379bc100SJani Nikula else 714379bc100SJani Nikula cpu_transcoder = (enum transcoder) pipe; 715379bc100SJani Nikula 716f7960e7fSJani Nikula tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder)); 717379bc100SJani Nikula 718379bc100SJani Nikula switch (tmp & TRANS_DDI_MODE_SELECT_MASK) { 719379bc100SJani Nikula case TRANS_DDI_MODE_SELECT_HDMI: 720379bc100SJani Nikula case TRANS_DDI_MODE_SELECT_DVI: 721379bc100SJani Nikula ret = type == DRM_MODE_CONNECTOR_HDMIA; 722379bc100SJani Nikula break; 723379bc100SJani Nikula 724379bc100SJani Nikula case TRANS_DDI_MODE_SELECT_DP_SST: 725379bc100SJani Nikula ret = type == DRM_MODE_CONNECTOR_eDP || 726379bc100SJani Nikula type == DRM_MODE_CONNECTOR_DisplayPort; 727379bc100SJani Nikula break; 728379bc100SJani Nikula 729379bc100SJani Nikula case TRANS_DDI_MODE_SELECT_DP_MST: 730379bc100SJani Nikula /* if the transcoder is in MST state then 731379bc100SJani Nikula * connector isn't connected */ 732379bc100SJani Nikula ret = false; 733379bc100SJani Nikula break; 734379bc100SJani Nikula 7357bb97db8SJani Nikula case TRANS_DDI_MODE_SELECT_FDI_OR_128B132B: 73665213594SJani Nikula if (HAS_DP20(dev_priv)) 73765213594SJani Nikula /* 128b/132b */ 73865213594SJani Nikula ret = false; 73965213594SJani Nikula else 74065213594SJani Nikula /* FDI */ 741379bc100SJani Nikula ret = type == DRM_MODE_CONNECTOR_VGA; 742379bc100SJani Nikula break; 743379bc100SJani Nikula 744379bc100SJani Nikula default: 745379bc100SJani Nikula ret = false; 746379bc100SJani Nikula break; 747379bc100SJani Nikula } 748379bc100SJani Nikula 749379bc100SJani Nikula out: 750379bc100SJani Nikula intel_display_power_put(dev_priv, encoder->power_domain, wakeref); 751379bc100SJani Nikula 752379bc100SJani Nikula return ret; 753379bc100SJani Nikula } 754379bc100SJani Nikula 755379bc100SJani Nikula static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, 756379bc100SJani Nikula u8 *pipe_mask, bool *is_dp_mst) 757379bc100SJani Nikula { 758379bc100SJani Nikula struct drm_device *dev = encoder->base.dev; 759379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(dev); 760379bc100SJani Nikula enum port port = encoder->port; 761379bc100SJani Nikula intel_wakeref_t wakeref; 762379bc100SJani Nikula enum pipe p; 763379bc100SJani Nikula u32 tmp; 764379bc100SJani Nikula u8 mst_pipe_mask; 765379bc100SJani Nikula 766379bc100SJani Nikula *pipe_mask = 0; 767379bc100SJani Nikula *is_dp_mst = false; 768379bc100SJani Nikula 769379bc100SJani Nikula wakeref = intel_display_power_get_if_enabled(dev_priv, 770379bc100SJani Nikula encoder->power_domain); 771379bc100SJani Nikula if (!wakeref) 772379bc100SJani Nikula return; 773379bc100SJani Nikula 774f7960e7fSJani Nikula tmp = intel_de_read(dev_priv, DDI_BUF_CTL(port)); 775379bc100SJani Nikula if (!(tmp & DDI_BUF_CTL_ENABLE)) 776379bc100SJani Nikula goto out; 777379bc100SJani Nikula 77810cf8e75SVille Syrjälä if (HAS_TRANSCODER(dev_priv, TRANSCODER_EDP) && port == PORT_A) { 779f7960e7fSJani Nikula tmp = intel_de_read(dev_priv, 780f7960e7fSJani Nikula TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)); 781379bc100SJani Nikula 782379bc100SJani Nikula switch (tmp & TRANS_DDI_EDP_INPUT_MASK) { 783379bc100SJani Nikula default: 784379bc100SJani Nikula MISSING_CASE(tmp & TRANS_DDI_EDP_INPUT_MASK); 785df561f66SGustavo A. R. Silva fallthrough; 786379bc100SJani Nikula case TRANS_DDI_EDP_INPUT_A_ON: 787379bc100SJani Nikula case TRANS_DDI_EDP_INPUT_A_ONOFF: 788379bc100SJani Nikula *pipe_mask = BIT(PIPE_A); 789379bc100SJani Nikula break; 790379bc100SJani Nikula case TRANS_DDI_EDP_INPUT_B_ONOFF: 791379bc100SJani Nikula *pipe_mask = BIT(PIPE_B); 792379bc100SJani Nikula break; 793379bc100SJani Nikula case TRANS_DDI_EDP_INPUT_C_ONOFF: 794379bc100SJani Nikula *pipe_mask = BIT(PIPE_C); 795379bc100SJani Nikula break; 796379bc100SJani Nikula } 797379bc100SJani Nikula 798379bc100SJani Nikula goto out; 799379bc100SJani Nikula } 800379bc100SJani Nikula 801379bc100SJani Nikula mst_pipe_mask = 0; 802379bc100SJani Nikula for_each_pipe(dev_priv, p) { 803379bc100SJani Nikula enum transcoder cpu_transcoder = (enum transcoder)p; 804df16b636SMahesh Kumar unsigned int port_mask, ddi_select; 8056aa3bef1SJosé Roberto de Souza intel_wakeref_t trans_wakeref; 8066aa3bef1SJosé Roberto de Souza 8076aa3bef1SJosé Roberto de Souza trans_wakeref = intel_display_power_get_if_enabled(dev_priv, 8086aa3bef1SJosé Roberto de Souza POWER_DOMAIN_TRANSCODER(cpu_transcoder)); 8096aa3bef1SJosé Roberto de Souza if (!trans_wakeref) 8106aa3bef1SJosé Roberto de Souza continue; 811df16b636SMahesh Kumar 812005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 12) { 813df16b636SMahesh Kumar port_mask = TGL_TRANS_DDI_PORT_MASK; 814df16b636SMahesh Kumar ddi_select = TGL_TRANS_DDI_SELECT_PORT(port); 815df16b636SMahesh Kumar } else { 816df16b636SMahesh Kumar port_mask = TRANS_DDI_PORT_MASK; 817df16b636SMahesh Kumar ddi_select = TRANS_DDI_SELECT_PORT(port); 818df16b636SMahesh Kumar } 819379bc100SJani Nikula 820f7960e7fSJani Nikula tmp = intel_de_read(dev_priv, 821f7960e7fSJani Nikula TRANS_DDI_FUNC_CTL(cpu_transcoder)); 8226aa3bef1SJosé Roberto de Souza intel_display_power_put(dev_priv, POWER_DOMAIN_TRANSCODER(cpu_transcoder), 8236aa3bef1SJosé Roberto de Souza trans_wakeref); 824379bc100SJani Nikula 825df16b636SMahesh Kumar if ((tmp & port_mask) != ddi_select) 826379bc100SJani Nikula continue; 827379bc100SJani Nikula 82865213594SJani Nikula if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST || 82965213594SJani Nikula (HAS_DP20(dev_priv) && 83065213594SJani Nikula (tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_FDI_OR_128B132B)) 831379bc100SJani Nikula mst_pipe_mask |= BIT(p); 832379bc100SJani Nikula 833379bc100SJani Nikula *pipe_mask |= BIT(p); 834379bc100SJani Nikula } 835379bc100SJani Nikula 836379bc100SJani Nikula if (!*pipe_mask) 83747bdb1caSJani Nikula drm_dbg_kms(&dev_priv->drm, 83847bdb1caSJani Nikula "No pipe for [ENCODER:%d:%s] found\n", 83966a990ddSVille Syrjälä encoder->base.base.id, encoder->base.name); 840379bc100SJani Nikula 841379bc100SJani Nikula if (!mst_pipe_mask && hweight8(*pipe_mask) > 1) { 84247bdb1caSJani Nikula drm_dbg_kms(&dev_priv->drm, 84347bdb1caSJani Nikula "Multiple pipes for [ENCODER:%d:%s] (pipe_mask %02x)\n", 84466a990ddSVille Syrjälä encoder->base.base.id, encoder->base.name, 84566a990ddSVille Syrjälä *pipe_mask); 846379bc100SJani Nikula *pipe_mask = BIT(ffs(*pipe_mask) - 1); 847379bc100SJani Nikula } 848379bc100SJani Nikula 849379bc100SJani Nikula if (mst_pipe_mask && mst_pipe_mask != *pipe_mask) 85047bdb1caSJani Nikula drm_dbg_kms(&dev_priv->drm, 85147bdb1caSJani Nikula "Conflicting MST and non-MST state for [ENCODER:%d:%s] (pipe_mask %02x mst_pipe_mask %02x)\n", 85266a990ddSVille Syrjälä encoder->base.base.id, encoder->base.name, 85366a990ddSVille Syrjälä *pipe_mask, mst_pipe_mask); 854379bc100SJani Nikula else 855379bc100SJani Nikula *is_dp_mst = mst_pipe_mask; 856379bc100SJani Nikula 857379bc100SJani Nikula out: 8582446e1d6SMatt Roper if (*pipe_mask && (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))) { 859f7960e7fSJani Nikula tmp = intel_de_read(dev_priv, BXT_PHY_CTL(port)); 860379bc100SJani Nikula if ((tmp & (BXT_PHY_CMNLANE_POWERDOWN_ACK | 861379bc100SJani Nikula BXT_PHY_LANE_POWERDOWN_ACK | 862379bc100SJani Nikula BXT_PHY_LANE_ENABLED)) != BXT_PHY_LANE_ENABLED) 86347bdb1caSJani Nikula drm_err(&dev_priv->drm, 86447bdb1caSJani Nikula "[ENCODER:%d:%s] enabled but PHY powered down? (PHY_CTL %08x)\n", 86547bdb1caSJani Nikula encoder->base.base.id, encoder->base.name, tmp); 866379bc100SJani Nikula } 867379bc100SJani Nikula 868379bc100SJani Nikula intel_display_power_put(dev_priv, encoder->power_domain, wakeref); 869379bc100SJani Nikula } 870379bc100SJani Nikula 871379bc100SJani Nikula bool intel_ddi_get_hw_state(struct intel_encoder *encoder, 872379bc100SJani Nikula enum pipe *pipe) 873379bc100SJani Nikula { 874379bc100SJani Nikula u8 pipe_mask; 875379bc100SJani Nikula bool is_mst; 876379bc100SJani Nikula 877379bc100SJani Nikula intel_ddi_get_encoder_pipes(encoder, &pipe_mask, &is_mst); 878379bc100SJani Nikula 879379bc100SJani Nikula if (is_mst || !pipe_mask) 880379bc100SJani Nikula return false; 881379bc100SJani Nikula 882379bc100SJani Nikula *pipe = ffs(pipe_mask) - 1; 883379bc100SJani Nikula 884379bc100SJani Nikula return true; 885379bc100SJani Nikula } 886379bc100SJani Nikula 88781b55ef1SJani Nikula static enum intel_display_power_domain 888637c7aa2SImre Deak intel_ddi_main_link_aux_domain(struct intel_digital_port *dig_port, 889637c7aa2SImre Deak const struct intel_crtc_state *crtc_state) 890379bc100SJani Nikula { 891f645cbdaSImre Deak struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 892637c7aa2SImre Deak enum phy phy = intel_port_to_phy(i915, dig_port->base.port); 893f645cbdaSImre Deak 894637c7aa2SImre Deak /* 895637c7aa2SImre Deak * ICL+ HW requires corresponding AUX IOs to be powered up for PSR with 896379bc100SJani Nikula * DC states enabled at the same time, while for driver initiated AUX 897379bc100SJani Nikula * transfers we need the same AUX IOs to be powered but with DC states 898637c7aa2SImre Deak * disabled. Accordingly use the AUX_IO_<port> power domain here which 899637c7aa2SImre Deak * leaves DC states enabled. 900637c7aa2SImre Deak * 901637c7aa2SImre Deak * Before MTL TypeC PHYs (in all TypeC modes and both DP/HDMI) also require 902637c7aa2SImre Deak * AUX IO to be enabled, but all these require DC_OFF to be enabled as 903637c7aa2SImre Deak * well, so we can acquire a wider AUX_<port> power domain reference 904637c7aa2SImre Deak * instead of a specific AUX_IO_<port> reference without powering up any 905637c7aa2SImre Deak * extra wells. 906379bc100SJani Nikula */ 907f645cbdaSImre Deak if (intel_encoder_can_psr(&dig_port->base)) 908f645cbdaSImre Deak return intel_display_power_aux_io_domain(i915, dig_port->aux_ch); 9091acefacaSImre Deak else if (DISPLAY_VER(i915) < 14 && 9101acefacaSImre Deak (intel_crtc_has_dp_encoder(crtc_state) || 9111acefacaSImre Deak intel_phy_is_tc(i915, phy))) 912b2e00dd3SImre Deak return intel_aux_power_domain(dig_port); 913637c7aa2SImre Deak else 914637c7aa2SImre Deak return POWER_DOMAIN_INVALID; 915637c7aa2SImre Deak } 916637c7aa2SImre Deak 917637c7aa2SImre Deak static void 918637c7aa2SImre Deak main_link_aux_power_domain_get(struct intel_digital_port *dig_port, 919637c7aa2SImre Deak const struct intel_crtc_state *crtc_state) 920637c7aa2SImre Deak { 921637c7aa2SImre Deak struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 922637c7aa2SImre Deak enum intel_display_power_domain domain = 923637c7aa2SImre Deak intel_ddi_main_link_aux_domain(dig_port, crtc_state); 924637c7aa2SImre Deak 925637c7aa2SImre Deak drm_WARN_ON(&i915->drm, dig_port->aux_wakeref); 926637c7aa2SImre Deak 927637c7aa2SImre Deak if (domain == POWER_DOMAIN_INVALID) 928637c7aa2SImre Deak return; 929637c7aa2SImre Deak 930637c7aa2SImre Deak dig_port->aux_wakeref = intel_display_power_get(i915, domain); 931637c7aa2SImre Deak } 932637c7aa2SImre Deak 933637c7aa2SImre Deak static void 934637c7aa2SImre Deak main_link_aux_power_domain_put(struct intel_digital_port *dig_port, 935637c7aa2SImre Deak const struct intel_crtc_state *crtc_state) 936637c7aa2SImre Deak { 937637c7aa2SImre Deak struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 938637c7aa2SImre Deak enum intel_display_power_domain domain = 939637c7aa2SImre Deak intel_ddi_main_link_aux_domain(dig_port, crtc_state); 940637c7aa2SImre Deak intel_wakeref_t wf; 941637c7aa2SImre Deak 942637c7aa2SImre Deak wf = fetch_and_zero(&dig_port->aux_wakeref); 943637c7aa2SImre Deak if (!wf) 944637c7aa2SImre Deak return; 945637c7aa2SImre Deak 946637c7aa2SImre Deak intel_display_power_put(i915, domain, wf); 947379bc100SJani Nikula } 948379bc100SJani Nikula 949379bc100SJani Nikula static void intel_ddi_get_power_domains(struct intel_encoder *encoder, 950379bc100SJani Nikula struct intel_crtc_state *crtc_state) 951379bc100SJani Nikula { 952379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 953379bc100SJani Nikula struct intel_digital_port *dig_port; 954379bc100SJani Nikula 955379bc100SJani Nikula /* 956379bc100SJani Nikula * TODO: Add support for MST encoders. Atm, the following should never 957379bc100SJani Nikula * happen since fake-MST encoders don't set their get_power_domains() 958379bc100SJani Nikula * hook. 959379bc100SJani Nikula */ 9601de143ccSPankaj Bharadiya if (drm_WARN_ON(&dev_priv->drm, 9611de143ccSPankaj Bharadiya intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST))) 962379bc100SJani Nikula return; 963379bc100SJani Nikula 964b7d02c3aSVille Syrjälä dig_port = enc_to_dig_port(encoder); 965f77a2db2SImre Deak 96611a89708SImre Deak if (!intel_tc_port_in_tbt_alt_mode(dig_port)) { 967a4550977SImre Deak drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref); 968a4550977SImre Deak dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv, 969f77a2db2SImre Deak dig_port->ddi_io_power_domain); 970a4550977SImre Deak } 971379bc100SJani Nikula 972637c7aa2SImre Deak main_link_aux_power_domain_get(dig_port, crtc_state); 973162e68e1SImre Deak } 974379bc100SJani Nikula 97555a4679eSVille Syrjälä void intel_ddi_enable_transcoder_clock(struct intel_encoder *encoder, 97602a715c3SVille Syrjälä const struct intel_crtc_state *crtc_state) 977379bc100SJani Nikula { 9782225f3c6SMaarten Lankhorst struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 979379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 980379bc100SJani Nikula enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; 981ed2615a8SMatt Roper enum phy phy = intel_port_to_phy(dev_priv, encoder->port); 982ed2615a8SMatt Roper u32 val; 983379bc100SJani Nikula 98448630a31SVille Syrjälä if (cpu_transcoder == TRANSCODER_EDP) 98548630a31SVille Syrjälä return; 98648630a31SVille Syrjälä 987ed2615a8SMatt Roper if (DISPLAY_VER(dev_priv) >= 13) 988ed2615a8SMatt Roper val = TGL_TRANS_CLK_SEL_PORT(phy); 989ed2615a8SMatt Roper else if (DISPLAY_VER(dev_priv) >= 12) 990ed2615a8SMatt Roper val = TGL_TRANS_CLK_SEL_PORT(encoder->port); 991df16b636SMahesh Kumar else 992ed2615a8SMatt Roper val = TRANS_CLK_SEL_PORT(encoder->port); 993ed2615a8SMatt Roper 994ed2615a8SMatt Roper intel_de_write(dev_priv, TRANS_CLK_SEL(cpu_transcoder), val); 995379bc100SJani Nikula } 996379bc100SJani Nikula 99755a4679eSVille Syrjälä void intel_ddi_disable_transcoder_clock(const struct intel_crtc_state *crtc_state) 998379bc100SJani Nikula { 9992225f3c6SMaarten Lankhorst struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); 1000379bc100SJani Nikula enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; 100148630a31SVille Syrjälä u32 val; 1002379bc100SJani Nikula 100348630a31SVille Syrjälä if (cpu_transcoder == TRANSCODER_EDP) 100448630a31SVille Syrjälä return; 100548630a31SVille Syrjälä 1006005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 12) 100748630a31SVille Syrjälä val = TGL_TRANS_CLK_SEL_DISABLED; 1008df16b636SMahesh Kumar else 100948630a31SVille Syrjälä val = TRANS_CLK_SEL_DISABLED; 101048630a31SVille Syrjälä 101148630a31SVille Syrjälä intel_de_write(dev_priv, TRANS_CLK_SEL(cpu_transcoder), val); 1012df16b636SMahesh Kumar } 1013379bc100SJani Nikula 1014379bc100SJani Nikula static void _skl_ddi_set_iboost(struct drm_i915_private *dev_priv, 1015379bc100SJani Nikula enum port port, u8 iboost) 1016379bc100SJani Nikula { 1017379bc100SJani Nikula u32 tmp; 1018379bc100SJani Nikula 1019f7960e7fSJani Nikula tmp = intel_de_read(dev_priv, DISPIO_CR_TX_BMU_CR0); 1020379bc100SJani Nikula tmp &= ~(BALANCE_LEG_MASK(port) | BALANCE_LEG_DISABLE(port)); 1021379bc100SJani Nikula if (iboost) 1022379bc100SJani Nikula tmp |= iboost << BALANCE_LEG_SHIFT(port); 1023379bc100SJani Nikula else 1024379bc100SJani Nikula tmp |= BALANCE_LEG_DISABLE(port); 1025f7960e7fSJani Nikula intel_de_write(dev_priv, DISPIO_CR_TX_BMU_CR0, tmp); 1026379bc100SJani Nikula } 1027379bc100SJani Nikula 1028379bc100SJani Nikula static void skl_ddi_set_iboost(struct intel_encoder *encoder, 1029a621860aSVille Syrjälä const struct intel_crtc_state *crtc_state, 1030a621860aSVille Syrjälä int level) 1031379bc100SJani Nikula { 10327801f3b7SLucas De Marchi struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 1033379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 1034379bc100SJani Nikula u8 iboost; 1035379bc100SJani Nikula 1036a621860aSVille Syrjälä if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) 103702107ef1SVille Syrjälä iboost = intel_bios_hdmi_boost_level(encoder->devdata); 1038379bc100SJani Nikula else 103902107ef1SVille Syrjälä iboost = intel_bios_dp_boost_level(encoder->devdata); 1040379bc100SJani Nikula 1041379bc100SJani Nikula if (iboost == 0) { 1042e505d764SVille Syrjälä const struct intel_ddi_buf_trans *trans; 1043379bc100SJani Nikula int n_entries; 1044379bc100SJani Nikula 1045e505d764SVille Syrjälä trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); 1046e505d764SVille Syrjälä if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) 1047379bc100SJani Nikula return; 1048379bc100SJani Nikula 1049e505d764SVille Syrjälä iboost = trans->entries[level].hsw.i_boost; 1050379bc100SJani Nikula } 1051379bc100SJani Nikula 1052379bc100SJani Nikula /* Make sure that the requested I_boost is valid */ 1053379bc100SJani Nikula if (iboost && iboost != 0x1 && iboost != 0x3 && iboost != 0x7) { 105447bdb1caSJani Nikula drm_err(&dev_priv->drm, "Invalid I_boost value %u\n", iboost); 1055379bc100SJani Nikula return; 1056379bc100SJani Nikula } 1057379bc100SJani Nikula 1058f0e86e05SJosé Roberto de Souza _skl_ddi_set_iboost(dev_priv, encoder->port, iboost); 1059379bc100SJani Nikula 1060f0e86e05SJosé Roberto de Souza if (encoder->port == PORT_A && dig_port->max_lanes == 4) 1061379bc100SJani Nikula _skl_ddi_set_iboost(dev_priv, PORT_E, iboost); 1062379bc100SJani Nikula } 1063379bc100SJani Nikula 1064a621860aSVille Syrjälä static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp, 1065a621860aSVille Syrjälä const struct intel_crtc_state *crtc_state) 1066379bc100SJani Nikula { 106753de0a20SVille Syrjälä struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; 1068379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 1069379bc100SJani Nikula int n_entries; 1070379bc100SJani Nikula 1071c40a253bSVille Syrjälä encoder->get_buf_trans(encoder, crtc_state, &n_entries); 1072379bc100SJani Nikula 10731de143ccSPankaj Bharadiya if (drm_WARN_ON(&dev_priv->drm, n_entries < 1)) 1074379bc100SJani Nikula n_entries = 1; 10751de143ccSPankaj Bharadiya if (drm_WARN_ON(&dev_priv->drm, 10761de143ccSPankaj Bharadiya n_entries > ARRAY_SIZE(index_to_dp_signal_levels))) 1077379bc100SJani Nikula n_entries = ARRAY_SIZE(index_to_dp_signal_levels); 1078379bc100SJani Nikula 1079379bc100SJani Nikula return index_to_dp_signal_levels[n_entries - 1] & 1080379bc100SJani Nikula DP_TRAIN_VOLTAGE_SWING_MASK; 1081379bc100SJani Nikula } 1082379bc100SJani Nikula 1083379bc100SJani Nikula /* 1084379bc100SJani Nikula * We assume that the full set of pre-emphasis values can be 1085379bc100SJani Nikula * used on all DDI platforms. Should that change we need to 1086379bc100SJani Nikula * rethink this code. 1087379bc100SJani Nikula */ 108853de0a20SVille Syrjälä static u8 intel_ddi_dp_preemph_max(struct intel_dp *intel_dp) 1089379bc100SJani Nikula { 1090379bc100SJani Nikula return DP_TRAIN_PRE_EMPH_LEVEL_3; 1091379bc100SJani Nikula } 1092379bc100SJani Nikula 10935e7fe4d9SVille Syrjälä static u32 icl_combo_phy_loadgen_select(const struct intel_crtc_state *crtc_state, 10945e7fe4d9SVille Syrjälä int lane) 10955e7fe4d9SVille Syrjälä { 10965e7fe4d9SVille Syrjälä if (crtc_state->port_clock > 600000) 10975e7fe4d9SVille Syrjälä return 0; 10985e7fe4d9SVille Syrjälä 10995e7fe4d9SVille Syrjälä if (crtc_state->lane_count == 4) 11005e7fe4d9SVille Syrjälä return lane >= 1 ? LOADGEN_SELECT : 0; 11015e7fe4d9SVille Syrjälä else 11025e7fe4d9SVille Syrjälä return lane == 1 || lane == 2 ? LOADGEN_SELECT : 0; 11035e7fe4d9SVille Syrjälä } 11045e7fe4d9SVille Syrjälä 1105a8143150SJosé Roberto de Souza static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, 1106193299adSVille Syrjälä const struct intel_crtc_state *crtc_state) 1107379bc100SJani Nikula { 1108a8143150SJosé Roberto de Souza struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 1109e505d764SVille Syrjälä const struct intel_ddi_buf_trans *trans; 1110f0e86e05SJosé Roberto de Souza enum phy phy = intel_port_to_phy(dev_priv, encoder->port); 1111a621860aSVille Syrjälä int n_entries, ln; 1112a621860aSVille Syrjälä u32 val; 1113379bc100SJani Nikula 1114e505d764SVille Syrjälä trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); 1115e505d764SVille Syrjälä if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) 111685da0292SVille Syrjälä return; 1117379bc100SJani Nikula 1118a621860aSVille Syrjälä if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) { 111981619f4aSJosé Roberto de Souza struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 112081619f4aSJosé Roberto de Souza 112181619f4aSJosé Roberto de Souza val = EDP4K2K_MODE_OVRD_EN | EDP4K2K_MODE_OVRD_OPTIMIZED; 1122e505d764SVille Syrjälä intel_dp->hobl_active = is_hobl_buf_trans(trans); 112381619f4aSJosé Roberto de Souza intel_de_rmw(dev_priv, ICL_PORT_CL_DW10(phy), val, 112481619f4aSJosé Roberto de Souza intel_dp->hobl_active ? val : 0); 112581619f4aSJosé Roberto de Souza } 112681619f4aSJosé Roberto de Souza 1127379bc100SJani Nikula /* Set PORT_TX_DW5 */ 1128e6908588SVille Syrjälä val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN(0, phy)); 1129379bc100SJani Nikula val &= ~(SCALING_MODE_SEL_MASK | RTERM_SELECT_MASK | 1130379bc100SJani Nikula TAP2_DISABLE | TAP3_DISABLE); 1131379bc100SJani Nikula val |= SCALING_MODE_SEL(0x2); 1132379bc100SJani Nikula val |= RTERM_SELECT(0x6); 1133379bc100SJani Nikula val |= TAP3_DISABLE; 1134f7960e7fSJani Nikula intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy), val); 1135379bc100SJani Nikula 1136379bc100SJani Nikula /* Program PORT_TX_DW2 */ 1137f20ca899SVille Syrjälä for (ln = 0; ln < 4; ln++) { 113831e914a2SVille Syrjälä int level = intel_ddi_level(encoder, crtc_state, ln); 113931e914a2SVille Syrjälä 1140c1d53cbdSVille Syrjälä intel_de_rmw(dev_priv, ICL_PORT_TX_DW2_LN(ln, phy), 1141c1d53cbdSVille Syrjälä SWING_SEL_UPPER_MASK | SWING_SEL_LOWER_MASK | RCOMP_SCALAR_MASK, 1142c1d53cbdSVille Syrjälä SWING_SEL_UPPER(trans->entries[level].icl.dw2_swing_sel) | 1143c1d53cbdSVille Syrjälä SWING_SEL_LOWER(trans->entries[level].icl.dw2_swing_sel) | 1144c1d53cbdSVille Syrjälä RCOMP_SCALAR(0x98)); 1145f20ca899SVille Syrjälä } 1146379bc100SJani Nikula 1147379bc100SJani Nikula /* Program PORT_TX_DW4 */ 1148379bc100SJani Nikula /* We cannot write to GRP. It would overwrite individual loadgen. */ 1149a1f01768SVille Syrjälä for (ln = 0; ln < 4; ln++) { 115031e914a2SVille Syrjälä int level = intel_ddi_level(encoder, crtc_state, ln); 115131e914a2SVille Syrjälä 1152c1d53cbdSVille Syrjälä intel_de_rmw(dev_priv, ICL_PORT_TX_DW4_LN(ln, phy), 1153c1d53cbdSVille Syrjälä POST_CURSOR_1_MASK | POST_CURSOR_2_MASK | CURSOR_COEFF_MASK, 1154c1d53cbdSVille Syrjälä POST_CURSOR_1(trans->entries[level].icl.dw4_post_cursor_1) | 1155c1d53cbdSVille Syrjälä POST_CURSOR_2(trans->entries[level].icl.dw4_post_cursor_2) | 1156c1d53cbdSVille Syrjälä CURSOR_COEFF(trans->entries[level].icl.dw4_cursor_coeff)); 1157379bc100SJani Nikula } 1158379bc100SJani Nikula 1159379bc100SJani Nikula /* Program PORT_TX_DW7 */ 1160f20ca899SVille Syrjälä for (ln = 0; ln < 4; ln++) { 116131e914a2SVille Syrjälä int level = intel_ddi_level(encoder, crtc_state, ln); 116231e914a2SVille Syrjälä 1163c1d53cbdSVille Syrjälä intel_de_rmw(dev_priv, ICL_PORT_TX_DW7_LN(ln, phy), 1164c1d53cbdSVille Syrjälä N_SCALAR_MASK, 1165c1d53cbdSVille Syrjälä N_SCALAR(trans->entries[level].icl.dw7_n_scalar)); 1166f20ca899SVille Syrjälä } 1167379bc100SJani Nikula } 1168379bc100SJani Nikula 1169193299adSVille Syrjälä static void icl_combo_phy_set_signal_levels(struct intel_encoder *encoder, 1170193299adSVille Syrjälä const struct intel_crtc_state *crtc_state) 1171379bc100SJani Nikula { 1172379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 1173dc867bc7SMatt Roper enum phy phy = intel_port_to_phy(dev_priv, encoder->port); 1174379bc100SJani Nikula u32 val; 11755e7fe4d9SVille Syrjälä int ln; 1176379bc100SJani Nikula 1177379bc100SJani Nikula /* 1178379bc100SJani Nikula * 1. If port type is eDP or DP, 1179379bc100SJani Nikula * set PORT_PCS_DW1 cmnkeeper_enable to 1b, 1180379bc100SJani Nikula * else clear to 0b. 1181379bc100SJani Nikula */ 1182e6908588SVille Syrjälä val = intel_de_read(dev_priv, ICL_PORT_PCS_DW1_LN(0, phy)); 1183a621860aSVille Syrjälä if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) 1184379bc100SJani Nikula val &= ~COMMON_KEEPER_EN; 1185379bc100SJani Nikula else 1186379bc100SJani Nikula val |= COMMON_KEEPER_EN; 1187f7960e7fSJani Nikula intel_de_write(dev_priv, ICL_PORT_PCS_DW1_GRP(phy), val); 1188379bc100SJani Nikula 1189379bc100SJani Nikula /* 2. Program loadgen select */ 1190379bc100SJani Nikula /* 1191e6908588SVille Syrjälä * Program PORT_TX_DW4 depending on Bit rate and used lanes 1192379bc100SJani Nikula * <= 6 GHz and 4 lanes (LN0=0, LN1=1, LN2=1, LN3=1) 1193379bc100SJani Nikula * <= 6 GHz and 1,2 lanes (LN0=0, LN1=1, LN2=1, LN3=0) 1194379bc100SJani Nikula * > 6 GHz (LN0=0, LN1=0, LN2=0, LN3=0) 1195379bc100SJani Nikula */ 1196a1f01768SVille Syrjälä for (ln = 0; ln < 4; ln++) { 1197c1d53cbdSVille Syrjälä intel_de_rmw(dev_priv, ICL_PORT_TX_DW4_LN(ln, phy), 1198c1d53cbdSVille Syrjälä LOADGEN_SELECT, 1199c1d53cbdSVille Syrjälä icl_combo_phy_loadgen_select(crtc_state, ln)); 1200379bc100SJani Nikula } 1201379bc100SJani Nikula 1202379bc100SJani Nikula /* 3. Set PORT_CL_DW5 SUS Clock Config to 11b */ 1203c1d53cbdSVille Syrjälä intel_de_rmw(dev_priv, ICL_PORT_CL_DW5(phy), 1204c1d53cbdSVille Syrjälä 0, SUS_CLOCK_CONFIG); 1205379bc100SJani Nikula 1206379bc100SJani Nikula /* 4. Clear training enable to change swing values */ 1207e6908588SVille Syrjälä val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN(0, phy)); 1208379bc100SJani Nikula val &= ~TX_TRAINING_EN; 1209f7960e7fSJani Nikula intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy), val); 1210379bc100SJani Nikula 1211379bc100SJani Nikula /* 5. Program swing and de-emphasis */ 1212193299adSVille Syrjälä icl_ddi_combo_vswing_program(encoder, crtc_state); 1213379bc100SJani Nikula 1214379bc100SJani Nikula /* 6. Set training enable to trigger update */ 1215e6908588SVille Syrjälä val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN(0, phy)); 1216379bc100SJani Nikula val |= TX_TRAINING_EN; 1217f7960e7fSJani Nikula intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy), val); 1218379bc100SJani Nikula } 1219379bc100SJani Nikula 1220193299adSVille Syrjälä static void icl_mg_phy_set_signal_levels(struct intel_encoder *encoder, 1221193299adSVille Syrjälä const struct intel_crtc_state *crtc_state) 1222379bc100SJani Nikula { 1223379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 1224f21e8b80SJosé Roberto de Souza enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port); 1225e505d764SVille Syrjälä const struct intel_ddi_buf_trans *trans; 1226a621860aSVille Syrjälä int n_entries, ln; 1227379bc100SJani Nikula 122811a89708SImre Deak if (intel_tc_port_in_tbt_alt_mode(enc_to_dig_port(encoder))) 1229f8c6b615SVille Syrjälä return; 1230f8c6b615SVille Syrjälä 1231e505d764SVille Syrjälä trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); 1232e505d764SVille Syrjälä if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) 123385da0292SVille Syrjälä return; 1234379bc100SJani Nikula 1235379bc100SJani Nikula for (ln = 0; ln < 2; ln++) { 1236d4e0f163SVille Syrjälä intel_de_rmw(dev_priv, MG_TX1_LINK_PARAMS(ln, tc_port), 1237d4e0f163SVille Syrjälä CRI_USE_FS32, 0); 1238d4e0f163SVille Syrjälä intel_de_rmw(dev_priv, MG_TX2_LINK_PARAMS(ln, tc_port), 1239d4e0f163SVille Syrjälä CRI_USE_FS32, 0); 1240379bc100SJani Nikula } 1241379bc100SJani Nikula 1242379bc100SJani Nikula /* Program MG_TX_SWINGCTRL with values from vswing table */ 1243379bc100SJani Nikula for (ln = 0; ln < 2; ln++) { 1244305448e5SVille Syrjälä int level; 1245305448e5SVille Syrjälä 1246305448e5SVille Syrjälä level = intel_ddi_level(encoder, crtc_state, 2*ln+0); 1247305448e5SVille Syrjälä 1248d4e0f163SVille Syrjälä intel_de_rmw(dev_priv, MG_TX1_SWINGCTRL(ln, tc_port), 1249d4e0f163SVille Syrjälä CRI_TXDEEMPH_OVERRIDE_17_12_MASK, 1250d4e0f163SVille Syrjälä CRI_TXDEEMPH_OVERRIDE_17_12(trans->entries[level].mg.cri_txdeemph_override_17_12)); 1251379bc100SJani Nikula 1252305448e5SVille Syrjälä level = intel_ddi_level(encoder, crtc_state, 2*ln+1); 1253305448e5SVille Syrjälä 1254d4e0f163SVille Syrjälä intel_de_rmw(dev_priv, MG_TX2_SWINGCTRL(ln, tc_port), 1255d4e0f163SVille Syrjälä CRI_TXDEEMPH_OVERRIDE_17_12_MASK, 1256d4e0f163SVille Syrjälä CRI_TXDEEMPH_OVERRIDE_17_12(trans->entries[level].mg.cri_txdeemph_override_17_12)); 1257379bc100SJani Nikula } 1258379bc100SJani Nikula 1259379bc100SJani Nikula /* Program MG_TX_DRVCTRL with values from vswing table */ 1260379bc100SJani Nikula for (ln = 0; ln < 2; ln++) { 1261305448e5SVille Syrjälä int level; 1262305448e5SVille Syrjälä 1263305448e5SVille Syrjälä level = intel_ddi_level(encoder, crtc_state, 2*ln+0); 1264305448e5SVille Syrjälä 1265d4e0f163SVille Syrjälä intel_de_rmw(dev_priv, MG_TX1_DRVCTRL(ln, tc_port), 1266d4e0f163SVille Syrjälä CRI_TXDEEMPH_OVERRIDE_11_6_MASK | 1267d4e0f163SVille Syrjälä CRI_TXDEEMPH_OVERRIDE_5_0_MASK, 1268d4e0f163SVille Syrjälä CRI_TXDEEMPH_OVERRIDE_11_6(trans->entries[level].mg.cri_txdeemph_override_11_6) | 1269d4e0f163SVille Syrjälä CRI_TXDEEMPH_OVERRIDE_5_0(trans->entries[level].mg.cri_txdeemph_override_5_0) | 1270d4e0f163SVille Syrjälä CRI_TXDEEMPH_OVERRIDE_EN); 1271379bc100SJani Nikula 1272305448e5SVille Syrjälä level = intel_ddi_level(encoder, crtc_state, 2*ln+1); 1273305448e5SVille Syrjälä 1274d4e0f163SVille Syrjälä intel_de_rmw(dev_priv, MG_TX2_DRVCTRL(ln, tc_port), 1275d4e0f163SVille Syrjälä CRI_TXDEEMPH_OVERRIDE_11_6_MASK | 1276d4e0f163SVille Syrjälä CRI_TXDEEMPH_OVERRIDE_5_0_MASK, 1277d4e0f163SVille Syrjälä CRI_TXDEEMPH_OVERRIDE_11_6(trans->entries[level].mg.cri_txdeemph_override_11_6) | 1278d4e0f163SVille Syrjälä CRI_TXDEEMPH_OVERRIDE_5_0(trans->entries[level].mg.cri_txdeemph_override_5_0) | 1279d4e0f163SVille Syrjälä CRI_TXDEEMPH_OVERRIDE_EN); 1280379bc100SJani Nikula 1281379bc100SJani Nikula /* FIXME: Program CRI_LOADGEN_SEL after the spec is updated */ 1282379bc100SJani Nikula } 1283379bc100SJani Nikula 1284379bc100SJani Nikula /* 1285379bc100SJani Nikula * Program MG_CLKHUB<LN, port being used> with value from frequency table 1286379bc100SJani Nikula * In case of Legacy mode on MG PHY, both TX1 and TX2 enabled so use the 1287379bc100SJani Nikula * values from table for which TX1 and TX2 enabled. 1288379bc100SJani Nikula */ 1289379bc100SJani Nikula for (ln = 0; ln < 2; ln++) { 1290d4e0f163SVille Syrjälä intel_de_rmw(dev_priv, MG_CLKHUB(ln, tc_port), 1291d4e0f163SVille Syrjälä CFG_LOW_RATE_LKREN_EN, 1292d4e0f163SVille Syrjälä crtc_state->port_clock < 300000 ? CFG_LOW_RATE_LKREN_EN : 0); 1293379bc100SJani Nikula } 1294379bc100SJani Nikula 1295379bc100SJani Nikula /* Program the MG_TX_DCC<LN, port being used> based on the link frequency */ 1296379bc100SJani Nikula for (ln = 0; ln < 2; ln++) { 1297d4e0f163SVille Syrjälä intel_de_rmw(dev_priv, MG_TX1_DCC(ln, tc_port), 1298d4e0f163SVille Syrjälä CFG_AMI_CK_DIV_OVERRIDE_VAL_MASK | 1299d4e0f163SVille Syrjälä CFG_AMI_CK_DIV_OVERRIDE_EN, 1300d4e0f163SVille Syrjälä crtc_state->port_clock > 500000 ? 1301d4e0f163SVille Syrjälä CFG_AMI_CK_DIV_OVERRIDE_VAL(1) | 1302d4e0f163SVille Syrjälä CFG_AMI_CK_DIV_OVERRIDE_EN : 0); 1303379bc100SJani Nikula 1304d4e0f163SVille Syrjälä intel_de_rmw(dev_priv, MG_TX2_DCC(ln, tc_port), 1305d4e0f163SVille Syrjälä CFG_AMI_CK_DIV_OVERRIDE_VAL_MASK | 1306d4e0f163SVille Syrjälä CFG_AMI_CK_DIV_OVERRIDE_EN, 1307d4e0f163SVille Syrjälä crtc_state->port_clock > 500000 ? 1308d4e0f163SVille Syrjälä CFG_AMI_CK_DIV_OVERRIDE_VAL(1) | 1309d4e0f163SVille Syrjälä CFG_AMI_CK_DIV_OVERRIDE_EN : 0); 1310379bc100SJani Nikula } 1311379bc100SJani Nikula 1312379bc100SJani Nikula /* Program MG_TX_PISO_READLOAD with values from vswing table */ 1313379bc100SJani Nikula for (ln = 0; ln < 2; ln++) { 1314d4e0f163SVille Syrjälä intel_de_rmw(dev_priv, MG_TX1_PISO_READLOAD(ln, tc_port), 1315d4e0f163SVille Syrjälä 0, CRI_CALCINIT); 1316d4e0f163SVille Syrjälä intel_de_rmw(dev_priv, MG_TX2_PISO_READLOAD(ln, tc_port), 1317d4e0f163SVille Syrjälä 0, CRI_CALCINIT); 1318379bc100SJani Nikula } 1319379bc100SJani Nikula } 1320379bc100SJani Nikula 1321193299adSVille Syrjälä static void tgl_dkl_phy_set_signal_levels(struct intel_encoder *encoder, 1322193299adSVille Syrjälä const struct intel_crtc_state *crtc_state) 1323978c3e53SClinton A Taylor { 1324978c3e53SClinton A Taylor struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 1325978c3e53SClinton A Taylor enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port); 1326e505d764SVille Syrjälä const struct intel_ddi_buf_trans *trans; 1327a621860aSVille Syrjälä int n_entries, ln; 1328978c3e53SClinton A Taylor 132911a89708SImre Deak if (intel_tc_port_in_tbt_alt_mode(enc_to_dig_port(encoder))) 1330f8c6b615SVille Syrjälä return; 1331f8c6b615SVille Syrjälä 1332e505d764SVille Syrjälä trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); 1333e505d764SVille Syrjälä if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) 133485da0292SVille Syrjälä return; 1335978c3e53SClinton A Taylor 1336978c3e53SClinton A Taylor for (ln = 0; ln < 2; ln++) { 1337a905ced6SVille Syrjälä int level; 1338a905ced6SVille Syrjälä 1339b8ed5533SImre Deak intel_dkl_phy_write(dev_priv, DKL_TX_PMD_LANE_SUS(tc_port, ln), 0); 13402d69c42eSJosé Roberto de Souza 1341a905ced6SVille Syrjälä level = intel_ddi_level(encoder, crtc_state, 2*ln+0); 1342a905ced6SVille Syrjälä 1343b8ed5533SImre Deak intel_dkl_phy_rmw(dev_priv, DKL_TX_DPCNTL0(tc_port, ln), 1344c86e1873SVille Syrjälä DKL_TX_PRESHOOT_COEFF_MASK | 1345a905ced6SVille Syrjälä DKL_TX_DE_EMPAHSIS_COEFF_MASK | 1346c86e1873SVille Syrjälä DKL_TX_VSWING_CONTROL_MASK, 1347c86e1873SVille Syrjälä DKL_TX_PRESHOOT_COEFF(trans->entries[level].dkl.preshoot) | 1348a905ced6SVille Syrjälä DKL_TX_DE_EMPHASIS_COEFF(trans->entries[level].dkl.de_emphasis) | 1349c86e1873SVille Syrjälä DKL_TX_VSWING_CONTROL(trans->entries[level].dkl.vswing)); 1350978c3e53SClinton A Taylor 1351a905ced6SVille Syrjälä level = intel_ddi_level(encoder, crtc_state, 2*ln+1); 1352a905ced6SVille Syrjälä 1353b8ed5533SImre Deak intel_dkl_phy_rmw(dev_priv, DKL_TX_DPCNTL1(tc_port, ln), 1354c86e1873SVille Syrjälä DKL_TX_PRESHOOT_COEFF_MASK | 1355a905ced6SVille Syrjälä DKL_TX_DE_EMPAHSIS_COEFF_MASK | 1356c86e1873SVille Syrjälä DKL_TX_VSWING_CONTROL_MASK, 1357c86e1873SVille Syrjälä DKL_TX_PRESHOOT_COEFF(trans->entries[level].dkl.preshoot) | 1358a905ced6SVille Syrjälä DKL_TX_DE_EMPHASIS_COEFF(trans->entries[level].dkl.de_emphasis) | 1359c86e1873SVille Syrjälä DKL_TX_VSWING_CONTROL(trans->entries[level].dkl.vswing)); 1360978c3e53SClinton A Taylor 1361b8ed5533SImre Deak intel_dkl_phy_rmw(dev_priv, DKL_TX_DPCNTL2(tc_port, ln), 1362c86e1873SVille Syrjälä DKL_TX_DP20BITMODE, 0); 13635ff59dddSJosé Roberto de Souza 13645ff59dddSJosé Roberto de Souza if (IS_ALDERLAKE_P(dev_priv)) { 13655ff59dddSJosé Roberto de Souza u32 val; 13665ff59dddSJosé Roberto de Souza 13675ff59dddSJosé Roberto de Souza if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { 13685ff59dddSJosé Roberto de Souza if (ln == 0) { 13695ff59dddSJosé Roberto de Souza val = DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1(0); 13705ff59dddSJosé Roberto de Souza val |= DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2(2); 13715ff59dddSJosé Roberto de Souza } else { 13725ff59dddSJosé Roberto de Souza val = DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1(3); 13735ff59dddSJosé Roberto de Souza val |= DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2(3); 13745ff59dddSJosé Roberto de Souza } 13755ff59dddSJosé Roberto de Souza } else { 13765ff59dddSJosé Roberto de Souza val = DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1(0); 13775ff59dddSJosé Roberto de Souza val |= DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2(0); 13785ff59dddSJosé Roberto de Souza } 13795ff59dddSJosé Roberto de Souza 1380b8ed5533SImre Deak intel_dkl_phy_rmw(dev_priv, DKL_TX_DPCNTL2(tc_port, ln), 13815ff59dddSJosé Roberto de Souza DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1_MASK | 13825ff59dddSJosé Roberto de Souza DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2_MASK, 13835ff59dddSJosé Roberto de Souza val); 13845ff59dddSJosé Roberto de Souza } 1385978c3e53SClinton A Taylor } 1386978c3e53SClinton A Taylor } 1387978c3e53SClinton A Taylor 1388a621860aSVille Syrjälä static int translate_signal_level(struct intel_dp *intel_dp, 1389a621860aSVille Syrjälä u8 signal_levels) 1390379bc100SJani Nikula { 13918b4f2137SPankaj Bharadiya struct drm_i915_private *i915 = dp_to_i915(intel_dp); 1392379bc100SJani Nikula int i; 1393379bc100SJani Nikula 1394379bc100SJani Nikula for (i = 0; i < ARRAY_SIZE(index_to_dp_signal_levels); i++) { 1395379bc100SJani Nikula if (index_to_dp_signal_levels[i] == signal_levels) 1396379bc100SJani Nikula return i; 1397379bc100SJani Nikula } 1398379bc100SJani Nikula 13998b4f2137SPankaj Bharadiya drm_WARN(&i915->drm, 1, 14008b4f2137SPankaj Bharadiya "Unsupported voltage swing/pre-emphasis level: 0x%x\n", 1401379bc100SJani Nikula signal_levels); 1402379bc100SJani Nikula 1403379bc100SJani Nikula return 0; 1404379bc100SJani Nikula } 1405379bc100SJani Nikula 14065c31e9d0SJani Nikula static int intel_ddi_dp_level(struct intel_dp *intel_dp, 14075c31e9d0SJani Nikula const struct intel_crtc_state *crtc_state, 14085c31e9d0SJani Nikula int lane) 1409379bc100SJani Nikula { 1410d0920a45SVille Syrjälä u8 train_set = intel_dp->train_set[lane]; 14115c31e9d0SJani Nikula 14125c31e9d0SJani Nikula if (intel_dp_is_uhbr(crtc_state)) { 14135c31e9d0SJani Nikula return train_set & DP_TX_FFE_PRESET_VALUE_MASK; 14145c31e9d0SJani Nikula } else { 1415a621860aSVille Syrjälä u8 signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK | 1416379bc100SJani Nikula DP_TRAIN_PRE_EMPHASIS_MASK); 1417379bc100SJani Nikula 14188b4f2137SPankaj Bharadiya return translate_signal_level(intel_dp, signal_levels); 1419379bc100SJani Nikula } 14205c31e9d0SJani Nikula } 1421379bc100SJani Nikula 1422193299adSVille Syrjälä int intel_ddi_level(struct intel_encoder *encoder, 1423d0920a45SVille Syrjälä const struct intel_crtc_state *crtc_state, 1424d0920a45SVille Syrjälä int lane) 1425a046a0daSMatt Roper { 14262c63e0f9SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 14272c63e0f9SVille Syrjälä const struct intel_ddi_buf_trans *trans; 14282c63e0f9SVille Syrjälä int level, n_entries; 14292c63e0f9SVille Syrjälä 14302c63e0f9SVille Syrjälä trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); 14312c63e0f9SVille Syrjälä if (drm_WARN_ON_ONCE(&i915->drm, !trans)) 14322c63e0f9SVille Syrjälä return 0; 14332c63e0f9SVille Syrjälä 1434e722ab8bSVille Syrjälä if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) 14353e022c1fSVille Syrjälä level = intel_ddi_hdmi_level(encoder, trans); 1436e722ab8bSVille Syrjälä else 14375c31e9d0SJani Nikula level = intel_ddi_dp_level(enc_to_intel_dp(encoder), crtc_state, 14385c31e9d0SJani Nikula lane); 14392c63e0f9SVille Syrjälä 14402c63e0f9SVille Syrjälä if (drm_WARN_ON_ONCE(&i915->drm, level >= n_entries)) 14412c63e0f9SVille Syrjälä level = n_entries - 1; 14422c63e0f9SVille Syrjälä 14432c63e0f9SVille Syrjälä return level; 1444e722ab8bSVille Syrjälä } 1445e722ab8bSVille Syrjälä 1446e722ab8bSVille Syrjälä static void 1447e722ab8bSVille Syrjälä hsw_set_signal_levels(struct intel_encoder *encoder, 1448a621860aSVille Syrjälä const struct intel_crtc_state *crtc_state) 1449fb83f72cSVille Syrjälä { 1450fb83f72cSVille Syrjälä struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 1451e722ab8bSVille Syrjälä struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 1452d0920a45SVille Syrjälä int level = intel_ddi_level(encoder, crtc_state, 0); 1453fb83f72cSVille Syrjälä enum port port = encoder->port; 1454fb83f72cSVille Syrjälä u32 signal_levels; 1455fb83f72cSVille Syrjälä 1456e722ab8bSVille Syrjälä if (has_iboost(dev_priv)) 1457e722ab8bSVille Syrjälä skl_ddi_set_iboost(encoder, crtc_state, level); 1458e722ab8bSVille Syrjälä 1459e722ab8bSVille Syrjälä /* HDMI ignores the rest */ 1460e722ab8bSVille Syrjälä if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) 1461e722ab8bSVille Syrjälä return; 1462e722ab8bSVille Syrjälä 1463fb83f72cSVille Syrjälä signal_levels = DDI_BUF_TRANS_SELECT(level); 1464fb83f72cSVille Syrjälä 1465fb83f72cSVille Syrjälä drm_dbg_kms(&dev_priv->drm, "Using signal levels %08x\n", 1466fb83f72cSVille Syrjälä signal_levels); 1467fb83f72cSVille Syrjälä 1468fb83f72cSVille Syrjälä intel_dp->DP &= ~DDI_BUF_EMP_MASK; 1469fb83f72cSVille Syrjälä intel_dp->DP |= signal_levels; 1470fb83f72cSVille Syrjälä 1471fb83f72cSVille Syrjälä intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP); 1472fb83f72cSVille Syrjälä intel_de_posting_read(dev_priv, DDI_BUF_CTL(port)); 1473379bc100SJani Nikula } 1474379bc100SJani Nikula 14754da27d5dSLucas De Marchi static void _icl_ddi_enable_clock(struct drm_i915_private *i915, i915_reg_t reg, 14769c6a5c35SVille Syrjälä u32 clk_sel_mask, u32 clk_sel, u32 clk_off) 14779c6a5c35SVille Syrjälä { 147836d225f3SJani Nikula mutex_lock(&i915->display.dpll.lock); 14799c6a5c35SVille Syrjälä 14809c6a5c35SVille Syrjälä intel_de_rmw(i915, reg, clk_sel_mask, clk_sel); 14819c6a5c35SVille Syrjälä 14829c6a5c35SVille Syrjälä /* 14839c6a5c35SVille Syrjälä * "This step and the step before must be 14849c6a5c35SVille Syrjälä * done with separate register writes." 14859c6a5c35SVille Syrjälä */ 14869c6a5c35SVille Syrjälä intel_de_rmw(i915, reg, clk_off, 0); 14879c6a5c35SVille Syrjälä 148836d225f3SJani Nikula mutex_unlock(&i915->display.dpll.lock); 14899c6a5c35SVille Syrjälä } 14909c6a5c35SVille Syrjälä 14914da27d5dSLucas De Marchi static void _icl_ddi_disable_clock(struct drm_i915_private *i915, i915_reg_t reg, 14929c6a5c35SVille Syrjälä u32 clk_off) 14939c6a5c35SVille Syrjälä { 149436d225f3SJani Nikula mutex_lock(&i915->display.dpll.lock); 14959c6a5c35SVille Syrjälä 14969c6a5c35SVille Syrjälä intel_de_rmw(i915, reg, 0, clk_off); 14979c6a5c35SVille Syrjälä 149836d225f3SJani Nikula mutex_unlock(&i915->display.dpll.lock); 14999c6a5c35SVille Syrjälä } 15009c6a5c35SVille Syrjälä 15014da27d5dSLucas De Marchi static bool _icl_ddi_is_clock_enabled(struct drm_i915_private *i915, i915_reg_t reg, 15020fbd8694SVille Syrjälä u32 clk_off) 15030fbd8694SVille Syrjälä { 15040fbd8694SVille Syrjälä return !(intel_de_read(i915, reg) & clk_off); 15050fbd8694SVille Syrjälä } 15060fbd8694SVille Syrjälä 1507351221ffSVille Syrjälä static struct intel_shared_dpll * 15084da27d5dSLucas De Marchi _icl_ddi_get_pll(struct drm_i915_private *i915, i915_reg_t reg, 1509351221ffSVille Syrjälä u32 clk_sel_mask, u32 clk_sel_shift) 1510351221ffSVille Syrjälä { 1511351221ffSVille Syrjälä enum intel_dpll_id id; 1512351221ffSVille Syrjälä 1513351221ffSVille Syrjälä id = (intel_de_read(i915, reg) & clk_sel_mask) >> clk_sel_shift; 1514351221ffSVille Syrjälä 1515351221ffSVille Syrjälä return intel_get_shared_dpll_by_id(i915, id); 1516351221ffSVille Syrjälä } 1517351221ffSVille Syrjälä 151840b316d4SVille Syrjälä static void adls_ddi_enable_clock(struct intel_encoder *encoder, 151940b316d4SVille Syrjälä const struct intel_crtc_state *crtc_state) 152040b316d4SVille Syrjälä { 152140b316d4SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 152240b316d4SVille Syrjälä const struct intel_shared_dpll *pll = crtc_state->shared_dpll; 152340b316d4SVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 152440b316d4SVille Syrjälä 152540b316d4SVille Syrjälä if (drm_WARN_ON(&i915->drm, !pll)) 152640b316d4SVille Syrjälä return; 152740b316d4SVille Syrjälä 15284da27d5dSLucas De Marchi _icl_ddi_enable_clock(i915, ADLS_DPCLKA_CFGCR(phy), 152940b316d4SVille Syrjälä ADLS_DPCLKA_CFGCR_DDI_CLK_SEL_MASK(phy), 153040b316d4SVille Syrjälä pll->info->id << ADLS_DPCLKA_CFGCR_DDI_SHIFT(phy), 153140b316d4SVille Syrjälä ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); 153240b316d4SVille Syrjälä } 153340b316d4SVille Syrjälä 153440b316d4SVille Syrjälä static void adls_ddi_disable_clock(struct intel_encoder *encoder) 153540b316d4SVille Syrjälä { 153640b316d4SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 153740b316d4SVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 153840b316d4SVille Syrjälä 15394da27d5dSLucas De Marchi _icl_ddi_disable_clock(i915, ADLS_DPCLKA_CFGCR(phy), 154040b316d4SVille Syrjälä ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); 154140b316d4SVille Syrjälä } 154240b316d4SVille Syrjälä 15430fbd8694SVille Syrjälä static bool adls_ddi_is_clock_enabled(struct intel_encoder *encoder) 15440fbd8694SVille Syrjälä { 15450fbd8694SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 15460fbd8694SVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 15470fbd8694SVille Syrjälä 15484da27d5dSLucas De Marchi return _icl_ddi_is_clock_enabled(i915, ADLS_DPCLKA_CFGCR(phy), 15490fbd8694SVille Syrjälä ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); 15500fbd8694SVille Syrjälä } 15510fbd8694SVille Syrjälä 1552351221ffSVille Syrjälä static struct intel_shared_dpll *adls_ddi_get_pll(struct intel_encoder *encoder) 1553351221ffSVille Syrjälä { 1554351221ffSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 1555351221ffSVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 1556351221ffSVille Syrjälä 15574da27d5dSLucas De Marchi return _icl_ddi_get_pll(i915, ADLS_DPCLKA_CFGCR(phy), 1558351221ffSVille Syrjälä ADLS_DPCLKA_CFGCR_DDI_CLK_SEL_MASK(phy), 1559351221ffSVille Syrjälä ADLS_DPCLKA_CFGCR_DDI_SHIFT(phy)); 1560351221ffSVille Syrjälä } 1561351221ffSVille Syrjälä 156240b316d4SVille Syrjälä static void rkl_ddi_enable_clock(struct intel_encoder *encoder, 156340b316d4SVille Syrjälä const struct intel_crtc_state *crtc_state) 156440b316d4SVille Syrjälä { 156540b316d4SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 156640b316d4SVille Syrjälä const struct intel_shared_dpll *pll = crtc_state->shared_dpll; 156740b316d4SVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 156840b316d4SVille Syrjälä 156940b316d4SVille Syrjälä if (drm_WARN_ON(&i915->drm, !pll)) 157040b316d4SVille Syrjälä return; 157140b316d4SVille Syrjälä 15724da27d5dSLucas De Marchi _icl_ddi_enable_clock(i915, ICL_DPCLKA_CFGCR0, 157340b316d4SVille Syrjälä RKL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy), 157440b316d4SVille Syrjälä RKL_DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, phy), 157540b316d4SVille Syrjälä RKL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); 157640b316d4SVille Syrjälä } 157740b316d4SVille Syrjälä 157840b316d4SVille Syrjälä static void rkl_ddi_disable_clock(struct intel_encoder *encoder) 157940b316d4SVille Syrjälä { 158040b316d4SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 158140b316d4SVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 158240b316d4SVille Syrjälä 15834da27d5dSLucas De Marchi _icl_ddi_disable_clock(i915, ICL_DPCLKA_CFGCR0, 158440b316d4SVille Syrjälä RKL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); 158540b316d4SVille Syrjälä } 158640b316d4SVille Syrjälä 15870fbd8694SVille Syrjälä static bool rkl_ddi_is_clock_enabled(struct intel_encoder *encoder) 15880fbd8694SVille Syrjälä { 15890fbd8694SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 15900fbd8694SVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 15910fbd8694SVille Syrjälä 15924da27d5dSLucas De Marchi return _icl_ddi_is_clock_enabled(i915, ICL_DPCLKA_CFGCR0, 15930fbd8694SVille Syrjälä RKL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); 15940fbd8694SVille Syrjälä } 15950fbd8694SVille Syrjälä 1596351221ffSVille Syrjälä static struct intel_shared_dpll *rkl_ddi_get_pll(struct intel_encoder *encoder) 1597351221ffSVille Syrjälä { 1598351221ffSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 1599351221ffSVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 1600351221ffSVille Syrjälä 16014da27d5dSLucas De Marchi return _icl_ddi_get_pll(i915, ICL_DPCLKA_CFGCR0, 1602351221ffSVille Syrjälä RKL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy), 1603351221ffSVille Syrjälä RKL_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(phy)); 1604351221ffSVille Syrjälä } 1605351221ffSVille Syrjälä 160635bb6b1aSVille Syrjälä static void dg1_ddi_enable_clock(struct intel_encoder *encoder, 160711ffe972SLucas De Marchi const struct intel_crtc_state *crtc_state) 160811ffe972SLucas De Marchi { 160997a24a70SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 16109c6a5c35SVille Syrjälä const struct intel_shared_dpll *pll = crtc_state->shared_dpll; 161197a24a70SVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 161211ffe972SLucas De Marchi 161397a24a70SVille Syrjälä if (drm_WARN_ON(&i915->drm, !pll)) 1614f67a008eSVille Syrjälä return; 1615f67a008eSVille Syrjälä 161611ffe972SLucas De Marchi /* 161711ffe972SLucas De Marchi * If we fail this, something went very wrong: first 2 PLLs should be 161811ffe972SLucas De Marchi * used by first 2 phys and last 2 PLLs by last phys 161911ffe972SLucas De Marchi */ 162097a24a70SVille Syrjälä if (drm_WARN_ON(&i915->drm, 162111ffe972SLucas De Marchi (pll->info->id < DPLL_ID_DG1_DPLL2 && phy >= PHY_C) || 162211ffe972SLucas De Marchi (pll->info->id >= DPLL_ID_DG1_DPLL2 && phy < PHY_C))) 162311ffe972SLucas De Marchi return; 162411ffe972SLucas De Marchi 16254da27d5dSLucas De Marchi _icl_ddi_enable_clock(i915, DG1_DPCLKA_CFGCR0(phy), 16267815ed88SVille Syrjälä DG1_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy), 16279c6a5c35SVille Syrjälä DG1_DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, phy), 16289c6a5c35SVille Syrjälä DG1_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); 162911ffe972SLucas De Marchi } 163011ffe972SLucas De Marchi 163135bb6b1aSVille Syrjälä static void dg1_ddi_disable_clock(struct intel_encoder *encoder) 163235bb6b1aSVille Syrjälä { 163397a24a70SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 163497a24a70SVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 163535bb6b1aSVille Syrjälä 16364da27d5dSLucas De Marchi _icl_ddi_disable_clock(i915, DG1_DPCLKA_CFGCR0(phy), 16379c6a5c35SVille Syrjälä DG1_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); 163835bb6b1aSVille Syrjälä } 163935bb6b1aSVille Syrjälä 16400fbd8694SVille Syrjälä static bool dg1_ddi_is_clock_enabled(struct intel_encoder *encoder) 16410fbd8694SVille Syrjälä { 16420fbd8694SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 16430fbd8694SVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 16440fbd8694SVille Syrjälä 16454da27d5dSLucas De Marchi return _icl_ddi_is_clock_enabled(i915, DG1_DPCLKA_CFGCR0(phy), 16460fbd8694SVille Syrjälä DG1_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); 16470fbd8694SVille Syrjälä } 16480fbd8694SVille Syrjälä 1649351221ffSVille Syrjälä static struct intel_shared_dpll *dg1_ddi_get_pll(struct intel_encoder *encoder) 1650351221ffSVille Syrjälä { 1651351221ffSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 1652351221ffSVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 16533352d86dSJosé Roberto de Souza enum intel_dpll_id id; 16543352d86dSJosé Roberto de Souza u32 val; 1655351221ffSVille Syrjälä 16563352d86dSJosé Roberto de Souza val = intel_de_read(i915, DG1_DPCLKA_CFGCR0(phy)); 16573352d86dSJosé Roberto de Souza val &= DG1_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy); 16583352d86dSJosé Roberto de Souza val >>= DG1_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(phy); 16593352d86dSJosé Roberto de Souza id = val; 16603352d86dSJosé Roberto de Souza 16613352d86dSJosé Roberto de Souza /* 16623352d86dSJosé Roberto de Souza * _DG1_DPCLKA0_CFGCR0 maps between DPLL 0 and 1 with one bit for phy A 16633352d86dSJosé Roberto de Souza * and B while _DG1_DPCLKA1_CFGCR0 maps between DPLL 2 and 3 with one 16643352d86dSJosé Roberto de Souza * bit for phy C and D. 16653352d86dSJosé Roberto de Souza */ 16663352d86dSJosé Roberto de Souza if (phy >= PHY_C) 16673352d86dSJosé Roberto de Souza id += DPLL_ID_DG1_DPLL2; 16683352d86dSJosé Roberto de Souza 16693352d86dSJosé Roberto de Souza return intel_get_shared_dpll_by_id(i915, id); 1670351221ffSVille Syrjälä } 1671351221ffSVille Syrjälä 167236ecb0ecSVille Syrjälä static void icl_ddi_combo_enable_clock(struct intel_encoder *encoder, 1673379bc100SJani Nikula const struct intel_crtc_state *crtc_state) 1674379bc100SJani Nikula { 167597a24a70SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 16769c6a5c35SVille Syrjälä const struct intel_shared_dpll *pll = crtc_state->shared_dpll; 167797a24a70SVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 1678cd803bb4SMatt Roper 167997a24a70SVille Syrjälä if (drm_WARN_ON(&i915->drm, !pll)) 1680f67a008eSVille Syrjälä return; 1681f67a008eSVille Syrjälä 16824da27d5dSLucas De Marchi _icl_ddi_enable_clock(i915, ICL_DPCLKA_CFGCR0, 168340b316d4SVille Syrjälä ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy), 168440b316d4SVille Syrjälä ICL_DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, phy), 168540b316d4SVille Syrjälä ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); 1686379bc100SJani Nikula } 1687379bc100SJani Nikula 168836ecb0ecSVille Syrjälä static void icl_ddi_combo_disable_clock(struct intel_encoder *encoder) 1689379bc100SJani Nikula { 169097a24a70SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 169197a24a70SVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 1692379bc100SJani Nikula 16934da27d5dSLucas De Marchi _icl_ddi_disable_clock(i915, ICL_DPCLKA_CFGCR0, 169440b316d4SVille Syrjälä ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); 1695379bc100SJani Nikula } 1696379bc100SJani Nikula 16970fbd8694SVille Syrjälä static bool icl_ddi_combo_is_clock_enabled(struct intel_encoder *encoder) 16980fbd8694SVille Syrjälä { 16990fbd8694SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 17000fbd8694SVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 17010fbd8694SVille Syrjälä 17024da27d5dSLucas De Marchi return _icl_ddi_is_clock_enabled(i915, ICL_DPCLKA_CFGCR0, 17030fbd8694SVille Syrjälä ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); 17040fbd8694SVille Syrjälä } 17050fbd8694SVille Syrjälä 1706351221ffSVille Syrjälä struct intel_shared_dpll *icl_ddi_combo_get_pll(struct intel_encoder *encoder) 1707351221ffSVille Syrjälä { 1708351221ffSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 1709351221ffSVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 1710351221ffSVille Syrjälä 17114da27d5dSLucas De Marchi return _icl_ddi_get_pll(i915, ICL_DPCLKA_CFGCR0, 1712351221ffSVille Syrjälä ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy), 1713351221ffSVille Syrjälä ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(phy)); 1714351221ffSVille Syrjälä } 1715351221ffSVille Syrjälä 171636ecb0ecSVille Syrjälä static void jsl_ddi_tc_enable_clock(struct intel_encoder *encoder, 1717379bc100SJani Nikula const struct intel_crtc_state *crtc_state) 1718379bc100SJani Nikula { 171936ecb0ecSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 1720379bc100SJani Nikula const struct intel_shared_dpll *pll = crtc_state->shared_dpll; 172136ecb0ecSVille Syrjälä enum port port = encoder->port; 1722379bc100SJani Nikula 172336ecb0ecSVille Syrjälä if (drm_WARN_ON(&i915->drm, !pll)) 1724379bc100SJani Nikula return; 1725379bc100SJani Nikula 1726c2052d6eSJosé Roberto de Souza /* 172736ecb0ecSVille Syrjälä * "For DDIC and DDID, program DDI_CLK_SEL to map the MG clock to the port. 172836ecb0ecSVille Syrjälä * MG does not exist, but the programming is required to ungate DDIC and DDID." 1729c2052d6eSJosé Roberto de Souza */ 173036ecb0ecSVille Syrjälä intel_de_write(i915, DDI_CLK_SEL(port), DDI_CLK_SEL_MG); 173136ecb0ecSVille Syrjälä 173236ecb0ecSVille Syrjälä icl_ddi_combo_enable_clock(encoder, crtc_state); 1733379bc100SJani Nikula } 1734379bc100SJani Nikula 173536ecb0ecSVille Syrjälä static void jsl_ddi_tc_disable_clock(struct intel_encoder *encoder) 1736379bc100SJani Nikula { 173736ecb0ecSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 1738379bc100SJani Nikula enum port port = encoder->port; 1739379bc100SJani Nikula 174036ecb0ecSVille Syrjälä icl_ddi_combo_disable_clock(encoder); 174136ecb0ecSVille Syrjälä 174236ecb0ecSVille Syrjälä intel_de_write(i915, DDI_CLK_SEL(port), DDI_CLK_SEL_NONE); 1743379bc100SJani Nikula } 174436ecb0ecSVille Syrjälä 17450fbd8694SVille Syrjälä static bool jsl_ddi_tc_is_clock_enabled(struct intel_encoder *encoder) 17460fbd8694SVille Syrjälä { 17470fbd8694SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 17480fbd8694SVille Syrjälä enum port port = encoder->port; 17490fbd8694SVille Syrjälä u32 tmp; 17500fbd8694SVille Syrjälä 17510fbd8694SVille Syrjälä tmp = intel_de_read(i915, DDI_CLK_SEL(port)); 17520fbd8694SVille Syrjälä 17530fbd8694SVille Syrjälä if ((tmp & DDI_CLK_SEL_MASK) == DDI_CLK_SEL_NONE) 17540fbd8694SVille Syrjälä return false; 17550fbd8694SVille Syrjälä 17560fbd8694SVille Syrjälä return icl_ddi_combo_is_clock_enabled(encoder); 17570fbd8694SVille Syrjälä } 17580fbd8694SVille Syrjälä 175936ecb0ecSVille Syrjälä static void icl_ddi_tc_enable_clock(struct intel_encoder *encoder, 176036ecb0ecSVille Syrjälä const struct intel_crtc_state *crtc_state) 176136ecb0ecSVille Syrjälä { 176236ecb0ecSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 176336ecb0ecSVille Syrjälä const struct intel_shared_dpll *pll = crtc_state->shared_dpll; 176436ecb0ecSVille Syrjälä enum tc_port tc_port = intel_port_to_tc(i915, encoder->port); 176536ecb0ecSVille Syrjälä enum port port = encoder->port; 176636ecb0ecSVille Syrjälä 176736ecb0ecSVille Syrjälä if (drm_WARN_ON(&i915->drm, !pll)) 176836ecb0ecSVille Syrjälä return; 176936ecb0ecSVille Syrjälä 177036ecb0ecSVille Syrjälä intel_de_write(i915, DDI_CLK_SEL(port), 177136ecb0ecSVille Syrjälä icl_pll_to_ddi_clk_sel(encoder, crtc_state)); 177236ecb0ecSVille Syrjälä 177336d225f3SJani Nikula mutex_lock(&i915->display.dpll.lock); 177436ecb0ecSVille Syrjälä 177536ecb0ecSVille Syrjälä intel_de_rmw(i915, ICL_DPCLKA_CFGCR0, 177636ecb0ecSVille Syrjälä ICL_DPCLKA_CFGCR0_TC_CLK_OFF(tc_port), 0); 177736ecb0ecSVille Syrjälä 177836d225f3SJani Nikula mutex_unlock(&i915->display.dpll.lock); 177936ecb0ecSVille Syrjälä } 178036ecb0ecSVille Syrjälä 178136ecb0ecSVille Syrjälä static void icl_ddi_tc_disable_clock(struct intel_encoder *encoder) 178236ecb0ecSVille Syrjälä { 178336ecb0ecSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 178436ecb0ecSVille Syrjälä enum tc_port tc_port = intel_port_to_tc(i915, encoder->port); 178536ecb0ecSVille Syrjälä enum port port = encoder->port; 178636ecb0ecSVille Syrjälä 178736d225f3SJani Nikula mutex_lock(&i915->display.dpll.lock); 178836ecb0ecSVille Syrjälä 178936ecb0ecSVille Syrjälä intel_de_rmw(i915, ICL_DPCLKA_CFGCR0, 179036ecb0ecSVille Syrjälä 0, ICL_DPCLKA_CFGCR0_TC_CLK_OFF(tc_port)); 179136ecb0ecSVille Syrjälä 179236d225f3SJani Nikula mutex_unlock(&i915->display.dpll.lock); 179336ecb0ecSVille Syrjälä 179436ecb0ecSVille Syrjälä intel_de_write(i915, DDI_CLK_SEL(port), DDI_CLK_SEL_NONE); 1795379bc100SJani Nikula } 1796379bc100SJani Nikula 17970fbd8694SVille Syrjälä static bool icl_ddi_tc_is_clock_enabled(struct intel_encoder *encoder) 17980fbd8694SVille Syrjälä { 17990fbd8694SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 18000fbd8694SVille Syrjälä enum tc_port tc_port = intel_port_to_tc(i915, encoder->port); 18010fbd8694SVille Syrjälä enum port port = encoder->port; 18020fbd8694SVille Syrjälä u32 tmp; 18030fbd8694SVille Syrjälä 18040fbd8694SVille Syrjälä tmp = intel_de_read(i915, DDI_CLK_SEL(port)); 18050fbd8694SVille Syrjälä 18060fbd8694SVille Syrjälä if ((tmp & DDI_CLK_SEL_MASK) == DDI_CLK_SEL_NONE) 18070fbd8694SVille Syrjälä return false; 18080fbd8694SVille Syrjälä 18090fbd8694SVille Syrjälä tmp = intel_de_read(i915, ICL_DPCLKA_CFGCR0); 18100fbd8694SVille Syrjälä 18110fbd8694SVille Syrjälä return !(tmp & ICL_DPCLKA_CFGCR0_TC_CLK_OFF(tc_port)); 18120fbd8694SVille Syrjälä } 18130fbd8694SVille Syrjälä 1814351221ffSVille Syrjälä static struct intel_shared_dpll *icl_ddi_tc_get_pll(struct intel_encoder *encoder) 1815351221ffSVille Syrjälä { 1816351221ffSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 1817351221ffSVille Syrjälä enum tc_port tc_port = intel_port_to_tc(i915, encoder->port); 1818351221ffSVille Syrjälä enum port port = encoder->port; 1819351221ffSVille Syrjälä enum intel_dpll_id id; 1820351221ffSVille Syrjälä u32 tmp; 1821351221ffSVille Syrjälä 1822351221ffSVille Syrjälä tmp = intel_de_read(i915, DDI_CLK_SEL(port)); 1823351221ffSVille Syrjälä 1824351221ffSVille Syrjälä switch (tmp & DDI_CLK_SEL_MASK) { 1825351221ffSVille Syrjälä case DDI_CLK_SEL_TBT_162: 1826351221ffSVille Syrjälä case DDI_CLK_SEL_TBT_270: 1827351221ffSVille Syrjälä case DDI_CLK_SEL_TBT_540: 1828351221ffSVille Syrjälä case DDI_CLK_SEL_TBT_810: 1829351221ffSVille Syrjälä id = DPLL_ID_ICL_TBTPLL; 1830351221ffSVille Syrjälä break; 1831351221ffSVille Syrjälä case DDI_CLK_SEL_MG: 1832351221ffSVille Syrjälä id = icl_tc_port_to_pll_id(tc_port); 1833351221ffSVille Syrjälä break; 1834351221ffSVille Syrjälä default: 1835351221ffSVille Syrjälä MISSING_CASE(tmp); 1836351221ffSVille Syrjälä fallthrough; 1837351221ffSVille Syrjälä case DDI_CLK_SEL_NONE: 1838351221ffSVille Syrjälä return NULL; 1839351221ffSVille Syrjälä } 1840351221ffSVille Syrjälä 1841351221ffSVille Syrjälä return intel_get_shared_dpll_by_id(i915, id); 1842351221ffSVille Syrjälä } 1843351221ffSVille Syrjälä 1844351221ffSVille Syrjälä static struct intel_shared_dpll *bxt_ddi_get_pll(struct intel_encoder *encoder) 1845351221ffSVille Syrjälä { 1846351221ffSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 1847351221ffSVille Syrjälä enum intel_dpll_id id; 1848351221ffSVille Syrjälä 1849351221ffSVille Syrjälä switch (encoder->port) { 1850351221ffSVille Syrjälä case PORT_A: 1851351221ffSVille Syrjälä id = DPLL_ID_SKL_DPLL0; 1852351221ffSVille Syrjälä break; 1853351221ffSVille Syrjälä case PORT_B: 1854351221ffSVille Syrjälä id = DPLL_ID_SKL_DPLL1; 1855351221ffSVille Syrjälä break; 1856351221ffSVille Syrjälä case PORT_C: 1857351221ffSVille Syrjälä id = DPLL_ID_SKL_DPLL2; 1858351221ffSVille Syrjälä break; 1859351221ffSVille Syrjälä default: 1860351221ffSVille Syrjälä MISSING_CASE(encoder->port); 1861351221ffSVille Syrjälä return NULL; 1862351221ffSVille Syrjälä } 1863351221ffSVille Syrjälä 1864351221ffSVille Syrjälä return intel_get_shared_dpll_by_id(i915, id); 1865351221ffSVille Syrjälä } 1866351221ffSVille Syrjälä 186738e31f1aSVille Syrjälä static void skl_ddi_enable_clock(struct intel_encoder *encoder, 186838e31f1aSVille Syrjälä const struct intel_crtc_state *crtc_state) 186938e31f1aSVille Syrjälä { 187038e31f1aSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 187138e31f1aSVille Syrjälä const struct intel_shared_dpll *pll = crtc_state->shared_dpll; 187238e31f1aSVille Syrjälä enum port port = encoder->port; 187338e31f1aSVille Syrjälä 187438e31f1aSVille Syrjälä if (drm_WARN_ON(&i915->drm, !pll)) 187538e31f1aSVille Syrjälä return; 187638e31f1aSVille Syrjälä 187736d225f3SJani Nikula mutex_lock(&i915->display.dpll.lock); 187838e31f1aSVille Syrjälä 18797815ed88SVille Syrjälä intel_de_rmw(i915, DPLL_CTRL2, 18807815ed88SVille Syrjälä DPLL_CTRL2_DDI_CLK_OFF(port) | 18817815ed88SVille Syrjälä DPLL_CTRL2_DDI_CLK_SEL_MASK(port), 18827815ed88SVille Syrjälä DPLL_CTRL2_DDI_CLK_SEL(pll->info->id, port) | 188338e31f1aSVille Syrjälä DPLL_CTRL2_DDI_SEL_OVERRIDE(port)); 188438e31f1aSVille Syrjälä 188536d225f3SJani Nikula mutex_unlock(&i915->display.dpll.lock); 188638e31f1aSVille Syrjälä } 188738e31f1aSVille Syrjälä 188838e31f1aSVille Syrjälä static void skl_ddi_disable_clock(struct intel_encoder *encoder) 188938e31f1aSVille Syrjälä { 189038e31f1aSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 189138e31f1aSVille Syrjälä enum port port = encoder->port; 189238e31f1aSVille Syrjälä 189336d225f3SJani Nikula mutex_lock(&i915->display.dpll.lock); 1894be317ca0SVille Syrjälä 18957815ed88SVille Syrjälä intel_de_rmw(i915, DPLL_CTRL2, 18967815ed88SVille Syrjälä 0, DPLL_CTRL2_DDI_CLK_OFF(port)); 1897be317ca0SVille Syrjälä 189836d225f3SJani Nikula mutex_unlock(&i915->display.dpll.lock); 189938e31f1aSVille Syrjälä } 190038e31f1aSVille Syrjälä 19010fbd8694SVille Syrjälä static bool skl_ddi_is_clock_enabled(struct intel_encoder *encoder) 19020fbd8694SVille Syrjälä { 19030fbd8694SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 19040fbd8694SVille Syrjälä enum port port = encoder->port; 19050fbd8694SVille Syrjälä 19060fbd8694SVille Syrjälä /* 19070fbd8694SVille Syrjälä * FIXME Not sure if the override affects both 19080fbd8694SVille Syrjälä * the PLL selection and the CLK_OFF bit. 19090fbd8694SVille Syrjälä */ 19100fbd8694SVille Syrjälä return !(intel_de_read(i915, DPLL_CTRL2) & DPLL_CTRL2_DDI_CLK_OFF(port)); 19110fbd8694SVille Syrjälä } 19120fbd8694SVille Syrjälä 1913351221ffSVille Syrjälä static struct intel_shared_dpll *skl_ddi_get_pll(struct intel_encoder *encoder) 1914351221ffSVille Syrjälä { 1915351221ffSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 1916351221ffSVille Syrjälä enum port port = encoder->port; 1917351221ffSVille Syrjälä enum intel_dpll_id id; 1918351221ffSVille Syrjälä u32 tmp; 1919351221ffSVille Syrjälä 1920351221ffSVille Syrjälä tmp = intel_de_read(i915, DPLL_CTRL2); 1921351221ffSVille Syrjälä 1922351221ffSVille Syrjälä /* 1923351221ffSVille Syrjälä * FIXME Not sure if the override affects both 1924351221ffSVille Syrjälä * the PLL selection and the CLK_OFF bit. 1925351221ffSVille Syrjälä */ 1926351221ffSVille Syrjälä if ((tmp & DPLL_CTRL2_DDI_SEL_OVERRIDE(port)) == 0) 1927351221ffSVille Syrjälä return NULL; 1928351221ffSVille Syrjälä 1929351221ffSVille Syrjälä id = (tmp & DPLL_CTRL2_DDI_CLK_SEL_MASK(port)) >> 1930351221ffSVille Syrjälä DPLL_CTRL2_DDI_CLK_SEL_SHIFT(port); 1931351221ffSVille Syrjälä 1932351221ffSVille Syrjälä return intel_get_shared_dpll_by_id(i915, id); 1933351221ffSVille Syrjälä } 1934351221ffSVille Syrjälä 1935d135368dSVille Syrjälä void hsw_ddi_enable_clock(struct intel_encoder *encoder, 1936d135368dSVille Syrjälä const struct intel_crtc_state *crtc_state) 1937d135368dSVille Syrjälä { 1938d135368dSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 1939d135368dSVille Syrjälä const struct intel_shared_dpll *pll = crtc_state->shared_dpll; 1940d135368dSVille Syrjälä enum port port = encoder->port; 1941d135368dSVille Syrjälä 1942d135368dSVille Syrjälä if (drm_WARN_ON(&i915->drm, !pll)) 1943d135368dSVille Syrjälä return; 1944d135368dSVille Syrjälä 1945d135368dSVille Syrjälä intel_de_write(i915, PORT_CLK_SEL(port), hsw_pll_to_ddi_pll_sel(pll)); 1946d135368dSVille Syrjälä } 1947d135368dSVille Syrjälä 1948d135368dSVille Syrjälä void hsw_ddi_disable_clock(struct intel_encoder *encoder) 1949d135368dSVille Syrjälä { 1950d135368dSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 1951d135368dSVille Syrjälä enum port port = encoder->port; 1952d135368dSVille Syrjälä 1953d135368dSVille Syrjälä intel_de_write(i915, PORT_CLK_SEL(port), PORT_CLK_SEL_NONE); 1954d135368dSVille Syrjälä } 1955d135368dSVille Syrjälä 19560fbd8694SVille Syrjälä bool hsw_ddi_is_clock_enabled(struct intel_encoder *encoder) 19570fbd8694SVille Syrjälä { 19580fbd8694SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 19590fbd8694SVille Syrjälä enum port port = encoder->port; 19600fbd8694SVille Syrjälä 19610fbd8694SVille Syrjälä return intel_de_read(i915, PORT_CLK_SEL(port)) != PORT_CLK_SEL_NONE; 19620fbd8694SVille Syrjälä } 19630fbd8694SVille Syrjälä 1964351221ffSVille Syrjälä static struct intel_shared_dpll *hsw_ddi_get_pll(struct intel_encoder *encoder) 1965351221ffSVille Syrjälä { 1966351221ffSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 1967351221ffSVille Syrjälä enum port port = encoder->port; 1968351221ffSVille Syrjälä enum intel_dpll_id id; 1969351221ffSVille Syrjälä u32 tmp; 1970351221ffSVille Syrjälä 1971351221ffSVille Syrjälä tmp = intel_de_read(i915, PORT_CLK_SEL(port)); 1972351221ffSVille Syrjälä 1973351221ffSVille Syrjälä switch (tmp & PORT_CLK_SEL_MASK) { 1974351221ffSVille Syrjälä case PORT_CLK_SEL_WRPLL1: 1975351221ffSVille Syrjälä id = DPLL_ID_WRPLL1; 1976351221ffSVille Syrjälä break; 1977351221ffSVille Syrjälä case PORT_CLK_SEL_WRPLL2: 1978351221ffSVille Syrjälä id = DPLL_ID_WRPLL2; 1979351221ffSVille Syrjälä break; 1980351221ffSVille Syrjälä case PORT_CLK_SEL_SPLL: 1981351221ffSVille Syrjälä id = DPLL_ID_SPLL; 1982351221ffSVille Syrjälä break; 1983351221ffSVille Syrjälä case PORT_CLK_SEL_LCPLL_810: 1984351221ffSVille Syrjälä id = DPLL_ID_LCPLL_810; 1985351221ffSVille Syrjälä break; 1986351221ffSVille Syrjälä case PORT_CLK_SEL_LCPLL_1350: 1987351221ffSVille Syrjälä id = DPLL_ID_LCPLL_1350; 1988351221ffSVille Syrjälä break; 1989351221ffSVille Syrjälä case PORT_CLK_SEL_LCPLL_2700: 1990351221ffSVille Syrjälä id = DPLL_ID_LCPLL_2700; 1991351221ffSVille Syrjälä break; 1992351221ffSVille Syrjälä default: 1993351221ffSVille Syrjälä MISSING_CASE(tmp); 1994351221ffSVille Syrjälä fallthrough; 1995351221ffSVille Syrjälä case PORT_CLK_SEL_NONE: 1996351221ffSVille Syrjälä return NULL; 1997351221ffSVille Syrjälä } 1998351221ffSVille Syrjälä 1999351221ffSVille Syrjälä return intel_get_shared_dpll_by_id(i915, id); 2000351221ffSVille Syrjälä } 2001351221ffSVille Syrjälä 2002c133df69SVille Syrjälä void intel_ddi_enable_clock(struct intel_encoder *encoder, 2003c133df69SVille Syrjälä const struct intel_crtc_state *crtc_state) 2004c133df69SVille Syrjälä { 2005c133df69SVille Syrjälä if (encoder->enable_clock) 2006c133df69SVille Syrjälä encoder->enable_clock(encoder, crtc_state); 2007c133df69SVille Syrjälä } 2008c133df69SVille Syrjälä 2009d39ef5d5SVille Syrjälä void intel_ddi_disable_clock(struct intel_encoder *encoder) 2010c133df69SVille Syrjälä { 2011c133df69SVille Syrjälä if (encoder->disable_clock) 2012c133df69SVille Syrjälä encoder->disable_clock(encoder); 2013c133df69SVille Syrjälä } 2014c133df69SVille Syrjälä 2015aaca50efSVille Syrjälä void intel_ddi_sanitize_encoder_pll_mapping(struct intel_encoder *encoder) 2016dc1ddac6SVille Syrjälä { 201797a24a70SVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 2018dc1ddac6SVille Syrjälä u32 port_mask; 2019dc1ddac6SVille Syrjälä bool ddi_clk_needed; 2020dc1ddac6SVille Syrjälä 2021dc1ddac6SVille Syrjälä /* 2022dc1ddac6SVille Syrjälä * In case of DP MST, we sanitize the primary encoder only, not the 2023dc1ddac6SVille Syrjälä * virtual ones. 2024dc1ddac6SVille Syrjälä */ 2025dc1ddac6SVille Syrjälä if (encoder->type == INTEL_OUTPUT_DP_MST) 2026dc1ddac6SVille Syrjälä return; 2027dc1ddac6SVille Syrjälä 2028dc1ddac6SVille Syrjälä if (!encoder->base.crtc && intel_encoder_is_dp(encoder)) { 2029dc1ddac6SVille Syrjälä u8 pipe_mask; 2030dc1ddac6SVille Syrjälä bool is_mst; 2031dc1ddac6SVille Syrjälä 2032dc1ddac6SVille Syrjälä intel_ddi_get_encoder_pipes(encoder, &pipe_mask, &is_mst); 2033dc1ddac6SVille Syrjälä /* 2034dc1ddac6SVille Syrjälä * In the unlikely case that BIOS enables DP in MST mode, just 2035dc1ddac6SVille Syrjälä * warn since our MST HW readout is incomplete. 2036dc1ddac6SVille Syrjälä */ 203797a24a70SVille Syrjälä if (drm_WARN_ON(&i915->drm, is_mst)) 2038dc1ddac6SVille Syrjälä return; 2039dc1ddac6SVille Syrjälä } 2040dc1ddac6SVille Syrjälä 2041dc1ddac6SVille Syrjälä port_mask = BIT(encoder->port); 2042dc1ddac6SVille Syrjälä ddi_clk_needed = encoder->base.crtc; 2043dc1ddac6SVille Syrjälä 2044dc1ddac6SVille Syrjälä if (encoder->type == INTEL_OUTPUT_DSI) { 2045dc1ddac6SVille Syrjälä struct intel_encoder *other_encoder; 2046dc1ddac6SVille Syrjälä 2047dc1ddac6SVille Syrjälä port_mask = intel_dsi_encoder_ports(encoder); 2048dc1ddac6SVille Syrjälä /* 2049dc1ddac6SVille Syrjälä * Sanity check that we haven't incorrectly registered another 2050dc1ddac6SVille Syrjälä * encoder using any of the ports of this DSI encoder. 2051dc1ddac6SVille Syrjälä */ 205297a24a70SVille Syrjälä for_each_intel_encoder(&i915->drm, other_encoder) { 2053dc1ddac6SVille Syrjälä if (other_encoder == encoder) 2054dc1ddac6SVille Syrjälä continue; 2055dc1ddac6SVille Syrjälä 205697a24a70SVille Syrjälä if (drm_WARN_ON(&i915->drm, 2057dc1ddac6SVille Syrjälä port_mask & BIT(other_encoder->port))) 2058dc1ddac6SVille Syrjälä return; 2059dc1ddac6SVille Syrjälä } 2060dc1ddac6SVille Syrjälä /* 2061dc1ddac6SVille Syrjälä * For DSI we keep the ddi clocks gated 2062dc1ddac6SVille Syrjälä * except during enable/disable sequence. 2063dc1ddac6SVille Syrjälä */ 2064dc1ddac6SVille Syrjälä ddi_clk_needed = false; 2065dc1ddac6SVille Syrjälä } 2066dc1ddac6SVille Syrjälä 2067f82f2563SMatt Roper if (ddi_clk_needed || !encoder->is_clock_enabled || 20680fbd8694SVille Syrjälä !encoder->is_clock_enabled(encoder)) 20690fbd8694SVille Syrjälä return; 20700fbd8694SVille Syrjälä 20710fbd8694SVille Syrjälä drm_notice(&i915->drm, 20720fbd8694SVille Syrjälä "[ENCODER:%d:%s] is disabled/in DSI mode with an ungated DDI clock, gate it\n", 20730fbd8694SVille Syrjälä encoder->base.base.id, encoder->base.name); 20740fbd8694SVille Syrjälä 2075dc1ddac6SVille Syrjälä encoder->disable_clock(encoder); 2076dc1ddac6SVille Syrjälä } 2077dc1ddac6SVille Syrjälä 20788aaf5cbdSJosé Roberto de Souza static void 20797801f3b7SLucas De Marchi icl_program_mg_dp_mode(struct intel_digital_port *dig_port, 20803b51be4eSClinton A Taylor const struct intel_crtc_state *crtc_state) 2081379bc100SJani Nikula { 20827801f3b7SLucas De Marchi struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); 20837801f3b7SLucas De Marchi enum tc_port tc_port = intel_port_to_tc(dev_priv, dig_port->base.port); 20845b6a9ba9SVille Syrjälä enum phy phy = intel_port_to_phy(dev_priv, dig_port->base.port); 20853b51be4eSClinton A Taylor u32 ln0, ln1, pin_assignment; 20863b51be4eSClinton A Taylor u8 width; 2087379bc100SJani Nikula 20885b6a9ba9SVille Syrjälä if (!intel_phy_is_tc(dev_priv, phy) || 208911a89708SImre Deak intel_tc_port_in_tbt_alt_mode(dig_port)) 2090379bc100SJani Nikula return; 2091379bc100SJani Nikula 2092005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 12) { 2093b8ed5533SImre Deak ln0 = intel_dkl_phy_read(dev_priv, DKL_DP_MODE(tc_port, 0)); 2094b8ed5533SImre Deak ln1 = intel_dkl_phy_read(dev_priv, DKL_DP_MODE(tc_port, 1)); 2095978c3e53SClinton A Taylor } else { 2096f7960e7fSJani Nikula ln0 = intel_de_read(dev_priv, MG_DP_MODE(0, tc_port)); 2097f7960e7fSJani Nikula ln1 = intel_de_read(dev_priv, MG_DP_MODE(1, tc_port)); 2098978c3e53SClinton A Taylor } 2099379bc100SJani Nikula 21004f72a8eeSKhaled Almahallawy ln0 &= ~(MG_DP_MODE_CFG_DP_X1_MODE | MG_DP_MODE_CFG_DP_X2_MODE); 2101379bc100SJani Nikula ln1 &= ~(MG_DP_MODE_CFG_DP_X1_MODE | MG_DP_MODE_CFG_DP_X2_MODE); 2102379bc100SJani Nikula 21033b51be4eSClinton A Taylor /* DPPATC */ 21047801f3b7SLucas De Marchi pin_assignment = intel_tc_port_get_pin_assignment_mask(dig_port); 21053b51be4eSClinton A Taylor width = crtc_state->lane_count; 2106379bc100SJani Nikula 21073b51be4eSClinton A Taylor switch (pin_assignment) { 21083b51be4eSClinton A Taylor case 0x0: 21091de143ccSPankaj Bharadiya drm_WARN_ON(&dev_priv->drm, 211011a89708SImre Deak !intel_tc_port_in_legacy_mode(dig_port)); 21113b51be4eSClinton A Taylor if (width == 1) { 2112379bc100SJani Nikula ln1 |= MG_DP_MODE_CFG_DP_X1_MODE; 21133b51be4eSClinton A Taylor } else { 21143b51be4eSClinton A Taylor ln0 |= MG_DP_MODE_CFG_DP_X2_MODE; 21153b51be4eSClinton A Taylor ln1 |= MG_DP_MODE_CFG_DP_X2_MODE; 2116379bc100SJani Nikula } 2117379bc100SJani Nikula break; 21183b51be4eSClinton A Taylor case 0x1: 21193b51be4eSClinton A Taylor if (width == 4) { 21203b51be4eSClinton A Taylor ln0 |= MG_DP_MODE_CFG_DP_X2_MODE; 21213b51be4eSClinton A Taylor ln1 |= MG_DP_MODE_CFG_DP_X2_MODE; 21223b51be4eSClinton A Taylor } 2123379bc100SJani Nikula break; 21243b51be4eSClinton A Taylor case 0x2: 21253b51be4eSClinton A Taylor if (width == 2) { 21263b51be4eSClinton A Taylor ln0 |= MG_DP_MODE_CFG_DP_X2_MODE; 21273b51be4eSClinton A Taylor ln1 |= MG_DP_MODE_CFG_DP_X2_MODE; 21283b51be4eSClinton A Taylor } 21293b51be4eSClinton A Taylor break; 21303b51be4eSClinton A Taylor case 0x3: 21313b51be4eSClinton A Taylor case 0x5: 21323b51be4eSClinton A Taylor if (width == 1) { 21333b51be4eSClinton A Taylor ln0 |= MG_DP_MODE_CFG_DP_X1_MODE; 21343b51be4eSClinton A Taylor ln1 |= MG_DP_MODE_CFG_DP_X1_MODE; 21353b51be4eSClinton A Taylor } else { 21363b51be4eSClinton A Taylor ln0 |= MG_DP_MODE_CFG_DP_X2_MODE; 21373b51be4eSClinton A Taylor ln1 |= MG_DP_MODE_CFG_DP_X2_MODE; 21383b51be4eSClinton A Taylor } 21393b51be4eSClinton A Taylor break; 21403b51be4eSClinton A Taylor case 0x4: 21413b51be4eSClinton A Taylor case 0x6: 21423b51be4eSClinton A Taylor if (width == 1) { 21433b51be4eSClinton A Taylor ln0 |= MG_DP_MODE_CFG_DP_X1_MODE; 21443b51be4eSClinton A Taylor ln1 |= MG_DP_MODE_CFG_DP_X1_MODE; 21453b51be4eSClinton A Taylor } else { 21463b51be4eSClinton A Taylor ln0 |= MG_DP_MODE_CFG_DP_X2_MODE; 21473b51be4eSClinton A Taylor ln1 |= MG_DP_MODE_CFG_DP_X2_MODE; 21483b51be4eSClinton A Taylor } 21493b51be4eSClinton A Taylor break; 2150379bc100SJani Nikula default: 21513b51be4eSClinton A Taylor MISSING_CASE(pin_assignment); 2152379bc100SJani Nikula } 2153379bc100SJani Nikula 2154005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 12) { 2155b8ed5533SImre Deak intel_dkl_phy_write(dev_priv, DKL_DP_MODE(tc_port, 0), ln0); 2156b8ed5533SImre Deak intel_dkl_phy_write(dev_priv, DKL_DP_MODE(tc_port, 1), ln1); 2157978c3e53SClinton A Taylor } else { 2158f7960e7fSJani Nikula intel_de_write(dev_priv, MG_DP_MODE(0, tc_port), ln0); 2159f7960e7fSJani Nikula intel_de_write(dev_priv, MG_DP_MODE(1, tc_port), ln1); 2160379bc100SJani Nikula } 2161978c3e53SClinton A Taylor } 2162379bc100SJani Nikula 2163ef79fafeSVille Syrjälä static enum transcoder 2164ef79fafeSVille Syrjälä tgl_dp_tp_transcoder(const struct intel_crtc_state *crtc_state) 2165ef79fafeSVille Syrjälä { 2166ef79fafeSVille Syrjälä if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) 2167ef79fafeSVille Syrjälä return crtc_state->mst_master_transcoder; 2168ef79fafeSVille Syrjälä else 2169ef79fafeSVille Syrjälä return crtc_state->cpu_transcoder; 2170ef79fafeSVille Syrjälä } 2171ef79fafeSVille Syrjälä 2172ef79fafeSVille Syrjälä i915_reg_t dp_tp_ctl_reg(struct intel_encoder *encoder, 2173ef79fafeSVille Syrjälä const struct intel_crtc_state *crtc_state) 2174ef79fafeSVille Syrjälä { 2175ef79fafeSVille Syrjälä struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 2176ef79fafeSVille Syrjälä 2177005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 12) 2178ef79fafeSVille Syrjälä return TGL_DP_TP_CTL(tgl_dp_tp_transcoder(crtc_state)); 2179ef79fafeSVille Syrjälä else 2180ef79fafeSVille Syrjälä return DP_TP_CTL(encoder->port); 2181ef79fafeSVille Syrjälä } 2182ef79fafeSVille Syrjälä 2183ef79fafeSVille Syrjälä i915_reg_t dp_tp_status_reg(struct intel_encoder *encoder, 2184ef79fafeSVille Syrjälä const struct intel_crtc_state *crtc_state) 2185ef79fafeSVille Syrjälä { 2186ef79fafeSVille Syrjälä struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 2187ef79fafeSVille Syrjälä 2188005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 12) 2189ef79fafeSVille Syrjälä return TGL_DP_TP_STATUS(tgl_dp_tp_transcoder(crtc_state)); 2190ef79fafeSVille Syrjälä else 2191ef79fafeSVille Syrjälä return DP_TP_STATUS(encoder->port); 2192ef79fafeSVille Syrjälä } 2193ef79fafeSVille Syrjälä 21941639406aSManasi Navare static void intel_dp_sink_set_msa_timing_par_ignore_state(struct intel_dp *intel_dp, 21951639406aSManasi Navare const struct intel_crtc_state *crtc_state, 21961639406aSManasi Navare bool enable) 21971639406aSManasi Navare { 21981639406aSManasi Navare struct drm_i915_private *i915 = dp_to_i915(intel_dp); 21991639406aSManasi Navare 22001639406aSManasi Navare if (!crtc_state->vrr.enable) 22011639406aSManasi Navare return; 22021639406aSManasi Navare 22031639406aSManasi Navare if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_DOWNSPREAD_CTRL, 22041639406aSManasi Navare enable ? DP_MSA_TIMING_PAR_IGNORE_EN : 0) <= 0) 22051639406aSManasi Navare drm_dbg_kms(&i915->drm, 22060868b1ceSVille Syrjälä "Failed to %s MSA_TIMING_PAR_IGNORE in the sink\n", 2207707c3a7dSLucas De Marchi str_enable_disable(enable)); 22081639406aSManasi Navare } 22091639406aSManasi Navare 2210379bc100SJani Nikula static void intel_dp_sink_set_fec_ready(struct intel_dp *intel_dp, 2211379bc100SJani Nikula const struct intel_crtc_state *crtc_state) 2212379bc100SJani Nikula { 221347bdb1caSJani Nikula struct drm_i915_private *i915 = dp_to_i915(intel_dp); 221447bdb1caSJani Nikula 2215379bc100SJani Nikula if (!crtc_state->fec_enable) 2216379bc100SJani Nikula return; 2217379bc100SJani Nikula 2218379bc100SJani Nikula if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_FEC_CONFIGURATION, DP_FEC_READY) <= 0) 221947bdb1caSJani Nikula drm_dbg_kms(&i915->drm, 222047bdb1caSJani Nikula "Failed to set FEC_READY in the sink\n"); 2221379bc100SJani Nikula } 2222379bc100SJani Nikula 2223379bc100SJani Nikula static void intel_ddi_enable_fec(struct intel_encoder *encoder, 2224379bc100SJani Nikula const struct intel_crtc_state *crtc_state) 2225379bc100SJani Nikula { 2226379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 22274444df6eSLucas De Marchi struct intel_dp *intel_dp; 2228379bc100SJani Nikula 2229379bc100SJani Nikula if (!crtc_state->fec_enable) 2230379bc100SJani Nikula return; 2231379bc100SJani Nikula 2232b7d02c3aSVille Syrjälä intel_dp = enc_to_intel_dp(encoder); 22338910d8b7SAndrzej Hajda intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), 22348910d8b7SAndrzej Hajda 0, DP_TP_CTL_FEC_ENABLE); 2235379bc100SJani Nikula } 2236379bc100SJani Nikula 2237379bc100SJani Nikula static void intel_ddi_disable_fec_state(struct intel_encoder *encoder, 2238379bc100SJani Nikula const struct intel_crtc_state *crtc_state) 2239379bc100SJani Nikula { 2240379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 22414444df6eSLucas De Marchi struct intel_dp *intel_dp; 2242379bc100SJani Nikula 2243379bc100SJani Nikula if (!crtc_state->fec_enable) 2244379bc100SJani Nikula return; 2245379bc100SJani Nikula 2246b7d02c3aSVille Syrjälä intel_dp = enc_to_intel_dp(encoder); 22478910d8b7SAndrzej Hajda intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), 22488910d8b7SAndrzej Hajda DP_TP_CTL_FEC_ENABLE, 0); 2249ef79fafeSVille Syrjälä intel_de_posting_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state)); 2250379bc100SJani Nikula } 2251379bc100SJani Nikula 22525cdf706fSVille Syrjälä static void intel_ddi_power_up_lanes(struct intel_encoder *encoder, 22535cdf706fSVille Syrjälä const struct intel_crtc_state *crtc_state) 22545cdf706fSVille Syrjälä { 22555cdf706fSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 22565cdf706fSVille Syrjälä struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 22575cdf706fSVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 22585cdf706fSVille Syrjälä 22595cdf706fSVille Syrjälä if (intel_phy_is_combo(i915, phy)) { 22605cdf706fSVille Syrjälä bool lane_reversal = 22615cdf706fSVille Syrjälä dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL; 22625cdf706fSVille Syrjälä 22635cdf706fSVille Syrjälä intel_combo_phy_power_up_lanes(i915, phy, false, 22645cdf706fSVille Syrjälä crtc_state->lane_count, 22655cdf706fSVille Syrjälä lane_reversal); 22665cdf706fSVille Syrjälä } 22675cdf706fSVille Syrjälä } 22685cdf706fSVille Syrjälä 2269f6864b27SJani Nikula /* Splitter enable for eDP MSO is limited to certain pipes. */ 2270f6864b27SJani Nikula static u8 intel_ddi_splitter_pipe_mask(struct drm_i915_private *i915) 2271f6864b27SJani Nikula { 2272f6864b27SJani Nikula if (IS_ALDERLAKE_P(i915)) 2273f6864b27SJani Nikula return BIT(PIPE_A) | BIT(PIPE_B); 2274f6864b27SJani Nikula else 2275f6864b27SJani Nikula return BIT(PIPE_A); 2276f6864b27SJani Nikula } 2277f6864b27SJani Nikula 22785b616a29SJani Nikula static void intel_ddi_mso_get_config(struct intel_encoder *encoder, 22795b616a29SJani Nikula struct intel_crtc_state *pipe_config) 22805b616a29SJani Nikula { 22815b616a29SJani Nikula struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); 22825b616a29SJani Nikula struct drm_i915_private *i915 = to_i915(crtc->base.dev); 22835b616a29SJani Nikula enum pipe pipe = crtc->pipe; 22845b616a29SJani Nikula u32 dss1; 22855b616a29SJani Nikula 22865b616a29SJani Nikula if (!HAS_MSO(i915)) 22875b616a29SJani Nikula return; 22885b616a29SJani Nikula 22895b616a29SJani Nikula dss1 = intel_de_read(i915, ICL_PIPE_DSS_CTL1(pipe)); 22905b616a29SJani Nikula 22915b616a29SJani Nikula pipe_config->splitter.enable = dss1 & SPLITTER_ENABLE; 22925b616a29SJani Nikula if (!pipe_config->splitter.enable) 22935b616a29SJani Nikula return; 22945b616a29SJani Nikula 2295f6864b27SJani Nikula if (drm_WARN_ON(&i915->drm, !(intel_ddi_splitter_pipe_mask(i915) & BIT(pipe)))) { 22965b616a29SJani Nikula pipe_config->splitter.enable = false; 22975b616a29SJani Nikula return; 22985b616a29SJani Nikula } 22995b616a29SJani Nikula 23005b616a29SJani Nikula switch (dss1 & SPLITTER_CONFIGURATION_MASK) { 23015b616a29SJani Nikula default: 23025b616a29SJani Nikula drm_WARN(&i915->drm, true, 23035b616a29SJani Nikula "Invalid splitter configuration, dss1=0x%08x\n", dss1); 23045b616a29SJani Nikula fallthrough; 23055b616a29SJani Nikula case SPLITTER_CONFIGURATION_2_SEGMENT: 23065b616a29SJani Nikula pipe_config->splitter.link_count = 2; 23075b616a29SJani Nikula break; 23085b616a29SJani Nikula case SPLITTER_CONFIGURATION_4_SEGMENT: 23095b616a29SJani Nikula pipe_config->splitter.link_count = 4; 23105b616a29SJani Nikula break; 23115b616a29SJani Nikula } 23125b616a29SJani Nikula 23135b616a29SJani Nikula pipe_config->splitter.pixel_overlap = REG_FIELD_GET(OVERLAP_PIXELS_MASK, dss1); 23145b616a29SJani Nikula } 23155b616a29SJani Nikula 2316bc71194eSJani Nikula static void intel_ddi_mso_configure(const struct intel_crtc_state *crtc_state) 2317bc71194eSJani Nikula { 2318bc71194eSJani Nikula struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 2319bc71194eSJani Nikula struct drm_i915_private *i915 = to_i915(crtc->base.dev); 2320bc71194eSJani Nikula enum pipe pipe = crtc->pipe; 2321bc71194eSJani Nikula u32 dss1 = 0; 2322bc71194eSJani Nikula 2323bc71194eSJani Nikula if (!HAS_MSO(i915)) 2324bc71194eSJani Nikula return; 2325bc71194eSJani Nikula 2326bc71194eSJani Nikula if (crtc_state->splitter.enable) { 2327bc71194eSJani Nikula dss1 |= SPLITTER_ENABLE; 2328bc71194eSJani Nikula dss1 |= OVERLAP_PIXELS(crtc_state->splitter.pixel_overlap); 2329bc71194eSJani Nikula if (crtc_state->splitter.link_count == 2) 2330bc71194eSJani Nikula dss1 |= SPLITTER_CONFIGURATION_2_SEGMENT; 2331bc71194eSJani Nikula else 2332bc71194eSJani Nikula dss1 |= SPLITTER_CONFIGURATION_4_SEGMENT; 2333bc71194eSJani Nikula } 2334bc71194eSJani Nikula 2335bc71194eSJani Nikula intel_de_rmw(i915, ICL_PIPE_DSS_CTL1(pipe), 2336bc71194eSJani Nikula SPLITTER_ENABLE | SPLITTER_CONFIGURATION_MASK | 2337bc71194eSJani Nikula OVERLAP_PIXELS_MASK, dss1); 2338bc71194eSJani Nikula } 2339bc71194eSJani Nikula 234023ef6194SJosé Roberto de Souza static u8 mtl_get_port_width(u8 lane_count) 234123ef6194SJosé Roberto de Souza { 234223ef6194SJosé Roberto de Souza switch (lane_count) { 234323ef6194SJosé Roberto de Souza case 1: 234423ef6194SJosé Roberto de Souza return 0; 234523ef6194SJosé Roberto de Souza case 2: 234623ef6194SJosé Roberto de Souza return 1; 234723ef6194SJosé Roberto de Souza case 3: 234823ef6194SJosé Roberto de Souza return 4; 234923ef6194SJosé Roberto de Souza case 4: 235023ef6194SJosé Roberto de Souza return 3; 235123ef6194SJosé Roberto de Souza default: 235223ef6194SJosé Roberto de Souza MISSING_CASE(lane_count); 235323ef6194SJosé Roberto de Souza return 4; 235423ef6194SJosé Roberto de Souza } 235523ef6194SJosé Roberto de Souza } 235623ef6194SJosé Roberto de Souza 235723ef6194SJosé Roberto de Souza static void 235823ef6194SJosé Roberto de Souza mtl_ddi_enable_d2d(struct intel_encoder *encoder) 235923ef6194SJosé Roberto de Souza { 236023ef6194SJosé Roberto de Souza struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 236123ef6194SJosé Roberto de Souza enum port port = encoder->port; 236223ef6194SJosé Roberto de Souza 236323ef6194SJosé Roberto de Souza intel_de_rmw(dev_priv, XELPDP_PORT_BUF_CTL1(port), 0, 236423ef6194SJosé Roberto de Souza XELPDP_PORT_BUF_D2D_LINK_ENABLE); 236523ef6194SJosé Roberto de Souza 236623ef6194SJosé Roberto de Souza if (wait_for_us((intel_de_read(dev_priv, XELPDP_PORT_BUF_CTL1(port)) & 236723ef6194SJosé Roberto de Souza XELPDP_PORT_BUF_D2D_LINK_STATE), 100)) { 236823ef6194SJosé Roberto de Souza drm_err(&dev_priv->drm, "Timeout waiting for D2D Link enable for PORT_BUF_CTL %c\n", 236923ef6194SJosé Roberto de Souza port_name(port)); 237023ef6194SJosé Roberto de Souza } 237123ef6194SJosé Roberto de Souza } 237223ef6194SJosé Roberto de Souza 237323ef6194SJosé Roberto de Souza static void mtl_port_buf_ctl_program(struct intel_encoder *encoder, 237423ef6194SJosé Roberto de Souza const struct intel_crtc_state *crtc_state) 237523ef6194SJosé Roberto de Souza { 237623ef6194SJosé Roberto de Souza struct drm_i915_private *i915 = to_i915(encoder->base.dev); 237723ef6194SJosé Roberto de Souza struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 237823ef6194SJosé Roberto de Souza enum port port = encoder->port; 237923ef6194SJosé Roberto de Souza u32 val; 238023ef6194SJosé Roberto de Souza 238123ef6194SJosé Roberto de Souza val = intel_de_read(i915, XELPDP_PORT_BUF_CTL1(port)); 238223ef6194SJosé Roberto de Souza val &= ~XELPDP_PORT_WIDTH_MASK; 238323ef6194SJosé Roberto de Souza val |= XELPDP_PORT_WIDTH(mtl_get_port_width(crtc_state->lane_count)); 238423ef6194SJosé Roberto de Souza 238523ef6194SJosé Roberto de Souza val &= ~XELPDP_PORT_BUF_PORT_DATA_WIDTH_MASK; 238623ef6194SJosé Roberto de Souza if (intel_dp_is_uhbr(crtc_state)) 238723ef6194SJosé Roberto de Souza val |= XELPDP_PORT_BUF_PORT_DATA_40BIT; 238823ef6194SJosé Roberto de Souza else 238923ef6194SJosé Roberto de Souza val |= XELPDP_PORT_BUF_PORT_DATA_10BIT; 239023ef6194SJosé Roberto de Souza 239123ef6194SJosé Roberto de Souza if (dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL) 239223ef6194SJosé Roberto de Souza val |= XELPDP_PORT_REVERSAL; 239323ef6194SJosé Roberto de Souza 239423ef6194SJosé Roberto de Souza intel_de_write(i915, XELPDP_PORT_BUF_CTL1(port), val); 239523ef6194SJosé Roberto de Souza } 239623ef6194SJosé Roberto de Souza 239723ef6194SJosé Roberto de Souza static void mtl_port_buf_ctl_io_selection(struct intel_encoder *encoder) 239823ef6194SJosé Roberto de Souza { 239923ef6194SJosé Roberto de Souza struct drm_i915_private *i915 = to_i915(encoder->base.dev); 240023ef6194SJosé Roberto de Souza struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 240123ef6194SJosé Roberto de Souza u32 val; 240223ef6194SJosé Roberto de Souza 240323ef6194SJosé Roberto de Souza val = intel_tc_port_in_tbt_alt_mode(dig_port) ? 240423ef6194SJosé Roberto de Souza XELPDP_PORT_BUF_IO_SELECT_TBT : 0; 240523ef6194SJosé Roberto de Souza intel_de_rmw(i915, XELPDP_PORT_BUF_CTL1(encoder->port), 240623ef6194SJosé Roberto de Souza XELPDP_PORT_BUF_IO_SELECT_TBT, val); 240723ef6194SJosé Roberto de Souza } 240823ef6194SJosé Roberto de Souza 240923ef6194SJosé Roberto de Souza static void mtl_ddi_pre_enable_dp(struct intel_atomic_state *state, 241023ef6194SJosé Roberto de Souza struct intel_encoder *encoder, 241123ef6194SJosé Roberto de Souza const struct intel_crtc_state *crtc_state, 241223ef6194SJosé Roberto de Souza const struct drm_connector_state *conn_state) 241323ef6194SJosé Roberto de Souza { 241423ef6194SJosé Roberto de Souza struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 241523ef6194SJosé Roberto de Souza bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); 241623ef6194SJosé Roberto de Souza 241723ef6194SJosé Roberto de Souza intel_dp_set_link_params(intel_dp, 241823ef6194SJosé Roberto de Souza crtc_state->port_clock, 241923ef6194SJosé Roberto de Souza crtc_state->lane_count); 242023ef6194SJosé Roberto de Souza 242123ef6194SJosé Roberto de Souza /* 242223ef6194SJosé Roberto de Souza * We only configure what the register value will be here. Actual 242323ef6194SJosé Roberto de Souza * enabling happens during link training farther down. 242423ef6194SJosé Roberto de Souza */ 242523ef6194SJosé Roberto de Souza intel_ddi_init_dp_buf_reg(encoder, crtc_state); 242623ef6194SJosé Roberto de Souza 242723ef6194SJosé Roberto de Souza /* 242823ef6194SJosé Roberto de Souza * 1. Enable Power Wells 242923ef6194SJosé Roberto de Souza * 243023ef6194SJosé Roberto de Souza * This was handled at the beginning of intel_atomic_commit_tail(), 243123ef6194SJosé Roberto de Souza * before we called down into this function. 243223ef6194SJosé Roberto de Souza */ 243323ef6194SJosé Roberto de Souza 243423ef6194SJosé Roberto de Souza /* 2. PMdemand was already set */ 243523ef6194SJosé Roberto de Souza 243623ef6194SJosé Roberto de Souza /* 3. Select Thunderbolt */ 243723ef6194SJosé Roberto de Souza mtl_port_buf_ctl_io_selection(encoder); 243823ef6194SJosé Roberto de Souza 243923ef6194SJosé Roberto de Souza /* 4. Enable Panel Power if PPS is required */ 244023ef6194SJosé Roberto de Souza intel_pps_on(intel_dp); 244123ef6194SJosé Roberto de Souza 244223ef6194SJosé Roberto de Souza /* 5. Enable the port PLL */ 244323ef6194SJosé Roberto de Souza intel_ddi_enable_clock(encoder, crtc_state); 244423ef6194SJosé Roberto de Souza 244523ef6194SJosé Roberto de Souza /* 244623ef6194SJosé Roberto de Souza * 6.a Configure Transcoder Clock Select to direct the Port clock to the 244723ef6194SJosé Roberto de Souza * Transcoder. 244823ef6194SJosé Roberto de Souza */ 244923ef6194SJosé Roberto de Souza intel_ddi_enable_transcoder_clock(encoder, crtc_state); 245023ef6194SJosé Roberto de Souza 245123ef6194SJosé Roberto de Souza /* 245223ef6194SJosé Roberto de Souza * 6.b If DP v2.0/128b mode - Configure TRANS_DP2_CTL register settings. 245323ef6194SJosé Roberto de Souza */ 245423ef6194SJosé Roberto de Souza intel_ddi_config_transcoder_dp2(encoder, crtc_state); 245523ef6194SJosé Roberto de Souza 245623ef6194SJosé Roberto de Souza /* 245723ef6194SJosé Roberto de Souza * 6.c Configure TRANS_DDI_FUNC_CTL DDI Select, DDI Mode Select & MST 245823ef6194SJosé Roberto de Souza * Transport Select 245923ef6194SJosé Roberto de Souza */ 246023ef6194SJosé Roberto de Souza intel_ddi_config_transcoder_func(encoder, crtc_state); 246123ef6194SJosé Roberto de Souza 246223ef6194SJosé Roberto de Souza /* 246323ef6194SJosé Roberto de Souza * 6.e Program CoG/MSO configuration bits in DSS_CTL1 if selected. 246423ef6194SJosé Roberto de Souza */ 246523ef6194SJosé Roberto de Souza intel_ddi_mso_configure(crtc_state); 246623ef6194SJosé Roberto de Souza 246723ef6194SJosé Roberto de Souza if (!is_mst) 246823ef6194SJosé Roberto de Souza intel_dp_set_power(intel_dp, DP_SET_POWER_D0); 246923ef6194SJosé Roberto de Souza 247023ef6194SJosé Roberto de Souza intel_dp_configure_protocol_converter(intel_dp, crtc_state); 247123ef6194SJosé Roberto de Souza intel_dp_sink_set_decompression_state(intel_dp, crtc_state, true); 247223ef6194SJosé Roberto de Souza /* 247323ef6194SJosé Roberto de Souza * DDI FEC: "anticipates enabling FEC encoding sets the FEC_READY bit 247423ef6194SJosé Roberto de Souza * in the FEC_CONFIGURATION register to 1 before initiating link 247523ef6194SJosé Roberto de Souza * training 247623ef6194SJosé Roberto de Souza */ 247723ef6194SJosé Roberto de Souza intel_dp_sink_set_fec_ready(intel_dp, crtc_state); 247823ef6194SJosé Roberto de Souza 247923ef6194SJosé Roberto de Souza intel_dp_check_frl_training(intel_dp); 248023ef6194SJosé Roberto de Souza intel_dp_pcon_dsc_configure(intel_dp, crtc_state); 248123ef6194SJosé Roberto de Souza 248223ef6194SJosé Roberto de Souza /* 248323ef6194SJosé Roberto de Souza * 6. The rest of the below are substeps under the bspec's "Enable and 248423ef6194SJosé Roberto de Souza * Train Display Port" step. Note that steps that are specific to 248523ef6194SJosé Roberto de Souza * MST will be handled by intel_mst_pre_enable_dp() before/after it 248623ef6194SJosé Roberto de Souza * calls into this function. Also intel_mst_pre_enable_dp() only calls 248723ef6194SJosé Roberto de Souza * us when active_mst_links==0, so any steps designated for "single 248823ef6194SJosé Roberto de Souza * stream or multi-stream master transcoder" can just be performed 248923ef6194SJosé Roberto de Souza * unconditionally here. 249023ef6194SJosé Roberto de Souza * 249123ef6194SJosé Roberto de Souza * mtl_ddi_prepare_link_retrain() that is called by 249223ef6194SJosé Roberto de Souza * intel_dp_start_link_train() will execute steps: 6.d, 6.f, 6.g, 6.h, 249323ef6194SJosé Roberto de Souza * 6.i and 6.j 249423ef6194SJosé Roberto de Souza * 249523ef6194SJosé Roberto de Souza * 6.k Follow DisplayPort specification training sequence (see notes for 249623ef6194SJosé Roberto de Souza * failure handling) 249723ef6194SJosé Roberto de Souza * 6.m If DisplayPort multi-stream - Set DP_TP_CTL link training to Idle 249823ef6194SJosé Roberto de Souza * Pattern, wait for 5 idle patterns (DP_TP_STATUS Min_Idles_Sent) 249923ef6194SJosé Roberto de Souza * (timeout after 800 us) 250023ef6194SJosé Roberto de Souza */ 250123ef6194SJosé Roberto de Souza intel_dp_start_link_train(intel_dp, crtc_state); 250223ef6194SJosé Roberto de Souza 250323ef6194SJosé Roberto de Souza /* 6.n Set DP_TP_CTL link training to Normal */ 250423ef6194SJosé Roberto de Souza if (!is_trans_port_sync_mode(crtc_state)) 250523ef6194SJosé Roberto de Souza intel_dp_stop_link_train(intel_dp, crtc_state); 250623ef6194SJosé Roberto de Souza 250723ef6194SJosé Roberto de Souza /* 6.o Configure and enable FEC if needed */ 250823ef6194SJosé Roberto de Souza intel_ddi_enable_fec(encoder, crtc_state); 250923ef6194SJosé Roberto de Souza 251023ef6194SJosé Roberto de Souza intel_dsc_dp_pps_write(encoder, crtc_state); 251123ef6194SJosé Roberto de Souza } 251223ef6194SJosé Roberto de Souza 2513ede9771dSVille Syrjälä static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, 2514ede9771dSVille Syrjälä struct intel_encoder *encoder, 251599389390SJosé Roberto de Souza const struct intel_crtc_state *crtc_state, 251699389390SJosé Roberto de Souza const struct drm_connector_state *conn_state) 251799389390SJosé Roberto de Souza { 2518b7d02c3aSVille Syrjälä struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 251999389390SJosé Roberto de Souza struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 2520b7d02c3aSVille Syrjälä struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 252199389390SJosé Roberto de Souza bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); 252299389390SJosé Roberto de Souza 2523a621860aSVille Syrjälä intel_dp_set_link_params(intel_dp, 2524a621860aSVille Syrjälä crtc_state->port_clock, 2525a621860aSVille Syrjälä crtc_state->lane_count); 252699389390SJosé Roberto de Souza 25275e19c0b0SMatt Roper /* 25289f620f1dSVille Syrjälä * We only configure what the register value will be here. Actual 25299f620f1dSVille Syrjälä * enabling happens during link training farther down. 25309f620f1dSVille Syrjälä */ 25319f620f1dSVille Syrjälä intel_ddi_init_dp_buf_reg(encoder, crtc_state); 25329f620f1dSVille Syrjälä 25339f620f1dSVille Syrjälä /* 25345e19c0b0SMatt Roper * 1. Enable Power Wells 25355e19c0b0SMatt Roper * 25365e19c0b0SMatt Roper * This was handled at the beginning of intel_atomic_commit_tail(), 25375e19c0b0SMatt Roper * before we called down into this function. 25385e19c0b0SMatt Roper */ 253999389390SJosé Roberto de Souza 25405e19c0b0SMatt Roper /* 2. Enable Panel Power if PPS is required */ 2541eb46f498SJani Nikula intel_pps_on(intel_dp); 254299389390SJosé Roberto de Souza 254399389390SJosé Roberto de Souza /* 25445e19c0b0SMatt Roper * 3. For non-TBT Type-C ports, set FIA lane count 25455e19c0b0SMatt Roper * (DFLEXDPSP.DPX4TXLATC) 25465e19c0b0SMatt Roper * 25475e19c0b0SMatt Roper * This was done before tgl_ddi_pre_enable_dp by 25481e98f88cSLucas De Marchi * hsw_crtc_enable()->intel_encoders_pre_pll_enable(). 254999389390SJosé Roberto de Souza */ 255099389390SJosé Roberto de Souza 25515e19c0b0SMatt Roper /* 25525e19c0b0SMatt Roper * 4. Enable the port PLL. 25535e19c0b0SMatt Roper * 25545e19c0b0SMatt Roper * The PLL enabling itself was already done before this function by 25551e98f88cSLucas De Marchi * hsw_crtc_enable()->intel_enable_shared_dpll(). We need only 25565e19c0b0SMatt Roper * configure the PLL to port mapping here. 25575e19c0b0SMatt Roper */ 2558c133df69SVille Syrjälä intel_ddi_enable_clock(encoder, crtc_state); 25596171e58bSClinton A Taylor 25605e19c0b0SMatt Roper /* 5. If IO power is controlled through PWR_WELL_CTL, Enable IO Power */ 256111a89708SImre Deak if (!intel_tc_port_in_tbt_alt_mode(dig_port)) { 2562a4550977SImre Deak drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref); 2563a4550977SImre Deak dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv, 256499389390SJosé Roberto de Souza dig_port->ddi_io_power_domain); 2565a4550977SImre Deak } 256699389390SJosé Roberto de Souza 25675e19c0b0SMatt Roper /* 6. Program DP_MODE */ 25683b51be4eSClinton A Taylor icl_program_mg_dp_mode(dig_port, crtc_state); 256999389390SJosé Roberto de Souza 257099389390SJosé Roberto de Souza /* 25715e19c0b0SMatt Roper * 7. The rest of the below are substeps under the bspec's "Enable and 25725e19c0b0SMatt Roper * Train Display Port" step. Note that steps that are specific to 25735e19c0b0SMatt Roper * MST will be handled by intel_mst_pre_enable_dp() before/after it 25745e19c0b0SMatt Roper * calls into this function. Also intel_mst_pre_enable_dp() only calls 25755e19c0b0SMatt Roper * us when active_mst_links==0, so any steps designated for "single 25765e19c0b0SMatt Roper * stream or multi-stream master transcoder" can just be performed 25775e19c0b0SMatt Roper * unconditionally here. 25785e19c0b0SMatt Roper */ 25795e19c0b0SMatt Roper 25805e19c0b0SMatt Roper /* 25815e19c0b0SMatt Roper * 7.a Configure Transcoder Clock Select to direct the Port clock to the 25825e19c0b0SMatt Roper * Transcoder. 258399389390SJosé Roberto de Souza */ 258455a4679eSVille Syrjälä intel_ddi_enable_transcoder_clock(encoder, crtc_state); 258599389390SJosé Roberto de Souza 2586fe6959a6SVille Syrjälä if (HAS_DP20(dev_priv)) 2587fe6959a6SVille Syrjälä intel_ddi_config_transcoder_dp2(encoder, crtc_state); 2588fe6959a6SVille Syrjälä 25895e19c0b0SMatt Roper /* 25905e19c0b0SMatt Roper * 7.b Configure TRANS_DDI_FUNC_CTL DDI Select, DDI Mode Select & MST 25915e19c0b0SMatt Roper * Transport Select 25925e19c0b0SMatt Roper */ 2593eed22a46SVille Syrjälä intel_ddi_config_transcoder_func(encoder, crtc_state); 259499389390SJosé Roberto de Souza 25955e19c0b0SMatt Roper /* 25965e19c0b0SMatt Roper * 7.c Configure & enable DP_TP_CTL with link training pattern 1 25975e19c0b0SMatt Roper * selected 25985e19c0b0SMatt Roper * 25995e19c0b0SMatt Roper * This will be handled by the intel_dp_start_link_train() farther 26005e19c0b0SMatt Roper * down this function. 26015e19c0b0SMatt Roper */ 26025e19c0b0SMatt Roper 26035e19c0b0SMatt Roper /* 7.e Configure voltage swing and related IO settings */ 2604e722ab8bSVille Syrjälä encoder->set_signal_levels(encoder, crtc_state); 260599389390SJosé Roberto de Souza 26065e19c0b0SMatt Roper /* 26075e19c0b0SMatt Roper * 7.f Combo PHY: Configure PORT_CL_DW10 Static Power Down to power up 26085e19c0b0SMatt Roper * the used lanes of the DDI. 26095e19c0b0SMatt Roper */ 26105cdf706fSVille Syrjälä intel_ddi_power_up_lanes(encoder, crtc_state); 261199389390SJosé Roberto de Souza 26125e19c0b0SMatt Roper /* 2613bc71194eSJani Nikula * 7.g Program CoG/MSO configuration bits in DSS_CTL1 if selected. 2614bc71194eSJani Nikula */ 2615bc71194eSJani Nikula intel_ddi_mso_configure(crtc_state); 2616bc71194eSJani Nikula 261799389390SJosé Roberto de Souza if (!is_mst) 26180e634efdSVille Syrjälä intel_dp_set_power(intel_dp, DP_SET_POWER_D0); 261999389390SJosé Roberto de Souza 2620522508b6SAnkit Nautiyal intel_dp_configure_protocol_converter(intel_dp, crtc_state); 262199389390SJosé Roberto de Souza intel_dp_sink_set_decompression_state(intel_dp, crtc_state, true); 262299389390SJosé Roberto de Souza /* 262399389390SJosé Roberto de Souza * DDI FEC: "anticipates enabling FEC encoding sets the FEC_READY bit 262499389390SJosé Roberto de Souza * in the FEC_CONFIGURATION register to 1 before initiating link 262599389390SJosé Roberto de Souza * training 262699389390SJosé Roberto de Souza */ 262799389390SJosé Roberto de Souza intel_dp_sink_set_fec_ready(intel_dp, crtc_state); 26285e19c0b0SMatt Roper 26294f3dd47aSAnkit Nautiyal intel_dp_check_frl_training(intel_dp); 263010fec80bSAnkit Nautiyal intel_dp_pcon_dsc_configure(intel_dp, crtc_state); 26314f3dd47aSAnkit Nautiyal 26325e19c0b0SMatt Roper /* 26335e19c0b0SMatt Roper * 7.i Follow DisplayPort specification training sequence (see notes for 26345e19c0b0SMatt Roper * failure handling) 26355e19c0b0SMatt Roper * 7.j If DisplayPort multi-stream - Set DP_TP_CTL link training to Idle 26365e19c0b0SMatt Roper * Pattern, wait for 5 idle patterns (DP_TP_STATUS Min_Idles_Sent) 26375e19c0b0SMatt Roper * (timeout after 800 us) 26385e19c0b0SMatt Roper */ 2639a621860aSVille Syrjälä intel_dp_start_link_train(intel_dp, crtc_state); 264099389390SJosé Roberto de Souza 26415e19c0b0SMatt Roper /* 7.k Set DP_TP_CTL link training to Normal */ 2642eadf6f91SManasi Navare if (!is_trans_port_sync_mode(crtc_state)) 2643a621860aSVille Syrjälä intel_dp_stop_link_train(intel_dp, crtc_state); 264499389390SJosé Roberto de Souza 26455e19c0b0SMatt Roper /* 7.l Configure and enable FEC if needed */ 264699389390SJosé Roberto de Souza intel_ddi_enable_fec(encoder, crtc_state); 26473126977dSVille Syrjälä 26483126977dSVille Syrjälä intel_dsc_dp_pps_write(encoder, crtc_state); 264999389390SJosé Roberto de Souza } 265099389390SJosé Roberto de Souza 2651ede9771dSVille Syrjälä static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, 2652ede9771dSVille Syrjälä struct intel_encoder *encoder, 2653379bc100SJani Nikula const struct intel_crtc_state *crtc_state, 2654379bc100SJani Nikula const struct drm_connector_state *conn_state) 2655379bc100SJani Nikula { 2656b7d02c3aSVille Syrjälä struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 2657379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 2658379bc100SJani Nikula enum port port = encoder->port; 2659b7d02c3aSVille Syrjälä struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 2660379bc100SJani Nikula bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); 2661379bc100SJani Nikula 2662005e9537SMatt Roper if (DISPLAY_VER(dev_priv) < 11) 26631de143ccSPankaj Bharadiya drm_WARN_ON(&dev_priv->drm, 26641de143ccSPankaj Bharadiya is_mst && (port == PORT_A || port == PORT_E)); 2665542dfab5SJosé Roberto de Souza else 26661de143ccSPankaj Bharadiya drm_WARN_ON(&dev_priv->drm, is_mst && port == PORT_A); 2667379bc100SJani Nikula 2668a621860aSVille Syrjälä intel_dp_set_link_params(intel_dp, 2669a621860aSVille Syrjälä crtc_state->port_clock, 2670a621860aSVille Syrjälä crtc_state->lane_count); 2671379bc100SJani Nikula 26729f620f1dSVille Syrjälä /* 26739f620f1dSVille Syrjälä * We only configure what the register value will be here. Actual 26749f620f1dSVille Syrjälä * enabling happens during link training farther down. 26759f620f1dSVille Syrjälä */ 26769f620f1dSVille Syrjälä intel_ddi_init_dp_buf_reg(encoder, crtc_state); 26779f620f1dSVille Syrjälä 2678eb46f498SJani Nikula intel_pps_on(intel_dp); 2679379bc100SJani Nikula 2680c133df69SVille Syrjälä intel_ddi_enable_clock(encoder, crtc_state); 2681379bc100SJani Nikula 268211a89708SImre Deak if (!intel_tc_port_in_tbt_alt_mode(dig_port)) { 2683a4550977SImre Deak drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref); 2684a4550977SImre Deak dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv, 26853b2ed431SImre Deak dig_port->ddi_io_power_domain); 2686a4550977SImre Deak } 2687379bc100SJani Nikula 26883b51be4eSClinton A Taylor icl_program_mg_dp_mode(dig_port, crtc_state); 2689379bc100SJani Nikula 26905bafd85dSVille Syrjälä if (has_buf_trans_select(dev_priv)) 2691266152aeSVille Syrjälä hsw_prepare_dp_ddi_buffers(encoder, crtc_state); 2692379bc100SJani Nikula 2693e722ab8bSVille Syrjälä encoder->set_signal_levels(encoder, crtc_state); 2694e722ab8bSVille Syrjälä 26955cdf706fSVille Syrjälä intel_ddi_power_up_lanes(encoder, crtc_state); 2696379bc100SJani Nikula 2697379bc100SJani Nikula if (!is_mst) 26980e634efdSVille Syrjälä intel_dp_set_power(intel_dp, DP_SET_POWER_D0); 2699522508b6SAnkit Nautiyal intel_dp_configure_protocol_converter(intel_dp, crtc_state); 2700379bc100SJani Nikula intel_dp_sink_set_decompression_state(intel_dp, crtc_state, 2701379bc100SJani Nikula true); 2702379bc100SJani Nikula intel_dp_sink_set_fec_ready(intel_dp, crtc_state); 2703a621860aSVille Syrjälä intel_dp_start_link_train(intel_dp, crtc_state); 2704005e9537SMatt Roper if ((port != PORT_A || DISPLAY_VER(dev_priv) >= 9) && 2705eadf6f91SManasi Navare !is_trans_port_sync_mode(crtc_state)) 2706a621860aSVille Syrjälä intel_dp_stop_link_train(intel_dp, crtc_state); 2707379bc100SJani Nikula 2708379bc100SJani Nikula intel_ddi_enable_fec(encoder, crtc_state); 2709379bc100SJani Nikula 2710379bc100SJani Nikula if (!is_mst) 271155a4679eSVille Syrjälä intel_ddi_enable_transcoder_clock(encoder, crtc_state); 2712379bc100SJani Nikula 27133126977dSVille Syrjälä intel_dsc_dp_pps_write(encoder, crtc_state); 2714379bc100SJani Nikula } 2715379bc100SJani Nikula 2716ede9771dSVille Syrjälä static void intel_ddi_pre_enable_dp(struct intel_atomic_state *state, 2717ede9771dSVille Syrjälä struct intel_encoder *encoder, 271899389390SJosé Roberto de Souza const struct intel_crtc_state *crtc_state, 271999389390SJosé Roberto de Souza const struct drm_connector_state *conn_state) 272099389390SJosé Roberto de Souza { 272199389390SJosé Roberto de Souza struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 272299389390SJosé Roberto de Souza 27231a324a40SArun R Murthy if (HAS_DP20(dev_priv)) 27241a324a40SArun R Murthy intel_dp_128b132b_sdp_crc16(enc_to_intel_dp(encoder), 27251a324a40SArun R Murthy crtc_state); 27261a324a40SArun R Murthy 272723ef6194SJosé Roberto de Souza if (DISPLAY_VER(dev_priv) >= 14) 272823ef6194SJosé Roberto de Souza mtl_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state); 272923ef6194SJosé Roberto de Souza else if (DISPLAY_VER(dev_priv) >= 12) 2730ede9771dSVille Syrjälä tgl_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state); 273199389390SJosé Roberto de Souza else 2732ede9771dSVille Syrjälä hsw_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state); 27330c06fa15SGwan-gyeong Mun 2734bd8c9ccaSGwan-gyeong Mun /* MST will call a setting of MSA after an allocating of Virtual Channel 2735bd8c9ccaSGwan-gyeong Mun * from MST encoder pre_enable callback. 2736bd8c9ccaSGwan-gyeong Mun */ 27378de5df3bSVille Syrjälä if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) 27380c06fa15SGwan-gyeong Mun intel_ddi_set_dp_msa(crtc_state, conn_state); 27391fc1e8d4SJosé Roberto de Souza } 274099389390SJosé Roberto de Souza 2741ede9771dSVille Syrjälä static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state, 2742ede9771dSVille Syrjälä struct intel_encoder *encoder, 2743379bc100SJani Nikula const struct intel_crtc_state *crtc_state, 2744379bc100SJani Nikula const struct drm_connector_state *conn_state) 2745379bc100SJani Nikula { 27460ba7ffeaSLucas De Marchi struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 27470ba7ffeaSLucas De Marchi struct intel_hdmi *intel_hdmi = &dig_port->hdmi; 2748379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 2749379bc100SJani Nikula 2750379bc100SJani Nikula intel_dp_dual_mode_set_tmds_output(intel_hdmi, true); 2751c133df69SVille Syrjälä intel_ddi_enable_clock(encoder, crtc_state); 2752379bc100SJani Nikula 2753a4550977SImre Deak drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref); 2754a4550977SImre Deak dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv, 2755a4550977SImre Deak dig_port->ddi_io_power_domain); 2756379bc100SJani Nikula 27573b51be4eSClinton A Taylor icl_program_mg_dp_mode(dig_port, crtc_state); 2758379bc100SJani Nikula 275955a4679eSVille Syrjälä intel_ddi_enable_transcoder_clock(encoder, crtc_state); 2760379bc100SJani Nikula 27610ba7ffeaSLucas De Marchi dig_port->set_infoframes(encoder, 2762379bc100SJani Nikula crtc_state->has_infoframe, 2763379bc100SJani Nikula crtc_state, conn_state); 2764379bc100SJani Nikula } 2765379bc100SJani Nikula 2766ede9771dSVille Syrjälä static void intel_ddi_pre_enable(struct intel_atomic_state *state, 2767ede9771dSVille Syrjälä struct intel_encoder *encoder, 2768379bc100SJani Nikula const struct intel_crtc_state *crtc_state, 2769379bc100SJani Nikula const struct drm_connector_state *conn_state) 2770379bc100SJani Nikula { 27712225f3c6SMaarten Lankhorst struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 2772379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 2773379bc100SJani Nikula enum pipe pipe = crtc->pipe; 2774379bc100SJani Nikula 2775379bc100SJani Nikula /* 2776379bc100SJani Nikula * When called from DP MST code: 2777379bc100SJani Nikula * - conn_state will be NULL 2778379bc100SJani Nikula * - encoder will be the main encoder (ie. mst->primary) 2779379bc100SJani Nikula * - the main connector associated with this port 2780379bc100SJani Nikula * won't be active or linked to a crtc 2781379bc100SJani Nikula * - crtc_state will be the state of the first stream to 2782379bc100SJani Nikula * be activated on this port, and it may not be the same 2783379bc100SJani Nikula * stream that will be deactivated last, but each stream 2784379bc100SJani Nikula * should have a state that is identical when it comes to 2785379bc100SJani Nikula * the DP link parameteres 2786379bc100SJani Nikula */ 2787379bc100SJani Nikula 27881de143ccSPankaj Bharadiya drm_WARN_ON(&dev_priv->drm, crtc_state->has_pch_encoder); 2789379bc100SJani Nikula 2790379bc100SJani Nikula intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); 2791379bc100SJani Nikula 2792379bc100SJani Nikula if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { 2793ede9771dSVille Syrjälä intel_ddi_pre_enable_hdmi(state, encoder, crtc_state, 2794ede9771dSVille Syrjälä conn_state); 2795379bc100SJani Nikula } else { 2796f7af425dSVille Syrjälä struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 2797379bc100SJani Nikula 2798ede9771dSVille Syrjälä intel_ddi_pre_enable_dp(state, encoder, crtc_state, 2799ede9771dSVille Syrjälä conn_state); 2800379bc100SJani Nikula 2801f7af425dSVille Syrjälä /* FIXME precompute everything properly */ 28020ea02bb8SJosé Roberto de Souza /* FIXME how do we turn infoframes off again? */ 2803f7af425dSVille Syrjälä if (dig_port->lspcon.active && dig_port->dp.has_hdmi_sink) 2804379bc100SJani Nikula dig_port->set_infoframes(encoder, 2805379bc100SJani Nikula crtc_state->has_infoframe, 2806379bc100SJani Nikula crtc_state, conn_state); 2807379bc100SJani Nikula } 2808379bc100SJani Nikula } 2809379bc100SJani Nikula 281023ef6194SJosé Roberto de Souza static void 281123ef6194SJosé Roberto de Souza mtl_ddi_disable_d2d_link(struct intel_encoder *encoder) 281223ef6194SJosé Roberto de Souza { 281323ef6194SJosé Roberto de Souza struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 281423ef6194SJosé Roberto de Souza enum port port = encoder->port; 281523ef6194SJosé Roberto de Souza 281623ef6194SJosé Roberto de Souza intel_de_rmw(dev_priv, XELPDP_PORT_BUF_CTL1(port), 281723ef6194SJosé Roberto de Souza XELPDP_PORT_BUF_D2D_LINK_ENABLE, 0); 281823ef6194SJosé Roberto de Souza 281923ef6194SJosé Roberto de Souza if (wait_for_us(!(intel_de_read(dev_priv, XELPDP_PORT_BUF_CTL1(port)) & 282023ef6194SJosé Roberto de Souza XELPDP_PORT_BUF_D2D_LINK_STATE), 100)) 282123ef6194SJosé Roberto de Souza drm_err(&dev_priv->drm, "Timeout waiting for D2D Link disable for PORT_BUF_CTL %c\n", 282223ef6194SJosé Roberto de Souza port_name(port)); 282323ef6194SJosé Roberto de Souza } 282423ef6194SJosé Roberto de Souza 282523ef6194SJosé Roberto de Souza static void mtl_disable_ddi_buf(struct intel_encoder *encoder, 282623ef6194SJosé Roberto de Souza const struct intel_crtc_state *crtc_state) 282723ef6194SJosé Roberto de Souza { 282823ef6194SJosé Roberto de Souza struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 282923ef6194SJosé Roberto de Souza enum port port = encoder->port; 283023ef6194SJosé Roberto de Souza u32 val; 283123ef6194SJosé Roberto de Souza 283223ef6194SJosé Roberto de Souza /* 3.b Clear DDI_CTL_DE Enable to 0. */ 283323ef6194SJosé Roberto de Souza val = intel_de_read(dev_priv, DDI_BUF_CTL(port)); 283423ef6194SJosé Roberto de Souza if (val & DDI_BUF_CTL_ENABLE) { 283523ef6194SJosé Roberto de Souza val &= ~DDI_BUF_CTL_ENABLE; 283623ef6194SJosé Roberto de Souza intel_de_write(dev_priv, DDI_BUF_CTL(port), val); 283723ef6194SJosé Roberto de Souza 283823ef6194SJosé Roberto de Souza /* 3.c Poll for PORT_BUF_CTL Idle Status == 1, timeout after 100us */ 283923ef6194SJosé Roberto de Souza mtl_wait_ddi_buf_idle(dev_priv, port); 284023ef6194SJosé Roberto de Souza } 284123ef6194SJosé Roberto de Souza 284223ef6194SJosé Roberto de Souza /* 3.d Disable D2D Link */ 284323ef6194SJosé Roberto de Souza mtl_ddi_disable_d2d_link(encoder); 284423ef6194SJosé Roberto de Souza 284523ef6194SJosé Roberto de Souza /* 3.e Disable DP_TP_CTL */ 284623ef6194SJosé Roberto de Souza if (intel_crtc_has_dp_encoder(crtc_state)) { 284723ef6194SJosé Roberto de Souza intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), 284823ef6194SJosé Roberto de Souza DP_TP_CTL_ENABLE, 0); 284923ef6194SJosé Roberto de Souza } 285023ef6194SJosé Roberto de Souza } 285123ef6194SJosé Roberto de Souza 285223ef6194SJosé Roberto de Souza static void disable_ddi_buf(struct intel_encoder *encoder, 2853379bc100SJani Nikula const struct intel_crtc_state *crtc_state) 2854379bc100SJani Nikula { 2855379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 2856379bc100SJani Nikula enum port port = encoder->port; 2857379bc100SJani Nikula bool wait = false; 2858379bc100SJani Nikula u32 val; 2859379bc100SJani Nikula 2860f7960e7fSJani Nikula val = intel_de_read(dev_priv, DDI_BUF_CTL(port)); 2861379bc100SJani Nikula if (val & DDI_BUF_CTL_ENABLE) { 2862379bc100SJani Nikula val &= ~DDI_BUF_CTL_ENABLE; 2863f7960e7fSJani Nikula intel_de_write(dev_priv, DDI_BUF_CTL(port), val); 2864379bc100SJani Nikula wait = true; 2865379bc100SJani Nikula } 2866379bc100SJani Nikula 28678910d8b7SAndrzej Hajda if (intel_crtc_has_dp_encoder(crtc_state)) 28688910d8b7SAndrzej Hajda intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), 28698c042949SVille Syrjälä DP_TP_CTL_ENABLE, 0); 2870379bc100SJani Nikula 2871379bc100SJani Nikula /* Disable FEC in DP Sink */ 2872379bc100SJani Nikula intel_ddi_disable_fec_state(encoder, crtc_state); 2873379bc100SJani Nikula 2874379bc100SJani Nikula if (wait) 2875379bc100SJani Nikula intel_wait_ddi_buf_idle(dev_priv, port); 2876379bc100SJani Nikula } 2877379bc100SJani Nikula 287823ef6194SJosé Roberto de Souza static void intel_disable_ddi_buf(struct intel_encoder *encoder, 287923ef6194SJosé Roberto de Souza const struct intel_crtc_state *crtc_state) 288023ef6194SJosé Roberto de Souza { 288123ef6194SJosé Roberto de Souza struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 288223ef6194SJosé Roberto de Souza 288323ef6194SJosé Roberto de Souza if (DISPLAY_VER(dev_priv) >= 14) { 288423ef6194SJosé Roberto de Souza mtl_disable_ddi_buf(encoder, crtc_state); 288523ef6194SJosé Roberto de Souza 288623ef6194SJosé Roberto de Souza /* 3.f Disable DP_TP_CTL FEC Enable if it is needed */ 288723ef6194SJosé Roberto de Souza intel_ddi_disable_fec_state(encoder, crtc_state); 288823ef6194SJosé Roberto de Souza } else { 288923ef6194SJosé Roberto de Souza disable_ddi_buf(encoder, crtc_state); 289023ef6194SJosé Roberto de Souza } 289123ef6194SJosé Roberto de Souza } 289223ef6194SJosé Roberto de Souza 2893ede9771dSVille Syrjälä static void intel_ddi_post_disable_dp(struct intel_atomic_state *state, 2894ede9771dSVille Syrjälä struct intel_encoder *encoder, 2895379bc100SJani Nikula const struct intel_crtc_state *old_crtc_state, 2896379bc100SJani Nikula const struct drm_connector_state *old_conn_state) 2897379bc100SJani Nikula { 2898379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 2899b7d02c3aSVille Syrjälä struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 2900379bc100SJani Nikula struct intel_dp *intel_dp = &dig_port->dp; 290123ef6194SJosé Roberto de Souza intel_wakeref_t wakeref; 2902379bc100SJani Nikula bool is_mst = intel_crtc_has_type(old_crtc_state, 2903379bc100SJani Nikula INTEL_OUTPUT_DP_MST); 2904379bc100SJani Nikula 2905c980216dSImre Deak if (!is_mst) 2906c980216dSImre Deak intel_dp_set_infoframes(encoder, false, 2907c980216dSImre Deak old_crtc_state, old_conn_state); 2908fa37a213SGwan-gyeong Mun 2909379bc100SJani Nikula /* 2910379bc100SJani Nikula * Power down sink before disabling the port, otherwise we end 2911379bc100SJani Nikula * up getting interrupts from the sink on detecting link loss. 2912379bc100SJani Nikula */ 29130e634efdSVille Syrjälä intel_dp_set_power(intel_dp, DP_SET_POWER_D3); 291478eaaba3SJosé Roberto de Souza 2915005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 12) { 2916c59053dcSJosé Roberto de Souza if (is_mst) { 2917c59053dcSJosé Roberto de Souza enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder; 2918c59053dcSJosé Roberto de Souza 29198910d8b7SAndrzej Hajda intel_de_rmw(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder), 29208910d8b7SAndrzej Hajda TGL_TRANS_DDI_PORT_MASK | TRANS_DDI_MODE_SELECT_MASK, 29218910d8b7SAndrzej Hajda 0); 2922c59053dcSJosé Roberto de Souza } 2923c59053dcSJosé Roberto de Souza } else { 2924c59053dcSJosé Roberto de Souza if (!is_mst) 292555a4679eSVille Syrjälä intel_ddi_disable_transcoder_clock(old_crtc_state); 2926c59053dcSJosé Roberto de Souza } 2927379bc100SJani Nikula 2928379bc100SJani Nikula intel_disable_ddi_buf(encoder, old_crtc_state); 2929379bc100SJani Nikula 29303ca8f191SJosé Roberto de Souza /* 29313ca8f191SJosé Roberto de Souza * From TGL spec: "If single stream or multi-stream master transcoder: 29323ca8f191SJosé Roberto de Souza * Configure Transcoder Clock select to direct no clock to the 29333ca8f191SJosé Roberto de Souza * transcoder" 29343ca8f191SJosé Roberto de Souza */ 2935005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 12) 293655a4679eSVille Syrjälä intel_ddi_disable_transcoder_clock(old_crtc_state); 29373ca8f191SJosé Roberto de Souza 2938eb46f498SJani Nikula intel_pps_vdd_on(intel_dp); 2939eb46f498SJani Nikula intel_pps_off(intel_dp); 2940379bc100SJani Nikula 294123ef6194SJosé Roberto de Souza wakeref = fetch_and_zero(&dig_port->ddi_io_wakeref); 294223ef6194SJosé Roberto de Souza 294323ef6194SJosé Roberto de Souza if (wakeref) 2944a4550977SImre Deak intel_display_power_put(dev_priv, 2945a4550977SImre Deak dig_port->ddi_io_power_domain, 294623ef6194SJosé Roberto de Souza wakeref); 2947379bc100SJani Nikula 2948c133df69SVille Syrjälä intel_ddi_disable_clock(encoder); 294923ef6194SJosé Roberto de Souza 295023ef6194SJosé Roberto de Souza /* De-select Thunderbolt */ 295123ef6194SJosé Roberto de Souza if (DISPLAY_VER(dev_priv) >= 14) 295223ef6194SJosé Roberto de Souza intel_de_rmw(dev_priv, XELPDP_PORT_BUF_CTL1(encoder->port), 295323ef6194SJosé Roberto de Souza XELPDP_PORT_BUF_IO_SELECT_TBT, 0); 2954379bc100SJani Nikula } 2955379bc100SJani Nikula 2956ede9771dSVille Syrjälä static void intel_ddi_post_disable_hdmi(struct intel_atomic_state *state, 2957ede9771dSVille Syrjälä struct intel_encoder *encoder, 2958379bc100SJani Nikula const struct intel_crtc_state *old_crtc_state, 2959379bc100SJani Nikula const struct drm_connector_state *old_conn_state) 2960379bc100SJani Nikula { 2961379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 2962b7d02c3aSVille Syrjälä struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 2963379bc100SJani Nikula struct intel_hdmi *intel_hdmi = &dig_port->hdmi; 296423ef6194SJosé Roberto de Souza intel_wakeref_t wakeref; 2965379bc100SJani Nikula 2966379bc100SJani Nikula dig_port->set_infoframes(encoder, false, 2967379bc100SJani Nikula old_crtc_state, old_conn_state); 2968379bc100SJani Nikula 2969c1949189SImre Deak if (DISPLAY_VER(dev_priv) < 12) 297055a4679eSVille Syrjälä intel_ddi_disable_transcoder_clock(old_crtc_state); 2971379bc100SJani Nikula 2972379bc100SJani Nikula intel_disable_ddi_buf(encoder, old_crtc_state); 2973379bc100SJani Nikula 2974c1949189SImre Deak if (DISPLAY_VER(dev_priv) >= 12) 297555a4679eSVille Syrjälä intel_ddi_disable_transcoder_clock(old_crtc_state); 2976c1949189SImre Deak 297723ef6194SJosé Roberto de Souza wakeref = fetch_and_zero(&dig_port->ddi_io_wakeref); 297823ef6194SJosé Roberto de Souza if (wakeref) 2979a4550977SImre Deak intel_display_power_put(dev_priv, 2980a4550977SImre Deak dig_port->ddi_io_power_domain, 298123ef6194SJosé Roberto de Souza wakeref); 2982379bc100SJani Nikula 2983c133df69SVille Syrjälä intel_ddi_disable_clock(encoder); 2984379bc100SJani Nikula 2985379bc100SJani Nikula intel_dp_dual_mode_set_tmds_output(intel_hdmi, false); 2986379bc100SJani Nikula } 2987379bc100SJani Nikula 2988ede9771dSVille Syrjälä static void intel_ddi_post_disable(struct intel_atomic_state *state, 2989ede9771dSVille Syrjälä struct intel_encoder *encoder, 2990379bc100SJani Nikula const struct intel_crtc_state *old_crtc_state, 2991379bc100SJani Nikula const struct drm_connector_state *old_conn_state) 2992379bc100SJani Nikula { 2993379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 2994a6e7a006SVille Syrjälä struct intel_crtc *slave_crtc; 2995379bc100SJani Nikula 29967829c92bSVille Syrjälä if (!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST)) { 2997773b4b54SVille Syrjälä intel_crtc_vblank_off(old_crtc_state); 2998773b4b54SVille Syrjälä 29990504d0acSVille Syrjälä intel_disable_transcoder(old_crtc_state); 30000504d0acSVille Syrjälä 3001773b4b54SVille Syrjälä intel_ddi_disable_transcoder_func(old_crtc_state); 3002773b4b54SVille Syrjälä 3003773b4b54SVille Syrjälä intel_dsc_disable(old_crtc_state); 3004773b4b54SVille Syrjälä 3005005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 9) 3006f6df4d46SLucas De Marchi skl_scaler_disable(old_crtc_state); 3007773b4b54SVille Syrjälä else 30089eae5e27SLucas De Marchi ilk_pfit_disable(old_crtc_state); 30097829c92bSVille Syrjälä } 3010773b4b54SVille Syrjälä 3011a6e7a006SVille Syrjälä for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, slave_crtc, 3012a6e7a006SVille Syrjälä intel_crtc_bigjoiner_slave_pipes(old_crtc_state)) { 30134e3cdb45SManasi Navare const struct intel_crtc_state *old_slave_crtc_state = 3014f2e19b58SVille Syrjälä intel_atomic_get_old_crtc_state(state, slave_crtc); 30154e3cdb45SManasi Navare 30164e3cdb45SManasi Navare intel_crtc_vblank_off(old_slave_crtc_state); 30174e3cdb45SManasi Navare 30184e3cdb45SManasi Navare intel_dsc_disable(old_slave_crtc_state); 30194e3cdb45SManasi Navare skl_scaler_disable(old_slave_crtc_state); 30204e3cdb45SManasi Navare } 30214e3cdb45SManasi Navare 3022379bc100SJani Nikula /* 3023379bc100SJani Nikula * When called from DP MST code: 3024379bc100SJani Nikula * - old_conn_state will be NULL 3025379bc100SJani Nikula * - encoder will be the main encoder (ie. mst->primary) 3026379bc100SJani Nikula * - the main connector associated with this port 3027379bc100SJani Nikula * won't be active or linked to a crtc 3028379bc100SJani Nikula * - old_crtc_state will be the state of the last stream to 3029379bc100SJani Nikula * be deactivated on this port, and it may not be the same 3030379bc100SJani Nikula * stream that was activated last, but each stream 3031379bc100SJani Nikula * should have a state that is identical when it comes to 3032379bc100SJani Nikula * the DP link parameteres 3033379bc100SJani Nikula */ 3034379bc100SJani Nikula 3035379bc100SJani Nikula if (intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_HDMI)) 3036ede9771dSVille Syrjälä intel_ddi_post_disable_hdmi(state, encoder, old_crtc_state, 3037ede9771dSVille Syrjälä old_conn_state); 3038379bc100SJani Nikula else 3039ede9771dSVille Syrjälä intel_ddi_post_disable_dp(state, encoder, old_crtc_state, 3040ede9771dSVille Syrjälä old_conn_state); 3041b108bdd0SImre Deak } 3042b108bdd0SImre Deak 3043b108bdd0SImre Deak static void intel_ddi_post_pll_disable(struct intel_atomic_state *state, 3044b108bdd0SImre Deak struct intel_encoder *encoder, 3045b108bdd0SImre Deak const struct intel_crtc_state *old_crtc_state, 3046b108bdd0SImre Deak const struct drm_connector_state *old_conn_state) 3047b108bdd0SImre Deak { 3048b108bdd0SImre Deak struct drm_i915_private *i915 = to_i915(encoder->base.dev); 3049b108bdd0SImre Deak struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 3050b108bdd0SImre Deak enum phy phy = intel_port_to_phy(i915, encoder->port); 3051b108bdd0SImre Deak bool is_tc_port = intel_phy_is_tc(i915, phy); 3052379bc100SJani Nikula 3053637c7aa2SImre Deak main_link_aux_power_domain_put(dig_port, old_crtc_state); 305417bef9baSVille Syrjälä 305517bef9baSVille Syrjälä if (is_tc_port) 305617bef9baSVille Syrjälä intel_tc_port_put_link(dig_port); 3057379bc100SJani Nikula } 3058379bc100SJani Nikula 3059d82a855aSVille Syrjälä static void trans_port_sync_stop_link_train(struct intel_atomic_state *state, 3060d82a855aSVille Syrjälä struct intel_encoder *encoder, 3061d82a855aSVille Syrjälä const struct intel_crtc_state *crtc_state) 3062d82a855aSVille Syrjälä { 3063d82a855aSVille Syrjälä const struct drm_connector_state *conn_state; 3064d82a855aSVille Syrjälä struct drm_connector *conn; 3065d82a855aSVille Syrjälä int i; 3066d82a855aSVille Syrjälä 3067d82a855aSVille Syrjälä if (!crtc_state->sync_mode_slaves_mask) 3068d82a855aSVille Syrjälä return; 3069d82a855aSVille Syrjälä 3070d82a855aSVille Syrjälä for_each_new_connector_in_state(&state->base, conn, conn_state, i) { 3071d82a855aSVille Syrjälä struct intel_encoder *slave_encoder = 3072d82a855aSVille Syrjälä to_intel_encoder(conn_state->best_encoder); 3073d82a855aSVille Syrjälä struct intel_crtc *slave_crtc = to_intel_crtc(conn_state->crtc); 3074d82a855aSVille Syrjälä const struct intel_crtc_state *slave_crtc_state; 3075d82a855aSVille Syrjälä 3076d82a855aSVille Syrjälä if (!slave_crtc) 3077d82a855aSVille Syrjälä continue; 3078d82a855aSVille Syrjälä 3079d82a855aSVille Syrjälä slave_crtc_state = 3080d82a855aSVille Syrjälä intel_atomic_get_new_crtc_state(state, slave_crtc); 3081d82a855aSVille Syrjälä 3082d82a855aSVille Syrjälä if (slave_crtc_state->master_transcoder != 3083d82a855aSVille Syrjälä crtc_state->cpu_transcoder) 3084d82a855aSVille Syrjälä continue; 3085d82a855aSVille Syrjälä 3086a621860aSVille Syrjälä intel_dp_stop_link_train(enc_to_intel_dp(slave_encoder), 3087a621860aSVille Syrjälä slave_crtc_state); 3088d82a855aSVille Syrjälä } 3089d82a855aSVille Syrjälä 3090d82a855aSVille Syrjälä usleep_range(200, 400); 3091d82a855aSVille Syrjälä 3092a621860aSVille Syrjälä intel_dp_stop_link_train(enc_to_intel_dp(encoder), 3093a621860aSVille Syrjälä crtc_state); 3094d82a855aSVille Syrjälä } 3095d82a855aSVille Syrjälä 3096ede9771dSVille Syrjälä static void intel_enable_ddi_dp(struct intel_atomic_state *state, 3097ede9771dSVille Syrjälä struct intel_encoder *encoder, 3098379bc100SJani Nikula const struct intel_crtc_state *crtc_state, 3099379bc100SJani Nikula const struct drm_connector_state *conn_state) 3100379bc100SJani Nikula { 3101379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 3102b7d02c3aSVille Syrjälä struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 3103998cc864SUma Shankar struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 3104379bc100SJani Nikula enum port port = encoder->port; 3105379bc100SJani Nikula 3106005e9537SMatt Roper if (port == PORT_A && DISPLAY_VER(dev_priv) < 9) 3107a621860aSVille Syrjälä intel_dp_stop_link_train(intel_dp, crtc_state); 3108379bc100SJani Nikula 31096306d8dbSHans de Goede drm_connector_update_privacy_screen(conn_state); 3110379bc100SJani Nikula intel_edp_backlight_on(crtc_state, conn_state); 3111998cc864SUma Shankar 3112998cc864SUma Shankar if (!dig_port->lspcon.active || dig_port->dp.has_hdmi_sink) 31131bf3657cSGwan-gyeong Mun intel_dp_set_infoframes(encoder, true, crtc_state, conn_state); 3114998cc864SUma Shankar 3115379bc100SJani Nikula intel_audio_codec_enable(encoder, crtc_state, conn_state); 3116d82a855aSVille Syrjälä 3117d82a855aSVille Syrjälä trans_port_sync_stop_link_train(state, encoder, crtc_state); 3118379bc100SJani Nikula } 3119379bc100SJani Nikula 3120379bc100SJani Nikula static i915_reg_t 3121379bc100SJani Nikula gen9_chicken_trans_reg_by_port(struct drm_i915_private *dev_priv, 3122379bc100SJani Nikula enum port port) 3123379bc100SJani Nikula { 312412c4d4c1SVille Syrjälä static const enum transcoder trans[] = { 312512c4d4c1SVille Syrjälä [PORT_A] = TRANSCODER_EDP, 312612c4d4c1SVille Syrjälä [PORT_B] = TRANSCODER_A, 312712c4d4c1SVille Syrjälä [PORT_C] = TRANSCODER_B, 312812c4d4c1SVille Syrjälä [PORT_D] = TRANSCODER_C, 312912c4d4c1SVille Syrjälä [PORT_E] = TRANSCODER_A, 3130379bc100SJani Nikula }; 3131379bc100SJani Nikula 3132005e9537SMatt Roper drm_WARN_ON(&dev_priv->drm, DISPLAY_VER(dev_priv) < 9); 3133379bc100SJani Nikula 31341de143ccSPankaj Bharadiya if (drm_WARN_ON(&dev_priv->drm, port < PORT_A || port > PORT_E)) 3135379bc100SJani Nikula port = PORT_A; 3136379bc100SJani Nikula 313712c4d4c1SVille Syrjälä return CHICKEN_TRANS(trans[port]); 3138379bc100SJani Nikula } 3139379bc100SJani Nikula 3140ede9771dSVille Syrjälä static void intel_enable_ddi_hdmi(struct intel_atomic_state *state, 3141ede9771dSVille Syrjälä struct intel_encoder *encoder, 3142379bc100SJani Nikula const struct intel_crtc_state *crtc_state, 3143379bc100SJani Nikula const struct drm_connector_state *conn_state) 3144379bc100SJani Nikula { 3145379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 3146b7d02c3aSVille Syrjälä struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 3147379bc100SJani Nikula struct drm_connector *connector = conn_state->connector; 3148379bc100SJani Nikula enum port port = encoder->port; 3149e99ba962SImre Deak enum phy phy = intel_port_to_phy(dev_priv, port); 3150e99ba962SImre Deak u32 buf_ctl; 3151379bc100SJani Nikula 3152379bc100SJani Nikula if (!intel_hdmi_handle_sink_scrambling(encoder, connector, 3153379bc100SJani Nikula crtc_state->hdmi_high_tmds_clock_ratio, 3154379bc100SJani Nikula crtc_state->hdmi_scrambling)) 315547bdb1caSJani Nikula drm_dbg_kms(&dev_priv->drm, 315647bdb1caSJani Nikula "[CONNECTOR:%d:%s] Failed to configure sink scrambling/TMDS bit clock ratio\n", 3157379bc100SJani Nikula connector->base.id, connector->name); 3158379bc100SJani Nikula 31595bafd85dSVille Syrjälä if (has_buf_trans_select(dev_priv)) 3160e722ab8bSVille Syrjälä hsw_prepare_hdmi_ddi_buffers(encoder, crtc_state); 3161c9b69041SVille Syrjälä 3162b66a8abaSAnkit Nautiyal /* e. Enable D2D Link for C10/C20 Phy */ 3163b66a8abaSAnkit Nautiyal if (DISPLAY_VER(dev_priv) >= 14) 3164b66a8abaSAnkit Nautiyal mtl_ddi_enable_d2d(encoder); 3165b66a8abaSAnkit Nautiyal 3166e722ab8bSVille Syrjälä encoder->set_signal_levels(encoder, crtc_state); 3167c9b69041SVille Syrjälä 3168379bc100SJani Nikula /* Display WA #1143: skl,kbl,cfl */ 316993e7e61eSLucas De Marchi if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv)) { 3170379bc100SJani Nikula /* 3171379bc100SJani Nikula * For some reason these chicken bits have been 3172379bc100SJani Nikula * stuffed into a transcoder register, event though 3173379bc100SJani Nikula * the bits affect a specific DDI port rather than 3174379bc100SJani Nikula * a specific transcoder. 3175379bc100SJani Nikula */ 3176379bc100SJani Nikula i915_reg_t reg = gen9_chicken_trans_reg_by_port(dev_priv, port); 3177379bc100SJani Nikula u32 val; 3178379bc100SJani Nikula 3179f7960e7fSJani Nikula val = intel_de_read(dev_priv, reg); 3180379bc100SJani Nikula 3181379bc100SJani Nikula if (port == PORT_E) 3182379bc100SJani Nikula val |= DDIE_TRAINING_OVERRIDE_ENABLE | 3183379bc100SJani Nikula DDIE_TRAINING_OVERRIDE_VALUE; 3184379bc100SJani Nikula else 3185379bc100SJani Nikula val |= DDI_TRAINING_OVERRIDE_ENABLE | 3186379bc100SJani Nikula DDI_TRAINING_OVERRIDE_VALUE; 3187379bc100SJani Nikula 3188f7960e7fSJani Nikula intel_de_write(dev_priv, reg, val); 3189f7960e7fSJani Nikula intel_de_posting_read(dev_priv, reg); 3190379bc100SJani Nikula 3191379bc100SJani Nikula udelay(1); 3192379bc100SJani Nikula 3193379bc100SJani Nikula if (port == PORT_E) 3194379bc100SJani Nikula val &= ~(DDIE_TRAINING_OVERRIDE_ENABLE | 3195379bc100SJani Nikula DDIE_TRAINING_OVERRIDE_VALUE); 3196379bc100SJani Nikula else 3197379bc100SJani Nikula val &= ~(DDI_TRAINING_OVERRIDE_ENABLE | 3198379bc100SJani Nikula DDI_TRAINING_OVERRIDE_VALUE); 3199379bc100SJani Nikula 3200f7960e7fSJani Nikula intel_de_write(dev_priv, reg, val); 3201379bc100SJani Nikula } 3202379bc100SJani Nikula 32031e0cb7beSVille Syrjälä intel_ddi_power_up_lanes(encoder, crtc_state); 32041e0cb7beSVille Syrjälä 3205379bc100SJani Nikula /* In HDMI/DVI mode, the port width, and swing/emphasis values 3206379bc100SJani Nikula * are ignored so nothing special needs to be done besides 3207379bc100SJani Nikula * enabling the port. 3208414002f1SImre Deak * 3209414002f1SImre Deak * On ADL_P the PHY link rate and lane count must be programmed but 3210414002f1SImre Deak * these are both 0 for HDMI. 3211b66a8abaSAnkit Nautiyal * 3212b66a8abaSAnkit Nautiyal * But MTL onwards HDMI2.1 is supported and in TMDS mode this 3213b66a8abaSAnkit Nautiyal * is filled with lane count, already set in the crtc_state. 3214b66a8abaSAnkit Nautiyal * The same is required to be filled in PORT_BUF_CTL for C10/20 Phy. 3215379bc100SJani Nikula */ 3216e99ba962SImre Deak buf_ctl = dig_port->saved_port_bits | DDI_BUF_CTL_ENABLE; 3217b66a8abaSAnkit Nautiyal if (DISPLAY_VER(dev_priv) >= 14) { 3218b66a8abaSAnkit Nautiyal u8 lane_count = mtl_get_port_width(crtc_state->lane_count); 3219b66a8abaSAnkit Nautiyal u32 port_buf = 0; 3220b66a8abaSAnkit Nautiyal 3221b66a8abaSAnkit Nautiyal port_buf |= XELPDP_PORT_WIDTH(lane_count); 3222b66a8abaSAnkit Nautiyal 3223b66a8abaSAnkit Nautiyal if (dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL) 3224b66a8abaSAnkit Nautiyal port_buf |= XELPDP_PORT_REVERSAL; 3225b66a8abaSAnkit Nautiyal 3226b66a8abaSAnkit Nautiyal intel_de_rmw(dev_priv, XELPDP_PORT_BUF_CTL1(port), 3227b66a8abaSAnkit Nautiyal XELPDP_PORT_WIDTH_MASK | XELPDP_PORT_REVERSAL, port_buf); 3228b66a8abaSAnkit Nautiyal 3229b66a8abaSAnkit Nautiyal buf_ctl |= DDI_PORT_WIDTH(lane_count); 3230b66a8abaSAnkit Nautiyal } else if (IS_ALDERLAKE_P(dev_priv) && intel_phy_is_tc(dev_priv, phy)) { 3231e99ba962SImre Deak drm_WARN_ON(&dev_priv->drm, !intel_tc_port_in_legacy_mode(dig_port)); 3232e99ba962SImre Deak buf_ctl |= DDI_BUF_CTL_TC_PHY_OWNERSHIP; 3233e99ba962SImre Deak } 3234b66a8abaSAnkit Nautiyal 3235e99ba962SImre Deak intel_de_write(dev_priv, DDI_BUF_CTL(port), buf_ctl); 3236379bc100SJani Nikula 323765e75edaSAnkit Nautiyal intel_wait_ddi_buf_active(dev_priv, port); 323865e75edaSAnkit Nautiyal 3239379bc100SJani Nikula intel_audio_codec_enable(encoder, crtc_state, conn_state); 3240379bc100SJani Nikula } 3241379bc100SJani Nikula 3242ede9771dSVille Syrjälä static void intel_enable_ddi(struct intel_atomic_state *state, 3243ede9771dSVille Syrjälä struct intel_encoder *encoder, 3244379bc100SJani Nikula const struct intel_crtc_state *crtc_state, 3245379bc100SJani Nikula const struct drm_connector_state *conn_state) 3246379bc100SJani Nikula { 32478b4f2137SPankaj Bharadiya drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder); 324821fd23acSJani Nikula 3249df529053SVille Syrjälä if (!intel_crtc_is_bigjoiner_slave(crtc_state)) 3250eed22a46SVille Syrjälä intel_ddi_enable_transcoder_func(encoder, crtc_state); 32517c2fedd7SVille Syrjälä 32528853750dSVinod Govindapillai /* Enable/Disable DP2.0 SDP split config before transcoder */ 32538853750dSVinod Govindapillai intel_audio_sdp_split_update(encoder, crtc_state); 32548853750dSVinod Govindapillai 32558c66081bSVille Syrjälä intel_enable_transcoder(crtc_state); 325621fd23acSJani Nikula 325721fd23acSJani Nikula intel_crtc_vblank_on(crtc_state); 325821fd23acSJani Nikula 3259379bc100SJani Nikula if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) 3260ede9771dSVille Syrjälä intel_enable_ddi_hdmi(state, encoder, crtc_state, conn_state); 3261379bc100SJani Nikula else 3262ede9771dSVille Syrjälä intel_enable_ddi_dp(state, encoder, crtc_state, conn_state); 3263379bc100SJani Nikula 3264379bc100SJani Nikula /* Enable hdcp if it's desired */ 3265379bc100SJani Nikula if (conn_state->content_protection == 3266379bc100SJani Nikula DRM_MODE_CONTENT_PROTECTION_DESIRED) 3267*4c4279a8SSuraj Kandpal intel_hdcp_enable(state, encoder, crtc_state, conn_state); 3268379bc100SJani Nikula } 3269379bc100SJani Nikula 3270ede9771dSVille Syrjälä static void intel_disable_ddi_dp(struct intel_atomic_state *state, 3271ede9771dSVille Syrjälä struct intel_encoder *encoder, 3272379bc100SJani Nikula const struct intel_crtc_state *old_crtc_state, 3273379bc100SJani Nikula const struct drm_connector_state *old_conn_state) 3274379bc100SJani Nikula { 3275b7d02c3aSVille Syrjälä struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 3276379bc100SJani Nikula 3277379bc100SJani Nikula intel_dp->link_trained = false; 3278379bc100SJani Nikula 3279179db7c1SJani Nikula intel_audio_codec_disable(encoder, old_crtc_state, old_conn_state); 3280f28c5950SVille Syrjälä 3281f28c5950SVille Syrjälä intel_psr_disable(intel_dp, old_crtc_state); 3282379bc100SJani Nikula intel_edp_backlight_off(old_conn_state); 3283379bc100SJani Nikula /* Disable the decompression in DP Sink */ 3284379bc100SJani Nikula intel_dp_sink_set_decompression_state(intel_dp, old_crtc_state, 3285379bc100SJani Nikula false); 32861639406aSManasi Navare /* Disable Ignore_MSA bit in DP Sink */ 32871639406aSManasi Navare intel_dp_sink_set_msa_timing_par_ignore_state(intel_dp, old_crtc_state, 32881639406aSManasi Navare false); 3289379bc100SJani Nikula } 3290379bc100SJani Nikula 3291ede9771dSVille Syrjälä static void intel_disable_ddi_hdmi(struct intel_atomic_state *state, 3292ede9771dSVille Syrjälä struct intel_encoder *encoder, 3293379bc100SJani Nikula const struct intel_crtc_state *old_crtc_state, 3294379bc100SJani Nikula const struct drm_connector_state *old_conn_state) 3295379bc100SJani Nikula { 329647bdb1caSJani Nikula struct drm_i915_private *i915 = to_i915(encoder->base.dev); 3297379bc100SJani Nikula struct drm_connector *connector = old_conn_state->connector; 3298379bc100SJani Nikula 3299179db7c1SJani Nikula intel_audio_codec_disable(encoder, old_crtc_state, old_conn_state); 3300f28c5950SVille Syrjälä 3301379bc100SJani Nikula if (!intel_hdmi_handle_sink_scrambling(encoder, connector, 3302379bc100SJani Nikula false, false)) 330347bdb1caSJani Nikula drm_dbg_kms(&i915->drm, 330447bdb1caSJani Nikula "[CONNECTOR:%d:%s] Failed to reset sink scrambling/TMDS bit clock ratio\n", 3305379bc100SJani Nikula connector->base.id, connector->name); 3306379bc100SJani Nikula } 3307379bc100SJani Nikula 3308ede9771dSVille Syrjälä static void intel_disable_ddi(struct intel_atomic_state *state, 3309ede9771dSVille Syrjälä struct intel_encoder *encoder, 3310379bc100SJani Nikula const struct intel_crtc_state *old_crtc_state, 3311379bc100SJani Nikula const struct drm_connector_state *old_conn_state) 3312379bc100SJani Nikula { 3313379bc100SJani Nikula intel_hdcp_disable(to_intel_connector(old_conn_state->connector)); 3314379bc100SJani Nikula 3315379bc100SJani Nikula if (intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_HDMI)) 3316ede9771dSVille Syrjälä intel_disable_ddi_hdmi(state, encoder, old_crtc_state, 3317ede9771dSVille Syrjälä old_conn_state); 3318379bc100SJani Nikula else 3319ede9771dSVille Syrjälä intel_disable_ddi_dp(state, encoder, old_crtc_state, 3320ede9771dSVille Syrjälä old_conn_state); 3321379bc100SJani Nikula } 3322379bc100SJani Nikula 3323ede9771dSVille Syrjälä static void intel_ddi_update_pipe_dp(struct intel_atomic_state *state, 3324ede9771dSVille Syrjälä struct intel_encoder *encoder, 3325379bc100SJani Nikula const struct intel_crtc_state *crtc_state, 3326379bc100SJani Nikula const struct drm_connector_state *conn_state) 3327379bc100SJani Nikula { 33280c06fa15SGwan-gyeong Mun intel_ddi_set_dp_msa(crtc_state, conn_state); 3329379bc100SJani Nikula 333076d45d06SGwan-gyeong Mun intel_dp_set_infoframes(encoder, true, crtc_state, conn_state); 3331379bc100SJani Nikula 3332c0a52f8bSJani Nikula intel_backlight_update(state, encoder, crtc_state, conn_state); 33336306d8dbSHans de Goede drm_connector_update_privacy_screen(conn_state); 3334379bc100SJani Nikula } 3335379bc100SJani Nikula 3336f1c7a36bSSean Paul void intel_ddi_update_pipe(struct intel_atomic_state *state, 3337ede9771dSVille Syrjälä struct intel_encoder *encoder, 3338379bc100SJani Nikula const struct intel_crtc_state *crtc_state, 3339379bc100SJani Nikula const struct drm_connector_state *conn_state) 3340379bc100SJani Nikula { 3341d456512cSRamalingam C 3342f1c7a36bSSean Paul if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) && 3343f1c7a36bSSean Paul !intel_encoder_is_mst(encoder)) 3344ede9771dSVille Syrjälä intel_ddi_update_pipe_dp(state, encoder, crtc_state, 3345ede9771dSVille Syrjälä conn_state); 3346379bc100SJani Nikula 3347ede9771dSVille Syrjälä intel_hdcp_update_pipe(state, encoder, crtc_state, conn_state); 3348379bc100SJani Nikula } 3349379bc100SJani Nikula 335027ac123bSImre Deak void intel_ddi_update_active_dpll(struct intel_atomic_state *state, 335127ac123bSImre Deak struct intel_encoder *encoder, 335227ac123bSImre Deak struct intel_crtc *crtc) 335327ac123bSImre Deak { 335427ac123bSImre Deak struct drm_i915_private *i915 = to_i915(encoder->base.dev); 335527ac123bSImre Deak struct intel_crtc_state *crtc_state = 335627ac123bSImre Deak intel_atomic_get_new_crtc_state(state, crtc); 335727ac123bSImre Deak struct intel_crtc *slave_crtc; 335827ac123bSImre Deak enum phy phy = intel_port_to_phy(i915, encoder->port); 335927ac123bSImre Deak 336062618c7fSMika Kahola /* FIXME: Add MTL pll_mgr */ 336162618c7fSMika Kahola if (DISPLAY_VER(i915) >= 14 || !intel_phy_is_tc(i915, phy)) 336227ac123bSImre Deak return; 336327ac123bSImre Deak 336427ac123bSImre Deak intel_update_active_dpll(state, crtc, encoder); 336527ac123bSImre Deak for_each_intel_crtc_in_pipe_mask(&i915->drm, slave_crtc, 336627ac123bSImre Deak intel_crtc_bigjoiner_slave_pipes(crtc_state)) 336727ac123bSImre Deak intel_update_active_dpll(state, slave_crtc, encoder); 336827ac123bSImre Deak } 336927ac123bSImre Deak 3370379bc100SJani Nikula static void 3371ede9771dSVille Syrjälä intel_ddi_pre_pll_enable(struct intel_atomic_state *state, 3372ede9771dSVille Syrjälä struct intel_encoder *encoder, 3373379bc100SJani Nikula const struct intel_crtc_state *crtc_state, 3374379bc100SJani Nikula const struct drm_connector_state *conn_state) 3375379bc100SJani Nikula { 3376379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 3377b7d02c3aSVille Syrjälä struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 3378d8fe2ab6SMatt Roper enum phy phy = intel_port_to_phy(dev_priv, encoder->port); 3379d8fe2ab6SMatt Roper bool is_tc_port = intel_phy_is_tc(dev_priv, phy); 3380379bc100SJani Nikula 33810f752b21SImre Deak if (is_tc_port) { 33820f752b21SImre Deak struct intel_crtc *master_crtc = 33830f752b21SImre Deak to_intel_crtc(crtc_state->uapi.crtc); 33840f752b21SImre Deak 338524a7bfe0SImre Deak intel_tc_port_get_link(dig_port, crtc_state->lane_count); 338627ac123bSImre Deak intel_ddi_update_active_dpll(state, encoder, master_crtc); 33870f752b21SImre Deak } 33880f752b21SImre Deak 3389637c7aa2SImre Deak main_link_aux_power_domain_get(dig_port, crtc_state); 3390379bc100SJani Nikula 339111a89708SImre Deak if (is_tc_port && !intel_tc_port_in_tbt_alt_mode(dig_port)) 33929d44dcb9SLucas De Marchi /* 33939d44dcb9SLucas De Marchi * Program the lane count for static/dynamic connections on 33949d44dcb9SLucas De Marchi * Type-C ports. Skip this step for TBT. 33959d44dcb9SLucas De Marchi */ 33969d44dcb9SLucas De Marchi intel_tc_port_set_fia_lane_count(dig_port, crtc_state->lane_count); 33972446e1d6SMatt Roper else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) 3398379bc100SJani Nikula bxt_ddi_phy_set_lane_optim_mask(encoder, 3399379bc100SJani Nikula crtc_state->lane_lat_optim_mask); 3400379bc100SJani Nikula } 3401379bc100SJani Nikula 340255223c3bSImre Deak static void adlp_tbt_to_dp_alt_switch_wa(struct intel_encoder *encoder) 340355223c3bSImre Deak { 340455223c3bSImre Deak struct drm_i915_private *i915 = to_i915(encoder->base.dev); 340555223c3bSImre Deak enum tc_port tc_port = intel_port_to_tc(i915, encoder->port); 340655223c3bSImre Deak int ln; 340755223c3bSImre Deak 340889cb0ba4SImre Deak for (ln = 0; ln < 2; ln++) 3409b8ed5533SImre Deak intel_dkl_phy_rmw(i915, DKL_PCS_DW5(tc_port, ln), DKL_PCS_DW5_CORE_SOFTRESET, 0); 341055223c3bSImre Deak } 341155223c3bSImre Deak 341223ef6194SJosé Roberto de Souza static void mtl_ddi_prepare_link_retrain(struct intel_dp *intel_dp, 341323ef6194SJosé Roberto de Souza const struct intel_crtc_state *crtc_state) 341423ef6194SJosé Roberto de Souza { 341523ef6194SJosé Roberto de Souza struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); 341623ef6194SJosé Roberto de Souza struct intel_encoder *encoder = &dig_port->base; 341723ef6194SJosé Roberto de Souza struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 341823ef6194SJosé Roberto de Souza enum port port = encoder->port; 341923ef6194SJosé Roberto de Souza u32 dp_tp_ctl; 342023ef6194SJosé Roberto de Souza 342123ef6194SJosé Roberto de Souza /* 342223ef6194SJosé Roberto de Souza * TODO: To train with only a different voltage swing entry is not 342323ef6194SJosé Roberto de Souza * necessary disable and enable port 342423ef6194SJosé Roberto de Souza */ 342523ef6194SJosé Roberto de Souza dp_tp_ctl = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state)); 342623ef6194SJosé Roberto de Souza if (dp_tp_ctl & DP_TP_CTL_ENABLE) 342723ef6194SJosé Roberto de Souza mtl_disable_ddi_buf(encoder, crtc_state); 342823ef6194SJosé Roberto de Souza 342923ef6194SJosé Roberto de Souza /* 6.d Configure and enable DP_TP_CTL with link training pattern 1 selected */ 343023ef6194SJosé Roberto de Souza dp_tp_ctl = DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_PAT1; 343123ef6194SJosé Roberto de Souza if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) { 343223ef6194SJosé Roberto de Souza dp_tp_ctl |= DP_TP_CTL_MODE_MST; 343323ef6194SJosé Roberto de Souza } else { 343423ef6194SJosé Roberto de Souza dp_tp_ctl |= DP_TP_CTL_MODE_SST; 343523ef6194SJosé Roberto de Souza if (drm_dp_enhanced_frame_cap(intel_dp->dpcd)) 343623ef6194SJosé Roberto de Souza dp_tp_ctl |= DP_TP_CTL_ENHANCED_FRAME_ENABLE; 343723ef6194SJosé Roberto de Souza } 343823ef6194SJosé Roberto de Souza intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), dp_tp_ctl); 343923ef6194SJosé Roberto de Souza intel_de_posting_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state)); 344023ef6194SJosé Roberto de Souza 344123ef6194SJosé Roberto de Souza /* 6.f Enable D2D Link */ 344223ef6194SJosé Roberto de Souza mtl_ddi_enable_d2d(encoder); 344323ef6194SJosé Roberto de Souza 344423ef6194SJosé Roberto de Souza /* 6.g Configure voltage swing and related IO settings */ 344523ef6194SJosé Roberto de Souza encoder->set_signal_levels(encoder, crtc_state); 344623ef6194SJosé Roberto de Souza 344723ef6194SJosé Roberto de Souza /* 6.h Configure PORT_BUF_CTL1 */ 344823ef6194SJosé Roberto de Souza mtl_port_buf_ctl_program(encoder, crtc_state); 344923ef6194SJosé Roberto de Souza 345023ef6194SJosé Roberto de Souza /* 6.i Configure and enable DDI_CTL_DE to start sending valid data to port slice */ 345123ef6194SJosé Roberto de Souza intel_dp->DP |= DDI_BUF_CTL_ENABLE; 345223ef6194SJosé Roberto de Souza intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP); 345323ef6194SJosé Roberto de Souza intel_de_posting_read(dev_priv, DDI_BUF_CTL(port)); 345423ef6194SJosé Roberto de Souza 345523ef6194SJosé Roberto de Souza /* 6.j Poll for PORT_BUF_CTL Idle Status == 0, timeout after 100 us */ 345623ef6194SJosé Roberto de Souza intel_wait_ddi_buf_active(dev_priv, port); 345723ef6194SJosé Roberto de Souza } 345823ef6194SJosé Roberto de Souza 3459a621860aSVille Syrjälä static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp, 3460a621860aSVille Syrjälä const struct intel_crtc_state *crtc_state) 3461379bc100SJani Nikula { 346255223c3bSImre Deak struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); 346355223c3bSImre Deak struct intel_encoder *encoder = &dig_port->base; 3464ef79fafeSVille Syrjälä struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 3465ef79fafeSVille Syrjälä enum port port = encoder->port; 346635ac28a8SLucas De Marchi u32 dp_tp_ctl, ddi_buf_ctl; 3467379bc100SJani Nikula bool wait = false; 3468379bc100SJani Nikula 3469ef79fafeSVille Syrjälä dp_tp_ctl = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state)); 347035ac28a8SLucas De Marchi 347135ac28a8SLucas De Marchi if (dp_tp_ctl & DP_TP_CTL_ENABLE) { 3472f7960e7fSJani Nikula ddi_buf_ctl = intel_de_read(dev_priv, DDI_BUF_CTL(port)); 347335ac28a8SLucas De Marchi if (ddi_buf_ctl & DDI_BUF_CTL_ENABLE) { 3474f7960e7fSJani Nikula intel_de_write(dev_priv, DDI_BUF_CTL(port), 347535ac28a8SLucas De Marchi ddi_buf_ctl & ~DDI_BUF_CTL_ENABLE); 3476379bc100SJani Nikula wait = true; 3477379bc100SJani Nikula } 3478379bc100SJani Nikula 34798c042949SVille Syrjälä dp_tp_ctl &= ~DP_TP_CTL_ENABLE; 3480ef79fafeSVille Syrjälä intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), dp_tp_ctl); 3481ef79fafeSVille Syrjälä intel_de_posting_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state)); 3482379bc100SJani Nikula 3483379bc100SJani Nikula if (wait) 3484379bc100SJani Nikula intel_wait_ddi_buf_idle(dev_priv, port); 3485379bc100SJani Nikula } 3486379bc100SJani Nikula 3487963501bdSImre Deak dp_tp_ctl = DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_PAT1; 3488a621860aSVille Syrjälä if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) { 348935ac28a8SLucas De Marchi dp_tp_ctl |= DP_TP_CTL_MODE_MST; 3490a621860aSVille Syrjälä } else { 349135ac28a8SLucas De Marchi dp_tp_ctl |= DP_TP_CTL_MODE_SST; 3492379bc100SJani Nikula if (drm_dp_enhanced_frame_cap(intel_dp->dpcd)) 349335ac28a8SLucas De Marchi dp_tp_ctl |= DP_TP_CTL_ENHANCED_FRAME_ENABLE; 3494379bc100SJani Nikula } 3495ef79fafeSVille Syrjälä intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), dp_tp_ctl); 3496ef79fafeSVille Syrjälä intel_de_posting_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state)); 3497379bc100SJani Nikula 349855223c3bSImre Deak if (IS_ALDERLAKE_P(dev_priv) && 349955223c3bSImre Deak (intel_tc_port_in_dp_alt_mode(dig_port) || intel_tc_port_in_legacy_mode(dig_port))) 350055223c3bSImre Deak adlp_tbt_to_dp_alt_switch_wa(encoder); 350155223c3bSImre Deak 3502379bc100SJani Nikula intel_dp->DP |= DDI_BUF_CTL_ENABLE; 3503f7960e7fSJani Nikula intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP); 3504f7960e7fSJani Nikula intel_de_posting_read(dev_priv, DDI_BUF_CTL(port)); 3505379bc100SJani Nikula 3506e828da30SManasi Navare intel_wait_ddi_buf_active(dev_priv, port); 3507379bc100SJani Nikula } 3508379bc100SJani Nikula 3509eee3f911SVille Syrjälä static void intel_ddi_set_link_train(struct intel_dp *intel_dp, 3510a621860aSVille Syrjälä const struct intel_crtc_state *crtc_state, 3511eee3f911SVille Syrjälä u8 dp_train_pat) 3512eee3f911SVille Syrjälä { 3513ef79fafeSVille Syrjälä struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; 3514ef79fafeSVille Syrjälä struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 3515eee3f911SVille Syrjälä u32 temp; 3516eee3f911SVille Syrjälä 3517ef79fafeSVille Syrjälä temp = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state)); 3518eee3f911SVille Syrjälä 3519eee3f911SVille Syrjälä temp &= ~DP_TP_CTL_LINK_TRAIN_MASK; 35206777a855SImre Deak switch (intel_dp_training_pattern_symbol(dp_train_pat)) { 3521eee3f911SVille Syrjälä case DP_TRAINING_PATTERN_DISABLE: 3522eee3f911SVille Syrjälä temp |= DP_TP_CTL_LINK_TRAIN_NORMAL; 3523eee3f911SVille Syrjälä break; 3524eee3f911SVille Syrjälä case DP_TRAINING_PATTERN_1: 3525eee3f911SVille Syrjälä temp |= DP_TP_CTL_LINK_TRAIN_PAT1; 3526eee3f911SVille Syrjälä break; 3527eee3f911SVille Syrjälä case DP_TRAINING_PATTERN_2: 3528eee3f911SVille Syrjälä temp |= DP_TP_CTL_LINK_TRAIN_PAT2; 3529eee3f911SVille Syrjälä break; 3530eee3f911SVille Syrjälä case DP_TRAINING_PATTERN_3: 3531eee3f911SVille Syrjälä temp |= DP_TP_CTL_LINK_TRAIN_PAT3; 3532eee3f911SVille Syrjälä break; 3533eee3f911SVille Syrjälä case DP_TRAINING_PATTERN_4: 3534eee3f911SVille Syrjälä temp |= DP_TP_CTL_LINK_TRAIN_PAT4; 3535eee3f911SVille Syrjälä break; 3536eee3f911SVille Syrjälä } 3537eee3f911SVille Syrjälä 3538ef79fafeSVille Syrjälä intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), temp); 3539eee3f911SVille Syrjälä } 3540eee3f911SVille Syrjälä 3541a621860aSVille Syrjälä static void intel_ddi_set_idle_link_train(struct intel_dp *intel_dp, 3542a621860aSVille Syrjälä const struct intel_crtc_state *crtc_state) 35438fdda385SVille Syrjälä { 35448fdda385SVille Syrjälä struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; 35458fdda385SVille Syrjälä struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 35468fdda385SVille Syrjälä enum port port = encoder->port; 35478fdda385SVille Syrjälä 35488910d8b7SAndrzej Hajda intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), 35498910d8b7SAndrzej Hajda DP_TP_CTL_LINK_TRAIN_MASK, DP_TP_CTL_LINK_TRAIN_IDLE); 35508fdda385SVille Syrjälä 35518fdda385SVille Syrjälä /* 35528fdda385SVille Syrjälä * Until TGL on PORT_A we can have only eDP in SST mode. There the only 35538fdda385SVille Syrjälä * reason we need to set idle transmission mode is to work around a HW 35548fdda385SVille Syrjälä * issue where we enable the pipe while not in idle link-training mode. 35558fdda385SVille Syrjälä * In this case there is requirement to wait for a minimum number of 35568fdda385SVille Syrjälä * idle patterns to be sent. 35578fdda385SVille Syrjälä */ 3558005e9537SMatt Roper if (port == PORT_A && DISPLAY_VER(dev_priv) < 12) 35598fdda385SVille Syrjälä return; 35608fdda385SVille Syrjälä 3561ef79fafeSVille Syrjälä if (intel_de_wait_for_set(dev_priv, 3562ef79fafeSVille Syrjälä dp_tp_status_reg(encoder, crtc_state), 35638fdda385SVille Syrjälä DP_TP_STATUS_IDLE_DONE, 1)) 35648fdda385SVille Syrjälä drm_err(&dev_priv->drm, 35658fdda385SVille Syrjälä "Timed out waiting for DP idle patterns\n"); 35668fdda385SVille Syrjälä } 35678fdda385SVille Syrjälä 3568379bc100SJani Nikula static bool intel_ddi_is_audio_enabled(struct drm_i915_private *dev_priv, 3569379bc100SJani Nikula enum transcoder cpu_transcoder) 3570379bc100SJani Nikula { 3571379bc100SJani Nikula if (cpu_transcoder == TRANSCODER_EDP) 3572379bc100SJani Nikula return false; 3573379bc100SJani Nikula 3574615a7724SAnshuman Gupta if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO_MMIO)) 3575379bc100SJani Nikula return false; 3576379bc100SJani Nikula 3577f7960e7fSJani Nikula return intel_de_read(dev_priv, HSW_AUD_PIN_ELD_CP_VLD) & 3578379bc100SJani Nikula AUDIO_OUTPUT_ENABLE(cpu_transcoder); 3579379bc100SJani Nikula } 3580379bc100SJani Nikula 3581379bc100SJani Nikula void intel_ddi_compute_min_voltage_level(struct drm_i915_private *dev_priv, 3582379bc100SJani Nikula struct intel_crtc_state *crtc_state) 3583379bc100SJani Nikula { 3584005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 12 && crtc_state->port_clock > 594000) 35850fde0b1dSMatt Roper crtc_state->min_voltage_level = 2; 358624ea098bSTejas Upadhyay else if (IS_JSL_EHL(dev_priv) && crtc_state->port_clock > 594000) 35879d5fd37eSMatt Roper crtc_state->min_voltage_level = 3; 3588005e9537SMatt Roper else if (DISPLAY_VER(dev_priv) >= 11 && crtc_state->port_clock > 594000) 3589379bc100SJani Nikula crtc_state->min_voltage_level = 1; 3590379bc100SJani Nikula } 3591379bc100SJani Nikula 3592dc5b8ed5SVille Syrjälä static enum transcoder bdw_transcoder_master_readout(struct drm_i915_private *dev_priv, 359302d8ea47SVille Syrjälä enum transcoder cpu_transcoder) 359402d8ea47SVille Syrjälä { 3595dc5b8ed5SVille Syrjälä u32 master_select; 359602d8ea47SVille Syrjälä 3597005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 11) { 3598dc5b8ed5SVille Syrjälä u32 ctl2 = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL2(cpu_transcoder)); 359902d8ea47SVille Syrjälä 360002d8ea47SVille Syrjälä if ((ctl2 & PORT_SYNC_MODE_ENABLE) == 0) 360102d8ea47SVille Syrjälä return INVALID_TRANSCODER; 360202d8ea47SVille Syrjälä 3603d4d7d9caSVille Syrjälä master_select = REG_FIELD_GET(PORT_SYNC_MODE_MASTER_SELECT_MASK, ctl2); 3604dc5b8ed5SVille Syrjälä } else { 3605dc5b8ed5SVille Syrjälä u32 ctl = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder)); 3606dc5b8ed5SVille Syrjälä 3607dc5b8ed5SVille Syrjälä if ((ctl & TRANS_DDI_PORT_SYNC_ENABLE) == 0) 3608dc5b8ed5SVille Syrjälä return INVALID_TRANSCODER; 3609dc5b8ed5SVille Syrjälä 3610dc5b8ed5SVille Syrjälä master_select = REG_FIELD_GET(TRANS_DDI_PORT_SYNC_MASTER_SELECT_MASK, ctl); 3611dc5b8ed5SVille Syrjälä } 361202d8ea47SVille Syrjälä 361302d8ea47SVille Syrjälä if (master_select == 0) 361402d8ea47SVille Syrjälä return TRANSCODER_EDP; 361502d8ea47SVille Syrjälä else 361602d8ea47SVille Syrjälä return master_select - 1; 361702d8ea47SVille Syrjälä } 361802d8ea47SVille Syrjälä 3619dc5b8ed5SVille Syrjälä static void bdw_get_trans_port_sync_config(struct intel_crtc_state *crtc_state) 362002d8ea47SVille Syrjälä { 362102d8ea47SVille Syrjälä struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); 362202d8ea47SVille Syrjälä u32 transcoders = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | 362302d8ea47SVille Syrjälä BIT(TRANSCODER_C) | BIT(TRANSCODER_D); 362402d8ea47SVille Syrjälä enum transcoder cpu_transcoder; 362502d8ea47SVille Syrjälä 362602d8ea47SVille Syrjälä crtc_state->master_transcoder = 3627dc5b8ed5SVille Syrjälä bdw_transcoder_master_readout(dev_priv, crtc_state->cpu_transcoder); 362802d8ea47SVille Syrjälä 362902d8ea47SVille Syrjälä for_each_cpu_transcoder_masked(dev_priv, cpu_transcoder, transcoders) { 363002d8ea47SVille Syrjälä enum intel_display_power_domain power_domain; 363102d8ea47SVille Syrjälä intel_wakeref_t trans_wakeref; 363202d8ea47SVille Syrjälä 363302d8ea47SVille Syrjälä power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder); 363402d8ea47SVille Syrjälä trans_wakeref = intel_display_power_get_if_enabled(dev_priv, 363502d8ea47SVille Syrjälä power_domain); 363602d8ea47SVille Syrjälä 363702d8ea47SVille Syrjälä if (!trans_wakeref) 363802d8ea47SVille Syrjälä continue; 363902d8ea47SVille Syrjälä 3640dc5b8ed5SVille Syrjälä if (bdw_transcoder_master_readout(dev_priv, cpu_transcoder) == 364102d8ea47SVille Syrjälä crtc_state->cpu_transcoder) 364202d8ea47SVille Syrjälä crtc_state->sync_mode_slaves_mask |= BIT(cpu_transcoder); 364302d8ea47SVille Syrjälä 364402d8ea47SVille Syrjälä intel_display_power_put(dev_priv, power_domain, trans_wakeref); 364502d8ea47SVille Syrjälä } 364602d8ea47SVille Syrjälä 364702d8ea47SVille Syrjälä drm_WARN_ON(&dev_priv->drm, 364802d8ea47SVille Syrjälä crtc_state->master_transcoder != INVALID_TRANSCODER && 364902d8ea47SVille Syrjälä crtc_state->sync_mode_slaves_mask); 365002d8ea47SVille Syrjälä } 365102d8ea47SVille Syrjälä 36520385eceaSManasi Navare static void intel_ddi_read_func_ctl(struct intel_encoder *encoder, 3653379bc100SJani Nikula struct intel_crtc_state *pipe_config) 3654379bc100SJani Nikula { 3655379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 3656f15f01a7SVille Syrjälä struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); 3657379bc100SJani Nikula enum transcoder cpu_transcoder = pipe_config->cpu_transcoder; 3658a44289b9SUma Shankar struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 3659379bc100SJani Nikula u32 temp, flags = 0; 3660379bc100SJani Nikula 3661f7960e7fSJani Nikula temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder)); 3662379bc100SJani Nikula if (temp & TRANS_DDI_PHSYNC) 3663379bc100SJani Nikula flags |= DRM_MODE_FLAG_PHSYNC; 3664379bc100SJani Nikula else 3665379bc100SJani Nikula flags |= DRM_MODE_FLAG_NHSYNC; 3666379bc100SJani Nikula if (temp & TRANS_DDI_PVSYNC) 3667379bc100SJani Nikula flags |= DRM_MODE_FLAG_PVSYNC; 3668379bc100SJani Nikula else 3669379bc100SJani Nikula flags |= DRM_MODE_FLAG_NVSYNC; 3670379bc100SJani Nikula 36711326a92cSMaarten Lankhorst pipe_config->hw.adjusted_mode.flags |= flags; 3672379bc100SJani Nikula 3673379bc100SJani Nikula switch (temp & TRANS_DDI_BPC_MASK) { 3674379bc100SJani Nikula case TRANS_DDI_BPC_6: 3675379bc100SJani Nikula pipe_config->pipe_bpp = 18; 3676379bc100SJani Nikula break; 3677379bc100SJani Nikula case TRANS_DDI_BPC_8: 3678379bc100SJani Nikula pipe_config->pipe_bpp = 24; 3679379bc100SJani Nikula break; 3680379bc100SJani Nikula case TRANS_DDI_BPC_10: 3681379bc100SJani Nikula pipe_config->pipe_bpp = 30; 3682379bc100SJani Nikula break; 3683379bc100SJani Nikula case TRANS_DDI_BPC_12: 3684379bc100SJani Nikula pipe_config->pipe_bpp = 36; 3685379bc100SJani Nikula break; 3686379bc100SJani Nikula default: 3687379bc100SJani Nikula break; 3688379bc100SJani Nikula } 3689379bc100SJani Nikula 3690379bc100SJani Nikula switch (temp & TRANS_DDI_MODE_SELECT_MASK) { 3691379bc100SJani Nikula case TRANS_DDI_MODE_SELECT_HDMI: 3692379bc100SJani Nikula pipe_config->has_hdmi_sink = true; 3693379bc100SJani Nikula 3694379bc100SJani Nikula pipe_config->infoframes.enable |= 3695379bc100SJani Nikula intel_hdmi_infoframes_enabled(encoder, pipe_config); 3696379bc100SJani Nikula 3697379bc100SJani Nikula if (pipe_config->infoframes.enable) 3698379bc100SJani Nikula pipe_config->has_infoframe = true; 3699379bc100SJani Nikula 3700379bc100SJani Nikula if (temp & TRANS_DDI_HDMI_SCRAMBLING) 3701379bc100SJani Nikula pipe_config->hdmi_scrambling = true; 3702379bc100SJani Nikula if (temp & TRANS_DDI_HIGH_TMDS_CHAR_RATE) 3703379bc100SJani Nikula pipe_config->hdmi_high_tmds_clock_ratio = true; 3704df561f66SGustavo A. R. Silva fallthrough; 3705379bc100SJani Nikula case TRANS_DDI_MODE_SELECT_DVI: 3706379bc100SJani Nikula pipe_config->output_types |= BIT(INTEL_OUTPUT_HDMI); 3707b66a8abaSAnkit Nautiyal if (DISPLAY_VER(dev_priv) >= 14) 3708b66a8abaSAnkit Nautiyal pipe_config->lane_count = 3709b66a8abaSAnkit Nautiyal ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1; 3710b66a8abaSAnkit Nautiyal else 3711379bc100SJani Nikula pipe_config->lane_count = 4; 3712379bc100SJani Nikula break; 3713379bc100SJani Nikula case TRANS_DDI_MODE_SELECT_DP_SST: 3714379bc100SJani Nikula if (encoder->type == INTEL_OUTPUT_EDP) 3715379bc100SJani Nikula pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP); 3716379bc100SJani Nikula else 3717379bc100SJani Nikula pipe_config->output_types |= BIT(INTEL_OUTPUT_DP); 3718379bc100SJani Nikula pipe_config->lane_count = 3719379bc100SJani Nikula ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1; 37206149cb68SVille Syrjälä 37215cd06644SVille Syrjälä intel_cpu_transcoder_get_m1_n1(crtc, cpu_transcoder, 37225cd06644SVille Syrjälä &pipe_config->dp_m_n); 37235cd06644SVille Syrjälä intel_cpu_transcoder_get_m2_n2(crtc, cpu_transcoder, 37246149cb68SVille Syrjälä &pipe_config->dp_m2_n2); 37258aa940c8SMaarten Lankhorst 3726005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 11) { 3727ef79fafeSVille Syrjälä i915_reg_t dp_tp_ctl = dp_tp_ctl_reg(encoder, pipe_config); 37288aa940c8SMaarten Lankhorst 37298aa940c8SMaarten Lankhorst pipe_config->fec_enable = 3730f7960e7fSJani Nikula intel_de_read(dev_priv, dp_tp_ctl) & DP_TP_CTL_FEC_ENABLE; 37318aa940c8SMaarten Lankhorst 373247bdb1caSJani Nikula drm_dbg_kms(&dev_priv->drm, 373347bdb1caSJani Nikula "[ENCODER:%d:%s] Fec status: %u\n", 37348aa940c8SMaarten Lankhorst encoder->base.base.id, encoder->base.name, 37358aa940c8SMaarten Lankhorst pipe_config->fec_enable); 37368aa940c8SMaarten Lankhorst } 37378aa940c8SMaarten Lankhorst 3738a44289b9SUma Shankar if (dig_port->lspcon.active && dig_port->dp.has_hdmi_sink) 3739a44289b9SUma Shankar pipe_config->infoframes.enable |= 3740a44289b9SUma Shankar intel_lspcon_infoframes_enabled(encoder, pipe_config); 3741a44289b9SUma Shankar else 3742dee66f3eSGwan-gyeong Mun pipe_config->infoframes.enable |= 3743dee66f3eSGwan-gyeong Mun intel_hdmi_infoframes_enabled(encoder, pipe_config); 3744379bc100SJani Nikula break; 374565213594SJani Nikula case TRANS_DDI_MODE_SELECT_FDI_OR_128B132B: 374665213594SJani Nikula if (!HAS_DP20(dev_priv)) { 374765213594SJani Nikula /* FDI */ 374865213594SJani Nikula pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG); 374965213594SJani Nikula break; 375065213594SJani Nikula } 375165213594SJani Nikula fallthrough; /* 128b/132b */ 3752379bc100SJani Nikula case TRANS_DDI_MODE_SELECT_DP_MST: 3753379bc100SJani Nikula pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST); 3754379bc100SJani Nikula pipe_config->lane_count = 3755379bc100SJani Nikula ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1; 37566671c367SJosé Roberto de Souza 3757005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 12) 37586671c367SJosé Roberto de Souza pipe_config->mst_master_transcoder = 37596671c367SJosé Roberto de Souza REG_FIELD_GET(TRANS_DDI_MST_TRANSPORT_SELECT_MASK, temp); 37606671c367SJosé Roberto de Souza 37615cd06644SVille Syrjälä intel_cpu_transcoder_get_m1_n1(crtc, cpu_transcoder, 37625cd06644SVille Syrjälä &pipe_config->dp_m_n); 3763dee66f3eSGwan-gyeong Mun 3764dee66f3eSGwan-gyeong Mun pipe_config->infoframes.enable |= 3765dee66f3eSGwan-gyeong Mun intel_hdmi_infoframes_enabled(encoder, pipe_config); 3766379bc100SJani Nikula break; 3767379bc100SJani Nikula default: 3768379bc100SJani Nikula break; 3769379bc100SJani Nikula } 37700385eceaSManasi Navare } 37710385eceaSManasi Navare 3772351221ffSVille Syrjälä static void intel_ddi_get_config(struct intel_encoder *encoder, 37730385eceaSManasi Navare struct intel_crtc_state *pipe_config) 37740385eceaSManasi Navare { 37750385eceaSManasi Navare struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 37760385eceaSManasi Navare enum transcoder cpu_transcoder = pipe_config->cpu_transcoder; 37770385eceaSManasi Navare 37780385eceaSManasi Navare /* XXX: DSI transcoder paranoia */ 37790385eceaSManasi Navare if (drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder))) 37800385eceaSManasi Navare return; 37810385eceaSManasi Navare 37820385eceaSManasi Navare intel_ddi_read_func_ctl(encoder, pipe_config); 3783379bc100SJani Nikula 37845b616a29SJani Nikula intel_ddi_mso_get_config(encoder, pipe_config); 37855b616a29SJani Nikula 3786379bc100SJani Nikula pipe_config->has_audio = 3787379bc100SJani Nikula intel_ddi_is_audio_enabled(dev_priv, cpu_transcoder); 3788379bc100SJani Nikula 3789822e5ae7SVille Syrjälä if (encoder->type == INTEL_OUTPUT_EDP) 3790822e5ae7SVille Syrjälä intel_edp_fixup_vbt_bpp(encoder, pipe_config->pipe_bpp); 3791379bc100SJani Nikula 3792351221ffSVille Syrjälä ddi_dotclock_get(pipe_config); 3793379bc100SJani Nikula 37942446e1d6SMatt Roper if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) 3795379bc100SJani Nikula pipe_config->lane_lat_optim_mask = 3796379bc100SJani Nikula bxt_ddi_phy_get_lane_lat_optim_mask(encoder); 3797379bc100SJani Nikula 3798379bc100SJani Nikula intel_ddi_compute_min_voltage_level(dev_priv, pipe_config); 3799379bc100SJani Nikula 3800379bc100SJani Nikula intel_hdmi_read_gcp_infoframe(encoder, pipe_config); 3801379bc100SJani Nikula 3802379bc100SJani Nikula intel_read_infoframe(encoder, pipe_config, 3803379bc100SJani Nikula HDMI_INFOFRAME_TYPE_AVI, 3804379bc100SJani Nikula &pipe_config->infoframes.avi); 3805379bc100SJani Nikula intel_read_infoframe(encoder, pipe_config, 3806379bc100SJani Nikula HDMI_INFOFRAME_TYPE_SPD, 3807379bc100SJani Nikula &pipe_config->infoframes.spd); 3808379bc100SJani Nikula intel_read_infoframe(encoder, pipe_config, 3809379bc100SJani Nikula HDMI_INFOFRAME_TYPE_VENDOR, 3810379bc100SJani Nikula &pipe_config->infoframes.hdmi); 3811379bc100SJani Nikula intel_read_infoframe(encoder, pipe_config, 3812379bc100SJani Nikula HDMI_INFOFRAME_TYPE_DRM, 3813379bc100SJani Nikula &pipe_config->infoframes.drm); 381402d8ea47SVille Syrjälä 3815005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 8) 3816dc5b8ed5SVille Syrjälä bdw_get_trans_port_sync_config(pipe_config); 3817dee66f3eSGwan-gyeong Mun 3818dee66f3eSGwan-gyeong Mun intel_read_dp_sdp(encoder, pipe_config, HDMI_PACKET_TYPE_GAMUT_METADATA); 38192c3928e4SGwan-gyeong Mun intel_read_dp_sdp(encoder, pipe_config, DP_SDP_VSC); 382078b772e1SJosé Roberto de Souza 382178b772e1SJosé Roberto de Souza intel_psr_get_config(encoder, pipe_config); 382261a60df6SVille Syrjälä 382361a60df6SVille Syrjälä intel_audio_codec_get_config(encoder, pipe_config); 3824379bc100SJani Nikula } 3825379bc100SJani Nikula 3826351221ffSVille Syrjälä void intel_ddi_get_clock(struct intel_encoder *encoder, 3827351221ffSVille Syrjälä struct intel_crtc_state *crtc_state, 3828351221ffSVille Syrjälä struct intel_shared_dpll *pll) 3829351221ffSVille Syrjälä { 3830351221ffSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 3831351221ffSVille Syrjälä enum icl_port_dpll_id port_dpll_id = ICL_PORT_DPLL_DEFAULT; 3832351221ffSVille Syrjälä struct icl_port_dpll *port_dpll = &crtc_state->icl_port_dplls[port_dpll_id]; 3833351221ffSVille Syrjälä bool pll_active; 3834351221ffSVille Syrjälä 3835086877a1SVille Syrjälä if (drm_WARN_ON(&i915->drm, !pll)) 3836086877a1SVille Syrjälä return; 3837086877a1SVille Syrjälä 3838351221ffSVille Syrjälä port_dpll->pll = pll; 3839351221ffSVille Syrjälä pll_active = intel_dpll_get_hw_state(i915, pll, &port_dpll->hw_state); 3840351221ffSVille Syrjälä drm_WARN_ON(&i915->drm, !pll_active); 3841351221ffSVille Syrjälä 3842351221ffSVille Syrjälä icl_set_active_port_dpll(crtc_state, port_dpll_id); 3843351221ffSVille Syrjälä 3844351221ffSVille Syrjälä crtc_state->port_clock = intel_dpll_get_freq(i915, crtc_state->shared_dpll, 3845351221ffSVille Syrjälä &crtc_state->dpll_hw_state); 3846351221ffSVille Syrjälä } 3847351221ffSVille Syrjälä 384851390cc0SRadhakrishna Sripada static void mtl_ddi_get_config(struct intel_encoder *encoder, 384951390cc0SRadhakrishna Sripada struct intel_crtc_state *crtc_state) 385051390cc0SRadhakrishna Sripada { 385151390cc0SRadhakrishna Sripada struct drm_i915_private *i915 = to_i915(encoder->base.dev); 385251390cc0SRadhakrishna Sripada enum phy phy = intel_port_to_phy(i915, encoder->port); 38537dee06bcSMika Kahola struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 385451390cc0SRadhakrishna Sripada 38557dee06bcSMika Kahola if (intel_tc_port_in_tbt_alt_mode(dig_port)) { 38567dee06bcSMika Kahola crtc_state->port_clock = intel_mtl_tbt_calc_port_clock(encoder); 38577dee06bcSMika Kahola } else if (intel_is_c10phy(i915, phy)) { 385851390cc0SRadhakrishna Sripada intel_c10pll_readout_hw_state(encoder, &crtc_state->cx0pll_state.c10); 385951390cc0SRadhakrishna Sripada intel_c10pll_dump_hw_state(i915, &crtc_state->cx0pll_state.c10); 3860f1f9e627SMika Kahola crtc_state->port_clock = intel_c10pll_calc_port_clock(encoder, &crtc_state->cx0pll_state.c10); 3861929f527aSMika Kahola } else { 3862929f527aSMika Kahola intel_c20pll_readout_hw_state(encoder, &crtc_state->cx0pll_state.c20); 3863f968a253SMika Kahola intel_c20pll_dump_hw_state(i915, &crtc_state->cx0pll_state.c20); 3864f1f9e627SMika Kahola crtc_state->port_clock = intel_c20pll_calc_port_clock(encoder, &crtc_state->cx0pll_state.c20); 3865929f527aSMika Kahola } 3866929f527aSMika Kahola 386751390cc0SRadhakrishna Sripada intel_ddi_get_config(encoder, crtc_state); 386851390cc0SRadhakrishna Sripada } 386951390cc0SRadhakrishna Sripada 3870865b73eaSMatt Roper static void dg2_ddi_get_config(struct intel_encoder *encoder, 3871865b73eaSMatt Roper struct intel_crtc_state *crtc_state) 3872865b73eaSMatt Roper { 3873865b73eaSMatt Roper intel_mpllb_readout_hw_state(encoder, &crtc_state->mpllb_state); 3874865b73eaSMatt Roper crtc_state->port_clock = intel_mpllb_calc_port_clock(encoder, &crtc_state->mpllb_state); 3875865b73eaSMatt Roper 3876865b73eaSMatt Roper intel_ddi_get_config(encoder, crtc_state); 3877865b73eaSMatt Roper } 3878865b73eaSMatt Roper 3879351221ffSVille Syrjälä static void adls_ddi_get_config(struct intel_encoder *encoder, 3880351221ffSVille Syrjälä struct intel_crtc_state *crtc_state) 3881351221ffSVille Syrjälä { 3882351221ffSVille Syrjälä intel_ddi_get_clock(encoder, crtc_state, adls_ddi_get_pll(encoder)); 3883351221ffSVille Syrjälä intel_ddi_get_config(encoder, crtc_state); 3884351221ffSVille Syrjälä } 3885351221ffSVille Syrjälä 3886351221ffSVille Syrjälä static void rkl_ddi_get_config(struct intel_encoder *encoder, 3887351221ffSVille Syrjälä struct intel_crtc_state *crtc_state) 3888351221ffSVille Syrjälä { 3889351221ffSVille Syrjälä intel_ddi_get_clock(encoder, crtc_state, rkl_ddi_get_pll(encoder)); 3890351221ffSVille Syrjälä intel_ddi_get_config(encoder, crtc_state); 3891351221ffSVille Syrjälä } 3892351221ffSVille Syrjälä 3893351221ffSVille Syrjälä static void dg1_ddi_get_config(struct intel_encoder *encoder, 3894351221ffSVille Syrjälä struct intel_crtc_state *crtc_state) 3895351221ffSVille Syrjälä { 3896351221ffSVille Syrjälä intel_ddi_get_clock(encoder, crtc_state, dg1_ddi_get_pll(encoder)); 3897351221ffSVille Syrjälä intel_ddi_get_config(encoder, crtc_state); 3898351221ffSVille Syrjälä } 3899351221ffSVille Syrjälä 3900351221ffSVille Syrjälä static void icl_ddi_combo_get_config(struct intel_encoder *encoder, 3901351221ffSVille Syrjälä struct intel_crtc_state *crtc_state) 3902351221ffSVille Syrjälä { 3903351221ffSVille Syrjälä intel_ddi_get_clock(encoder, crtc_state, icl_ddi_combo_get_pll(encoder)); 3904351221ffSVille Syrjälä intel_ddi_get_config(encoder, crtc_state); 3905351221ffSVille Syrjälä } 3906351221ffSVille Syrjälä 39077c1da068SImre Deak static bool icl_ddi_tc_pll_is_tbt(const struct intel_shared_dpll *pll) 39087c1da068SImre Deak { 39097c1da068SImre Deak return pll->info->id == DPLL_ID_ICL_TBTPLL; 39107c1da068SImre Deak } 39117c1da068SImre Deak 39127c1da068SImre Deak static enum icl_port_dpll_id 39137c1da068SImre Deak icl_ddi_tc_port_pll_type(struct intel_encoder *encoder, 39147c1da068SImre Deak const struct intel_crtc_state *crtc_state) 39157c1da068SImre Deak { 39167c1da068SImre Deak struct drm_i915_private *i915 = to_i915(encoder->base.dev); 39177c1da068SImre Deak const struct intel_shared_dpll *pll = crtc_state->shared_dpll; 39187c1da068SImre Deak 39197c1da068SImre Deak if (drm_WARN_ON(&i915->drm, !pll)) 39207c1da068SImre Deak return ICL_PORT_DPLL_DEFAULT; 39217c1da068SImre Deak 39227c1da068SImre Deak if (icl_ddi_tc_pll_is_tbt(pll)) 39237c1da068SImre Deak return ICL_PORT_DPLL_DEFAULT; 39247c1da068SImre Deak else 39257c1da068SImre Deak return ICL_PORT_DPLL_MG_PHY; 39267c1da068SImre Deak } 39277c1da068SImre Deak 39287c1da068SImre Deak enum icl_port_dpll_id 39297c1da068SImre Deak intel_ddi_port_pll_type(struct intel_encoder *encoder, 39307c1da068SImre Deak const struct intel_crtc_state *crtc_state) 39317c1da068SImre Deak { 39327c1da068SImre Deak if (!encoder->port_pll_type) 39337c1da068SImre Deak return ICL_PORT_DPLL_DEFAULT; 39347c1da068SImre Deak 39357c1da068SImre Deak return encoder->port_pll_type(encoder, crtc_state); 39367c1da068SImre Deak } 39377c1da068SImre Deak 3938086877a1SVille Syrjälä static void icl_ddi_tc_get_clock(struct intel_encoder *encoder, 3939086877a1SVille Syrjälä struct intel_crtc_state *crtc_state, 3940086877a1SVille Syrjälä struct intel_shared_dpll *pll) 3941351221ffSVille Syrjälä { 3942351221ffSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 3943351221ffSVille Syrjälä enum icl_port_dpll_id port_dpll_id; 3944351221ffSVille Syrjälä struct icl_port_dpll *port_dpll; 3945351221ffSVille Syrjälä bool pll_active; 3946351221ffSVille Syrjälä 3947086877a1SVille Syrjälä if (drm_WARN_ON(&i915->drm, !pll)) 3948086877a1SVille Syrjälä return; 3949351221ffSVille Syrjälä 39507c1da068SImre Deak if (icl_ddi_tc_pll_is_tbt(pll)) 3951351221ffSVille Syrjälä port_dpll_id = ICL_PORT_DPLL_DEFAULT; 3952351221ffSVille Syrjälä else 3953351221ffSVille Syrjälä port_dpll_id = ICL_PORT_DPLL_MG_PHY; 3954351221ffSVille Syrjälä 3955351221ffSVille Syrjälä port_dpll = &crtc_state->icl_port_dplls[port_dpll_id]; 3956351221ffSVille Syrjälä 3957351221ffSVille Syrjälä port_dpll->pll = pll; 3958351221ffSVille Syrjälä pll_active = intel_dpll_get_hw_state(i915, pll, &port_dpll->hw_state); 3959351221ffSVille Syrjälä drm_WARN_ON(&i915->drm, !pll_active); 3960351221ffSVille Syrjälä 3961351221ffSVille Syrjälä icl_set_active_port_dpll(crtc_state, port_dpll_id); 3962351221ffSVille Syrjälä 39637c1da068SImre Deak if (icl_ddi_tc_pll_is_tbt(crtc_state->shared_dpll)) 3964351221ffSVille Syrjälä crtc_state->port_clock = icl_calc_tbt_pll_link(i915, encoder->port); 3965351221ffSVille Syrjälä else 3966351221ffSVille Syrjälä crtc_state->port_clock = intel_dpll_get_freq(i915, crtc_state->shared_dpll, 3967351221ffSVille Syrjälä &crtc_state->dpll_hw_state); 3968086877a1SVille Syrjälä } 3969351221ffSVille Syrjälä 3970086877a1SVille Syrjälä static void icl_ddi_tc_get_config(struct intel_encoder *encoder, 3971086877a1SVille Syrjälä struct intel_crtc_state *crtc_state) 3972086877a1SVille Syrjälä { 3973086877a1SVille Syrjälä icl_ddi_tc_get_clock(encoder, crtc_state, icl_ddi_tc_get_pll(encoder)); 3974351221ffSVille Syrjälä intel_ddi_get_config(encoder, crtc_state); 3975351221ffSVille Syrjälä } 3976351221ffSVille Syrjälä 3977351221ffSVille Syrjälä static void bxt_ddi_get_config(struct intel_encoder *encoder, 3978351221ffSVille Syrjälä struct intel_crtc_state *crtc_state) 3979351221ffSVille Syrjälä { 3980351221ffSVille Syrjälä intel_ddi_get_clock(encoder, crtc_state, bxt_ddi_get_pll(encoder)); 3981351221ffSVille Syrjälä intel_ddi_get_config(encoder, crtc_state); 3982351221ffSVille Syrjälä } 3983351221ffSVille Syrjälä 3984351221ffSVille Syrjälä static void skl_ddi_get_config(struct intel_encoder *encoder, 3985351221ffSVille Syrjälä struct intel_crtc_state *crtc_state) 3986351221ffSVille Syrjälä { 3987351221ffSVille Syrjälä intel_ddi_get_clock(encoder, crtc_state, skl_ddi_get_pll(encoder)); 3988351221ffSVille Syrjälä intel_ddi_get_config(encoder, crtc_state); 3989351221ffSVille Syrjälä } 3990351221ffSVille Syrjälä 3991351221ffSVille Syrjälä void hsw_ddi_get_config(struct intel_encoder *encoder, 3992351221ffSVille Syrjälä struct intel_crtc_state *crtc_state) 3993351221ffSVille Syrjälä { 3994351221ffSVille Syrjälä intel_ddi_get_clock(encoder, crtc_state, hsw_ddi_get_pll(encoder)); 3995351221ffSVille Syrjälä intel_ddi_get_config(encoder, crtc_state); 3996351221ffSVille Syrjälä } 3997351221ffSVille Syrjälä 3998f9e76a6eSImre Deak static void intel_ddi_sync_state(struct intel_encoder *encoder, 3999f9e76a6eSImre Deak const struct intel_crtc_state *crtc_state) 4000f9e76a6eSImre Deak { 40017194dc99SImre Deak struct drm_i915_private *i915 = to_i915(encoder->base.dev); 40027194dc99SImre Deak enum phy phy = intel_port_to_phy(i915, encoder->port); 40037194dc99SImre Deak 40047194dc99SImre Deak if (intel_phy_is_tc(i915, phy)) 40052a4d292fSImre Deak intel_tc_port_sanitize_mode(enc_to_dig_port(encoder), 40062a4d292fSImre Deak crtc_state); 40077194dc99SImre Deak 40087194dc99SImre Deak if (crtc_state && intel_crtc_has_dp_encoder(crtc_state)) 4009f9e76a6eSImre Deak intel_dp_sync_state(encoder, crtc_state); 4010f9e76a6eSImre Deak } 4011f9e76a6eSImre Deak 4012b671d6efSImre Deak static bool intel_ddi_initial_fastset_check(struct intel_encoder *encoder, 4013b671d6efSImre Deak struct intel_crtc_state *crtc_state) 4014b671d6efSImre Deak { 4015eddb4afcSVille Syrjälä struct drm_i915_private *i915 = to_i915(encoder->base.dev); 4016eddb4afcSVille Syrjälä enum phy phy = intel_port_to_phy(i915, encoder->port); 4017eddb4afcSVille Syrjälä bool fastset = true; 4018b671d6efSImre Deak 4019eddb4afcSVille Syrjälä if (intel_phy_is_tc(i915, phy)) { 4020eddb4afcSVille Syrjälä drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] Forcing full modeset to compute TC port DPLLs\n", 4021eddb4afcSVille Syrjälä encoder->base.base.id, encoder->base.name); 4022eddb4afcSVille Syrjälä crtc_state->uapi.mode_changed = true; 4023eddb4afcSVille Syrjälä fastset = false; 4024eddb4afcSVille Syrjälä } 4025eddb4afcSVille Syrjälä 4026eddb4afcSVille Syrjälä if (intel_crtc_has_dp_encoder(crtc_state) && 4027eddb4afcSVille Syrjälä !intel_dp_initial_fastset_check(encoder, crtc_state)) 4028eddb4afcSVille Syrjälä fastset = false; 4029eddb4afcSVille Syrjälä 4030eddb4afcSVille Syrjälä return fastset; 4031b671d6efSImre Deak } 4032b671d6efSImre Deak 4033379bc100SJani Nikula static enum intel_output_type 4034379bc100SJani Nikula intel_ddi_compute_output_type(struct intel_encoder *encoder, 4035379bc100SJani Nikula struct intel_crtc_state *crtc_state, 4036379bc100SJani Nikula struct drm_connector_state *conn_state) 4037379bc100SJani Nikula { 4038379bc100SJani Nikula switch (conn_state->connector->connector_type) { 4039379bc100SJani Nikula case DRM_MODE_CONNECTOR_HDMIA: 4040379bc100SJani Nikula return INTEL_OUTPUT_HDMI; 4041379bc100SJani Nikula case DRM_MODE_CONNECTOR_eDP: 4042379bc100SJani Nikula return INTEL_OUTPUT_EDP; 4043379bc100SJani Nikula case DRM_MODE_CONNECTOR_DisplayPort: 4044379bc100SJani Nikula return INTEL_OUTPUT_DP; 4045379bc100SJani Nikula default: 4046379bc100SJani Nikula MISSING_CASE(conn_state->connector->connector_type); 4047379bc100SJani Nikula return INTEL_OUTPUT_UNUSED; 4048379bc100SJani Nikula } 4049379bc100SJani Nikula } 4050379bc100SJani Nikula 4051379bc100SJani Nikula static int intel_ddi_compute_config(struct intel_encoder *encoder, 4052379bc100SJani Nikula struct intel_crtc_state *pipe_config, 4053379bc100SJani Nikula struct drm_connector_state *conn_state) 4054379bc100SJani Nikula { 40552225f3c6SMaarten Lankhorst struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); 4056379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 4057379bc100SJani Nikula enum port port = encoder->port; 4058379bc100SJani Nikula int ret; 4059379bc100SJani Nikula 406010cf8e75SVille Syrjälä if (HAS_TRANSCODER(dev_priv, TRANSCODER_EDP) && port == PORT_A) 4061379bc100SJani Nikula pipe_config->cpu_transcoder = TRANSCODER_EDP; 4062379bc100SJani Nikula 4063bdacf087SAnshuman Gupta if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_HDMI)) { 406434682d60SVille Syrjälä pipe_config->has_hdmi_sink = 406534682d60SVille Syrjälä intel_hdmi_compute_has_hdmi_sink(encoder, pipe_config, conn_state); 406634682d60SVille Syrjälä 4067379bc100SJani Nikula ret = intel_hdmi_compute_config(encoder, pipe_config, conn_state); 4068bdacf087SAnshuman Gupta } else { 4069379bc100SJani Nikula ret = intel_dp_compute_config(encoder, pipe_config, conn_state); 4070bdacf087SAnshuman Gupta } 4071bdacf087SAnshuman Gupta 4072379bc100SJani Nikula if (ret) 4073379bc100SJani Nikula return ret; 4074379bc100SJani Nikula 4075379bc100SJani Nikula if (IS_HASWELL(dev_priv) && crtc->pipe == PIPE_A && 4076379bc100SJani Nikula pipe_config->cpu_transcoder == TRANSCODER_EDP) 4077379bc100SJani Nikula pipe_config->pch_pfit.force_thru = 4078379bc100SJani Nikula pipe_config->pch_pfit.enabled || 4079379bc100SJani Nikula pipe_config->crc_enabled; 4080379bc100SJani Nikula 40812446e1d6SMatt Roper if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) 4082379bc100SJani Nikula pipe_config->lane_lat_optim_mask = 4083379bc100SJani Nikula bxt_ddi_phy_calc_lane_lat_optim_mask(pipe_config->lane_count); 4084379bc100SJani Nikula 4085379bc100SJani Nikula intel_ddi_compute_min_voltage_level(dev_priv, pipe_config); 4086379bc100SJani Nikula 4087379bc100SJani Nikula return 0; 4088379bc100SJani Nikula } 4089379bc100SJani Nikula 4090b50a1aa6SManasi Navare static bool mode_equal(const struct drm_display_mode *mode1, 4091b50a1aa6SManasi Navare const struct drm_display_mode *mode2) 4092b50a1aa6SManasi Navare { 4093b50a1aa6SManasi Navare return drm_mode_match(mode1, mode2, 4094b50a1aa6SManasi Navare DRM_MODE_MATCH_TIMINGS | 4095b50a1aa6SManasi Navare DRM_MODE_MATCH_FLAGS | 4096b50a1aa6SManasi Navare DRM_MODE_MATCH_3D_FLAGS) && 4097b50a1aa6SManasi Navare mode1->clock == mode2->clock; /* we want an exact match */ 4098b50a1aa6SManasi Navare } 4099b50a1aa6SManasi Navare 4100b50a1aa6SManasi Navare static bool m_n_equal(const struct intel_link_m_n *m_n_1, 4101b50a1aa6SManasi Navare const struct intel_link_m_n *m_n_2) 4102b50a1aa6SManasi Navare { 4103b50a1aa6SManasi Navare return m_n_1->tu == m_n_2->tu && 41045f721a5dSVille Syrjälä m_n_1->data_m == m_n_2->data_m && 41055f721a5dSVille Syrjälä m_n_1->data_n == m_n_2->data_n && 4106b50a1aa6SManasi Navare m_n_1->link_m == m_n_2->link_m && 4107b50a1aa6SManasi Navare m_n_1->link_n == m_n_2->link_n; 4108b50a1aa6SManasi Navare } 4109b50a1aa6SManasi Navare 4110b50a1aa6SManasi Navare static bool crtcs_port_sync_compatible(const struct intel_crtc_state *crtc_state1, 4111b50a1aa6SManasi Navare const struct intel_crtc_state *crtc_state2) 4112b50a1aa6SManasi Navare { 4113b50a1aa6SManasi Navare return crtc_state1->hw.active && crtc_state2->hw.active && 4114b50a1aa6SManasi Navare crtc_state1->output_types == crtc_state2->output_types && 4115b50a1aa6SManasi Navare crtc_state1->output_format == crtc_state2->output_format && 4116b50a1aa6SManasi Navare crtc_state1->lane_count == crtc_state2->lane_count && 4117b50a1aa6SManasi Navare crtc_state1->port_clock == crtc_state2->port_clock && 4118b50a1aa6SManasi Navare mode_equal(&crtc_state1->hw.adjusted_mode, 4119b50a1aa6SManasi Navare &crtc_state2->hw.adjusted_mode) && 4120b50a1aa6SManasi Navare m_n_equal(&crtc_state1->dp_m_n, &crtc_state2->dp_m_n); 4121b50a1aa6SManasi Navare } 4122b50a1aa6SManasi Navare 4123b50a1aa6SManasi Navare static u8 4124b50a1aa6SManasi Navare intel_ddi_port_sync_transcoders(const struct intel_crtc_state *ref_crtc_state, 4125b50a1aa6SManasi Navare int tile_group_id) 4126b50a1aa6SManasi Navare { 4127b50a1aa6SManasi Navare struct drm_connector *connector; 4128b50a1aa6SManasi Navare const struct drm_connector_state *conn_state; 4129b50a1aa6SManasi Navare struct drm_i915_private *dev_priv = to_i915(ref_crtc_state->uapi.crtc->dev); 4130b50a1aa6SManasi Navare struct intel_atomic_state *state = 4131b50a1aa6SManasi Navare to_intel_atomic_state(ref_crtc_state->uapi.state); 4132b50a1aa6SManasi Navare u8 transcoders = 0; 4133b50a1aa6SManasi Navare int i; 4134b50a1aa6SManasi Navare 4135dc5b8ed5SVille Syrjälä /* 4136dc5b8ed5SVille Syrjälä * We don't enable port sync on BDW due to missing w/as and 4137dc5b8ed5SVille Syrjälä * due to not having adjusted the modeset sequence appropriately. 4138dc5b8ed5SVille Syrjälä */ 4139005e9537SMatt Roper if (DISPLAY_VER(dev_priv) < 9) 4140b50a1aa6SManasi Navare return 0; 4141b50a1aa6SManasi Navare 4142b50a1aa6SManasi Navare if (!intel_crtc_has_type(ref_crtc_state, INTEL_OUTPUT_DP)) 4143b50a1aa6SManasi Navare return 0; 4144b50a1aa6SManasi Navare 4145b50a1aa6SManasi Navare for_each_new_connector_in_state(&state->base, connector, conn_state, i) { 4146b50a1aa6SManasi Navare struct intel_crtc *crtc = to_intel_crtc(conn_state->crtc); 4147b50a1aa6SManasi Navare const struct intel_crtc_state *crtc_state; 4148b50a1aa6SManasi Navare 4149b50a1aa6SManasi Navare if (!crtc) 4150b50a1aa6SManasi Navare continue; 4151b50a1aa6SManasi Navare 4152b50a1aa6SManasi Navare if (!connector->has_tile || 4153b50a1aa6SManasi Navare connector->tile_group->id != 4154b50a1aa6SManasi Navare tile_group_id) 4155b50a1aa6SManasi Navare continue; 4156b50a1aa6SManasi Navare crtc_state = intel_atomic_get_new_crtc_state(state, 4157b50a1aa6SManasi Navare crtc); 4158b50a1aa6SManasi Navare if (!crtcs_port_sync_compatible(ref_crtc_state, 4159b50a1aa6SManasi Navare crtc_state)) 4160b50a1aa6SManasi Navare continue; 4161b50a1aa6SManasi Navare transcoders |= BIT(crtc_state->cpu_transcoder); 4162b50a1aa6SManasi Navare } 4163b50a1aa6SManasi Navare 4164b50a1aa6SManasi Navare return transcoders; 4165b50a1aa6SManasi Navare } 4166b50a1aa6SManasi Navare 4167b50a1aa6SManasi Navare static int intel_ddi_compute_config_late(struct intel_encoder *encoder, 4168b50a1aa6SManasi Navare struct intel_crtc_state *crtc_state, 4169b50a1aa6SManasi Navare struct drm_connector_state *conn_state) 4170b50a1aa6SManasi Navare { 417147bdb1caSJani Nikula struct drm_i915_private *i915 = to_i915(encoder->base.dev); 4172b50a1aa6SManasi Navare struct drm_connector *connector = conn_state->connector; 4173b50a1aa6SManasi Navare u8 port_sync_transcoders = 0; 4174b50a1aa6SManasi Navare 417547bdb1caSJani Nikula drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] [CRTC:%d:%s]", 4176b50a1aa6SManasi Navare encoder->base.base.id, encoder->base.name, 4177b50a1aa6SManasi Navare crtc_state->uapi.crtc->base.id, crtc_state->uapi.crtc->name); 4178b50a1aa6SManasi Navare 4179b50a1aa6SManasi Navare if (connector->has_tile) 4180b50a1aa6SManasi Navare port_sync_transcoders = intel_ddi_port_sync_transcoders(crtc_state, 4181b50a1aa6SManasi Navare connector->tile_group->id); 4182b50a1aa6SManasi Navare 4183b50a1aa6SManasi Navare /* 4184b50a1aa6SManasi Navare * EDP Transcoders cannot be ensalved 4185b50a1aa6SManasi Navare * make them a master always when present 4186b50a1aa6SManasi Navare */ 4187b50a1aa6SManasi Navare if (port_sync_transcoders & BIT(TRANSCODER_EDP)) 4188b50a1aa6SManasi Navare crtc_state->master_transcoder = TRANSCODER_EDP; 4189b50a1aa6SManasi Navare else 4190b50a1aa6SManasi Navare crtc_state->master_transcoder = ffs(port_sync_transcoders) - 1; 4191b50a1aa6SManasi Navare 4192b50a1aa6SManasi Navare if (crtc_state->master_transcoder == crtc_state->cpu_transcoder) { 4193b50a1aa6SManasi Navare crtc_state->master_transcoder = INVALID_TRANSCODER; 4194b50a1aa6SManasi Navare crtc_state->sync_mode_slaves_mask = 4195b50a1aa6SManasi Navare port_sync_transcoders & ~BIT(crtc_state->cpu_transcoder); 4196b50a1aa6SManasi Navare } 4197b50a1aa6SManasi Navare 4198b50a1aa6SManasi Navare return 0; 4199b50a1aa6SManasi Navare } 4200b50a1aa6SManasi Navare 4201379bc100SJani Nikula static void intel_ddi_encoder_destroy(struct drm_encoder *encoder) 4202379bc100SJani Nikula { 42034a300e65SImre Deak struct drm_i915_private *i915 = to_i915(encoder->dev); 4204b7d02c3aSVille Syrjälä struct intel_digital_port *dig_port = enc_to_dig_port(to_intel_encoder(encoder)); 42053e0abc76SImre Deak enum phy phy = intel_port_to_phy(i915, dig_port->base.port); 4206379bc100SJani Nikula 4207379bc100SJani Nikula intel_dp_encoder_flush_work(encoder); 42083e0abc76SImre Deak if (intel_phy_is_tc(i915, phy)) 4209c5879999SImre Deak intel_tc_port_cleanup(dig_port); 42104a300e65SImre Deak intel_display_power_flush_work(i915); 4211379bc100SJani Nikula 4212379bc100SJani Nikula drm_encoder_cleanup(encoder); 4213a6c6eac9SAnshuman Gupta kfree(dig_port->hdcp_port_data.streams); 4214379bc100SJani Nikula kfree(dig_port); 4215379bc100SJani Nikula } 4216379bc100SJani Nikula 4217764f6729SVille Syrjälä static void intel_ddi_encoder_reset(struct drm_encoder *encoder) 4218764f6729SVille Syrjälä { 4219a82796a2SImre Deak struct drm_i915_private *i915 = to_i915(encoder->dev); 4220764f6729SVille Syrjälä struct intel_dp *intel_dp = enc_to_intel_dp(to_intel_encoder(encoder)); 4221a82796a2SImre Deak struct intel_digital_port *dig_port = enc_to_dig_port(to_intel_encoder(encoder)); 4222a82796a2SImre Deak enum phy phy = intel_port_to_phy(i915, dig_port->base.port); 4223764f6729SVille Syrjälä 4224764f6729SVille Syrjälä intel_dp->reset_link_params = true; 4225764f6729SVille Syrjälä 4226764f6729SVille Syrjälä intel_pps_encoder_reset(intel_dp); 4227a82796a2SImre Deak 4228a82796a2SImre Deak if (intel_phy_is_tc(i915, phy)) 4229a82796a2SImre Deak intel_tc_port_init_mode(dig_port); 4230764f6729SVille Syrjälä } 4231764f6729SVille Syrjälä 4232379bc100SJani Nikula static const struct drm_encoder_funcs intel_ddi_funcs = { 4233764f6729SVille Syrjälä .reset = intel_ddi_encoder_reset, 4234379bc100SJani Nikula .destroy = intel_ddi_encoder_destroy, 4235379bc100SJani Nikula }; 4236379bc100SJani Nikula 4237379bc100SJani Nikula static struct intel_connector * 42387801f3b7SLucas De Marchi intel_ddi_init_dp_connector(struct intel_digital_port *dig_port) 4239379bc100SJani Nikula { 424023ef6194SJosé Roberto de Souza struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 4241379bc100SJani Nikula struct intel_connector *connector; 42427801f3b7SLucas De Marchi enum port port = dig_port->base.port; 4243379bc100SJani Nikula 4244379bc100SJani Nikula connector = intel_connector_alloc(); 4245379bc100SJani Nikula if (!connector) 4246379bc100SJani Nikula return NULL; 4247379bc100SJani Nikula 42487801f3b7SLucas De Marchi dig_port->dp.output_reg = DDI_BUF_CTL(port); 424923ef6194SJosé Roberto de Souza if (DISPLAY_VER(i915) >= 14) 425023ef6194SJosé Roberto de Souza dig_port->dp.prepare_link_retrain = mtl_ddi_prepare_link_retrain; 425123ef6194SJosé Roberto de Souza else 42527801f3b7SLucas De Marchi dig_port->dp.prepare_link_retrain = intel_ddi_prepare_link_retrain; 42537801f3b7SLucas De Marchi dig_port->dp.set_link_train = intel_ddi_set_link_train; 42547801f3b7SLucas De Marchi dig_port->dp.set_idle_link_train = intel_ddi_set_idle_link_train; 4255eee3f911SVille Syrjälä 42567801f3b7SLucas De Marchi dig_port->dp.voltage_max = intel_ddi_dp_voltage_max; 42577801f3b7SLucas De Marchi dig_port->dp.preemph_max = intel_ddi_dp_preemph_max; 425853de0a20SVille Syrjälä 42597801f3b7SLucas De Marchi if (!intel_dp_init_connector(dig_port, connector)) { 4260379bc100SJani Nikula kfree(connector); 4261379bc100SJani Nikula return NULL; 4262379bc100SJani Nikula } 4263379bc100SJani Nikula 42646306d8dbSHans de Goede if (dig_port->base.type == INTEL_OUTPUT_EDP) { 42656306d8dbSHans de Goede struct drm_device *dev = dig_port->base.base.dev; 42666306d8dbSHans de Goede struct drm_privacy_screen *privacy_screen; 42676306d8dbSHans de Goede 42686306d8dbSHans de Goede privacy_screen = drm_privacy_screen_get(dev->dev, NULL); 42696306d8dbSHans de Goede if (!IS_ERR(privacy_screen)) { 42706306d8dbSHans de Goede drm_connector_attach_privacy_screen_provider(&connector->base, 42716306d8dbSHans de Goede privacy_screen); 42726306d8dbSHans de Goede } else if (PTR_ERR(privacy_screen) != -ENODEV) { 42736306d8dbSHans de Goede drm_warn(dev, "Error getting privacy-screen\n"); 42746306d8dbSHans de Goede } 42756306d8dbSHans de Goede } 42766306d8dbSHans de Goede 4277379bc100SJani Nikula return connector; 4278379bc100SJani Nikula } 4279379bc100SJani Nikula 4280379bc100SJani Nikula static int modeset_pipe(struct drm_crtc *crtc, 4281379bc100SJani Nikula struct drm_modeset_acquire_ctx *ctx) 4282379bc100SJani Nikula { 4283379bc100SJani Nikula struct drm_atomic_state *state; 4284379bc100SJani Nikula struct drm_crtc_state *crtc_state; 4285379bc100SJani Nikula int ret; 4286379bc100SJani Nikula 4287379bc100SJani Nikula state = drm_atomic_state_alloc(crtc->dev); 4288379bc100SJani Nikula if (!state) 4289379bc100SJani Nikula return -ENOMEM; 4290379bc100SJani Nikula 4291379bc100SJani Nikula state->acquire_ctx = ctx; 429276ec6927SVille Syrjälä to_intel_atomic_state(state)->internal = true; 4293379bc100SJani Nikula 4294379bc100SJani Nikula crtc_state = drm_atomic_get_crtc_state(state, crtc); 4295379bc100SJani Nikula if (IS_ERR(crtc_state)) { 4296379bc100SJani Nikula ret = PTR_ERR(crtc_state); 4297379bc100SJani Nikula goto out; 4298379bc100SJani Nikula } 4299379bc100SJani Nikula 4300379bc100SJani Nikula crtc_state->connectors_changed = true; 4301379bc100SJani Nikula 4302379bc100SJani Nikula ret = drm_atomic_commit(state); 4303379bc100SJani Nikula out: 4304379bc100SJani Nikula drm_atomic_state_put(state); 4305379bc100SJani Nikula 4306379bc100SJani Nikula return ret; 4307379bc100SJani Nikula } 4308379bc100SJani Nikula 4309379bc100SJani Nikula static int intel_hdmi_reset_link(struct intel_encoder *encoder, 4310379bc100SJani Nikula struct drm_modeset_acquire_ctx *ctx) 4311379bc100SJani Nikula { 4312379bc100SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 4313b7d02c3aSVille Syrjälä struct intel_hdmi *hdmi = enc_to_intel_hdmi(encoder); 4314379bc100SJani Nikula struct intel_connector *connector = hdmi->attached_connector; 4315379bc100SJani Nikula struct i2c_adapter *adapter = 4316379bc100SJani Nikula intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus); 4317379bc100SJani Nikula struct drm_connector_state *conn_state; 4318379bc100SJani Nikula struct intel_crtc_state *crtc_state; 4319379bc100SJani Nikula struct intel_crtc *crtc; 4320379bc100SJani Nikula u8 config; 4321379bc100SJani Nikula int ret; 4322379bc100SJani Nikula 4323379bc100SJani Nikula if (!connector || connector->base.status != connector_status_connected) 4324379bc100SJani Nikula return 0; 4325379bc100SJani Nikula 4326379bc100SJani Nikula ret = drm_modeset_lock(&dev_priv->drm.mode_config.connection_mutex, 4327379bc100SJani Nikula ctx); 4328379bc100SJani Nikula if (ret) 4329379bc100SJani Nikula return ret; 4330379bc100SJani Nikula 4331379bc100SJani Nikula conn_state = connector->base.state; 4332379bc100SJani Nikula 4333379bc100SJani Nikula crtc = to_intel_crtc(conn_state->crtc); 4334379bc100SJani Nikula if (!crtc) 4335379bc100SJani Nikula return 0; 4336379bc100SJani Nikula 4337379bc100SJani Nikula ret = drm_modeset_lock(&crtc->base.mutex, ctx); 4338379bc100SJani Nikula if (ret) 4339379bc100SJani Nikula return ret; 4340379bc100SJani Nikula 4341379bc100SJani Nikula crtc_state = to_intel_crtc_state(crtc->base.state); 4342379bc100SJani Nikula 43431de143ccSPankaj Bharadiya drm_WARN_ON(&dev_priv->drm, 43441de143ccSPankaj Bharadiya !intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)); 4345379bc100SJani Nikula 43461326a92cSMaarten Lankhorst if (!crtc_state->hw.active) 4347379bc100SJani Nikula return 0; 4348379bc100SJani Nikula 4349379bc100SJani Nikula if (!crtc_state->hdmi_high_tmds_clock_ratio && 4350379bc100SJani Nikula !crtc_state->hdmi_scrambling) 4351379bc100SJani Nikula return 0; 4352379bc100SJani Nikula 4353379bc100SJani Nikula if (conn_state->commit && 4354379bc100SJani Nikula !try_wait_for_completion(&conn_state->commit->hw_done)) 4355379bc100SJani Nikula return 0; 4356379bc100SJani Nikula 4357379bc100SJani Nikula ret = drm_scdc_readb(adapter, SCDC_TMDS_CONFIG, &config); 4358379bc100SJani Nikula if (ret < 0) { 435947bdb1caSJani Nikula drm_err(&dev_priv->drm, "Failed to read TMDS config: %d\n", 436047bdb1caSJani Nikula ret); 4361379bc100SJani Nikula return 0; 4362379bc100SJani Nikula } 4363379bc100SJani Nikula 4364379bc100SJani Nikula if (!!(config & SCDC_TMDS_BIT_CLOCK_RATIO_BY_40) == 4365379bc100SJani Nikula crtc_state->hdmi_high_tmds_clock_ratio && 4366379bc100SJani Nikula !!(config & SCDC_SCRAMBLING_ENABLE) == 4367379bc100SJani Nikula crtc_state->hdmi_scrambling) 4368379bc100SJani Nikula return 0; 4369379bc100SJani Nikula 4370379bc100SJani Nikula /* 4371379bc100SJani Nikula * HDMI 2.0 says that one should not send scrambled data 4372379bc100SJani Nikula * prior to configuring the sink scrambling, and that 4373379bc100SJani Nikula * TMDS clock/data transmission should be suspended when 4374379bc100SJani Nikula * changing the TMDS clock rate in the sink. So let's 4375379bc100SJani Nikula * just do a full modeset here, even though some sinks 4376379bc100SJani Nikula * would be perfectly happy if were to just reconfigure 4377379bc100SJani Nikula * the SCDC settings on the fly. 4378379bc100SJani Nikula */ 4379379bc100SJani Nikula return modeset_pipe(&crtc->base, ctx); 4380379bc100SJani Nikula } 4381379bc100SJani Nikula 43823944709dSImre Deak static enum intel_hotplug_state 43833944709dSImre Deak intel_ddi_hotplug(struct intel_encoder *encoder, 43848c8919c7SImre Deak struct intel_connector *connector) 4385379bc100SJani Nikula { 4386b4df5405SImre Deak struct drm_i915_private *i915 = to_i915(encoder->base.dev); 4387b7d02c3aSVille Syrjälä struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 4388699390f7SVille Syrjälä struct intel_dp *intel_dp = &dig_port->dp; 4389b4df5405SImre Deak enum phy phy = intel_port_to_phy(i915, encoder->port); 4390b4df5405SImre Deak bool is_tc = intel_phy_is_tc(i915, phy); 4391379bc100SJani Nikula struct drm_modeset_acquire_ctx ctx; 43923944709dSImre Deak enum intel_hotplug_state state; 4393379bc100SJani Nikula int ret; 4394379bc100SJani Nikula 4395699390f7SVille Syrjälä if (intel_dp->compliance.test_active && 4396699390f7SVille Syrjälä intel_dp->compliance.test_type == DP_TEST_LINK_PHY_TEST_PATTERN) { 4397699390f7SVille Syrjälä intel_dp_phy_test(encoder); 4398699390f7SVille Syrjälä /* just do the PHY test and nothing else */ 4399699390f7SVille Syrjälä return INTEL_HOTPLUG_UNCHANGED; 4400699390f7SVille Syrjälä } 4401699390f7SVille Syrjälä 44028c8919c7SImre Deak state = intel_encoder_hotplug(encoder, connector); 4403379bc100SJani Nikula 4404379bc100SJani Nikula drm_modeset_acquire_init(&ctx, 0); 4405379bc100SJani Nikula 4406379bc100SJani Nikula for (;;) { 4407379bc100SJani Nikula if (connector->base.connector_type == DRM_MODE_CONNECTOR_HDMIA) 4408379bc100SJani Nikula ret = intel_hdmi_reset_link(encoder, &ctx); 4409379bc100SJani Nikula else 4410379bc100SJani Nikula ret = intel_dp_retrain_link(encoder, &ctx); 4411379bc100SJani Nikula 4412379bc100SJani Nikula if (ret == -EDEADLK) { 4413379bc100SJani Nikula drm_modeset_backoff(&ctx); 4414379bc100SJani Nikula continue; 4415379bc100SJani Nikula } 4416379bc100SJani Nikula 4417379bc100SJani Nikula break; 4418379bc100SJani Nikula } 4419379bc100SJani Nikula 4420379bc100SJani Nikula drm_modeset_drop_locks(&ctx); 4421379bc100SJani Nikula drm_modeset_acquire_fini(&ctx); 44223a47ae20SPankaj Bharadiya drm_WARN(encoder->base.dev, ret, 44233a47ae20SPankaj Bharadiya "Acquiring modeset locks failed with %i\n", ret); 4424379bc100SJani Nikula 4425bb80c925SJosé Roberto de Souza /* 4426bb80c925SJosé Roberto de Souza * Unpowered type-c dongles can take some time to boot and be 4427bb80c925SJosé Roberto de Souza * responsible, so here giving some time to those dongles to power up 4428bb80c925SJosé Roberto de Souza * and then retrying the probe. 4429bb80c925SJosé Roberto de Souza * 4430bb80c925SJosé Roberto de Souza * On many platforms the HDMI live state signal is known to be 4431bb80c925SJosé Roberto de Souza * unreliable, so we can't use it to detect if a sink is connected or 4432bb80c925SJosé Roberto de Souza * not. Instead we detect if it's connected based on whether we can 4433bb80c925SJosé Roberto de Souza * read the EDID or not. That in turn has a problem during disconnect, 4434bb80c925SJosé Roberto de Souza * since the HPD interrupt may be raised before the DDC lines get 4435bb80c925SJosé Roberto de Souza * disconnected (due to how the required length of DDC vs. HPD 4436bb80c925SJosé Roberto de Souza * connector pins are specified) and so we'll still be able to get a 4437bb80c925SJosé Roberto de Souza * valid EDID. To solve this schedule another detection cycle if this 4438bb80c925SJosé Roberto de Souza * time around we didn't detect any change in the sink's connection 4439bb80c925SJosé Roberto de Souza * status. 4440b4df5405SImre Deak * 4441b4df5405SImre Deak * Type-c connectors which get their HPD signal deasserted then 4442b4df5405SImre Deak * reasserted, without unplugging/replugging the sink from the 4443b4df5405SImre Deak * connector, introduce a delay until the AUX channel communication 4444b4df5405SImre Deak * becomes functional. Retry the detection for 5 seconds on type-c 4445b4df5405SImre Deak * connectors to account for this delay. 4446bb80c925SJosé Roberto de Souza */ 4447b4df5405SImre Deak if (state == INTEL_HOTPLUG_UNCHANGED && 4448b4df5405SImre Deak connector->hotplug_retries < (is_tc ? 5 : 1) && 4449bb80c925SJosé Roberto de Souza !dig_port->dp.is_mst) 4450bb80c925SJosé Roberto de Souza state = INTEL_HOTPLUG_RETRY; 4451bb80c925SJosé Roberto de Souza 44523944709dSImre Deak return state; 4453379bc100SJani Nikula } 4454379bc100SJani Nikula 4455edc0e09cSVille Syrjälä static bool lpt_digital_port_connected(struct intel_encoder *encoder) 4456edc0e09cSVille Syrjälä { 4457edc0e09cSVille Syrjälä struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 44585a4dd6f0SJani Nikula u32 bit = dev_priv->display.hotplug.pch_hpd[encoder->hpd_pin]; 4459edc0e09cSVille Syrjälä 4460edc0e09cSVille Syrjälä return intel_de_read(dev_priv, SDEISR) & bit; 4461edc0e09cSVille Syrjälä } 4462edc0e09cSVille Syrjälä 4463edc0e09cSVille Syrjälä static bool hsw_digital_port_connected(struct intel_encoder *encoder) 4464edc0e09cSVille Syrjälä { 4465edc0e09cSVille Syrjälä struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 44665a4dd6f0SJani Nikula u32 bit = dev_priv->display.hotplug.hpd[encoder->hpd_pin]; 4467edc0e09cSVille Syrjälä 4468c7e8a3d6SVille Syrjälä return intel_de_read(dev_priv, DEISR) & bit; 4469edc0e09cSVille Syrjälä } 4470edc0e09cSVille Syrjälä 4471edc0e09cSVille Syrjälä static bool bdw_digital_port_connected(struct intel_encoder *encoder) 4472edc0e09cSVille Syrjälä { 4473edc0e09cSVille Syrjälä struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 44745a4dd6f0SJani Nikula u32 bit = dev_priv->display.hotplug.hpd[encoder->hpd_pin]; 4475edc0e09cSVille Syrjälä 4476edc0e09cSVille Syrjälä return intel_de_read(dev_priv, GEN8_DE_PORT_ISR) & bit; 4477edc0e09cSVille Syrjälä } 4478edc0e09cSVille Syrjälä 4479379bc100SJani Nikula static struct intel_connector * 44807801f3b7SLucas De Marchi intel_ddi_init_hdmi_connector(struct intel_digital_port *dig_port) 4481379bc100SJani Nikula { 4482379bc100SJani Nikula struct intel_connector *connector; 44837801f3b7SLucas De Marchi enum port port = dig_port->base.port; 4484379bc100SJani Nikula 4485379bc100SJani Nikula connector = intel_connector_alloc(); 4486379bc100SJani Nikula if (!connector) 4487379bc100SJani Nikula return NULL; 4488379bc100SJani Nikula 44897801f3b7SLucas De Marchi dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port); 44907801f3b7SLucas De Marchi intel_hdmi_init_connector(dig_port, connector); 4491379bc100SJani Nikula 4492379bc100SJani Nikula return connector; 4493379bc100SJani Nikula } 4494379bc100SJani Nikula 44957801f3b7SLucas De Marchi static bool intel_ddi_a_force_4_lanes(struct intel_digital_port *dig_port) 4496379bc100SJani Nikula { 44977801f3b7SLucas De Marchi struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); 4498379bc100SJani Nikula 44997801f3b7SLucas De Marchi if (dig_port->base.port != PORT_A) 4500379bc100SJani Nikula return false; 4501379bc100SJani Nikula 45027801f3b7SLucas De Marchi if (dig_port->saved_port_bits & DDI_A_4_LANES) 4503379bc100SJani Nikula return false; 4504379bc100SJani Nikula 4505379bc100SJani Nikula /* Broxton/Geminilake: Bspec says that DDI_A_4_LANES is the only 4506379bc100SJani Nikula * supported configuration 4507379bc100SJani Nikula */ 45082446e1d6SMatt Roper if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) 4509379bc100SJani Nikula return true; 4510379bc100SJani Nikula 4511379bc100SJani Nikula return false; 4512379bc100SJani Nikula } 4513379bc100SJani Nikula 4514379bc100SJani Nikula static int 45157801f3b7SLucas De Marchi intel_ddi_max_lanes(struct intel_digital_port *dig_port) 4516379bc100SJani Nikula { 45177801f3b7SLucas De Marchi struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); 45187801f3b7SLucas De Marchi enum port port = dig_port->base.port; 4519379bc100SJani Nikula int max_lanes = 4; 4520379bc100SJani Nikula 4521005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 11) 4522379bc100SJani Nikula return max_lanes; 4523379bc100SJani Nikula 4524379bc100SJani Nikula if (port == PORT_A || port == PORT_E) { 4525f7960e7fSJani Nikula if (intel_de_read(dev_priv, DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES) 4526379bc100SJani Nikula max_lanes = port == PORT_A ? 4 : 0; 4527379bc100SJani Nikula else 4528379bc100SJani Nikula /* Both A and E share 2 lanes */ 4529379bc100SJani Nikula max_lanes = 2; 4530379bc100SJani Nikula } 4531379bc100SJani Nikula 4532379bc100SJani Nikula /* 4533379bc100SJani Nikula * Some BIOS might fail to set this bit on port A if eDP 4534379bc100SJani Nikula * wasn't lit up at boot. Force this bit set when needed 4535379bc100SJani Nikula * so we use the proper lane count for our calculations. 4536379bc100SJani Nikula */ 45377801f3b7SLucas De Marchi if (intel_ddi_a_force_4_lanes(dig_port)) { 453847bdb1caSJani Nikula drm_dbg_kms(&dev_priv->drm, 453947bdb1caSJani Nikula "Forcing DDI_A_4_LANES for port A\n"); 45407801f3b7SLucas De Marchi dig_port->saved_port_bits |= DDI_A_4_LANES; 4541379bc100SJani Nikula max_lanes = 4; 4542379bc100SJani Nikula } 4543379bc100SJani Nikula 4544379bc100SJani Nikula return max_lanes; 4545379bc100SJani Nikula } 4546379bc100SJani Nikula 4547ed2615a8SMatt Roper static enum hpd_pin xelpd_hpd_pin(struct drm_i915_private *dev_priv, 4548ed2615a8SMatt Roper enum port port) 4549ed2615a8SMatt Roper { 4550ed2615a8SMatt Roper if (port >= PORT_D_XELPD) 4551ed2615a8SMatt Roper return HPD_PORT_D + port - PORT_D_XELPD; 4552ed2615a8SMatt Roper else if (port >= PORT_TC1) 4553ed2615a8SMatt Roper return HPD_PORT_TC1 + port - PORT_TC1; 4554ed2615a8SMatt Roper else 4555ed2615a8SMatt Roper return HPD_PORT_A + port - PORT_A; 4556ed2615a8SMatt Roper } 4557ed2615a8SMatt Roper 4558229f31e2SLucas De Marchi static enum hpd_pin dg1_hpd_pin(struct drm_i915_private *dev_priv, 4559229f31e2SLucas De Marchi enum port port) 4560229f31e2SLucas De Marchi { 45611d8ca002SVille Syrjälä if (port >= PORT_TC1) 45621d8ca002SVille Syrjälä return HPD_PORT_C + port - PORT_TC1; 4563229f31e2SLucas De Marchi else 4564229f31e2SLucas De Marchi return HPD_PORT_A + port - PORT_A; 4565229f31e2SLucas De Marchi } 4566229f31e2SLucas De Marchi 4567da51e4baSVille Syrjälä static enum hpd_pin tgl_hpd_pin(struct drm_i915_private *dev_priv, 4568da51e4baSVille Syrjälä enum port port) 4569da51e4baSVille Syrjälä { 45701d8ca002SVille Syrjälä if (port >= PORT_TC1) 45711d8ca002SVille Syrjälä return HPD_PORT_TC1 + port - PORT_TC1; 4572da51e4baSVille Syrjälä else 4573da51e4baSVille Syrjälä return HPD_PORT_A + port - PORT_A; 4574da51e4baSVille Syrjälä } 4575da51e4baSVille Syrjälä 4576da51e4baSVille Syrjälä static enum hpd_pin rkl_hpd_pin(struct drm_i915_private *dev_priv, 4577da51e4baSVille Syrjälä enum port port) 4578da51e4baSVille Syrjälä { 4579da51e4baSVille Syrjälä if (HAS_PCH_TGP(dev_priv)) 4580da51e4baSVille Syrjälä return tgl_hpd_pin(dev_priv, port); 4581da51e4baSVille Syrjälä 45821d8ca002SVille Syrjälä if (port >= PORT_TC1) 45831d8ca002SVille Syrjälä return HPD_PORT_C + port - PORT_TC1; 4584da51e4baSVille Syrjälä else 4585da51e4baSVille Syrjälä return HPD_PORT_A + port - PORT_A; 4586da51e4baSVille Syrjälä } 4587da51e4baSVille Syrjälä 4588da51e4baSVille Syrjälä static enum hpd_pin icl_hpd_pin(struct drm_i915_private *dev_priv, 4589da51e4baSVille Syrjälä enum port port) 4590da51e4baSVille Syrjälä { 4591da51e4baSVille Syrjälä if (port >= PORT_C) 4592da51e4baSVille Syrjälä return HPD_PORT_TC1 + port - PORT_C; 4593da51e4baSVille Syrjälä else 4594da51e4baSVille Syrjälä return HPD_PORT_A + port - PORT_A; 4595da51e4baSVille Syrjälä } 4596da51e4baSVille Syrjälä 4597da51e4baSVille Syrjälä static enum hpd_pin ehl_hpd_pin(struct drm_i915_private *dev_priv, 4598da51e4baSVille Syrjälä enum port port) 4599da51e4baSVille Syrjälä { 4600da51e4baSVille Syrjälä if (port == PORT_D) 4601da51e4baSVille Syrjälä return HPD_PORT_A; 4602da51e4baSVille Syrjälä 4603f24d1d45SVille Syrjälä if (HAS_PCH_TGP(dev_priv)) 4604da51e4baSVille Syrjälä return icl_hpd_pin(dev_priv, port); 4605da51e4baSVille Syrjälä 4606da51e4baSVille Syrjälä return HPD_PORT_A + port - PORT_A; 4607da51e4baSVille Syrjälä } 4608da51e4baSVille Syrjälä 4609c8455098SLyude Paul static enum hpd_pin skl_hpd_pin(struct drm_i915_private *dev_priv, enum port port) 4610c8455098SLyude Paul { 4611c8455098SLyude Paul if (HAS_PCH_TGP(dev_priv)) 4612c8455098SLyude Paul return icl_hpd_pin(dev_priv, port); 4613c8455098SLyude Paul 4614c8455098SLyude Paul return HPD_PORT_A + port - PORT_A; 4615c8455098SLyude Paul } 4616c8455098SLyude Paul 461736ecb0ecSVille Syrjälä static bool intel_ddi_is_tc(struct drm_i915_private *i915, enum port port) 461836ecb0ecSVille Syrjälä { 4619005e9537SMatt Roper if (DISPLAY_VER(i915) >= 12) 462036ecb0ecSVille Syrjälä return port >= PORT_TC1; 4621005e9537SMatt Roper else if (DISPLAY_VER(i915) >= 11) 462236ecb0ecSVille Syrjälä return port >= PORT_C; 462336ecb0ecSVille Syrjälä else 462436ecb0ecSVille Syrjälä return false; 462536ecb0ecSVille Syrjälä } 462636ecb0ecSVille Syrjälä 4627151ec347SImre Deak static void intel_ddi_encoder_suspend(struct intel_encoder *encoder) 4628151ec347SImre Deak { 4629151ec347SImre Deak struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 4630151ec347SImre Deak struct drm_i915_private *i915 = dp_to_i915(intel_dp); 4631151ec347SImre Deak struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); 4632151ec347SImre Deak enum phy phy = intel_port_to_phy(i915, encoder->port); 4633151ec347SImre Deak 4634151ec347SImre Deak intel_dp_encoder_suspend(encoder); 4635151ec347SImre Deak 4636151ec347SImre Deak if (!intel_phy_is_tc(i915, phy)) 4637151ec347SImre Deak return; 4638151ec347SImre Deak 46393e0abc76SImre Deak intel_tc_port_flush_work(dig_port); 4640151ec347SImre Deak } 4641151ec347SImre Deak 4642151ec347SImre Deak static void intel_ddi_encoder_shutdown(struct intel_encoder *encoder) 4643151ec347SImre Deak { 4644151ec347SImre Deak struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 4645151ec347SImre Deak struct drm_i915_private *i915 = dp_to_i915(intel_dp); 4646151ec347SImre Deak struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); 4647151ec347SImre Deak enum phy phy = intel_port_to_phy(i915, encoder->port); 4648151ec347SImre Deak 4649151ec347SImre Deak intel_dp_encoder_shutdown(encoder); 465049c55f7bSVille Syrjälä intel_hdmi_encoder_shutdown(encoder); 4651151ec347SImre Deak 4652151ec347SImre Deak if (!intel_phy_is_tc(i915, phy)) 4653151ec347SImre Deak return; 4654151ec347SImre Deak 4655c5879999SImre Deak intel_tc_port_cleanup(dig_port); 4656151ec347SImre Deak } 4657151ec347SImre Deak 465883566d13SVille Syrjälä #define port_tc_name(port) ((port) - PORT_TC1 + '1') 465983566d13SVille Syrjälä #define tc_port_name(tc_port) ((tc_port) - TC_PORT_1 + '1') 466083566d13SVille Syrjälä 4661379bc100SJani Nikula void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) 4662379bc100SJani Nikula { 46637801f3b7SLucas De Marchi struct intel_digital_port *dig_port; 466470dfbc29SLucas De Marchi struct intel_encoder *encoder; 466545c0673aSJani Nikula const struct intel_bios_encoder_data *devdata; 4666f542d671SKai-Heng Feng bool init_hdmi, init_dp; 4667d8fe2ab6SMatt Roper enum phy phy = intel_port_to_phy(dev_priv, port); 4668379bc100SJani Nikula 4669ddff9a60SMatt Roper /* 4670ddff9a60SMatt Roper * On platforms with HTI (aka HDPORT), if it's enabled at boot it may 4671ddff9a60SMatt Roper * have taken over some of the PHYs and made them unavailable to the 4672ddff9a60SMatt Roper * driver. In that case we should skip initializing the corresponding 4673ddff9a60SMatt Roper * outputs. 4674ddff9a60SMatt Roper */ 467503120fefSJani Nikula if (intel_hti_uses_phy(dev_priv, phy)) { 4676ddff9a60SMatt Roper drm_dbg_kms(&dev_priv->drm, "PORT %c / PHY %c reserved by HTI\n", 4677ddff9a60SMatt Roper port_name(port), phy_name(phy)); 4678ddff9a60SMatt Roper return; 4679ddff9a60SMatt Roper } 4680ddff9a60SMatt Roper 468145c0673aSJani Nikula devdata = intel_bios_encoder_data_lookup(dev_priv, port); 468245c0673aSJani Nikula if (!devdata) { 468345c0673aSJani Nikula drm_dbg_kms(&dev_priv->drm, 468445c0673aSJani Nikula "VBT says port %c is not present\n", 468545c0673aSJani Nikula port_name(port)); 468645c0673aSJani Nikula return; 468745c0673aSJani Nikula } 468845c0673aSJani Nikula 468945c0673aSJani Nikula init_hdmi = intel_bios_encoder_supports_dvi(devdata) || 469045c0673aSJani Nikula intel_bios_encoder_supports_hdmi(devdata); 469145c0673aSJani Nikula init_dp = intel_bios_encoder_supports_dp(devdata); 4692379bc100SJani Nikula 4693db5d650fSVille Syrjälä if (intel_bios_encoder_is_lspcon(devdata)) { 4694379bc100SJani Nikula /* 4695379bc100SJani Nikula * Lspcon device needs to be driven with DP connector 4696379bc100SJani Nikula * with special detection sequence. So make sure DP 4697379bc100SJani Nikula * is initialized before lspcon. 4698379bc100SJani Nikula */ 4699379bc100SJani Nikula init_dp = true; 4700379bc100SJani Nikula init_hdmi = false; 470147bdb1caSJani Nikula drm_dbg_kms(&dev_priv->drm, "VBT says port %c has lspcon\n", 470247bdb1caSJani Nikula port_name(port)); 4703379bc100SJani Nikula } 4704379bc100SJani Nikula 4705379bc100SJani Nikula if (!init_dp && !init_hdmi) { 470647bdb1caSJani Nikula drm_dbg_kms(&dev_priv->drm, 470747bdb1caSJani Nikula "VBT says port %c is not DVI/HDMI/DP compatible, respect it\n", 4708379bc100SJani Nikula port_name(port)); 4709379bc100SJani Nikula return; 4710379bc100SJani Nikula } 4711379bc100SJani Nikula 4712b4eb76d8SMatt Roper if (intel_phy_is_snps(dev_priv, phy) && 47133a7e2d58SJani Nikula dev_priv->display.snps.phy_failed_calibration & BIT(phy)) { 4714b4eb76d8SMatt Roper drm_dbg_kms(&dev_priv->drm, 471582c362f2SLucas De Marchi "SNPS PHY %c failed to calibrate, proceeding anyway\n", 4716b4eb76d8SMatt Roper phy_name(phy)); 4717b4eb76d8SMatt Roper } 4718b4eb76d8SMatt Roper 47197801f3b7SLucas De Marchi dig_port = kzalloc(sizeof(*dig_port), GFP_KERNEL); 47207801f3b7SLucas De Marchi if (!dig_port) 4721379bc100SJani Nikula return; 4722379bc100SJani Nikula 47237801f3b7SLucas De Marchi encoder = &dig_port->base; 4724c0a950d1SJani Nikula encoder->devdata = devdata; 4725379bc100SJani Nikula 4726ed2615a8SMatt Roper if (DISPLAY_VER(dev_priv) >= 13 && port >= PORT_D_XELPD) { 4727ed2615a8SMatt Roper drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs, 4728ed2615a8SMatt Roper DRM_MODE_ENCODER_TMDS, 4729ed2615a8SMatt Roper "DDI %c/PHY %c", 4730ed2615a8SMatt Roper port_name(port - PORT_D_XELPD + PORT_D), 4731ed2615a8SMatt Roper phy_name(phy)); 4732ed2615a8SMatt Roper } else if (DISPLAY_VER(dev_priv) >= 12) { 47332d709a5aSVille Syrjälä enum tc_port tc_port = intel_port_to_tc(dev_priv, port); 47342d709a5aSVille Syrjälä 473570dfbc29SLucas De Marchi drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs, 47362d709a5aSVille Syrjälä DRM_MODE_ENCODER_TMDS, 47372d709a5aSVille Syrjälä "DDI %s%c/PHY %s%c", 47382d709a5aSVille Syrjälä port >= PORT_TC1 ? "TC" : "", 473983566d13SVille Syrjälä port >= PORT_TC1 ? port_tc_name(port) : port_name(port), 47402d709a5aSVille Syrjälä tc_port != TC_PORT_NONE ? "TC" : "", 474183566d13SVille Syrjälä tc_port != TC_PORT_NONE ? tc_port_name(tc_port) : phy_name(phy)); 4742005e9537SMatt Roper } else if (DISPLAY_VER(dev_priv) >= 11) { 47432d709a5aSVille Syrjälä enum tc_port tc_port = intel_port_to_tc(dev_priv, port); 47442d709a5aSVille Syrjälä 47452d709a5aSVille Syrjälä drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs, 47462d709a5aSVille Syrjälä DRM_MODE_ENCODER_TMDS, 47472d709a5aSVille Syrjälä "DDI %c%s/PHY %s%c", 47482d709a5aSVille Syrjälä port_name(port), 47492d709a5aSVille Syrjälä port >= PORT_C ? " (TC)" : "", 47502d709a5aSVille Syrjälä tc_port != TC_PORT_NONE ? "TC" : "", 475183566d13SVille Syrjälä tc_port != TC_PORT_NONE ? tc_port_name(tc_port) : phy_name(phy)); 47522d709a5aSVille Syrjälä } else { 47532d709a5aSVille Syrjälä drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs, 47542d709a5aSVille Syrjälä DRM_MODE_ENCODER_TMDS, 47552d709a5aSVille Syrjälä "DDI %c/PHY %c", port_name(port), phy_name(phy)); 47562d709a5aSVille Syrjälä } 4757379bc100SJani Nikula 475836e5e704SSean Paul mutex_init(&dig_port->hdcp_mutex); 475936e5e704SSean Paul dig_port->num_hdcp_streams = 0; 476036e5e704SSean Paul 476170dfbc29SLucas De Marchi encoder->hotplug = intel_ddi_hotplug; 476270dfbc29SLucas De Marchi encoder->compute_output_type = intel_ddi_compute_output_type; 476370dfbc29SLucas De Marchi encoder->compute_config = intel_ddi_compute_config; 4764b50a1aa6SManasi Navare encoder->compute_config_late = intel_ddi_compute_config_late; 476570dfbc29SLucas De Marchi encoder->enable = intel_enable_ddi; 476670dfbc29SLucas De Marchi encoder->pre_pll_enable = intel_ddi_pre_pll_enable; 476770dfbc29SLucas De Marchi encoder->pre_enable = intel_ddi_pre_enable; 476870dfbc29SLucas De Marchi encoder->disable = intel_disable_ddi; 4769b108bdd0SImre Deak encoder->post_pll_disable = intel_ddi_post_pll_disable; 477070dfbc29SLucas De Marchi encoder->post_disable = intel_ddi_post_disable; 477170dfbc29SLucas De Marchi encoder->update_pipe = intel_ddi_update_pipe; 477270dfbc29SLucas De Marchi encoder->get_hw_state = intel_ddi_get_hw_state; 4773f9e76a6eSImre Deak encoder->sync_state = intel_ddi_sync_state; 4774b671d6efSImre Deak encoder->initial_fastset_check = intel_ddi_initial_fastset_check; 4775151ec347SImre Deak encoder->suspend = intel_ddi_encoder_suspend; 4776151ec347SImre Deak encoder->shutdown = intel_ddi_encoder_shutdown; 477770dfbc29SLucas De Marchi encoder->get_power_domains = intel_ddi_get_power_domains; 477870dfbc29SLucas De Marchi 477970dfbc29SLucas De Marchi encoder->type = INTEL_OUTPUT_DDI; 4780979e1b32SImre Deak encoder->power_domain = intel_display_power_ddi_lanes_domain(dev_priv, port); 478170dfbc29SLucas De Marchi encoder->port = port; 478270dfbc29SLucas De Marchi encoder->cloneable = 0; 478370dfbc29SLucas De Marchi encoder->pipe_mask = ~0; 4784da51e4baSVille Syrjälä 478551390cc0SRadhakrishna Sripada if (DISPLAY_VER(dev_priv) >= 14) { 478673fc3abcSMika Kahola encoder->enable_clock = intel_mtl_pll_enable; 478773fc3abcSMika Kahola encoder->disable_clock = intel_mtl_pll_disable; 47886f0423b0SMika Kahola encoder->port_pll_type = intel_mtl_port_pll_type; 478951390cc0SRadhakrishna Sripada encoder->get_config = mtl_ddi_get_config; 479051390cc0SRadhakrishna Sripada } else if (IS_DG2(dev_priv)) { 4791f82f2563SMatt Roper encoder->enable_clock = intel_mpllb_enable; 4792f82f2563SMatt Roper encoder->disable_clock = intel_mpllb_disable; 4793865b73eaSMatt Roper encoder->get_config = dg2_ddi_get_config; 4794865b73eaSMatt Roper } else if (IS_ALDERLAKE_S(dev_priv)) { 479540b316d4SVille Syrjälä encoder->enable_clock = adls_ddi_enable_clock; 479640b316d4SVille Syrjälä encoder->disable_clock = adls_ddi_disable_clock; 47970fbd8694SVille Syrjälä encoder->is_clock_enabled = adls_ddi_is_clock_enabled; 4798351221ffSVille Syrjälä encoder->get_config = adls_ddi_get_config; 479940b316d4SVille Syrjälä } else if (IS_ROCKETLAKE(dev_priv)) { 480040b316d4SVille Syrjälä encoder->enable_clock = rkl_ddi_enable_clock; 480140b316d4SVille Syrjälä encoder->disable_clock = rkl_ddi_disable_clock; 48020fbd8694SVille Syrjälä encoder->is_clock_enabled = rkl_ddi_is_clock_enabled; 4803351221ffSVille Syrjälä encoder->get_config = rkl_ddi_get_config; 480436ecb0ecSVille Syrjälä } else if (IS_DG1(dev_priv)) { 480535bb6b1aSVille Syrjälä encoder->enable_clock = dg1_ddi_enable_clock; 480635bb6b1aSVille Syrjälä encoder->disable_clock = dg1_ddi_disable_clock; 48070fbd8694SVille Syrjälä encoder->is_clock_enabled = dg1_ddi_is_clock_enabled; 4808351221ffSVille Syrjälä encoder->get_config = dg1_ddi_get_config; 480936ecb0ecSVille Syrjälä } else if (IS_JSL_EHL(dev_priv)) { 481036ecb0ecSVille Syrjälä if (intel_ddi_is_tc(dev_priv, port)) { 481136ecb0ecSVille Syrjälä encoder->enable_clock = jsl_ddi_tc_enable_clock; 481236ecb0ecSVille Syrjälä encoder->disable_clock = jsl_ddi_tc_disable_clock; 48130fbd8694SVille Syrjälä encoder->is_clock_enabled = jsl_ddi_tc_is_clock_enabled; 48147c1da068SImre Deak encoder->port_pll_type = icl_ddi_tc_port_pll_type; 4815351221ffSVille Syrjälä encoder->get_config = icl_ddi_combo_get_config; 481636ecb0ecSVille Syrjälä } else { 481736ecb0ecSVille Syrjälä encoder->enable_clock = icl_ddi_combo_enable_clock; 481836ecb0ecSVille Syrjälä encoder->disable_clock = icl_ddi_combo_disable_clock; 48190fbd8694SVille Syrjälä encoder->is_clock_enabled = icl_ddi_combo_is_clock_enabled; 4820351221ffSVille Syrjälä encoder->get_config = icl_ddi_combo_get_config; 482136ecb0ecSVille Syrjälä } 4822005e9537SMatt Roper } else if (DISPLAY_VER(dev_priv) >= 11) { 482336ecb0ecSVille Syrjälä if (intel_ddi_is_tc(dev_priv, port)) { 482436ecb0ecSVille Syrjälä encoder->enable_clock = icl_ddi_tc_enable_clock; 482536ecb0ecSVille Syrjälä encoder->disable_clock = icl_ddi_tc_disable_clock; 48260fbd8694SVille Syrjälä encoder->is_clock_enabled = icl_ddi_tc_is_clock_enabled; 48277c1da068SImre Deak encoder->port_pll_type = icl_ddi_tc_port_pll_type; 4828351221ffSVille Syrjälä encoder->get_config = icl_ddi_tc_get_config; 482936ecb0ecSVille Syrjälä } else { 483036ecb0ecSVille Syrjälä encoder->enable_clock = icl_ddi_combo_enable_clock; 483136ecb0ecSVille Syrjälä encoder->disable_clock = icl_ddi_combo_disable_clock; 48320fbd8694SVille Syrjälä encoder->is_clock_enabled = icl_ddi_combo_is_clock_enabled; 4833351221ffSVille Syrjälä encoder->get_config = icl_ddi_combo_get_config; 483436ecb0ecSVille Syrjälä } 48352446e1d6SMatt Roper } else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { 4836351221ffSVille Syrjälä /* BXT/GLK have fixed PLL->port mapping */ 4837351221ffSVille Syrjälä encoder->get_config = bxt_ddi_get_config; 483893e7e61eSLucas De Marchi } else if (DISPLAY_VER(dev_priv) == 9) { 483938e31f1aSVille Syrjälä encoder->enable_clock = skl_ddi_enable_clock; 484038e31f1aSVille Syrjälä encoder->disable_clock = skl_ddi_disable_clock; 48410fbd8694SVille Syrjälä encoder->is_clock_enabled = skl_ddi_is_clock_enabled; 4842351221ffSVille Syrjälä encoder->get_config = skl_ddi_get_config; 484338e31f1aSVille Syrjälä } else if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) { 4844d135368dSVille Syrjälä encoder->enable_clock = hsw_ddi_enable_clock; 4845d135368dSVille Syrjälä encoder->disable_clock = hsw_ddi_disable_clock; 48460fbd8694SVille Syrjälä encoder->is_clock_enabled = hsw_ddi_is_clock_enabled; 4847351221ffSVille Syrjälä encoder->get_config = hsw_ddi_get_config; 4848d135368dSVille Syrjälä } 4849d135368dSVille Syrjälä 4850ea8af87aSMika Kahola if (DISPLAY_VER(dev_priv) >= 14) { 4851ea8af87aSMika Kahola encoder->set_signal_levels = intel_cx0_phy_set_signal_levels; 4852ea8af87aSMika Kahola } else if (IS_DG2(dev_priv)) { 4853193299adSVille Syrjälä encoder->set_signal_levels = intel_snps_phy_set_signal_levels; 4854193299adSVille Syrjälä } else if (DISPLAY_VER(dev_priv) >= 12) { 4855193299adSVille Syrjälä if (intel_phy_is_combo(dev_priv, phy)) 4856193299adSVille Syrjälä encoder->set_signal_levels = icl_combo_phy_set_signal_levels; 4857e722ab8bSVille Syrjälä else 4858193299adSVille Syrjälä encoder->set_signal_levels = tgl_dkl_phy_set_signal_levels; 4859193299adSVille Syrjälä } else if (DISPLAY_VER(dev_priv) >= 11) { 4860193299adSVille Syrjälä if (intel_phy_is_combo(dev_priv, phy)) 4861193299adSVille Syrjälä encoder->set_signal_levels = icl_combo_phy_set_signal_levels; 4862193299adSVille Syrjälä else 4863193299adSVille Syrjälä encoder->set_signal_levels = icl_mg_phy_set_signal_levels; 4864193299adSVille Syrjälä } else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { 48655f5ada0bSVille Syrjälä encoder->set_signal_levels = bxt_ddi_phy_set_signal_levels; 4866193299adSVille Syrjälä } else { 4867e722ab8bSVille Syrjälä encoder->set_signal_levels = hsw_set_signal_levels; 4868193299adSVille Syrjälä } 4869e722ab8bSVille Syrjälä 4870c40a253bSVille Syrjälä intel_ddi_buf_trans_init(encoder); 4871c40a253bSVille Syrjälä 4872ed2615a8SMatt Roper if (DISPLAY_VER(dev_priv) >= 13) 4873ed2615a8SMatt Roper encoder->hpd_pin = xelpd_hpd_pin(dev_priv, port); 4874ed2615a8SMatt Roper else if (IS_DG1(dev_priv)) 4875229f31e2SLucas De Marchi encoder->hpd_pin = dg1_hpd_pin(dev_priv, port); 4876229f31e2SLucas De Marchi else if (IS_ROCKETLAKE(dev_priv)) 4877da51e4baSVille Syrjälä encoder->hpd_pin = rkl_hpd_pin(dev_priv, port); 4878005e9537SMatt Roper else if (DISPLAY_VER(dev_priv) >= 12) 4879da51e4baSVille Syrjälä encoder->hpd_pin = tgl_hpd_pin(dev_priv, port); 488024ea098bSTejas Upadhyay else if (IS_JSL_EHL(dev_priv)) 4881da51e4baSVille Syrjälä encoder->hpd_pin = ehl_hpd_pin(dev_priv, port); 488293e7e61eSLucas De Marchi else if (DISPLAY_VER(dev_priv) == 11) 4883da51e4baSVille Syrjälä encoder->hpd_pin = icl_hpd_pin(dev_priv, port); 488493e7e61eSLucas De Marchi else if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv)) 4885c8455098SLyude Paul encoder->hpd_pin = skl_hpd_pin(dev_priv, port); 4886da51e4baSVille Syrjälä else 488703c7e4f1SVille Syrjälä encoder->hpd_pin = intel_hpd_pin_default(dev_priv, port); 4888379bc100SJani Nikula 4889005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 11) 48907801f3b7SLucas De Marchi dig_port->saved_port_bits = 48917801f3b7SLucas De Marchi intel_de_read(dev_priv, DDI_BUF_CTL(port)) 48927801f3b7SLucas De Marchi & DDI_BUF_PORT_REVERSAL; 4893379bc100SJani Nikula else 48947801f3b7SLucas De Marchi dig_port->saved_port_bits = 48957801f3b7SLucas De Marchi intel_de_read(dev_priv, DDI_BUF_CTL(port)) 48967801f3b7SLucas De Marchi & (DDI_BUF_PORT_REVERSAL | DDI_A_4_LANES); 489770dfbc29SLucas De Marchi 48985f42196dSVille Syrjälä if (intel_bios_encoder_lane_reversal(devdata)) 4899aaab24bbSUma Shankar dig_port->saved_port_bits |= DDI_BUF_PORT_REVERSAL; 4900aaab24bbSUma Shankar 49017801f3b7SLucas De Marchi dig_port->dp.output_reg = INVALID_MMIO_REG; 49027801f3b7SLucas De Marchi dig_port->max_lanes = intel_ddi_max_lanes(dig_port); 4903bb45217fSVille Syrjälä dig_port->aux_ch = intel_dp_aux_ch(encoder); 4904379bc100SJani Nikula 4905d8fe2ab6SMatt Roper if (intel_phy_is_tc(dev_priv, phy)) { 4906c5faae5aSJani Nikula bool is_legacy = 4907f08fbe6aSJani Nikula !intel_bios_encoder_supports_typec_usb(devdata) && 4908f08fbe6aSJani Nikula !intel_bios_encoder_supports_tbt(devdata); 4909379bc100SJani Nikula 491040a55b84SImre Deak if (!is_legacy && init_hdmi) { 491140a55b84SImre Deak is_legacy = !init_dp; 491240a55b84SImre Deak 491340a55b84SImre Deak drm_dbg_kms(&dev_priv->drm, 491440a55b84SImre Deak "VBT says port %c is non-legacy TC and has HDMI (with DP: %s), assume it's %s\n", 491540a55b84SImre Deak port_name(port), 491640a55b84SImre Deak str_yes_no(init_dp), 491740a55b84SImre Deak is_legacy ? "legacy" : "non-legacy"); 491840a55b84SImre Deak } 491940a55b84SImre Deak 4920c5879999SImre Deak if (intel_tc_port_init(dig_port, is_legacy) < 0) 4921c5879999SImre Deak goto err; 4922ab7bc4e1SImre Deak } 4923ab7bc4e1SImre Deak 49241de143ccSPankaj Bharadiya drm_WARN_ON(&dev_priv->drm, port > PORT_I); 4925979e1b32SImre Deak dig_port->ddi_io_power_domain = intel_display_power_ddi_io_domain(dev_priv, port); 4926379bc100SJani Nikula 4927005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 11) { 4928edc0e09cSVille Syrjälä if (intel_phy_is_tc(dev_priv, phy)) 49297801f3b7SLucas De Marchi dig_port->connected = intel_tc_port_connected; 4930edc0e09cSVille Syrjälä else 49317801f3b7SLucas De Marchi dig_port->connected = lpt_digital_port_connected; 4932dded35acSVille Syrjälä } else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { 4933dded35acSVille Syrjälä dig_port->connected = bdw_digital_port_connected; 4934dded35acSVille Syrjälä } else if (DISPLAY_VER(dev_priv) == 9) { 4935dded35acSVille Syrjälä dig_port->connected = lpt_digital_port_connected; 4936dded35acSVille Syrjälä } else if (IS_BROADWELL(dev_priv)) { 4937dded35acSVille Syrjälä if (port == PORT_A) 49387801f3b7SLucas De Marchi dig_port->connected = bdw_digital_port_connected; 4939edc0e09cSVille Syrjälä else 49407801f3b7SLucas De Marchi dig_port->connected = lpt_digital_port_connected; 4941dded35acSVille Syrjälä } else if (IS_HASWELL(dev_priv)) { 4942c7e8a3d6SVille Syrjälä if (port == PORT_A) 49437801f3b7SLucas De Marchi dig_port->connected = hsw_digital_port_connected; 4944edc0e09cSVille Syrjälä else 49457801f3b7SLucas De Marchi dig_port->connected = lpt_digital_port_connected; 4946edc0e09cSVille Syrjälä } 4947edc0e09cSVille Syrjälä 49487801f3b7SLucas De Marchi intel_infoframe_init(dig_port); 4949379bc100SJani Nikula 4950a98ffd6eSVille Syrjälä if (init_dp) { 4951a98ffd6eSVille Syrjälä if (!intel_ddi_init_dp_connector(dig_port)) 4952a98ffd6eSVille Syrjälä goto err; 4953a98ffd6eSVille Syrjälä 4954a98ffd6eSVille Syrjälä dig_port->hpd_pulse = intel_dp_hpd_pulse; 4955a98ffd6eSVille Syrjälä 4956a98ffd6eSVille Syrjälä if (dig_port->dp.mso_link_count) 4957a98ffd6eSVille Syrjälä encoder->pipe_mask = intel_ddi_splitter_pipe_mask(dev_priv); 4958a98ffd6eSVille Syrjälä } 4959a98ffd6eSVille Syrjälä 4960a98ffd6eSVille Syrjälä /* 4961a98ffd6eSVille Syrjälä * In theory we don't need the encoder->type check, 4962a98ffd6eSVille Syrjälä * but leave it just in case we have some really bad VBTs... 4963a98ffd6eSVille Syrjälä */ 4964a98ffd6eSVille Syrjälä if (encoder->type != INTEL_OUTPUT_EDP && init_hdmi) { 4965a98ffd6eSVille Syrjälä if (!intel_ddi_init_hdmi_connector(dig_port)) 4966a98ffd6eSVille Syrjälä goto err; 4967a98ffd6eSVille Syrjälä } 4968a98ffd6eSVille Syrjälä 4969379bc100SJani Nikula return; 4970379bc100SJani Nikula 4971379bc100SJani Nikula err: 497270dfbc29SLucas De Marchi drm_encoder_cleanup(&encoder->base); 49737801f3b7SLucas De Marchi kfree(dig_port); 4974379bc100SJani Nikula } 4975