From 5a033517c33785c4973dd06fdffc64f3e13a9f4c Mon Sep 17 00:00:00 2001 From: Shridhar Rasal Date: Thu, 8 Dec 2016 16:17:59 +0530 Subject: [PATCH] video: tegra: host: dla: rework task alloc - add new API to calculate task descriptor size - split task alloc and add new API for preaction and postaction filling. - reserve max possible memory for post and preactions Jira DLA-236 Change-Id: Ide5c4f909f093695f441622fb7709acbe2a25e87 Signed-off-by: Shridhar Rasal Reviewed-on: http://git-master/r/1267518 Reviewed-by: Prashant Gaikwad GVS: Gerrit_Virtual_Submit --- drivers/video/tegra/host/nvdla/nvdla.h | 6 + drivers/video/tegra/host/nvdla/nvdla_queue.c | 279 ++++++++++--------- 2 files changed, 159 insertions(+), 126 deletions(-) diff --git a/drivers/video/tegra/host/nvdla/nvdla.h b/drivers/video/tegra/host/nvdla/nvdla.h index 6480cc77..3300001c 100644 --- a/drivers/video/tegra/host/nvdla/nvdla.h +++ b/drivers/video/tegra/host/nvdla/nvdla.h @@ -51,6 +51,12 @@ */ #define TRACE_BUFFER_SIZE 0x100000 +/** + * Max number of fences supported + */ +#define MAX_NUM_NVDLA_PREFENCES 4 +#define MAX_NUM_NVDLA_POSTFENCES 4 + /** * data structure to keep per DLA engine device data * diff --git a/drivers/video/tegra/host/nvdla/nvdla_queue.c b/drivers/video/tegra/host/nvdla/nvdla_queue.c index 3fab8761..d85f2f90 100644 --- a/drivers/video/tegra/host/nvdla/nvdla_queue.c +++ b/drivers/video/tegra/host/nvdla/nvdla_queue.c @@ -43,6 +43,18 @@ #define NVDLA_QUEUE_ABORT_TIMEOUT 10000 /* 10 sec */ #define NVDLA_QUEUE_ABORT_RETRY_PERIOD 500 /* 500 ms */ +#define NVDLA_MAX_PREACTION_SIZE (MAX_NUM_NVDLA_PREFENCES * \ + sizeof(struct dla_action_opcode) + \ + MAX_NUM_NVDLA_PREFENCES * \ + sizeof(struct dla_action_semaphore) + \ + sizeof(struct dla_action_opcode)) + +#define NVDLA_MAX_POSTACTION_SIZE (MAX_NUM_NVDLA_POSTFENCES * \ + sizeof(struct dla_action_opcode) + \ + MAX_NUM_NVDLA_POSTFENCES * \ + sizeof(struct dla_action_semaphore) + \ + sizeof(struct dla_action_opcode)) + static DEFINE_DMA_ATTRS(attrs); /* task management API's */ @@ -342,6 +354,138 @@ fail_to_alloc_handles: return err; } +static size_t nvdla_get_task_desc_size(void) +{ + + size_t size = 0; + + /* calculate size of task desc, actions and its list, buffers + * this is max possible size for updating task desc and + * and allocated mem size can be more than required size + */ + size += sizeof(struct dla_task_descriptor); + size += (2 * MAX_NUM_ACTION_LIST * sizeof(struct dla_action_list)); + size += NVDLA_MAX_PREACTION_SIZE; + size += NVDLA_MAX_POSTACTION_SIZE; + + return size; + +} + +static int nvdla_fill_postactions(struct nvdla_ioctl_submit_task *user_task, + struct nvdla_task *task) +{ + struct dla_task_descriptor *task_desc = task->task_desc; + struct nvhost_queue *queue = task->queue; + struct platform_device *pdev = queue->pool->pdev; + struct dla_action_semaphore *postaction; + struct dla_action_list *postactionl; + struct dla_action_opcode *opcode; + uint16_t postactionlist_of; + void *mem; + int i; + + /* update postaction list offset */ + postactionlist_of = task_desc->postactions + + sizeof(struct dla_action_list) + NVDLA_MAX_PREACTION_SIZE; + + /* fill all postactions */ + for (i = 0; i < user_task->num_postfences; i++, postaction++) { + void *next = NULL; + + /* get next post action base */ + next = (char *)task_desc + postactionlist_of + + i * (sizeof(struct dla_action_opcode) + + sizeof(struct dla_action_semaphore)); + + /* get base opcode */ + opcode = (struct dla_action_opcode *)next; + + /* update end of list */ + if (i == user_task->num_postfences) { + opcode->value = POSTACTION_TERMINATE; + break; + } + + /* set action type */ + opcode->value = POSTACTION_SEM; + + /* get actual post action mem */ + postaction = (struct dla_action_semaphore *) + ((char *)opcode + sizeof(struct dla_action_opcode)); + + /* update action */ + postaction->address = nvhost_syncpt_address(pdev, queue->syncpt_id); + } + + mem = (char *)task_desc + task_desc->postactions; + postactionl = (struct dla_action_list *)mem; + postactionl->offset = postactionlist_of; + postactionl->size = i * (sizeof(struct dla_action_opcode) + + sizeof(struct dla_action_semaphore)) + + sizeof(struct dla_action_opcode); + + return 0; +} + +static int nvdla_fill_preactions(struct nvdla_ioctl_submit_task *user_task, + struct nvdla_task *task) +{ + struct dla_task_descriptor *task_desc = task->task_desc; + struct nvhost_queue *queue = task->queue; + struct platform_device *pdev = queue->pool->pdev; + struct dla_action_semaphore *preaction; + struct dla_action_list *preactionl; + struct dla_action_opcode *opcode; + uint16_t preactionlist_of; + void *mem; + int i; + + /* preaction list offset update */ + preactionlist_of = task_desc->postactions + sizeof(struct dla_action_list); + + /* fill all preactions */ + for (i = 0; i <= user_task->num_prefences; i++) { + void *next = NULL; + + /* get next preaction base */ + next = (char *)task_desc + preactionlist_of + + i * (sizeof(struct dla_action_opcode) + + sizeof(struct dla_action_semaphore)); + + /* get base opcode */ + opcode = (struct dla_action_opcode *)next; + + /* update end of action list */ + if (i == user_task->num_prefences) { + opcode->value = PREACTION_TERMINATE; + break; + } + + /* set action type */ + opcode->value = PREACTION_SEM_GE; + + /* get actual preaction address */ + preaction = (struct dla_action_semaphore *) + ((char *)opcode + sizeof(struct dla_action_opcode)); + + /* update action */ + preaction->address = nvhost_syncpt_address(pdev, + task->prefences[i].syncpoint_index); + preaction->value = task->prefences[i].syncpoint_value; + } + + /* actually update lists data */ + mem = (char *)task_desc + task_desc->preactions; + preactionl = (struct dla_action_list *)mem; + preactionl->offset = preactionlist_of; + preactionl->size = i * (sizeof(struct dla_action_opcode) + + sizeof(struct dla_action_semaphore)) + + sizeof(struct dla_action_opcode); + + return 0; +} + struct nvdla_task *nvdla_task_alloc(struct nvhost_queue *queue, struct nvhost_buffers *buffers, struct nvdla_ioctl_submit_task *user_task) @@ -349,26 +493,14 @@ struct nvdla_task *nvdla_task_alloc(struct nvhost_queue *queue, struct platform_device *pdev = queue->pool->pdev; u32 num_postfences = user_task->num_postfences; u32 num_prefences = user_task->num_prefences; - struct dla_action_semaphore *postaction; - struct dla_action_semaphore *preaction; struct dla_task_descriptor *task_desc; - struct dla_action_list *postactionl; - struct dla_action_list *preactionl; - struct dla_action_opcode *opcode; struct nvdla_task *task = NULL; - uint16_t postactionlist_of; - size_t postactionlist_size; - uint16_t preactionlist_of; - size_t preactionlist_size; - uint16_t postactionl_of; - uint16_t preactionl_of; dma_addr_t buffer_pa; size_t task_size; size_t buf_size; u32 *buffer_va; void *mem; int err; - int i; nvdla_dbg_fn(pdev, ""); @@ -396,35 +528,10 @@ struct nvdla_task *nvdla_task_alloc(struct nvhost_queue *queue, mem += num_prefences * sizeof(struct nvdla_fence); task->postfences = mem; - /* update local fences into task*/ + /* update local fences into task */ nvdla_get_fences(user_task, task); - /* calculate size of task desc, actions and its list, buffers - * this is max possible size for updating task desc and - * and allocated mem size can be more than required size - */ - preactionlist_size = - num_prefences * sizeof(struct dla_action_opcode) + - num_prefences * sizeof(struct dla_action_semaphore) + - sizeof(struct dla_action_opcode); - - postactionlist_size = - num_postfences * sizeof(struct dla_action_opcode) + - num_postfences * sizeof(struct dla_action_semaphore) + - sizeof(struct dla_action_opcode); - - buf_size = sizeof(struct dla_task_descriptor) + - (2 * MAX_NUM_ACTION_LIST * sizeof(struct dla_action_list)) + - preactionlist_size + - postactionlist_size; - - nvdla_dbg_info(pdev, "num of prefences[%d] num of postfences[%d]", - num_prefences, num_postfences); - nvdla_dbg_info(pdev, "preaction list size[%zu]", - preactionlist_size); - nvdla_dbg_info(pdev, "postaction list size[%zu]", - postactionlist_size); - nvdla_dbg_info(pdev, "Total task desc size[%zu]", buf_size); + buf_size = nvdla_get_task_desc_size(); /* allocate task descriptor */ buffer_va = dma_alloc_attrs(&pdev->dev, buf_size, &buffer_pa, @@ -468,96 +575,16 @@ struct nvdla_task *nvdla_task_alloc(struct nvhost_queue *queue, * - postactions list HEAD followed after preaction list head offset * - DLA has only one list of actions for each of pre and post */ - preactionl_of = sizeof(struct dla_task_descriptor); - postactionl_of = preactionl_of + sizeof(struct dla_action_list); + task_desc->preactions = sizeof(struct dla_task_descriptor); + task_desc->postactions = task_desc->preactions + sizeof(struct dla_action_list); - nvdla_dbg_info(pdev, "preaction meta offset[%d]", preactionl_of); - nvdla_dbg_info(pdev, "postaction meta offset[%d]", postactionl_of); + /* fill pre actions */ + nvdla_fill_preactions(user_task, task); - /* ..and send those through descriptor */ - task_desc->preactions = preactionl_of; - task_desc->postactions = postactionl_of; - - /* actual preaction list offset update */ - preactionlist_of = postactionl_of + sizeof(struct dla_action_list); - - /* actual postaction list offset update */ - postactionlist_of = preactionlist_of + preactionlist_size; - - nvdla_dbg_info(pdev, "preaction list offset[%d]", preactionlist_of); - nvdla_dbg_info(pdev, "postaction list offset[%d]", postactionlist_of); - - /* actually update lists data */ - mem = (char *)task_desc + preactionl_of; - preactionl = (struct dla_action_list *)mem; - preactionl->offset = preactionlist_of; - preactionl->size = preactionlist_size; - - mem = (char *)task_desc + postactionl_of; - postactionl = (struct dla_action_list *)mem; - postactionl->offset = postactionlist_of; - postactionl->size = postactionlist_size; - - /* fill all preactions */ - for (i = 0; i <= user_task->num_prefences; i++) { - void *next = NULL; - - /* get next preaction base */ - next = (char *)task_desc + preactionlist_of + - i * (sizeof(struct dla_action_opcode) + - sizeof(struct dla_action_semaphore)); - - /* get base opcode */ - opcode = (struct dla_action_opcode *)next; - - /* update end of action list */ - if (i == user_task->num_prefences) { - opcode->value = PREACTION_TERMINATE; - break; - } - - /* set action type */ - opcode->value = PREACTION_SEM_GE; - - /* get actual preaction address */ - preaction = (struct dla_action_semaphore *) - ((char *)opcode + sizeof(struct dla_action_opcode)); - - /* update action */ - preaction->address = nvhost_syncpt_address(pdev, - task->prefences[i].syncpoint_index); - preaction->value = task->prefences[i].syncpoint_value; - } - - /* fill all postactions */ - for (i = 0; i < user_task->num_postfences; i++, postaction++) { - void *next = NULL; - - /* get next post action base */ - next = (char *)task_desc + postactionlist_of + - i * (sizeof(struct dla_action_opcode) + - sizeof(struct dla_action_semaphore)); - - /* get base opcode */ - opcode = (struct dla_action_opcode *)next; - - /* update end of list */ - if (i == user_task->num_postfences) { - opcode->value = POSTACTION_TERMINATE; - break; - } - - /* set action type */ - opcode->value = POSTACTION_SEM; - - /* get actual post action mem */ - postaction = (struct dla_action_semaphore *) - ((char *)opcode + sizeof(struct dla_action_opcode)); - - /* update action */ - postaction->address = nvhost_syncpt_address(pdev, queue->syncpt_id); - } + /* fill post actions */ + nvdla_fill_postactions(user_task, task); + /* ping user memory before submit to engine */ err = nvdla_map_task_memory(buffers, user_task, task, task_desc); if (err) goto fail_to_dma_alloc;