aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_gpu.c9
-rw-r--r--drivers/gpu/drm/msm/msm_ringbuffer.c1
-rw-r--r--drivers/gpu/drm/msm/msm_ringbuffer.h12
3 files changed, 16 insertions, 6 deletions
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 4e9caf97b20f..63d05a376700 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -188,6 +188,7 @@ int adreno_hw_init(struct msm_gpu *gpu)
}
ring->cur = ring->start;
+ ring->next = ring->start;
/* reset completed fence seqno: */
ring->memptrs->fence = ring->seqno;
@@ -332,12 +333,15 @@ void adreno_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
uint32_t wptr;
+ /* Copy the shadow to the actual register */
+ ring->cur = ring->next;
+
/*
* Mask wptr value that we calculate to fit in the HW range. This is
* to account for the possibility that the last command fit exactly into
* the ringbuffer and rb->next hasn't wrapped to zero yet
*/
- wptr = get_wptr(ring) % (MSM_GPU_RINGBUFFER_SZ >> 2);
+ wptr = (ring->cur - ring->start) % (MSM_GPU_RINGBUFFER_SZ >> 2);
/* ensure writes to ringbuffer have hit system memory: */
mb();
@@ -449,7 +453,8 @@ static uint32_t ring_freewords(struct msm_ringbuffer *ring)
{
struct adreno_gpu *adreno_gpu = to_adreno_gpu(ring->gpu);
uint32_t size = MSM_GPU_RINGBUFFER_SZ >> 2;
- uint32_t wptr = get_wptr(ring);
+ /* Use ring->next to calculate free size */
+ uint32_t wptr = ring->next - ring->start;
uint32_t rptr = get_rptr(adreno_gpu, ring);
return (rptr + (size - 1) - wptr) % size;
}
diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.c b/drivers/gpu/drm/msm/msm_ringbuffer.c
index 4db6ca719706..e39c4e392854 100644
--- a/drivers/gpu/drm/msm/msm_ringbuffer.c
+++ b/drivers/gpu/drm/msm/msm_ringbuffer.c
@@ -46,6 +46,7 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int id,
goto fail;
}
ring->end = ring->start + (MSM_GPU_RINGBUFFER_SZ >> 2);
+ ring->next = ring->start;
ring->cur = ring->start;
ring->memptrs = memptrs;
diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.h b/drivers/gpu/drm/msm/msm_ringbuffer.h
index ec44251ef9f2..3749764a238e 100644
--- a/drivers/gpu/drm/msm/msm_ringbuffer.h
+++ b/drivers/gpu/drm/msm/msm_ringbuffer.h
@@ -32,7 +32,7 @@ struct msm_ringbuffer {
struct msm_gpu *gpu;
int id;
struct drm_gem_object *bo;
- uint32_t *start, *end, *cur;
+ uint32_t *start, *end, *cur, *next;
struct list_head submits;
uint64_t iova;
uint32_t seqno;
@@ -51,9 +51,13 @@ void msm_ringbuffer_destroy(struct msm_ringbuffer *ring);
static inline void
OUT_RING(struct msm_ringbuffer *ring, uint32_t data)
{
- if (ring->cur == ring->end)
- ring->cur = ring->start;
- *(ring->cur++) = data;
+ /*
+ * ring->next points to the current command being written - it won't be
+ * committed as ring->cur until the flush
+ */
+ if (ring->next == ring->end)
+ ring->next = ring->start;
+ *(ring->next++) = data;
}
#endif /* __MSM_RINGBUFFER_H__ */