diff --git a/drivers/video/tegra/host/pva/pva_ioctl.c b/drivers/video/tegra/host/pva/pva_ioctl.c index a6947869..33c0eb25 100644 --- a/drivers/video/tegra/host/pva/pva_ioctl.c +++ b/drivers/video/tegra/host/pva/pva_ioctl.c @@ -319,7 +319,8 @@ out: * @return 0 on Success or negative error code * */ -static int pva_submit(struct pva_private *priv, void *arg) + +static int pva_submit(struct pva_private *priv, void *arg, bool is_ex) { struct nvpva_ioctl_submit_in_arg *ioctl_tasks_header = (struct nvpva_ioctl_submit_in_arg *)arg; @@ -419,6 +420,10 @@ static int pva_submit(struct pva_private *priv, void *arg) task->pva = priv->pva; task->queue = priv->queue; task->client = priv->client; + if (is_ex) + task->default_sem_update_method = false; + else + task->default_sem_update_method = true; /* setup ownership */ err = nvhost_module_busy(task->pva->pdev); @@ -953,7 +958,10 @@ static long pva_ioctl(struct file *file, unsigned int cmd, unsigned long arg) err = pva_unpin(priv, buf); break; case NVPVA_IOCTL_SUBMIT: - err = pva_submit(priv, buf); + err = pva_submit(priv, buf, false); + break; + case NVPVA_IOCTL_SUBMIT_EX: + err = pva_submit(priv, buf, true); break; case NVPVA_IOCTL_SET_VPU_PRINT_BUFFER_SIZE: err = pva_set_vpu_print_buffer_size(priv, buf); diff --git a/drivers/video/tegra/host/pva/pva_queue.c b/drivers/video/tegra/host/pva/pva_queue.c index 0502b5eb..047cfad8 100644 --- a/drivers/video/tegra/host/pva/pva_queue.c +++ b/drivers/video/tegra/host/pva/pva_queue.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2020-2023, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2020-2024, NVIDIA CORPORATION. All rights reserved. */ #include @@ -376,6 +376,7 @@ pva_task_process_fence_actions(struct pva_submit_task *task, } case NVPVA_FENCE_OBJ_SEM: { + u32 update_method; err = pva_task_pin_fence(task, &fence_action->fence, &fence_addr, @@ -383,10 +384,17 @@ pva_task_process_fence_actions(struct pva_submit_task *task, if (err) goto out; - task->sem_num += 1; - task->sem_thresh += 1; - fence_value = task->sem_thresh; - fence_action->fence.obj.sem.value = fence_value; + update_method = fence_action->fence.update_method; + if ((task->default_sem_update_method) + || (update_method == NVPVA_FENCE_OBJ_UPDATE_INC)) { + task->sem_num += 1; + task->sem_thresh += 1; + fence_value = task->sem_thresh; + fence_action->fence.obj.sem.value = fence_value; + } else { + fence_value = fence_action->fence.obj.sem.value; + } + task->fence_act_serial_ids[fence_type][i] = serial_id; break; } diff --git a/drivers/video/tegra/host/pva/pva_queue.h b/drivers/video/tegra/host/pva/pva_queue.h index a6d39a67..f2b611e5 100644 --- a/drivers/video/tegra/host/pva/pva_queue.h +++ b/drivers/video/tegra/host/pva/pva_queue.h @@ -194,6 +194,7 @@ struct pva_submit_task { u64 src_surf_base_addr; u64 dst_surf_base_addr; bool is_system_app; + bool default_sem_update_method; }; struct pva_submit_tasks { diff --git a/include/uapi/linux/nvpva_ioctl.h b/include/uapi/linux/nvpva_ioctl.h index d94dddf3..6f9c275c 100644 --- a/include/uapi/linux/nvpva_ioctl.h +++ b/include/uapi/linux/nvpva_ioctl.h @@ -234,6 +234,12 @@ enum nvpva_fence_obj_type { NVPVA_FENCE_OBJ_SYNC_FD = 3U, }; +enum nvpva_fence_obj_update_method { + NVPVA_FENCE_OBJ_UPDATE_INC = 0U, + NVPVA_FENCE_OBJ_UPDATE_SET = 1U, + NVPVA_FENCE_OBJ_UPDATE_INVALID = 2U, +}; + enum nvpva_symbol_config { NVPVA_SYMBOL_PARAM = 0U, NVPVA_SYMBOL_POINTER = 1U, @@ -284,7 +290,7 @@ union nvpva_fence_obj { struct nvpva_submit_fence { uint32_t type; - uint32_t reserved; + uint32_t update_method; union nvpva_fence_obj obj; }; @@ -596,7 +602,10 @@ union nvpva_set_vpu_print_buffer_size_args { #define NVPVA_IOCTL_PIN_EX \ _IOWR(NVPVA_IOCTL_MAGIC, 12, union nvpva_pin_args_ex) -#define NVPVA_IOCTL_NUMBER_MAX 12 +#define NVPVA_IOCTL_SUBMIT_EX \ + _IOW(NVPVA_IOCTL_MAGIC, 13, union nvpva_ioctl_submit_args) + +#define NVPVA_IOCTL_NUMBER_MAX 13 #ifndef MAX #define MAX(a, b) ((a) > (b) ? (a) : (b))