diff --git a/drivers/video/tegra/host/nvdla/dla_queue.c b/drivers/video/tegra/host/nvdla/dla_queue.c
new file mode 100644
index 00000000..69f10680
--- /dev/null
+++ b/drivers/video/tegra/host/nvdla/dla_queue.c
@@ -0,0 +1,601 @@
+/*
+ * NVDLA queue management
+ *
+ * Copyright (c) 2019, NVIDIA Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include "nvhost_vm.h"
+#include "nvhost_channel.h"
+#include "nvhost_job.h"
+#include "dla_queue.h"
+#include "dev.h"
+
+#define CMDBUF_SIZE 4096
+
+/**
+ * @brief Describe a task pool struct
+ *
+ * Array of fixed task memory is allocated during queue_alloc call.
+ * The memory will be shared for various task based on availability
+ *
+ * dma_addr Physical address of task memory pool
+ * va Virtual address of the task memory pool
+ * kmem_addr Kernel memory for task struct
+ * lock Mutex lock for the array access.
+ * alloc_table Keep track of the index being assigned
+ * and freed for a task
+ * max_task_cnt Maximum task count that can be supported.
+ *
+ */
+
+struct nvdla_queue_task_pool {
+ dma_addr_t dma_addr;
+ void *va;
+ void *kmem_addr;
+ struct mutex lock;
+
+ unsigned long alloc_table;
+ unsigned long max_task_cnt;
+};
+
+static int nvdla_queue_task_pool_alloc(struct platform_device *pdev,
+ struct nvdla_queue *queue,
+ unsigned int num_tasks)
+{
+ int err = 0;
+ struct nvdla_queue_task_pool *task_pool;
+
+ task_pool = queue->task_pool;
+
+ /* Allocate the kernel memory needed for the task */
+ if (queue->task_kmem_size) {
+ task_pool->kmem_addr = kcalloc(num_tasks,
+ queue->task_kmem_size, GFP_KERNEL);
+ if (!task_pool->kmem_addr) {
+ nvhost_err(&pdev->dev,
+ "failed to allocate task_pool->kmem_addr");
+ err = -ENOMEM;
+ goto err_alloc_task_kmem;
+ }
+ }
+
+ /* Allocate memory for the task itself */
+ task_pool->va = dma_alloc_attrs(&pdev->dev,
+ queue->task_dma_size * num_tasks,
+ &task_pool->dma_addr, GFP_KERNEL,
+ 0);
+
+ if (task_pool->va == NULL) {
+ nvhost_err(&pdev->dev, "failed to allocate task_pool->va");
+ err = -ENOMEM;
+ goto err_alloc_task_pool;
+ }
+ task_pool->max_task_cnt = num_tasks;
+
+ mutex_init(&task_pool->lock);
+
+ return err;
+
+err_alloc_task_pool:
+ kfree(task_pool->kmem_addr);
+err_alloc_task_kmem:
+ return err;
+}
+
+static void nvdla_queue_task_free_pool(struct platform_device *pdev,
+ struct nvdla_queue *queue)
+{
+ struct nvdla_queue_task_pool *task_pool =
+ (struct nvdla_queue_task_pool *)queue->task_pool;
+
+ dma_free_attrs(&queue->vm_pdev->dev,
+ queue->task_dma_size * task_pool->max_task_cnt,
+ task_pool->va, task_pool->dma_addr,
+ 0);
+
+ kfree(task_pool->kmem_addr);
+ task_pool->max_task_cnt = 0;
+ task_pool->alloc_table = 0;
+}
+
+static int nvdla_queue_dump(struct nvdla_queue_pool *pool,
+ struct nvdla_queue *queue,
+ struct seq_file *s)
+{
+ if (pool->ops && pool->ops->dump)
+ pool->ops->dump(queue, s);
+
+ return 0;
+}
+
+static int queue_dump(struct seq_file *s, void *data)
+{
+ struct nvdla_queue_pool *pool = s->private;
+ unsigned long queue_id;
+
+ mutex_lock(&pool->queue_lock);
+ for_each_set_bit(queue_id, &pool->alloc_table,
+ pool->max_queue_cnt)
+ nvdla_queue_dump(pool, &pool->queues[queue_id], s);
+ mutex_unlock(&pool->queue_lock);
+ return 0;
+}
+
+static int queue_expose_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, queue_dump, inode->i_private);
+}
+
+static const struct file_operations queue_expose_operations = {
+ .open = queue_expose_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+struct nvdla_queue_pool *nvdla_queue_init(struct platform_device *pdev,
+ struct nvdla_queue_ops *ops,
+ unsigned int num_queues)
+{
+ struct nvhost_device_data *pdata;
+ struct nvdla_queue_pool *pool;
+ struct nvdla_queue *queues;
+ struct nvdla_queue *queue;
+ struct nvdla_queue_task_pool *task_pool;
+ unsigned int i;
+ int err;
+
+ pool = kzalloc(sizeof(struct nvdla_queue_pool), GFP_KERNEL);
+ if (pool == NULL) {
+ nvhost_err(&pdev->dev, "failed to allocate queue pool");
+ err = -ENOMEM;
+ goto fail_alloc_pool;
+ }
+
+ queues = kcalloc(num_queues, sizeof(struct nvdla_queue), GFP_KERNEL);
+ if (queues == NULL) {
+ nvhost_err(&pdev->dev, "failed to allocate queues");
+ err = -ENOMEM;
+ goto fail_alloc_queues;
+ }
+
+ task_pool = kcalloc(num_queues,
+ sizeof(struct nvdla_queue_task_pool), GFP_KERNEL);
+ if (task_pool == NULL) {
+ nvhost_err(&pdev->dev, "failed to allocate task_pool");
+ err = -ENOMEM;
+ goto fail_alloc_task_pool;
+ }
+
+ pdata = platform_get_drvdata(pdev);
+
+ /* initialize pool and queues */
+ pool->pdev = pdev;
+ pool->ops = ops;
+ pool->queues = queues;
+ pool->alloc_table = 0;
+ pool->max_queue_cnt = num_queues;
+ pool->queue_task_pool = task_pool;
+ mutex_init(&pool->queue_lock);
+
+ debugfs_create_file("queues", S_IRUGO,
+ pdata->debugfs, pool,
+ &queue_expose_operations);
+
+
+ for (i = 0; i < num_queues; i++) {
+ queue = &queues[i];
+ queue->id = i;
+ queue->pool = pool;
+ queue->task_pool = (void *)&task_pool[i];
+ nvdla_queue_get_task_size(queue);
+ }
+
+ return pool;
+
+fail_alloc_task_pool:
+ kfree(pool->queues);
+fail_alloc_queues:
+ kfree(pool);
+fail_alloc_pool:
+ return ERR_PTR(err);
+}
+
+void nvdla_queue_deinit(struct nvdla_queue_pool *pool)
+{
+ if (!pool)
+ return;
+
+ kfree(pool->queue_task_pool);
+ kfree(pool->queues);
+ kfree(pool);
+ pool = NULL;
+}
+
+void nvdla_queue_abort_all(struct nvdla_queue_pool *pool)
+{
+ u32 id;
+
+ mutex_lock(&pool->queue_lock);
+ for_each_set_bit(id, &pool->alloc_table, pool->max_queue_cnt)
+ nvdla_queue_abort(&pool->queues[id]);
+ mutex_unlock(&pool->queue_lock);
+}
+
+static void nvdla_queue_release(struct kref *ref)
+{
+ struct nvdla_queue *queue = container_of(ref, struct nvdla_queue,
+ kref);
+ struct nvdla_queue_pool *pool = queue->pool;
+
+ nvhost_dbg_fn("");
+
+ if (queue->use_channel)
+ nvhost_putchannel(queue->channel, 1);
+
+ /* release allocated resources */
+ nvhost_syncpt_put_ref_ext(pool->pdev, queue->syncpt_id);
+
+ /* free the task_pool */
+ if (queue->task_dma_size)
+ nvdla_queue_task_free_pool(pool->pdev, queue);
+
+ /* ..and mark the queue free */
+ mutex_lock(&pool->queue_lock);
+ clear_bit(queue->id, &pool->alloc_table);
+ mutex_unlock(&pool->queue_lock);
+}
+
+void nvdla_queue_put(struct nvdla_queue *queue)
+{
+ nvhost_dbg_fn("");
+ kref_put(&queue->kref, nvdla_queue_release);
+}
+
+void nvdla_queue_get(struct nvdla_queue *queue)
+{
+ nvhost_dbg_fn("");
+ kref_get(&queue->kref);
+}
+
+struct nvdla_queue *nvdla_queue_alloc(struct nvdla_queue_pool *pool,
+ unsigned int num_tasks,
+ bool use_channel)
+{
+ struct platform_device *pdev = pool->pdev;
+ struct nvhost_device_data *pdata = platform_get_drvdata(pdev);
+ struct nvdla_queue *queues = pool->queues;
+ struct nvdla_queue *queue;
+ int index = 0;
+ int err = 0;
+
+ mutex_lock(&pool->queue_lock);
+
+ index = find_first_zero_bit(&pool->alloc_table,
+ pool->max_queue_cnt);
+
+ /* quit if we found a queue */
+ if (index >= pool->max_queue_cnt) {
+ dev_err(&pdev->dev, "failed to get free Queue\n");
+ err = -ENOMEM;
+ goto err_alloc_queue;
+ }
+
+ /* reserve the queue */
+ queue = &queues[index];
+ set_bit(index, &pool->alloc_table);
+
+ /* allocate a syncpt for the queue */
+ queue->syncpt_id = nvhost_get_syncpt_host_managed(pdev, index, NULL);
+ if (!queue->syncpt_id) {
+ dev_err(&pdev->dev, "failed to get syncpt id\n");
+ err = -ENOMEM;
+ goto err_alloc_syncpt;
+ }
+
+ /* initialize queue ref count and sequence*/
+ kref_init(&queue->kref);
+ queue->use_channel = use_channel;
+ queue->sequence = 0;
+
+ /* initialize task list */
+ INIT_LIST_HEAD(&queue->tasklist);
+ mutex_init(&queue->list_lock);
+
+ /* initialize task list */
+ queue->attr = NULL;
+ mutex_init(&queue->attr_lock);
+
+ mutex_unlock(&pool->queue_lock);
+
+ /* Check if the queue should allocate a channel */
+ if (use_channel) {
+ err = nvhost_channel_map(pdata, &queue->channel, queue);
+ if (err < 0)
+ goto err_alloc_channel;
+
+ queue->channel->syncpts[0] = queue->syncpt_id;
+ queue->vm_pdev = queue->channel->vm->pdev;
+ } else {
+ queue->vm_pdev = pdev;
+ }
+
+ if (queue->task_dma_size) {
+ err = nvdla_queue_task_pool_alloc(queue->vm_pdev,
+ queue,
+ num_tasks);
+ if (err < 0)
+ goto err_alloc_task_pool;
+ }
+
+ return queue;
+
+err_alloc_task_pool:
+ if (use_channel)
+ nvhost_putchannel(queue->channel, 1);
+err_alloc_channel:
+ mutex_lock(&pool->queue_lock);
+ nvhost_syncpt_put_ref_ext(pdev, queue->syncpt_id);
+err_alloc_syncpt:
+ clear_bit(queue->id, &pool->alloc_table);
+err_alloc_queue:
+ mutex_unlock(&pool->queue_lock);
+ return ERR_PTR(err);
+}
+
+int nvdla_queue_abort(struct nvdla_queue *queue)
+{
+ struct nvdla_queue_pool *pool = queue->pool;
+
+ if (pool->ops && pool->ops->abort)
+ return pool->ops->abort(queue);
+
+ return 0;
+}
+
+int nvdla_queue_submit(struct nvdla_queue *queue, void *task_arg)
+{
+ struct nvdla_queue_pool *pool = queue->pool;
+
+ if (pool->ops && pool->ops->submit)
+ return pool->ops->submit(queue, task_arg);
+
+ return 0;
+}
+
+int nvdla_queue_set_attr(struct nvdla_queue *queue, void *arg)
+{
+ struct nvdla_queue_pool *pool = queue->pool;
+
+ if (pool->ops && pool->ops->set_attribute)
+ return pool->ops->set_attribute(queue, arg);
+
+ return 0;
+}
+
+struct nvdla_queue_task {
+ struct platform_device *host1x_pdev;
+
+ struct nvdla_queue *queue;
+
+ dma_addr_t dma_addr;
+ u32 *cpu_addr;
+};
+
+static void queue_task_update(void *priv, int nr_completed)
+{
+ struct nvdla_queue_task *task = priv;
+ struct platform_device *host1x_pdev = task->host1x_pdev;
+
+ dma_free_coherent(&host1x_pdev->dev,
+ CMDBUF_SIZE,
+ task->cpu_addr,
+ task->dma_addr);
+ kfree(task);
+}
+
+int nvdla_queue_submit_to_host1x(struct nvdla_queue *queue,
+ u32 *cmdbuf,
+ u32 num_cmdbuf_words,
+ u32 num_syncpt_incrs,
+ u32 *wait_syncpt_ids,
+ u32 *wait_syncpt_thresholds,
+ u32 num_syncpt_waits,
+ u32 *task_syncpt_threshold)
+{
+ struct nvdla_queue_pool *pool = queue->pool;
+ struct platform_device *client_pdev = pool->pdev;
+ struct platform_device *host1x_pdev =
+ to_platform_device(client_pdev->dev.parent);
+ struct nvhost_device_data *pdata = platform_get_drvdata(client_pdev);
+ struct nvdla_queue_task *task;
+ struct nvhost_job *job;
+ unsigned int i;
+ int err = 0;
+
+ if (queue->use_channel == false)
+ return -EINVAL;
+
+ /* Allocate memory for the task and task command buffer */
+ task = kzalloc(sizeof(*task), GFP_KERNEL);
+ if (task == NULL) {
+ nvhost_err(&client_pdev->dev, "failed to allocate task");
+ goto err_alloc_task;
+ }
+
+ task->cpu_addr = dma_alloc_coherent(&host1x_pdev->dev,
+ CMDBUF_SIZE,
+ &task->dma_addr,
+ GFP_KERNEL);
+ if (task->cpu_addr == NULL) {
+ nvhost_err(&client_pdev->dev, "failed to allocate task");
+ err = -ENOMEM;
+ goto err_alloc_cmdbuf;
+ }
+
+ /* Copy the command buffer */
+ memcpy(task->cpu_addr, cmdbuf, num_cmdbuf_words * 4);
+
+ job = nvhost_job_alloc(queue->channel,
+ 1,
+ 0,
+ num_syncpt_waits,
+ 1);
+ if (job == NULL) {
+ err = -ENOMEM;
+ goto err_alloc_job;
+ }
+
+ task->queue = queue;
+ task->host1x_pdev = host1x_pdev;
+
+ /* Write waits to the job */
+ job->num_waitchk = num_syncpt_waits;
+ for (i = 0; i < num_syncpt_waits; i++) {
+ job->waitchk[i].syncpt_id = wait_syncpt_ids[i];
+ job->waitchk[i].thresh = wait_syncpt_thresholds[i];
+ job->waitchk[i].mem = 0;
+ }
+
+ /* Initialize syncpoint increments */
+ job->sp->id = queue->syncpt_id;
+ job->sp->incrs = num_syncpt_incrs;
+ job->num_syncpts = 1;
+
+ /* Add the command buffer */
+ nvhost_job_add_client_gather_address(job,
+ num_cmdbuf_words,
+ pdata->class,
+ task->dma_addr);
+
+ /* Submit task to hardware */
+ err = nvhost_channel_submit(job);
+ if (err < 0)
+ goto err_submit_job;
+
+ /* Return the number of increments back to the caller */
+ *task_syncpt_threshold = job->sp->fence;
+
+ /* Register a callback function for releasing resources */
+ err = nvhost_intr_register_notifier(host1x_pdev,
+ queue->syncpt_id,
+ job->sp->fence,
+ queue_task_update, task);
+ if (err < 0) {
+ nvhost_err(&client_pdev->dev,
+ "failed to register notifier err=%d",
+ err);
+ goto err_register_notifier;
+ }
+
+ /* nvhost keeps a reference on the job and we don't
+ * need to access it anymore
+ */
+ nvhost_job_put(job);
+
+ return 0;
+
+err_register_notifier:
+err_submit_job:
+ nvhost_job_put(job);
+err_alloc_job:
+ dma_free_coherent(&host1x_pdev->dev, CMDBUF_SIZE, task->cpu_addr,
+ task->dma_addr);
+err_alloc_cmdbuf:
+ kfree(task);
+err_alloc_task:
+ return err;
+}
+
+int nvdla_queue_get_task_size(struct nvdla_queue *queue)
+{
+ struct nvdla_queue_pool *pool = queue->pool;
+
+ if (pool->ops && pool->ops->get_task_size)
+ pool->ops->get_task_size(&queue->task_dma_size,
+ &queue->task_kmem_size);
+
+ return 0;
+}
+
+int nvdla_queue_alloc_task_memory(
+ struct nvdla_queue *queue,
+ struct nvdla_queue_task_mem_info *task_mem_info)
+{
+ int err = 0;
+ int index, hw_offset, sw_offset;
+ struct platform_device *pdev = queue->pool->pdev;
+ struct nvdla_queue_task_pool *task_pool =
+ (struct nvdla_queue_task_pool *)queue->task_pool;
+
+ mutex_lock(&task_pool->lock);
+
+ index = find_first_zero_bit(&task_pool->alloc_table,
+ task_pool->max_task_cnt);
+
+ /* quit if pre-allocated task array is not free */
+ if (index >= task_pool->max_task_cnt) {
+ dev_err(&pdev->dev,
+ "failed to get Task Pool Memory\n");
+ err = -EAGAIN;
+ goto err_alloc_task_mem;
+ }
+
+ /* assign the task array */
+ set_bit(index, &task_pool->alloc_table);
+ hw_offset = index * queue->task_dma_size;
+ sw_offset = index * queue->task_kmem_size;
+ task_mem_info->kmem_addr =
+ (void *)((u8 *)task_pool->kmem_addr + sw_offset);
+ task_mem_info->va = (void *)((u8 *)task_pool->va + hw_offset);
+ task_mem_info->dma_addr = task_pool->dma_addr + hw_offset;
+ task_mem_info->pool_index = index;
+
+err_alloc_task_mem:
+ mutex_unlock(&task_pool->lock);
+
+ return err;
+}
+
+void nvdla_queue_free_task_memory(struct nvdla_queue *queue, int index)
+{
+ int hw_offset, sw_offset;
+ u8 *task_kmem, *task_dma_va;
+ struct nvdla_queue_task_pool *task_pool =
+ (struct nvdla_queue_task_pool *)queue->task_pool;
+
+ /* clear task kernel and dma virtual memory contents*/
+ hw_offset = index * queue->task_dma_size;
+ sw_offset = index * queue->task_kmem_size;
+ task_kmem = (u8 *)task_pool->kmem_addr + sw_offset;
+ task_dma_va = (u8 *)task_pool->va + hw_offset;
+
+ memset(task_kmem, 0, queue->task_kmem_size);
+ memset(task_dma_va, 0, queue->task_dma_size);
+
+ mutex_lock(&task_pool->lock);
+ clear_bit(index, &task_pool->alloc_table);
+ mutex_unlock(&task_pool->lock);
+}
diff --git a/drivers/video/tegra/host/nvdla/dla_queue.h b/drivers/video/tegra/host/nvdla/dla_queue.h
new file mode 100644
index 00000000..1f5801c6
--- /dev/null
+++ b/drivers/video/tegra/host/nvdla/dla_queue.h
@@ -0,0 +1,307 @@
+/*
+ * NVHOST Queue management header for T194
+ *
+ * Copyright (c) 2016-2017, NVIDIA Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef __NVHOST_NVDLA_QUEUE_H__
+#define __NVHOST_NVDLA_QUEUE_H__
+
+#include
+
+struct nvdla_queue_task_pool;
+
+/**
+ * @brief Describe a allocated task mem struct
+ *
+ * kmem_addr Address for the task kernel memory
+ * dma_addr Physical address of task memory
+ * va Virtual address of the task memory
+ * pool_index Index to the allocated task memory
+ *
+ * This is keep track of the memory details of the task
+ * struct that is being shared between kernel and firmware.
+ */
+struct nvdla_queue_task_mem_info {
+ void *kmem_addr;
+ dma_addr_t dma_addr;
+ void *va;
+ int pool_index;
+};
+/**
+ * @brief Information needed in a Queue
+ *
+ * pool pointer queue pool
+ * kref struct kref for reference count
+ * syncpt_id Host1x syncpt id
+ * id Queue id
+ * list_lock mutex for tasks lists control
+ * tasklist Head of tasks list
+ * sequence monotonically incrementing task id per queue
+ * task_pool pointer to struct for task memory pool
+ * task_dma_size dma size used in hardware for a task
+ * task_kmem_size kernel memory size for a task
+ * attr queue attribute associated with the host module
+ *
+ */
+struct nvdla_queue {
+ struct nvdla_queue_task_pool *task_pool;
+ struct nvdla_queue_pool *pool;
+ struct kref kref;
+ u32 id;
+
+ /* Host1x resources */
+ struct nvhost_channel *channel;
+ struct platform_device *vm_pdev;
+ bool use_channel;
+ u32 syncpt_id;
+
+ size_t task_dma_size;
+ size_t task_kmem_size;
+
+ u32 sequence;
+
+ struct mutex attr_lock;
+ void *attr;
+
+ struct mutex list_lock;
+ struct list_head tasklist;
+};
+
+/**
+ * @brief hardware specific queue callbacks
+ *
+ * dump dump the task information
+ * abort abort all tasks from a queue
+ * submit submit the given list of tasks to hardware
+ * get_task_size get the dma size needed for the task in hw
+ * and the kernel memory size needed for task.
+ *
+ */
+struct nvdla_queue_ops {
+ void (*dump)(struct nvdla_queue *queue, struct seq_file *s);
+ int (*abort)(struct nvdla_queue *queue);
+ int (*submit)(struct nvdla_queue *queue, void *task_arg);
+ void (*get_task_size)(size_t *dma_size, size_t *kmem_size);
+ int (*set_attribute)(struct nvdla_queue *queue, void *arg);
+};
+
+/**
+ * @brief Queue pool data structure to hold queue table
+ *
+ * pdev Pointer to the Queue client device
+ * ops Pointer to hardware specific queue ops
+ * queues Queues available for the client
+ * queue_lock Mutex for the bitmap of reserved queues
+ * alloc_table Bitmap of allocated queues
+ * max_queue_cnt Max number queues available for client
+ * queue_task_pool Pointer to the task memory pool for queues.
+ *
+ */
+struct nvdla_queue_pool {
+ struct platform_device *pdev;
+ struct nvdla_queue_ops *ops;
+ struct nvdla_queue *queues;
+ struct mutex queue_lock;
+ unsigned long alloc_table;
+ unsigned int max_queue_cnt;
+ void *queue_task_pool;
+};
+
+/**
+ * @brief Initialize queue structures
+ *
+ * This function allocates and initializes queue data structures.
+ *
+ * @param pdev Pointer to the Queue client device
+ * @param ops Pointer to device speicific callbacks
+ * @param num_queues Max number queues available for client
+ * @return pointer to queue pool
+ *
+ */
+struct nvdla_queue_pool *nvdla_queue_init(struct platform_device *pdev,
+ struct nvdla_queue_ops *ops,
+ unsigned int num_queues);
+
+/**
+ * @brief De-initialize queue structures
+ *
+ * This function free's all queue data structures.
+ *
+ * @param pool pointer to queue pool
+ * @return void
+ *
+ */
+void nvdla_queue_deinit(struct nvdla_queue_pool *pool);
+
+/**
+ * @brief Release reference of a queue
+ *
+ * This function releases reference for a queue.
+ *
+ * @param queue Pointer to an allocated queue.
+ * @return void
+ *
+ */
+void nvdla_queue_put(struct nvdla_queue *queue);
+
+/**
+ * @brief Get reference on a queue.
+ *
+ * This function used to get a reference to an already allocated queue.
+ *
+ * @param queue Pointer to an allocated queue.
+ * @return None
+ *
+ */
+void nvdla_queue_get(struct nvdla_queue *queue);
+
+/**
+ * @brief Allocate a queue for client.
+ *
+ * This function allocates a queue from the pool to client for the user.
+ *
+ * @param pool Pointer to a queue pool table
+ * @param num_tasks Max number of tasks per queue
+ * @param use_channel Determines whether the routine allocates a channel for
+ * the queue.
+ *
+ * @return Pointer to a queue struct on success
+ * or negative error on failure.
+ *
+ */
+struct nvdla_queue *nvdla_queue_alloc(struct nvdla_queue_pool *pool,
+ unsigned int num_tasks,
+ bool use_channel);
+
+/**
+ * @brief Abort all active queues
+ *
+ * @param pool Pointer to a queue pool table
+ */
+void nvdla_queue_abort_all(struct nvdla_queue_pool *pool);
+
+/**
+ * @brief Abort tasks within a client queue
+ *
+ * This function aborts all tasks from the given clinet queue. If there is no
+ * active tasks, the function call is no-op.
+ * It is expected to be called when an active device fd gets closed.
+ *
+ * @param queue Pointer to an allocated queue
+ * @return None
+ *
+ */
+int nvdla_queue_abort(struct nvdla_queue *queue);
+
+/**
+ * @brief submits the given list of tasks to hardware
+ *
+ * This function submits the given list of tasks to hardware.
+ * The submit structure is updated with the fence values as appropriate.
+ *
+ * @param queue Pointer to an allocated queue
+ * @param submit Submit the given list of tasks to hardware
+ * @return 0 on success or negative error code on failure.
+ *
+ */
+int nvdla_queue_submit(struct nvdla_queue *queue, void *submit);
+
+/**
+ * @brief Get the Task Size needed
+ *
+ * This function get the needed memory size for the task. This memory is
+ * shared memory between kernel and firmware
+ *
+ * @param queue Pointer to an allocated queue
+ * @return Size of the task
+ *
+ */
+int nvdla_queue_get_task_size(struct nvdla_queue *queue);
+
+/**
+ * @brief Allocate a memory from task memory pool
+ *
+ * This function helps to assign a task memory from
+ * the preallocated task memory pool. This memory is shared memory between
+ * kernel and firmware
+ *
+ * @queue Pointer to an allocated queue
+ * @task_mem_info Pointer to nvdla_queue_task_mem_info struct
+ *
+ * @return 0 on success, otherwise a negative error code is returned
+ *
+ */
+int nvdla_queue_alloc_task_memory(
+ struct nvdla_queue *queue,
+ struct nvdla_queue_task_mem_info *task_mem_info);
+
+/**
+ * @brief Free the assigned task memory
+ *
+ * This function helps to unset the assigned task memory
+ *
+ * @param queue Pointer to an allocated queue
+ * @param index Index of the assigned task pool memory
+ * @return void
+ *
+ */
+void nvdla_queue_free_task_memory(struct nvdla_queue *queue, int index);
+
+/**
+ * @brief Sets the attribute to the queue
+ *
+ * This function set the attribute of the queue with the arguments passed
+ *
+ * @param queue Pointer to an allocated queue
+ * @param arg The structure which consists of the id and value
+ * @return 0 on success or negative error code on failure.
+ *
+ */
+int nvdla_queue_set_attr(struct nvdla_queue *queue, void *arg);
+
+/**
+ * @brief Submit the given command buffer to the device
+ *
+ * This functions submits the given cmdbuf to a Host1x channel. The
+ * submit must perform the given number of syncpoint increments
+ * on the engine.
+ *
+ * @param queue Pointer to an allocated queue
+ * @param cmdbuf Pointer to a command buffer to submit
+ * @param num_cmdbuf_words Number of words in the command buffer
+ * @param num_syncpt_incrs Number of syncpoint increments the task
+ * issues
+ * @param wait_syncpt_ids Syncpoint ids that should be waited on
+ * Host1x
+ * @param wait_syncpoint_thresholds Syncpoint thresholds for the waits
+ * @param task_syncpt_threshold Pointer to a u32. The variable is
+ * initialized to have the completion
+ * threshold.
+ *
+ * @return 0 on success or negative error code on
+ * failure.
+ *
+ */
+int nvdla_queue_submit_to_host1x(struct nvdla_queue *queue,
+ u32 *cmdbuf,
+ u32 num_cmdbuf_words,
+ u32 num_syncpt_incrs,
+ u32 *wait_syncpt_ids,
+ u32 *wait_syncpt_thresholds,
+ u32 num_syncpt_waits,
+ u32 *task_syncpt_threshold);
+
+#endif