summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/display/intel_ddi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_ddi.c')
-rw-r--r--drivers/gpu/drm/i915/display/intel_ddi.c75
1 files changed, 55 insertions, 20 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 12a29363e5df..c17462b4c2ac 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -54,6 +54,7 @@
#include "intel_dp_aux.h"
#include "intel_dp_link_training.h"
#include "intel_dp_mst.h"
+#include "intel_dp_tunnel.h"
#include "intel_dpio_phy.h"
#include "intel_dsi.h"
#include "intel_fdi.h"
@@ -178,7 +179,7 @@ static void mtl_wait_ddi_buf_idle(struct drm_i915_private *i915, enum port port)
int ret;
/* FIXME: find out why Bspec's 100us timeout is too short */
- ret = wait_for_us((intel_de_read(i915, XELPDP_PORT_BUF_CTL1(port)) &
+ 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",
@@ -226,7 +227,9 @@ static void intel_wait_ddi_buf_active(struct drm_i915_private *dev_priv,
}
if (DISPLAY_VER(dev_priv) >= 14)
- ret = _wait_for(!(intel_de_read(dev_priv, XELPDP_PORT_BUF_CTL1(port)) & XELPDP_PORT_BUF_PHY_IDLE),
+ 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),
@@ -2429,13 +2432,22 @@ mtl_ddi_enable_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 set_bits, wait_bits;
- intel_de_rmw(dev_priv, XELPDP_PORT_BUF_CTL1(port), 0,
- XELPDP_PORT_BUF_D2D_LINK_ENABLE);
+ if (DISPLAY_VER(dev_priv) >= 20) {
+ reg = DDI_BUF_CTL(port);
+ set_bits = XE2LPD_DDI_BUF_D2D_LINK_ENABLE;
+ wait_bits = XE2LPD_DDI_BUF_D2D_LINK_STATE;
+ } else {
+ reg = XELPDP_PORT_BUF_CTL1(dev_priv, port);
+ set_bits = XELPDP_PORT_BUF_D2D_LINK_ENABLE;
+ wait_bits = XELPDP_PORT_BUF_D2D_LINK_STATE;
+ }
- if (wait_for_us((intel_de_read(dev_priv, XELPDP_PORT_BUF_CTL1(port)) &
- XELPDP_PORT_BUF_D2D_LINK_STATE), 100)) {
- drm_err(&dev_priv->drm, "Timeout waiting for D2D Link enable for PORT_BUF_CTL %c\n",
+ intel_de_rmw(dev_priv, reg, 0, set_bits);
+ if (wait_for_us(intel_de_read(dev_priv, reg) & wait_bits, 100)) {
+ drm_err(&dev_priv->drm, "Timeout waiting for D2D Link enable for DDI/PORT_BUF_CTL %c\n",
port_name(port));
}
}
@@ -2448,7 +2460,7 @@ static void mtl_port_buf_ctl_program(struct intel_encoder *encoder,
enum port port = encoder->port;
u32 val;
- val = intel_de_read(i915, XELPDP_PORT_BUF_CTL1(port));
+ val = intel_de_read(i915, XELPDP_PORT_BUF_CTL1(i915, port));
val &= ~XELPDP_PORT_WIDTH_MASK;
val |= XELPDP_PORT_WIDTH(mtl_get_port_width(crtc_state->lane_count));
@@ -2461,7 +2473,7 @@ static void mtl_port_buf_ctl_program(struct intel_encoder *encoder,
if (dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL)
val |= XELPDP_PORT_REVERSAL;
- intel_de_write(i915, XELPDP_PORT_BUF_CTL1(port), val);
+ intel_de_write(i915, XELPDP_PORT_BUF_CTL1(i915, port), val);
}
static void mtl_port_buf_ctl_io_selection(struct intel_encoder *encoder)
@@ -2472,7 +2484,7 @@ static void mtl_port_buf_ctl_io_selection(struct intel_encoder *encoder)
val = intel_tc_port_in_tbt_alt_mode(dig_port) ?
XELPDP_PORT_BUF_IO_SELECT_TBT : 0;
- intel_de_rmw(i915, XELPDP_PORT_BUF_CTL1(encoder->port),
+ intel_de_rmw(i915, XELPDP_PORT_BUF_CTL1(i915, encoder->port),
XELPDP_PORT_BUF_IO_SELECT_TBT, val);
}
@@ -2898,13 +2910,22 @@ mtl_ddi_disable_d2d_link(struct intel_encoder *encoder)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
enum port port = encoder->port;
+ i915_reg_t reg;
+ u32 clr_bits, wait_bits;
- intel_de_rmw(dev_priv, XELPDP_PORT_BUF_CTL1(port),
- XELPDP_PORT_BUF_D2D_LINK_ENABLE, 0);
+ if (DISPLAY_VER(dev_priv) >= 20) {
+ reg = DDI_BUF_CTL(port);
+ clr_bits = XE2LPD_DDI_BUF_D2D_LINK_ENABLE;
+ wait_bits = XE2LPD_DDI_BUF_D2D_LINK_STATE;
+ } else {
+ reg = XELPDP_PORT_BUF_CTL1(dev_priv, port);
+ clr_bits = XELPDP_PORT_BUF_D2D_LINK_ENABLE;
+ wait_bits = XELPDP_PORT_BUF_D2D_LINK_STATE;
+ }
- if (wait_for_us(!(intel_de_read(dev_priv, XELPDP_PORT_BUF_CTL1(port)) &
- XELPDP_PORT_BUF_D2D_LINK_STATE), 100))
- drm_err(&dev_priv->drm, "Timeout waiting for D2D Link disable for PORT_BUF_CTL %c\n",
+ intel_de_rmw(dev_priv, reg, clr_bits, 0);
+ if (wait_for_us(!(intel_de_read(dev_priv, reg) & wait_bits), 100))
+ drm_err(&dev_priv->drm, "Timeout waiting for D2D Link disable for DDI/PORT_BUF_CTL %c\n",
port_name(port));
}
@@ -3038,7 +3059,7 @@ static void intel_ddi_post_disable_dp(struct intel_atomic_state *state,
/* De-select Thunderbolt */
if (DISPLAY_VER(dev_priv) >= 14)
- intel_de_rmw(dev_priv, XELPDP_PORT_BUF_CTL1(encoder->port),
+ intel_de_rmw(dev_priv, XELPDP_PORT_BUF_CTL1(dev_priv, encoder->port),
XELPDP_PORT_BUF_IO_SELECT_TBT, 0);
}
@@ -3319,10 +3340,13 @@ static void intel_enable_ddi_hdmi(struct intel_atomic_state *state,
if (dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL)
port_buf |= XELPDP_PORT_REVERSAL;
- intel_de_rmw(dev_priv, XELPDP_PORT_BUF_CTL1(port),
+ intel_de_rmw(dev_priv, XELPDP_PORT_BUF_CTL1(dev_priv, port),
XELPDP_PORT_WIDTH_MASK | XELPDP_PORT_REVERSAL, port_buf);
buf_ctl |= DDI_PORT_WIDTH(lane_count);
+
+ if (DISPLAY_VER(dev_priv) >= 20)
+ buf_ctl |= XE2LPD_DDI_BUF_D2D_LINK_ENABLE;
} else if (IS_ALDERLAKE_P(dev_priv) && intel_phy_is_tc(dev_priv, phy)) {
drm_WARN_ON(&dev_priv->drm, !intel_tc_port_in_legacy_mode(dig_port));
buf_ctl |= DDI_BUF_CTL_TC_PHY_OWNERSHIP;
@@ -3543,6 +3567,9 @@ static void mtl_ddi_prepare_link_retrain(struct intel_dp *intel_dp,
/* 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(dev_priv) >= 20)
+ intel_dp->DP |= XE2LPD_DDI_BUF_D2D_LINK_ENABLE;
+
intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP);
intel_de_posting_read(dev_priv, DDI_BUF_CTL(port));
@@ -3941,11 +3968,11 @@ static void intel_ddi_get_config(struct intel_encoder *encoder,
if (DISPLAY_VER(dev_priv) >= 8)
bdw_get_trans_port_sync_config(pipe_config);
+ intel_psr_get_config(encoder, pipe_config);
+
intel_read_dp_sdp(encoder, pipe_config, HDMI_PACKET_TYPE_GAMUT_METADATA);
intel_read_dp_sdp(encoder, pipe_config, DP_SDP_VSC);
- intel_psr_get_config(encoder, pipe_config);
-
intel_audio_codec_get_config(encoder, pipe_config);
}
@@ -4124,7 +4151,7 @@ static void intel_ddi_sync_state(struct intel_encoder *encoder,
intel_tc_port_sanitize_mode(enc_to_dig_port(encoder),
crtc_state);
- if (crtc_state && intel_crtc_has_dp_encoder(crtc_state))
+ if (intel_encoder_is_dp(encoder))
intel_dp_sync_state(encoder, crtc_state);
}
@@ -4229,7 +4256,12 @@ static bool m_n_equal(const struct intel_link_m_n *m_n_1,
static bool crtcs_port_sync_compatible(const struct intel_crtc_state *crtc_state1,
const struct intel_crtc_state *crtc_state2)
{
+ /*
+ * FIXME the modeset sequence is currently wrong and
+ * can't deal with bigjoiner + port sync at the same time.
+ */
return crtc_state1->hw.active && crtc_state2->hw.active &&
+ !crtc_state1->bigjoiner_pipes && !crtc_state2->bigjoiner_pipes &&
crtc_state1->output_types == crtc_state2->output_types &&
crtc_state1->output_format == crtc_state2->output_format &&
crtc_state1->lane_count == crtc_state2->lane_count &&
@@ -5117,6 +5149,9 @@ void intel_ddi_init(struct drm_i915_private *dev_priv,
encoder->suspend_complete = intel_ddi_tc_encoder_suspend_complete;
encoder->shutdown_complete = intel_ddi_tc_encoder_shutdown_complete;
+ dig_port->lock = intel_tc_port_lock;
+ dig_port->unlock = intel_tc_port_unlock;
+
if (intel_tc_port_init(dig_port, is_legacy) < 0)
goto err;
}