blob: f9cf37a54cb408b637fc3833c13f405f864254a4 [file] [log] [blame]
From 925cdffd7db75dc492ed4600bd0b9e20e98ad1c3 Mon Sep 17 00:00:00 2001
From: Ben Widawsky <ben@bwidawsk.net>
Date: Tue, 28 May 2013 19:22:31 -0700
Subject: drm/i915: Enable vebox interrupts
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)
v3: Reword error message (Damien)
Modify postinstall to do the right thing based on previous fixup. (Ben)
CC: Xiang, Haihao <haihao.xiang@intel.com>
Reviewed-by: Damien Lespiau <damien.lespiau@intel.com>
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
(cherry picked from commit 12638c57f31952127c734c26315e1348fa1334c2)
Signed-off-by: Darren Hart <dvhart@linux.intel.com>
---
drivers/gpu/drm/i915/i915_irq.c | 31 +++++++++++++++++++++++++------
drivers/gpu/drm/i915/i915_reg.h | 3 +++
drivers/gpu/drm/i915/intel_ringbuffer.c | 3 ++-
3 files changed, 30 insertions(+), 7 deletions(-)
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -935,8 +935,15 @@ static void hsw_pm_irq_handler(struct dr
}
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("VEBOX CS error interrupt 0x%08x\n", pm_iir);
+ i915_handle_error(dev_priv->dev, false);
+ }
+ }
}
static irqreturn_t valleyview_irq_handler(int irq, void *arg)
@@ -2727,6 +2734,7 @@ static int ivybridge_irq_postinstall(str
DE_PLANEA_FLIP_DONE_IVB |
DE_AUX_CHANNEL_A_IVB |
DE_ERR_INT_IVB;
+ u32 pm_irqs = GEN6_PM_RPS_EVENTS;
u32 gt_irqs;
dev_priv->irq_mask = ~display_mask;
@@ -2752,10 +2760,21 @@ static int ivybridge_irq_postinstall(str
I915_WRITE(GTIER, gt_irqs);
POSTING_READ(GTIER);
- /* Power management */
- I915_WRITE(GEN6_PMIMR, ~GEN6_PM_RPS_EVENTS);
- I915_WRITE(GEN6_PMIER, GEN6_PM_RPS_EVENTS);
- POSTING_READ(GEN6_PMIMR);
+ I915_WRITE(GEN6_PMIIR, I915_READ(GEN6_PMIIR));
+ if (HAS_VEBOX(dev))
+ 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.
+ * The RMW is extra paranoia since this should be called after being set
+ * to a known state in preinstall.
+ * */
+ I915_WRITE(GEN6_PMIMR,
+ (I915_READ(GEN6_PMIMR) | ~GEN6_PM_RPS_EVENTS) & ~pm_irqs);
+ I915_WRITE(GEN6_PMIER,
+ (I915_READ(GEN6_PMIER) & GEN6_PM_RPS_EVENTS) | pm_irqs);
+ POSTING_READ(GEN6_PMIER);
ibx_irq_postinstall(dev);
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -889,6 +889,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)
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1990,7 +1990,8 @@ int intel_init_vebox_ring_buffer(struct
ring->add_request = gen6_add_request;
ring->get_seqno = gen6_ring_get_seqno;
ring->set_seqno = ring_set_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;