mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-23 17:55:05 +03:00
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 <srasal@nvidia.com> Reviewed-on: http://git-master/r/1267518 Reviewed-by: Prashant Gaikwad <pgaikwad@nvidia.com> GVS: Gerrit_Virtual_Submit
This commit is contained in:
committed by
Laxman Dewangan
parent
6b544422ad
commit
5a033517c3
@@ -51,6 +51,12 @@
|
|||||||
*/
|
*/
|
||||||
#define TRACE_BUFFER_SIZE 0x100000
|
#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
|
* data structure to keep per DLA engine device data
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -43,6 +43,18 @@
|
|||||||
#define NVDLA_QUEUE_ABORT_TIMEOUT 10000 /* 10 sec */
|
#define NVDLA_QUEUE_ABORT_TIMEOUT 10000 /* 10 sec */
|
||||||
#define NVDLA_QUEUE_ABORT_RETRY_PERIOD 500 /* 500 ms */
|
#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);
|
static DEFINE_DMA_ATTRS(attrs);
|
||||||
|
|
||||||
/* task management API's */
|
/* task management API's */
|
||||||
@@ -342,6 +354,138 @@ fail_to_alloc_handles:
|
|||||||
return err;
|
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 nvdla_task *nvdla_task_alloc(struct nvhost_queue *queue,
|
||||||
struct nvhost_buffers *buffers,
|
struct nvhost_buffers *buffers,
|
||||||
struct nvdla_ioctl_submit_task *user_task)
|
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;
|
struct platform_device *pdev = queue->pool->pdev;
|
||||||
u32 num_postfences = user_task->num_postfences;
|
u32 num_postfences = user_task->num_postfences;
|
||||||
u32 num_prefences = user_task->num_prefences;
|
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_task_descriptor *task_desc;
|
||||||
struct dla_action_list *postactionl;
|
|
||||||
struct dla_action_list *preactionl;
|
|
||||||
struct dla_action_opcode *opcode;
|
|
||||||
struct nvdla_task *task = NULL;
|
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;
|
dma_addr_t buffer_pa;
|
||||||
size_t task_size;
|
size_t task_size;
|
||||||
size_t buf_size;
|
size_t buf_size;
|
||||||
u32 *buffer_va;
|
u32 *buffer_va;
|
||||||
void *mem;
|
void *mem;
|
||||||
int err;
|
int err;
|
||||||
int i;
|
|
||||||
|
|
||||||
nvdla_dbg_fn(pdev, "");
|
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);
|
mem += num_prefences * sizeof(struct nvdla_fence);
|
||||||
task->postfences = mem;
|
task->postfences = mem;
|
||||||
|
|
||||||
/* update local fences into task*/
|
/* update local fences into task */
|
||||||
nvdla_get_fences(user_task, task);
|
nvdla_get_fences(user_task, task);
|
||||||
|
|
||||||
/* calculate size of task desc, actions and its list, buffers
|
buf_size = nvdla_get_task_desc_size();
|
||||||
* 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);
|
|
||||||
|
|
||||||
/* allocate task descriptor */
|
/* allocate task descriptor */
|
||||||
buffer_va = dma_alloc_attrs(&pdev->dev, buf_size, &buffer_pa,
|
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
|
* - postactions list HEAD followed after preaction list head offset
|
||||||
* - DLA has only one list of actions for each of pre and post
|
* - DLA has only one list of actions for each of pre and post
|
||||||
*/
|
*/
|
||||||
preactionl_of = sizeof(struct dla_task_descriptor);
|
task_desc->preactions = sizeof(struct dla_task_descriptor);
|
||||||
postactionl_of = preactionl_of + sizeof(struct dla_action_list);
|
task_desc->postactions = task_desc->preactions + sizeof(struct dla_action_list);
|
||||||
|
|
||||||
nvdla_dbg_info(pdev, "preaction meta offset[%d]", preactionl_of);
|
/* fill pre actions */
|
||||||
nvdla_dbg_info(pdev, "postaction meta offset[%d]", postactionl_of);
|
nvdla_fill_preactions(user_task, task);
|
||||||
|
|
||||||
/* ..and send those through descriptor */
|
/* fill post actions */
|
||||||
task_desc->preactions = preactionl_of;
|
nvdla_fill_postactions(user_task, task);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* ping user memory before submit to engine */
|
||||||
err = nvdla_map_task_memory(buffers, user_task, task, task_desc);
|
err = nvdla_map_task_memory(buffers, user_task, task, task_desc);
|
||||||
if (err)
|
if (err)
|
||||||
goto fail_to_dma_alloc;
|
goto fail_to_dma_alloc;
|
||||||
|
|||||||
Reference in New Issue
Block a user