diff --git a/drivers/video/tegra/host/nvdla/nvdla.h b/drivers/video/tegra/host/nvdla/nvdla.h index 697447be..11e014bd 100644 --- a/drivers/video/tegra/host/nvdla/nvdla.h +++ b/drivers/video/tegra/host/nvdla/nvdla.h @@ -265,12 +265,14 @@ struct nvdla_task { struct nvdev_fence prefences[MAX_NUM_NVDLA_PREFENCES]; struct nvdev_fence postfences[MAX_NUM_NVDLA_POSTFENCES]; struct nvdla_status_notify in_task_status[MAX_NUM_NVDLA_IN_TASK_STATUS]; - struct nvdla_status_notify out_task_status[MAX_NUM_NVDLA_OUT_TASK_STATUS]; + struct nvdla_status_notify sof_task_status[MAX_NUM_NVDLA_OUT_TASK_STATUS]; + struct nvdla_status_notify eof_task_status[MAX_NUM_NVDLA_OUT_TASK_STATUS]; struct nvdla_mem_handle memory_handles[NVDLA_MAX_BUFFERS_PER_TASK]; u8 num_prefences; u8 num_postfences; u8 num_in_task_status; - u8 num_out_task_status; + u8 num_sof_task_status; + u8 num_eof_task_status; u32 num_addresses; u32 fence; u32 fence_counter; @@ -286,7 +288,8 @@ struct nvdla_task { struct dma_buf *prefences_sem_dmabuf[MAX_NUM_NVDLA_PREFENCES]; struct dma_buf *in_task_status_dmabuf[MAX_NUM_NVDLA_IN_TASK_STATUS]; struct dma_buf *postfences_sem_dmabuf[MAX_NUM_NVDLA_POSTFENCES]; - struct dma_buf *out_task_status_dmabuf[MAX_NUM_NVDLA_OUT_TASK_STATUS]; + struct dma_buf *sof_task_status_dmabuf[MAX_NUM_NVDLA_OUT_TASK_STATUS]; + struct dma_buf *eof_task_status_dmabuf[MAX_NUM_NVDLA_OUT_TASK_STATUS]; }; struct dla_mem_addr { diff --git a/drivers/video/tegra/host/nvdla/nvdla_ioctl.c b/drivers/video/tegra/host/nvdla/nvdla_ioctl.c index 266a9d27..04652af4 100644 --- a/drivers/video/tegra/host/nvdla/nvdla_ioctl.c +++ b/drivers/video/tegra/host/nvdla/nvdla_ioctl.c @@ -376,13 +376,23 @@ static int nvdla_get_actions(struct nvdla_ioctl_submit_task *user_task, goto fail; } - /* get output task status */ - if (copy_from_user(task->out_task_status, - (void __user *)user_task->output_task_status, - (task->num_out_task_status * + /* get sof task status */ + if (copy_from_user(task->sof_task_status, + (void __user *)user_task->sof_task_status, + (task->num_sof_task_status * sizeof(struct nvdla_status_notify)))) { err = -EFAULT; - nvdla_dbg_err(pdev, "failed to copy output task status"); + nvdla_dbg_err(pdev, "failed to copy sof task status"); + goto fail; + } + + /* get eof task status */ + if (copy_from_user(task->eof_task_status, + (void __user *)user_task->eof_task_status, + (task->num_eof_task_status * + sizeof(struct nvdla_status_notify)))) { + err = -EFAULT; + nvdla_dbg_err(pdev, "failed to copy eof task status"); goto fail; } @@ -618,9 +628,15 @@ static int nvdla_val_task_submit_input(struct nvdla_ioctl_submit_task *in_task) MAX_NUM_NVDLA_IN_TASK_STATUS); return -EINVAL; } - if (in_task->num_output_task_status > MAX_NUM_NVDLA_OUT_TASK_STATUS) { - pr_err("out task status[%u] crossing expected[%d]\n", - in_task->num_output_task_status, + if (in_task->num_sof_task_status > MAX_NUM_NVDLA_OUT_TASK_STATUS) { + pr_err("sof task status[%u] crossing expected[%d]\n", + in_task->num_sof_task_status, + MAX_NUM_NVDLA_OUT_TASK_STATUS); + return -EINVAL; + } + if (in_task->num_eof_task_status > MAX_NUM_NVDLA_OUT_TASK_STATUS) { + pr_err("eof task status[%u] crossing expected[%d]\n", + in_task->num_eof_task_status, MAX_NUM_NVDLA_OUT_TASK_STATUS); return -EINVAL; } @@ -665,7 +681,8 @@ static int nvdla_fill_task(struct nvdla_queue *queue, task->num_prefences = local_task->num_prefences; task->num_postfences = local_task->num_postfences; task->num_in_task_status = local_task->num_input_task_status; - task->num_out_task_status = local_task->num_output_task_status; + task->num_sof_task_status = local_task->num_sof_task_status; + task->num_eof_task_status = local_task->num_eof_task_status; task->num_addresses = local_task->num_addresses; task->timeout = local_task->timeout; @@ -709,8 +726,11 @@ static void nvdla_dump_task(struct nvdla_task *task) nvdla_dbg_info(pdev, "dumping input task [%p] parameters:", task); nvdla_dbg_info(pdev, "num_prefences[%u] num_postfences[%u]", task->num_prefences, task->num_postfences); - nvdla_dbg_info(pdev, "num_in_status[%u] num_out_task_status[%u]", - task->num_in_task_status, task->num_out_task_status); + nvdla_dbg_info(pdev, "num_in_status[%u] num_sof_task_status[%u] " + "num_eof_task_status[%u]", + task->num_in_task_status, + task->num_sof_task_status, + task->num_eof_task_status); nvdla_dbg_info(pdev, "num_addresses[%u]", task->num_addresses); for (i = 0; i < task->num_prefences; i++) { @@ -747,12 +767,20 @@ static void nvdla_dump_task(struct nvdla_task *task) task->in_task_status[i].status); } - for (i = 0; i < task->num_out_task_status; i++) { - nvdla_dbg_info(pdev, "Output task status[%d]:" + for (i = 0; i < task->num_sof_task_status; i++) { + nvdla_dbg_info(pdev, "SOF task status[%d]:" "handle[%u] offset[%u] status[%u]", - i, task->out_task_status[i].handle, - task->out_task_status[i].offset, - task->out_task_status[i].status); + i, task->sof_task_status[i].handle, + task->sof_task_status[i].offset, + task->sof_task_status[i].status); + } + + for (i = 0; i < task->num_eof_task_status; i++) { + nvdla_dbg_info(pdev, "EOF task status[%d]:" + "handle[%u] offset[%u] status[%u]", + i, task->eof_task_status[i].handle, + task->eof_task_status[i].offset, + task->eof_task_status[i].status); } for (i = 0; i < task->num_addresses; i++) { diff --git a/drivers/video/tegra/host/nvdla/nvdla_queue.c b/drivers/video/tegra/host/nvdla/nvdla_queue.c index 7f8d48b7..0ce4e700 100644 --- a/drivers/video/tegra/host/nvdla/nvdla_queue.c +++ b/drivers/video/tegra/host/nvdla/nvdla_queue.c @@ -210,12 +210,20 @@ static int nvdla_unmap_task_memory(struct nvdla_task *task) } nvdla_dbg_fn(pdev, "all postfences unmaped"); - /* unpin input task status memory */ - for (ii = 0; ii < task->num_out_task_status; ii++) { - if (task->out_task_status[ii].handle) { + /* unpin output task status memory */ + for (ii = 0; ii < task->num_sof_task_status; ii++) { + if (task->sof_task_status[ii].handle) { nvdla_buffer_submit_unpin(task->buffers, - &task->out_task_status_dmabuf[ii], 1); - dma_buf_put(task->out_task_status_dmabuf[ii]); + &task->sof_task_status_dmabuf[ii], 1); + dma_buf_put(task->sof_task_status_dmabuf[ii]); + } + } + + for (ii = 0; ii < task->num_eof_task_status; ii++) { + if (task->eof_task_status[ii].handle) { + nvdla_buffer_submit_unpin(task->buffers, + &task->eof_task_status_dmabuf[ii], 1); + dma_buf_put(task->eof_task_status_dmabuf[ii]); } } nvdla_dbg_fn(pdev, "all out task status unmaped"); @@ -252,11 +260,12 @@ static void nvdla_task_syncpt_reset(struct nvhost_syncpt *syncpt, static inline int nvdla_get_max_preaction_size(void) { - return (((MAX_NUM_NVDLA_PREFENCES + MAX_NUM_NVDLA_IN_TASK_STATUS) * + return (((MAX_NUM_NVDLA_PREFENCES + MAX_NUM_NVDLA_IN_TASK_STATUS + + MAX_NUM_NVDLA_OUT_TASK_STATUS) * sizeof(struct dla_action_opcode)) + (MAX_NUM_NVDLA_PREFENCES * sizeof(struct dla_action_semaphore)) + - (MAX_NUM_NVDLA_IN_TASK_STATUS * + ((MAX_NUM_NVDLA_IN_TASK_STATUS + MAX_NUM_NVDLA_OUT_TASK_STATUS) * sizeof(struct dla_action_task_status)) + sizeof(struct dla_action_opcode)); } @@ -933,13 +942,15 @@ static int nvdla_fill_postactions(struct nvdla_task *task) task->task_desc_pa + nvdla_profile_status_offset(task), 0); /* fill output task status */ - for (i = 0; i < task->num_out_task_status; i++) { + for (i = 0; i < task->num_eof_task_status; i++) { err = nvdla_fill_taskstatus_write_action(task, - &task->out_task_status[i], - &task->out_task_status_dmabuf[i], + &task->eof_task_status[i], + &task->eof_task_status_dmabuf[i], &next); if (err < 0) { - nvdla_dbg_info(pdev, "failed to fill out task status[%u]", i); + nvdla_dbg_err(pdev, + "failed to fill eof taskstatus[%d]", + i); goto fail; } } @@ -1004,14 +1015,30 @@ static int nvdla_fill_preactions(struct nvdla_task *task) } } - /* fill input status after filling sem/synpt/gos */ + /* fill input status after filling sem/syncpt/gos */ for (i = 0; i < task->num_in_task_status; i++) { err = nvdla_fill_taskstatus_read_action(task, &task->in_task_status[i], &task->in_task_status_dmabuf[i], &next); if (err < 0) { - nvdla_dbg_info(pdev, "failed to fill in task status[%u]", i); + nvdla_dbg_err(pdev, + "failed to fill in taskstatus[%d]", + i); + goto fail; + } + } + + /* fill sof task status actions */ + for (i = 0; i < task->num_sof_task_status; i++) { + err = nvdla_fill_taskstatus_write_action(task, + &task->sof_task_status[i], + &task->sof_task_status_dmabuf[i], + &next); + if (err < 0) { + nvdla_dbg_err(pdev, + "failed to fill sof taskstatus[%d]", + i); goto fail; } } diff --git a/include/uapi/linux/nvhost_nvdla_ioctl.h b/include/uapi/linux/nvhost_nvdla_ioctl.h index 41652321..a3e750ac 100644 --- a/include/uapi/linux/nvhost_nvdla_ioctl.h +++ b/include/uapi/linux/nvhost_nvdla_ioctl.h @@ -125,13 +125,15 @@ struct nvdla_mem_handle { * @num_prefences number of pre-fences in task * @num_postfences number of post-fences in task * @num_input_task_status number of input task status - * @num_output_task_status number of output task status + * @num_sof_task_status number of sof task status + * @num_eof_task_status number of eof task status * @flags flags for bitwise task info embeddeing * @reserved reserved for future use * @prefences pointer to pre-fence struct table * @postfences pointer to post-fence struct table * @input_task_status pointer to input task status struct table - * @output_task_status pointer to output task status struct table + * @sof_task_status pointer to sof task status struct table + * @eof_task_status pointer to eof task status struct table * @num_addresses total number of addressed passed in structure * @address_list pointer to address list * @timeout task timeout @@ -141,17 +143,20 @@ struct nvdla_ioctl_submit_task { __u8 num_prefences; __u8 num_postfences; __u8 num_input_task_status; - __u8 num_output_task_status; + __u8 num_sof_task_status; + __u8 num_eof_task_status; + __u8 reserved0[3]; #define NVDLA_MAX_BUFFERS_PER_TASK (6144) __u32 num_addresses; __u16 flags; - __u16 reserved; + __u16 reserved1; __u64 prefences; __u64 postfences; __u64 input_task_status; - __u64 output_task_status; + __u64 sof_task_status; + __u64 eof_task_status; __u64 address_list; __u64 timeout; };