public inbox for intel-gfx@lists.freedesktop.org
 help / color / mirror / Atom feed
* [PATCH] drm/i915: Don't rmw PIPESTAT enable bits
@ 2017-09-14 15:17 Ville Syrjala
  2017-09-14 16:04 ` ✓ Fi.CI.BAT: success for " Patchwork
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Ville Syrjala @ 2017-09-14 15:17 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

i830 seems to occasionally forget the PIPESTAT enable bits when
we read the register. These aren't the only registers on i830 that
have problems with RMW, as reading the double buffered plane
registers returns the latched value rather than the last written
value. So something similar is perhaps going on with PIPESTAT.

This corruption results on vblank interrupts occasionally turning off
on their own, which leads to vblank timeouts and generally a stuck
display subsystem.

So let's not RMW the pipestat enable bits, and instead use the cached
copy we have around.

Cc: Imre Deak <imre.deak@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h            |   2 +
 drivers/gpu/drm/i915/i915_irq.c            | 135 ++++++++++++-----------------
 drivers/gpu/drm/i915/intel_fifo_underrun.c |  14 +--
 3 files changed, 66 insertions(+), 85 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 28ad5dadbb18..3b4dd410cad1 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3307,6 +3307,8 @@ static inline bool intel_vgpu_active(struct drm_i915_private *dev_priv)
 	return dev_priv->vgpu.active;
 }
 
+u32 i915_pipestat_enable_mask(struct drm_i915_private *dev_priv,
+			      enum pipe pipe);
 void
 i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
 		     u32 status_mask);
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 003a92857102..7c4e1a1faed7 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -567,62 +567,16 @@ void ibx_display_interrupt_update(struct drm_i915_private *dev_priv,
 	POSTING_READ(SDEIMR);
 }
 
-static void
-__i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
-		       u32 enable_mask, u32 status_mask)
+u32 i915_pipestat_enable_mask(struct drm_i915_private *dev_priv,
+			      enum pipe pipe)
 {
-	i915_reg_t reg = PIPESTAT(pipe);
-	u32 pipestat = I915_READ(reg) & PIPESTAT_INT_ENABLE_MASK;
-
-	lockdep_assert_held(&dev_priv->irq_lock);
-	WARN_ON(!intel_irqs_enabled(dev_priv));
-
-	if (WARN_ONCE(enable_mask & ~PIPESTAT_INT_ENABLE_MASK ||
-		      status_mask & ~PIPESTAT_INT_STATUS_MASK,
-		      "pipe %c: enable_mask=0x%x, status_mask=0x%x\n",
-		      pipe_name(pipe), enable_mask, status_mask))
-		return;
-
-	if ((pipestat & enable_mask) == enable_mask)
-		return;
-
-	dev_priv->pipestat_irq_mask[pipe] |= status_mask;
-
-	/* Enable the interrupt, clear any pending status */
-	pipestat |= enable_mask | status_mask;
-	I915_WRITE(reg, pipestat);
-	POSTING_READ(reg);
-}
-
-static void
-__i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
-		        u32 enable_mask, u32 status_mask)
-{
-	i915_reg_t reg = PIPESTAT(pipe);
-	u32 pipestat = I915_READ(reg) & PIPESTAT_INT_ENABLE_MASK;
+	u32 status_mask = dev_priv->pipestat_irq_mask[pipe];
+	u32 enable_mask = status_mask << 16;
 
 	lockdep_assert_held(&dev_priv->irq_lock);
-	WARN_ON(!intel_irqs_enabled(dev_priv));
-
-	if (WARN_ONCE(enable_mask & ~PIPESTAT_INT_ENABLE_MASK ||
-		      status_mask & ~PIPESTAT_INT_STATUS_MASK,
-		      "pipe %c: enable_mask=0x%x, status_mask=0x%x\n",
-		      pipe_name(pipe), enable_mask, status_mask))
-		return;
-
-	if ((pipestat & enable_mask) == 0)
-		return;
-
-	dev_priv->pipestat_irq_mask[pipe] &= ~status_mask;
-
-	pipestat &= ~enable_mask;
-	I915_WRITE(reg, pipestat);
-	POSTING_READ(reg);
-}
 
-static u32 vlv_get_pipestat_enable_mask(struct drm_device *dev, u32 status_mask)
-{
-	u32 enable_mask = status_mask << 16;
+	if (INTEL_GEN(dev_priv) < 5)
+		goto out;
 
 	/*
 	 * On pipe A we don't support the PSR interrupt yet,
@@ -645,35 +599,59 @@ static u32 vlv_get_pipestat_enable_mask(struct drm_device *dev, u32 status_mask)
 	if (status_mask & SPRITE1_FLIP_DONE_INT_STATUS_VLV)
 		enable_mask |= SPRITE1_FLIP_DONE_INT_EN_VLV;
 
+out:
+	WARN_ONCE(enable_mask & ~PIPESTAT_INT_ENABLE_MASK ||
+		  status_mask & ~PIPESTAT_INT_STATUS_MASK,
+		  "pipe %c: enable_mask=0x%x, status_mask=0x%x\n",
+		  pipe_name(pipe), enable_mask, status_mask);
+
 	return enable_mask;
 }
 
-void
-i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
-		     u32 status_mask)
+void i915_enable_pipestat(struct drm_i915_private *dev_priv,
+			  enum pipe pipe, u32 status_mask)
 {
+	i915_reg_t reg = PIPESTAT(pipe);
 	u32 enable_mask;
 
-	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
-		enable_mask = vlv_get_pipestat_enable_mask(&dev_priv->drm,
-							   status_mask);
-	else
-		enable_mask = status_mask << 16;
-	__i915_enable_pipestat(dev_priv, pipe, enable_mask, status_mask);
+	WARN_ONCE(status_mask & ~PIPESTAT_INT_STATUS_MASK,
+		  "pipe %c: status_mask=0x%x\n",
+		  pipe_name(pipe), status_mask);
+
+	lockdep_assert_held(&dev_priv->irq_lock);
+	WARN_ON(!intel_irqs_enabled(dev_priv));
+
+	if ((dev_priv->pipestat_irq_mask[pipe] & status_mask) == status_mask)
+		return;
+
+	dev_priv->pipestat_irq_mask[pipe] |= status_mask;
+	enable_mask = i915_pipestat_enable_mask(dev_priv, pipe);
+
+	I915_WRITE(reg, enable_mask | status_mask);
+	POSTING_READ(reg);
 }
 
-void
-i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
-		      u32 status_mask)
+void i915_disable_pipestat(struct drm_i915_private *dev_priv,
+			   enum pipe pipe, u32 status_mask)
 {
+	i915_reg_t reg = PIPESTAT(pipe);
 	u32 enable_mask;
 
-	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
-		enable_mask = vlv_get_pipestat_enable_mask(&dev_priv->drm,
-							   status_mask);
-	else
-		enable_mask = status_mask << 16;
-	__i915_disable_pipestat(dev_priv, pipe, enable_mask, status_mask);
+	WARN_ONCE(status_mask & ~PIPESTAT_INT_STATUS_MASK,
+		  "pipe %c: status_mask=0x%x\n",
+		  pipe_name(pipe), status_mask);
+
+	lockdep_assert_held(&dev_priv->irq_lock);
+	WARN_ON(!intel_irqs_enabled(dev_priv));
+
+	if ((dev_priv->pipestat_irq_mask[pipe] & status_mask) == 0)
+		return;
+
+	dev_priv->pipestat_irq_mask[pipe] &= ~status_mask;
+	enable_mask = i915_pipestat_enable_mask(dev_priv, pipe);
+
+	I915_WRITE(reg, enable_mask | status_mask);
+	POSTING_READ(reg);
 }
 
 /**
@@ -1769,7 +1747,7 @@ static void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv,
 
 	for_each_pipe(dev_priv, pipe) {
 		i915_reg_t reg;
-		u32 mask, iir_bit = 0;
+		u32 status_mask, enable_mask, iir_bit = 0;
 
 		/*
 		 * PIPESTAT bits get signalled even when the interrupt is
@@ -1780,7 +1758,7 @@ static void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv,
 		 */
 
 		/* fifo underruns are filterered in the underrun handler. */
-		mask = PIPE_FIFO_UNDERRUN_STATUS;
+		status_mask = PIPE_FIFO_UNDERRUN_STATUS;
 
 		switch (pipe) {
 		case PIPE_A:
@@ -1794,21 +1772,20 @@ static void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv,
 			break;
 		}
 		if (iir & iir_bit)
-			mask |= dev_priv->pipestat_irq_mask[pipe];
+			status_mask |= dev_priv->pipestat_irq_mask[pipe];
 
-		if (!mask)
+		if (!status_mask)
 			continue;
 
 		reg = PIPESTAT(pipe);
-		mask |= PIPESTAT_INT_ENABLE_MASK;
-		pipe_stats[pipe] = I915_READ(reg) & mask;
+		pipe_stats[pipe] = I915_READ(reg) & status_mask;
+		enable_mask = i915_pipestat_enable_mask(dev_priv, pipe);
 
 		/*
 		 * Clear the PIPE*STAT regs before the IIR
 		 */
-		if (pipe_stats[pipe] & (PIPE_FIFO_UNDERRUN_STATUS |
-					PIPESTAT_INT_STATUS_MASK))
-			I915_WRITE(reg, pipe_stats[pipe]);
+		if (pipe_stats[pipe])
+			I915_WRITE(reg, enable_mask | pipe_stats[pipe]);
 	}
 	spin_unlock(&dev_priv->irq_lock);
 }
diff --git a/drivers/gpu/drm/i915/intel_fifo_underrun.c b/drivers/gpu/drm/i915/intel_fifo_underrun.c
index 04689600e337..77c123cc8817 100644
--- a/drivers/gpu/drm/i915/intel_fifo_underrun.c
+++ b/drivers/gpu/drm/i915/intel_fifo_underrun.c
@@ -88,14 +88,15 @@ static void i9xx_check_fifo_underruns(struct intel_crtc *crtc)
 {
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	i915_reg_t reg = PIPESTAT(crtc->pipe);
-	u32 pipestat = I915_READ(reg) & 0xffff0000;
+	u32 enable_mask;
 
 	lockdep_assert_held(&dev_priv->irq_lock);
 
-	if ((pipestat & PIPE_FIFO_UNDERRUN_STATUS) == 0)
+	if ((I915_READ(reg) & PIPE_FIFO_UNDERRUN_STATUS) == 0)
 		return;
 
-	I915_WRITE(reg, pipestat | PIPE_FIFO_UNDERRUN_STATUS);
+	enable_mask = i915_pipestat_enable_mask(dev_priv, crtc->pipe);
+	I915_WRITE(reg, enable_mask | PIPE_FIFO_UNDERRUN_STATUS);
 	POSTING_READ(reg);
 
 	trace_intel_cpu_fifo_underrun(dev_priv, crtc->pipe);
@@ -108,15 +109,16 @@ static void i9xx_set_fifo_underrun_reporting(struct drm_device *dev,
 {
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	i915_reg_t reg = PIPESTAT(pipe);
-	u32 pipestat = I915_READ(reg) & 0xffff0000;
 
 	lockdep_assert_held(&dev_priv->irq_lock);
 
 	if (enable) {
-		I915_WRITE(reg, pipestat | PIPE_FIFO_UNDERRUN_STATUS);
+		u32 enable_mask = i915_pipestat_enable_mask(dev_priv, pipe);
+
+		I915_WRITE(reg, enable_mask | PIPE_FIFO_UNDERRUN_STATUS);
 		POSTING_READ(reg);
 	} else {
-		if (old && pipestat & PIPE_FIFO_UNDERRUN_STATUS)
+		if (old && I915_READ(reg) & PIPE_FIFO_UNDERRUN_STATUS)
 			DRM_ERROR("pipe %c underrun\n", pipe_name(pipe));
 	}
 }
-- 
2.13.5

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* ✓ Fi.CI.BAT: success for drm/i915: Don't rmw PIPESTAT enable bits
  2017-09-14 15:17 [PATCH] drm/i915: Don't rmw PIPESTAT enable bits Ville Syrjala
@ 2017-09-14 16:04 ` Patchwork
  2017-09-14 20:37 ` [PATCH] " Chris Wilson
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 9+ messages in thread
From: Patchwork @ 2017-09-14 16:04 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Don't rmw PIPESTAT enable bits
URL   : https://patchwork.freedesktop.org/series/30367/
State : success

== Summary ==

Series 30367v1 drm/i915: Don't rmw PIPESTAT enable bits
https://patchwork.freedesktop.org/api/1.0/series/30367/revisions/1/mbox/

Test kms_cursor_legacy:
        Subgroup basic-busy-flip-before-cursor-legacy:
                pass       -> FAIL       (fi-snb-2600) fdo#100215
Test kms_flip:
        Subgroup basic-flip-vs-wf_vblank:
                skip       -> PASS       (fi-skl-x1585l)

fdo#100215 https://bugs.freedesktop.org/show_bug.cgi?id=100215

fi-bdw-5557u     total:289  pass:268  dwarn:0   dfail:0   fail:0   skip:21  time:443s
fi-bdw-gvtdvm    total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:455s
fi-blb-e6850     total:289  pass:224  dwarn:1   dfail:0   fail:0   skip:64  time:381s
fi-bsw-n3050     total:289  pass:243  dwarn:0   dfail:0   fail:0   skip:46  time:533s
fi-bwr-2160      total:289  pass:184  dwarn:0   dfail:0   fail:0   skip:105 time:271s
fi-bxt-j4205     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:501s
fi-byt-j1900     total:289  pass:254  dwarn:1   dfail:0   fail:0   skip:34  time:504s
fi-byt-n2820     total:289  pass:250  dwarn:1   dfail:0   fail:0   skip:38  time:495s
fi-cfl-s         total:289  pass:223  dwarn:34  dfail:0   fail:0   skip:32  time:554s
fi-elk-e7500     total:289  pass:230  dwarn:0   dfail:0   fail:0   skip:59  time:447s
fi-glk-2a        total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:592s
fi-hsw-4770      total:289  pass:263  dwarn:0   dfail:0   fail:0   skip:26  time:426s
fi-hsw-4770r     total:289  pass:263  dwarn:0   dfail:0   fail:0   skip:26  time:407s
fi-ilk-650       total:289  pass:229  dwarn:0   dfail:0   fail:0   skip:60  time:441s
fi-ivb-3520m     total:289  pass:261  dwarn:0   dfail:0   fail:0   skip:28  time:486s
fi-ivb-3770      total:289  pass:261  dwarn:0   dfail:0   fail:0   skip:28  time:467s
fi-kbl-7500u     total:289  pass:264  dwarn:1   dfail:0   fail:0   skip:24  time:490s
fi-kbl-7560u     total:289  pass:270  dwarn:0   dfail:0   fail:0   skip:19  time:577s
fi-kbl-r         total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:584s
fi-pnv-d510      total:289  pass:223  dwarn:1   dfail:0   fail:0   skip:65  time:550s
fi-skl-6260u     total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:462s
fi-skl-6700k     total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:519s
fi-skl-6770hq    total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:503s
fi-skl-gvtdvm    total:289  pass:266  dwarn:0   dfail:0   fail:0   skip:23  time:464s
fi-skl-x1585l    total:289  pass:268  dwarn:0   dfail:0   fail:0   skip:21  time:476s
fi-snb-2520m     total:289  pass:251  dwarn:0   dfail:0   fail:0   skip:38  time:570s
fi-snb-2600      total:289  pass:249  dwarn:0   dfail:0   fail:1   skip:39  time:420s

46e05d756fe32271bca4ac3ef1b3f1f6006fcc0c drm-tip: 2017y-09m-14d-14h-46m-01s UTC integration manifest
ae8aa6262034 drm/i915: Don't rmw PIPESTAT enable bits

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_5702/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] drm/i915: Don't rmw PIPESTAT enable bits
  2017-09-14 15:17 [PATCH] drm/i915: Don't rmw PIPESTAT enable bits Ville Syrjala
  2017-09-14 16:04 ` ✓ Fi.CI.BAT: success for " Patchwork
@ 2017-09-14 20:37 ` Chris Wilson
  2017-09-15 10:03   ` Ville Syrjälä
  2017-09-14 21:20 ` ✗ Fi.CI.IGT: failure for " Patchwork
  2017-09-25 10:33 ` [PATCH] " Imre Deak
  3 siblings, 1 reply; 9+ messages in thread
From: Chris Wilson @ 2017-09-14 20:37 UTC (permalink / raw)
  To: Ville Syrjala, intel-gfx

Quoting Ville Syrjala (2017-09-14 16:17:31)
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> i830 seems to occasionally forget the PIPESTAT enable bits when
> we read the register. These aren't the only registers on i830 that
> have problems with RMW, as reading the double buffered plane
> registers returns the latched value rather than the last written
> value. So something similar is perhaps going on with PIPESTAT.
> 
> This corruption results on vblank interrupts occasionally turning off
> on their own, which leads to vblank timeouts and generally a stuck
> display subsystem.
> 
> So let's not RMW the pipestat enable bits, and instead use the cached
> copy we have around.
> 
> Cc: Imre Deak <imre.deak@intel.com>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

Well it didn't make my 845g any worse. Still has

[  245.683349] [drm:pipe_config_err] *ERROR* mismatch in base.adjusted_mode.flags (2) (expected 0, found 2)
[  245.683382] [drm:pipe_config_err] *ERROR* mismatch in base.adjusted_mode.flags (8) (expected 0, found 8)
[  245.683427] pipe state doesn't match!

if you are interested.

How occasional and which test in particular hits the issue?
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 9+ messages in thread

* ✗ Fi.CI.IGT: failure for drm/i915: Don't rmw PIPESTAT enable bits
  2017-09-14 15:17 [PATCH] drm/i915: Don't rmw PIPESTAT enable bits Ville Syrjala
  2017-09-14 16:04 ` ✓ Fi.CI.BAT: success for " Patchwork
  2017-09-14 20:37 ` [PATCH] " Chris Wilson
@ 2017-09-14 21:20 ` Patchwork
  2017-09-25 10:33 ` [PATCH] " Imre Deak
  3 siblings, 0 replies; 9+ messages in thread
From: Patchwork @ 2017-09-14 21:20 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Don't rmw PIPESTAT enable bits
URL   : https://patchwork.freedesktop.org/series/30367/
State : failure

== Summary ==

Test perf:
        Subgroup polling:
                pass       -> FAIL       (shard-hsw) fdo#102252 +1
Test kms_plane:
        Subgroup plane-panning-bottom-right-suspend-pipe-C-planes:
                skip       -> PASS       (shard-hsw)
Test kms_rmfb:
        Subgroup close-fd:
                skip       -> PASS       (shard-hsw)
Test kms_universal_plane:
        Subgroup universal-plane-pipe-B-functional:
                skip       -> PASS       (shard-hsw)
Test kms_cursor_crc:
        Subgroup cursor-256x256-dpms:
                skip       -> PASS       (shard-hsw)
Test kms_flip:
        Subgroup flip-vs-fences-interruptible:
                pass       -> FAIL       (shard-hsw)

fdo#102252 https://bugs.freedesktop.org/show_bug.cgi?id=102252

shard-hsw        total:2313 pass:1243 dwarn:0   dfail:0   fail:15  skip:1055 time:9384s

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_5702/shards.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] drm/i915: Don't rmw PIPESTAT enable bits
  2017-09-14 20:37 ` [PATCH] " Chris Wilson
@ 2017-09-15 10:03   ` Ville Syrjälä
  2017-09-25 14:05     ` Ville Syrjälä
  0 siblings, 1 reply; 9+ messages in thread
From: Ville Syrjälä @ 2017-09-15 10:03 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

On Thu, Sep 14, 2017 at 09:37:37PM +0100, Chris Wilson wrote:
> Quoting Ville Syrjala (2017-09-14 16:17:31)
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > i830 seems to occasionally forget the PIPESTAT enable bits when
> > we read the register. These aren't the only registers on i830 that
> > have problems with RMW, as reading the double buffered plane
> > registers returns the latched value rather than the last written
> > value. So something similar is perhaps going on with PIPESTAT.
> > 
> > This corruption results on vblank interrupts occasionally turning off
> > on their own, which leads to vblank timeouts and generally a stuck
> > display subsystem.
> > 
> > So let's not RMW the pipestat enable bits, and instead use the cached
> > copy we have around.
> > 
> > Cc: Imre Deak <imre.deak@intel.com>
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Well it didn't make my 845g any worse. Still has
> 
> [  245.683349] [drm:pipe_config_err] *ERROR* mismatch in base.adjusted_mode.flags (2) (expected 0, found 2)
> [  245.683382] [drm:pipe_config_err] *ERROR* mismatch in base.adjusted_mode.flags (8) (expected 0, found 8)
> [  245.683427] pipe state doesn't match!
> 
> if you are interested.

That's a bit odd. Even if the mode originally doesn't have any
hsync/vsync flags intel_modeset_pipe_config() should give it some.
So I can't immediately see how we could manage to get there with
expected==0.

> 
> How occasional and which test in particular hits the issue?

It's been a few months but IIRC I was just running xonotic when I
hit the problem. It was pretty good at hitting it. Prior to the fix
I had to rewrite PIPESTAT several times to make it through the
the-big-keybench demo. I don't recall anymore if I hit it with
anything else.

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] drm/i915: Don't rmw PIPESTAT enable bits
  2017-09-14 15:17 [PATCH] drm/i915: Don't rmw PIPESTAT enable bits Ville Syrjala
                   ` (2 preceding siblings ...)
  2017-09-14 21:20 ` ✗ Fi.CI.IGT: failure for " Patchwork
@ 2017-09-25 10:33 ` Imre Deak
  2017-09-25 13:53   ` Ville Syrjälä
  3 siblings, 1 reply; 9+ messages in thread
From: Imre Deak @ 2017-09-25 10:33 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

On Thu, Sep 14, 2017 at 06:17:31PM +0300, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> i830 seems to occasionally forget the PIPESTAT enable bits when
> we read the register. These aren't the only registers on i830 that
> have problems with RMW, as reading the double buffered plane
> registers returns the latched value rather than the last written
> value. So something similar is perhaps going on with PIPESTAT.
> 
> This corruption results on vblank interrupts occasionally turning off
> on their own, which leads to vblank timeouts and generally a stuck
> display subsystem.
> 
> So let's not RMW the pipestat enable bits, and instead use the cached
> copy we have around.
> 
> Cc: Imre Deak <imre.deak@intel.com>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h            |   2 +
>  drivers/gpu/drm/i915/i915_irq.c            | 135 ++++++++++++-----------------
>  drivers/gpu/drm/i915/intel_fifo_underrun.c |  14 +--
>  3 files changed, 66 insertions(+), 85 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 28ad5dadbb18..3b4dd410cad1 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -3307,6 +3307,8 @@ static inline bool intel_vgpu_active(struct drm_i915_private *dev_priv)
>  	return dev_priv->vgpu.active;
>  }
>  
> +u32 i915_pipestat_enable_mask(struct drm_i915_private *dev_priv,
> +			      enum pipe pipe);
>  void
>  i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
>  		     u32 status_mask);
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index 003a92857102..7c4e1a1faed7 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -567,62 +567,16 @@ void ibx_display_interrupt_update(struct drm_i915_private *dev_priv,
>  	POSTING_READ(SDEIMR);
>  }
>  
> -static void
> -__i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
> -		       u32 enable_mask, u32 status_mask)
> +u32 i915_pipestat_enable_mask(struct drm_i915_private *dev_priv,
> +			      enum pipe pipe)
>  {
> -	i915_reg_t reg = PIPESTAT(pipe);
> -	u32 pipestat = I915_READ(reg) & PIPESTAT_INT_ENABLE_MASK;
> -
> -	lockdep_assert_held(&dev_priv->irq_lock);
> -	WARN_ON(!intel_irqs_enabled(dev_priv));
> -
> -	if (WARN_ONCE(enable_mask & ~PIPESTAT_INT_ENABLE_MASK ||
> -		      status_mask & ~PIPESTAT_INT_STATUS_MASK,
> -		      "pipe %c: enable_mask=0x%x, status_mask=0x%x\n",
> -		      pipe_name(pipe), enable_mask, status_mask))
> -		return;
> -
> -	if ((pipestat & enable_mask) == enable_mask)
> -		return;
> -
> -	dev_priv->pipestat_irq_mask[pipe] |= status_mask;
> -
> -	/* Enable the interrupt, clear any pending status */
> -	pipestat |= enable_mask | status_mask;
> -	I915_WRITE(reg, pipestat);
> -	POSTING_READ(reg);
> -}
> -
> -static void
> -__i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
> -		        u32 enable_mask, u32 status_mask)
> -{
> -	i915_reg_t reg = PIPESTAT(pipe);
> -	u32 pipestat = I915_READ(reg) & PIPESTAT_INT_ENABLE_MASK;
> +	u32 status_mask = dev_priv->pipestat_irq_mask[pipe];
> +	u32 enable_mask = status_mask << 16;
>  
>  	lockdep_assert_held(&dev_priv->irq_lock);
> -	WARN_ON(!intel_irqs_enabled(dev_priv));
> -
> -	if (WARN_ONCE(enable_mask & ~PIPESTAT_INT_ENABLE_MASK ||
> -		      status_mask & ~PIPESTAT_INT_STATUS_MASK,
> -		      "pipe %c: enable_mask=0x%x, status_mask=0x%x\n",
> -		      pipe_name(pipe), enable_mask, status_mask))
> -		return;
> -
> -	if ((pipestat & enable_mask) == 0)
> -		return;
> -
> -	dev_priv->pipestat_irq_mask[pipe] &= ~status_mask;
> -
> -	pipestat &= ~enable_mask;
> -	I915_WRITE(reg, pipestat);
> -	POSTING_READ(reg);
> -}
>  
> -static u32 vlv_get_pipestat_enable_mask(struct drm_device *dev, u32 status_mask)
> -{
> -	u32 enable_mask = status_mask << 16;
> +	if (INTEL_GEN(dev_priv) < 5)
> +		goto out;
>  
>  	/*
>  	 * On pipe A we don't support the PSR interrupt yet,
> @@ -645,35 +599,59 @@ static u32 vlv_get_pipestat_enable_mask(struct drm_device *dev, u32 status_mask)
>  	if (status_mask & SPRITE1_FLIP_DONE_INT_STATUS_VLV)
>  		enable_mask |= SPRITE1_FLIP_DONE_INT_EN_VLV;
>  
> +out:
> +	WARN_ONCE(enable_mask & ~PIPESTAT_INT_ENABLE_MASK ||
> +		  status_mask & ~PIPESTAT_INT_STATUS_MASK,
> +		  "pipe %c: enable_mask=0x%x, status_mask=0x%x\n",
> +		  pipe_name(pipe), enable_mask, status_mask);
> +
>  	return enable_mask;
>  }
>  
> -void
> -i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
> -		     u32 status_mask)
> +void i915_enable_pipestat(struct drm_i915_private *dev_priv,
> +			  enum pipe pipe, u32 status_mask)
>  {
> +	i915_reg_t reg = PIPESTAT(pipe);
>  	u32 enable_mask;
>  
> -	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
> -		enable_mask = vlv_get_pipestat_enable_mask(&dev_priv->drm,
> -							   status_mask);
> -	else
> -		enable_mask = status_mask << 16;
> -	__i915_enable_pipestat(dev_priv, pipe, enable_mask, status_mask);
> +	WARN_ONCE(status_mask & ~PIPESTAT_INT_STATUS_MASK,
> +		  "pipe %c: status_mask=0x%x\n",
> +		  pipe_name(pipe), status_mask);
> +
> +	lockdep_assert_held(&dev_priv->irq_lock);
> +	WARN_ON(!intel_irqs_enabled(dev_priv));
> +
> +	if ((dev_priv->pipestat_irq_mask[pipe] & status_mask) == status_mask)
> +		return;
> +
> +	dev_priv->pipestat_irq_mask[pipe] |= status_mask;
> +	enable_mask = i915_pipestat_enable_mask(dev_priv, pipe);
> +
> +	I915_WRITE(reg, enable_mask | status_mask);
> +	POSTING_READ(reg);
>  }
>  
> -void
> -i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
> -		      u32 status_mask)
> +void i915_disable_pipestat(struct drm_i915_private *dev_priv,
> +			   enum pipe pipe, u32 status_mask)
>  {
> +	i915_reg_t reg = PIPESTAT(pipe);
>  	u32 enable_mask;
>  
> -	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
> -		enable_mask = vlv_get_pipestat_enable_mask(&dev_priv->drm,
> -							   status_mask);
> -	else
> -		enable_mask = status_mask << 16;
> -	__i915_disable_pipestat(dev_priv, pipe, enable_mask, status_mask);
> +	WARN_ONCE(status_mask & ~PIPESTAT_INT_STATUS_MASK,
> +		  "pipe %c: status_mask=0x%x\n",
> +		  pipe_name(pipe), status_mask);
> +
> +	lockdep_assert_held(&dev_priv->irq_lock);
> +	WARN_ON(!intel_irqs_enabled(dev_priv));
> +
> +	if ((dev_priv->pipestat_irq_mask[pipe] & status_mask) == 0)
> +		return;
> +
> +	dev_priv->pipestat_irq_mask[pipe] &= ~status_mask;
> +	enable_mask = i915_pipestat_enable_mask(dev_priv, pipe);
> +
> +	I915_WRITE(reg, enable_mask | status_mask);
> +	POSTING_READ(reg);
>  }
>  
>  /**
> @@ -1769,7 +1747,7 @@ static void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv,
>  
>  	for_each_pipe(dev_priv, pipe) {
>  		i915_reg_t reg;
> -		u32 mask, iir_bit = 0;
> +		u32 status_mask, enable_mask, iir_bit = 0;
>  
>  		/*
>  		 * PIPESTAT bits get signalled even when the interrupt is
> @@ -1780,7 +1758,7 @@ static void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv,
>  		 */
>  
>  		/* fifo underruns are filterered in the underrun handler. */
> -		mask = PIPE_FIFO_UNDERRUN_STATUS;
> +		status_mask = PIPE_FIFO_UNDERRUN_STATUS;
>  
>  		switch (pipe) {
>  		case PIPE_A:
> @@ -1794,21 +1772,20 @@ static void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv,
>  			break;
>  		}
>  		if (iir & iir_bit)
> -			mask |= dev_priv->pipestat_irq_mask[pipe];
> +			status_mask |= dev_priv->pipestat_irq_mask[pipe];
>  
> -		if (!mask)
> +		if (!status_mask)
>  			continue;

Not introduced here, but the above could be removed.
The patch looks ok:

Reviewed-by: Imre Deak <imre.deak@intel.com>

>  
>  		reg = PIPESTAT(pipe);
> -		mask |= PIPESTAT_INT_ENABLE_MASK;
> -		pipe_stats[pipe] = I915_READ(reg) & mask;
> +		pipe_stats[pipe] = I915_READ(reg) & status_mask;
> +		enable_mask = i915_pipestat_enable_mask(dev_priv, pipe);
>  
>  		/*
>  		 * Clear the PIPE*STAT regs before the IIR
>  		 */
> -		if (pipe_stats[pipe] & (PIPE_FIFO_UNDERRUN_STATUS |
> -					PIPESTAT_INT_STATUS_MASK))
> -			I915_WRITE(reg, pipe_stats[pipe]);
> +		if (pipe_stats[pipe])
> +			I915_WRITE(reg, enable_mask | pipe_stats[pipe]);
>  	}
>  	spin_unlock(&dev_priv->irq_lock);
>  }
> diff --git a/drivers/gpu/drm/i915/intel_fifo_underrun.c b/drivers/gpu/drm/i915/intel_fifo_underrun.c
> index 04689600e337..77c123cc8817 100644
> --- a/drivers/gpu/drm/i915/intel_fifo_underrun.c
> +++ b/drivers/gpu/drm/i915/intel_fifo_underrun.c
> @@ -88,14 +88,15 @@ static void i9xx_check_fifo_underruns(struct intel_crtc *crtc)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	i915_reg_t reg = PIPESTAT(crtc->pipe);
> -	u32 pipestat = I915_READ(reg) & 0xffff0000;
> +	u32 enable_mask;
>  
>  	lockdep_assert_held(&dev_priv->irq_lock);
>  
> -	if ((pipestat & PIPE_FIFO_UNDERRUN_STATUS) == 0)
> +	if ((I915_READ(reg) & PIPE_FIFO_UNDERRUN_STATUS) == 0)
>  		return;
>  
> -	I915_WRITE(reg, pipestat | PIPE_FIFO_UNDERRUN_STATUS);
> +	enable_mask = i915_pipestat_enable_mask(dev_priv, crtc->pipe);
> +	I915_WRITE(reg, enable_mask | PIPE_FIFO_UNDERRUN_STATUS);
>  	POSTING_READ(reg);
>  
>  	trace_intel_cpu_fifo_underrun(dev_priv, crtc->pipe);
> @@ -108,15 +109,16 @@ static void i9xx_set_fifo_underrun_reporting(struct drm_device *dev,
>  {
>  	struct drm_i915_private *dev_priv = to_i915(dev);
>  	i915_reg_t reg = PIPESTAT(pipe);
> -	u32 pipestat = I915_READ(reg) & 0xffff0000;
>  
>  	lockdep_assert_held(&dev_priv->irq_lock);
>  
>  	if (enable) {
> -		I915_WRITE(reg, pipestat | PIPE_FIFO_UNDERRUN_STATUS);
> +		u32 enable_mask = i915_pipestat_enable_mask(dev_priv, pipe);
> +
> +		I915_WRITE(reg, enable_mask | PIPE_FIFO_UNDERRUN_STATUS);
>  		POSTING_READ(reg);
>  	} else {
> -		if (old && pipestat & PIPE_FIFO_UNDERRUN_STATUS)
> +		if (old && I915_READ(reg) & PIPE_FIFO_UNDERRUN_STATUS)
>  			DRM_ERROR("pipe %c underrun\n", pipe_name(pipe));
>  	}
>  }
> -- 
> 2.13.5
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] drm/i915: Don't rmw PIPESTAT enable bits
  2017-09-25 10:33 ` [PATCH] " Imre Deak
@ 2017-09-25 13:53   ` Ville Syrjälä
  0 siblings, 0 replies; 9+ messages in thread
From: Ville Syrjälä @ 2017-09-25 13:53 UTC (permalink / raw)
  To: Imre Deak; +Cc: intel-gfx

On Mon, Sep 25, 2017 at 01:33:18PM +0300, Imre Deak wrote:
> On Thu, Sep 14, 2017 at 06:17:31PM +0300, Ville Syrjala wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > i830 seems to occasionally forget the PIPESTAT enable bits when
> > we read the register. These aren't the only registers on i830 that
> > have problems with RMW, as reading the double buffered plane
> > registers returns the latched value rather than the last written
> > value. So something similar is perhaps going on with PIPESTAT.
> > 
> > This corruption results on vblank interrupts occasionally turning off
> > on their own, which leads to vblank timeouts and generally a stuck
> > display subsystem.
> > 
> > So let's not RMW the pipestat enable bits, and instead use the cached
> > copy we have around.
> > 
> > Cc: Imre Deak <imre.deak@intel.com>
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/i915_drv.h            |   2 +
> >  drivers/gpu/drm/i915/i915_irq.c            | 135 ++++++++++++-----------------
> >  drivers/gpu/drm/i915/intel_fifo_underrun.c |  14 +--
> >  3 files changed, 66 insertions(+), 85 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > index 28ad5dadbb18..3b4dd410cad1 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -3307,6 +3307,8 @@ static inline bool intel_vgpu_active(struct drm_i915_private *dev_priv)
> >  	return dev_priv->vgpu.active;
> >  }
> >  
> > +u32 i915_pipestat_enable_mask(struct drm_i915_private *dev_priv,
> > +			      enum pipe pipe);
> >  void
> >  i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
> >  		     u32 status_mask);
> > diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> > index 003a92857102..7c4e1a1faed7 100644
> > --- a/drivers/gpu/drm/i915/i915_irq.c
> > +++ b/drivers/gpu/drm/i915/i915_irq.c
> > @@ -567,62 +567,16 @@ void ibx_display_interrupt_update(struct drm_i915_private *dev_priv,
> >  	POSTING_READ(SDEIMR);
> >  }
> >  
> > -static void
> > -__i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
> > -		       u32 enable_mask, u32 status_mask)
> > +u32 i915_pipestat_enable_mask(struct drm_i915_private *dev_priv,
> > +			      enum pipe pipe)
> >  {
> > -	i915_reg_t reg = PIPESTAT(pipe);
> > -	u32 pipestat = I915_READ(reg) & PIPESTAT_INT_ENABLE_MASK;
> > -
> > -	lockdep_assert_held(&dev_priv->irq_lock);
> > -	WARN_ON(!intel_irqs_enabled(dev_priv));
> > -
> > -	if (WARN_ONCE(enable_mask & ~PIPESTAT_INT_ENABLE_MASK ||
> > -		      status_mask & ~PIPESTAT_INT_STATUS_MASK,
> > -		      "pipe %c: enable_mask=0x%x, status_mask=0x%x\n",
> > -		      pipe_name(pipe), enable_mask, status_mask))
> > -		return;
> > -
> > -	if ((pipestat & enable_mask) == enable_mask)
> > -		return;
> > -
> > -	dev_priv->pipestat_irq_mask[pipe] |= status_mask;
> > -
> > -	/* Enable the interrupt, clear any pending status */
> > -	pipestat |= enable_mask | status_mask;
> > -	I915_WRITE(reg, pipestat);
> > -	POSTING_READ(reg);
> > -}
> > -
> > -static void
> > -__i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
> > -		        u32 enable_mask, u32 status_mask)
> > -{
> > -	i915_reg_t reg = PIPESTAT(pipe);
> > -	u32 pipestat = I915_READ(reg) & PIPESTAT_INT_ENABLE_MASK;
> > +	u32 status_mask = dev_priv->pipestat_irq_mask[pipe];
> > +	u32 enable_mask = status_mask << 16;
> >  
> >  	lockdep_assert_held(&dev_priv->irq_lock);
> > -	WARN_ON(!intel_irqs_enabled(dev_priv));
> > -
> > -	if (WARN_ONCE(enable_mask & ~PIPESTAT_INT_ENABLE_MASK ||
> > -		      status_mask & ~PIPESTAT_INT_STATUS_MASK,
> > -		      "pipe %c: enable_mask=0x%x, status_mask=0x%x\n",
> > -		      pipe_name(pipe), enable_mask, status_mask))
> > -		return;
> > -
> > -	if ((pipestat & enable_mask) == 0)
> > -		return;
> > -
> > -	dev_priv->pipestat_irq_mask[pipe] &= ~status_mask;
> > -
> > -	pipestat &= ~enable_mask;
> > -	I915_WRITE(reg, pipestat);
> > -	POSTING_READ(reg);
> > -}
> >  
> > -static u32 vlv_get_pipestat_enable_mask(struct drm_device *dev, u32 status_mask)
> > -{
> > -	u32 enable_mask = status_mask << 16;
> > +	if (INTEL_GEN(dev_priv) < 5)
> > +		goto out;
> >  
> >  	/*
> >  	 * On pipe A we don't support the PSR interrupt yet,
> > @@ -645,35 +599,59 @@ static u32 vlv_get_pipestat_enable_mask(struct drm_device *dev, u32 status_mask)
> >  	if (status_mask & SPRITE1_FLIP_DONE_INT_STATUS_VLV)
> >  		enable_mask |= SPRITE1_FLIP_DONE_INT_EN_VLV;
> >  
> > +out:
> > +	WARN_ONCE(enable_mask & ~PIPESTAT_INT_ENABLE_MASK ||
> > +		  status_mask & ~PIPESTAT_INT_STATUS_MASK,
> > +		  "pipe %c: enable_mask=0x%x, status_mask=0x%x\n",
> > +		  pipe_name(pipe), enable_mask, status_mask);
> > +
> >  	return enable_mask;
> >  }
> >  
> > -void
> > -i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
> > -		     u32 status_mask)
> > +void i915_enable_pipestat(struct drm_i915_private *dev_priv,
> > +			  enum pipe pipe, u32 status_mask)
> >  {
> > +	i915_reg_t reg = PIPESTAT(pipe);
> >  	u32 enable_mask;
> >  
> > -	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
> > -		enable_mask = vlv_get_pipestat_enable_mask(&dev_priv->drm,
> > -							   status_mask);
> > -	else
> > -		enable_mask = status_mask << 16;
> > -	__i915_enable_pipestat(dev_priv, pipe, enable_mask, status_mask);
> > +	WARN_ONCE(status_mask & ~PIPESTAT_INT_STATUS_MASK,
> > +		  "pipe %c: status_mask=0x%x\n",
> > +		  pipe_name(pipe), status_mask);
> > +
> > +	lockdep_assert_held(&dev_priv->irq_lock);
> > +	WARN_ON(!intel_irqs_enabled(dev_priv));
> > +
> > +	if ((dev_priv->pipestat_irq_mask[pipe] & status_mask) == status_mask)
> > +		return;
> > +
> > +	dev_priv->pipestat_irq_mask[pipe] |= status_mask;
> > +	enable_mask = i915_pipestat_enable_mask(dev_priv, pipe);
> > +
> > +	I915_WRITE(reg, enable_mask | status_mask);
> > +	POSTING_READ(reg);
> >  }
> >  
> > -void
> > -i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
> > -		      u32 status_mask)
> > +void i915_disable_pipestat(struct drm_i915_private *dev_priv,
> > +			   enum pipe pipe, u32 status_mask)
> >  {
> > +	i915_reg_t reg = PIPESTAT(pipe);
> >  	u32 enable_mask;
> >  
> > -	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
> > -		enable_mask = vlv_get_pipestat_enable_mask(&dev_priv->drm,
> > -							   status_mask);
> > -	else
> > -		enable_mask = status_mask << 16;
> > -	__i915_disable_pipestat(dev_priv, pipe, enable_mask, status_mask);
> > +	WARN_ONCE(status_mask & ~PIPESTAT_INT_STATUS_MASK,
> > +		  "pipe %c: status_mask=0x%x\n",
> > +		  pipe_name(pipe), status_mask);
> > +
> > +	lockdep_assert_held(&dev_priv->irq_lock);
> > +	WARN_ON(!intel_irqs_enabled(dev_priv));
> > +
> > +	if ((dev_priv->pipestat_irq_mask[pipe] & status_mask) == 0)
> > +		return;
> > +
> > +	dev_priv->pipestat_irq_mask[pipe] &= ~status_mask;
> > +	enable_mask = i915_pipestat_enable_mask(dev_priv, pipe);
> > +
> > +	I915_WRITE(reg, enable_mask | status_mask);
> > +	POSTING_READ(reg);
> >  }
> >  
> >  /**
> > @@ -1769,7 +1747,7 @@ static void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv,
> >  
> >  	for_each_pipe(dev_priv, pipe) {
> >  		i915_reg_t reg;
> > -		u32 mask, iir_bit = 0;
> > +		u32 status_mask, enable_mask, iir_bit = 0;
> >  
> >  		/*
> >  		 * PIPESTAT bits get signalled even when the interrupt is
> > @@ -1780,7 +1758,7 @@ static void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv,
> >  		 */
> >  
> >  		/* fifo underruns are filterered in the underrun handler. */
> > -		mask = PIPE_FIFO_UNDERRUN_STATUS;
> > +		status_mask = PIPE_FIFO_UNDERRUN_STATUS;
> >  
> >  		switch (pipe) {
> >  		case PIPE_A:
> > @@ -1794,21 +1772,20 @@ static void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv,
> >  			break;
> >  		}
> >  		if (iir & iir_bit)
> > -			mask |= dev_priv->pipestat_irq_mask[pipe];
> > +			status_mask |= dev_priv->pipestat_irq_mask[pipe];
> >  
> > -		if (!mask)
> > +		if (!status_mask)
> >  			continue;
> 
> Not introduced here, but the above could be removed.

Indeed. I guess a separate patch would be cleaner.

> The patch looks ok:
> 
> Reviewed-by: Imre Deak <imre.deak@intel.com>

Thanks. Pushed to dinq.

> 
> >  
> >  		reg = PIPESTAT(pipe);
> > -		mask |= PIPESTAT_INT_ENABLE_MASK;
> > -		pipe_stats[pipe] = I915_READ(reg) & mask;
> > +		pipe_stats[pipe] = I915_READ(reg) & status_mask;
> > +		enable_mask = i915_pipestat_enable_mask(dev_priv, pipe);
> >  
> >  		/*
> >  		 * Clear the PIPE*STAT regs before the IIR
> >  		 */
> > -		if (pipe_stats[pipe] & (PIPE_FIFO_UNDERRUN_STATUS |
> > -					PIPESTAT_INT_STATUS_MASK))
> > -			I915_WRITE(reg, pipe_stats[pipe]);
> > +		if (pipe_stats[pipe])
> > +			I915_WRITE(reg, enable_mask | pipe_stats[pipe]);
> >  	}
> >  	spin_unlock(&dev_priv->irq_lock);
> >  }
> > diff --git a/drivers/gpu/drm/i915/intel_fifo_underrun.c b/drivers/gpu/drm/i915/intel_fifo_underrun.c
> > index 04689600e337..77c123cc8817 100644
> > --- a/drivers/gpu/drm/i915/intel_fifo_underrun.c
> > +++ b/drivers/gpu/drm/i915/intel_fifo_underrun.c
> > @@ -88,14 +88,15 @@ static void i9xx_check_fifo_underruns(struct intel_crtc *crtc)
> >  {
> >  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> >  	i915_reg_t reg = PIPESTAT(crtc->pipe);
> > -	u32 pipestat = I915_READ(reg) & 0xffff0000;
> > +	u32 enable_mask;
> >  
> >  	lockdep_assert_held(&dev_priv->irq_lock);
> >  
> > -	if ((pipestat & PIPE_FIFO_UNDERRUN_STATUS) == 0)
> > +	if ((I915_READ(reg) & PIPE_FIFO_UNDERRUN_STATUS) == 0)
> >  		return;
> >  
> > -	I915_WRITE(reg, pipestat | PIPE_FIFO_UNDERRUN_STATUS);
> > +	enable_mask = i915_pipestat_enable_mask(dev_priv, crtc->pipe);
> > +	I915_WRITE(reg, enable_mask | PIPE_FIFO_UNDERRUN_STATUS);
> >  	POSTING_READ(reg);
> >  
> >  	trace_intel_cpu_fifo_underrun(dev_priv, crtc->pipe);
> > @@ -108,15 +109,16 @@ static void i9xx_set_fifo_underrun_reporting(struct drm_device *dev,
> >  {
> >  	struct drm_i915_private *dev_priv = to_i915(dev);
> >  	i915_reg_t reg = PIPESTAT(pipe);
> > -	u32 pipestat = I915_READ(reg) & 0xffff0000;
> >  
> >  	lockdep_assert_held(&dev_priv->irq_lock);
> >  
> >  	if (enable) {
> > -		I915_WRITE(reg, pipestat | PIPE_FIFO_UNDERRUN_STATUS);
> > +		u32 enable_mask = i915_pipestat_enable_mask(dev_priv, pipe);
> > +
> > +		I915_WRITE(reg, enable_mask | PIPE_FIFO_UNDERRUN_STATUS);
> >  		POSTING_READ(reg);
> >  	} else {
> > -		if (old && pipestat & PIPE_FIFO_UNDERRUN_STATUS)
> > +		if (old && I915_READ(reg) & PIPE_FIFO_UNDERRUN_STATUS)
> >  			DRM_ERROR("pipe %c underrun\n", pipe_name(pipe));
> >  	}
> >  }
> > -- 
> > 2.13.5
> > 

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] drm/i915: Don't rmw PIPESTAT enable bits
  2017-09-15 10:03   ` Ville Syrjälä
@ 2017-09-25 14:05     ` Ville Syrjälä
  2017-09-25 14:10       ` Chris Wilson
  0 siblings, 1 reply; 9+ messages in thread
From: Ville Syrjälä @ 2017-09-25 14:05 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

On Fri, Sep 15, 2017 at 01:03:36PM +0300, Ville Syrjälä wrote:
> On Thu, Sep 14, 2017 at 09:37:37PM +0100, Chris Wilson wrote:
> > Quoting Ville Syrjala (2017-09-14 16:17:31)
> > > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > 
> > > i830 seems to occasionally forget the PIPESTAT enable bits when
> > > we read the register. These aren't the only registers on i830 that
> > > have problems with RMW, as reading the double buffered plane
> > > registers returns the latched value rather than the last written
> > > value. So something similar is perhaps going on with PIPESTAT.
> > > 
> > > This corruption results on vblank interrupts occasionally turning off
> > > on their own, which leads to vblank timeouts and generally a stuck
> > > display subsystem.
> > > 
> > > So let's not RMW the pipestat enable bits, and instead use the cached
> > > copy we have around.
> > > 
> > > Cc: Imre Deak <imre.deak@intel.com>
> > > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > Well it didn't make my 845g any worse. Still has
> > 
> > [  245.683349] [drm:pipe_config_err] *ERROR* mismatch in base.adjusted_mode.flags (2) (expected 0, found 2)
> > [  245.683382] [drm:pipe_config_err] *ERROR* mismatch in base.adjusted_mode.flags (8) (expected 0, found 8)
> > [  245.683427] pipe state doesn't match!
> > 
> > if you are interested.
> 
> That's a bit odd. Even if the mode originally doesn't have any
> hsync/vsync flags intel_modeset_pipe_config() should give it some.
> So I can't immediately see how we could manage to get there with
> expected==0.

Hmm. Does you 845g have DVO encoders? That could potentially explain if
it ends up using intel_crtc_mode_get(). That one fails to read out the
sync flags correctly, and it has other issues as well.

https://patchwork.freedesktop.org/series/5183/ but not sure it applies
cleanly anymore.

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] drm/i915: Don't rmw PIPESTAT enable bits
  2017-09-25 14:05     ` Ville Syrjälä
@ 2017-09-25 14:10       ` Chris Wilson
  0 siblings, 0 replies; 9+ messages in thread
From: Chris Wilson @ 2017-09-25 14:10 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

Quoting Ville Syrjälä (2017-09-25 15:05:51)
> On Fri, Sep 15, 2017 at 01:03:36PM +0300, Ville Syrjälä wrote:
> > On Thu, Sep 14, 2017 at 09:37:37PM +0100, Chris Wilson wrote:
> > > Quoting Ville Syrjala (2017-09-14 16:17:31)
> > > > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > > 
> > > > i830 seems to occasionally forget the PIPESTAT enable bits when
> > > > we read the register. These aren't the only registers on i830 that
> > > > have problems with RMW, as reading the double buffered plane
> > > > registers returns the latched value rather than the last written
> > > > value. So something similar is perhaps going on with PIPESTAT.
> > > > 
> > > > This corruption results on vblank interrupts occasionally turning off
> > > > on their own, which leads to vblank timeouts and generally a stuck
> > > > display subsystem.
> > > > 
> > > > So let's not RMW the pipestat enable bits, and instead use the cached
> > > > copy we have around.
> > > > 
> > > > Cc: Imre Deak <imre.deak@intel.com>
> > > > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > 
> > > Well it didn't make my 845g any worse. Still has
> > > 
> > > [  245.683349] [drm:pipe_config_err] *ERROR* mismatch in base.adjusted_mode.flags (2) (expected 0, found 2)
> > > [  245.683382] [drm:pipe_config_err] *ERROR* mismatch in base.adjusted_mode.flags (8) (expected 0, found 8)
> > > [  245.683427] pipe state doesn't match!
> > > 
> > > if you are interested.
> > 
> > That's a bit odd. Even if the mode originally doesn't have any
> > hsync/vsync flags intel_modeset_pipe_config() should give it some.
> > So I can't immediately see how we could manage to get there with
> > expected==0.
> 
> Hmm. Does you 845g have DVO encoders? That could potentially explain if
> it ends up using intel_crtc_mode_get(). That one fails to read out the
> sync flags correctly, and it has other issues as well.

CRTC info
---------
CRTC 31: pipe: A, active=yes, (size=1024x768), dither=no, bpp=24
	fb: 39, pos: 0x0, size: 1024x768
	encoder 34: type: DVO C, connectors:
		connector 35: type: LVDS-1, status: connected, mode:
		id 0:"1024x768" freq 60 clock 65000 hdisp 1024 hss 1048 hse 1184 htot 1344 vdisp 768 vss 771 vse 777 vtot 806 type 0x8 flags 0x0
	cursor visible? no, position (0, 0), size 0x0, addr 0x00000000
	No scalers available on this platform
	--Plane id 27: type=PRI, crtc_pos=   0x   0, crtc_size=1024x 768, src_pos=0.0000x0.0000, src_size=1024.0000x768.0000, format=XR24 little-endian (0x34325258), rotation=0 (0x00000001)
	--Plane id 29: type=CUR, crtc_pos=   0x   0, crtc_size=   0x   0, src_pos=0.0000x0.0000, src_size=0.0000x0.0000, format=N/A, rotation=0 (0x00000001)
	underrun reporting: cpu=yes pch=yes 

Connector info
--------------
connector 35: type LVDS-1, status: connected
	name: 
	physical dimensions: 0x0mm
	subpixel order: Horizontal RGB
	CEA rev: 0
	modes:
		id 37:"1024x768" freq 60 clock 65000 hdisp 1024 hss 1048 hse 1184 htot 1344 vdisp 768 vss 771 vse 777 vtot 806 type 0x8 flags 0x0
connector 32: type VGA-1, status: unknown
	modes:

So yes, it appears LVDS is attached via DVO.

> https://patchwork.freedesktop.org/series/5183/ but not sure it applies
> cleanly anymore.

It has two chances...
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2017-09-25 14:10 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-09-14 15:17 [PATCH] drm/i915: Don't rmw PIPESTAT enable bits Ville Syrjala
2017-09-14 16:04 ` ✓ Fi.CI.BAT: success for " Patchwork
2017-09-14 20:37 ` [PATCH] " Chris Wilson
2017-09-15 10:03   ` Ville Syrjälä
2017-09-25 14:05     ` Ville Syrjälä
2017-09-25 14:10       ` Chris Wilson
2017-09-14 21:20 ` ✗ Fi.CI.IGT: failure for " Patchwork
2017-09-25 10:33 ` [PATCH] " Imre Deak
2017-09-25 13:53   ` Ville Syrjälä

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox