diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 59433df46859fdeed05f98f0cd5b96e28d661ee0..bb6fc1e08a52daddd61d95e589cf24685fcd714c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3088,11 +3088,23 @@ int intel_wait_for_register(struct drm_i915_private *dev_priv, 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) { diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index bcabf54ef854439a10cb72d9607944d4ccfce157..ace099381d1161df02fffe2b43d8951b7c0c7cfa 100644 --- 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_i915_private *dev_priv, } /** - * 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_i915_private *dev_priv, * * 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) -{ -#define done ((I915_READ_FW(reg) & mask) == value) - int ret = wait_for_us(done, 2); +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) +{ + 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 }