580.65.06

This commit is contained in:
Maneet Singh
2025-08-04 11:15:02 -07:00
parent d890313300
commit 307159f262
1315 changed files with 477791 additions and 279973 deletions

View File

@@ -83,6 +83,7 @@ typedef struct tagHDMI_QUERY_FRL_CLIENT_CONTROL
NvU32 forceFRLRate : 1;
NvU32 forceAudio2Ch48KHz : 1;
NvU32 forceDisableDSC : 1;
NvU32 enableDSC : 1;
NvU32 forceSliceCount : 1;
NvU32 forceSliceWidth : 1;

View File

@@ -56,6 +56,8 @@
#include "class/clca7d.h"
#include "class/clcb70.h"
#include "class/clcb7d.h"
#include "class/clcc70.h"
#include "class/clcc7d.h"
#include "hdmi_spec.h"
@@ -223,12 +225,22 @@ static const NVHDMIPKT_CLASS_HIERARCHY hierarchy[] =
NVHDMIPKT_CB71_CLASS, // classId
NVHDMIPKT_C971_CLASS, // parentClassId
NV_FALSE, // isRootClass
initializeHdmiPktInterfaceC971, // initInterface
initializeHdmiPktInterfaceCB71, // initInterface
hdmiConstructorC971, // constructor
hdmiDestructorC971, // destructor
NVCB70_DISPLAY, // displayClass
NVCB7D_CORE_CHANNEL_DMA // coreDmaClass
},
[NVHDMIPKT_CC71_CLASS] = {// Index 13==NVHDMIPKT_CC71_CLASS
NVHDMIPKT_CC71_CLASS, // classId
NVHDMIPKT_C971_CLASS, // parentClassId
NV_FALSE, // isRootClass
initializeHdmiPktInterfaceCC71, // initInterface
hdmiConstructorC971, // constructor
hdmiDestructorC971, // destructor
NVCC70_DISPLAY, // displayClass
NVCC7D_CORE_CHANNEL_DMA // coreDmaClass
},
};
/********************************** HDMI Library interfaces *************************************/

View File

@@ -364,8 +364,7 @@ static void populateDscCaps(HDMI_SRC_CAPS const * const pSrcCaps,
// Per DSC v1.2 spec, native 422/420 per-slice peak throughput is approximately twice of RGB/444 peak throughput
// HDMI has only one throughput cap reporting, no separate 422/420 throughput cap unlike for DP, so just double 444's value here.
pDscInfo->sinkCaps.peakThroughputMode1 = (peakThroughput == DSC_DECODER_PEAK_THROUGHPUT_MODE0_340) ?
DSC_DECODER_PEAK_THROUGHPUT_MODE1_650 : // closest approximation to 680Mhz
DSC_DECODER_PEAK_THROUGHPUT_MODE1_800;
DSC_DECODER_PEAK_THROUGHPUT_MODE1_680 : DSC_DECODER_PEAK_THROUGHPUT_MODE1_800;
}
// Fill in mode related info for DSC lib
@@ -585,6 +584,13 @@ static void calcBppMinMax(HDMI_SRC_CAPS const *pSrcCaps,
{
bppMaxX16 = (bppMaxX16 > 12*16) ? 12*16 : bppMaxX16;
}
// DSC_GeneratePPS : Multi-tile configs (NVD 5.0 and later),
// because of architectural limitation we can't use bits_per_pixel more than 16.
if (pSrcCaps->dscCaps.maxNumHztSlices > 4U)
{
bppMaxX16 = (bppMaxX16 > 16*16) ? 16*16 : bppMaxX16;
}
if (pVidTransInfo->bDualHeadMode && (bppMaxX16 > pSrcCaps->dscCaps.dualHeadBppTargetMaxX16))
{
@@ -781,12 +787,22 @@ hdmiQueryFRLConfigC671(NVHDMIPKT_CLASS *pThis,
&frlParams);
calcBppMinMax(pSrcCaps, pSinkCaps, pVidTransInfo, &bppMinX16, &bppMaxX16);
bCanUseDSC = evaluateIsDSCPossible(pThis, pSrcCaps, pSinkCaps, pVidTransInfo, &frlParams);
if (pClientCtrl->forceDisableDSC)
{
bCanUseDSC = NV_FALSE;
}
else
{
bCanUseDSC = evaluateIsDSCPossible(pThis, pSrcCaps, pSinkCaps, pVidTransInfo, &frlParams);
}
const NvU32 numHeadsDrivingSink = pVidTransInfo->bDualHeadMode ? 2 : 1;
// Input validation
// Note, maxNumHztSlices src cap is per head. account for total number of heads driving the sink
if ((pClientCtrl->forceFRLRate && (pClientCtrl->frlRate > pSinkCaps->linkMaxFRLRate)) ||
(pClientCtrl->enableDSC && pClientCtrl->forceDisableDSC) ||
(pClientCtrl->enableDSC && !bCanUseDSC) ||
(pClientCtrl->forceSliceCount && (pClientCtrl->sliceCount >
(NvU32)(NV_MIN(pSrcCaps->dscCaps.maxNumHztSlices * numHeadsDrivingSink,

View File

@@ -0,0 +1,46 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* File: nvhdmipkt_CB71.c
*
*/
#include "nvhdmipkt_common.h"
/*
* Purpose: Provides packet write functions for HDMI library for NVD5.0 chips
*/
#include "nvhdmipkt_class.h"
#include "nvhdmipkt_internal.h"
#include "class/clcb71.h"
// non-HW - class utility/maintenance functions
/*
* initializeHdmiPktInterfaceCB71
*/
void
initializeHdmiPktInterfaceCB71(NVHDMIPKT_CLASS* pClass)
{
// Update SF_USER data
pClass->dispSfUserClassId = NVCB71_DISP_SF_USER;
pClass->dispSfUserSize = sizeof(NvCB71DispSfUserMap);
}

View File

@@ -0,0 +1,46 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* File: nvhdmipkt_CC71.c
*
*/
#include "nvhdmipkt_common.h"
/*
* Purpose: Provides packet write functions for HDMI library for NVD5.0 chips
*/
#include "nvhdmipkt_class.h"
#include "nvhdmipkt_internal.h"
#include "class/clcc71.h"
// non-HW - class utility/maintenance functions
/*
* initializeHdmiPktInterfaceCC71
*/
void
initializeHdmiPktInterfaceCC71(NVHDMIPKT_CLASS* pClass)
{
// Update SF_USER data
pClass->dispSfUserClassId = NVCC71_DISP_SF_USER;
pClass->dispSfUserSize = sizeof(NvCC71DispSfUserMap);
}

View File

@@ -52,6 +52,7 @@ typedef enum
NVHDMIPKT_C971_CLASS = 10, // NVD5.0
NVHDMIPKT_CA71_CLASS = 11,
NVHDMIPKT_CB71_CLASS = 12,
NVHDMIPKT_CC71_CLASS = 13,
NVHDMIPKT_INVALID_CLASS // Not to be used by client, and always the last entry here.
} NVHDMIPKT_CLASS_ID;

View File

@@ -48,6 +48,8 @@ extern void initializeHdmiPktInterfaceC771(NVHDMIPKT_CLASS*);
extern void initializeHdmiPktInterfaceC871(NVHDMIPKT_CLASS*);
extern void initializeHdmiPktInterfaceC971(NVHDMIPKT_CLASS*);
extern void initializeHdmiPktInterfaceCA71(NVHDMIPKT_CLASS*);
extern void initializeHdmiPktInterfaceCB71(NVHDMIPKT_CLASS*);
extern void initializeHdmiPktInterfaceCC71(NVHDMIPKT_CLASS*);
extern NvBool hdmiConstructor0073(NVHDMIPKT_CLASS*);
extern void hdmiDestructor0073 (NVHDMIPKT_CLASS*);

View File

@@ -225,7 +225,7 @@ NVT_STATUS NvTiming_CalcCVT(NvU32 width, NvU32 height, NvU32 rr, NvU32 flag, NVT
pT->etc.flag = 0;
pT->etc.rr = (NvU16)rr;
pT->etc.rrx1k = axb_div_c((NvU32)pT->pclk, (NvU32)10000*(NvU32)1000, (NvU32)pT->HTotal*(NvU32)pT->VTotal);
pT->etc.rrx1k = axb_div_c((NvU32)pT->pclk1khz, (NvU32)1000*(NvU32)1000, (NvU32)pT->HTotal*(NvU32)pT->VTotal);
pT->etc.aspect = 0;
pT->etc.rep = 0x1;
NVT_SNPRINTF((char *)pT->etc.name, 40, "CVT:%dx%dx%dHz",width, height, rr);
@@ -240,6 +240,7 @@ NVT_STATUS NvTiming_CalcCVT(NvU32 width, NvU32 height, NvU32 rr, NvU32 flag, NVT
pT->interlaced = NVT_INTERLACED_NO_EXTRA_VBLANK_ON_FIELD2;
pT->pclk >>= 1;
pT->pclk1khz >>= 1;
pT->VTotal >>= 1;
pT->VVisible = (pT->VVisible + 1) / 2;
}
@@ -299,6 +300,7 @@ NVT_STATUS NvTiming_CalcCVT_RB(NvU32 width, NvU32 height, NvU32 rr, NvU32 flag,
pT->VSyncWidth = (NvU16)dwVSyncWidth;
pT->pclk = dwPClk;
pT->pclk1khz = (dwPClk << 3) + (dwPClk << 1); // *10;
pT->HSyncPol = NVT_H_SYNC_POSITIVE;
pT->VSyncPol = NVT_V_SYNC_NEGATIVE;
@@ -310,7 +312,7 @@ NVT_STATUS NvTiming_CalcCVT_RB(NvU32 width, NvU32 height, NvU32 rr, NvU32 flag,
// fill in the extra timing info
pT->etc.flag = 0;
pT->etc.rr = (NvU16)rr;
pT->etc.rrx1k = axb_div_c((NvU32)pT->pclk, (NvU32)10000*(NvU32)1000, (NvU32)pT->HTotal*(NvU32)pT->VTotal);
pT->etc.rrx1k = axb_div_c((NvU32)pT->pclk1khz, (NvU32)1000*(NvU32)1000, (NvU32)pT->HTotal*(NvU32)pT->VTotal);
pT->etc.aspect = 0;
pT->etc.rep = 0x1;
NVT_SNPRINTF((char *)pT->etc.name, 40, "CVT-RB:%dx%dx%dHz",width, height, rr);
@@ -325,6 +327,7 @@ NVT_STATUS NvTiming_CalcCVT_RB(NvU32 width, NvU32 height, NvU32 rr, NvU32 flag,
pT->interlaced = NVT_INTERLACED_NO_EXTRA_VBLANK_ON_FIELD2;
pT->pclk >>= 1;
pT->pclk1khz >>= 1;
pT->VTotal >>= 1;
pT->VVisible = (pT->VVisible + 1) / 2;
}

View File

@@ -1349,17 +1349,17 @@ parseDisplayId20VendorSpecific(
if (pDataBlock->data_bytes == NVT_VESA_VENDOR_SPECIFIC_LENGTH)
{
pVendorSpecific->vesaVsdb.data_struct_type.type =
block->vendor_specific_data[3] & NVT_VESA_ORG_VSDB_DATA_TYPE_MASK;
block->vendor_specific_data[0] & NVT_VESA_ORG_VSDB_DATA_TYPE_MASK;
pVendorSpecific->vesaVsdb.data_struct_type.color_space_and_eotf =
(block->vendor_specific_data[3] & NVT_VESA_ORG_VSDB_COLOR_SPACE_AND_EOTF_MASK) >> NVT_VESA_ORG_VSDB_COLOR_SPACE_AND_EOTF_SHIFT;
(block->vendor_specific_data[0] & NVT_VESA_ORG_VSDB_COLOR_SPACE_AND_EOTF_MASK) >> NVT_VESA_ORG_VSDB_COLOR_SPACE_AND_EOTF_SHIFT;
pVendorSpecific->vesaVsdb.overlapping.pixels_overlapping_count =
block->vendor_specific_data[4] & NVT_VESA_ORG_VSDB_PIXELS_OVERLAPPING_MASK;
block->vendor_specific_data[1] & NVT_VESA_ORG_VSDB_PIXELS_OVERLAPPING_MASK;
pVendorSpecific->vesaVsdb.overlapping.multi_sst =
(block->vendor_specific_data[4] & NVT_VESA_ORG_VSDB_MULTI_SST_MODE_MASK) >> NVT_VESA_ORG_VSDB_MULTI_SST_MODE_SHIFT;
(block->vendor_specific_data[1] & NVT_VESA_ORG_VSDB_MULTI_SST_MODE_MASK) >> NVT_VESA_ORG_VSDB_MULTI_SST_MODE_SHIFT;
pVendorSpecific->vesaVsdb.pass_through_integer.pass_through_integer_dsc =
block->vendor_specific_data[5] & NVT_VESA_ORG_VSDB_PASS_THROUGH_INTEGER_MASK;
block->vendor_specific_data[2] & NVT_VESA_ORG_VSDB_PASS_THROUGH_INTEGER_MASK;
pVendorSpecific->vesaVsdb.pass_through_fractional.pass_through_fraction_dsc =
block->vendor_specific_data[6] & NVT_VESA_ORG_VSDB_PASS_THROUGH_FRACTIOINAL_MASK;
block->vendor_specific_data[3] & NVT_VESA_ORG_VSDB_PASS_THROUGH_FRACTIOINAL_MASK;
}
else
{
@@ -1640,14 +1640,14 @@ parseDisplayId20Timing7Descriptor(
pTiming->etc.rr = NvTiming_CalcRR(pTiming->pclk1khz,
pTiming->interlaced,
pTiming->HTotal,
pTiming->VTotal) / 10;
pTiming->VTotal);
pTiming->etc.rrx1k = NvTiming_CalcRRx1k(pTiming->pclk1khz,
pTiming->interlaced,
pTiming->HTotal,
pTiming->VTotal) / 10;
pTiming->VTotal);
// pclk change to 10kHz
pTiming->pclk = pTiming->pclk1khz / 10;
pTiming->pclk = (pTiming->pclk1khz + 5) / 10;
pTiming->etc.status = NVT_STATUS_DISPLAYID_7N(++count);

View File

@@ -179,9 +179,7 @@ NVT_STATUS NvTiming_EnumDMT(NvU32 dmtId, NVT_TIMING *pT)
{
*pT = DMT[dmtId - 1];
pT->etc.rrx1k = axb_div_c((NvU32)pT->pclk,
(NvU32)10000*(NvU32)1000,
(NvU32)pT->HTotal*(NvU32)pT->VTotal);
pT->etc.rrx1k = axb_div_c((NvU32)pT->pclk1khz, (NvU32)1000*(NvU32)1000, (NvU32)pT->HTotal*(NvU32)pT->VTotal);
NVT_SNPRINTF((char *)pT->etc.name, 40, "DMT:#%d:%dx%dx%dHz",
dmtId, pT->HVisible, pT->VVisible, pT->etc.rr);
((char *)pT->etc.name)[39] = '\0';
@@ -254,7 +252,7 @@ NVT_STATUS NvTiming_CalcDMT(NvU32 width, NvU32 height, NvU32 rr, NvU32 flag, NVT
{
NVMISC_MEMSET(pT, 0, sizeof(NVT_TIMING));
*pT = *p;
pT->etc.rrx1k = axb_div_c((NvU32)pT->pclk, (NvU32)10000*(NvU32)1000, (NvU32)pT->HTotal*(NvU32)pT->VTotal);
pT->etc.rrx1k = axb_div_c((NvU32)pT->pclk1khz, (NvU32)1000*(NvU32)1000, (NvU32)pT->HTotal*(NvU32)pT->VTotal);
NVT_SNPRINTF((char *)pT->etc.name, 40, "DMT:%dx%dx%dHz",width, height, rr);
pT->etc.name[39] = '\0';
pT->etc.rgb444.bpc.bpc8 = 1;
@@ -294,7 +292,7 @@ NVT_STATUS NvTiming_CalcDMT_RB(NvU32 width, NvU32 height, NvU32 rr, NvU32 flag,
{
NVMISC_MEMSET(pT, 0, sizeof(NVT_TIMING));
*pT = *p;
pT->etc.rrx1k = axb_div_c((NvU32)pT->pclk, (NvU32)10000*(NvU32)1000, (NvU32)pT->HTotal*(NvU32)pT->VTotal);
pT->etc.rrx1k = axb_div_c((NvU32)pT->pclk1khz, (NvU32)1000*(NvU32)1000, (NvU32)pT->HTotal*(NvU32)pT->VTotal);
NVT_SNPRINTF((char *)pT->etc.name, 40, "DMT-RB:%dx%dx%dHz",width, height, rr);
pT->etc.name[39] = '\0';
pT->etc.rgb444.bpc.bpc8 = 1;
@@ -332,7 +330,7 @@ NVT_STATUS NvTiming_CalcDMT_RB2(NvU32 width, NvU32 height, NvU32 rr, NvU32 flag,
{
NVMISC_MEMSET(pT, 0, sizeof(NVT_TIMING));
*pT = *p;
pT->etc.rrx1k = axb_div_c((NvU32)pT->pclk, (NvU32)10000*(NvU32)1000, (NvU32)pT->HTotal*(NvU32)pT->VTotal);
pT->etc.rrx1k = axb_div_c((NvU32)pT->pclk1khz, (NvU32)1000*(NvU32)1000, (NvU32)pT->HTotal*(NvU32)pT->VTotal);
NVT_SNPRINTF((char *)pT->etc.name, 40, "DMT-RB2:%dx%dx%dHz",width, height, rr);
pT->etc.name[39] = '\0';
pT->etc.rgb444.bpc.bpc8 = 1;

View File

@@ -41,6 +41,7 @@
#define MIN_CHECK(s,a,b) { if((a)<(b)) { return (NVT_STATUS_ERR);} }
#define RANGE_CHECK(s,a,b,c) { if((((NvS32)(a))<(NvS32)(b))||(((NvS32)(a))>(NvS32)(c))) { return (NVT_STATUS_ERR);} }
#define ENUM_CHECK(s,a,b) { if((a)!=(b)) { return (NVT_STATUS_ERR);} }
#define ENUM2_CHECK(s,a,b,c) { if(((a)!=(b))&&((a)!=(c))) { return (NVT_STATUS_ERR);} }
#define ENUM3_CHECK(s,a,b,c,d) { if(((a)!=(b))&&((a)!=(c))&&((a)!=(d))) { return (NVT_STATUS_ERR);} }
#define MAX(a,b) (((a)>=(b) || (b == 0xffffffff))?(a):(b))
@@ -1136,6 +1137,130 @@ DSC_PpsConstruct
data[i] = 0;
}
/*
* @brief Extract DSC parameters from PPS data
*
* @param[in] pps PPS data array
* @param[out] out DSC output parameters
*/
static void
DSC_GenerateDataFromPPS(const NvU32 *pps, DSC_OUTPUT_PARAMS *out)
{
NvU32 i;
out->dsc_version_major = pps[0] >> 4;
out->dsc_version_minor = pps[0] & 0xF;
out->pps_identifier = pps[1];
out->bits_per_component = (pps[3] >> 4);
out->linebuf_depth = pps[3] & 0xF;
out->block_pred_enable = (pps[4] >> 5) & 0x1;
out->convert_rgb = (pps[4] >> 4) & 0x1;
out->simple_422 = (pps[4] >> 3) & 0x1;
out->vbr_enable = (pps[4] >> 2) & 0x1;
out->bits_per_pixel = (pps[4] & 0x3) << 8 | pps[5];
out->pic_height = (pps[6] << 8) | pps[7];
out->pic_width = (pps[8] << 8) | pps[9];
out->slice_height = (pps[10] << 8) | pps[11];
out->slice_width = (pps[12] << 8) | pps[13];
out->chunk_size = (pps[14] << 8) | pps[15];
out->initial_xmit_delay = (pps[16] << 8) | pps[17];
out->initial_dec_delay = (pps[18] << 8) | pps[19];
out->initial_scale_value = pps[21];
out->scale_increment_interval = (pps[22] << 8) | pps[23];
out->scale_decrement_interval = (pps[24] << 8) | pps[25];
out->first_line_bpg_offset = pps[27];
out->nfl_bpg_offset = (pps[28] << 8) | pps[29];
out->slice_bpg_offset = (pps[30] << 8) | pps[31];
out->initial_offset = (pps[32] << 8) | pps[33];
out->final_offset = (pps[34] << 8) | pps[35];
out->flatness_min_qp = pps[36];
out->flatness_max_qp = pps[37];
out->rc_model_size = (pps[38] << 8) | pps[39];
out->rc_edge_factor = pps[40];
out->rc_quant_incr_limit0 = pps[41];
out->rc_quant_incr_limit1 = pps[42];
out->rc_tgt_offset_hi = (pps[43] >> 4) & 0xF;
out->rc_tgt_offset_lo = pps[43] & 0xF;
for (i = 0; i < NUM_BUF_RANGES - 1; i++)
out->rc_buf_thresh[i] = (pps[44 + i] << 6);
for (i = 0; i < NUM_BUF_RANGES; i++) {
out->range_min_qp[i] = (pps[58 + i * 2] >> 3);
out->range_max_qp[i] = (pps[58 + i * 2] & 0x7) << 2 | (pps[59 + i * 2] >> 6);
out->range_bpg_offset[i] = pps[59 + i * 2] & 0x3F;
}
out->native_420 = (pps[88] >> 1) & 0x1;
out->native_422 = pps[88] & 0x1;
out->second_line_bpg_offset = pps[89];
out->nsl_bpg_offset = (pps[90] << 8) | pps[91];
out->second_line_offset_adj = (pps[92] << 8) | pps[93];
}
/*
@brief Validate DSC PPS data
@param[in] PPS data
@return true if PPS data is valid, false otherwise
*/
NVT_STATUS
DSC_ValidatePPSData(DSCPPSDATA *pPps)
{
DSC_OUTPUT_PARAMS outParams;
DSC_OUTPUT_PARAMS *out = &outParams;
NvU32 i;
NvU32 pps[96];
NvU32 slice_num; /* Added missing slice_num variable used in validation check */
if(pPps == NULL)
{
return NVT_STATUS_ERR;
}
/* Extract params from PPS data */
for(i = 0; i < 24; i++)
{
pps[i*4 + 0] = (pPps->pPps[i] >> 0) & 0xFF;
pps[i*4 + 1] = (pPps->pPps[i] >> 8) & 0xFF;
pps[i*4 + 2] = (pPps->pPps[i] >> 16) & 0xFF;
pps[i*4 + 3] = (pPps->pPps[i] >> 24) & 0xFF;
}
DSC_GenerateDataFromPPS(pps, out);
slice_num = out->pic_width / out->slice_width;
ENUM_CHECK("dsc_version_major", out->dsc_version_major, 1);
ENUM2_CHECK("dsc_version_minor", out->dsc_version_minor, 1, 2);
ENUM3_CHECK("bits_per_component", out->bits_per_component, 8, 10, 12);
RANGE_CHECK("linebuf_depth", out->linebuf_depth, DSC_DECODER_LINE_BUFFER_BIT_DEPTH_MIN, DSC_DECODER_LINE_BUFFER_BIT_DEPTH_MAX);
ENUM2_CHECK("block_pred_enable", out->block_pred_enable, 0, 1);
ENUM2_CHECK("convert_rgb", out->convert_rgb, 0, 1);
RANGE_CHECK("initial_offset", out->initial_offset, 0, out->rc_model_size);
RANGE_CHECK("initial_scale_value", out->initial_scale_value, 0, 63);
RANGE_CHECK("initial_xmit_delay", out->initial_xmit_delay, 0, 1023);
RANGE_CHECK("slice_height", out->slice_height, 8, out->pic_height);
RANGE_CHECK("first_line_bpg_offset", out->first_line_bpg_offset, 0, 31);
RANGE_CHECK("nfl_bpg_offset", out->nfl_bpg_offset, 0, 65535);
RANGE_CHECK("second_line_bpg_offset", out->second_line_bpg_offset, 0, 31);
RANGE_CHECK("nsl_bpg_offset", out->nsl_bpg_offset, 0, 65535);
RANGE_CHECK("slice_bpg_offset", out->slice_bpg_offset, 0, 65535);
RANGE_CHECK("initial_dec_delay", out->initial_dec_delay, 0, 65535);
// check if rc_model_size is non zero
if (out->rc_model_size)
{
RANGE_CHECK("final_offset", out->final_offset, 0, out->rc_model_size - 1);
}
RANGE_CHECK("scale_increment_interval", out->scale_increment_interval, 0, 65535);
RANGE_CHECK("scale_decrement_interval", out->scale_decrement_interval, 1, 4095);
if ((out->chunk_size + 3) / 4 * slice_num > out->pic_width)
{
// Error! bpp too high
return NVT_STATUS_ERR;
}
return NVT_STATUS_SUCCESS;
}
/*
* @brief Generate slice count supported mask with given slice num.
*
@@ -1232,6 +1357,10 @@ DSC_GetPeakThroughputMps(NvU32 peak_throughput)
case DSC_DECODER_PEAK_THROUGHPUT_MODE0_170:
peak_throughput_mps = 170;
break;
// Custom one, defined for HDMI YUV422/YUV420 modes
case DSC_DECODER_PEAK_THROUGHPUT_MODE0_680:
peak_throughput_mps = 680;
break;
default:
peak_throughput_mps = 0;
}
@@ -2296,14 +2425,20 @@ _calculateEffectiveBppForDSC
const DSC_INFO *pDscInfo,
const MODESET_INFO *pModesetInfo,
const WAR_DATA *pWARData,
NvU32 bpp
NvU32 bpp,
DSC_INPUT_PARAMS *in
)
{
NvU32 LogicLaneCount, BytePerLogicLane;
NvU32 BitPerSymbol;
NvU32 slicewidth, chunkSize, sliceCount;
NvU32 chunkSymbols, totalSymbolsPerLane;
NvU32 totalSymbols;
NvU32 LogicLaneCount, BytePerLogicLane;
NvU32 BitPerSymbol;
NvU32 slicewidth, chunkSize, sliceCount;
NvU32 chunkSymbols, totalSymbolsPerLane;
NvU32 totalSymbols;
NvU32 gpu_slice_count_mask;
NvU32 common_slice_count_mask;
NvU32 peak_throughput;
NvU32 peak_throughput_mps;
NVT_STATUS status;
if (pWARData->dpData.bIs128b132bChannelCoding)
{
@@ -2333,11 +2468,52 @@ _calculateEffectiveBppForDSC
slicewidth = pDscInfo->forcedDscParams.sliceWidth;
sliceCount = (NvU32)NV_CEIL(pModesetInfo->activeWidth, pDscInfo->forcedDscParams.sliceWidth);
}
else
else if (pDscInfo->forcedDscParams.sliceCount > 0U)
{
slicewidth = (NvU32)NV_CEIL(pModesetInfo->activeWidth, pDscInfo->forcedDscParams.sliceCount);
sliceCount = pDscInfo->forcedDscParams.sliceCount;
}
else
{
gpu_slice_count_mask = DSC_GetSliceCountMask(in->max_slice_num, NV_TRUE /*bInclusive*/);
common_slice_count_mask = gpu_slice_count_mask & in->slice_count_mask;
if (!common_slice_count_mask)
{
// DSC cannot be supported since no common supported slice count
return 0U;
}
if (in->native_420 || in->native_422)
{
peak_throughput = in->peak_throughput_mode1;
}
else
{
peak_throughput = in->peak_throughput_mode0;
}
peak_throughput_mps = DSC_GetPeakThroughputMps(peak_throughput);
if (!peak_throughput_mps || !(in->max_slice_width))
{
return 0;
}
status = DSC_GetMinSliceCountForMode(in->pic_width, in->pixel_clkMHz,
in->max_slice_width, peak_throughput_mps,
in->max_slice_num,
common_slice_count_mask,
&sliceCount);
if (status != NVT_STATUS_SUCCESS || sliceCount == 0U)
{
return 0U;
}
slicewidth = (NvU32)NV_CEIL(pModesetInfo->activeWidth, sliceCount);
}
chunkSize = (NvU32)NV_CEIL((bpp*slicewidth), (8U * BPP_UNIT));
@@ -2404,10 +2580,27 @@ DSC_GeneratePPS
NVMISC_MEMSET(in, 0, sizeof(DSC_INPUT_PARAMS));
in->bits_per_component = pModesetInfo->bitsPerComponent;
in->linebuf_depth = MIN((pDscInfo->sinkCaps.lineBufferBitDepth), (pDscInfo->gpuCaps.lineBufferBitDepth));
in->block_pred_enable = pDscInfo->sinkCaps.bBlockPrediction;
in->multi_tile = (pDscInfo->gpuCaps.maxNumHztSlices > 4U) ? 1 : 0;
in->bits_per_component = pModesetInfo->bitsPerComponent;
in->linebuf_depth = MIN((pDscInfo->sinkCaps.lineBufferBitDepth), (pDscInfo->gpuCaps.lineBufferBitDepth));
in->block_pred_enable = pDscInfo->sinkCaps.bBlockPrediction;
in->multi_tile = (pDscInfo->gpuCaps.maxNumHztSlices > 4U) ? 1 : 0;
in->dsc_version_minor = pDscInfo->forcedDscParams.dscRevision.versionMinor ? pDscInfo->forcedDscParams.dscRevision.versionMinor :
pDscInfo->sinkCaps.algorithmRevision.versionMinor;
in->pic_width = pModesetInfo->activeWidth;
in->pic_height = pModesetInfo->activeHeight;
in->slice_height = pDscInfo->forcedDscParams.sliceHeight;
in->slice_width = pDscInfo->forcedDscParams.sliceWidth;
in->slice_num = pDscInfo->forcedDscParams.sliceCount;
in->max_slice_num = MIN(pDscInfo->sinkCaps.maxNumHztSlices,
pModesetInfo->bDualMode ? pDscInfo->gpuCaps.maxNumHztSlices * 2 : pDscInfo->gpuCaps.maxNumHztSlices);
// lineBufferSize is reported in 1024 units by HW, so need to multiply by 1024 to get pixels.
in->max_slice_width = MIN(pDscInfo->sinkCaps.maxSliceWidth, pDscInfo->gpuCaps.lineBufferSize * 1024);
in->pixel_clkMHz = (NvU32)(pModesetInfo->pixelClockHz / 1000000L);
in->dual_mode = pModesetInfo->bDualMode;
in->drop_mode = pModesetInfo->bDropMode;
in->slice_count_mask = pDscInfo->sinkCaps.sliceCountSupportedMask;
in->peak_throughput_mode0 = pDscInfo->sinkCaps.peakThroughputMode0;
in->peak_throughput_mode1 = pDscInfo->sinkCaps.peakThroughputMode1;
switch (pModesetInfo->colorFormat)
{
@@ -2584,7 +2777,7 @@ DSC_GeneratePPS
do
{
max_bpp--;
eff_bpp = _calculateEffectiveBppForDSC(pDscInfo, pModesetInfo, pWARData, max_bpp);
eff_bpp = _calculateEffectiveBppForDSC(pDscInfo, pModesetInfo, pWARData, max_bpp, in);
} while ((eff_bpp * (pModesetInfo->pixelClockHz)) > (availableBandwidthBitsPerSecond*BPP_UNIT));
@@ -2624,7 +2817,7 @@ DSC_GeneratePPS
((pWARData->dpData.dpMode == DSC_DP_MST) ||
pWARData->dpData.bIs128b132bChannelCoding)))
{
eff_bpp = _calculateEffectiveBppForDSC(pDscInfo, pModesetInfo, pWARData, in->bits_per_pixel);
eff_bpp = _calculateEffectiveBppForDSC(pDscInfo, pModesetInfo, pWARData, in->bits_per_pixel, in);
}
}
@@ -2684,10 +2877,9 @@ DSC_GeneratePPS
((pWARData->dpData.dpMode == DSC_DP_MST) ||
pWARData->dpData.bIs128b132bChannelCoding)))
{
eff_bpp = _calculateEffectiveBppForDSC(pDscInfo, pModesetInfo, pWARData, in->bits_per_pixel);
eff_bpp = _calculateEffectiveBppForDSC(pDscInfo, pModesetInfo, pWARData, in->bits_per_pixel, in);
}
}
}
if (pModesetInfo->bDualMode && (pDscInfo->gpuCaps.maxNumHztSlices > 4U))
@@ -2697,24 +2889,6 @@ DSC_GeneratePPS
goto done;
}
in->dsc_version_minor = pDscInfo->forcedDscParams.dscRevision.versionMinor ? pDscInfo->forcedDscParams.dscRevision.versionMinor :
pDscInfo->sinkCaps.algorithmRevision.versionMinor;
in->pic_width = pModesetInfo->activeWidth;
in->pic_height = pModesetInfo->activeHeight;
in->slice_height = pDscInfo->forcedDscParams.sliceHeight;
in->slice_width = pDscInfo->forcedDscParams.sliceWidth;
in->slice_num = pDscInfo->forcedDscParams.sliceCount;
in->max_slice_num = MIN(pDscInfo->sinkCaps.maxNumHztSlices,
pModesetInfo->bDualMode ? pDscInfo->gpuCaps.maxNumHztSlices * 2 : pDscInfo->gpuCaps.maxNumHztSlices);
// lineBufferSize is reported in 1024 units by HW, so need to multiply by 1024 to get pixels.
in->max_slice_width = MIN(pDscInfo->sinkCaps.maxSliceWidth, pDscInfo->gpuCaps.lineBufferSize * 1024);
in->pixel_clkMHz = (NvU32)(pModesetInfo->pixelClockHz / 1000000L);
in->dual_mode = pModesetInfo->bDualMode;
in->drop_mode = pModesetInfo->bDropMode;
in->slice_count_mask = pDscInfo->sinkCaps.sliceCountSupportedMask;
in->peak_throughput_mode0 = pDscInfo->sinkCaps.peakThroughputMode0;
in->peak_throughput_mode1 = pDscInfo->sinkCaps.peakThroughputMode1;
if (in->native_422)
{
// bits_per_pixel in PPS is defined as 5 fractional bits in native422 mode
@@ -2748,15 +2922,21 @@ DSC_GeneratePPS
ret = DSC_PpsDataGen(in, out, pps);
if (in->multi_tile && eff_bpp)
if (pWARData && (pWARData->connectorType == DSC_DP) && in->multi_tile)
{
*pBitsPerPixelX16 = eff_bpp;
if (eff_bpp)
{
*pBitsPerPixelX16 = eff_bpp;
}
else
{
return NVT_STATUS_INVALID_BPP;
}
}
else
{
*pBitsPerPixelX16 = in->bits_per_pixel;
}
/* fall through */
done:
return ret;

View File

@@ -150,6 +150,9 @@ typedef struct
#define DSC_DECODER_PEAK_THROUGHPUT_MODE0_950 (0x0000000D)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE0_1000 (0x0000000E)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE0_170 (0x0000000F)
// Custom definition of peak throughput for HDMI YUV422/YUV420 modes since those are not defined in spec
// Starting with 0x100 to provide headroom for DSC spec definitions in future
#define DSC_DECODER_PEAK_THROUGHPUT_MODE0_680 (0x00000100)
// Peak throughput supported for native 422 and 420 modes
NvU32 peakThroughputMode1;
@@ -169,6 +172,9 @@ typedef struct
#define DSC_DECODER_PEAK_THROUGHPUT_MODE1_950 (0x0000000D)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE1_1000 (0x0000000E)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE1_170 (0x0000000F)
// Custom definition of peak throughput for HDMI YUV modes since those are not defined in spec
// Starting with 0x100 to provide headroom for DSC spec definitions in future
#define DSC_DECODER_PEAK_THROUGHPUT_MODE1_680 (0x00000100)
// Maximum bits_per_pixel supported by the DSC decompressor multiplied by 16
NvU32 maxBitsPerPixelX16;
@@ -264,6 +270,11 @@ typedef struct {
NvU8 data[500U]; // total size of DSC_IN/OUTPUT_PARAMS
} DSC_GENERATE_PPS_OPAQUE_WORKAREA;
typedef struct
{
NvU32 pPps[DSC_MAX_PPS_SIZE_DWORD]; // Out - PPS SDP data
} DSCPPSDATA;
/*
* Windows testbed compiles are done with warnings as errors
* with the maximum warning level. Here we turn off some
@@ -336,6 +347,8 @@ DSC_GeneratePPSWithSliceCountMask
NvU32 *sliceCountMask
);
NVT_STATUS DSC_ValidatePPSData(DSCPPSDATA *pPps);
#ifdef __cplusplus
}
#endif

View File

@@ -53,7 +53,7 @@ static const NVT_TIMING EDID_EST[] =
{
EST_TIMING( 720, 0, 0, 720,'-', 400, 0,0, 400,'-',70, 0,NVT_STATUS_EDID_EST), // 720x400x70Hz (IBM, VGA)
EST_TIMING( 720, 0, 0, 720,'-', 400, 0,0, 400,'-',88, 0,NVT_STATUS_EDID_EST), // 720x400x88Hz (IBM, XGA2)
{640,0,16,96,800,NVT_H_SYNC_NEGATIVE,480,0,10,2,525,NVT_V_SYNC_NEGATIVE,NVT_PROGRESSIVE,2518,25180,{0,60,60000,0,1,{0},{0},{0},{0},NVT_STATUS_EDID_EST,"EDID_Established"}},
{640,0,16,96,800,NVT_H_SYNC_NEGATIVE,480,0,10,2,525,NVT_V_SYNC_NEGATIVE,NVT_PROGRESSIVE,2518,25175,{0,60,60000,0,1,{0},{0},{0},{0},NVT_STATUS_EDID_EST,"EDID_Established"}},
EST_TIMING( 640, 0, 0, 640,'-', 480, 0,0, 480,'-',67, 0,NVT_STATUS_EDID_EST), // 640x480x67Hz (Apple, Mac II)
@@ -154,8 +154,8 @@ NVT_STATUS NvTiming_EnumEST(NvU32 index, NVT_TIMING *pT)
return NVT_STATUS_ERR;
}
pT->etc.rrx1k = axb_div_c((NvU32)pT->pclk,
(NvU32)10000*(NvU32)1000,
pT->etc.rrx1k = axb_div_c((NvU32)pT->pclk1khz,
(NvU32)1000*(NvU32)1000,
(NvU32)pT->HTotal*(NvU32)pT->VTotal);
return NVT_STATUS_SUCCESS;
@@ -176,8 +176,8 @@ NVT_STATUS NvTiming_EnumESTIII(NvU32 index, NVT_TIMING *pT)
return NVT_STATUS_ERR;
}
pT->etc.rrx1k = axb_div_c((NvU32)pT->pclk,
(NvU32)10000*(NvU32)1000,
pT->etc.rrx1k = axb_div_c((NvU32)pT->pclk1khz,
(NvU32)1000*(NvU32)1000,
(NvU32)pT->HTotal*(NvU32)pT->VTotal);
return NVT_STATUS_SUCCESS;
@@ -347,7 +347,7 @@ void parseEdidEstablishedTiming(NVT_EDID_INFO *pInfo)
for (i = 1 << (sizeof(pInfo->established_timings_1_2) * 8 - 1), j = 0; i != 0; i >>= 1, j ++)
{
if ((pInfo->established_timings_1_2 & i) != 0 && EDID_EST[j].pclk != 0)
if ((pInfo->established_timings_1_2 & i) != 0 && EDID_EST[j].pclk1khz != 0)
{
// count the timing
newTiming = EDID_EST[j];
@@ -382,7 +382,7 @@ void parseEdidEstablishedTiming(NVT_EDID_INFO *pInfo)
for (k=7; k<=7; k--)
{
// find if the bit is 1 and we have a valid associated timing
if (pEST->data[j] & (1<<k) && EDID_ESTIII[(j*8)+(7-k)].pclk != 0)
if (pEST->data[j] & (1<<k) && EDID_ESTIII[(j*8)+(7-k)].pclk1khz != 0)
{
newTiming = EDID_ESTIII[(j*8)+(7-k)];
newTiming.etc.status = NVT_STATUS_EDID_ESTn(++count);
@@ -565,7 +565,7 @@ NVT_STATUS parseEdidDetailedTimingDescriptor(NvU8 *p, NVT_TIMING *pT)
// pixel clock
pT->pclk = (NvU32)pDTD->wDTPixelClock;
pT->pclk1khz = (NvU32)((pT->pclk << 3) + (pT->pclk << 1));
pT->pclk1khz = (NvU32)((pDTD->wDTPixelClock << 3) + (pDTD->wDTPixelClock << 1));
// sync polarities
if ((pDTD->bDTFlags & 0x18) == 0x18)
@@ -2048,7 +2048,8 @@ NVT_STATUS NvTiming_GetEDIDBasedASPRTiming( NvU16 width, NvU16 height, NvU16 rr,
if(rr != pT->etc.rr)
{
pT->etc.rrx1k = rr * 1000;
pT->pclk = RRx1kToPclk (pT);
pT->pclk = RRx1kToPclk (pT);
pT->pclk1khz = RRx1kToPclk1khz(pT);
}
pT->etc.status = NVT_STATUS_ASPR;
@@ -2991,7 +2992,7 @@ NvU32 NvTiming_CalculateCommonEDIDCRC32(NvU8* pEDIDBuffer, NvU32 edidVersion)
CODE_SEGMENT(PAGE_DD_CODE)
NVT_STATUS NvTiming_CalculateEDIDLimits(NVT_EDID_INFO *pEdidInfo, NVT_EDID_RANGE_LIMIT *pLimit)
{
NvU32 i;
NvU32 i, pclk10khz;
NVMISC_MEMSET(pLimit, 0, sizeof(NVT_EDID_RANGE_LIMIT));
@@ -3022,7 +3023,7 @@ NVT_STATUS NvTiming_CalculateEDIDLimits(NVT_EDID_INFO *pEdidInfo, NVT_EDID_RANGE
pLimit->max_v_rate_hzx1k = pTiming->etc.rrx1k;
}
h_rate_hz = axb_div_c(pTiming->pclk, 10000, (NvU32)pTiming->HTotal);
h_rate_hz = axb_div_c(pTiming->pclk1khz, 1000, (NvU32)pTiming->HTotal);
if (pLimit->min_h_rate_hz > h_rate_hz)
{
@@ -3033,9 +3034,11 @@ NVT_STATUS NvTiming_CalculateEDIDLimits(NVT_EDID_INFO *pEdidInfo, NVT_EDID_RANGE
pLimit->max_h_rate_hz = h_rate_hz;
}
if (pLimit->max_pclk_10khz < pTiming->pclk)
pclk10khz = (pTiming->pclk1khz + 5 ) / 10;
if (pLimit->max_pclk_10khz < pclk10khz)
{
pLimit->max_pclk_10khz = pTiming->pclk;
pLimit->max_pclk_10khz = pclk10khz;
}
}

View File

@@ -783,7 +783,7 @@ void parseCta861VideoFormatDataBlock(NVT_EDID_CEA861_INFO *pExt861, void *pRawIn
if (NvTiming_CalcOVT(width, height, VF_FRAME_RATE[rateIdx], &newTiming) == NVT_STATUS_SUCCESS)
{
if (pExt861->vfdb[vfdb_idx].info.y420 && newTiming.pclk > NVT_HDMI_YUV_420_PCLK_SUPPORTED_MIN)
if (pExt861->vfdb[vfdb_idx].info.y420 && newTiming.pclk1khz > NVT_HDMI_YUV_420_PCLK_SUPPORTED_MIN)
{
UPDATE_BPC_FOR_COLORFORMAT(newTiming.etc.yuv420, 0, 1,
pInfo->hdmiForumInfo.dc_30bit_420,
@@ -927,7 +927,7 @@ void parse861bShortYuv420Timing(NVT_EDID_CEA861_INFO *pExt861,
// calculate the pixel clock
newTiming.pclk = RRx1kToPclk(&newTiming);
newTiming.pclk1khz = (newTiming.pclk << 3) + (newTiming.pclk << 1); // *10
newTiming.pclk1khz = RRx1kToPclk1khz(&newTiming);
// From CTA-861-F: By default, Y420VDB SVDs, when present in the EDID, shall be less preferred than all regular Video Data Block SVDs.
// So it should use normal VIC code without native flag.
@@ -2275,7 +2275,7 @@ NVT_STATUS NvTiming_CalcCEA861bTiming(NvU32 width, NvU32 height, NvU32 rr, NvU32
// calculate the pixel clock
pT->pclk = RRx1kToPclk (pT);
pT->pclk1khz = (pT->pclk << 3) + (pT->pclk << 1); // *10
pT->pclk1khz = RRx1kToPclk1khz (pT);
NVT_SET_CEA_FORMAT(pT->etc.status, NVT_GET_TIMING_STATUS_SEQ(pT->etc.status));
@@ -3915,7 +3915,7 @@ void parseCta861DIDType7VideoTimingDataBlock(NVT_EDID_CEA861_INFO *pExt861, void
pT7Descriptor = (const DISPLAYID_2_0_TIMING_7_DESCRIPTOR *)
&pExt861->did_type7_data_block[t7db_idx].payload[i*eachOfDescSize];
if (pT7Descriptor->options.is_preferred_or_ycc420 == 1 && newTiming.pclk > NVT_HDMI_YUV_420_PCLK_SUPPORTED_MIN)
if (pT7Descriptor->options.is_preferred_or_ycc420 == 1 && newTiming.pclk1khz > NVT_HDMI_YUV_420_PCLK_SUPPORTED_MIN)
{
newTiming.etc.yuv420.bpcs = 0;
UPDATE_BPC_FOR_COLORFORMAT(newTiming.etc.yuv420, 0, 1,
@@ -3976,7 +3976,7 @@ void parseCta861DIDType8VideoTimingDataBlock(NVT_EDID_CEA861_INFO *pExt861, void
if (parseDisplayId20Timing8Descriptor(pExt861->did_type8_data_block[t8db_idx].payload,
&newTiming, codeType, codeSize, i, startSeqNum + i) == NVT_STATUS_SUCCESS)
{
if (pExt861->did_type8_data_block[t8db_idx].version.t8y420 == 1 && newTiming.pclk > NVT_HDMI_YUV_420_PCLK_SUPPORTED_MIN)
if (pExt861->did_type8_data_block[t8db_idx].version.t8y420 == 1 && newTiming.pclk1khz > NVT_HDMI_YUV_420_PCLK_SUPPORTED_MIN)
{
UPDATE_BPC_FOR_COLORFORMAT(newTiming.etc.yuv420, 0, 1,
pInfo->hdmiForumInfo.dc_30bit_420,
@@ -4037,7 +4037,7 @@ void parseCta861DIDType10VideoTimingDataBlock(NVT_EDID_CEA861_INFO *pExt861, voi
p6bytesDescriptor = (const DISPLAYID_2_0_TIMING_10_6BYTES_DESCRIPTOR *)
&pExt861->did_type10_data_block[t10db_idx].payload[i*eachOfDescriptorsSize];
if (p6bytesDescriptor->options.ycc420_support && newTiming.pclk > NVT_HDMI_YUV_420_PCLK_SUPPORTED_MIN)
if (p6bytesDescriptor->options.ycc420_support && newTiming.pclk1khz > NVT_HDMI_YUV_420_PCLK_SUPPORTED_MIN)
{
UPDATE_BPC_FOR_COLORFORMAT(newTiming.etc.yuv420, 0, 1,
pInfo->hdmiForumInfo.dc_30bit_420,

View File

@@ -505,6 +505,7 @@ static NVT_STATUS parseDisplayIdTiming1Descriptor(DISPLAYID_TIMING_1_DESCRIPTOR
// the pixel clock
pT->pclk = (NvU32)((type1->pixel_clock_high << 16) + (type1->pixel_clock_mid << 8) + type1->pixel_clock_low_minus_0_01MHz + 1);
pT->pclk1khz = (pT->pclk << 3) + (pT->pclk << 1);
// the DisplayID spec does not support border
pT->HBorder = pT->VBorder = 0;
@@ -560,8 +561,8 @@ static NVT_STATUS parseDisplayIdTiming1Descriptor(DISPLAYID_TIMING_1_DESCRIPTOR
}
// the refresh rate
pT->etc.rr = NvTiming_CalcRR(pT->pclk, pT->interlaced, pT->HTotal, pT->VTotal);
pT->etc.rrx1k = NvTiming_CalcRRx1k(pT->pclk, pT->interlaced, pT->HTotal, pT->VTotal);
pT->etc.rr = NvTiming_CalcRR(pT->pclk1khz, pT->interlaced, pT->HTotal, pT->VTotal);
pT->etc.rrx1k = NvTiming_CalcRRx1k(pT->pclk1khz, pT->interlaced, pT->HTotal, pT->VTotal);
pT->etc.name[39] = '\0';
pT->etc.rep = 0x1; // bit mask for no pixel repetition
@@ -632,6 +633,7 @@ static NVT_STATUS parseDisplayIdTiming2Descriptor(DISPLAYID_TIMING_2_DESCRIPTOR
// the pixel clock
pT->pclk = (NvU32)((type2->pixel_clock_high << 16) + (type2->pixel_clock_mid << 8) + type2->pixel_clock_low_minus_0_01MHz + 1);
pT->pclk1khz = (pT->pclk << 3) + (pT->pclk << 1);
// the DisplayID spec does not support border
pT->HBorder = pT->VBorder = 0;
@@ -654,8 +656,8 @@ static NVT_STATUS parseDisplayIdTiming2Descriptor(DISPLAYID_TIMING_2_DESCRIPTOR
pT->interlaced = type2->options.interface_frame_scanning_type;
// the refresh rate
pT->etc.rr = NvTiming_CalcRR(pT->pclk, pT->interlaced, pT->HTotal, pT->VTotal);
pT->etc.rrx1k = NvTiming_CalcRRx1k(pT->pclk, pT->interlaced, pT->HTotal, pT->VTotal);
pT->etc.rr = NvTiming_CalcRR(pT->pclk1khz, pT->interlaced, pT->HTotal, pT->VTotal);
pT->etc.rrx1k = NvTiming_CalcRRx1k(pT->pclk1khz, pT->interlaced, pT->HTotal, pT->VTotal);
pT->etc.aspect = 0;
pT->etc.name[39] = '\0';

View File

@@ -226,7 +226,7 @@ NVT_STATUS NvTiming_ComposeCustTimingString(NVT_TIMING *pT)
}
CODE_SEGMENT(PAGE_DD_CODE)
NvU16 NvTiming_CalcRR(NvU32 pclk, NvU16 interlaced, NvU16 HTotal, NvU16 VTotal)
NvU16 NvTiming_CalcRR(NvU32 pclk1khz, NvU16 interlaced, NvU16 HTotal, NvU16 VTotal)
{
NvU16 rr = 0;
@@ -236,7 +236,7 @@ NvU16 NvTiming_CalcRR(NvU32 pclk, NvU16 interlaced, NvU16 HTotal, NvU16 VTotal)
if (totalPixelsIn2Fields != 0)
{
rr = (NvU16)axb_div_c_64((NvU64)pclk * 2, (NvU64)10000, (NvU64)totalPixelsIn2Fields);
rr = (NvU16)axb_div_c_64((NvU64)pclk1khz * 2, (NvU64)1000, (NvU64)totalPixelsIn2Fields);
}
}
else
@@ -245,14 +245,14 @@ NvU16 NvTiming_CalcRR(NvU32 pclk, NvU16 interlaced, NvU16 HTotal, NvU16 VTotal)
if (totalPixels != 0)
{
rr = (NvU16)axb_div_c_64((NvU64)pclk, (NvU64)10000, (NvU64)totalPixels);
rr = (NvU16)axb_div_c_64((NvU64)pclk1khz, (NvU64)1000, (NvU64)totalPixels);
}
}
return rr;
}
CODE_SEGMENT(PAGE_DD_CODE)
NvU32 NvTiming_CalcRRx1k(NvU32 pclk, NvU16 interlaced, NvU16 HTotal, NvU16 VTotal)
NvU32 NvTiming_CalcRRx1k(NvU32 pclk1khz, NvU16 interlaced, NvU16 HTotal, NvU16 VTotal)
{
NvU32 rrx1k = 0;
@@ -262,7 +262,7 @@ NvU32 NvTiming_CalcRRx1k(NvU32 pclk, NvU16 interlaced, NvU16 HTotal, NvU16 VTota
if (totalPixelsIn2Fields != 0)
{
rrx1k = (NvU32)axb_div_c_64((NvU64)pclk * 2, (NvU64)10000000, (NvU64)totalPixelsIn2Fields);
rrx1k = (NvU32)axb_div_c_64((NvU64)pclk1khz * 2, (NvU64)1000000, (NvU64)totalPixelsIn2Fields);
}
}
else
@@ -271,7 +271,7 @@ NvU32 NvTiming_CalcRRx1k(NvU32 pclk, NvU16 interlaced, NvU16 HTotal, NvU16 VTota
if (totalPixels != 0)
{
rrx1k = (NvU32)axb_div_c_64((NvU64)pclk, (NvU64)10000000, (NvU64)totalPixels);
rrx1k = (NvU32)axb_div_c_64((NvU64)pclk1khz, (NvU64)1000000, (NvU64)totalPixels);
}
}
@@ -348,6 +348,14 @@ NvU32 RRx1kToPclk (NVT_TIMING *pT)
1000 * ((pT->interlaced != 0) ? 20000 : 10000));
}
CODE_SEGMENT(NONPAGE_DD_CODE)
NvU32 RRx1kToPclk1khz (NVT_TIMING *pT)
{
return (NvU32)axb_div_c_64((NvU32)pT->HTotal * (NvU32)(pT->VTotal + ((pT->interlaced != 0) ? (pT->VTotal + 1) : 0)),
pT->etc.rrx1k,
1000 * ((pT->interlaced != 0) ? 2000 : 1000));
}
CODE_SEGMENT(PAGE_DD_CODE)
NvU16 NvTiming_MaxFrameWidth(NvU16 HVisible, NvU16 repMask)
{

View File

@@ -558,7 +558,7 @@ typedef enum NVT_TV_FORMAT
#define NVT_CTA861_VIDEO_VIC_MASK 0xFF //the VIC mask of the short video descriptor
#define NVT_CTA861_7BIT_VIDEO_VIC_MASK 0x7F //the 7 bits VIC mask of the short video descriptor
#define NVT_CTA861_VIDEO_NATIVE_MASK 0x80 //the Native mask of the short video descriptor
#define NVT_HDMI_YUV_420_PCLK_SUPPORTED_MIN 59000 //the vale shall equal or larger than 590MHz to support YCbCr in HDMI2.1
#define NVT_HDMI_YUV_420_PCLK_SUPPORTED_MIN 590000//the vale shall equal or larger than 590MHz to support YCbCr in HDMI2.1 , unit of 1khz
// CTA-861G supports more SVDs which is over 0x7F index
// All value below 192 will be treated as 7 bit VIC. Value 128~192 shall be forbidden.
@@ -5782,7 +5782,7 @@ typedef enum
#define NVT_FLAG_CEA_4X3_TIMING 0x00000400
#define NVT_FLAG_CEA_16X9_TIMING 0x00000800
#define NVT_FLAG_OS_ADDED_TIMING 0x00001000
#define NVT_FLAG_SPECTRUM_SPREAD 0x00002000
#define NVT_FLAG_SPECTRUM_SPREAD 0x00002000 // TODO: remove this
#define NVT_FLAG_EDID_TIMING_RR_MATCH 0x00004000
#define NVT_FLAG_EDID_861_ST 0x00008000
#define NVT_FLAG_EDID_DTD_EIZO_SPLIT 0x00010000
@@ -5805,8 +5805,8 @@ extern "C" {
#endif
// Generic timing parameter calculation
NvU16 NvTiming_CalcRR(NvU32 pclk, NvU16 interlaced, NvU16 HTotal, NvU16 VTotal);
NvU32 NvTiming_CalcRRx1k(NvU32 pclk, NvU16 interlaced, NvU16 HTotal, NvU16 VTotal);
NvU16 NvTiming_CalcRR(NvU32 pclk1khz, NvU16 interlaced, NvU16 HTotal, NvU16 VTotal);
NvU32 NvTiming_CalcRRx1k(NvU32 pclk1khz, NvU16 interlaced, NvU16 HTotal, NvU16 VTotal);
NvU32 NvTiming_IsRoundedRREqual(NvU16 rr1, NvU32 rr1x1k, NvU16 rr2);
NvU32 NvTiming_IsTimingExactEqual(const NVT_TIMING *pT1, const NVT_TIMING *pT2);
@@ -5896,6 +5896,7 @@ NvU32 calculateCRC32(NvU8* pBuf, NvU32 bufsize);
void patchChecksum(NvU8* pBuf);
NvBool isChecksumValid(NvU8* pBuf);
NvU32 RRx1kToPclk (NVT_TIMING *pT);
NvU32 RRx1kToPclk1khz (NVT_TIMING *pT);
NVT_STATUS NvTiming_ComposeCustTimingString(NVT_TIMING *pT);