Commit d5c7854b authored by Lucas De Marchi's avatar Lucas De Marchi

drm/i915/xe2lpd: Move D2D enable/disable

Bits to enable/disable and check state for D2D moved from
XELPDP_PORT_BUF_CTL1 to DDI_BUF_CTL (now named DDI_CTL_DE in the spec).
Make the functions mtl_ddi_disable_d2d() and mtl_ddi_enable_d2d generic
to work with multiple reg location and bitfield layout.

v2: Set/Clear XE2LPD_DDI_BUF_D2D_LINK_ENABLE in saved_port_bits when
    enabling/disabling D2D so DDI_BUF_CTL is correctly programmed in
    other places without overriding these bits (Clint)
v3: Leave saved_port_bits alone as those bits are not meant to be
    modified outside of the port initialization. Rather propagate the
    additional bit in DDI_BUF_CTL to be set when that register is
    written again after D2D is enabled.

Cc: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: default avatarLucas De Marchi <lucas.demarchi@intel.com>
Reviewed-by: default avatarMatt Roper <matthew.d.roper@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240126224638.4132016-2-lucas.demarchi@intel.com
parent 4073dbbc
...@@ -2429,13 +2429,22 @@ mtl_ddi_enable_d2d(struct intel_encoder *encoder) ...@@ -2429,13 +2429,22 @@ mtl_ddi_enable_d2d(struct intel_encoder *encoder)
{ {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
enum port port = encoder->port; 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, if (DISPLAY_VER(dev_priv) >= 20) {
XELPDP_PORT_BUF_D2D_LINK_ENABLE); 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(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)) & intel_de_rmw(dev_priv, reg, 0, set_bits);
XELPDP_PORT_BUF_D2D_LINK_STATE), 100)) { 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 PORT_BUF_CTL %c\n", drm_err(&dev_priv->drm, "Timeout waiting for D2D Link enable for DDI/PORT_BUF_CTL %c\n",
port_name(port)); port_name(port));
} }
} }
...@@ -2898,13 +2907,22 @@ mtl_ddi_disable_d2d_link(struct intel_encoder *encoder) ...@@ -2898,13 +2907,22 @@ mtl_ddi_disable_d2d_link(struct intel_encoder *encoder)
{ {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
enum port port = encoder->port; enum port port = encoder->port;
i915_reg_t reg;
u32 clr_bits, wait_bits;
intel_de_rmw(dev_priv, XELPDP_PORT_BUF_CTL1(port), if (DISPLAY_VER(dev_priv) >= 20) {
XELPDP_PORT_BUF_D2D_LINK_ENABLE, 0); 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(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)) & intel_de_rmw(dev_priv, reg, clr_bits, 0);
XELPDP_PORT_BUF_D2D_LINK_STATE), 100)) 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 PORT_BUF_CTL %c\n", drm_err(&dev_priv->drm, "Timeout waiting for D2D Link disable for DDI/PORT_BUF_CTL %c\n",
port_name(port)); port_name(port));
} }
...@@ -3323,6 +3341,9 @@ static void intel_enable_ddi_hdmi(struct intel_atomic_state *state, ...@@ -3323,6 +3341,9 @@ static void intel_enable_ddi_hdmi(struct intel_atomic_state *state,
XELPDP_PORT_WIDTH_MASK | XELPDP_PORT_REVERSAL, port_buf); XELPDP_PORT_WIDTH_MASK | XELPDP_PORT_REVERSAL, port_buf);
buf_ctl |= DDI_PORT_WIDTH(lane_count); 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)) { } 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)); drm_WARN_ON(&dev_priv->drm, !intel_tc_port_in_legacy_mode(dig_port));
buf_ctl |= DDI_BUF_CTL_TC_PHY_OWNERSHIP; buf_ctl |= DDI_BUF_CTL_TC_PHY_OWNERSHIP;
...@@ -3543,6 +3564,9 @@ static void mtl_ddi_prepare_link_retrain(struct intel_dp *intel_dp, ...@@ -3543,6 +3564,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 */ /* 6.i Configure and enable DDI_CTL_DE to start sending valid data to port slice */
intel_dp->DP |= DDI_BUF_CTL_ENABLE; 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_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP);
intel_de_posting_read(dev_priv, DDI_BUF_CTL(port)); intel_de_posting_read(dev_priv, DDI_BUF_CTL(port));
......
...@@ -5690,6 +5690,8 @@ enum skl_power_gate { ...@@ -5690,6 +5690,8 @@ enum skl_power_gate {
/* Known as DDI_CTL_DE in MTL+ */ /* Known as DDI_CTL_DE in MTL+ */
#define DDI_BUF_CTL(port) _MMIO_PORT(port, _DDI_BUF_CTL_A, _DDI_BUF_CTL_B) #define DDI_BUF_CTL(port) _MMIO_PORT(port, _DDI_BUF_CTL_A, _DDI_BUF_CTL_B)
#define DDI_BUF_CTL_ENABLE (1 << 31) #define DDI_BUF_CTL_ENABLE (1 << 31)
#define XE2LPD_DDI_BUF_D2D_LINK_ENABLE REG_BIT(29)
#define XE2LPD_DDI_BUF_D2D_LINK_STATE REG_BIT(28)
#define DDI_BUF_TRANS_SELECT(n) ((n) << 24) #define DDI_BUF_TRANS_SELECT(n) ((n) << 24)
#define DDI_BUF_EMP_MASK (0xf << 24) #define DDI_BUF_EMP_MASK (0xf << 24)
#define DDI_BUF_PHY_LINK_RATE(r) ((r) << 20) #define DDI_BUF_PHY_LINK_RATE(r) ((r) << 20)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment