mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 09:11:26 +03:00
drivers: pva: ignore blk height if pitch transfers
If all linked descripotrs on a channel only use pitch linear transfers, then ignore block height value passed in to the driver. in all cases, value of block height should be a valid value Bug 4185299 Change-Id: Iad795f9799de9422f787f3e6cd6414b2825aeb60 Signed-off-by: omar <onemri@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2980988 GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> Reviewed-by: Vivek Bangera <vbangera@nvidia.com>
This commit is contained in:
@@ -742,6 +742,7 @@ static int32_t nvpva_task_dma_desc_mapping(struct pva_submit_task *task,
|
|||||||
struct pva_hw_task *hw_task,
|
struct pva_hw_task *hw_task,
|
||||||
uint num_descs,
|
uint num_descs,
|
||||||
u8 *did,
|
u8 *did,
|
||||||
|
u8 *bl_xfers_in_use,
|
||||||
u8 *block_height_log2)
|
u8 *block_height_log2)
|
||||||
{
|
{
|
||||||
struct nvpva_dma_descriptor *umd_dma_desc = NULL;
|
struct nvpva_dma_descriptor *umd_dma_desc = NULL;
|
||||||
@@ -786,6 +787,10 @@ static int32_t nvpva_task_dma_desc_mapping(struct pva_submit_task *task,
|
|||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
/* return flag if block linear format is in use */
|
||||||
|
if ((umd_dma_desc->srcFormat == 1) || (umd_dma_desc->dstFormat == 1))
|
||||||
|
*bl_xfers_in_use |= 1;
|
||||||
|
|
||||||
/* DMA_DESC_TRANS CNTL0 */
|
/* DMA_DESC_TRANS CNTL0 */
|
||||||
dma_desc->transfer_control0 =
|
dma_desc->transfer_control0 =
|
||||||
umd_dma_desc->srcTransferMode |
|
umd_dma_desc->srcTransferMode |
|
||||||
@@ -926,7 +931,9 @@ static int
|
|||||||
verify_dma_desc_hwseq(struct pva_submit_task *task,
|
verify_dma_desc_hwseq(struct pva_submit_task *task,
|
||||||
struct nvpva_dma_channel *user_ch,
|
struct nvpva_dma_channel *user_ch,
|
||||||
struct pva_hw_sweq_blob_s *blob,
|
struct pva_hw_sweq_blob_s *blob,
|
||||||
u32 did)
|
u32 did,
|
||||||
|
u16 mode,
|
||||||
|
u8 *bl_xfers_in_use)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
u64 *desc_hwseq_frm = &task->desc_hwseq_frm;
|
u64 *desc_hwseq_frm = &task->desc_hwseq_frm;
|
||||||
@@ -943,14 +950,19 @@ verify_dma_desc_hwseq(struct pva_submit_task *task,
|
|||||||
|
|
||||||
did = array_index_nospec((did - 1),
|
did = array_index_nospec((did - 1),
|
||||||
NVPVA_TASK_MAX_DMA_DESCRIPTORS);
|
NVPVA_TASK_MAX_DMA_DESCRIPTORS);
|
||||||
|
desc = &task->dma_descriptors[did];
|
||||||
|
|
||||||
|
/* return flag if block linear format is in use */
|
||||||
|
if ((desc->srcFormat == 1)
|
||||||
|
|| (desc->dstFormat == 1))
|
||||||
|
*bl_xfers_in_use |= 1;
|
||||||
|
if (is_desc_mode(mode))
|
||||||
|
goto out;
|
||||||
|
|
||||||
if ((*desc_hwseq_frm & (1ULL << did)) != 0ULL)
|
if ((*desc_hwseq_frm & (1ULL << did)) != 0ULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
*desc_hwseq_frm |= (1ULL << did);
|
*desc_hwseq_frm |= (1ULL << did);
|
||||||
|
|
||||||
desc = &task->dma_descriptors[did];
|
|
||||||
|
|
||||||
if ((desc->px != 0U)
|
if ((desc->px != 0U)
|
||||||
|| (desc->py != 0U)
|
|| (desc->py != 0U)
|
||||||
|| (desc->descReloadEnable != 0U)) {
|
|| (desc->descReloadEnable != 0U)) {
|
||||||
@@ -1712,8 +1724,8 @@ verify_hwseq_blob(struct pva_submit_task *task,
|
|||||||
struct nvpva_dma_channel *user_ch,
|
struct nvpva_dma_channel *user_ch,
|
||||||
struct nvpva_dma_descriptor *decriptors,
|
struct nvpva_dma_descriptor *decriptors,
|
||||||
uint8_t *hwseqbuf_cpuva,
|
uint8_t *hwseqbuf_cpuva,
|
||||||
|
u8 *bl_xfers_in_use,
|
||||||
int8_t ch_num)
|
int8_t ch_num)
|
||||||
|
|
||||||
{
|
{
|
||||||
struct pva_hw_sweq_blob_s *blob;
|
struct pva_hw_sweq_blob_s *blob;
|
||||||
struct pva_hwseq_desc_header_s *blob_desc;
|
struct pva_hwseq_desc_header_s *blob_desc;
|
||||||
@@ -1762,17 +1774,16 @@ verify_hwseq_blob(struct pva_submit_task *task,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_desc_mode(blob->f_header.fid)) {
|
if ((!is_desc_mode(blob->f_header.fid))
|
||||||
if (task->hwseq_config.hwseqTrigMode == NVPVA_HWSEQTM_DMATRIG) {
|
&& !is_frame_mode(blob->f_header.fid)) {
|
||||||
pr_err("dma master not allowed");
|
pr_err("invalid addressing mode");
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
}
|
|
||||||
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_frame_mode(blob->f_header.fid)) {
|
if ((is_desc_mode(blob->f_header.fid))
|
||||||
pr_err("invalid addressing mode");
|
&& task->hwseq_config.hwseqTrigMode == NVPVA_HWSEQTM_DMATRIG) {
|
||||||
|
pr_err("dma master not allowed");
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -1796,7 +1807,9 @@ verify_hwseq_blob(struct pva_submit_task *task,
|
|||||||
"n_descs=%d, n_entries=%d",
|
"n_descs=%d, n_entries=%d",
|
||||||
num_descriptors,
|
num_descriptors,
|
||||||
num_desc_entries);
|
num_desc_entries);
|
||||||
if (num_descriptors > PVA_HWSEQ_DESC_LIMIT) {
|
|
||||||
|
if ((is_frame_mode(blob->f_header.fid))
|
||||||
|
&& (num_descriptors > PVA_HWSEQ_DESC_LIMIT)) {
|
||||||
pr_err("number of descriptors is greater than %d",
|
pr_err("number of descriptors is greater than %d",
|
||||||
PVA_HWSEQ_DESC_LIMIT);
|
PVA_HWSEQ_DESC_LIMIT);
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
@@ -1819,7 +1832,10 @@ verify_hwseq_blob(struct pva_submit_task *task,
|
|||||||
err = verify_dma_desc_hwseq(task,
|
err = verify_dma_desc_hwseq(task,
|
||||||
user_ch,
|
user_ch,
|
||||||
blob,
|
blob,
|
||||||
blob_desc->did1);
|
blob_desc->did1,
|
||||||
|
blob->f_header.fid,
|
||||||
|
bl_xfers_in_use);
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
pr_err("seq descriptor 1 verification failed");
|
pr_err("seq descriptor 1 verification failed");
|
||||||
goto out;
|
goto out;
|
||||||
@@ -1827,13 +1843,16 @@ 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);
|
NVPVA_TASK_MAX_DMA_DESCRIPTORS);
|
||||||
|
desc_block_height_log2[did] = user_ch->blockHeight;
|
||||||
|
if (!is_desc_mode(blob->f_header.fid)) {
|
||||||
desc_entries[k].did = did;
|
desc_entries[k].did = did;
|
||||||
desc_entries[k].dr = blob_desc->dr1;
|
desc_entries[k].dr = blob_desc->dr1;
|
||||||
hwseq_info->tiles_per_packet += (blob_desc->dr1 + 1U);
|
hwseq_info->tiles_per_packet += (blob_desc->dr1 + 1U);
|
||||||
nvpva_dbg_fn(task->pva,
|
nvpva_dbg_fn(task->pva,
|
||||||
"tiles per packet=%d",
|
"tiles per packet=%d",
|
||||||
hwseq_info->tiles_per_packet);
|
hwseq_info->tiles_per_packet);
|
||||||
desc_block_height_log2[did] = user_ch->blockHeight;
|
}
|
||||||
|
|
||||||
++k;
|
++k;
|
||||||
if (k >= num_descriptors) {
|
if (k >= num_descriptors) {
|
||||||
++blob_desc;
|
++blob_desc;
|
||||||
@@ -1843,7 +1862,10 @@ verify_hwseq_blob(struct pva_submit_task *task,
|
|||||||
err = verify_dma_desc_hwseq(task,
|
err = verify_dma_desc_hwseq(task,
|
||||||
user_ch,
|
user_ch,
|
||||||
blob,
|
blob,
|
||||||
blob_desc->did2);
|
blob_desc->did2,
|
||||||
|
blob->f_header.fid,
|
||||||
|
bl_xfers_in_use);
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
pr_err("seq descriptor 2 verification failed");
|
pr_err("seq descriptor 2 verification failed");
|
||||||
goto out;
|
goto out;
|
||||||
@@ -1851,13 +1873,16 @@ 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);
|
NVPVA_TASK_MAX_DMA_DESCRIPTORS);
|
||||||
|
desc_block_height_log2[did] = user_ch->blockHeight;
|
||||||
|
if (!is_desc_mode(blob->f_header.fid)) {
|
||||||
desc_entries[k].did = did;
|
desc_entries[k].did = did;
|
||||||
desc_entries[k].dr = blob_desc->dr2;
|
desc_entries[k].dr = blob_desc->dr2;
|
||||||
hwseq_info->tiles_per_packet += (blob_desc->dr2 + 1U);
|
hwseq_info->tiles_per_packet += (blob_desc->dr2 + 1U);
|
||||||
nvpva_dbg_fn(task->pva,
|
nvpva_dbg_fn(task->pva,
|
||||||
"tiles per packet=%d",
|
"tiles per packet=%d",
|
||||||
hwseq_info->tiles_per_packet);
|
hwseq_info->tiles_per_packet);
|
||||||
desc_block_height_log2[did] = user_ch->blockHeight;
|
}
|
||||||
|
|
||||||
++blob_desc;
|
++blob_desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1874,10 +1899,32 @@ verify_hwseq_blob(struct pva_submit_task *task,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!is_desc_mode(blob->f_header.fid)) {
|
||||||
hwseq_info->dma_descs = (struct pva_hwseq_desc_header_s *) desc_entries;
|
hwseq_info->dma_descs = (struct pva_hwseq_desc_header_s *) desc_entries;
|
||||||
hwseq_info->head_desc = &decriptors[desc_entries[0].did];
|
hwseq_info->head_desc = &decriptors[desc_entries[0].did];
|
||||||
hwseq_info->tail_desc = &decriptors[desc_entries[num_descriptors - 1U].did];
|
hwseq_info->tail_desc = &decriptors[desc_entries[num_descriptors - 1U].did];
|
||||||
hwseq_info->verify_bounds = true;
|
hwseq_info->verify_bounds = true;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
nvpva_update_blockheight(struct pva_dma_ch_config_s *ch,
|
||||||
|
u8 block_height_log2)
|
||||||
|
{
|
||||||
|
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
/* DMA_CHANNEL_CNTL0_CHBH */
|
||||||
|
if (block_height_log2 > NVPVA_MAX_VALID_BLK_HGT_LG2) {
|
||||||
|
pr_err("ERR: Invalid block height");
|
||||||
|
err = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ch->cntl0 &= ~(0x7U << 25U);
|
||||||
|
ch->cntl0 |= ((block_height_log2 & 7U) << 25U);
|
||||||
out:
|
out:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -1896,7 +1943,7 @@ nvpva_task_dma_channel_mapping(struct pva_submit_task *task,
|
|||||||
struct nvpva_dma_descriptor *decriptors = task->dma_descriptors;
|
struct nvpva_dma_descriptor *decriptors = task->dma_descriptors;
|
||||||
u32 adb_limit;
|
u32 adb_limit;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
u8 block_height_log2 = user_ch->blockHeight;
|
u8 bl_xfers_in_use = 0;
|
||||||
|
|
||||||
nvpva_dbg_fn(task->pva, "");
|
nvpva_dbg_fn(task->pva, "");
|
||||||
|
|
||||||
@@ -1927,14 +1974,11 @@ nvpva_task_dma_channel_mapping(struct pva_submit_task *task,
|
|||||||
|
|
||||||
ch->cntl0 |= ((user_ch->adbSize & 0x1FFU) << 16U);
|
ch->cntl0 |= ((user_ch->adbSize & 0x1FFU) << 16U);
|
||||||
|
|
||||||
/* DMA_CHANNEL_CNTL0_CHBH */
|
/*
|
||||||
if (block_height_log2 > NVPVA_MAX_VALID_BLK_HGT_LG2) {
|
* defer updating block height until it is known if there are
|
||||||
pr_err("ERR: Invalid block height");
|
* block linear transfers on the channel. set default value.
|
||||||
err = -EINVAL;
|
*/
|
||||||
goto out;
|
ch->cntl0 |= (0x5U << 25U);
|
||||||
}
|
|
||||||
|
|
||||||
ch->cntl0 |= ((block_height_log2 & 7U) << 25U);
|
|
||||||
|
|
||||||
/* DMA_CHANNEL_CNTL0_CHPREF */
|
/* DMA_CHANNEL_CNTL0_CHPREF */
|
||||||
ch->cntl0 |= ((user_ch->prefetchEnable & 1U) << 30U);
|
ch->cntl0 |= ((user_ch->prefetchEnable & 1U) << 30U);
|
||||||
@@ -1992,8 +2036,11 @@ nvpva_task_dma_channel_mapping(struct pva_submit_task *task,
|
|||||||
user_ch,
|
user_ch,
|
||||||
decriptors,
|
decriptors,
|
||||||
hwseqbuf_cpuva,
|
hwseqbuf_cpuva,
|
||||||
|
&bl_xfers_in_use,
|
||||||
ch_num);
|
ch_num);
|
||||||
|
|
||||||
|
if (!err && (bl_xfers_in_use != 0))
|
||||||
|
err = nvpva_update_blockheight(ch, user_ch->blockHeight);
|
||||||
out:
|
out:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -2014,6 +2061,7 @@ int pva_task_write_dma_info(struct pva_submit_task *task,
|
|||||||
u8 *desc_block_height_log2 = task->desc_block_height_log2;
|
u8 *desc_block_height_log2 = task->desc_block_height_log2;
|
||||||
u8 did;
|
u8 did;
|
||||||
u8 prev_did;
|
u8 prev_did;
|
||||||
|
u8 bl_xfers_in_use = 0;
|
||||||
|
|
||||||
nvpva_dbg_fn(task->pva, "");
|
nvpva_dbg_fn(task->pva, "");
|
||||||
|
|
||||||
@@ -2078,6 +2126,7 @@ int pva_task_write_dma_info(struct pva_submit_task *task,
|
|||||||
for (i = 0; i < task->num_dma_channels; i++) {
|
for (i = 0; i < task->num_dma_channels; i++) {
|
||||||
struct nvpva_dma_channel *user_ch = &task->dma_channels[i];
|
struct nvpva_dma_channel *user_ch = &task->dma_channels[i];
|
||||||
|
|
||||||
|
bl_xfers_in_use = 0;
|
||||||
ch_num = i + 1; /* Channel 0 can't use */
|
ch_num = i + 1; /* Channel 0 can't use */
|
||||||
err = nvpva_task_dma_channel_mapping(
|
err = nvpva_task_dma_channel_mapping(
|
||||||
task,
|
task,
|
||||||
@@ -2132,12 +2181,17 @@ int pva_task_write_dma_info(struct pva_submit_task *task,
|
|||||||
hw_task,
|
hw_task,
|
||||||
1,
|
1,
|
||||||
&did,
|
&did,
|
||||||
|
&bl_xfers_in_use,
|
||||||
desc_block_height_log2);
|
desc_block_height_log2);
|
||||||
if (err) {
|
if (err) {
|
||||||
task_err(task, "failed to map DMA desc info");
|
task_err(task, "failed to map DMA desc info");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bl_xfers_in_use != 0)
|
||||||
|
nvpva_update_blockheight(&hw_task_dma_info->dma_channels[i],
|
||||||
|
user_ch->blockHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
did = 0;
|
did = 0;
|
||||||
@@ -2145,6 +2199,7 @@ int pva_task_write_dma_info(struct pva_submit_task *task,
|
|||||||
hw_task,
|
hw_task,
|
||||||
task->num_dma_descriptors,
|
task->num_dma_descriptors,
|
||||||
&did,
|
&did,
|
||||||
|
&bl_xfers_in_use,
|
||||||
desc_block_height_log2);
|
desc_block_height_log2);
|
||||||
if (err) {
|
if (err) {
|
||||||
task_err(task, "failed to map DMA desc info");
|
task_err(task, "failed to map DMA desc info");
|
||||||
|
|||||||
Reference in New Issue
Block a user