[5/9] drm: Wait 1ms before retrying aux transactions on EBUSY.

Submitted by Rodrigo Vivi on Nov. 26, 2015, 12:04 a.m.

Details

Message ID 1448496245-1495-6-git-send-email-rodrigo.vivi@intel.com
State New
Headers show
Series "Organize aux retries v3" ( rev: 1 ) in Intel GFX

Not browsing as part of any series.

Commit Message

Rodrigo Vivi Nov. 26, 2015, 12:04 a.m.
DP Specs isn't really clear about the amount of retries,
but for cases it mentions retries it also mention times that
vary from 300us to 1ms.

For many cases hardware can handled the timeouts before retry
is possible and allowed, but for many other cases it is better
to wait and give time so the aux channels can recover.

For instance one general case there is when downstream device
is waking up from sleep states generating HPD so it might take
up to 1ms before getting responsive.

I believe with this msleep we could minimize the 32 times retries
and still let Dell monitors happy, but I don't have this monitor
to test here so let's just add the sleep for now and still retry
32 times.

v2: Include doc comment.
    Also apply the 1ms to i2c helper.
    Use usleep_range for better precision as suggested by Jani.

Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Dave Airlie <airlied@redhat.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Tested-by: Daniel Stone <daniels@collabora.com> # v1 on SKL
---
 drivers/gpu/drm/drm_dp_helper.c | 10 +++++++---
 include/drm/drm_dp_helper.h     |  3 ++-
 2 files changed, 9 insertions(+), 4 deletions(-)

Patch hide | download patch | download mbox

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 2e26097..e328715 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -202,9 +202,11 @@  static int drm_dp_dpcd_access(struct drm_dp_aux *aux, u8 request,
 			if (err == -EAGAIN)
 				continue;
 
-			/* FIXME: On BUSY we could wait before retrying */
-			if (err == -EBUSY)
+			/* Give a time for aux channels to recover */
+			if (err == -EBUSY) {
+				usleep_range(1000, 1000);
 				continue;
+			}
 
 			return err;
 		}
@@ -557,8 +559,10 @@  static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
 			 * -EAGAIN retries are handled by i2c layer with
 			 * timeouts for repeated -EAGAINs
 			 */
-			if (ret == -EBUSY)
+			if (ret == -EBUSY) {
+				usleep_range(1000, 1000);
 				continue;
+			}
 
 			DRM_DEBUG_KMS("transaction failed: %d\n", ret);
 			return ret;
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 518fc1b..ac9de5e 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -757,7 +757,8 @@  struct drm_dp_aux {
 	 * - -EPROTO: On a short, helpers will return -EPROTO to make it simpler
 	 *   to check for failure.
 	 * - -EBUSY: When BUSY helpers will attempt retries before propagating
-	 *   this error.
+	 *   this error, with 1ms between attempts to give a time for downstream
+	 *   devices to recover.
 	 * - -EAGAIN: DPCD helper will attempt immediatelly retries before
 	 *   propagating this error. i2c helper will only propagate directly
 	 *   since i2c layer already perform retries with timeouts for repeated