Re: [PATCH v2] drm/i915: Try EDID bitbanging on HDMI after failed read

From: Daniel Vetter
Date: Tue Jan 09 2018 - 04:06:21 EST


On Sun, Dec 31, 2017 at 11:34:54PM +0100, Stefan Brüns wrote:
> 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.
>
> Bug: https://bugs.freedesktop.org/show_bug.cgi?id=92685
>
> Signed-off-by: Stefan Brüns <stefan.bruens@xxxxxxxxxxxxxx>
>
> ---
>
> Changes in v2:
> - Fix/enhance commit message, no code changes

Ok, found v2, merged this one instead.
-Daniel

>
> 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 4dea833f9d1b..847cda4c017c 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -1573,12 +1573,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);
>
> --
> 2.15.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@xxxxxxxxxxxxxxxxxxxxx
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch