All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] drm/i915: Fix DDC probe for passive adapters
@ 2015-05-28  8:51 ` Jani Nikula
  0 siblings, 0 replies; 30+ messages in thread
From: Jani Nikula @ 2015-05-28  8:51 UTC (permalink / raw)
  To: intel-gfx; +Cc: stable, jani.nikula, tprevite, jim.bride

Passive DP->DVI/HDMI dongles on DP++ ports show up to the system as HDMI
devices, as they do not have a sink device in them to respond to any AUX
traffic. When probing these dongles over the DDC, sometimes they will
NAK the first attempt even though the transaction is valid and they
support the DDC protocol. The retry loop inside of
drm_do_probe_ddc_edid() would normally catch this case and try the
transaction again, resulting in success.

That, however, was thwarted by the fix for [1]:

commit 9292f37e1f5c79400254dca46f83313488093825
Author: Eugeni Dodonov <eugeni.dodonov@intel.com>
Date:   Thu Jan 5 09:34:28 2012 -0200

    drm: give up on edid retries when i2c bus is not responding

This added code to exit immediately if the return code from the
i2c_transfer function was -ENXIO in order to reduce the amount of time
spent in waiting for unresponsive or disconnected devices. That was
possible because the underlying i2c bit banging algorithm had retries of
its own (which, of course, were part of the reason for the bug the
commit fixes).

Since its introduction in

commit f899fc64cda8569d0529452aafc0da31c042df2e
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Tue Jul 20 15:44:45 2010 -0700

    drm/i915: use GMBUS to manage i2c links

we've been flipping back and forth enabling the GMBUS transfers, but
we've settled since then. The GMBUS implementation does not do any
retries, however, bailing out of the drm_do_probe_ddc_edid() retry loop
on first encounter of -ENXIO. This, combined with Eugeni's commit, broke
the retry on -ENXIO.

Retry GMBUS once on -ENXIO to mitigate the issues with passive adapters.

This patch is based on the work, and commit message, by Todd Previte
<tprevite@gmail.com>.

[1] https://bugs.freedesktop.org/show_bug.cgi?id=41059

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85924
Cc: Todd Previte <tprevite@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/intel_i2c.c | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index 92072f56e418..e58f39e167fb 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -478,9 +478,7 @@ gmbus_xfer_index_read(struct drm_i915_private *dev_priv, struct i2c_msg *msgs)
 }
 
 static int
-gmbus_xfer(struct i2c_adapter *adapter,
-	   struct i2c_msg *msgs,
-	   int num)
+do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
 {
 	struct intel_gmbus *bus = container_of(adapter,
 					       struct intel_gmbus,
@@ -593,6 +591,24 @@ out:
 	return ret;
 }
 
+static int
+gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
+{
+	int ret;
+
+	ret = do_gmbus_xfer(adapter, msgs, num);
+
+	/*
+	 * Passive adapters sometimes NAK the first probe. Retry once on
+	 * -ENXIO. See also the retry loop in drm_do_probe_ddc_edid, which bails
+	 * out on the first -ENXIO.
+	 */
+	if (ret == -ENXIO)
+		ret = do_gmbus_xfer(adapter, msgs, num);
+
+	return ret;
+}
+
 static u32 gmbus_func(struct i2c_adapter *adapter)
 {
 	return i2c_bit_algo.functionality(adapter) &
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH] drm/i915: Fix DDC probe for passive adapters
@ 2015-05-28  8:51 ` Jani Nikula
  0 siblings, 0 replies; 30+ messages in thread
From: Jani Nikula @ 2015-05-28  8:51 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula, stable

Passive DP->DVI/HDMI dongles on DP++ ports show up to the system as HDMI
devices, as they do not have a sink device in them to respond to any AUX
traffic. When probing these dongles over the DDC, sometimes they will
NAK the first attempt even though the transaction is valid and they
support the DDC protocol. The retry loop inside of
drm_do_probe_ddc_edid() would normally catch this case and try the
transaction again, resulting in success.

That, however, was thwarted by the fix for [1]:

commit 9292f37e1f5c79400254dca46f83313488093825
Author: Eugeni Dodonov <eugeni.dodonov@intel.com>
Date:   Thu Jan 5 09:34:28 2012 -0200

    drm: give up on edid retries when i2c bus is not responding

This added code to exit immediately if the return code from the
i2c_transfer function was -ENXIO in order to reduce the amount of time
spent in waiting for unresponsive or disconnected devices. That was
possible because the underlying i2c bit banging algorithm had retries of
its own (which, of course, were part of the reason for the bug the
commit fixes).

Since its introduction in

commit f899fc64cda8569d0529452aafc0da31c042df2e
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Tue Jul 20 15:44:45 2010 -0700

    drm/i915: use GMBUS to manage i2c links

we've been flipping back and forth enabling the GMBUS transfers, but
we've settled since then. The GMBUS implementation does not do any
retries, however, bailing out of the drm_do_probe_ddc_edid() retry loop
on first encounter of -ENXIO. This, combined with Eugeni's commit, broke
the retry on -ENXIO.

Retry GMBUS once on -ENXIO to mitigate the issues with passive adapters.

This patch is based on the work, and commit message, by Todd Previte
<tprevite@gmail.com>.

[1] https://bugs.freedesktop.org/show_bug.cgi?id=41059

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85924
Cc: Todd Previte <tprevite@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/intel_i2c.c | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index 92072f56e418..e58f39e167fb 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -478,9 +478,7 @@ gmbus_xfer_index_read(struct drm_i915_private *dev_priv, struct i2c_msg *msgs)
 }
 
 static int
-gmbus_xfer(struct i2c_adapter *adapter,
-	   struct i2c_msg *msgs,
-	   int num)
+do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
 {
 	struct intel_gmbus *bus = container_of(adapter,
 					       struct intel_gmbus,
@@ -593,6 +591,24 @@ out:
 	return ret;
 }
 
+static int
+gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
+{
+	int ret;
+
+	ret = do_gmbus_xfer(adapter, msgs, num);
+
+	/*
+	 * Passive adapters sometimes NAK the first probe. Retry once on
+	 * -ENXIO. See also the retry loop in drm_do_probe_ddc_edid, which bails
+	 * out on the first -ENXIO.
+	 */
+	if (ret == -ENXIO)
+		ret = do_gmbus_xfer(adapter, msgs, num);
+
+	return ret;
+}
+
 static u32 gmbus_func(struct i2c_adapter *adapter)
 {
 	return i2c_bit_algo.functionality(adapter) &
-- 
2.1.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2] drm/i915: Fix DDC probe for passive adapters
  2015-05-28  8:51 ` Jani Nikula
  (?)
@ 2015-05-28 10:05 ` Jani Nikula
  2015-05-28 10:48     ` Ville Syrjälä
                     ` (2 more replies)
  -1 siblings, 3 replies; 30+ messages in thread
From: Jani Nikula @ 2015-05-28 10:05 UTC (permalink / raw)
  To: Jani Nikula, intel-gfx; +Cc: stable, tprevite, jim.bride

Passive DP->DVI/HDMI dongles on DP++ ports show up to the system as HDMI
devices, as they do not have a sink device in them to respond to any AUX
traffic. When probing these dongles over the DDC, sometimes they will
NAK the first attempt even though the transaction is valid and they
support the DDC protocol. The retry loop inside of
drm_do_probe_ddc_edid() would normally catch this case and try the
transaction again, resulting in success.

That, however, was thwarted by the fix for [1]:

commit 9292f37e1f5c79400254dca46f83313488093825
Author: Eugeni Dodonov <eugeni.dodonov@intel.com>
Date:   Thu Jan 5 09:34:28 2012 -0200

    drm: give up on edid retries when i2c bus is not responding

This added code to exit immediately if the return code from the
i2c_transfer function was -ENXIO in order to reduce the amount of time
spent in waiting for unresponsive or disconnected devices. That was
possible because the underlying i2c bit banging algorithm had retries of
its own (which, of course, were part of the reason for the bug the
commit fixes).

Since its introduction in

commit f899fc64cda8569d0529452aafc0da31c042df2e
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Tue Jul 20 15:44:45 2010 -0700

    drm/i915: use GMBUS to manage i2c links

we've been flipping back and forth enabling the GMBUS transfers, but
we've settled since then. The GMBUS implementation does not do any
retries, however, bailing out of the drm_do_probe_ddc_edid() retry loop
on first encounter of -ENXIO. This, combined with Eugeni's commit, broke
the retry on -ENXIO.

Retry GMBUS once on -ENXIO to mitigate the issues with passive adapters.

This patch is based on the work, and commit message, by Todd Previte
<tprevite@gmail.com>.

[1] https://bugs.freedesktop.org/show_bug.cgi?id=41059

v2: Don't retry if using bit banging.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85924
Cc: Todd Previte <tprevite@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/intel_i2c.c | 25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index 92072f56e418..c3f72b509d1f 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -478,9 +478,7 @@ gmbus_xfer_index_read(struct drm_i915_private *dev_priv, struct i2c_msg *msgs)
 }
 
 static int
-gmbus_xfer(struct i2c_adapter *adapter,
-	   struct i2c_msg *msgs,
-	   int num)
+do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
 {
 	struct intel_gmbus *bus = container_of(adapter,
 					       struct intel_gmbus,
@@ -593,6 +591,27 @@ out:
 	return ret;
 }
 
+static int
+gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
+{
+	struct intel_gmbus *bus = container_of(adapter, struct intel_gmbus,
+					       adapter);
+	int ret;
+
+	ret = do_gmbus_xfer(adapter, msgs, num);
+
+	/*
+	 * Passive adapters sometimes NAK the first probe. Retry once on -ENXIO
+	 * for GMBUS transfers; the bit banging algorithm has retries
+	 * internally. See also the retry loop in drm_do_probe_ddc_edid, which
+	 * bails out on the first -ENXIO.
+	 */
+	if (ret == -ENXIO && !bus->force_bit)
+		ret = do_gmbus_xfer(adapter, msgs, num);
+
+	return ret;
+}
+
 static u32 gmbus_func(struct i2c_adapter *adapter)
 {
 	return i2c_bit_algo.functionality(adapter) &
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [Intel-gfx] [PATCH v2] drm/i915: Fix DDC probe for passive adapters
  2015-05-28 10:05 ` [PATCH v2] " Jani Nikula
@ 2015-05-28 10:48     ` Ville Syrjälä
  2015-05-31 12:03   ` shuang.he
  2015-06-02  8:29   ` [PATCH v3] " Jani Nikula
  2 siblings, 0 replies; 30+ messages in thread
From: Ville Syrjälä @ 2015-05-28 10:48 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, stable

On Thu, May 28, 2015 at 01:05:39PM +0300, Jani Nikula wrote:
> Passive DP->DVI/HDMI dongles on DP++ ports show up to the system as HDMI
> devices, as they do not have a sink device in them to respond to any AUX
> traffic. When probing these dongles over the DDC, sometimes they will
> NAK the first attempt even though the transaction is valid and they
> support the DDC protocol. The retry loop inside of
> drm_do_probe_ddc_edid() would normally catch this case and try the
> transaction again, resulting in success.
> 
> That, however, was thwarted by the fix for [1]:
> 
> commit 9292f37e1f5c79400254dca46f83313488093825
> Author: Eugeni Dodonov <eugeni.dodonov@intel.com>
> Date:   Thu Jan 5 09:34:28 2012 -0200
> 
>     drm: give up on edid retries when i2c bus is not responding
> 
> This added code to exit immediately if the return code from the
> i2c_transfer function was -ENXIO in order to reduce the amount of time
> spent in waiting for unresponsive or disconnected devices. That was
> possible because the underlying i2c bit banging algorithm had retries of
> its own (which, of course, were part of the reason for the bug the
> commit fixes).
> 
> Since its introduction in
> 
> commit f899fc64cda8569d0529452aafc0da31c042df2e
> Author: Chris Wilson <chris@chris-wilson.co.uk>
> Date:   Tue Jul 20 15:44:45 2010 -0700
> 
>     drm/i915: use GMBUS to manage i2c links
> 
> we've been flipping back and forth enabling the GMBUS transfers, but
> we've settled since then. The GMBUS implementation does not do any
> retries, however, bailing out of the drm_do_probe_ddc_edid() retry loop
> on first encounter of -ENXIO. This, combined with Eugeni's commit, broke
> the retry on -ENXIO.
> 
> Retry GMBUS once on -ENXIO to mitigate the issues with passive adapters.
> 
> This patch is based on the work, and commit message, by Todd Previte
> <tprevite@gmail.com>.
> 
> [1] https://bugs.freedesktop.org/show_bug.cgi?id=41059
> 
> v2: Don't retry if using bit banging.
> 
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85924
> Cc: Todd Previte <tprevite@gmail.com>
> Cc: stable@vger.kernel.org
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_i2c.c | 25 ++++++++++++++++++++++---
>  1 file changed, 22 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
> index 92072f56e418..c3f72b509d1f 100644
> --- a/drivers/gpu/drm/i915/intel_i2c.c
> +++ b/drivers/gpu/drm/i915/intel_i2c.c
> @@ -478,9 +478,7 @@ gmbus_xfer_index_read(struct drm_i915_private *dev_priv, struct i2c_msg *msgs)
>  }
>  
>  static int
> -gmbus_xfer(struct i2c_adapter *adapter,
> -	   struct i2c_msg *msgs,
> -	   int num)
> +do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
>  {
>  	struct intel_gmbus *bus = container_of(adapter,
>  					       struct intel_gmbus,
> @@ -593,6 +591,27 @@ out:
>  	return ret;
>  }
>  
> +static int
> +gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
> +{
> +	struct intel_gmbus *bus = container_of(adapter, struct intel_gmbus,
> +					       adapter);
> +	int ret;
> +
> +	ret = do_gmbus_xfer(adapter, msgs, num);
> +
> +	/*
> +	 * Passive adapters sometimes NAK the first probe. Retry once on -ENXIO
> +	 * for GMBUS transfers; the bit banging algorithm has retries
> +	 * internally. See also the retry loop in drm_do_probe_ddc_edid, which
> +	 * bails out on the first -ENXIO.
> +	 */
> +	if (ret == -ENXIO && !bus->force_bit)
> +		ret = do_gmbus_xfer(adapter, msgs, num);

i2c-algo-bit does the retry for each msg when sending the address. This
on the other hand will redo the entire transfer. So if we get a nak but
not on the first message we end up repeating the succesful part of the
transfer twice.

To match i2c-algo-bit we'd need to do the retry for each individual
message. I suppose that would make the error handling more
complicated as we'd supposedly still need to clear the error, but
then repeat the same msg without generating a STOP in between.

> +
> +	return ret;
> +}
> +
>  static u32 gmbus_func(struct i2c_adapter *adapter)
>  {
>  	return i2c_bit_algo.functionality(adapter) &
> -- 
> 2.1.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrj�l�
Intel OTC

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Intel-gfx] [PATCH v2] drm/i915: Fix DDC probe for passive adapters
@ 2015-05-28 10:48     ` Ville Syrjälä
  0 siblings, 0 replies; 30+ messages in thread
From: Ville Syrjälä @ 2015-05-28 10:48 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, stable

On Thu, May 28, 2015 at 01:05:39PM +0300, Jani Nikula wrote:
> Passive DP->DVI/HDMI dongles on DP++ ports show up to the system as HDMI
> devices, as they do not have a sink device in them to respond to any AUX
> traffic. When probing these dongles over the DDC, sometimes they will
> NAK the first attempt even though the transaction is valid and they
> support the DDC protocol. The retry loop inside of
> drm_do_probe_ddc_edid() would normally catch this case and try the
> transaction again, resulting in success.
> 
> That, however, was thwarted by the fix for [1]:
> 
> commit 9292f37e1f5c79400254dca46f83313488093825
> Author: Eugeni Dodonov <eugeni.dodonov@intel.com>
> Date:   Thu Jan 5 09:34:28 2012 -0200
> 
>     drm: give up on edid retries when i2c bus is not responding
> 
> This added code to exit immediately if the return code from the
> i2c_transfer function was -ENXIO in order to reduce the amount of time
> spent in waiting for unresponsive or disconnected devices. That was
> possible because the underlying i2c bit banging algorithm had retries of
> its own (which, of course, were part of the reason for the bug the
> commit fixes).
> 
> Since its introduction in
> 
> commit f899fc64cda8569d0529452aafc0da31c042df2e
> Author: Chris Wilson <chris@chris-wilson.co.uk>
> Date:   Tue Jul 20 15:44:45 2010 -0700
> 
>     drm/i915: use GMBUS to manage i2c links
> 
> we've been flipping back and forth enabling the GMBUS transfers, but
> we've settled since then. The GMBUS implementation does not do any
> retries, however, bailing out of the drm_do_probe_ddc_edid() retry loop
> on first encounter of -ENXIO. This, combined with Eugeni's commit, broke
> the retry on -ENXIO.
> 
> Retry GMBUS once on -ENXIO to mitigate the issues with passive adapters.
> 
> This patch is based on the work, and commit message, by Todd Previte
> <tprevite@gmail.com>.
> 
> [1] https://bugs.freedesktop.org/show_bug.cgi?id=41059
> 
> v2: Don't retry if using bit banging.
> 
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85924
> Cc: Todd Previte <tprevite@gmail.com>
> Cc: stable@vger.kernel.org
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_i2c.c | 25 ++++++++++++++++++++++---
>  1 file changed, 22 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
> index 92072f56e418..c3f72b509d1f 100644
> --- a/drivers/gpu/drm/i915/intel_i2c.c
> +++ b/drivers/gpu/drm/i915/intel_i2c.c
> @@ -478,9 +478,7 @@ gmbus_xfer_index_read(struct drm_i915_private *dev_priv, struct i2c_msg *msgs)
>  }
>  
>  static int
> -gmbus_xfer(struct i2c_adapter *adapter,
> -	   struct i2c_msg *msgs,
> -	   int num)
> +do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
>  {
>  	struct intel_gmbus *bus = container_of(adapter,
>  					       struct intel_gmbus,
> @@ -593,6 +591,27 @@ out:
>  	return ret;
>  }
>  
> +static int
> +gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
> +{
> +	struct intel_gmbus *bus = container_of(adapter, struct intel_gmbus,
> +					       adapter);
> +	int ret;
> +
> +	ret = do_gmbus_xfer(adapter, msgs, num);
> +
> +	/*
> +	 * Passive adapters sometimes NAK the first probe. Retry once on -ENXIO
> +	 * for GMBUS transfers; the bit banging algorithm has retries
> +	 * internally. See also the retry loop in drm_do_probe_ddc_edid, which
> +	 * bails out on the first -ENXIO.
> +	 */
> +	if (ret == -ENXIO && !bus->force_bit)
> +		ret = do_gmbus_xfer(adapter, msgs, num);

i2c-algo-bit does the retry for each msg when sending the address. This
on the other hand will redo the entire transfer. So if we get a nak but
not on the first message we end up repeating the succesful part of the
transfer twice.

To match i2c-algo-bit we'd need to do the retry for each individual
message. I suppose that would make the error handling more
complicated as we'd supposedly still need to clear the error, but
then repeat the same msg without generating a STOP in between.

> +
> +	return ret;
> +}
> +
>  static u32 gmbus_func(struct i2c_adapter *adapter)
>  {
>  	return i2c_bit_algo.functionality(adapter) &
> -- 
> 2.1.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Intel-gfx] [PATCH v2] drm/i915: Fix DDC probe for passive adapters
  2015-05-28 10:48     ` Ville Syrjälä
  (?)
@ 2015-05-28 11:36     ` Jani Nikula
  2015-05-28 12:26         ` Ville Syrjälä
  2015-05-28 12:28         ` Daniel Vetter
  -1 siblings, 2 replies; 30+ messages in thread
From: Jani Nikula @ 2015-05-28 11:36 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, stable

On Thu, 28 May 2015, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> On Thu, May 28, 2015 at 01:05:39PM +0300, Jani Nikula wrote:
>> Passive DP->DVI/HDMI dongles on DP++ ports show up to the system as HDMI
>> devices, as they do not have a sink device in them to respond to any AUX
>> traffic. When probing these dongles over the DDC, sometimes they will
>> NAK the first attempt even though the transaction is valid and they
>> support the DDC protocol. The retry loop inside of
>> drm_do_probe_ddc_edid() would normally catch this case and try the
>> transaction again, resulting in success.
>> 
>> That, however, was thwarted by the fix for [1]:
>> 
>> commit 9292f37e1f5c79400254dca46f83313488093825
>> Author: Eugeni Dodonov <eugeni.dodonov@intel.com>
>> Date:   Thu Jan 5 09:34:28 2012 -0200
>> 
>>     drm: give up on edid retries when i2c bus is not responding
>> 
>> This added code to exit immediately if the return code from the
>> i2c_transfer function was -ENXIO in order to reduce the amount of time
>> spent in waiting for unresponsive or disconnected devices. That was
>> possible because the underlying i2c bit banging algorithm had retries of
>> its own (which, of course, were part of the reason for the bug the
>> commit fixes).
>> 
>> Since its introduction in
>> 
>> commit f899fc64cda8569d0529452aafc0da31c042df2e
>> Author: Chris Wilson <chris@chris-wilson.co.uk>
>> Date:   Tue Jul 20 15:44:45 2010 -0700
>> 
>>     drm/i915: use GMBUS to manage i2c links
>> 
>> we've been flipping back and forth enabling the GMBUS transfers, but
>> we've settled since then. The GMBUS implementation does not do any
>> retries, however, bailing out of the drm_do_probe_ddc_edid() retry loop
>> on first encounter of -ENXIO. This, combined with Eugeni's commit, broke
>> the retry on -ENXIO.
>> 
>> Retry GMBUS once on -ENXIO to mitigate the issues with passive adapters.
>> 
>> This patch is based on the work, and commit message, by Todd Previte
>> <tprevite@gmail.com>.
>> 
>> [1] https://bugs.freedesktop.org/show_bug.cgi?id=41059
>> 
>> v2: Don't retry if using bit banging.
>> 
>> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85924
>> Cc: Todd Previte <tprevite@gmail.com>
>> Cc: stable@vger.kernel.org
>> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
>> ---
>>  drivers/gpu/drm/i915/intel_i2c.c | 25 ++++++++++++++++++++++---
>>  1 file changed, 22 insertions(+), 3 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
>> index 92072f56e418..c3f72b509d1f 100644
>> --- a/drivers/gpu/drm/i915/intel_i2c.c
>> +++ b/drivers/gpu/drm/i915/intel_i2c.c
>> @@ -478,9 +478,7 @@ gmbus_xfer_index_read(struct drm_i915_private *dev_priv, struct i2c_msg *msgs)
>>  }
>>  
>>  static int
>> -gmbus_xfer(struct i2c_adapter *adapter,
>> -	   struct i2c_msg *msgs,
>> -	   int num)
>> +do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
>>  {
>>  	struct intel_gmbus *bus = container_of(adapter,
>>  					       struct intel_gmbus,
>> @@ -593,6 +591,27 @@ out:
>>  	return ret;
>>  }
>>  
>> +static int
>> +gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
>> +{
>> +	struct intel_gmbus *bus = container_of(adapter, struct intel_gmbus,
>> +					       adapter);
>> +	int ret;
>> +
>> +	ret = do_gmbus_xfer(adapter, msgs, num);
>> +
>> +	/*
>> +	 * Passive adapters sometimes NAK the first probe. Retry once on -ENXIO
>> +	 * for GMBUS transfers; the bit banging algorithm has retries
>> +	 * internally. See also the retry loop in drm_do_probe_ddc_edid, which
>> +	 * bails out on the first -ENXIO.
>> +	 */
>> +	if (ret == -ENXIO && !bus->force_bit)
>> +		ret = do_gmbus_xfer(adapter, msgs, num);
>
> i2c-algo-bit does the retry for each msg when sending the address. This
> on the other hand will redo the entire transfer. So if we get a nak but
> not on the first message we end up repeating the succesful part of the
> transfer twice.

Which is also the case for the retry loop in drm_do_probe_ddc_edid for
errors other than -ENXIO.

How likely do you think it is to *not* get -ENXIO at first, but get it
in a later message?

> To match i2c-algo-bit we'd need to do the retry for each individual
> message. I suppose that would make the error handling more
> complicated as we'd supposedly still need to clear the error, but
> then repeat the same msg without generating a STOP in between.

Looking at the code, and i2c-algo-bit.c, I'm not sure if I'd be
comfortable backporting something like that to stable. It does get
complicated. So sure, this is an attempt to pick the low hanging fruit.

Do you think this makes the driver worse?

I plead item (c) of the Reviewer's statement of oversight. ;)


BR,
Jani.



>
>> +
>> +	return ret;
>> +}
>> +
>>  static u32 gmbus_func(struct i2c_adapter *adapter)
>>  {
>>  	return i2c_bit_algo.functionality(adapter) &
>> -- 
>> 2.1.4
>> 
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
> -- 
> Ville Syrjälä
> Intel OTC

-- 
Jani Nikula, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Intel-gfx] [PATCH v2] drm/i915: Fix DDC probe for passive adapters
  2015-05-28 11:36     ` Jani Nikula
@ 2015-05-28 12:26         ` Ville Syrjälä
  2015-05-28 12:28         ` Daniel Vetter
  1 sibling, 0 replies; 30+ messages in thread
From: Ville Syrjälä @ 2015-05-28 12:26 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, stable

On Thu, May 28, 2015 at 02:36:01PM +0300, Jani Nikula wrote:
> On Thu, 28 May 2015, Ville Syrj�l� <ville.syrjala@linux.intel.com> wrote:
> > On Thu, May 28, 2015 at 01:05:39PM +0300, Jani Nikula wrote:
> >> Passive DP->DVI/HDMI dongles on DP++ ports show up to the system as HDMI
> >> devices, as they do not have a sink device in them to respond to any AUX
> >> traffic. When probing these dongles over the DDC, sometimes they will
> >> NAK the first attempt even though the transaction is valid and they
> >> support the DDC protocol. The retry loop inside of
> >> drm_do_probe_ddc_edid() would normally catch this case and try the
> >> transaction again, resulting in success.
> >> 
> >> That, however, was thwarted by the fix for [1]:
> >> 
> >> commit 9292f37e1f5c79400254dca46f83313488093825
> >> Author: Eugeni Dodonov <eugeni.dodonov@intel.com>
> >> Date:   Thu Jan 5 09:34:28 2012 -0200
> >> 
> >>     drm: give up on edid retries when i2c bus is not responding
> >> 
> >> This added code to exit immediately if the return code from the
> >> i2c_transfer function was -ENXIO in order to reduce the amount of time
> >> spent in waiting for unresponsive or disconnected devices. That was
> >> possible because the underlying i2c bit banging algorithm had retries of
> >> its own (which, of course, were part of the reason for the bug the
> >> commit fixes).
> >> 
> >> Since its introduction in
> >> 
> >> commit f899fc64cda8569d0529452aafc0da31c042df2e
> >> Author: Chris Wilson <chris@chris-wilson.co.uk>
> >> Date:   Tue Jul 20 15:44:45 2010 -0700
> >> 
> >>     drm/i915: use GMBUS to manage i2c links
> >> 
> >> we've been flipping back and forth enabling the GMBUS transfers, but
> >> we've settled since then. The GMBUS implementation does not do any
> >> retries, however, bailing out of the drm_do_probe_ddc_edid() retry loop
> >> on first encounter of -ENXIO. This, combined with Eugeni's commit, broke
> >> the retry on -ENXIO.
> >> 
> >> Retry GMBUS once on -ENXIO to mitigate the issues with passive adapters.
> >> 
> >> This patch is based on the work, and commit message, by Todd Previte
> >> <tprevite@gmail.com>.
> >> 
> >> [1] https://bugs.freedesktop.org/show_bug.cgi?id=41059
> >> 
> >> v2: Don't retry if using bit banging.
> >> 
> >> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85924
> >> Cc: Todd Previte <tprevite@gmail.com>
> >> Cc: stable@vger.kernel.org
> >> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> >> ---
> >>  drivers/gpu/drm/i915/intel_i2c.c | 25 ++++++++++++++++++++++---
> >>  1 file changed, 22 insertions(+), 3 deletions(-)
> >> 
> >> diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
> >> index 92072f56e418..c3f72b509d1f 100644
> >> --- a/drivers/gpu/drm/i915/intel_i2c.c
> >> +++ b/drivers/gpu/drm/i915/intel_i2c.c
> >> @@ -478,9 +478,7 @@ gmbus_xfer_index_read(struct drm_i915_private *dev_priv, struct i2c_msg *msgs)
> >>  }
> >>  
> >>  static int
> >> -gmbus_xfer(struct i2c_adapter *adapter,
> >> -	   struct i2c_msg *msgs,
> >> -	   int num)
> >> +do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
> >>  {
> >>  	struct intel_gmbus *bus = container_of(adapter,
> >>  					       struct intel_gmbus,
> >> @@ -593,6 +591,27 @@ out:
> >>  	return ret;
> >>  }
> >>  
> >> +static int
> >> +gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
> >> +{
> >> +	struct intel_gmbus *bus = container_of(adapter, struct intel_gmbus,
> >> +					       adapter);
> >> +	int ret;
> >> +
> >> +	ret = do_gmbus_xfer(adapter, msgs, num);
> >> +
> >> +	/*
> >> +	 * Passive adapters sometimes NAK the first probe. Retry once on -ENXIO
> >> +	 * for GMBUS transfers; the bit banging algorithm has retries
> >> +	 * internally. See also the retry loop in drm_do_probe_ddc_edid, which
> >> +	 * bails out on the first -ENXIO.
> >> +	 */
> >> +	if (ret == -ENXIO && !bus->force_bit)
> >> +		ret = do_gmbus_xfer(adapter, msgs, num);
> >
> > i2c-algo-bit does the retry for each msg when sending the address. This
> > on the other hand will redo the entire transfer. So if we get a nak but
> > not on the first message we end up repeating the succesful part of the
> > transfer twice.
> 
> Which is also the case for the retry loop in drm_do_probe_ddc_edid for
> errors other than -ENXIO.
> 
> How likely do you think it is to *not* get -ENXIO at first, but get it
> in a later message?

I suppose for our normal use cases it should be unlikely.

> 
> > To match i2c-algo-bit we'd need to do the retry for each individual
> > message. I suppose that would make the error handling more
> > complicated as we'd supposedly still need to clear the error, but
> > then repeat the same msg without generating a STOP in between.
> 
> Looking at the code, and i2c-algo-bit.c, I'm not sure if I'd be
> comfortable backporting something like that to stable. It does get
> complicated. So sure, this is an attempt to pick the low hanging fruit.
> 
> Do you think this makes the driver worse?
> 
> I plead item (c) of the Reviewer's statement of oversight. ;)

I suppose the simple thing is good enough at least for now.

In fact, after another look I'm also not sure i2c-algo-bit is
entirely sane as it'll do a stop+start when retrying the address.
If it was originally meant to be a repeated start things might go
badly. Eg. for EDID read if it would for some reason ACK the
segment address, but then temporarily NAK one of the later
addresses, the segment address would get reset to 0 when the
STOP is issued. So we'd end up accessing the wrong segment
in the end. So retrying the full thing may be actually more
correct. I suppose if someone is going to do further work on
this i2c-algo-bit might need to be changed to reissue repeated
starts when it already issued one instead of doing the
stop+start unconditionally.

I also noticed that bus->force_bit locking is a bit lax in places
(in pre-existing code already). Something to look at later perhaps.

Anyway the patch seems sane enough so
Reviewed-by: Ville Syrj�l� <ville.syrjala@linux.intel.com>

-- 
Ville Syrj�l�
Intel OTC

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Intel-gfx] [PATCH v2] drm/i915: Fix DDC probe for passive adapters
@ 2015-05-28 12:26         ` Ville Syrjälä
  0 siblings, 0 replies; 30+ messages in thread
From: Ville Syrjälä @ 2015-05-28 12:26 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, stable

On Thu, May 28, 2015 at 02:36:01PM +0300, Jani Nikula wrote:
> On Thu, 28 May 2015, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> > On Thu, May 28, 2015 at 01:05:39PM +0300, Jani Nikula wrote:
> >> Passive DP->DVI/HDMI dongles on DP++ ports show up to the system as HDMI
> >> devices, as they do not have a sink device in them to respond to any AUX
> >> traffic. When probing these dongles over the DDC, sometimes they will
> >> NAK the first attempt even though the transaction is valid and they
> >> support the DDC protocol. The retry loop inside of
> >> drm_do_probe_ddc_edid() would normally catch this case and try the
> >> transaction again, resulting in success.
> >> 
> >> That, however, was thwarted by the fix for [1]:
> >> 
> >> commit 9292f37e1f5c79400254dca46f83313488093825
> >> Author: Eugeni Dodonov <eugeni.dodonov@intel.com>
> >> Date:   Thu Jan 5 09:34:28 2012 -0200
> >> 
> >>     drm: give up on edid retries when i2c bus is not responding
> >> 
> >> This added code to exit immediately if the return code from the
> >> i2c_transfer function was -ENXIO in order to reduce the amount of time
> >> spent in waiting for unresponsive or disconnected devices. That was
> >> possible because the underlying i2c bit banging algorithm had retries of
> >> its own (which, of course, were part of the reason for the bug the
> >> commit fixes).
> >> 
> >> Since its introduction in
> >> 
> >> commit f899fc64cda8569d0529452aafc0da31c042df2e
> >> Author: Chris Wilson <chris@chris-wilson.co.uk>
> >> Date:   Tue Jul 20 15:44:45 2010 -0700
> >> 
> >>     drm/i915: use GMBUS to manage i2c links
> >> 
> >> we've been flipping back and forth enabling the GMBUS transfers, but
> >> we've settled since then. The GMBUS implementation does not do any
> >> retries, however, bailing out of the drm_do_probe_ddc_edid() retry loop
> >> on first encounter of -ENXIO. This, combined with Eugeni's commit, broke
> >> the retry on -ENXIO.
> >> 
> >> Retry GMBUS once on -ENXIO to mitigate the issues with passive adapters.
> >> 
> >> This patch is based on the work, and commit message, by Todd Previte
> >> <tprevite@gmail.com>.
> >> 
> >> [1] https://bugs.freedesktop.org/show_bug.cgi?id=41059
> >> 
> >> v2: Don't retry if using bit banging.
> >> 
> >> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85924
> >> Cc: Todd Previte <tprevite@gmail.com>
> >> Cc: stable@vger.kernel.org
> >> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> >> ---
> >>  drivers/gpu/drm/i915/intel_i2c.c | 25 ++++++++++++++++++++++---
> >>  1 file changed, 22 insertions(+), 3 deletions(-)
> >> 
> >> diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
> >> index 92072f56e418..c3f72b509d1f 100644
> >> --- a/drivers/gpu/drm/i915/intel_i2c.c
> >> +++ b/drivers/gpu/drm/i915/intel_i2c.c
> >> @@ -478,9 +478,7 @@ gmbus_xfer_index_read(struct drm_i915_private *dev_priv, struct i2c_msg *msgs)
> >>  }
> >>  
> >>  static int
> >> -gmbus_xfer(struct i2c_adapter *adapter,
> >> -	   struct i2c_msg *msgs,
> >> -	   int num)
> >> +do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
> >>  {
> >>  	struct intel_gmbus *bus = container_of(adapter,
> >>  					       struct intel_gmbus,
> >> @@ -593,6 +591,27 @@ out:
> >>  	return ret;
> >>  }
> >>  
> >> +static int
> >> +gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
> >> +{
> >> +	struct intel_gmbus *bus = container_of(adapter, struct intel_gmbus,
> >> +					       adapter);
> >> +	int ret;
> >> +
> >> +	ret = do_gmbus_xfer(adapter, msgs, num);
> >> +
> >> +	/*
> >> +	 * Passive adapters sometimes NAK the first probe. Retry once on -ENXIO
> >> +	 * for GMBUS transfers; the bit banging algorithm has retries
> >> +	 * internally. See also the retry loop in drm_do_probe_ddc_edid, which
> >> +	 * bails out on the first -ENXIO.
> >> +	 */
> >> +	if (ret == -ENXIO && !bus->force_bit)
> >> +		ret = do_gmbus_xfer(adapter, msgs, num);
> >
> > i2c-algo-bit does the retry for each msg when sending the address. This
> > on the other hand will redo the entire transfer. So if we get a nak but
> > not on the first message we end up repeating the succesful part of the
> > transfer twice.
> 
> Which is also the case for the retry loop in drm_do_probe_ddc_edid for
> errors other than -ENXIO.
> 
> How likely do you think it is to *not* get -ENXIO at first, but get it
> in a later message?

I suppose for our normal use cases it should be unlikely.

> 
> > To match i2c-algo-bit we'd need to do the retry for each individual
> > message. I suppose that would make the error handling more
> > complicated as we'd supposedly still need to clear the error, but
> > then repeat the same msg without generating a STOP in between.
> 
> Looking at the code, and i2c-algo-bit.c, I'm not sure if I'd be
> comfortable backporting something like that to stable. It does get
> complicated. So sure, this is an attempt to pick the low hanging fruit.
> 
> Do you think this makes the driver worse?
> 
> I plead item (c) of the Reviewer's statement of oversight. ;)

I suppose the simple thing is good enough at least for now.

In fact, after another look I'm also not sure i2c-algo-bit is
entirely sane as it'll do a stop+start when retrying the address.
If it was originally meant to be a repeated start things might go
badly. Eg. for EDID read if it would for some reason ACK the
segment address, but then temporarily NAK one of the later
addresses, the segment address would get reset to 0 when the
STOP is issued. So we'd end up accessing the wrong segment
in the end. So retrying the full thing may be actually more
correct. I suppose if someone is going to do further work on
this i2c-algo-bit might need to be changed to reissue repeated
starts when it already issued one instead of doing the
stop+start unconditionally.

I also noticed that bus->force_bit locking is a bit lax in places
(in pre-existing code already). Something to look at later perhaps.

Anyway the patch seems sane enough so
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

-- 
Ville Syrjälä
Intel OTC

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Intel-gfx] [PATCH v2] drm/i915: Fix DDC probe for passive adapters
  2015-05-28 11:36     ` Jani Nikula
@ 2015-05-28 12:28         ` Daniel Vetter
  2015-05-28 12:28         ` Daniel Vetter
  1 sibling, 0 replies; 30+ messages in thread
From: Daniel Vetter @ 2015-05-28 12:28 UTC (permalink / raw)
  To: Jani Nikula; +Cc: Ville Syrjälä, intel-gfx, stable

On Thu, May 28, 2015 at 02:36:01PM +0300, Jani Nikula wrote:
> On Thu, 28 May 2015, Ville Syrj�l� <ville.syrjala@linux.intel.com> wrote:
> > On Thu, May 28, 2015 at 01:05:39PM +0300, Jani Nikula wrote:
> >> Passive DP->DVI/HDMI dongles on DP++ ports show up to the system as HDMI
> >> devices, as they do not have a sink device in them to respond to any AUX
> >> traffic. When probing these dongles over the DDC, sometimes they will
> >> NAK the first attempt even though the transaction is valid and they
> >> support the DDC protocol. The retry loop inside of
> >> drm_do_probe_ddc_edid() would normally catch this case and try the
> >> transaction again, resulting in success.
> >> 
> >> That, however, was thwarted by the fix for [1]:
> >> 
> >> commit 9292f37e1f5c79400254dca46f83313488093825
> >> Author: Eugeni Dodonov <eugeni.dodonov@intel.com>
> >> Date:   Thu Jan 5 09:34:28 2012 -0200
> >> 
> >>     drm: give up on edid retries when i2c bus is not responding
> >> 
> >> This added code to exit immediately if the return code from the
> >> i2c_transfer function was -ENXIO in order to reduce the amount of time
> >> spent in waiting for unresponsive or disconnected devices. That was
> >> possible because the underlying i2c bit banging algorithm had retries of
> >> its own (which, of course, were part of the reason for the bug the
> >> commit fixes).
> >> 
> >> Since its introduction in
> >> 
> >> commit f899fc64cda8569d0529452aafc0da31c042df2e
> >> Author: Chris Wilson <chris@chris-wilson.co.uk>
> >> Date:   Tue Jul 20 15:44:45 2010 -0700
> >> 
> >>     drm/i915: use GMBUS to manage i2c links
> >> 
> >> we've been flipping back and forth enabling the GMBUS transfers, but
> >> we've settled since then. The GMBUS implementation does not do any
> >> retries, however, bailing out of the drm_do_probe_ddc_edid() retry loop
> >> on first encounter of -ENXIO. This, combined with Eugeni's commit, broke
> >> the retry on -ENXIO.
> >> 
> >> Retry GMBUS once on -ENXIO to mitigate the issues with passive adapters.
> >> 
> >> This patch is based on the work, and commit message, by Todd Previte
> >> <tprevite@gmail.com>.
> >> 
> >> [1] https://bugs.freedesktop.org/show_bug.cgi?id=41059
> >> 
> >> v2: Don't retry if using bit banging.
> >> 
> >> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85924
> >> Cc: Todd Previte <tprevite@gmail.com>
> >> Cc: stable@vger.kernel.org
> >> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> >> ---
> >>  drivers/gpu/drm/i915/intel_i2c.c | 25 ++++++++++++++++++++++---
> >>  1 file changed, 22 insertions(+), 3 deletions(-)
> >> 
> >> diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
> >> index 92072f56e418..c3f72b509d1f 100644
> >> --- a/drivers/gpu/drm/i915/intel_i2c.c
> >> +++ b/drivers/gpu/drm/i915/intel_i2c.c
> >> @@ -478,9 +478,7 @@ gmbus_xfer_index_read(struct drm_i915_private *dev_priv, struct i2c_msg *msgs)
> >>  }
> >>  
> >>  static int
> >> -gmbus_xfer(struct i2c_adapter *adapter,
> >> -	   struct i2c_msg *msgs,
> >> -	   int num)
> >> +do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
> >>  {
> >>  	struct intel_gmbus *bus = container_of(adapter,
> >>  					       struct intel_gmbus,
> >> @@ -593,6 +591,27 @@ out:
> >>  	return ret;
> >>  }
> >>  
> >> +static int
> >> +gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
> >> +{
> >> +	struct intel_gmbus *bus = container_of(adapter, struct intel_gmbus,
> >> +					       adapter);
> >> +	int ret;
> >> +
> >> +	ret = do_gmbus_xfer(adapter, msgs, num);
> >> +
> >> +	/*
> >> +	 * Passive adapters sometimes NAK the first probe. Retry once on -ENXIO
> >> +	 * for GMBUS transfers; the bit banging algorithm has retries
> >> +	 * internally. See also the retry loop in drm_do_probe_ddc_edid, which
> >> +	 * bails out on the first -ENXIO.
> >> +	 */
> >> +	if (ret == -ENXIO && !bus->force_bit)
> >> +		ret = do_gmbus_xfer(adapter, msgs, num);
> >
> > i2c-algo-bit does the retry for each msg when sending the address. This
> > on the other hand will redo the entire transfer. So if we get a nak but
> > not on the first message we end up repeating the succesful part of the
> > transfer twice.
> 
> Which is also the case for the retry loop in drm_do_probe_ddc_edid for
> errors other than -ENXIO.
> 
> How likely do you think it is to *not* get -ENXIO at first, but get it
> in a later message?
> 
> > To match i2c-algo-bit we'd need to do the retry for each individual
> > message. I suppose that would make the error handling more
> > complicated as we'd supposedly still need to clear the error, but
> > then repeat the same msg without generating a STOP in between.
> 
> Looking at the code, and i2c-algo-bit.c, I'm not sure if I'd be
> comfortable backporting something like that to stable. It does get
> complicated. So sure, this is an attempt to pick the low hanging fruit.
> 
> Do you think this makes the driver worse?
> 
> I plead item (c) of the Reviewer's statement of oversight. ;)

Doesn't look too complicated tdrt here:

diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index 92072f56e418..ae9f4be1b644 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -486,7 +486,7 @@ gmbus_xfer(struct i2c_adapter *adapter,
 					       struct intel_gmbus,
 					       adapter);
 	struct drm_i915_private *dev_priv = bus->dev_priv;
-	int i, reg_offset;
+	int i = 0, reg_offset;
 	int ret = 0;
 
 	intel_aux_display_runtime_get(dev_priv);
@@ -499,9 +499,10 @@ gmbus_xfer(struct i2c_adapter *adapter,
 
 	reg_offset = dev_priv->gpio_mmio_base;
 
+retry:
 	I915_WRITE(GMBUS0 + reg_offset, bus->reg0);
 
-	for (i = 0; i < num; i++) {
+	for (i; i < num; i++) {
 		if (gmbus_is_index_read(msgs, i, num)) {
 			ret = gmbus_xfer_index_read(dev_priv, &msgs[i]);
 			i += 1;  /* set i to the index of the read xfer */
@@ -576,6 +577,9 @@ clear_err:
 			 adapter->name, msgs[i].addr,
 			 (msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len);
 
+	if (bla)
+		goto retry;
+
 	goto out;
 
 timeout:

---
Totally untested ofc ;-)

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

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [Intel-gfx] [PATCH v2] drm/i915: Fix DDC probe for passive adapters
@ 2015-05-28 12:28         ` Daniel Vetter
  0 siblings, 0 replies; 30+ messages in thread
From: Daniel Vetter @ 2015-05-28 12:28 UTC (permalink / raw)
  To: Jani Nikula; +Cc: Ville Syrjälä, intel-gfx, stable

On Thu, May 28, 2015 at 02:36:01PM +0300, Jani Nikula wrote:
> On Thu, 28 May 2015, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> > On Thu, May 28, 2015 at 01:05:39PM +0300, Jani Nikula wrote:
> >> Passive DP->DVI/HDMI dongles on DP++ ports show up to the system as HDMI
> >> devices, as they do not have a sink device in them to respond to any AUX
> >> traffic. When probing these dongles over the DDC, sometimes they will
> >> NAK the first attempt even though the transaction is valid and they
> >> support the DDC protocol. The retry loop inside of
> >> drm_do_probe_ddc_edid() would normally catch this case and try the
> >> transaction again, resulting in success.
> >> 
> >> That, however, was thwarted by the fix for [1]:
> >> 
> >> commit 9292f37e1f5c79400254dca46f83313488093825
> >> Author: Eugeni Dodonov <eugeni.dodonov@intel.com>
> >> Date:   Thu Jan 5 09:34:28 2012 -0200
> >> 
> >>     drm: give up on edid retries when i2c bus is not responding
> >> 
> >> This added code to exit immediately if the return code from the
> >> i2c_transfer function was -ENXIO in order to reduce the amount of time
> >> spent in waiting for unresponsive or disconnected devices. That was
> >> possible because the underlying i2c bit banging algorithm had retries of
> >> its own (which, of course, were part of the reason for the bug the
> >> commit fixes).
> >> 
> >> Since its introduction in
> >> 
> >> commit f899fc64cda8569d0529452aafc0da31c042df2e
> >> Author: Chris Wilson <chris@chris-wilson.co.uk>
> >> Date:   Tue Jul 20 15:44:45 2010 -0700
> >> 
> >>     drm/i915: use GMBUS to manage i2c links
> >> 
> >> we've been flipping back and forth enabling the GMBUS transfers, but
> >> we've settled since then. The GMBUS implementation does not do any
> >> retries, however, bailing out of the drm_do_probe_ddc_edid() retry loop
> >> on first encounter of -ENXIO. This, combined with Eugeni's commit, broke
> >> the retry on -ENXIO.
> >> 
> >> Retry GMBUS once on -ENXIO to mitigate the issues with passive adapters.
> >> 
> >> This patch is based on the work, and commit message, by Todd Previte
> >> <tprevite@gmail.com>.
> >> 
> >> [1] https://bugs.freedesktop.org/show_bug.cgi?id=41059
> >> 
> >> v2: Don't retry if using bit banging.
> >> 
> >> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85924
> >> Cc: Todd Previte <tprevite@gmail.com>
> >> Cc: stable@vger.kernel.org
> >> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> >> ---
> >>  drivers/gpu/drm/i915/intel_i2c.c | 25 ++++++++++++++++++++++---
> >>  1 file changed, 22 insertions(+), 3 deletions(-)
> >> 
> >> diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
> >> index 92072f56e418..c3f72b509d1f 100644
> >> --- a/drivers/gpu/drm/i915/intel_i2c.c
> >> +++ b/drivers/gpu/drm/i915/intel_i2c.c
> >> @@ -478,9 +478,7 @@ gmbus_xfer_index_read(struct drm_i915_private *dev_priv, struct i2c_msg *msgs)
> >>  }
> >>  
> >>  static int
> >> -gmbus_xfer(struct i2c_adapter *adapter,
> >> -	   struct i2c_msg *msgs,
> >> -	   int num)
> >> +do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
> >>  {
> >>  	struct intel_gmbus *bus = container_of(adapter,
> >>  					       struct intel_gmbus,
> >> @@ -593,6 +591,27 @@ out:
> >>  	return ret;
> >>  }
> >>  
> >> +static int
> >> +gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
> >> +{
> >> +	struct intel_gmbus *bus = container_of(adapter, struct intel_gmbus,
> >> +					       adapter);
> >> +	int ret;
> >> +
> >> +	ret = do_gmbus_xfer(adapter, msgs, num);
> >> +
> >> +	/*
> >> +	 * Passive adapters sometimes NAK the first probe. Retry once on -ENXIO
> >> +	 * for GMBUS transfers; the bit banging algorithm has retries
> >> +	 * internally. See also the retry loop in drm_do_probe_ddc_edid, which
> >> +	 * bails out on the first -ENXIO.
> >> +	 */
> >> +	if (ret == -ENXIO && !bus->force_bit)
> >> +		ret = do_gmbus_xfer(adapter, msgs, num);
> >
> > i2c-algo-bit does the retry for each msg when sending the address. This
> > on the other hand will redo the entire transfer. So if we get a nak but
> > not on the first message we end up repeating the succesful part of the
> > transfer twice.
> 
> Which is also the case for the retry loop in drm_do_probe_ddc_edid for
> errors other than -ENXIO.
> 
> How likely do you think it is to *not* get -ENXIO at first, but get it
> in a later message?
> 
> > To match i2c-algo-bit we'd need to do the retry for each individual
> > message. I suppose that would make the error handling more
> > complicated as we'd supposedly still need to clear the error, but
> > then repeat the same msg without generating a STOP in between.
> 
> Looking at the code, and i2c-algo-bit.c, I'm not sure if I'd be
> comfortable backporting something like that to stable. It does get
> complicated. So sure, this is an attempt to pick the low hanging fruit.
> 
> Do you think this makes the driver worse?
> 
> I plead item (c) of the Reviewer's statement of oversight. ;)

Doesn't look too complicated tdrt here:

diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index 92072f56e418..ae9f4be1b644 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -486,7 +486,7 @@ gmbus_xfer(struct i2c_adapter *adapter,
 					       struct intel_gmbus,
 					       adapter);
 	struct drm_i915_private *dev_priv = bus->dev_priv;
-	int i, reg_offset;
+	int i = 0, reg_offset;
 	int ret = 0;
 
 	intel_aux_display_runtime_get(dev_priv);
@@ -499,9 +499,10 @@ gmbus_xfer(struct i2c_adapter *adapter,
 
 	reg_offset = dev_priv->gpio_mmio_base;
 
+retry:
 	I915_WRITE(GMBUS0 + reg_offset, bus->reg0);
 
-	for (i = 0; i < num; i++) {
+	for (i; i < num; i++) {
 		if (gmbus_is_index_read(msgs, i, num)) {
 			ret = gmbus_xfer_index_read(dev_priv, &msgs[i]);
 			i += 1;  /* set i to the index of the read xfer */
@@ -576,6 +577,9 @@ clear_err:
 			 adapter->name, msgs[i].addr,
 			 (msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len);
 
+	if (bla)
+		goto retry;
+
 	goto out;
 
 timeout:

---
Totally untested ofc ;-)

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

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [Intel-gfx] [PATCH v2] drm/i915: Fix DDC probe for passive adapters
  2015-05-28 12:28         ` Daniel Vetter
@ 2015-05-28 12:34           ` Jani Nikula
  -1 siblings, 0 replies; 30+ messages in thread
From: Jani Nikula @ 2015-05-28 12:34 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Ville Syrjälä, intel-gfx, stable

On Thu, 28 May 2015, Daniel Vetter <daniel@ffwll.ch> wrote:
> On Thu, May 28, 2015 at 02:36:01PM +0300, Jani Nikula wrote:
>> On Thu, 28 May 2015, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
>> > On Thu, May 28, 2015 at 01:05:39PM +0300, Jani Nikula wrote:
>> >> Passive DP->DVI/HDMI dongles on DP++ ports show up to the system as HDMI
>> >> devices, as they do not have a sink device in them to respond to any AUX
>> >> traffic. When probing these dongles over the DDC, sometimes they will
>> >> NAK the first attempt even though the transaction is valid and they
>> >> support the DDC protocol. The retry loop inside of
>> >> drm_do_probe_ddc_edid() would normally catch this case and try the
>> >> transaction again, resulting in success.
>> >> 
>> >> That, however, was thwarted by the fix for [1]:
>> >> 
>> >> commit 9292f37e1f5c79400254dca46f83313488093825
>> >> Author: Eugeni Dodonov <eugeni.dodonov@intel.com>
>> >> Date:   Thu Jan 5 09:34:28 2012 -0200
>> >> 
>> >>     drm: give up on edid retries when i2c bus is not responding
>> >> 
>> >> This added code to exit immediately if the return code from the
>> >> i2c_transfer function was -ENXIO in order to reduce the amount of time
>> >> spent in waiting for unresponsive or disconnected devices. That was
>> >> possible because the underlying i2c bit banging algorithm had retries of
>> >> its own (which, of course, were part of the reason for the bug the
>> >> commit fixes).
>> >> 
>> >> Since its introduction in
>> >> 
>> >> commit f899fc64cda8569d0529452aafc0da31c042df2e
>> >> Author: Chris Wilson <chris@chris-wilson.co.uk>
>> >> Date:   Tue Jul 20 15:44:45 2010 -0700
>> >> 
>> >>     drm/i915: use GMBUS to manage i2c links
>> >> 
>> >> we've been flipping back and forth enabling the GMBUS transfers, but
>> >> we've settled since then. The GMBUS implementation does not do any
>> >> retries, however, bailing out of the drm_do_probe_ddc_edid() retry loop
>> >> on first encounter of -ENXIO. This, combined with Eugeni's commit, broke
>> >> the retry on -ENXIO.
>> >> 
>> >> Retry GMBUS once on -ENXIO to mitigate the issues with passive adapters.
>> >> 
>> >> This patch is based on the work, and commit message, by Todd Previte
>> >> <tprevite@gmail.com>.
>> >> 
>> >> [1] https://bugs.freedesktop.org/show_bug.cgi?id=41059
>> >> 
>> >> v2: Don't retry if using bit banging.
>> >> 
>> >> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85924
>> >> Cc: Todd Previte <tprevite@gmail.com>
>> >> Cc: stable@vger.kernel.org
>> >> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
>> >> ---
>> >>  drivers/gpu/drm/i915/intel_i2c.c | 25 ++++++++++++++++++++++---
>> >>  1 file changed, 22 insertions(+), 3 deletions(-)
>> >> 
>> >> diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
>> >> index 92072f56e418..c3f72b509d1f 100644
>> >> --- a/drivers/gpu/drm/i915/intel_i2c.c
>> >> +++ b/drivers/gpu/drm/i915/intel_i2c.c
>> >> @@ -478,9 +478,7 @@ gmbus_xfer_index_read(struct drm_i915_private *dev_priv, struct i2c_msg *msgs)
>> >>  }
>> >>  
>> >>  static int
>> >> -gmbus_xfer(struct i2c_adapter *adapter,
>> >> -	   struct i2c_msg *msgs,
>> >> -	   int num)
>> >> +do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
>> >>  {
>> >>  	struct intel_gmbus *bus = container_of(adapter,
>> >>  					       struct intel_gmbus,
>> >> @@ -593,6 +591,27 @@ out:
>> >>  	return ret;
>> >>  }
>> >>  
>> >> +static int
>> >> +gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
>> >> +{
>> >> +	struct intel_gmbus *bus = container_of(adapter, struct intel_gmbus,
>> >> +					       adapter);
>> >> +	int ret;
>> >> +
>> >> +	ret = do_gmbus_xfer(adapter, msgs, num);
>> >> +
>> >> +	/*
>> >> +	 * Passive adapters sometimes NAK the first probe. Retry once on -ENXIO
>> >> +	 * for GMBUS transfers; the bit banging algorithm has retries
>> >> +	 * internally. See also the retry loop in drm_do_probe_ddc_edid, which
>> >> +	 * bails out on the first -ENXIO.
>> >> +	 */
>> >> +	if (ret == -ENXIO && !bus->force_bit)
>> >> +		ret = do_gmbus_xfer(adapter, msgs, num);
>> >
>> > i2c-algo-bit does the retry for each msg when sending the address. This
>> > on the other hand will redo the entire transfer. So if we get a nak but
>> > not on the first message we end up repeating the succesful part of the
>> > transfer twice.
>> 
>> Which is also the case for the retry loop in drm_do_probe_ddc_edid for
>> errors other than -ENXIO.
>> 
>> How likely do you think it is to *not* get -ENXIO at first, but get it
>> in a later message?
>> 
>> > To match i2c-algo-bit we'd need to do the retry for each individual
>> > message. I suppose that would make the error handling more
>> > complicated as we'd supposedly still need to clear the error, but
>> > then repeat the same msg without generating a STOP in between.
>> 
>> Looking at the code, and i2c-algo-bit.c, I'm not sure if I'd be
>> comfortable backporting something like that to stable. It does get
>> complicated. So sure, this is an attempt to pick the low hanging fruit.
>> 
>> Do you think this makes the driver worse?
>> 
>> I plead item (c) of the Reviewer's statement of oversight. ;)
>
> Doesn't look too complicated tdrt here:
>
> diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
> index 92072f56e418..ae9f4be1b644 100644
> --- a/drivers/gpu/drm/i915/intel_i2c.c
> +++ b/drivers/gpu/drm/i915/intel_i2c.c
> @@ -486,7 +486,7 @@ gmbus_xfer(struct i2c_adapter *adapter,
>  					       struct intel_gmbus,
>  					       adapter);
>  	struct drm_i915_private *dev_priv = bus->dev_priv;
> -	int i, reg_offset;
> +	int i = 0, reg_offset;
>  	int ret = 0;
>  
>  	intel_aux_display_runtime_get(dev_priv);
> @@ -499,9 +499,10 @@ gmbus_xfer(struct i2c_adapter *adapter,
>  
>  	reg_offset = dev_priv->gpio_mmio_base;
>  
> +retry:
>  	I915_WRITE(GMBUS0 + reg_offset, bus->reg0);
>  
> -	for (i = 0; i < num; i++) {
> +	for (i; i < num; i++) {
>  		if (gmbus_is_index_read(msgs, i, num)) {
>  			ret = gmbus_xfer_index_read(dev_priv, &msgs[i]);
>  			i += 1;  /* set i to the index of the read xfer */
> @@ -576,6 +577,9 @@ clear_err:
>  			 adapter->name, msgs[i].addr,
>  			 (msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len);
>  
> +	if (bla)
> +		goto retry;

Bla indeed. Already too many gotos in this piece of code to my taste...

> +
>  	goto out;
>  
>  timeout:
>
> ---
> Totally untested ofc ;-)

Hey don't worry, so was mine. But at least mine compiles. ;)

BR,
Jani.



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

-- 
Jani Nikula, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v2] drm/i915: Fix DDC probe for passive adapters
@ 2015-05-28 12:34           ` Jani Nikula
  0 siblings, 0 replies; 30+ messages in thread
From: Jani Nikula @ 2015-05-28 12:34 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx, stable

On Thu, 28 May 2015, Daniel Vetter <daniel@ffwll.ch> wrote:
> On Thu, May 28, 2015 at 02:36:01PM +0300, Jani Nikula wrote:
>> On Thu, 28 May 2015, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
>> > On Thu, May 28, 2015 at 01:05:39PM +0300, Jani Nikula wrote:
>> >> Passive DP->DVI/HDMI dongles on DP++ ports show up to the system as HDMI
>> >> devices, as they do not have a sink device in them to respond to any AUX
>> >> traffic. When probing these dongles over the DDC, sometimes they will
>> >> NAK the first attempt even though the transaction is valid and they
>> >> support the DDC protocol. The retry loop inside of
>> >> drm_do_probe_ddc_edid() would normally catch this case and try the
>> >> transaction again, resulting in success.
>> >> 
>> >> That, however, was thwarted by the fix for [1]:
>> >> 
>> >> commit 9292f37e1f5c79400254dca46f83313488093825
>> >> Author: Eugeni Dodonov <eugeni.dodonov@intel.com>
>> >> Date:   Thu Jan 5 09:34:28 2012 -0200
>> >> 
>> >>     drm: give up on edid retries when i2c bus is not responding
>> >> 
>> >> This added code to exit immediately if the return code from the
>> >> i2c_transfer function was -ENXIO in order to reduce the amount of time
>> >> spent in waiting for unresponsive or disconnected devices. That was
>> >> possible because the underlying i2c bit banging algorithm had retries of
>> >> its own (which, of course, were part of the reason for the bug the
>> >> commit fixes).
>> >> 
>> >> Since its introduction in
>> >> 
>> >> commit f899fc64cda8569d0529452aafc0da31c042df2e
>> >> Author: Chris Wilson <chris@chris-wilson.co.uk>
>> >> Date:   Tue Jul 20 15:44:45 2010 -0700
>> >> 
>> >>     drm/i915: use GMBUS to manage i2c links
>> >> 
>> >> we've been flipping back and forth enabling the GMBUS transfers, but
>> >> we've settled since then. The GMBUS implementation does not do any
>> >> retries, however, bailing out of the drm_do_probe_ddc_edid() retry loop
>> >> on first encounter of -ENXIO. This, combined with Eugeni's commit, broke
>> >> the retry on -ENXIO.
>> >> 
>> >> Retry GMBUS once on -ENXIO to mitigate the issues with passive adapters.
>> >> 
>> >> This patch is based on the work, and commit message, by Todd Previte
>> >> <tprevite@gmail.com>.
>> >> 
>> >> [1] https://bugs.freedesktop.org/show_bug.cgi?id=41059
>> >> 
>> >> v2: Don't retry if using bit banging.
>> >> 
>> >> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85924
>> >> Cc: Todd Previte <tprevite@gmail.com>
>> >> Cc: stable@vger.kernel.org
>> >> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
>> >> ---
>> >>  drivers/gpu/drm/i915/intel_i2c.c | 25 ++++++++++++++++++++++---
>> >>  1 file changed, 22 insertions(+), 3 deletions(-)
>> >> 
>> >> diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
>> >> index 92072f56e418..c3f72b509d1f 100644
>> >> --- a/drivers/gpu/drm/i915/intel_i2c.c
>> >> +++ b/drivers/gpu/drm/i915/intel_i2c.c
>> >> @@ -478,9 +478,7 @@ gmbus_xfer_index_read(struct drm_i915_private *dev_priv, struct i2c_msg *msgs)
>> >>  }
>> >>  
>> >>  static int
>> >> -gmbus_xfer(struct i2c_adapter *adapter,
>> >> -	   struct i2c_msg *msgs,
>> >> -	   int num)
>> >> +do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
>> >>  {
>> >>  	struct intel_gmbus *bus = container_of(adapter,
>> >>  					       struct intel_gmbus,
>> >> @@ -593,6 +591,27 @@ out:
>> >>  	return ret;
>> >>  }
>> >>  
>> >> +static int
>> >> +gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
>> >> +{
>> >> +	struct intel_gmbus *bus = container_of(adapter, struct intel_gmbus,
>> >> +					       adapter);
>> >> +	int ret;
>> >> +
>> >> +	ret = do_gmbus_xfer(adapter, msgs, num);
>> >> +
>> >> +	/*
>> >> +	 * Passive adapters sometimes NAK the first probe. Retry once on -ENXIO
>> >> +	 * for GMBUS transfers; the bit banging algorithm has retries
>> >> +	 * internally. See also the retry loop in drm_do_probe_ddc_edid, which
>> >> +	 * bails out on the first -ENXIO.
>> >> +	 */
>> >> +	if (ret == -ENXIO && !bus->force_bit)
>> >> +		ret = do_gmbus_xfer(adapter, msgs, num);
>> >
>> > i2c-algo-bit does the retry for each msg when sending the address. This
>> > on the other hand will redo the entire transfer. So if we get a nak but
>> > not on the first message we end up repeating the succesful part of the
>> > transfer twice.
>> 
>> Which is also the case for the retry loop in drm_do_probe_ddc_edid for
>> errors other than -ENXIO.
>> 
>> How likely do you think it is to *not* get -ENXIO at first, but get it
>> in a later message?
>> 
>> > To match i2c-algo-bit we'd need to do the retry for each individual
>> > message. I suppose that would make the error handling more
>> > complicated as we'd supposedly still need to clear the error, but
>> > then repeat the same msg without generating a STOP in between.
>> 
>> Looking at the code, and i2c-algo-bit.c, I'm not sure if I'd be
>> comfortable backporting something like that to stable. It does get
>> complicated. So sure, this is an attempt to pick the low hanging fruit.
>> 
>> Do you think this makes the driver worse?
>> 
>> I plead item (c) of the Reviewer's statement of oversight. ;)
>
> Doesn't look too complicated tdrt here:
>
> diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
> index 92072f56e418..ae9f4be1b644 100644
> --- a/drivers/gpu/drm/i915/intel_i2c.c
> +++ b/drivers/gpu/drm/i915/intel_i2c.c
> @@ -486,7 +486,7 @@ gmbus_xfer(struct i2c_adapter *adapter,
>  					       struct intel_gmbus,
>  					       adapter);
>  	struct drm_i915_private *dev_priv = bus->dev_priv;
> -	int i, reg_offset;
> +	int i = 0, reg_offset;
>  	int ret = 0;
>  
>  	intel_aux_display_runtime_get(dev_priv);
> @@ -499,9 +499,10 @@ gmbus_xfer(struct i2c_adapter *adapter,
>  
>  	reg_offset = dev_priv->gpio_mmio_base;
>  
> +retry:
>  	I915_WRITE(GMBUS0 + reg_offset, bus->reg0);
>  
> -	for (i = 0; i < num; i++) {
> +	for (i; i < num; i++) {
>  		if (gmbus_is_index_read(msgs, i, num)) {
>  			ret = gmbus_xfer_index_read(dev_priv, &msgs[i]);
>  			i += 1;  /* set i to the index of the read xfer */
> @@ -576,6 +577,9 @@ clear_err:
>  			 adapter->name, msgs[i].addr,
>  			 (msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len);
>  
> +	if (bla)
> +		goto retry;

Bla indeed. Already too many gotos in this piece of code to my taste...

> +
>  	goto out;
>  
>  timeout:
>
> ---
> Totally untested ofc ;-)

Hey don't worry, so was mine. But at least mine compiles. ;)

BR,
Jani.



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

-- 
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] drm/i915: Fix DDC probe for passive adapters
  2015-05-28  8:51 ` Jani Nikula
  (?)
  (?)
@ 2015-05-31  9:43 ` shuang.he
  -1 siblings, 0 replies; 30+ messages in thread
From: shuang.he @ 2015-05-31  9:43 UTC (permalink / raw)
  To: shuang.he, lei.a.liu, intel-gfx, jani.nikula

Tested-By: Intel Graphics QA PRTS (Patch Regression Test System Contact: shuang.he@intel.com)
Task id: 6490
-------------------------------------Summary-------------------------------------
Platform          Delta          drm-intel-nightly          Series Applied
PNV                                  276/276              276/276
ILK                                  303/303              303/303
SNB                 -1              315/315              314/315
IVB                                  343/343              343/343
BYT                                  287/287              287/287
BDW                 -1              320/320              319/320
-------------------------------------Detailed-------------------------------------
Platform  Test                                drm-intel-nightly          Series Applied
*SNB  igt@pm_rpm@dpms-mode-unset-non-lpsp      PASS(1)      DMESG_WARN(1)
(dmesg patch applied)WARNING:at_drivers/gpu/drm/i915/intel_uncore.c:#assert_device_not_suspended[i915]()@WARNING:.* at .* assert_device_not_suspended+0x
*BDW  igt@gem_flink_race@flink_name      PASS(1)      DMESG_WARN(1)
(dmesg patch applied)WARNING:at_drivers/gpu/drm/i915/intel_display.c:#assert_plane[i915]()@WARNING:.* at .* assert_plane
assertion_failure@assertion failure
WARNING:at_drivers/gpu/drm/drm_irq.c:#drm_wait_one_vblank[drm]()@WARNING:.* at .* drm_wait_one_vblank+0x
Note: You need to pay more attention to line start with '*'
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v2] drm/i915: Fix DDC probe for passive adapters
  2015-05-28 10:05 ` [PATCH v2] " Jani Nikula
  2015-05-28 10:48     ` Ville Syrjälä
@ 2015-05-31 12:03   ` shuang.he
  2015-06-02  8:29   ` [PATCH v3] " Jani Nikula
  2 siblings, 0 replies; 30+ messages in thread
From: shuang.he @ 2015-05-31 12:03 UTC (permalink / raw)
  To: shuang.he, lei.a.liu, intel-gfx, jani.nikula

Tested-By: Intel Graphics QA PRTS (Patch Regression Test System Contact: shuang.he@intel.com)
Task id: 6491
-------------------------------------Summary-------------------------------------
Platform          Delta          drm-intel-nightly          Series Applied
PNV                                  276/276              276/276
ILK                                  303/303              303/303
SNB                 -1              315/315              314/315
IVB                                  343/343              343/343
BYT                                  287/287              287/287
BDW                                  320/320              320/320
-------------------------------------Detailed-------------------------------------
Platform  Test                                drm-intel-nightly          Series Applied
*SNB  igt@pm_rpm@dpms-mode-unset-non-lpsp      PASS(1)      DMESG_WARN(1)
(dmesg patch applied)WARNING:at_drivers/gpu/drm/i915/intel_uncore.c:#assert_device_not_suspended[i915]()@WARNING:.* at .* assert_device_not_suspended+0x
Note: You need to pay more attention to line start with '*'
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH v3] drm/i915: Fix DDC probe for passive adapters
  2015-05-28 10:05 ` [PATCH v2] " Jani Nikula
  2015-05-28 10:48     ` Ville Syrjälä
  2015-05-31 12:03   ` shuang.he
@ 2015-06-02  8:29   ` Jani Nikula
  2015-06-02 10:35       ` Ville Syrjälä
  2015-06-02 13:07     ` [PATCH v3] " shuang.he
  2 siblings, 2 replies; 30+ messages in thread
From: Jani Nikula @ 2015-06-02  8:29 UTC (permalink / raw)
  To: Jani Nikula, intel-gfx; +Cc: stable, tprevite, jim.bride

Passive DP->DVI/HDMI dongles on DP++ ports show up to the system as HDMI
devices, as they do not have a sink device in them to respond to any AUX
traffic. When probing these dongles over the DDC, sometimes they will
NAK the first attempt even though the transaction is valid and they
support the DDC protocol. The retry loop inside of
drm_do_probe_ddc_edid() would normally catch this case and try the
transaction again, resulting in success.

That, however, was thwarted by the fix for [1]:

commit 9292f37e1f5c79400254dca46f83313488093825
Author: Eugeni Dodonov <eugeni.dodonov@intel.com>
Date:   Thu Jan 5 09:34:28 2012 -0200

    drm: give up on edid retries when i2c bus is not responding

This added code to exit immediately if the return code from the
i2c_transfer function was -ENXIO in order to reduce the amount of time
spent in waiting for unresponsive or disconnected devices. That was
possible because the underlying i2c bit banging algorithm had retries of
its own (which, of course, were part of the reason for the bug the
commit fixes).

Since its introduction in

commit f899fc64cda8569d0529452aafc0da31c042df2e
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Tue Jul 20 15:44:45 2010 -0700

    drm/i915: use GMBUS to manage i2c links

we've been flipping back and forth enabling the GMBUS transfers, but
we've settled since then. The GMBUS implementation does not do any
retries, however, bailing out of the drm_do_probe_ddc_edid() retry loop
on first encounter of -ENXIO. This, combined with Eugeni's commit, broke
the retry on -ENXIO.

Retry GMBUS once on -ENXIO on first message to mitigate the issues with
passive adapters.

This patch is based on the work, and commit message, by Todd Previte
<tprevite@gmail.com>.

[1] https://bugs.freedesktop.org/show_bug.cgi?id=41059

v2: Don't retry if using bit banging.

v3: Move retry within gmbux_xfer, retry only on first message.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85924
Cc: Todd Previte <tprevite@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/intel_i2c.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index 92072f56e418..5519ad3a9574 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -486,7 +486,7 @@ gmbus_xfer(struct i2c_adapter *adapter,
 					       struct intel_gmbus,
 					       adapter);
 	struct drm_i915_private *dev_priv = bus->dev_priv;
-	int i, reg_offset;
+	int i, try = 0, reg_offset;
 	int ret = 0;
 
 	intel_aux_display_runtime_get(dev_priv);
@@ -502,6 +502,7 @@ gmbus_xfer(struct i2c_adapter *adapter,
 	I915_WRITE(GMBUS0 + reg_offset, bus->reg0);
 
 	for (i = 0; i < num; i++) {
+retry:
 		if (gmbus_is_index_read(msgs, i, num)) {
 			ret = gmbus_xfer_index_read(dev_priv, &msgs[i]);
 			i += 1;  /* set i to the index of the read xfer */
@@ -576,6 +577,18 @@ clear_err:
 			 adapter->name, msgs[i].addr,
 			 (msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len);
 
+	/*
+	 * Passive adapters sometimes NAK the first probe. Retry once on -ENXIO
+	 * for GMBUS transfers; the bit banging algorithm has retries
+	 * internally. See also the retry loop in drm_do_probe_ddc_edid, which
+	 * bails out on the first -ENXIO.
+	 */
+	if (ret == -ENXIO && i == 0 && try++ == 0) {
+		DRM_DEBUG_KMS("GMBUS [%s] NAK on first message, retry\n",
+			      adapter->name);
+		goto retry;
+	}
+
 	goto out;
 
 timeout:
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [Intel-gfx] [PATCH v3] drm/i915: Fix DDC probe for passive adapters
  2015-06-02  8:29   ` [PATCH v3] " Jani Nikula
@ 2015-06-02 10:35       ` Ville Syrjälä
  2015-06-02 13:07     ` [PATCH v3] " shuang.he
  1 sibling, 0 replies; 30+ messages in thread
From: Ville Syrjälä @ 2015-06-02 10:35 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, stable

On Tue, Jun 02, 2015 at 11:29:23AM +0300, Jani Nikula wrote:
> Passive DP->DVI/HDMI dongles on DP++ ports show up to the system as HDMI
> devices, as they do not have a sink device in them to respond to any AUX
> traffic. When probing these dongles over the DDC, sometimes they will
> NAK the first attempt even though the transaction is valid and they
> support the DDC protocol. The retry loop inside of
> drm_do_probe_ddc_edid() would normally catch this case and try the
> transaction again, resulting in success.
> 
> That, however, was thwarted by the fix for [1]:
> 
> commit 9292f37e1f5c79400254dca46f83313488093825
> Author: Eugeni Dodonov <eugeni.dodonov@intel.com>
> Date:   Thu Jan 5 09:34:28 2012 -0200
> 
>     drm: give up on edid retries when i2c bus is not responding
> 
> This added code to exit immediately if the return code from the
> i2c_transfer function was -ENXIO in order to reduce the amount of time
> spent in waiting for unresponsive or disconnected devices. That was
> possible because the underlying i2c bit banging algorithm had retries of
> its own (which, of course, were part of the reason for the bug the
> commit fixes).
> 
> Since its introduction in
> 
> commit f899fc64cda8569d0529452aafc0da31c042df2e
> Author: Chris Wilson <chris@chris-wilson.co.uk>
> Date:   Tue Jul 20 15:44:45 2010 -0700
> 
>     drm/i915: use GMBUS to manage i2c links
> 
> we've been flipping back and forth enabling the GMBUS transfers, but
> we've settled since then. The GMBUS implementation does not do any
> retries, however, bailing out of the drm_do_probe_ddc_edid() retry loop
> on first encounter of -ENXIO. This, combined with Eugeni's commit, broke
> the retry on -ENXIO.
> 
> Retry GMBUS once on -ENXIO on first message to mitigate the issues with
> passive adapters.
> 
> This patch is based on the work, and commit message, by Todd Previte
> <tprevite@gmail.com>.
> 
> [1] https://bugs.freedesktop.org/show_bug.cgi?id=41059
> 
> v2: Don't retry if using bit banging.
> 
> v3: Move retry within gmbux_xfer, retry only on first message.
> 
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85924
> Cc: Todd Previte <tprevite@gmail.com>
> Cc: stable@vger.kernel.org
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_i2c.c | 15 ++++++++++++++-
>  1 file changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
> index 92072f56e418..5519ad3a9574 100644
> --- a/drivers/gpu/drm/i915/intel_i2c.c
> +++ b/drivers/gpu/drm/i915/intel_i2c.c
> @@ -486,7 +486,7 @@ gmbus_xfer(struct i2c_adapter *adapter,
>  					       struct intel_gmbus,
>  					       adapter);
>  	struct drm_i915_private *dev_priv = bus->dev_priv;
> -	int i, reg_offset;
> +	int i, try = 0, reg_offset;
>  	int ret = 0;
>  
>  	intel_aux_display_runtime_get(dev_priv);
> @@ -502,6 +502,7 @@ gmbus_xfer(struct i2c_adapter *adapter,
>  	I915_WRITE(GMBUS0 + reg_offset, bus->reg0);
>  
>  	for (i = 0; i < num; i++) {
> +retry:
>  		if (gmbus_is_index_read(msgs, i, num)) {
>  			ret = gmbus_xfer_index_read(dev_priv, &msgs[i]);
>  			i += 1;  /* set i to the index of the read xfer */
> @@ -576,6 +577,18 @@ clear_err:
>  			 adapter->name, msgs[i].addr,
>  			 (msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len);
>  
> +	/*
> +	 * Passive adapters sometimes NAK the first probe. Retry once on -ENXIO
> +	 * for GMBUS transfers; the bit banging algorithm has retries
> +	 * internally. See also the retry loop in drm_do_probe_ddc_edid, which
> +	 * bails out on the first -ENXIO.
> +	 */
> +	if (ret == -ENXIO && i == 0 && try++ == 0) {
> +		DRM_DEBUG_KMS("GMBUS [%s] NAK on first message, retry\n",
> +			      adapter->name);
> +		goto retry;
> +	}
> +

This would leave GMBUS0 set to 0 for the retry.

>  	goto out;
>  
>  timeout:
> -- 
> 2.1.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrj�l�
Intel OTC

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v3] drm/i915: Fix DDC probe for passive adapters
@ 2015-06-02 10:35       ` Ville Syrjälä
  0 siblings, 0 replies; 30+ messages in thread
From: Ville Syrjälä @ 2015-06-02 10:35 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, stable

On Tue, Jun 02, 2015 at 11:29:23AM +0300, Jani Nikula wrote:
> Passive DP->DVI/HDMI dongles on DP++ ports show up to the system as HDMI
> devices, as they do not have a sink device in them to respond to any AUX
> traffic. When probing these dongles over the DDC, sometimes they will
> NAK the first attempt even though the transaction is valid and they
> support the DDC protocol. The retry loop inside of
> drm_do_probe_ddc_edid() would normally catch this case and try the
> transaction again, resulting in success.
> 
> That, however, was thwarted by the fix for [1]:
> 
> commit 9292f37e1f5c79400254dca46f83313488093825
> Author: Eugeni Dodonov <eugeni.dodonov@intel.com>
> Date:   Thu Jan 5 09:34:28 2012 -0200
> 
>     drm: give up on edid retries when i2c bus is not responding
> 
> This added code to exit immediately if the return code from the
> i2c_transfer function was -ENXIO in order to reduce the amount of time
> spent in waiting for unresponsive or disconnected devices. That was
> possible because the underlying i2c bit banging algorithm had retries of
> its own (which, of course, were part of the reason for the bug the
> commit fixes).
> 
> Since its introduction in
> 
> commit f899fc64cda8569d0529452aafc0da31c042df2e
> Author: Chris Wilson <chris@chris-wilson.co.uk>
> Date:   Tue Jul 20 15:44:45 2010 -0700
> 
>     drm/i915: use GMBUS to manage i2c links
> 
> we've been flipping back and forth enabling the GMBUS transfers, but
> we've settled since then. The GMBUS implementation does not do any
> retries, however, bailing out of the drm_do_probe_ddc_edid() retry loop
> on first encounter of -ENXIO. This, combined with Eugeni's commit, broke
> the retry on -ENXIO.
> 
> Retry GMBUS once on -ENXIO on first message to mitigate the issues with
> passive adapters.
> 
> This patch is based on the work, and commit message, by Todd Previte
> <tprevite@gmail.com>.
> 
> [1] https://bugs.freedesktop.org/show_bug.cgi?id=41059
> 
> v2: Don't retry if using bit banging.
> 
> v3: Move retry within gmbux_xfer, retry only on first message.
> 
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85924
> Cc: Todd Previte <tprevite@gmail.com>
> Cc: stable@vger.kernel.org
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_i2c.c | 15 ++++++++++++++-
>  1 file changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
> index 92072f56e418..5519ad3a9574 100644
> --- a/drivers/gpu/drm/i915/intel_i2c.c
> +++ b/drivers/gpu/drm/i915/intel_i2c.c
> @@ -486,7 +486,7 @@ gmbus_xfer(struct i2c_adapter *adapter,
>  					       struct intel_gmbus,
>  					       adapter);
>  	struct drm_i915_private *dev_priv = bus->dev_priv;
> -	int i, reg_offset;
> +	int i, try = 0, reg_offset;
>  	int ret = 0;
>  
>  	intel_aux_display_runtime_get(dev_priv);
> @@ -502,6 +502,7 @@ gmbus_xfer(struct i2c_adapter *adapter,
>  	I915_WRITE(GMBUS0 + reg_offset, bus->reg0);
>  
>  	for (i = 0; i < num; i++) {
> +retry:
>  		if (gmbus_is_index_read(msgs, i, num)) {
>  			ret = gmbus_xfer_index_read(dev_priv, &msgs[i]);
>  			i += 1;  /* set i to the index of the read xfer */
> @@ -576,6 +577,18 @@ clear_err:
>  			 adapter->name, msgs[i].addr,
>  			 (msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len);
>  
> +	/*
> +	 * Passive adapters sometimes NAK the first probe. Retry once on -ENXIO
> +	 * for GMBUS transfers; the bit banging algorithm has retries
> +	 * internally. See also the retry loop in drm_do_probe_ddc_edid, which
> +	 * bails out on the first -ENXIO.
> +	 */
> +	if (ret == -ENXIO && i == 0 && try++ == 0) {
> +		DRM_DEBUG_KMS("GMBUS [%s] NAK on first message, retry\n",
> +			      adapter->name);
> +		goto retry;
> +	}
> +

This would leave GMBUS0 set to 0 for the retry.

>  	goto out;
>  
>  timeout:
> -- 
> 2.1.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH v4] drm/i915: Fix DDC probe for passive adapters
  2015-06-02 10:35       ` Ville Syrjälä
  (?)
@ 2015-06-02 10:42       ` Jani Nikula
  2015-06-02 13:09           ` Ville Syrjälä
  2015-06-02 15:28         ` [PATCH v4] " shuang.he
  -1 siblings, 2 replies; 30+ messages in thread
From: Jani Nikula @ 2015-06-02 10:42 UTC (permalink / raw)
  To: Ville Syrjälä, Jani Nikula; +Cc: intel-gfx, stable

Passive DP->DVI/HDMI dongles on DP++ ports show up to the system as HDMI
devices, as they do not have a sink device in them to respond to any AUX
traffic. When probing these dongles over the DDC, sometimes they will
NAK the first attempt even though the transaction is valid and they
support the DDC protocol. The retry loop inside of
drm_do_probe_ddc_edid() would normally catch this case and try the
transaction again, resulting in success.

That, however, was thwarted by the fix for [1]:

commit 9292f37e1f5c79400254dca46f83313488093825
Author: Eugeni Dodonov <eugeni.dodonov@intel.com>
Date:   Thu Jan 5 09:34:28 2012 -0200

    drm: give up on edid retries when i2c bus is not responding

This added code to exit immediately if the return code from the
i2c_transfer function was -ENXIO in order to reduce the amount of time
spent in waiting for unresponsive or disconnected devices. That was
possible because the underlying i2c bit banging algorithm had retries of
its own (which, of course, were part of the reason for the bug the
commit fixes).

Since its introduction in

commit f899fc64cda8569d0529452aafc0da31c042df2e
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Tue Jul 20 15:44:45 2010 -0700

    drm/i915: use GMBUS to manage i2c links

we've been flipping back and forth enabling the GMBUS transfers, but
we've settled since then. The GMBUS implementation does not do any
retries, however, bailing out of the drm_do_probe_ddc_edid() retry loop
on first encounter of -ENXIO. This, combined with Eugeni's commit, broke
the retry on -ENXIO.

Retry GMBUS once on -ENXIO on first message to mitigate the issues with
passive adapters.

This patch is based on the work, and commit message, by Todd Previte
<tprevite@gmail.com>.

[1] https://bugs.freedesktop.org/show_bug.cgi?id=41059

v2: Don't retry if using bit banging.

v3: Move retry within gmbux_xfer, retry only on first message.

v4: Initialize GMBUS0 on retry (Ville).

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85924
Cc: Todd Previte <tprevite@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/intel_i2c.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index 92072f56e418..5f2e88d39baf 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -486,7 +486,7 @@ gmbus_xfer(struct i2c_adapter *adapter,
 					       struct intel_gmbus,
 					       adapter);
 	struct drm_i915_private *dev_priv = bus->dev_priv;
-	int i, reg_offset;
+	int i = 0, try = 0, reg_offset;
 	int ret = 0;
 
 	intel_aux_display_runtime_get(dev_priv);
@@ -499,9 +499,10 @@ gmbus_xfer(struct i2c_adapter *adapter,
 
 	reg_offset = dev_priv->gpio_mmio_base;
 
+retry:
 	I915_WRITE(GMBUS0 + reg_offset, bus->reg0);
 
-	for (i = 0; i < num; i++) {
+	for (; i < num; i++) {
 		if (gmbus_is_index_read(msgs, i, num)) {
 			ret = gmbus_xfer_index_read(dev_priv, &msgs[i]);
 			i += 1;  /* set i to the index of the read xfer */
@@ -576,6 +577,18 @@ clear_err:
 			 adapter->name, msgs[i].addr,
 			 (msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len);
 
+	/*
+	 * Passive adapters sometimes NAK the first probe. Retry once on -ENXIO
+	 * for GMBUS transfers; the bit banging algorithm has retries
+	 * internally. See also the retry loop in drm_do_probe_ddc_edid, which
+	 * bails out on the first -ENXIO.
+	 */
+	if (ret == -ENXIO && i == 0 && try++ == 0) {
+		DRM_DEBUG_KMS("GMBUS [%s] NAK on first message, retry\n",
+			      adapter->name);
+		goto retry;
+	}
+
 	goto out;
 
 timeout:
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [PATCH v3] drm/i915: Fix DDC probe for passive adapters
  2015-06-02  8:29   ` [PATCH v3] " Jani Nikula
  2015-06-02 10:35       ` Ville Syrjälä
@ 2015-06-02 13:07     ` shuang.he
  1 sibling, 0 replies; 30+ messages in thread
From: shuang.he @ 2015-06-02 13:07 UTC (permalink / raw)
  To: shuang.he, lei.a.liu, intel-gfx, jani.nikula

Tested-By: Intel Graphics QA PRTS (Patch Regression Test System Contact: shuang.he@intel.com)
Task id: 6519
-------------------------------------Summary-------------------------------------
Platform          Delta          drm-intel-nightly          Series Applied
PNV                                  276/276              276/276
ILK                                  303/303              303/303
SNB                 -1              315/315              314/315
IVB                                  343/343              343/343
BYT                                  287/287              287/287
BDW                                  321/321              321/321
-------------------------------------Detailed-------------------------------------
Platform  Test                                drm-intel-nightly          Series Applied
*SNB  igt@pm_rpm@dpms-mode-unset-non-lpsp      PASS(1)      DMESG_WARN(1)
(dmesg patch applied)WARNING:at_drivers/gpu/drm/i915/intel_uncore.c:#assert_device_not_suspended[i915]()@WARNING:.* at .* assert_device_not_suspended+0x
Note: You need to pay more attention to line start with '*'
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v4] drm/i915: Fix DDC probe for passive adapters
  2015-06-02 10:42       ` [PATCH v4] " Jani Nikula
@ 2015-06-02 13:09           ` Ville Syrjälä
  2015-06-02 15:28         ` [PATCH v4] " shuang.he
  1 sibling, 0 replies; 30+ messages in thread
From: Ville Syrjälä @ 2015-06-02 13:09 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, stable

On Tue, Jun 02, 2015 at 01:42:52PM +0300, Jani Nikula wrote:
> Passive DP->DVI/HDMI dongles on DP++ ports show up to the system as HDMI
> devices, as they do not have a sink device in them to respond to any AUX
> traffic. When probing these dongles over the DDC, sometimes they will
> NAK the first attempt even though the transaction is valid and they
> support the DDC protocol. The retry loop inside of
> drm_do_probe_ddc_edid() would normally catch this case and try the
> transaction again, resulting in success.
> 
> That, however, was thwarted by the fix for [1]:
> 
> commit 9292f37e1f5c79400254dca46f83313488093825
> Author: Eugeni Dodonov <eugeni.dodonov@intel.com>
> Date:   Thu Jan 5 09:34:28 2012 -0200
> 
>     drm: give up on edid retries when i2c bus is not responding
> 
> This added code to exit immediately if the return code from the
> i2c_transfer function was -ENXIO in order to reduce the amount of time
> spent in waiting for unresponsive or disconnected devices. That was
> possible because the underlying i2c bit banging algorithm had retries of
> its own (which, of course, were part of the reason for the bug the
> commit fixes).
> 
> Since its introduction in
> 
> commit f899fc64cda8569d0529452aafc0da31c042df2e
> Author: Chris Wilson <chris@chris-wilson.co.uk>
> Date:   Tue Jul 20 15:44:45 2010 -0700
> 
>     drm/i915: use GMBUS to manage i2c links
> 
> we've been flipping back and forth enabling the GMBUS transfers, but
> we've settled since then. The GMBUS implementation does not do any
> retries, however, bailing out of the drm_do_probe_ddc_edid() retry loop
> on first encounter of -ENXIO. This, combined with Eugeni's commit, broke
> the retry on -ENXIO.
> 
> Retry GMBUS once on -ENXIO on first message to mitigate the issues with
> passive adapters.
> 
> This patch is based on the work, and commit message, by Todd Previte
> <tprevite@gmail.com>.
> 
> [1] https://bugs.freedesktop.org/show_bug.cgi?id=41059
> 
> v2: Don't retry if using bit banging.
> 
> v3: Move retry within gmbux_xfer, retry only on first message.
> 
> v4: Initialize GMBUS0 on retry (Ville).
> 
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85924
> Cc: Todd Previte <tprevite@gmail.com>
> Cc: stable@vger.kernel.org
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_i2c.c | 17 +++++++++++++++--
>  1 file changed, 15 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
> index 92072f56e418..5f2e88d39baf 100644
> --- a/drivers/gpu/drm/i915/intel_i2c.c
> +++ b/drivers/gpu/drm/i915/intel_i2c.c
> @@ -486,7 +486,7 @@ gmbus_xfer(struct i2c_adapter *adapter,
>  					       struct intel_gmbus,
>  					       adapter);
>  	struct drm_i915_private *dev_priv = bus->dev_priv;
> -	int i, reg_offset;
> +	int i = 0, try = 0, reg_offset;
>  	int ret = 0;
>  
>  	intel_aux_display_runtime_get(dev_priv);
> @@ -499,9 +499,10 @@ gmbus_xfer(struct i2c_adapter *adapter,
>  
>  	reg_offset = dev_priv->gpio_mmio_base;
>  
> +retry:
>  	I915_WRITE(GMBUS0 + reg_offset, bus->reg0);
>  
> -	for (i = 0; i < num; i++) {
> +	for (; i < num; i++) {
>  		if (gmbus_is_index_read(msgs, i, num)) {
>  			ret = gmbus_xfer_index_read(dev_priv, &msgs[i]);
>  			i += 1;  /* set i to the index of the read xfer */

This increment means we'll never retry if we decice to use
gmbus_xfer_index_read() for the first two messages. AFAICS that
should always be the case for EDID reads where we don't send the
segment address.

> @@ -576,6 +577,18 @@ clear_err:
>  			 adapter->name, msgs[i].addr,
>  			 (msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len);
>  
> +	/*
> +	 * Passive adapters sometimes NAK the first probe. Retry once on -ENXIO
> +	 * for GMBUS transfers; the bit banging algorithm has retries
> +	 * internally. See also the retry loop in drm_do_probe_ddc_edid, which
> +	 * bails out on the first -ENXIO.
> +	 */
> +	if (ret == -ENXIO && i == 0 && try++ == 0) {
> +		DRM_DEBUG_KMS("GMBUS [%s] NAK on first message, retry\n",
> +			      adapter->name);
> +		goto retry;
> +	}
> +
>  	goto out;
>  
>  timeout:
> -- 
> 2.1.4

-- 
Ville Syrj�l�
Intel OTC

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v4] drm/i915: Fix DDC probe for passive adapters
@ 2015-06-02 13:09           ` Ville Syrjälä
  0 siblings, 0 replies; 30+ messages in thread
From: Ville Syrjälä @ 2015-06-02 13:09 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, stable

On Tue, Jun 02, 2015 at 01:42:52PM +0300, Jani Nikula wrote:
> Passive DP->DVI/HDMI dongles on DP++ ports show up to the system as HDMI
> devices, as they do not have a sink device in them to respond to any AUX
> traffic. When probing these dongles over the DDC, sometimes they will
> NAK the first attempt even though the transaction is valid and they
> support the DDC protocol. The retry loop inside of
> drm_do_probe_ddc_edid() would normally catch this case and try the
> transaction again, resulting in success.
> 
> That, however, was thwarted by the fix for [1]:
> 
> commit 9292f37e1f5c79400254dca46f83313488093825
> Author: Eugeni Dodonov <eugeni.dodonov@intel.com>
> Date:   Thu Jan 5 09:34:28 2012 -0200
> 
>     drm: give up on edid retries when i2c bus is not responding
> 
> This added code to exit immediately if the return code from the
> i2c_transfer function was -ENXIO in order to reduce the amount of time
> spent in waiting for unresponsive or disconnected devices. That was
> possible because the underlying i2c bit banging algorithm had retries of
> its own (which, of course, were part of the reason for the bug the
> commit fixes).
> 
> Since its introduction in
> 
> commit f899fc64cda8569d0529452aafc0da31c042df2e
> Author: Chris Wilson <chris@chris-wilson.co.uk>
> Date:   Tue Jul 20 15:44:45 2010 -0700
> 
>     drm/i915: use GMBUS to manage i2c links
> 
> we've been flipping back and forth enabling the GMBUS transfers, but
> we've settled since then. The GMBUS implementation does not do any
> retries, however, bailing out of the drm_do_probe_ddc_edid() retry loop
> on first encounter of -ENXIO. This, combined with Eugeni's commit, broke
> the retry on -ENXIO.
> 
> Retry GMBUS once on -ENXIO on first message to mitigate the issues with
> passive adapters.
> 
> This patch is based on the work, and commit message, by Todd Previte
> <tprevite@gmail.com>.
> 
> [1] https://bugs.freedesktop.org/show_bug.cgi?id=41059
> 
> v2: Don't retry if using bit banging.
> 
> v3: Move retry within gmbux_xfer, retry only on first message.
> 
> v4: Initialize GMBUS0 on retry (Ville).
> 
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85924
> Cc: Todd Previte <tprevite@gmail.com>
> Cc: stable@vger.kernel.org
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_i2c.c | 17 +++++++++++++++--
>  1 file changed, 15 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
> index 92072f56e418..5f2e88d39baf 100644
> --- a/drivers/gpu/drm/i915/intel_i2c.c
> +++ b/drivers/gpu/drm/i915/intel_i2c.c
> @@ -486,7 +486,7 @@ gmbus_xfer(struct i2c_adapter *adapter,
>  					       struct intel_gmbus,
>  					       adapter);
>  	struct drm_i915_private *dev_priv = bus->dev_priv;
> -	int i, reg_offset;
> +	int i = 0, try = 0, reg_offset;
>  	int ret = 0;
>  
>  	intel_aux_display_runtime_get(dev_priv);
> @@ -499,9 +499,10 @@ gmbus_xfer(struct i2c_adapter *adapter,
>  
>  	reg_offset = dev_priv->gpio_mmio_base;
>  
> +retry:
>  	I915_WRITE(GMBUS0 + reg_offset, bus->reg0);
>  
> -	for (i = 0; i < num; i++) {
> +	for (; i < num; i++) {
>  		if (gmbus_is_index_read(msgs, i, num)) {
>  			ret = gmbus_xfer_index_read(dev_priv, &msgs[i]);
>  			i += 1;  /* set i to the index of the read xfer */

This increment means we'll never retry if we decice to use
gmbus_xfer_index_read() for the first two messages. AFAICS that
should always be the case for EDID reads where we don't send the
segment address.

> @@ -576,6 +577,18 @@ clear_err:
>  			 adapter->name, msgs[i].addr,
>  			 (msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len);
>  
> +	/*
> +	 * Passive adapters sometimes NAK the first probe. Retry once on -ENXIO
> +	 * for GMBUS transfers; the bit banging algorithm has retries
> +	 * internally. See also the retry loop in drm_do_probe_ddc_edid, which
> +	 * bails out on the first -ENXIO.
> +	 */
> +	if (ret == -ENXIO && i == 0 && try++ == 0) {
> +		DRM_DEBUG_KMS("GMBUS [%s] NAK on first message, retry\n",
> +			      adapter->name);
> +		goto retry;
> +	}
> +
>  	goto out;
>  
>  timeout:
> -- 
> 2.1.4

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v4] drm/i915: Fix DDC probe for passive adapters
  2015-06-02 10:42       ` [PATCH v4] " Jani Nikula
  2015-06-02 13:09           ` Ville Syrjälä
@ 2015-06-02 15:28         ` shuang.he
  1 sibling, 0 replies; 30+ messages in thread
From: shuang.he @ 2015-06-02 15:28 UTC (permalink / raw)
  To: shuang.he, lei.a.liu, intel-gfx, jani.nikula

Tested-By: Intel Graphics QA PRTS (Patch Regression Test System Contact: shuang.he@intel.com)
Task id: 6520
-------------------------------------Summary-------------------------------------
Platform          Delta          drm-intel-nightly          Series Applied
PNV                                  276/276              276/276
ILK                                  303/303              303/303
SNB                 -1              315/315              314/315
IVB                                  343/343              343/343
BYT                                  287/287              287/287
BDW                                  321/321              321/321
-------------------------------------Detailed-------------------------------------
Platform  Test                                drm-intel-nightly          Series Applied
*SNB  igt@pm_rpm@dpms-mode-unset-non-lpsp      PASS(1)      DMESG_WARN(1)
(dmesg patch applied)WARNING:at_drivers/gpu/drm/i915/intel_uncore.c:#assert_device_not_suspended[i915]()@WARNING:.* at .* assert_device_not_suspended+0x
Note: You need to pay more attention to line start with '*'
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH v5] drm/i915: Fix DDC probe for passive adapters
  2015-06-02 13:09           ` Ville Syrjälä
@ 2015-06-02 16:21             ` Jani Nikula
  -1 siblings, 0 replies; 30+ messages in thread
From: Jani Nikula @ 2015-06-02 16:21 UTC (permalink / raw)
  To: Ville Syrjälä, Jani Nikula; +Cc: intel-gfx, stable

Passive DP->DVI/HDMI dongles on DP++ ports show up to the system as HDMI
devices, as they do not have a sink device in them to respond to any AUX
traffic. When probing these dongles over the DDC, sometimes they will
NAK the first attempt even though the transaction is valid and they
support the DDC protocol. The retry loop inside of
drm_do_probe_ddc_edid() would normally catch this case and try the
transaction again, resulting in success.

That, however, was thwarted by the fix for [1]:

commit 9292f37e1f5c79400254dca46f83313488093825
Author: Eugeni Dodonov <eugeni.dodonov@intel.com>
Date:   Thu Jan 5 09:34:28 2012 -0200

    drm: give up on edid retries when i2c bus is not responding

This added code to exit immediately if the return code from the
i2c_transfer function was -ENXIO in order to reduce the amount of time
spent in waiting for unresponsive or disconnected devices. That was
possible because the underlying i2c bit banging algorithm had retries of
its own (which, of course, were part of the reason for the bug the
commit fixes).

Since its introduction in

commit f899fc64cda8569d0529452aafc0da31c042df2e
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Tue Jul 20 15:44:45 2010 -0700

    drm/i915: use GMBUS to manage i2c links

we've been flipping back and forth enabling the GMBUS transfers, but
we've settled since then. The GMBUS implementation does not do any
retries, however, bailing out of the drm_do_probe_ddc_edid() retry loop
on first encounter of -ENXIO. This, combined with Eugeni's commit, broke
the retry on -ENXIO.

Retry GMBUS once on -ENXIO on first message to mitigate the issues with
passive adapters.

This patch is based on the work, and commit message, by Todd Previte
<tprevite@gmail.com>.

[1] https://bugs.freedesktop.org/show_bug.cgi?id=41059

v2: Don't retry if using bit banging.

v3: Move retry within gmbux_xfer, retry only on first message.

v4: Initialize GMBUS0 on retry (Ville).

v5: Take index reads into account (Ville).

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85924
Cc: Todd Previte <tprevite@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/intel_i2c.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index 92072f56e418..a64f26c670af 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -486,7 +486,7 @@ gmbus_xfer(struct i2c_adapter *adapter,
 					       struct intel_gmbus,
 					       adapter);
 	struct drm_i915_private *dev_priv = bus->dev_priv;
-	int i, reg_offset;
+	int i = 0, inc, try = 0, reg_offset;
 	int ret = 0;
 
 	intel_aux_display_runtime_get(dev_priv);
@@ -499,12 +499,14 @@ gmbus_xfer(struct i2c_adapter *adapter,
 
 	reg_offset = dev_priv->gpio_mmio_base;
 
+retry:
 	I915_WRITE(GMBUS0 + reg_offset, bus->reg0);
 
-	for (i = 0; i < num; i++) {
+	for (; i < num; i += inc) {
+		inc = 1;
 		if (gmbus_is_index_read(msgs, i, num)) {
 			ret = gmbus_xfer_index_read(dev_priv, &msgs[i]);
-			i += 1;  /* set i to the index of the read xfer */
+			inc = 2; /* an index read is two msgs */
 		} else if (msgs[i].flags & I2C_M_RD) {
 			ret = gmbus_xfer_read(dev_priv, &msgs[i], 0);
 		} else {
@@ -576,6 +578,18 @@ clear_err:
 			 adapter->name, msgs[i].addr,
 			 (msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len);
 
+	/*
+	 * Passive adapters sometimes NAK the first probe. Retry the first
+	 * message once on -ENXIO for GMBUS transfers; the bit banging algorithm
+	 * has retries internally. See also the retry loop in
+	 * drm_do_probe_ddc_edid, which bails out on the first -ENXIO.
+	 */
+	if (ret == -ENXIO && i == 0 && try++ == 0) {
+		DRM_DEBUG_KMS("GMBUS [%s] NAK on first message, retry\n",
+			      adapter->name);
+		goto retry;
+	}
+
 	goto out;
 
 timeout:
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v5] drm/i915: Fix DDC probe for passive adapters
@ 2015-06-02 16:21             ` Jani Nikula
  0 siblings, 0 replies; 30+ messages in thread
From: Jani Nikula @ 2015-06-02 16:21 UTC (permalink / raw)
  To: Ville Syrjälä, Jani Nikula; +Cc: intel-gfx, stable

Passive DP->DVI/HDMI dongles on DP++ ports show up to the system as HDMI
devices, as they do not have a sink device in them to respond to any AUX
traffic. When probing these dongles over the DDC, sometimes they will
NAK the first attempt even though the transaction is valid and they
support the DDC protocol. The retry loop inside of
drm_do_probe_ddc_edid() would normally catch this case and try the
transaction again, resulting in success.

That, however, was thwarted by the fix for [1]:

commit 9292f37e1f5c79400254dca46f83313488093825
Author: Eugeni Dodonov <eugeni.dodonov@intel.com>
Date:   Thu Jan 5 09:34:28 2012 -0200

    drm: give up on edid retries when i2c bus is not responding

This added code to exit immediately if the return code from the
i2c_transfer function was -ENXIO in order to reduce the amount of time
spent in waiting for unresponsive or disconnected devices. That was
possible because the underlying i2c bit banging algorithm had retries of
its own (which, of course, were part of the reason for the bug the
commit fixes).

Since its introduction in

commit f899fc64cda8569d0529452aafc0da31c042df2e
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Tue Jul 20 15:44:45 2010 -0700

    drm/i915: use GMBUS to manage i2c links

we've been flipping back and forth enabling the GMBUS transfers, but
we've settled since then. The GMBUS implementation does not do any
retries, however, bailing out of the drm_do_probe_ddc_edid() retry loop
on first encounter of -ENXIO. This, combined with Eugeni's commit, broke
the retry on -ENXIO.

Retry GMBUS once on -ENXIO on first message to mitigate the issues with
passive adapters.

This patch is based on the work, and commit message, by Todd Previte
<tprevite@gmail.com>.

[1] https://bugs.freedesktop.org/show_bug.cgi?id=41059

v2: Don't retry if using bit banging.

v3: Move retry within gmbux_xfer, retry only on first message.

v4: Initialize GMBUS0 on retry (Ville).

v5: Take index reads into account (Ville).

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85924
Cc: Todd Previte <tprevite@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/intel_i2c.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index 92072f56e418..a64f26c670af 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -486,7 +486,7 @@ gmbus_xfer(struct i2c_adapter *adapter,
 					       struct intel_gmbus,
 					       adapter);
 	struct drm_i915_private *dev_priv = bus->dev_priv;
-	int i, reg_offset;
+	int i = 0, inc, try = 0, reg_offset;
 	int ret = 0;
 
 	intel_aux_display_runtime_get(dev_priv);
@@ -499,12 +499,14 @@ gmbus_xfer(struct i2c_adapter *adapter,
 
 	reg_offset = dev_priv->gpio_mmio_base;
 
+retry:
 	I915_WRITE(GMBUS0 + reg_offset, bus->reg0);
 
-	for (i = 0; i < num; i++) {
+	for (; i < num; i += inc) {
+		inc = 1;
 		if (gmbus_is_index_read(msgs, i, num)) {
 			ret = gmbus_xfer_index_read(dev_priv, &msgs[i]);
-			i += 1;  /* set i to the index of the read xfer */
+			inc = 2; /* an index read is two msgs */
 		} else if (msgs[i].flags & I2C_M_RD) {
 			ret = gmbus_xfer_read(dev_priv, &msgs[i], 0);
 		} else {
@@ -576,6 +578,18 @@ clear_err:
 			 adapter->name, msgs[i].addr,
 			 (msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len);
 
+	/*
+	 * Passive adapters sometimes NAK the first probe. Retry the first
+	 * message once on -ENXIO for GMBUS transfers; the bit banging algorithm
+	 * has retries internally. See also the retry loop in
+	 * drm_do_probe_ddc_edid, which bails out on the first -ENXIO.
+	 */
+	if (ret == -ENXIO && i == 0 && try++ == 0) {
+		DRM_DEBUG_KMS("GMBUS [%s] NAK on first message, retry\n",
+			      adapter->name);
+		goto retry;
+	}
+
 	goto out;
 
 timeout:
-- 
2.1.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [PATCH v5] drm/i915: Fix DDC probe for passive adapters
  2015-06-02 16:21             ` Jani Nikula
@ 2015-06-02 16:40               ` Ville Syrjälä
  -1 siblings, 0 replies; 30+ messages in thread
From: Ville Syrjälä @ 2015-06-02 16:40 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, stable

On Tue, Jun 02, 2015 at 07:21:15PM +0300, Jani Nikula wrote:
> Passive DP->DVI/HDMI dongles on DP++ ports show up to the system as HDMI
> devices, as they do not have a sink device in them to respond to any AUX
> traffic. When probing these dongles over the DDC, sometimes they will
> NAK the first attempt even though the transaction is valid and they
> support the DDC protocol. The retry loop inside of
> drm_do_probe_ddc_edid() would normally catch this case and try the
> transaction again, resulting in success.
> 
> That, however, was thwarted by the fix for [1]:
> 
> commit 9292f37e1f5c79400254dca46f83313488093825
> Author: Eugeni Dodonov <eugeni.dodonov@intel.com>
> Date:   Thu Jan 5 09:34:28 2012 -0200
> 
>     drm: give up on edid retries when i2c bus is not responding
> 
> This added code to exit immediately if the return code from the
> i2c_transfer function was -ENXIO in order to reduce the amount of time
> spent in waiting for unresponsive or disconnected devices. That was
> possible because the underlying i2c bit banging algorithm had retries of
> its own (which, of course, were part of the reason for the bug the
> commit fixes).
> 
> Since its introduction in
> 
> commit f899fc64cda8569d0529452aafc0da31c042df2e
> Author: Chris Wilson <chris@chris-wilson.co.uk>
> Date:   Tue Jul 20 15:44:45 2010 -0700
> 
>     drm/i915: use GMBUS to manage i2c links
> 
> we've been flipping back and forth enabling the GMBUS transfers, but
> we've settled since then. The GMBUS implementation does not do any
> retries, however, bailing out of the drm_do_probe_ddc_edid() retry loop
> on first encounter of -ENXIO. This, combined with Eugeni's commit, broke
> the retry on -ENXIO.
> 
> Retry GMBUS once on -ENXIO on first message to mitigate the issues with
> passive adapters.
> 
> This patch is based on the work, and commit message, by Todd Previte
> <tprevite@gmail.com>.
> 
> [1] https://bugs.freedesktop.org/show_bug.cgi?id=41059
> 
> v2: Don't retry if using bit banging.
> 
> v3: Move retry within gmbux_xfer, retry only on first message.
> 
> v4: Initialize GMBUS0 on retry (Ville).
> 
> v5: Take index reads into account (Ville).
> 
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85924
> Cc: Todd Previte <tprevite@gmail.com>
> Cc: stable@vger.kernel.org
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

OK, I think I'm done shooting any more holes into this one:
Reviewed-by: Ville Syrj�l� <ville.syrjala@linux.intel.com>

Hopefully it works too. I don't have very good intuition into the gmbus
hardware. I think one day I need to set up a bit-banged i2c slave and
play around with it just for fun.

> ---
>  drivers/gpu/drm/i915/intel_i2c.c | 20 +++++++++++++++++---
>  1 file changed, 17 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
> index 92072f56e418..a64f26c670af 100644
> --- a/drivers/gpu/drm/i915/intel_i2c.c
> +++ b/drivers/gpu/drm/i915/intel_i2c.c
> @@ -486,7 +486,7 @@ gmbus_xfer(struct i2c_adapter *adapter,
>  					       struct intel_gmbus,
>  					       adapter);
>  	struct drm_i915_private *dev_priv = bus->dev_priv;
> -	int i, reg_offset;
> +	int i = 0, inc, try = 0, reg_offset;
>  	int ret = 0;
>  
>  	intel_aux_display_runtime_get(dev_priv);
> @@ -499,12 +499,14 @@ gmbus_xfer(struct i2c_adapter *adapter,
>  
>  	reg_offset = dev_priv->gpio_mmio_base;
>  
> +retry:
>  	I915_WRITE(GMBUS0 + reg_offset, bus->reg0);
>  
> -	for (i = 0; i < num; i++) {
> +	for (; i < num; i += inc) {
> +		inc = 1;
>  		if (gmbus_is_index_read(msgs, i, num)) {
>  			ret = gmbus_xfer_index_read(dev_priv, &msgs[i]);
> -			i += 1;  /* set i to the index of the read xfer */
> +			inc = 2; /* an index read is two msgs */
>  		} else if (msgs[i].flags & I2C_M_RD) {
>  			ret = gmbus_xfer_read(dev_priv, &msgs[i], 0);
>  		} else {
> @@ -576,6 +578,18 @@ clear_err:
>  			 adapter->name, msgs[i].addr,
>  			 (msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len);
>  
> +	/*
> +	 * Passive adapters sometimes NAK the first probe. Retry the first
> +	 * message once on -ENXIO for GMBUS transfers; the bit banging algorithm
> +	 * has retries internally. See also the retry loop in
> +	 * drm_do_probe_ddc_edid, which bails out on the first -ENXIO.
> +	 */
> +	if (ret == -ENXIO && i == 0 && try++ == 0) {
> +		DRM_DEBUG_KMS("GMBUS [%s] NAK on first message, retry\n",
> +			      adapter->name);
> +		goto retry;
> +	}
> +
>  	goto out;
>  
>  timeout:
> -- 
> 2.1.4

-- 
Ville Syrj�l�
Intel OTC

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v5] drm/i915: Fix DDC probe for passive adapters
@ 2015-06-02 16:40               ` Ville Syrjälä
  0 siblings, 0 replies; 30+ messages in thread
From: Ville Syrjälä @ 2015-06-02 16:40 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, stable

On Tue, Jun 02, 2015 at 07:21:15PM +0300, Jani Nikula wrote:
> Passive DP->DVI/HDMI dongles on DP++ ports show up to the system as HDMI
> devices, as they do not have a sink device in them to respond to any AUX
> traffic. When probing these dongles over the DDC, sometimes they will
> NAK the first attempt even though the transaction is valid and they
> support the DDC protocol. The retry loop inside of
> drm_do_probe_ddc_edid() would normally catch this case and try the
> transaction again, resulting in success.
> 
> That, however, was thwarted by the fix for [1]:
> 
> commit 9292f37e1f5c79400254dca46f83313488093825
> Author: Eugeni Dodonov <eugeni.dodonov@intel.com>
> Date:   Thu Jan 5 09:34:28 2012 -0200
> 
>     drm: give up on edid retries when i2c bus is not responding
> 
> This added code to exit immediately if the return code from the
> i2c_transfer function was -ENXIO in order to reduce the amount of time
> spent in waiting for unresponsive or disconnected devices. That was
> possible because the underlying i2c bit banging algorithm had retries of
> its own (which, of course, were part of the reason for the bug the
> commit fixes).
> 
> Since its introduction in
> 
> commit f899fc64cda8569d0529452aafc0da31c042df2e
> Author: Chris Wilson <chris@chris-wilson.co.uk>
> Date:   Tue Jul 20 15:44:45 2010 -0700
> 
>     drm/i915: use GMBUS to manage i2c links
> 
> we've been flipping back and forth enabling the GMBUS transfers, but
> we've settled since then. The GMBUS implementation does not do any
> retries, however, bailing out of the drm_do_probe_ddc_edid() retry loop
> on first encounter of -ENXIO. This, combined with Eugeni's commit, broke
> the retry on -ENXIO.
> 
> Retry GMBUS once on -ENXIO on first message to mitigate the issues with
> passive adapters.
> 
> This patch is based on the work, and commit message, by Todd Previte
> <tprevite@gmail.com>.
> 
> [1] https://bugs.freedesktop.org/show_bug.cgi?id=41059
> 
> v2: Don't retry if using bit banging.
> 
> v3: Move retry within gmbux_xfer, retry only on first message.
> 
> v4: Initialize GMBUS0 on retry (Ville).
> 
> v5: Take index reads into account (Ville).
> 
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85924
> Cc: Todd Previte <tprevite@gmail.com>
> Cc: stable@vger.kernel.org
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

OK, I think I'm done shooting any more holes into this one:
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

Hopefully it works too. I don't have very good intuition into the gmbus
hardware. I think one day I need to set up a bit-banged i2c slave and
play around with it just for fun.

> ---
>  drivers/gpu/drm/i915/intel_i2c.c | 20 +++++++++++++++++---
>  1 file changed, 17 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
> index 92072f56e418..a64f26c670af 100644
> --- a/drivers/gpu/drm/i915/intel_i2c.c
> +++ b/drivers/gpu/drm/i915/intel_i2c.c
> @@ -486,7 +486,7 @@ gmbus_xfer(struct i2c_adapter *adapter,
>  					       struct intel_gmbus,
>  					       adapter);
>  	struct drm_i915_private *dev_priv = bus->dev_priv;
> -	int i, reg_offset;
> +	int i = 0, inc, try = 0, reg_offset;
>  	int ret = 0;
>  
>  	intel_aux_display_runtime_get(dev_priv);
> @@ -499,12 +499,14 @@ gmbus_xfer(struct i2c_adapter *adapter,
>  
>  	reg_offset = dev_priv->gpio_mmio_base;
>  
> +retry:
>  	I915_WRITE(GMBUS0 + reg_offset, bus->reg0);
>  
> -	for (i = 0; i < num; i++) {
> +	for (; i < num; i += inc) {
> +		inc = 1;
>  		if (gmbus_is_index_read(msgs, i, num)) {
>  			ret = gmbus_xfer_index_read(dev_priv, &msgs[i]);
> -			i += 1;  /* set i to the index of the read xfer */
> +			inc = 2; /* an index read is two msgs */
>  		} else if (msgs[i].flags & I2C_M_RD) {
>  			ret = gmbus_xfer_read(dev_priv, &msgs[i], 0);
>  		} else {
> @@ -576,6 +578,18 @@ clear_err:
>  			 adapter->name, msgs[i].addr,
>  			 (msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len);
>  
> +	/*
> +	 * Passive adapters sometimes NAK the first probe. Retry the first
> +	 * message once on -ENXIO for GMBUS transfers; the bit banging algorithm
> +	 * has retries internally. See also the retry loop in
> +	 * drm_do_probe_ddc_edid, which bails out on the first -ENXIO.
> +	 */
> +	if (ret == -ENXIO && i == 0 && try++ == 0) {
> +		DRM_DEBUG_KMS("GMBUS [%s] NAK on first message, retry\n",
> +			      adapter->name);
> +		goto retry;
> +	}
> +
>  	goto out;
>  
>  timeout:
> -- 
> 2.1.4

-- 
Ville Syrjälä
Intel OTC

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v5] drm/i915: Fix DDC probe for passive adapters
  2015-06-02 16:40               ` Ville Syrjälä
@ 2015-06-02 16:43                 ` Jani Nikula
  -1 siblings, 0 replies; 30+ messages in thread
From: Jani Nikula @ 2015-06-02 16:43 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, stable

On Tue, 02 Jun 2015, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> On Tue, Jun 02, 2015 at 07:21:15PM +0300, Jani Nikula wrote:
>> Passive DP->DVI/HDMI dongles on DP++ ports show up to the system as HDMI
>> devices, as they do not have a sink device in them to respond to any AUX
>> traffic. When probing these dongles over the DDC, sometimes they will
>> NAK the first attempt even though the transaction is valid and they
>> support the DDC protocol. The retry loop inside of
>> drm_do_probe_ddc_edid() would normally catch this case and try the
>> transaction again, resulting in success.
>> 
>> That, however, was thwarted by the fix for [1]:
>> 
>> commit 9292f37e1f5c79400254dca46f83313488093825
>> Author: Eugeni Dodonov <eugeni.dodonov@intel.com>
>> Date:   Thu Jan 5 09:34:28 2012 -0200
>> 
>>     drm: give up on edid retries when i2c bus is not responding
>> 
>> This added code to exit immediately if the return code from the
>> i2c_transfer function was -ENXIO in order to reduce the amount of time
>> spent in waiting for unresponsive or disconnected devices. That was
>> possible because the underlying i2c bit banging algorithm had retries of
>> its own (which, of course, were part of the reason for the bug the
>> commit fixes).
>> 
>> Since its introduction in
>> 
>> commit f899fc64cda8569d0529452aafc0da31c042df2e
>> Author: Chris Wilson <chris@chris-wilson.co.uk>
>> Date:   Tue Jul 20 15:44:45 2010 -0700
>> 
>>     drm/i915: use GMBUS to manage i2c links
>> 
>> we've been flipping back and forth enabling the GMBUS transfers, but
>> we've settled since then. The GMBUS implementation does not do any
>> retries, however, bailing out of the drm_do_probe_ddc_edid() retry loop
>> on first encounter of -ENXIO. This, combined with Eugeni's commit, broke
>> the retry on -ENXIO.
>> 
>> Retry GMBUS once on -ENXIO on first message to mitigate the issues with
>> passive adapters.
>> 
>> This patch is based on the work, and commit message, by Todd Previte
>> <tprevite@gmail.com>.
>> 
>> [1] https://bugs.freedesktop.org/show_bug.cgi?id=41059
>> 
>> v2: Don't retry if using bit banging.
>> 
>> v3: Move retry within gmbux_xfer, retry only on first message.
>> 
>> v4: Initialize GMBUS0 on retry (Ville).
>> 
>> v5: Take index reads into account (Ville).
>> 
>> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85924
>> Cc: Todd Previte <tprevite@gmail.com>
>> Cc: stable@vger.kernel.org
>> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
>
> OK, I think I'm done shooting any more holes into this one:
> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

\o/

Thanks for all the review. I suck.

> Hopefully it works too. I don't have very good intuition into the gmbus
> hardware. I think one day I need to set up a bit-banged i2c slave and
> play around with it just for fun.

AFAICT it should be functionally equivalent to the v1 patch that got
tested in the referenced bug. I'm hoping to get a test result for this
one too.


>
>> ---
>>  drivers/gpu/drm/i915/intel_i2c.c | 20 +++++++++++++++++---
>>  1 file changed, 17 insertions(+), 3 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
>> index 92072f56e418..a64f26c670af 100644
>> --- a/drivers/gpu/drm/i915/intel_i2c.c
>> +++ b/drivers/gpu/drm/i915/intel_i2c.c
>> @@ -486,7 +486,7 @@ gmbus_xfer(struct i2c_adapter *adapter,
>>  					       struct intel_gmbus,
>>  					       adapter);
>>  	struct drm_i915_private *dev_priv = bus->dev_priv;
>> -	int i, reg_offset;
>> +	int i = 0, inc, try = 0, reg_offset;
>>  	int ret = 0;
>>  
>>  	intel_aux_display_runtime_get(dev_priv);
>> @@ -499,12 +499,14 @@ gmbus_xfer(struct i2c_adapter *adapter,
>>  
>>  	reg_offset = dev_priv->gpio_mmio_base;
>>  
>> +retry:
>>  	I915_WRITE(GMBUS0 + reg_offset, bus->reg0);
>>  
>> -	for (i = 0; i < num; i++) {
>> +	for (; i < num; i += inc) {
>> +		inc = 1;
>>  		if (gmbus_is_index_read(msgs, i, num)) {
>>  			ret = gmbus_xfer_index_read(dev_priv, &msgs[i]);
>> -			i += 1;  /* set i to the index of the read xfer */
>> +			inc = 2; /* an index read is two msgs */
>>  		} else if (msgs[i].flags & I2C_M_RD) {
>>  			ret = gmbus_xfer_read(dev_priv, &msgs[i], 0);
>>  		} else {
>> @@ -576,6 +578,18 @@ clear_err:
>>  			 adapter->name, msgs[i].addr,
>>  			 (msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len);
>>  
>> +	/*
>> +	 * Passive adapters sometimes NAK the first probe. Retry the first
>> +	 * message once on -ENXIO for GMBUS transfers; the bit banging algorithm
>> +	 * has retries internally. See also the retry loop in
>> +	 * drm_do_probe_ddc_edid, which bails out on the first -ENXIO.
>> +	 */
>> +	if (ret == -ENXIO && i == 0 && try++ == 0) {
>> +		DRM_DEBUG_KMS("GMBUS [%s] NAK on first message, retry\n",
>> +			      adapter->name);
>> +		goto retry;
>> +	}
>> +
>>  	goto out;
>>  
>>  timeout:
>> -- 
>> 2.1.4
>
> -- 
> Ville Syrjälä
> Intel OTC

-- 
Jani Nikula, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v5] drm/i915: Fix DDC probe for passive adapters
@ 2015-06-02 16:43                 ` Jani Nikula
  0 siblings, 0 replies; 30+ messages in thread
From: Jani Nikula @ 2015-06-02 16:43 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, stable

On Tue, 02 Jun 2015, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> On Tue, Jun 02, 2015 at 07:21:15PM +0300, Jani Nikula wrote:
>> Passive DP->DVI/HDMI dongles on DP++ ports show up to the system as HDMI
>> devices, as they do not have a sink device in them to respond to any AUX
>> traffic. When probing these dongles over the DDC, sometimes they will
>> NAK the first attempt even though the transaction is valid and they
>> support the DDC protocol. The retry loop inside of
>> drm_do_probe_ddc_edid() would normally catch this case and try the
>> transaction again, resulting in success.
>> 
>> That, however, was thwarted by the fix for [1]:
>> 
>> commit 9292f37e1f5c79400254dca46f83313488093825
>> Author: Eugeni Dodonov <eugeni.dodonov@intel.com>
>> Date:   Thu Jan 5 09:34:28 2012 -0200
>> 
>>     drm: give up on edid retries when i2c bus is not responding
>> 
>> This added code to exit immediately if the return code from the
>> i2c_transfer function was -ENXIO in order to reduce the amount of time
>> spent in waiting for unresponsive or disconnected devices. That was
>> possible because the underlying i2c bit banging algorithm had retries of
>> its own (which, of course, were part of the reason for the bug the
>> commit fixes).
>> 
>> Since its introduction in
>> 
>> commit f899fc64cda8569d0529452aafc0da31c042df2e
>> Author: Chris Wilson <chris@chris-wilson.co.uk>
>> Date:   Tue Jul 20 15:44:45 2010 -0700
>> 
>>     drm/i915: use GMBUS to manage i2c links
>> 
>> we've been flipping back and forth enabling the GMBUS transfers, but
>> we've settled since then. The GMBUS implementation does not do any
>> retries, however, bailing out of the drm_do_probe_ddc_edid() retry loop
>> on first encounter of -ENXIO. This, combined with Eugeni's commit, broke
>> the retry on -ENXIO.
>> 
>> Retry GMBUS once on -ENXIO on first message to mitigate the issues with
>> passive adapters.
>> 
>> This patch is based on the work, and commit message, by Todd Previte
>> <tprevite@gmail.com>.
>> 
>> [1] https://bugs.freedesktop.org/show_bug.cgi?id=41059
>> 
>> v2: Don't retry if using bit banging.
>> 
>> v3: Move retry within gmbux_xfer, retry only on first message.
>> 
>> v4: Initialize GMBUS0 on retry (Ville).
>> 
>> v5: Take index reads into account (Ville).
>> 
>> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85924
>> Cc: Todd Previte <tprevite@gmail.com>
>> Cc: stable@vger.kernel.org
>> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
>
> OK, I think I'm done shooting any more holes into this one:
> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

\o/

Thanks for all the review. I suck.

> Hopefully it works too. I don't have very good intuition into the gmbus
> hardware. I think one day I need to set up a bit-banged i2c slave and
> play around with it just for fun.

AFAICT it should be functionally equivalent to the v1 patch that got
tested in the referenced bug. I'm hoping to get a test result for this
one too.


>
>> ---
>>  drivers/gpu/drm/i915/intel_i2c.c | 20 +++++++++++++++++---
>>  1 file changed, 17 insertions(+), 3 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
>> index 92072f56e418..a64f26c670af 100644
>> --- a/drivers/gpu/drm/i915/intel_i2c.c
>> +++ b/drivers/gpu/drm/i915/intel_i2c.c
>> @@ -486,7 +486,7 @@ gmbus_xfer(struct i2c_adapter *adapter,
>>  					       struct intel_gmbus,
>>  					       adapter);
>>  	struct drm_i915_private *dev_priv = bus->dev_priv;
>> -	int i, reg_offset;
>> +	int i = 0, inc, try = 0, reg_offset;
>>  	int ret = 0;
>>  
>>  	intel_aux_display_runtime_get(dev_priv);
>> @@ -499,12 +499,14 @@ gmbus_xfer(struct i2c_adapter *adapter,
>>  
>>  	reg_offset = dev_priv->gpio_mmio_base;
>>  
>> +retry:
>>  	I915_WRITE(GMBUS0 + reg_offset, bus->reg0);
>>  
>> -	for (i = 0; i < num; i++) {
>> +	for (; i < num; i += inc) {
>> +		inc = 1;
>>  		if (gmbus_is_index_read(msgs, i, num)) {
>>  			ret = gmbus_xfer_index_read(dev_priv, &msgs[i]);
>> -			i += 1;  /* set i to the index of the read xfer */
>> +			inc = 2; /* an index read is two msgs */
>>  		} else if (msgs[i].flags & I2C_M_RD) {
>>  			ret = gmbus_xfer_read(dev_priv, &msgs[i], 0);
>>  		} else {
>> @@ -576,6 +578,18 @@ clear_err:
>>  			 adapter->name, msgs[i].addr,
>>  			 (msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len);
>>  
>> +	/*
>> +	 * Passive adapters sometimes NAK the first probe. Retry the first
>> +	 * message once on -ENXIO for GMBUS transfers; the bit banging algorithm
>> +	 * has retries internally. See also the retry loop in
>> +	 * drm_do_probe_ddc_edid, which bails out on the first -ENXIO.
>> +	 */
>> +	if (ret == -ENXIO && i == 0 && try++ == 0) {
>> +		DRM_DEBUG_KMS("GMBUS [%s] NAK on first message, retry\n",
>> +			      adapter->name);
>> +		goto retry;
>> +	}
>> +
>>  	goto out;
>>  
>>  timeout:
>> -- 
>> 2.1.4
>
> -- 
> Ville Syrjälä
> Intel OTC

-- 
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v5] drm/i915: Fix DDC probe for passive adapters
  2015-06-02 16:21             ` Jani Nikula
  (?)
  (?)
@ 2015-06-03  0:51             ` shuang.he
  -1 siblings, 0 replies; 30+ messages in thread
From: shuang.he @ 2015-06-03  0:51 UTC (permalink / raw)
  To: shuang.he, lei.a.liu, intel-gfx, jani.nikula

Tested-By: Intel Graphics QA PRTS (Patch Regression Test System Contact: shuang.he@intel.com)
Task id: 6525
-------------------------------------Summary-------------------------------------
Platform          Delta          drm-intel-nightly          Series Applied
PNV                                  276/276              276/276
ILK                                  303/303              303/303
SNB                 -1              315/315              314/315
IVB                                  343/343              343/343
BYT                                  287/287              287/287
BDW                 -1              321/321              320/321
-------------------------------------Detailed-------------------------------------
Platform  Test                                drm-intel-nightly          Series Applied
*SNB  igt@pm_rpm@dpms-mode-unset-non-lpsp      PASS(1)      DMESG_WARN(1)
(dmesg patch applied)WARNING:at_drivers/gpu/drm/i915/intel_uncore.c:#assert_device_not_suspended[i915]()@WARNING:.* at .* assert_device_not_suspended+0x
*BDW  igt@gem_gtt_hog      PASS(1)      DMESG_WARN(1)
(dmesg patch applied)WARNING:at_drivers/gpu/drm/i915/intel_display.c:#assert_plane[i915]()@WARNING:.* at .* assert_plane
assertion_failure@assertion failure
WARNING:at_drivers/gpu/drm/drm_irq.c:#drm_wait_one_vblank[drm]()@WARNING:.* at .* drm_wait_one_vblank+0x
Note: You need to pay more attention to line start with '*'
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v5] drm/i915: Fix DDC probe for passive adapters
  2015-06-02 16:40               ` Ville Syrjälä
  (?)
  (?)
@ 2015-06-09  7:44               ` Jani Nikula
  -1 siblings, 0 replies; 30+ messages in thread
From: Jani Nikula @ 2015-06-09  7:44 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, stable

On Tue, 02 Jun 2015, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> On Tue, Jun 02, 2015 at 07:21:15PM +0300, Jani Nikula wrote:
>> Passive DP->DVI/HDMI dongles on DP++ ports show up to the system as HDMI
>> devices, as they do not have a sink device in them to respond to any AUX
>> traffic. When probing these dongles over the DDC, sometimes they will
>> NAK the first attempt even though the transaction is valid and they
>> support the DDC protocol. The retry loop inside of
>> drm_do_probe_ddc_edid() would normally catch this case and try the
>> transaction again, resulting in success.
>> 
>> That, however, was thwarted by the fix for [1]:
>> 
>> commit 9292f37e1f5c79400254dca46f83313488093825
>> Author: Eugeni Dodonov <eugeni.dodonov@intel.com>
>> Date:   Thu Jan 5 09:34:28 2012 -0200
>> 
>>     drm: give up on edid retries when i2c bus is not responding
>> 
>> This added code to exit immediately if the return code from the
>> i2c_transfer function was -ENXIO in order to reduce the amount of time
>> spent in waiting for unresponsive or disconnected devices. That was
>> possible because the underlying i2c bit banging algorithm had retries of
>> its own (which, of course, were part of the reason for the bug the
>> commit fixes).
>> 
>> Since its introduction in
>> 
>> commit f899fc64cda8569d0529452aafc0da31c042df2e
>> Author: Chris Wilson <chris@chris-wilson.co.uk>
>> Date:   Tue Jul 20 15:44:45 2010 -0700
>> 
>>     drm/i915: use GMBUS to manage i2c links
>> 
>> we've been flipping back and forth enabling the GMBUS transfers, but
>> we've settled since then. The GMBUS implementation does not do any
>> retries, however, bailing out of the drm_do_probe_ddc_edid() retry loop
>> on first encounter of -ENXIO. This, combined with Eugeni's commit, broke
>> the retry on -ENXIO.
>> 
>> Retry GMBUS once on -ENXIO on first message to mitigate the issues with
>> passive adapters.
>> 
>> This patch is based on the work, and commit message, by Todd Previte
>> <tprevite@gmail.com>.
>> 
>> [1] https://bugs.freedesktop.org/show_bug.cgi?id=41059
>> 
>> v2: Don't retry if using bit banging.
>> 
>> v3: Move retry within gmbux_xfer, retry only on first message.
>> 
>> v4: Initialize GMBUS0 on retry (Ville).
>> 
>> v5: Take index reads into account (Ville).
>> 
>> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85924
>> Cc: Todd Previte <tprevite@gmail.com>
>> Cc: stable@vger.kernel.org
>> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
>
> OK, I think I'm done shooting any more holes into this one:
> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
>
> Hopefully it works too. I don't have very good intuition into the gmbus
> hardware. I think one day I need to set up a bit-banged i2c slave and
> play around with it just for fun.

Pushed to drm-intel-fixes, with Tested-by from Jim Bride. Thanks for the
review.

BR,
Jani.



>
>> ---
>>  drivers/gpu/drm/i915/intel_i2c.c | 20 +++++++++++++++++---
>>  1 file changed, 17 insertions(+), 3 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
>> index 92072f56e418..a64f26c670af 100644
>> --- a/drivers/gpu/drm/i915/intel_i2c.c
>> +++ b/drivers/gpu/drm/i915/intel_i2c.c
>> @@ -486,7 +486,7 @@ gmbus_xfer(struct i2c_adapter *adapter,
>>  					       struct intel_gmbus,
>>  					       adapter);
>>  	struct drm_i915_private *dev_priv = bus->dev_priv;
>> -	int i, reg_offset;
>> +	int i = 0, inc, try = 0, reg_offset;
>>  	int ret = 0;
>>  
>>  	intel_aux_display_runtime_get(dev_priv);
>> @@ -499,12 +499,14 @@ gmbus_xfer(struct i2c_adapter *adapter,
>>  
>>  	reg_offset = dev_priv->gpio_mmio_base;
>>  
>> +retry:
>>  	I915_WRITE(GMBUS0 + reg_offset, bus->reg0);
>>  
>> -	for (i = 0; i < num; i++) {
>> +	for (; i < num; i += inc) {
>> +		inc = 1;
>>  		if (gmbus_is_index_read(msgs, i, num)) {
>>  			ret = gmbus_xfer_index_read(dev_priv, &msgs[i]);
>> -			i += 1;  /* set i to the index of the read xfer */
>> +			inc = 2; /* an index read is two msgs */
>>  		} else if (msgs[i].flags & I2C_M_RD) {
>>  			ret = gmbus_xfer_read(dev_priv, &msgs[i], 0);
>>  		} else {
>> @@ -576,6 +578,18 @@ clear_err:
>>  			 adapter->name, msgs[i].addr,
>>  			 (msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len);
>>  
>> +	/*
>> +	 * Passive adapters sometimes NAK the first probe. Retry the first
>> +	 * message once on -ENXIO for GMBUS transfers; the bit banging algorithm
>> +	 * has retries internally. See also the retry loop in
>> +	 * drm_do_probe_ddc_edid, which bails out on the first -ENXIO.
>> +	 */
>> +	if (ret == -ENXIO && i == 0 && try++ == 0) {
>> +		DRM_DEBUG_KMS("GMBUS [%s] NAK on first message, retry\n",
>> +			      adapter->name);
>> +		goto retry;
>> +	}
>> +
>>  	goto out;
>>  
>>  timeout:
>> -- 
>> 2.1.4
>
> -- 
> Ville Syrjälä
> Intel OTC

-- 
Jani Nikula, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2015-06-09  7:42 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-28  8:51 [PATCH] drm/i915: Fix DDC probe for passive adapters Jani Nikula
2015-05-28  8:51 ` Jani Nikula
2015-05-28 10:05 ` [PATCH v2] " Jani Nikula
2015-05-28 10:48   ` [Intel-gfx] " Ville Syrjälä
2015-05-28 10:48     ` Ville Syrjälä
2015-05-28 11:36     ` Jani Nikula
2015-05-28 12:26       ` Ville Syrjälä
2015-05-28 12:26         ` Ville Syrjälä
2015-05-28 12:28       ` Daniel Vetter
2015-05-28 12:28         ` Daniel Vetter
2015-05-28 12:34         ` Jani Nikula
2015-05-28 12:34           ` Jani Nikula
2015-05-31 12:03   ` shuang.he
2015-06-02  8:29   ` [PATCH v3] " Jani Nikula
2015-06-02 10:35     ` [Intel-gfx] " Ville Syrjälä
2015-06-02 10:35       ` Ville Syrjälä
2015-06-02 10:42       ` [PATCH v4] " Jani Nikula
2015-06-02 13:09         ` Ville Syrjälä
2015-06-02 13:09           ` Ville Syrjälä
2015-06-02 16:21           ` [PATCH v5] " Jani Nikula
2015-06-02 16:21             ` Jani Nikula
2015-06-02 16:40             ` Ville Syrjälä
2015-06-02 16:40               ` Ville Syrjälä
2015-06-02 16:43               ` Jani Nikula
2015-06-02 16:43                 ` Jani Nikula
2015-06-09  7:44               ` Jani Nikula
2015-06-03  0:51             ` shuang.he
2015-06-02 15:28         ` [PATCH v4] " shuang.he
2015-06-02 13:07     ` [PATCH v3] " shuang.he
2015-05-31  9:43 ` [PATCH] " shuang.he

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.