mirror of https://gitee.com/openkylin/linux.git
drm/i915: Convert i915_reset.c over to using uncore mmio
Currently i915_reset.c mixes calls to intel_uncore, pci and our old style I915_READ mmio interfaces. Cast aside the old implicit macros, and harmonise on using uncore throughout. add/remove: 1/1 grow/shrink: 0/4 up/down: 65/-207 (-142) Function old new delta rmw_register - 65 +65 gen8_reset_engines 945 942 -3 g4x_do_reset 407 376 -31 intel_gpu_reset 545 509 -36 clear_register 63 - -63 i915_clear_error_registers 461 387 -74 A little bit of pointer dancing elimination works wonders. v2: Roll up the helpers into intel_uncore for general use With the helpers gcc was a little more eager to inline: add/remove: 0/1 grow/shrink: 1/3 up/down: 99/-133 (-34) Function old new delta i915_clear_error_registers 461 560 +99 gen8_reset_engines 945 942 -3 g4x_do_reset 407 376 -31 intel_gpu_reset 545 509 -36 clear_register 63 - -63 Total: Before=1544400, After=1544366, chg -0.00% Win some, lose some, gcc is gcc. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> Cc: Paulo Zanoni <paulo.r.zanoni@intel.com> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20190405202419.3093-1-chris@chris-wilson.co.uk
This commit is contained in:
parent
fdc4e9267f
commit
95007efbe6
|
@ -18,6 +18,26 @@
|
||||||
/* XXX How to handle concurrent GGTT updates using tiling registers? */
|
/* XXX How to handle concurrent GGTT updates using tiling registers? */
|
||||||
#define RESET_UNDER_STOP_MACHINE 0
|
#define RESET_UNDER_STOP_MACHINE 0
|
||||||
|
|
||||||
|
static void rmw_set(struct intel_uncore *uncore, i915_reg_t reg, u32 set)
|
||||||
|
{
|
||||||
|
intel_uncore_rmw(uncore, reg, 0, set);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rmw_clear(struct intel_uncore *uncore, i915_reg_t reg, u32 clr)
|
||||||
|
{
|
||||||
|
intel_uncore_rmw(uncore, reg, clr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rmw_set_fw(struct intel_uncore *uncore, i915_reg_t reg, u32 set)
|
||||||
|
{
|
||||||
|
intel_uncore_rmw_fw(uncore, reg, 0, set);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rmw_clear_fw(struct intel_uncore *uncore, i915_reg_t reg, u32 clr)
|
||||||
|
{
|
||||||
|
intel_uncore_rmw_fw(uncore, reg, clr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static void engine_skip_context(struct i915_request *rq)
|
static void engine_skip_context(struct i915_request *rq)
|
||||||
{
|
{
|
||||||
struct intel_engine_cs *engine = rq->engine;
|
struct intel_engine_cs *engine = rq->engine;
|
||||||
|
@ -119,7 +139,7 @@ void i915_reset_request(struct i915_request *rq, bool guilty)
|
||||||
|
|
||||||
static void gen3_stop_engine(struct intel_engine_cs *engine)
|
static void gen3_stop_engine(struct intel_engine_cs *engine)
|
||||||
{
|
{
|
||||||
struct drm_i915_private *dev_priv = engine->i915;
|
struct intel_uncore *uncore = engine->uncore;
|
||||||
const u32 base = engine->mmio_base;
|
const u32 base = engine->mmio_base;
|
||||||
|
|
||||||
GEM_TRACE("%s\n", engine->name);
|
GEM_TRACE("%s\n", engine->name);
|
||||||
|
@ -127,20 +147,23 @@ static void gen3_stop_engine(struct intel_engine_cs *engine)
|
||||||
if (intel_engine_stop_cs(engine))
|
if (intel_engine_stop_cs(engine))
|
||||||
GEM_TRACE("%s: timed out on STOP_RING\n", engine->name);
|
GEM_TRACE("%s: timed out on STOP_RING\n", engine->name);
|
||||||
|
|
||||||
I915_WRITE_FW(RING_HEAD(base), I915_READ_FW(RING_TAIL(base)));
|
intel_uncore_write_fw(uncore,
|
||||||
POSTING_READ_FW(RING_HEAD(base)); /* paranoia */
|
RING_HEAD(base),
|
||||||
|
intel_uncore_read_fw(uncore, RING_TAIL(base)));
|
||||||
|
intel_uncore_posting_read_fw(uncore, RING_HEAD(base)); /* paranoia */
|
||||||
|
|
||||||
I915_WRITE_FW(RING_HEAD(base), 0);
|
intel_uncore_write_fw(uncore, RING_HEAD(base), 0);
|
||||||
I915_WRITE_FW(RING_TAIL(base), 0);
|
intel_uncore_write_fw(uncore, RING_TAIL(base), 0);
|
||||||
POSTING_READ_FW(RING_TAIL(base));
|
intel_uncore_posting_read_fw(uncore, RING_TAIL(base));
|
||||||
|
|
||||||
/* The ring must be empty before it is disabled */
|
/* The ring must be empty before it is disabled */
|
||||||
I915_WRITE_FW(RING_CTL(base), 0);
|
intel_uncore_write_fw(uncore, RING_CTL(base), 0);
|
||||||
|
|
||||||
/* Check acts as a post */
|
/* Check acts as a post */
|
||||||
if (I915_READ_FW(RING_HEAD(base)))
|
if (intel_uncore_read_fw(uncore, RING_HEAD(base)))
|
||||||
GEM_TRACE("%s: ring head [%x] not parked\n",
|
GEM_TRACE("%s: ring head [%x] not parked\n",
|
||||||
engine->name, I915_READ_FW(RING_HEAD(base)));
|
engine->name,
|
||||||
|
intel_uncore_read_fw(uncore, RING_HEAD(base)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void i915_stop_engines(struct drm_i915_private *i915,
|
static void i915_stop_engines(struct drm_i915_private *i915,
|
||||||
|
@ -203,17 +226,17 @@ static int g33_do_reset(struct drm_i915_private *i915,
|
||||||
return wait_for_atomic(g4x_reset_complete(pdev), 50);
|
return wait_for_atomic(g4x_reset_complete(pdev), 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int g4x_do_reset(struct drm_i915_private *dev_priv,
|
static int g4x_do_reset(struct drm_i915_private *i915,
|
||||||
intel_engine_mask_t engine_mask,
|
intel_engine_mask_t engine_mask,
|
||||||
unsigned int retry)
|
unsigned int retry)
|
||||||
{
|
{
|
||||||
struct pci_dev *pdev = dev_priv->drm.pdev;
|
struct pci_dev *pdev = i915->drm.pdev;
|
||||||
|
struct intel_uncore *uncore = &i915->uncore;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* WaVcpClkGateDisableForMediaReset:ctg,elk */
|
/* WaVcpClkGateDisableForMediaReset:ctg,elk */
|
||||||
I915_WRITE_FW(VDECCLK_GATE_D,
|
rmw_set_fw(uncore, VDECCLK_GATE_D, VCP_UNIT_CLOCK_GATE_DISABLE);
|
||||||
I915_READ(VDECCLK_GATE_D) | VCP_UNIT_CLOCK_GATE_DISABLE);
|
intel_uncore_posting_read_fw(uncore, VDECCLK_GATE_D);
|
||||||
POSTING_READ_FW(VDECCLK_GATE_D);
|
|
||||||
|
|
||||||
pci_write_config_byte(pdev, I915_GDRST,
|
pci_write_config_byte(pdev, I915_GDRST,
|
||||||
GRDOM_MEDIA | GRDOM_RESET_ENABLE);
|
GRDOM_MEDIA | GRDOM_RESET_ENABLE);
|
||||||
|
@ -234,18 +257,17 @@ static int g4x_do_reset(struct drm_i915_private *dev_priv,
|
||||||
out:
|
out:
|
||||||
pci_write_config_byte(pdev, I915_GDRST, 0);
|
pci_write_config_byte(pdev, I915_GDRST, 0);
|
||||||
|
|
||||||
I915_WRITE_FW(VDECCLK_GATE_D,
|
rmw_clear_fw(uncore, VDECCLK_GATE_D, VCP_UNIT_CLOCK_GATE_DISABLE);
|
||||||
I915_READ(VDECCLK_GATE_D) & ~VCP_UNIT_CLOCK_GATE_DISABLE);
|
intel_uncore_posting_read_fw(uncore, VDECCLK_GATE_D);
|
||||||
POSTING_READ_FW(VDECCLK_GATE_D);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ironlake_do_reset(struct drm_i915_private *dev_priv,
|
static int ironlake_do_reset(struct drm_i915_private *i915,
|
||||||
intel_engine_mask_t engine_mask,
|
intel_engine_mask_t engine_mask,
|
||||||
unsigned int retry)
|
unsigned int retry)
|
||||||
{
|
{
|
||||||
struct intel_uncore *uncore = &dev_priv->uncore;
|
struct intel_uncore *uncore = &i915->uncore;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
intel_uncore_write_fw(uncore, ILK_GDSR,
|
intel_uncore_write_fw(uncore, ILK_GDSR,
|
||||||
|
@ -277,10 +299,10 @@ static int ironlake_do_reset(struct drm_i915_private *dev_priv,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset the hardware domains (GENX_GRDOM_*) specified by mask */
|
/* Reset the hardware domains (GENX_GRDOM_*) specified by mask */
|
||||||
static int gen6_hw_domain_reset(struct drm_i915_private *dev_priv,
|
static int gen6_hw_domain_reset(struct drm_i915_private *i915,
|
||||||
u32 hw_domain_mask)
|
u32 hw_domain_mask)
|
||||||
{
|
{
|
||||||
struct intel_uncore *uncore = &dev_priv->uncore;
|
struct intel_uncore *uncore = &i915->uncore;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -381,7 +403,7 @@ static u32 gen11_lock_sfc(struct intel_engine_cs *engine)
|
||||||
* ends up being locked to the engine we want to reset, we have to reset
|
* ends up being locked to the engine we want to reset, we have to reset
|
||||||
* it as well (we will unlock it once the reset sequence is completed).
|
* it as well (we will unlock it once the reset sequence is completed).
|
||||||
*/
|
*/
|
||||||
intel_uncore_rmw_or_fw(uncore, sfc_forced_lock, sfc_forced_lock_bit);
|
rmw_set_fw(uncore, sfc_forced_lock, sfc_forced_lock_bit);
|
||||||
|
|
||||||
if (__intel_wait_for_register_fw(uncore,
|
if (__intel_wait_for_register_fw(uncore,
|
||||||
sfc_forced_lock_ack,
|
sfc_forced_lock_ack,
|
||||||
|
@ -404,7 +426,6 @@ static void gen11_unlock_sfc(struct intel_engine_cs *engine)
|
||||||
u8 vdbox_sfc_access = RUNTIME_INFO(engine->i915)->vdbox_sfc_access;
|
u8 vdbox_sfc_access = RUNTIME_INFO(engine->i915)->vdbox_sfc_access;
|
||||||
i915_reg_t sfc_forced_lock;
|
i915_reg_t sfc_forced_lock;
|
||||||
u32 sfc_forced_lock_bit;
|
u32 sfc_forced_lock_bit;
|
||||||
u32 val;
|
|
||||||
|
|
||||||
switch (engine->class) {
|
switch (engine->class) {
|
||||||
case VIDEO_DECODE_CLASS:
|
case VIDEO_DECODE_CLASS:
|
||||||
|
@ -424,9 +445,7 @@ static void gen11_unlock_sfc(struct intel_engine_cs *engine)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
val = intel_uncore_read_fw(uncore, sfc_forced_lock);
|
rmw_clear_fw(uncore, sfc_forced_lock, sfc_forced_lock_bit);
|
||||||
val &= ~sfc_forced_lock_bit;
|
|
||||||
intel_uncore_write_fw(uncore, sfc_forced_lock, val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gen11_reset_engines(struct drm_i915_private *i915,
|
static int gen11_reset_engines(struct drm_i915_private *i915,
|
||||||
|
@ -491,10 +510,9 @@ static int gen8_engine_reset_prepare(struct intel_engine_cs *engine)
|
||||||
|
|
||||||
static void gen8_engine_reset_cancel(struct intel_engine_cs *engine)
|
static void gen8_engine_reset_cancel(struct intel_engine_cs *engine)
|
||||||
{
|
{
|
||||||
struct drm_i915_private *dev_priv = engine->i915;
|
intel_uncore_write_fw(engine->uncore,
|
||||||
|
RING_RESET_CTL(engine->mmio_base),
|
||||||
I915_WRITE_FW(RING_RESET_CTL(engine->mmio_base),
|
_MASKED_BIT_DISABLE(RESET_CTL_REQUEST_RESET));
|
||||||
_MASKED_BIT_DISABLE(RESET_CTL_REQUEST_RESET));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gen8_reset_engines(struct drm_i915_private *i915,
|
static int gen8_reset_engines(struct drm_i915_private *i915,
|
||||||
|
@ -1178,49 +1196,49 @@ static void i915_reset_device(struct drm_i915_private *i915,
|
||||||
kobject_uevent_env(kobj, KOBJ_CHANGE, reset_done_event);
|
kobject_uevent_env(kobj, KOBJ_CHANGE, reset_done_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clear_register(struct drm_i915_private *dev_priv, i915_reg_t reg)
|
static void clear_register(struct intel_uncore *uncore, i915_reg_t reg)
|
||||||
{
|
{
|
||||||
I915_WRITE(reg, I915_READ(reg));
|
intel_uncore_rmw(uncore, reg, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void i915_clear_error_registers(struct drm_i915_private *dev_priv)
|
void i915_clear_error_registers(struct drm_i915_private *i915)
|
||||||
{
|
{
|
||||||
|
struct intel_uncore *uncore = &i915->uncore;
|
||||||
u32 eir;
|
u32 eir;
|
||||||
|
|
||||||
if (!IS_GEN(dev_priv, 2))
|
if (!IS_GEN(i915, 2))
|
||||||
clear_register(dev_priv, PGTBL_ER);
|
clear_register(uncore, PGTBL_ER);
|
||||||
|
|
||||||
if (INTEL_GEN(dev_priv) < 4)
|
if (INTEL_GEN(i915) < 4)
|
||||||
clear_register(dev_priv, IPEIR(RENDER_RING_BASE));
|
clear_register(uncore, IPEIR(RENDER_RING_BASE));
|
||||||
else
|
else
|
||||||
clear_register(dev_priv, IPEIR_I965);
|
clear_register(uncore, IPEIR_I965);
|
||||||
|
|
||||||
clear_register(dev_priv, EIR);
|
clear_register(uncore, EIR);
|
||||||
eir = I915_READ(EIR);
|
eir = intel_uncore_read(uncore, EIR);
|
||||||
if (eir) {
|
if (eir) {
|
||||||
/*
|
/*
|
||||||
* some errors might have become stuck,
|
* some errors might have become stuck,
|
||||||
* mask them.
|
* mask them.
|
||||||
*/
|
*/
|
||||||
DRM_DEBUG_DRIVER("EIR stuck: 0x%08x, masking\n", eir);
|
DRM_DEBUG_DRIVER("EIR stuck: 0x%08x, masking\n", eir);
|
||||||
I915_WRITE(EMR, I915_READ(EMR) | eir);
|
rmw_set(uncore, EMR, eir);
|
||||||
I915_WRITE(IIR, I915_MASTER_ERROR_INTERRUPT);
|
intel_uncore_write(uncore, IIR, I915_MASTER_ERROR_INTERRUPT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (INTEL_GEN(dev_priv) >= 8) {
|
if (INTEL_GEN(i915) >= 8) {
|
||||||
I915_WRITE(GEN8_RING_FAULT_REG,
|
rmw_clear(uncore, GEN8_RING_FAULT_REG, RING_FAULT_VALID);
|
||||||
I915_READ(GEN8_RING_FAULT_REG) & ~RING_FAULT_VALID);
|
intel_uncore_posting_read(uncore, GEN8_RING_FAULT_REG);
|
||||||
POSTING_READ(GEN8_RING_FAULT_REG);
|
} else if (INTEL_GEN(i915) >= 6) {
|
||||||
} else if (INTEL_GEN(dev_priv) >= 6) {
|
|
||||||
struct intel_engine_cs *engine;
|
struct intel_engine_cs *engine;
|
||||||
enum intel_engine_id id;
|
enum intel_engine_id id;
|
||||||
|
|
||||||
for_each_engine(engine, dev_priv, id) {
|
for_each_engine(engine, i915, id) {
|
||||||
I915_WRITE(RING_FAULT_REG(engine),
|
rmw_clear(uncore,
|
||||||
I915_READ(RING_FAULT_REG(engine)) &
|
RING_FAULT_REG(engine), RING_FAULT_VALID);
|
||||||
~RING_FAULT_VALID);
|
intel_uncore_posting_read(uncore,
|
||||||
|
RING_FAULT_REG(engine));
|
||||||
}
|
}
|
||||||
POSTING_READ(RING_FAULT_REG(dev_priv->engine[RCS0]));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -369,11 +369,26 @@ intel_uncore_read64_2x32(struct intel_uncore *uncore,
|
||||||
#define intel_uncore_write64_fw(...) __raw_uncore_write64(__VA_ARGS__)
|
#define intel_uncore_write64_fw(...) __raw_uncore_write64(__VA_ARGS__)
|
||||||
#define intel_uncore_posting_read_fw(...) ((void)intel_uncore_read_fw(__VA_ARGS__))
|
#define intel_uncore_posting_read_fw(...) ((void)intel_uncore_read_fw(__VA_ARGS__))
|
||||||
|
|
||||||
static inline void intel_uncore_rmw_or_fw(struct intel_uncore *uncore,
|
static inline void intel_uncore_rmw(struct intel_uncore *uncore,
|
||||||
i915_reg_t reg, u32 or_val)
|
i915_reg_t reg, u32 clear, u32 set)
|
||||||
{
|
{
|
||||||
intel_uncore_write_fw(uncore, reg,
|
u32 val;
|
||||||
intel_uncore_read_fw(uncore, reg) | or_val);
|
|
||||||
|
val = intel_uncore_read(uncore, reg);
|
||||||
|
val &= ~clear;
|
||||||
|
val |= set;
|
||||||
|
intel_uncore_write(uncore, reg, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void intel_uncore_rmw_fw(struct intel_uncore *uncore,
|
||||||
|
i915_reg_t reg, u32 clear, u32 set)
|
||||||
|
{
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
val = intel_uncore_read_fw(uncore, reg);
|
||||||
|
val &= ~clear;
|
||||||
|
val |= set;
|
||||||
|
intel_uncore_write_fw(uncore, reg, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define raw_reg_read(base, reg) \
|
#define raw_reg_read(base, reg) \
|
||||||
|
|
Loading…
Reference in New Issue