Blob Blame History Raw
From 1d1a9774e40414148ecebbdb713746bfb6f9a561 Mon Sep 17 00:00:00 2001
From: Michal Wajdeczko <michal.wajdeczko@intel.com>
Date: Fri, 7 Apr 2017 16:01:44 +0000
Subject: [PATCH] drm/i915: Extend intel_wait_for_register_fw() with fast timeout
Git-commit: 1d1a9774e40414148ecebbdb713746bfb6f9a561
Patch-mainline: v4.13-rc1
References: FATE#322643 bsc#1055900

In some cases we may want to spend more time in atomic wait than
hardcoded 2us. Let's add additional fast timeout parameter to allow
flexible configuration of atomic timeout before switching into heavy wait.
Add also possibility to return registry value to avoid extra read.

V2: use explicit fast timeout (Tvrtko/Chris)    allow returning register value (Chris)

Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
Suggested-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Link: http://patchwork.freedesktop.org/patch/msgid/20170407160145.181328-1-michal.wajdeczko@intel.com
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Takashi Iwai <tiwai@suse.de>

---
 drivers/gpu/drm/i915/i915_drv.h     |   14 +++++++++++++-
 drivers/gpu/drm/i915/intel_uncore.c |   34 +++++++++++++++++++++++-----------
 2 files changed, 36 insertions(+), 12 deletions(-)

--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3099,11 +3099,23 @@ int intel_wait_for_register(struct drm_i
 			    const u32 mask,
 			    const u32 value,
 			    const unsigned long timeout_ms);
+int __intel_wait_for_register_fw(struct drm_i915_private *dev_priv,
+				 i915_reg_t reg,
+				 const u32 mask,
+				 const u32 value,
+				 const unsigned int fast_timeout_us,
+				 const unsigned int slow_timeout_ms,
+				 u32 *out_value);
+static inline
 int intel_wait_for_register_fw(struct drm_i915_private *dev_priv,
 			       i915_reg_t reg,
 			       const u32 mask,
 			       const u32 value,
-			       const unsigned int timeout_ms);
+			       const unsigned int timeout_ms)
+{
+	return __intel_wait_for_register_fw(dev_priv, reg, mask, value,
+					    2, timeout_ms, NULL);
+}
 
 static inline bool intel_gvt_active(struct drm_i915_private *dev_priv)
 {
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -1585,19 +1585,21 @@ static int gen6_reset_engines(struct drm
 }
 
 /**
- * intel_wait_for_register_fw - wait until register matches expected state
+ * __intel_wait_for_register_fw - wait until register matches expected state
  * @dev_priv: the i915 device
  * @reg: the register to read
  * @mask: mask to apply to register value
  * @value: expected value
- * @timeout_ms: timeout in millisecond
+ * @fast_timeout_us: fast timeout in microsecond for atomic/tight wait
+ * @slow_timeout_ms: slow timeout in millisecond
+ * @out_value: optional placeholder to hold registry value
  *
  * This routine waits until the target register @reg contains the expected
  * @value after applying the @mask, i.e. it waits until ::
  *
  *     (I915_READ_FW(reg) & mask) == value
  *
- * Otherwise, the wait will timeout after @timeout_ms milliseconds.
+ * Otherwise, the wait will timeout after @slow_timeout_ms milliseconds.
  *
  * Note that this routine assumes the caller holds forcewake asserted, it is
  * not suitable for very long waits. See intel_wait_for_register() if you
@@ -1606,16 +1608,26 @@ static int gen6_reset_engines(struct drm
  *
  * Returns 0 if the register matches the desired condition, or -ETIMEOUT.
  */
-int intel_wait_for_register_fw(struct drm_i915_private *dev_priv,
-			       i915_reg_t reg,
-			       const u32 mask,
-			       const u32 value,
-			       const unsigned int timeout_ms)
+int __intel_wait_for_register_fw(struct drm_i915_private *dev_priv,
+				 i915_reg_t reg,
+				 const u32 mask,
+				 const u32 value,
+				 const unsigned int fast_timeout_us,
+				 const unsigned int slow_timeout_ms,
+				 u32 *out_value)
 {
-#define done ((I915_READ_FW(reg) & mask) == value)
-	int ret = wait_for_us(done, 2);
+	u32 reg_value;
+#define done (((reg_value = I915_READ_FW(reg)) & mask) == value)
+	int ret;
+
+	if (fast_timeout_us > 10)
+		ret = _wait_for(done, fast_timeout_us, 10);
+	else
+		ret = _wait_for_atomic(done, fast_timeout_us, 0);
 	if (ret)
-		ret = wait_for(done, timeout_ms);
+		ret = wait_for(done, slow_timeout_ms);
+	if (out_value)
+		*out_value = reg_value;
 	return ret;
 #undef done
 }