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

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

drm/i915: ring irq cleanups



- gen6 put/get only need one argument
    rflags and gflags are always the same (see above explanation)
- remove a couple redundantly defined IRQs
- reordered some lines to make things go in descending order

Every ring has its own interrupts, enables, masks, and status bits that
are fed into the main interrupt enable/mask/status registers. At one
point in time it seemed like a good idea to make our functions support
the notion that each interrupt may have a different bit position in the
corresponding register (blitter parser error may be bit n in IMR, but
bit m in blitter IMR). It turned out though that the HW designers did us
a solid on Gen6+ and this unfortunate situation has been avoided. This
allows our interrupt code to be cleaned up a bit.

I jammed this into one commit because there should be no functional
change with this commit, and staging it into multiple commits was
unnecessarily artificial IMO.

CC: Chris Wilson <chris@chris-wilson.co.uk>
CC: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: default avatarBen Widawsky <benjamin.widawsky@intel.com>
Reviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
[danvet:
- fixed up merged conflict with vlv changes.
- added GEN6 to GT blitter bit, we only use it on gen6+.
- added a comment to both ring irq bits and GT irq bits that on gen6+
  these alias.
- added comment that GT_BSD_USER_INTERRUPT is ilk-only.
- I've got confused a bit that we still use GT_USER_INTERRUPT on ivb
  for the render ring - but this goes back to ilk where we have only
  gt interrupt bits and so we be equally confusing if changed.]
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 96d6e350
Loading
Loading
Loading
Loading
+10 −10
Original line number Original line Diff line number Diff line
@@ -462,7 +462,7 @@ static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS)
			notify_ring(dev, &dev_priv->ring[RCS]);
			notify_ring(dev, &dev_priv->ring[RCS]);
		if (gt_iir & GT_GEN6_BSD_USER_INTERRUPT)
		if (gt_iir & GT_GEN6_BSD_USER_INTERRUPT)
			notify_ring(dev, &dev_priv->ring[VCS]);
			notify_ring(dev, &dev_priv->ring[VCS]);
		if (gt_iir & GT_BLT_USER_INTERRUPT)
		if (gt_iir & GT_GEN6_BLT_USER_INTERRUPT)
			notify_ring(dev, &dev_priv->ring[BCS]);
			notify_ring(dev, &dev_priv->ring[BCS]);


		if (gt_iir & (GT_GEN6_BLT_CS_ERROR_INTERRUPT |
		if (gt_iir & (GT_GEN6_BLT_CS_ERROR_INTERRUPT |
@@ -620,9 +620,9 @@ static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS)


	if (gt_iir & (GT_USER_INTERRUPT | GT_PIPE_NOTIFY))
	if (gt_iir & (GT_USER_INTERRUPT | GT_PIPE_NOTIFY))
		notify_ring(dev, &dev_priv->ring[RCS]);
		notify_ring(dev, &dev_priv->ring[RCS]);
	if (gt_iir & GT_GEN6_BSD_USER_INTERRUPT)
	if (gt_iir & GEN6_BSD_USER_INTERRUPT)
		notify_ring(dev, &dev_priv->ring[VCS]);
		notify_ring(dev, &dev_priv->ring[VCS]);
	if (gt_iir & GT_BLT_USER_INTERRUPT)
	if (gt_iir & GEN6_BLITTER_USER_INTERRUPT)
		notify_ring(dev, &dev_priv->ring[BCS]);
		notify_ring(dev, &dev_priv->ring[BCS]);


	if (de_iir & DE_GSE_IVB)
	if (de_iir & DE_GSE_IVB)
@@ -688,7 +688,7 @@ static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS)
	atomic_inc(&dev_priv->irq_received);
	atomic_inc(&dev_priv->irq_received);


	if (IS_GEN6(dev))
	if (IS_GEN6(dev))
		bsd_usr_interrupt = GT_GEN6_BSD_USER_INTERRUPT;
		bsd_usr_interrupt = GEN6_BSD_USER_INTERRUPT;


	/* disable master interrupt before clearing iir  */
	/* disable master interrupt before clearing iir  */
	de_ier = I915_READ(DEIER);
	de_ier = I915_READ(DEIER);
@@ -722,7 +722,7 @@ static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS)
		notify_ring(dev, &dev_priv->ring[RCS]);
		notify_ring(dev, &dev_priv->ring[RCS]);
	if (gt_iir & bsd_usr_interrupt)
	if (gt_iir & bsd_usr_interrupt)
		notify_ring(dev, &dev_priv->ring[VCS]);
		notify_ring(dev, &dev_priv->ring[VCS]);
	if (gt_iir & GT_BLT_USER_INTERRUPT)
	if (gt_iir & GEN6_BLITTER_USER_INTERRUPT)
		notify_ring(dev, &dev_priv->ring[BCS]);
		notify_ring(dev, &dev_priv->ring[BCS]);


	if (de_iir & DE_GSE)
	if (de_iir & DE_GSE)
@@ -2081,8 +2081,8 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
	if (IS_GEN6(dev))
	if (IS_GEN6(dev))
		render_irqs =
		render_irqs =
			GT_USER_INTERRUPT |
			GT_USER_INTERRUPT |
			GT_GEN6_BSD_USER_INTERRUPT |
			GEN6_BSD_USER_INTERRUPT |
			GT_BLT_USER_INTERRUPT;
			GEN6_BLITTER_USER_INTERRUPT;
	else
	else
		render_irqs =
		render_irqs =
			GT_USER_INTERRUPT |
			GT_USER_INTERRUPT |
@@ -2154,8 +2154,8 @@ static int ivybridge_irq_postinstall(struct drm_device *dev)
	I915_WRITE(GTIIR, I915_READ(GTIIR));
	I915_WRITE(GTIIR, I915_READ(GTIIR));
	I915_WRITE(GTIMR, dev_priv->gt_irq_mask);
	I915_WRITE(GTIMR, dev_priv->gt_irq_mask);


	render_irqs = GT_USER_INTERRUPT | GT_GEN6_BSD_USER_INTERRUPT |
	render_irqs = GT_USER_INTERRUPT | GEN6_BSD_USER_INTERRUPT |
		GT_BLT_USER_INTERRUPT;
		GEN6_BLITTER_USER_INTERRUPT;
	I915_WRITE(GTIER, render_irqs);
	I915_WRITE(GTIER, render_irqs);
	POSTING_READ(GTIER);
	POSTING_READ(GTIER);


@@ -2218,7 +2218,7 @@ static int valleyview_irq_postinstall(struct drm_device *dev)


	render_irqs = GT_GEN6_BLT_FLUSHDW_NOTIFY_INTERRUPT |
	render_irqs = GT_GEN6_BLT_FLUSHDW_NOTIFY_INTERRUPT |
		GT_GEN6_BLT_CS_ERROR_INTERRUPT |
		GT_GEN6_BLT_CS_ERROR_INTERRUPT |
		GT_BLT_USER_INTERRUPT |
		GT_GEN6_BLT_USER_INTERRUPT |
		GT_GEN6_BSD_USER_INTERRUPT |
		GT_GEN6_BSD_USER_INTERRUPT |
		GT_GEN6_BSD_CS_ERROR_INTERRUPT |
		GT_GEN6_BSD_CS_ERROR_INTERRUPT |
		GT_GEN7_L3_PARITY_ERROR_INTERRUPT |
		GT_GEN7_L3_PARITY_ERROR_INTERRUPT |
+8 −4
Original line number Original line Diff line number Diff line
@@ -643,7 +643,9 @@
#define CACHE_MODE_1		0x7004 /* IVB+ */
#define CACHE_MODE_1		0x7004 /* IVB+ */
#define   PIXEL_SUBSPAN_COLLECT_OPT_DISABLE (1<<6)
#define   PIXEL_SUBSPAN_COLLECT_OPT_DISABLE (1<<6)


/* GEN6 interrupt control */
/* GEN6 interrupt control
 * Note that the per-ring interrupt bits do alias with the global interrupt bits
 * in GTIMR. */
#define GEN6_RENDER_HWSTAM	0x2098
#define GEN6_RENDER_HWSTAM	0x2098
#define GEN6_RENDER_IMR		0x20a8
#define GEN6_RENDER_IMR		0x20a8
#define   GEN6_RENDER_CONTEXT_SWITCH_INTERRUPT		(1 << 8)
#define   GEN6_RENDER_CONTEXT_SWITCH_INTERRUPT		(1 << 8)
@@ -3203,13 +3205,15 @@
#define DEIIR   0x44008
#define DEIIR   0x44008
#define DEIER   0x4400c
#define DEIER   0x4400c


/* GT interrupt */
/* GT interrupt.
 * Note that for gen6+ the ring-specific interrupt bits do alias with the
 * corresponding bits in the per-ring interrupt control registers. */
#define GT_GEN6_BLT_FLUSHDW_NOTIFY_INTERRUPT	(1 << 26)
#define GT_GEN6_BLT_FLUSHDW_NOTIFY_INTERRUPT	(1 << 26)
#define GT_GEN6_BLT_CS_ERROR_INTERRUPT		(1 << 25)
#define GT_GEN6_BLT_CS_ERROR_INTERRUPT		(1 << 25)
#define GT_BLT_USER_INTERRUPT			(1 << 22)
#define GT_GEN6_BLT_USER_INTERRUPT		(1 << 22)
#define GT_GEN6_BSD_CS_ERROR_INTERRUPT		(1 << 15)
#define GT_GEN6_BSD_CS_ERROR_INTERRUPT		(1 << 15)
#define GT_GEN6_BSD_USER_INTERRUPT		(1 << 12)
#define GT_GEN6_BSD_USER_INTERRUPT		(1 << 12)
#define GT_BSD_USER_INTERRUPT			(1 << 5)
#define GT_BSD_USER_INTERRUPT			(1 << 5) /* ilk only */
#define GT_GEN7_L3_PARITY_ERROR_INTERRUPT	(1 << 5)
#define GT_GEN7_L3_PARITY_ERROR_INTERRUPT	(1 << 5)
#define GT_PIPE_NOTIFY				(1 << 4)
#define GT_PIPE_NOTIFY				(1 << 4)
#define GT_RENDER_CS_ERROR_INTERRUPT		(1 << 3)
#define GT_RENDER_CS_ERROR_INTERRUPT		(1 << 3)
+12 −24
Original line number Original line Diff line number Diff line
@@ -788,7 +788,7 @@ ring_add_request(struct intel_ring_buffer *ring,
}
}


static bool
static bool
gen6_ring_get_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag)
gen6_ring_get_irq(struct intel_ring_buffer *ring, u32 mask)
{
{
	struct drm_device *dev = ring->dev;
	struct drm_device *dev = ring->dev;
	drm_i915_private_t *dev_priv = dev->dev_private;
	drm_i915_private_t *dev_priv = dev->dev_private;
@@ -803,9 +803,9 @@ gen6_ring_get_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag)


	spin_lock(&ring->irq_lock);
	spin_lock(&ring->irq_lock);
	if (ring->irq_refcount++ == 0) {
	if (ring->irq_refcount++ == 0) {
		ring->irq_mask &= ~rflag;
		ring->irq_mask &= ~mask;
		I915_WRITE_IMR(ring, ring->irq_mask);
		I915_WRITE_IMR(ring, ring->irq_mask);
		ironlake_enable_irq(dev_priv, gflag);
		ironlake_enable_irq(dev_priv, mask);
	}
	}
	spin_unlock(&ring->irq_lock);
	spin_unlock(&ring->irq_lock);


@@ -813,16 +813,16 @@ gen6_ring_get_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag)
}
}


static void
static void
gen6_ring_put_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag)
gen6_ring_put_irq(struct intel_ring_buffer *ring, u32 mask)
{
{
	struct drm_device *dev = ring->dev;
	struct drm_device *dev = ring->dev;
	drm_i915_private_t *dev_priv = dev->dev_private;
	drm_i915_private_t *dev_priv = dev->dev_private;


	spin_lock(&ring->irq_lock);
	spin_lock(&ring->irq_lock);
	if (--ring->irq_refcount == 0) {
	if (--ring->irq_refcount == 0) {
		ring->irq_mask |= rflag;
		ring->irq_mask |= mask;
		I915_WRITE_IMR(ring, ring->irq_mask);
		I915_WRITE_IMR(ring, ring->irq_mask);
		ironlake_disable_irq(dev_priv, gflag);
		ironlake_disable_irq(dev_priv, mask);
	}
	}
	spin_unlock(&ring->irq_lock);
	spin_unlock(&ring->irq_lock);


@@ -1376,33 +1376,25 @@ gen6_ring_dispatch_execbuffer(struct intel_ring_buffer *ring,
static bool
static bool
gen6_render_ring_get_irq(struct intel_ring_buffer *ring)
gen6_render_ring_get_irq(struct intel_ring_buffer *ring)
{
{
	return gen6_ring_get_irq(ring,
	return gen6_ring_get_irq(ring, GT_USER_INTERRUPT);
				 GT_USER_INTERRUPT,
				 GEN6_RENDER_USER_INTERRUPT);
}
}


static void
static void
gen6_render_ring_put_irq(struct intel_ring_buffer *ring)
gen6_render_ring_put_irq(struct intel_ring_buffer *ring)
{
{
	return gen6_ring_put_irq(ring,
	return gen6_ring_put_irq(ring, GT_USER_INTERRUPT);
				 GT_USER_INTERRUPT,
				 GEN6_RENDER_USER_INTERRUPT);
}
}


static bool
static bool
gen6_bsd_ring_get_irq(struct intel_ring_buffer *ring)
gen6_bsd_ring_get_irq(struct intel_ring_buffer *ring)
{
{
	return gen6_ring_get_irq(ring,
	return gen6_ring_get_irq(ring, GEN6_BSD_USER_INTERRUPT);
				 GT_GEN6_BSD_USER_INTERRUPT,
				 GEN6_BSD_USER_INTERRUPT);
}
}


static void
static void
gen6_bsd_ring_put_irq(struct intel_ring_buffer *ring)
gen6_bsd_ring_put_irq(struct intel_ring_buffer *ring)
{
{
	return gen6_ring_put_irq(ring,
	return gen6_ring_put_irq(ring, GEN6_BSD_USER_INTERRUPT);
				 GT_GEN6_BSD_USER_INTERRUPT,
				 GEN6_BSD_USER_INTERRUPT);
}
}


/* ring buffer for Video Codec for Gen6+ */
/* ring buffer for Video Codec for Gen6+ */
@@ -1431,17 +1423,13 @@ static const struct intel_ring_buffer gen6_bsd_ring = {
static bool
static bool
blt_ring_get_irq(struct intel_ring_buffer *ring)
blt_ring_get_irq(struct intel_ring_buffer *ring)
{
{
	return gen6_ring_get_irq(ring,
	return gen6_ring_get_irq(ring, GEN6_BLITTER_USER_INTERRUPT);
				 GT_BLT_USER_INTERRUPT,
				 GEN6_BLITTER_USER_INTERRUPT);
}
}


static void
static void
blt_ring_put_irq(struct intel_ring_buffer *ring)
blt_ring_put_irq(struct intel_ring_buffer *ring)
{
{
	gen6_ring_put_irq(ring,
	gen6_ring_put_irq(ring, GEN6_BLITTER_USER_INTERRUPT);
			  GT_BLT_USER_INTERRUPT,
			  GEN6_BLITTER_USER_INTERRUPT);
}
}


static int blt_ring_flush(struct intel_ring_buffer *ring,
static int blt_ring_flush(struct intel_ring_buffer *ring,