mirror of
https://github.com/NVIDIA/open-gpu-kernel-modules.git
synced 2026-01-30 04:59:46 +00:00
580.65.06
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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 *************************************/
|
||||
|
||||
@@ -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,
|
||||
|
||||
46
src/common/modeset/hdmipacket/nvhdmipkt_CB71.c
Normal file
46
src/common/modeset/hdmipacket/nvhdmipkt_CB71.c
Normal 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);
|
||||
}
|
||||
46
src/common/modeset/hdmipacket/nvhdmipkt_CC71.c
Normal file
46
src/common/modeset/hdmipacket/nvhdmipkt_CC71.c
Normal 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);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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*);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user