static int adreno_ringbuffer_waitspace(struct adreno_ringbuffer *rb, unsigned int numcmds, int wptr_ahead) { int nopcount; unsigned int freecmds; unsigned int *cmds; unsigned int gpuaddr; unsigned long wait_time; unsigned long wait_timeout = msecs_to_jiffies(ADRENO_IDLE_TIMEOUT); unsigned long wait_time_part; unsigned int rptr; /* if wptr ahead, fill the remaining with NOPs */ if (wptr_ahead) { /* -1 for header */ nopcount = KGSL_RB_DWORDS - rb->wptr - 1; cmds = RB_HOSTPTR(rb, rb->wptr); gpuaddr = RB_GPUADDR(rb, rb->wptr); *cmds = cp_nop_packet(nopcount); kgsl_cffdump_write(rb->device, gpuaddr, *cmds); /* Make sure that rptr is not 0 before submitting * commands at the end of ringbuffer. We do not * want the rptr and wptr to become equal when * the ringbuffer is not empty */ do { rptr = adreno_get_rptr(rb); } while (!rptr); rb->wptr = 0; } wait_time = jiffies + wait_timeout; wait_time_part = jiffies + msecs_to_jiffies(KGSL_TIMEOUT_PART); /* wait for space in ringbuffer */ while (1) { rptr = adreno_get_rptr(rb); freecmds = rptr - rb->wptr; if (freecmds == 0 || freecmds > numcmds) break; 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", rptr, rb->wptr); return -ETIMEDOUT; } } return 0; }
static void _cff_write_ringbuffer(struct adreno_ringbuffer *rb) { struct adreno_device *adreno_dev = ADRENO_DEVICE(rb->device); struct kgsl_device *device = &adreno_dev->dev; uint64_t gpuaddr; unsigned int *hostptr; size_t size; if (device->cff_dump_enable == 0) return; BUG_ON(rb->wptr < rb->last_wptr); size = (rb->wptr - rb->last_wptr) * sizeof(unsigned int); hostptr = RB_HOSTPTR(rb, rb->last_wptr); gpuaddr = RB_GPUADDR(rb, rb->last_wptr); kgsl_cffdump_memcpy(device, gpuaddr, hostptr, size); }
static void _cff_write_ringbuffer(struct adreno_ringbuffer *rb) { struct adreno_device *adreno_dev = ADRENO_DEVICE(rb->device); struct kgsl_device *device = &adreno_dev->dev; unsigned int gpuaddr; unsigned int *hostptr; size_t size; if (device->cff_dump_enable == 0) return; /* * This code is predicated on the fact that we write a full block of * stuff without wrapping */ BUG_ON(rb->wptr < rb->last_wptr); size = (rb->wptr - rb->last_wptr) * sizeof(unsigned int); hostptr = RB_HOSTPTR(rb, rb->last_wptr); gpuaddr = RB_GPUADDR(rb, rb->last_wptr); kgsl_cffdump_memcpy(device, gpuaddr, hostptr, size); }
static int adreno_ringbuffer_waitspace(struct adreno_ringbuffer *rb, unsigned int numcmds, int wptr_ahead) { int nopcount = 0; unsigned int freecmds; unsigned int wptr = rb->wptr; unsigned int *cmds = NULL; uint64_t gpuaddr; unsigned long wait_time; unsigned long wait_timeout = msecs_to_jiffies(ADRENO_IDLE_TIMEOUT); unsigned int rptr; struct adreno_device *adreno_dev = ADRENO_DEVICE(rb->device); if (wptr_ahead) { nopcount = KGSL_RB_DWORDS - rb->wptr - 1; cmds = RB_HOSTPTR(rb, rb->wptr); gpuaddr = RB_GPUADDR(rb, rb->wptr); rptr = adreno_get_rptr(rb); if ((adreno_dev->cur_rb != rb || !adreno_preempt_state(adreno_dev, ADRENO_DISPATCHER_PREEMPT_CLEAR)) && !rptr) return -ENOSPC; wait_time = jiffies + wait_timeout; while (!rptr) { rptr = adreno_get_rptr(rb); if (time_after(jiffies, wait_time)) return -ETIMEDOUT; } rb->wptr = 0; } rptr = adreno_get_rptr(rb); freecmds = rptr - rb->wptr; if (freecmds == 0 || freecmds > numcmds) goto done; if (adreno_dev->cur_rb != rb || !adreno_preempt_state(adreno_dev, ADRENO_DISPATCHER_PREEMPT_CLEAR)) { rb->wptr = wptr; return -ENOSPC; } wait_time = jiffies + wait_timeout; while (1) { rptr = adreno_get_rptr(rb); freecmds = rptr - rb->wptr; if (freecmds == 0 || freecmds > numcmds) break; if (time_after(jiffies, wait_time)) { KGSL_DRV_ERR(rb->device, "Timed out waiting for freespace in RB rptr: 0x%x, wptr: 0x%x, rb id %d\n", rptr, wptr, rb->id); return -ETIMEDOUT; } } done: if (wptr_ahead) { *cmds = cp_packet(adreno_dev, CP_NOP, nopcount); kgsl_cffdump_write(rb->device, gpuaddr, *cmds); } return 0; }