drm/i915: Split out functions for different kinds of workarounds

There are different kind of workarounds (those that modify registers that
live in the context image, those that modify global registers, those that
whitelist registers, etc...) and they have different requirements in terms
of where they are applied and how. Also, by splitting them apart, it should
be easier to decide where a new workaround should go.

v2:
  - Add multiple MISSING_CASE
  - Rebased

v3:
  - Rename mmio_workarounds to gt_workarounds (Chris, Mika)
  - Create empty placeholders for BDW and CHV GT WAs
  - Rebased

v4: Rebased

v5:
 - Rebased
 - FORCE_TO_NONPRIV register exists since BDW, so make a path
   for it to achieve universality, even if empty (Chris)

Signed-off-by: Oscar Mateo <oscar.mateo@intel.com>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
[ickle: appease checkpatch]
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/1523376767-18480-2-git-send-email-oscar.mateo@intel.com
This commit is contained in:
Oscar Mateo
2018-04-10 09:12:47 -07:00
committed by Chris Wilson
parent 7d3c425fef
commit 59b449d5c8
6 changed files with 473 additions and 278 deletions
+3
View File
@@ -35,6 +35,7 @@
#include "intel_drv.h"
#include "intel_frontbuffer.h"
#include "intel_mocs.h"
#include "intel_workarounds.h"
#include "i915_gemfs.h"
#include <linux/dma-fence-array.h>
#include <linux/kthread.h>
@@ -5191,6 +5192,8 @@ int i915_gem_init_hw(struct drm_i915_private *dev_priv)
}
}
intel_gt_workarounds_apply(dev_priv);
i915_gem_init_swizzling(dev_priv);
/*
+6
View File
@@ -90,6 +90,7 @@
#include <drm/i915_drm.h>
#include "i915_drv.h"
#include "i915_trace.h"
#include "intel_workarounds.h"
#define ALL_L3_SLICES(dev) (1 << NUM_L3_SLICES(dev)) - 1
@@ -459,11 +460,16 @@ static bool needs_preempt_context(struct drm_i915_private *i915)
int i915_gem_contexts_init(struct drm_i915_private *dev_priv)
{
struct i915_gem_context *ctx;
int ret;
/* Reassure ourselves we are only called once */
GEM_BUG_ON(dev_priv->kernel_context);
GEM_BUG_ON(dev_priv->preempt_context);
ret = intel_ctx_workarounds_init(dev_priv);
if (ret)
return ret;
INIT_LIST_HEAD(&dev_priv->contexts.list);
INIT_WORK(&dev_priv->contexts.free_work, contexts_free_worker);
init_llist_head(&dev_priv->contexts.free_list);
+11 -3
View File
@@ -1744,6 +1744,10 @@ static int gen8_init_render_ring(struct intel_engine_cs *engine)
if (ret)
return ret;
ret = intel_whitelist_workarounds_apply(engine);
if (ret)
return ret;
/* We need to disable the AsyncFlip performance optimisations in order
* to use MI_WAIT_FOR_EVENT within the CS. It should already be
* programmed to '1' on all products.
@@ -1754,7 +1758,7 @@ static int gen8_init_render_ring(struct intel_engine_cs *engine)
I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_FORCE_ORDERING));
return init_workarounds_ring(engine);
return 0;
}
static int gen9_init_render_ring(struct intel_engine_cs *engine)
@@ -1765,7 +1769,11 @@ static int gen9_init_render_ring(struct intel_engine_cs *engine)
if (ret)
return ret;
return init_workarounds_ring(engine);
ret = intel_whitelist_workarounds_apply(engine);
if (ret)
return ret;
return 0;
}
static void reset_common_ring(struct intel_engine_cs *engine,
@@ -2090,7 +2098,7 @@ static int gen8_init_rcs_context(struct i915_request *rq)
{
int ret;
ret = intel_ring_workarounds_emit(rq);
ret = intel_ctx_workarounds_emit(rq);
if (ret)
return ret;
+6 -2
View File
@@ -600,7 +600,7 @@ static int intel_rcs_ctx_init(struct i915_request *rq)
{
int ret;
ret = intel_ring_workarounds_emit(rq);
ret = intel_ctx_workarounds_emit(rq);
if (ret != 0)
return ret;
@@ -618,6 +618,10 @@ static int init_render_ring(struct intel_engine_cs *engine)
if (ret)
return ret;
ret = intel_whitelist_workarounds_apply(engine);
if (ret)
return ret;
/* WaTimedSingleVertexDispatch:cl,bw,ctg,elk,ilk,snb */
if (IS_GEN(dev_priv, 4, 6))
I915_WRITE(MI_MODE, _MASKED_BIT_ENABLE(VS_TIMER_DISPATCH));
@@ -659,7 +663,7 @@ static int init_render_ring(struct intel_engine_cs *engine)
if (INTEL_GEN(dev_priv) >= 6)
I915_WRITE_IMR(engine, ~engine->irq_keep_mask);
return init_workarounds_ring(engine);
return 0;
}
static u32 *gen6_signal(struct i915_request *rq, u32 *cs)
File diff suppressed because it is too large Load Diff
+6 -2
View File
@@ -7,7 +7,11 @@
#ifndef _I915_WORKAROUNDS_H_
#define _I915_WORKAROUNDS_H_
int init_workarounds_ring(struct intel_engine_cs *engine);
int intel_ring_workarounds_emit(struct i915_request *rq);
int intel_ctx_workarounds_init(struct drm_i915_private *dev_priv);
int intel_ctx_workarounds_emit(struct i915_request *rq);
void intel_gt_workarounds_apply(struct drm_i915_private *dev_priv);
int intel_whitelist_workarounds_apply(struct intel_engine_cs *engine);
#endif