From 8555599aeba3dab176d7dd295b196c05a1f2a40f Mon Sep 17 00:00:00 2001 From: Jeremy Gebben Date: Fri, 14 Jun 2013 08:13:12 -0600 Subject: [PATCH] msm: kgsl: don't store rptr in struct adreno_ringbuffer Since the rptr is written by the GPU, there's no point in keeping a copy in the ringbuffer struct where it will likely be out of date. If you need to look at the ringbuffer, read it into a local variable with adreno_get_rptr(). Change-Id: Ibf1ba0b9c71a93f65a5c85a58328b2202a27af3f Signed-off-by: Jeremy Gebben --- drivers/gpu/msm/adreno.c | 12 ++++++------ drivers/gpu/msm/adreno_ringbuffer.c | 22 +++++++++++----------- drivers/gpu/msm/adreno_ringbuffer.h | 19 ++++++++++++++----- 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index 224fa1f46ac..ecd3c0d6fb7 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -2880,6 +2880,7 @@ static int adreno_ringbuffer_drain(struct kgsl_device *device, struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer; unsigned long wait; unsigned long timeout = jiffies + msecs_to_jiffies(ADRENO_IDLE_TIMEOUT); + unsigned int rptr; /* * The first time into the loop, wait for 100 msecs and kick wptr again @@ -2898,14 +2899,13 @@ static int adreno_ringbuffer_drain(struct kgsl_device *device, wait = jiffies + msecs_to_jiffies(KGSL_TIMEOUT_PART); } - GSL_RB_GET_READPTR(rb, &rb->rptr); - + rptr = adreno_get_rptr(rb); if (time_after(jiffies, timeout)) { KGSL_DRV_ERR(device, "rptr: %x, wptr: %x\n", - rb->rptr, rb->wptr); + rptr, rb->wptr); return -ETIMEDOUT; } - } while (rb->rptr != rb->wptr); + } while (rptr != rb->wptr); return 0; } @@ -3005,8 +3005,8 @@ static unsigned int adreno_isidle(struct kgsl_device *device) /* If the device isn't active, don't force it on. */ if (device->state == KGSL_STATE_ACTIVE) { /* Is the ring buffer is empty? */ - GSL_RB_GET_READPTR(rb, &rb->rptr); - if (rb->rptr == rb->wptr) { + unsigned int rptr = adreno_get_rptr(rb); + if (rptr == rb->wptr) { /* * Are there interrupts pending? If so then pretend we * are not idle - this avoids the possiblity that we go diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c index 50ecbb0a0fb..2d87263b8fb 100644 --- a/drivers/gpu/msm/adreno_ringbuffer.c +++ b/drivers/gpu/msm/adreno_ringbuffer.c @@ -67,6 +67,7 @@ adreno_ringbuffer_waitspace(struct adreno_ringbuffer *rb, unsigned long wait_timeout = msecs_to_jiffies(ADRENO_IDLE_TIMEOUT); unsigned long wait_time_part; unsigned int prev_reg_val[FT_DETECT_REGS_COUNT]; + unsigned int rptr; memset(prev_reg_val, 0, sizeof(prev_reg_val)); @@ -86,8 +87,8 @@ adreno_ringbuffer_waitspace(struct adreno_ringbuffer *rb, * want the rptr and wptr to become equal when * the ringbuffer is not empty */ do { - GSL_RB_GET_READPTR(rb, &rb->rptr); - } while (!rb->rptr); + rptr = adreno_get_rptr(rb); + } while (!rptr); rb->wptr++; @@ -100,9 +101,9 @@ adreno_ringbuffer_waitspace(struct adreno_ringbuffer *rb, wait_time_part = jiffies + msecs_to_jiffies(KGSL_TIMEOUT_PART); /* wait for space in ringbuffer */ while (1) { - GSL_RB_GET_READPTR(rb, &rb->rptr); + rptr = adreno_get_rptr(rb); - freecmds = rb->rptr - rb->wptr; + freecmds = rptr - rb->wptr; if (freecmds == 0 || freecmds > numcmds) break; @@ -117,7 +118,7 @@ adreno_ringbuffer_waitspace(struct adreno_ringbuffer *rb, KGSL_DRV_ERR(rb->device, "Hang detected while waiting for freespace in" "ringbuffer rptr: 0x%x, wptr: 0x%x\n", - rb->rptr, rb->wptr); + rptr, rb->wptr); goto err; } } @@ -125,7 +126,7 @@ adreno_ringbuffer_waitspace(struct adreno_ringbuffer *rb, if (time_after(jiffies, wait_time)) { KGSL_DRV_ERR(rb->device, "Timed out while waiting for freespace in ringbuffer " - "rptr: 0x%x, wptr: 0x%x\n", rb->rptr, rb->wptr); + "rptr: 0x%x, wptr: 0x%x\n", rptr, rb->wptr); goto err; } @@ -154,11 +155,12 @@ unsigned int *adreno_ringbuffer_allocspace(struct adreno_ringbuffer *rb, { unsigned int *ptr = NULL; int ret = 0; + unsigned int rptr; BUG_ON(numcmds >= rb->sizedwords); - GSL_RB_GET_READPTR(rb, &rb->rptr); + rptr = adreno_get_rptr(rb); /* check for available space */ - if (rb->wptr >= rb->rptr) { + if (rb->wptr >= rptr) { /* wptr ahead or equal to rptr */ /* reserve dwords for nop packet */ if ((rb->wptr + numcmds) > (rb->sizedwords - @@ -167,7 +169,7 @@ unsigned int *adreno_ringbuffer_allocspace(struct adreno_ringbuffer *rb, numcmds, 1); } else { /* wptr behind rptr */ - if ((rb->wptr + numcmds) >= rb->rptr) + if ((rb->wptr + numcmds) >= rptr) ret = adreno_ringbuffer_waitspace(rb, context, numcmds, 0); /* check for remaining space */ @@ -453,7 +455,6 @@ int _ringbuffer_start_common(struct adreno_ringbuffer *rb) else if (adreno_is_a330(adreno_dev) || adreno_is_a305b(adreno_dev)) adreno_regwrite(device, REG_CP_QUEUE_THRESHOLDS, 0x003E2008); - rb->rptr = 0; rb->wptr = 0; /* clear ME_HALT to start micro engine */ @@ -1378,7 +1379,6 @@ adreno_ringbuffer_restore(struct adreno_ringbuffer *rb, unsigned int *rb_buff, if (num_rb_contents > (rb->buffer_desc.size - rb->wptr)) { adreno_regwrite(rb->device, REG_CP_RB_RPTR, 0); - rb->rptr = 0; BUG_ON(num_rb_contents > rb->buffer_desc.size); } ringcmds = (unsigned int *)rb->buffer_desc.hostptr + rb->wptr; diff --git a/drivers/gpu/msm/adreno_ringbuffer.h b/drivers/gpu/msm/adreno_ringbuffer.h index f59b834c8e2..e9fb050cd43 100644 --- a/drivers/gpu/msm/adreno_ringbuffer.h +++ b/drivers/gpu/msm/adreno_ringbuffer.h @@ -54,7 +54,6 @@ struct adreno_ringbuffer { unsigned int sizedwords; unsigned int wptr; /* write pointer offset in dwords from baseaddr */ - unsigned int rptr; /* read pointer offset in dwords from baseaddr */ unsigned int timestamp[KGSL_MEMSTORE_MAX]; }; @@ -74,10 +73,20 @@ struct adreno_ringbuffer { /* mem rptr */ #define GSL_RB_CNTL_NO_UPDATE 0x0 /* enable */ -#define GSL_RB_GET_READPTR(rb, data) \ - do { \ - *(data) = rb->memptrs->rptr; \ - } while (0) + +/** + * adreno_get_rptr - Get the current ringbuffer read pointer + * @rb - the ringbuffer + * + * Get the current read pointer, which is written by the GPU. + */ +static inline unsigned int +adreno_get_rptr(struct adreno_ringbuffer *rb) +{ + unsigned int result = rb->memptrs->rptr; + rmb(); + return result; +} #define GSL_RB_CNTL_POLL_EN 0x0 /* disable */