mirror of
https://github.com/NVIDIA/open-gpu-kernel-modules.git
synced 2026-02-04 15:19:59 +00:00
550.40.07
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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) |
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user