Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6e138f76 authored by Russell King's avatar Russell King Committed by Lucas Stach
Browse files

drm: etnaviv: extract replacement of WAIT command



Extract out the replacement of the WAIT command with some other command.

Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: default avatarLucas Stach <l.stach@pengutronix.de>
parent 584a13c6
Loading
Loading
Loading
Loading
+23 −9
Original line number Diff line number Diff line
@@ -131,6 +131,23 @@ static void etnaviv_buffer_dump(struct etnaviv_gpu *gpu,
			ptr, len * 4, 0);
}

/*
 * Safely replace the WAIT of a waitlink with a new command and argument.
 * The GPU may be executing this WAIT while we're modifying it, so we have
 * to write it in a specific order to avoid the GPU branching to somewhere
 * else.  'wl_offset' is the offset to the first byte of the WAIT command.
 */
static void etnaviv_buffer_replace_wait(struct etnaviv_cmdbuf *buffer,
	unsigned int wl_offset, u32 cmd, u32 arg)
{
	u32 *lw = buffer->vaddr + wl_offset;

	lw[1] = arg;
	mb();
	lw[0] = cmd;
	mb();
}

/*
 * Ensure that there is space in the command buffer to contiguously write
 * 'cmd_dwords' 64-bit words into the buffer, wrapping if necessary.
@@ -172,7 +189,7 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, unsigned int event,
	struct etnaviv_cmdbuf *cmdbuf)
{
	struct etnaviv_cmdbuf *buffer = gpu->buffer;
	u32 *lw = buffer->vaddr + buffer->user_size - 16;
	unsigned int waitlink_offset = buffer->user_size - 16;
	u32 back, link_target, link_size, reserve_size, extra_size = 0;

	if (drm_debug & DRM_UT_DRIVER)
@@ -219,8 +236,7 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, unsigned int event,
		print_hex_dump(KERN_INFO, "cmd ", DUMP_PREFIX_OFFSET, 16, 4,
			       cmdbuf->vaddr, cmdbuf->size, 0);

		pr_info("link op: %p\n", lw);
		pr_info("link addr: %p\n", lw + 1);
		pr_info("link op: %p\n", buffer->vaddr + waitlink_offset);
		pr_info("addr: 0x%08x\n", link_target);
		pr_info("back: 0x%08x\n", gpu_va(gpu, buffer) + back);
		pr_info("event: %d\n", event);
@@ -262,12 +278,10 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, unsigned int event,
	CMD_WAIT(buffer);
	CMD_LINK(buffer, 2, gpu_va(gpu, buffer) + (buffer->user_size - 4));

	/* Change WAIT into a LINK command; write the address first. */
	*(lw + 1) = link_target;
	mb();
	*(lw) = VIV_FE_LINK_HEADER_OP_LINK |
		VIV_FE_LINK_HEADER_PREFETCH(link_size);
	mb();
	etnaviv_buffer_replace_wait(buffer, waitlink_offset,
				    VIV_FE_LINK_HEADER_OP_LINK |
				    VIV_FE_LINK_HEADER_PREFETCH(link_size),
				    link_target);

	if (drm_debug & DRM_UT_DRIVER)
		etnaviv_buffer_dump(gpu, buffer, 0, 0x50);