Commit e32192e1 authored by Tvrtko Ursulin's avatar Tvrtko Ursulin

drm/i915/gen8: Tidy display interrupt processing

One bugfix and a few tidy-ups:

 * Pipe fault logging was broken on Gen9+.
 * Removed some unnecessary local variables.
 * Removed unnecessary initializers.
 * Decreased pipe iir block indentation level.
 * Grouped variable initialization close to use sites.
Signed-off-by: default avatarTvrtko Ursulin <tvrtko.ursulin@intel.com>
Reviewed-by: default avatarChris Wilson <chris@cris-wilson.co.uk>
Link: http://patchwork.freedesktop.org/patch/msgid/1452614647-13973-1-git-send-email-tvrtko.ursulin@linux.intel.com
parent 1892faa9
...@@ -2268,11 +2268,9 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) ...@@ -2268,11 +2268,9 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
{ {
struct drm_device *dev = arg; struct drm_device *dev = arg;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
u32 master_ctl; u32 master_ctl, iir;
irqreturn_t ret = IRQ_NONE; irqreturn_t ret = IRQ_NONE;
uint32_t tmp = 0;
enum pipe pipe; enum pipe pipe;
u32 aux_mask = GEN8_AUX_CHANNEL_A;
if (!intel_irqs_enabled(dev_priv)) if (!intel_irqs_enabled(dev_priv))
return IRQ_NONE; return IRQ_NONE;
...@@ -2280,10 +2278,6 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) ...@@ -2280,10 +2278,6 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
/* IRQs are synced during runtime_suspend, we don't require a wakeref */ /* IRQs are synced during runtime_suspend, we don't require a wakeref */
disable_rpm_wakeref_asserts(dev_priv); disable_rpm_wakeref_asserts(dev_priv);
if (INTEL_INFO(dev_priv)->gen >= 9)
aux_mask |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C |
GEN9_AUX_CHANNEL_D;
master_ctl = I915_READ_FW(GEN8_MASTER_IRQ); master_ctl = I915_READ_FW(GEN8_MASTER_IRQ);
master_ctl &= ~GEN8_MASTER_IRQ_CONTROL; master_ctl &= ~GEN8_MASTER_IRQ_CONTROL;
if (!master_ctl) if (!master_ctl)
...@@ -2296,11 +2290,11 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) ...@@ -2296,11 +2290,11 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
ret = gen8_gt_irq_handler(dev_priv, master_ctl); ret = gen8_gt_irq_handler(dev_priv, master_ctl);
if (master_ctl & GEN8_DE_MISC_IRQ) { if (master_ctl & GEN8_DE_MISC_IRQ) {
tmp = I915_READ(GEN8_DE_MISC_IIR); iir = I915_READ(GEN8_DE_MISC_IIR);
if (tmp) { if (iir) {
I915_WRITE(GEN8_DE_MISC_IIR, tmp); I915_WRITE(GEN8_DE_MISC_IIR, iir);
ret = IRQ_HANDLED; ret = IRQ_HANDLED;
if (tmp & GEN8_DE_MISC_GSE) if (iir & GEN8_DE_MISC_GSE)
intel_opregion_asle_intr(dev); intel_opregion_asle_intr(dev);
else else
DRM_ERROR("Unexpected DE Misc interrupt\n"); DRM_ERROR("Unexpected DE Misc interrupt\n");
...@@ -2310,33 +2304,40 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) ...@@ -2310,33 +2304,40 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
} }
if (master_ctl & GEN8_DE_PORT_IRQ) { if (master_ctl & GEN8_DE_PORT_IRQ) {
tmp = I915_READ(GEN8_DE_PORT_IIR); iir = I915_READ(GEN8_DE_PORT_IIR);
if (tmp) { if (iir) {
u32 tmp_mask;
bool found = false; bool found = false;
u32 hotplug_trigger = 0;
if (IS_BROXTON(dev_priv))
hotplug_trigger = tmp & BXT_DE_PORT_HOTPLUG_MASK;
else if (IS_BROADWELL(dev_priv))
hotplug_trigger = tmp & GEN8_PORT_DP_A_HOTPLUG;
I915_WRITE(GEN8_DE_PORT_IIR, tmp); I915_WRITE(GEN8_DE_PORT_IIR, iir);
ret = IRQ_HANDLED; ret = IRQ_HANDLED;
if (tmp & aux_mask) { tmp_mask = GEN8_AUX_CHANNEL_A;
if (INTEL_INFO(dev_priv)->gen >= 9)
tmp_mask |= GEN9_AUX_CHANNEL_B |
GEN9_AUX_CHANNEL_C |
GEN9_AUX_CHANNEL_D;
if (iir & tmp_mask) {
dp_aux_irq_handler(dev); dp_aux_irq_handler(dev);
found = true; found = true;
} }
if (hotplug_trigger) { if (IS_BROXTON(dev_priv)) {
if (IS_BROXTON(dev)) tmp_mask = iir & BXT_DE_PORT_HOTPLUG_MASK;
bxt_hpd_irq_handler(dev, hotplug_trigger, hpd_bxt); if (tmp_mask) {
else bxt_hpd_irq_handler(dev, tmp_mask, hpd_bxt);
ilk_hpd_irq_handler(dev, hotplug_trigger, hpd_bdw); found = true;
found = true; }
} else if (IS_BROADWELL(dev_priv)) {
tmp_mask = iir & GEN8_PORT_DP_A_HOTPLUG;
if (tmp_mask) {
ilk_hpd_irq_handler(dev, tmp_mask, hpd_bdw);
found = true;
}
} }
if (IS_BROXTON(dev) && (tmp & BXT_DE_PORT_GMBUS)) { if (IS_BROXTON(dev) && (iir & BXT_DE_PORT_GMBUS)) {
gmbus_irq_handler(dev); gmbus_irq_handler(dev);
found = true; found = true;
} }
...@@ -2349,49 +2350,51 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) ...@@ -2349,49 +2350,51 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
} }
for_each_pipe(dev_priv, pipe) { for_each_pipe(dev_priv, pipe) {
uint32_t pipe_iir, flip_done = 0, fault_errors = 0; u32 flip_done, fault_errors;
if (!(master_ctl & GEN8_DE_PIPE_IRQ(pipe))) if (!(master_ctl & GEN8_DE_PIPE_IRQ(pipe)))
continue; continue;
pipe_iir = I915_READ(GEN8_DE_PIPE_IIR(pipe)); iir = I915_READ(GEN8_DE_PIPE_IIR(pipe));
if (pipe_iir) { if (!iir) {
ret = IRQ_HANDLED; DRM_ERROR("The master control interrupt lied (DE PIPE)!\n");
I915_WRITE(GEN8_DE_PIPE_IIR(pipe), pipe_iir); continue;
}
if (pipe_iir & GEN8_PIPE_VBLANK && ret = IRQ_HANDLED;
intel_pipe_handle_vblank(dev, pipe)) I915_WRITE(GEN8_DE_PIPE_IIR(pipe), iir);
intel_check_page_flip(dev, pipe);
if (INTEL_INFO(dev_priv)->gen >= 9) if (iir & GEN8_PIPE_VBLANK &&
flip_done = pipe_iir & GEN9_PIPE_PLANE1_FLIP_DONE; intel_pipe_handle_vblank(dev, pipe))
else intel_check_page_flip(dev, pipe);
flip_done = pipe_iir & GEN8_PIPE_PRIMARY_FLIP_DONE;
if (flip_done) { flip_done = iir;
intel_prepare_page_flip(dev, pipe); if (INTEL_INFO(dev_priv)->gen >= 9)
intel_finish_page_flip_plane(dev, pipe); flip_done &= GEN9_PIPE_PLANE1_FLIP_DONE;
} else
flip_done &= GEN8_PIPE_PRIMARY_FLIP_DONE;
if (pipe_iir & GEN8_PIPE_CDCLK_CRC_DONE) if (flip_done) {
hsw_pipe_crc_irq_handler(dev, pipe); intel_prepare_page_flip(dev, pipe);
intel_finish_page_flip_plane(dev, pipe);
}
if (pipe_iir & GEN8_PIPE_FIFO_UNDERRUN) if (iir & GEN8_PIPE_CDCLK_CRC_DONE)
intel_cpu_fifo_underrun_irq_handler(dev_priv, hsw_pipe_crc_irq_handler(dev, pipe);
pipe);
if (iir & GEN8_PIPE_FIFO_UNDERRUN)
intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe);
if (INTEL_INFO(dev_priv)->gen >= 9) fault_errors = iir;
fault_errors = pipe_iir & GEN9_DE_PIPE_IRQ_FAULT_ERRORS; if (INTEL_INFO(dev_priv)->gen >= 9)
else fault_errors &= GEN9_DE_PIPE_IRQ_FAULT_ERRORS;
fault_errors = pipe_iir & GEN8_DE_PIPE_IRQ_FAULT_ERRORS; else
fault_errors &= GEN8_DE_PIPE_IRQ_FAULT_ERRORS;
if (fault_errors) if (fault_errors)
DRM_ERROR("Fault errors on pipe %c\n: 0x%08x", DRM_ERROR("Fault errors on pipe %c\n: 0x%08x",
pipe_name(pipe), pipe_name(pipe),
pipe_iir & GEN8_DE_PIPE_IRQ_FAULT_ERRORS); fault_errors);
} else
DRM_ERROR("The master control interrupt lied (DE PIPE)!\n");
} }
if (HAS_PCH_SPLIT(dev) && !HAS_PCH_NOP(dev) && if (HAS_PCH_SPLIT(dev) && !HAS_PCH_NOP(dev) &&
...@@ -2401,15 +2404,15 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) ...@@ -2401,15 +2404,15 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
* scheme also closed the SDE interrupt handling race we've seen * scheme also closed the SDE interrupt handling race we've seen
* on older pch-split platforms. But this needs testing. * on older pch-split platforms. But this needs testing.
*/ */
u32 pch_iir = I915_READ(SDEIIR); iir = I915_READ(SDEIIR);
if (pch_iir) { if (iir) {
I915_WRITE(SDEIIR, pch_iir); I915_WRITE(SDEIIR, iir);
ret = IRQ_HANDLED; ret = IRQ_HANDLED;
if (HAS_PCH_SPT(dev_priv)) if (HAS_PCH_SPT(dev_priv))
spt_irq_handler(dev, pch_iir); spt_irq_handler(dev, iir);
else else
cpt_irq_handler(dev, pch_iir); cpt_irq_handler(dev, iir);
} else { } else {
/* /*
* Like on previous PCH there seems to be something * Like on previous PCH there seems to be something
......
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