Files
linux-nv-oot/drivers/video/tegra/host/pva/pva_queue.h
Amruta Bhamidipati a4607dbdfd drivers: pva: Update HWSEQ checks
Add additional HW SEQ validation checks
- Validate all frames with different addressing modes in a
  HW SEQ blob
- Validate multiple frames on a single channel in RDF
  frame-linking mode
- Validate each column/row within a given frame since
  multiple column/rows are supported in next chip

Bug 4588239

Signed-off-by: Amruta Bhamidipati<abhamidipati@nvidia.com>

Change-Id: Ic30c8c1982c5ac21a960f0546c39e5a28cc7d4bd
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3153297
GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
Tested-by: Amruta Sai Anusha Bhamidipati <abhamidipati@nvidia.com>
Reviewed-by: Krish Agarwal <krisha@nvidia.com>
Reviewed-by: Sreehari Mohan <sreeharim@nvidia.com>
Reviewed-by: Omar Nemri <onemri@nvidia.com>
2024-06-21 23:05:14 -07:00

328 lines
9.8 KiB
C

/* SPDX-License-Identifier: GPL-2.0-only */
/*
* SPDX-FileCopyrightText: Copyright (c) 2016-2024 NVIDIA CORPORATION. All rights reserved.
*/
#ifndef PVA_QUEUE_H
#define PVA_QUEUE_H
#include <uapi/linux/nvpva_ioctl.h>
#include "nvpva_queue.h"
#include "nvpva_buffer.h"
#include "pva-sys-params.h"
#include "pva-interface.h"
#include "pva-task.h"
#include "pva_hwseq.h"
#ifdef CONFIG_TEGRA_T26X_GRHOST_PVA
#include <nvpva_ioctl_t264.h>
#else
#define NVPVA_TASK_MAX_DMA_DESCRIPTOR_ID_T26X \
NVPVA_TASK_MAX_DMA_DESCRIPTORS_T23X
#define NVPVA_TASK_MAX_DMA_CHANNELS_T26X \
NVPVA_TASK_MAX_DMA_CHANNELS_T23X
#define NVPVA_TASK_MAX_HWSEQ_FRAME_COUNT_T26X 1U
#endif
#define task_err(task, fmt, ...) \
dev_err(&task->pva->pdev->dev, fmt, ##__VA_ARGS__)
#define MAX_VAL(x, y) (((x) > (y)) ? (x) : (y))
#define MAX_NUM_DESCS MAX_VAL((MAX_VAL(NVPVA_TASK_MAX_DMA_DESCRIPTORS_T19X, \
NVPVA_TASK_MAX_DMA_DESCRIPTORS_T23X)), \
NVPVA_TASK_MAX_DMA_DESCRIPTOR_ID_T26X)
#define MAX_NUM_CHANNELS MAX_VAL((MAX_VAL(NVPVA_TASK_MAX_DMA_CHANNELS_T19X, \
NVPVA_TASK_MAX_DMA_CHANNELS_T23X)), \
NVPVA_TASK_MAX_DMA_CHANNELS_T26X)
#define MAX_NUM_FRAMES NVPVA_TASK_MAX_HWSEQ_FRAME_COUNT_T26X
struct dma_buf;
extern struct nvpva_queue_ops pva_queue_ops;
struct pva_pinned_memory {
u64 size;
u64 serial_id;
dma_addr_t dma_addr;
struct dma_buf *dmabuf;
int id;
enum nvpva_buffers_heap heap;
};
struct pva_cb {
dma_addr_t head_addr;
uint32_t *head_va;
dma_addr_t tail_addr;
uint32_t *tail_va;
dma_addr_t err_addr;
uint32_t *err_va;
dma_addr_t buffer_addr;
uint8_t *buffer_va;
uint32_t tail;
uint32_t size;
};
/**
* @brief descriptor src/dest buffer inforamtion
*
* This structure holds information about buffers addressed
* by a DMA descriptor. This information is used to imrove
* efficiency of bounds checking on DMA access.
*/
struct pva_dma_task_buffer_info_s {
uint64_t src_buffer_size;
uint64_t dst_buffer_size;
uint64_t dst2_buffer_size;
};
/**
* @brief Describe a task for PVA
*
* This is an internal representation of the task structure. All
* pointers refer to kernel memory.
*
* pva Pointer to struct pva
* buffers Pointer to struct nvpva_buffers
* queue Pointer to struct nvpva_queue
* node Used to build queue task list
* kref Used to manage allocation and freeing
* dma_addr task dma_addr
* aux_dma_addr task auxdma_addr
* va task virtual address
* aux_va task aux virtual address
* pool_index task pool index
* postfence_va postfence virtual address
* num_prefences Number of pre-fences in this task
* num_postfences Number of post-fences in this task
* num_input_surfaces Number of input surfaces
* num_output_surfaces Number of output surfaces
* num_input_task_status Number of input task status structures
* num_output_task_status Number of output task status structures
* operation task operation
* timeout Latest Unix time when the task must complete or
* 0 if disabled.
* prefences Pre-fence structures
* postfences Post-fence structures
* input_surfaces Input surfaces structures
* input_scalars Information for input scalars
* output_surfaces Output surfaces
* output_scalars Information for output scalars
* input_task_status Input status structure
* output_task_status Output status structure
*
*/
struct pva_submit_task {
struct pva *pva;
struct nvpva_queue *queue;
struct nvpva_client_context *client;
struct list_head node;
struct kref ref;
dma_addr_t dma_addr;
dma_addr_t aux_dma_addr;
void *va;
void *aux_va;
int pool_index;
bool pinned_app;
u32 exe_id1;
u64 stream_id;
u64 prog_id;
u32 exe_id2;
u32 l2_alloc_size; /* Not applicable for Xavier */
struct pva_cb *stdout;
u32 symbol_payload_size;
u32 flags;
u8 num_prefences;
u8 num_user_fence_actions;
u8 num_input_task_status;
u8 num_output_task_status;
u8 num_dma_descriptors;
u8 num_dma_channels;
u8 num_symbols;
u8 special_access;
u64 timeout;
u64 desc_hwseq_frm[2];
u64 desc_hwseq_t26x[2];
u64 desc_processed[2];
u8 num_dma_desc_processed;
u32 syncpt_thresh;
u32 fence_num;
u32 local_sync_counter;
u32 sem_thresh;
u32 sem_num;
u32 id;
/* Data provided by userspace "as is" */
struct nvpva_submit_fence prefences[NVPVA_TASK_MAX_PREFENCES];
struct nvpva_fence_action
user_fence_actions[NVPVA_MAX_FENCE_TYPES *
NVPVA_TASK_MAX_FENCEACTIONS];
struct nvpva_mem input_task_status[NVPVA_TASK_MAX_INPUT_STATUS];
struct nvpva_mem output_task_status[NVPVA_TASK_MAX_OUTPUT_STATUS];
struct nvpva_dma_descriptor
dma_descriptors[MAX_NUM_DESCS]; /* max of T19x, T23x & T26x */
struct nvpva_dma_channel dma_channels
[MAX_NUM_CHANNELS]; /* max of T19x, T23x & T26x */
struct nvpva_dma_misr dma_misr_config;
struct nvpva_hwseq_config hwseq_config;
struct nvpva_symbol_param symbols[NVPVA_TASK_MAX_SYMBOLS];
u8 symbol_payload[NVPVA_TASK_MAX_PAYLOAD_SIZE];
struct pva_pinned_memory pinned_memory[256];
u32 num_pinned;
u8 num_pva_fence_actions[NVPVA_MAX_FENCE_TYPES];
struct nvpva_fence_action
pva_fence_actions[NVPVA_MAX_FENCE_TYPES]
[NVPVA_TASK_MAX_FENCEACTIONS];
u64 fence_act_serial_ids[NVPVA_MAX_FENCE_TYPES]
[NVPVA_TASK_MAX_FENCEACTIONS];
u64 prefences_serial_ids[NVPVA_TASK_MAX_PREFENCES];
struct pva_hwseq_priv_s hwseq_info[MAX_NUM_CHANNELS][MAX_NUM_FRAMES];
u8 desc_block_height_log2[MAX_NUM_DESCS];
struct pva_dma_task_buffer_info_s task_buff_info[MAX_NUM_DESCS];
struct pva_dma_hwseq_desc_entry_s
desc_entries[MAX_NUM_CHANNELS][MAX_NUM_FRAMES][PVA_HWSEQ_DESC_LIMIT];
/** Store Suface base address */
u64 src_surf_base_addr;
u64 dst_surf_base_addr;
bool is_system_app;
};
struct pva_submit_tasks {
struct pva_submit_task *tasks[NVPVA_SUBMIT_MAX_TASKS];
u32 task_thresh[NVPVA_SUBMIT_MAX_TASKS];
u16 num_tasks;
u64 execution_timeout_us;
};
#define ACTION_LIST_FENCE_SIZE 21U
#define ACTION_LIST_STATUS_OPERATION_SIZE 11U
#define ACTION_LIST_TERMINATION_SIZE 1U
#define ACTION_LIST_STATS_SIZE 9U
#define PVA_TSC_TICKS_TO_US_FACTOR (0.032f)
/*
* The worst-case input action buffer size:
* - Prefences trigger a word memory operation (size 13 bytes)
* - Input status reads trigger a half-word memory operation (size 11 bytes)
* - The action list is terminated by a null action (1 byte)
*/
#define INPUT_ACTION_BUFFER_SIZE \
ALIGN(((NVPVA_TASK_MAX_PREFENCES * ACTION_LIST_FENCE_SIZE) + \
((NVPVA_TASK_MAX_FENCEACTIONS * 2U) * ACTION_LIST_FENCE_SIZE) + \
NVPVA_TASK_MAX_INPUT_STATUS * \
ACTION_LIST_STATUS_OPERATION_SIZE + \
ACTION_LIST_TERMINATION_SIZE), \
256)
/**
* Ensure that sufficient preactions per task are supported by FW/KMD interface.
* Maximum possible number of preactions can be determined by adding below
* limits:
* - Maximum number of prefences allowed per task
* - Maximum number of SOT_R and SOT_V fences allowed per task
* - Maximum number of input status buffers allowed per task
*/
#if ((PVA_MAX_PREACTION_LISTS) < \
( \
(NVPVA_TASK_MAX_PREFENCES) + \
(NVPVA_TASK_MAX_FENCEACTIONS * 2U) + \
(NVPVA_TASK_MAX_INPUT_STATUS) \
) \
)
#error "Insufficient preactions supported by FW/KMD interface"
#endif
/**
* Ensure that sufficient postactions per task are supported by FW/KMD interface.
* Maximum possible number of postactions can be determined by adding below
* limits:
* - Maximum number of EOT_V, EOT_R and EOT fences allowed per task
* - Maximum number of output status buffers allowed per task
* - Maximum one postaction for statistics
*/
#if ((PVA_MAX_POSTACTION_LISTS) < \
( \
(NVPVA_TASK_MAX_FENCEACTIONS * 3U) + \
(NVPVA_TASK_MAX_OUTPUT_STATUS) + \
(1U) \
) \
)
#error "Insufficient postactions supported by FW/KMD interface"
#endif
struct PVA_PACKED pva_task_action_ptr_s {
/* IOVA Pointer to update Sync Point Value */
pva_iova p;
/* Value to be written to Sync Point */
uint32_t v;
/* Pointer to write timestamp */
pva_iova t;
};
struct PVA_PACKED pva_task_action_status_s {
/* IOVA to pva_gen_task_status_t struct */
pva_iova p;
uint16_t status;
/* Padding to ensure that structure is 4byte aligned for FW perf optimization */
uint8_t pad[2];
};
struct PVA_PACKED pva_task_action_statistics_s {
/* IOVA to pva_task_statistics_t struct */
pva_iova p;
};
struct PVA_PACKED pva_task_action_s {
uint8_t action;
/* Padding to ensure that structure is 4byte aligned for FW perf optimization */
uint8_t pad[3];
union {
struct pva_task_action_ptr_s ptr;
struct pva_task_action_status_s status;
struct pva_task_action_statistics_s statistics;
} args;
};
/* This structure is created to ensure dma_info and params_list is always
* stored in contiguous memory within the HW task structure. This is done as a perf
* optimization so that a single dma copy can be triggered by R5 FW for copying both
* the dma_info and param_list.
*/
struct pva_dma_info_and_params_list_s {
struct pva_dma_info_s dma_info;
struct pva_vpu_parameters_s param_list[NVPVA_TASK_MAX_SYMBOLS];
};
struct pva_hw_task {
struct pva_td_s task;
struct pva_task_action_s preactions[PVA_MAX_PREACTION_LISTS];
struct pva_task_action_s postactions[PVA_MAX_POSTACTION_LISTS];
struct pva_dma_info_and_params_list_s dma_info_and_params_list;
struct pva_dma_misr_config_s dma_misr_config;
struct pva_dtd_s dma_desc[MAX_NUM_DESCS]; /* max of all gens */
struct pva_vpu_parameter_info_s param_info;
struct pva_task_statistics_s statistics;
struct pva_circular_buffer_info_s stdout_cb_info;
};
void pva_task_remove(struct pva_submit_task *task);
void pva_task_free(struct kref *ref);
void pva_task_update(struct work_struct *work);
struct pva_pinned_memory *pva_task_pin_mem(struct pva_submit_task *task,
u32 id);
void pva_dmabuf_vunmap(struct dma_buf *dmabuf, void *addr);
void *pva_dmabuf_vmap(struct dma_buf *dmabuf);
#endif