Quoting Tomasz Lis (2018-10-31 14:24:13) > From: Oscar Mateo <oscar.mateo@xxxxxxxxx> > > 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 <tomasz.lis@xxxxxxxxx> > Signed-off-by: Oscar Mateo <oscar.mateo@xxxxxxxxx> > Signed-off-by: Michel Thierry <michel.thierry@xxxxxxxxx> > Cc: Michel Thierry <michel.thierry@xxxxxxxxx> > Cc: Joonas Lahtinen <joonas.lahtinen@xxxxxxxxxxxxxxx> > Cc: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> > Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@xxxxxxxxx> > --- > 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; > + > + 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)) { Sleeping is not allowed. -Chris _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx