Re: [PATCH 1/2] drm/i915/xe2lpd: Move D2D enable/disable

2024-01-29 Thread Matt Roper
On Fri, Jan 26, 2024 at 02:46:36PM -0800, Lucas De Marchi wrote:
> 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 
> Signed-off-by: Lucas De Marchi 

Reviewed-by: Matt Roper 

> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c | 44 ++--
>  drivers/gpu/drm/i915/i915_reg.h  |  2 ++
>  2 files changed, 36 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
> b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 12a29363e5df..188c537dbb5d 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -2429,13 +2429,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(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));
>   }
>  }
> @@ -2898,13 +2907,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(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));
>  }
>  
> @@ -3323,6 +3341,9 @@ static void intel_enable_ddi_hdmi(struct 
> intel_atomic_state *state,
>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 +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 */
>   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));
>  
> dif

[PATCH 1/2] drm/i915/xe2lpd: Move D2D enable/disable

2024-01-26 Thread Lucas De Marchi
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 
Signed-off-by: Lucas De Marchi 
---
 drivers/gpu/drm/i915/display/intel_ddi.c | 44 ++--
 drivers/gpu/drm/i915/i915_reg.h  |  2 ++
 2 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index 12a29363e5df..188c537dbb5d 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -2429,13 +2429,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(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));
}
 }
@@ -2898,13 +2907,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(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));
 }
 
@@ -3323,6 +3341,9 @@ static void intel_enable_ddi_hdmi(struct 
intel_atomic_state *state,
 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 +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 */
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));
 
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 27dc903f0553..f034b7b0f1da 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -5684,