[Intel-gfx] [PATCH] drm/i915: Check live status before reading edid

Sonika Jindal sonika.jindal at intel.com
Sun Sep 6 22:02:15 PDT 2015


Adding this for SKL onwards.

v2: Adding checks for VLV/CHV as well. Reusing old ibx and g4x functions
to check digital port status. Adding a separate function to get bxt live
status (Daniel)
v3: Using intel_encoder->hpd_pin to check the live status (Siva)
Moving the live status read to intel_hdmi_probe and passing parameter
to read/not to read the edid. (me)
v4:
* Added live status check for all platforms using
intel_digital_port_connected.
* Rebased on top of Jani's DP cleanup series
* Some monitors take time in setting the live status. So retry for few
times if this is a connect HPD
v5: Removed extra "drm/i915" from commit message. Adding Shashank's sob
which was missed.

Signed-off-by: Shashank Sharma <shashank.sharma at intel.com>
Signed-off-by: Sonika Jindal <sonika.jindal at intel.com>
---
 drivers/gpu/drm/i915/intel_hdmi.c |   35 ++++++++++++++++++++++++++++-------
 1 file changed, 28 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 1eda71a..d82887b 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1329,22 +1329,23 @@ intel_hdmi_unset_edid(struct drm_connector *connector)
 }
 
 static bool
-intel_hdmi_set_edid(struct drm_connector *connector)
+intel_hdmi_set_edid(struct drm_connector *connector, bool force)
 {
 	struct drm_i915_private *dev_priv = to_i915(connector->dev);
 	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
 	struct intel_encoder *intel_encoder =
 		&hdmi_to_dig_port(intel_hdmi)->base;
 	enum intel_display_power_domain power_domain;
-	struct edid *edid;
+	struct edid *edid = NULL;
 	bool connected = false;
 
 	power_domain = intel_display_port_power_domain(intel_encoder);
 	intel_display_power_get(dev_priv, power_domain);
 
-	edid = drm_get_edid(connector,
-			    intel_gmbus_get_adapter(dev_priv,
-						    intel_hdmi->ddc_bus));
+	if (force)
+		edid = drm_get_edid(connector,
+				    intel_gmbus_get_adapter(dev_priv,
+				    intel_hdmi->ddc_bus));
 
 	intel_display_power_put(dev_priv, power_domain);
 
@@ -1374,6 +1375,26 @@ void intel_hdmi_probe(struct intel_encoder *intel_encoder)
 			enc_to_intel_hdmi(&intel_encoder->base);
 	struct intel_connector *intel_connector =
 				intel_hdmi->attached_connector;
+	struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev);
+	bool live_status = false;
+	unsigned int retry = 3;
+
+	live_status = intel_digital_port_connected(dev_priv,
+						   hdmi_to_dig_port(intel_hdmi));
+	if (!intel_connector->detect_edid && live_status == false) {
+		/*
+		 * Hotplug had occurred and old status was disconnected,
+		 * so it might be possible that live status is not set,
+		 * so retry for few times
+		 */
+		do {
+			mdelay(10);
+			live_status = intel_digital_port_connected(dev_priv,
+						hdmi_to_dig_port(intel_hdmi));
+			if (live_status)
+				break;
+		} while (retry--);
+	}
 
 	/*
 	 * We are here, means there is a hotplug or a force
@@ -1381,7 +1402,7 @@ void intel_hdmi_probe(struct intel_encoder *intel_encoder)
 	 * DDC bus to check the current status of HDMI.
 	 */
 	intel_hdmi_unset_edid(&intel_connector->base);
-	if (intel_hdmi_set_edid(&intel_connector->base))
+	if (intel_hdmi_set_edid(&intel_connector->base, live_status))
 		DRM_DEBUG_DRIVER("DDC probe: got EDID\n");
 	else
 		DRM_DEBUG_DRIVER("DDC probe: no EDID\n");
@@ -1432,7 +1453,7 @@ intel_hdmi_force(struct drm_connector *connector)
 	if (connector->status != connector_status_connected)
 		return;
 
-	intel_hdmi_set_edid(connector);
+	intel_hdmi_set_edid(connector, true);
 	hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
 }
 
-- 
1.7.10.4



More information about the Intel-gfx mailing list