drm/i915: Try EDID bitbanging on HDMI after failed read

"Linux Kernel Mailing List" <[email protected]>
Newsgroups gmane.linux.kernel.commits.head
Message-ID <[email protected]>
Web:        https://git.kernel.org/torvalds/c/90024a5951029685acc5396258f1b0de9b23cf4a
Commit:     90024a5951029685acc5396258f1b0de9b23cf4a
Parent:     2afba81c7909ac259720c0d3e7616cf54d4a5368
Refname:    refs/heads/master
Author:     Stefan Brüns <[email protected]>
AuthorDate: Sun Dec 31 23:34:54 2017 +0100
Committer:  Rodrigo Vivi <[email protected]>
CommitDate: Thu Feb 1 07:31:27 2018 -0800

    drm/i915: Try EDID bitbanging on HDMI after failed read
    
    The ACK/NACK implementation as found in e.g. the G965 has the falling
    clock edge and the release of the data line after the ACK for the received
    byte happen at the same time.
    
    This is conformant with the I2C specification, which allows a zero hold
    time, see footnote [3]: "A device must internally provide a hold time of
    at least 300 ns for the SDA signal (with respect to the V IH(min) of the
    SCL signal) to bridge the undefined region of the falling edge of SCL."
    
    Some HDMI-to-VGA converters apparently fail to adhere to this requirement
    and latch SDA at the falling clock edge, so instead of an ACK
    sometimes a NACK is read and the slave (i.e. the EDID ROM) ends the
    transfer.
    
    The bitbanging releases the data line for the ACK only 1/4 bit time after
    the falling clock edge, so a slave will see the correct value no matter
    if it samples at the rising or the falling clock edge or in the center.
    
    Fallback to bitbanging is already done for the CRT connector.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92685
    Signed-off-by: Stefan Brüns <[email protected]>
    Cc: [email protected]
    Signed-off-by: Daniel Vetter <[email protected]>
    Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
    (cherry picked from commit cfb926e148e99acc02351d72e8b85e32b5f786ef)
    Signed-off-by: Rodrigo Vivi <[email protected]>
---
 drivers/gpu/drm/i915/intel_hdmi.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index bced7b954d93..179d0ad3889d 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1595,12 +1595,20 @@ intel_hdmi_set_edid(struct drm_connector *connector)
 	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
 	struct edid *edid;
 	bool connected = false;
+	struct i2c_adapter *i2c;
 
 	intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
 
-	edid = drm_get_edid(connector,
-			    intel_gmbus_get_adapter(dev_priv,
-			    intel_hdmi->ddc_bus));
+	i2c = intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus);
+
+	edid = drm_get_edid(connector, i2c);
+
+	if (!edid && !intel_gmbus_is_forced_bit(i2c)) {
+		DRM_DEBUG_KMS("HDMI GMBUS EDID read failed, retry using GPIO bit-banging\n");
+		intel_gmbus_force_bit(i2c, true);
+		edid = drm_get_edid(connector, i2c);
+		intel_gmbus_force_bit(i2c, false);
+	}
 
 	intel_hdmi_dp_dual_mode_detect(connector, edid != NULL);
 
--
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.