diff mbox

[4/9] drm/i915: add post-flush store dw workaround

Message ID 1348086543-24427-4-git-send-email-jbarnes@virtuousgeek.org (mailing list archive)
State New, archived
Headers show

Commit Message

Jesse Barnes Sept. 19, 2012, 8:28 p.m. UTC
Several platforms need this to flush the CS write buffers.

References: https://bugs.freedesktop.org/show_bug.cgi?id=50241
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/intel_ringbuffer.c |   15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

Comments

Daniel Vetter Sept. 25, 2012, 8:49 a.m. UTC | #1
On Wed, Sep 19, 2012 at 01:28:58PM -0700, Jesse Barnes wrote:
> Several platforms need this to flush the CS write buffers.

Chris spent quite some effort to dump less crap into the rings on gen6,
and your description here sounds like we only need this when flushing
write caches. Or it might only apply to CS writes (in which case this is
at the wrong spot). In any case, can you please double check where exactly
we need this and only add it there, with a neat comment explaining things
added?

I'm bitching because afair the CS stuff the windows driver emits (of which
I've seen some traces) only emits one such 8x MI_WRITE block per batch,
whereas your code here would emit 2 such 2x MI_WRITE blocks.

Thanks, Daniel
> 
> References: https://bugs.freedesktop.org/show_bug.cgi?id=50241
> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
> ---
>  drivers/gpu/drm/i915/intel_ringbuffer.c |   15 ++++++++++++++-
>  1 file changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
> index 55cdb4d..ef5101f 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
> @@ -216,7 +216,7 @@ gen6_render_ring_flush(struct intel_ring_buffer *ring,
>  	u32 flags = 0;
>  	struct pipe_control *pc = ring->private;
>  	u32 scratch_addr = pc->gtt_offset + 128;
> -	int ret;
> +	int ret, i;
>  
>  	/* Force SNB workarounds for PIPE_CONTROL flushes */
>  	ret = intel_emit_post_sync_nonzero_flush(ring);
> @@ -259,6 +259,19 @@ gen6_render_ring_flush(struct intel_ring_buffer *ring,
>  	intel_ring_emit(ring, 0);
>  	intel_ring_advance(ring);
>  
> +	ret = intel_ring_begin(ring, 4 * 8);
> +	if (ret)
> +		return ret;
> +
> +	for (i = 0; i < 8; i++) {
> +		intel_ring_emit(ring, MI_STORE_DWORD_INDEX);
> +		intel_ring_emit(ring, I915_GEM_SCRATCH_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
> +		intel_ring_emit(ring, 0);
> +		intel_ring_emit(ring, MI_NOOP);
> +	}
> +	intel_ring_advance(ring);
> +
> +
>  	return 0;
>  }
>  
> -- 
> 1.7.9.5
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Jesse Barnes Sept. 25, 2012, 11:07 a.m. UTC | #2
On Tue, 25 Sep 2012 10:49:28 +0200
Daniel Vetter <daniel@ffwll.ch> wrote:

> On Wed, Sep 19, 2012 at 01:28:58PM -0700, Jesse Barnes wrote:
> > Several platforms need this to flush the CS write buffers.
> 
> Chris spent quite some effort to dump less crap into the rings on gen6,
> and your description here sounds like we only need this when flushing
> write caches. Or it might only apply to CS writes (in which case this is
> at the wrong spot). In any case, can you please double check where exactly
> we need this and only add it there, with a neat comment explaining things
> added?

"write caches" as in "any time we do a store dw and want to read the
result coherently" is my understanding.

> I'm bitching because afair the CS stuff the windows driver emits (of which
> I've seen some traces) only emits one such 8x MI_WRITE block per batch,
> whereas your code here would emit 2 such 2x MI_WRITE blocks.

Doing it once should be sufficient, I guess I need to split this out
(probably a good idea anyway for comment & naming purposes).
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 55cdb4d..ef5101f 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -216,7 +216,7 @@  gen6_render_ring_flush(struct intel_ring_buffer *ring,
 	u32 flags = 0;
 	struct pipe_control *pc = ring->private;
 	u32 scratch_addr = pc->gtt_offset + 128;
-	int ret;
+	int ret, i;
 
 	/* Force SNB workarounds for PIPE_CONTROL flushes */
 	ret = intel_emit_post_sync_nonzero_flush(ring);
@@ -259,6 +259,19 @@  gen6_render_ring_flush(struct intel_ring_buffer *ring,
 	intel_ring_emit(ring, 0);
 	intel_ring_advance(ring);
 
+	ret = intel_ring_begin(ring, 4 * 8);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < 8; i++) {
+		intel_ring_emit(ring, MI_STORE_DWORD_INDEX);
+		intel_ring_emit(ring, I915_GEM_SCRATCH_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
+		intel_ring_emit(ring, 0);
+		intel_ring_emit(ring, MI_NOOP);
+	}
+	intel_ring_advance(ring);
+
+
 	return 0;
 }