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; }
static inline int adreno_rb_ctxtswitch(struct adreno_device *adreno_dev, unsigned int *cmd) { return cmd[0] == cp_packet(adreno_dev, CP_NOP, 1) && cmd[1] == KGSL_CONTEXT_TO_MEM_IDENTIFIER; }