diff mbox

[1/2] drm/i915: clear GFX_MODE on IVB at init time

Message ID 20110812152832.6c922a17@jbarnes-desktop (mailing list archive)
State New, archived
Headers show

Commit Message

Jesse Barnes Aug. 12, 2011, 10:28 p.m. UTC
On Fri, 12 Aug 2011 15:18:09 -0700
Jesse Barnes <jbarnes@virtuousgeek.org> wrote:

> On Fri, 12 Aug 2011 14:55:32 -0700
> Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> 
> > GFX_MODE controls important behavior like PPGTT, run lists, and TLB
> > invalidate behavior.  On the SDV I'm using, the TLB invalidation mode
> > was defaulting to "pipe control only" which meant regular MI_FLUSHes
> > wouldn't actually flush the TLB, leading to all sorts of stale data
> > getting used.
> > 
> > So initialize it to 0 at ring buffer init time until we actually use
> > PIPE_CONTROL for TLB invalidation.
> 
> Ignore this one, see below for an updated patch that uses bit
> definitions and makes sure the register gets reset at GPU reset time as
> well.

Ignore the last one too.  Third time's the charm!

Comments

Chris Wilson Aug. 12, 2011, 10:56 p.m. UTC | #1
On Fri, 12 Aug 2011 15:28:32 -0700, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
>  		I915_WRITE(MI_MODE, mode);
> +		if (IS_GEN7(dev))
> +			I915_WRITE(GFX_MODE_GEN7, ((GFX_TLB_INVALIDATE_ALWAYS |
> +						    GFX_REPLAY_MODE) << 16) |
> +				   GFX_REPLAY_MODE);

That's maximally confusing indentation ;-)
Also it reads like that is a chicken bit, as in order to invalidate always
on flush we need to clear it? Can we play around with the name to avoid
confusion in the code and confusion with the spec?

#define ENABLE(x) ((x) << 16 | (x))
#define DISABLE(x) ((x) << 16 | 0)

Granted finding good names for those is hard. Perhaps ENABLE_16(x),
DISABLE_16(x) to indicate the mask size.
-Chris
Kenneth Graunke Aug. 15, 2011, 11:59 p.m. UTC | #2
On 08/12/2011 03:28 PM, Jesse Barnes wrote:
> On Fri, 12 Aug 2011 15:18:09 -0700
> Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> 
>> On Fri, 12 Aug 2011 14:55:32 -0700
>> Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
>>
>>> GFX_MODE controls important behavior like PPGTT, run lists, and TLB
>>> invalidate behavior.  On the SDV I'm using, the TLB invalidation mode
>>> was defaulting to "pipe control only" which meant regular MI_FLUSHes
>>> wouldn't actually flush the TLB, leading to all sorts of stale data
>>> getting used.
>>>
>>> So initialize it to 0 at ring buffer init time until we actually use
>>> PIPE_CONTROL for TLB invalidation.
>>
>> Ignore this one, see below for an updated patch that uses bit
>> definitions and makes sure the register gets reset at GPU reset time as
>> well.
> 
> Ignore the last one too.  Third time's the charm!

Tested-by: Kenneth Graunke <kenneth@whitecape.org>

With drm-intel-next, I've been seeing frequent but intermittent
rendering corruption in GNOME Terminal, rendercheck failures, and the
occasional kernel crash.

After applying the patch, I was able to run for an entire day without
any crashes or rendering corruption.  To double check, I reverted this
patch and was immediately able to reproduce my earlier problems.

With this patch and C0 hardware, my system seems quite stable.  Thanks
Jesse!
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 7033e01..26641ad 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -375,6 +375,7 @@ 
 # define MI_FLUSH_ENABLE				(1 << 11)
 
 #define GFX_MODE	0x02520
+#define GFX_MODE_GEN7	0x0229c
 #define   GFX_RUN_LIST_ENABLE		(1<<15)
 #define   GFX_TLB_INVALIDATE_ALWAYS	(1<<13)
 #define   GFX_SURFACE_FAULT_ENABLE	(1<<12)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 47b9b27..0b17036 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -290,6 +290,10 @@  static int init_render_ring(struct intel_ring_buffer *ring)
 		if (IS_GEN6(dev) || IS_GEN7(dev))
 			mode |= MI_FLUSH_ENABLE << 16 | MI_FLUSH_ENABLE;
 		I915_WRITE(MI_MODE, mode);
+		if (IS_GEN7(dev))
+			I915_WRITE(GFX_MODE_GEN7, ((GFX_TLB_INVALIDATE_ALWAYS |
+						    GFX_REPLAY_MODE) << 16) |
+				   GFX_REPLAY_MODE);
 	}
 
 	if (INTEL_INFO(dev)->gen >= 6) {