drivers: pva: Update HW SEQ and ADB for T26x

- T26x support 304 ADBs compared to 272 on T23x. Add code to support
this distinction.

- T26x introduces the following updates to HWSEQ:
	- a new HWSEQ mode - Random Region Access (RRA).
	- increased HWSEQ RAM size of 2KB.
  Add code to support these changes.

Jira PVAAS-13252

Change-Id: I92d65524b526eda1be8f8dc81dc4e41d0db7f488
Signed-off-by: abhinayaa <abhinayaa@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-t264/+/2926761
Reviewed-by: Sreehari Mohan <sreeharim@nvidia.com>
Reviewed-by: Amruta Sai Anusha Bhamidipati <abhamidipati@nvidia.com>
Reviewed-by: Omar Nemri <onemri@nvidia.com>
GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
abhinayaa
2023-06-27 01:04:31 +00:00
committed by Jon Hunter
parent 1f317971e6
commit 569844dd83
3 changed files with 241 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
/*
* Copyright (c) 2023, 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 <http://www.gnu.org/licenses/>.
*/
#ifndef FW_CONFIG_T264_H
#define FW_CONFIG_T264_H
/**
* @brief Total number of AXI data buffers for T26x.
*/
#define PVA_NUM_DMA_ADB_BUFFS_T26X 304U
/**
* @brief Number of reserved AXI data buffers for T26x.
*/
#define PVA_NUM_RESERVED_ADB_BUFFERS_T26X 16U
/**
* @brief Number of dynamic AXI data buffers for T26x.
* These exclude the reserved AXI data buffers from total available ones.
*/
#define PVA_NUM_DYNAMIC_ADB_BUFFS_T26X \
(PVA_NUM_DMA_ADB_BUFFS_T26X - PVA_NUM_RESERVED_ADB_BUFFERS_T26X)
#endif

View File

@@ -37,5 +37,37 @@
* R5 FW reserves one DMA channel for internal use.
*/
#define NVPVA_TASK_MAX_DMA_CHANNELS_T26X (15U)
/* NOTE: This is a re-definition of nvpva_dma_channel that
* contains T26x specific changes. Once T26x is public,
* this definition may be merged nvpva_dma_channel.
*
* Also note that the flags1 field has the following flags:
* - MSB for the HW Sequencer start index field in channel registers
* DMA_CHANNEL_HWSEQCNTL[1].bit[0] = flags1[0].bit[0];
* - MSB for the HW Sequencer end index field in channel registers
* DMA_CHANNEL_HWSEQCNTL[2].bit[4] = flags1[0].bit[2];
*/
struct nvpva_dma_channel_ex {
uint8_t descIndex;
uint8_t blockHeight;
uint16_t adbSize;
uint8_t vdbSize;
uint16_t adbOffset;
uint8_t vdbOffset;
uint32_t outputEnableMask;
uint32_t padValue;
uint8_t reqPerGrant;
uint8_t prefetchEnable;
uint8_t chRepFactor;
uint8_t hwseqStart;
uint8_t hwseqEnd;
uint8_t hwseqEnable;
uint8_t hwseqTraversalOrder;
uint8_t hwseqTxSelect;
uint8_t hwseqTriggerDone;
uint8_t hwseqFrameCount;
uint8_t hwseqConFrameSeq;
uint8_t flags1;
};
#endif /* __NVPVA_IOCTL_T264_H__ */

View File

@@ -0,0 +1,173 @@
/*
* Copyright (c) 2023, 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 <http://www.gnu.org/licenses/>.
*/
#ifndef PVA_HWSEQ_T264_H
#define PVA_HWSEQ_T264_H
#define PVA_HWSEQ_RAM_SIZE_T26X 2048U
#define PVA_HWSEQ_RAM_ID_MASK_T26X 0x1FFU
#define PVA_HWSEQ_RRA_ADDR 0xC0DAU
#define PVA_HWSEQ_RRA_MAX_NOCR 31U
#define PVA_HWSEQ_RRA_MAX_FRAME_COUNT 63U
/** \brief Mask used to derive the MSB for HW sequencer
* buffer start index for a channel
*/
#define PVA_CH_FLAGS1_HWSEQ_START_IDX_MSB_MASK (1U)
/** \brief Mask used to derive the MSB for HW sequencer
* buffer start index for a channel
*/
#define PVA_CH_FLAGS1_HWSEQ_START_IDX_MSB_SHIFT (0U)
/** \brief Mask used to derive the MSB for HW sequencer
* buffer end index for a channel
*/
#define PVA_CH_FLAGS1_HWSEQ_END_IDX_MSB_MASK (1U << 2U)
/** \brief Mask used to derive the MSB for HW sequencer
* buffer end index for a channel
*/
#define PVA_CH_FLAGS1_HWSEQ_END_IDX_MSB_SHIFT (2U)
#define PVA_CH_FLAGS1_HWSEQ_START_IDX_MSB(flag) \
((flag & PVA_CH_FLAGS1_HWSEQ_START_IDX_MSB_MASK) \
>> PVA_CH_FLAGS1_HWSEQ_START_IDX_MSB_SHIFT)
#define PVA_CH_FLAGS1_HWSEQ_END_IDX_MSB(flag) \
((flag & PVA_CH_FLAGS1_HWSEQ_END_IDX_MSB_MASK) \
>> PVA_CH_FLAGS1_HWSEQ_END_IDX_MSB_SHIFT)
static inline bool is_rra_mode(u16 id)
{
return (id == PVA_HWSEQ_RRA_ADDR);
}
static inline u32 nvpva_get_hwseq_start_idx_t26x(
struct nvpva_dma_channel *user_ch)
{
u32 idx = ((user_ch->hwseqStart & 0xFF)
| (PVA_CH_FLAGS1_HWSEQ_START_IDX_MSB(user_ch->flags1) << 8U));
return (idx & (u32)PVA_HWSEQ_RAM_ID_MASK_T26X);
}
static inline u32 nvpva_get_hwseq_end_idx_t26x(
struct nvpva_dma_channel *user_ch)
{
u32 idx = ((user_ch->hwseqEnd & 0xFF)
| (PVA_CH_FLAGS1_HWSEQ_END_IDX_MSB(user_ch->flags1) << 8U));
return (idx & (u32)PVA_HWSEQ_RAM_ID_MASK_T26X);
}
static int validate_rra_mode(struct pva_hw_sweq_blob_s *blob,
struct pva_submit_task *task,
struct nvpva_dma_channel *dma_ch)
{
const u8 *desc_entry = NULL;
const u8 *column = 0U;
uint32_t i = 0U;
uint32_t num_columns = 0U;
u32 end = nvpva_get_hwseq_end_idx_t26x(dma_ch) * 4U;
u8 *blob_end = &((uint8_t *)blob)[end + 4];
// In each NOCR entry, 4 bytes are used for CRO
// and 4 bytes are used for Desc info
const u8 column_entry_size = 8U;
if (task->pva->version < PVA_HW_GEN3) {
pr_err("Selected HWSEQ mode is not supported");
return -EINVAL;
}
if (dma_ch->hwseqFrameCount > PVA_HWSEQ_RRA_MAX_FRAME_COUNT) {
pr_err("Invalid HWSEQ frame count");
return -EINVAL;
}
if (blob->f_header.no_cr > PVA_HWSEQ_RRA_MAX_NOCR) {
pr_err("Invalid HWSEQ column count");
return -EINVAL;
}
if (blob->f_header.fr != 0) {
pr_err("Invalid HWSEQ repetition factor");
return -EINVAL;
}
num_columns = blob->f_header.no_cr + 1U;
column = (u8 *)&blob->cr_header;
desc_entry = (u8 *)&blob->desc_header;
// Ensure there are sufficient CRO and Desc ID entries in the HWSEQ blob
if (((blob_end - column) / column_entry_size) < num_columns) {
pr_err("HWSEQ Program does not have enough columns");
return -EINVAL;
}
for (i = 0U; i < num_columns; i++) {
// In RRA mode, each HWSEQ column has only 1 descriptor
// Hence, we validate the first descriptor and ignore the second
// descriptor in each column
if ((*desc_entry == 0U) ||
(*desc_entry > (NVPVA_TASK_MAX_DMA_DESCRIPTOR_ID_T26X))) {
pr_err("Invalid Descritor ID found in HW Sequencer");
return -EINVAL;
}
desc_entry += column_entry_size;
}
return 0;
}
static inline bool hwseq_blob_validate_t26x(struct pva_hw_sweq_blob_s *blob,
struct pva_submit_task *task,
struct nvpva_dma_channel *dma_ch,
bool *validation_done)
{
if (is_rra_mode(blob->f_header.fid)) {
*validation_done = true;
if (validate_rra_mode(blob, task, dma_ch) != 0) {
return false;
}
} else {
*validation_done = false;
}
return true;
}
static inline void nvpva_task_dma_channel_mapping_t26x(
struct pva_dma_ch_config_s *ch,
struct nvpva_dma_channel *user_ch)
{
/* DMA_CHANNEL_HWSEQCNTL_CHHWSEQSTART */
/* Note: the MSB for HWSEQ start idx comes from bit 0 of flags1 field*/
ch->hwseqcntl &= ~((u32)PVA_HWSEQ_RAM_ID_MASK_T26X);
ch->hwseqcntl |= nvpva_get_hwseq_start_idx_t26x(user_ch);
/* DMA_CHANNEL_HWSEQCNTL_CHHWSEQEND */
/* Note: the MSB for HWSEQ end idx comes from bit 2 of flags1 field*/
ch->hwseqcntl &= (~((u32)PVA_HWSEQ_RAM_ID_MASK_T26X << 12U));
ch->hwseqcntl |= (nvpva_get_hwseq_end_idx_t26x(user_ch) << 12U);
/* DMA_CHANNEL_HWSEQFSCNTL_CHHWSEQFCNT*/
ch->hwseqfscntl |= (((uint32_t)user_ch->hwseqConFrameSeq & 0x1U) << 0U);
/* DMA_CHANNEL_HWSEQFSCNTL_CHHWSEQCFS*/
ch->hwseqfscntl |= (((uint32_t)user_ch->hwseqFrameCount & 0x3FU) << 16U);
}
#endif