diff mbox series

drm/i915/dg2: Skip output init on PHY calibration failure

Message ID 20220223165421.3949883-1-matthew.d.roper@intel.com (mailing list archive)
State New, archived
Headers show
Series drm/i915/dg2: Skip output init on PHY calibration failure | expand

Commit Message

Matt Roper Feb. 23, 2022, 4:54 p.m. UTC
If one of our PHYs fails to complete calibration, we should skip the
general initialization of the corresponding output.  Most likely this is
going to happen on outputs that don't actually exist on the board; in
theory we should have already decided to skip this output based on the
VBT, but we can't always rely on the VBT being accurate.

Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c      |  8 ++++++++
 drivers/gpu/drm/i915/display/intel_snps_phy.c |  8 ++++++--
 drivers/gpu/drm/i915/i915_drv.h               | 12 ++++++++++--
 3 files changed, 24 insertions(+), 4 deletions(-)

Comments

Lucas De Marchi Feb. 23, 2022, 5:14 p.m. UTC | #1
On Wed, Feb 23, 2022 at 08:54:21AM -0800, Matt Roper wrote:
>If one of our PHYs fails to complete calibration, we should skip the
>general initialization of the corresponding output.  Most likely this is
>going to happen on outputs that don't actually exist on the board; in
>theory we should have already decided to skip this output based on the
>VBT, but we can't always rely on the VBT being accurate.
>
>Cc: Lucas De Marchi <lucas.demarchi@intel.com>
>Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
>---
> drivers/gpu/drm/i915/display/intel_ddi.c      |  8 ++++++++
> drivers/gpu/drm/i915/display/intel_snps_phy.c |  8 ++++++--
> drivers/gpu/drm/i915/i915_drv.h               | 12 ++++++++++--
> 3 files changed, 24 insertions(+), 4 deletions(-)
>
>diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
>index e4260806c2a4..b71035a5db85 100644
>--- a/drivers/gpu/drm/i915/display/intel_ddi.c
>+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
>@@ -4308,6 +4308,14 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
> 		return;
> 	}
>
>+	if (intel_phy_is_snps(dev_priv, phy) &&
>+	    dev_priv->snps_phy_failed_calibration & BIT(phy)) {
>+		drm_dbg_kms(&dev_priv->drm,
>+			    "SNPS PHY %c failed to calibrate after 25ms; output will not be used.\n",

								   ^^^^
I would only skip mentioning the timeout here, as this can very easily
get out of sync.


>+			    phy_name(phy));
>+		return;
>+	}
>+
> 	dig_port = kzalloc(sizeof(*dig_port), GFP_KERNEL);
> 	if (!dig_port)
> 		return;
>diff --git a/drivers/gpu/drm/i915/display/intel_snps_phy.c b/drivers/gpu/drm/i915/display/intel_snps_phy.c
>index 7e6245b97fed..0dd4775e8195 100644
>--- a/drivers/gpu/drm/i915/display/intel_snps_phy.c
>+++ b/drivers/gpu/drm/i915/display/intel_snps_phy.c
>@@ -32,10 +32,14 @@ void intel_snps_phy_wait_for_calibration(struct drm_i915_private *i915)
> 		if (!intel_phy_is_snps(i915, phy))
> 			continue;
>
>+		/*
>+		 * If calibration does not complete successfully, we'll remember
>+		 * which phy was affected and skip setup of the corresponding
>+		 * output later.
>+		 */
> 		if (intel_de_wait_for_clear(i915, DG2_PHY_MISC(phy),
> 					    DG2_PHY_DP_TX_ACK_MASK, 25))
>-			drm_err(&i915->drm, "SNPS PHY %c failed to calibrate after 25ms.\n",
>-				phy_name(phy));

or just leave the message here as a debug.


Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>

and I think this can go to drm-intel-next, not only topic/core-for-CI.

thanks
Lucas De Marchi
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index e4260806c2a4..b71035a5db85 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -4308,6 +4308,14 @@  void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
 		return;
 	}
 
+	if (intel_phy_is_snps(dev_priv, phy) &&
+	    dev_priv->snps_phy_failed_calibration & BIT(phy)) {
+		drm_dbg_kms(&dev_priv->drm,
+			    "SNPS PHY %c failed to calibrate after 25ms; output will not be used.\n",
+			    phy_name(phy));
+		return;
+	}
+
 	dig_port = kzalloc(sizeof(*dig_port), GFP_KERNEL);
 	if (!dig_port)
 		return;
diff --git a/drivers/gpu/drm/i915/display/intel_snps_phy.c b/drivers/gpu/drm/i915/display/intel_snps_phy.c
index 7e6245b97fed..0dd4775e8195 100644
--- a/drivers/gpu/drm/i915/display/intel_snps_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_snps_phy.c
@@ -32,10 +32,14 @@  void intel_snps_phy_wait_for_calibration(struct drm_i915_private *i915)
 		if (!intel_phy_is_snps(i915, phy))
 			continue;
 
+		/*
+		 * If calibration does not complete successfully, we'll remember
+		 * which phy was affected and skip setup of the corresponding
+		 * output later.
+		 */
 		if (intel_de_wait_for_clear(i915, DG2_PHY_MISC(phy),
 					    DG2_PHY_DP_TX_ACK_MASK, 25))
-			drm_err(&i915->drm, "SNPS PHY %c failed to calibrate after 25ms.\n",
-				phy_name(phy));
+			i915->snps_phy_failed_calibration |= BIT(phy);
 	}
 }
 
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 1c2f4ae4ebf9..a9d5823d7e78 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -837,8 +837,16 @@  struct drm_i915_private {
 
 	bool irq_enabled;
 
-	/* perform PHY state sanity checks? */
-	bool chv_phy_assert[2];
+	union {
+		/* perform PHY state sanity checks? */
+		bool chv_phy_assert[2];
+
+		/*
+		 * DG2: Mask of PHYs that were not calibrated by the firmware
+		 * and should not be used.
+		 */
+		u8 snps_phy_failed_calibration;
+	};
 
 	bool ipc_enabled;