drm/i915: Reduce locking in gen8 IRQ handler
Similar in vain in reducing the number of unrequired spinlocks used for execlist command submission (where the forcewake is required but manually controlled), we know that the IRQ registers are outside of the powerwell and so we can access them directly. Since we now have direct access exported via I915_READ_FW/I915_WRITE_FW, lets put those to use in the irq handlers as well. In the process, reorder the execlist submission to happen as early as possible. v2: Restrict the untraced register mmio to just the GT path (i.e. the hotpath for execlists) Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
parent
a6111f7b66
commit
cb0d205e0f
@ -1285,56 +1285,56 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev,
|
||||
irqreturn_t ret = IRQ_NONE;
|
||||
|
||||
if (master_ctl & (GEN8_GT_RCS_IRQ | GEN8_GT_BCS_IRQ)) {
|
||||
tmp = I915_READ(GEN8_GT_IIR(0));
|
||||
tmp = I915_READ_FW(GEN8_GT_IIR(0));
|
||||
if (tmp) {
|
||||
I915_WRITE(GEN8_GT_IIR(0), tmp);
|
||||
I915_WRITE_FW(GEN8_GT_IIR(0), tmp);
|
||||
ret = IRQ_HANDLED;
|
||||
|
||||
rcs = tmp >> GEN8_RCS_IRQ_SHIFT;
|
||||
ring = &dev_priv->ring[RCS];
|
||||
if (rcs & GT_RENDER_USER_INTERRUPT)
|
||||
notify_ring(dev, ring);
|
||||
if (rcs & GT_CONTEXT_SWITCH_INTERRUPT)
|
||||
intel_lrc_irq_handler(ring);
|
||||
if (rcs & GT_RENDER_USER_INTERRUPT)
|
||||
notify_ring(dev, ring);
|
||||
|
||||
bcs = tmp >> GEN8_BCS_IRQ_SHIFT;
|
||||
ring = &dev_priv->ring[BCS];
|
||||
if (bcs & GT_RENDER_USER_INTERRUPT)
|
||||
notify_ring(dev, ring);
|
||||
if (bcs & GT_CONTEXT_SWITCH_INTERRUPT)
|
||||
intel_lrc_irq_handler(ring);
|
||||
if (bcs & GT_RENDER_USER_INTERRUPT)
|
||||
notify_ring(dev, ring);
|
||||
} else
|
||||
DRM_ERROR("The master control interrupt lied (GT0)!\n");
|
||||
}
|
||||
|
||||
if (master_ctl & (GEN8_GT_VCS1_IRQ | GEN8_GT_VCS2_IRQ)) {
|
||||
tmp = I915_READ(GEN8_GT_IIR(1));
|
||||
tmp = I915_READ_FW(GEN8_GT_IIR(1));
|
||||
if (tmp) {
|
||||
I915_WRITE(GEN8_GT_IIR(1), tmp);
|
||||
I915_WRITE_FW(GEN8_GT_IIR(1), tmp);
|
||||
ret = IRQ_HANDLED;
|
||||
|
||||
vcs = tmp >> GEN8_VCS1_IRQ_SHIFT;
|
||||
ring = &dev_priv->ring[VCS];
|
||||
if (vcs & GT_RENDER_USER_INTERRUPT)
|
||||
notify_ring(dev, ring);
|
||||
if (vcs & GT_CONTEXT_SWITCH_INTERRUPT)
|
||||
intel_lrc_irq_handler(ring);
|
||||
if (vcs & GT_RENDER_USER_INTERRUPT)
|
||||
notify_ring(dev, ring);
|
||||
|
||||
vcs = tmp >> GEN8_VCS2_IRQ_SHIFT;
|
||||
ring = &dev_priv->ring[VCS2];
|
||||
if (vcs & GT_RENDER_USER_INTERRUPT)
|
||||
notify_ring(dev, ring);
|
||||
if (vcs & GT_CONTEXT_SWITCH_INTERRUPT)
|
||||
intel_lrc_irq_handler(ring);
|
||||
if (vcs & GT_RENDER_USER_INTERRUPT)
|
||||
notify_ring(dev, ring);
|
||||
} else
|
||||
DRM_ERROR("The master control interrupt lied (GT1)!\n");
|
||||
}
|
||||
|
||||
if (master_ctl & GEN8_GT_PM_IRQ) {
|
||||
tmp = I915_READ(GEN8_GT_IIR(2));
|
||||
tmp = I915_READ_FW(GEN8_GT_IIR(2));
|
||||
if (tmp & dev_priv->pm_rps_events) {
|
||||
I915_WRITE(GEN8_GT_IIR(2),
|
||||
tmp & dev_priv->pm_rps_events);
|
||||
I915_WRITE_FW(GEN8_GT_IIR(2),
|
||||
tmp & dev_priv->pm_rps_events);
|
||||
ret = IRQ_HANDLED;
|
||||
gen6_rps_irq_handler(dev_priv, tmp);
|
||||
} else
|
||||
@ -1342,17 +1342,17 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev,
|
||||
}
|
||||
|
||||
if (master_ctl & GEN8_GT_VECS_IRQ) {
|
||||
tmp = I915_READ(GEN8_GT_IIR(3));
|
||||
tmp = I915_READ_FW(GEN8_GT_IIR(3));
|
||||
if (tmp) {
|
||||
I915_WRITE(GEN8_GT_IIR(3), tmp);
|
||||
I915_WRITE_FW(GEN8_GT_IIR(3), tmp);
|
||||
ret = IRQ_HANDLED;
|
||||
|
||||
vcs = tmp >> GEN8_VECS_IRQ_SHIFT;
|
||||
ring = &dev_priv->ring[VECS];
|
||||
if (vcs & GT_RENDER_USER_INTERRUPT)
|
||||
notify_ring(dev, ring);
|
||||
if (vcs & GT_CONTEXT_SWITCH_INTERRUPT)
|
||||
intel_lrc_irq_handler(ring);
|
||||
if (vcs & GT_RENDER_USER_INTERRUPT)
|
||||
notify_ring(dev, ring);
|
||||
} else
|
||||
DRM_ERROR("The master control interrupt lied (GT3)!\n");
|
||||
}
|
||||
@ -2178,13 +2178,12 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
|
||||
aux_mask |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C |
|
||||
GEN9_AUX_CHANNEL_D;
|
||||
|
||||
master_ctl = I915_READ(GEN8_MASTER_IRQ);
|
||||
master_ctl = I915_READ_FW(GEN8_MASTER_IRQ);
|
||||
master_ctl &= ~GEN8_MASTER_IRQ_CONTROL;
|
||||
if (!master_ctl)
|
||||
return IRQ_NONE;
|
||||
|
||||
I915_WRITE(GEN8_MASTER_IRQ, 0);
|
||||
POSTING_READ(GEN8_MASTER_IRQ);
|
||||
I915_WRITE_FW(GEN8_MASTER_IRQ, 0);
|
||||
|
||||
/* Find, clear, then process each source of interrupt */
|
||||
|
||||
@ -2281,8 +2280,8 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
|
||||
|
||||
}
|
||||
|
||||
I915_WRITE(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL);
|
||||
POSTING_READ(GEN8_MASTER_IRQ);
|
||||
I915_WRITE_FW(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL);
|
||||
POSTING_READ_FW(GEN8_MASTER_IRQ);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user