Commit 00936779 authored by Tvrtko Ursulin's avatar Tvrtko Ursulin Committed by Joonas Lahtinen

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
(cherry picked from commit 25d140fa)
Fixes: 59b449d5 ("drm/i915: Split out functions for different kinds of workarounds")
Signed-off-by: default avatarJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
parent 25956467
...@@ -1444,6 +1444,7 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv) ...@@ -1444,6 +1444,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
......
...@@ -67,6 +67,7 @@ ...@@ -67,6 +67,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"
...@@ -1805,6 +1806,7 @@ struct drm_i915_private { ...@@ -1805,6 +1806,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;
......
...@@ -5305,7 +5305,7 @@ int i915_gem_init_hw(struct drm_i915_private *dev_priv) ...@@ -5305,7 +5305,7 @@ int i915_gem_init_hw(struct drm_i915_private *dev_priv)
} }
} }
intel_gt_workarounds_apply(dev_priv); intel_gt_apply_workarounds(dev_priv);
i915_gem_init_swizzling(dev_priv); i915_gem_init_swizzling(dev_priv);
...@@ -5677,6 +5677,8 @@ void i915_gem_fini(struct drm_i915_private *dev_priv) ...@@ -5677,6 +5677,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