diff options
author | Carter Cooper <ccooper@codeaurora.org> | 2016-05-03 14:11:04 -0600 |
---|---|---|
committer | Carter Cooper <ccooper@codeaurora.org> | 2016-07-20 15:19:32 -0600 |
commit | 2e7b23f2afb9ccfcc5b9fcd45ababc9666046695 (patch) | |
tree | 222e9c55710f2f593af16c2642fb1ee8d2c969b9 /drivers/gpu/msm/adreno_ringbuffer.c | |
parent | 0ff59e62624886a564f582b7e370c85d107b26ce (diff) |
msm: kgsl: Use the GPU to write the RPTR
The memstore shared between the CPU and GPU is old but can not be
messed with. Rather than stealing values from it where available,
add a new block of shared memory that is exclusive to the driver
and GPU. This block can be used more freely than the old
memstore block.
Program the GPU to write the RPTR out to an address the CPU can read rather
than having the CPU read a GPU register directly. There are some very
small but very real conditions where different blocks on the GPU have
outdated values for the RPTR. When scheduling preemption the value read
from the register could not reflect the actual value of the RPTR in the CP.
This can cause the save/restore from preemption to give back incorrect RPTR
values causing much confusion between the GPU and CPU.
Remove the ringbuffers copy of the read pointer shadow.
Now that the GPU will update a shared memory address with the
value of the read pointer, there is no need to poll the register
to get the value and then keep a local copy of it.
CRs-Fixed: 987082
Change-Id: Ic44759d1a5c6e48b2f0f566ea8c153f01cf68279
Signed-off-by: Carter Cooper <ccooper@codeaurora.org>
Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
Diffstat (limited to 'drivers/gpu/msm/adreno_ringbuffer.c')
-rw-r--r-- | drivers/gpu/msm/adreno_ringbuffer.c | 31 |
1 files changed, 14 insertions, 17 deletions
diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c index dceb8fb93461..8f0c31361854 100644 --- a/drivers/gpu/msm/adreno_ringbuffer.c +++ b/drivers/gpu/msm/adreno_ringbuffer.c @@ -279,8 +279,9 @@ int adreno_ringbuffer_start(struct adreno_device *adreno_dev, FOR_EACH_RINGBUFFER(adreno_dev, rb, i) { kgsl_sharedmem_set(device, &(rb->buffer_desc), 0, 0xAA, KGSL_RB_SIZE); + kgsl_sharedmem_writel(device, &device->scratch, + SCRATCH_RPTR_OFFSET(rb->id), 0); rb->wptr = 0; - rb->rptr = 0; rb->wptr_preempt_end = 0xFFFFFFFF; rb->starve_timer_state = ADRENO_DISPATCHER_RB_STARVE_TIMER_UNINIT; @@ -446,7 +447,6 @@ adreno_ringbuffer_addcmds(struct adreno_ringbuffer *rb, unsigned int total_sizedwords = sizedwords; unsigned int i; unsigned int context_id = 0; - uint64_t gpuaddr = device->memstore.gpuaddr; bool profile_ready; struct adreno_context *drawctxt = rb->drawctxt_active; struct kgsl_context *context = NULL; @@ -565,9 +565,7 @@ adreno_ringbuffer_addcmds(struct adreno_ringbuffer *rb, if (adreno_is_preemption_enabled(adreno_dev) && gpudev->preemption_pre_ibsubmit) { - cond_addr = device->memstore.gpuaddr + - KGSL_MEMSTORE_OFFSET(context_id, - preempted); + cond_addr = MEMSTORE_ID_GPU_ADDR(device, context_id, preempted); ringcmds += gpudev->preemption_pre_ibsubmit( adreno_dev, rb, ringcmds, context, cond_addr, NULL); @@ -605,11 +603,10 @@ adreno_ringbuffer_addcmds(struct adreno_ringbuffer *rb, *ringcmds++ = cp_mem_packet(adreno_dev, CP_MEM_WRITE, 2, 1); if (drawctxt && !(flags & KGSL_CMD_FLAGS_INTERNAL_ISSUE)) ringcmds += cp_gpuaddr(adreno_dev, ringcmds, - gpuaddr + KGSL_MEMSTORE_OFFSET(context_id, - soptimestamp)); + MEMSTORE_ID_GPU_ADDR(device, context_id, soptimestamp)); else ringcmds += cp_gpuaddr(adreno_dev, ringcmds, - gpuaddr + KGSL_MEMSTORE_RB_OFFSET(rb, soptimestamp)); + MEMSTORE_ID_GPU_ADDR(device, context_id, soptimestamp)); *ringcmds++ = timestamp; if (secured_ctxt) @@ -660,9 +657,9 @@ adreno_ringbuffer_addcmds(struct adreno_ringbuffer *rb, * off system collapse. */ *ringcmds++ = cp_mem_packet(adreno_dev, CP_MEM_WRITE, 2, 1); - ringcmds += cp_gpuaddr(adreno_dev, ringcmds, gpuaddr + - KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL, - ref_wait_ts)); + ringcmds += cp_gpuaddr(adreno_dev, ringcmds, + MEMSTORE_ID_GPU_ADDR(device, KGSL_MEMSTORE_GLOBAL, + ref_wait_ts)); *ringcmds++ = ++_seq_cnt; /* @@ -677,16 +674,16 @@ adreno_ringbuffer_addcmds(struct adreno_ringbuffer *rb, *ringcmds++ = CACHE_FLUSH_TS; if (drawctxt && !(flags & KGSL_CMD_FLAGS_INTERNAL_ISSUE)) { - ringcmds += cp_gpuaddr(adreno_dev, ringcmds, gpuaddr + - KGSL_MEMSTORE_OFFSET(context_id, eoptimestamp)); + ringcmds += cp_gpuaddr(adreno_dev, ringcmds, + MEMSTORE_ID_GPU_ADDR(device, context_id, eoptimestamp)); *ringcmds++ = timestamp; *ringcmds++ = cp_mem_packet(adreno_dev, CP_MEM_WRITE, 2, 1); - ringcmds += cp_gpuaddr(adreno_dev, ringcmds, gpuaddr + - KGSL_MEMSTORE_RB_OFFSET(rb, eoptimestamp)); + ringcmds += cp_gpuaddr(adreno_dev, ringcmds, + MEMSTORE_RB_GPU_ADDR(device, rb, eoptimestamp)); *ringcmds++ = rb->timestamp; } else { - ringcmds += cp_gpuaddr(adreno_dev, ringcmds, gpuaddr + - KGSL_MEMSTORE_RB_OFFSET(rb, eoptimestamp)); + ringcmds += cp_gpuaddr(adreno_dev, ringcmds, + MEMSTORE_RB_GPU_ADDR(device, rb, eoptimestamp)); *ringcmds++ = timestamp; } |