drivers: pva: Update channel and descriptor limit

Update code to account for t26x channel and descriptor limits.

Also, the reserved descriptors for all generations of PVA HW are
at indices 60-63. Update KMD checks to ensure the reserved descriptors
are never patched, and are not linked to either during SW sequencing
or HW sequencing.

Jira PVAAS-13055

Change-Id: I276490d51d65648a406fabed06c47e45d9e6978a
Signed-off-by: abhinayaa <abhinayaa@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2908053
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2999158
Reviewed-by: Amruta Sai Anusha Bhamidipati <abhamidipati@nvidia.com>
Reviewed-by: Omar Nemri <onemri@nvidia.com>
Tested-by: Omar Nemri <onemri@nvidia.com>
GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
abhinayaa
2023-04-18 00:25:09 +00:00
committed by mobile promotions
parent 5d5f42c1b1
commit 97f5252632
6 changed files with 94 additions and 29 deletions

View File

@@ -76,7 +76,7 @@
* @brief The first Reserved DMA descriptor. This is used as a
* starting point to iterate over reserved DMA descriptors.
*/
#define PVA_RESERVED_DESC_START PVA_NUM_DYNAMIC_DESCS
#define PVA_RESERVED_DESC_START (60U)
/**
* @brief The first Reserved AXI data buffers. This is used as a

View File

@@ -17,6 +17,10 @@
#include <pva-bit.h>
#include <pva-packed.h>
#ifdef CONFIG_TEGRA_T26X_GRHOST_PVA
#include <pva-sys-dma-t264.h>
#endif
/*** Version number of the current DMA info structure */
#define PVA_DMA_INFO_VERSION_ID (1U)
@@ -45,8 +49,10 @@ struct PVA_PACKED pva_dma_ch_config_s {
#define PVA_SYS_DMA_NUM_TRIGGERS (9U)
/** Number of DMA channel configurations in DMA info structure. */
#define PVA_SYS_DMA_NUM_CHANNELS (15U)
/** Maximum number of DMA descriptors allowed. */
#define PVA_SYS_DMA_MAX_DESCRIPTORS (60U)
/** Maximum number of DMA descriptors allowed in T19x. */
#define PVA_SYS_DMA_MAX_DESCRIPTORS_T19X (60U)
/** Maximum number of DMA descriptors allowed in T23x. */
#define PVA_SYS_DMA_MAX_DESCRIPTORS_T23X (60U)
/** @brief DMA info for a VPU app.
*

View File

@@ -336,7 +336,7 @@ struct nvpva_syncpts_desc {
/**
* @brief Driver private data, shared with all applications
*
* version pva version; 1 or 2
* version pva version; 1, 2 or 3
* pdev Pointer to the PVA device
* pool Pointer to Queue table available for the PVA
* fw_info firmware information struct
@@ -368,7 +368,7 @@ struct nvpva_syncpts_desc {
*/
struct pva {
int version;
u32 version;
struct pva_version_config *version_config;
struct platform_device *pdev;
struct platform_device *aux_pdev;

View File

@@ -23,6 +23,13 @@
#define LOW_BITS (0xFFFFFFFFU >> (32U - 4U))
#define NVPVA_MAX_VALID_BLK_HGT_LG2 5U
static const u8 max_desc_id[4] = {
[0] = 0U, // dummy entry to simplify lookup
[PVA_HW_GEN1] = NVPVA_TASK_MAX_DMA_DESCRIPTORS_T19X,
[PVA_HW_GEN2] = NVPVA_TASK_MAX_DMA_DESCRIPTORS_T23X,
[PVA_HW_GEN3] = NVPVA_TASK_MAX_DMA_DESCRIPTOR_ID_T26X
};
int
pitch_linear_eq_offset(struct nvpva_dma_descriptor const *dma_desc,
s64 *frame_buf_offset,
@@ -779,6 +786,9 @@ static int32_t nvpva_task_dma_desc_mapping(struct pva_submit_task *task,
u8 num_dma_descriptors = task->num_dma_descriptors;
u8 *num_dma_desc_processed = &task->num_dma_desc_processed;
uint16_t exe_id = 0;
const uint8_t resv_desc_start_idx = NVPVA_RESERVED_DESCRIPTORS_START_IDX;
const uint8_t resv_desc_end_idx = (NVPVA_RESERVED_DESCRIPTORS_START_IDX
+ NVPVA_NUM_RESERVED_DESCRIPTORS - 1);
nvpva_dbg_fn(task->pva, "");
@@ -788,8 +798,12 @@ static int32_t nvpva_task_dma_desc_mapping(struct pva_submit_task *task,
if (task->desc_processed & (1LLU << desc_num))
continue;
task->desc_processed |= (1LLU << desc_num);
++(*num_dma_desc_processed);
if (desc_num == resv_desc_start_idx) {
desc_num = resv_desc_end_idx;
i += (resv_desc_end_idx - resv_desc_start_idx + 1);
continue;
}
umd_dma_desc = &task->dma_descriptors[desc_num];
dma_desc = &hw_task->dma_desc[desc_num];
is_misr = !((task->dma_misr_config.descriptor_mask
@@ -865,8 +879,10 @@ static int32_t nvpva_task_dma_desc_mapping(struct pva_submit_task *task,
(u8)((task->dst_surf_base_addr & 0x3E00) >> 6U);
}
if (umd_dma_desc->linkDescId > task->num_dma_descriptors) {
task_err(task, "invalid link ID");
if ((umd_dma_desc->linkDescId > task->num_dma_descriptors)
|| ((umd_dma_desc->linkDescId > resv_desc_start_idx)
&& (umd_dma_desc->linkDescId <= resv_desc_end_idx + 1))) {
task_err(task, "invalid link ID %u", umd_dma_desc->linkDescId);
return -EINVAL;
}
@@ -965,17 +981,20 @@ verify_dma_desc_hwseq(struct pva_submit_task *task,
u64 *desc_hwseq_frm = &task->desc_hwseq_frm;
struct nvpva_dma_descriptor *desc;
nvpva_dbg_fn(task->pva, "");
const uint8_t resv_desc_start_idx = NVPVA_RESERVED_DESCRIPTORS_START_IDX;
const uint8_t resv_desc_end_idx = (NVPVA_RESERVED_DESCRIPTORS_START_IDX
+ NVPVA_NUM_RESERVED_DESCRIPTORS - 1);
if ((did == 0U)
|| (did >= NVPVA_TASK_MAX_DMA_DESCRIPTORS)) {
|| (did >= max_desc_id[task->pva->version])
|| (((did - 1) >= resv_desc_start_idx) && ((did - 1) <= resv_desc_end_idx))) {
pr_err("invalid Descritor ID");
err = -EINVAL;
goto out;
}
did = array_index_nospec((did - 1),
NVPVA_TASK_MAX_DMA_DESCRIPTORS);
max_desc_id[task->pva->version]);
desc = &task->dma_descriptors[did];
/* return flag if block linear format is in use */
@@ -1869,7 +1888,7 @@ verify_hwseq_blob(struct pva_submit_task *task,
}
did = array_index_nospec((blob_desc->did1 - 1U),
NVPVA_TASK_MAX_DMA_DESCRIPTORS);
max_desc_id[task->pva->version]);
desc_block_height_log2[did] = user_ch->blockHeight;
if (!is_desc_mode(blob->f_header.fid)) {
desc_entries[k].did = did;
@@ -1899,7 +1918,7 @@ verify_hwseq_blob(struct pva_submit_task *task,
}
did = array_index_nospec((blob_desc->did2 - 1U),
NVPVA_TASK_MAX_DMA_DESCRIPTORS);
max_desc_id[task->pva->version]);
desc_block_height_log2[did] = user_ch->blockHeight;
if (!is_desc_mode(blob->f_header.fid)) {
desc_entries[k].did = did;
@@ -1971,11 +1990,15 @@ nvpva_task_dma_channel_mapping(struct pva_submit_task *task,
u32 adb_limit;
int err = 0;
u8 bl_xfers_in_use = 0;
const u8 resv_desc_start = NVPVA_RESERVED_DESCRIPTORS_START_IDX;
const u8 resv_desc_end = NVPVA_RESERVED_DESCRIPTORS_START_IDX
+ NVPVA_NUM_RESERVED_DESCRIPTORS - 1;
nvpva_dbg_fn(task->pva, "");
if (((user_ch->descIndex > PVA_NUM_DYNAMIC_DESCS) ||
((user_ch->vdbSize + user_ch->vdbOffset) >
if ((((user_ch->descIndex > resv_desc_start)
&& (user_ch->descIndex <= resv_desc_end))
|| ((user_ch->vdbSize + user_ch->vdbOffset) >
PVA_NUM_DYNAMIC_VDB_BUFFS))) {
pr_err("ERR: Invalid Channel control data");
err = -EINVAL;

View File

@@ -14,9 +14,27 @@
#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
#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)
struct dma_buf;
extern struct nvpva_queue_ops pva_queue_ops;
@@ -145,9 +163,9 @@ struct pva_submit_task {
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[NVPVA_TASK_MAX_DMA_DESCRIPTORS];
dma_descriptors[MAX_NUM_DESCS]; /* max of T19x, T23x & T26x */
struct nvpva_dma_channel dma_channels
[NVPVA_TASK_MAX_DMA_CHANNELS_T23X]; /* max of T19x & T23x */
[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];
@@ -162,11 +180,10 @@ struct pva_submit_task {
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[NVPVA_TASK_MAX_DMA_CHANNELS_T23X];
u8 desc_block_height_log2[NVPVA_TASK_MAX_DMA_DESCRIPTORS];
struct pva_dma_task_buffer_info_s task_buff_info[NVPVA_TASK_MAX_DMA_DESCRIPTORS];
struct pva_dma_hwseq_desc_entry_s desc_entries[NVPVA_TASK_MAX_DMA_CHANNELS_T23X]
[PVA_HWSEQ_DESC_LIMIT];
struct pva_hwseq_priv_s hwseq_info[MAX_NUM_CHANNELS];
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][PVA_HWSEQ_DESC_LIMIT];
/** Store Suface base address */
u64 src_surf_base_addr;
@@ -285,7 +302,7 @@ struct pva_hw_task {
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[NVPVA_TASK_MAX_DMA_DESCRIPTORS];
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;

View File

@@ -516,12 +516,31 @@ union nvpva_set_vpu_print_buffer_size_args {
struct nvpva_set_vpu_print_buffer_size_in_arg in;
};
/* There are 64 DMA descriptors in T19x and T23x. But R5 FW reserves
/**
* There are 64 DMA descriptors in T19x. But R5 FW reserves
* 4 DMA descriptors for internal use.
*/
#define NVPVA_TASK_MAX_DMA_DESCRIPTORS (60U)
#define NVPVA_TASK_MAX_DMA_DESCRIPTORS_T19X (60U)
/**
* There are 64 DMA descriptors in T23x. But R5 FW reserves
* 4 DMA descriptors for internal use.
*/
#define NVPVA_TASK_MAX_DMA_DESCRIPTORS_T23X (60U)
/**
* Number of DMA descriptors reserved for R5 FW's
* internal use
*/
#define NVPVA_NUM_RESERVED_DESCRIPTORS (4U)
/**
* Index of the first reserved DMA descriptor
*/
#define NVPVA_RESERVED_DESCRIPTORS_START_IDX (60U)
/*TODO: Remove NVPVA_TASK_MAX_DMA_CHANNELS */
/*There are 14 DMA channels in T19x and 16 DMA channels in T23X.
/**
* There are 14 DMA channels in T19x and 16 DMA channels in T23X.
* R5 FW reserves one DMA channel for internal use.
*/
#define NVPVA_TASK_MAX_DMA_CHANNELS 16U
@@ -597,7 +616,7 @@ union nvpva_set_vpu_print_buffer_size_args {
NVPVA_MAX_FENCE_TYPES * sizeof(struct nvpva_fence_action) + \
NVPVA_TASK_MAX_INPUT_STATUS * sizeof(struct nvpva_mem) + \
NVPVA_TASK_MAX_OUTPUT_STATUS * sizeof(struct nvpva_mem) + \
NVPVA_TASK_MAX_DMA_DESCRIPTORS * \
NVPVA_TASK_MAX_DMA_DESCRIPTORS_T23X * \
sizeof(struct nvpva_dma_descriptor) + \
NVPVA_TASK_MAX_DMA_CHANNELS * sizeof(struct nvpva_dma_channel) + \
sizeof(struct nvpva_hwseq_config) + \