[PATCH 15/18] drm/i915: Enable vebox interrupts

Ben Widawsky
2012-11-06T16:27:01Z

Similar to a patch originally written by:

v2: Reversed the meanings of masked and enabled (Haihao)
Made non-destructive writes in case enable/disabler rps runs first
(Haihao)

CC: Xiang, Haihao <haihao.xiang@intel.com>
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
---
drivers/gpu/drm/i915/i915_irq.c | 25 +++++++++++++++++++++++--
drivers/gpu/drm/i915/i915_reg.h | 3 +++
drivers/gpu/drm/i915/intel_ringbuffer.c | 2 +-
3 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index d3838c6..7714ca6 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -546,8 +546,15 @@ static void hsw_pm_irq_handler(struct drm_i915_private *dev_priv,
}
spin_unlock_irqrestore(&dev_priv->rps.lock, flags);

- if (pm_iir & ~GEN6_PM_RPS_EVENTS)
- DRM_ERROR("Unexpected PM interrupted\n");
+ if (pm_iir & ~GEN6_PM_RPS_EVENTS) {
+ if (pm_iir & PM_VEBOX_USER_INTERRUPT)
+ notify_ring(dev_priv->dev, &dev_priv->ring[VECS]);
+
+ if (pm_iir & PM_VEBOX_CS_ERROR_INTERRUPT) {
+ DRM_ERROR("PM error interrupt 0x%08x\n", pm_iir);
+ i915_handle_error(dev_priv->dev, false);
+ }
+ }
}

static irqreturn_t valleyview_irq_handler(int irq, void *arg)
@@ -2000,6 +2007,20 @@ static int ivybridge_irq_postinstall(struct drm_device *dev)
I915_WRITE(SDEIER, hotplug_mask);
POSTING_READ(SDEIER);

+ I915_WRITE(GEN6_PMIIR, I915_READ(GEN6_PMIIR));
+ if (HAS_VEBOX(dev)) {
+ u32 pm_irqs, pmier, pmimr;
+ pm_irqs = PM_VEBOX_USER_INTERRUPT | PM_VEBOX_CS_ERROR_INTERRUPT;
+
+ /* Our enable/disable rps functions may touch these registers so
+ * make sure to set a known state for only the non-RPS bits. */
+ pmier = (I915_READ(GEN6_PMIER) & GEN6_PM_RPS_EVENTS) | pm_irqs;
+ pmimr = (I915_READ(GEN6_PMIMR) | ~GEN6_PM_RPS_EVENTS) & ~pm_irqs;
+ I915_WRITE(GEN6_PMIMR, pmimr);
+ I915_WRITE(GEN6_PMIER, pmier);
+ }
+ POSTING_READ(GEN6_PMIER);
+
ironlake_enable_pch_hotplug(dev);

return 0;
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index b83928d..885f481 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -717,6 +717,9 @@
#define GT_RENDER_DEBUG_INTERRUPT (1 << 1)
#define GT_RENDER_USER_INTERRUPT (1 << 0)

+#define PM_VEBOX_CS_ERROR_INTERRUPT (1 << 12) /* hsw+ */
+#define PM_VEBOX_USER_INTERRUPT (1 << 10) /* hsw+ */
+
/* These are all the "old" interrupts */
#define ILK_BSD_USER_INTERRUPT (1<<5)
#define I915_PIPE_CONTROL_NOTIFY_INTERRUPT (1<<18)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 5f03abc..9ec00a9 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1766,7 +1766,7 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev)
ring->flush = gen6_ring_flush;
ring->add_request = gen6_add_request;
ring->get_seqno = gen6_ring_get_seqno;
- ring->irq_enable_mask = 0;
+ ring->irq_enable_mask = PM_VEBOX_USER_INTERRUPT | PM_VEBOX_CS_ERROR_INTERRUPT;
ring->irq_get = hsw_vebox_get_irq;
ring->irq_put = hsw_vebox_put_irq;
ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
--
1.8.0