[PATCH 47/48] staging: etnaviv: don't use GEM buffer for internal ring buffer

Lucas Stach l.stach at pengutronix.de
Fri Sep 25 04:57:59 PDT 2015


Instead of using a GEM buffer for the kernel internal ring buffer
use the newly introduced cmdbuf object. This removes the last remaining
user of the CMDSTREAM GEM flag.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 drivers/staging/etnaviv/etnaviv_buffer.c | 90 ++++++++++++++------------------
 drivers/staging/etnaviv/etnaviv_drv.c    |  8 +--
 drivers/staging/etnaviv/etnaviv_gpu.c    | 13 +++--
 drivers/staging/etnaviv/etnaviv_gpu.h    |  4 +-
 4 files changed, 53 insertions(+), 62 deletions(-)

diff --git a/drivers/staging/etnaviv/etnaviv_buffer.c b/drivers/staging/etnaviv/etnaviv_buffer.c
index 76c646076b05..586f84316f1a 100644
--- a/drivers/staging/etnaviv/etnaviv_buffer.c
+++ b/drivers/staging/etnaviv/etnaviv_buffer.c
@@ -28,21 +28,22 @@
  */
 
 
-static inline void OUT(struct etnaviv_gem_object *buffer, u32 data)
+static inline void OUT(struct etnaviv_cmdbuf *buffer, u32 data)
 {
 	u32 *vaddr = (u32 *)buffer->vaddr;
 
-	BUG_ON(buffer->offset >= buffer->base.size / sizeof(*vaddr));
+	BUG_ON(buffer->user_size >= buffer->size);
 
-	vaddr[buffer->offset++] = data;
+	vaddr[buffer->user_size / 4] = data;
+	buffer->user_size += 4;
 }
 
-static inline void CMD_LOAD_STATE(struct etnaviv_gem_object *buffer,
+static inline void CMD_LOAD_STATE(struct etnaviv_cmdbuf *buffer,
 	u32 reg, u32 value)
 {
 	u32 index = reg >> VIV_FE_LOAD_STATE_HEADER_OFFSET__SHR;
 
-	buffer->offset = ALIGN(buffer->offset, 2);
+	buffer->user_size = ALIGN(buffer->user_size, 8);
 
 	/* write a register via cmd stream */
 	OUT(buffer, VIV_FE_LOAD_STATE_HEADER_OP_LOAD_STATE |
@@ -51,40 +52,40 @@ static inline void CMD_LOAD_STATE(struct etnaviv_gem_object *buffer,
 	OUT(buffer, value);
 }
 
-static inline void CMD_END(struct etnaviv_gem_object *buffer)
+static inline void CMD_END(struct etnaviv_cmdbuf *buffer)
 {
-	buffer->offset = ALIGN(buffer->offset, 2);
+	buffer->user_size = ALIGN(buffer->user_size, 8);
 
 	OUT(buffer, VIV_FE_END_HEADER_OP_END);
 }
 
-static inline void CMD_WAIT(struct etnaviv_gem_object *buffer)
+static inline void CMD_WAIT(struct etnaviv_cmdbuf *buffer)
 {
-	buffer->offset = ALIGN(buffer->offset, 2);
+	buffer->user_size = ALIGN(buffer->user_size, 8);
 
 	OUT(buffer, VIV_FE_WAIT_HEADER_OP_WAIT | 200);
 }
 
-static inline void CMD_LINK(struct etnaviv_gem_object *buffer,
+static inline void CMD_LINK(struct etnaviv_cmdbuf *buffer,
 	u16 prefetch, u32 address)
 {
-	buffer->offset = ALIGN(buffer->offset, 2);
+	buffer->user_size = ALIGN(buffer->user_size, 8);
 
 	OUT(buffer, VIV_FE_LINK_HEADER_OP_LINK |
 		    VIV_FE_LINK_HEADER_PREFETCH(prefetch));
 	OUT(buffer, address);
 }
 
-static inline void CMD_STALL(struct etnaviv_gem_object *buffer,
+static inline void CMD_STALL(struct etnaviv_cmdbuf *buffer,
 	u32 from, u32 to)
 {
-	buffer->offset = ALIGN(buffer->offset, 2);
+	buffer->user_size = ALIGN(buffer->user_size, 8);
 
 	OUT(buffer, VIV_FE_STALL_HEADER_OP_STALL);
 	OUT(buffer, VIV_FE_STALL_TOKEN_FROM(from) | VIV_FE_STALL_TOKEN_TO(to));
 }
 
-static void etnaviv_cmd_select_pipe(struct etnaviv_gem_object *buffer, u8 pipe)
+static void etnaviv_cmd_select_pipe(struct etnaviv_cmdbuf *buffer, u8 pipe)
 {
 	u32 flush;
 	u32 stall;
@@ -106,24 +107,19 @@ static void etnaviv_cmd_select_pipe(struct etnaviv_gem_object *buffer, u8 pipe)
 		       VIVS_GL_PIPE_SELECT_PIPE(pipe));
 }
 
-static u32 gpu_va(struct etnaviv_gpu *gpu, struct etnaviv_gem_object *obj)
+static u32 gpu_va(struct etnaviv_gpu *gpu, struct etnaviv_cmdbuf *buf)
 {
-	return obj->paddr - gpu->memory_base;
-}
-
-static u32 gpu_va_raw(struct etnaviv_gpu *gpu, u32 paddr)
-{
-	return paddr - gpu->memory_base;
+	return buf->paddr - gpu->memory_base;
 }
 
 static void etnaviv_buffer_dump(struct etnaviv_gpu *gpu,
-	struct etnaviv_gem_object *obj, u32 off, u32 len)
+	struct etnaviv_cmdbuf *buf, u32 off, u32 len)
 {
-	u32 size = obj->base.size;
-	u32 *ptr = obj->vaddr + off;
+	u32 size = buf->size;
+	u32 *ptr = buf->vaddr + off;
 
 	dev_info(gpu->dev, "virt %p phys 0x%08x free 0x%08x\n",
-			ptr, gpu_va(gpu, obj) + off, size - len * 4 - off);
+			ptr, gpu_va(gpu, buf) + off, size - len * 4 - off);
 
 	print_hex_dump(KERN_INFO, "cmd ", DUMP_PREFIX_OFFSET, 16, 4,
 			ptr, len * 4, 0);
@@ -131,24 +127,23 @@ static void etnaviv_buffer_dump(struct etnaviv_gpu *gpu,
 
 u16 etnaviv_buffer_init(struct etnaviv_gpu *gpu)
 {
-	struct etnaviv_gem_object *buffer = to_etnaviv_bo(gpu->buffer);
+	struct etnaviv_cmdbuf *buffer = gpu->buffer;
 
 	/* initialize buffer */
-	buffer->offset = 0;
-	buffer->is_ring_buffer = true;
+	buffer->user_size = 0;
 
 	CMD_WAIT(buffer);
-	CMD_LINK(buffer, 2, gpu_va(gpu, buffer) + ((buffer->offset - 1) * 4));
+	CMD_LINK(buffer, 2, gpu_va(gpu, buffer) + buffer->user_size - 4);
 
-	return buffer->offset / 2;
+	return buffer->user_size / 8;
 }
 
 void etnaviv_buffer_end(struct etnaviv_gpu *gpu)
 {
-	struct etnaviv_gem_object *buffer = to_etnaviv_bo(gpu->buffer);
+	struct etnaviv_cmdbuf *buffer = gpu->buffer;
 
 	/* Replace the last WAIT with an END */
-	buffer->offset -= 4;
+	buffer->user_size -= 16;
 
 	CMD_END(buffer);
 	mb();
@@ -157,9 +152,8 @@ void etnaviv_buffer_end(struct etnaviv_gpu *gpu)
 void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, unsigned int event,
 	struct etnaviv_gem_submit *submit)
 {
-	struct etnaviv_gem_object *buffer = to_etnaviv_bo(gpu->buffer);
-	u32 *lw = buffer->vaddr + ((buffer->offset - 4) * 4);
-	u32 *usercmd = submit->cmdbuf->vaddr;
+	struct etnaviv_cmdbuf *buffer = gpu->buffer;
+	u32 *lw = buffer->vaddr + buffer->user_size - 16;
 	u32 back, link_target, link_size, reserve_size, extra_size = 0;
 
 	if (drm_debug & DRM_UT_DRIVER)
@@ -181,18 +175,17 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, unsigned int event,
 			extra_size += 8;
 	}
 
-	reserve_size = 6 + extra_size;
+	reserve_size = (6 + extra_size) * 4;
 
 	/*
 	 * if we are going to completely overflow the buffer, we need to wrap.
 	 */
-	if (buffer->offset + reserve_size >
-	    buffer->base.size / sizeof(u32))
-		buffer->offset = 0;
+	if (buffer->user_size + reserve_size > buffer->size)
+		buffer->user_size = 0;
 
 	/* save offset back into main buffer */
-	back = buffer->offset + reserve_size - 6;
-	link_target = gpu_va(gpu, buffer) + buffer->offset * 4;
+	back = buffer->user_size + reserve_size - 6 * 4;
+	link_target = gpu_va(gpu, buffer) + buffer->user_size;
 	link_size = 6;
 
 	/* Skip over any extra instructions */
@@ -200,15 +193,13 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, unsigned int event,
 
 	if (drm_debug & DRM_UT_DRIVER)
 		pr_info("stream link to 0x%08x @ 0x%08x %p\n",
-			link_target, gpu_va_raw(gpu, submit->cmdbuf->paddr),
+			link_target, gpu_va(gpu, submit->cmdbuf),
 			submit->cmdbuf->vaddr);
 
 	/* jump back from cmd to main buffer */
-	usercmd[submit->cmdbuf->user_size/4] = VIV_FE_LINK_HEADER_OP_LINK |
-				    VIV_FE_LINK_HEADER_PREFETCH(link_size);
-	usercmd[submit->cmdbuf->user_size/4 + 1] = link_target;
+	CMD_LINK(submit->cmdbuf, link_size, link_target);
 
-	link_target = gpu_va_raw(gpu, submit->cmdbuf->paddr);
+	link_target = gpu_va(gpu, submit->cmdbuf);
 	link_size = submit->cmdbuf->size / 8;
 
 
@@ -220,13 +211,12 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, unsigned int event,
 		pr_info("link op: %p\n", lw);
 		pr_info("link addr: %p\n", lw + 1);
 		pr_info("addr: 0x%08x\n", link_target);
-		pr_info("back: 0x%08x\n", gpu_va(gpu, buffer) + (back * 4));
+		pr_info("back: 0x%08x\n", gpu_va(gpu, buffer) + back);
 		pr_info("event: %d\n", event);
 	}
 
 	if (gpu->mmu->need_flush || gpu->switch_context) {
-		u32 new_target = gpu_va(gpu, buffer) + buffer->offset *
-					sizeof(u32);
+		u32 new_target = gpu_va(gpu, buffer) + buffer->user_size;
 
 		if (gpu->mmu->need_flush) {
 			/* Add the MMU flush */
@@ -267,7 +257,7 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, unsigned int event,
 
 	/* append WAIT/LINK to main buffer */
 	CMD_WAIT(buffer);
-	CMD_LINK(buffer, 2, gpu_va(gpu, buffer) + ((buffer->offset - 1) * 4));
+	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;
diff --git a/drivers/staging/etnaviv/etnaviv_drv.c b/drivers/staging/etnaviv/etnaviv_drv.c
index d55d2c9f4d0f..30f6e5d0c91d 100644
--- a/drivers/staging/etnaviv/etnaviv_drv.c
+++ b/drivers/staging/etnaviv/etnaviv_drv.c
@@ -237,13 +237,13 @@ static int etnaviv_mmu_show(struct drm_device *dev, struct seq_file *m)
 
 static void etnaviv_buffer_dump(struct etnaviv_gpu *gpu, struct seq_file *m)
 {
-	struct etnaviv_gem_object *obj = to_etnaviv_bo(gpu->buffer);
-	u32 size = obj->base.size;
-	u32 *ptr = obj->vaddr;
+	struct etnaviv_cmdbuf *buf = gpu->buffer;
+	u32 size = buf->size;
+	u32 *ptr = buf->vaddr;
 	u32 i;
 
 	seq_printf(m, "virt %p - phys 0x%llx - free 0x%08x\n",
-			obj->vaddr, (u64)obj->paddr, size - (obj->offset * 4));
+			buf->vaddr, (u64)buf->paddr, size - buf->user_size);
 
 	for (i = 0; i < size / 4; i++) {
 		if (i && !(i % 4))
diff --git a/drivers/staging/etnaviv/etnaviv_gpu.c b/drivers/staging/etnaviv/etnaviv_gpu.c
index f8b507406e41..e12fe3508db2 100644
--- a/drivers/staging/etnaviv/etnaviv_gpu.c
+++ b/drivers/staging/etnaviv/etnaviv_gpu.c
@@ -430,7 +430,7 @@ static void etnaviv_gpu_hw_init(struct etnaviv_gpu *gpu)
 
 	gpu_write(gpu, VIVS_HI_INTR_ENBL, ~0U);
 	gpu_write(gpu, VIVS_FE_COMMAND_ADDRESS,
-		  etnaviv_gem_paddr_locked(gpu->buffer) - gpu->memory_base);
+		  gpu->buffer->paddr - gpu->memory_base);
 	gpu_write(gpu, VIVS_FE_COMMAND_CONTROL,
 		  VIVS_FE_COMMAND_CONTROL_ENABLE |
 		  VIVS_FE_COMMAND_CONTROL_PREFETCH(prefetch));
@@ -488,11 +488,10 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
 	}
 
 	/* Create buffer: */
-	gpu->buffer = etnaviv_gem_new(gpu->drm, PAGE_SIZE, ETNA_BO_CMDSTREAM);
-	if (IS_ERR(gpu->buffer)) {
-		ret = PTR_ERR(gpu->buffer);
-		gpu->buffer = NULL;
-		dev_err(gpu->dev, "could not create buffer: %d\n", ret);
+	gpu->buffer = etnaviv_gpu_cmdbuf_new(gpu, PAGE_SIZE);
+	if (!gpu->buffer) {
+		ret = -ENOMEM;
+		dev_err(gpu->dev, "could not create command buffer\n");
 		goto fail;
 	}
 
@@ -1295,7 +1294,7 @@ static void etnaviv_gpu_unbind(struct device *dev, struct device *master,
 #endif
 
 	if (gpu->buffer) {
-		drm_gem_object_unreference_unlocked(gpu->buffer);
+		etnaviv_gpu_cmdbuf_free(gpu->buffer);
 		gpu->buffer = NULL;
 	}
 
diff --git a/drivers/staging/etnaviv/etnaviv_gpu.h b/drivers/staging/etnaviv/etnaviv_gpu.h
index ee1c8504e4c8..3be5b481d8d1 100644
--- a/drivers/staging/etnaviv/etnaviv_gpu.h
+++ b/drivers/staging/etnaviv/etnaviv_gpu.h
@@ -82,6 +82,8 @@ struct etnaviv_event {
 	u32 fence;
 };
 
+struct etnaviv_cmdbuf;
+
 struct etnaviv_gpu {
 	struct drm_device *drm;
 	struct device *dev;
@@ -90,7 +92,7 @@ struct etnaviv_gpu {
 	bool switch_context;
 
 	/* 'ring'-buffer: */
-	struct drm_gem_object *buffer;
+	struct etnaviv_cmdbuf *buffer;
 
 	/* bus base address of memory  */
 	u32 memory_base;
-- 
2.5.1



More information about the dri-devel mailing list