[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