mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-25 10:42:21 +03:00
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:
36
drivers/video/tegra/host/pva/fw_config_t264.h
Normal file
36
drivers/video/tegra/host/pva/fw_config_t264.h
Normal 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
|
||||
@@ -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__ */
|
||||
|
||||
173
drivers/video/tegra/host/pva/pva_hwseq_t264.h
Normal file
173
drivers/video/tegra/host/pva/pva_hwseq_t264.h
Normal 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
|
||||
Reference in New Issue
Block a user