OUT(buffer, VIV_FE_END_HEADER_OP_END);
}
-static inline void CMD_WAIT(struct etnaviv_cmdbuf *buffer)
+static inline void CMD_WAIT(struct etnaviv_cmdbuf *buffer,
+ unsigned int waitcycles)
{
buffer->user_size = ALIGN(buffer->user_size, 8);
- OUT(buffer, VIV_FE_WAIT_HEADER_OP_WAIT | 200);
+ OUT(buffer, VIV_FE_WAIT_HEADER_OP_WAIT | waitcycles);
}
static inline void CMD_LINK(struct etnaviv_cmdbuf *buffer,
/* initialize buffer */
buffer->user_size = 0;
- CMD_WAIT(buffer);
+ CMD_WAIT(buffer, gpu->fe_waitcycles);
CMD_LINK(buffer, 2,
etnaviv_cmdbuf_get_va(buffer, &gpu->mmu_context->cmdbuf_mapping)
+ buffer->user_size - 4);
CMD_END(buffer);
/* Append waitlink */
- CMD_WAIT(buffer);
+ CMD_WAIT(buffer, gpu->fe_waitcycles);
CMD_LINK(buffer, 2,
etnaviv_cmdbuf_get_va(buffer, &gpu->mmu_context->cmdbuf_mapping)
+ buffer->user_size - 4);
CMD_LOAD_STATE(buffer, VIVS_GL_EVENT, VIVS_GL_EVENT_EVENT_ID(event) |
VIVS_GL_EVENT_FROM_PE);
- CMD_WAIT(buffer);
+ CMD_WAIT(buffer, gpu->fe_waitcycles);
CMD_LINK(buffer, 2,
etnaviv_cmdbuf_get_va(buffer, &gpu->mmu_context->cmdbuf_mapping)
+ buffer->user_size - 4);
clock |= VIVS_HI_CLOCK_CONTROL_FSCALE_VAL(fscale);
etnaviv_gpu_load_clock(gpu, clock);
}
+
+ /*
+ * Choose number of wait cycles to target a ~30us (1/32768) max latency
+ * until new work is picked up by the FE when it polls in the idle loop.
+ * If the GPU base frequency is unknown use 200 wait cycles.
+ */
+ gpu->fe_waitcycles = clamp(gpu->base_rate_core >> (15 - gpu->freq_scale),
+ 200UL, 0xffffUL);
}
static int etnaviv_hw_reset(struct etnaviv_gpu *gpu)