550.40.07

This commit is contained in:
Bernhard Stoeckner
2024-01-24 17:51:53 +01:00
parent bb2dac1f20
commit 91676d6628
1411 changed files with 261367 additions and 145959 deletions

View File

@@ -243,7 +243,7 @@ NvHdmiPkt_PacketWrite(NvHdmiPkt_Handle libHandle,
((infoframeType == hdmi_pktType_GamutMetadata) && (packetLen < sizeof(NVT_GAMUT_METADATA))) ||
((infoframeType == hdmi_pktType_ExtendedMetadata) && (packetLen < sizeof(NVT_EXTENDED_METADATA_PACKET_INFOFRAME)))||
((infoframeType == hdmi_pktType_VendorSpecInfoFrame) && (packetLen < 8)) ||
((infoframeType == hdmi_pktType_AviInfoFrame) && (packetLen < sizeof(NVT_VIDEO_INFOFRAME))) ||
((infoframeType == hdmi_pktType_AviInfoFrame) && (packetLen < 13)) ||
((infoframeType == hdmi_pktType_SrcProdDescInfoFrame) && (packetLen < sizeof(NVT_SPD_INFOFRAME))) ||
((infoframeType == hdmi_pktType_DynamicRangeMasteringInfoFrame) && (packetLen < sizeof(NVT_HDR_INFOFRAME))))
// Unused: hdmi_pktType_AudioClkRegeneration

View File

@@ -127,6 +127,12 @@ typedef enum _NVHDMIPKT_TC
DRF_DEF(_HDMI_PKT, _TRANSMIT_CTRL, _SINGLE, _DIS) |
DRF_DEF(_HDMI_PKT, _TRANSMIT_CTRL, _CHKSUM_HW, _EN)),
NVHDMIPKT_TRANSMIT_CONTROL_ENABLE_EVERY_FRAME_SW_CHECKSUM =
(DRF_DEF(_HDMI_PKT, _TRANSMIT_CTRL, _ENABLE, _EN) |
DRF_DEF(_HDMI_PKT, _TRANSMIT_CTRL, _OTHER, _DIS) |
DRF_DEF(_HDMI_PKT, _TRANSMIT_CTRL, _SINGLE, _DIS) |
DRF_DEF(_HDMI_PKT, _TRANSMIT_CTRL, _CHKSUM_HW, _DIS)),
NVHDMIPKT_TRANSMIT_CONTROL_ENABLE_SINGLE_FRAME =
(DRF_DEF(_HDMI_PKT, _TRANSMIT_CTRL, _ENABLE, _EN) |
DRF_DEF(_HDMI_PKT, _TRANSMIT_CTRL, _OTHER, _DIS) |

View File

@@ -36,7 +36,6 @@
#include "ctrl/ctrl0073/ctrl0073specific.h"
#define NVHDMIPKT_9171_INVALID_PKT_TYPE ((NV9171_SF_HDMI_INFO_IDX_VSI) + 1)
#define NVHDMIPKT_CTAIF_MAX_PKT_BYTES 31 // 3 bytes header + 28 bytes data (CTA infoframe max payload size)
#define NVHDMIPKT_9171_MAX_PKT_BYTES_AVI 17 // 3 bytes header + 14 bytes data
NVHDMIPKT_RESULT
@@ -157,8 +156,7 @@ hdmiWriteAviPacket9171(NVHDMIPKT_CLASS* pThis,
if (packetLen > NVHDMIPKT_9171_MAX_PKT_BYTES_AVI)
{
NvHdmiPkt_Print(pThis, "ERROR - input AVI packet length incorrect. Write will be capped to max allowable bytes");
NvHdmiPkt_Assert(0);
NvHdmiPkt_Print(pThis, "WARNING - input AVI packet length incorrect. Write will be capped to max allowable bytes");
}
data = REG_RD32(pBaseReg, NV9171_SF_HDMI_AVI_INFOFRAME_HEADER(head));

View File

@@ -777,11 +777,15 @@ hdmiQueryFRLConfigC671(NVHDMIPKT_CLASS *pThis,
calcBppMinMax(pSrcCaps, pSinkCaps, pVidTransInfo, &bppMinX16, &bppMaxX16);
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 && !bCanUseDSC) ||
(pClientCtrl->forceSliceCount && (pClientCtrl->sliceCount > (NvU32)(NV_MIN(pSrcCaps->dscCaps.maxNumHztSlices, pSinkCaps->pHdmiForumInfo->dsc_MaxSlices)))) ||
(pClientCtrl->forceSliceCount && (pClientCtrl->sliceCount >
(NvU32)(NV_MIN(pSrcCaps->dscCaps.maxNumHztSlices * numHeadsDrivingSink,
pSinkCaps->pHdmiForumInfo->dsc_MaxSlices)))) ||
(pClientCtrl->forceSliceWidth && (pClientCtrl->sliceWidth > NV_MIN(pSrcCaps->dscCaps.maxWidthPerSlice, MAX_RECONSTRUCTED_HACTIVE_PIXELS))) ||
(pClientCtrl->forceBppx16 && ((pClientCtrl->bitsPerPixelX16 < bppMinX16) || (pClientCtrl->bitsPerPixelX16 > bppMaxX16))) ||
(pClientCtrl->forceBppx16 && !pSinkCaps->pHdmiForumInfo->dsc_All_bpp))
@@ -1171,20 +1175,18 @@ frlQuery_Success:
DSC_GENERATE_PPS_OPAQUE_WORKAREA *pDscScratchBuffer = NULL;
pDscScratchBuffer = (DSC_GENERATE_PPS_OPAQUE_WORKAREA*)pThis->callback.malloc(pThis->cbHandle,
sizeof(DSC_GENERATE_PPS_OPAQUE_WORKAREA));
if ((DSC_GeneratePPS(&dscInfo,
&dscModesetInfo,
&warData,
availableLinkBw,
pDscScratchBuffer,
pFRLConfig->dscInfo.pps,
&bitsPerPixelX16,
pDscScratchBuffer)) != NVT_STATUS_SUCCESS)
&bitsPerPixelX16)) != NVT_STATUS_SUCCESS)
{
NvHdmiPkt_Print(pThis, "ERROR - DSC PPS calculation failed.");
NvHdmiPkt_Assert(0);
result = NVHDMIPKT_FAIL;
}
if (pDscScratchBuffer != NULL)
{
pThis->callback.free(pThis->cbHandle, pDscScratchBuffer);

View File

@@ -34,6 +34,9 @@
#define toHdmiPktHandle(p) ((NvHdmiPkt_Handle)(p))
#define fromHdmiPktHandle(h) ((NVHDMIPKT_CLASS*)(h))
// CTA infoframe max payload size
#define NVHDMIPKT_CTAIF_MAX_PKT_BYTES 31 // 3 bytes header + 28 bytes data
extern void initializeHdmiPktInterface0073(NVHDMIPKT_CLASS*);
extern void initializeHdmiPktInterface9171(NVHDMIPKT_CLASS*);
extern void initializeHdmiPktInterface9271(NVHDMIPKT_CLASS*);

File diff suppressed because it is too large Load Diff

View File

@@ -42,7 +42,6 @@
#define DSC_MAX_PPS_SIZE_DWORD 32
/* ------------------------ Datatypes -------------------------------------- */
typedef struct
{
NvU32 versionMajor;
@@ -257,14 +256,8 @@ typedef struct
}dpData;
} WAR_DATA;
//
// DSC PPS calculations need large scratch buffer to work with, which can be too
// big for some platforms. These buffers need to be allocated on heap rather
// than local stack variable. Clients are expected to pre-allocate
// this buffer and pass it in to DSC PPS interface
//
typedef struct {
NvU8 data[512U]; // an upper bound of total size of DSC_IN/OUTPUT_PARAMS
NvU8 data[492U]; // total size of DSC_IN/OUTPUT_PARAMS
} DSC_GENERATE_PPS_OPAQUE_WORKAREA;
/*
@@ -281,6 +274,7 @@ typedef struct {
#ifdef __cplusplus
extern "C" {
#endif
/*
* @brief Calculate PPS parameters based on passed down Sink,
* GPU capability and modeset info
@@ -290,6 +284,8 @@ extern "C" {
* @param[in] pWARData Data required for providing WAR for issues
* @param[in] availableBandwidthBitsPerSecond Available bandwidth for video
* transmission(After FEC/Downspread overhead consideration)
* @param[in] pOpaqueWorkarea Scratch buffer of sufficient size pre-allocated
by client for DSC PPS calculations use
* @param[out] pps Calculated PPS parameter.
* The data can be send to SetDscPpsData* methods directly.
* @param[out] pBitsPerPixelX16 Bits per pixel multiplied by 16
@@ -301,9 +297,40 @@ NVT_STATUS DSC_GeneratePPS(const DSC_INFO *pDscInfo,
const MODESET_INFO *pModesetInfo,
const WAR_DATA *pWARData,
NvU64 availableBandwidthBitsPerSecond,
DSC_GENERATE_PPS_OPAQUE_WORKAREA *pOpaqueWorkarea,
NvU32 pps[DSC_MAX_PPS_SIZE_DWORD],
NvU32 *pBitsPerPixelX16,
DSC_GENERATE_PPS_OPAQUE_WORKAREA *pOpaqueWorkarea);
NvU32 *pBitsPerPixelX16);
/*
* @brief Calculate PPS parameters and slice count mask based on passed down
* Sink, GPU capability and modeset info
*
*
* @param[in] pDscInfo Includes Sink and GPU DSC capabilities
* @param[in] pModesetInfo Modeset related information
* @param[in] pWARData Data required for providing WAR for issues
* @param[in] availableBandwidthBitsPerSecond Available bandwidth for video
* transmission(After FEC/Downspread overhead consideration)
* @param[out] pps Calculated PPS parameter.
* The data can be send to SetDscPpsData* methods directly.
* @param[out] pBitsPerPixelX16 Bits per pixel multiplied by 16
* @param[out] pSliceCountMask Mask of all slice counts supported by the mode.
*
* @returns NVT_STATUS_SUCCESS if successful;
* NVT_STATUS_ERR if unsuccessful;
* In case this returns failure consider that PPS is not possible.
*/
NVT_STATUS
DSC_GeneratePPSWithSliceCountMask
(
const DSC_INFO *pDscInfo,
const MODESET_INFO *pModesetInfo,
const WAR_DATA *pWARData,
NvU64 availableBandwidthBitsPerSecond,
NvU32 pps[DSC_MAX_PPS_SIZE_DWORD],
NvU32 *pBitsPerPixelX16,
NvU32 *sliceCountMask
);
#ifdef __cplusplus
}

View File

@@ -1076,6 +1076,7 @@ NVT_STATUS NV_STDCALL NvTiming_ParseEDIDInfo(NvU8 *pEdid, NvU32 length, NVT_EDID
if (p861Info->revision >= NVT_CTA861_REV_H)
{
if (p861Info->total_vfdb != 0) parseCta861VideoFormatDataBlock(p861Info, pInfo);
if (p861Info->total_did_type7db != 0) parseCta861DIDType7VideoTimingDataBlock(p861Info, pInfo);
if (p861Info->total_did_type8db != 0) parseCta861DIDType8VideoTimingDataBlock(p861Info, pInfo);
if (p861Info->total_did_type10db != 0) parseCta861DIDType10VideoTimingDataBlock(p861Info, pInfo);
@@ -1105,9 +1106,14 @@ NVT_STATUS NV_STDCALL NvTiming_ParseEDIDInfo(NvU8 *pEdid, NvU32 length, NVT_EDID
pInfo->ext_displayid20.interface_features.yuv420_min_pclk = 0;
}
if (!pInfo->ext861.basic_caps)
if (pInfo->ext861.revision == 0 && pInfo->ext_displayid20.valid_data_blocks.interface_feature_present)
{
pInfo->ext861.basic_caps = pInfo->ext_displayid20.basic_caps;
pInfo->ext861.revision = NVT_CEA861_REV_B;
}
if (pInfo->ext_displayid20.valid_data_blocks.interface_feature_present)
{
pInfo->ext861.basic_caps |= pInfo->ext_displayid20.basic_caps;
}
}
}
@@ -1161,7 +1167,7 @@ NVT_STATUS NV_STDCALL NvTiming_ParseEDIDInfo(NvU8 *pEdid, NvU32 length, NVT_EDID
}
// check for cvt timings - in display range limits or cvt 3-byte LDD, only for EDID1.4 and above
if (pInfo->version > 0x0103)
if (pInfo->version > NVT_EDID_VER_1_3)
{
parseEdidCvtTiming(pInfo);
}
@@ -1436,7 +1442,7 @@ NVT_STATUS NvTiming_Get18ByteLongDescriptorIndex(NVT_EDID_INFO *pEdidInfo, NvU8
// get the edid timing
CODE_SEGMENT(PAGE_DD_CODE)
NVT_STATUS NvTiming_GetEdidTimingEx(NvU32 width, NvU32 height, NvU32 rr, NvU32 flag, NVT_EDID_INFO *pEdidInfo, NVT_TIMING *pT, NvU32 rrx1k)
NVT_STATUS NvTiming_GetEdidTimingExWithPclk(NvU32 width, NvU32 height, NvU32 rr, NvU32 flag, NVT_EDID_INFO *pEdidInfo, NVT_TIMING *pT, NvU32 rrx1k, NvU32 pclk)
{
NvU8 kth = 0;
NvU32 i, j;
@@ -1449,7 +1455,7 @@ NVT_STATUS NvTiming_GetEdidTimingEx(NvU32 width, NvU32 height, NvU32 rr, NvU32 f
if (pEdidInfo == NULL || pEdidInfo->total_timings == 0 || pT == 0)
return NVT_STATUS_ERR;
if (width == 0 || height == 0 || rr == 0) // rrx1k is optional, can be 0.
if (width == 0 || height == 0 || rr == 0 ) // rrx1k and pclk are optional, can be 0.
return NVT_STATUS_ERR;
pEdidTiming = pEdidInfo->timing;
@@ -1473,7 +1479,7 @@ NVT_STATUS NvTiming_GetEdidTimingEx(NvU32 width, NvU32 height, NvU32 rr, NvU32 f
if (pEdidInfo->ext861.total_svr > 1)
{
kth = getHighestPrioritySVRIdx(pEdidInfo->ext861.svr_vfpdb[0]);
kth = getHighestPrioritySVRIdx(&pEdidInfo->ext861);
}
for (i = 0; i < pEdidInfo->total_timings; i++)
@@ -1492,7 +1498,7 @@ NVT_STATUS NvTiming_GetEdidTimingEx(NvU32 width, NvU32 height, NvU32 rr, NvU32 f
((rrx1k == 0) || (rrx1k == pEdidTiming[i].etc.rrx1k)) &&
!!(flag & NVT_PVT_INTERLACED_MASK) == !!pEdidTiming[i].interlaced)
{
if (map0 >= pEdidInfo->total_timings)
if (map0 >= pEdidInfo->total_timings || pEdidTiming[i].pclk == pclk)
{
// make sure we take the priority as "detailed>standard>established". (The array timing[] always have the detailed timings in the front and then the standard and established.)
map0 = i;
@@ -1906,6 +1912,12 @@ NVT_STATUS NvTiming_GetEdidTimingEx(NvU32 width, NvU32 height, NvU32 rr, NvU32 f
return NVT_STATUS_SUCCESS;
}
CODE_SEGMENT(PAGE_DD_CODE)
NVT_STATUS NvTiming_GetEdidTimingEx(NvU32 width, NvU32 height, NvU32 rr, NvU32 flag, NVT_EDID_INFO *pEdidInfo, NVT_TIMING *pT, NvU32 rrx1k)
{
return NvTiming_GetEdidTimingExWithPclk(width, height, rr, flag, pEdidInfo, pT, rrx1k, 0);
}
// get the edid timing
CODE_SEGMENT(PAGE_DD_CODE)
NVT_STATUS NvTiming_GetEdidTiming(NvU32 width, NvU32 height, NvU32 rr, NvU32 flag, NVT_EDID_INFO *pEdidInfo, NVT_TIMING *pT)
@@ -2814,28 +2826,35 @@ NvBool assignNextAvailableTiming(NVT_EDID_INFO *pInfo,
}
/**
* @brief Return the first high priority nth index based on the different SVR
* @brief Return the nth highest priority index based on the different SVR
* @param svr Short Video Reference
*/
CODE_SEGMENT(PAGE_DD_CODE)
NvU8 getHighestPrioritySVRIdx(NvU8 svr)
NvU8 getHighestPrioritySVRIdx(const NVT_EDID_CEA861_INFO *pExt861)
{
// In general sink shall define the first one timing sequence
// In general, sink shall define the first one timing sequence
NvU8 kth = 1;
NvU8 i = 0;
// Reserved
if (svr == 0 || svr == 128 || (svr >= 176 && svr <= 192) || svr == 255)
return 0;
if (svr >= 129 && svr <= 144) return svr - 128; // Interpret as the Kth 18-byte DTD in both base0 and CTA block (for N = 1 to 16)
else if (svr >= 145 && svr <= 160) return svr - 144; // Interpret as the Nth 20-byte DTD or 6- or 7-byte CVT-based descriptor. (for N = 1 to 16)
else if (svr >= 161 && svr <= 175) return svr - 160; // Interpret as the video format indicated by the first VFD of the first VFDB with Frame Rates of Rate Index N (for N = 1 to 15)
else if (svr == 254) return kth; // Interpret as the timing format indicated by the first code of the first T8VTDB (for N = 1)
else // assign corresponding CTA format's timing from pre-defined CE timing table, EIA861B
for (i = 0; i < pExt861->total_svr; i++)
{
// ( SVR >= 1 and SVR <= 127) and (SVR >= 193 and SVR <= 253) needs to handle it by client
return svr;
NvU8 svr = pExt861->svr_vfpdb[i];
// Reserved
if (svr == 0 || svr == 128 || (svr >= 176 && svr <= 192) || svr == 255)
continue;
if (svr >= 129 && svr <= 144) return svr - 128; // Interpret as the Kth 18-byte DTD in both base0 and CTA block (for N = 1 to 16)
else if (svr >= 145 && svr <= 160) return svr - 144; // Interpret as the Nth 20-byte DTD or 6- or 7-byte CVT-based descriptor. (for N = 1 to 16)
else if (svr >= 161 && svr <= 175) return svr - 160; // Interpret as the video format indicated by the first VFD of the first VFDB with Frame Rates of Rate Index N (for N = 1 to 15)
else if (svr == 254) return kth; // Interpret as the timing format indicated by the first code of the first T8VTDB (for N = 1)
else // assign corresponding CTA format's timing from pre-defined CE timing table, EIA861B
{
// ( SVR >= 1 and SVR <= 127) and (SVR >= 193 and SVR <= 253) needs to handle it by client
return svr;
}
}
return 0;
}

View File

@@ -40,7 +40,6 @@ PUSH_SEGMENTS
{hv,0,hfp,hsw,ht,(hsp)=='-',vv,0,vfp,vsw,vt,(vsp)=='-',(ip)=='i' ? NVT_INTERLACED:NVT_PROGRESSIVE,\
0,{0,((rrx1k)+500)/1000,rrx1k,((1?aspect)<<16)|(0?aspect),rep,{0},{0},{0},{0},NVT_STATUS_EDID_861STn(format),"CEA-861B:#"#format""}}
#define NVT_TIMING(hv,hfp,hsw,ht,hsp,vv,vfp,vsw,vt,vsp,rrx1k,ip,aspect,rep,format,name) \
{hv,0,hfp,hsw,ht,(hsp)=='-',vv,0,vfp,vsw,vt,(vsp)=='-',(ip)=='i' ? NVT_INTERLACED:NVT_PROGRESSIVE,\
0,{0,((rrx1k)+500)/1000,rrx1k,((1?aspect)<<16)|(0?aspect),rep,{0},{0},{0},{0},NVT_TYPE_NV_PREDEFINEDn(format),name}}
@@ -49,6 +48,8 @@ PUSH_SEGMENTS
{hv,0,hfp,hsw,ht,(hsp)=='-',vv,0,vfp,vsw,vt,(vsp)=='-',(ip)=='i' ? NVT_INTERLACED:NVT_PROGRESSIVE,\
0,{0,((rrx1k)+500)/1000,rrx1k,((1?aspect)<<16)|(0?aspect),rep,{0},{0},{0},{0},NVT_STATUS_HDMI_EXTn(format),name}}
#define RID_MODE(hv, hsp, vv, vsp, ip, aspect, rid) \
{hv, (hsp)=='-', vv, (vsp)=='-',(ip)=='i'? NVT_INTERLACED:NVT_PROGRESSIVE,((1?aspect)<<16)|(0?aspect), rid}
DATA_SEGMENT(PAGE_DATA)
CONS_SEGMENT(PAGE_CONS)
@@ -280,7 +281,7 @@ static const NVT_TIMING EIA861B[]=
EIA_TIMING( 4096, 800, 88, 5280,'+',2160, 8,10,2250,'+',100000,'p',256:135,0x1,218),// 4096 x 2160p @100 (Format 218)
EIA_TIMING( 4096, 88, 88, 4400,'+',2160, 8,10,2250,'+',119880,'p',256:135,0x1,219),// 4096 x 2160p @119.88/120 (Format 219)
// 220-255 Reserved for the Future
// the end
// the end
EIA_TIMING(0,0,0,0,'-',0,0,0,0,'-',0,'p',4:3,0,0)
};
static NvU32 MAX_CEA861B_FORMAT = sizeof(EIA861B)/sizeof(EIA861B[0]) - 1;
@@ -338,6 +339,81 @@ static const NvU32 EIA861B_DUAL_ASPECT_VICS[][2] =
};
static NvU32 MAX_EIA861B_DUAL_ASPECT_VICS = sizeof(EIA861B_DUAL_ASPECT_VICS) / sizeof(EIA861B_DUAL_ASPECT_VICS[0]);
static const NVT_RID_CODES RID[] =
{
RID_MODE( 0, '+', 0, '+', 'p', 16:9 , 0), // No Resolution Identification Available
RID_MODE( 1280, '+', 720, '+', 'p', 16:9 , 1), // HD, 720p
RID_MODE( 1280, '+', 720, '+', 'p', 64:27, 2), // HD, 720p, 21:9 anamorphic
RID_MODE( 1680, '+', 720, '+', 'p', 64:27, 3), // 21:9 "1.5k"
RID_MODE( 1920, '+', 1080, '+', 'p', 16:9 , 4), // Full HD, 1080p
RID_MODE( 1929, '+', 1080, '+', 'p', 64:27, 5), // Full HD, 1080p, 21:9 anamorphic
RID_MODE( 2560, '+', 1080, '+', 'p', 64:27, 6), // 21:9 "2.5k"
RID_MODE( 3840, '+', 1080, '+', 'p', 32:9 , 7), // 32:9 "4K"
RID_MODE( 2560, '+', 1440, '+', 'p', 16:9 , 8), // QHD, 1440p
RID_MODE( 3440, '+', 1440, '+', 'p', 64:27, 9), // WQHD
RID_MODE( 5120, '+', 1440, '+', 'p', 32:9 ,10), // 32:9 5k
RID_MODE( 3840, '+', 2160, '+', 'p', 16:9 ,11), // HD "4K", 2160p
RID_MODE( 3840, '+', 2160, '+', 'p', 64:27,12), // UHD "4K", 2160p, 21:9 anamorphic
RID_MODE( 5120, '+', 2160, '+', 'p', 64:27,13), // 21:9 "5K"
RID_MODE( 7680, '+', 2160, '+', 'p', 32:9 ,14), // 32:9 "8K"
RID_MODE( 5120, '+', 2880, '+', 'p', 16:9 ,15), // 2880p
RID_MODE( 5120, '+', 2880, '+', 'p', 64:27,16), // 2880p, 21:9 anamorphic
RID_MODE( 6880, '+', 2880, '+', 'p', 64:27,17), // 21:9 "6K"
RID_MODE(10240, '+', 2880, '+', 'p', 32:9 ,18), // 32:9 "10K"
RID_MODE( 7680, '+', 4320, '+', 'p', 16:9 ,19), // UHD "8K", 4320p
RID_MODE( 7680, '+', 4320, '+', 'p', 64:27,20), // UHD "8K", 4320p, 21:9 anamorphic
RID_MODE(10240, '+', 4320, '+', 'p', 64:27,21), // 21:9 "10K"
RID_MODE(15360, '+', 4320, '+', 'p', 32:9 ,22), // 32:9 "15K"
RID_MODE(11520, '+', 6480, '+', 'p', 16:9 ,23), // UHD "12K", 6480p
RID_MODE(11520, '+', 6480, '+', 'p', 64:27,24), // UHD "12K", 6480p, 21:9 anamorphic
RID_MODE(15360, '+', 6480, '+', 'p', 64:27,25), // 21:9 "15K"
RID_MODE(15360, '+', 8640, '+', 'p', 16:9 ,26), // UHD "16K", 8640p
RID_MODE(15360, '+', 8640, '+', 'p', 64:27,27), // UHD "16K", 8640p, 21:9 anamorphic
RID_MODE(20480, '+', 8640, '+', 'p', 64:27,28) // 21:9 "20K"
// 29...63 Reserved for future
};
static NvU32 MAX_RID_CODES_COUNT = sizeof(RID) / sizeof(RID[0]) - 1;
// RID to VIC Mapping
static const NvU8 RID_VIC_MAP[][8] =
{
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 60, 61, 62, 108, 19, 4, 41, 47 }, // RID 01
{ 65, 66, 67, 109, 68, 69, 70, 71 }, // RID 02
{ 79, 80, 81, 110, 82, 83, 84, 85 }, // RID 03
{ 32, 33, 34, 111, 31, 16, 64, 63 }, // RID 04
{ 72, 73, 74, 112, 75, 76, 77, 78 }, // RID 05
{ 86, 87, 88, 113, 89, 90, 91, 92 }, // RID 06
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 93, 94, 95, 114, 96, 97, 117, 118 }, // RID 11
{ 103, 104, 105, 116, 106, 107, 119, 120 }, // RID 12
{ 121, 122, 123, 124, 125, 126, 127, 193 }, // RID 13
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 194, 195, 196, 197, 198, 199, 200, 201 }, // RID 19
{ 202, 203, 204, 205, 206, 207, 208, 209 }, // RID 20
{ 210, 211, 212, 213, 214, 215, 216, 217 }, // RID 21
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 }
};
// All the frame rate supported in VF
static const NvU16 VF_FRAME_RATE[] =
{
0, 24, 25, 30, 48, 50, 60, 100, 120, 144, 200, 240, 300, 360, 400, 480
};
static NvU8 MAX_VF_FRAME_RATE_COUNT = sizeof(VF_FRAME_RATE) / sizeof (VF_FRAME_RATE[0])-1;
static const NVT_TIMING PSF_TIMING[]=
{
NVT_TIMING( 1920,600, 88,2750,'+', 540, 2,5,562,'+',47952,'i',16:9, 0x1, 1, "ITU-R BT.709-5:1080i/24Psf"),//1920x1080i @47.952Hz | 24/PsF | ITU-R BT.709-5
@@ -371,7 +447,7 @@ static const HDMI3DDETAILS HDMI_MANDATORY_3D_FORMATS[] =
{20, NVT_HDMI_3D_SUPPORTED_SIDEBYSIDEHALF_MASK, NVT_HDMI_VS_BYTE_OPT1_HDMI_3DEX_SSH} // 1920 x 1080i @ 50 Hz
};
static NvU32 MAX_HDMI_MANDATORY_3D_FORMAT = sizeof(HDMI_MANDATORY_3D_FORMATS) / sizeof(HDMI_MANDATORY_3D_FORMATS[0]);
static const NVT_VIDEO_INFOFRAME DEFAULT_VIDEO_INFOFRAME = {/*header*/2,2,13, /*byte1*/0, /*byte2*/0x8, /*byte3*/0, /*byte4*/0, /*byte5*/0, /*byte6~13*/0,0,0,0,0,0,0,0};
static const NVT_VIDEO_INFOFRAME DEFAULT_VIDEO_INFOFRAME = {/*header*/2,2,13, /*byte1*/0, /*byte2*/0x8, /*byte3*/0, /*byte4*/0, /*byte5*/0, /*byte6~13*/0,0,0,0,0,0,0,0, /*byte14~15*/0,0};
static const NVT_AUDIO_INFOFRAME DEFAULT_AUDIO_INFOFRAME = {/*header*/4,1,10, /*byte1*/0, /*byte2*/0, /*byte3*/0, /*byte*/0, /*byte5*/0, /*byte6~10*/0,0,0,0,0};
CODE_SEGMENT(PAGE_DD_CODE)
@@ -388,6 +464,7 @@ getExistedCTATimingSeqNumber(
case NVT_TYPE_CTA861_DID_T7:
case NVT_TYPE_CTA861_DID_T8:
case NVT_TYPE_CTA861_DID_T10:
case NVT_TYPE_EDID_861ST:
break;
default:
return count;
@@ -395,13 +472,79 @@ getExistedCTATimingSeqNumber(
for (i = 0; i< pInfo->total_timings; i++)
{
if (NVT_GET_TIMING_STATUS_TYPE(pInfo->timing[i].etc.status) == timingType)
if (timingType == NVT_TYPE_EDID_861ST)
{
if (NVT_TIMING_IS_OVT(pInfo->timing[i].etc.flag))
++count;
}
else if (NVT_GET_TIMING_STATUS_TYPE(pInfo->timing[i].etc.status) == timingType)
{
++count;
}
}
return count;
}
CODE_SEGMENT(PAGE_DD_CODE)
static NvBool isVFDRefreshRate(NvU8 vfdSize, NvU8 *vfd, NvU8 rateIdx)
{
NvU8 rid, factor, i;
NvU16 rr;
NvBool bFR24, bFR48, bBFR50, bBFR60, bFR144, bFRFactor;
// frame rate factor {0.5x, 1x, 2x, 4x, 6x, 8x} x 2
const NvU8 frame_rate_factors[6] = { 1, 2, 4, 8, 12, 16 };
rr = VF_FRAME_RATE[rateIdx];
factor = 0;
rid = ((const VFD_ONE_BYTE*)vfd)->rid;
if (rid == 0) return NV_FALSE;
bBFR50 = ((const VFD_ONE_BYTE*)vfd)->bfr50;
// frame rate factor
// If Byte 2 is not present in the VFD, flags 0.5X, 1X and BFR60 shall be considered set
bBFR60 = vfdSize > 1 ? ((const VFD_TWO_BYTE*)vfd)->bfr60 : 1;
bFRFactor = vfdSize > 1 ? ((const VFD_TWO_BYTE*)vfd)->frRate : 3;
// individual frame rate
bFR24 = ((const VFD_ONE_BYTE*)vfd)->fr24;
if (rr == 24) return bFR24;
// individual frame rate
bFR48 = vfdSize > 2 ? ((const VFD_THREE_BYTE*)vfd)->fr48 : 0;
if (rr == 48) return bFR48;
// individual frame rate
bFR144 = vfdSize > 1 ? ((const VFD_TWO_BYTE*)vfd)->fr144 : 0;
if (rr == 144) return bFR144;
if (rr % (50/2) == 0)
{
if (!bBFR50) return NV_FALSE;
factor = rr / 25;
}
else if (rr % (60/2) == 0)
{
if (!bBFR60) return NV_FALSE;
factor = rr / 30;
}
for (i = 0; i < COUNT(frame_rate_factors); i++)
{
if (frame_rate_factors[i] == factor)
{
if (bFRFactor & (1 << i))
return NV_TRUE;
else
break;
}
}
return NV_FALSE;
}
// parse the 861 detailed timing info
CODE_SEGMENT(PAGE_DD_CODE)
void parse861ExtDetailedTiming(NvU8 *pEdidExt,
@@ -485,7 +628,7 @@ void parse861bShortTiming(NVT_EDID_CEA861_INFO *pExt861,
for (i = 0; i < total_svd; i++)
{
vic = NVT_GET_CTA_8BIT_VIC(pVic[i]);
vic = NVT_GET_CTA_8BIT_VIC(pVic[i]);
if (vic == 0 || vic > MAX_CEA861B_FORMAT)
continue;
@@ -563,6 +706,120 @@ void parse861bShortTiming(NVT_EDID_CEA861_INFO *pExt861,
}
}
CODE_SEGMENT(PAGE_DD_CODE)
void parseCta861VideoFormatDataBlock(NVT_EDID_CEA861_INFO *pExt861, void *pRawInfo)
{
NvU8 i = 0;
NvU8 rateIdx = 0;
NvU8 vfdb_idx = 0;
NvU8 startSeqNum = 0;
NvU8 eachOfDescSize = 0;
NvU32 width = 0;
NvU32 height = 0;
const VFD_ONE_BYTE *pVFDOneByte = 0 ;
NVT_TIMING newTiming;
NVT_EDID_INFO *pInfo = (NVT_EDID_INFO *)pRawInfo;
for (vfdb_idx = 0; vfdb_idx < pExt861->total_vfdb; vfdb_idx++)
{
eachOfDescSize = pExt861->vfdb[vfdb_idx].info.vfd_len + 1;
if (eachOfDescSize == 0)
{
nvt_assert(0 && "Video Format Descriptor length is 0!\n");
return;
}
for (i = 0; i < pExt861->vfdb[vfdb_idx].total_vfd; i++)
{
// data block value sanity check:
if (eachOfDescSize > 2 && (((const VFD_THREE_BYTE*)&pExt861->vfdb[vfdb_idx].video_format_desc[i*eachOfDescSize])->f31_37 != 0))
nvt_assert(0 && "F31-F37 bits does not be 0 in Byte3!.\n");
if (eachOfDescSize > 3 && ((const VFD_FOUR_BYTE*)&pExt861->vfdb[vfdb_idx].video_format_desc[i*eachOfDescSize])->f40_47 !=0)
nvt_assert(0 && "It is not support yet in Byte4!");
pVFDOneByte = (const VFD_ONE_BYTE *)&pExt861->vfdb[vfdb_idx].video_format_desc[i*eachOfDescSize];
/*
* If any of the following is true, then the RID shall be set to 0:
* 1. If a Video Format not listed in "Table 12 - Resolution Identification (RID) is sent
* 2. if a Video Format with Frame Rates not listed in "Table 13 - AVI InfoFrame Video Format Frame Rate" is sent
* 3. if a Video Format listed in "Table 14 - RID To VIC Mapping" is sent.
*/
// For 1.
if ((pVFDOneByte->rid & NVT_CTA861_VF_RID_MASK) == 0 || pVFDOneByte->rid > MAX_RID_CODES_COUNT)
{
nvt_assert(0 && "shall have a non-zero RID value or RID code value larger than 28");
continue;
}
width = RID[pVFDOneByte->rid].HVisible;
height = RID[pVFDOneByte->rid].VVisible;
// If the Source is sending a Video Format that can be indicated by RID and FR,
// and is not listed in Table 14 (RID to VIC), then it shall set the RID and FR fields to the proper codes
for (rateIdx = 1; rateIdx <= MAX_VF_FRAME_RATE_COUNT; rateIdx++)
{
// For 2.
if (!isVFDRefreshRate(eachOfDescSize, &pExt861->vfdb[vfdb_idx].video_format_desc[i*eachOfDescSize], rateIdx))
{
continue;
}
// For 3.
if (VF_FRAME_RATE[rateIdx] < 144 && RID_VIC_MAP[pVFDOneByte->rid][rateIdx-1])
{
nvt_assert(0 && "RID not allowed since it maps to VIC!");
continue;
}
startSeqNum = getExistedCTATimingSeqNumber(pInfo, NVT_TYPE_EDID_861ST);
NVMISC_MEMSET(&newTiming, 0, sizeof(newTiming));
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)
{
UPDATE_BPC_FOR_COLORFORMAT(newTiming.etc.yuv420, 0, 1,
pInfo->hdmiForumInfo.dc_30bit_420,
pInfo->hdmiForumInfo.dc_36bit_420, 0,
pInfo->hdmiForumInfo.dc_48bit_420);
}
newTiming.etc.flag |= NVT_FLAG_CTA_OVT_TIMING;
if (pExt861->vfdb[vfdb_idx].info.ntsc)
{
newTiming.etc.flag |= NVT_FLAG_CTA_OVT_FRR_TIMING;
}
newTiming.etc.status = NVT_STATUS_EDID_861STn(++startSeqNum);
NVT_SNPRINTF((char *)newTiming.etc.name, sizeof(newTiming.etc.name), "CTA861-OVT%d:#%3d:%dx%dx%3d.%03dHz/%s",
(int)pVFDOneByte->rid,
(int)NVT_GET_TIMING_STATUS_SEQ(newTiming.etc.status),
(int)newTiming.HVisible,
(int)newTiming.VVisible,
(int)newTiming.etc.rrx1k/1000,
(int)newTiming.etc.rrx1k%1000,
(newTiming.interlaced ? "I":"P"));
newTiming.etc.name[sizeof(newTiming.etc.name) - 1] = '\0';
if (!assignNextAvailableTiming(pInfo, &newTiming))
{
continue;
}
}
else
{
continue;
}
}
}
}
}
// parse the 861B short Yuv420 timing descriptor
CODE_SEGMENT(PAGE_DD_CODE)
void parse861bShortYuv420Timing(NVT_EDID_CEA861_INFO *pExt861,
@@ -603,7 +860,6 @@ void parse861bShortYuv420Timing(NVT_EDID_CEA861_INFO *pExt861,
return;
}
for (i = 0; i < total_y420vdb; i++)
{
vic = NVT_GET_CTA_8BIT_VIC(pYuv420Vic[i]);
@@ -735,6 +991,7 @@ void parseCta861NativeOrPreferredTiming(NVT_EDID_CEA861_INFO *pExt861,
NvU8 extDTDCount = 0;
NvU8 DIDT7Count = 0;
NvU8 DIDT10Count = 0;
NvU8 OVTCount = 0;
if (flag == FROM_CTA861_EXTENSION || flag == FROM_DISPLAYID_13_DATA_BLOCK)
{
@@ -765,10 +1022,11 @@ void parseCta861NativeOrPreferredTiming(NVT_EDID_CEA861_INFO *pExt861,
else if (NVT_IS_EXT_DTD(pInfo->timing[j].etc.status)) extDTDCount++;
else if (NVT_IS_CTA861_DID_T7(pInfo->timing[j].etc.status)) DIDT7Count++;
else if (NVT_IS_CTA861_DID_T10(pInfo->timing[j].etc.status)) DIDT10Count++;
else if (NVT_TIMING_IS_OVT(pInfo->timing[j].etc.flag)) OVTCount++;
}
}
// this only handle single SVR right now
// this only handles single SVR
for (i = 0; i < totalSvr; i++)
{
NvU8 svr = 0;
@@ -804,17 +1062,12 @@ void parseCta861NativeOrPreferredTiming(NVT_EDID_CEA861_INFO *pExt861,
break;
}
}
if (pExt861->valid.NVRDB == 1)
pInfo->timing[j].etc.flag |= NVT_FLAG_CTA_NATIVE_TIMING;
else
pInfo->timing[j].etc.flag |= NVT_FLAG_CTA_PREFERRED_TIMING;
}
}
else if (svr >= 145 && svr <= 160)
{
// Interpret as the Nth 20-byte DTD or 6- or 7-byte CVT-based descriptor
// where N = SVR 144 (for N = 1 to 16)
// where N = SVR - 144 (for N = 1 to 16)
kth = svr - 144;
if (flag == FROM_CTA861_EXTENSION)
@@ -833,18 +1086,24 @@ void parseCta861NativeOrPreferredTiming(NVT_EDID_CEA861_INFO *pExt861,
break;
}
}
if (pExt861->valid.NVRDB == 1)
pInfo->timing[j].etc.flag |= NVT_FLAG_CTA_NATIVE_TIMING;
else
pInfo->timing[j].etc.flag |= NVT_FLAG_CTA_PREFERRED_TIMING;
}
}
}
else if (svr >= 161 && svr <= 175)
{
// Interpret as the video format indicated by the first VFD of the first VFDB with Frame Rates of Rate Index N
// where N = SVR - 160 (for N = 1 to 15)
break;
kth = svr - 160;
if (flag == FROM_CTA861_EXTENSION)
{
for (j = 0; j < pInfo->total_timings; j++)
{
if (kth <= OVTCount)
{
if (NVT_IS_CTA861_OVT_Tn(pInfo->timing[j].etc.flag, pInfo->timing[j].etc.status, kth))
break;
}
}
}
}
else if (svr == 254)
{
@@ -855,15 +1114,11 @@ void parseCta861NativeOrPreferredTiming(NVT_EDID_CEA861_INFO *pExt861,
{
if (NVT_IS_CTA861_DID_T8_1(pInfo->timing[j].etc.status))
{
if (pExt861->valid.NVRDB == 1)
pInfo->timing[j].etc.flag |= NVT_FLAG_CTA_NATIVE_TIMING;
else
pInfo->timing[j].etc.flag |= NVT_FLAG_CTA_PREFERRED_TIMING;
kth = 1;
break;
}
}
}
break;
}
else // assign corresponding CEA format's timing from pre-defined CE timing table, EIA861B
{
@@ -877,13 +1132,7 @@ void parseCta861NativeOrPreferredTiming(NVT_EDID_CEA861_INFO *pExt861,
{
isMatch = NvTiming_IsTimingExactEqual(&pInfo->timing[j], &preferTiming);
if (isMatch && (NVT_GET_TIMING_STATUS_TYPE(pInfo->timing[j].etc.status) == NVT_TYPE_EDID_861ST))
{
if (pExt861->valid.NVRDB == 1)
pInfo->timing[j].etc.flag |= NVT_FLAG_CTA_NATIVE_TIMING;
else
pInfo->timing[j].etc.flag |= NVT_FLAG_CTA_PREFERRED_TIMING;
break;
}
}
}
else if (flag == FROM_DISPLAYID_20_DATA_BLOCK)
@@ -892,16 +1141,25 @@ void parseCta861NativeOrPreferredTiming(NVT_EDID_CEA861_INFO *pExt861,
{
isMatch = NvTiming_IsTimingExactEqual(&pDisplayID20->timing[j], &preferTiming);
if (isMatch && (NVT_GET_TIMING_STATUS_TYPE(pDisplayID20->timing[j].etc.status) == NVT_TYPE_EDID_861ST))
{
if (pExt861->valid.NVRDB == 1)
pDisplayID20->timing[j].etc.flag |= NVT_FLAG_CTA_NATIVE_TIMING | NVT_FLAG_DISPLAYID_2_0_TIMING;
else
pDisplayID20->timing[j].etc.flag |= NVT_FLAG_CTA_PREFERRED_TIMING | NVT_FLAG_DISPLAYID_2_0_TIMING;
break;
}
}
}
}
if (flag == FROM_CTA861_EXTENSION || flag == FROM_DISPLAYID_13_DATA_BLOCK)
{
if (pExt861->valid.NVRDB == 1)
pInfo->timing[j].etc.flag |= NVT_FLAG_CTA_NATIVE_TIMING;
else if (vic != 0 || kth != 0)
pInfo->timing[j].etc.flag |= NVT_FLAG_CTA_PREFERRED_TIMING;
}
else if (flag == FROM_DISPLAYID_20_DATA_BLOCK)
{
if (pExt861->valid.NVRDB == 1)
pDisplayID20->timing[j].etc.flag |= NVT_FLAG_CTA_NATIVE_TIMING | NVT_FLAG_DISPLAYID_2_0_TIMING;
else if (vic !=0 || kth != 0)
pDisplayID20->timing[j].etc.flag |= NVT_FLAG_CTA_PREFERRED_TIMING | NVT_FLAG_DISPLAYID_2_0_TIMING;
}
}
}
@@ -1423,6 +1681,7 @@ NVT_STATUS parseCta861DataBlockInfo(NvU8 *p,
NvU32 vsvdb_index = 0;
NvU32 yuv420vdb_index = 0;
NvU32 yuv420cmdb_index = 0;
NvU8 vfd_index = 0;
NvU8 didT7_index = 0;
NvU8 didT8_index = 0;
NvU8 didT10_index = 0;
@@ -1456,6 +1715,9 @@ NVT_STATUS parseCta861DataBlockInfo(NvU8 *p,
case NVT_CEA861_TAG_VESA_DTC:
case NVT_CEA861_TAG_RSVD:
break;
case NVT_CTA861_TAG_VIDEO_FORMAT:
if (payload < 2) return NVT_STATUS_ERR; // no VFD
break;
case NVT_CEA861_TAG_VENDOR:
if (payload < 3) return NVT_STATUS_ERR;
break;
@@ -1504,7 +1766,7 @@ NVT_STATUS parseCta861DataBlockInfo(NvU8 *p,
}
break;
default:
break;
break;
}
return NVT_STATUS_SUCCESS;
}
@@ -1592,6 +1854,22 @@ NVT_STATUS parseCta861DataBlockInfo(NvU8 *p,
vendor_index++;
}
}
else if (tag == NVT_CTA861_TAG_VIDEO_FORMAT)
{
p861info->vfdb[vfd_index].info.vfd_len = p[i] & 0x03;
p861info->vfdb[vfd_index].info.ntsc = (p[i] & 0x40) >> 6;
p861info->vfdb[vfd_index].info.y420 = (p[i] & 0x80) >> 7;
p861info->vfdb[vfd_index].total_vfd = (NvU8)(payload - 1) / (p861info->vfdb[vfd_index].info.vfd_len + 1);
i++; payload--;
for (j = 0; j < payload; j++, i++)
{
p861info->vfdb[vfd_index].video_format_desc[j] = p[i];
}
p861info->total_vfdb = ++vfd_index;
}
else if (tag == NVT_CEA861_TAG_EXTENDED_FLAG)
{
if (payload >= 1)
@@ -2025,6 +2303,7 @@ NVT_STATUS NvTiming_ConstructVideoInfoframeCtrl(const NVT_TIMING *pTiming, NVT_V
{
// Prior RFE 543088
if (pCtrl->video_format_id == 0 &&
!(NVT_FRR_TIMING_IS_OVT(pTiming->etc.flag) || NVT_TIMING_IS_OVT(pTiming->etc.flag)) &&
NVT_GET_TIMING_STATUS_TYPE(pTiming->etc.status) == NVT_TYPE_EDID_861ST)
{
pCtrl->video_format_id = (NvU8)NVT_GET_TIMING_STATUS_SEQ(pTiming->etc.status);
@@ -2040,6 +2319,129 @@ NVT_STATUS NvTiming_ConstructVideoInfoframeCtrl(const NVT_TIMING *pTiming, NVT_V
}
}
// setup RID code
if (pCtrl->rid == NVT_INFOFRAME_CTRL_DONTCARE)
{
if (NVT_TYPE_EDID_861ST == NVT_GET_TIMING_STATUS_TYPE(pTiming->etc.status) &&
NVT_TIMING_IS_OVT(pTiming->etc.flag))
{
NvU8 ridIdx = 0;
// get the correct rid from the name string = CTA861-OVT'%d':xxx
// %d value shall included two digital or one digital character
if (pTiming->etc.name[11] == ':')
{
ridIdx = pTiming->etc.name[10] - '0';
}
else
{
ridIdx = 10 * (pTiming->etc.name[10] - '0') + (pTiming->etc.name[11] - '0');
}
if (ridIdx > NVT_CTA861_RID_1280x720p_16x9 &&
ridIdx < NVT_CTA861_RID_20480x8640p_64x27)
{
pCtrl->rid = ridIdx;
}
else
{
pCtrl->rid = NVT_INFOFRAME_CTRL_DONTCARE;
}
}
}
// setup Video Format Frame Rate
if (pCtrl->rid != NVT_INFOFRAME_CTRL_DONTCARE)
{
switch (pTiming->etc.rr)
{
case 24:
pCtrl->frame_rate = NVT_CTA861_FR_2400;
if (NVT_FRR_TIMING_IS_OVT(pTiming->etc.flag))
{
pCtrl->frame_rate = NVT_CTA861_FR_2398;
}
break;
case 25:
pCtrl->frame_rate = NVT_CTA861_FR_2500;
break;
case 30:
pCtrl->frame_rate = NVT_CTA861_FR_3000;
if (NVT_FRR_TIMING_IS_OVT(pTiming->etc.flag))
{
pCtrl->frame_rate = NVT_CTA861_FR_2997;
}
break;
case 48:
pCtrl->frame_rate = NVT_CTA861_FR_48000;
if (NVT_FRR_TIMING_IS_OVT(pTiming->etc.flag))
{
pCtrl->frame_rate = NVT_CTA861_FR_4795;
}
break;
case 50:
pCtrl->frame_rate = NVT_CTA861_FR_5000;
break;
case 60:
pCtrl->frame_rate = NVT_CTA861_FR_6000;
if (NVT_FRR_TIMING_IS_OVT(pTiming->etc.flag))
{
pCtrl->frame_rate = NVT_CTA861_FR_5994;
}
break;
case 100:
pCtrl->frame_rate = NVT_CTA861_FR_10000;
break;
case 120:
pCtrl->frame_rate = NVT_CTA861_FR_12000;
if (NVT_FRR_TIMING_IS_OVT(pTiming->etc.flag))
{
pCtrl->frame_rate = NVT_CTA861_FR_11988;
}
break;
case 144:
pCtrl->frame_rate = NVT_CTA861_FR_14400;
if (NVT_FRR_TIMING_IS_OVT(pTiming->etc.flag))
{
pCtrl->frame_rate = NVT_CTA861_FR_14386;
}
break;
case 200:
pCtrl->frame_rate = NVT_CTA861_FR_20000;
break;
case 240:
pCtrl->frame_rate = NVT_CTA861_FR_24000;
if (NVT_FRR_TIMING_IS_OVT(pTiming->etc.flag))
{
pCtrl->frame_rate = NVT_CTA861_FR_23976;
}
break;
case 300:
pCtrl->frame_rate = NVT_CTA861_FR_30000;
break;
case 360:
pCtrl->frame_rate = NVT_CTA861_FR_36000;
if (NVT_FRR_TIMING_IS_OVT(pTiming->etc.flag))
{
pCtrl->frame_rate = NVT_CTA861_FR_35964;
}
break;
case 400:
pCtrl->frame_rate = NVT_CTA861_FR_40000;
break;
case 480:
pCtrl->frame_rate = NVT_CTA861_FR_48000;
if (NVT_FRR_TIMING_IS_OVT(pTiming->etc.flag))
{
pCtrl->frame_rate = NVT_CTA861_FR_47952;
}
break;
default:
pCtrl->frame_rate = NVT_INFOFRAME_CTRL_DONTCARE;
break;
}
}
// for HDMI_EXT timing, AVI VIC should be 0.
if (NVT_GET_TIMING_STATUS_TYPE(pTiming->etc.status) == NVT_TYPE_HDMI_EXT)
{
@@ -2125,47 +2527,42 @@ NVT_STATUS NvTiming_ConstructVideoInfoframe(NVT_EDID_INFO *pEdidInfo, NVT_VIDEO_
// init the header
pInfoFrame->type = NVT_INFOFRAME_TYPE_VIDEO;
// TODO : This is just to check the version, we still need to change lots of structure
// "NVT_VIDEO_INFOFRAME" / "VIDEO_INFOFRAME" / "DEFAULT_VIDEO_INFOFRAME" / "NVM_DISP_STATE" etc..
// to accept the new ACE0-3 bits supported in the future. Right now no any sink to support this.
//
// Based on the latest CTA-861-H.pdf file, we need to do following logic to get the correct CTA861 version
// When Y=7, the IDO defines the C, EC and ACE fields, it shall use AVI InfoFrame Version 4.
// When Y < 7, the following algorithm shall be used for AVI InfoFrame version selection:
// if (C=3 and EC=7)
// Sources shall use AVI InfoFrame Version 4.
// Else if (VIC>=128)
// Sources shall use AVI InfoFrame Version 3.
// Else
// Sources shall use AVI InfoFrame Version 2.
// End if
//
// see 6.4 Format of Version 2, 3, and 4 AVI InfoFrames in CTA861-I
if (pCtrl)
{
if (nvt_get_bits(pInfoFrame->byte1, NVT_VIDEO_INFOFRAME_BYTE1_Y2Y1Y0_MASK, NVT_VIDEO_INFOFRAME_BYTE1_Y2Y1Y0_SHIFT) == NVT_VIDEO_INFOFRAME_BYTE1_Y2Y1Y0_IDODEFINED)
{
pInfoFrame->version = NVT_VIDEO_INFOFRAME_VERSION_4;
}
else if (nvt_get_bits(pInfoFrame->byte1, NVT_VIDEO_INFOFRAME_BYTE1_Y2Y1Y0_MASK, NVT_VIDEO_INFOFRAME_BYTE1_Y2Y1Y0_SHIFT) < NVT_VIDEO_INFOFRAME_BYTE1_Y2Y1Y0_IDODEFINED)
if (nvt_get_bits(pInfoFrame->byte1, NVT_VIDEO_INFOFRAME_BYTE1_Y2Y1Y0_MASK, NVT_VIDEO_INFOFRAME_BYTE1_Y2Y1Y0_SHIFT) <= NVT_VIDEO_INFOFRAME_BYTE1_Y2Y1Y0_YCbCr420) // this shall be as 0 always.
{
if ((pCtrl->rid != NVT_CTA861_RID_NONE) || (pCtrl->frame_rate != NVT_CTA861_FR_NO_DATA))
{
pInfoFrame->version = NVT_VIDEO_INFOFRAME_VERSION_4; // just put the logic to get the correct version 4, but it shall not be used at currently stage.
pInfoFrame->length = sizeof(NVT_VIDEO_INFOFRAME) - sizeof(NVT_INFOFRAME_HEADER); // Length == 15
}
else
if ((nvt_get_bits(pInfoFrame->byte2, NVT_VIDEO_INFOFRAME_BYTE2_C1C0_MASK, NVT_VIDEO_INFOFRAME_BYTE2_C1C0_SHIFT) == NVT_VIDEO_INFOFRAME_BYTE2_C1C0_EXT_COLORIMETRY) &&
//EC2-0 is based on the 7.5.5 at CTA861-G which DCI-P3 bit defined or notat byte4
(nvt_get_bits(pInfoFrame->byte3, NVT_VIDEO_INFOFRAME_BYTE3_EC_MASK, NVT_VIDEO_INFOFRAME_BYTE3_EC_SHIFT) == NVT_VIDEO_INFOFRAME_BYTE3_EC_AdditionalColorExt))
{
pInfoFrame->version = NVT_VIDEO_INFOFRAME_VERSION_4; // just put the logic to get the correct version 4, but it shall not be used at currently stage.
pInfoFrame->version = NVT_VIDEO_INFOFRAME_VERSION_4; // just put the logic to get the correct version 4, but it shall not be used at currently stage.
pInfoFrame->length = 14;
}
else
{
pInfoFrame->version = (((pCtrl->video_format_id & NVT_VIDEO_INFOFRAME_BYTE4_VIC7) == NVT_VIDEO_INFOFRAME_BYTE4_VIC7) ? NVT_VIDEO_INFOFRAME_VERSION_3 :
pInfoFrame->version = (((pCtrl->video_format_id & NVT_VIDEO_INFOFRAME_BYTE4_VIC7) != 0) ? NVT_VIDEO_INFOFRAME_VERSION_3 :
((pEdidInfo->ext861.revision >= NVT_CEA861_REV_B) ? NVT_VIDEO_INFOFRAME_VERSION_2 : NVT_VIDEO_INFOFRAME_VERSION_1));
pInfoFrame->length = 13;
}
}
else // Y=7, the IDO defineds the C, EC, ACE fileds. In the case the Source shall set the AVI InforFrame Version filed to no less than 3
{
pInfoFrame->version = NVT_VIDEO_INFOFRAME_VERSION_4;
pInfoFrame->length = 14;
}
}
else
{
pInfoFrame->version = (pEdidInfo->ext861.revision >= NVT_CEA861_REV_B) ? NVT_VIDEO_INFOFRAME_VERSION_2 : NVT_VIDEO_INFOFRAME_VERSION_1;
pInfoFrame->length = 13;
}
pInfoFrame->length = sizeof(NVT_VIDEO_INFOFRAME) - sizeof(NVT_INFOFRAME_HEADER);
if (pInfoFrame->version < NVT_VIDEO_INFOFRAME_VERSION_3)
{
@@ -2287,6 +2684,34 @@ NVT_STATUS NvTiming_ConstructVideoInfoframe(NVT_EDID_INFO *pEdidInfo, NVT_VIDEO_
pInfoFrame->right_bar_low = (NvU8)(pCtrl->right_bar % 0x100);
pInfoFrame->right_bar_high = (NvU8)(pCtrl->right_bar / 0x100);
}
// byte 14-15
if (pInfoFrame->version >= NVT_VIDEO_INFOFRAME_VERSION_4)
{
if (pCtrl->addition_colorimetry_ext != NVT_INFOFRAME_CTRL_DONTCARE)
{
nvt_nvu8_set_bits(pInfoFrame->byte14, pCtrl->addition_colorimetry_ext, NVT_VIDEO_INFOFRAME_BYTE14_ACE0_3_MASK, NVT_VIDEO_INFOFRAME_BYTE14_ACE0_3_SHIFT);
}
if (pCtrl->frame_rate != NVT_INFOFRAME_CTRL_DONTCARE)
{
// Frame rate
nvt_nvu8_set_bits(pInfoFrame->byte14, pCtrl->frame_rate, NVT_VIDEO_INFOFRAME_BYTE14_FR0_FR3_MASK, NVT_VIDEO_INFOFRAME_BYTE14_FR0_FR3_SHIFT);
pInfoFrame->byte15 &= NVT_VIDEO_INFOFRAME_BYTE15_FR4_MASK^0xFFU;
pInfoFrame->byte15 |= ((pCtrl->frame_rate & NVT_VIDEO_INFOFRAME_BYTE14_FR4_ONE_BIT_MASK) << NVT_VIDEO_INFOFRAME_BYTE15_FR4_SHIFT) & NVT_VIDEO_INFOFRAME_BYTE15_FR4_MASK;
}
if (pCtrl->rid != NVT_INFOFRAME_CTRL_DONTCARE)
{
// RID
nvt_nvu8_set_bits(pInfoFrame->byte15, pCtrl->rid, NVT_VIDEO_INFOFRAME_BYTE15_RID_MASK, NVT_VIDEO_INFOFRAME_BYTE15_RID_SHIFT);
}
}
else // version 2 or 3
{
pInfoFrame->byte14 = 0;
pInfoFrame->byte15 = 0;
}
}
return NVT_STATUS_SUCCESS;
@@ -2602,7 +3027,7 @@ NVT_STATUS NvTiming_ConstructExtendedMetadataPacketInfoframe(
}
else if (pCtrl->EnableQMS)
{
nvt_nvu8_set_bits(pInfoFrame->Data.metadataBytes[0], 1,
nvt_nvu8_set_bits(pInfoFrame->Data.metadataBytes[0], pCtrl->MConst,
NVT_HDMI_EMP_BYTE8_MD0_M_CONST_MASK,
NVT_HDMI_EMP_BYTE8_MD0_M_CONST_SHIFT);
nvt_nvu8_set_bits(pInfoFrame->Data.metadataBytes[0],
@@ -2711,6 +3136,16 @@ void NvTiming_ConstructAdaptiveSyncSDP(
NVT_DP_ADAPTIVE_SYNC_SDP_DB4_TARGET_RR_DIVIDER_MASK,
NVT_DP_ADAPTIVE_SYNC_SDP_DB4_TARGET_RR_DIVIDER_SHIFT);
}
if (pCtrl->srCoastingVTotal)
{
nvt_nvu8_set_bits(pSdp->payload.db7, pCtrl->srCoastingVTotal & 0xff,
NVT_DP_ADAPTIVE_SYNC_SDP_DB7_PR_COASTING_VTOTAL_LSB_MASK,
NVT_DP_ADAPTIVE_SYNC_SDP_DB7_PR_COASTING_VTOTAL_LSB_SHIFT);
nvt_nvu8_set_bits(pSdp->payload.db8, (pCtrl->srCoastingVTotal & 0xff00) >> 8,
NVT_DP_ADAPTIVE_SYNC_SDP_DB8_PR_COASTING_VTOTAL_MSB_MASK,
NVT_DP_ADAPTIVE_SYNC_SDP_DB8_PR_COASTING_VTOTAL_MSB_SHIFT);
}
}
// Enumerate Psf Timing
@@ -3406,7 +3841,6 @@ void parseEdidHdmiForumVSDB(VSDB_DATA *pVsdb, NVT_HDMI_FORUM_INFO *pHdmiInfo)
default:
break;
}
}

View File

@@ -28,3 +28,266 @@
//*****************************************************************************
#include "nvBinSegment.h"
#include "nvmisc.h"
#include "nvtiming_pvt.h"
PUSH_SEGMENTS
CONS_SEGMENT(PAGE_CONS)
const NvU32 NVT_OVT_PIXEL_CLOCK_GRANULARITY = 1000; // Resulting Pixel Clock will be a multiple of this
const NvU32 NVT_OVT_MIN_H_TOTAL_GRANULARITY = 8; // Resulting Htotal value will be a multiple of this
const NvU32 NVT_OVT_MIN_V_BLANK_MICROSEC = 460; // Minimum duration of Vblank (us)
const NvU32 NVT_OVT_MIN_V_SYNC_LEADING_EDGE = 400; // Minimum duration of Vsync + Vback (us)
const NvU32 NVT_OVT_MIN_CLOCK_RATE_420 = 590000000; // interface-specific minimum pixel rate for transport of 4:2:0 sample
const NvU32 NVT_OVT_PIXEL_FACTOR_420 = 2; // Worst case of two pixels per link character for pixel rates of MinClockRate420 or more
const NvU32 NVT_OVT_MIN_H_BLANK_444 = 80; // Minimum Hblank width for pixel rates below MinClockRate420
const NvU32 NVT_OVT_MIN_H_BLANK_420 = 128; // Minimum Hblank width for pixel rates of MinClockRate420 or more
const NvU32 NVT_OVT_MAX_CHUNK_RATE = 650000000; // Maximum rate of chunks of pixels with a power-of-two size
const NvU32 NVT_OVT_AUDIO_PACKET_RATE = 195000; // 192k sample packets + 3k auxiliary data packets
const NvU32 NVT_OVT_AUDIO_PACKET_SIZE = 32; // each packet carries 8 audio sample
const NvU32 NVT_OVT_LINE_OVERHEAD = 32; // interface-specific overhead: 32 pixels/line
const NvU32 NVT_OVT_H_SYNC_PIXELS = 32;
const NvU32 NVT_OVT_H_BACK_WIDTH = 32;
const NvU32 NVT_OVT_V_SYNC_WIDTH = 8;
CODE_SEGMENT(PAGE_DD_CODE)
static NvU32 nvFloorPow2_U32(NvU32 x)
{
return x & ~(x - 1);
}
CODE_SEGMENT(PAGE_DD_CODE)
static NvU32 computeGCD(NvU32 a, NvU32 b)
{
NvU32 temp;
while (b != 0)
{
temp = a % b;
if (temp == 0) return b;
a = b;
b = temp;
}
return a;
}
CODE_SEGMENT(PAGE_DD_CODE)
static NvU32 calculate_aspect_ratio(NVT_TIMING *pT)
{
NvU32 gcd = computeGCD(pT->HVisible, pT->VVisible);
if (gcd == 0)
{
pT->etc.aspect = (NvU32)0;
return 0;
}
return (pT->HVisible / gcd) << 16 | (pT->VVisible / gcd);
}
/**
* OVT Algorithm Calculations Formula
*
* @brief Sinks can indicate supported video formats with VFD in a VFDB that are not represented by a CTA VIC.
* The timing parameters of those Video Formats are determined by the Optimized Video Timing(OVT) algorithm
*
* @param width : resolution width from RID
* @param height : resolution height from RID
* @param refreshRate : refresh rate x fraction rate
* @param pT : output all the parameters in NVT_TIMING
*
* @return NVT_STATUS_SUCCESS
*
*/
CODE_SEGMENT(PAGE_DD_CODE)
NVT_STATUS NvTiming_CalcOVT(NvU32 width, NvU32 height, NvU32 refreshRate, NVT_TIMING *pT)
{
NvU32 hTotal = 0;
NvU32 vTotal = 0;
NvU32 maxVRate = refreshRate;
NvU32 vTotalGranularity = 1;
NvU32 resolutionGranularity = 0;
NvU32 minVBlank, minVTotal, minLineRate, minHBlank, minHTotal, vBlank, vSyncPosition;
NvU32 hTotalGranularityChunk, hTotalGranularity, maxAudioPacketsPerLine;
NvU64 minPixelClockRate = 0LL;
NvU64 pixelClockRate = 0LL;
NvU64 maxActiveTime = 0LL;
NvU64 minLineTime = 0LL;
NvU64 minResolution = 0LL;
NvU32 V = 0;
NvU32 H = 0;
NvU64 R = 0;
// parameter sanity check
if (width % 8 != 0)
return NVT_STATUS_ERR;
// ** Preparation **
// 1. Determine maximum Vrate of frame rate group (see Table 13) and V-Total granularity:
switch (refreshRate)
{
case 24: case 25: case 30:
maxVRate = 30;
vTotalGranularity = 20;
break;
case 48: case 50: case 60:
maxVRate = 60;
vTotalGranularity = 20;
break;
case 100: case 120:
maxVRate = 120;
vTotalGranularity = 5;
break;
case 144:
maxVRate = 144;
vTotalGranularity = 1;
break;
case 200: case 240:
maxVRate = 240;
vTotalGranularity = 5;
break;
case 300: case 360:
maxVRate = 360;
vTotalGranularity = 5;
break;
case 400: case 480:
maxVRate = 480;
vTotalGranularity = 5;
break;
default:
vTotalGranularity = 1;
maxVRate = refreshRate;
nvt_assert (0 && "invalid input refresh rate!");
}
// 2. Minimum Vtotal is found from highest frame rate of Vrate group, Vactive and the minimum Vblank time of 460 μSec:
// 2.1 the minimum number of determine the maximum active time. For the sake of precision, it is multiplied by 1,000,000.
maxActiveTime = ((NvU64)1000000000000 / (NvU64)maxVRate) - (NvU64)NVT_OVT_MIN_V_BLANK_MICROSEC * 1000000;
// 2.2 get the minimum line time
minLineTime = maxActiveTime / (NvU64)height;
// 2.3 get the minimum number of VBlank lines. The multiplicand 1000000 is for accuracy, because we multiply it at 2.1
minVBlank = (NvU32)(NV_UNSIGNED_DIV_CEIL((NvU64)NVT_OVT_MIN_V_BLANK_MICROSEC * (NvU64)1000000, (NvU64)minLineTime));
// 2.4 get the minimum total number of lines
minVTotal = height + minVBlank;
if (minVTotal % vTotalGranularity !=0)
minVTotal += (vTotalGranularity - (minVTotal % vTotalGranularity));
// 3. Find the audio packet rate and use it to determine the required audio packets per line:
// 3.1 determine a minimum line rate
minLineRate = maxVRate * minVTotal; // Hz
// 3.2 The maximum number of audio packets
maxAudioPacketsPerLine = NV_UNSIGNED_DIV_CEIL(NVT_OVT_AUDIO_PACKET_RATE, minLineRate);
// 4. Find initial minimum horizontal total size, based on audio requirements (1 pixel = 1 character):
minHBlank = NVT_OVT_LINE_OVERHEAD + NVT_OVT_AUDIO_PACKET_SIZE * maxAudioPacketsPerLine;
// 4.1 determine a minimum Horizontal Total pixel (MinHtotal)
minHTotal = width + NV_MAX(NVT_OVT_MIN_H_BLANK_444, minHBlank);
// 5. Find hTotal and vTotal so that the pixelClockRate is divisible by the pixelClockGranularity, and
// hTotal is divisible by an appropriate processing chunk size:
minPixelClockRate = (NvU64)maxVRate * (NvU64)minHTotal * (NvU64)minVTotal; // Hz
// 5.1 determinate new granularity and minHtotal based on the new granularity
hTotalGranularityChunk = nvNextPow2_U32((NvU32)NV_UNSIGNED_DIV_CEIL(minPixelClockRate, (NvU64)NVT_OVT_MAX_CHUNK_RATE));
// 5.2 If this value is greater than the 8, it becomes the new horizontal granularity
hTotalGranularity = NV_MAX((NvU64)NVT_OVT_MIN_H_TOTAL_GRANULARITY, hTotalGranularityChunk);
if (minHTotal % hTotalGranularity != 0)
{
minHTotal += (hTotalGranularity - (minHTotal % hTotalGranularity));
}
// 5.3 optimized by iterating on resolution totals without multiplying by the max refresh rate.
resolutionGranularity = NVT_OVT_PIXEL_CLOCK_GRANULARITY / computeGCD(NVT_OVT_PIXEL_CLOCK_GRANULARITY, maxVRate);
// ** OVT Timing Search **
// 5.4 it will repeat until the found pixel clock is greater than the divisible pixel clock of the search at hte previous vTotal value,
// the hTotal and vTotal values of that preceding search are chosen for the video timing
for(;;)
{
minResolution = 0;
V = minVTotal;
for(;;)
{
H = minHTotal;
R = (NvU64)H * (NvU64)V;
if (minResolution && R > minResolution)
break;
while (R % resolutionGranularity || maxVRate * R / nvFloorPow2_U32(H) > NVT_OVT_MAX_CHUNK_RATE)
{
H += hTotalGranularity;
R = (NvU64)H * (NvU64)V;
}
if (minResolution == 0 || R < minResolution)
{
hTotal = H;
vTotal = V;
minResolution = R;
}
V += vTotalGranularity;
}
pixelClockRate = maxVRate * minResolution;
// 6. Check if timing requires adjustments for 4:2:0:
// 6.a Re-calculate minHTotal, in pixels, adjusted for 4:2:0 requirements. (2 pixels = 1 character):
minHTotal = width + NV_MAX(NVT_OVT_MIN_H_BLANK_420, NVT_OVT_PIXEL_FACTOR_420 * minHBlank);
// 6.b If the resulting PixelClockRate allows for 4:2:0, assure that the new Hblank requirement is met, or repeat calculation with new MinHtotal:
if (pixelClockRate >= NVT_OVT_MIN_CLOCK_RATE_420 && hTotal < minHTotal)
{
continue;
}
break;
}
// ** post-processing **
// 7. Adjust Vtotal, in lines, to achieve (integer) target Vrate:
vTotal = vTotal * maxVRate / refreshRate;
// 8. Find Vsync leading edge:
vBlank = vTotal - height;
vSyncPosition = (NvU32)NV_UNSIGNED_DIV_CEIL(((NvU64)NVT_OVT_MIN_V_SYNC_LEADING_EDGE * (NvU64)pixelClockRate), ((NvU64)1000000 * (NvU64)hTotal));
// 10. fill in the essential timing info for output
pT->HVisible = (NvU16)width;
pT->HTotal = (NvU16)hTotal;
pT->HFrontPorch = (NvU16)(hTotal - width - NVT_OVT_H_SYNC_PIXELS - NVT_OVT_H_BACK_WIDTH);
pT->HSyncWidth = (NvU16)NVT_OVT_H_SYNC_PIXELS;
pT->VVisible = (NvU16)height;
pT->VTotal = (NvU16)vTotal;
pT->VSyncWidth = (NvU16)NVT_OVT_V_SYNC_WIDTH;
pT->VFrontPorch = (NvU16)(vBlank - vSyncPosition);
pT->pclk = (NvU32)(pixelClockRate /*Hz*/ / 1000 + 5) / 10; //convert to 10Khz
pT->HSyncPol = NVT_H_SYNC_POSITIVE;
pT->VSyncPol = NVT_V_SYNC_POSITIVE;
pT->HBorder = pT->VBorder = 0; // not supported
pT->interlaced = 0; // not supported
// fill in the extra timing info
pT->etc.flag = 0;
pT->etc.rr = (NvU16)refreshRate;
pT->etc.rrx1k = (NvU32)axb_div_c_64((NvU64)pT->pclk, (NvU64)10000 * (NvU64)1000, (NvU64)pT->HTotal*(NvU64)pT->VTotal);
pT->etc.aspect = calculate_aspect_ratio(pT);
pT->etc.rep = 0x1;
NVT_SNPRINTF((char *)pT->etc.name, 40, "CTA861-OVT:%dx%dx%dHz", width, height, refreshRate);
pT->etc.name[39] = '\0';
return NVT_STATUS_SUCCESS;
}
CODE_SEGMENT(PAGE_DD_CODE)
NvBool NvTiming_IsTimingOVT(const NVT_TIMING *pTiming)
{
// Check from the Timing Type
if (pTiming->etc.flag & NVT_FLAG_CTA_OVT_TIMING)
{
return NV_TRUE;
}
return NV_FALSE;
}
POP_SEGMENTS

View File

@@ -114,6 +114,13 @@ typedef union tagNVT_COLORDEPTH
(_colorFormat).bpc.bpc8 ? NVT_EDID_VIDEOSIGNAL_BPC_8 : \
(_colorFormat).bpc.bpc6 ? NVT_EDID_VIDEOSIGNAL_BPC_6 : NVT_EDID_VIDEOSIGNAL_BPC_NOT_DEFINED
#define NVT_COLORDEPTH_LOWEREST_BPC(_colorFormat) \
(_colorFormat).bpc.bpc6 ? NVT_EDID_VIDEOSIGNAL_BPC_6 : \
(_colorFormat).bpc.bpc8 ? NVT_EDID_VIDEOSIGNAL_BPC_8 : \
(_colorFormat).bpc.bpc10 ? NVT_EDID_VIDEOSIGNAL_BPC_10 : \
(_colorFormat).bpc.bpc12 ? NVT_EDID_VIDEOSIGNAL_BPC_12 : \
(_colorFormat).bpc.bpc16 ? NVT_EDID_VIDEOSIGNAL_BPC_16 : NVT_EDID_VIDEOSIGNAL_BPC_NOT_DEFINED
typedef struct tagNVT_TIMINGEXT
{
NvU32 flag; // reserve for NV h/w based enhancement like double-scan.
@@ -430,6 +437,7 @@ typedef enum NVT_TV_FORMAT
#define NVT_STATUS_CTA861_DID_T7N(n) NVT_DEF_TIMING_STATUS(NVT_TYPE_CTA861_DID_T7, n)
#define NVT_STATUS_CTA861_DID_T8N(n) NVT_DEF_TIMING_STATUS(NVT_TYPE_CTA861_DID_T8, n)
#define NVT_STATUS_CTA861_DID_T10N(n) NVT_DEF_TIMING_STATUS(NVT_TYPE_CTA861_DID_T10, n)
#define NVT_STATUS_CTA861_OVT_Tn(n) NVT_DEF_TIMING_STATUS(NVT_TYPE_CTA861_OVT, n)
//********************************
// CEA/EIA 861 related EDID info
@@ -469,7 +477,7 @@ typedef enum NVT_TV_FORMAT
#define NVT_CEA861_TAG_VENDOR 3 // Vendor Specific Data Block
#define NVT_CEA861_TAG_SPEAKER_ALLOC 4 // Speaker Allocation Data Block
#define NVT_CEA861_TAG_VESA_DTC 5 // VESA DTC data block
#define NVT_CEA861_TAG_RSVD1 6 // reserved block
#define NVT_CTA861_TAG_VIDEO_FORMAT 6 // Video Format Data Block in CTA861.6
#define NVT_CEA861_TAG_EXTENDED_FLAG 7 // use Extended Tag
//
// the extended tag codes when NVT_CEA861_TAG_EXTENDED_FLAG
@@ -563,7 +571,7 @@ typedef enum NVT_TV_FORMAT
// information but where the vertical frequency is adjusted by a factor of
// 1000/1001 (i.e., 24/1.001, 30/1.001, 60/1.001, 120/1.001 or 240/1.001).
// Excluding ceaIndex 1 640x480 which is a PC Mode.
#define NVT_CEA861_TIMING_FRR(_VID_, _RR_) ((_VID_) > 1 && ((_RR_) % 6) == 0)
#define NVT_CTA861_TIMING_FRR(_VID_, _RR_) ((_VID_) > 1 && ((_RR_) % 6) == 0)
#define NVT_CEA861_640X480P_59940HZ_4X3 1 // Video Identification Code: format 1
#define NVT_CEA861_720X480P_59940HZ_4X3 2 // Video Identification Code: format 2
#define NVT_CEA861_720X480P_59940HZ_16X9 3 // Video Identification Code: format 3
@@ -734,6 +742,66 @@ typedef enum NVT_TV_FORMAT
// NVT_CEA861_1280X720P_100000HZ_16X9,
// NVT_CEA861_1280X720P_119880HZ_16X9
// According to CEA-861-I Spec.
// Table 11 - Resoution Identification (RID)
#define NVT_CTA861_OVT_TIMING_FRR(_FLAG_, _RR_) (((_FLAG_) & (NVT_FLAG_CTA_OVT_TIMING)) != 0 && ((_RR_) % 6) == 0 && (_RR_) != 300)
#define NVT_CTA861_RID_NONE NVT_INFOFRAME_CTRL_DONTCARE
#define NVT_CTA861_RID_1280x720p_16x9 1
#define NVT_CTA861_RID_1280x720p_64x27 2
#define NVT_CTA861_RID_1680x720p_64x27 3
#define NVT_CTA861_RID_1920x1080p_16x9 4
#define NVT_CTA861_RID_1920x1080p_64x27 5
#define NVT_CTA861_RID_2560x1080p_64x27 6
#define NVT_CTA861_RID_3840x1080p_32x9 7
#define NVT_CTA861_RID_2560x1440p_16x9 8
#define NVT_CTA861_RID_3440x1440p_64x27 9
#define NVT_CTA861_RID_5120x1440p_32x9 10
#define NVT_CTA861_RID_3840x2160p_16x9 11
#define NVT_CTA861_RID_3840x2160p_64x27 12
#define NVT_CTA861_RID_5120x2160p_64x27 13
#define NVT_CTA861_RID_7680x2160p_32x9 14
#define NVT_CTA861_RID_5120x2880p_16x9 15
#define NVT_CTA861_RID_5120x2880p_64x27 16
#define NVT_CTA861_RID_6880x2880p_64x27 17
#define NVT_CTA861_RID_10240x2880p_32x9 18
#define NVT_CTA861_RID_7680x4320p_16x9 19
#define NVT_CTA861_RID_7680x4320p_64x27 20
#define NVT_CTA861_RID_10240x4320p_64x27 21
#define NVT_CTA861_RID_15360x4320p_32x9 22
#define NVT_CTA861_RID_11520x6480p_16x9 23
#define NVT_CTA861_RID_11520x6480p_64x27 24
#define NVT_CTA861_RID_15360x6480p_64x27 25
#define NVT_CTA861_RID_15360x8640p_16x9 26
#define NVT_CTA861_RID_15360x8640p_64x27 27
#define NVT_CTA861_RID_20480x8640p_64x27 28
// Table 12 - AVI InfoFrame Video Format Frame Rate
#define NVT_CTA861_FR_NO_DATA NVT_INFOFRAME_CTRL_DONTCARE
#define NVT_CTA861_FR_2398 1
#define NVT_CTA861_FR_2400 2
#define NVT_CTA861_FR_2500 3
#define NVT_CTA861_FR_2997 4
#define NVT_CTA861_FR_3000 5
#define NVT_CTA861_FR_4795 6
#define NVT_CTA861_FR_4800 7
#define NVT_CTA861_FR_5000 8
#define NVT_CTA861_FR_5994 9
#define NVT_CTA861_FR_6000 10
#define NVT_CTA861_FR_10000 11
#define NVT_CTA861_FR_11988 12
#define NVT_CTA861_FR_12000 13
#define NVT_CTA861_FR_14386 14
#define NVT_CTA861_FR_14400 15
#define NVT_CTA861_FR_20000 16
#define NVT_CTA861_FR_23976 17
#define NVT_CTA861_FR_24000 18
#define NVT_CTA861_FR_30000 19
#define NVT_CTA861_FR_35964 20
#define NVT_CTA861_FR_36000 21
#define NVT_CTA861_FR_40000 22
#define NVT_CTA861_FR_47952 23
#define NVT_CTA861_FR_48000 24
//*************************
// short audio descriptor
//*************************
@@ -845,7 +913,68 @@ typedef struct VSVDB_DATA
NvU8 vendor_data[NVT_CEA861_VSVDB_PAYLOAD_MAX_LENGTH];
} VSVDB_DATA;
//*******************************
// Video Format Data Block (VFDB)
//*******************************
#define NVT_CTA861_VF_MAX_BLOCKS 4
#define NVT_CTA861_VF_MAX_DESCRIPTORS 30
#define NVT_CTA861_VF_RID_MASK 0x3F
typedef struct tagNVT_RID_CODES
{
NvU16 HVisible; // horizontal visible
NvU8 HSyncPol; // horizontal sync polarity: 1-negative, 0-positive
NvU16 VVisible; // vertical visible
NvU8 VSyncPol; // vertical sync polarity: 1-negative, 0-positive
NvU16 interlaced; // 1-interlaced, 0-progressive
NvU32 aspect; // the display aspect ratio Hi(aspect):horizontal-aspect, Low(aspect):vertical-aspect
NvU8 rid; // Resolution Identification (RID)
} NVT_RID_CODES;
#pragma pack(1)
typedef struct tagVFD_ONE_BYTE
{
NvU8 rid : 6;
NvU8 fr24 : 1;
NvU8 bfr50 : 1;
} VFD_ONE_BYTE;
typedef struct tagVFD_TWO_BYTE
{
VFD_ONE_BYTE in_onebyte;
NvU8 frRate : 6;
NvU8 fr144 : 1;
NvU8 bfr60 : 1;
} VFD_TWO_BYTE;
typedef struct tagVFD_THREE_BYTE
{
VFD_TWO_BYTE in_twobyte;
NvU8 fr48 : 1;
NvU8 f31_37 : 7;
} VFD_THREE_BYTE;
typedef struct tagVFD_FOUR_BYTE
{
VFD_THREE_BYTE in_threebyte;
NvU8 f40_47;
} VFD_FOUR_BYTE;
typedef struct tagVFDB_DATA
{
struct {
NvU8 vfd_len : 2;
NvU8 f22_25 : 4;
NvU8 ntsc : 1;
NvU8 y420 : 1;
} info;
NvU8 total_vfd;
NvU8 video_format_desc[NVT_CTA861_VF_MAX_DESCRIPTORS];
} VFDB_DATA;
typedef struct tagNVT_DV_STATIC_METADATA_TYPE0
{
// first byte
@@ -1290,6 +1419,10 @@ typedef struct tagEDID_CEA861_INFO
// vendor specific video data
NvU8 total_vsvdb;
VSVDB_DATA vsvdb[NVT_CEA861_VSVDB_MAX_BLOCKS];
// video format data
NvU8 total_vfdb;
VFDB_DATA vfdb[NVT_CTA861_VF_MAX_BLOCKS];
// indicates which of the extended data blocks below contain valid data excluding extended blocks with total count
NVT_VALID_EXTENDED_BLOCKS valid;
@@ -2858,6 +2991,7 @@ typedef enum
NVT_PROTOCOL_UNKNOWN = 0,
NVT_PROTOCOL_DP = 1,
NVT_PROTOCOL_HDMI = 2,
NVT_PROTOCOL_DVI = 3,
} NVT_PROTOCOL;
// the display interface/connector claimed by the EDID
@@ -2870,14 +3004,14 @@ typedef enum
// the EDID extension TAG
#define NVT_EDID_EXTENSION_CTA 0x02 // CTA 861 series extensions
#define NVT_EDID_EXTENSION_VTB 0x10 // video timing block extension
#define NVT_EDID_EXTENSION_DI 0x40 // display information extension
#define NVT_EDID_EXTENSION_LS 0x50 // localized string extension
#define NVT_EDID_EXTENSION_DPVL 0x60 // digital packet video link extension
#define NVT_EDID_EXTENSION_DISPLAYID 0x70 // display id
#define NVT_EDID_EXTENSION_BM 0xF0 // extension block map
#define NVT_EDID_EXTENSION_OEM 0xFF // extension defined by the display manufacturer
#define NVT_EDID_EXTENSION_CTA 0x02 // CTA 861 series extensions
#define NVT_EDID_EXTENSION_VTB 0x10 // video timing block extension
#define NVT_EDID_EXTENSION_DI 0x40 // display information extension
#define NVT_EDID_EXTENSION_LS 0x50 // localized string extension
#define NVT_EDID_EXTENSION_DPVL 0x60 // digital packet video link extension
#define NVT_EDID_EXTENSION_DISPLAYID 0x70 // display id
#define NVT_EDID_EXTENSION_BM 0xF0 // extension block map
#define NVT_EDID_EXTENSION_OEM 0xFF // extension defined by the display manufacturer
//************************************
// Audio and Video Infoframe Control
@@ -2906,6 +3040,9 @@ typedef struct tagNVT_VIDEO_INFOFRAME_CTRL
NvU16 bottom_bar;
NvU16 left_bar;
NvU16 right_bar;
NvU8 addition_colorimetry_ext;
NvU8 frame_rate;
NvU8 rid;
}NVT_VIDEO_INFOFRAME_CTRL;
//
@@ -2922,7 +3059,7 @@ typedef struct tagNVT_AUDIO_INFOFRAME_CTRL
typedef struct tagNVT_VENDOR_SPECIFIC_INFOFRAME_CTRL
{
NvU32 Enable;
NvU8 Enable;
NvU8 HDMIRevision;
NvU8 HDMIFormat;
NvU8 HDMI_VIC;
@@ -2950,12 +3087,14 @@ typedef struct tagNVT_EXTENDED_METADATA_PACKET_INFOFRAME_CTRL
NvU32 EnableQMS;
NvU32 NextTFR;
NvU32 Sync;
NvU32 MConst;
} NVT_EXTENDED_METADATA_PACKET_INFOFRAME_CTRL;
typedef struct tagNVT_ADAPTIVE_SYNC_SDP_CTRL
{
NvU32 minVTotal;
NvU32 targetRefreshRate;
NvU32 srCoastingVTotal;
NvBool bFixedVTotal;
NvBool bRefreshRateDivider;
}NVT_ADAPTIVE_SYNC_SDP_CTRL;
@@ -3032,6 +3171,10 @@ typedef struct tagNVT_VIDEO_INFOFRAME
NvU8 left_bar_high;
NvU8 right_bar_low;
NvU8 right_bar_high;
// byte 14~15
NvU8 byte14;
NvU8 byte15;
}NVT_VIDEO_INFOFRAME;
//
#define NVT_VIDEO_INFOFRAME_VERSION_1 1
@@ -3186,8 +3329,17 @@ typedef struct tagNVT_VIDEO_INFOFRAME
#define NVT_VIDEO_INFOFRAME_BYTE5_RESERVED_V1_MASK 0xFF
#define NVT_VIDEO_INFOFRAME_BYTE5_RESERVED_V1_SHIFT 0
//
#define NVT_VIDEO_INFOFRAME_BYTE14_RESERVED_MASK 0x0F
#define NVT_VIDEO_INFOFRAME_BYTE14_RESERVED_SHIFT 0
#define NVT_VIDEO_INFOFRAME_BYTE14_FR0_FR3_MASK 0x0F
#define NVT_VIDEO_INFOFRAME_BYTE14_FR0_FR3_SHIFT 0
#define NVT_VIDEO_INFOFRAME_BYTE14_FR0_FR3_NODATA 0
#define NVT_VIDEO_INFOFRAME_BYTE14_FR4_ONE_BIT_MASK 0x10
#define NVT_VIDEO_INFOFRAME_BYTE15_FR4_MASK 0x40
#define NVT_VIDEO_INFOFRAME_BYTE15_FR4_NODATA 0
#define NVT_VIDEO_INFOFRAME_BYTE15_FR4_SHIFT 2
//
#define NVT_VIDEO_INFOFRAME_BYTE15_RID_MASK 0x3F
#define NVT_VIDEO_INFOFRAME_BYTE15_RID_SHIFT 0
#define NVT_VIDEO_INFOFRAME_BYTE15_RID_NODATA 0
//
#define NVT_VIDEO_INFOFRAME_BYTE14_ACE0_3_MASK 0xF0
#define NVT_VIDEO_INFOFRAME_BYTE14_ACE0_3_SHIFT 4
@@ -3252,7 +3404,21 @@ typedef struct
NvU16 topBar;
NvU16 bottomBar;
NvU16 leftBar;
NvU16 rightBar;
NvU16 rightBar;
// byte 14~15
struct
{
NvU8 fr_low : 4;
NvU8 ace : 4;
} byte14;
struct
{
NvU8 rid : 6;
NvU8 fr_hi : 1;
NvU8 rsvd_bits_byte15 : 1;
}byte15;
} NVT_VIDEO_INFOFRAME_OVERRIDE;
#pragma pack()
@@ -3302,6 +3468,11 @@ typedef struct
#define NVT_VIDEO_INFOFRAME_OVERRIDE_BYTE5_PR_MASK 0xF // pixel repetitions
#define NVT_VIDEO_INFOFRAME_OVERRIDE_BYTE5_CN1CN0_MASK 0x3
#define NVT_VIDEO_INFOFRAME_OVERRIDE_BYTE5_YQ1YQ0_MASK 0x3 // YCC quantization
//
#define NVT_VIDEO_INFOFRAME_OVERRIDE_BYTE14_FR0FR3_MASK 0xF // Frame rate 0-3 bits in Byte14
#define NVT_VIDEO_INFOFRAME_OVERRIDE_BYTE14_ACE0ACE3_MASK 0xF // Additional Colorimetry Extension
#define NVT_VIDEO_INFOFRAME_OVERRIDE_BYTE15_RID0RID5_MASK 0x3F // Resolution Identification
#define NVT_VIDEO_INFOFRAME_OVERRIDE_BYTE15_FR4_MASK 0x1 // Frame rate 4th bit in Byte 15
// audio infoframe structure
typedef struct tagNVT_AUDIO_INFOFRAME
@@ -3778,9 +3949,9 @@ typedef struct tagNVT_EXTENDED_METADATA_PACKET_INFOFRAME
#define NVT_HDMI_EMP_BYTE8_MD0_VRR_EN_SHIFT 0
#define NVT_HDMI_EMP_BYTE8_MD0_VRR_EN_DISABLE 0
#define NVT_HDMI_EMP_BYTE8_MD0_VRR_EN_ENABLE 1
#define NVT_HDMI_EMP_BYTE8_MD0_M_CONST_MASK 0x01
#define NVT_HDMI_EMP_BYTE8_MD0_M_CONST_MASK 0x02
#define NVT_HDMI_EMP_BYTE8_MD0_M_CONST_SHIFT 1
#define NVT_HDMI_EMP_BYTE8_MD0_QMS_EN_MASK 0x01
#define NVT_HDMI_EMP_BYTE8_MD0_QMS_EN_MASK 0x04
#define NVT_HDMI_EMP_BYTE8_MD0_QMS_EN_SHIFT 2
#define NVT_HDMI_EMP_BYTE8_MD0_QMS_EN_DISABLE 0
#define NVT_HDMI_EMP_BYTE8_MD0_QMS_EN_ENABLE 1
@@ -3793,7 +3964,7 @@ typedef struct tagNVT_EXTENDED_METADATA_PACKET_INFOFRAME
#define NVT_HDMI_EMP_BYTE8_MD2_RB_DISABLE 0
#define NVT_HDMI_EMP_BYTE8_MD2_RB_ENABLE 1
#define NVT_HDMI_EMP_BYTE8_MD2_NEXT_TFR_MASK 0x1f
#define NVT_HDMI_EMP_BYTE8_MD2_NEXT_TFR_MASK 0xf8
#define NVT_HDMI_EMP_BYTE8_MD2_NEXT_TFR_SHIFT 3
#define NVT_HDMI_EMP_BYTE8_MD2_BASE_RR_MSB_MASK 0x03
@@ -4622,7 +4793,7 @@ typedef struct tagNVT_DPCD
#define NVT_DPCD_LANE_COUNT_8 8
// note: the values of NVT_COLOR_FORMAT_* are fixed in order to match the equivalent NV classes
typedef enum
typedef enum _NVT_COLOR_FORMAT
{
NVT_COLOR_FORMAT_RGB = 0,
NVT_COLOR_FORMAT_YCbCr422 = 1,
@@ -5617,6 +5788,8 @@ typedef enum
#define NVT_FLAG_DISPLAYID_2_0_TIMING 0x00800000 // this one for the CTA861 embedded in DID20
#define NVT_FLAG_DISPLAYID_T7_T8_EXPLICT_YUV420 0x01000000 // DID2 E7 spec. supported yuv420 indicated
#define NVT_FLAG_CTA_NATIVE_TIMING 0x02000000 // NVRDB defined
#define NVT_FLAG_CTA_OVT_TIMING 0x04000000 // CTA861 CTA OVT Timing
#define NVT_FLAG_CTA_OVT_FRR_TIMING 0x08000000 // CTA861 CTA OVT Timing supported ntsc
#define NVT_FLAG_INTERLACED_MASK (NVT_FLAG_INTERLACED_TIMING | NVT_FLAG_INTERLACED_TIMING2)
@@ -5655,6 +5828,10 @@ NVT_STATUS NvTiming_CalcCVT_RB2(NvU32 width, NvU32 height, NvU32 rr, NvBool is10
NVT_STATUS NvTiming_CalcCVT_RB3(NvU32 width, NvU32 height, NvU32 rr, NvU32 deltaHBlank, NvU32 vBlankMicroSec, NvBool isEarlyVSync, NVT_TIMING *pT);
NvBool NvTiming_IsTimingCVTRB(const NVT_TIMING *pTiming);
// OVT timing calculation
NVT_STATUS NvTiming_CalcOVT(NvU32 width, NvU32 height, NvU32 rr, NVT_TIMING *pT);
NvBool NvTiming_IsTimingOVT(const NVT_TIMING *pTiming);
// CEA/EIA/Psf timing
NVT_STATUS NvTiming_CalcCEA861bTiming(NvU32 width, NvU32 height, NvU32 rr, NvU32 flag, NvU32 pixelRepeatCount, NVT_TIMING *pT);
NVT_STATUS NvTiming_EnumCEA861bTiming(NvU32 ceaFormat, NVT_TIMING *pT);
@@ -5668,6 +5845,7 @@ NVT_STATUS NvTiming_EnumHdmiVsdbExtendedTiming(NvU32 hdmi_vic, NVT_TIMING *pT);
NVT_STATUS NvTiming_GetTvTiming(NvU32 width, NvU32 height, NvU32 rr, NvU32 flag, NvU32 tvFormat, NVT_TIMING *pT);
// Get EDID timing
NVT_STATUS NvTiming_GetEdidTimingExWithPclk(NvU32 width, NvU32 height, NvU32 rr, NvU32 flag, NVT_EDID_INFO *pEdidInfo, NVT_TIMING *pT, NvU32 rrx1k, NvU32 pclk);
NVT_STATUS NvTiming_GetEdidTimingEx(NvU32 width, NvU32 height, NvU32 rr, NvU32 flag, NVT_EDID_INFO *pEdidInfo, NVT_TIMING *pT, NvU32 rrx1k);
NVT_STATUS NvTiming_GetEdidTiming(NvU32 width, NvU32 height, NvU32 rr, NvU32 flag, NVT_EDID_INFO *pEdidInfo, NVT_TIMING *pT);
@@ -5679,7 +5857,6 @@ NVT_STATUS NvTiming_GetHDMIStereoMandatoryFormatDetail(const NvU8 vic, NvU16 *pS
// EDID based AspectRatio Timing
NVT_STATUS NvTiming_GetEDIDBasedASPRTiming(NvU16 width, NvU16 height, NvU16 rr, NVT_EDID_INFO *pEI, NVT_TIMING *ft);
// EDID or DISPLAYID2 version
NvU32 NvTiming_GetVESADisplayDescriptorVersion(NvU8 *rawData, NvU32 *pVer);
@@ -5738,11 +5915,15 @@ NVT_STATUS NvTiming_GetDTD1Timing (NVT_EDID_INFO * pEdidInfo, NVT_TIMING * pT);
#define NVT_IS_CTA861_DID_T8_1(d) ((NVT_IS_CTA861_DID_T8((d))) && (NVT_GET_TIMING_STATUS_SEQ((d)) == 1))
#define NVT_IS_CTA861_DID_T10n(d, n) ((NVT_IS_CTA861_DID_T10((d))) && (NVT_GET_TIMING_STATUS_SEQ((d)) == n))
#define NVT_IS_CTA861_OVT_Tn(flag, status, n) ((0 != (NVT_FLAG_CTA_OVT_TIMING & (flag))) && (NVT_GET_TIMING_STATUS_SEQ((status)) == n))
#define NVT_DID20_TIMING_IS_CTA861(flag, status) ((NVT_IS_CTA861((status))) && (0 != (NVT_FLAG_DISPLAYID_2_0_TIMING & (flag))))
#define NVT_PREFERRED_TIMING_IS_DTD1(flag, status) ((NVT_IS_DTD1((status))) && (0 != (NVT_FLAG_DTD1_PREFERRED_TIMING & (flag))))
#define NVT_PREFERRED_TIMING_IS_DISPLAYID(flag) (0 != (NVT_FLAG_DISPLAYID_DTD_PREFERRED_TIMING & flag))
#define NVT_PREFERRED_TIMING_IS_CTA(flag) (0 != (NVT_FLAG_CTA_PREFERRED_TIMING & flag))
#define NVT_NATIVE_TIMING_IS_CTA(flag) (0 != (NVT_FLAG_CTA_NATIVE_TIMING & flag))
#define NVT_TIMING_IS_OVT(flag) (0 != (NVT_FLAG_CTA_OVT_TIMING & flag))
#define NVT_FRR_TIMING_IS_OVT(flag) (0 != (NVT_FLAG_CTA_OVT_FRR_TIMING & flag))
#ifdef __cplusplus
}

View File

@@ -72,6 +72,7 @@ NVT_STATUS parseCta861DataBlockInfo(NvU8 *pEdid, NvU32 size, NVT_EDID_CEA861_INF
void parse861ExtDetailedTiming(NvU8 *pEdidExt, NvU8 basicCaps, NVT_EDID_INFO *pInfo);
void parse861bShortTiming(NVT_EDID_CEA861_INFO *pExt861, void *pRawInfo, NVT_CTA861_ORIGIN flag);
void parse861bShortYuv420Timing(NVT_EDID_CEA861_INFO *pExt861, void *pRawInfo, NVT_CTA861_ORIGIN flag);
void parseCta861VideoFormatDataBlock(NVT_EDID_CEA861_INFO *pExt861, void *pRawInfo);
void parseCta861NativeOrPreferredTiming(NVT_EDID_CEA861_INFO *pExt861, void *pRawInfo, NVT_CTA861_ORIGIN flag);
void parseCta861VsdbBlocks(NVT_EDID_CEA861_INFO *pExt861, void *pRawInfo, NVT_CTA861_ORIGIN flag);
void parseCta861VsvdbBlocks(NVT_EDID_CEA861_INFO *pExt861, void *pRawInfo, NVT_CTA861_ORIGIN flag);
@@ -94,7 +95,7 @@ NvBool isMatchedStandardTiming(NVT_EDID_INFO *pInfo, NVT_TIMING *pT);
NvBool isMatchedEstablishedTiming(NVT_EDID_INFO *pInfo, NVT_TIMING *pT);
NvU32 isHdmi3DStereoType(NvU8 StereoStructureType);
NvU32 getCEA861TimingAspectRatio(NvU32 vic);
NvU8 getHighestPrioritySVRIdx(NvU8 svr);
NvU8 getHighestPrioritySVRIdx(const NVT_EDID_CEA861_INFO *pExt861);
void SetActiveSpaceForHDMI3DStereo(const NVT_TIMING *pTiming, NVT_EXT_TIMING *pExtTiming);
void AddModeToSupportMap(HDMI3DSUPPORTMAP * pMap, NvU8 vic, NvU8 structure, NvU8 Detail);
void getMonitorDescriptorString(NvU8 *pEdid, NvU8 tag, char *str, int onceOnly);