mirror of
https://github.com/NVIDIA/open-gpu-kernel-modules.git
synced 2026-03-01 19:30:10 +00:00
525.53
This commit is contained in:
@@ -254,6 +254,7 @@ typedef struct _tagNVHDMIPKT_CALLBACK
|
||||
NvBool expression);
|
||||
} NVHDMIPKT_CALLBACK;
|
||||
|
||||
|
||||
/*********************** HDMI Library interface to write hdmi ctrl/packet ***********************/
|
||||
typedef void* NvHdmiPkt_Handle;
|
||||
#define NVHDMIPKT_INVALID_HANDLE ((NvHdmiPkt_Handle)0)
|
||||
@@ -300,6 +301,7 @@ NvHdmiPkt_PacketWrite(NvHdmiPkt_Handle libHandle,
|
||||
NvU32 packetLen,
|
||||
NvU8 const *const pPacket);
|
||||
|
||||
|
||||
/***************************** Interface to initialize HDMI Library *****************************/
|
||||
|
||||
/************************************************************************************************
|
||||
|
||||
@@ -388,4 +388,5 @@ initializeHdmiPktInterface0073(NVHDMIPKT_CLASS* pClass)
|
||||
pClass->hdmiQueryFRLConfig = hdmiQueryFRLConfigDummy;
|
||||
pClass->hdmiSetFRLConfig = hdmiSetFRLConfigDummy;
|
||||
pClass->hdmiClearFRLConfig = hdmiClearFRLConfigDummy;
|
||||
|
||||
}
|
||||
|
||||
@@ -846,4 +846,5 @@ initializeHdmiPktInterface9171(NVHDMIPKT_CLASS* pClass)
|
||||
pClass->hdmiQueryFRLConfig = hdmiQueryFRLConfigDummy;
|
||||
pClass->hdmiSetFRLConfig = hdmiSetFRLConfigDummy;
|
||||
pClass->hdmiClearFRLConfig = hdmiClearFRLConfigDummy;
|
||||
|
||||
}
|
||||
|
||||
@@ -110,5 +110,4 @@ extern NVHDMIPKT_RESULT hdmiClearFRLConfigDummy(NVHDMIPKT_CLASS *pThis,
|
||||
NvU32 subDevice,
|
||||
NvU32 displayId);
|
||||
|
||||
|
||||
#endif //_NVHDMIPKT_COMMON_H_
|
||||
|
||||
@@ -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
|
||||
@@ -100,14 +100,20 @@ typedef struct _tagDISPLAYID_2_0_DATA_BLOCK_HEADER
|
||||
#define DISPLAYID_2_0_BLOCK_TYPE_TIMING_7 0x22
|
||||
#define DISPLAYID_2_0_BLOCK_TYPE_TIMING_8 0x23
|
||||
#define DISPLAYID_2_0_BLOCK_TYPE_TIMING_9 0x24
|
||||
#define DISPLAYID_2_0_BLOCK_TYPE_TIMING_10 0x2A
|
||||
#define DISPLAYID_2_0_BLOCK_TYPE_RANGE_LIMITS 0x25
|
||||
#define DISPLAYID_2_0_BLOCK_TYPE_INTERFACE_FEATURES 0x26
|
||||
#define DISPLAYID_2_0_BLOCK_TYPE_STEREO 0x27
|
||||
#define DISPLAYID_2_0_BLOCK_TYPE_TILED_DISPLAY 0x28
|
||||
#define DISPLAYID_2_0_BLOCK_TYPE_CONTAINER_ID 0x29
|
||||
#define DISPLAYID_2_0_BLOCK_TYPE_TIMING_10 0x2A
|
||||
#define DISPLAYID_2_0_BLOCK_TYPE_ADAPTIVE_SYNC 0x2B
|
||||
#define DISPLAYID_2_0_BLOCK_TYPE_ARVR_HMD 0x2C
|
||||
#define DISPLAYID_2_0_BLOCK_TYPE_ARVR_LAYER 0x2D
|
||||
// 0x7D - 0x2E RESERVED for Additional VESA-defined Data Blocks
|
||||
#define DISPLAYID_2_0_BLOCK_TYPE_VENDOR_SPEC 0x7E
|
||||
// 0x80 - 0x7F RESERVED
|
||||
#define DISPLAYID_2_0_BLOCK_TYPE_CTA_DATA 0x81
|
||||
// 0xFF - 0x82 RESERVED for additional data blocks related to external standards organization(s).
|
||||
|
||||
#define DISPLAYID_2_0_PRODUCT_NAME_STRING_MAX_LEN ((0xFB - 0xF) + 1)
|
||||
|
||||
@@ -236,7 +242,7 @@ typedef struct _tag_DISPLAYID_2_0_TIMING_7_DESCRIPTOR
|
||||
NvU8 interface_frame_scanning_type : 1;
|
||||
NvU8 stereo_support : 2;
|
||||
NvU8 is_preferred_or_ycc420 : 1;
|
||||
}options;
|
||||
} options;
|
||||
|
||||
struct
|
||||
{
|
||||
@@ -246,7 +252,7 @@ typedef struct _tag_DISPLAYID_2_0_TIMING_7_DESCRIPTOR
|
||||
NvU8 front_porch_pixels_high : 7;
|
||||
NvU8 sync_polarity : 1;
|
||||
NvU8 sync_width_pixels[2];
|
||||
}horizontal;
|
||||
} horizontal;
|
||||
|
||||
struct
|
||||
{
|
||||
@@ -256,8 +262,7 @@ typedef struct _tag_DISPLAYID_2_0_TIMING_7_DESCRIPTOR
|
||||
NvU8 front_porch_lines_high : 7;
|
||||
NvU8 sync_polarity : 1;
|
||||
NvU8 sync_width_lines[2];
|
||||
}vertical;
|
||||
|
||||
} vertical;
|
||||
} DISPLAYID_2_0_TIMING_7_DESCRIPTOR;
|
||||
|
||||
#define DISPLAYID_2_0_TIMING_7_MAX_DESCRIPTORS 12
|
||||
@@ -336,11 +341,11 @@ typedef struct _tagDISPLAYID_2_0_TIMING_8_BLOCK
|
||||
typedef struct _TAG_DISPLAYID_2_0_TIMING_9_DESCRIPTOR
|
||||
{
|
||||
struct {
|
||||
NvU8 timing_formula:3;
|
||||
NvU8 reserved0:1;
|
||||
NvU8 fractional_refresh_rate_support:1;
|
||||
NvU8 stereo_support:2;
|
||||
NvU8 reserved1:1;
|
||||
NvU8 timing_formula :3;
|
||||
NvU8 reserved0 :1;
|
||||
NvU8 rr_1000div1001_support :1;
|
||||
NvU8 stereo_support :2;
|
||||
NvU8 reserved1 :1;
|
||||
} options;
|
||||
|
||||
NvU8 horizontal_active_pixels[2];
|
||||
@@ -350,10 +355,10 @@ typedef struct _TAG_DISPLAYID_2_0_TIMING_9_DESCRIPTOR
|
||||
|
||||
#define DISPLAYID_2_0_TIMING_FORMULA_CVT_1_2_STANDARD 0
|
||||
#define DISPLAYID_2_0_TIMING_FORMULA_CVT_1_2_REDUCED_BLANKING_1 1
|
||||
#define DISPLAYID_2_0_TIMING_FORMULA_CVT_1_2_REDUCED_BLANKING_2 2
|
||||
#define DISPLAYID_2_0_TIMING_FORMULA_CVT_1_2_REDUCED_BLANKING_3 3
|
||||
#define DISPLAYID_2_0_TIMING_FORMULA_CVT_2_0_REDUCED_BLANKING_2 2
|
||||
#define DISPLAYID_2_0_TIMING_FORMULA_CVT_2_0_REDUCED_BLANKING_3 3
|
||||
|
||||
#define DISPLAYID_2_0_TIMING_9_MAX_DESCRIPTORS 41
|
||||
#define DISPLAYID_2_0_TIMING_9_MAX_DESCRIPTORS 18
|
||||
|
||||
typedef struct _tagDISPLAYID_2_0_TIMING_9_BLOCK
|
||||
{
|
||||
@@ -379,8 +384,8 @@ typedef struct _DISPLAYID_2_0_TIMING_10_6BYTES_DESCRIPTOR
|
||||
{
|
||||
struct {
|
||||
NvU8 timing_formula :3;
|
||||
NvU8 reserved0 :1;
|
||||
NvU8 vrr_or_hblank :1;
|
||||
NvU8 early_vsync :1;
|
||||
NvU8 rr1000div1001_or_hblank :1;
|
||||
NvU8 stereo_support :2;
|
||||
NvU8 ycc420_support :1;
|
||||
} options;
|
||||
@@ -398,8 +403,8 @@ typedef struct _DISPLAYID_2_0_TIMING_10_7BYTES_DESCRIPTOR
|
||||
NvU8 additional_vblank_timing :3;
|
||||
} DISPLAYID_2_0_TIMING_10_7BYTES_DESCRIPTOR;
|
||||
|
||||
#define DISPLAYID_2_0_TIMING_10_MAX_6BYTES_DESCRIPTORS 41
|
||||
#define DISPLAYID_2_0_TIMING_10_MAX_7BYTES_DESCRIPTORS 35
|
||||
#define DISPLAYID_2_0_TIMING_10_MAX_6BYTES_DESCRIPTORS 18
|
||||
#define DISPLAYID_2_0_TIMING_10_MAX_7BYTES_DESCRIPTORS 16
|
||||
|
||||
typedef struct _DISPLAYID_2_0_TIMING_10_BLOCK
|
||||
{
|
||||
@@ -416,10 +421,11 @@ typedef struct _tagDISPLAYID_2_0_RANGE_LIMITS_BLOCK
|
||||
NvU8 pixel_clock_max[3];
|
||||
NvU8 vertical_frequency_min;
|
||||
NvU8 vertical_frequency_max_7_0;
|
||||
|
||||
struct {
|
||||
NvU8 vertical_frequency_max_9_8:2;
|
||||
NvU8 reserved:5;
|
||||
NvU8 seamless_dynamic_video_timing_change:1;
|
||||
NvU8 vertical_frequency_max_9_8 :2;
|
||||
NvU8 reserved :5;
|
||||
NvU8 seamless_dynamic_video_timing_change :1;
|
||||
} dynamic_video_timing_range_support;
|
||||
} DISPLAYID_2_0_RANGE_LIMITS_BLOCK;
|
||||
|
||||
@@ -677,6 +683,51 @@ typedef struct _tagDISPLAYID_2_0_CONTAINERID_BLOCK
|
||||
NvU8 container_id[DISPLAYID_2_0_CONTAINERID_BLOCK_PAYLOAD_LENGTH];
|
||||
} DISPLAYID_2_0_CONTAINERID_BLOCK;
|
||||
|
||||
#define DISPLAYID_2_0_ADAPTIVE_SYNC_DETAILED_TIMING_COUNT 4
|
||||
typedef struct _tagDISPLAYID_2_0_ADAPTIVE_SYNC_BLOCK_HEADER
|
||||
{
|
||||
NvU8 type; // Adaptive-Sync (0x2B)
|
||||
NvU8 revision :3;
|
||||
NvU8 reserved0 :1;
|
||||
NvU8 payload_bytes_adaptive_sync_len :3;
|
||||
NvU8 reserved1 :1;
|
||||
NvU8 payload_bytes;
|
||||
} DISPLAYID_2_0_ADAPTIVE_SYNC_BLOCK_HEADER;
|
||||
|
||||
typedef struct _tagDISPLAYID_2_0_ADAPTIVE_SYNC_DESCRIPTOR
|
||||
{
|
||||
struct
|
||||
{
|
||||
NvU8 range : 1;
|
||||
NvU8 successive_frame_inc_tolerance : 1;
|
||||
NvU8 modes : 2;
|
||||
NvU8 seamless_transition_not_support: 1;
|
||||
NvU8 successive_frame_dec_tolerance : 1;
|
||||
NvU8 reserved : 2;
|
||||
} operation_range_info;
|
||||
|
||||
// 6.2 format (six integer bits and two fractional bits)
|
||||
// six integer bits == 0 - 63ms
|
||||
// two fractional bits == 0.00(00), 0.25(01b),0.50(10), 0.75(11b)
|
||||
NvU8 max_single_frame_inc;
|
||||
NvU8 min_refresh_rate;
|
||||
struct
|
||||
{
|
||||
NvU8 max_rr_7_0;
|
||||
NvU8 max_rr_9_8 : 2;
|
||||
NvU8 reserved : 6;
|
||||
} max_refresh_rate;
|
||||
|
||||
// same as max_single_frame_inc expression
|
||||
NvU8 max_single_frame_dec;
|
||||
} DISPLAYID_2_0_ADAPTIVE_SYNC_DESCRIPTOR;
|
||||
|
||||
typedef struct _tagDISPLAYID_2_0_ADAPTIVE_SYNC_BLOCK
|
||||
{
|
||||
DISPLAYID_2_0_ADAPTIVE_SYNC_BLOCK_HEADER header;
|
||||
DISPLAYID_2_0_ADAPTIVE_SYNC_DESCRIPTOR descriptors[DISPLAYID_2_0_ADAPTIVE_SYNC_DETAILED_TIMING_COUNT];
|
||||
} DISPLAYID_2_0_ADAPTIVE_SYNC_BLOCK;
|
||||
|
||||
typedef struct _tagDISPLAYID_2_0_VENDOR_SPECIFIC_BLOCK
|
||||
{
|
||||
DISPLAYID_2_0_DATA_BLOCK_HEADER header;
|
||||
|
||||
@@ -49,8 +49,8 @@ typedef enum tagSDP_VSC_REVNUM
|
||||
{
|
||||
SDP_VSC_REVNUM_STEREO = 1,
|
||||
SDP_VSC_REVNUM_STEREO_PSR,
|
||||
SDP_VSC_REVNUM_STEREO_PSR2,
|
||||
SDP_VSC_REVNUM_PSR2_EXTN,
|
||||
SDP_VSC_REVNUM_STEREO_PSR2,
|
||||
SDP_VSC_REVNUM_PSR2_EXTN,
|
||||
SDP_VSC_REVNUM_STEREO_PSR2_COLOR,
|
||||
SDP_VSC_REVNUM_STEREO_PR,
|
||||
SDP_VSC_REVNUM_STEREO_PR_COLOR,
|
||||
@@ -60,7 +60,7 @@ typedef enum tagSDP_VSC_VALID_DATA_BYTES
|
||||
{
|
||||
SDP_VSC_VALID_DATA_BYTES_STEREO = 1,
|
||||
SDP_VSC_VALID_DATA_BYTES_STEREO_PSR = 8,
|
||||
SDP_VSC_VALID_DATA_BYTES_PSR2 = 12,
|
||||
SDP_VSC_VALID_DATA_BYTES_PSR2 = 12,
|
||||
SDP_VSC_VALID_DATA_BYTES_PSR2_COLOR = 19,
|
||||
SDP_VSC_VALID_DATA_BYTES_PR = 16,
|
||||
SDP_VSC_VALID_DATA_BYTES_PR_COLOR = 19,
|
||||
@@ -161,7 +161,7 @@ typedef enum tagSDP_VSC_COLOR_FMT_Y_COLORIMETRY
|
||||
typedef struct tagDPSDP_DP_VSC_SDP_DESCRIPTOR
|
||||
{
|
||||
NvU8 dataSize; // the db data size
|
||||
|
||||
|
||||
// header
|
||||
struct
|
||||
{
|
||||
@@ -174,11 +174,11 @@ typedef struct tagDPSDP_DP_VSC_SDP_DESCRIPTOR
|
||||
} hb;
|
||||
|
||||
// data content
|
||||
struct
|
||||
struct
|
||||
{
|
||||
// Stereo field. Note: Needs to be expanded when needed. Refer to DP1.3 spec.
|
||||
// Stereo field. Note: Needs to be expanded when needed. Refer to DP1.3 spec.
|
||||
NvU8 stereoInterface; // DB0
|
||||
// PSR Field. Note: Needs to be expanded when needed. Refer to DP1.3 spec.
|
||||
// PSR Field. Note: Needs to be expanded when needed. Refer to DP1.3 spec.
|
||||
NvU8 psrState : 1; //DB1
|
||||
NvU8 psrUpdateRfb : 1;
|
||||
NvU8 psrCrcValid : 1;
|
||||
@@ -203,7 +203,7 @@ typedef struct tagDPSDP_DP_VSC_SDP_DESCRIPTOR
|
||||
NvU8 db14;
|
||||
NvU8 db15;
|
||||
|
||||
// Colorimetry Infoframe Secondary Data Package following DP1.3 spec
|
||||
// Colorimetry Infoframe Secondary Data Package following DP1.3 spec
|
||||
NvU8 colorimetryFormat : 4; // DB16 infoframe per DP1.3 spec
|
||||
NvU8 pixEncoding : 4; // DB16 infoframe per DP1.3 spec
|
||||
|
||||
@@ -229,7 +229,7 @@ typedef struct tagDPSDP_DP_VSC_SDP_DESCRIPTOR
|
||||
typedef struct tagDPSDP_DP_PR_VSC_SDP_DESCRIPTOR
|
||||
{
|
||||
NvU8 dataSize; // the db data size
|
||||
|
||||
|
||||
// header
|
||||
struct
|
||||
{
|
||||
@@ -242,11 +242,11 @@ typedef struct tagDPSDP_DP_PR_VSC_SDP_DESCRIPTOR
|
||||
} hb;
|
||||
|
||||
// data content
|
||||
struct
|
||||
struct
|
||||
{
|
||||
// Stereo field. Note: Needs to be expanded when needed. Refer to DP1.3 spec.
|
||||
// Stereo field. Note: Needs to be expanded when needed. Refer to DP1.3 spec.
|
||||
NvU8 stereoInterface; // DB0
|
||||
// PSR Field. Note: Needs to be expanded when needed. Refer to DP1.3 spec.
|
||||
// PSR Field. Note: Needs to be expanded when needed. Refer to DP1.3 spec.
|
||||
NvU8 prState : 1; // DB1
|
||||
NvU8 prReserved : 1; // Always ZERO
|
||||
NvU8 prCrcValid : 1;
|
||||
@@ -268,7 +268,7 @@ typedef struct tagDPSDP_DP_PR_VSC_SDP_DESCRIPTOR
|
||||
NvU8 db14;
|
||||
NvU8 db15;
|
||||
|
||||
// Colorimetry Infoframe Secondary Data Package following DP1.3 spec
|
||||
// Colorimetry Infoframe Secondary Data Package following DP1.3 spec
|
||||
NvU8 colorimetryFormat : 4; // DB16 infoframe per DP1.3 spec
|
||||
NvU8 pixEncoding : 4; // DB16 infoframe per DP1.3 spec
|
||||
|
||||
@@ -294,12 +294,12 @@ typedef struct tagDPSDP_DP_PR_VSC_SDP_DESCRIPTOR
|
||||
typedef struct tagDPSDP_DESCRIPTOR
|
||||
{
|
||||
NvU8 dataSize;
|
||||
|
||||
|
||||
// header byte
|
||||
struct
|
||||
struct
|
||||
{
|
||||
NvU8 hb0;
|
||||
NvU8 hb1;
|
||||
NvU8 hb1;
|
||||
NvU8 hb2;
|
||||
NvU8 hb3;
|
||||
} hb;
|
||||
@@ -308,7 +308,7 @@ typedef struct tagDPSDP_DESCRIPTOR
|
||||
struct
|
||||
{
|
||||
NvU8 db0;
|
||||
NvU8 db1;
|
||||
NvU8 db1;
|
||||
NvU8 db2;
|
||||
NvU8 db3;
|
||||
NvU8 db4;
|
||||
|
||||
@@ -30,12 +30,12 @@
|
||||
#ifndef __EDID_H_
|
||||
#define __EDID_H_
|
||||
|
||||
#include "nvtiming.h"
|
||||
#include "nvtiming_pvt.h"
|
||||
#include "displayid.h"
|
||||
#include "displayid20.h"
|
||||
|
||||
// EDID 1.x detailed timing template
|
||||
|
||||
|
||||
#define NVT_PVT_EDID_LDD_PAYLOAD_SIZE 13
|
||||
|
||||
typedef struct _tagEDID_LONG_DISPLAY_DESCRIPTOR
|
||||
@@ -286,7 +286,6 @@ typedef struct _tagEIA861EXTENSION
|
||||
NvU8 checksum; // 0x7F
|
||||
}EIA861EXTENSION;
|
||||
|
||||
|
||||
typedef struct _tagVTBEXTENSION
|
||||
{
|
||||
NvU8 tag; // 0x00
|
||||
@@ -298,6 +297,18 @@ typedef struct _tagVTBEXTENSION
|
||||
NvU8 checksum;
|
||||
}VTBEXTENSION;
|
||||
|
||||
// EDID DisplayID extension block template
|
||||
typedef struct _tagDIDEXTENSION
|
||||
{
|
||||
NvU8 tag; // 0x00
|
||||
NvU8 struct_version; // 0x01
|
||||
NvU8 length; // 0x02
|
||||
NvU8 use_case; // 0x03
|
||||
NvU8 ext_count; // 0x04
|
||||
NvU8 data[NVT_DID_MAX_EXT_PAYLOAD]; // 0x05 - 0x7E
|
||||
NvU8 checksum; // 0x7F
|
||||
}DIDEXTENSION;
|
||||
|
||||
// video signal interface mask
|
||||
#define NVT_PVT_EDID_INPUT_ISDIGITAL_MASK 0x80 // 0==analog
|
||||
#define NVT_PVT_EDID_INPUT_ISDIGITAL_SHIFT 7
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2171,7 +2171,13 @@ DSC_GeneratePPS
|
||||
if (*pBitsPerPixelX16 != 0)
|
||||
{
|
||||
*pBitsPerPixelX16 = DSC_AlignDownForBppPrecision(*pBitsPerPixelX16, pDscInfo->sinkCaps.bitsPerPixelPrecision);
|
||||
if (*pBitsPerPixelX16 > in->bits_per_pixel)
|
||||
|
||||
// The calculation of in->bits_per_pixel here in PPSlib, which is the maximum bpp that is allowed by available bandwidth,
|
||||
// which is applicable to DP alone and not to HDMI FRL.
|
||||
// Before calling PPS lib to generate PPS data, HDMI library has done calculation according to HDMI2.1 spec
|
||||
// to determine if FRL rate is sufficient for the requested bpp. So restricting the condition to DP alone.
|
||||
if ((pWARData && (pWARData->connectorType == DSC_DP)) &&
|
||||
(*pBitsPerPixelX16 > in->bits_per_pixel))
|
||||
{
|
||||
DSC_Print("ERROR - Invalid bits per pixel value specified.");
|
||||
ret = NVT_STATUS_INVALID_PARAMETER;
|
||||
|
||||
@@ -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
|
||||
@@ -217,7 +217,7 @@ NvU32 getEdidVersion(NvU8 *pEdid, NvU32 *pVer)
|
||||
|
||||
*pVer = (((NvU32) p->bVersionNumber) << 8) + ((NvU32) p->bRevisionNumber);
|
||||
}
|
||||
else if ((pEdid[0] & 0xF0) == 0x20 && (pEdid[0] & 0x0F) >=0)
|
||||
else if ((pEdid[0] & 0xF0) == 0x20)
|
||||
*pVer = (((NvU32) (pEdid[0] & 0XF0) << 4) + (NvU32) (pEdid[0] & 0X0F)) ; // DisplayID version 2.x
|
||||
else
|
||||
return NVT_STATUS_ERR; // un-recongnized EDID version
|
||||
@@ -432,10 +432,9 @@ void parseEdidStandardTimingDescriptor(NvU16 timing, NVT_EDID_INFO *pInfo, NvU32
|
||||
NVT_SNPRINTF((char *)pT->etc.name, 40, "EDID-STD(DMT):%dx%dx%dHz", (int)width, (int)height, (int)rr);
|
||||
pT->etc.name[39] = '\0';
|
||||
}
|
||||
else if (pInfo->version >= NVT_EDID_VER_1_4)
|
||||
// EDID1.4 and above defaults to CVT, instead of GTF. GTF is deprecated as of 1.4.
|
||||
else if ((pInfo->version >= NVT_EDID_VER_1_4) && (NvTiming_CalcCVT(width, height, rr, NVT_PROGRESSIVE, pT) == NVT_STATUS_SUCCESS))
|
||||
{
|
||||
// EDID1.4 and above defaults to CVT, instead of GTF. GTF is deprecated as of 1.4.
|
||||
NvTiming_CalcCVT(width, height, rr, NVT_PROGRESSIVE, pT);
|
||||
pT->etc.status = NVT_STATUS_EDID_STDn(count);
|
||||
NVT_SNPRINTF((char *)pT->etc.name, 40, "EDID-STD(CVT):%dx%dx%dHz", (int)width, (int)height, (int)rr);
|
||||
pT->etc.name[39] = '\0';
|
||||
@@ -443,10 +442,12 @@ void parseEdidStandardTimingDescriptor(NvU16 timing, NVT_EDID_INFO *pInfo, NvU32
|
||||
else
|
||||
{
|
||||
// if the mode is not found in DMT, use GTF timing
|
||||
NvTiming_CalcGTF(width, height, rr, NVT_PROGRESSIVE, pT);
|
||||
if (NvTiming_CalcGTF(width, height, rr, NVT_PROGRESSIVE, pT) == NVT_STATUS_SUCCESS)
|
||||
{
|
||||
NVT_SNPRINTF((char *)pT->etc.name, 40, "EDID-STD(GTF):%dx%dx%dHz", (int)width, (int)height, (int)rr);
|
||||
pT->etc.name[39] = '\0';
|
||||
}
|
||||
pT->etc.status = NVT_STATUS_EDID_STDn(count);
|
||||
NVT_SNPRINTF((char *)pT->etc.name, 40, "EDID-STD(GTF):%dx%dx%dHz", (int)width, (int)height, (int)rr);
|
||||
pT->etc.name[39] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1055,7 +1056,10 @@ NVT_STATUS NV_STDCALL NvTiming_ParseEDIDInfo(NvU8 *pEdid, NvU32 length, NVT_EDID
|
||||
parseCea861HdrStaticMetadataDataBlock(p861Info, pInfo, FROM_CTA861_EXTENSION);
|
||||
|
||||
// parse Dolby Vision related information from the DV vendor specific video data block
|
||||
parseCea861DvStaticMetadataDataBlock(p861Info, &pInfo->dv_static_metadata_info);
|
||||
parseCea861DvStaticMetadataDataBlock(p861Info, pInfo, FROM_CTA861_EXTENSION);
|
||||
|
||||
// parse HDR10+ related information from the HDR10+ LLC Vendor Specific Video Data Block
|
||||
parseCea861Hdr10PlusDataBlock(p861Info, pInfo, FROM_CTA861_EXTENSION);
|
||||
|
||||
// Timings are listed (or shall) be listed in priority order
|
||||
// So read SVD, yuv420 SVDs first before reading detailed timings
|
||||
@@ -1955,7 +1959,15 @@ NVT_STATUS NvTiming_GetEDIDBasedASPRTiming( NvU16 width, NvU16 height, NvU16 rr,
|
||||
return NVT_STATUS_ERR;
|
||||
}
|
||||
|
||||
// check whether EDID is valid
|
||||
/**
|
||||
*
|
||||
* @brief check EDID raw data is valid or not, and it will return the err flags if it existed
|
||||
* @param pEdid : this is a pointer to EDID data
|
||||
* @param length : read length of EDID
|
||||
* @param bIsTrongValidation : true - added more check
|
||||
* false- only header and checksum and size check
|
||||
*
|
||||
*/
|
||||
CODE_SEGMENT(PAGE_DD_CODE)
|
||||
NvU32 NvTiming_EDIDValidationMask(NvU8 *pEdid, NvU32 length, NvBool bIsStrongValidation)
|
||||
{
|
||||
@@ -2120,8 +2132,369 @@ NvU32 NvTiming_EDIDValidationMask(NvU8 *pEdid, NvU32 length, NvBool bIsStrongVal
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief sanity check EDID binary frequently used data block is valid or not,
|
||||
* and it will return error checkpoint flag if it existed
|
||||
* @param pEdid : this is a pointer to EDID raw data
|
||||
* @param length : read length of EDID
|
||||
*
|
||||
*/
|
||||
CODE_SEGMENT(PAGE_DD_CODE)
|
||||
NvU32 NvTiming_EDIDStrongValidationMask(NvU8 *pEdid, NvU32 length)
|
||||
{
|
||||
NvU32 i, j, version, extnCount;
|
||||
EDIDV1STRUC *p = (EDIDV1STRUC *)pEdid;
|
||||
EDID_LONG_DISPLAY_DESCRIPTOR *pLdd;
|
||||
NvU8 *pExt;
|
||||
DETAILEDTIMINGDESCRIPTOR *pDTD;
|
||||
// For CTA861
|
||||
NvU8 ctaDTD_Offset;
|
||||
NvU8 *pData_collection;
|
||||
NvU32 ctaBlockTag, ctaPayload, vic;
|
||||
// For DisplayID
|
||||
DIDEXTENSION *pDisplayid;
|
||||
NvU8 did_section_length = 0x79;
|
||||
NvU8 did2ExtCount = 0;
|
||||
DISPLAYID_2_0_DATA_BLOCK_HEADER *pDID2Header;
|
||||
DISPLAYID_DATA_BLOCK_HEADER *pHeader;
|
||||
NvU8 block_length = 0;
|
||||
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))
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_SIZE);
|
||||
|
||||
// check the EDID version and signature
|
||||
if (getEdidVersion(pEdid, &version) != NVT_STATUS_SUCCESS)
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_HEADER);
|
||||
|
||||
// check block 0 checksum value
|
||||
if (!isChecksumValid(pEdid))
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_CHECKSUM);
|
||||
|
||||
if (p->bVersionNumber != 0x01 || p->bRevisionNumber > 0x04)
|
||||
{
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_VERSION);
|
||||
}
|
||||
|
||||
// 18bytes in DTD or Display Descriptor check
|
||||
for (i = 0; i < NVT_EDID_MAX_LONG_DISPLAY_DESCRIPTOR; i++)
|
||||
{
|
||||
if (*((NvU16 *)&p->DetailedTimingDesc[i]) != 0)
|
||||
{
|
||||
// This block is not a Display Descriptor.
|
||||
// It must be a valid timing definition
|
||||
// validate the block by passing NULL as the NVTIMING parameter to parseEdidDetailedTimingDescriptor
|
||||
if (parseEdidDetailedTimingDescriptor((NvU8 *)&p->DetailedTimingDesc[i], NULL) != NVT_STATUS_SUCCESS)
|
||||
{
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_DTD);
|
||||
}
|
||||
else
|
||||
{
|
||||
// check the max image size in monitor and its DTD defines value
|
||||
if (p->bMaxHorizImageSize != 0 && p->bMaxVertImageSize != 0)
|
||||
{
|
||||
DETAILEDTIMINGDESCRIPTOR *pDTD = (DETAILEDTIMINGDESCRIPTOR *)&p->DetailedTimingDesc[i];
|
||||
NvU16 hDTDImageSize = (pDTD->bDTHorizVertImage & 0xF0) << 4 | pDTD->bDTHorizontalImage;
|
||||
NvU16 vDTDImageSize = (pDTD->bDTHorizVertImage & 0x0F) << 8 | pDTD->bDTVerticalImage;
|
||||
|
||||
if ((hDTDImageSize/10) > p->bMaxHorizImageSize || (vDTDImageSize/10) > p->bMaxVertImageSize)
|
||||
{
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_DTD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pLdd = (EDID_LONG_DISPLAY_DESCRIPTOR *)&p->DetailedTimingDesc[i];
|
||||
|
||||
// This block is a display descriptor, validate
|
||||
if (((EDID_LONG_DISPLAY_DESCRIPTOR *)&p->DetailedTimingDesc[i])->rsvd != 0 || // (00 00 00)h indicates Display Descriptor
|
||||
(pLdd->tag >= 0x11 && pLdd->tag <= 0xF6)) // Reserved : Do Not Use
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_DESCRIPTOR);
|
||||
|
||||
if (pLdd->tag == NVT_EDID_DISPLAY_DESCRIPTOR_DRL && (version == 0x103 || (version == 0x104 && (p->bFeatureSupport & 1))))
|
||||
{
|
||||
EDID_MONITOR_RANGE_LIMIT *pRangeLimit = (EDID_MONITOR_RANGE_LIMIT *)pLdd->data;
|
||||
NvU8 max_v_rate_offset, min_v_rate_offset, max_h_rate_offset, min_h_rate_offset;
|
||||
|
||||
// add 255Hz offsets as needed before doing the check, use descriptor->rsvd2
|
||||
nvt_assert(!(pLdd->rsvd2 & 0xF0));
|
||||
|
||||
max_v_rate_offset = pLdd->rsvd2 & NVT_PVT_EDID_RANGE_OFFSET_VER_MAX ? NVT_PVT_EDID_RANGE_OFFSET_AMOUNT : 0;
|
||||
min_v_rate_offset = pLdd->rsvd2 & NVT_PVT_EDID_RANGE_OFFSET_VER_MIN ? NVT_PVT_EDID_RANGE_OFFSET_AMOUNT : 0;
|
||||
max_h_rate_offset = pLdd->rsvd2 & NVT_PVT_EDID_RANGE_OFFSET_HOR_MAX ? NVT_PVT_EDID_RANGE_OFFSET_AMOUNT : 0;
|
||||
min_h_rate_offset = pLdd->rsvd2 & NVT_PVT_EDID_RANGE_OFFSET_HOR_MIN ? NVT_PVT_EDID_RANGE_OFFSET_AMOUNT : 0;
|
||||
|
||||
if ((pRangeLimit->minVRate + min_v_rate_offset) > (pRangeLimit->maxVRate + max_v_rate_offset) ||
|
||||
(pRangeLimit->minHRate + min_h_rate_offset) > (pRangeLimit->maxHRate + max_h_rate_offset) ||
|
||||
pRangeLimit->maxVRate == 0 ||
|
||||
pRangeLimit->maxHRate == 0)
|
||||
{
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_RANGE_LIMIT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// extension and size check
|
||||
if ((NvU32)(p->bExtensionFlag + 1) * sizeof(EDIDV1STRUC) > length)
|
||||
{
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_EXTENSION_COUNT);
|
||||
}
|
||||
|
||||
// validate extension blocks
|
||||
for (j = 1; j <= p->bExtensionFlag; j++)
|
||||
{
|
||||
pExt = pEdid + sizeof(EDIDV1STRUC) * j;
|
||||
|
||||
// check for 861 extension
|
||||
switch (*pExt)
|
||||
{
|
||||
case NVT_EDID_EXTENSION_CTA:
|
||||
ctaDTD_Offset = ((EIA861EXTENSION *)pExt)->offset;
|
||||
// first sanity check on the extension block
|
||||
if (get861ExtInfo(pExt, sizeof(EIA861EXTENSION), NULL) != NVT_STATUS_SUCCESS ||
|
||||
((EIA861EXTENSION *)pExt)->revision < NVT_CEA861_REV_B)
|
||||
{
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_EXT_CTA_BASIC);
|
||||
}
|
||||
|
||||
// 0 indicated there is no DTD and data collection in this block
|
||||
if (ctaDTD_Offset == 0)
|
||||
{
|
||||
if(!isChecksumValid(pExt))
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_EXT_CTA_CHECKSUM);
|
||||
continue;
|
||||
}
|
||||
|
||||
// validate SVD block
|
||||
ctaBlockTag = NVT_CEA861_GET_SHORT_DESCRIPTOR_TAG(((EIA861EXTENSION *)pExt)->data[0]);
|
||||
pData_collection = ((EIA861EXTENSION *)pExt)->data;
|
||||
|
||||
while ((ctaDTD_Offset - 4) > 0 && pData_collection != &pExt[ctaDTD_Offset] &&
|
||||
ctaBlockTag > NVT_CEA861_TAG_RSVD && ctaBlockTag <= NVT_CEA861_TAG_EXTENDED_FLAG)
|
||||
{
|
||||
ctaBlockTag = NVT_CEA861_GET_SHORT_DESCRIPTOR_TAG(*pData_collection);
|
||||
ctaPayload = NVT_CEA861_GET_SHORT_DESCRIPTOR_SIZE(*pData_collection);
|
||||
|
||||
if (parseCta861DataBlockInfo(pData_collection, (NvU32)ctaDTD_Offset - 4, NULL) == NVT_STATUS_SUCCESS)
|
||||
{
|
||||
pData_collection++;
|
||||
if (ctaBlockTag == NVT_CEA861_TAG_VIDEO)
|
||||
{
|
||||
for (i=0; i < ctaPayload; i++)
|
||||
{
|
||||
vic = NVT_GET_CTA_8BIT_VIC(*pData_collection);
|
||||
if (vic == 0 || vic > 255 || (vic >= 128 && vic <=192))
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_EXT_CTA_SVD);
|
||||
pData_collection++;
|
||||
}
|
||||
}
|
||||
else if (ctaBlockTag == NVT_CEA861_TAG_EXTENDED_FLAG)
|
||||
{
|
||||
if (*pData_collection == NVT_CEA861_EXT_TAG_HF_EEODB)
|
||||
{
|
||||
if ((p->bVersionNumber != 0x01) || (p->bRevisionNumber != 0x03))
|
||||
{
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_EXT_CTA_INVALID_DATA_BLOCK);
|
||||
pData_collection += ctaPayload;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret &= ~NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_EXTENSION_COUNT);
|
||||
extnCount = *(++pData_collection);
|
||||
// check the EDID extension count value again because EDID extension block count
|
||||
// value in EEODB override it and source shall ignore extension flag > 1 value
|
||||
if ((extnCount + 1) != (length / (sizeof(EDIDV1STRUC))))
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_EXTENSION_COUNT);
|
||||
pData_collection++;
|
||||
}
|
||||
}
|
||||
else
|
||||
pData_collection += ctaPayload;
|
||||
}
|
||||
else if (ctaBlockTag == NVT_CEA861_TAG_RSVD || ctaBlockTag == NVT_CEA861_TAG_RSVD1)
|
||||
{
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_EXT_CTA_TAG);
|
||||
pData_collection += ctaPayload;
|
||||
}
|
||||
else
|
||||
pData_collection += ctaPayload;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_EXT_CTA_INVALID_DATA_BLOCK);
|
||||
pData_collection += ctaPayload;
|
||||
}
|
||||
}
|
||||
|
||||
// validate DTD blocks
|
||||
pDTD = (DETAILEDTIMINGDESCRIPTOR *)&pExt[((EIA861EXTENSION *)pExt)->offset];
|
||||
while (pDTD->wDTPixelClock != 0 && (NvU8 *)pDTD - pExt < (int)sizeof(EIA861EXTENSION))
|
||||
{
|
||||
if (parseEdidDetailedTimingDescriptor((NvU8 *)pDTD, NULL) != NVT_STATUS_SUCCESS)
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_EXT_DTD);
|
||||
else
|
||||
{
|
||||
// check the max image size and
|
||||
if (p->bMaxHorizImageSize != 0 && p->bMaxVertImageSize != 0)
|
||||
{
|
||||
NvU16 hDTDImageSize = (pDTD->bDTHorizVertImage & 0xF0) << 4 | pDTD->bDTHorizontalImage;
|
||||
NvU16 vDTDImageSize = (pDTD->bDTHorizVertImage & 0x0F) << 8 | pDTD->bDTVerticalImage;
|
||||
|
||||
if ((hDTDImageSize/10) > (p->bMaxHorizImageSize) || (vDTDImageSize/10) > p->bMaxVertImageSize)
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_EXT_CTA_DTD);
|
||||
}
|
||||
}
|
||||
pDTD++;
|
||||
}
|
||||
|
||||
if(!isChecksumValid(pExt))
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_EXT_CTA_CHECKSUM);
|
||||
break;
|
||||
case NVT_EDID_EXTENSION_DISPLAYID:
|
||||
pDisplayid = ((DIDEXTENSION *)pExt);
|
||||
if (pDisplayid->ext_count != 0)
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_EXT_DID_EXTCOUNT);
|
||||
|
||||
if (pDisplayid->length != 0x79)
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_EXT_DID_SEC_SIZE);
|
||||
|
||||
if (!isChecksumValid(pExt))
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_EXT_DID_CHECKSUM);
|
||||
|
||||
// check the DID2 data blocks
|
||||
if ((pDisplayid->struct_version & 0xF0) >> 4 == 2)
|
||||
{
|
||||
if ((pDisplayid->struct_version & 0xFF) == 0x21)
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_EXT_DID_VERSION);
|
||||
|
||||
did2ExtCount++;
|
||||
|
||||
if (pDisplayid->use_case == 0 && did2ExtCount == 1)
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_EXT_DID2_USE_CASE);
|
||||
|
||||
// check the DisplayId2 valid timing
|
||||
pDID2Header = (DISPLAYID_2_0_DATA_BLOCK_HEADER*)pDisplayid->data;
|
||||
pData_collection = pDisplayid->data;
|
||||
|
||||
// Sanity check every data blocks
|
||||
while (((pDID2Header->type >= DISPLAYID_2_0_BLOCK_TYPE_PRODUCT_IDENTITY &&
|
||||
pDID2Header->type <= DISPLAYID_2_0_BLOCK_TYPE_ARVR_LAYER) ||
|
||||
pDID2Header->type == DISPLAYID_2_0_BLOCK_TYPE_VENDOR_SPEC ||
|
||||
pDID2Header->type == DISPLAYID_2_0_BLOCK_TYPE_CTA_DATA) && pDID2Header->data_bytes != 0 &&
|
||||
(pData_collection - pExt < (int)sizeof(DIDEXTENSION)))
|
||||
{
|
||||
if (parseDisplayId20EDIDExtDataBlocks(pData_collection, did_section_length, &block_length, NULL) == NVT_STATUS_ERR)
|
||||
{
|
||||
if (pDID2Header->type == DISPLAYID_2_0_BLOCK_TYPE_TIMING_7)
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_EXT_DID2_TYPE7);
|
||||
|
||||
if (pDID2Header->type == DISPLAYID_2_0_BLOCK_TYPE_RANGE_LIMITS)
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_EXT_RANGE_LIMIT);
|
||||
|
||||
if (pDID2Header->type == DISPLAYID_2_0_BLOCK_TYPE_ADAPTIVE_SYNC)
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_EXT_DID2_ADAPTIVE_SYNC);
|
||||
// add more data blocks tag here to evaluate
|
||||
}
|
||||
pData_collection += block_length;
|
||||
pDID2Header = (DISPLAYID_2_0_DATA_BLOCK_HEADER*)pData_collection;
|
||||
}
|
||||
|
||||
// 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++)
|
||||
{
|
||||
if (pData_collection[i] != 0)
|
||||
{
|
||||
bAllZero = NV_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if the first tag failed, ignore all the tags afterward then
|
||||
if (!bAllZero &&
|
||||
(pDID2Header->type < DISPLAYID_2_0_BLOCK_TYPE_PRODUCT_IDENTITY ||
|
||||
(pDID2Header->type > DISPLAYID_2_0_BLOCK_TYPE_ARVR_LAYER &&
|
||||
pDID2Header->type != DISPLAYID_2_0_BLOCK_TYPE_VENDOR_SPEC &&
|
||||
pDID2Header->type != DISPLAYID_2_0_BLOCK_TYPE_CTA_DATA)) &&
|
||||
(pData_collection - pExt < (int)sizeof(DIDEXTENSION)))
|
||||
{
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_EXT_DID2_TAG);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if ((pDisplayid->struct_version & 0xFF) == 0x12 || (pDisplayid->struct_version & 0xFF) == 0x13)
|
||||
{
|
||||
if ((pDisplayid->struct_version & 0xFF) == 0x13)
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_EXT_DID_VERSION);
|
||||
|
||||
pHeader = (DISPLAYID_DATA_BLOCK_HEADER*)pDisplayid->data;
|
||||
pData_collection = pDisplayid->data;
|
||||
|
||||
// Sanity check every data blocks
|
||||
while ((pHeader->type <= NVT_DISPLAYID_BLOCK_TYPE_TILEDDISPLAY ||
|
||||
pHeader->type == NVT_DISPLAYID_BLOCK_TYPE_CTA_DATA ||
|
||||
pHeader->type == NVT_DISPLAYID_BLOCK_TYPE_VENDOR_SPEC) && pHeader->data_bytes != 0 &&
|
||||
(pData_collection - pExt < (int)sizeof(DIDEXTENSION)))
|
||||
{
|
||||
if (parseDisplayIdBlock(pData_collection, did_section_length, &block_length, NULL) == NVT_STATUS_ERR)
|
||||
{
|
||||
if (pHeader->type == NVT_DISPLAYID_BLOCK_TYPE_TIMING_1)
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_EXT_DID13_TYPE1);
|
||||
|
||||
if (pHeader->type == NVT_DISPLAYID_BLOCK_TYPE_RANGE_LIMITS)
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_EXT_RANGE_LIMIT);
|
||||
|
||||
// add more data blocks tag here to evaluate
|
||||
}
|
||||
pData_collection += block_length;
|
||||
pHeader = (DISPLAYID_DATA_BLOCK_HEADER*)pData_collection;
|
||||
}
|
||||
|
||||
// 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++)
|
||||
{
|
||||
if (pData_collection[i] != 0)
|
||||
{
|
||||
bAllZero = NV_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if the first tag failed, ignore all the tags afterward then
|
||||
if (!bAllZero &&
|
||||
pHeader->type > NVT_DISPLAYID_BLOCK_TYPE_TILEDDISPLAY &&
|
||||
pHeader->type != NVT_DISPLAYID_BLOCK_TYPE_CTA_DATA &&
|
||||
pHeader->type != NVT_DISPLAYID_BLOCK_TYPE_VENDOR_SPEC &&
|
||||
(pData_collection - pExt < (int)sizeof(DIDEXTENSION)))
|
||||
{
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_EXT_DID13_TAG);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_EXT_DID_VERSION);
|
||||
break;
|
||||
default:
|
||||
// the useful extension only CTA (0x02) and DisplayID (0x70)
|
||||
if ( *pExt != NVT_EDID_EXTENSION_VTB && *pExt != NVT_EDID_EXTENSION_DI &&
|
||||
*pExt != NVT_EDID_EXTENSION_LS && *pExt != NVT_EDID_EXTENSION_DPVL &&
|
||||
*pExt != NVT_EDID_EXTENSION_BM && *pExt != NVT_EDID_EXTENSION_OEM )
|
||||
{
|
||||
ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_EXTENSION_TAG);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -2335,6 +2708,8 @@ CODE_SEGMENT(PAGE_DD_CODE)
|
||||
NvBool assignNextAvailableTiming(NVT_EDID_INFO *pInfo,
|
||||
const NVT_TIMING *pTiming)
|
||||
{
|
||||
if (pInfo == NULL) return NV_TRUE;
|
||||
|
||||
// Don't write past the end of
|
||||
// pInfo->timing[NVT_EDID_MAX_TOTAL_TIMING]
|
||||
if (pInfo->total_timings >= COUNT(pInfo->timing)) {
|
||||
@@ -2386,7 +2761,7 @@ NvU32 NvTiming_CalculateEDIDCRC32(NvU8* pEDIDBuffer, NvU32 edidsize)
|
||||
return calculateCRC32(pEDIDBuffer, edidsize);
|
||||
}
|
||||
|
||||
//Calculates EDID's CRC after purging 'Week of Manufacture', 'Year of Manufacture',
|
||||
//Calculates EDID/DisplayID2 CRC after purging 'Week of Manufacture', 'Year of Manufacture',
|
||||
//'Product ID String' & 'Serial Number' from EDID
|
||||
CODE_SEGMENT(PAGE_DD_CODE)
|
||||
NvU32 NvTiming_CalculateCommonEDIDCRC32(NvU8* pEDIDBuffer, NvU32 edidVersion)
|
||||
@@ -2403,30 +2778,64 @@ NvU32 NvTiming_CalculateCommonEDIDCRC32(NvU8* pEDIDBuffer, NvU32 edidVersion)
|
||||
// Transfer over the original EDID buffer
|
||||
NVMISC_MEMCPY(CommonEDIDBuffer, pEDIDBuffer, 256);
|
||||
|
||||
// Wipe out the Serial Number, Week of Manufacture, and Year of Manufacture or Model Year
|
||||
NVMISC_MEMSET(CommonEDIDBuffer + 0x0C, 0, 6);
|
||||
|
||||
// Wipe out the checksums
|
||||
CommonEDIDBuffer[0x7F] = 0;
|
||||
CommonEDIDBuffer[0xFF] = 0;
|
||||
|
||||
// We also need to zero out any "EDID Other Monitor Descriptors" (https://en.wikipedia.org/wiki/Extended_display_identification_data)
|
||||
for (edidBufferIndex = 54; edidBufferIndex <= 108; edidBufferIndex += 18)
|
||||
if ((pEDIDBuffer[0] & 0xF0) == 0x20)
|
||||
{
|
||||
if (CommonEDIDBuffer[edidBufferIndex] == 0 && CommonEDIDBuffer[edidBufferIndex+1] == 0)
|
||||
/*
|
||||
typedef struct DisplayId2Struct
|
||||
{
|
||||
// Wipe this block out. It contains OEM-specific details that contain things like serial numbers
|
||||
NVMISC_MEMSET(CommonEDIDBuffer + edidBufferIndex, 0, 18);
|
||||
}
|
||||
}
|
||||
NvU8 bVersion; // 0x00
|
||||
NvU8 bSectionBytes; // 0x01 - section length, exclusive the five mandatory bytes.
|
||||
NvU8 bwPrimaryUseCase; // 0x02
|
||||
NvU8 bExtensionCount; // 0x03
|
||||
// 0x20 DisplayId2 Standalone always exists Product Identification data block
|
||||
NvU8 bProductIdtag; // 0x04
|
||||
NvU8 bPIDRevision; // 0x05
|
||||
NvU8 bPayloadByte; // 0x06
|
||||
NvU8 bManuId[3]; // 0x07-0x09
|
||||
NvU16 wProductId; // 0x0A-0x0B
|
||||
NvU32 dwSerialNum; // 0x0C-0x0F
|
||||
NvU16 wWeekandYear; // 0x10-0x11
|
||||
NvU8 SizeOfProductNameString; // 0x12
|
||||
} DISPLAY_ID2_FIXED_FORMAT;
|
||||
*/
|
||||
|
||||
// Check what size we should do the compare against
|
||||
if ( edidVersion > NVT_EDID_VER_1_4 )
|
||||
{
|
||||
// Wipe out the Serial Number, Week of Manufacture, and Year of Manufacture or Model Year
|
||||
NVMISC_MEMSET(CommonEDIDBuffer + 0x0C, 0, 6);
|
||||
|
||||
// Wipe out the checksums
|
||||
CommonEDIDBuffer[CommonEDIDBuffer[1]+5/*mandatory bytes*/-1] = 0;
|
||||
CommonEDIDBuffer[0xFF] = 0;
|
||||
|
||||
// zero out any Produc Name in Prodcut Identification data block
|
||||
if (CommonEDIDBuffer[0x12] != 0)
|
||||
{
|
||||
NVMISC_MEMSET(CommonEDIDBuffer + 0x13, 0, CommonEDIDBuffer[0x12]);
|
||||
CommonEDIDBuffer[0x12] = 0;
|
||||
}
|
||||
|
||||
// displayId2 standalone uses 256 length sections
|
||||
commonEDIDBufferSize = 256;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
// Wipe out the Serial Number, Week of Manufacture, and Year of Manufacture or Model Year
|
||||
NVMISC_MEMSET(CommonEDIDBuffer + 0x0C, 0, 6);
|
||||
|
||||
// Wipe out the checksums
|
||||
CommonEDIDBuffer[0x7F] = 0;
|
||||
CommonEDIDBuffer[0xFF] = 0;
|
||||
|
||||
// We also need to zero out any "EDID Other Monitor Descriptors" (http://en.wikipedia.org/wiki/Extended_display_identification_data)
|
||||
for (edidBufferIndex = 54; edidBufferIndex <= 108; edidBufferIndex += 18)
|
||||
{
|
||||
if (CommonEDIDBuffer[edidBufferIndex] == 0 && CommonEDIDBuffer[edidBufferIndex+1] == 0)
|
||||
{
|
||||
// Wipe this block out. It contains OEM-specific details that contain things like serial numbers
|
||||
NVMISC_MEMSET(CommonEDIDBuffer + edidBufferIndex, 0, 18);
|
||||
}
|
||||
}
|
||||
|
||||
// Check what size we should do the compare against
|
||||
commonEDIDBufferSize = 128;
|
||||
}
|
||||
|
||||
|
||||
@@ -880,7 +880,7 @@ void parseCea861HdrStaticMetadataDataBlock(NVT_EDID_CEA861_INFO *pExt861,
|
||||
}
|
||||
|
||||
CODE_SEGMENT(PAGE_DD_CODE)
|
||||
void parseCea861DvStaticMetadataDataBlock(NVT_EDID_CEA861_INFO *pExt861, NVT_DV_STATIC_METADATA *pDvInfo)
|
||||
void parseCea861DvStaticMetadataDataBlock(NVT_EDID_CEA861_INFO *pExt861, void *pRawInfo, NVT_CTA861_ORIGIN flag)
|
||||
{
|
||||
NvU32 vsvdbVersion = 0;
|
||||
NVT_DV_STATIC_METADATA_TYPE0 *pDvType0 = NULL;
|
||||
@@ -888,7 +888,26 @@ void parseCea861DvStaticMetadataDataBlock(NVT_EDID_CEA861_INFO *pExt861, NVT_DV_
|
||||
NVT_DV_STATIC_METADATA_TYPE1_1 *pvDvType1_1 = NULL;
|
||||
NVT_DV_STATIC_METADATA_TYPE2 *pDvType2 = NULL;
|
||||
|
||||
if (pExt861 == NULL || pDvInfo == NULL)
|
||||
NVT_EDID_INFO *pInfo = NULL;
|
||||
NVT_DISPLAYID_2_0_INFO *pDisplayID20 = NULL;
|
||||
NVT_DV_STATIC_METADATA *pDvInfo = NULL;
|
||||
|
||||
if (pExt861 == NULL || pRawInfo == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (flag == FROM_CTA861_EXTENSION || flag == FROM_DISPLAYID_13_DATA_BLOCK)
|
||||
{
|
||||
pInfo = (NVT_EDID_INFO *)pRawInfo;
|
||||
pDvInfo = &pInfo->dv_static_metadata_info;
|
||||
}
|
||||
else if (flag == FROM_DISPLAYID_20_DATA_BLOCK)
|
||||
{
|
||||
pDisplayID20 = (NVT_DISPLAYID_2_0_INFO *)pRawInfo;
|
||||
pDvInfo = &pDisplayID20->cta.dvInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -898,6 +917,7 @@ void parseCea861DvStaticMetadataDataBlock(NVT_EDID_CEA861_INFO *pExt861, NVT_DV_
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//init
|
||||
NVMISC_MEMSET(pDvInfo, 0, sizeof(NVT_DV_STATIC_METADATA));
|
||||
|
||||
@@ -1004,10 +1024,10 @@ void parseCea861DvStaticMetadataDataBlock(NVT_EDID_CEA861_INFO *pExt861, NVT_DV_
|
||||
pDvInfo->supports_backlight_control = pDvType2->supports_backlight_control;
|
||||
pDvInfo->supports_YUV422_12bit = pDvType2->supports_YUV422_12bit;
|
||||
pDvInfo->dm_version = pDvType2->dm_version;
|
||||
pDvInfo->backlt_min_luma = pDvType2->backlt_min_luma;
|
||||
pDvInfo->supports_global_dimming = pDvType2->supports_global_dimming;
|
||||
pDvInfo->target_min_luminance = pDvType2->target_min_luminance;
|
||||
pDvInfo->interface_supported_by_sink = pDvType2->interface_supported_by_sink;
|
||||
pDvInfo->parity = pDvType2->parity;
|
||||
pDvInfo->target_max_luminance = pDvType2->target_max_luminance;
|
||||
pDvInfo->cc_green_x = NVT_DOLBY_CHROMATICITY_MSB_GX | pDvType2->unique_Gx;
|
||||
pDvInfo->cc_green_y = NVT_DOLBY_CHROMATICITY_MSB_GY | pDvType2->unique_Gy;
|
||||
@@ -1213,8 +1233,13 @@ NVT_STATUS get861ExtInfo(NvU8 *p, NvU32 size, NVT_EDID_CEA861_INFO *p861info)
|
||||
return NVT_STATUS_ERR;
|
||||
}
|
||||
|
||||
// DTD offset sanity check
|
||||
if (p[2] >= 1 && p[2] <= 3)
|
||||
{
|
||||
return NVT_STATUS_ERR;
|
||||
}
|
||||
|
||||
// don't do anything further if p is NULL
|
||||
// don't do anything further if p861info is NULL
|
||||
if (p861info == NULL)
|
||||
{
|
||||
return NVT_STATUS_SUCCESS;
|
||||
@@ -1251,7 +1276,8 @@ NVT_STATUS get861ExtInfo(NvU8 *p, NvU32 size, NVT_EDID_CEA861_INFO *p861info)
|
||||
return parseCta861DataBlockInfo(&p[4], dtd_offset - 4, p861info);
|
||||
}
|
||||
|
||||
// get the 861 extension tags info
|
||||
// 1. get the 861 extension tags info
|
||||
// 2. or validation purpose if p861info == NULL
|
||||
CODE_SEGMENT(PAGE_DD_CODE)
|
||||
NVT_STATUS parseCta861DataBlockInfo(NvU8 *p,
|
||||
NvU32 size,
|
||||
@@ -1265,6 +1291,7 @@ NVT_STATUS parseCta861DataBlockInfo(NvU8 *p,
|
||||
NvU32 yuv420vdb_index = 0;
|
||||
NvU32 yuv420cmdb_index = 0;
|
||||
NvU8 svr_index = 0;
|
||||
NvU32 ieee_id = 0;
|
||||
NvU32 tag, ext_tag, payload;
|
||||
i= 0;
|
||||
|
||||
@@ -1276,6 +1303,42 @@ NVT_STATUS parseCta861DataBlockInfo(NvU8 *p,
|
||||
|
||||
// move the pointer to the payload section
|
||||
i++;
|
||||
|
||||
// NvTiming_EDIDValidationMask will use the different tag/payload value to make sure each of cta861 data block legal
|
||||
if (p861info == NULL)
|
||||
{
|
||||
switch(tag)
|
||||
{
|
||||
case NVT_CEA861_TAG_AUDIO:
|
||||
case NVT_CEA861_TAG_VIDEO:
|
||||
case NVT_CEA861_TAG_SPEAKER_ALLOC:
|
||||
case NVT_CEA861_TAG_VESA_DTC:
|
||||
case NVT_CEA861_TAG_RSVD:
|
||||
case NVT_CEA861_TAG_RSVD1:
|
||||
break;
|
||||
case NVT_CEA861_TAG_VENDOR:
|
||||
if (payload < 3) return NVT_STATUS_ERR;
|
||||
break;
|
||||
case NVT_CEA861_TAG_EXTENDED_FLAG:
|
||||
if (payload >= 1)
|
||||
{
|
||||
ext_tag = p[i];
|
||||
if (ext_tag == NVT_CEA861_EXT_TAG_VIDEO_CAP && payload < 2) return NVT_STATUS_ERR;
|
||||
else if (ext_tag == NVT_CEA861_EXT_TAG_COLORIMETRY && payload < 3) return NVT_STATUS_ERR;
|
||||
else if (ext_tag == NVT_CEA861_EXT_TAG_VIDEO_FORMAT_PREFERENCE && payload < 2) return NVT_STATUS_ERR;
|
||||
else if (ext_tag == NVT_CEA861_EXT_TAG_YCBCR420_VIDEO && payload < 2) return NVT_STATUS_ERR;
|
||||
else if (ext_tag == NVT_CEA861_EXT_TAG_YCBCR420_CAP && payload < 1) return NVT_STATUS_ERR;
|
||||
else if (ext_tag == NVT_CEA861_EXT_TAG_HDR_STATIC_METADATA && payload < 3) return NVT_STATUS_ERR;
|
||||
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;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return NVT_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// loop through all descriptors
|
||||
if (tag == NVT_CEA861_TAG_VIDEO)
|
||||
@@ -1447,30 +1510,46 @@ NVT_STATUS parseCta861DataBlockInfo(NvU8 *p,
|
||||
|
||||
p861info->valid.hdr_static_metadata = 1;
|
||||
}
|
||||
else if(ext_tag == NVT_CEA861_EXT_TAG_VENDOR_SPECIFIC_VIDEO && ((payload >= 14) || (payload >= 11))) //version 2 of VSDB has 11 bytes of data and version 1 has 14
|
||||
else if(ext_tag == NVT_CEA861_EXT_TAG_VENDOR_SPECIFIC_VIDEO)
|
||||
{
|
||||
ieee_id = p[i + 1]; //IEEE ID low byte
|
||||
ieee_id |= (p[i + 2]) << 8; //IEEE ID middle byte
|
||||
ieee_id |= (p[i + 3]) << 16; //IEEE ID high byte
|
||||
|
||||
// exclude the extended tag
|
||||
i++; payload--;
|
||||
|
||||
p861info->vsvdb.ieee_id = p[i]; //IEEE ID low byte
|
||||
p861info->vsvdb.ieee_id |= (p[i + 1]) << 8; //IEEE ID middle byte
|
||||
p861info->vsvdb.ieee_id |= (p[i + 2]) << 16; //IEEE ID high byte
|
||||
|
||||
p861info->vsvdb.vendor_data_size = payload - 3;
|
||||
|
||||
// move the pointer to the payload
|
||||
i += 3;
|
||||
|
||||
// get the other vendor specific video data
|
||||
for (j = 0; j < payload - 3; j++, i++)
|
||||
if ((ieee_id == NVT_CEA861_DV_IEEE_ID) || (ieee_id == NVT_CEA861_HDR10PLUS_IEEE_ID))
|
||||
{
|
||||
if (j < NVT_CEA861_VSDB_PAYLOAD_MAX_LENGTH)
|
||||
// exclude the extended tag
|
||||
i++; payload--;
|
||||
|
||||
p861info->vsvdb.ieee_id = ieee_id;
|
||||
p861info->vsvdb.vendor_data_size = payload - 3;
|
||||
|
||||
// move the pointer to the payload
|
||||
i += 3;
|
||||
|
||||
// get the other vendor specific video data
|
||||
for (j = 0; j < payload - 3; j++, i++)
|
||||
{
|
||||
p861info->vsvdb.vendor_data[j] = p[i];
|
||||
if (j < NVT_CEA861_VSVDB_PAYLOAD_MAX_LENGTH)
|
||||
{
|
||||
p861info->vsvdb.vendor_data[j] = p[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (p861info->vsvdb.ieee_id == NVT_CEA861_DV_IEEE_ID)
|
||||
{
|
||||
p861info->valid.dv_static_metadata = 1;
|
||||
}
|
||||
else if (p861info->vsvdb.ieee_id == NVT_CEA861_HDR10PLUS_IEEE_ID)
|
||||
{
|
||||
p861info->valid.hdr10Plus = 1;
|
||||
}
|
||||
}
|
||||
p861info->valid.dv_static_metadata = 1;
|
||||
else
|
||||
{
|
||||
// skip the unsupported extended block
|
||||
i += payload;
|
||||
}
|
||||
}
|
||||
else if(ext_tag == NVT_CTA861_EXT_TAG_SCDB && payload >= 7) // sizeof(HDMI Forum Sink Capability Data Block) ranges between 7 to 31 bytes
|
||||
{
|
||||
@@ -1528,6 +1607,9 @@ NVT_STATUS NvTiming_EnumCEA861bTiming(NvU32 ceaFormat, NVT_TIMING *pT)
|
||||
|
||||
ceaFormat = NVT_GET_CTA_8BIT_VIC(ceaFormat);
|
||||
|
||||
if (ceaFormat ==0)
|
||||
return NVT_STATUS_ERR;
|
||||
|
||||
*pT = EIA861B[ceaFormat - 1];
|
||||
|
||||
// calculate the pixel clock
|
||||
@@ -2935,8 +3017,49 @@ void parseEdidHdmiForumVSDB(VSDB_DATA *pVsdb, NVT_HDMI_FORUM_INFO *pHdmiInfo)
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
CODE_SEGMENT(PAGE_DD_CODE)
|
||||
void parseCea861Hdr10PlusDataBlock(NVT_EDID_CEA861_INFO *pExt861, void *pRawInfo, NVT_CTA861_ORIGIN flag)
|
||||
{
|
||||
NVT_EDID_INFO *pInfo = NULL;
|
||||
NVT_DISPLAYID_2_0_INFO *pDisplayID20 = NULL;
|
||||
NVT_HDR10PLUS_INFO *pHdr10PlusInfo = NULL;
|
||||
|
||||
if (pExt861 == NULL || pRawInfo == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (flag == FROM_CTA861_EXTENSION || flag == FROM_DISPLAYID_13_DATA_BLOCK)
|
||||
{
|
||||
pInfo = (NVT_EDID_INFO *)pRawInfo;
|
||||
pHdr10PlusInfo = &pInfo->hdr10PlusInfo;
|
||||
}
|
||||
else if (flag == FROM_DISPLAYID_20_DATA_BLOCK)
|
||||
{
|
||||
pDisplayID20 = (NVT_DISPLAYID_2_0_INFO *)pRawInfo;
|
||||
pHdr10PlusInfo = &pDisplayID20->cta.hdr10PlusInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(pExt861->vsvdb.ieee_id != NVT_CEA861_HDR10PLUS_IEEE_ID)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NVMISC_MEMSET(pHdr10PlusInfo, 0, sizeof(NVT_HDR10PLUS_INFO));
|
||||
|
||||
if (pExt861->vsvdb.vendor_data_size < sizeof(NVT_HDR10PLUS_INFO))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NVMISC_MEMCPY(pHdr10PlusInfo, &pExt861->vsvdb.vendor_data, sizeof(NVT_HDR10PLUS_INFO));
|
||||
}
|
||||
|
||||
POP_SEGMENTS
|
||||
|
||||
@@ -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
|
||||
@@ -30,7 +30,6 @@
|
||||
#include "nvBinSegment.h"
|
||||
#include "nvmisc.h"
|
||||
|
||||
#include "displayid.h"
|
||||
#include "edid.h"
|
||||
|
||||
PUSH_SEGMENTS
|
||||
@@ -38,10 +37,6 @@ PUSH_SEGMENTS
|
||||
static NVT_STATUS parseDisplayIdSection(DISPLAYID_SECTION * section,
|
||||
NvU32 max_length,
|
||||
NVT_EDID_INFO *pEdidInfo);
|
||||
static NVT_STATUS parseDisplayIdBlock(NvU8 * block,
|
||||
NvU8 max_length,
|
||||
NvU8 * pLength,
|
||||
NVT_EDID_INFO *pEdidInfo);
|
||||
|
||||
// Specific blocks that can be parsed based on DisplayID
|
||||
static NVT_STATUS parseDisplayIdProdIdentityBlock(NvU8 * block, NVT_DISPLAYID_INFO *pInfo);
|
||||
@@ -51,7 +46,7 @@ static NVT_STATUS parseDisplayIdTiming1(NvU8 * block, NVT_EDID_INFO *pEdidInfo);
|
||||
static NVT_STATUS parseDisplayIdTiming2(NvU8 * block, NVT_EDID_INFO *pEdidInfo);
|
||||
static NVT_STATUS parseDisplayIdTiming3(NvU8 * block, NVT_EDID_INFO *pEdidInfo);
|
||||
static NVT_STATUS parseDisplayIdTiming4(NvU8 * block, NVT_EDID_INFO *pEdidInfo);
|
||||
static NVT_STATUS parseDisplayIdTiming5(NvU8 * block, NVT_EDID_INFO *pEdidInfo, NVT_DISPLAYID_INFO *pInfo);
|
||||
static NVT_STATUS parseDisplayIdTiming5(NvU8 * block, NVT_EDID_INFO *pEdidInfo);
|
||||
static NVT_STATUS parseDisplayIdTimingVesa(NvU8 * block, NVT_EDID_INFO *pEdidInfo);
|
||||
static NVT_STATUS parseDisplayIdTimingEIA(NvU8 * block, NVT_EDID_INFO *pEdidInfo);
|
||||
static NVT_STATUS parseDisplayIdRangeLimits(NvU8 * block, NVT_DISPLAYID_INFO *pInfo);
|
||||
@@ -63,7 +58,7 @@ static NVT_STATUS parseDisplayIdTransferChar(NvU8 * block, NVT_DISPLAYID_INFO *p
|
||||
static NVT_STATUS parseDisplayIdDisplayInterface(NvU8 * block, NVT_DISPLAYID_INFO *pInfo);
|
||||
static NVT_STATUS parseDisplayIdStereo(NvU8 * block, NVT_DISPLAYID_INFO *pInfo);
|
||||
static NVT_STATUS parseDisplayIdTiledDisplay(NvU8 * block, NVT_DISPLAYID_INFO *pInfo);
|
||||
static NVT_STATUS parseDisplayIdCtaData(NvU8 * block, NVT_EDID_INFO *pInfo, NVT_DISPLAYID_INFO *pDisplayIdInfo);
|
||||
static NVT_STATUS parseDisplayIdCtaData(NvU8 * block, NVT_EDID_INFO *pInfo);
|
||||
static NVT_STATUS parseDisplayIdDisplayInterfaceFeatures(NvU8 * block, NVT_DISPLAYID_INFO *pInfo);
|
||||
|
||||
static NVT_STATUS parseDisplayIdTiming1Descriptor(DISPLAYID_TIMING_1_DESCRIPTOR * desc, NVT_TIMING *pT);
|
||||
@@ -232,7 +227,7 @@ static NVT_STATUS parseDisplayIdSection(DISPLAYID_SECTION * section,
|
||||
while (block_location < section->section_bytes)
|
||||
{
|
||||
DISPLAYID_DATA_BLOCK_HEADER * hdr = (DISPLAYID_DATA_BLOCK_HEADER *) (section->data + block_location);
|
||||
NvU8 is_prod_id = remaining_length > 3 && block_location == 0 && hdr->type == 0 && hdr->data_bytes > 0;
|
||||
NvBool is_prod_id = remaining_length > 3 && block_location == 0 && hdr->type == 0 && hdr->data_bytes > 0;
|
||||
NvU8 i;
|
||||
|
||||
// Check the padding.
|
||||
@@ -265,90 +260,106 @@ static NVT_STATUS parseDisplayIdSection(DISPLAYID_SECTION * section,
|
||||
return NVT_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parses a displayID data block
|
||||
* @param block The DisplayID data block to parse
|
||||
* @param max_length The indicated total length of the each data block for checking
|
||||
* @param pLength return the indicated length of the each data block
|
||||
* @param pEdidInfo EDID struct containing DisplayID information and
|
||||
* the timings or validation purpose if it is NULL
|
||||
*/
|
||||
CODE_SEGMENT(PAGE_DD_CODE)
|
||||
static NVT_STATUS parseDisplayIdBlock(NvU8 * block,
|
||||
NvU8 max_length,
|
||||
NvU8 * pLength,
|
||||
NVT_EDID_INFO *pEdidInfo)
|
||||
NVT_STATUS parseDisplayIdBlock(NvU8* pBlock,
|
||||
NvU8 max_length,
|
||||
NvU8* pLength,
|
||||
NVT_EDID_INFO *pEdidInfo)
|
||||
{
|
||||
DISPLAYID_DATA_BLOCK_HEADER * hdr = (DISPLAYID_DATA_BLOCK_HEADER *) block;
|
||||
NVT_DISPLAYID_INFO *pInfo = &pEdidInfo->ext_displayid;
|
||||
DISPLAYID_DATA_BLOCK_HEADER * hdr = (DISPLAYID_DATA_BLOCK_HEADER *) pBlock;
|
||||
NVT_STATUS ret = NVT_STATUS_SUCCESS;
|
||||
NVT_DISPLAYID_INFO *pInfo;
|
||||
|
||||
if (block == NULL || max_length <= NVT_DISPLAYID_DATABLOCK_HEADER_LEN)
|
||||
if (pBlock == NULL || max_length <= NVT_DISPLAYID_DATABLOCK_HEADER_LEN)
|
||||
return NVT_STATUS_ERR;
|
||||
|
||||
if (hdr->data_bytes > max_length - NVT_DISPLAYID_DATABLOCK_HEADER_LEN)
|
||||
return NVT_STATUS_ERR;
|
||||
|
||||
pInfo = pEdidInfo == NULL ? NULL : &pEdidInfo->ext_displayid;
|
||||
|
||||
*pLength = hdr->data_bytes + NVT_DISPLAYID_DATABLOCK_HEADER_LEN;
|
||||
|
||||
switch (hdr->type)
|
||||
{
|
||||
case NVT_DISPLAYID_BLOCK_TYPE_PRODUCT_IDENTITY:
|
||||
parseDisplayIdProdIdentityBlock(block, pInfo);
|
||||
ret = parseDisplayIdProdIdentityBlock(pBlock, pInfo);
|
||||
break;
|
||||
case NVT_DISPLAYID_BLOCK_TYPE_DISPLAY_PARAM:
|
||||
parseDisplayIdParam(block, pInfo);
|
||||
ret = parseDisplayIdParam(pBlock, pInfo);
|
||||
break;
|
||||
case NVT_DISPLAYID_BLOCK_TYPE_COLOR_CHAR:
|
||||
parseDisplayIdColorChar(block, pInfo);
|
||||
ret = parseDisplayIdColorChar(pBlock, pInfo);
|
||||
break;
|
||||
case NVT_DISPLAYID_BLOCK_TYPE_TIMING_1:
|
||||
parseDisplayIdTiming1(block, pEdidInfo);
|
||||
ret = parseDisplayIdTiming1(pBlock, pEdidInfo);
|
||||
break;
|
||||
case NVT_DISPLAYID_BLOCK_TYPE_TIMING_2:
|
||||
parseDisplayIdTiming2(block, pEdidInfo);
|
||||
ret = parseDisplayIdTiming2(pBlock, pEdidInfo);
|
||||
break;
|
||||
case NVT_DISPLAYID_BLOCK_TYPE_TIMING_3:
|
||||
parseDisplayIdTiming3(block, pEdidInfo);
|
||||
ret = parseDisplayIdTiming3(pBlock, pEdidInfo);
|
||||
break;
|
||||
case NVT_DISPLAYID_BLOCK_TYPE_TIMING_4:
|
||||
parseDisplayIdTiming4(block, pEdidInfo);
|
||||
ret = parseDisplayIdTiming4(pBlock, pEdidInfo);
|
||||
break;
|
||||
case NVT_DISPLAYID_BLOCK_TYPE_TIMING_5:
|
||||
parseDisplayIdTiming5(block, pEdidInfo, pInfo);
|
||||
ret = parseDisplayIdTiming5(pBlock, pEdidInfo);
|
||||
break;
|
||||
case NVT_DISPLAYID_BLOCK_TYPE_TIMING_VESA:
|
||||
parseDisplayIdTimingVesa(block, pEdidInfo);
|
||||
ret = parseDisplayIdTimingVesa(pBlock, pEdidInfo);
|
||||
break;
|
||||
case NVT_DISPLAYID_BLOCK_TYPE_TIMING_CEA:
|
||||
parseDisplayIdTimingEIA(block, pEdidInfo);
|
||||
ret = parseDisplayIdTimingEIA(pBlock, pEdidInfo);
|
||||
break;
|
||||
case NVT_DISPLAYID_BLOCK_TYPE_RANGE_LIMITS:
|
||||
parseDisplayIdRangeLimits(block, pInfo);
|
||||
ret = parseDisplayIdRangeLimits(pBlock, pInfo);
|
||||
break;
|
||||
case NVT_DISPLAYID_BLOCK_TYPE_SERIAL_NUMBER:
|
||||
parseDisplayIdSerialNumber(block, pInfo);
|
||||
ret = parseDisplayIdSerialNumber(pBlock, pInfo);
|
||||
break;
|
||||
case NVT_DISPLAYID_BLOCK_TYPE_ASCII_STRING:
|
||||
parseDisplayIdAsciiString(block, pInfo);
|
||||
ret = parseDisplayIdAsciiString(pBlock, pInfo);
|
||||
break;
|
||||
case NVT_DISPLAYID_BLOCK_TYPE_DEVICE_DATA:
|
||||
parseDisplayIdDeviceData(block, pInfo);
|
||||
ret = parseDisplayIdDeviceData(pBlock, pInfo);
|
||||
break;
|
||||
case NVT_DISPLAYID_BLOCK_TYPE_INTERFACE_POWER:
|
||||
parseDisplayIdInterfacePower(block, pInfo);
|
||||
ret = parseDisplayIdInterfacePower(pBlock, pInfo);
|
||||
break;
|
||||
case NVT_DISPLAYID_BLOCK_TYPE_TRANSFER_CHAR:
|
||||
parseDisplayIdTransferChar(block, pInfo);
|
||||
ret = parseDisplayIdTransferChar(pBlock, pInfo);
|
||||
break;
|
||||
case NVT_DISPLAYID_BLOCK_TYPE_DISPLAY_INTERFACE:
|
||||
parseDisplayIdDisplayInterface(block, pInfo);
|
||||
ret = parseDisplayIdDisplayInterface(pBlock, pInfo);
|
||||
break;
|
||||
case NVT_DISPLAYID_BLOCK_TYPE_STEREO:
|
||||
parseDisplayIdStereo(block, pInfo);
|
||||
ret = parseDisplayIdStereo(pBlock, pInfo);
|
||||
break;
|
||||
case NVT_DISPLAYID_BLOCK_TYPE_TILEDDISPLAY:
|
||||
parseDisplayIdTiledDisplay(block, pInfo);
|
||||
ret = parseDisplayIdTiledDisplay(pBlock, pInfo);
|
||||
break;
|
||||
case NVT_DISPLAYID_BLOCK_TYPE_CTA_DATA:
|
||||
parseDisplayIdCtaData(block, pEdidInfo, pInfo);
|
||||
ret = parseDisplayIdCtaData(pBlock, pEdidInfo);
|
||||
break;
|
||||
case NVT_DISPLAYID_BLOCK_TYPE_DISPLAY_INTERFACE_FEATURES:
|
||||
parseDisplayIdDisplayInterfaceFeatures(block, pInfo);
|
||||
ret = parseDisplayIdDisplayInterfaceFeatures(pBlock, pInfo);
|
||||
break;
|
||||
default:
|
||||
ret = NVT_STATUS_ERR;
|
||||
break;
|
||||
}
|
||||
|
||||
if (pEdidInfo == NULL) return ret;
|
||||
|
||||
return NVT_STATUS_SUCCESS;
|
||||
}
|
||||
CODE_SEGMENT(PAGE_DD_CODE)
|
||||
@@ -371,6 +382,8 @@ static NVT_STATUS parseDisplayIdColorChar(NvU8 * block, NVT_DISPLAYID_INFO *pInf
|
||||
return NVT_STATUS_ERR;
|
||||
}
|
||||
|
||||
if (pInfo == NULL) return NVT_STATUS_SUCCESS;
|
||||
|
||||
for (i = 0; i < prim_num; i++)
|
||||
{
|
||||
x_p = (blk->points)[i].color_x_bits_low +
|
||||
@@ -408,6 +421,8 @@ static NVT_STATUS parseDisplayIdProdIdentityBlock(NvU8 * block, NVT_DISPLAYID_IN
|
||||
return NVT_STATUS_ERR;
|
||||
}
|
||||
|
||||
if (pInfo == NULL) return NVT_STATUS_SUCCESS;
|
||||
|
||||
pInfo->vendor_id = (blk->vendor)[2] | ((blk->vendor)[1] << 8) | ((blk->vendor)[0] << 16);
|
||||
pInfo->product_id = blk->product_code;
|
||||
pInfo->serial_number = blk->serial_number;
|
||||
@@ -432,6 +447,8 @@ static NVT_STATUS parseDisplayIdParam(NvU8 * block, NVT_DISPLAYID_INFO *pInfo)
|
||||
return NVT_STATUS_ERR;
|
||||
}
|
||||
|
||||
if (pInfo == NULL) return NVT_STATUS_SUCCESS;
|
||||
|
||||
pInfo->horiz_size = blk->horizontal_image_size;
|
||||
pInfo->vert_size = blk->vertical_image_size;
|
||||
pInfo->horiz_pixels = blk->horizontal_pixel_count;
|
||||
@@ -474,11 +491,17 @@ static NVT_STATUS parseDisplayIdTiming1(NvU8 * block, NVT_EDID_INFO *pEdidInfo)
|
||||
if (parseDisplayIdTiming1Descriptor(blk->descriptors + i,
|
||||
&newTiming) == NVT_STATUS_SUCCESS)
|
||||
{
|
||||
if (pEdidInfo == NULL) continue;
|
||||
|
||||
if (!assignNextAvailableTiming(pEdidInfo, &newTiming))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pEdidInfo == NULL) return NVT_STATUS_ERR;
|
||||
}
|
||||
}
|
||||
return NVT_STATUS_SUCCESS;
|
||||
}
|
||||
@@ -610,11 +633,17 @@ static NVT_STATUS parseDisplayIdTiming2(NvU8 * block, NVT_EDID_INFO *pEdidInfo)
|
||||
if (parseDisplayIdTiming2Descriptor(blk->descriptors + i,
|
||||
&newTiming) == NVT_STATUS_SUCCESS)
|
||||
{
|
||||
if (pEdidInfo == NULL) continue;
|
||||
|
||||
if (!assignNextAvailableTiming(pEdidInfo, &newTiming))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pEdidInfo == NULL) return NVT_STATUS_ERR;
|
||||
}
|
||||
}
|
||||
return NVT_STATUS_SUCCESS;
|
||||
}
|
||||
@@ -777,11 +806,17 @@ static NVT_STATUS parseDisplayIdTiming3(NvU8 * block, NVT_EDID_INFO *pEdidInfo)
|
||||
if (parseDisplayIdTiming3Descriptor(blk->descriptors + i,
|
||||
&newTiming) == NVT_STATUS_SUCCESS)
|
||||
{
|
||||
if (pEdidInfo == NULL) continue;
|
||||
|
||||
if (!assignNextAvailableTiming(pEdidInfo, &newTiming))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pEdidInfo == NULL) return NVT_STATUS_ERR;
|
||||
}
|
||||
}
|
||||
return NVT_STATUS_SUCCESS;
|
||||
}
|
||||
@@ -806,11 +841,17 @@ static NVT_STATUS parseDisplayIdTiming4(NvU8 * block, NVT_EDID_INFO *pEdidInfo)
|
||||
if (NvTiming_EnumDMT((NvU32)(blk->timing_codes[i]),
|
||||
&newTiming) == NVT_STATUS_SUCCESS)
|
||||
{
|
||||
if (pEdidInfo == NULL) continue;
|
||||
|
||||
if (!assignNextAvailableTiming(pEdidInfo, &newTiming))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pEdidInfo == NULL) return NVT_STATUS_ERR;
|
||||
}
|
||||
}
|
||||
return NVT_STATUS_SUCCESS;
|
||||
}
|
||||
@@ -837,7 +878,7 @@ static NVT_STATUS parseDisplayIdTiming5Descriptor(DISPLAYID_TIMING_5_DESCRIPTOR
|
||||
}
|
||||
|
||||
CODE_SEGMENT(PAGE_DD_CODE)
|
||||
static NVT_STATUS parseDisplayIdTiming5(NvU8 * block, NVT_EDID_INFO *pEdidInfo, NVT_DISPLAYID_INFO *pInfo)
|
||||
static NVT_STATUS parseDisplayIdTiming5(NvU8 * block, NVT_EDID_INFO *pEdidInfo)
|
||||
{
|
||||
NvU16 i;
|
||||
NVT_TIMING newTiming;
|
||||
@@ -854,11 +895,17 @@ static NVT_STATUS parseDisplayIdTiming5(NvU8 * block, NVT_EDID_INFO *pEdidInfo,
|
||||
|
||||
if (parseDisplayIdTiming5Descriptor(blk->descriptors + i, &newTiming) == NVT_STATUS_SUCCESS)
|
||||
{
|
||||
if (pEdidInfo == NULL) continue;
|
||||
|
||||
if (!assignNextAvailableTiming(pEdidInfo, &newTiming))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pEdidInfo == NULL) return NVT_STATUS_ERR;
|
||||
}
|
||||
}
|
||||
return NVT_STATUS_SUCCESS;
|
||||
}
|
||||
@@ -887,11 +934,17 @@ static NVT_STATUS parseDisplayIdTimingVesa(NvU8 * block, NVT_EDID_INFO *pEdidInf
|
||||
if (NvTiming_EnumDMT((NvU32)(i * 8 + j + 1),
|
||||
&newTiming) == NVT_STATUS_SUCCESS)
|
||||
{
|
||||
if (pEdidInfo == NULL) continue;
|
||||
|
||||
if (!assignNextAvailableTiming(pEdidInfo, &newTiming))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pEdidInfo == NULL) return NVT_STATUS_ERR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -922,11 +975,17 @@ static NVT_STATUS parseDisplayIdTimingEIA(NvU8 * block, NVT_EDID_INFO *pEdidInfo
|
||||
if (NvTiming_EnumCEA861bTiming((NvU32)(i * 8 + j + 1),
|
||||
&newTiming) == NVT_STATUS_SUCCESS)
|
||||
{
|
||||
if (pEdidInfo == NULL) continue;
|
||||
|
||||
if (!assignNextAvailableTiming(pEdidInfo, &newTiming))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pEdidInfo == NULL) return NVT_STATUS_ERR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -938,8 +997,31 @@ static NVT_STATUS parseDisplayIdRangeLimits(NvU8 * block, NVT_DISPLAYID_INFO *pI
|
||||
{
|
||||
NVT_DISPLAYID_RANGE_LIMITS * rl;
|
||||
DISPLAYID_RANGE_LIMITS_BLOCK * blk = (DISPLAYID_RANGE_LIMITS_BLOCK *)block;
|
||||
if ((blk->header.data_bytes != DISPLAYID_RANGE_LIMITS_BLOCK_LEN) ||
|
||||
(pInfo->rl_num >= NVT_DISPLAYID_RANGE_LIMITS_MAX_COUNT))
|
||||
NVT_STATUS status = NVT_STATUS_SUCCESS;
|
||||
NvU32 minPclk = 0;
|
||||
NvU32 maxPclk = 0;
|
||||
|
||||
if (blk->header.data_bytes != DISPLAYID_RANGE_LIMITS_BLOCK_LEN)
|
||||
{
|
||||
// Assert since this error is ignored
|
||||
nvt_assert(0);
|
||||
return NVT_STATUS_ERR;
|
||||
}
|
||||
|
||||
minPclk = blk->pixel_clock_min[0] | (blk->pixel_clock_min[1] << 8) | (blk->pixel_clock_min[2] << 16);
|
||||
maxPclk = blk->pixel_clock_max[0] | (blk->pixel_clock_max[1] << 8) | (blk->pixel_clock_max[2] << 16);
|
||||
|
||||
if (blk->vertical_refresh_rate_min == 0 || blk->vertical_refresh_rate_max == 0 ||
|
||||
blk->vertical_refresh_rate_min > blk->vertical_refresh_rate_max ||
|
||||
minPclk > maxPclk)
|
||||
{
|
||||
nvt_assert(0 && "wrong range limit");
|
||||
status = NVT_STATUS_ERR;
|
||||
}
|
||||
|
||||
if (pInfo == NULL) return status;
|
||||
|
||||
if (pInfo->rl_num >= NVT_DISPLAYID_RANGE_LIMITS_MAX_COUNT)
|
||||
{
|
||||
// Assert since this error is ignored
|
||||
nvt_assert(0);
|
||||
@@ -949,8 +1031,8 @@ static NVT_STATUS parseDisplayIdRangeLimits(NvU8 * block, NVT_DISPLAYID_INFO *pI
|
||||
rl = pInfo->range_limits + pInfo->rl_num;
|
||||
(pInfo->rl_num)++;
|
||||
|
||||
rl->pclk_min = blk->pixel_clock_min[0] | (blk->pixel_clock_min[1] << 8) | (blk->pixel_clock_min[2] << 16);
|
||||
rl->pclk_max = blk->pixel_clock_max[0] | (blk->pixel_clock_max[1] << 8) | (blk->pixel_clock_max[2] << 16);
|
||||
rl->pclk_min = minPclk;
|
||||
rl->pclk_max = maxPclk;
|
||||
|
||||
rl->interlaced = DRF_VAL(T_DISPLAYID, _RANGE_LIMITS, _INTERLACE, blk->optns);
|
||||
rl->cvt = DRF_VAL(T_DISPLAYID, _RANGE_LIMITS, _CVT_STANDARD, blk->optns);
|
||||
@@ -978,6 +1060,8 @@ static NVT_STATUS parseDisplayIdSerialNumber(NvU8 * block, NVT_DISPLAYID_INFO *p
|
||||
return NVT_STATUS_ERR;
|
||||
}
|
||||
|
||||
if (pInfo == NULL) return NVT_STATUS_SUCCESS;
|
||||
|
||||
// Nothing is currently done to store any ASCII Serial Number, if it is
|
||||
// required. Code here may need to be modified sometime in the future, along
|
||||
// with NVT_DISPLAYID_INFO struct
|
||||
@@ -995,6 +1079,8 @@ static NVT_STATUS parseDisplayIdAsciiString(NvU8 * block, NVT_DISPLAYID_INFO *pI
|
||||
return NVT_STATUS_ERR;
|
||||
}
|
||||
|
||||
if (pInfo == NULL) return NVT_STATUS_SUCCESS;
|
||||
|
||||
// Nothing is currently done to store any ASCII String Data, if it is
|
||||
// required. Code here may need to be modified sometime in the future, along
|
||||
// with NVT_DISPLAYID_INFO struct
|
||||
@@ -1012,6 +1098,8 @@ static NVT_STATUS parseDisplayIdDeviceData(NvU8 * block, NVT_DISPLAYID_INFO *pIn
|
||||
return NVT_STATUS_ERR;
|
||||
}
|
||||
|
||||
if (pInfo == NULL) return NVT_STATUS_SUCCESS;
|
||||
|
||||
pInfo->tech_type = blk->technology;
|
||||
|
||||
pInfo->device_op_mode = DRF_VAL(T_DISPLAYID, _DEVICE, _OPERATING_MODE, blk->operating_mode);
|
||||
@@ -1048,6 +1136,8 @@ static NVT_STATUS parseDisplayIdInterfacePower(NvU8 * block, NVT_DISPLAYID_INFO
|
||||
return NVT_STATUS_ERR;
|
||||
}
|
||||
|
||||
if (pInfo == NULL) return NVT_STATUS_SUCCESS;
|
||||
|
||||
// Note specifically that the data inside T1/T2 variables are the exact
|
||||
// interface power data. the millisecond increments are dependent on the
|
||||
// DisplayID specification.
|
||||
@@ -1065,6 +1155,8 @@ static NVT_STATUS parseDisplayIdInterfacePower(NvU8 * block, NVT_DISPLAYID_INFO
|
||||
CODE_SEGMENT(PAGE_DD_CODE)
|
||||
static NVT_STATUS parseDisplayIdTransferChar(NvU8 * block, NVT_DISPLAYID_INFO *pInfo)
|
||||
{
|
||||
if (pInfo == NULL) return NVT_STATUS_SUCCESS;
|
||||
|
||||
// Transfer Characteristics are currently not supported, but parsing of the
|
||||
// block should be added in the future when more specifications on monitors
|
||||
// that require this information is located here.
|
||||
@@ -1081,6 +1173,9 @@ static NVT_STATUS parseDisplayIdDisplayInterface(NvU8 * block, NVT_DISPLAYID_INF
|
||||
nvt_assert(0);
|
||||
return NVT_STATUS_ERR;
|
||||
}
|
||||
|
||||
if (pInfo == NULL) return NVT_STATUS_SUCCESS;
|
||||
|
||||
pInfo->supported_displayId2_0 = 0;
|
||||
|
||||
// Type/Link Info
|
||||
@@ -1152,6 +1247,8 @@ static NVT_STATUS parseDisplayIdStereo(NvU8 * block, NVT_DISPLAYID_INFO *pInfo)
|
||||
return NVT_STATUS_ERR;
|
||||
}
|
||||
|
||||
if (pInfo == NULL) return NVT_STATUS_SUCCESS;
|
||||
|
||||
sub = blk->timing_sub_block;
|
||||
|
||||
pInfo->stereo_code = blk->stereo_code;
|
||||
@@ -1196,6 +1293,8 @@ static NVT_STATUS parseDisplayIdTiledDisplay(NvU8 * block, NVT_DISPLAYID_INFO *p
|
||||
return NVT_STATUS_ERR;
|
||||
}
|
||||
|
||||
if (pInfo == NULL) return NVT_STATUS_SUCCESS;
|
||||
|
||||
// For revision 0, we only allow one tiled display data block.
|
||||
if (!blk->header.revision && pInfo->tile_topology_id.vendor_id)
|
||||
return NVT_STATUS_SUCCESS;
|
||||
@@ -1237,17 +1336,22 @@ static NVT_STATUS parseDisplayIdTiledDisplay(NvU8 * block, NVT_DISPLAYID_INFO *p
|
||||
}
|
||||
|
||||
CODE_SEGMENT(PAGE_DD_CODE)
|
||||
static NVT_STATUS parseDisplayIdCtaData(NvU8 * block, NVT_EDID_INFO *pInfo, NVT_DISPLAYID_INFO *pDisplayIdInfo)
|
||||
static NVT_STATUS parseDisplayIdCtaData(NvU8 * block, NVT_EDID_INFO *pInfo)
|
||||
{
|
||||
DISPLAYID_DATA_BLOCK_HEADER * blk = (DISPLAYID_DATA_BLOCK_HEADER*)block;
|
||||
NVT_EDID_CEA861_INFO *p861info = &pInfo->ext861;
|
||||
NVT_EDID_CEA861_INFO *p861info;
|
||||
if (blk->data_bytes > NVT_DISPLAYID_DATABLOCK_MAX_PAYLOAD_LEN)
|
||||
{
|
||||
// Assert since this error is ignored
|
||||
nvt_assert(0);
|
||||
return NVT_STATUS_ERR;
|
||||
}
|
||||
pDisplayIdInfo->cea_data_block_present = 1;
|
||||
|
||||
if (pInfo == NULL) return NVT_STATUS_SUCCESS;
|
||||
|
||||
p861info = &pInfo->ext861;
|
||||
|
||||
pInfo->ext_displayid.cea_data_block_present = 1;
|
||||
p861info->revision = blk->revision;
|
||||
|
||||
//parse CEA tags which starts at 3rd byte from block
|
||||
@@ -1287,6 +1391,9 @@ static NVT_STATUS parseDisplayIdDisplayInterfaceFeatures(NvU8 * block, NVT_DISPL
|
||||
nvt_assert(0);
|
||||
return NVT_STATUS_ERR;
|
||||
}
|
||||
|
||||
if (pInfo == NULL) return NVT_STATUS_SUCCESS;
|
||||
|
||||
pInfo->supported_displayId2_0 = 1;
|
||||
|
||||
// Color Depths
|
||||
@@ -1342,5 +1449,4 @@ static NVT_STATUS parseDisplayIdDisplayInterfaceFeatures(NvU8 * block, NVT_DISPL
|
||||
return NVT_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
POP_SEGMENTS
|
||||
|
||||
@@ -30,14 +30,12 @@
|
||||
#include "nvBinSegment.h"
|
||||
#include "nvmisc.h"
|
||||
|
||||
#include "displayid20.h"
|
||||
#include "edid.h"
|
||||
|
||||
PUSH_SEGMENTS
|
||||
|
||||
// DisplayId2 as EDID extension entry point functions
|
||||
static NVT_STATUS parseDisplayId20EDIDExtSection(DISPLAYID_2_0_SECTION *section, NVT_EDID_INFO *pEdidInfo);
|
||||
static NVT_STATUS parseDisplayId20EDIDExtDataBlocks(DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NvU8 remainSectionLength, NvU8 *pCurrentDBLength, NVT_EDID_INFO *pEdidInfo);
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -70,8 +68,7 @@ getDisplayId20EDIDExtInfo(
|
||||
// The function name
|
||||
if (computeDisplayId20SectionCheckSum(p, sizeof(EDIDV1STRUC)) != 0)
|
||||
{
|
||||
return NVT_STATUS_ERR;
|
||||
// ret |= NVT_EDID_VALIDATION_ERR_MASK(NVT_EDID_VALIDATION_ERR_CHECK_SUM);
|
||||
nvt_assert(0 && "displayid2ext invalid checksum");
|
||||
}
|
||||
|
||||
extSection = (DISPLAYID_2_0_SECTION *)(p + 1);
|
||||
@@ -105,16 +102,20 @@ parseDisplayId20EDIDExtSection(
|
||||
|
||||
if (extSection->header.version == DISPLAYID_2_0_VERSION)
|
||||
{
|
||||
if (((pEdidInfo->total_did2_extensions == 1) && (extSection->header.product_type == 0 ||
|
||||
if (((pEdidInfo->total_did2_extensions == 1) && (extSection->header.product_type == DISPLAYID_2_0_PROD_EXTENSION ||
|
||||
extSection->header.product_type > DISPLAYID_2_0_PROD_HMD_AR ||
|
||||
extSection->header.extension_count != 0)) ||
|
||||
(pEdidInfo->total_did2_extensions > 1 && extSection->header.product_type != 0))
|
||||
extSection->header.extension_count != DISPLAYID_2_0_PROD_EXTENSION)) ||
|
||||
(pEdidInfo->total_did2_extensions > 1 && extSection->header.product_type != DISPLAYID_2_0_PROD_EXTENSION))
|
||||
{
|
||||
nvt_assert(0); // product_type value set incorrect in Display Product Primary Use Case field
|
||||
}
|
||||
|
||||
pEdidInfo->ext_displayid20.version = extSection->header.version;
|
||||
pEdidInfo->ext_displayid20.revision = extSection->header.revision;
|
||||
if (pEdidInfo->total_did2_extensions == 1)
|
||||
{
|
||||
pEdidInfo->ext_displayid20.primary_use_case = extSection->header.product_type;
|
||||
}
|
||||
pEdidInfo->ext_displayid20.as_edid_extension = NV_TRUE;
|
||||
}
|
||||
else
|
||||
@@ -152,11 +153,10 @@ parseDisplayId20EDIDExtSection(
|
||||
}
|
||||
else
|
||||
{
|
||||
if (parseDisplayId20EDIDExtDataBlocks(
|
||||
dbHeader,
|
||||
extSection->header.section_bytes - datablock_location,
|
||||
&datablock_length,
|
||||
pEdidInfo) != NVT_STATUS_SUCCESS)
|
||||
if (parseDisplayId20EDIDExtDataBlocks((NvU8 *)(extSection->data + datablock_location),
|
||||
extSection->header.section_bytes - datablock_location,
|
||||
&datablock_length,
|
||||
pEdidInfo) != NVT_STATUS_SUCCESS)
|
||||
return NVT_STATUS_ERR;
|
||||
}
|
||||
|
||||
@@ -169,39 +169,49 @@ parseDisplayId20EDIDExtSection(
|
||||
|
||||
/*
|
||||
* @brief DisplayId20 as EDID extension block's "Data Block" entry point functions
|
||||
* For validation, passed the NULL pEdidInfo, and client will check the return value
|
||||
*/
|
||||
CODE_SEGMENT(PAGE_DD_CODE)
|
||||
static NVT_STATUS
|
||||
NVT_STATUS
|
||||
parseDisplayId20EDIDExtDataBlocks(
|
||||
DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock,
|
||||
NvU8 *pDataBlock,
|
||||
NvU8 RemainSectionLength,
|
||||
NvU8 *pCurrentDBLength,
|
||||
NVT_EDID_INFO *pEdidInfo)
|
||||
{
|
||||
DISPLAYID_2_0_DATA_BLOCK_HEADER * block_header = (DISPLAYID_2_0_DATA_BLOCK_HEADER *) pDataBlock;
|
||||
NVT_STATUS status = NVT_STATUS_SUCCESS;
|
||||
NVT_DISPLAYID_2_0_INFO *pDisplayId20Info = NULL;
|
||||
|
||||
|
||||
// size sanity checking
|
||||
if ((pDataBlock == NULL || RemainSectionLength <= NVT_DISPLAYID_DATABLOCK_HEADER_LEN) ||
|
||||
(pDataBlock->data_bytes > RemainSectionLength - NVT_DISPLAYID_DATABLOCK_HEADER_LEN))
|
||||
(block_header->data_bytes > RemainSectionLength - NVT_DISPLAYID_DATABLOCK_HEADER_LEN))
|
||||
return NVT_STATUS_ERR;
|
||||
|
||||
if (pDataBlock->type < DISPLAYID_2_0_BLOCK_TYPE_PRODUCT_IDENTITY)
|
||||
if (block_header->type < DISPLAYID_2_0_BLOCK_TYPE_PRODUCT_IDENTITY)
|
||||
{
|
||||
return NVT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
pDisplayId20Info = &pEdidInfo->ext_displayid20;
|
||||
|
||||
*pCurrentDBLength = pDataBlock->data_bytes + NVT_DISPLAYID_DATABLOCK_HEADER_LEN;
|
||||
if (pEdidInfo != NULL)
|
||||
{
|
||||
pDisplayId20Info = &(pEdidInfo->ext_displayid20);
|
||||
}
|
||||
|
||||
status = parseDisplayId20DataBlock(pDataBlock, pDisplayId20Info);
|
||||
*pCurrentDBLength = block_header->data_bytes + NVT_DISPLAYID_DATABLOCK_HEADER_LEN;
|
||||
|
||||
status = parseDisplayId20DataBlock(block_header, pDisplayId20Info);
|
||||
|
||||
if (pDisplayId20Info == NULL) return status;
|
||||
|
||||
// TODO : All the data blocks shall sync the data from the datablock in DisplayID2_0 to pEdidInfo
|
||||
if (status == NVT_STATUS_SUCCESS && pDisplayId20Info->as_edid_extension == NV_TRUE)
|
||||
{
|
||||
switch (pDataBlock->type)
|
||||
switch (block_header->type)
|
||||
{
|
||||
case DISPLAYID_2_0_BLOCK_TYPE_PRODUCT_IDENTITY:
|
||||
pDisplayId20Info->valid_data_blocks.product_id_present = NV_TRUE;
|
||||
break;
|
||||
case DISPLAYID_2_0_BLOCK_TYPE_INTERFACE_FEATURES:
|
||||
pDisplayId20Info->valid_data_blocks.interface_feature_present = NV_TRUE;
|
||||
|
||||
@@ -234,15 +244,16 @@ parseDisplayId20EDIDExtDataBlocks(
|
||||
pDisplayId20Info->valid_data_blocks.cta_data_present = NV_TRUE;
|
||||
|
||||
// copy all the vendor specific data block from DisplayId20 to pEdidInfo
|
||||
// TODO: mixed CTA extension block and DID2.0 extension block is not handled
|
||||
// NOTE: mixed CTA extension block and DID2.0 extension block are not handled
|
||||
NVMISC_MEMCPY(&pEdidInfo->hdmiLlcInfo, &pDisplayId20Info->vendor_specific.hdmiLlc, sizeof(NVT_HDMI_LLC_INFO));
|
||||
NVMISC_MEMCPY(&pEdidInfo->hdmiForumInfo, &pDisplayId20Info->vendor_specific.hfvs, sizeof(NVT_HDMI_FORUM_INFO));
|
||||
NVMISC_MEMCPY(&pEdidInfo->nvdaVsdbInfo, &pDisplayId20Info->vendor_specific.nvVsdb, sizeof(NVDA_VSDB_PARSED_INFO));
|
||||
NVMISC_MEMCPY(&pEdidInfo->msftVsdbInfo, &pDisplayId20Info->vendor_specific.msftVsdb, sizeof(MSFT_VSDB_PARSED_INFO));
|
||||
NVMISC_MEMCPY(&pEdidInfo->hdr_static_metadata_info, &pDisplayId20Info->cta.hdrInfo, sizeof(NVT_HDR_STATIC_METADATA));
|
||||
NVMISC_MEMCPY(&pEdidInfo->dv_static_metadata_info, &pDisplayId20Info->cta.dvInfo, sizeof(NVT_DV_STATIC_METADATA));
|
||||
NVMISC_MEMCPY(&pEdidInfo->hdr10PlusInfo, &pDisplayId20Info->cta.hdr10PlusInfo, sizeof(NVT_HDR10PLUS_INFO));
|
||||
|
||||
// If the CTA861 extension existed already, we need to transfer the revision/basic_caps to cta embedded in DID20.
|
||||
// If the CTA861 extension existed already, we need to synced the revision/basic_caps to CTA which is embedded in DID20
|
||||
if (pEdidInfo->ext861.revision >= NVT_CEA861_REV_B)
|
||||
{
|
||||
pDisplayId20Info->cta.cta861_info.revision = pEdidInfo->ext861.revision;
|
||||
@@ -268,7 +279,36 @@ parseDisplayId20EDIDExtDataBlocks(
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case DISPLAYID_2_0_BLOCK_TYPE_STEREO:
|
||||
pDisplayId20Info->valid_data_blocks.stereo_interface_present = NV_TRUE;
|
||||
break;
|
||||
case DISPLAYID_2_0_BLOCK_TYPE_TILED_DISPLAY:
|
||||
pDisplayId20Info->valid_data_blocks.tiled_display_present = NV_TRUE;
|
||||
break;
|
||||
case DISPLAYID_2_0_BLOCK_TYPE_CONTAINER_ID:
|
||||
pDisplayId20Info->valid_data_blocks.container_id_present = NV_TRUE;
|
||||
break;
|
||||
case DISPLAYID_2_0_BLOCK_TYPE_TIMING_7:
|
||||
pDisplayId20Info->valid_data_blocks.type7Timing_present = NV_TRUE;
|
||||
break;
|
||||
case DISPLAYID_2_0_BLOCK_TYPE_TIMING_8:
|
||||
pDisplayId20Info->valid_data_blocks.type8Timing_present = NV_TRUE;
|
||||
break;
|
||||
case DISPLAYID_2_0_BLOCK_TYPE_TIMING_9:
|
||||
pDisplayId20Info->valid_data_blocks.type9Timing_present = NV_TRUE;
|
||||
break;
|
||||
case DISPLAYID_2_0_BLOCK_TYPE_TIMING_10:
|
||||
pDisplayId20Info->valid_data_blocks.type10Timing_present = NV_TRUE;
|
||||
break;
|
||||
case DISPLAYID_2_0_BLOCK_TYPE_RANGE_LIMITS:
|
||||
pDisplayId20Info->valid_data_blocks.dynamic_range_limit_present = NV_TRUE;
|
||||
break;
|
||||
case DISPLAYID_2_0_BLOCK_TYPE_ADAPTIVE_SYNC:
|
||||
pDisplayId20Info->valid_data_blocks.adaptive_sync_present = NV_TRUE;
|
||||
break;
|
||||
case DISPLAYID_2_0_BLOCK_TYPE_VENDOR_SPEC:
|
||||
pDisplayId20Info->valid_data_blocks.vendor_specific_present = NV_TRUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -356,7 +356,7 @@ typedef enum NVT_TV_FORMAT
|
||||
#define NVT_STATUS_NTSC_TV NVT_DEF_TIMING_STATUS(NVT_TYPE_NTSC_TV, 0) // TVN
|
||||
#define NVT_STATUS_PAL_TV NVT_DEF_TIMING_STATUS(NVT_TYPE_PAL_TV, 0) // TVP
|
||||
#define NVT_STATUS_CVT NVT_DEF_TIMING_STATUS(NVT_TYPE_CVT, 0) // CVT timing with regular blanking
|
||||
#define NVT_STATUS_CVT_RB NVT_DEF_TIMING_STATUS(NVT_TYPE_CVT_RB, 0) // CVT_RB timing
|
||||
#define NVT_STATUS_CVT_RB NVT_DEF_TIMING_STATUS(NVT_TYPE_CVT_RB, 0) // CVT_RB timing V1
|
||||
#define NVT_STATUS_CVT_RB_2 NVT_DEF_TIMING_STATUS(NVT_TYPE_CVT_RB_2, 0) // CVT_RB timing V2
|
||||
#define NVT_STATUS_CVT_RB_3 NVT_DEF_TIMING_STATUS(NVT_TYPE_CVT_RB_3, 0) // CVT_RB timing V3
|
||||
#define NVT_STATUS_CUST NVT_DEF_TIMING_STATUS(NVT_TYPE_CUST, 0) // Customized timing
|
||||
@@ -814,6 +814,7 @@ typedef struct VSDB_DATA
|
||||
// vendor specific video data
|
||||
//*******************************
|
||||
#define NVT_CEA861_DV_IEEE_ID 0x00D046
|
||||
#define NVT_CEA861_HDR10PLUS_IEEE_ID 0x90848B
|
||||
#define NVT_CEA861_VSVDB_PAYLOAD_MAX_LENGTH 25 // max allowed vendor specific video data block payload (in byte)
|
||||
#define NVT_CEA861_VSVDB_VERSION_MASK 0xE0 // vsdb version mask
|
||||
#define NVT_CEA861_VSVDB_VERSION_MASK_SHIFT 5 // vsdb version shift mask
|
||||
@@ -941,13 +942,13 @@ typedef struct tagNVT_DV_STATIC_METADATA_TYPE2
|
||||
NvU8 VSVDB_version : 3;
|
||||
|
||||
// second byte
|
||||
NvU8 backlt_min_luma : 2;
|
||||
NvU8 reserved : 2;
|
||||
NvU8 supports_global_dimming : 1;
|
||||
NvU8 target_min_luminance : 5;
|
||||
|
||||
// third byte
|
||||
NvU8 interface_supported_by_sink : 2;
|
||||
NvU8 reserved : 1;
|
||||
NvU8 parity : 1;
|
||||
NvU8 target_max_luminance : 5;
|
||||
|
||||
//fourth byte
|
||||
@@ -967,6 +968,14 @@ typedef struct tagNVT_DV_STATIC_METADATA_TYPE2
|
||||
NvU8 unique_Ry : 5;
|
||||
|
||||
} NVT_DV_STATIC_METADATA_TYPE2;
|
||||
|
||||
typedef struct tagNVT_HDR10PLUS_INFO
|
||||
{
|
||||
// first byte
|
||||
NvU8 application_version : 2;
|
||||
NvU8 full_frame_peak_luminance_index : 2;
|
||||
NvU8 peak_luminance_index : 4;
|
||||
} NVT_HDR10PLUS_INFO;
|
||||
#pragma pack()
|
||||
|
||||
//***************************
|
||||
@@ -1111,6 +1120,7 @@ typedef struct tagNVT_VALID_EXTENDED_BLOCKS
|
||||
NvU32 y420cmdb : 1;
|
||||
NvU32 hdr_static_metadata : 1;
|
||||
NvU32 dv_static_metadata : 1;
|
||||
NvU32 hdr10Plus : 1;
|
||||
NvU32 SCDB : 1;
|
||||
NvU32 HF_EEODB : 1;
|
||||
} NVT_VALID_EXTENDED_BLOCKS;
|
||||
@@ -1799,7 +1809,7 @@ typedef struct tagNVT_EDID_DD_DUMMY_DESCRIPTOR
|
||||
//
|
||||
//
|
||||
//
|
||||
//*** (Tag = 0x0F) ***/
|
||||
//*** (Tag = 0x00 to 0x0F) ***/
|
||||
// Manufacturer Special Data
|
||||
typedef struct tagNVT_EDID_DD_MANUF_DATA
|
||||
{
|
||||
@@ -2169,6 +2179,7 @@ typedef struct tagNVT_DV_STATIC_METADATA
|
||||
NvU32 backlt_min_luma : 2;
|
||||
NvU32 interface_supported_by_sink : 2;
|
||||
NvU32 supports_10b_12b_444 : 2;
|
||||
NvU32 parity : 1;
|
||||
}NVT_DV_STATIC_METADATA;
|
||||
|
||||
//***********************************
|
||||
@@ -2182,7 +2193,6 @@ typedef struct tagNVT_DV_STATIC_METADATA
|
||||
#define NVT_DISPLAY_2_0_CAP_YCbCr_422 0x10 // DTV monitor supports YCbCr4:2:2
|
||||
|
||||
// vendor specific
|
||||
|
||||
#define NVT_VESA_VENDOR_SPECIFIC_IEEE_ID 0x3A0292
|
||||
#define NVT_VESA_VENDOR_SPECIFIC_LENGTH 7
|
||||
|
||||
@@ -2195,6 +2205,9 @@ typedef struct tagNVT_DV_STATIC_METADATA
|
||||
#define NVT_VESA_ORG_VSDB_PASS_THROUGH_INTEGER_MASK 0x3F
|
||||
#define NVT_VESA_ORG_VSDB_PASS_THROUGH_FRACTIOINAL_MASK 0x0F
|
||||
|
||||
// adaptive-sync
|
||||
#define NVT_ADAPTIVE_SYNC_DESCRIPTOR_MAX_COUNT 0x04
|
||||
|
||||
typedef enum _tagNVT_DISPLAYID_PRODUCT_PRIMARY_USE_CASE
|
||||
{
|
||||
PRODUCT_PRIMARY_USE_TEST_EQUIPMENT = 1,
|
||||
@@ -2383,6 +2396,28 @@ typedef struct _tagNVT_DISPLAYID_DISPLAY_PARAMETERS
|
||||
NvBool audio_speakers_integrated;
|
||||
} NVT_DISPLAYID_DISPLAY_PARAMETERS;
|
||||
|
||||
typedef struct _tagNVT_DISPLAYID_ADAPTIVE_SYNC
|
||||
{
|
||||
union
|
||||
{
|
||||
NvU8 operation_range_info;
|
||||
struct
|
||||
{
|
||||
NvU8 adaptive_sync_range : 1;
|
||||
NvU8 duration_inc_flicker_perf : 1;
|
||||
NvU8 modes : 2;
|
||||
NvU8 seamless_not_support : 1;
|
||||
NvU8 duration_dec_flicker_perf : 1;
|
||||
NvU8 reserved : 2;
|
||||
} information;
|
||||
} u;
|
||||
|
||||
NvU8 max_duration_inc;
|
||||
NvU8 min_rr;
|
||||
NvU16 max_rr;
|
||||
NvU8 max_duration_dec;
|
||||
} NVT_DISPLAYID_ADAPTIVE_SYNC;
|
||||
|
||||
typedef struct _tagVESA_VSDB_PARSED_INFO
|
||||
{
|
||||
struct
|
||||
@@ -2411,7 +2446,6 @@ typedef struct _tagVESA_VSDB_PARSED_INFO
|
||||
NvU8 pass_through_fraction_dsc : 4;
|
||||
NvU8 reserved : 4;
|
||||
} pass_through_fractional;
|
||||
|
||||
} VESA_VSDB_PARSED_INFO;
|
||||
|
||||
typedef struct _tagNVT_DISPLAYID_VENDOR_SPECIFIC
|
||||
@@ -2427,7 +2461,8 @@ typedef struct _tagNVT_DISPLAYID_CTA
|
||||
{
|
||||
NVT_EDID_CEA861_INFO cta861_info;
|
||||
NVT_HDR_STATIC_METADATA hdrInfo;
|
||||
NVT_DV_STATIC_METADATA dvInfo;
|
||||
NVT_DV_STATIC_METADATA dvInfo;
|
||||
NVT_HDR10PLUS_INFO hdr10PlusInfo;
|
||||
} NVT_DISPLAYID_CTA;
|
||||
|
||||
typedef struct _tagNVT_VALID_DATA_BLOCKS
|
||||
@@ -2442,6 +2477,10 @@ typedef struct _tagNVT_VALID_DATA_BLOCKS
|
||||
NvBool stereo_interface_present;
|
||||
NvBool tiled_display_present;
|
||||
NvBool container_id_present;
|
||||
NvBool type10Timing_present;
|
||||
NvBool adaptive_sync_present;
|
||||
NvBool arvr_hmd_present;
|
||||
NvBool arvr_layer_present;
|
||||
NvBool vendor_specific_present;
|
||||
NvBool cta_data_present;
|
||||
} NVT_VALID_DATA_BLOCKS;
|
||||
@@ -2494,6 +2533,10 @@ typedef struct _tagNVT_DISPLAYID_2_0_INFO
|
||||
// ContainerID Data Block (Mandatory for Multi-function Device)
|
||||
NVT_DISPLAYID_CONTAINERID container_id;
|
||||
|
||||
// Adaptive-Sync Data Block (Mandatory for display device supports Adaptive-Sync)
|
||||
NvU32 total_adaptive_sync_descriptor;
|
||||
NVT_DISPLAYID_ADAPTIVE_SYNC adaptive_sync_descriptor[NVT_ADAPTIVE_SYNC_DESCRIPTOR_MAX_COUNT];
|
||||
|
||||
// Vendor-specific Data Block (Not Mandatory)
|
||||
NVT_DISPLAYID_VENDOR_SPECIFIC vendor_specific;
|
||||
|
||||
@@ -2632,6 +2675,9 @@ typedef struct tagNVT_EDID_INFO
|
||||
// DV capability information from the DV Metadata Data Block
|
||||
NVT_DV_STATIC_METADATA dv_static_metadata_info;
|
||||
|
||||
// HDR10+ capability information from the HDR10+ LLC VSVDB
|
||||
NVT_HDR10PLUS_INFO hdr10PlusInfo;
|
||||
|
||||
// HDMI LLC info
|
||||
NVT_HDMI_LLC_INFO hdmiLlcInfo;
|
||||
|
||||
@@ -5182,28 +5228,60 @@ typedef enum
|
||||
|
||||
typedef enum
|
||||
{
|
||||
// errors returned as a bitmask by NvTiming_EDIDValidationMask()
|
||||
// errors returned as a bitmask by NvTiming_EDIDValidationMask()
|
||||
NVT_EDID_VALIDATION_ERR_EXT = 0,
|
||||
NVT_EDID_VALIDATION_ERR_VERSION,
|
||||
NVT_EDID_VALIDATION_ERR_SIZE,
|
||||
NVT_EDID_VALIDATION_ERR_CHECKSUM,
|
||||
NVT_EDID_VALIDATION_ERR_RANGE_LIMIT,
|
||||
NVT_EDID_VALIDATION_ERR_DTD,
|
||||
NVT_EDID_VALIDATION_ERR_HEADER,
|
||||
NVT_EDID_VALIDATION_ERR_EXT_DTD,
|
||||
NVT_EDID_VALIDATION_ERR_EXTENSION_TAG,
|
||||
NVT_EDID_VALIDATION_ERR_EXTENSION_COUNT,
|
||||
NVT_EDID_VALIDATION_ERR_DESCRIPTOR,
|
||||
NVT_EDID_VALIDATION_ERR_EXT_CTA_BASIC,
|
||||
NVT_EDID_VALIDATION_ERR_EXT_CTA_DTD,
|
||||
NVT_EDID_VALIDATION_ERR_EXT_CTA_TAG,
|
||||
NVT_EDID_VALIDATION_ERR_EXT_CTA_SVD,
|
||||
NVT_EDID_VALIDATION_ERR_EXT_CTA_INVALID_DATA_BLOCK,
|
||||
NVT_EDID_VALIDATION_ERR_EXT_CTA_CHECKSUM,
|
||||
NVT_EDID_VALIDATION_ERR_EXT_DID_VERSION,
|
||||
NVT_EDID_VALIDATION_ERR_EXT_DID_EXTCOUNT,
|
||||
NVT_EDID_VALIDATION_ERR_EXT_DID_CHECKSUM,
|
||||
NVT_EDID_VALIDATION_ERR_EXT_DID_SEC_SIZE,
|
||||
NVT_EDID_VALIDATION_ERR_EXT_DID13_TAG,
|
||||
NVT_EDID_VALIDATION_ERR_EXT_DID13_TYPE1,
|
||||
NVT_EDID_VALIDATION_ERR_EXT_DID2_TAG,
|
||||
NVT_EDID_VALIDATION_ERR_EXT_DID2_USE_CASE,
|
||||
NVT_EDID_VALIDATION_ERR_EXT_DID2_MANDATORY_BLOCKS,
|
||||
NVT_EDID_VALIDATION_ERR_EXT_DID2_TYPE7,
|
||||
NVT_EDID_VALIDATION_ERR_EXT_DID2_TYPE10,
|
||||
NVT_EDID_VALIDATION_ERR_EXT_RANGE_LIMIT,
|
||||
NVT_EDID_VALIDATION_ERR_EXT_DID2_ADAPTIVE_SYNC,
|
||||
} NVT_EDID_VALIDATION_ERR_STATUS;
|
||||
#define NVT_EDID_VALIDATION_ERR_MASK(x) NVBIT32(x)
|
||||
|
||||
//*************************************
|
||||
// The DisplayID2 validation Mask
|
||||
//*************************************
|
||||
typedef enum
|
||||
{
|
||||
// errors returned as a bitmask by NvTiming_DisplayID2ValidationMask()
|
||||
NVT_DID2_VALIDATION_ERR_EXT = 0,
|
||||
NVT_DID2_VALIDATION_ERR_VERSION,
|
||||
NVT_DID2_VALIDATION_ERR_VERSION = 0,
|
||||
NVT_DID2_VALIDATION_ERR_SIZE,
|
||||
NVT_DID2_VALIDATION_ERR_CHECKSUM,
|
||||
NVT_DID2_VALIDATION_ERR_PRODUCT_ID,
|
||||
NVT_DID2_VALIDATION_ERR_CHECKSUM,
|
||||
NVT_DID2_VALIDATION_ERR_NO_DATA_BLOCK,
|
||||
NVT_EDID_VALIDATION_ERR_TAG,
|
||||
NVT_DID2_VALIDATION_ERR_RANGE_LIMIT,
|
||||
NVT_DID2_VALIDATION_ERR_NATIVE_DTD,
|
||||
NVT_DID2_VALIDATION_ERR_MANDATORY_BLOCKS,
|
||||
NVT_DID2_VALIDATION_ERR_PRODUCT_IDENTIFY,
|
||||
NVT_DID2_VALIDATION_ERR_PARAMETER,
|
||||
NVT_DID2_VALIDATION_ERR_INTERFACE,
|
||||
NVT_DID2_VALIDATION_ERR_TYPE7,
|
||||
NVT_DID2_VALIDATION_ERR_TYPE10,
|
||||
NVT_DID2_VALIDATION_ERR_ADAPTIVE_SYNC,
|
||||
} NVT_DID2_VALIDATION_ERR_STATUS;
|
||||
#define NVT_DID2_VALIDATION_ERR_MASK(x) NVBIT32(x)
|
||||
|
||||
@@ -5229,9 +5307,9 @@ typedef enum
|
||||
#define NVT_FLAG_DTD1_PREFERRED_TIMING 0x00080000
|
||||
#define NVT_FLAG_DISPLAYID_DTD_PREFERRED_TIMING 0x00100000
|
||||
#define NVT_FLAG_CEA_PREFERRED_TIMING 0x00200000
|
||||
#define NVT_FLAG_DISPLAYID_7_DSC_PASSTHRU 0x00400000
|
||||
#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_2_0_EXPLICT_YUV420 0x01000000 // DID2 E7 spec. supported yuv420 indicated
|
||||
#define NVT_FLAG_DISPLAYID_T7_T8_EXPLICT_YUV420 0x01000000 // DID2 E7 spec. supported yuv420 indicated
|
||||
|
||||
#define NVT_FLAG_INTERLACED_MASK (NVT_FLAG_INTERLACED_TIMING | NVT_FLAG_INTERLACED_TIMING2)
|
||||
|
||||
@@ -5299,6 +5377,7 @@ NvU32 NvTiming_GetVESADisplayDescriptorVersion(NvU8 *rawData, NvU32 *pVer);
|
||||
// EDID entry parse
|
||||
NVT_STATUS NV_STDCALL NvTiming_ParseEDIDInfo(NvU8 *pEdid, NvU32 length, NVT_EDID_INFO *pEdidInfo);
|
||||
NvU32 NvTiming_EDIDValidationMask(NvU8 *pEdid, NvU32 length, NvBool bIsStrongValidation);
|
||||
NvU32 NvTiming_EDIDStrongValidationMask(NvU8 *pEdid, NvU32 length);
|
||||
NVT_STATUS NvTiming_EDIDValidation(NvU8 *pEdid, NvU32 length, NvBool bIsStrongValidation);
|
||||
|
||||
// DisplayID20 standalone entry parse
|
||||
|
||||
@@ -78,8 +78,9 @@ void parseEdidHdmiForumVSDB(VSDB_DATA *pVsdb, NVT_HDMI_FORUM_INFO *pHdmiIn
|
||||
void getEdidHDM1_4bVsdbTiming(NVT_EDID_INFO *pInfo);
|
||||
void parseEdidHDMILLCTiming(NVT_EDID_INFO *pInfo, VSDB_DATA *pVsdb, NvU32 *pSupported, HDMI3DSUPPORTMAP * pM);
|
||||
void parseEdidNvidiaVSDBBlock(VSDB_DATA *pVsdb, NVDA_VSDB_PARSED_INFO *vsdbInfo);
|
||||
void parseCea861HdrStaticMetadataDataBlock(NVT_EDID_CEA861_INFO *pExt861, void *pRawInfo, NVT_CTA861_ORIGIN);
|
||||
void parseCea861DvStaticMetadataDataBlock(NVT_EDID_CEA861_INFO *pExt861, NVT_DV_STATIC_METADATA *pDvInfo);
|
||||
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);
|
||||
NvBool isMatchedCTA861Timing(NVT_EDID_INFO *pInfo, NVT_TIMING *pT);
|
||||
NvU32 isHdmi3DStereoType(NvU8 StereoStructureType);
|
||||
NvU32 getCEA861TimingAspectRatio(NvU32 vic);
|
||||
@@ -91,7 +92,9 @@ void getMonitorDescriptorString(NvU8 *pEdid, NvU8 tag, char *str, int once
|
||||
// DispalyID base / extension related functions
|
||||
NvU32 getDID2Version(NvU8 *pData, NvU32 *pVer);
|
||||
NVT_STATUS getDisplayIdEDIDExtInfo(NvU8* pEdid, NvU32 edidSize, NVT_EDID_INFO* pEdidInfo);
|
||||
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);
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user