drm/i915: take a reference to uncore in the engine and use it
A few advantages: - Prepares us for the planned split of display uncore from GT uncore - Improves our engine-centric view of the world in the engine code and allows us to avoid jumping back to dev_priv. - Allows us to wrap accesses to engine register in nice macros that automatically pick the right mmio base. Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> Cc: Paulo Zanoni <paulo.r.zanoni@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Link: https://patchwork.freedesktop.org/patch/msgid/20190325214940.23632-10-daniele.ceraolospurio@intel.com
This commit is contained in:

committed by
Chris Wilson

parent
97a04e0d07
commit
baba6e572b
@@ -575,19 +575,19 @@ static void set_hwsp(struct intel_engine_cs *engine, u32 offset)
|
||||
static void flush_cs_tlb(struct intel_engine_cs *engine)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = engine->i915;
|
||||
i915_reg_t instpm = RING_INSTPM(engine->mmio_base);
|
||||
|
||||
if (!IS_GEN_RANGE(dev_priv, 6, 7))
|
||||
return;
|
||||
|
||||
/* ring should be idle before issuing a sync flush*/
|
||||
WARN_ON((I915_READ_MODE(engine) & MODE_IDLE) == 0);
|
||||
WARN_ON((ENGINE_READ(engine, RING_MI_MODE) & MODE_IDLE) == 0);
|
||||
|
||||
I915_WRITE(instpm,
|
||||
_MASKED_BIT_ENABLE(INSTPM_TLB_INVALIDATE |
|
||||
INSTPM_SYNC_FLUSH));
|
||||
if (intel_wait_for_register(&dev_priv->uncore,
|
||||
instpm, INSTPM_SYNC_FLUSH, 0,
|
||||
ENGINE_WRITE(engine, RING_INSTPM,
|
||||
_MASKED_BIT_ENABLE(INSTPM_TLB_INVALIDATE |
|
||||
INSTPM_SYNC_FLUSH));
|
||||
if (intel_wait_for_register(engine->uncore,
|
||||
RING_INSTPM(engine->mmio_base),
|
||||
INSTPM_SYNC_FLUSH, 0,
|
||||
1000))
|
||||
DRM_ERROR("%s: wait for SyncFlush to complete for TLB invalidation timed out\n",
|
||||
engine->name);
|
||||
@@ -606,32 +606,36 @@ static bool stop_ring(struct intel_engine_cs *engine)
|
||||
struct drm_i915_private *dev_priv = engine->i915;
|
||||
|
||||
if (INTEL_GEN(dev_priv) > 2) {
|
||||
I915_WRITE_MODE(engine, _MASKED_BIT_ENABLE(STOP_RING));
|
||||
if (intel_wait_for_register(&dev_priv->uncore,
|
||||
ENGINE_WRITE(engine,
|
||||
RING_MI_MODE, _MASKED_BIT_ENABLE(STOP_RING));
|
||||
if (intel_wait_for_register(engine->uncore,
|
||||
RING_MI_MODE(engine->mmio_base),
|
||||
MODE_IDLE,
|
||||
MODE_IDLE,
|
||||
1000)) {
|
||||
DRM_ERROR("%s : timed out trying to stop ring\n",
|
||||
engine->name);
|
||||
/* Sometimes we observe that the idle flag is not
|
||||
|
||||
/*
|
||||
* Sometimes we observe that the idle flag is not
|
||||
* set even though the ring is empty. So double
|
||||
* check before giving up.
|
||||
*/
|
||||
if (I915_READ_HEAD(engine) != I915_READ_TAIL(engine))
|
||||
if (ENGINE_READ(engine, RING_HEAD) !=
|
||||
ENGINE_READ(engine, RING_TAIL))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
I915_WRITE_HEAD(engine, I915_READ_TAIL(engine));
|
||||
ENGINE_WRITE(engine, RING_HEAD, ENGINE_READ(engine, RING_TAIL));
|
||||
|
||||
I915_WRITE_HEAD(engine, 0);
|
||||
I915_WRITE_TAIL(engine, 0);
|
||||
ENGINE_WRITE(engine, RING_HEAD, 0);
|
||||
ENGINE_WRITE(engine, RING_TAIL, 0);
|
||||
|
||||
/* The ring must be empty before it is disabled */
|
||||
I915_WRITE_CTL(engine, 0);
|
||||
ENGINE_WRITE(engine, RING_CTL, 0);
|
||||
|
||||
return (I915_READ_HEAD(engine) & HEAD_ADDR) == 0;
|
||||
return (ENGINE_READ(engine, RING_HEAD) & HEAD_ADDR) == 0;
|
||||
}
|
||||
|
||||
static int init_ring_common(struct intel_engine_cs *engine)
|
||||
@@ -640,26 +644,26 @@ static int init_ring_common(struct intel_engine_cs *engine)
|
||||
struct intel_ring *ring = engine->buffer;
|
||||
int ret = 0;
|
||||
|
||||
intel_uncore_forcewake_get(&dev_priv->uncore, FORCEWAKE_ALL);
|
||||
intel_uncore_forcewake_get(engine->uncore, FORCEWAKE_ALL);
|
||||
|
||||
if (!stop_ring(engine)) {
|
||||
/* G45 ring initialization often fails to reset head to zero */
|
||||
DRM_DEBUG_DRIVER("%s head not reset to zero "
|
||||
"ctl %08x head %08x tail %08x start %08x\n",
|
||||
engine->name,
|
||||
I915_READ_CTL(engine),
|
||||
I915_READ_HEAD(engine),
|
||||
I915_READ_TAIL(engine),
|
||||
I915_READ_START(engine));
|
||||
ENGINE_READ(engine, RING_CTL),
|
||||
ENGINE_READ(engine, RING_HEAD),
|
||||
ENGINE_READ(engine, RING_TAIL),
|
||||
ENGINE_READ(engine, RING_START));
|
||||
|
||||
if (!stop_ring(engine)) {
|
||||
DRM_ERROR("failed to set %s head to zero "
|
||||
"ctl %08x head %08x tail %08x start %08x\n",
|
||||
engine->name,
|
||||
I915_READ_CTL(engine),
|
||||
I915_READ_HEAD(engine),
|
||||
I915_READ_TAIL(engine),
|
||||
I915_READ_START(engine));
|
||||
ENGINE_READ(engine, RING_CTL),
|
||||
ENGINE_READ(engine, RING_HEAD),
|
||||
ENGINE_READ(engine, RING_TAIL),
|
||||
ENGINE_READ(engine, RING_START));
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
@@ -673,18 +677,18 @@ static int init_ring_common(struct intel_engine_cs *engine)
|
||||
intel_engine_reset_breadcrumbs(engine);
|
||||
|
||||
/* Enforce ordering by reading HEAD register back */
|
||||
I915_READ_HEAD(engine);
|
||||
ENGINE_READ(engine, RING_HEAD);
|
||||
|
||||
/* Initialize the ring. This must happen _after_ we've cleared the ring
|
||||
* registers with the above sequence (the readback of the HEAD registers
|
||||
* also enforces ordering), otherwise the hw might lose the new ring
|
||||
* register values. */
|
||||
I915_WRITE_START(engine, i915_ggtt_offset(ring->vma));
|
||||
ENGINE_WRITE(engine, RING_START, i915_ggtt_offset(ring->vma));
|
||||
|
||||
/* WaClearRingBufHeadRegAtInit:ctg,elk */
|
||||
if (I915_READ_HEAD(engine))
|
||||
if (ENGINE_READ(engine, RING_HEAD))
|
||||
DRM_DEBUG_DRIVER("%s initialization failed [head=%08x], fudging\n",
|
||||
engine->name, I915_READ_HEAD(engine));
|
||||
engine->name, ENGINE_READ(engine, RING_HEAD));
|
||||
|
||||
/* Check that the ring offsets point within the ring! */
|
||||
GEM_BUG_ON(!intel_ring_offset_valid(ring, ring->head));
|
||||
@@ -692,43 +696,44 @@ static int init_ring_common(struct intel_engine_cs *engine)
|
||||
intel_ring_update_space(ring);
|
||||
|
||||
/* First wake the ring up to an empty/idle ring */
|
||||
I915_WRITE_HEAD(engine, ring->head);
|
||||
I915_WRITE_TAIL(engine, ring->head);
|
||||
(void)I915_READ_TAIL(engine);
|
||||
ENGINE_WRITE(engine, RING_HEAD, ring->head);
|
||||
ENGINE_WRITE(engine, RING_TAIL, ring->head);
|
||||
ENGINE_POSTING_READ(engine, RING_TAIL);
|
||||
|
||||
I915_WRITE_CTL(engine, RING_CTL_SIZE(ring->size) | RING_VALID);
|
||||
ENGINE_WRITE(engine, RING_CTL, RING_CTL_SIZE(ring->size) | RING_VALID);
|
||||
|
||||
/* If the head is still not zero, the ring is dead */
|
||||
if (intel_wait_for_register(&dev_priv->uncore,
|
||||
if (intel_wait_for_register(engine->uncore,
|
||||
RING_CTL(engine->mmio_base),
|
||||
RING_VALID, RING_VALID,
|
||||
50)) {
|
||||
DRM_ERROR("%s initialization failed "
|
||||
"ctl %08x (valid? %d) head %08x [%08x] tail %08x [%08x] start %08x [expected %08x]\n",
|
||||
engine->name,
|
||||
I915_READ_CTL(engine),
|
||||
I915_READ_CTL(engine) & RING_VALID,
|
||||
I915_READ_HEAD(engine), ring->head,
|
||||
I915_READ_TAIL(engine), ring->tail,
|
||||
I915_READ_START(engine),
|
||||
ENGINE_READ(engine, RING_CTL),
|
||||
ENGINE_READ(engine, RING_CTL) & RING_VALID,
|
||||
ENGINE_READ(engine, RING_HEAD), ring->head,
|
||||
ENGINE_READ(engine, RING_TAIL), ring->tail,
|
||||
ENGINE_READ(engine, RING_START),
|
||||
i915_ggtt_offset(ring->vma));
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (INTEL_GEN(dev_priv) > 2)
|
||||
I915_WRITE_MODE(engine, _MASKED_BIT_DISABLE(STOP_RING));
|
||||
ENGINE_WRITE(engine,
|
||||
RING_MI_MODE, _MASKED_BIT_DISABLE(STOP_RING));
|
||||
|
||||
/* Now awake, let it get started */
|
||||
if (ring->tail != ring->head) {
|
||||
I915_WRITE_TAIL(engine, ring->tail);
|
||||
(void)I915_READ_TAIL(engine);
|
||||
ENGINE_WRITE(engine, RING_TAIL, ring->tail);
|
||||
ENGINE_POSTING_READ(engine, RING_TAIL);
|
||||
}
|
||||
|
||||
/* Papering over lost _interrupts_ immediately following the restart */
|
||||
intel_engine_queue_breadcrumbs(engine);
|
||||
out:
|
||||
intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
|
||||
intel_uncore_forcewake_put(engine->uncore, FORCEWAKE_ALL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -869,7 +874,7 @@ static int init_render_ring(struct intel_engine_cs *engine)
|
||||
I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_FORCE_ORDERING));
|
||||
|
||||
if (INTEL_GEN(dev_priv) >= 6)
|
||||
I915_WRITE_IMR(engine, ~engine->irq_keep_mask);
|
||||
ENGINE_WRITE(engine, RING_IMR, ~engine->irq_keep_mask);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -896,12 +901,10 @@ static void cancel_requests(struct intel_engine_cs *engine)
|
||||
|
||||
static void i9xx_submit_request(struct i915_request *request)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = request->i915;
|
||||
|
||||
i915_request_submit(request);
|
||||
|
||||
I915_WRITE_TAIL(request->engine,
|
||||
intel_ring_set_tail(request->ring, request->tail));
|
||||
ENGINE_WRITE(request->engine, RING_TAIL,
|
||||
intel_ring_set_tail(request->ring, request->tail));
|
||||
}
|
||||
|
||||
static u32 *i9xx_emit_breadcrumb(struct i915_request *rq, u32 *cs)
|
||||
@@ -973,20 +976,20 @@ gen5_irq_disable(struct intel_engine_cs *engine)
|
||||
static void
|
||||
i9xx_irq_enable(struct intel_engine_cs *engine)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = engine->i915;
|
||||
GEM_BUG_ON(engine->id != RCS0);
|
||||
|
||||
dev_priv->irq_mask &= ~engine->irq_enable_mask;
|
||||
I915_WRITE(IMR, dev_priv->irq_mask);
|
||||
POSTING_READ_FW(RING_IMR(engine->mmio_base));
|
||||
engine->i915->irq_mask &= ~engine->irq_enable_mask;
|
||||
ENGINE_WRITE(engine, RING_IMR, engine->i915->irq_mask);
|
||||
ENGINE_POSTING_READ(engine, RING_IMR);
|
||||
}
|
||||
|
||||
static void
|
||||
i9xx_irq_disable(struct intel_engine_cs *engine)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = engine->i915;
|
||||
GEM_BUG_ON(engine->id != RCS0);
|
||||
|
||||
dev_priv->irq_mask |= engine->irq_enable_mask;
|
||||
I915_WRITE(IMR, dev_priv->irq_mask);
|
||||
engine->i915->irq_mask |= engine->irq_enable_mask;
|
||||
ENGINE_WRITE(engine, RING_IMR, engine->i915->irq_mask);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1026,47 +1029,38 @@ bsd_ring_flush(struct i915_request *rq, u32 mode)
|
||||
static void
|
||||
gen6_irq_enable(struct intel_engine_cs *engine)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = engine->i915;
|
||||
|
||||
I915_WRITE_IMR(engine,
|
||||
~(engine->irq_enable_mask |
|
||||
engine->irq_keep_mask));
|
||||
ENGINE_WRITE(engine, RING_IMR,
|
||||
~(engine->irq_enable_mask | engine->irq_keep_mask));
|
||||
|
||||
/* Flush/delay to ensure the RING_IMR is active before the GT IMR */
|
||||
POSTING_READ_FW(RING_IMR(engine->mmio_base));
|
||||
ENGINE_POSTING_READ(engine, RING_IMR);
|
||||
|
||||
gen5_enable_gt_irq(dev_priv, engine->irq_enable_mask);
|
||||
gen5_enable_gt_irq(engine->i915, engine->irq_enable_mask);
|
||||
}
|
||||
|
||||
static void
|
||||
gen6_irq_disable(struct intel_engine_cs *engine)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = engine->i915;
|
||||
|
||||
I915_WRITE_IMR(engine, ~engine->irq_keep_mask);
|
||||
gen5_disable_gt_irq(dev_priv, engine->irq_enable_mask);
|
||||
ENGINE_WRITE(engine, RING_IMR, ~engine->irq_keep_mask);
|
||||
gen5_disable_gt_irq(engine->i915, engine->irq_enable_mask);
|
||||
}
|
||||
|
||||
static void
|
||||
hsw_vebox_irq_enable(struct intel_engine_cs *engine)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = engine->i915;
|
||||
|
||||
I915_WRITE_IMR(engine, ~engine->irq_enable_mask);
|
||||
ENGINE_WRITE(engine, RING_IMR, ~engine->irq_enable_mask);
|
||||
|
||||
/* Flush/delay to ensure the RING_IMR is active before the GT IMR */
|
||||
POSTING_READ_FW(RING_IMR(engine->mmio_base));
|
||||
ENGINE_POSTING_READ(engine, RING_IMR);
|
||||
|
||||
gen6_unmask_pm_irq(dev_priv, engine->irq_enable_mask);
|
||||
gen6_unmask_pm_irq(engine->i915, engine->irq_enable_mask);
|
||||
}
|
||||
|
||||
static void
|
||||
hsw_vebox_irq_disable(struct intel_engine_cs *engine)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = engine->i915;
|
||||
|
||||
I915_WRITE_IMR(engine, ~0);
|
||||
gen6_mask_pm_irq(dev_priv, engine->irq_enable_mask);
|
||||
ENGINE_WRITE(engine, RING_IMR, ~0);
|
||||
gen6_mask_pm_irq(engine->i915, engine->irq_enable_mask);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1577,7 +1571,7 @@ void intel_engine_cleanup(struct intel_engine_cs *engine)
|
||||
struct drm_i915_private *dev_priv = engine->i915;
|
||||
|
||||
WARN_ON(INTEL_GEN(dev_priv) > 2 &&
|
||||
(I915_READ_MODE(engine) & MODE_IDLE) == 0);
|
||||
(ENGINE_READ(engine, RING_MI_MODE) & MODE_IDLE) == 0);
|
||||
|
||||
intel_ring_unpin(engine->buffer);
|
||||
intel_ring_put(engine->buffer);
|
||||
@@ -1612,11 +1606,11 @@ static int load_pd_dir(struct i915_request *rq,
|
||||
return PTR_ERR(cs);
|
||||
|
||||
*cs++ = MI_LOAD_REGISTER_IMM(1);
|
||||
*cs++ = i915_mmio_reg_offset(RING_PP_DIR_DCLV(engine));
|
||||
*cs++ = i915_mmio_reg_offset(RING_PP_DIR_DCLV(engine->mmio_base));
|
||||
*cs++ = PP_DIR_DCLV_2G;
|
||||
|
||||
*cs++ = MI_LOAD_REGISTER_IMM(1);
|
||||
*cs++ = i915_mmio_reg_offset(RING_PP_DIR_BASE(engine));
|
||||
*cs++ = i915_mmio_reg_offset(RING_PP_DIR_BASE(engine->mmio_base));
|
||||
*cs++ = ppgtt->pd.base.ggtt_offset << 10;
|
||||
|
||||
intel_ring_advance(rq, cs);
|
||||
@@ -1635,7 +1629,7 @@ static int flush_pd_dir(struct i915_request *rq)
|
||||
|
||||
/* Stall until the page table load is complete */
|
||||
*cs++ = MI_STORE_REGISTER_MEM | MI_SRM_LRM_GLOBAL_GTT;
|
||||
*cs++ = i915_mmio_reg_offset(RING_PP_DIR_BASE(engine));
|
||||
*cs++ = i915_mmio_reg_offset(RING_PP_DIR_BASE(engine->mmio_base));
|
||||
*cs++ = i915_scratch_offset(rq->i915);
|
||||
*cs++ = MI_NOOP;
|
||||
|
||||
@@ -2052,7 +2046,7 @@ int intel_ring_cacheline_align(struct i915_request *rq)
|
||||
|
||||
static void gen6_bsd_submit_request(struct i915_request *request)
|
||||
{
|
||||
struct intel_uncore *uncore = &request->i915->uncore;
|
||||
struct intel_uncore *uncore = request->engine->uncore;
|
||||
|
||||
intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL);
|
||||
|
||||
|
Reference in New Issue
Block a user