530.30.02

This commit is contained in:
Andy Ritger
2023-02-28 11:12:44 -08:00
parent e598191e8e
commit 4397463e73
928 changed files with 124728 additions and 88525 deletions

View File

@@ -1,6 +1,6 @@
//*****************************************************************************
//
// SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: MIT
//
// Permission is hereby granted, free of charge, to any person obtaining a
@@ -42,7 +42,7 @@ static NVT_STATUS parseDisplayId20SectionDataBlocks(const DISPLAYID_2_0_SECTION
static NVT_STATUS parseDisplayId20ExtensionSection(const DISPLAYID_2_0_SECTION *pSection, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo);
// DisplayID20 Data Block Tag Alloction
static NVT_STATUS parseDisplayId20ProductIdentity(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo); // 0x20 Product Identificaton Block Tag
static NVT_STATUS parseDisplayId20ProductIdentity(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo); // 0x20 Product Identificaton
static NVT_STATUS parseDisplayId20DisplayParam(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo); // 0x21 Display Parameters
static NVT_STATUS parseDisplayId20Timing7(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo); // 0x22 Type VII Timing - Detailed Timing
static NVT_STATUS parseDisplayId20Timing8(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo); // 0x23 Type VIII Timing - Enumerated Timing
@@ -52,10 +52,10 @@ static NVT_STATUS parseDisplayId20DisplayInterfaceFeatures(const DISPLAYID_2_0_D
static NVT_STATUS parseDisplayId20Stereo(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo); // 0x27 Stereo Display Interface
static NVT_STATUS parseDisplayId20TiledDisplay(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo); // 0x28 Tiled Display Topology
static NVT_STATUS parseDisplayId20ContainerId(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo); // 0x29 ContainerID
static NVT_STATUS parseDisplayId20Timing10(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo); // 0x2A Type X Timing - Formula-based RR up to 1024Hz
static NVT_STATUS parseDisplayId20Timing10(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo); // 0x2A Type X Timing - Formula-based Timing
static NVT_STATUS parseDisplayId20AdaptiveSync(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo); // 0x2B Adaptive-Sync
static NVT_STATUS parseDisplayId20ARVRHMD(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo); // 0x2C ARVR HMD
static NVT_STATUS parseDisplayId20ARVRLayer(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo); // 0x2D ARVR Layer
static NVT_STATUS parseDisplayId20ARVRHMD(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo); // 0x2C ARVR HMD
static NVT_STATUS parseDisplayId20ARVRLayer(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo); // 0x2D ARVR Layer
static NVT_STATUS parseDisplayId20VendorSpecific(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo); // 0x7E Vendor-specific
static NVT_STATUS parseDisplayId20CtaData(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo); // 0x81 CTA DisplayID
@@ -63,7 +63,6 @@ static NVT_STATUS parseDisplayId20CtaData(const DISPLAYID_2_0_DATA_BLOCK_HEADER
static NVT_STATUS getPrimaryUseCase(NvU8 product_type, NVT_DISPLAYID_PRODUCT_PRIMARY_USE_CASE *primary_use_case);
static NVT_STATUS parseDisplayId20Timing7Descriptor(const DISPLAYID_2_0_TIMING_7_DESCRIPTOR *pDescriptor, NVT_TIMING *pTiming, NvU8 revision, NvU8 count);
static NVT_STATUS parseDisplayId20Timing9Descriptor(const DISPLAYID_2_0_TIMING_9_DESCRIPTOR *pDescriptor, NVT_TIMING *pTiming, NvU8 count);
static NVT_STATUS parseDisplayId20Timing10Descriptor(const void *pDescriptor, NVT_TIMING *pTiming, NvU8 payloadbytes, NvU8 count);
static NvU32 greatestCommonDenominator(NvU32 x, NvU32 y);
static NvU8 getExistedTimingSeqNumber(NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo, enum NVT_TIMING_TYPE);
@@ -812,11 +811,13 @@ parseDisplayId20Timing10(
NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo)
{
NVT_STATUS status = NVT_STATUS_SUCCESS;
const DISPLAYID_2_0_TIMING_10_BLOCK *pTiming10Block = NULL;
NvU32 descriptorCount = 0;
NvU8 startSeqNumber = 0;
NvU8 i = 0;
NvU8 eachOfDescriptorsSize = sizeof(DISPLAYID_2_0_TIMING_10_6BYTES_DESCRIPTOR);
NvU32 descriptorCount = 0;
NvU8 startSeqNumber = 0;
NvU8 i = 0;
NvU8 eachOfDescriptorsSize = sizeof(DISPLAYID_2_0_TIMING_10_6BYTES_DESCRIPTOR);
const DISPLAYID_2_0_TIMING_10_BLOCK *pTiming10Block = NULL;
const DISPLAYID_2_0_TIMING_10_6BYTES_DESCRIPTOR *p6bytesDescriptor = NULL;
NVT_TIMING newTiming;
@@ -858,10 +859,44 @@ parseDisplayId20Timing10(
for (i = 0; i < descriptorCount; i++)
{
startSeqNumber += i;
NVMISC_MEMSET(&newTiming, 0, sizeof(newTiming));
if (NVT_STATUS_SUCCESS == parseDisplayId20Timing10Descriptor(&pTiming10Block->descriptors[i*eachOfDescriptorsSize], &newTiming, pTiming10Block->header.payload_bytes_len, startSeqNumber+i))
if (NVT_STATUS_SUCCESS == parseDisplayId20Timing10Descriptor(&pTiming10Block->descriptors[i*eachOfDescriptorsSize],
&newTiming,
pTiming10Block->header.payload_bytes_len))
{
p6bytesDescriptor = (const DISPLAYID_2_0_TIMING_10_6BYTES_DESCRIPTOR *)&pTiming10Block->descriptors[i*eachOfDescriptorsSize];
if (p6bytesDescriptor->options.ycc420_support)
{
UPDATE_BPC_FOR_COLORFORMAT(newTiming.etc.yuv420, 0, 1, 1, 1, 0, 1);
}
if (p6bytesDescriptor->options.timing_formula == DISPLAYID_2_0_TIMING_FORMULA_CVT_1_2_STANDARD)
{
NVT_SNPRINTF((char *)newTiming.etc.name, sizeof(newTiming.etc.name), "DID20-Type10:#%3d:%dx%dx%3d.%03dHz/%s",
(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"));
}
else
{
NVT_SNPRINTF((char *)newTiming.etc.name, sizeof(newTiming.etc.name), "DID20-Type10RB%d:#%3d:%dx%dx%3d.%03dHz/%s",
p6bytesDescriptor->options.timing_formula,
(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.status = NVT_STATUS_DISPLAYID_10N(++startSeqNumber);
newTiming.etc.name[sizeof(newTiming.etc.name) - 1] = '\0';
if (!assignNextAvailableDisplayId20Timing(pDisplayIdInfo, &newTiming))
{
break;
@@ -869,7 +904,11 @@ parseDisplayId20Timing10(
}
else
{
if (pDisplayIdInfo == NULL) return NVT_STATUS_ERR;
if (pDisplayIdInfo == NULL)
{
return NVT_STATUS_ERR;
}
continue;
}
}
@@ -1306,14 +1345,18 @@ parseDisplayId20VendorSpecific(
// TODO: below parser shall be updated if DID21 changed in the future
if (pDataBlock->data_bytes == NVT_VESA_VENDOR_SPECIFIC_LENGTH)
{
pVendorSpecific->vesaVsdb.data_struct_type.type = block->vendor_specific_data[3] & NVT_VESA_ORG_VSDB_DATA_TYPE_MASK;
pVendorSpecific->vesaVsdb.data_struct_type.color_space_and_eotf = (block->vendor_specific_data[3] & NVT_VESA_ORG_VSDB_COLOR_SPACE_AND_EOTF_MASK) >> NVT_VESA_ORG_VSDB_COLOR_SPACE_AND_EOTF_SHIFT;
pVendorSpecific->vesaVsdb.overlapping.pixels_overlapping_count = block->vendor_specific_data[4] & NVT_VESA_ORG_VSDB_PIXELS_OVERLAPPING_MASK;
pVendorSpecific->vesaVsdb.overlapping.multi_sst = (block->vendor_specific_data[4] & NVT_VESA_ORG_VSDB_MULTI_SST_MODE_MASK) >> NVT_VESA_ORG_VSDB_MULTI_SST_MODE_SHIFT;
pVendorSpecific->vesaVsdb.pass_through_integer.pass_through_integer_dsc = block->vendor_specific_data[5] & NVT_VESA_ORG_VSDB_PASS_THROUGH_INTEGER_MASK;
pVendorSpecific->vesaVsdb.pass_through_fractional.pass_through_fraction_dsc = block->vendor_specific_data[6] & NVT_VESA_ORG_VSDB_PASS_THROUGH_FRACTIOINAL_MASK;
pVendorSpecific->vesaVsdb.data_struct_type.type =
block->vendor_specific_data[3] & NVT_VESA_ORG_VSDB_DATA_TYPE_MASK;
pVendorSpecific->vesaVsdb.data_struct_type.color_space_and_eotf =
(block->vendor_specific_data[3] & NVT_VESA_ORG_VSDB_COLOR_SPACE_AND_EOTF_MASK) >> NVT_VESA_ORG_VSDB_COLOR_SPACE_AND_EOTF_SHIFT;
pVendorSpecific->vesaVsdb.overlapping.pixels_overlapping_count =
block->vendor_specific_data[4] & NVT_VESA_ORG_VSDB_PIXELS_OVERLAPPING_MASK;
pVendorSpecific->vesaVsdb.overlapping.multi_sst =
(block->vendor_specific_data[4] & NVT_VESA_ORG_VSDB_MULTI_SST_MODE_MASK) >> NVT_VESA_ORG_VSDB_MULTI_SST_MODE_SHIFT;
pVendorSpecific->vesaVsdb.pass_through_integer.pass_through_integer_dsc =
block->vendor_specific_data[5] & NVT_VESA_ORG_VSDB_PASS_THROUGH_INTEGER_MASK;
pVendorSpecific->vesaVsdb.pass_through_fractional.pass_through_fraction_dsc =
block->vendor_specific_data[6] & NVT_VESA_ORG_VSDB_PASS_THROUGH_FRACTIOINAL_MASK;
}
else
{
@@ -1655,18 +1698,21 @@ parseDisplayId20Timing9Descriptor(
status = NvTiming_CalcCVT_RB2(width, height, rr, pDescriptor->options.rr_1000div1001_support, pTiming);
break;
default:
{
nvt_assert(0 && "Unknown timing formula");
status = NVT_STATUS_ERR;
}
break;
}
if (status == NVT_STATUS_SUCCESS)
{
{
NVMISC_MEMSET(pTiming->etc.name, 0, sizeof(pTiming->etc.name));
pTiming->etc.status = NVT_STATUS_DISPLAYID_9N(++count);
if ( pDescriptor->options.timing_formula== DISPLAYID_2_0_TIMING_FORMULA_CVT_1_2_STANDARD)
if (pDescriptor->options.timing_formula == DISPLAYID_2_0_TIMING_FORMULA_CVT_1_2_STANDARD)
{
NVT_SNPRINTF((char *)pTiming->etc.name, sizeof(pTiming->etc.name), "DID20-Type9:#%3d:%dx%dx%3d.%03dHz/%s",
NVT_SNPRINTF((char *)pTiming->etc.name, sizeof(pTiming->etc.name), "DID20-Type9:#%3d:%dx%dx%3d.%03dHz/%s",
(int)NVT_GET_TIMING_STATUS_SEQ(pTiming->etc.status),
(int)pTiming->HVisible,
(int)pTiming->VVisible,
@@ -1674,19 +1720,10 @@ parseDisplayId20Timing9Descriptor(
(int)pTiming->etc.rrx1k%1000,
(pTiming->interlaced ? "I":"P"));
}
else if (pDescriptor->options.timing_formula == DISPLAYID_2_0_TIMING_FORMULA_CVT_1_2_REDUCED_BLANKING_1)
else
{
NVT_SNPRINTF((char *)pTiming->etc.name, sizeof(pTiming->etc.name), "DID20-Type9-RB1:#%3d:%dx%dx%3d.%03dHz/%s",
(int)NVT_GET_TIMING_STATUS_SEQ(pTiming->etc.status),
(int)pTiming->HVisible,
(int)pTiming->VVisible,
(int)pTiming->etc.rrx1k/1000,
(int)pTiming->etc.rrx1k%1000,
(pTiming->interlaced ? "I":"P"));
}
else if (pDescriptor->options.timing_formula == DISPLAYID_2_0_TIMING_FORMULA_CVT_2_0_REDUCED_BLANKING_2)
{
NVT_SNPRINTF((char *)pTiming->etc.name, sizeof(pTiming->etc.name), "DID20-Type9-RB2:#%3d:%dx%dx%3d.%03dHz/%s",
NVT_SNPRINTF((char *)pTiming->etc.name, sizeof(pTiming->etc.name), "DID20-Type9RB%d:#%3d:%dx%dx%3d.%03dHz/%s",
pDescriptor->options.timing_formula,
(int)NVT_GET_TIMING_STATUS_SEQ(pTiming->etc.status),
(int)pTiming->HVisible,
(int)pTiming->VVisible,
@@ -1695,19 +1732,17 @@ parseDisplayId20Timing9Descriptor(
(pTiming->interlaced ? "I":"P"));
}
}
pTiming->etc.name[sizeof(pTiming->etc.name) - 1] = '\0';
return status;
}
CODE_SEGMENT(PAGE_DD_CODE)
static NVT_STATUS
NVT_STATUS
parseDisplayId20Timing10Descriptor(
const void *pDescriptor,
NVT_TIMING *pTiming,
NvU8 payloadbytes,
NvU8 count)
NvU8 payloadBytes)
{
NVT_STATUS status = NVT_STATUS_SUCCESS;
const DISPLAYID_2_0_TIMING_10_6BYTES_DESCRIPTOR* p6bytesDescriptor = NULL;
@@ -1722,7 +1757,7 @@ parseDisplayId20Timing10Descriptor(
height = (p6bytesDescriptor->vertical_active_lines[1] << 8 | p6bytesDescriptor->vertical_active_lines[0]) + 1;
rr = p6bytesDescriptor->refresh_rate + 1;
if (payloadbytes == DISPLAYID_2_0_TIMING_10_PAYLOAD_BYTES_7)
if (payloadBytes == DISPLAYID_2_0_TIMING_10_PAYLOAD_BYTES_7)
{
p7bytesDescriptor = (const DISPLAYID_2_0_TIMING_10_7BYTES_DESCRIPTOR *)pDescriptor;
rr = (p7bytesDescriptor->descriptor_6_bytes.refresh_rate | p7bytesDescriptor->refresh_rate_high << 8) + 1;
@@ -1740,92 +1775,42 @@ parseDisplayId20Timing10Descriptor(
status = NvTiming_CalcCVT_RB2(width, height, rr, p6bytesDescriptor->options.rr1000div1001_or_hblank, pTiming);
break;
case DISPLAYID_2_0_TIMING_FORMULA_CVT_2_0_REDUCED_BLANKING_3:
{
NvU32 deltaHBlank = 0;
if (p7bytesDescriptor != NULL)
{
if (p6bytesDescriptor->options.rr1000div1001_or_hblank == 0) // Horizontal Blank in Pixels = [Field Value] * 8 + 80
{
deltaHBlank = p7bytesDescriptor->delta_hblank * 8;
}
else if (p6bytesDescriptor->options.rr1000div1001_or_hblank == 1)
{
if (p7bytesDescriptor->delta_hblank <= 5)
deltaHBlank = (p7bytesDescriptor->delta_hblank * 8 + 160) - 80;
else // if 5 < Field Value <=7
deltaHBlank = (160 - ((p7bytesDescriptor->delta_hblank - 5) * 8)) - 80;
}
status = NvTiming_CalcCVT_RB3(width, height, rr, deltaHBlank, p7bytesDescriptor->additional_vblank_timing * 35, p6bytesDescriptor->options.early_vsync, pTiming);
}
else // 6 bytes descriptor
{
if (p6bytesDescriptor->options.rr1000div1001_or_hblank == 1)
deltaHBlank = 80;
status = NvTiming_CalcCVT_RB3(width, height, rr, deltaHBlank, 0, p6bytesDescriptor->options.early_vsync, pTiming);
}
break;
}
}
if ( status == NVT_STATUS_SUCCESS )
{
NVMISC_MEMSET(pTiming->etc.name, 0, sizeof(pTiming->etc.name));
pTiming->etc.status = NVT_STATUS_DISPLAYID_10N(++count);
NvU32 deltaHBlank = 0;
if (p7bytesDescriptor != NULL)
{
if (p6bytesDescriptor->options.rr1000div1001_or_hblank == 0) // Horizontal Blank in Pixels = [Field Value] * 8 + 80
{
deltaHBlank = p7bytesDescriptor->delta_hblank * 8;
}
else if (p6bytesDescriptor->options.rr1000div1001_or_hblank == 1)
{
if (p7bytesDescriptor->delta_hblank <= 5)
deltaHBlank = (p7bytesDescriptor->delta_hblank * 8 + 160) - 80;
else // if 5 < Field Value <=7
deltaHBlank = (160 - ((p7bytesDescriptor->delta_hblank - 5) * 8)) - 80;
}
if (p6bytesDescriptor->options.ycc420_support)
{
// YCC 420 support
UPDATE_BPC_FOR_COLORFORMAT(pTiming->etc.yuv420, 0, 1, 1, 1, 0, 1);
status = NvTiming_CalcCVT_RB3(width, height, rr, deltaHBlank, p7bytesDescriptor->additional_vblank_timing * 35, p6bytesDescriptor->options.early_vsync, pTiming);
}
else // 6 bytes descriptor
{
if (p6bytesDescriptor->options.rr1000div1001_or_hblank == 1)
deltaHBlank = 80;
if (p6bytesDescriptor->options.timing_formula == DISPLAYID_2_0_TIMING_FORMULA_CVT_1_2_STANDARD)
{
NVT_SNPRINTF((char *)pTiming->etc.name, sizeof(pTiming->etc.name), "DID20-Type10:#%3d:%dx%dx%3d.%03dHz/%s",
(int)NVT_GET_TIMING_STATUS_SEQ(pTiming->etc.status),
(int)pTiming->HVisible,
(int)pTiming->VVisible,
(int)pTiming->etc.rrx1k/1000,
(int)pTiming->etc.rrx1k%1000,
(pTiming->interlaced ? "I":"P"));
}
else if (p6bytesDescriptor->options.timing_formula == DISPLAYID_2_0_TIMING_FORMULA_CVT_1_2_REDUCED_BLANKING_1)
{
NVT_SNPRINTF((char *)pTiming->etc.name, sizeof(pTiming->etc.name), "DID20-Type10RB1:#%3d:%dx%dx%3d.%03dHz/%s",
(int)NVT_GET_TIMING_STATUS_SEQ(pTiming->etc.status),
(int)pTiming->HVisible,
(int)pTiming->VVisible,
(int)pTiming->etc.rrx1k/1000,
(int)pTiming->etc.rrx1k%1000,
(pTiming->interlaced ? "I":"P"));
}
else if (p6bytesDescriptor->options.timing_formula == DISPLAYID_2_0_TIMING_FORMULA_CVT_2_0_REDUCED_BLANKING_2)
{
NVT_SNPRINTF((char *)pTiming->etc.name, sizeof(pTiming->etc.name), "DID20-Type10RB2:#%3d:%dx%dx%3d.%03dHz/%s",
(int)NVT_GET_TIMING_STATUS_SEQ(pTiming->etc.status),
(int)pTiming->HVisible,
(int)pTiming->VVisible,
(int)pTiming->etc.rrx1k/1000,
(int)pTiming->etc.rrx1k%1000,
(pTiming->interlaced ? "I":"P"));
}
else if (p6bytesDescriptor->options.timing_formula == DISPLAYID_2_0_TIMING_FORMULA_CVT_2_0_REDUCED_BLANKING_3)
{
NVT_SNPRINTF((char *)pTiming->etc.name, sizeof(pTiming->etc.name), "DID20-Type10RB3:#%3d:%dx%dx%3d.%03dHz/%s",
(int)NVT_GET_TIMING_STATUS_SEQ(pTiming->etc.status),
(int)pTiming->HVisible,
(int)pTiming->VVisible,
(int)pTiming->etc.rrx1k/1000,
(int)pTiming->etc.rrx1k%1000,
(pTiming->interlaced ? "I":"P"));
status = NvTiming_CalcCVT_RB3(width, height, rr, deltaHBlank, 0, p6bytesDescriptor->options.early_vsync, pTiming);
}
}
break;
default:
{
nvt_assert(0 && "Unknown timing formula");
status = NVT_STATUS_ERR;
}
break;
}
pTiming->etc.name[sizeof(pTiming->etc.name) - 1] = '\0';
if (status == NVT_STATUS_SUCCESS) return status;
return status;
}
@@ -1842,7 +1827,7 @@ getExistedTimingSeqNumber(
switch (timingType)
{
case NVT_TYPE_DISPLAYID_7:
case NVT_TYPE_DISPLAYID_7:
case NVT_TYPE_DISPLAYID_8:
case NVT_TYPE_DISPLAYID_9:
case NVT_TYPE_DISPLAYID_10:

View File

@@ -1079,6 +1079,11 @@ NVT_STATUS NV_STDCALL NvTiming_ParseEDIDInfo(NvU8 *pEdid, NvU32 length, NVT_EDID
// add the detailed timings in 18-byte long display descriptor
parse861ExtDetailedTiming(pExt, p861Info->basic_caps, pInfo);
if (p861Info->revision >= NVT_CTA861_REV_H && p861Info->total_did_type10db != 0)
{
parseCta861DIDType10VideoTimingDataBlock(p861Info, pInfo);
}
// CEA861-F at 7.5.12 section about VFPDB block.
if (p861Info->revision >= NVT_CEA861_REV_F && p861Info->total_vfpdb != 0)
{
@@ -2169,9 +2174,8 @@ NvU32 NvTiming_EDIDStrongValidationMask(NvU8 *pEdid, NvU32 length)
NvBool bAllZero = NV_TRUE;
NvU32 ret = 0;
// check the EDID base size to avoid accessing beyond the EDID buffer, do not proceed with
// further validation.
if (length < sizeof(EDIDV1STRUC))
// check the EDID base size to avoid accessing beyond the EDID buffer
if (length < sizeof(EDIDV1STRUC) || (length > sizeof(EDIDV1STRUC) && (length % sizeof(EDIDV1STRUC) != 0)))
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_SIZE);
// check the EDID version and signature
@@ -2254,6 +2258,11 @@ NvU32 NvTiming_EDIDStrongValidationMask(NvU8 *pEdid, NvU32 length)
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_EXTENSION_COUNT);
}
// we shall not trust any extension blocks with wrong input EDID size
if (NVT_IS_EDID_VALIDATION_FLAGS(ret, NVT_EDID_VALIDATION_ERR_SIZE) ||
NVT_IS_EDID_VALIDATION_FLAGS(ret, NVT_EDID_VALIDATION_ERR_EXTENSION_COUNT))
return ret;
// validate extension blocks
for (j = 1; j <= p->bExtensionFlag; j++)
{
@@ -2415,7 +2424,7 @@ NvU32 NvTiming_EDIDStrongValidationMask(NvU8 *pEdid, NvU32 length)
}
// compare the remain 0 value are correct or not before meet checksum byte
for (i = 0; i <= (NvU32)(&pDisplayid->data[NVT_DID_MAX_EXT_PAYLOAD-1] - pData_collection); i++)
for (i = 0; i < (NvU32)(&pDisplayid->data[NVT_DID_MAX_EXT_PAYLOAD-1] - pData_collection); i++)
{
if (pData_collection[i] != 0)
{
@@ -2465,7 +2474,7 @@ NvU32 NvTiming_EDIDStrongValidationMask(NvU8 *pEdid, NvU32 length)
}
// compare the remain 0 value are correct or not before meet checksum byte
for (i = 0; i <= (NvU32)(&pDisplayid->data[NVT_DID_MAX_EXT_PAYLOAD-1] - pData_collection); i++)
for (i = 0; i < (NvU32)(&pDisplayid->data[NVT_DID_MAX_EXT_PAYLOAD-1] - pData_collection); i++)
{
if (pData_collection[i] != 0)
{

View File

@@ -720,7 +720,7 @@ void parse861bShortPreferredTiming(NVT_EDID_CEA861_INFO *pExt861,
return;
}
// finding all the DTD
// finding all the DTD in Base 0 or CTA861
if (flag == FROM_CTA861_EXTENSION)
{
for (j = 0; j < pInfo->total_timings; j++)
@@ -1288,6 +1288,7 @@ NVT_STATUS parseCta861DataBlockInfo(NvU8 *p,
NvU32 vendor_index = 0;
NvU32 yuv420vdb_index = 0;
NvU32 yuv420cmdb_index = 0;
NvU32 didT10_index = 0;
NvU8 svr_index = 0;
NvU32 ieee_id = 0;
NvU32 tag, ext_tag, payload;
@@ -1330,6 +1331,11 @@ NVT_STATUS parseCta861DataBlockInfo(NvU8 *p,
else if (ext_tag == NVT_CEA861_EXT_TAG_VENDOR_SPECIFIC_VIDEO && payload < 4) return NVT_STATUS_ERR;
else if (ext_tag == NVT_CTA861_EXT_TAG_SCDB && payload < 7) return NVT_STATUS_ERR;
else if (ext_tag == NVT_CEA861_EXT_TAG_HF_EEODB && payload != 2) return NVT_STATUS_ERR;
else if (ext_tag == NVT_CTA861_EXT_TAG_DID_TYPE_X)
{
if (((p[i+1] & 0x70) >> 4 == 0) && (payload-2) % 6) return NVT_STATUS_ERR;
if (((p[i+1] & 0x70) >> 4 == 1) && (payload-2) % 7) return NVT_STATUS_ERR;
}
}
break;
default:
@@ -1549,6 +1555,29 @@ NVT_STATUS parseCta861DataBlockInfo(NvU8 *p,
i += payload;
}
}
else if (ext_tag == NVT_CTA861_EXT_TAG_DID_TYPE_X && ((payload-2) % 6 == 0 || (payload-2) % 7 == 0))
{
i++; payload--;
p861info->did_type10_data_block[didT10_index].version.revision = p[i] & 0x7;
p861info->did_type10_data_block[didT10_index].version.t10_m = (p[i] & 0x70) >> 4;
// do not consider Byte 3
i++; payload--;
if (p861info->did_type10_data_block[didT10_index].version.t10_m == 0)
p861info->did_type10_data_block[didT10_index].total_descriptors = (NvU8)(payload / 6);
else if (p861info->did_type10_data_block[didT10_index].version.t10_m == 1)
p861info->did_type10_data_block[didT10_index].total_descriptors = (NvU8)(payload / 7);
for (j = 0; j < payload; j++, i++)
{
p861info->did_type10_data_block[didT10_index].payload[j] = p[i];
}
// next type10 data block if it exists
p861info->total_did_type10db++;
didT10_index++;
}
else if(ext_tag == NVT_CTA861_EXT_TAG_SCDB && payload >= 7) // sizeof(HDMI Forum Sink Capability Data Block) ranges between 7 to 31 bytes
{
// As per HDMI2.1 A1 amendment Sink Capability Data Structure(SCDS) can alternatively be included in HDMI Forum Sink Capability Data Block(HF-SCDB),
@@ -1561,7 +1590,7 @@ NVT_STATUS parseCta861DataBlockInfo(NvU8 *p,
// Copy SCDS over to p861info->vsdb[vendor_index]. Parsing will later be handled in parseEdidHdmiForumVSDB().
for (j = 0; (j < payload - 3) && (j < NVT_CTA861_EXT_SCDB_PAYLOAD_MAX_LENGTH); j ++, i ++)
{
p861info->hfscdb[j] = p[i];
p861info->hfscdb[j] = p[i];
}
p861info->hfscdbSize = MIN(payload - 3, NVT_CTA861_EXT_SCDB_PAYLOAD_MAX_LENGTH);
p861info->valid.SCDB = 1;
@@ -1706,8 +1735,7 @@ NVT_STATUS NvTiming_CalcCEA861bTiming(NvU32 width, NvU32 height, NvU32 rr, NvU32
// loop through the table
for (i = 0; i < MAX_CEA861B_FORMAT; i ++)
{
{
if ((EIA861B[i].etc.rep & pixelRepeatMask) == 0)
{
continue;
@@ -3060,4 +3088,85 @@ void parseCea861Hdr10PlusDataBlock(NVT_EDID_CEA861_INFO *pExt861, void *pRawInfo
NVMISC_MEMCPY(pHdr10PlusInfo, &pExt861->vsvdb.vendor_data, sizeof(NVT_HDR10PLUS_INFO));
}
CODE_SEGMENT(PAGE_DD_CODE)
void parseCta861DIDType10VideoTimingDataBlock(NVT_EDID_CEA861_INFO *pExt861, void *pRawInfo)
{
NvU8 i = 0;
NvU8 t10db_idx = 0;
NVT_TIMING newTiming;
NVT_EDID_INFO *pInfo = (NVT_EDID_INFO *)pRawInfo;
const DISPLAYID_2_0_TIMING_10_6BYTES_DESCRIPTOR *p6bytesDescriptor = NULL;
NvU8 eachOfDescriptorsSize = sizeof (DISPLAYID_2_0_TIMING_10_6BYTES_DESCRIPTOR);
for (t10db_idx = 0; t10db_idx < pExt861->total_did_type10db; t10db_idx++)
{
// 6 or 7 bytes length
eachOfDescriptorsSize = sizeof(DISPLAYID_2_0_TIMING_10_6BYTES_DESCRIPTOR) + pExt861->did_type10_data_block[t10db_idx].version.t10_m;
for (i = 0; i < pExt861->did_type10_data_block[t10db_idx].total_descriptors; i++)
{
if (pExt861->did_type10_data_block[t10db_idx].total_descriptors < NVT_CTA861_DID_TYPE10_DESCRIPTORS_MIN ||
pExt861->did_type10_data_block[t10db_idx].total_descriptors > NVT_CTA861_DID_TYPE10_DESCRIPTORS_MAX)
{
nvt_assert(0 && "payload descriptor invalid. expect minimum 1 descriptor, maximum 4 descriptors");
continue;
}
NVMISC_MEMSET(&newTiming, 0, sizeof(newTiming));
if (NVT_STATUS_SUCCESS == parseDisplayId20Timing10Descriptor(&pExt861->did_type10_data_block[t10db_idx].payload[i*eachOfDescriptorsSize],
&newTiming,
pExt861->did_type10_data_block[t10db_idx].version.t10_m))
{
p6bytesDescriptor = (const DISPLAYID_2_0_TIMING_10_6BYTES_DESCRIPTOR *)
&pExt861->did_type10_data_block[t10db_idx].payload[i*eachOfDescriptorsSize];
if (p6bytesDescriptor->options.ycc420_support)
{
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);
}
if (p6bytesDescriptor->options.timing_formula == DISPLAYID_2_0_TIMING_FORMULA_CVT_1_2_STANDARD)
{
NVT_SNPRINTF((char *)newTiming.etc.name, sizeof(newTiming.etc.name), "CTA861-T10:#%3d:%dx%dx%3d.%03dHz/%s",
(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"));
}
else
{
NVT_SNPRINTF((char *)newTiming.etc.name, sizeof(newTiming.etc.name), "CTA861-T10RB%d:#%3d:%dx%dx%3d.%03dHz/%s",
p6bytesDescriptor->options.timing_formula,
(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.status = NVT_STATUS_DISPLAYID_10N(i+1);
newTiming.etc.flag |= NVT_FLAG_DISPLAYID_T10_TIMING;
newTiming.etc.name[sizeof(newTiming.etc.name) - 1] = '\0';
if (!assignNextAvailableTiming(pInfo, &newTiming))
{
break;
}
}
else
{
continue;
}
}
}
return;
}
POP_SEGMENTS

View File

@@ -1,6 +1,6 @@
//****************************************************************************
//
// SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: MIT
//
// Permission is hereby granted, free of charge, to any person obtaining a
@@ -438,6 +438,7 @@ typedef enum NVT_TV_FORMAT
#define NVT_CEA861_REV_E 3
#define NVT_CEA861_REV_F 3
#define NVT_CTA861_REV_G 3
#define NVT_CTA861_REV_H 3
//
// max data after misc/basic_caps in EIA861EXTENSION
#define NVT_CEA861_MAX_PAYLOAD 123
@@ -469,28 +470,39 @@ typedef enum NVT_TV_FORMAT
// the extended tag codes when NVT_CEA861_TAG_EXTENDED_FLAG
#define NVT_CEA861_EXT_TAG_VIDEO_CAP 0 // Video Capability Data Block
#define NVT_CEA861_EXT_TAG_VENDOR_SPECIFIC_VIDEO 1 // Vendor-Specific Video Data Block
#define NVT_CEA861_EXT_TAG_VESA_VIDEO_DISPLAY_DEVICE 2 // Reserved for VESA Video Display Device Information Data Block
#define NVT_CEA861_EXT_TAG_VESA_VIDEO_DISPLAY_DEVICE 2 // VESA Video Display Device Information Data Block
#define NVT_CEA861_EXT_TAG_VESA_VIDEO 3 // Reserved for VESA Video Data BLock
#define NVT_CEA861_EXT_TAG_HDMI_VIDEO 4 // Reserved for HDMI Video Data Block
#define NVT_CEA861_EXT_TAG_COLORIMETRY 5 // Colorimetry Data Block
#define NVT_CEA861_EXT_TAG_HDR_STATIC_METADATA 6 // HDR Static Metadata Data Block CEA861.3 HDR extension for HDMI 2.0a
#define NVT_CEA861_EXT_TAG_VIDEO_RSVD_MIN 7 // 7...12 : Reserved for video-related blocks
#define NVT_CEA861_EXT_TAG_VIDEO_RSVD_MAX 12
#define NVT_CTA861_EXT_TAG_HDR_DYNAMIC_METADATA 7 // CTA861-H HDR Dynamic Metadata Data Block
#define NVT_CTA861_EXT_TAG_VIDEO_RSVD_MIN 8 // 8...12 : Reserved for video-related blocks
#define NVT_CTA861_EXT_TAG_VIDEO_RSVD_MAX 12
#define NVT_CEA861_EXT_TAG_VIDEO_FORMAT_PREFERENCE 13 // CEA861F Video Format Preference Data Block
#define NVT_CEA861_EXT_TAG_YCBCR420_VIDEO 14 // CEA861F YCBCR 4:2:0 Video Data Block
#define NVT_CEA861_EXT_TAG_YCBCR420_CAP 15 // CEA861F YCBCR 4:2:0 Capability Map Data Block
#define NVT_CEA861_EXT_TAG_MISC_AUDIO 16 // CEA Miscellaneous Audio Fields
#define NVT_CEA861_EXT_TAG_VENDOR_SPECIFIC_AUDIO 17 // Vendor-Specific Audio Data Block
#define NVT_CEA861_EXT_TAG_HDMI_AUDIO 18 // Reserved for HDMI Audio Data Block
#define NVT_CEA861_EXT_TAG_AUDIO_RSVD_MIN 19 // 19...31 : Reserved for audio-related blocks
#define NVT_CEA861_EXT_TAG_AUDIO_RSVD_MAX 31
#define NVT_CTA861_EXT_TAG_ROOM_CONFIGURATION 19 // CTA861-H Room Configuration Data Block
#define NVT_CTA861_EXT_TAG_SPEACKER_LOCATION 20 // CTA861-H Speaker Location Data Block
#define NVT_CTA861_EXT_TAG_AUDIO_RSVD_MIN 21 // 21...31 : Reserved for audio-related blocks
#define NVT_CTA861_EXT_TAG_AUDIO_RSVD_MAX 31
#define NVT_CEA861_EXT_TAG_INFOFRAME 32 // Infoframe Data Block
#define NVT_CEA861_EXT_TAG_RSVD_MIN_1 33 // 33...120 : Reserved for general
#define NVT_CEA861_EXT_TAG_RSVD_MAX_1 119
#define NVT_CEA861_EXT_TAG_RSVD 33 // Reserved
#define NVT_CTA861_EXT_TAG_DID_TYPE_VII 34 // DisplayID Type VII Video Timing Data Block
#define NVT_CTA861_EXT_TAG_DID_TYPE_VIII 35 // DisplayID Type VIII Video Timing Data Block
#define NVT_CTA861_EXT_TAG_RSVD_MIN_1 36 // 36...41 : Reserved for general
#define NVT_CTA861_EXT_TAG_RSVD_MAX_1 41
#define NVT_CTA861_EXT_TAG_DID_TYPE_X 42 // DisplayID Type X Video Timing Data Block
#define NVT_CTA861_EXT_TAG_RSVD_MIN_2 43 // 43...119 : Reserved for general
#define NVT_CEA861_EXT_TAG_RSVD_MAX_2 119
#define NVT_CEA861_EXT_TAG_HF_EEODB 120 // HDMI Forum Edid Extension Override Data Block
#define NVT_CTA861_EXT_TAG_SCDB 121 // 0x79 == Tag for Sink Capability Data Block
#define NVT_CEA861_EXT_TAG_RSVD_MIN_2 122 // 122...255 : Reserved for general
#define NVT_CEA861_EXT_TAG_RSVD_MAX_2 255
#define NVT_CEA861_EXT_TAG_HDMI_RSVD_MIN 122 // 122...127 : Reserved for HDMI
#define NVT_CEA861_EXT_TAG_HDMI_RSVD_MAX 127
#define NVT_CEA861_EXT_TAG_RSVD_MIN_3 128 // 128...255 : Reserved for general
#define NVT_CEA861_EXT_TAG_RSVD_MAX_3 255
//
//the extended tag payload size; the size includes the extended tag code
#define NVT_CEA861_EXT_VIDEO_CAP_SD_SIZE 2
@@ -1108,7 +1120,28 @@ typedef struct tagNVT_2BYTES
NvU8 byte1;
NvU8 byte2;
} NVT_2BYTES;
//
//***********************
// DisplayID 10 Timing Data Block
//***********************
#define NVT_CTA861_DID_TYPE10_DESCRIPTORS_MIN 1
#define NVT_CTA861_DID_TYPE10_DESCRIPTORS_MAX 4
#define NVT_CTA861_DID_TYPE10_MAX_DATA_BLOCK 4
typedef struct DID_TYPE10_DATA
{
struct {
NvU8 revision : 3;
NvU8 F33 : 1;
NvU8 t10_m : 3;
NvU8 F37 : 1;
} version;
NvU8 total_descriptors;
NvU8 payload[28]; // given the 7bytes * 4 space
} DID_TYPE10_DATA;
// See CEA-861E, Table 42, 43 Extended Tags; indicates that the corresponding CEA extended data block value is valid, e.g. if colorimetry is set, then NVT_EDID_CEA861_INFO::colorimetry is valid
typedef struct tagNVT_VALID_EXTENDED_BLOCKS
{
@@ -1127,7 +1160,6 @@ typedef struct tagNVT_VALID_EXTENDED_BLOCKS
NvU32 msft_vsdb : 1;
} NVT_VALID_EXTENDED_BLOCKS;
//*************************
// extended data blocks
//*************************
@@ -1206,6 +1238,10 @@ typedef struct tagEDID_CEA861_INFO
NvU32 hfscdbSize;
NvU8 hfscdb[NVT_CTA861_EXT_SCDB_PAYLOAD_MAX_LENGTH];
// DID Type X Video extended block, see CTA861-H, section 3.5.17.3 DisplayID Type X Video Timing Data Block
NvU8 total_did_type10db;
DID_TYPE10_DATA did_type10_data_block[NVT_CTA861_DID_TYPE10_MAX_DATA_BLOCK];
NvU8 hfeeodb; // HDMI Forum Edid Extension Override Data Block.
} NVT_EDID_CEA861_INFO;
@@ -5312,6 +5348,9 @@ typedef enum
#define NVT_FLAG_DISPLAYID_T7_DSC_PASSTHRU 0x00400000
#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_DISPLAYID_T7_TIMING 0x02000000
#define NVT_FLAG_DISPLAYID_T8_TIMING 0x04000000
#define NVT_FLAG_DISPLAYID_T10_TIMING 0x08000000
#define NVT_FLAG_INTERLACED_MASK (NVT_FLAG_INTERLACED_TIMING | NVT_FLAG_INTERLACED_TIMING2)

View File

@@ -1,6 +1,6 @@
//*****************************************************************************
//
// SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: MIT
//
// Permission is hereby granted, free of charge, to any person obtaining a
@@ -81,6 +81,7 @@ void parseEdidNvidiaVSDBBlock(VSDB_DATA *pVsdb, NVDA_VSDB_PARSED_INFO *vsd
void parseCea861HdrStaticMetadataDataBlock(NVT_EDID_CEA861_INFO *pExt861, void *pRawInfo, NVT_CTA861_ORIGIN flag);
void parseCea861DvStaticMetadataDataBlock(NVT_EDID_CEA861_INFO *pExt861, void *pRawInfo, NVT_CTA861_ORIGIN flag);
void parseCea861Hdr10PlusDataBlock(NVT_EDID_CEA861_INFO *pExt861, void *pRawInfo, NVT_CTA861_ORIGIN flag);
void parseCta861DIDType10VideoTimingDataBlock(NVT_EDID_CEA861_INFO *pExt861, void *pRawInfo);
NvBool isMatchedCTA861Timing(NVT_EDID_INFO *pInfo, NVT_TIMING *pT);
NvU32 isHdmi3DStereoType(NvU8 StereoStructureType);
NvU32 getCEA861TimingAspectRatio(NvU32 vic);
@@ -95,6 +96,7 @@ NVT_STATUS getDisplayIdEDIDExtInfo(NvU8* pEdid, NvU32 edidSize, NVT_EDID_INFO* p
NVT_STATUS parseDisplayIdBlock(NvU8* pBlock, NvU8 max_length, NvU8* pLength, NVT_EDID_INFO* pEdidInfo);
NVT_STATUS getDisplayId20EDIDExtInfo(NvU8* pDisplayid, NvU32 edidSize, NVT_EDID_INFO* pEdidInfo);
NVT_STATUS parseDisplayId20EDIDExtDataBlocks(NvU8* pDataBlock, NvU8 remainSectionLength, NvU8* pCurrentDBLength, NVT_EDID_INFO* pEdidInfo);
NVT_STATUS parseDisplayId20Timing10Descriptor(const void *pDescriptor, NVT_TIMING *pTiming, NvU8 payloadBytes);
void updateColorFormatForDisplayIdExtnTimings(NVT_EDID_INFO* pInfo, NvU32 timingIdx);
void updateColorFormatForDisplayId20ExtnTimings(NVT_EDID_INFO* pInfo, NvU32 timingIdx);
NvBool assignNextAvailableDisplayId20Timing(NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo, const NVT_TIMING *pTiming);