Commit 25d140fa authored by Tvrtko Ursulin's avatar Tvrtko Ursulin

drm/i915: Record GT workarounds in a list

To enable later verification of GT workaround state at various stages of
driver lifetime, we record the list of applicable ones per platforms to a
list, from which they are also applied.

The added data structure is a simple array of register, mask and value
items, which is allocated on demand as workarounds are added to the list.

This is a temporary implementation which later in the series gets fused
with the existing per context workaround list handling. It is separated at
this stage since the following patch fixes a bug which needs to be as easy
to backport as possible.

Also, since in the following patch we will be adding a new class of
workarounds (per engine) which can be applied from interrupt context, we
straight away make the provision for safe read-modify-write cycle.

v2:
 * Change dev_priv to i915 along the init path. (Chris Wilson)
 * API rename. (Chris Wilson)

v3:
 * Remove explicit list size tracking in favour of growing the allocation
   in power of two chunks. (Chris Wilson)

v4:
 Chris Wilson:
 * Change wa_list_finish to early return.
 * Copy workarounds using the compiler for static checking.
 * Do not bother zeroing unused entries.
 * Re-order struct i915_wa_list.

v5:
 * kmalloc_array.
 * Whitespace cleanup.
Signed-off-by: default avatarTvrtko Ursulin <tvrtko.ursulin@intel.com>
Reviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/20181203133319.10174-1-tvrtko.ursulin@linux.intel.com
parent 635b3bc6
...@@ -1467,6 +1467,7 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv) ...@@ -1467,6 +1467,7 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
intel_uncore_sanitize(dev_priv); intel_uncore_sanitize(dev_priv);
intel_gt_init_workarounds(dev_priv);
i915_gem_load_init_fences(dev_priv); i915_gem_load_init_fences(dev_priv);
/* On the 945G/GM, the chipset reports the MSI capability on the /* On the 945G/GM, the chipset reports the MSI capability on the
......
...@@ -69,6 +69,7 @@ ...@@ -69,6 +69,7 @@
#include "intel_ringbuffer.h" #include "intel_ringbuffer.h"
#include "intel_uncore.h" #include "intel_uncore.h"
#include "intel_wopcm.h" #include "intel_wopcm.h"
#include "intel_workarounds.h"
#include "intel_uc.h" #include "intel_uc.h"
#include "i915_gem.h" #include "i915_gem.h"
...@@ -1653,6 +1654,7 @@ struct drm_i915_private { ...@@ -1653,6 +1654,7 @@ struct drm_i915_private {
int dpio_phy_iosf_port[I915_NUM_PHYS_VLV]; int dpio_phy_iosf_port[I915_NUM_PHYS_VLV];
struct i915_workarounds workarounds; struct i915_workarounds workarounds;
struct i915_wa_list gt_wa_list;
struct i915_frontbuffer_tracking fb_tracking; struct i915_frontbuffer_tracking fb_tracking;
......
...@@ -5300,7 +5300,7 @@ int i915_gem_init_hw(struct drm_i915_private *dev_priv) ...@@ -5300,7 +5300,7 @@ int i915_gem_init_hw(struct drm_i915_private *dev_priv)
I915_WRITE(MI_PREDICATE_RESULT_2, IS_HSW_GT3(dev_priv) ? I915_WRITE(MI_PREDICATE_RESULT_2, IS_HSW_GT3(dev_priv) ?
LOWER_SLICE_ENABLED : LOWER_SLICE_DISABLED); LOWER_SLICE_ENABLED : LOWER_SLICE_DISABLED);
intel_gt_workarounds_apply(dev_priv); intel_gt_apply_workarounds(dev_priv);
i915_gem_init_swizzling(dev_priv); i915_gem_init_swizzling(dev_priv);
...@@ -5672,6 +5672,8 @@ void i915_gem_fini(struct drm_i915_private *dev_priv) ...@@ -5672,6 +5672,8 @@ void i915_gem_fini(struct drm_i915_private *dev_priv)
i915_gem_contexts_fini(dev_priv); i915_gem_contexts_fini(dev_priv);
mutex_unlock(&dev_priv->drm.struct_mutex); mutex_unlock(&dev_priv->drm.struct_mutex);
intel_wa_list_free(&dev_priv->gt_wa_list);
intel_cleanup_gt_powersave(dev_priv); intel_cleanup_gt_powersave(dev_priv);
intel_uc_fini_misc(dev_priv); intel_uc_fini_misc(dev_priv);
......
This diff is collapsed.
...@@ -7,10 +7,31 @@ ...@@ -7,10 +7,31 @@
#ifndef _I915_WORKAROUNDS_H_ #ifndef _I915_WORKAROUNDS_H_
#define _I915_WORKAROUNDS_H_ #define _I915_WORKAROUNDS_H_
#include <linux/slab.h>
struct i915_wa {
i915_reg_t reg;
u32 mask;
u32 val;
};
struct i915_wa_list {
const char *name;
struct i915_wa *list;
unsigned int count;
};
static inline void intel_wa_list_free(struct i915_wa_list *wal)
{
kfree(wal->list);
memset(wal, 0, sizeof(*wal));
}
int intel_ctx_workarounds_init(struct drm_i915_private *dev_priv); int intel_ctx_workarounds_init(struct drm_i915_private *dev_priv);
int intel_ctx_workarounds_emit(struct i915_request *rq); int intel_ctx_workarounds_emit(struct i915_request *rq);
void intel_gt_workarounds_apply(struct drm_i915_private *dev_priv); void intel_gt_init_workarounds(struct drm_i915_private *dev_priv);
void intel_gt_apply_workarounds(struct drm_i915_private *dev_priv);
void intel_whitelist_workarounds_apply(struct intel_engine_cs *engine); void intel_whitelist_workarounds_apply(struct intel_engine_cs *engine);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment