Tomasz Lis <[email protected]> writes:

> From: Oscar Mateo <[email protected]>
>
> SFC (Scaler & Format Converter) units are shared between VD and VEBoxes.
> They also happen to have separate reset bits. So, whenever we want to reset
> one or more of the media engines, we have to make sure the SFCs do not
> change owner in the process and, if this owner happens to be one of the
> engines being reset, we need to reset the SFC as well.
>
> This happens in 4 steps:
>
> 1) Tell the engine that a software reset is going to happen. The engine
> will then try to force lock the SFC (if currently locked, it will
> remain so; if currently unlocked, it will ignore this and all new lock
> requests).
>
> 2) Poll the ack bit to make sure the hardware has received the forced
> lock from the driver. Once this bit is set, it indicates SFC status
> (lock or unlock) will not change anymore (until we tell the engine it
> is safe to unlock again).
>
> 3) Check the usage bit to see if the SFC has ended up being locked to
> the engine we want to reset. If this is the case, we have to reset
> the SFC as well.
>
> 4) Unlock all the SFCs once the reset sequence is completed.
>
> Obviously, if we are resetting the whole GPU, we don't have to worry
> about all of this.
>
> BSpec: 10989
> BSpec: 10990
> BSpec: 10954
> BSpec: 10955
> BSpec: 10956
> BSpec: 19212
>
> Signed-off-by: Tomasz Lis <[email protected]>
> Signed-off-by: Oscar Mateo <[email protected]>
> Signed-off-by: Michel Thierry <[email protected]>
> Cc: Michel Thierry <[email protected]>
> Cc: Joonas Lahtinen <[email protected]>
> Cc: Chris Wilson <[email protected]>
> Cc: Daniele Ceraolo Spurio <[email protected]>
> ---
>  drivers/gpu/drm/i915/i915_reg.h     |  18 +++++++
>  drivers/gpu/drm/i915/intel_uncore.c | 105 
> ++++++++++++++++++++++++++++++++++--
>  2 files changed, 119 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 8d089ef..7b4dffa 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -330,6 +330,24 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
>  #define  GEN11_GRDOM_MEDIA4          (1 << 8)
>  #define  GEN11_GRDOM_VECS            (1 << 13)
>  #define  GEN11_GRDOM_VECS2           (1 << 14)
> +#define  GEN11_GRDOM_SFC0            (1 << 17)
> +#define  GEN11_GRDOM_SFC1            (1 << 18)
> +
> +#define  GEN11_VCS_SFC_RESET_BIT(instance)   (GEN11_GRDOM_SFC0 << 
> ((instance) >> 1))
> +#define  GEN11_VECS_SFC_RESET_BIT(instance)  (GEN11_GRDOM_SFC0 << (instance))
> +
> +#define GEN11_VCS_SFC_FORCED_LOCK(engine)    _MMIO((engine)->mmio_base + 
> 0x88C)
> +#define   GEN11_VCS_SFC_FORCED_LOCK_BIT              (1 << 0)
> +#define GEN11_VCS_SFC_LOCK_STATUS(engine)    _MMIO((engine)->mmio_base + 
> 0x890)
> +#define   GEN11_VCS_SFC_USAGE_BIT            (1 << 0)
> +#define   GEN11_VCS_SFC_LOCK_ACK_BIT         (1 << 1)
> +
> +#define GEN11_VECS_SFC_FORCED_LOCK(engine)   _MMIO((engine)->mmio_base + 
> 0x201C)
> +#define   GEN11_VECS_SFC_FORCED_LOCK_BIT     (1 << 0)
> +#define GEN11_VECS_SFC_LOCK_ACK(engine)              
> _MMIO((engine)->mmio_base + 0x2018)
> +#define   GEN11_VECS_SFC_LOCK_ACK_BIT                (1 << 0)
> +#define GEN11_VECS_SFC_USAGE(engine)         _MMIO((engine)->mmio_base + 
> 0x2014)
> +#define   GEN11_VECS_SFC_USAGE_BIT           (1 << 0)
>  
>  #define RING_PP_DIR_BASE(engine)     _MMIO((engine)->mmio_base + 0x228)
>  #define RING_PP_DIR_BASE_READ(engine)        _MMIO((engine)->mmio_base + 
> 0x518)
> diff --git a/drivers/gpu/drm/i915/intel_uncore.c 
> b/drivers/gpu/drm/i915/intel_uncore.c
> index 9289515..481e70e 100644
> --- a/drivers/gpu/drm/i915/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/intel_uncore.c
> @@ -1931,6 +1931,95 @@ static int gen6_reset_engines(struct drm_i915_private 
> *dev_priv,
>       return gen6_hw_domain_reset(dev_priv, hw_mask);
>  }
>  
> +static u32 gen11_lock_sfc(struct drm_i915_private *dev_priv,
> +                       struct intel_engine_cs *engine)
> +{
> +     u8 vdbox_sfc_access = INTEL_INFO(dev_priv)->vdbox_sfc_access;
> +     i915_reg_t sfc_forced_lock;
> +     u32 sfc_forced_lock_bit;
> +     i915_reg_t sfc_forced_lock_ack;
> +     u32 sfc_forced_lock_ack_bit;
> +     i915_reg_t sfc_usage;
> +     u32 sfc_usage_bit;
> +     u32 sfc_reset_bit;
> +

You can save many lines here by grouping by type.
-Mika



> +     switch (engine->class) {
> +     case VIDEO_DECODE_CLASS:
> +             if ((BIT(engine->instance) & vdbox_sfc_access) == 0)
> +                     return 0;
> +             sfc_forced_lock = GEN11_VCS_SFC_FORCED_LOCK(engine);
> +             sfc_forced_lock_bit = GEN11_VCS_SFC_FORCED_LOCK_BIT;
> +             sfc_forced_lock_ack = GEN11_VCS_SFC_LOCK_STATUS(engine);
> +             sfc_forced_lock_ack_bit  = GEN11_VCS_SFC_LOCK_ACK_BIT;
> +             sfc_usage = GEN11_VCS_SFC_LOCK_STATUS(engine);
> +             sfc_usage_bit = GEN11_VCS_SFC_USAGE_BIT;
> +             sfc_reset_bit = GEN11_VCS_SFC_RESET_BIT(engine->instance);
> +             break;
> +     case VIDEO_ENHANCEMENT_CLASS:
> +             sfc_forced_lock = GEN11_VECS_SFC_FORCED_LOCK(engine);
> +             sfc_forced_lock_bit = GEN11_VECS_SFC_FORCED_LOCK_BIT;
> +             sfc_forced_lock_ack = GEN11_VECS_SFC_LOCK_ACK(engine);
> +             sfc_forced_lock_ack_bit  = GEN11_VECS_SFC_LOCK_ACK_BIT;
> +             sfc_usage = GEN11_VECS_SFC_USAGE(engine);
> +             sfc_usage_bit = GEN11_VECS_SFC_USAGE_BIT;
> +             sfc_reset_bit = GEN11_VECS_SFC_RESET_BIT(engine->instance);
> +             break;
> +     default:
> +             return 0;
> +     }
> +
> +     /*
> +      * Tell the engine that a software reset is going to happen. The engine
> +      * will then try to force lock the SFC (if currently locked, it will
> +      * remain so until we tell the engine it is safe to unlock; if currently
> +      * unlocked, it will ignore this and all new lock requests). If SFC
> +      * ends up being locked to the engine we want to reset, we have to reset
> +      * it as well (we will unlock it once the reset sequence is completed).
> +      */
> +     I915_WRITE(sfc_forced_lock, I915_READ(sfc_forced_lock) |
> +                                 sfc_forced_lock_bit);
> +
> +     if (intel_wait_for_register(dev_priv,
> +                                 sfc_forced_lock_ack,
> +                                 sfc_forced_lock_ack_bit,
> +                                 sfc_forced_lock_ack_bit,
> +                                 500)) {
> +             DRM_DEBUG_DRIVER("Wait for SFC forced lock ack failed\n");
> +             return 0;
> +     }
> +
> +     if ((I915_READ(sfc_usage) & sfc_usage_bit) == sfc_usage_bit)
> +             return sfc_reset_bit;
> +
> +     return 0;
> +}
> +
> +static void gen11_unlock_sfc(struct drm_i915_private *dev_priv,
> +                          struct intel_engine_cs *engine)
> +{
> +     u8 vdbox_sfc_access = INTEL_INFO(dev_priv)->vdbox_sfc_access;
> +     i915_reg_t sfc_forced_lock;
> +     u32 sfc_forced_lock_bit;
> +
> +     switch (engine->class) {
> +     case VIDEO_DECODE_CLASS:
> +             if ((BIT(engine->instance) & vdbox_sfc_access) == 0)
> +                     return;
> +             sfc_forced_lock = GEN11_VCS_SFC_FORCED_LOCK(engine);
> +             sfc_forced_lock_bit = GEN11_VCS_SFC_FORCED_LOCK_BIT;
> +             break;
> +     case VIDEO_ENHANCEMENT_CLASS:
> +             sfc_forced_lock = GEN11_VECS_SFC_FORCED_LOCK(engine);
> +             sfc_forced_lock_bit = GEN11_VECS_SFC_FORCED_LOCK_BIT;
> +             break;
> +     default:
> +             return;
> +     }
> +
> +     I915_WRITE(sfc_forced_lock, (I915_READ(sfc_forced_lock) &
> +                                  ~sfc_forced_lock_bit));
> +}
> +
>  /**
>   * gen11_reset_engines - reset individual engines
>   * @dev_priv: i915 device
> @@ -1959,20 +2048,28 @@ static int gen11_reset_engines(struct 
> drm_i915_private *dev_priv,
>               [VECS2] = GEN11_GRDOM_VECS2,
>       };
>       u32 hw_mask;
> +     unsigned int tmp;
> +     int ret;
>  
>       BUILD_BUG_ON(VECS2 + 1 != I915_NUM_ENGINES);
>  
>       if (engine_mask == ALL_ENGINES) {
>               hw_mask = GEN11_GRDOM_FULL;
>       } else {
> -             unsigned int tmp;
> -
>               hw_mask = 0;
> -             for_each_engine_masked(engine, dev_priv, engine_mask, tmp)
> +             for_each_engine_masked(engine, dev_priv, engine_mask, tmp) {
>                       hw_mask |= hw_engine_mask[engine->id];
> +                     hw_mask |= gen11_lock_sfc(dev_priv, engine);
> +             }
>       }
>  
> -     return gen6_hw_domain_reset(dev_priv, hw_mask);
> +     ret = gen6_hw_domain_reset(dev_priv, hw_mask);
> +
> +     if (engine_mask != ALL_ENGINES)
> +             for_each_engine_masked(engine, dev_priv, engine_mask, tmp)
> +                     gen11_unlock_sfc(dev_priv, engine);
> +
> +     return ret;
>  }
>  
>  /**
> -- 
> 2.7.4
>
> _______________________________________________
> Intel-gfx mailing list
> [email protected]
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to