diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_ddi.c')
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_ddi.c | 512 |
1 files changed, 246 insertions, 266 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index ff2cf3daa7a2..f38c998935b9 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -70,6 +70,7 @@ #include "intel_lspcon.h" #include "intel_mg_phy_regs.h" #include "intel_modeset_lock.h" +#include "intel_pfit.h" #include "intel_pps.h" #include "intel_psr.h" #include "intel_quirks.h" @@ -177,69 +178,60 @@ static void hsw_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder, trans->entries[level].hsw.trans2); } -static void mtl_wait_ddi_buf_idle(struct drm_i915_private *i915, enum port port) +static i915_reg_t intel_ddi_buf_status_reg(struct intel_display *display, enum port port) { - int ret; + struct drm_i915_private *i915 = to_i915(display->drm); - /* FIXME: find out why Bspec's 100us timeout is too short */ - ret = wait_for_us((intel_de_read(i915, XELPDP_PORT_BUF_CTL1(i915, port)) & - XELPDP_PORT_BUF_PHY_IDLE), 10000); - if (ret) - drm_err(&i915->drm, "Timeout waiting for DDI BUF %c to get idle\n", - port_name(port)); + if (DISPLAY_VER(display) >= 14) + return XELPDP_PORT_BUF_CTL1(i915, port); + else + return DDI_BUF_CTL(port); } -void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv, - enum port port) +void intel_wait_ddi_buf_idle(struct intel_display *display, enum port port) { - if (IS_BROXTON(dev_priv)) { + /* + * Bspec's platform specific timeouts: + * MTL+ : 100 us + * BXT : fixed 16 us + * HSW-ADL: 8 us + * + * FIXME: MTL requires 10 ms based on tests, find out why 100 us is too short + */ + if (display->platform.broxton) { udelay(16); return; } - if (wait_for_us((intel_de_read(dev_priv, DDI_BUF_CTL(port)) & - DDI_BUF_IS_IDLE), 8)) - drm_err(&dev_priv->drm, "Timeout waiting for DDI BUF %c to get idle\n", + static_assert(DDI_BUF_IS_IDLE == XELPDP_PORT_BUF_PHY_IDLE); + if (intel_de_wait_for_set(display, intel_ddi_buf_status_reg(display, port), + DDI_BUF_IS_IDLE, 10)) + drm_err(display->drm, "Timeout waiting for DDI BUF %c to get idle\n", port_name(port)); } static void intel_wait_ddi_buf_active(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum port port = encoder->port; - int timeout_us; - int ret; - /* Wait > 518 usecs for DDI_BUF_CTL to be non idle */ - if (DISPLAY_VER(dev_priv) < 10) { + /* + * Bspec's platform specific timeouts: + * MTL+ : 10000 us + * DG2 : 1200 us + * TGL-ADL combo PHY: 1000 us + * TGL-ADL TypeC PHY: 3000 us + * HSW-ICL : fixed 518 us + */ + if (DISPLAY_VER(display) < 10) { usleep_range(518, 1000); return; } - if (DISPLAY_VER(dev_priv) >= 14) { - timeout_us = 10000; - } else if (IS_DG2(dev_priv)) { - timeout_us = 1200; - } else if (DISPLAY_VER(dev_priv) >= 12) { - if (intel_encoder_is_tc(encoder)) - timeout_us = 3000; - else - timeout_us = 1000; - } else { - timeout_us = 500; - } - - if (DISPLAY_VER(dev_priv) >= 14) - ret = _wait_for(!(intel_de_read(dev_priv, - XELPDP_PORT_BUF_CTL1(dev_priv, port)) & - XELPDP_PORT_BUF_PHY_IDLE), - timeout_us, 10, 10); - else - ret = _wait_for(!(intel_de_read(dev_priv, DDI_BUF_CTL(port)) & DDI_BUF_IS_IDLE), - timeout_us, 10, 10); - - if (ret) - drm_err(&dev_priv->drm, "Timeout waiting for DDI BUF %c to get active\n", + static_assert(DDI_BUF_IS_IDLE == XELPDP_PORT_BUF_PHY_IDLE); + if (intel_de_wait_for_clear(display, intel_ddi_buf_status_reg(display, port), + DDI_BUF_IS_IDLE, 10)) + drm_err(display->drm, "Timeout waiting for DDI BUF %c to get active\n", port_name(port)); } @@ -328,9 +320,32 @@ static u32 ddi_buf_phy_link_rate(int port_clock) } } +static int dp_phy_lane_stagger_delay(int port_clock) +{ + /* + * Return the number of symbol clocks delay used to stagger the + * assertion/desassertion of the port lane enables. The target delay + * time is 100 ns or greater, return the number of symbols specific to + * the provided port_clock (aka link clock) corresponding to this delay + * time, i.e. so that + * + * number_of_symbols * duration_of_one_symbol >= 100 ns + * + * The delay must be applied only on TypeC DP outputs, for everything else + * the delay must be set to 0. + * + * Return the number of link symbols per 100 ns: + * port_clock (10 kHz) -> bits / 100 us + * / symbol_size -> symbols / 100 us + * / 1000 -> symbols / 100 ns + */ + return DIV_ROUND_UP(port_clock, intel_dp_link_symbol_size(port_clock) * 1000); +} + static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(encoder); struct drm_i915_private *i915 = to_i915(encoder->base.dev); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); @@ -356,12 +371,18 @@ static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder, if (!intel_tc_port_in_tbt_alt_mode(dig_port)) intel_dp->DP |= DDI_BUF_CTL_TC_PHY_OWNERSHIP; } + + if (IS_DISPLAY_VER(display, 11, 13) && intel_encoder_is_tc(encoder)) { + int delay = dp_phy_lane_stagger_delay(crtc_state->port_clock); + + intel_dp->DP |= DDI_BUF_LANE_STAGGER_DELAY(delay); + } } -static int icl_calc_tbt_pll_link(struct drm_i915_private *dev_priv, +static int icl_calc_tbt_pll_link(struct intel_display *display, enum port port) { - u32 val = intel_de_read(dev_priv, DDI_CLK_SEL(port)) & DDI_CLK_SEL_MASK; + u32 val = intel_de_read(display, DDI_CLK_SEL(port)) & DDI_CLK_SEL_MASK; switch (val) { case DDI_CLK_SEL_NONE: @@ -703,19 +724,20 @@ int intel_ddi_toggle_hdcp_bits(struct intel_encoder *intel_encoder, enum transcoder cpu_transcoder, bool enable, u32 hdcp_mask) { + struct intel_display *display = to_intel_display(intel_encoder); struct drm_device *dev = intel_encoder->base.dev; struct drm_i915_private *dev_priv = to_i915(dev); intel_wakeref_t wakeref; int ret = 0; - wakeref = intel_display_power_get_if_enabled(dev_priv, + wakeref = intel_display_power_get_if_enabled(display, intel_encoder->power_domain); if (drm_WARN_ON(dev, !wakeref)) return -ENXIO; intel_de_rmw(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder), hdcp_mask, enable ? hdcp_mask : 0); - intel_display_power_put(dev_priv, intel_encoder->power_domain, wakeref); + intel_display_power_put(display, intel_encoder->power_domain, wakeref); return ret; } @@ -732,7 +754,7 @@ bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector) u32 ddi_mode; bool ret; - wakeref = intel_display_power_get_if_enabled(dev_priv, + wakeref = intel_display_power_get_if_enabled(display, encoder->power_domain); if (!wakeref) return false; @@ -773,7 +795,7 @@ bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector) } out: - intel_display_power_put(dev_priv, encoder->power_domain, wakeref); + intel_display_power_put(display, encoder->power_domain, wakeref); return ret; } @@ -792,7 +814,7 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, *pipe_mask = 0; *is_dp_mst = false; - wakeref = intel_display_power_get_if_enabled(dev_priv, + wakeref = intel_display_power_get_if_enabled(display, encoder->power_domain); if (!wakeref) return; @@ -829,7 +851,7 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, u32 port_mask, ddi_select, ddi_mode; intel_wakeref_t trans_wakeref; - trans_wakeref = intel_display_power_get_if_enabled(dev_priv, + trans_wakeref = intel_display_power_get_if_enabled(display, POWER_DOMAIN_TRANSCODER(cpu_transcoder)); if (!trans_wakeref) continue; @@ -844,7 +866,7 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder)); - intel_display_power_put(dev_priv, POWER_DOMAIN_TRANSCODER(cpu_transcoder), + intel_display_power_put(display, POWER_DOMAIN_TRANSCODER(cpu_transcoder), trans_wakeref); if ((tmp & port_mask) != ddi_select) @@ -910,7 +932,7 @@ out: encoder->base.base.id, encoder->base.name, tmp); } - intel_display_power_put(dev_priv, encoder->power_domain, wakeref); + intel_display_power_put(display, encoder->power_domain, wakeref); } bool intel_ddi_get_hw_state(struct intel_encoder *encoder, @@ -933,7 +955,7 @@ static enum intel_display_power_domain intel_ddi_main_link_aux_domain(struct intel_digital_port *dig_port, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_display *display = to_intel_display(dig_port); /* * ICL+ HW requires corresponding AUX IOs to be powered up for PSR with @@ -949,8 +971,8 @@ intel_ddi_main_link_aux_domain(struct intel_digital_port *dig_port, * extra wells. */ if (intel_psr_needs_aux_io_power(&dig_port->base, crtc_state)) - return intel_display_power_aux_io_domain(i915, dig_port->aux_ch); - else if (DISPLAY_VER(i915) < 14 && + return intel_display_power_aux_io_domain(display, dig_port->aux_ch); + else if (DISPLAY_VER(display) < 14 && (intel_crtc_has_dp_encoder(crtc_state) || intel_encoder_is_tc(&dig_port->base))) return intel_aux_power_domain(dig_port); @@ -962,23 +984,23 @@ static void main_link_aux_power_domain_get(struct intel_digital_port *dig_port, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_display *display = to_intel_display(dig_port); enum intel_display_power_domain domain = intel_ddi_main_link_aux_domain(dig_port, crtc_state); - drm_WARN_ON(&i915->drm, dig_port->aux_wakeref); + drm_WARN_ON(display->drm, dig_port->aux_wakeref); if (domain == POWER_DOMAIN_INVALID) return; - dig_port->aux_wakeref = intel_display_power_get(i915, domain); + dig_port->aux_wakeref = intel_display_power_get(display, domain); } static void main_link_aux_power_domain_put(struct intel_digital_port *dig_port, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_display *display = to_intel_display(dig_port); enum intel_display_power_domain domain = intel_ddi_main_link_aux_domain(dig_port, crtc_state); intel_wakeref_t wf; @@ -987,13 +1009,13 @@ main_link_aux_power_domain_put(struct intel_digital_port *dig_port, if (!wf) return; - intel_display_power_put(i915, domain, wf); + intel_display_power_put(display, domain, wf); } static void intel_ddi_get_power_domains(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_digital_port *dig_port; /* @@ -1001,15 +1023,15 @@ static void intel_ddi_get_power_domains(struct intel_encoder *encoder, * happen since fake-MST encoders don't set their get_power_domains() * hook. */ - if (drm_WARN_ON(&dev_priv->drm, + if (drm_WARN_ON(display->drm, intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST))) return; dig_port = enc_to_dig_port(encoder); if (!intel_tc_port_in_tbt_alt_mode(dig_port)) { - drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref); - dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv, + drm_WARN_ON(display->drm, dig_port->ddi_io_wakeref); + dig_port->ddi_io_wakeref = intel_display_power_get(display, dig_port->ddi_io_power_domain); } @@ -1171,7 +1193,8 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, /* Set PORT_TX_DW5 */ val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN(0, phy)); val &= ~(SCALING_MODE_SEL_MASK | RTERM_SELECT_MASK | - TAP2_DISABLE | TAP3_DISABLE); + COEFF_POLARITY | CURSOR_PROGRAM | + TAP2_DISABLE | TAP3_DISABLE); val |= SCALING_MODE_SEL(0x2); val |= RTERM_SELECT(0x6); val |= TAP3_DISABLE; @@ -1365,7 +1388,7 @@ static void icl_mg_phy_set_signal_levels(struct intel_encoder *encoder, static void tgl_dkl_phy_set_signal_levels(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum tc_port tc_port = intel_encoder_to_tc(encoder); const struct intel_ddi_buf_trans *trans; int n_entries, ln; @@ -1374,17 +1397,17 @@ static void tgl_dkl_phy_set_signal_levels(struct intel_encoder *encoder, return; trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); - if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) + if (drm_WARN_ON_ONCE(display->drm, !trans)) return; for (ln = 0; ln < 2; ln++) { int level; - intel_dkl_phy_write(dev_priv, DKL_TX_PMD_LANE_SUS(tc_port, ln), 0); + intel_dkl_phy_write(display, DKL_TX_PMD_LANE_SUS(tc_port, ln), 0); level = intel_ddi_level(encoder, crtc_state, 2*ln+0); - intel_dkl_phy_rmw(dev_priv, DKL_TX_DPCNTL0(tc_port, ln), + intel_dkl_phy_rmw(display, DKL_TX_DPCNTL0(tc_port, ln), DKL_TX_PRESHOOT_COEFF_MASK | DKL_TX_DE_EMPAHSIS_COEFF_MASK | DKL_TX_VSWING_CONTROL_MASK, @@ -1394,7 +1417,7 @@ static void tgl_dkl_phy_set_signal_levels(struct intel_encoder *encoder, level = intel_ddi_level(encoder, crtc_state, 2*ln+1); - intel_dkl_phy_rmw(dev_priv, DKL_TX_DPCNTL1(tc_port, ln), + intel_dkl_phy_rmw(display, DKL_TX_DPCNTL1(tc_port, ln), DKL_TX_PRESHOOT_COEFF_MASK | DKL_TX_DE_EMPAHSIS_COEFF_MASK | DKL_TX_VSWING_CONTROL_MASK, @@ -1402,10 +1425,10 @@ static void tgl_dkl_phy_set_signal_levels(struct intel_encoder *encoder, DKL_TX_DE_EMPHASIS_COEFF(trans->entries[level].dkl.de_emphasis) | DKL_TX_VSWING_CONTROL(trans->entries[level].dkl.vswing)); - intel_dkl_phy_rmw(dev_priv, DKL_TX_DPCNTL2(tc_port, ln), + intel_dkl_phy_rmw(display, DKL_TX_DPCNTL2(tc_port, ln), DKL_TX_DP20BITMODE, 0); - if (IS_ALDERLAKE_P(dev_priv)) { + if (display->platform.alderlake_p) { u32 val; if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { @@ -1421,7 +1444,7 @@ static void tgl_dkl_phy_set_signal_levels(struct intel_encoder *encoder, val |= DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2(0); } - intel_dkl_phy_rmw(dev_priv, DKL_TX_DPCNTL2(tc_port, ln), + intel_dkl_phy_rmw(display, DKL_TX_DPCNTL2(tc_port, ln), DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1_MASK | DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2_MASK, val); @@ -1549,14 +1572,14 @@ static bool _icl_ddi_is_clock_enabled(struct drm_i915_private *i915, i915_reg_t } static struct intel_shared_dpll * -_icl_ddi_get_pll(struct drm_i915_private *i915, i915_reg_t reg, +_icl_ddi_get_pll(struct intel_display *display, i915_reg_t reg, u32 clk_sel_mask, u32 clk_sel_shift) { enum intel_dpll_id id; - id = (intel_de_read(i915, reg) & clk_sel_mask) >> clk_sel_shift; + id = (intel_de_read(display, reg) & clk_sel_mask) >> clk_sel_shift; - return intel_get_shared_dpll_by_id(i915, id); + return intel_get_shared_dpll_by_id(display, id); } static void adls_ddi_enable_clock(struct intel_encoder *encoder, @@ -1595,10 +1618,10 @@ static bool adls_ddi_is_clock_enabled(struct intel_encoder *encoder) static struct intel_shared_dpll *adls_ddi_get_pll(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum phy phy = intel_encoder_to_phy(encoder); - return _icl_ddi_get_pll(i915, ADLS_DPCLKA_CFGCR(phy), + return _icl_ddi_get_pll(display, ADLS_DPCLKA_CFGCR(phy), ADLS_DPCLKA_CFGCR_DDI_CLK_SEL_MASK(phy), ADLS_DPCLKA_CFGCR_DDI_SHIFT(phy)); } @@ -1639,10 +1662,10 @@ static bool rkl_ddi_is_clock_enabled(struct intel_encoder *encoder) static struct intel_shared_dpll *rkl_ddi_get_pll(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum phy phy = intel_encoder_to_phy(encoder); - return _icl_ddi_get_pll(i915, ICL_DPCLKA_CFGCR0, + return _icl_ddi_get_pll(display, ICL_DPCLKA_CFGCR0, RKL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy), RKL_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(phy)); } @@ -1692,12 +1715,12 @@ static bool dg1_ddi_is_clock_enabled(struct intel_encoder *encoder) static struct intel_shared_dpll *dg1_ddi_get_pll(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum phy phy = intel_encoder_to_phy(encoder); enum intel_dpll_id id; u32 val; - val = intel_de_read(i915, DG1_DPCLKA_CFGCR0(phy)); + val = intel_de_read(display, DG1_DPCLKA_CFGCR0(phy)); val &= DG1_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy); val >>= DG1_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(phy); id = val; @@ -1710,7 +1733,7 @@ static struct intel_shared_dpll *dg1_ddi_get_pll(struct intel_encoder *encoder) if (phy >= PHY_C) id += DPLL_ID_DG1_DPLL2; - return intel_get_shared_dpll_by_id(i915, id); + return intel_get_shared_dpll_by_id(display, id); } static void icl_ddi_combo_enable_clock(struct intel_encoder *encoder, @@ -1749,10 +1772,10 @@ static bool icl_ddi_combo_is_clock_enabled(struct intel_encoder *encoder) struct intel_shared_dpll *icl_ddi_combo_get_pll(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum phy phy = intel_encoder_to_phy(encoder); - return _icl_ddi_get_pll(i915, ICL_DPCLKA_CFGCR0, + return _icl_ddi_get_pll(display, ICL_DPCLKA_CFGCR0, ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy), ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(phy)); } @@ -1857,13 +1880,13 @@ static bool icl_ddi_tc_is_clock_enabled(struct intel_encoder *encoder) static struct intel_shared_dpll *icl_ddi_tc_get_pll(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum tc_port tc_port = intel_encoder_to_tc(encoder); enum port port = encoder->port; enum intel_dpll_id id; u32 tmp; - tmp = intel_de_read(i915, DDI_CLK_SEL(port)); + tmp = intel_de_read(display, DDI_CLK_SEL(port)); switch (tmp & DDI_CLK_SEL_MASK) { case DDI_CLK_SEL_TBT_162: @@ -1882,12 +1905,12 @@ static struct intel_shared_dpll *icl_ddi_tc_get_pll(struct intel_encoder *encode return NULL; } - return intel_get_shared_dpll_by_id(i915, id); + return intel_get_shared_dpll_by_id(display, id); } static struct intel_shared_dpll *bxt_ddi_get_pll(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder->base.dev); enum intel_dpll_id id; switch (encoder->port) { @@ -1905,7 +1928,7 @@ static struct intel_shared_dpll *bxt_ddi_get_pll(struct intel_encoder *encoder) return NULL; } - return intel_get_shared_dpll_by_id(i915, id); + return intel_get_shared_dpll_by_id(display, id); } static void skl_ddi_enable_clock(struct intel_encoder *encoder, @@ -1956,12 +1979,12 @@ static bool skl_ddi_is_clock_enabled(struct intel_encoder *encoder) static struct intel_shared_dpll *skl_ddi_get_pll(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum port port = encoder->port; enum intel_dpll_id id; u32 tmp; - tmp = intel_de_read(i915, DPLL_CTRL2); + tmp = intel_de_read(display, DPLL_CTRL2); /* * FIXME Not sure if the override affects both @@ -1973,7 +1996,7 @@ static struct intel_shared_dpll *skl_ddi_get_pll(struct intel_encoder *encoder) id = (tmp & DPLL_CTRL2_DDI_CLK_SEL_MASK(port)) >> DPLL_CTRL2_DDI_CLK_SEL_SHIFT(port); - return intel_get_shared_dpll_by_id(i915, id); + return intel_get_shared_dpll_by_id(display, id); } void hsw_ddi_enable_clock(struct intel_encoder *encoder, @@ -2007,12 +2030,12 @@ bool hsw_ddi_is_clock_enabled(struct intel_encoder *encoder) static struct intel_shared_dpll *hsw_ddi_get_pll(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum port port = encoder->port; enum intel_dpll_id id; u32 tmp; - tmp = intel_de_read(i915, PORT_CLK_SEL(port)); + tmp = intel_de_read(display, PORT_CLK_SEL(port)); switch (tmp & PORT_CLK_SEL_MASK) { case PORT_CLK_SEL_WRPLL1: @@ -2040,7 +2063,7 @@ static struct intel_shared_dpll *hsw_ddi_get_pll(struct intel_encoder *encoder) return NULL; } - return intel_get_shared_dpll_by_id(i915, id); + return intel_get_shared_dpll_by_id(display, id); } void intel_ddi_enable_clock(struct intel_encoder *encoder, @@ -2120,27 +2143,37 @@ void intel_ddi_sanitize_encoder_pll_mapping(struct intel_encoder *encoder) } static void +tgl_dkl_phy_check_and_rewrite(struct intel_display *display, + enum tc_port tc_port, u32 ln0, u32 ln1) +{ + if (ln0 != intel_dkl_phy_read(display, DKL_DP_MODE(tc_port, 0))) + intel_dkl_phy_write(display, DKL_DP_MODE(tc_port, 0), ln0); + if (ln1 != intel_dkl_phy_read(display, DKL_DP_MODE(tc_port, 1))) + intel_dkl_phy_write(display, DKL_DP_MODE(tc_port, 1), ln1); +} + +static void icl_program_mg_dp_mode(struct intel_digital_port *dig_port, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); + struct intel_display *display = to_intel_display(crtc_state); enum tc_port tc_port = intel_encoder_to_tc(&dig_port->base); u32 ln0, ln1, pin_assignment; u8 width; - if (DISPLAY_VER(dev_priv) >= 14) + if (DISPLAY_VER(display) >= 14) return; if (!intel_encoder_is_tc(&dig_port->base) || intel_tc_port_in_tbt_alt_mode(dig_port)) return; - if (DISPLAY_VER(dev_priv) >= 12) { - ln0 = intel_dkl_phy_read(dev_priv, DKL_DP_MODE(tc_port, 0)); - ln1 = intel_dkl_phy_read(dev_priv, DKL_DP_MODE(tc_port, 1)); + if (DISPLAY_VER(display) >= 12) { + ln0 = intel_dkl_phy_read(display, DKL_DP_MODE(tc_port, 0)); + ln1 = intel_dkl_phy_read(display, DKL_DP_MODE(tc_port, 1)); } else { - ln0 = intel_de_read(dev_priv, MG_DP_MODE(0, tc_port)); - ln1 = intel_de_read(dev_priv, MG_DP_MODE(1, tc_port)); + ln0 = intel_de_read(display, MG_DP_MODE(0, tc_port)); + ln1 = intel_de_read(display, MG_DP_MODE(1, tc_port)); } ln0 &= ~(MG_DP_MODE_CFG_DP_X1_MODE | MG_DP_MODE_CFG_DP_X2_MODE); @@ -2152,7 +2185,7 @@ icl_program_mg_dp_mode(struct intel_digital_port *dig_port, switch (pin_assignment) { case 0x0: - drm_WARN_ON(&dev_priv->drm, + drm_WARN_ON(display->drm, !intel_tc_port_in_legacy_mode(dig_port)); if (width == 1) { ln1 |= MG_DP_MODE_CFG_DP_X1_MODE; @@ -2197,12 +2230,16 @@ icl_program_mg_dp_mode(struct intel_digital_port *dig_port, MISSING_CASE(pin_assignment); } - if (DISPLAY_VER(dev_priv) >= 12) { - intel_dkl_phy_write(dev_priv, DKL_DP_MODE(tc_port, 0), ln0); - intel_dkl_phy_write(dev_priv, DKL_DP_MODE(tc_port, 1), ln1); + if (DISPLAY_VER(display) >= 12) { + intel_dkl_phy_write(display, DKL_DP_MODE(tc_port, 0), ln0); + intel_dkl_phy_write(display, DKL_DP_MODE(tc_port, 1), ln1); + /* WA_14018221282 */ + if (IS_DISPLAY_VER(display, 12, 13)) + tgl_dkl_phy_check_and_rewrite(display, tc_port, ln0, ln1); + } else { - intel_de_write(dev_priv, MG_DP_MODE(0, tc_port), ln0); - intel_de_write(dev_priv, MG_DP_MODE(1, tc_port), ln1); + intel_de_write(display, MG_DP_MODE(0, tc_port), ln0); + intel_de_write(display, MG_DP_MODE(1, tc_port), ln1); } } @@ -2421,13 +2458,13 @@ static void intel_ddi_disable_fec(struct intel_encoder *encoder, static void intel_ddi_power_up_lanes(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); if (intel_encoder_is_combo(encoder)) { enum phy phy = intel_encoder_to_phy(encoder); - intel_combo_phy_power_up_lanes(i915, phy, false, + intel_combo_phy_power_up_lanes(display, phy, false, crtc_state->lane_count, dig_port->lane_reversal); } @@ -2509,23 +2546,6 @@ static void intel_ddi_mso_configure(const struct intel_crtc_state *crtc_state) OVERLAP_PIXELS_MASK, dss1); } -static u8 mtl_get_port_width(u8 lane_count) -{ - switch (lane_count) { - case 1: - return 0; - case 2: - return 1; - case 3: - return 4; - case 4: - return 3; - default: - MISSING_CASE(lane_count); - return 4; - } -} - static void mtl_ddi_enable_d2d(struct intel_encoder *encoder) { @@ -2534,6 +2554,9 @@ mtl_ddi_enable_d2d(struct intel_encoder *encoder) i915_reg_t reg; u32 set_bits, wait_bits; + if (DISPLAY_VER(dev_priv) < 14) + return; + if (DISPLAY_VER(dev_priv) >= 20) { reg = DDI_BUF_CTL(port); set_bits = XE2LPD_DDI_BUF_D2D_LINK_ENABLE; @@ -2559,7 +2582,7 @@ static void mtl_port_buf_ctl_program(struct intel_encoder *encoder, enum port port = encoder->port; u32 val = 0; - val |= XELPDP_PORT_WIDTH(mtl_get_port_width(crtc_state->lane_count)); + val |= XELPDP_PORT_WIDTH(crtc_state->lane_count); if (intel_dp_is_uhbr(crtc_state)) val |= XELPDP_PORT_BUF_PORT_DATA_40BIT; @@ -2593,6 +2616,7 @@ static void mtl_ddi_pre_enable_dp(struct intel_atomic_state *state, { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); + bool transparent_mode; int ret; intel_dp_set_link_params(intel_dp, @@ -2644,6 +2668,9 @@ static void mtl_ddi_pre_enable_dp(struct intel_atomic_state *state, if (!is_mst) intel_dp_set_power(intel_dp, DP_SET_POWER_D0); + transparent_mode = intel_dp_lttpr_transparent_mode_enabled(intel_dp); + drm_dp_lttpr_wake_timeout_setup(&intel_dp->aux, transparent_mode); + intel_dp_configure_protocol_converter(intel_dp, crtc_state); if (!is_mst) intel_dp_sink_enable_decompression(state, @@ -2705,6 +2732,7 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { + struct intel_display *display = to_intel_display(encoder); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); @@ -2751,7 +2779,7 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, /* 5. If IO power is controlled through PWR_WELL_CTL, Enable IO Power */ if (!intel_tc_port_in_tbt_alt_mode(dig_port)) { drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref); - dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv, + dig_port->ddi_io_wakeref = intel_display_power_get(display, dig_port->ddi_io_power_domain); } @@ -2852,6 +2880,7 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { + struct intel_display *display = to_intel_display(encoder); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum port port = encoder->port; @@ -2880,7 +2909,7 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, if (!intel_tc_port_in_tbt_alt_mode(dig_port)) { drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref); - dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv, + dig_port->ddi_io_wakeref = intel_display_power_get(display, dig_port->ddi_io_power_domain); } @@ -2926,8 +2955,7 @@ static void intel_ddi_pre_enable_dp(struct intel_atomic_state *state, crtc_state); /* Panel replay has to be enabled in sink dpcd before link training. */ - if (crtc_state->has_panel_replay) - intel_psr_enable_sink(enc_to_intel_dp(encoder), crtc_state); + intel_psr_panel_replay_enable_sink(enc_to_intel_dp(encoder)); if (DISPLAY_VER(display) >= 14) mtl_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state); @@ -2948,6 +2976,7 @@ static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state, const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { + struct intel_display *display = to_intel_display(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); struct intel_hdmi *intel_hdmi = &dig_port->hdmi; struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); @@ -2956,7 +2985,7 @@ static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state, intel_ddi_enable_clock(encoder, crtc_state); drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref); - dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv, + dig_port->ddi_io_wakeref = intel_display_power_get(display, dig_port->ddi_io_power_domain); icl_program_mg_dp_mode(dig_port, crtc_state); @@ -2984,20 +3013,21 @@ static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state, * - crtc_state will be the state of the first stream to be activated on this * port, and it may not be the same stream that will be deactivated last, but * each stream should have a state that is identical when it comes to the DP - * link parameteres + * link parameters. */ static void intel_ddi_pre_enable(struct intel_atomic_state *state, struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { + struct intel_display *display = to_intel_display(state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; drm_WARN_ON(&dev_priv->drm, crtc_state->has_pch_encoder); - intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); + intel_set_cpu_fifo_underrun_reporting(display, pipe, true); if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { intel_ddi_pre_enable_hdmi(state, encoder, crtc_state, @@ -3010,7 +3040,7 @@ static void intel_ddi_pre_enable(struct intel_atomic_state *state, /* FIXME precompute everything properly */ /* FIXME how do we turn infoframes off again? */ - if (dig_port->lspcon.active && intel_dp_has_hdmi_sink(&dig_port->dp)) + if (intel_lspcon_active(dig_port) && intel_dp_has_hdmi_sink(&dig_port->dp)) dig_port->set_infoframes(encoder, crtc_state->has_infoframe, crtc_state, conn_state); @@ -3018,13 +3048,16 @@ static void intel_ddi_pre_enable(struct intel_atomic_state *state, } static void -mtl_ddi_disable_d2d_link(struct intel_encoder *encoder) +mtl_ddi_disable_d2d(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum port port = encoder->port; i915_reg_t reg; u32 clr_bits, wait_bits; + if (DISPLAY_VER(dev_priv) < 14) + return; + if (DISPLAY_VER(dev_priv) >= 20) { reg = DDI_BUF_CTL(port); clr_bits = XE2LPD_DDI_BUF_D2D_LINK_ENABLE; @@ -3041,71 +3074,40 @@ mtl_ddi_disable_d2d_link(struct intel_encoder *encoder) port_name(port)); } -static void mtl_disable_ddi_buf(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state) +static void intel_ddi_buf_enable(struct intel_encoder *encoder, u32 buf_ctl) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum port port = encoder->port; - u32 val; - /* 3.b Clear DDI_CTL_DE Enable to 0. */ - val = intel_de_read(dev_priv, DDI_BUF_CTL(port)); - if (val & DDI_BUF_CTL_ENABLE) { - val &= ~DDI_BUF_CTL_ENABLE; - intel_de_write(dev_priv, DDI_BUF_CTL(port), val); - - /* 3.c Poll for PORT_BUF_CTL Idle Status == 1, timeout after 100us */ - mtl_wait_ddi_buf_idle(dev_priv, port); - } - - /* 3.d Disable D2D Link */ - mtl_ddi_disable_d2d_link(encoder); + intel_de_write(display, DDI_BUF_CTL(port), buf_ctl | DDI_BUF_CTL_ENABLE); + intel_de_posting_read(display, DDI_BUF_CTL(port)); - /* 3.e Disable DP_TP_CTL */ - if (intel_crtc_has_dp_encoder(crtc_state)) { - intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), - DP_TP_CTL_ENABLE, 0); - } + intel_wait_ddi_buf_active(encoder); } -static void disable_ddi_buf(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state) +static void intel_ddi_buf_disable(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(encoder); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum port port = encoder->port; - bool wait = false; - u32 val; - val = intel_de_read(dev_priv, DDI_BUF_CTL(port)); - if (val & DDI_BUF_CTL_ENABLE) { - val &= ~DDI_BUF_CTL_ENABLE; - intel_de_write(dev_priv, DDI_BUF_CTL(port), val); - wait = true; - } + intel_de_rmw(dev_priv, DDI_BUF_CTL(port), DDI_BUF_CTL_ENABLE, 0); + + if (DISPLAY_VER(display) >= 14) + intel_wait_ddi_buf_idle(display, port); + + mtl_ddi_disable_d2d(encoder); - if (intel_crtc_has_dp_encoder(crtc_state)) + if (intel_crtc_has_dp_encoder(crtc_state)) { intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), DP_TP_CTL_ENABLE, 0); + } intel_ddi_disable_fec(encoder, crtc_state); - if (wait) - intel_wait_ddi_buf_idle(dev_priv, port); -} - -static void intel_disable_ddi_buf(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state) -{ - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - - if (DISPLAY_VER(dev_priv) >= 14) { - mtl_disable_ddi_buf(encoder, crtc_state); - - /* 3.f Disable DP_TP_CTL FEC Enable if it is needed */ - intel_ddi_disable_fec(encoder, crtc_state); - } else { - disable_ddi_buf(encoder, crtc_state); - } + if (DISPLAY_VER(display) < 14) + intel_wait_ddi_buf_idle(display, port); intel_ddi_wait_for_fec_status(encoder, crtc_state, false); } @@ -3115,6 +3117,7 @@ static void intel_ddi_post_disable_dp(struct intel_atomic_state *state, const struct intel_crtc_state *old_crtc_state, const struct drm_connector_state *old_conn_state) { + struct intel_display *display = to_intel_display(encoder); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); struct intel_dp *intel_dp = &dig_port->dp; @@ -3146,7 +3149,7 @@ static void intel_ddi_post_disable_dp(struct intel_atomic_state *state, intel_ddi_disable_transcoder_clock(old_crtc_state); } - intel_disable_ddi_buf(encoder, old_crtc_state); + intel_ddi_buf_disable(encoder, old_crtc_state); intel_dp_sink_set_fec_ready(intel_dp, old_crtc_state, false); @@ -3166,7 +3169,7 @@ static void intel_ddi_post_disable_dp(struct intel_atomic_state *state, wakeref = fetch_and_zero(&dig_port->ddi_io_wakeref); if (wakeref) - intel_display_power_put(dev_priv, + intel_display_power_put(display, dig_port->ddi_io_power_domain, wakeref); @@ -3183,6 +3186,7 @@ static void intel_ddi_post_disable_hdmi(struct intel_atomic_state *state, const struct intel_crtc_state *old_crtc_state, const struct drm_connector_state *old_conn_state) { + struct intel_display *display = to_intel_display(encoder); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); struct intel_hdmi *intel_hdmi = &dig_port->hdmi; @@ -3194,14 +3198,14 @@ static void intel_ddi_post_disable_hdmi(struct intel_atomic_state *state, if (DISPLAY_VER(dev_priv) < 12) intel_ddi_disable_transcoder_clock(old_crtc_state); - intel_disable_ddi_buf(encoder, old_crtc_state); + intel_ddi_buf_disable(encoder, old_crtc_state); if (DISPLAY_VER(dev_priv) >= 12) intel_ddi_disable_transcoder_clock(old_crtc_state); wakeref = fetch_and_zero(&dig_port->ddi_io_wakeref); if (wakeref) - intel_display_power_put(dev_priv, + intel_display_power_put(display, dig_port->ddi_io_power_domain, wakeref); @@ -3284,7 +3288,7 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state, * be deactivated on this port, and it may not be the same * stream that was activated last, but each stream * should have a state that is identical when it comes to - * the DP link parameteres + * the DP link parameters */ if (intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_HDMI)) @@ -3366,7 +3370,7 @@ static void intel_ddi_enable_dp(struct intel_atomic_state *state, drm_connector_update_privacy_screen(conn_state); intel_edp_backlight_on(crtc_state, conn_state); - if (!dig_port->lspcon.active || intel_dp_has_hdmi_sink(&dig_port->dp)) + if (!intel_lspcon_active(dig_port) || intel_dp_has_hdmi_sink(&dig_port->dp)) intel_dp_set_infoframes(encoder, true, crtc_state, conn_state); trans_port_sync_stop_link_train(state, encoder, crtc_state); @@ -3401,7 +3405,7 @@ static void intel_ddi_enable_hdmi(struct intel_atomic_state *state, struct intel_digital_port *dig_port = enc_to_dig_port(encoder); struct drm_connector *connector = conn_state->connector; enum port port = encoder->port; - u32 buf_ctl; + u32 buf_ctl = 0; if (!intel_hdmi_handle_sink_scrambling(encoder, connector, crtc_state->hdmi_high_tmds_clock_ratio, @@ -3414,8 +3418,7 @@ static void intel_ddi_enable_hdmi(struct intel_atomic_state *state, hsw_prepare_hdmi_ddi_buffers(encoder, crtc_state); /* e. Enable D2D Link for C10/C20 Phy */ - if (DISPLAY_VER(dev_priv) >= 14) - mtl_ddi_enable_d2d(encoder); + mtl_ddi_enable_d2d(encoder); encoder->set_signal_levels(encoder, crtc_state); @@ -3467,18 +3470,15 @@ static void intel_ddi_enable_hdmi(struct intel_atomic_state *state, * is filled with lane count, already set in the crtc_state. * The same is required to be filled in PORT_BUF_CTL for C10/20 Phy. */ - buf_ctl = DDI_BUF_CTL_ENABLE; - if (dig_port->lane_reversal) buf_ctl |= DDI_BUF_PORT_REVERSAL; if (dig_port->ddi_a_4_lanes) buf_ctl |= DDI_A_4_LANES; if (DISPLAY_VER(dev_priv) >= 14) { - u8 lane_count = mtl_get_port_width(crtc_state->lane_count); u32 port_buf = 0; - port_buf |= XELPDP_PORT_WIDTH(lane_count); + port_buf |= XELPDP_PORT_WIDTH(crtc_state->lane_count); if (dig_port->lane_reversal) port_buf |= XELPDP_PORT_REVERSAL; @@ -3495,9 +3495,7 @@ static void intel_ddi_enable_hdmi(struct intel_atomic_state *state, buf_ctl |= DDI_BUF_CTL_TC_PHY_OWNERSHIP; } - intel_de_write(dev_priv, DDI_BUF_CTL(port), buf_ctl); - - intel_wait_ddi_buf_active(encoder); + intel_ddi_buf_enable(encoder, buf_ctl); } static void intel_ddi_enable(struct intel_atomic_state *state, @@ -3706,12 +3704,13 @@ intel_ddi_pre_pll_enable(struct intel_atomic_state *state, static void adlp_tbt_to_dp_alt_switch_wa(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum tc_port tc_port = intel_encoder_to_tc(encoder); int ln; for (ln = 0; ln < 2; ln++) - intel_dkl_phy_rmw(i915, DKL_PCS_DW5(tc_port, ln), DKL_PCS_DW5_CORE_SOFTRESET, 0); + intel_dkl_phy_rmw(display, DKL_PCS_DW5(tc_port, ln), + DKL_PCS_DW5_CORE_SOFTRESET, 0); } static void mtl_ddi_prepare_link_retrain(struct intel_dp *intel_dp, @@ -3720,7 +3719,6 @@ static void mtl_ddi_prepare_link_retrain(struct intel_dp *intel_dp, struct intel_display *display = to_intel_display(crtc_state); struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct intel_encoder *encoder = &dig_port->base; - enum port port = encoder->port; u32 dp_tp_ctl; /* @@ -3728,8 +3726,8 @@ static void mtl_ddi_prepare_link_retrain(struct intel_dp *intel_dp, * necessary disable and enable port */ dp_tp_ctl = intel_de_read(display, dp_tp_ctl_reg(encoder, crtc_state)); - if (dp_tp_ctl & DP_TP_CTL_ENABLE) - mtl_disable_ddi_buf(encoder, crtc_state); + + drm_WARN_ON(display->drm, dp_tp_ctl & DP_TP_CTL_ENABLE); /* 6.d Configure and enable DP_TP_CTL with link training pattern 1 selected */ dp_tp_ctl = DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_PAT1; @@ -3754,44 +3752,25 @@ static void mtl_ddi_prepare_link_retrain(struct intel_dp *intel_dp, mtl_port_buf_ctl_program(encoder, crtc_state); /* 6.i Configure and enable DDI_CTL_DE to start sending valid data to port slice */ - intel_dp->DP |= DDI_BUF_CTL_ENABLE; if (DISPLAY_VER(display) >= 20) intel_dp->DP |= XE2LPD_DDI_BUF_D2D_LINK_ENABLE; - intel_de_write(display, DDI_BUF_CTL(port), intel_dp->DP); - intel_de_posting_read(display, DDI_BUF_CTL(port)); - - /* 6.j Poll for PORT_BUF_CTL Idle Status == 0, timeout after 100 us */ - intel_wait_ddi_buf_active(encoder); + intel_ddi_buf_enable(encoder, intel_dp->DP); + intel_dp->DP |= DDI_BUF_CTL_ENABLE; } static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(intel_dp); struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct intel_encoder *encoder = &dig_port->base; struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - enum port port = encoder->port; - u32 dp_tp_ctl, ddi_buf_ctl; - bool wait = false; + u32 dp_tp_ctl; dp_tp_ctl = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state)); - if (dp_tp_ctl & DP_TP_CTL_ENABLE) { - ddi_buf_ctl = intel_de_read(dev_priv, DDI_BUF_CTL(port)); - if (ddi_buf_ctl & DDI_BUF_CTL_ENABLE) { - intel_de_write(dev_priv, DDI_BUF_CTL(port), - ddi_buf_ctl & ~DDI_BUF_CTL_ENABLE); - wait = true; - } - - dp_tp_ctl &= ~DP_TP_CTL_ENABLE; - intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), dp_tp_ctl); - intel_de_posting_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state)); - - if (wait) - intel_wait_ddi_buf_idle(dev_priv, port); - } + drm_WARN_ON(display->drm, dp_tp_ctl & DP_TP_CTL_ENABLE); dp_tp_ctl = DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_PAT1; if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) || @@ -3809,11 +3788,8 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp, (intel_tc_port_in_dp_alt_mode(dig_port) || intel_tc_port_in_legacy_mode(dig_port))) adlp_tbt_to_dp_alt_switch_wa(encoder); + intel_ddi_buf_enable(encoder, intel_dp->DP); intel_dp->DP |= DDI_BUF_CTL_ENABLE; - intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP); - intel_de_posting_read(dev_priv, DDI_BUF_CTL(port)); - - intel_wait_ddi_buf_active(encoder); } static void intel_ddi_set_link_train(struct intel_dp *intel_dp, @@ -3878,10 +3854,12 @@ static void intel_ddi_set_idle_link_train(struct intel_dp *intel_dp, static bool intel_ddi_is_audio_enabled(struct drm_i915_private *dev_priv, enum transcoder cpu_transcoder) { + struct intel_display *display = &dev_priv->display; + if (cpu_transcoder == TRANSCODER_EDP) return false; - if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO_MMIO)) + if (!intel_display_power_is_enabled(display, POWER_DOMAIN_AUDIO_MMIO)) return false; return intel_de_read(dev_priv, HSW_AUD_PIN_ELD_CP_VLD) & @@ -3957,6 +3935,7 @@ static enum transcoder bdw_transcoder_master_readout(struct drm_i915_private *de static void bdw_get_trans_port_sync_config(struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); u32 transcoders = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C) | BIT(TRANSCODER_D); @@ -3970,7 +3949,7 @@ static void bdw_get_trans_port_sync_config(struct intel_crtc_state *crtc_state) intel_wakeref_t trans_wakeref; power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder); - trans_wakeref = intel_display_power_get_if_enabled(dev_priv, + trans_wakeref = intel_display_power_get_if_enabled(display, power_domain); if (!trans_wakeref) @@ -3980,7 +3959,7 @@ static void bdw_get_trans_port_sync_config(struct intel_crtc_state *crtc_state) crtc_state->cpu_transcoder) crtc_state->sync_mode_slaves_mask |= BIT(cpu_transcoder); - intel_display_power_put(dev_priv, power_domain, trans_wakeref); + intel_display_power_put(display, power_domain, trans_wakeref); } drm_WARN_ON(&dev_priv->drm, @@ -4067,7 +4046,7 @@ static void intel_ddi_read_func_ctl_dp_sst(struct intel_encoder *encoder, intel_de_read(display, dp_tp_ctl_reg(encoder, crtc_state)) & DP_TP_CTL_FEC_ENABLE; - if (dig_port->lspcon.active && intel_dp_has_hdmi_sink(&dig_port->dp)) + if (intel_lspcon_active(dig_port) && intel_dp_has_hdmi_sink(&dig_port->dp)) crtc_state->infoframes.enable |= intel_lspcon_infoframes_enabled(encoder, crtc_state); else @@ -4229,21 +4208,21 @@ void intel_ddi_get_clock(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state, struct intel_shared_dpll *pll) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum icl_port_dpll_id port_dpll_id = ICL_PORT_DPLL_DEFAULT; struct icl_port_dpll *port_dpll = &crtc_state->icl_port_dplls[port_dpll_id]; bool pll_active; - if (drm_WARN_ON(&i915->drm, !pll)) + if (drm_WARN_ON(display->drm, !pll)) return; port_dpll->pll = pll; - pll_active = intel_dpll_get_hw_state(i915, pll, &port_dpll->hw_state); - drm_WARN_ON(&i915->drm, !pll_active); + pll_active = intel_dpll_get_hw_state(display, pll, &port_dpll->hw_state); + drm_WARN_ON(display->drm, !pll_active); icl_set_active_port_dpll(crtc_state, port_dpll_id); - crtc_state->port_clock = intel_dpll_get_freq(i915, crtc_state->shared_dpll, + crtc_state->port_clock = intel_dpll_get_freq(display, crtc_state->shared_dpll, &crtc_state->dpll_hw_state); } @@ -4332,12 +4311,12 @@ static void icl_ddi_tc_get_clock(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state, struct intel_shared_dpll *pll) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum icl_port_dpll_id port_dpll_id; struct icl_port_dpll *port_dpll; bool pll_active; - if (drm_WARN_ON(&i915->drm, !pll)) + if (drm_WARN_ON(display->drm, !pll)) return; if (icl_ddi_tc_pll_is_tbt(pll)) @@ -4348,15 +4327,15 @@ static void icl_ddi_tc_get_clock(struct intel_encoder *encoder, port_dpll = &crtc_state->icl_port_dplls[port_dpll_id]; port_dpll->pll = pll; - pll_active = intel_dpll_get_hw_state(i915, pll, &port_dpll->hw_state); - drm_WARN_ON(&i915->drm, !pll_active); + pll_active = intel_dpll_get_hw_state(display, pll, &port_dpll->hw_state); + drm_WARN_ON(display->drm, !pll_active); icl_set_active_port_dpll(crtc_state, port_dpll_id); if (icl_ddi_tc_pll_is_tbt(crtc_state->shared_dpll)) - crtc_state->port_clock = icl_calc_tbt_pll_link(i915, encoder->port); + crtc_state->port_clock = icl_calc_tbt_pll_link(display, encoder->port); else - crtc_state->port_clock = intel_dpll_get_freq(i915, crtc_state->shared_dpll, + crtc_state->port_clock = intel_dpll_get_freq(display, crtc_state->shared_dpll, &crtc_state->dpll_hw_state); } @@ -4595,16 +4574,16 @@ static int intel_ddi_compute_config_late(struct intel_encoder *encoder, static void intel_ddi_encoder_destroy(struct drm_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->dev); + struct intel_display *display = to_intel_display(encoder->dev); struct intel_digital_port *dig_port = enc_to_dig_port(to_intel_encoder(encoder)); intel_dp_encoder_flush_work(encoder); if (intel_encoder_is_tc(&dig_port->base)) intel_tc_port_cleanup(dig_port); - intel_display_power_flush_work(i915); + intel_display_power_flush_work(display); drm_encoder_cleanup(encoder); - kfree(dig_port->hdcp_port_data.streams); + kfree(dig_port->hdcp.port_data.streams); kfree(dig_port); } @@ -4682,6 +4661,7 @@ static int intel_ddi_init_dp_connector(struct intel_digital_port *dig_port) static int intel_hdmi_reset_link(struct intel_encoder *encoder, struct drm_modeset_acquire_ctx *ctx) { + struct intel_display *display = to_intel_display(encoder); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_hdmi *hdmi = enc_to_intel_hdmi(encoder); struct intel_connector *connector = hdmi->attached_connector; @@ -4748,7 +4728,7 @@ static int intel_hdmi_reset_link(struct intel_encoder *encoder, * would be perfectly happy if were to just reconfigure * the SCDC settings on the fly. */ - return intel_modeset_commit_pipes(dev_priv, BIT(crtc->pipe), ctx); + return intel_modeset_commit_pipes(display, BIT(crtc->pipe), ctx); } static void intel_ddi_link_check(struct intel_encoder *encoder) @@ -5104,7 +5084,7 @@ void intel_ddi_init(struct intel_display *display, return; } - if (!assert_port_valid(dev_priv, port)) + if (!assert_port_valid(display, port)) return; if (port_in_use(dev_priv, port)) { @@ -5122,7 +5102,7 @@ void intel_ddi_init(struct intel_display *display, return; } - phy = intel_port_to_phy(dev_priv, port); + phy = intel_port_to_phy(display, port); /* * On platforms with HTI (aka HDPORT), if it's enabled at boot it may @@ -5159,7 +5139,7 @@ void intel_ddi_init(struct intel_display *display, return; } - if (intel_phy_is_snps(dev_priv, phy) && + if (intel_phy_is_snps(display, phy) && dev_priv->display.snps.phy_failed_calibration & BIT(phy)) { drm_dbg_kms(&dev_priv->drm, "SNPS PHY %c failed to calibrate, proceeding anyway\n", @@ -5182,7 +5162,7 @@ void intel_ddi_init(struct intel_display *display, port_name(port - PORT_D_XELPD + PORT_D), phy_name(phy)); } else if (DISPLAY_VER(dev_priv) >= 12) { - enum tc_port tc_port = intel_port_to_tc(dev_priv, port); + enum tc_port tc_port = intel_port_to_tc(display, port); drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs, DRM_MODE_ENCODER_TMDS, @@ -5192,7 +5172,7 @@ void intel_ddi_init(struct intel_display *display, tc_port != TC_PORT_NONE ? "TC" : "", tc_port != TC_PORT_NONE ? tc_port_name(tc_port) : phy_name(phy)); } else if (DISPLAY_VER(dev_priv) >= 11) { - enum tc_port tc_port = intel_port_to_tc(dev_priv, port); + enum tc_port tc_port = intel_port_to_tc(display, port); drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs, DRM_MODE_ENCODER_TMDS, @@ -5209,8 +5189,8 @@ void intel_ddi_init(struct intel_display *display, intel_encoder_link_check_init(encoder, intel_ddi_link_check); - mutex_init(&dig_port->hdcp_mutex); - dig_port->num_hdcp_streams = 0; + mutex_init(&dig_port->hdcp.mutex); + dig_port->hdcp.num_streams = 0; encoder->hotplug = intel_ddi_hotplug; encoder->compute_output_type = intel_ddi_compute_output_type; @@ -5233,7 +5213,7 @@ void intel_ddi_init(struct intel_display *display, encoder->get_power_domains = intel_ddi_get_power_domains; encoder->type = INTEL_OUTPUT_DDI; - encoder->power_domain = intel_display_power_ddi_lanes_domain(dev_priv, port); + encoder->power_domain = intel_display_power_ddi_lanes_domain(display, port); encoder->port = port; encoder->cloneable = 0; encoder->pipe_mask = ~0; @@ -5340,7 +5320,7 @@ void intel_ddi_init(struct intel_display *display, else if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv)) encoder->hpd_pin = skl_hpd_pin(dev_priv, port); else - encoder->hpd_pin = intel_hpd_pin_default(dev_priv, port); + encoder->hpd_pin = intel_hpd_pin_default(port); ddi_buf_ctl = intel_de_read(dev_priv, DDI_BUF_CTL(port)); @@ -5384,7 +5364,7 @@ void intel_ddi_init(struct intel_display *display, } drm_WARN_ON(&dev_priv->drm, port > PORT_I); - dig_port->ddi_io_power_domain = intel_display_power_ddi_io_domain(dev_priv, port); + dig_port->ddi_io_power_domain = intel_display_power_ddi_io_domain(display, port); if (DISPLAY_VER(dev_priv) >= 11) { if (intel_encoder_is_tc(encoder)) |