From c5de5abbd90333fe1359283fb3a5e457b0f389f3 Mon Sep 17 00:00:00 2001
From: Rob Clark <robclark@freedesktop.org>
Date: Wed, 19 Feb 2014 11:01:23 -0500
Subject: freedreno: some msm-ring reset/flush fixes

Need to update timestamp on all ring's associated with a submit (ie.
both the binning pass and main ring).  Also, make sure nr_reloc's
in particular gets cleared if the rb is reset.

Signed-off-by: Rob Clark <robclark@freedesktop.org>
---
 freedreno/freedreno_priv.h       |  1 +
 freedreno/freedreno_ringbuffer.c |  2 ++
 freedreno/msm/msm_ringbuffer.c   | 41 +++++++++++++++++++++++++++++++---------
 3 files changed, 35 insertions(+), 9 deletions(-)

(limited to 'freedreno')

diff --git a/freedreno/freedreno_priv.h b/freedreno/freedreno_priv.h
index d5cf9f97..74384858 100644
--- a/freedreno/freedreno_priv.h
+++ b/freedreno/freedreno_priv.h
@@ -114,6 +114,7 @@ struct fd_ringmarker {
 struct fd_ringbuffer_funcs {
 	void * (*hostptr)(struct fd_ringbuffer *ring);
 	int (*flush)(struct fd_ringbuffer *ring, uint32_t *last_start);
+	void (*reset)(struct fd_ringbuffer *ring);
 	void (*emit_reloc)(struct fd_ringbuffer *ring,
 			const struct fd_reloc *reloc);
 	void (*emit_reloc_ring)(struct fd_ringbuffer *ring,
diff --git a/freedreno/freedreno_ringbuffer.c b/freedreno/freedreno_ringbuffer.c
index 44437906..b9849c5f 100644
--- a/freedreno/freedreno_ringbuffer.c
+++ b/freedreno/freedreno_ringbuffer.c
@@ -72,6 +72,8 @@ void fd_ringbuffer_reset(struct fd_ringbuffer *ring)
 	if (ring->pipe->id == FD_PIPE_2D)
 		start = &ring->start[0x140];
 	ring->cur = ring->last_start = start;
+	if (ring->funcs->reset)
+		ring->funcs->reset(ring);
 }
 
 /* maybe get rid of this and use fd_ringmarker_flush() from DDX too? */
diff --git a/freedreno/msm/msm_ringbuffer.c b/freedreno/msm/msm_ringbuffer.c
index f3e951f9..c9c92561 100644
--- a/freedreno/msm/msm_ringbuffer.c
+++ b/freedreno/msm/msm_ringbuffer.c
@@ -169,6 +169,22 @@ static uint32_t find_next_reloc_idx(struct msm_ringbuffer *msm_ring,
 	return i;
 }
 
+static void flush_reset(struct fd_ringbuffer *ring)
+{
+	struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring);
+	unsigned i;
+
+	/* for each of the cmd buffers, clear their reloc's: */
+	for (i = 0; i < msm_ring->nr_cmds; i++) {
+		struct msm_ringbuffer *target_ring = to_msm_ringbuffer(msm_ring->rings[i]);
+		target_ring->nr_relocs = 0;
+	}
+
+	msm_ring->nr_relocs = 0;
+	msm_ring->nr_cmds = 0;
+	msm_ring->nr_bos = 0;
+}
+
 static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start)
 {
 	struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring);
@@ -205,8 +221,16 @@ static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start
 
 	ret = drmCommandWriteRead(ring->pipe->dev->fd, DRM_MSM_GEM_SUBMIT,
 			&req, sizeof(req));
-	if (ret)
+	if (ret) {
 		ERROR_MSG("submit failed: %d (%s)", ret, strerror(errno));
+	} else {
+		/* update timestamp on all rings associated with submit: */
+		for (i = 0; i < msm_ring->nr_cmds; i++) {
+			struct fd_ringbuffer *target_ring = msm_ring->rings[i];
+			if (!ret)
+				target_ring->last_timestamp = req.fence;
+		}
+	}
 
 	LIST_FOR_EACH_ENTRY_SAFE(msm_bo, tmp, &msm_ring->submit_list, list[id]) {
 		struct list_head *list = &msm_bo->list[id];
@@ -215,18 +239,16 @@ static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start
 		fd_bo_del(&msm_bo->base);
 	}
 
-	/* for each of the cmd buffers, clear their reloc's: */
-	for (i = 0; i < msm_ring->nr_cmds; i++) {
-		struct msm_ringbuffer *target_ring = to_msm_ringbuffer(msm_ring->rings[i]);
-		target_ring->nr_relocs = 0;
-	}
-
-	msm_ring->nr_cmds = 0;
-	msm_ring->nr_bos = 0;
+	flush_reset(ring);
 
 	return ret;
 }
 
+static void msm_ringbuffer_reset(struct fd_ringbuffer *ring)
+{
+	flush_reset(ring);
+}
+
 static void msm_ringbuffer_emit_reloc(struct fd_ringbuffer *ring,
 		const struct fd_reloc *r)
 {
@@ -285,6 +307,7 @@ static void msm_ringbuffer_destroy(struct fd_ringbuffer *ring)
 static struct fd_ringbuffer_funcs funcs = {
 		.hostptr = msm_ringbuffer_hostptr,
 		.flush = msm_ringbuffer_flush,
+		.reset = msm_ringbuffer_reset,
 		.emit_reloc = msm_ringbuffer_emit_reloc,
 		.emit_reloc_ring = msm_ringbuffer_emit_reloc_ring,
 		.destroy = msm_ringbuffer_destroy,
-- 
cgit v1.2.3