Merge drm/drm-next into drm-intel-next-queued
[sfrench/cifs-2.6.git] / drivers / gpu / drm / i915 / gt / intel_workarounds.c
index d692b83583fa4d3a29869c5ff4829016d5195ee5..f6fd6905ee6fb4758f93287dcfb3e436a915adea 100644 (file)
@@ -5,6 +5,8 @@
  */
 
 #include "i915_drv.h"
+#include "intel_context.h"
+#include "intel_gt.h"
 #include "intel_workarounds.h"
 
 /**
@@ -37,7 +39,7 @@
  *    costly and simplifies things. We can revisit this in the future.
  *
  * Layout
- * ''''''
+ * ~~~~~~
  *
  * Keep things in this file ordered by WA type, as per the above (context, GT,
  * display, register whitelist, batchbuffer). Then, inside each type, keep the
@@ -529,6 +531,18 @@ static void icl_ctx_workarounds_init(struct intel_engine_cs *engine,
 {
        struct drm_i915_private *i915 = engine->i915;
 
+       /* WaDisableBankHangMode:icl */
+       wa_write(wal,
+                GEN8_L3CNTLREG,
+                intel_uncore_read(engine->uncore, GEN8_L3CNTLREG) |
+                GEN8_ERRDETBCTRL);
+
+       /* WaDisableBankHangMode:icl */
+       wa_write(wal,
+                GEN8_L3CNTLREG,
+                intel_uncore_read(engine->uncore, GEN8_L3CNTLREG) |
+                GEN8_ERRDETBCTRL);
+
        /* Wa_1604370585:icl (pre-prod)
         * Formerly known as WaPushConstantDereferenceHoldDisable
         */
@@ -567,6 +581,10 @@ static void icl_ctx_workarounds_init(struct intel_engine_cs *engine,
        WA_SET_FIELD_MASKED(GEN8_CS_CHICKEN1,
                            GEN9_PREEMPT_GPGPU_LEVEL_MASK,
                            GEN9_PREEMPT_GPGPU_THREAD_GROUP_LEVEL);
+
+       /* allow headerless messages for preemptible GPGPU context */
+       WA_SET_BIT_MASKED(GEN10_SAMPLER_MODE,
+                         GEN11_SAMPLER_ENABLE_HEADLESS_MSG);
 }
 
 static void
@@ -973,9 +991,9 @@ wa_list_apply(struct intel_uncore *uncore, const struct i915_wa_list *wal)
        spin_unlock_irqrestore(&uncore->lock, flags);
 }
 
-void intel_gt_apply_workarounds(struct drm_i915_private *i915)
+void intel_gt_apply_workarounds(struct intel_gt *gt)
 {
-       wa_list_apply(&i915->uncore, &i915->gt_wa_list);
+       wa_list_apply(gt->uncore, &gt->i915->gt_wa_list);
 }
 
 static bool wa_list_verify(struct intel_uncore *uncore,
@@ -994,14 +1012,13 @@ static bool wa_list_verify(struct intel_uncore *uncore,
        return ok;
 }
 
-bool intel_gt_verify_workarounds(struct drm_i915_private *i915,
-                                const char *from)
+bool intel_gt_verify_workarounds(struct intel_gt *gt, const char *from)
 {
-       return wa_list_verify(&i915->uncore, &i915->gt_wa_list, from);
+       return wa_list_verify(gt->uncore, &gt->i915->gt_wa_list, from);
 }
 
 static void
-whitelist_reg(struct i915_wa_list *wal, i915_reg_t reg)
+whitelist_reg_ext(struct i915_wa_list *wal, i915_reg_t reg, u32 flags)
 {
        struct i915_wa wa = {
                .reg = reg
@@ -1010,9 +1027,16 @@ whitelist_reg(struct i915_wa_list *wal, i915_reg_t reg)
        if (GEM_DEBUG_WARN_ON(wal->count >= RING_MAX_NONPRIV_SLOTS))
                return;
 
+       wa.reg.reg |= flags;
        _wa_add(wal, &wa);
 }
 
+static void
+whitelist_reg(struct i915_wa_list *wal, i915_reg_t reg)
+{
+       whitelist_reg_ext(wal, reg, RING_FORCE_TO_NONPRIV_RW);
+}
+
 static void gen9_whitelist_build(struct i915_wa_list *w)
 {
        /* WaVFEStateAfterPipeControlwithMediaStateClear:skl,bxt,glk,cfl */
@@ -1025,56 +1049,131 @@ static void gen9_whitelist_build(struct i915_wa_list *w)
        whitelist_reg(w, GEN8_HDC_CHICKEN1);
 }
 
-static void skl_whitelist_build(struct i915_wa_list *w)
+static void skl_whitelist_build(struct intel_engine_cs *engine)
 {
+       struct i915_wa_list *w = &engine->whitelist;
+
+       if (engine->class != RENDER_CLASS)
+               return;
+
        gen9_whitelist_build(w);
 
        /* WaDisableLSQCROPERFforOCL:skl */
        whitelist_reg(w, GEN8_L3SQCREG4);
 }
 
-static void bxt_whitelist_build(struct i915_wa_list *w)
+static void bxt_whitelist_build(struct intel_engine_cs *engine)
 {
-       gen9_whitelist_build(w);
+       if (engine->class != RENDER_CLASS)
+               return;
+
+       gen9_whitelist_build(&engine->whitelist);
 }
 
-static void kbl_whitelist_build(struct i915_wa_list *w)
+static void kbl_whitelist_build(struct intel_engine_cs *engine)
 {
+       struct i915_wa_list *w = &engine->whitelist;
+
+       if (engine->class != RENDER_CLASS)
+               return;
+
        gen9_whitelist_build(w);
 
        /* WaDisableLSQCROPERFforOCL:kbl */
        whitelist_reg(w, GEN8_L3SQCREG4);
 }
 
-static void glk_whitelist_build(struct i915_wa_list *w)
+static void glk_whitelist_build(struct intel_engine_cs *engine)
 {
+       struct i915_wa_list *w = &engine->whitelist;
+
+       if (engine->class != RENDER_CLASS)
+               return;
+
        gen9_whitelist_build(w);
 
        /* WA #0862: Userspace has to set "Barrier Mode" to avoid hangs. */
        whitelist_reg(w, GEN9_SLICE_COMMON_ECO_CHICKEN1);
 }
 
-static void cfl_whitelist_build(struct i915_wa_list *w)
+static void cfl_whitelist_build(struct intel_engine_cs *engine)
 {
+       struct i915_wa_list *w = &engine->whitelist;
+
+       if (engine->class != RENDER_CLASS)
+               return;
+
        gen9_whitelist_build(w);
+
+       /*
+        * WaAllowPMDepthAndInvocationCountAccessFromUMD:cfl,whl,cml,aml
+        *
+        * This covers 4 register which are next to one another :
+        *   - PS_INVOCATION_COUNT
+        *   - PS_INVOCATION_COUNT_UDW
+        *   - PS_DEPTH_COUNT
+        *   - PS_DEPTH_COUNT_UDW
+        */
+       whitelist_reg_ext(w, PS_INVOCATION_COUNT,
+                         RING_FORCE_TO_NONPRIV_RD |
+                         RING_FORCE_TO_NONPRIV_RANGE_4);
 }
 
-static void cnl_whitelist_build(struct i915_wa_list *w)
+static void cnl_whitelist_build(struct intel_engine_cs *engine)
 {
+       struct i915_wa_list *w = &engine->whitelist;
+
+       if (engine->class != RENDER_CLASS)
+               return;
+
        /* WaEnablePreemptionGranularityControlByUMD:cnl */
        whitelist_reg(w, GEN8_CS_CHICKEN1);
 }
 
-static void icl_whitelist_build(struct i915_wa_list *w)
+static void icl_whitelist_build(struct intel_engine_cs *engine)
 {
-       /* WaAllowUMDToModifyHalfSliceChicken7:icl */
-       whitelist_reg(w, GEN9_HALF_SLICE_CHICKEN7);
+       struct i915_wa_list *w = &engine->whitelist;
 
-       /* WaAllowUMDToModifySamplerMode:icl */
-       whitelist_reg(w, GEN10_SAMPLER_MODE);
+       switch (engine->class) {
+       case RENDER_CLASS:
+               /* WaAllowUMDToModifyHalfSliceChicken7:icl */
+               whitelist_reg(w, GEN9_HALF_SLICE_CHICKEN7);
 
-       /* WaEnableStateCacheRedirectToCS:icl */
-       whitelist_reg(w, GEN9_SLICE_COMMON_ECO_CHICKEN1);
+               /* WaAllowUMDToModifySamplerMode:icl */
+               whitelist_reg(w, GEN10_SAMPLER_MODE);
+
+               /* WaEnableStateCacheRedirectToCS:icl */
+               whitelist_reg(w, GEN9_SLICE_COMMON_ECO_CHICKEN1);
+
+               /*
+                * WaAllowPMDepthAndInvocationCountAccessFromUMD:icl
+                *
+                * This covers 4 register which are next to one another :
+                *   - PS_INVOCATION_COUNT
+                *   - PS_INVOCATION_COUNT_UDW
+                *   - PS_DEPTH_COUNT
+                *   - PS_DEPTH_COUNT_UDW
+                */
+               whitelist_reg_ext(w, PS_INVOCATION_COUNT,
+                                 RING_FORCE_TO_NONPRIV_RD |
+                                 RING_FORCE_TO_NONPRIV_RANGE_4);
+               break;
+
+       case VIDEO_DECODE_CLASS:
+               /* hucStatusRegOffset */
+               whitelist_reg_ext(w, _MMIO(0x2000 + engine->mmio_base),
+                                 RING_FORCE_TO_NONPRIV_RD);
+               /* hucUKernelHdrInfoRegOffset */
+               whitelist_reg_ext(w, _MMIO(0x2014 + engine->mmio_base),
+                                 RING_FORCE_TO_NONPRIV_RD);
+               /* hucStatus2RegOffset */
+               whitelist_reg_ext(w, _MMIO(0x23B0 + engine->mmio_base),
+                                 RING_FORCE_TO_NONPRIV_RD);
+               break;
+
+       default:
+               break;
+       }
 }
 
 void intel_engine_init_whitelist(struct intel_engine_cs *engine)
@@ -1082,25 +1181,22 @@ void intel_engine_init_whitelist(struct intel_engine_cs *engine)
        struct drm_i915_private *i915 = engine->i915;
        struct i915_wa_list *w = &engine->whitelist;
 
-       if (engine->class != RENDER_CLASS)
-               return;
-
        wa_init_start(w, "whitelist");
 
        if (IS_GEN(i915, 11))
-               icl_whitelist_build(w);
+               icl_whitelist_build(engine);
        else if (IS_CANNONLAKE(i915))
-               cnl_whitelist_build(w);
+               cnl_whitelist_build(engine);
        else if (IS_COFFEELAKE(i915))
-               cfl_whitelist_build(w);
+               cfl_whitelist_build(engine);
        else if (IS_GEMINILAKE(i915))
-               glk_whitelist_build(w);
+               glk_whitelist_build(engine);
        else if (IS_KABYLAKE(i915))
-               kbl_whitelist_build(w);
+               kbl_whitelist_build(engine);
        else if (IS_BROXTON(i915))
-               bxt_whitelist_build(w);
+               bxt_whitelist_build(engine);
        else if (IS_SKYLAKE(i915))
-               skl_whitelist_build(w);
+               skl_whitelist_build(engine);
        else if (INTEL_GEN(i915) <= 8)
                return;
        else
@@ -1190,8 +1286,12 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)
                if (IS_ICL_REVID(i915, ICL_REVID_A0, ICL_REVID_B0))
                        wa_write_or(wal,
                                    GEN7_SARCHKMD,
-                                   GEN7_DISABLE_DEMAND_PREFETCH |
-                                   GEN7_DISABLE_SAMPLER_PREFETCH);
+                                   GEN7_DISABLE_DEMAND_PREFETCH);
+
+               /* Wa_1606682166:icl */
+               wa_write_or(wal,
+                           GEN7_SARCHKMD,
+                           GEN7_DISABLE_SAMPLER_PREFETCH);
        }
 
        if (IS_GEN_RANGE(i915, 9, 11)) {
@@ -1260,7 +1360,7 @@ engine_init_workarounds(struct intel_engine_cs *engine, struct i915_wa_list *wal
        if (I915_SELFTEST_ONLY(INTEL_GEN(engine->i915) < 8))
                return;
 
-       if (engine->id == RCS0)
+       if (engine->class == RENDER_CLASS)
                rcs_engine_wa_init(engine, wal);
        else
                xcs_engine_wa_init(engine, wal);
@@ -1270,7 +1370,7 @@ void intel_engine_init_workarounds(struct intel_engine_cs *engine)
 {
        struct i915_wa_list *wal = &engine->wa_list;
 
-       if (GEM_WARN_ON(INTEL_GEN(engine->i915) < 8))
+       if (INTEL_GEN(engine->i915) < 8)
                return;
 
        wa_init_start(wal, engine->name);
@@ -1358,7 +1458,7 @@ static int engine_wa_list_verify(struct intel_context *ce,
        if (!wal->count)
                return 0;
 
-       vma = create_scratch(&ce->engine->i915->ggtt.vm, wal->count);
+       vma = create_scratch(&ce->engine->gt->ggtt->vm, wal->count);
        if (IS_ERR(vma))
                return PTR_ERR(vma);
 
@@ -1373,7 +1473,7 @@ static int engine_wa_list_verify(struct intel_context *ce,
                goto err_vma;
 
        i915_request_add(rq);
-       if (i915_request_wait(rq, I915_WAIT_LOCKED, HZ / 5) < 0) {
+       if (i915_request_wait(rq, 0, HZ / 5) < 0) {
                err = -ETIME;
                goto err_vma;
        }