From: Ben Widawsky <ben@xxxxxxxxxxxx> The docs specify this needs to be set on HSW GT1 parts. I've implemented it as such since it should only be needed when using RC6, but it can probably go anywhere. This patch fixes extremely reproducible hangs on our Jenkins setup. The interesting failure signature is: IPEHR: 0x780c0000 (3DSTATE_VF) INSTDONE_0: 0xffdfbffa (SVG + VS) This replaces the homebrew workaround we implemented in commit 2c550183476dfa25641309ae9a28d30feed14379 Author: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> Date: Tue Dec 16 10:02:27 2014 +0000 drm/i915: Disable PSMI sleep messages on all rings around context switches as that is coupled into HW semaphore support which is scheduled for removal in the next patch. References: 2c550183476d ("drm/i915: Disable PSMI sleep messages on all rings around context switches") Signed-off-by: Ben Widawsky <ben@xxxxxxxxxxxx> Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> Cc: Mika Kuoppala <mika.kuoppala@xxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/i915_reg.h | 7 ++++ drivers/gpu/drm/i915/intel_pm.c | 16 +++++++- drivers/gpu/drm/i915/intel_ringbuffer.c | 49 ++----------------------- 4 files changed, 27 insertions(+), 47 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d44255a8655e..24a5e63cc443 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2276,6 +2276,8 @@ intel_info(const struct drm_i915_private *dev_priv) (dev_priv)->info.gt == 3) #define IS_HSW_ULT(dev_priv) (IS_HASWELL(dev_priv) && \ (INTEL_DEVID(dev_priv) & 0xFF00) == 0x0A00) +#define IS_HSW_GT1(dev_priv) (IS_HASWELL(dev_priv) && \ + (dev_priv)->info.gt == 1) #define IS_HSW_GT3(dev_priv) (IS_HASWELL(dev_priv) && \ (dev_priv)->info.gt == 3) /* ULX machines are also considered ULT. */ diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 02af9b5add34..ca6a2e925194 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2464,6 +2464,13 @@ enum i915_power_well_id { #define RING_DMA_FADD_UDW(base) _MMIO((base) + 0x60) /* gen8+ */ #define RING_INSTPM(base) _MMIO((base) + 0xc0) #define RING_MI_MODE(base) _MMIO((base) + 0x9c) +#define RING_WAIT_FOR_RC6_EXIT(base) _MMIO((base) + 0xcc) +#define RING_RC6_SEL_WRITE_ADDR_MASK (0x7 << 4) +#define RING_RC6_SEL_WRITE_ADDR_MULTICAST (0x0 << 4) +#define RING_RC6_SEL_WRITE_ADDR_UPPER_LEFT (0x4 << 4) +#define RING_RC6_SEL_WRITE_ADDR_UPPER_RIGHT (0x5 << 4) +#define RING_RC6_SEL_WRITE_ADDR_LOWER_LEFT (0x6 << 4) +#define RING_RC6_SEL_WRITE_ADDR_LOWER_RIGHT (0x7 << 4) #define INSTPS _MMIO(0x2070) /* 965+ only */ #define GEN4_INSTDONE1 _MMIO(0x207c) /* 965+ only, aka INSTDONE_2 on SNB */ #define ACTHD_I965 _MMIO(0x2074) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 2a6ffb8b975a..c2e3502090c6 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -7122,9 +7122,23 @@ static void gen6_enable_rc6(struct drm_i915_private *dev_priv) I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); - for_each_engine(engine, dev_priv, id) + for_each_engine(engine, dev_priv, id) { I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10); + /* + * HSW GT1: "This field must be always [be] programmed to “100”, + * this is required to address know [sic] HW issue." + * + * Failure to do so leads to a gpu hang on context load from + * under rc6, with a characteristic IPEHR of 0x780c0000 (the + * last command from the context image). + */ + if (IS_HSW_GT1(dev_priv)) + I915_WRITE(RING_WAIT_FOR_RC6_EXIT(engine->mmio_base), + _MASKED_FIELD(RING_RC6_SEL_WRITE_ADDR_MASK, + RING_RC6_SEL_WRITE_ADDR_UPPER_LEFT)); + } + I915_WRITE(GEN6_RC_SLEEP, 0); I915_WRITE(GEN6_RC1e_THRESHOLD, 1000); if (IS_IVYBRIDGE(dev_priv)) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 65fd92eb071d..57f20033b19d 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1602,12 +1602,6 @@ static inline int mi_set_context(struct i915_request *rq, u32 flags) { struct drm_i915_private *i915 = rq->i915; struct intel_engine_cs *engine = rq->engine; - enum intel_engine_id id; - const int num_rings = - /* Use an extended w/a on gen7 if signalling from other rings */ - (HAS_LEGACY_SEMAPHORES(i915) && IS_GEN(i915, 7)) ? - INTEL_INFO(i915)->num_rings - 1 : - 0; bool force_restore = false; int len; u32 *cs; @@ -1621,7 +1615,7 @@ static inline int mi_set_context(struct i915_request *rq, u32 flags) len = 4; if (IS_GEN(i915, 7)) - len += 2 + (num_rings ? 4*num_rings + 6 : 0); + len += 2; if (flags & MI_FORCE_RESTORE) { GEM_BUG_ON(flags & MI_RESTORE_INHIBIT); flags &= ~MI_FORCE_RESTORE; @@ -1634,23 +1628,8 @@ static inline int mi_set_context(struct i915_request *rq, u32 flags) return PTR_ERR(cs); /* WaProgramMiArbOnOffAroundMiSetContext:ivb,vlv,hsw,bdw,chv */ - if (IS_GEN(i915, 7)) { + if (IS_GEN(i915, 7)) *cs++ = MI_ARB_ON_OFF | MI_ARB_DISABLE; - if (num_rings) { - struct intel_engine_cs *signaller; - - *cs++ = MI_LOAD_REGISTER_IMM(num_rings); - for_each_engine(signaller, i915, id) { - if (signaller == engine) - continue; - - *cs++ = i915_mmio_reg_offset( - RING_PSMI_CTL(signaller->mmio_base)); - *cs++ = _MASKED_BIT_ENABLE( - GEN6_PSMI_SLEEP_MSG_DISABLE); - } - } - } if (force_restore) { /* @@ -1681,30 +1660,8 @@ static inline int mi_set_context(struct i915_request *rq, u32 flags) */ *cs++ = MI_NOOP; - if (IS_GEN(i915, 7)) { - if (num_rings) { - struct intel_engine_cs *signaller; - i915_reg_t last_reg = {}; /* keep gcc quiet */ - - *cs++ = MI_LOAD_REGISTER_IMM(num_rings); - for_each_engine(signaller, i915, id) { - if (signaller == engine) - continue; - - last_reg = RING_PSMI_CTL(signaller->mmio_base); - *cs++ = i915_mmio_reg_offset(last_reg); - *cs++ = _MASKED_BIT_DISABLE( - GEN6_PSMI_SLEEP_MSG_DISABLE); - } - - /* Insert a delay before the next switch! */ - *cs++ = MI_STORE_REGISTER_MEM | MI_SRM_LRM_GLOBAL_GTT; - *cs++ = i915_mmio_reg_offset(last_reg); - *cs++ = i915_scratch_offset(rq->i915); - *cs++ = MI_NOOP; - } + if (IS_GEN(i915, 7)) *cs++ = MI_ARB_ON_OFF | MI_ARB_ENABLE; - } intel_ring_advance(rq, cs); -- 2.20.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx