[Intel-gfx] [PATCH 1/3] drm/i915: Use intel_engine_stop_cs when stopping ringbuffer
Chris Wilson
chris at chris-wilson.co.uk
Thu Feb 28 16:34:53 UTC 2019
Quoting Mika Kuoppala (2019-02-28 16:14:11)
> We have an exported function for stopping the engine before
> disabling a ringbuffer. Take it into use.
>
> v2: use fw on empty check
> v3: tail is tail
>
> Cc: Chris Wilson <chris at chris-wilson.co.uk>
> Signed-off-by: Mika Kuoppala <mika.kuoppala at linux.intel.com>
> Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>
> ---
> drivers/gpu/drm/i915/intel_engine_cs.c | 3 ++
> drivers/gpu/drm/i915/intel_ringbuffer.c | 41 ++++++++++++++-----------
> 2 files changed, 26 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c
> index df8f88142f1d..e35dc0386bf6 100644
> --- a/drivers/gpu/drm/i915/intel_engine_cs.c
> +++ b/drivers/gpu/drm/i915/intel_engine_cs.c
> @@ -856,6 +856,9 @@ void intel_engine_cancel_stop_cs(struct intel_engine_cs *engine)
> {
> struct drm_i915_private *dev_priv = engine->i915;
>
> + if (INTEL_GEN(dev_priv) < 3)
> + return;
> +
> GEM_TRACE("%s\n", engine->name);
>
> I915_WRITE_FW(RING_MI_MODE(engine->mmio_base),
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
> index 1b96b0960adc..5fe28d9087b7 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
> @@ -604,26 +604,32 @@ static void ring_setup_status_page(struct intel_engine_cs *engine)
> flush_cs_tlb(engine);
> }
>
> +static bool ring_is_empty(struct intel_engine_cs *engine)
> +{
> + struct drm_i915_private *dev_priv = engine->i915;
> + const u32 base = engine->mmio_base;
> +
> + return (I915_READ_FW(RING_HEAD(base)) & HEAD_ADDR) ==
> + (I915_READ_FW(RING_TAIL(base)) & TAIL_ADDR);
> +}
> +
> static bool stop_ring(struct intel_engine_cs *engine)
> {
> struct drm_i915_private *dev_priv = engine->i915;
> + int ret;
>
> - if (INTEL_GEN(dev_priv) > 2) {
> - I915_WRITE_MODE(engine, _MASKED_BIT_ENABLE(STOP_RING));
> - if (intel_wait_for_register(dev_priv,
> - RING_MI_MODE(engine->mmio_base),
> - MODE_IDLE,
> - MODE_IDLE,
> - 1000)) {
> - DRM_ERROR("%s : timed out trying to stop ring\n",
> - engine->name);
> - /* Sometimes we observe that the idle flag is not
> - * set even though the ring is empty. So double
> - * check before giving up.
> - */
> - if (I915_READ_HEAD(engine) != I915_READ_TAIL(engine))
> - return false;
> - }
> + ret = intel_engine_stop_cs(engine);
> + if (ret == -ENODEV)
> + ret = 0;
> +
> + if (ret) {
> + /*
> + * Sometimes we observe that the idle flag is not
> + * set even though the ring is empty. So double
> + * check before giving up.
> + */
> + if (!ring_is_empty(engine))
> + return false;
Hmm, thinking more about this, shouldn't we push this down to stop_cs()?
If that's reporting an error in a situation where we can determine that
the ring is idle anyway, we can report the stop_cs succeeded.
-Chris
More information about the Intel-gfx
mailing list