Skip to content

Commit

Permalink
drm/i915: optimize ilk/snb irq handler
Browse files Browse the repository at this point in the history
We only need to read/write the south interrupt register if the
corresponding bit is set in the north master interrupt register.
Noticed while reading our interrupt handling code.

Same optimization has already been applied on ivb in

commit 0e43406
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Wed May 9 21:45:44 2012 +0100

    drm/i915: Simplify interrupt processing for IvyBridge

    We can take advantage that the PCH_IIR is a subordinate register to
    reduce one of the required IIR reads, and that we only need to clear
    interrupts handled to reduce the writes. And by simply tidying the code
    we can reduce the line count and hopefully make it more readable.

Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
  • Loading branch information
Daniel Vetter committed Nov 30, 2012
1 parent 99057c8 commit acd15b6
Showing 1 changed file with 7 additions and 6 deletions.
13 changes: 7 additions & 6 deletions drivers/gpu/drm/i915/i915_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -758,7 +758,7 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
struct drm_device *dev = (struct drm_device *) arg;
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
int ret = IRQ_NONE;
u32 de_iir, gt_iir, de_ier, pch_iir, pm_iir;
u32 de_iir, gt_iir, de_ier, pm_iir;

atomic_inc(&dev_priv->irq_received);

Expand All @@ -769,11 +769,9 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)

de_iir = I915_READ(DEIIR);
gt_iir = I915_READ(GTIIR);
pch_iir = I915_READ(SDEIIR);
pm_iir = I915_READ(GEN6_PMIIR);

if (de_iir == 0 && gt_iir == 0 && pch_iir == 0 &&
(!IS_GEN6(dev) || pm_iir == 0))
if (de_iir == 0 && gt_iir == 0 && (!IS_GEN6(dev) || pm_iir == 0))
goto done;

ret = IRQ_HANDLED;
Expand Down Expand Up @@ -804,10 +802,15 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)

/* check event from PCH */
if (de_iir & DE_PCH_EVENT) {
u32 pch_iir = I915_READ(SDEIIR);

if (HAS_PCH_CPT(dev))
cpt_irq_handler(dev, pch_iir);
else
ibx_irq_handler(dev, pch_iir);

/* should clear PCH hotplug event before clear CPU irq */
I915_WRITE(SDEIIR, pch_iir);
}

if (IS_GEN5(dev) && de_iir & DE_PCU_EVENT)
Expand All @@ -816,8 +819,6 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
if (IS_GEN6(dev) && pm_iir & GEN6_PM_DEFERRED_EVENTS)
gen6_queue_rps_work(dev_priv, pm_iir);

/* should clear PCH hotplug event before clear CPU irq */
I915_WRITE(SDEIIR, pch_iir);
I915_WRITE(GTIIR, gt_iir);
I915_WRITE(DEIIR, de_iir);
I915_WRITE(GEN6_PMIIR, pm_iir);
Expand Down

0 comments on commit acd15b6

Please sign in to comment.