drm/etnaviv: ensure write caches are flushed at end of user cmdstream

If the GPU is done with one user command stream the buffers referenced
by this command stream may go away and get unmapped from the MMU. If
the write caches are still dirty at this point later evictions will run
into MMU faults, killing the GPU.

Make sure the write caches are flushed before signaling completion
of the user command stream.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
This commit is contained in:
Lucas Stach 2016-10-05 18:30:43 +02:00
parent b898578526
commit 8c136b590f
1 changed files with 19 additions and 5 deletions

View File

@ -329,20 +329,34 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, unsigned int event,
/* /*
* Append a LINK to the submitted command buffer to return to * Append a LINK to the submitted command buffer to return to
* the ring buffer. return_target is the ring target address. * the ring buffer. return_target is the ring target address.
* We need three dwords: event, wait, link. * We need at most 7 dwords in the return target: 2 cache flush +
* 2 semaphore stall + 1 event + 1 wait + 1 link.
*/ */
return_dwords = 3; return_dwords = 7;
return_target = etnaviv_buffer_reserve(gpu, buffer, return_dwords); return_target = etnaviv_buffer_reserve(gpu, buffer, return_dwords);
CMD_LINK(cmdbuf, return_dwords, return_target); CMD_LINK(cmdbuf, return_dwords, return_target);
/* /*
* Append event, wait and link pointing back to the wait * Append a cache flush, stall, event, wait and link pointing back to
* command to the ring buffer. * the wait command to the ring buffer.
*/ */
if (gpu->exec_state == ETNA_PIPE_2D) {
CMD_LOAD_STATE(buffer, VIVS_GL_FLUSH_CACHE,
VIVS_GL_FLUSH_CACHE_PE2D);
} else {
CMD_LOAD_STATE(buffer, VIVS_GL_FLUSH_CACHE,
VIVS_GL_FLUSH_CACHE_DEPTH |
VIVS_GL_FLUSH_CACHE_COLOR);
CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE,
VIVS_TS_FLUSH_CACHE_FLUSH);
}
CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
CMD_LOAD_STATE(buffer, VIVS_GL_EVENT, VIVS_GL_EVENT_EVENT_ID(event) | CMD_LOAD_STATE(buffer, VIVS_GL_EVENT, VIVS_GL_EVENT_EVENT_ID(event) |
VIVS_GL_EVENT_FROM_PE); VIVS_GL_EVENT_FROM_PE);
CMD_WAIT(buffer); CMD_WAIT(buffer);
CMD_LINK(buffer, 2, return_target + 8); CMD_LINK(buffer, 2, etnaviv_iommu_get_cmdbuf_va(gpu, buffer) +
buffer->user_size - 4);
if (drm_debug & DRM_UT_DRIVER) if (drm_debug & DRM_UT_DRIVER)
pr_info("stream link to 0x%08x @ 0x%08x %p\n", pr_info("stream link to 0x%08x @ 0x%08x %p\n",