Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 12638c57 authored by Ben Widawsky's avatar Ben Widawsky Committed by Daniel Vetter
Browse files

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: default avatarDamien Lespiau <damien.lespiau@intel.com>
Signed-off-by: default avatarBen Widawsky <ben@bwidawsk.net>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent a19d2933
Loading
Loading
Loading
Loading
+25 −6
Original line number Diff line number Diff line
@@ -944,8 +944,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("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)
@@ -2690,6 +2697,7 @@ static int ivybridge_irq_postinstall(struct drm_device *dev)
		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;
@@ -2715,10 +2723,21 @@ static int ivybridge_irq_postinstall(struct drm_device *dev)
	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);

+3 −0
Original line number Diff line number Diff line
@@ -886,6 +886,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)
+2 −1
Original line number Diff line number Diff line
@@ -1969,7 +1969,8 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev)
	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;