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 * @brief The first Reserved DMA descriptor. This is used as a
* starting point to iterate over reserved DMA descriptors. * 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 * @brief The first Reserved AXI data buffers. This is used as a

View File

@@ -17,6 +17,10 @@
#include <pva-bit.h> #include <pva-bit.h>
#include <pva-packed.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 */ /*** Version number of the current DMA info structure */
#define PVA_DMA_INFO_VERSION_ID (1U) #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) #define PVA_SYS_DMA_NUM_TRIGGERS (9U)
/** Number of DMA channel configurations in DMA info structure. */ /** Number of DMA channel configurations in DMA info structure. */
#define PVA_SYS_DMA_NUM_CHANNELS (15U) #define PVA_SYS_DMA_NUM_CHANNELS (15U)
/** Maximum number of DMA descriptors allowed. */ /** Maximum number of DMA descriptors allowed in T19x. */
#define PVA_SYS_DMA_MAX_DESCRIPTORS (60U) #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. /** @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 * @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 * pdev Pointer to the PVA device
* pool Pointer to Queue table available for the PVA * pool Pointer to Queue table available for the PVA
* fw_info firmware information struct * fw_info firmware information struct
@@ -368,7 +368,7 @@ struct nvpva_syncpts_desc {
*/ */
struct pva { struct pva {
int version; u32 version;
struct pva_version_config *version_config; struct pva_version_config *version_config;
struct platform_device *pdev; struct platform_device *pdev;
struct platform_device *aux_pdev; struct platform_device *aux_pdev;

View File

@@ -23,6 +23,13 @@
#define LOW_BITS (0xFFFFFFFFU >> (32U - 4U)) #define LOW_BITS (0xFFFFFFFFU >> (32U - 4U))
#define NVPVA_MAX_VALID_BLK_HGT_LG2 5U #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 int
pitch_linear_eq_offset(struct nvpva_dma_descriptor const *dma_desc, pitch_linear_eq_offset(struct nvpva_dma_descriptor const *dma_desc,
s64 *frame_buf_offset, 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_descriptors = task->num_dma_descriptors;
u8 *num_dma_desc_processed = &task->num_dma_desc_processed; u8 *num_dma_desc_processed = &task->num_dma_desc_processed;
uint16_t exe_id = 0; 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, ""); 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)) if (task->desc_processed & (1LLU << desc_num))
continue; continue;
task->desc_processed |= (1LLU << desc_num); if (desc_num == resv_desc_start_idx) {
++(*num_dma_desc_processed); 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]; umd_dma_desc = &task->dma_descriptors[desc_num];
dma_desc = &hw_task->dma_desc[desc_num]; dma_desc = &hw_task->dma_desc[desc_num];
is_misr = !((task->dma_misr_config.descriptor_mask 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); (u8)((task->dst_surf_base_addr & 0x3E00) >> 6U);
} }
if (umd_dma_desc->linkDescId > task->num_dma_descriptors) { if ((umd_dma_desc->linkDescId > task->num_dma_descriptors)
task_err(task, "invalid link ID"); || ((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; return -EINVAL;
} }
@@ -965,17 +981,20 @@ verify_dma_desc_hwseq(struct pva_submit_task *task,
u64 *desc_hwseq_frm = &task->desc_hwseq_frm; u64 *desc_hwseq_frm = &task->desc_hwseq_frm;
struct nvpva_dma_descriptor *desc; 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) 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"); pr_err("invalid Descritor ID");
err = -EINVAL; err = -EINVAL;
goto out; goto out;
} }
did = array_index_nospec((did - 1), did = array_index_nospec((did - 1),
NVPVA_TASK_MAX_DMA_DESCRIPTORS); max_desc_id[task->pva->version]);
desc = &task->dma_descriptors[did]; desc = &task->dma_descriptors[did];
/* return flag if block linear format is in use */ /* 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), 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; desc_block_height_log2[did] = user_ch->blockHeight;
if (!is_desc_mode(blob->f_header.fid)) { if (!is_desc_mode(blob->f_header.fid)) {
desc_entries[k].did = did; 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), 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; desc_block_height_log2[did] = user_ch->blockHeight;
if (!is_desc_mode(blob->f_header.fid)) { if (!is_desc_mode(blob->f_header.fid)) {
desc_entries[k].did = did; desc_entries[k].did = did;
@@ -1971,11 +1990,15 @@ nvpva_task_dma_channel_mapping(struct pva_submit_task *task,
u32 adb_limit; u32 adb_limit;
int err = 0; int err = 0;
u8 bl_xfers_in_use = 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, ""); nvpva_dbg_fn(task->pva, "");
if (((user_ch->descIndex > PVA_NUM_DYNAMIC_DESCS) || if ((((user_ch->descIndex > resv_desc_start)
((user_ch->vdbSize + user_ch->vdbOffset) > && (user_ch->descIndex <= resv_desc_end))
|| ((user_ch->vdbSize + user_ch->vdbOffset) >
PVA_NUM_DYNAMIC_VDB_BUFFS))) { PVA_NUM_DYNAMIC_VDB_BUFFS))) {
pr_err("ERR: Invalid Channel control data"); pr_err("ERR: Invalid Channel control data");
err = -EINVAL; err = -EINVAL;

View File

@@ -14,9 +14,27 @@
#include "pva-task.h" #include "pva-task.h"
#include "pva_hwseq.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, ...) \ #define task_err(task, fmt, ...) \
dev_err(&task->pva->pdev->dev, fmt, ##__VA_ARGS__) 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; struct dma_buf;
extern struct nvpva_queue_ops pva_queue_ops; 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 input_task_status[NVPVA_TASK_MAX_INPUT_STATUS];
struct nvpva_mem output_task_status[NVPVA_TASK_MAX_OUTPUT_STATUS]; struct nvpva_mem output_task_status[NVPVA_TASK_MAX_OUTPUT_STATUS];
struct nvpva_dma_descriptor 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 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_dma_misr dma_misr_config;
struct nvpva_hwseq_config hwseq_config; struct nvpva_hwseq_config hwseq_config;
struct nvpva_symbol_param symbols[NVPVA_TASK_MAX_SYMBOLS]; 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] u64 fence_act_serial_ids[NVPVA_MAX_FENCE_TYPES]
[NVPVA_TASK_MAX_FENCEACTIONS]; [NVPVA_TASK_MAX_FENCEACTIONS];
u64 prefences_serial_ids[NVPVA_TASK_MAX_PREFENCES]; u64 prefences_serial_ids[NVPVA_TASK_MAX_PREFENCES];
struct pva_hwseq_priv_s hwseq_info[NVPVA_TASK_MAX_DMA_CHANNELS_T23X]; struct pva_hwseq_priv_s hwseq_info[MAX_NUM_CHANNELS];
u8 desc_block_height_log2[NVPVA_TASK_MAX_DMA_DESCRIPTORS]; u8 desc_block_height_log2[MAX_NUM_DESCS];
struct pva_dma_task_buffer_info_s task_buff_info[NVPVA_TASK_MAX_DMA_DESCRIPTORS]; struct pva_dma_task_buffer_info_s task_buff_info[MAX_NUM_DESCS];
struct pva_dma_hwseq_desc_entry_s desc_entries[NVPVA_TASK_MAX_DMA_CHANNELS_T23X] struct pva_dma_hwseq_desc_entry_s desc_entries[MAX_NUM_CHANNELS][PVA_HWSEQ_DESC_LIMIT];
[PVA_HWSEQ_DESC_LIMIT];
/** Store Suface base address */ /** Store Suface base address */
u64 src_surf_base_addr; 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_task_action_s postactions[PVA_MAX_POSTACTION_LISTS];
struct pva_dma_info_and_params_list_s dma_info_and_params_list; struct pva_dma_info_and_params_list_s dma_info_and_params_list;
struct pva_dma_misr_config_s dma_misr_config; 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_vpu_parameter_info_s param_info;
struct pva_task_statistics_s statistics; struct pva_task_statistics_s statistics;
struct pva_circular_buffer_info_s stdout_cb_info; 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; 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. * 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 */ /*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. * R5 FW reserves one DMA channel for internal use.
*/ */
#define NVPVA_TASK_MAX_DMA_CHANNELS 16U #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_MAX_FENCE_TYPES * sizeof(struct nvpva_fence_action) + \
NVPVA_TASK_MAX_INPUT_STATUS * sizeof(struct nvpva_mem) + \ NVPVA_TASK_MAX_INPUT_STATUS * sizeof(struct nvpva_mem) + \
NVPVA_TASK_MAX_OUTPUT_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) + \ sizeof(struct nvpva_dma_descriptor) + \
NVPVA_TASK_MAX_DMA_CHANNELS * sizeof(struct nvpva_dma_channel) + \ NVPVA_TASK_MAX_DMA_CHANNELS * sizeof(struct nvpva_dma_channel) + \
sizeof(struct nvpva_hwseq_config) + \ sizeof(struct nvpva_hwseq_config) + \