515.43.04

This commit is contained in:
Andy Ritger
2022-05-09 13:18:59 -07:00
commit 1739a20efc
2519 changed files with 1060036 additions and 0 deletions

View File

@@ -0,0 +1,268 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/** @file nvhdmi_frlInterface.h
* @brief This file provides FRL related interfaces between client and HDMI lib
*/
#ifndef _NVHDMI_FRLINTERFACE_H_
#define _NVHDMI_FRLINTERFACE_H_
#include "nvhdmipkt.h"
#include "nvHdmiFrlCommon.h"
#include "../timing/nvtiming.h"
#ifdef __cplusplus
extern "C" {
#endif
// DSC encoder color format bitmasks (these match DSC lib & RM ctrl 0073 fields)
typedef enum tagHDMI_DSC_ENCODER_COLOR_FORMAT
{
HDMI_DSC_ENCODER_COLOR_FORMAT_RGB = 1,
HDMI_DSC_ENCODER_COLOR_FORMAT_YCBCR444 = 2,
HDMI_DSC_ENCODER_COLOR_FORMAT_YCBCRNATIVE422 = 4,
HDMI_DSC_ENCODER_COLOR_FORMAT_YCBCRNATIVE420 = 8
} HDMI_DSC_ENCODER_COLOR_FORMAT;
// Options for QueryFRLConfig interface
typedef enum tagHDMI_QUERY_FRL_OPTION
{
HDMI_QUERY_FRL_ANY_CONFIG = 0, // any FRL config that supports mode
HDMI_QUERY_FRL_OPTIMUM_CONFIG, // find best fit config for this mode
HDMI_QUERY_FRL_LOWEST_BANDWIDTH, // min bw
HDMI_QUERY_FRL_HIGHEST_PIXEL_QUALITY, // trade off bandwidth for pixel quality
HDMI_QUERY_FRL_HIGHEST_BANDWIDTH
} HDMI_QUERY_FRL_OPTION;
/*************************************************************************************************
* HDMI_VIDEO_TRANSPORT_INFO: *
* Video transport format - a combination of timing, bpc, packing represents what goes on the link*
* client passes this in, lib uses this for bandwidth calculations to decide required FRL rate *
**************************************************************************************************/
typedef struct tagHDMI_VIDEO_TRANSPORT_INFO
{
const NVT_TIMING *pTiming; // backend timing
HDMI_BPC bpc;
HDMI_PIXEL_PACKING packing;
NvBool bDualHeadMode; // 2H1OR
} HDMI_VIDEO_TRANSPORT_INFO;
/************************************************************************************************
* HDMI_QUERY_FRL_CLIENT_CONTROL: *
* Allow client to force request DSC/FRL configurations. For testing purpose or otherwise *
* eg, client could query for any fitting FRL config instead of most optimum. It could trade off *
* bandwidth for pixel quality. *
*************************************************************************************************/
typedef struct tagHDMI_QUERY_FRL_CLIENT_CONTROL
{
HDMI_QUERY_FRL_OPTION option;
NvU32 forceFRLRate : 1;
NvU32 forceAudio2Ch48KHz : 1;
NvU32 enableDSC : 1;
NvU32 forceSliceCount : 1;
NvU32 forceSliceWidth : 1;
NvU32 forceBppx16 : 1;
NvU32 skipGeneratePPS : 1;
NvU32 reserved : 25;
// client can set below params if respective force flag is set
NvU32 sliceCount;
NvU32 sliceWidth;
NvU32 bitsPerPixelX16;
HDMI_FRL_DATA_RATE frlRate;
} HDMI_QUERY_FRL_CLIENT_CONTROL;
/************************************************************************************************
* HDMI_SRC_CAPS: *
* Input to HDMI lib. *
* *
* Client gives info about GPU capabilities - DSC related caps *
*************************************************************************************************/
typedef struct tagHDMI_SRC_CAPS
{
struct
{
NvU32 dscCapable : 1;
NvU32 bppPrecision : 8;
NvU32 encoderColorFormatMask : 8;
NvU32 lineBufferSizeKB : 8;
NvU32 rateBufferSizeKB : 8;
NvU32 maxNumHztSlices : 8;
NvU32 lineBufferBitDepth : 8;
NvU32 dualHeadBppTargetMaxX16 : 16;
NvU32 maxWidthPerSlice;
} dscCaps;
HDMI_FRL_DATA_RATE linkMaxFRLRate;
} HDMI_SRC_CAPS;
/************************************************************************************************
* HDMI_SINK_CAPS: *
* Input to HDMI lib. *
* *
* Client gives info from EDID, HDMI lib uses DSC related info to call DSC lib to generate PPS *
* Audio information from CEA861 block is used for bandwidth calculations *
* linkMaxFRLRate and linkMaxFRLRateDSC are max link rates determined from physical link *
* training. *
*************************************************************************************************/
typedef struct tagHDMI_SINK_CAPS
{
const NVT_HDMI_FORUM_INFO *pHdmiForumInfo;
NvU32 audioType;
NvU32 maxAudioChannels;
NvU32 maxAudioFreqKHz;
NvBool bHBRAudio;
HDMI_FRL_DATA_RATE linkMaxFRLRate;
HDMI_FRL_DATA_RATE linkMaxFRLRateDSC;
} HDMI_SINK_CAPS;
/************************************************************************************************
* HDMI_FRL_CONFIG: *
* Output from HDMI lib. Client uses this info for modeset *
* *
* maxSupportedAudioCh, maxSupportedAudioFreqKHz - max possible audio settings at the chosen *
* FRL rate, though the sink caps may have reported higher caps *
* *
* dscInfo - if current timing requires DSC, lib returns PPS information here *
* *
* bitsPerPixelx16 - optimum bpp value calculated per spec *
* dscHActiveBytes - in compressed video transport mode, number of bytes in 1 line *
* dscHActiveTriBytes - in compressed video transport mode, number of tri-bytes in 1 line *
* dscHBlankTriBytes - in compressed video transport mode, number of tri-bytes to be sent *
* to represent horizontal blanking *
* *
* pps[32] - PPS data. HDMI lib calls DSC lib to fill it in *
*************************************************************************************************/
#define HDMI_DSC_MAX_PPS_SIZE_DWORD 32
typedef struct tagHDMI_FRL_CONFIG
{
HDMI_FRL_DATA_RATE frlRate;
NvU32 maxSupportedAudioCh;
NvU32 maxSupportedAudioFreqKHz;
// DSC info client will use for core channel modeset
struct
{
NvU32 bEnableDSC : 1;
NvU32 reserved : 31;
NvU32 bitsPerPixelX16;
NvU32 sliceCount;
NvU32 sliceWidth;
NvU32 pps[HDMI_DSC_MAX_PPS_SIZE_DWORD];
NvU32 dscHActiveBytes;
NvU32 dscHActiveTriBytes;
NvU32 dscHBlankTriBytes;
NvU32 dscTBlankToTTotalRatioX1k;
} dscInfo;
} HDMI_FRL_CONFIG;
/************************************************************************************************
* NvHdmi_AssessLinkCapabilities: *
* *
* Input parameters: *
* subDevice - Sub Device ID. *
* displayId - Display ID. *
* pSinkEdid - EDID of sink *
* *
* Output parameters: *
* pSrcCaps - src capabilities - DSC caps *
* pSinkCaps - sink capabilities - actual caps calculated from link training *
* *
* Calls RM to get DSC related src side caps. Performs physical link training to determine if *
* sink reported max FRL rate can actually be supported on the physical link *
*************************************************************************************************/
NVHDMIPKT_RESULT
NvHdmi_AssessLinkCapabilities(NvHdmiPkt_Handle libHandle,
NvU32 subDevice,
NvU32 displayId,
NVT_EDID_INFO const * const pSinkEdid,
HDMI_SRC_CAPS *pSrcCaps,
HDMI_SINK_CAPS *pSinkCaps);
/************************************************************************************************
* NvHdmi_QueryFRLConfig: *
* *
* Input parameters: *
* libHandle - Hdmi library handle, provided on initializing the library. *
* pVidTransInfo - information about timing, bpc and packing *
* pClientCtrl - settings client wants to see set. HDMI lib tries to honor these *
* pSinkCaps - sink capabilities *
* *
* Output parameters: *
* pFRLConfig - chosen FRL rate and DSC configuration *
* *
*************************************************************************************************/
NVHDMIPKT_RESULT
NvHdmi_QueryFRLConfig(NvHdmiPkt_Handle libHandle,
HDMI_VIDEO_TRANSPORT_INFO const * const pVidTransInfo,
HDMI_QUERY_FRL_CLIENT_CONTROL const * const pClientCtrl,
HDMI_SRC_CAPS const * const pSrcCaps,
HDMI_SINK_CAPS const * const pSinkCaps,
HDMI_FRL_CONFIG *pFRLConfig);
/************************************************************************************************
* NvHdmi_SetFRLConfig: *
* *
* Input parameters: *
* libHandle - Hdmi library handle, provided on initializing the library. *
* subDevice - Sub Device ID. *
* displayId - Display ID. *
* bFakeLt - Indicates that the GPU's link configuration should be forced and that *
* configuration of the sink device should be skipped. *
* pFRLConfig - Link configuration to set. *
* *
************************************************************************************************/
NVHDMIPKT_RESULT
NvHdmi_SetFRLConfig(NvHdmiPkt_Handle libHandle,
NvU32 subDevice,
NvU32 displayId,
NvBool bFakeLt,
HDMI_FRL_CONFIG *pFRLConfig);
/************************************************************************************************
* NvHdmi_ClearFRLConfig: *
* *
* Input parameters: *
* libHandle - Hdmi library handle, provided on initializing the library. *
* subDevice - Sub Device ID. *
* displayId - Display ID to change the settings on. *
* *
************************************************************************************************/
NVHDMIPKT_RESULT
NvHdmi_ClearFRLConfig(NvHdmiPkt_Handle libHandle,
NvU32 subDevice,
NvU32 displayId);
#ifdef __cplusplus
}
#endif
#endif // _NVHDMI_FRLINTERFACE_H_

View File

@@ -0,0 +1,616 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* File: nvhdmipkt.c
*
* Purpose: Provide initialization functions for HDMI library
*/
#include "nvlimits.h"
#include "nvhdmipkt_common.h"
#include "nvhdmipkt_class.h"
#include "nvhdmipkt_internal.h"
#include "../timing/nvt_dsc_pps.h"
#include "class/cl9170.h"
#include "class/cl917d.h"
#include "class/cl9270.h"
#include "class/cl927d.h"
#include "class/cl9470.h"
#include "class/cl947d.h"
#include "class/cl9570.h"
#include "class/cl957d.h"
#include "class/clc370.h"
#include "class/clc37d.h"
#include "class/clc570.h"
#include "class/clc57d.h"
#include "class/clc670.h"
#include "class/clc67d.h"
// Class hierarchy structure
typedef struct tagNVHDMIPKT_CLASS_HIERARCHY
{
NVHDMIPKT_CLASS_ID classId;
NVHDMIPKT_CLASS_ID parentClassId;
NvBool isRootClass;
void (*initInterface)(NVHDMIPKT_CLASS*);
NvBool (*constructor) (NVHDMIPKT_CLASS*);
void (*destructor) (NVHDMIPKT_CLASS*);
NvU32 displayClass;
NvU32 coreDmaClass;
} NVHDMIPKT_CLASS_HIERARCHY;
/*************************************************************************************************
* hierarchy structure establishes the relationship between classes. *
* If isRootClass=NV_TRUE, it is a root class, else it is a child of a class. classId *
* also acts as an index, and hence the order of the structure below should be maintanied. *
* *
* ASSUMPTION: There are two huge assumptions while creating the class relationship and *
* while traversing it. 1. That of the Class ID definitaion (NVHDMIPKT_CLASS_ID), which has *
* to be strictly indexed, that is 0, 1, 2... and so on. And 2. that the structure *
* CLASS_HIERARCHY (above) follow that indexing. That is NVHDMIPKT_0073_CLASS is value 0 and *
* the first entry in CLASS_HIERARCHY, NVHDMIPKT_9171_CLASS is value 1 and hence the second *
* entry in CLASS_HIERARCHY, so on and so forth. *
* *
* HOW TO ADD A NEW CLASS? *
* 1. Add an ID in NVHDMIPKT_CLASS_ID. *
* 2. Add a source file nvhdmipkt_XXXX.c, and include it into makefiles. Makefiles of *
* Mods, Windows, and Linux. *
* 3. Provide initializeHdmiPktInterfaceXXXX, hdmiConstructorXXXX, and, hdmiDestructorXXXX. *
* 4. Add functions that needs to be overridden in NVHDMIPKT_CLASS. *
* 5. Add a relationship in hierarchy[] array. The new class can be a subclass or a root. In *
* case of a root all the interfaces needs to be overridden in NVHDMIPKT_CLASS. *
************************************************************************************************/
static const NVHDMIPKT_CLASS_HIERARCHY hierarchy[] =
{
{// Index 0==NVHDMIPKT_0073_CLASS
NVHDMIPKT_0073_CLASS, // classId
NVHDMIPKT_0073_CLASS, // parentClassId
NV_TRUE, // isRootClass
initializeHdmiPktInterface0073, // initInterface
hdmiConstructor0073, // constructor
hdmiDestructor0073, // destructor
0, // displayClass
0 // coreDmaClass
},
{// Index 1==NVHDMIPKT_9171_CLASS
NVHDMIPKT_9171_CLASS, // classId
NVHDMIPKT_9171_CLASS, // parentClassId
NV_TRUE, // isRootClass
initializeHdmiPktInterface9171, // initInterface
hdmiConstructor9171, // constructor
hdmiDestructor9171, // destructor
NV9170_DISPLAY, // displayClass
NV917D_CORE_CHANNEL_DMA // coreDmaClass
},
{// Index 2==NVHDMIPKT_9271_CLASS
NVHDMIPKT_9271_CLASS, // classId
NVHDMIPKT_9171_CLASS, // parentClassId
NV_FALSE, // isRootClass
initializeHdmiPktInterface9271, // initInterface
hdmiConstructor9271, // constructor
hdmiDestructor9271, // destructor
NV9270_DISPLAY, // displayClass
NV927D_CORE_CHANNEL_DMA // coreDmaClass
},
{// Index 3==NVHDMIPKT_9471_CLASS
NVHDMIPKT_9471_CLASS, // classId
NVHDMIPKT_9171_CLASS, // parentClassId
NV_FALSE, // isRootClass
initializeHdmiPktInterface9471, // initInterface
hdmiConstructor9471, // constructor
hdmiDestructor9471, // destructor
NV9470_DISPLAY, // displayClass
NV947D_CORE_CHANNEL_DMA // coreDmaClass
},
{// Index 4==NVHDMIPKT_9571_CLASS
NVHDMIPKT_9571_CLASS, // classId
NVHDMIPKT_9171_CLASS, // parentClassId
NV_FALSE, // isRootClass
initializeHdmiPktInterface9571, // initInterface
hdmiConstructor9571, // constructor
hdmiDestructor9571, // destructor
NV9570_DISPLAY, // displayClass
NV957D_CORE_CHANNEL_DMA // coreDmaClass
},
{// Index 5==NVHDMIPKT_C371_CLASS
NVHDMIPKT_C371_CLASS, // classId
NVHDMIPKT_9171_CLASS, // parentClassId
NV_FALSE, // isRootClass
initializeHdmiPktInterfaceC371, // initInterface
hdmiConstructorC371, // constructor
hdmiDestructorC371, // destructor
NVC370_DISPLAY, // displayClass
NVC37D_CORE_CHANNEL_DMA // coreDmaClass
},
{// Index 6==NVHDMIPKT_C571_CLASS
// Note that Turing (C57x) has a distinct displayClass and coreDmaClass,
// but it inherits the _DISP_SF_USER class from Volta (C37x). We call this
// NVHDMIPKT_C571_CLASS, but reuse initInterface()/constructor()/destructor()
// from C371.
NVHDMIPKT_C571_CLASS,
NVHDMIPKT_9171_CLASS, // parentClassId
NV_FALSE, // isRootClass
initializeHdmiPktInterfaceC371, // initInterface
hdmiConstructorC371, // constructor
hdmiDestructorC371, // destructor
NVC570_DISPLAY, // displayClass
NVC57D_CORE_CHANNEL_DMA // coreDmaClass
},
{// Index 7==NVHDMIPKT_C671_CLASS
NVHDMIPKT_C671_CLASS, // classId
NVHDMIPKT_9171_CLASS, // parentClassId
NV_FALSE, // isRootClass
initializeHdmiPktInterfaceC671, // initInterface
hdmiConstructorC671, // constructor
hdmiDestructorC671, // destructor
NVC670_DISPLAY, // displayClass
NVC67D_CORE_CHANNEL_DMA // coreDmaClass
},
};
#if defined(DSC_CALLBACK_MODIFIED)
// Callbacks for DSC PPS library
void *hdmipktMallocCb(const void *clientHandle, NvLength size);
void hdmipktFreeCb(const void *clientHandle, void *pMemPtr);
void *hdmipktMallocCb(const void *clientHandle, NvLength size)
{
const NVHDMIPKT_CLASS *pClass = (const NVHDMIPKT_CLASS*)(clientHandle);
return pClass->callback.malloc(pClass->cbHandle, size);
}
void hdmipktFreeCb(const void *clientHandle, void *pMemPtr)
{
const NVHDMIPKT_CLASS *pClass = (const NVHDMIPKT_CLASS*)(clientHandle);
pClass->callback.free(pClass->cbHandle, pMemPtr);
}
#endif // DSC_CALLBACK_MODIFIED
/********************************** HDMI Library interfaces *************************************/
/*
* NvHdmiPkt_PacketCtrl
*/
NVHDMIPKT_RESULT
NvHdmiPkt_PacketCtrl(NvHdmiPkt_Handle libHandle,
NvU32 subDevice,
NvU32 displayId,
NvU32 head,
NVHDMIPKT_TYPE packetType,
NVHDMIPKT_TC transmitControl)
{
NVHDMIPKT_CLASS* pClass = fromHdmiPktHandle(libHandle);
if (libHandle == NVHDMIPKT_INVALID_HANDLE)
{
return NVHDMIPKT_LIBRARY_INIT_FAIL;
}
return pClass->hdmiPacketCtrl(pClass,
subDevice,
displayId,
head,
packetType,
transmitControl);
}
/*
* NvHdmiPkt_PacketWrite
*/
NVHDMIPKT_RESULT
NvHdmiPkt_PacketWrite(NvHdmiPkt_Handle libHandle,
NvU32 subDevice,
NvU32 displayId,
NvU32 head,
NVHDMIPKT_TYPE packetType,
NVHDMIPKT_TC transmitControl,
NvU32 packetLen,
NvU8 const *const pPacket)
{
NVHDMIPKT_CLASS* pClass = fromHdmiPktHandle(libHandle);
if (libHandle == NVHDMIPKT_INVALID_HANDLE)
{
return NVHDMIPKT_LIBRARY_INIT_FAIL;
}
return pClass->hdmiPacketWrite(pClass,
subDevice,
displayId,
head,
packetType,
transmitControl,
packetLen,
pPacket);
}
NVHDMIPKT_RESULT
NvHdmi_AssessLinkCapabilities(NvHdmiPkt_Handle libHandle,
NvU32 subDevice,
NvU32 displayId,
NVT_EDID_INFO const * const pSinkEdid,
HDMI_SRC_CAPS *pSrcCaps,
HDMI_SINK_CAPS *pSinkCaps)
{
if (libHandle == NVHDMIPKT_INVALID_HANDLE)
{
return NVHDMIPKT_LIBRARY_INIT_FAIL;
}
if (!pSinkEdid ||
!pSrcCaps ||
!pSinkCaps)
{
return NVHDMIPKT_INVALID_ARG;
}
NVHDMIPKT_CLASS* pClass = fromHdmiPktHandle(libHandle);
return pClass->hdmiAssessLinkCapabilities(pClass,
subDevice,
displayId,
pSinkEdid,
pSrcCaps,
pSinkCaps);
}
/*
* NvHdmi_QueryFRLConfig
*/
NVHDMIPKT_RESULT
NvHdmi_QueryFRLConfig(NvHdmiPkt_Handle libHandle,
HDMI_VIDEO_TRANSPORT_INFO const * const pVidTransInfo,
HDMI_QUERY_FRL_CLIENT_CONTROL const * const pClientCtrl,
HDMI_SRC_CAPS const * const pSrcCaps,
HDMI_SINK_CAPS const * const pSinkCaps,
HDMI_FRL_CONFIG *pFRLConfig)
{
if (libHandle == NVHDMIPKT_INVALID_HANDLE)
{
return NVHDMIPKT_LIBRARY_INIT_FAIL;
}
if (!pVidTransInfo ||
!pClientCtrl ||
!pSrcCaps ||
!pSinkCaps ||
!pFRLConfig)
{
return NVHDMIPKT_INVALID_ARG;
}
// if there is no FRL capability reported fail this call
if (pSinkCaps->linkMaxFRLRate == HDMI_FRL_DATA_RATE_NONE)
{
return NVHDMIPKT_FAIL;
}
NVHDMIPKT_CLASS* pClass = fromHdmiPktHandle(libHandle);
return pClass->hdmiQueryFRLConfig(pClass,
pVidTransInfo,
pClientCtrl,
pSrcCaps,
pSinkCaps,
pFRLConfig);
}
/*
* NvHdmi_SetFRLConfig
*/
NVHDMIPKT_RESULT
NvHdmi_SetFRLConfig(NvHdmiPkt_Handle libHandle,
NvU32 subDevice,
NvU32 displayId,
NvBool bFakeLt,
HDMI_FRL_CONFIG *pFRLConfig)
{
if (libHandle == NVHDMIPKT_INVALID_HANDLE)
{
return NVHDMIPKT_LIBRARY_INIT_FAIL;
}
if (!pFRLConfig)
{
return NVHDMIPKT_INVALID_ARG;
}
NVHDMIPKT_CLASS* pClass = fromHdmiPktHandle(libHandle);
return pClass->hdmiSetFRLConfig(pClass,
subDevice,
displayId,
bFakeLt,
pFRLConfig);
}
/*
* NvHdmi_ClearFRLConfig
*/
NVHDMIPKT_RESULT
NvHdmi_ClearFRLConfig(NvHdmiPkt_Handle libHandle,
NvU32 subDevice,
NvU32 displayId)
{
if (libHandle == NVHDMIPKT_INVALID_HANDLE)
{
return NVHDMIPKT_LIBRARY_INIT_FAIL;
}
NVHDMIPKT_CLASS* pClass = fromHdmiPktHandle(libHandle);
return pClass->hdmiClearFRLConfig(pClass,
subDevice,
displayId);
}
/*************************** HDMI Library internal helper functions *****************************/
/*
* NvHdmiPkt_HwClass2HdmiClass
* internal function; translates display/display-dma class to hdmi class
*/
static NVHDMIPKT_CLASS_ID
NvHdmiPkt_HwClass2HdmiClass(NvU32 const hwClass)
{
NVHDMIPKT_CLASS_ID hdmiClassId = NVHDMIPKT_9571_CLASS;
NvU32 i = 0;
for (i = 0; i < NVHDMIPKT_INVALID_CLASS; i++)
{
if ((hierarchy[i].displayClass == hwClass) ||
(hierarchy[i].coreDmaClass == hwClass))
{
hdmiClassId = hierarchy[i].classId;
break;
}
}
// Assign default class 73 to pre-Kepler families
if (hwClass < NV9170_DISPLAY)
{
hdmiClassId = NVHDMIPKT_0073_CLASS;
}
return hdmiClassId;
}
/*
* NvHdmiPkt_InitInterfaces
* internal function; calls class init interface functions
*/
static void
NvHdmiPkt_InitInterfaces(NVHDMIPKT_CLASS_ID const thisClassId,
NVHDMIPKT_CLASS* const pClass)
{
// Recurse to the root first, and then call each initInterface() method
// from root to child.
if (!hierarchy[thisClassId].isRootClass)
{
NvHdmiPkt_InitInterfaces(hierarchy[thisClassId].parentClassId, pClass);
}
hierarchy[thisClassId].initInterface(pClass);
}
static void
NvHdmiPkt_CallDestructors(NVHDMIPKT_CLASS_ID const thisClassId,
NVHDMIPKT_CLASS* const pClass)
{
// Destructor calls are made from this to root class.
hierarchy[thisClassId].destructor(pClass);
if (!hierarchy[thisClassId].isRootClass)
{
NvHdmiPkt_CallDestructors(hierarchy[thisClassId].parentClassId, pClass);
}
}
/*
* NvHdmiPkt_CallConstructors
* internal function; calls class constructors and returns boolean success/failure
*/
static NvBool
NvHdmiPkt_CallConstructors(NVHDMIPKT_CLASS_ID const thisClassId,
NVHDMIPKT_CLASS* const pClass)
{
// Recurse to the root first, and then call each constructor
// from root to child.
if (!hierarchy[thisClassId].isRootClass)
{
if (!NvHdmiPkt_CallConstructors(hierarchy[thisClassId].parentClassId, pClass))
{
return NV_FALSE;
}
}
if (!hierarchy[thisClassId].constructor(pClass))
{
if (!hierarchy[thisClassId].isRootClass)
{
// Backtrack on constructor failure
NvHdmiPkt_CallDestructors(hierarchy[thisClassId].parentClassId, pClass);
}
return NV_FALSE;
}
return NV_TRUE;
}
/******************************** HDMI Library Init functions ***********************************/
/*
* NvHdmiPkt_InitializeLibrary
*/
NvHdmiPkt_Handle
NvHdmiPkt_InitializeLibrary(NvU32 const hwClass,
NvU32 const numSubDevices,
NvHdmiPkt_CBHandle const cbHandle,
const NVHDMIPKT_CALLBACK* const pCallbacks,
NvU32 const sfUserHandle,
const NVHDMIPKT_RM_CLIENT_HANDLES* const pClientHandles)
{
NVHDMIPKT_CLASS* pClass = 0;
NvU32 i = 0;
NvBool result = NV_FALSE;
NVHDMIPKT_CLASS_ID thisClassId = NVHDMIPKT_INVALID_CLASS;
// Argument validations
if (pCallbacks == 0 || numSubDevices == 0)
{
goto NvHdmiPkt_InitializeLibrary_exit;
}
// Validating RM handles/callbacks
#if NVHDMIPKT_RM_CALLS_INTERNAL
if (sfUserHandle == 0 || pClientHandles == 0)
{
goto NvHdmiPkt_InitializeLibrary_exit;
}
#else // !NVHDMIPKT_RM_CALLS_INTERNAL
if (pCallbacks->rmGetMemoryMap == 0 ||
pCallbacks->rmFreeMemoryMap == 0 ||
pCallbacks->rmDispControl2 == 0)
{
goto NvHdmiPkt_InitializeLibrary_exit;
}
#endif // NVHDMIPKT_RM_CALLS_INTERNAL
// Mandatory mutex callbacks.
if (pCallbacks->acquireMutex == 0 || pCallbacks->releaseMutex == 0)
{
goto NvHdmiPkt_InitializeLibrary_exit;
}
// Mandatory memory allocation callbacks.
if (pCallbacks->malloc == 0 || pCallbacks->free == 0)
{
goto NvHdmiPkt_InitializeLibrary_exit;
}
pClass = pCallbacks->malloc(cbHandle, sizeof(NVHDMIPKT_CLASS));
if (!pClass)
{
goto NvHdmiPkt_InitializeLibrary_exit;
}
// 0. Get the hdmi class ID
thisClassId = NvHdmiPkt_HwClass2HdmiClass(hwClass);
// Init data
NVMISC_MEMSET(pClass, 0, sizeof(NVHDMIPKT_CLASS));
for (i = 0; i < NV_MAX_SUBDEVICES; i++)
{
pClass->memMap[i].subDevice = NVHDMIPKT_INVALID_SUBDEV;
}
pClass->numSubDevices = numSubDevices;
pClass->cbHandle = cbHandle;
pClass->thisId = thisClassId;
// RM handles/callbacks
#if NVHDMIPKT_RM_CALLS_INTERNAL
pClass->isRMCallInternal = NV_TRUE;
pClass->sfUserHandle = sfUserHandle;
pClass->clientHandles.hClient = pClientHandles->hClient;
pClass->clientHandles.hDevice = pClientHandles->hDevice;
pClass->clientHandles.hDisplay = pClientHandles->hDisplay;
for (i = 0; i < NV_MAX_SUBDEVICES; i++)
{
pClass->clientHandles.hSubDevices[i] = pClientHandles->hSubDevices[i];
}
#else // !NVHDMIPKT_RM_CALLS_INTERNAL
pClass->isRMCallInternal = NV_FALSE;
pClass->callback.rmGetMemoryMap = pCallbacks->rmGetMemoryMap;
pClass->callback.rmFreeMemoryMap = pCallbacks->rmFreeMemoryMap;
pClass->callback.rmDispControl2 = pCallbacks->rmDispControl2;
#endif // NVHDMIPKT_RM_CALLS_INTERNAL
pClass->callback.acquireMutex = pCallbacks->acquireMutex;
pClass->callback.releaseMutex = pCallbacks->releaseMutex;
pClass->callback.malloc = pCallbacks->malloc;
pClass->callback.free = pCallbacks->free;
#if !defined (NVHDMIPKT_DONT_USE_TIMER)
pClass->callback.setTimeout = pCallbacks->setTimeout;
pClass->callback.checkTimeout = pCallbacks->checkTimeout;
#endif
#if defined (DEBUG)
pClass->callback.print = pCallbacks->print;
pClass->callback.assert = pCallbacks->assert;
#endif
// 1. Init interfaces
NvHdmiPkt_InitInterfaces(thisClassId, pClass);
// 2. Constructor calls
result = NvHdmiPkt_CallConstructors(thisClassId, pClass);
#if defined(DSC_CALLBACK_MODIFIED)
DSC_CALLBACK callbacks;
NVMISC_MEMSET(&callbacks, 0, sizeof(DSC_CALLBACK));
callbacks.clientHandle = pClass;
callbacks.dscMalloc = hdmipktMallocCb;
callbacks.dscFree = hdmipktFreeCb;
DSC_InitializeCallback(callbacks);
#endif // DSC_CALLBACK_MODIFIED
NvHdmiPkt_InitializeLibrary_exit:
if (result)
{
NvHdmiPkt_Print(pClass, "Initialize Success.");
}
else
{
if (pClass)
{
NvHdmiPkt_Print(pClass, "Initialize Failed.");
}
if (pCallbacks && pCallbacks->free)
{
pCallbacks->free(cbHandle, pClass);
}
}
return (result == NV_TRUE) ? toHdmiPktHandle(pClass) : NVHDMIPKT_INVALID_HANDLE;
}
/*
* NvHdmiPkt_DestroyLibrary
*/
void
NvHdmiPkt_DestroyLibrary(NvHdmiPkt_Handle libHandle)
{
NVHDMIPKT_CLASS* pClass = fromHdmiPktHandle(libHandle);
NVHDMIPKT_CLASS_ID currClassId = NVHDMIPKT_0073_CLASS;
if (pClass != 0)
{
NvHdmiPkt_Print(pClass, "Destroy.");
NvHdmiPkt_CBHandle cbHandle = pClass->cbHandle;
void (*freeCb) (NvHdmiPkt_CBHandle handle,
void *pMem) = pClass->callback.free;
currClassId = pClass->thisId;
NvHdmiPkt_CallDestructors(currClassId, pClass);
freeCb(cbHandle, pClass);
}
}

View File

@@ -0,0 +1,317 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* File: nvhdmipkt.h
*
* Purpose: This file is a common header for all HDMI Library Clients
*/
#ifndef _NVHDMIPKT_H_
#define _NVHDMIPKT_H_
#include <nvlimits.h>
#include "nvmisc.h"
#ifdef __cplusplus
extern "C" {
#endif
/**************************** HDMI Library defines, enums and structs ***************************/
/************************************************************************************************
* NOTE: NVHDMIPKT_RM_CALLS_INTERNAL define tells this library to make RM calls (allocate, free *
* control, etc.) internally and not through callbacks into the client. *
************************************************************************************************/
#if !defined(NVHDMIPKT_RM_CALLS_INTERNAL)
# define NVHDMIPKT_RM_CALLS_INTERNAL 1
#endif
// NVHDMIPKT_RESULT: HDMI library return result enums
typedef enum
{
NVHDMIPKT_SUCCESS = 0,
NVHDMIPKT_FAIL = 1,
NVHDMIPKT_LIBRARY_INIT_FAIL = 2,
NVHDMIPKT_INVALID_ARG = 3,
NVHDMIPKT_TIMEOUT = 4,
NVHDMIPKT_ERR_GENERAL = 5,
NVHDMIPKT_INSUFFICIENT_BANDWIDTH = 6,
NVHDMIPKT_RETRY = 7
} NVHDMIPKT_RESULT;
// NVHDMIPKT_TYPE: HDMI Packet Enums
typedef enum _NVHDMIPKT_TYPE
{
NVHDMIPKT_TYPE_UNDEFINED = 0, // Undefined Packet Type
NVHDMIPKT_TYPE_GENERIC = 1, // Generic packet, any Generic Packet
// (e.g Gamut Metadata packet)
NVHDMIPKT_TYPE_AVI_INFOFRAME = 2, // Avi infoframe
NVHDMIPKT_TYPE_GENERAL_CONTROL = 3, // GCP
NVHDMIPKT_TYPE_VENDOR_SPECIFIC_INFOFRAME = 4, // VSI
NVHDMIPKT_TYPE_AUDIO_INFOFRAME = 5, // Audio InfoFrame
NVHDMIPKT_TYPE_EXTENDED_METADATA_PACKET = 6, // Extended Metadata Packet (HDMI 2.1)
NVHDMIPKT_INVALID_PKT_TYPE = 13
} NVHDMIPKT_TYPE;
// Hdmi packet TransmitControl defines. These definitions reflect the
// defines from ctrl and class defines for info frames.
#define NV_HDMI_PKT_TRANSMIT_CTRL_ENABLE 0:0
#define NV_HDMI_PKT_TRANSMIT_CTRL_ENABLE_DIS 0x00000000
#define NV_HDMI_PKT_TRANSMIT_CTRL_ENABLE_EN 0x00000001
#define NV_HDMI_PKT_TRANSMIT_CTRL_OTHER 1:1
#define NV_HDMI_PKT_TRANSMIT_CTRL_OTHER_DIS 0x00000000
#define NV_HDMI_PKT_TRANSMIT_CTRL_OTHER_EN 0x00000001
#define NV_HDMI_PKT_TRANSMIT_CTRL_SINGLE 2:2
#define NV_HDMI_PKT_TRANSMIT_CTRL_SINGLE_DIS 0x00000000
#define NV_HDMI_PKT_TRANSMIT_CTRL_SINGLE_EN 0x00000001
#define NV_HDMI_PKT_TRANSMIT_CTRL_CHKSUM_HW 3:3
#define NV_HDMI_PKT_TRANSMIT_CTRL_CHKSUM_HW_DIS 0x00000000
#define NV_HDMI_PKT_TRANSMIT_CTRL_CHKSUM_HW_EN 0x00000001
#define NV_HDMI_PKT_TRANSMIT_CTRL_HBLANK 4:4
#define NV_HDMI_PKT_TRANSMIT_CTRL_HBLANK_DIS 0x00000000
#define NV_HDMI_PKT_TRANSMIT_CTRL_HBLANK_EN 0x00000001
#define NV_HDMI_PKT_TRANSMIT_CTRL_VIDEO_FMT 5:5
#define NV_HDMI_PKT_TRANSMIT_CTRL_VIDEO_FMT_SW_CTRL 0x00000000
#define NV_HDMI_PKT_TRANSMIT_CTRL_VIDEO_FMT_HW_CTRL 0x00000001
// NVHDMIPKT_TC: HDMI Packet Transmit Control
// NOTE: Client should use these defines below for transmit control, and avoid using the ones
// above. Use only if client knows and wants fine control. And in that case the value
// passed has to be explicitly typecasted to NVHDMIPKT_TC by the client.
typedef enum _NVHDMIPKT_TC
{
NVHDMIPKT_TRANSMIT_CONTROL_DISABLE =
(DRF_DEF(_HDMI_PKT, _TRANSMIT_CTRL, _ENABLE, _DIS) |
DRF_DEF(_HDMI_PKT, _TRANSMIT_CTRL, _OTHER, _DIS) |
DRF_DEF(_HDMI_PKT, _TRANSMIT_CTRL, _SINGLE, _DIS) |
DRF_DEF(_HDMI_PKT, _TRANSMIT_CTRL, _CHKSUM_HW, _DIS)),
NVHDMIPKT_TRANSMIT_CONTROL_ENABLE_EVERY_FRAME =
(DRF_DEF(_HDMI_PKT, _TRANSMIT_CTRL, _ENABLE, _EN) |
DRF_DEF(_HDMI_PKT, _TRANSMIT_CTRL, _OTHER, _DIS) |
DRF_DEF(_HDMI_PKT, _TRANSMIT_CTRL, _SINGLE, _DIS) |
DRF_DEF(_HDMI_PKT, _TRANSMIT_CTRL, _CHKSUM_HW, _EN)),
NVHDMIPKT_TRANSMIT_CONTROL_ENABLE_SINGLE_FRAME =
(DRF_DEF(_HDMI_PKT, _TRANSMIT_CTRL, _ENABLE, _EN) |
DRF_DEF(_HDMI_PKT, _TRANSMIT_CTRL, _OTHER, _DIS) |
DRF_DEF(_HDMI_PKT, _TRANSMIT_CTRL, _SINGLE, _EN) |
DRF_DEF(_HDMI_PKT, _TRANSMIT_CTRL, _CHKSUM_HW, _EN)),
NVHDMIPKT_TRANSMIT_CONTROL_ENABLE_EVERY_OTHER_FRAME =
(DRF_DEF(_HDMI_PKT, _TRANSMIT_CTRL, _ENABLE, _EN) |
DRF_DEF(_HDMI_PKT, _TRANSMIT_CTRL, _OTHER, _EN) |
DRF_DEF(_HDMI_PKT, _TRANSMIT_CTRL, _SINGLE, _DIS) |
DRF_DEF(_HDMI_PKT, _TRANSMIT_CTRL, _CHKSUM_HW, _EN)),
NVHDMIPKT_TRANSMIT_CONTROL_VIDEO_FMT_HW_CTRL =
(DRF_DEF(_HDMI_PKT, _TRANSMIT_CTRL, _VIDEO_FMT, _HW_CTRL)),
} NVHDMIPKT_TC;
// RM client handles. Used when client chooses that hdmi library make RM calls.
// NOTE: NVHDMIPKT_RM_CALLS_INTERNAL macro should be define to use it.
typedef struct tagNVHDMIPKT_RM_CLIENT_HANDLES
{
NvU32 hClient;
NvU32 hDevice;
NvU32 hSubDevices[NV_MAX_SUBDEVICES];
NvU32 hDisplay;
} NVHDMIPKT_RM_CLIENT_HANDLES;
/****************************** HDMI Library callbacks into client ******************************/
typedef void* NvHdmiPkt_CBHandle;
/************************************************************************************************
* [rmGetMemoryMap, rmFreeMemoryMap, rmDispControl,] acquireMutex and releaseMutex are mandatory*
* callbacks, to be implemented by the client. Callbacks in [] above are mandatory only for *
* Windows. *
* Linux need not implement those, if they plan to use NVHDMIPKT_RM_CALLS_INTERNAL define. *
* *
* rmGetMemoryMap and rmFreeMemoryMap are RM calls to allocate the DISP_SF_USER class. *
* And mutex callbacks keep hemi packet operations atomic. *
************************************************************************************************/
typedef struct _tagNVHDMIPKT_CALLBACK
{
// MANDATORY callbacks.
NvBool
(*rmGetMemoryMap) (NvHdmiPkt_CBHandle handle,
NvU32 dispSfUserClassId,
NvU32 dispSfUserSize,
NvU32 subDevice,
NvU32* pMemHandle,
void** ppBaseMem);
void
(*rmFreeMemoryMap) (NvHdmiPkt_CBHandle handle,
NvU32 subDevice,
NvU32 memHandle,
void* pMem);
NvBool
(*rmDispControl2) (NvHdmiPkt_CBHandle handle,
NvU32 subDevice,
NvU32 cmd,
void* pParams,
NvU32 paramSize);
void
(*acquireMutex) (NvHdmiPkt_CBHandle handle);
void
(*releaseMutex) (NvHdmiPkt_CBHandle handle);
// OPTIONAL callbacks
/* time in microseconds (us) */
NvBool
(*setTimeout) (NvHdmiPkt_CBHandle handle,
NvU32 us_timeout);
/* ChecTimeout returns true when timer times out */
NvBool
(*checkTimeout) (NvHdmiPkt_CBHandle handle);
// callbacks to allocate memory on heap to reduce stack usage
void*
(*malloc) (NvHdmiPkt_CBHandle handle,
NvLength numBytes);
void
(*free) (NvHdmiPkt_CBHandle handle,
void *pMem);
void
(*print) (NvHdmiPkt_CBHandle handle,
const char* fmtstring,
...)
#if defined(__GNUC__)
__attribute__ ((format (printf, 2, 3)))
#endif
;
void
(*assert) (NvHdmiPkt_CBHandle handle,
NvBool expression);
} NVHDMIPKT_CALLBACK;
/*********************** HDMI Library interface to write hdmi ctrl/packet ***********************/
typedef void* NvHdmiPkt_Handle;
#define NVHDMIPKT_INVALID_HANDLE ((NvHdmiPkt_Handle)0)
/************************************************************************************************
* NvHdmiPkt_PacketCtrl - Returns HDMI NVHDMIPKT_RESULT. *
* *
* Parameters: *
* libHandle - Hdmi library handle, provided on initializing the library. *
* subDevice - Sub Device ID. *
* displayId - Display ID. *
* head - Head number. *
* packetType - One of the NVHDMIPKT_TYPE types. *
* transmitControl - Packet transmit control setting. *
************************************************************************************************/
NVHDMIPKT_RESULT
NvHdmiPkt_PacketCtrl (NvHdmiPkt_Handle libHandle,
NvU32 subDevice,
NvU32 displayId,
NvU32 head,
NVHDMIPKT_TYPE packetType,
NVHDMIPKT_TC transmitControl);
/************************************************************************************************
* NvHdmiPkt_PacketWrite - Returns HDMI NVHDMIPKT_RESULT. *
* *
* Parameters: *
* libHandle - Hdmi library handle, provided on initializing the library. *
* subDevice - Sub Device ID. *
* displayId - Display ID. *
* head - Head number. *
* packetType - One of the NVHDMIPKT_TYPE types. *
* transmitControl - Packet transmit control setting. *
* packetLen - Length of the packet in bytes to be transmitted. *
* pPacket - Pointer to packet data. *
************************************************************************************************/
NVHDMIPKT_RESULT
NvHdmiPkt_PacketWrite(NvHdmiPkt_Handle libHandle,
NvU32 subDevice,
NvU32 displayId,
NvU32 head,
NVHDMIPKT_TYPE packetType,
NVHDMIPKT_TC transmitControl,
NvU32 packetLen,
NvU8 const *const pPacket);
/***************************** Interface to initialize HDMI Library *****************************/
/************************************************************************************************
* NvHdmiPkt_InitializeLibrary - Returns NvHdmiPkt_Handle. This handle is used to call *
* library interfaces. If handle returned is invalid - *
* NVHDMIPKT_INVALID_HANDLE -, there was a problem in *
* initialization and the library won't work. *
* *
* Parameters: *
* hwClass - Depending on HW, apply display class or display dma class. Either will do.*
* Eg. for GK104- NV9170_DISPLAY or NV917D_CORE_CHANNEL_DMA. *
* numSubDevices - Number of sub devices. *
* *
* cbHandle - Callback handle. Client cookie for callbacks made to client. *
* pCallback - Callbacks. Struct NVHDMIPKT_CALLBACK. *
* *
* Below mentioned sfUserHandle and clientHandles parameters are used only when not providing *
* rmGetMemoryMap, rmFreeMemoryMap and rmDispControl callbacks. This is meant for Linux. *
* And is controlled by NVHDMIPKT_RM_CALLS_INTERNAL macro. *
* NOTE: And Clients not using NVHDMIPKT_RM_CALLS_INTERNAL, need to set both sfUserHandle and *
* clientHandles to 0. *
* *
* sfUserHandle - SF_USER handle; this is the base handle. Subsequent subdevice handles are *
* derived incrementally from this handle. *
* pClientHandles - RM handles for client, device, subdevices and displayCommon. *
* *
************************************************************************************************/
NvHdmiPkt_Handle
NvHdmiPkt_InitializeLibrary(NvU32 const hwClass,
NvU32 const numSubDevices,
NvHdmiPkt_CBHandle const cbHandle,
const NVHDMIPKT_CALLBACK* const pCallback,
NvU32 const sfUserHandle,
const NVHDMIPKT_RM_CLIENT_HANDLES* const pClientHandles);
/************************************************************************************************
* NvHdmiPkt_DestroyLibrary *
* *
* When done with the HDMI Library call NvHdmiPkt_DestroyLibrary. It is like a destructor. *
* This destructor frees up resources acquired during initialize. *
* *
************************************************************************************************/
void
NvHdmiPkt_DestroyLibrary(NvHdmiPkt_Handle libHandle);
#ifdef __cplusplus
}
#endif
#endif // _NVHDMIPKT_H_

View File

@@ -0,0 +1,385 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* File: nvhdmipkt_0073.c
*
* Purpose: Provides infoframe write functions for HDMI library for Pre-KEPLER chips
*/
#include "nvhdmipkt_common.h"
#include "nvhdmipkt_class.h"
#include "nvhdmipkt_internal.h"
#include "hdmi_spec.h"
#include "ctrl/ctrl0073/ctrl0073specific.h"
NVHDMIPKT_RESULT
hdmiPacketCtrl0073(NVHDMIPKT_CLASS* pThis,
NvU32 subDevice,
NvU32 displayId,
NvU32 head,
NVHDMIPKT_TYPE packetType,
NVHDMIPKT_TC transmitControl);
NVHDMIPKT_RESULT
hdmiPacketWrite0073(NVHDMIPKT_CLASS* pThis,
NvU32 subDevice,
NvU32 displayId,
NvU32 head,
NVHDMIPKT_TYPE packetType,
NVHDMIPKT_TC transmitControl,
NvU32 packetLen,
NvU8 const *const pPacket);
/*
* hdmiPacketCtrl0073
*/
NVHDMIPKT_RESULT
hdmiPacketCtrl0073(NVHDMIPKT_CLASS* pThis,
NvU32 subDevice,
NvU32 displayId,
NvU32 head,
NVHDMIPKT_TYPE packetType,
NVHDMIPKT_TC transmitControl)
{
NVHDMIPKT_RESULT result = NVHDMIPKT_SUCCESS;
NV0073_CTRL_SPECIFIC_SET_OD_PACKET_CTRL_PARAMS params = {0};
NVMISC_MEMSET(&params, 0, sizeof(params));
params.subDeviceInstance = subDevice;
params.displayId = displayId;
params.type = pThis->translatePacketType(pThis, packetType);
params.transmitControl = pThis->translateTransmitControl(pThis, transmitControl);
#if NVHDMIPKT_RM_CALLS_INTERNAL
if (NvRmControl(pThis->clientHandles.hClient,
pThis->clientHandles.hDisplay,
NV0073_CTRL_CMD_SPECIFIC_SET_OD_PACKET_CTRL,
&params,
sizeof(params)) != NVOS_STATUS_SUCCESS)
#else // !NVHDMIPKT_RM_CALLS_INTERNAL
NvBool bSuccess = pThis->callback.rmDispControl2(pThis->cbHandle,
params.subDeviceInstance,
NV0073_CTRL_CMD_SPECIFIC_SET_OD_PACKET_CTRL,
&params, sizeof(params));
if (bSuccess == NV_FALSE)
#endif // NVHDMIPKT_RM_CALLS_INTERNAL
{
NvHdmiPkt_Print(pThis, "ERROR - RM call to hdmiPacketCtrl failed.");
NvHdmiPkt_Assert(0);
result = NVHDMIPKT_FAIL;
}
return result;
}
/*
* hdmiPacketWrite0073
*/
NVHDMIPKT_RESULT
hdmiPacketWrite0073(NVHDMIPKT_CLASS* pThis,
NvU32 subDevice,
NvU32 displayId,
NvU32 head,
NVHDMIPKT_TYPE packetType,
NVHDMIPKT_TC transmitControl,
NvU32 packetLen,
NvU8 const *const pPacket)
{
NVHDMIPKT_RESULT result = NVHDMIPKT_SUCCESS;
NV0073_CTRL_SPECIFIC_SET_OD_PACKET_PARAMS params = {0};
NVMISC_MEMSET(&params, 0, sizeof(params));
params.subDeviceInstance = subDevice;
params.displayId = displayId;
params.packetSize = packetLen;
params.transmitControl = pThis->translateTransmitControl(pThis, transmitControl);
// init the infoframe packet
NVMISC_MEMSET(params.aPacket, 0, NV0073_CTRL_SET_OD_MAX_PACKET_SIZE);
// copy the payload
NVMISC_MEMCPY(params.aPacket, pPacket, packetLen);
#if NVHDMIPKT_RM_CALLS_INTERNAL
if (NvRmControl(pThis->clientHandles.hClient,
pThis->clientHandles.hDisplay,
NV0073_CTRL_CMD_SPECIFIC_SET_OD_PACKET,
&params,
sizeof(params)) != NVOS_STATUS_SUCCESS)
#else // !NVHDMIPKT_RM_CALLS_INTERNAL
NvBool bSuccess = pThis->callback.rmDispControl2(pThis->cbHandle,
params.subDeviceInstance,
NV0073_CTRL_CMD_SPECIFIC_SET_OD_PACKET,
&params,
sizeof(params));
if (bSuccess == NV_FALSE)
#endif // NVHDMIPKT_RM_CALLS_INTERNAL
{
NvHdmiPkt_Print(pThis, "ERROR - RM call to hdmiPacketWrite failed.");
NvHdmiPkt_Assert(0);
result = NVHDMIPKT_FAIL;
}
return result;
}
/*
* translatePacketType0073
*/
static NvU32
translatePacketType0073(NVHDMIPKT_CLASS* pThis,
NVHDMIPKT_TYPE packetType)
{
NvU32 type0073 = 0;
switch (packetType)
{
case NVHDMIPKT_TYPE_AVI_INFOFRAME:
type0073 = pktType_AviInfoFrame;
break;
case NVHDMIPKT_TYPE_GENERIC:
type0073 = pktType_GamutMetadata;
break;
case NVHDMIPKT_TYPE_GENERAL_CONTROL:
type0073 = pktType_GeneralControl;
break;
case NVHDMIPKT_TYPE_VENDOR_SPECIFIC_INFOFRAME:
type0073 = pktType_VendorSpecInfoFrame;
break;
case NVHDMIPKT_TYPE_AUDIO_INFOFRAME:
type0073 = pktType_AudioInfoFrame;
break;
default:
NvHdmiPkt_Print(pThis, "ERROR - translatePacketType wrong packet type: %0x",
packetType);
NvHdmiPkt_Assert(0);
break;
}
return type0073;
}
/*
* translateTransmitControl0073
*/
static NvU32
translateTransmitControl0073(NVHDMIPKT_CLASS* pThis,
NVHDMIPKT_TC transmitControl)
{
NvU32 tc = 0;
// TODO: tc validation
if (FLD_TEST_DRF(_HDMI_PKT, _TRANSMIT_CTRL, _ENABLE, _EN, transmitControl))
{
tc = FLD_SET_DRF(0073, _CTRL_SPECIFIC_SET_OD_PACKET_CTRL_TRANSMIT_CONTROL,
_ENABLE, _YES, tc);
}
if (FLD_TEST_DRF(_HDMI_PKT, _TRANSMIT_CTRL, _OTHER, _EN, transmitControl))
{
tc = FLD_SET_DRF(0073, _CTRL_SPECIFIC_SET_OD_PACKET_CTRL_TRANSMIT_CONTROL,
_OTHER_FRAME, _ENABLE, tc);
}
if (FLD_TEST_DRF(_HDMI_PKT, _TRANSMIT_CTRL, _SINGLE, _EN, transmitControl))
{
tc = FLD_SET_DRF(0073, _CTRL_SPECIFIC_SET_OD_PACKET_CTRL_TRANSMIT_CONTROL,
_SINGLE_FRAME, _ENABLE, tc);
}
if (FLD_TEST_DRF(_HDMI_PKT, _TRANSMIT_CTRL, _HBLANK, _EN, transmitControl))
{
tc = FLD_SET_DRF(0073, _CTRL_SPECIFIC_SET_OD_PACKET_CTRL_TRANSMIT_CONTROL,
_ON_HBLANK, _ENABLE, tc);
}
if (FLD_TEST_DRF(_HDMI_PKT, _TRANSMIT_CTRL, _VIDEO_FMT, _HW_CTRL, transmitControl))
{
tc = FLD_SET_DRF(0073, _CTRL_SPECIFIC_SET_OD_PACKET_CTRL_TRANSMIT_CONTROL,
_VIDEO_FMT, _HW_CONTROLLED, tc);
}
return tc;
}
// non-HW - class utility/maintenance functions
/*
* hdmiConstructor0073
*/
NvBool
hdmiConstructor0073(NVHDMIPKT_CLASS* pThis)
{
return NV_TRUE;
}
/*
* hdmiUnDestructor0073
*/
void
hdmiDestructor0073(NVHDMIPKT_CLASS* pThis)
{
return;
}
// Below are dummy functions for the HW functions not needed for a display class
/*
* hdmiWriteDummyPacket
*/
void
hdmiWriteDummyPacket(NVHDMIPKT_CLASS* pThis,
NvU32* pBaseReg,
NvU32 head,
NvU32 packetLen,
NvU8 const *const pPacket)
{
NvHdmiPkt_Print(pThis, "ERROR - Dummy function hdmiWriteDummyPacket called. "
"Should never be called.");
NvHdmiPkt_Assert(0);
return;
}
/*
* hdmiReadDummyPacketStatus
*/
static NvBool
hdmiReadDummyPacketStatus(NVHDMIPKT_CLASS* pThis,
NvU32* pBaseReg,
NvU32 head,
NvU32 pktType0073)
{
NvHdmiPkt_Print(pThis, "ERROR - Dummy function hdmiReadDummyPacketStatus called. "
"Should never be called.");
NvHdmiPkt_Assert(0);
return NV_TRUE;
}
/*
* hdmiWriteDummyPacketCtrl
*/
static NVHDMIPKT_RESULT
hdmiWriteDummyPacketCtrl(NVHDMIPKT_CLASS* pThis,
NvU32* pBaseReg,
NvU32 head,
NvU32 pktType0073,
NvU32 transmitControl,
NvBool bDisable)
{
NvHdmiPkt_Print(pThis, "ERROR - Dummy function hdmiWriteDummyPacketCtrl called. "
"Should never be called.");
NvHdmiPkt_Assert(0);
return NVHDMIPKT_SUCCESS;
}
NVHDMIPKT_RESULT
hdmiAssessLinkCapabilitiesDummy(NVHDMIPKT_CLASS *pThis,
NvU32 subDevice,
NvU32 displayId,
NVT_EDID_INFO const * const pSinkEdid,
HDMI_SRC_CAPS *pSrcCaps,
HDMI_SINK_CAPS *pSinkCaps)
{
NvHdmiPkt_Print(pThis, "ERROR - Dummy function hdmiAssessLinkCapabilitiesDummy called. "
"Should never be called.");
NvHdmiPkt_Assert(0);
return NVHDMIPKT_SUCCESS;
}
NVHDMIPKT_RESULT
hdmiQueryFRLConfigDummy(NVHDMIPKT_CLASS *pThis,
HDMI_VIDEO_TRANSPORT_INFO const * const pVidTransInfo,
HDMI_QUERY_FRL_CLIENT_CONTROL const * const pClientCtrl,
HDMI_SRC_CAPS const * const pSrcCaps,
HDMI_SINK_CAPS const * const pSinkCaps,
HDMI_FRL_CONFIG *pFRLConfig)
{
NvHdmiPkt_Print(pThis, "ERROR - Dummy function hdmiQueryFRLConfigDummy called. "
"Should never be called.");
NvHdmiPkt_Assert(0);
return NVHDMIPKT_SUCCESS;
}
NVHDMIPKT_RESULT
hdmiSetFRLConfigDummy(NVHDMIPKT_CLASS *pThis,
NvU32 subDevice,
NvU32 displayId,
NvBool bFakeLt,
HDMI_FRL_CONFIG *pFRLConfig)
{
NvHdmiPkt_Print(pThis, "ERROR - Dummy function hdmiSetFRLConfigDummy called. "
"Should never be called.");
NvHdmiPkt_Assert(0);
return NVHDMIPKT_SUCCESS;
}
NVHDMIPKT_RESULT
hdmiClearFRLConfigDummy(NVHDMIPKT_CLASS *pThis,
NvU32 subDevice,
NvU32 displayId)
{
NvHdmiPkt_Print(pThis, "ERROR - Dummy function hdmiClearFRLConfigDummy called. "
"Should never be called.");
NvHdmiPkt_Assert(0);
return NVHDMIPKT_SUCCESS;
}
/*
* initializeHdmiPktInterface0073
*/
void
initializeHdmiPktInterface0073(NVHDMIPKT_CLASS* pClass)
{
pClass->hdmiPacketCtrl = hdmiPacketCtrl0073;
pClass->hdmiPacketWrite = hdmiPacketWrite0073;
pClass->translatePacketType = translatePacketType0073;
pClass->translateTransmitControl = translateTransmitControl0073;
// Functions below are mapped to dummy functions, as not needed for HW before GK104
pClass->hdmiReadPacketStatus = hdmiReadDummyPacketStatus;
pClass->hdmiWritePacketCtrl = hdmiWriteDummyPacketCtrl;
pClass->hdmiWriteAviPacket = hdmiWriteDummyPacket;
pClass->hdmiWriteAudioPacket = hdmiWriteDummyPacket;
pClass->hdmiWriteGenericPacket = hdmiWriteDummyPacket;
pClass->hdmiWriteGeneralCtrlPacket = hdmiWriteDummyPacket;
pClass->hdmiWriteVendorPacket = hdmiWriteDummyPacket;
// Update SF_USER data
pClass->dispSfUserClassId = 0;
pClass->dispSfUserSize = 0;
// Functions below are used by HDMI FRL and will be available for Ampere+.
pClass->hdmiAssessLinkCapabilities = hdmiAssessLinkCapabilitiesDummy;
pClass->hdmiQueryFRLConfig = hdmiQueryFRLConfigDummy;
pClass->hdmiSetFRLConfig = hdmiSetFRLConfigDummy;
pClass->hdmiClearFRLConfig = hdmiClearFRLConfigDummy;
}

View File

@@ -0,0 +1,804 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* File: nvhdmipkt_9171.c
*
* Purpose: Provides packet write functions for HDMI library for KEPLER + chips
*/
#include "nvlimits.h"
#include "nvhdmipkt_common.h"
#include "nvhdmipkt_class.h"
#include "nvhdmipkt_internal.h"
#include "hdmi_spec.h"
#include "class/cl9171.h"
#include "ctrl/ctrl0073/ctrl0073specific.h"
#define NVHDMIPKT_9171_INVALID_PKT_TYPE ((NV9171_SF_HDMI_INFO_IDX_VSI) + 1)
NVHDMIPKT_RESULT
hdmiPacketWrite9171(NVHDMIPKT_CLASS* pThis,
NvU32 subDevice,
NvU32 displayId,
NvU32 head,
NVHDMIPKT_TYPE packetType,
NVHDMIPKT_TC transmitControl,
NvU32 packetLen,
NvU8 const *const pPacket);
NVHDMIPKT_RESULT
hdmiPacketCtrl9171(NVHDMIPKT_CLASS* pThis,
NvU32 subDevice,
NvU32 displayId,
NvU32 head,
NVHDMIPKT_TYPE packetType,
NVHDMIPKT_TC transmitControl);
/*
* hdmiReadPacketStatus9171
*/
static NvBool
hdmiReadPacketStatus9171(NVHDMIPKT_CLASS* pThis,
NvU32* pBaseReg,
NvU32 head,
NvU32 pktType9171)
{
NvBool bResult = NV_FALSE;
NvU32 regOffset = 0;
NvU32 status = 0;
if (pBaseReg == 0 || head >= NV9171_SF_HDMI_INFO_STATUS__SIZE_1)
{
return bResult;
}
switch (pktType9171)
{
case NV9171_SF_HDMI_INFO_IDX_AVI_INFOFRAME:
case NV9171_SF_HDMI_INFO_IDX_GENERIC_INFOFRAME:
case NV9171_SF_HDMI_INFO_IDX_GCP:
case NV9171_SF_HDMI_INFO_IDX_VSI:
regOffset = NV9171_SF_HDMI_INFO_STATUS(head, pktType9171);
status = REG_RD32(pBaseReg, regOffset);
bResult = FLD_TEST_DRF(9171, _SF_HDMI_INFO_STATUS, _SENT, _DONE, status);
break;
default:
break;
}
return bResult;
}
/*
* hdmiWritePacketCtrl9171
*/
static NVHDMIPKT_RESULT
hdmiWritePacketCtrl9171(NVHDMIPKT_CLASS* pThis,
NvU32* pBaseReg,
NvU32 head,
NvU32 pktType9171,
NvU32 transmitControl,
NvBool bDisable)
{
NVHDMIPKT_RESULT result = NVHDMIPKT_INVALID_ARG;
NvU32 regOffset = 0;
NvU32 hdmiCtrl = 0;
if (pBaseReg == 0 || head >= NV9171_SF_HDMI_INFO_CTRL__SIZE_1)
{
return result;
}
switch (pktType9171)
{
case NV9171_SF_HDMI_INFO_IDX_AVI_INFOFRAME:
case NV9171_SF_HDMI_INFO_IDX_GENERIC_INFOFRAME:
case NV9171_SF_HDMI_INFO_IDX_GCP:
case NV9171_SF_HDMI_INFO_IDX_VSI:
regOffset = NV9171_SF_HDMI_INFO_CTRL(head, pktType9171);
hdmiCtrl = REG_RD32(pBaseReg, regOffset);
hdmiCtrl = (bDisable == NV_TRUE) ?
(FLD_SET_DRF(9171, _SF_HDMI_INFO_CTRL, _ENABLE, _DIS, hdmiCtrl)) :
(transmitControl);
REG_WR32(pBaseReg, regOffset, hdmiCtrl);
result = NVHDMIPKT_SUCCESS;
break;
default:
break;
}
return result;
}
/*
* hdmiWriteAviPacket9171
*/
static void
hdmiWriteAviPacket9171(NVHDMIPKT_CLASS* pThis,
NvU32* pBaseReg,
NvU32 head,
NvU32 packetLen,
NvU8 const *const pPacket)
{
NvU32 data = 0;
data = REG_RD32(pBaseReg, NV9171_SF_HDMI_AVI_INFOFRAME_HEADER(head));
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_AVI_INFOFRAME_HEADER, _HB0, pPacket[0], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_AVI_INFOFRAME_HEADER, _HB1, pPacket[1], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_AVI_INFOFRAME_HEADER, _HB2, pPacket[2], data);
REG_WR32(pBaseReg, NV9171_SF_HDMI_AVI_INFOFRAME_HEADER(head), data);
data = REG_RD32(pBaseReg, NV9171_SF_HDMI_AVI_INFOFRAME_SUBPACK0_LOW(head));
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_AVI_INFOFRAME_SUBPACK0_LOW, _PB0, pPacket[3], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_AVI_INFOFRAME_SUBPACK0_LOW, _PB1, pPacket[4], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_AVI_INFOFRAME_SUBPACK0_LOW, _PB2, pPacket[5], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_AVI_INFOFRAME_SUBPACK0_LOW, _PB3, pPacket[6], data);
REG_WR32(pBaseReg, NV9171_SF_HDMI_AVI_INFOFRAME_SUBPACK0_LOW(head), data);
data = REG_RD32(pBaseReg, NV9171_SF_HDMI_AVI_INFOFRAME_SUBPACK0_HIGH(head));
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_AVI_INFOFRAME_SUBPACK0_HIGH, _PB4, pPacket[7], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_AVI_INFOFRAME_SUBPACK0_HIGH, _PB5, pPacket[8], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_AVI_INFOFRAME_SUBPACK0_HIGH, _PB6, pPacket[9], data);
REG_WR32(pBaseReg, NV9171_SF_HDMI_AVI_INFOFRAME_SUBPACK0_HIGH(head), data);
data = REG_RD32(pBaseReg, NV9171_SF_HDMI_AVI_INFOFRAME_SUBPACK1_LOW(head));
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_AVI_INFOFRAME_SUBPACK1_LOW, _PB7, pPacket[10], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_AVI_INFOFRAME_SUBPACK1_LOW, _PB8, pPacket[11], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_AVI_INFOFRAME_SUBPACK1_LOW, _PB9, pPacket[12], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_AVI_INFOFRAME_SUBPACK1_LOW, _PB10, pPacket[13], data);
REG_WR32(pBaseReg, NV9171_SF_HDMI_AVI_INFOFRAME_SUBPACK1_LOW(head), data);
data = REG_RD32(pBaseReg, NV9171_SF_HDMI_AVI_INFOFRAME_SUBPACK1_HIGH(head));
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_AVI_INFOFRAME_SUBPACK1_HIGH, _PB11, pPacket[14], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_AVI_INFOFRAME_SUBPACK1_HIGH, _PB12, pPacket[15], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_AVI_INFOFRAME_SUBPACK1_HIGH, _PB13, pPacket[16], data);
REG_WR32(pBaseReg, NV9171_SF_HDMI_AVI_INFOFRAME_SUBPACK1_HIGH(head), data);
return;
}
/*
* hdmiWriteGenericPacket9171
*/
static void
hdmiWriteGenericPacket9171(NVHDMIPKT_CLASS* pThis,
NvU32* pBaseReg,
NvU32 head,
NvU32 packetLen,
NvU8 const *const pPacket)
{
NvU32 data = 0;
data = REG_RD32(pBaseReg, NV9171_SF_HDMI_GENERIC_HEADER(head));
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GENERIC_HEADER, _HB0, pPacket[0], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GENERIC_HEADER, _HB1, pPacket[1], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GENERIC_HEADER, _HB2, pPacket[2], data);
REG_WR32(pBaseReg, NV9171_SF_HDMI_GENERIC_HEADER(head), data);
data = REG_RD32(pBaseReg, NV9171_SF_HDMI_GENERIC_SUBPACK0_LOW(head));
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GENERIC_SUBPACK0_LOW, _PB0, pPacket[3], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GENERIC_SUBPACK0_LOW, _PB1, pPacket[4], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GENERIC_SUBPACK0_LOW, _PB2, pPacket[5], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GENERIC_SUBPACK0_LOW, _PB3, pPacket[6], data);
REG_WR32(pBaseReg, NV9171_SF_HDMI_GENERIC_SUBPACK0_LOW(head), data);
data = REG_RD32(pBaseReg, NV9171_SF_HDMI_GENERIC_SUBPACK0_HIGH(head));
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GENERIC_SUBPACK0_HIGH, _PB4, pPacket[7], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GENERIC_SUBPACK0_HIGH, _PB5, pPacket[8], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GENERIC_SUBPACK0_HIGH, _PB6, pPacket[9], data);
REG_WR32(pBaseReg, NV9171_SF_HDMI_GENERIC_SUBPACK0_HIGH(head), data);
data = REG_RD32(pBaseReg, NV9171_SF_HDMI_GENERIC_SUBPACK1_LOW(head));
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GENERIC_SUBPACK1_LOW, _PB7, pPacket[10], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GENERIC_SUBPACK1_LOW, _PB8, pPacket[11], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GENERIC_SUBPACK1_LOW, _PB9, pPacket[12], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GENERIC_SUBPACK1_LOW, _PB10, pPacket[13], data);
REG_WR32(pBaseReg, NV9171_SF_HDMI_GENERIC_SUBPACK1_LOW(head), data);
data = REG_RD32(pBaseReg, NV9171_SF_HDMI_GENERIC_SUBPACK1_HIGH(head));
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GENERIC_SUBPACK1_HIGH, _PB11, pPacket[14], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GENERIC_SUBPACK1_HIGH, _PB12, pPacket[15], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GENERIC_SUBPACK1_HIGH, _PB13, pPacket[16], data);
REG_WR32(pBaseReg, NV9171_SF_HDMI_GENERIC_SUBPACK1_HIGH(head), data);
data = REG_RD32(pBaseReg, NV9171_SF_HDMI_GENERIC_SUBPACK2_LOW(head));
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GENERIC_SUBPACK2_LOW, _PB14, pPacket[17], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GENERIC_SUBPACK2_LOW, _PB15, pPacket[18], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GENERIC_SUBPACK2_LOW, _PB16, pPacket[19], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GENERIC_SUBPACK2_LOW, _PB17, pPacket[20], data);
REG_WR32(pBaseReg, NV9171_SF_HDMI_GENERIC_SUBPACK2_LOW(head), data);
data = REG_RD32(pBaseReg, NV9171_SF_HDMI_GENERIC_SUBPACK2_HIGH(head));
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GENERIC_SUBPACK2_HIGH, _PB18, pPacket[21], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GENERIC_SUBPACK2_HIGH, _PB19, pPacket[22], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GENERIC_SUBPACK2_HIGH, _PB20, pPacket[23], data);
REG_WR32(pBaseReg, NV9171_SF_HDMI_GENERIC_SUBPACK2_HIGH(head), data);
data = REG_RD32(pBaseReg, NV9171_SF_HDMI_GENERIC_SUBPACK3_LOW(head));
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GENERIC_SUBPACK3_LOW, _PB21, pPacket[24], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GENERIC_SUBPACK3_LOW, _PB22, pPacket[25], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GENERIC_SUBPACK3_LOW, _PB23, pPacket[26], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GENERIC_SUBPACK3_LOW, _PB24, pPacket[27], data);
REG_WR32(pBaseReg, NV9171_SF_HDMI_GENERIC_SUBPACK3_LOW(head), data);
data = REG_RD32(pBaseReg, NV9171_SF_HDMI_GENERIC_SUBPACK3_HIGH(head));
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GENERIC_SUBPACK3_HIGH, _PB25, pPacket[28], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GENERIC_SUBPACK3_HIGH, _PB26, pPacket[29], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GENERIC_SUBPACK3_HIGH, _PB27, pPacket[30], data);
REG_WR32(pBaseReg, NV9171_SF_HDMI_GENERIC_SUBPACK3_HIGH(head), data);
return;
}
/*
* hdmiWriteGeneralCtrlPacket9171
*/
static void
hdmiWriteGeneralCtrlPacket9171(NVHDMIPKT_CLASS* pThis,
NvU32* pBaseReg,
NvU32 head,
NvU32 packetLen,
NvU8 const *const pPacket)
{
NvU32 data = 0;
// orIndexer info is ignored.
data = REG_RD32(pBaseReg, NV9171_SF_HDMI_GCP_SUBPACK(head));
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GCP_SUBPACK, _SB0, pPacket[3], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GCP_SUBPACK, _SB1, pPacket[4], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_GCP_SUBPACK, _SB2, pPacket[5], data);
REG_WR32(pBaseReg, NV9171_SF_HDMI_GCP_SUBPACK(head), data);
return;
}
/*
* hdmiWriteVendorPacket9171
*/
static void
hdmiWriteVendorPacket9171(NVHDMIPKT_CLASS* pThis,
NvU32* pBaseReg,
NvU32 head,
NvU32 packetLen,
NvU8 const *const pPacketIn)
{
NvU32 data = 0;
NvU8 pPacket[31] = {0};
NVMISC_MEMCPY(pPacket, pPacketIn, packetLen);
data = REG_RD32(pBaseReg, NV9171_SF_HDMI_VSI_HEADER(head));
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_VSI_HEADER, _HB0, pPacket[0], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_VSI_HEADER, _HB1, pPacket[1], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_VSI_HEADER, _HB2, pPacket[2], data);
REG_WR32(pBaseReg, NV9171_SF_HDMI_VSI_HEADER(head), data);
data = REG_RD32(pBaseReg, NV9171_SF_HDMI_VSI_SUBPACK0_LOW(head));
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_VSI_SUBPACK0_LOW, _PB0, pPacket[3], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_VSI_SUBPACK0_LOW, _PB1, pPacket[4], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_VSI_SUBPACK0_LOW, _PB2, pPacket[5], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_VSI_SUBPACK0_LOW, _PB3, pPacket[6], data);
REG_WR32(pBaseReg, NV9171_SF_HDMI_VSI_SUBPACK0_LOW(head), data);
data = REG_RD32(pBaseReg, NV9171_SF_HDMI_VSI_SUBPACK0_HIGH(head));
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_VSI_SUBPACK0_HIGH, _PB4, pPacket[7], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_VSI_SUBPACK0_HIGH, _PB5, pPacket[8], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_VSI_SUBPACK0_HIGH, _PB6, pPacket[9], data);
REG_WR32(pBaseReg, NV9171_SF_HDMI_VSI_SUBPACK0_HIGH(head), data);
data = REG_RD32(pBaseReg, NV9171_SF_HDMI_VSI_SUBPACK1_LOW(head));
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_VSI_SUBPACK1_LOW, _PB7, pPacket[10], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_VSI_SUBPACK1_LOW, _PB8, pPacket[11], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_VSI_SUBPACK1_LOW, _PB9, pPacket[12], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_VSI_SUBPACK1_LOW, _PB10, pPacket[13], data);
REG_WR32(pBaseReg, NV9171_SF_HDMI_VSI_SUBPACK1_LOW(head), data);
data = REG_RD32(pBaseReg, NV9171_SF_HDMI_VSI_SUBPACK1_HIGH(head));
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_VSI_SUBPACK1_HIGH, _PB11, pPacket[14], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_VSI_SUBPACK1_HIGH, _PB12, pPacket[15], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_VSI_SUBPACK1_HIGH, _PB13, pPacket[16], data);
REG_WR32(pBaseReg, NV9171_SF_HDMI_VSI_SUBPACK1_HIGH(head), data);
data = REG_RD32(pBaseReg, NV9171_SF_HDMI_VSI_SUBPACK2_LOW(head));
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_VSI_SUBPACK2_LOW, _PB14, pPacket[17], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_VSI_SUBPACK2_LOW, _PB15, pPacket[18], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_VSI_SUBPACK2_LOW, _PB16, pPacket[19], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_VSI_SUBPACK2_LOW, _PB17, pPacket[20], data);
REG_WR32(pBaseReg, NV9171_SF_HDMI_VSI_SUBPACK2_LOW(head), data);
data = REG_RD32(pBaseReg, NV9171_SF_HDMI_VSI_SUBPACK2_HIGH(head));
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_VSI_SUBPACK2_HIGH, _PB18, pPacket[21], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_VSI_SUBPACK2_HIGH, _PB19, pPacket[22], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_VSI_SUBPACK2_HIGH, _PB20, pPacket[23], data);
REG_WR32(pBaseReg, NV9171_SF_HDMI_VSI_SUBPACK2_HIGH(head), data);
data = REG_RD32(pBaseReg, NV9171_SF_HDMI_GENERIC_SUBPACK3_LOW(head));
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_VSI_SUBPACK3_LOW, _PB21, pPacket[24], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_VSI_SUBPACK3_LOW, _PB22, pPacket[25], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_VSI_SUBPACK3_LOW, _PB23, pPacket[26], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_VSI_SUBPACK3_LOW, _PB24, pPacket[27], data);
REG_WR32(pBaseReg, NV9171_SF_HDMI_VSI_SUBPACK3_LOW(head), data);
data = REG_RD32(pBaseReg, NV9171_SF_HDMI_VSI_SUBPACK3_HIGH(head));
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_VSI_SUBPACK3_HIGH, _PB25, pPacket[28], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_VSI_SUBPACK3_HIGH, _PB26, pPacket[29], data);
data = FLD_SET_DRF_NUM(9171, _SF_HDMI_VSI_SUBPACK3_HIGH, _PB27, pPacket[30], data);
REG_WR32(pBaseReg, NV9171_SF_HDMI_VSI_SUBPACK3_HIGH(head), data);
return;
}
/*
* translatePacketType9171
*/
static NvU32
translatePacketType9171(NVHDMIPKT_CLASS* pThis,
NVHDMIPKT_TYPE packetType)
{
NvU32 type9171 = NVHDMIPKT_9171_INVALID_PKT_TYPE;
switch (packetType)
{
case NVHDMIPKT_TYPE_AVI_INFOFRAME:
type9171 = NV9171_SF_HDMI_INFO_IDX_AVI_INFOFRAME;
break;
case NVHDMIPKT_TYPE_GENERIC:
type9171 = NV9171_SF_HDMI_INFO_IDX_GENERIC_INFOFRAME;
break;
case NVHDMIPKT_TYPE_GENERAL_CONTROL:
type9171 = NV9171_SF_HDMI_INFO_IDX_GCP;
break;
case NVHDMIPKT_TYPE_VENDOR_SPECIFIC_INFOFRAME:
type9171 = NV9171_SF_HDMI_INFO_IDX_VSI;
break;
case NVHDMIPKT_TYPE_AUDIO_INFOFRAME:
default:
NvHdmiPkt_Print(pThis, "ERROR - translatePacketType wrong packet type: %0x.",
packetType);
NvHdmiPkt_Assert(0);
break;
}
return type9171;
}
/*
* translateTransmitControl9171
*/
static NvU32
translateTransmitControl9171(NVHDMIPKT_CLASS* pThis,
NVHDMIPKT_TC transmitControl)
{
NvU32 tc = 0;
// TODO: tc validation
if (FLD_TEST_DRF(_HDMI_PKT, _TRANSMIT_CTRL, _ENABLE, _EN, transmitControl))
{
tc = FLD_SET_DRF(9171, _SF_HDMI_INFO_CTRL, _ENABLE, _EN, tc);
}
if (FLD_TEST_DRF(_HDMI_PKT, _TRANSMIT_CTRL, _OTHER, _EN, transmitControl))
{
tc = FLD_SET_DRF(9171, _SF_HDMI_INFO_CTRL, _OTHER, _EN, tc);
}
if (FLD_TEST_DRF(_HDMI_PKT, _TRANSMIT_CTRL, _SINGLE, _EN, transmitControl))
{
tc = FLD_SET_DRF(9171, _SF_HDMI_INFO_CTRL, _SINGLE, _EN, tc);
}
if (FLD_TEST_DRF(_HDMI_PKT, _TRANSMIT_CTRL, _CHKSUM_HW, _EN, transmitControl))
{
tc = FLD_SET_DRF(9171, _SF_HDMI_INFO_CTRL, _CHKSUM_HW, _EN, tc);
}
if (FLD_TEST_DRF(_HDMI_PKT, _TRANSMIT_CTRL, _HBLANK, _EN, transmitControl))
{
tc = FLD_SET_DRF(9171, _SF_HDMI_INFO_CTRL, _HBLANK, _EN, tc);
}
if (FLD_TEST_DRF(_HDMI_PKT, _TRANSMIT_CTRL, _VIDEO_FMT, _HW_CTRL, transmitControl))
{
tc = FLD_SET_DRF(9171, _SF_HDMI_INFO_CTRL, _VIDEO_FMT, _HW_CONTROLLED, tc);
}
return tc;
}
/*
* hdmiPacketCtrl9171
*/
NVHDMIPKT_RESULT
hdmiPacketCtrl9171(NVHDMIPKT_CLASS* pThis,
NvU32 subDevice,
NvU32 displayId,
NvU32 head,
NVHDMIPKT_TYPE packetType,
NVHDMIPKT_TC transmitControl)
{
NvU32* pBaseReg = (NvU32*)pThis->memMap[subDevice].pMemBase;
NvU32 pktType9171 = pThis->translatePacketType(pThis, packetType);
NvU32 tc = pThis->translateTransmitControl(pThis, transmitControl);
if (pBaseReg == 0 || head >= NV9171_SF_HDMI_AVI_INFOFRAME_CTRL__SIZE_1 ||
pktType9171 == NVHDMIPKT_9171_INVALID_PKT_TYPE)
{
return NVHDMIPKT_INVALID_ARG;
}
return pThis->hdmiWritePacketCtrl(pThis, pBaseReg, head, pktType9171, tc, NV_FALSE);
}
/*
* internal utility function
* checkPacketStatus
*/
static NVHDMIPKT_RESULT
checkPacketStatus(NVHDMIPKT_CLASS* pThis,
NvU32* pBaseReg,
NvU32 head,
NvU32 pktType9171)
{
NVHDMIPKT_RESULT result = NVHDMIPKT_SUCCESS;
NvBool bCheckPacketStatus = NV_TRUE;
NvU32 regOffset = 0;
NvU32 status = 0;
// check to see if timer callbacks are provided
if (pThis->callback.setTimeout == 0 || pThis->callback.checkTimeout == 0)
{
goto checkPacketStatus_exit;
}
// Mark packets that don't need status check
switch (pktType9171)
{
case NV9171_SF_HDMI_INFO_IDX_AVI_INFOFRAME:
case NV9171_SF_HDMI_INFO_IDX_GCP:
regOffset = NV9171_SF_HDMI_INFO_STATUS(head, pktType9171);
status = REG_RD32(pBaseReg, regOffset);
bCheckPacketStatus = FLD_TEST_DRF(9171, _SF_HDMI_INFO_CTRL, _SINGLE, _EN, status);
break;
default:
bCheckPacketStatus = NV_FALSE;
break;
}
if (bCheckPacketStatus == NV_TRUE)
{
if (pThis->callback.setTimeout(pThis->cbHandle, NVHDMIPKT_STATUS_READ_TIMEOUT_IN_us)
== NV_FALSE)
{
// Timer set failed
goto checkPacketStatus_exit;
}
while(pThis->hdmiReadPacketStatus(pThis, pBaseReg, head, pktType9171) == NV_FALSE)
{
if (pThis->callback.checkTimeout(pThis->cbHandle) == NV_TRUE)
{
// status check operation timed out
result = NVHDMIPKT_TIMEOUT;
goto checkPacketStatus_exit;
}
}
}
checkPacketStatus_exit:
return result;
}
/*
* hdmiPacketWrite9171
*/
NVHDMIPKT_RESULT
hdmiPacketWrite9171(NVHDMIPKT_CLASS* pThis,
NvU32 subDevice,
NvU32 displayId,
NvU32 head,
NVHDMIPKT_TYPE packetType,
NVHDMIPKT_TC transmitControl,
NvU32 packetLen,
NvU8 const *const pPacket)
{
NVHDMIPKT_RESULT result = NVHDMIPKT_SUCCESS;
NvU32* pBaseReg = (NvU32*)pThis->memMap[subDevice].pMemBase;
NvU32 pktType9171 = pThis->translatePacketType(pThis, packetType);
NvU32 tc = pThis->translateTransmitControl(pThis, transmitControl);
NV0073_CTRL_SPECIFIC_CTRL_HDMI_PARAMS params = {0};
if (pBaseReg == 0 || head >= NV9171_SF_HDMI_AVI_INFOFRAME_CTRL__SIZE_1 ||
packetLen == 0 || pPacket == 0 || pktType9171 == NVHDMIPKT_9171_INVALID_PKT_TYPE)
{
result = NVHDMIPKT_INVALID_ARG;
goto hdmiPacketWrite9171_exit;
}
// acquire mutex
pThis->callback.acquireMutex(pThis->cbHandle);
// Check status if last infoframe was sent out or not
if ((result = checkPacketStatus(pThis, pBaseReg, head, pktType9171)) ==
NVHDMIPKT_TIMEOUT)
{
NvHdmiPkt_Print(pThis, "ERROR - Packet status check timed out.");
NvHdmiPkt_Assert(0);
goto hdmiPacketWrite9171_release_mutex_exit;
}
// Disable this packet type.
pThis->hdmiWritePacketCtrl(pThis, pBaseReg, head, pktType9171, tc, NV_TRUE);
// write the packet
switch (pktType9171)
{
case NV9171_SF_HDMI_INFO_IDX_AVI_INFOFRAME:
pThis->hdmiWriteAviPacket(pThis, pBaseReg, head, packetLen, pPacket);
break;
case NV9171_SF_HDMI_INFO_IDX_GENERIC_INFOFRAME:
pThis->hdmiWriteGenericPacket(pThis, pBaseReg, head, packetLen, pPacket);
break;
case NV9171_SF_HDMI_INFO_IDX_GCP:
// Check whether the GCP packet is AVMute DISABLE or AvMute ENABLE
// Enable HDMI only on GCP unmute i.e. AVMUTE DISABLE
if (pPacket[HDMI_PKT_HDR_SIZE] == HDMI_GENCTRL_PACKET_MUTE_DISABLE)
{
// Enable HDMI.
NVMISC_MEMSET(&params, 0, sizeof(params));
params.subDeviceInstance = (NvU8)subDevice;
params.displayId = displayId;
params.bEnable = NV0073_CTRL_SPECIFIC_CTRL_HDMI_ENABLE;
#if NVHDMIPKT_RM_CALLS_INTERNAL
if (CALL_DISP_RM(NvRmControl)(pThis->clientHandles.hClient,
pThis->clientHandles.hDisplay,
NV0073_CTRL_CMD_SPECIFIC_CTRL_HDMI,
&params,
sizeof(params)) != NVOS_STATUS_SUCCESS)
#else // !NVHDMIPKT_RM_CALLS_INTERNAL
NvBool bSuccess = pThis->callback.rmDispControl2(pThis->cbHandle,
params.subDeviceInstance,
NV0073_CTRL_CMD_SPECIFIC_CTRL_HDMI,
&params,
sizeof(params));
if (bSuccess == NV_FALSE)
#endif // NVHDMIPKT_RM_CALLS_INTERNAL
{
NvHdmiPkt_Print(pThis, "ERROR - RM call to enable hdmi ctrl failed.");
NvHdmiPkt_Assert(0);
result = NVHDMIPKT_FAIL;
}
}
pThis->hdmiWriteGeneralCtrlPacket(pThis, pBaseReg, head, packetLen, pPacket);
break;
case NV9171_SF_HDMI_INFO_IDX_VSI:
pThis->hdmiWriteVendorPacket(pThis, pBaseReg, head, packetLen, pPacket);
break;
default:
result = NVHDMIPKT_INVALID_ARG;
break;
}
// Enable this infoframe.
pThis->hdmiWritePacketCtrl(pThis, pBaseReg, head, pktType9171, tc, NV_FALSE);
hdmiPacketWrite9171_release_mutex_exit:
// release mutex
pThis->callback.releaseMutex(pThis->cbHandle);
hdmiPacketWrite9171_exit:
return result;
}
// non-HW - class utility/maintenance functions
/*
* hdmiConstructor9171
*/
NvBool
hdmiConstructor9171(NVHDMIPKT_CLASS* pThis)
{
NvU32 i = 0;
NvBool result = NV_TRUE;
#if NVHDMIPKT_RM_CALLS_INTERNAL
for (i = 0; i < pThis->numSubDevices; i++)
{
if (CALL_DISP_RM(NvRmAlloc)(pThis->clientHandles.hClient,
pThis->clientHandles.hSubDevices[i],
pThis->sfUserHandle + i,
pThis->dispSfUserClassId,
(void*)0) != NVOS_STATUS_SUCCESS)
{
NvHdmiPkt_Print(pThis, "ERROR - Init failed. "
"Failed to alloc SF_USER handle");
NvHdmiPkt_Assert(0);
break;
}
pThis->memMap[i].memHandle = pThis->sfUserHandle + i;
if (CALL_DISP_RM(NvRmMapMemory)(pThis->clientHandles.hClient,
pThis->clientHandles.hSubDevices[i],
pThis->memMap[i].memHandle,
0,
pThis->dispSfUserSize,
&pThis->memMap[i].pMemBase,
0) != NVOS_STATUS_SUCCESS)
{
NvHdmiPkt_Print(pThis, "ERROR - Init failed. "
"Failed to map SF_USER memory.");
NvHdmiPkt_Assert(0);
break;
}
if (pThis->memMap[i].pMemBase == 0)
{
NvHdmiPkt_Print(pThis, "ERROR - Init failed. "
"SF_USER memory returned is NULL.");
NvHdmiPkt_Assert(0);
break;
}
pThis->memMap[i].subDevice = i;
}
// coudln't complete the loop above
if (i < pThis->numSubDevices)
{
result = NV_FALSE;
goto hdmiConstructor9171_exit;
}
#else // !NVHDMIPKT_RM_CALLS_INTERNAL
for (i = 0; i < pThis->numSubDevices; i++)
{
result = pThis->callback.rmGetMemoryMap(pThis->cbHandle,
pThis->dispSfUserClassId,
pThis->dispSfUserSize,
i,
&pThis->memMap[i].memHandle,
&pThis->memMap[i].pMemBase);
if (result == NV_TRUE)
{
pThis->memMap[i].subDevice = i;
}
else
{
NvHdmiPkt_Print(pThis, "ERROR - Init failed. "
"Failed to map SF_USER memory.");
NvHdmiPkt_Assert(0);
result = NV_FALSE;
goto hdmiConstructor9171_exit;
}
}
#endif // NVHDMIPKT_RM_CALLS_INTERNAL
hdmiConstructor9171_exit:
return result;
}
/*
* hdmiDestructor9171
*/
void
hdmiDestructor9171(NVHDMIPKT_CLASS* pThis)
{
NvU32 i = 0;
#if NVHDMIPKT_RM_CALLS_INTERNAL
for (i = 0; i < NV_MAX_SUBDEVICES; i++)
{
// free memory
if (pThis->memMap[i].pMemBase)
{
if (CALL_DISP_RM(NvRmUnmapMemory)(pThis->clientHandles.hClient,
pThis->clientHandles.hSubDevices[i],
pThis->memMap[i].memHandle,
pThis->memMap[i].pMemBase,
0) != NVOS_STATUS_SUCCESS)
{
NvHdmiPkt_Print(pThis, "ERROR - unInit failed. "
"SF_USER memory unMap failed.");
NvHdmiPkt_Assert(0);
}
}
// free handle
if (pThis->memMap[i].memHandle)
{
if (CALL_DISP_RM(NvRmFree)(pThis->clientHandles.hClient,
pThis->clientHandles.hSubDevices[i],
pThis->memMap[i].memHandle) != NVOS_STATUS_SUCCESS)
{
NvHdmiPkt_Print(pThis, "ERROR - unInit failed. "
"Freeing SF_USER memory handle failed.");
NvHdmiPkt_Assert(0);
}
}
pThis->memMap[i].subDevice = NVHDMIPKT_INVALID_SUBDEV;
pThis->memMap[i].memHandle = 0;
pThis->memMap[i].pMemBase = 0;
}
#else // !NVHDMIPKT_RM_CALLS_INTERNAL
for (i = 0; i < NV_MAX_SUBDEVICES; i++)
{
if (pThis->memMap[i].memHandle)
{
pThis->callback.rmFreeMemoryMap(pThis->cbHandle,
i,
pThis->memMap[i].memHandle,
pThis->memMap[i].pMemBase);
pThis->memMap[i].subDevice = NVHDMIPKT_INVALID_SUBDEV;
pThis->memMap[i].memHandle = 0;
pThis->memMap[i].pMemBase = 0;
}
}
#endif // NVHDMIPKT_RM_CALLS_INTERNAL
return;
}
/*
* initializeHdmiPktInterface9171
*/
void
initializeHdmiPktInterface9171(NVHDMIPKT_CLASS* pClass)
{
pClass->hdmiPacketCtrl = hdmiPacketCtrl9171;
pClass->hdmiPacketWrite = hdmiPacketWrite9171;
pClass->translatePacketType = translatePacketType9171;
pClass->translateTransmitControl = translateTransmitControl9171;
// HW register write functions
pClass->hdmiReadPacketStatus = hdmiReadPacketStatus9171;
pClass->hdmiWritePacketCtrl = hdmiWritePacketCtrl9171;
pClass->hdmiWriteAviPacket = hdmiWriteAviPacket9171;
pClass->hdmiWriteAudioPacket = hdmiWriteDummyPacket;
pClass->hdmiWriteGenericPacket = hdmiWriteGenericPacket9171;
pClass->hdmiWriteGeneralCtrlPacket = hdmiWriteGeneralCtrlPacket9171;
pClass->hdmiWriteVendorPacket = hdmiWriteVendorPacket9171;
// Update SF_USER data
pClass->dispSfUserClassId = NV9171_DISP_SF_USER;
pClass->dispSfUserSize = sizeof(Nv9171DispSfUserMap);
// Functions below are used by HDMI FRL and will be available for Ampere+.
pClass->hdmiAssessLinkCapabilities = hdmiAssessLinkCapabilitiesDummy;
pClass->hdmiQueryFRLConfig = hdmiQueryFRLConfigDummy;
pClass->hdmiSetFRLConfig = hdmiSetFRLConfigDummy;
pClass->hdmiClearFRLConfig = hdmiClearFRLConfigDummy;
}

View File

@@ -0,0 +1,71 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* File: nvhdmipkt_9271.c
*
* Purpose: Provides packet write functions for HDMI library for KEPLER + chips
*/
#include "nvhdmipkt_common.h"
#include "nvhdmipkt_class.h"
#include "nvhdmipkt_internal.h"
#include "class/cl9271.h"
/******************************************** NOTE ***********************************************
* This file serves as an example on how to add a new HW SF USER CLASS. Notice that this *
* Class didn't override any functions, as 9171 is identical to 9271. *
*************************************************************************************************/
// non-HW - class utility/maintenance functions
/*
* hdmiConstructor9271
*/
NvBool
hdmiConstructor9271(NVHDMIPKT_CLASS* pThis)
{
NvBool result = NV_TRUE;
return result;
}
/*
* hdmiDestructor9271
*/
void
hdmiDestructor9271(NVHDMIPKT_CLASS* pThis)
{
return;
}
/*
* initializeHdmiPktInterface9271
*/
void
initializeHdmiPktInterface9271(NVHDMIPKT_CLASS* pClass)
{
// Update SF_USER data
pClass->dispSfUserClassId = NV9271_DISP_SF_USER;
pClass->dispSfUserSize = sizeof(Nv9271DispSfUserMap);
}

View File

@@ -0,0 +1,71 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* File: nvhdmipkt_9471.c
*
* Purpose: Provides packet write functions for HDMI library for Maxwell + chips
*/
#include "nvhdmipkt_common.h"
#include "nvhdmipkt_class.h"
#include "nvhdmipkt_internal.h"
#include "class/cl9471.h"
/******************************************** NOTE ***********************************************
* This file serves as an example on how to add a new HW SF USER CLASS. Notice that this *
* Class didn't override any functions, as 9171 is identical to 9471. *
*************************************************************************************************/
// non-HW - class utility/maintenance functions
/*
* hdmiConstructor9471
*/
NvBool
hdmiConstructor9471(NVHDMIPKT_CLASS* pThis)
{
NvBool result = NV_TRUE;
return result;
}
/*
* hdmiDestructor9471
*/
void
hdmiDestructor9471(NVHDMIPKT_CLASS* pThis)
{
return;
}
/*
* initializeHdmiPktInterface9471
*/
void
initializeHdmiPktInterface9471(NVHDMIPKT_CLASS* pClass)
{
// Update SF_USER data
pClass->dispSfUserClassId = NV9471_DISP_SF_USER;
pClass->dispSfUserSize = sizeof(Nv9471DispSfUserMap);
}

View File

@@ -0,0 +1,71 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* File: nvhdmipkt_9571.c
*
* Purpose: Provides packet write functions for HDMI library for Maxwell + chips
*/
#include "nvhdmipkt_common.h"
#include "nvhdmipkt_class.h"
#include "nvhdmipkt_internal.h"
#include "class/cl9571.h"
/******************************************** NOTE ***********************************************
* This file serves as an example on how to add a new HW SF USER CLASS. Notice that this *
* Class didn't override any functions, as 9171 is identical to 9571. *
*************************************************************************************************/
// non-HW - class utility/maintenance functions
/*
* hdmiConstructor9571
*/
NvBool
hdmiConstructor9571(NVHDMIPKT_CLASS* pThis)
{
NvBool result = NV_TRUE;
return result;
}
/*
* hdmiDestructor9571
*/
void
hdmiDestructor9571(NVHDMIPKT_CLASS* pThis)
{
return;
}
/*
* initializeHdmiPktInterface9571
*/
void
initializeHdmiPktInterface9571(NVHDMIPKT_CLASS* pClass)
{
// Update SF_USER data
pClass->dispSfUserClassId = NV9571_DISP_SF_USER;
pClass->dispSfUserSize = sizeof(Nv9571DispSfUserMap);
}

View File

@@ -0,0 +1,71 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* File: nvhdmipkt_C371.c
*
* Purpose: Provides packet write functions for HDMI library for Volta+ chips
*/
#include "nvhdmipkt_common.h"
#include "nvhdmipkt_class.h"
#include "nvhdmipkt_internal.h"
#include "class/clc371.h"
/******************************************** NOTE ***********************************************
* This file serves as an example on how to add a new HW SF USER CLASS. Notice that this *
* Class didn't override any functions, as 9171 is identical to C371. *
*************************************************************************************************/
// non-HW - class utility/maintenance functions
/*
* hdmiConstructorC371
*/
NvBool
hdmiConstructorC371(NVHDMIPKT_CLASS* pThis)
{
NvBool result = NV_TRUE;
return result;
}
/*
* hdmiDestructorC371
*/
void
hdmiDestructorC371(NVHDMIPKT_CLASS* pThis)
{
return;
}
/*
* initializeHdmiPktInterfaceC371
*/
void
initializeHdmiPktInterfaceC371(NVHDMIPKT_CLASS* pClass)
{
// Update SF_USER data
pClass->dispSfUserClassId = NVC371_DISP_SF_USER;
pClass->dispSfUserSize = sizeof(NvC371DispSfUserMap);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,179 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* File: nvhdmipkt_class.h
*
* Purpose: This file contains hdmipkt class definition. Which defines class interfaces.
*/
#ifndef _NVHDMIPKT_CLASS_H_
#define _NVHDMIPKT_CLASS_H_
#include "nvlimits.h"
#include "nvhdmi_frlInterface.h"
/*************************************************************************************************
* NOTE * This header file to be used only inside this (Hdmi Packet) library. *
************************************************************************************************/
// NVHDMIPKT_CLASS_ID: HDMI packet class version
// NOTE: Anytime a new class comes with upgrades, it needs to be added here.
// Consult resman\kernel\inc\classhal.h, before adding a class.
typedef enum
{
NVHDMIPKT_0073_CLASS = 0, // pre GK104
NVHDMIPKT_9171_CLASS = 1, // GK104
NVHDMIPKT_9271_CLASS = 2, // GK110
NVHDMIPKT_9471_CLASS = 3, // GM10X
NVHDMIPKT_9571_CLASS = 4, // GM20X
NVHDMIPKT_C371_CLASS = 5, // GV100
NVHDMIPKT_C571_CLASS = 6, // TU102
NVHDMIPKT_C671_CLASS = 7, // GA102, T234D
NVHDMIPKT_INVALID_CLASS // Not to be used by client, and always the last entry here.
} NVHDMIPKT_CLASS_ID;
// Hdmi packet class
struct tagNVHDMIPKT_CLASS
{
// data
NvU32 dispSfUserClassId; // Id from nvidia/class definition
NvU32 dispSfUserSize;
NvU32 numSubDevices;
NvU32 sfUserHandle;
NVHDMIPKT_RM_CLIENT_HANDLES clientHandles;
NVHDMIPKT_MEM_MAP memMap[NV_MAX_SUBDEVICES];
NvHdmiPkt_CBHandle cbHandle;
NVHDMIPKT_CALLBACK callback;
NVHDMIPKT_CLASS_ID thisId;
NvBool isRMCallInternal;
// functions
NVHDMIPKT_RESULT
(*hdmiPacketCtrl) (NVHDMIPKT_CLASS* pThis,
NvU32 subDevice,
NvU32 displayId,
NvU32 head,
NVHDMIPKT_TYPE packetType,
NVHDMIPKT_TC transmitControl);
NVHDMIPKT_RESULT
(*hdmiPacketWrite) (NVHDMIPKT_CLASS* pThis,
NvU32 subDevice,
NvU32 displayId,
NvU32 head,
NVHDMIPKT_TYPE packetType,
NVHDMIPKT_TC transmitControl,
NvU32 packetLen,
NvU8 const *const pPacket);
// HW functions - that read/write registers
NvBool
(*hdmiReadPacketStatus) (NVHDMIPKT_CLASS* pThis,
NvU32* pBaseReg,
NvU32 head,
NvU32 pktTypeNative);
NVHDMIPKT_RESULT
(*hdmiWritePacketCtrl) (NVHDMIPKT_CLASS* pThis,
NvU32* pBaseReg,
NvU32 head,
NvU32 pktTypeNative,
NvU32 transmitControl,
NvBool bDisable);
void
(*hdmiWriteAviPacket) (NVHDMIPKT_CLASS* pThis,
NvU32* pBaseReg,
NvU32 head,
NvU32 packetLen,
NvU8 const *const pPacket);
void
(*hdmiWriteAudioPacket) (NVHDMIPKT_CLASS* pThis,
NvU32* pBaseReg,
NvU32 head,
NvU32 packetLen,
NvU8 const *const pPacket);
void
(*hdmiWriteGenericPacket) (NVHDMIPKT_CLASS* pThis,
NvU32* pBaseReg,
NvU32 head,
NvU32 packetLen,
NvU8 const *const pPacket);
void
(*hdmiWriteGeneralCtrlPacket)(NVHDMIPKT_CLASS* pThis,
NvU32* pBaseReg,
NvU32 head,
NvU32 packetLen,
NvU8 const *const pPacket);
void
(*hdmiWriteVendorPacket) (NVHDMIPKT_CLASS* pThis,
NvU32* pBaseReg,
NvU32 head,
NvU32 packetLen,
NvU8 const *const pPacket);
// utility functions to translate the generic packet type and transmit control
// to corresponding rm ctrl or hw define types.
NvU32
(*translatePacketType) (NVHDMIPKT_CLASS* pThis,
NVHDMIPKT_TYPE packetType);
NvU32
(*translateTransmitControl) (NVHDMIPKT_CLASS* pThis,
NVHDMIPKT_TC transmitControl);
//
// HDMI FRL functions to enable/disable HDMI FRL and calculate the bandwidth
// capacity required for target timing.
//
NVHDMIPKT_RESULT
(*hdmiAssessLinkCapabilities) (NVHDMIPKT_CLASS *pThis,
NvU32 subDevice,
NvU32 displayId,
NVT_EDID_INFO const * const pSinkEdid,
HDMI_SRC_CAPS *pSrcCaps,
HDMI_SINK_CAPS *pSinkCaps);
NVHDMIPKT_RESULT
(*hdmiQueryFRLConfig) (NVHDMIPKT_CLASS *pThis,
HDMI_VIDEO_TRANSPORT_INFO const * const pVidTransInfo,
HDMI_QUERY_FRL_CLIENT_CONTROL const * const pClientCtrl,
HDMI_SRC_CAPS const * const pSrcCaps,
HDMI_SINK_CAPS const * const pSinkCaps,
HDMI_FRL_CONFIG *pFRLConfig);
NVHDMIPKT_RESULT
(*hdmiSetFRLConfig) (NVHDMIPKT_CLASS *pThis,
NvU32 subDevice,
NvU32 displayId,
NvBool bFakeLt,
HDMI_FRL_CONFIG *pFRLConfig);
NVHDMIPKT_RESULT
(*hdmiClearFRLConfig) (NVHDMIPKT_CLASS* pThis,
NvU32 subDevice,
NvU32 displayId);
};
#endif //_NVHDMIPKT_CLASS_H_

View File

@@ -0,0 +1,114 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* File: nvhdmipkt_common.h
*
* Purpose: This file contains defines and structures used across hdmipkt library. All the
* common stuff goes here.
*/
#ifndef _NVHDMIPKT_COMMON_H_
#define _NVHDMIPKT_COMMON_H_
/*************************************************************************************************
* NOTE * This header file to be used only inside this (Hdmi Packet) library. *
************************************************************************************************/
#include "nvhdmipkt.h"
#include "nvhdmi_frlInterface.h"
#if NVHDMIPKT_RM_CALLS_INTERNAL
#include "nvRmApi.h"
#define CALL_DISP_RM(x) x
#endif
/**************************** HDMI Library defines, enums and structs ***************************/
// typedefs
typedef struct tagNVHDMIPKT_CLASS NVHDMIPKT_CLASS;
typedef struct tagNVHDMIPKT_MEM_MAP NVHDMIPKT_MEM_MAP;
// Register read/write defines
#define REG_RD32(reg, offset) (*(((volatile NvU32*)(reg)) + ((offset)/4)))
#define REG_WR32(reg, offset, data) ((*(((volatile NvU32*)(reg)) + ((offset)/4))) = (data))
#define NVHDMIPKT_INVALID_SUBDEV (0xFFFFFFFF)
#define NVHDMIPKT_DONT_USE_TIMER
#define NVHDMIPKT_STATUS_READ_TIMEOUT_IN_us (1*1000*1000) /* us - micro second */
// Disp SF User memory map and handle structure
struct tagNVHDMIPKT_MEM_MAP
{
NvU32 subDevice;
NvU32 memHandle;
void* pMemBase;
};
// HDMIPKT print define
#if defined (DEBUG)
#define NvHdmiPkt_Print(_p, ...) \
do { \
if ((_p)->callback.print) \
{ \
(_p)->callback.print((_p)->cbHandle, "HdmiPacketLibrary: " __VA_ARGS__); \
} \
} while(0)
#else
#define NvHdmiPkt_Print(_p, ...) /* nothing */
#endif
// HDMIPKT assert define
#if defined (DEBUG)
#define NvHdmiPkt_AssertP(p, expr) ((p)->callback.assert ? \
(p)->callback.assert((p)->cbHandle, !!(expr)) : 0)
#define NvHdmiPkt_Assert(expr) NvHdmiPkt_AssertP(pThis, expr)
#else
#define NvHdmiPkt_AssertP(p, expr)
#define NvHdmiPkt_Assert(expr)
#endif
// Prototypes for common functions shared across implementations.
extern void hdmiWriteDummyPacket(NVHDMIPKT_CLASS*, NvU32*, NvU32, NvU32, NvU8 const *const);
extern NVHDMIPKT_RESULT hdmiAssessLinkCapabilitiesDummy(NVHDMIPKT_CLASS *pThis,
NvU32 subDevice,
NvU32 displayId,
NVT_EDID_INFO const * const pSinkEdid,
HDMI_SRC_CAPS *pSrcCaps,
HDMI_SINK_CAPS *pSinkCaps);
extern NVHDMIPKT_RESULT hdmiQueryFRLConfigDummy(NVHDMIPKT_CLASS *pThis,
HDMI_VIDEO_TRANSPORT_INFO const * const pVidTransInfo,
HDMI_QUERY_FRL_CLIENT_CONTROL const * const pClientCtrl,
HDMI_SRC_CAPS const * const pSrcCaps,
HDMI_SINK_CAPS const * const pSinkCaps,
HDMI_FRL_CONFIG *pFRLConfig);
extern NVHDMIPKT_RESULT hdmiSetFRLConfigDummy(NVHDMIPKT_CLASS *pThis,
NvU32 subDevice,
NvU32 displayId,
NvBool bFakeLt,
HDMI_FRL_CONFIG *pFRLConfig);
extern NVHDMIPKT_RESULT hdmiClearFRLConfigDummy(NVHDMIPKT_CLASS *pThis,
NvU32 subDevice,
NvU32 displayId);
#endif //_NVHDMIPKT_COMMON_H_

View File

@@ -0,0 +1,60 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* File: nvhdmipkt_internal.h
*
* Purpose: This files contains defines to be used by nvhdmipkt.c
*/
#ifndef _NVHDMIPKT_INTERNAL_H_
#define _NVHDMIPKT_INTERNAL_H_
/*************************************************************************************************
* NOTE * This header file to be used only inside this (Hdmi Packet) library. *
************************************************************************************************/
#define toHdmiPktHandle(p) ((NvHdmiPkt_Handle)(p))
#define fromHdmiPktHandle(h) ((NVHDMIPKT_CLASS*)(h))
extern void initializeHdmiPktInterface0073(NVHDMIPKT_CLASS*);
extern void initializeHdmiPktInterface9171(NVHDMIPKT_CLASS*);
extern void initializeHdmiPktInterface9271(NVHDMIPKT_CLASS*);
extern void initializeHdmiPktInterface9471(NVHDMIPKT_CLASS*);
extern void initializeHdmiPktInterface9571(NVHDMIPKT_CLASS*);
extern void initializeHdmiPktInterfaceC371(NVHDMIPKT_CLASS*);
extern void initializeHdmiPktInterfaceC671(NVHDMIPKT_CLASS*);
extern NvBool hdmiConstructor0073(NVHDMIPKT_CLASS*);
extern void hdmiDestructor0073 (NVHDMIPKT_CLASS*);
extern NvBool hdmiConstructor9171(NVHDMIPKT_CLASS*);
extern void hdmiDestructor9171 (NVHDMIPKT_CLASS*);
extern NvBool hdmiConstructor9271(NVHDMIPKT_CLASS*);
extern void hdmiDestructor9271 (NVHDMIPKT_CLASS*);
extern NvBool hdmiConstructor9471(NVHDMIPKT_CLASS*);
extern void hdmiDestructor9471 (NVHDMIPKT_CLASS*);
extern NvBool hdmiConstructor9571(NVHDMIPKT_CLASS*);
extern void hdmiDestructor9571 (NVHDMIPKT_CLASS*);
extern NvBool hdmiConstructorC371(NVHDMIPKT_CLASS*);
extern void hdmiDestructorC371 (NVHDMIPKT_CLASS*);
extern NvBool hdmiConstructorC671(NVHDMIPKT_CLASS*);
extern void hdmiDestructorC671 (NVHDMIPKT_CLASS*);
#endif //_NVHDMIPKT_INTERNAL_H_

View File

@@ -0,0 +1,776 @@
//*****************************************************************************
//
// SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: MIT
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File: displayid.h
//
// Purpose: the template for DisplayID parsing (future replacement for EDID)
//
//*****************************************************************************
#ifndef __DISPLAYID_H_
#define __DISPLAYID_H_
#include "nvtiming.h"
// The structures below must be tightly packed, in order to correctly
// overlay on the EDID DisplayID extension block bytes. Both MSVC and
// gcc support the pack() pragma for this.
#if defined(__GNUC__) || defined(_MSC_VER)
# define __SUPPORTS_PACK_PRAGMA 1
#else
# error "unrecognized compiler: displayid structures must be tightly packed"
#endif
#ifdef __SUPPORTS_PACK_PRAGMA
#pragma pack(1)
#endif
typedef struct _tagDISPLAYID_SECTION
{
NvU8 version; // displayid version
NvU8 section_bytes; // length of this displayID section excluding mandatory bytes [0, 251]
NvU8 product_type; // NVT_DISPLAYID_PROD_X
NvU8 extension_count;
NvU8 data[NVT_DISPLAYID_SECTION_MAX_SIZE]; // data blocks. Note, the length of this structure may
// exceed valid memory, as DisplayID has variable length
} DISPLAYID_SECTION;
#define NVT_DISPLAYID_VER_1_1 0x101
#define NVT_DISPLAYID_PROD_EXTENSION 0 // Extension (product type not declared)
#define NVT_DISPLAYID_PROD_TEST 1 // Test Structure/Test Equipment
#define NVT_DISPLAYID_PROD_DISPLAY_PANEL 2 // Display Panel, LCD, or PDP module, etc.
#define NVT_DISPLAYID_PROD_STANDALONE_MONITOR 3 // Standalone display device, desktop monitor, TV monitor
#define NVT_DISPLAYID_PROD_RECEIVER 4 // Television receiver or display product capable of RF signals
#define NVT_DISPLAYID_PROD_REPEATER 5 // Repeater/translator that is not intended as display device
#define NVT_DISPLAYID_PROD_DIRECT_DRIVE 6 // Direct Drive monitor
#define NVT_DISPLAYID_PROD_MAX_NUMBER 6 // max product number
typedef struct _tagDISPLAYID_DATA_BLOCK_HEADER
{
NvU8 type; // identification
NvU8 revision;
NvU8 data_bytes; // number of payload bytes [0, 248]
} DISPLAYID_DATA_BLOCK_HEADER;
#define NVT_DISPLAYID_BLOCK_TYPE_PRODUCT_IDENTITY 0 // Product Identification block
#define NVT_DISPLAYID_BLOCK_TYPE_DISPLAY_PARAM 1 // Display Parameters block
#define NVT_DISPLAYID_BLOCK_TYPE_COLOR_CHAR 2 // Color Characteristics block
#define NVT_DISPLAYID_BLOCK_TYPE_TIMING_1 3 // Type 1 Detailed Timing block
#define NVT_DISPLAYID_BLOCK_TYPE_TIMING_2 4 // Type 2 Detailed Timing block
#define NVT_DISPLAYID_BLOCK_TYPE_TIMING_3 5 // Type 3 Short Timing block
#define NVT_DISPLAYID_BLOCK_TYPE_TIMING_4 6 // Type 4 DMT ID Timing block
#define NVT_DISPLAYID_BLOCK_TYPE_TIMING_VESA 7 // VESA Standard Timing block
#define NVT_DISPLAYID_BLOCK_TYPE_TIMING_CEA 8 // CEA Standard Timing block
#define NVT_DISPLAYID_BLOCK_TYPE_RANGE_LIMITS 9 // Video Timing Range Limits block
#define NVT_DISPLAYID_BLOCK_TYPE_SERIAL_NUMBER 10 // Product Serial Number block
#define NVT_DISPLAYID_BLOCK_TYPE_ASCII_STRING 11 // General Purpose ASCII String block
#define NVT_DISPLAYID_BLOCK_TYPE_DEVICE_DATA 12 // Display Device Data block
#define NVT_DISPLAYID_BLOCK_TYPE_INTERFACE_POWER 13 // Interface Power Sequencing block
#define NVT_DISPLAYID_BLOCK_TYPE_TRANSFER_CHAR 14 // Transfer Characteristics block
#define NVT_DISPLAYID_BLOCK_TYPE_DISPLAY_INTERFACE 15 // Display Interface Data Block
#define NVT_DISPLAYID_BLOCK_TYPE_STEREO 16 // Stereo Data Block
#define NVT_DISPLAYID_BLOCK_TYPE_TIMING_5 17 // Type V Timing Short Descriptor
#define NVT_DISPLAYID_BLOCK_TYPE_TILEDDISPLAY 18 // Tiled Display Data Block
#define NVT_DISPLAYID_BLOCK_TYPE_DISPLAY_INTERFACE_FEATURES 0X26 // DisplayID2.0 Display Interface Features Data Block //
#define NVT_DISPLAYID_BLOCK_TYPE_CTA_DATA 0x81 // DIsplay ID data block
#define NVT_DISPLAYID_BLOCK_TYPE_VENDOR_SPEC 0x7F // Vendor Specific Data Block
#define NVT_DISPLAYID_PRODUCT_IDENTITY_MIN_LEN 12
#define NVT_DISPLAYID_PRODUCT_IDENTITY_MAX_STRING_LEN 0xE9
typedef struct _tagDISPLAYID_PROD_IDENTIFICATION_BLOCK
{
DISPLAYID_DATA_BLOCK_HEADER header;
NvU8 vendor[3];
NvU16 product_code;
NvU32 serial_number;
NvU8 model_tag;
NvU8 model_year;
NvU8 productid_string_size;
NvU8 productid_string[NVT_DISPLAYID_PRODUCT_IDENTITY_MAX_STRING_LEN];
} DISPLAYID_PROD_IDENTIFICATION_BLOCK;
typedef struct _tagDISPLAYID_DISPLAY_PARAM_BLOCK
{
DISPLAYID_DATA_BLOCK_HEADER header;
NvU16 horizontal_image_size;
NvU16 vertical_image_size;
NvU16 horizontal_pixel_count;
NvU16 vertical_pixel_count;
NvU8 feature;
NvU8 transfer_char_gamma;
NvU8 aspect_ratio;
NvU8 color_bit_depth;
} DISPLAYID_DISPLAY_PARAM_BLOCK;
#define NVT_DISPLAYID_DISPLAY_PARAM_BLOCK_LEN 0x0C
#define NVT_DISPLAYID_DISPLAY_PARAM_SUPPORT_AUDIO 7:7
#define NVT_DISPLAYID_DISPLAY_PARAM_SEPARATE_AUDIO 6:6
#define NVT_DISPLAYID_DISPLAY_PARAM_AUDIO_INPUT_OVERRIDE 5:5
#define NVT_DISPLAYID_DISPLAY_PARAM_POWER_MANAGEMENT 4:4
#define NVT_DISPLAYID_DISPLAY_PARAM_FIXED_TIMING 3:3
#define NVT_DISPLAYID_DISPLAY_PARAM_FIXED_PIXEL_FORMAT 2:2
#define NVT_DISPLAYID_DISPLAY_PARAM_DEINTERLACING 0:0
#define NVT_DISPLAYID_DISPLAY_PARAM_DEPTH_OVERALL 7:4
#define NVT_DISPLAYID_DISPLAY_PARAM_DEPTH_NATIVE 3:0
typedef struct _tagDISPLAYID_COLOR_POINT
{
NvU8 color_x_bits_low;
NvU8 color_bits_mid;
NvU8 color_y_bits_high;
} DISPLAYID_COLOR_POINT;
#define NVT_DISPLAYID_COLOR_POINT_Y 7:4
#define NVT_DISPLAYID_COLOR_POINT_X 3:0
#define NVT_DISPLAYID_COLOR_MAX_POINTS 22
typedef struct _tagDISPLAYID_COLOR_CHAR_BLOCK
{
DISPLAYID_DATA_BLOCK_HEADER header;
// Color Characteristics Information
NvU8 point_info;
DISPLAYID_COLOR_POINT points[NVT_DISPLAYID_COLOR_MAX_POINTS];
} DISPLAYID_COLOR_CHAR_BLOCK;
#define NVT_DISPLAYID_COLOR_PRIMARIES 6:4
#define NVT_DISPLAYID_COLOR_WHITE_POINTS 3:0
#define NVT_DISPLAYID_COLOR_TEMPORAL 7:7
// the following fields apply to Timing Descriptors 1-3 (Not all of them are
// used per descriptor, but the format is the same
#define NVT_DISPLAYID_TIMING_PREFERRED 7:7
#define NVT_DISPLAYID_TIMING_3D_STEREO 6:5
#define NVT_DISPLAYID_TIMING_3D_STEREO_MONO 0
#define NVT_DISPLAYID_TIMING_3D_STEREO_STEREO 1
#define NVT_DISPLAYID_TIMING_3D_STEREO_EITHER 2
#define NVT_DISPLAYID_TIMING_INTERLACE 4:4
#define NVT_DISPLAYID_TIMING_ASPECT_RATIO 2:0
#define NVT_DISPLAYID_TIMING_ASPECT_RATIO_1_1 0
#define NVT_DISPLAYID_TIMING_ASPECT_RATIO_5_4 1
#define NVT_DISPLAYID_TIMING_ASPECT_RATIO_4_3 2
#define NVT_DISPLAYID_TIMING_ASPECT_RATIO_15_9 3
#define NVT_DISPLAYID_TIMING_ASPECT_RATIO_16_9 4
#define NVT_DISPLAYID_TIMING_ASPECT_RATIO_16_10 5
typedef struct _tag_DISPLAYID_TIMING_1_DESCRIPTOR
{
NvU8 pixel_clock_low_minus_0_01MHz;
NvU8 pixel_clock_mid;
NvU8 pixel_clock_high;
struct
{
NvU8 aspect_ratio : 3;
NvU8 rsvd : 1;
NvU8 interface_frame_scanning_type : 1;
NvU8 stereo_support : 2;
NvU8 is_preferred_detailed_timing : 1;
}options;
struct
{
NvU8 active_image_pixels_low_minus_1;
NvU8 active_image_pixels_high;
NvU8 blank_pixels_low_minus_1;
NvU8 blank_pixels_high;
NvU8 front_porch_low_minus_1;
NvU8 front_porch_high : 7;
NvU8 sync_polarity : 1;
NvU8 sync_width_low_minus_1;
NvU8 sync_width_high;
}horizontal;
struct
{
NvU8 active_image_lines_low_minus_1;
NvU8 active_image_lines_high;
NvU8 blank_lines_low_minus_1;
NvU8 blank_lines_high;
NvU8 front_porch_lines_low_minus_1;
NvU8 front_porch_lines_high : 7;
NvU8 sync_polarity : 1;
NvU8 sync_width_lines_low_minus_1;
NvU8 sync_width_lines_high;
}vertical;
} DISPLAYID_TIMING_1_DESCRIPTOR;
#define NVT_DISPLAYID_TIMING_1_MAX_DESCRIPTORS 12
typedef struct _tagDISPLAYID_TIMING_1_BLOCK
{
DISPLAYID_DATA_BLOCK_HEADER header;
DISPLAYID_TIMING_1_DESCRIPTOR descriptors[NVT_DISPLAYID_TIMING_1_MAX_DESCRIPTORS];
} DISPLAYID_TIMING_1_BLOCK;
#define NVT_DISPLAYID_TIMING_1_POLARITY_SHIFT 15
#define NVT_DISPLAYID_CHAR_WIDTH_IN_PIXELS 8
typedef struct _tag_DISPLAYID_TIMING_2_DESCRIPTOR
{
NvU8 pixel_clock_low_minus_0_01MHz;
NvU8 pixel_clock_mid;
NvU8 pixel_clock_high;
struct
{
NvU8 rsvd : 2;
NvU8 vsync_polarity : 1;
NvU8 hsync_polarity : 1;
NvU8 interface_frame_scanning_type : 1;
NvU8 stereo_support : 2;
NvU8 is_preferred_detailed_timing : 1;
}options;
struct
{
NvU8 active_image_in_char_minus_1;
NvU8 active_image_in_char_high : 1;
NvU8 blank_in_char_minus_1 : 7;
NvU8 sync_width_in_char_minus_1 : 4;
NvU8 front_porch_in_char_minus_1 : 4;
}horizontal;
struct
{
NvU8 active_image_lines_low_minus_1;
NvU8 active_image_lines_high : 4;
NvU8 reserved : 4;
NvU8 blank_lines_minus_1;
NvU8 sync_width_lines_minus_1 : 4;
NvU8 front_porch_lines_minus_1 : 4;
}vertical;
} DISPLAYID_TIMING_2_DESCRIPTOR;
#define NVT_DISPLAYID_TIMING_2_HORIZ_BLANK_PIXEL 7:1
#define NVT_DISPLAYID_TIMING_2_HORIZ_ACTIVE_PIXEL_HIGH 0:0
#define NVT_DISPLAYID_TIMING_2_HORIZ_OFFSET 7:4
#define NVT_DISPLAYID_TIMING_2_HORIZ_SYNC 3:0
#define NVT_DISPLAYID_TIMING_2_VERT_ACTIVE_PIXEL_HIGH 3:0
#define NVT_DISPLAYID_TIMING_2_VERT_OFFSET 7:4
#define NVT_DISPLAYID_TIMING_2_VERT_SYNC 3:0
#define NVT_DISPLAYID_TIMING_2_MAX_DESCRIPTORS 22
typedef struct _tagDISPLAYID_TIMING_2_BLOCK
{
DISPLAYID_DATA_BLOCK_HEADER header;
DISPLAYID_TIMING_2_DESCRIPTOR descriptors[NVT_DISPLAYID_TIMING_2_MAX_DESCRIPTORS];
} DISPLAYID_TIMING_2_BLOCK;
typedef struct _TAG_DISPLAYID_TIMING_3_DESCRIPTOR
{
NvU8 optns;
NvU8 horizontal_active_pixels;
NvU8 transfer;
} DISPLAYID_TIMING_3_DESCRIPTOR;
#define NVT_DISPLAYID_TIMING_3_FORMULA 6:4
#define NVT_DISPLAYID_TIMING_3_FORMULA_STANDARD 0
#define NVT_DISPLAYID_TIMING_3_FORMULA_REDUCED_BLANKING 1
#define NVT_DISPLAYID_TIMING_3_ASPECT_RATIO 3:0
#define NVT_DISPLAYID_TIMING_3_ASPECT_RATIO_1_1 0
#define NVT_DISPLAYID_TIMING_3_ASPECT_RATIO_5_4 1
#define NVT_DISPLAYID_TIMING_3_ASPECT_RATIO_4_3 2
#define NVT_DISPLAYID_TIMING_3_ASPECT_RATIO_15_9 3
#define NVT_DISPLAYID_TIMING_3_ASPECT_RATIO_16_9 4
#define NVT_DISPLAYID_TIMING_3_ASPECT_RATIO_16_10 5
#define NVT_DISPLAYID_TIMING_3_INTERLACE 7:7
#define NVT_DISPLAYID_TIMING_3_REFRESH_RATE 6:0
#define NVT_DISPLAYID_TIMING_3_MAX_DESCRIPTORS 82
typedef struct _tagDISPLAYID_TIMING_3_BLOCK
{
DISPLAYID_DATA_BLOCK_HEADER header;
DISPLAYID_TIMING_3_DESCRIPTOR descriptors[NVT_DISPLAYID_TIMING_3_MAX_DESCRIPTORS];
} DISPLAYID_TIMING_3_BLOCK;
#define NVT_DISPLAYID_TIMING_4_MAX_CODES NVT_DISPLAYID_DATABLOCK_MAX_PAYLOAD_LEN
typedef struct _tagDISPLAYID_TIMING_4_BLOCK
{
DISPLAYID_DATA_BLOCK_HEADER header;
NvU8 timing_codes[NVT_DISPLAYID_TIMING_4_MAX_CODES];
} DISPLAYID_TIMING_4_BLOCK;
#define NVT_DISPLAYID_TIMING_5_STEREO_SUPPORT_MASK 0x60
#define NVT_DISPLAYID_TIMING_5_FRACTIONAL_RR_SUPPORT_MASK 0x10
#define NVT_DISPLAYID_TIMING_5_FORMULA_SUPPORT_MASK 3
typedef struct _TAG_DISPLAYID_TIMING_5_DESCRIPTOR
{
NvU8 optns;
NvU8 rsvd;
NvU8 horizontal_active_pixels_low;
NvU8 horizontal_active_pixels_high;
NvU8 vertical_active_pixels_low;
NvU8 vertical_active_pixels_high;
NvU8 refresh_rate;
} DISPLAYID_TIMING_5_DESCRIPTOR;
#define NVT_DISPLAYID_TIMING_5_MAX_DESCRIPTORS 53
typedef struct _tagDISPLAYID_TIMING_5_BLOCK
{
DISPLAYID_DATA_BLOCK_HEADER header;
DISPLAYID_TIMING_5_DESCRIPTOR descriptors[NVT_DISPLAYID_TIMING_5_MAX_DESCRIPTORS];
} DISPLAYID_TIMING_5_BLOCK;
#define DISPLAYID_TIMING_VESA_BLOCK_SIZE 0x0A
#define DISPLAYID_TIMING_CEA_BLOCK_SIZE 0x08
typedef struct _tagDISPLAYID_TIMING_MODE_BLOCK
{
DISPLAYID_DATA_BLOCK_HEADER header;
NvU8 timing_modes[DISPLAYID_TIMING_VESA_BLOCK_SIZE];
} DISPLAYID_TIMING_MODE_BLOCK;
typedef struct _tagDISPLAYID_RANGE_LIMITS_BLOCK
{
DISPLAYID_DATA_BLOCK_HEADER header;
NvU8 pixel_clock_min[3];
NvU8 pixel_clock_max[3];
NvU8 horizontal_frequency_min;
NvU8 horizontal_frequency_max;
NvU16 horizontal_blanking_min;
NvU8 vertical_refresh_rate_min;
NvU8 vertical_refresh_rate_max;
NvU16 vertical_blanking_min;
NvU8 optns;
} DISPLAYID_RANGE_LIMITS_BLOCK;
#define DISPLAYID_RANGE_LIMITS_BLOCK_LEN 0xF
#define NVT_DISPLAYID_RANGE_LIMITS_INTERLACE 7:7
#define NVT_DISPLAYID_RANGE_LIMITS_CVT_STANDARD 6:6
#define NVT_DISPLAYID_RANGE_LIMITS_CVT_REDUCED 5:5
#define NVT_DISPLAYID_RANGE_LIMITS_DFD 4:4
typedef struct _tagDISPLAYID_ASCII_STRING_BLOCK
{
DISPLAYID_DATA_BLOCK_HEADER header;
NvU8 data[NVT_DISPLAYID_DATABLOCK_MAX_PAYLOAD_LEN];
} DISPLAYID_ASCII_STRING_BLOCK;
typedef struct _tagDISPLAYID_DEVICE_DATA_BLOCK
{
DISPLAYID_DATA_BLOCK_HEADER header;
NvU8 technology;
NvU8 operating_mode;
NvU16 horizontal_pixel_count;
NvU16 vertical_pixel_count;
NvU8 aspect_ratio;
NvU8 orientation;
NvU8 subpixel_info;
NvU8 horizontal_pitch;
NvU8 vertical_pitch;
NvU8 color_bit_depth;
NvU8 response_time;
} DISPLAYID_DEVICE_DATA_BLOCK;
#define DISPLAYID_DEVICE_DATA_BLOCK_LEN 0xD
#define NVT_DISPLAYID_DEVICE_TECHNOLOGY_CRT_MONOCHROME 0x00
#define NVT_DISPLAYID_DEVICE_TECHNOLOGY_CRT_STANDARD 0x01
#define NVT_DISPLAYID_DEVICE_TECHNOLOGY_CRT_OTHER 0x02
#define NVT_DISPLAYID_DEVICE_TECHNOLOGY_LCD_PASSIVE_MATRIX_TN 0x10
#define NVT_DISPLAYID_DEVICE_TECHNOLOGY_LCD_PASSIVE_MATRIX_CHOL_LC 0x11
#define NVT_DISPLAYID_DEVICE_TECHNOLOGY_LCD_PASSIVE_MATRIX_FERRO_LC 0x12
#define NVT_DISPLAYID_DEVICE_TECHNOLOGY_LCD_PASSIVE_MATRIX_OTHER 0x13
#define NVT_DISPLAYID_DEVICE_TECHNOLOGY_LCD_ACTIVE_MATRIX_TN 0x14
#define NVT_DISPLAYID_DEVICE_TECHNOLOGY_LCD_ACTIVE_MATRIX_IPS 0x15
#define NVT_DISPLAYID_DEVICE_TECHNOLOGY_LCD_ACTIVE_MATRIX_VA 0x16
#define NVT_DISPLAYID_DEVICE_TECHNOLOGY_LCD_ACTIVE_MATRIX_OCB 0x17
#define NVT_DISPLAYID_DEVICE_TECHNOLOGY_LCD_ACTIVE_MATRIX_FERRO 0x18
#define NVT_DISPLAYID_DEVICE_TECHNOLOGY_LCD_OTHER 0x1F
#define NVT_DISPLAYID_DEVICE_TECHNOLOGY_PLASMA_DC 0x20
#define NVT_DISPLAYID_DEVICE_TECHNOLOGY_PLASMA_AC 0x21
#define NVT_DISPLAYID_DEVICE_TECHNOLOGY_ELECTROLUM 0x30
#define NVT_DISPLAYID_DEVICE_TECHNOLOGY_INORGANIC_LED 0x40
#define NVT_DISPLAYID_DEVICE_TECHNOLOGY_ORGANIC_LED 0x50
#define NVT_DISPLAYID_DEVICE_TECHNOLOGY_FED 0x60
#define NVT_DISPLAYID_DEVICE_TECHNOLOGY_ELECTROPHORETIC 0x70
#define NVT_DISPLAYID_DEVICE_TECHNOLOGY_ELECTROCHROMIC 0x80
#define NVT_DISPLAYID_DEVICE_TECHNOLOGY_ELECTROMECHANICAL 0x90
#define NVT_DISPLAYID_DEVICE_TECHNOLOGY_ELECTROWETTING 0xA0
#define NVT_DISPLAYID_DEVICE_TECHNOLOGY_OTHER 0xF0
// Display Device operating mode info
#define NVT_DISPLAYID_DEVICE_OPERATING_MODE 7:4
#define NVT_DISPLAYID_DEVICE_OPERATING_MODE_REFLECTIVE_NO_ILLUM 0x0
#define NVT_DISPLAYID_DEVICE_OPERATING_MODE_REFLECTIVE_ILLUM 0x1
#define NVT_DISPLAYID_DEVICE_OPERATING_MODE_REFLECTIVE_ILLUM_DEF 0x2
#define NVT_DISPLAYID_DEVICE_OPERATING_MODE_TRANSMISSIVE_NO_ILLUM 0x3
#define NVT_DISPLAYID_DEVICE_OPERATING_MODE_TRANSMISSIVE_ILLUM 0x4
#define NVT_DISPLAYID_DEVICE_OPERATING_MODE_TRANSMISSIVE_ILLUM_DEF 0x5
#define NVT_DISPLAYID_DEVICE_OPERATING_MODE_EMISSIVE 0x6
#define NVT_DISPLAYID_DEVICE_OPERATING_MODE_TRANSFLECTIVE_REF 0x7
#define NVT_DISPLAYID_DEVICE_OPERATING_MODE_TRANSFLECTIVE_TRANS 0x8
#define NVT_DISPLAYID_DEVICE_OPERATING_MODE_TRANSPARENT_AMB 0x9
#define NVT_DISPLAYID_DEVICE_OPERATING_MODE_TRANSPARENT_EMIS 0xA
#define NVT_DISPLAYID_DEVICE_OPERATING_MODE_PROJECTION_REF 0xB
#define NVT_DISPLAYID_DEVICE_OPERATING_MODE_PROJECTION_TRANS 0xC
#define NVT_DISPLAYID_DEVICE_OPERATING_MODE_PROJECTION_EMIS 0xD
#define NVT_DISPLAYID_DEVICE_BACKLIGHT 3:3
#define NVT_DISPLAYID_DEVICE_INTENSITY 2:2
// Display Device aspect ratio/orientation info
#define NVT_DISPLAYID_DEVICE_ORIENTATION 7:6
#define NVT_DISPLAYID_DEVICE_ORIENTATION_LANDSCAPE 0
#define NVT_DISPLAYID_DEVICE_ORIENTATION_PORTRAIT 1
#define NVT_DISPLAYID_DEVICE_ORIENTATION_NOT_FIXED 2
#define NVT_DISPLAYID_DEVICE_ORIENTATION_UNDEFINED 3
#define NVT_DISPLAYID_DEVICE_ROTATION 5:4
#define NVT_DISPLAYID_DEVICE_ROTATION_NONE 0
#define NVT_DISPLAYID_DEVICE_ROTATION_CLOCKWISE 1
#define NVT_DISPLAYID_DEVICE_ROTATION_COUNTERCLOCKWISE 2
#define NVT_DISPLAYID_DEVICE_ROTATION_BOTH 3
#define NVT_DISPLAYID_DEVICE_ZERO_PIXEL 3:2
#define NVT_DISPLAYID_DEVICE_ZERO_PIXEL_UPPER_LEFT 0
#define NVT_DISPLAYID_DEVICE_ZERO_PIXEL_UPPER_RIGHT 1
#define NVT_DISPLAYID_DEVICE_ZERO_PIXEL_LOWER_LEFT 2
#define NVT_DISPLAYID_DEVICE_ZERO_PIXEL_LOWER RIGHT 3
#define NVT_DISPLAYID_DEVICE_SCAN 1:0
#define NVT_DISPLAYID_DEVICE_SCAN_UNDEFINED 0
#define NVT_DISPLAYID_DEVICE_SCAN_FAST_LONG 1
#define NVT_DISPLAYID_DEVICE_SCAN_FAST_SHORT 2
// Display Device Color Depth information
#define NVT_DISPLAYID_DEVICE_COLOR_DEPTH 3:0
// Display Device Response Time information
#define NVT_DISPLAYID_DEVICE_WHITE_BLACK 7:7
#define NVT_DISPLAYID_DEVICE_RESPONSE_TIME 6:0
#define NVT_DISPLAYID_SUBPIXEL_UNDEFINED 0
#define NVT_DISPLAYID_SUBPIXEL_RGB_VERTICAL 1
#define NVT_DISPLAYID_SUBPIXEL_RGB_HORIZONTAL 2
#define NVT_DISPLAYID_SUBPIXEL_VERTICAL_STR 3
#define NVT_DISPLAYID_SUBPIXEL_HORIZONTAL_STR 4
#define NVT_DISPLAYID_SUBPIXEL_QUAD_RED_TOP_LEFT 5
#define NVT_DISPLAYID_SUBPIXEL_QUAD_RED_BOTTOM_LEFT 6
#define NVT_DISPLAYID_SUBPIXEL_DELTA_RGB 7
#define NVT_DISPLAYID_SUBPIXEL_MOSAIC 8
#define NVT_DISPLAYID_SUBPIXEL_QUAD_INC_WHITE 9
#define NVT_DISPLAYID_SUBPIXEL_FIVE 10
#define NVT_DISPLAYID_SUBPIXEL_SIX 11
#define NVT_DISPLAYID_SUBPIXEL_PENTILE 12
typedef struct _tagDISPLAYID_INTERFACE_POWER_BLOCK
{
DISPLAYID_DATA_BLOCK_HEADER header;
NvU8 power_sequence_T1;
NvU8 power_sequence_T2;
NvU8 power_sequence_T3;
NvU8 power_sequence_T4_min;
NvU8 power_sequence_T5_min;
NvU8 power_sequence_T6_min;
} DISPLAYID_INTERFACE_POWER_BLOCK;
#define DISPLAYID_INTERFACE_POWER_BLOCK_LEN 0x6
#define NVT_DISPLAYID_POWER_T1_MIN 7:4
#define NVT_DISPLAYID_POWER_T1_MAX 3:0
#define NVT_DISPLAYID_POWER_T2 5:0
#define NVT_DISPLAYID_POWER_T3 5:0
#define NVT_DISPLAYID_POWER_T4_MIN 6:0
#define NVT_DISPLAYID_POWER_T5_MIN 5:0
#define NVT_DISPLAYID_POWER_T6_MIN 5:0
typedef struct _tagDISPLAYID_TRANSFER_CHAR_BLOCK
{
DISPLAYID_DATA_BLOCK_HEADER header;
NvU8 info;
NvU8 samples;
NvU8 curve_data[NVT_DISPLAYID_DATABLOCK_MAX_PAYLOAD_LEN - 2];
} DISPLAYID_TRANSFER_CHAR_BLOCK;
typedef struct _tagDISPLAYID_INTERFACE_DATA_BLOCK
{
DISPLAYID_DATA_BLOCK_HEADER header;
NvU8 info;
NvU8 version;
NvU8 color_depth_rgb;
NvU8 color_depth_ycbcr444;
NvU8 color_depth_ycbcr422;
NvU8 content_protection;
NvU8 content_protection_version;
NvU8 spread;
NvU8 interface_attribute_1;
NvU8 interface_attribute_2;
} DISPLAYID_INTERFACE_DATA_BLOCK;
#define DISPLAYID_INTERFACE_DATA_BLOCK_LEN 0xA
#define NVT_DISPLAYID_INTERFACE_TYPE 7:4
// Interface Codes (note exception for Analog Interface)
#define NVT_DISPLAYID_INTERFACE_TYPE_ANALOG 0
#define NVT_DISPLAYID_INTERFACE_TYPE_LVDS 1
#define NVT_DISPLAYID_INTERFACE_TYPE_TMDS 2
#define NVT_DISPLAYID_INTERFACE_TYPE_RSDS 3
#define NVT_DISPLAYID_INTERFACE_TYPE_DVI_D 4
#define NVT_DISPLAYID_INTERFACE_TYPE_DVI_I_ANALOG 5
#define NVT_DISPLAYID_INTERFACE_TYPE_DVI_I_DIGITAL 6
#define NVT_DISPLAYID_INTERFACE_TYPE_HDMI_A 7
#define NVT_DISPLAYID_INTERFACE_TYPE_HDMI_B 8
#define NVT_DISPLAYID_INTERFACE_TYPE_MDDI 9
#define NVT_DISPLAYID_INTERFACE_TYPE_DISPLAYPORT 10
#define NVT_DISPLAYID_INTERFACE_TYPE_PROPRIETARY 11
// Analog Interface Subtype codes
#define NVT_DISPLAYID_INTERFACE_TYPE_ANALOG_VGA 0
#define NVT_DISPLAYID_INTERFACE_TYPE_ANALOG_VESA_NAVI_V 1
#define NVT_DISPLAYID_INTERFACE_TYPE_ANALOG_VESA_NAVI_D 2
#define NVT_DISPLAYID_INTERFACE_NUMLINKS 3:0
#define NVT_DISPLAYID_INTERFACE_CONTENT 2:0
#define NVT_DISPLAYID_INTERFACE_CONTENT_NONE 0
#define NVT_DISPLAYID_INTERFACE_CONTENT_HDCP 1
#define NVT_DISPLAYID_INTERFACE_CONTENT_DTCP 2
#define NVT_DISPLAYID_INTERFACE_CONTENT_DPCP 3
#define NVT_DISPLAYID_INTERFACE_SPREAD_TYPE 7:6
#define NVT_DISPLAYID_INTERFACE_SPREAD_TYPE_NONE 0
#define NVT_DISPLAYID_INTERFACE_SPREAD_TYPE_DOWN 1
#define NVT_DISPLAYID_INTERFACE_SPREAD_TYPE_CENTER 2
#define NVT_DISPLAYID_INTERFACE_SPREAD_PER 3:0
#define NVT_DISPLAYID_INTERFACE_RGB16 5:5
#define NVT_DISPLAYID_INTERFACE_RGB14 4:4
#define NVT_DISPLAYID_INTERFACE_RGB12 3:3
#define NVT_DISPLAYID_INTERFACE_RGB10 2:2
#define NVT_DISPLAYID_INTERFACE_RGB8 1:1
#define NVT_DISPLAYID_INTERFACE_RGB6 0:0
#define NVT_DISPLAYID_INTERFACE_YCBCR444_16 5:5
#define NVT_DISPLAYID_INTERFACE_YCBCR444_14 4:4
#define NVT_DISPLAYID_INTERFACE_YCBCR444_12 3:3
#define NVT_DISPLAYID_INTERFACE_YCBCR444_10 2:2
#define NVT_DISPLAYID_INTERFACE_YCBCR444_8 1:1
#define NVT_DISPLAYID_INTERFACE_YCBCR444_6 0:0
#define NVT_DISPLAYID_INTERFACE_YCBCR422_16 4:4
#define NVT_DISPLAYID_INTERFACE_YCBCR422_14 3:3
#define NVT_DISPLAYID_INTERFACE_YCBCR422_12 2:2
#define NVT_DISPLAYID_INTERFACE_YCBCR422_10 1:1
#define NVT_DISPLAYID_INTERFACE_YCBCR422_8 0:0
// LVDS specific settings
#define NVT_DISPLAYID_LVDS_COLOR 4:4
#define NVT_DISPLAYID_LVDS_2_8 3:3
#define NVT_DISPLAYID_LVDS_12 2:2
#define NVT_DISPLAYID_LVDS_5 1:1
#define NVT_DISPLAYID_LVDS_3_3 0:0
#define NVT_DISPLAYID_INTERFACE_DE 2:2
#define NVT_DISPLAYID_INTERFACE_POLARITY 1:1
#define NVT_DISPLAYID_INTERFACE_STROBE 0:0
typedef struct _tagDISPLAYID_STEREO_INTERFACE_METHOD_BLOCK
{
DISPLAYID_DATA_BLOCK_HEADER header;
NvU8 stereo_bytes;
NvU8 stereo_code;
NvU8 timing_sub_block[NVT_DISPLAYID_DATABLOCK_MAX_PAYLOAD_LEN];
} DISPLAYID_STEREO_INTERFACE_METHOD_BLOCK;
#define NVT_DISPLAYID_STEREO_FIELD_SEQUENTIAL 0x0
#define NVT_DISPLAYID_STEREO_SIDE_BY_SIDE 0x1
#define NVT_DISPLAYID_STEREO_PIXEL_INTERLEAVED 0x2
#define NVT_DISPLAYID_STEREO_DUAL_INTERFACE 0x3
#define NVT_DISPLAYID_STEREO_MULTIVIEW 0x4
#define NVT_DISPLAYID_STEREO_PROPRIETARY 0xFF
#define NVT_DISPLAYID_STEREO_MIRRORING 2:1
#define NVT_DISPLAYID_STEREO_POLARITY 0:0
typedef struct _tagDISPLAYID_TILED_DISPLAY_BLOCK
{
DISPLAYID_DATA_BLOCK_HEADER header;
struct
{
NvU8 single_tile_behavior:3; // 0x03
NvU8 multi_tile_behavior:2; // 0x03
NvU8 rsvd :1; // 0x03
NvU8 has_bezel_info :1; // 0x03
NvU8 single_enclosure :1; // 0x03
} capability;
struct
{
NvU8 row :4; // 0x04
NvU8 col :4; // 0x04
} topology_low;
struct
{
NvU8 y :4; // 0x05
NvU8 x :4; // 0x05
} location_low;
struct
{
NvU8 y :1; // 0x06
NvU8 reserved1 :1; // 0x06
NvU8 x :1; // 0x06
NvU8 reserved2 :1; // 0x06
NvU8 row :1; // 0x06
NvU8 reserved3 :1; // 0x06
NvU8 col :1; // 0x06
NvU8 reserved4 :1; // 0x06
} topo_loc_high;
struct
{
NvU8 width_low; // 0x07
NvU8 width_high; // 0x08
NvU8 height_low; // 0x09
NvU8 height_high; // 0X0A
} native_resolution;
struct
{
NvU8 pixel_density; // 0x0B
NvU8 top; // 0x0C
NvU8 bottom; // 0x0D
NvU8 right; // 0x0E
NvU8 left; // 0x0F
} bezel_info;
struct
{
NvU8 vendor_id[3]; // 0x10 ~ 0x12
NvU8 product_id[2]; // 0x13 ~ 0x14
NvU8 serial_number[4]; // 0x15 ~ 0x18
} topology_id;
} DISPLAYID_TILED_DISPLAY_BLOCK;
typedef struct _tagDISPLAYID_INTERFACE_FEATURES_DATA_BLOCK
{
DISPLAYID_DATA_BLOCK_HEADER header;
NvU8 supported_color_depth_rgb;
NvU8 supported_color_depth_ycbcr444;
NvU8 supported_color_depth_ycbcr422;
NvU8 supported_color_depth_ycbcr420;
NvU8 minimum_pixel_rate_ycbcr420;
NvU8 supported_audio_capability;
NvU8 supported_colorspace_eotf_combination_1;
NvU8 supported_colorspace_eotf_combination_2;
NvU8 additional_supported_colorspace_eotf_total;
NvU8 additional_supported_colorspace_eotf[NVT_DISPLAYID_DISPLAY_INTERFACE_FEATURES_MAX_ADDITIONAL_SUPPORTED_COLORSPACE_EOTF];
} DISPLAYID_INTERFACE_FEATURES_DATA_BLOCK;
#define DISPLAYID_INTERFACE_FEATURES_DATA_BLOCK_MAX_LEN sizeof(DISPLAYID_INTERFACE_FEATURES_DATA_BLOCK)
#define NVT_DISPLAYID_INTERFACE_FEATURES_RGB16 5:5
#define NVT_DISPLAYID_INTERFACE_FEATURES_RGB14 4:4
#define NVT_DISPLAYID_INTERFACE_FEATURES_RGB12 3:3
#define NVT_DISPLAYID_INTERFACE_FEATURES_RGB10 2:2
#define NVT_DISPLAYID_INTERFACE_FEATURES_RGB8 1:1
#define NVT_DISPLAYID_INTERFACE_FEATURES_RGB6 0:0
#define NVT_DISPLAYID_INTERFACE_FEATURES_YCBCR444_16 5:5
#define NVT_DISPLAYID_INTERFACE_FEATURES_YCBCR444_14 4:4
#define NVT_DISPLAYID_INTERFACE_FEATURES_YCBCR444_12 3:3
#define NVT_DISPLAYID_INTERFACE_FEATURES_YCBCR444_10 2:2
#define NVT_DISPLAYID_INTERFACE_FEATURES_YCBCR444_8 1:1
#define NVT_DISPLAYID_INTERFACE_FEATURES_YCBCR444_6 0:0
#define NVT_DISPLAYID_INTERFACE_FEATURES_YCBCR422_16 4:4
#define NVT_DISPLAYID_INTERFACE_FEATURES_YCBCR422_14 3:3
#define NVT_DISPLAYID_INTERFACE_FEATURES_YCBCR422_12 2:2
#define NVT_DISPLAYID_INTERFACE_FEATURES_YCBCR422_10 1:1
#define NVT_DISPLAYID_INTERFACE_FEATURES_YCBCR422_8 0:0
#define NVT_DISPLAYID_INTERFACE_FEATURES_YCBCR420_16 4:4
#define NVT_DISPLAYID_INTERFACE_FEATURES_YCBCR420_14 3:3
#define NVT_DISPLAYID_INTERFACE_FEATURES_YCBCR420_12 2:2
#define NVT_DISPLAYID_INTERFACE_FEATURES_YCBCR420_10 1:1
#define NVT_DISPLAYID_INTERFACE_FEATURES_YCBCR420_8 0:0
#define NVT_DISPLAYID_INTERFACE_FEATURES_AUDIO_SUPPORTED_32KHZ 7:7
#define NVT_DISPLAYID_INTERFACE_FEATURES_AUDIO_SUPPORTED_44_1KHZ 6:6
#define NVT_DISPLAYID_INTERFACE_FEATURES_AUDIO_SUPPORTED_48KHZ 5:5
#define NVT_DISPLAYID_INTERFACE_FEATURES_COLORSPACE_BT2020_EOTF_SMPTE_ST2084 6:6
#define NVT_DISPLAYID_INTERFACE_FEATURES_COLORSPACE_BT2020_EOTF_BT2020 5:5
#define NVT_DISPLAYID_INTERFACE_FEATURES_COLORSPACE_DCI_P3_EOTF_DCI_P3 4:4
#define NVT_DISPLAYID_INTERFACE_FEATURES_COLORSPACE_ADOBE_RGB_EOTF_ADOBE_RGB 3:3
#define NVT_DISPLAYID_INTERFACE_FEATURES_COLORSPACE_BT709_EOTF_BT1886 2:2
#define NVT_DISPLAYID_INTERFACE_FEATURES_COLORSPACE_BT601_EOTF_BT601 1:1
#define NVT_DISPLAYID_INTERFACE_FEATURES_COLORSPACE_SRGB_EOTF_SRGB 0:0
#define NVT_DISPLAYID_INTERFACE_FEATURES_ADDITIONAL_SUPPORTED_COLORSPACE_EOTF_TOTAL 2:0
#define NVT_DISPLAYID_INTERFACE_FEATURES_ADDITIONAL_SUPPORTED_COLORSPACE 7:4
#define NVT_DISPLAYID_INTERFACE_FEATURES_ADDITIONAL_SUPPORTED_COLORSPACE_NOT_DEFINED 0
#define NVT_DISPLAYID_INTERFACE_FEATURES_ADDITIONAL_SUPPORTED_COLORSPACE_SRGB 1
#define NVT_DISPLAYID_INTERFACE_FEATURES_ADDITIONAL_SUPPORTED_COLORSPACE_BT601 2
#define NVT_DISPLAYID_INTERFACE_FEATURES_ADDITIONAL_SUPPORTED_COLORSPACE_BT709 3
#define NVT_DISPLAYID_INTERFACE_FEATURES_ADDITIONAL_SUPPORTED_COLORSPACE_ADOBE_RGB 4
#define NVT_DISPLAYID_INTERFACE_FEATURES_ADDITIONAL_SUPPORTED_COLORSPACE_DCI_P3 5
#define NVT_DISPLAYID_INTERFACE_FEATURES_ADDITIONAL_SUPPORTED_COLORSPACE_BT2020 6
#define NVT_DISPLAYID_INTERFACE_FEATURES_ADDITIONAL_SUPPORTED_COLORSPACE_CUSTOM 7
#define NVT_DISPLAYID_INTERFACE_FEATURES_ADDITIONAL_SUPPORTED_EOTF 3:0
#define NVT_DISPLAYID_INTERFACE_FEATURES_ADDITIONAL_SUPPORTED_EOTF_NOT_DEFINED 0
#define NVT_DISPLAYID_INTERFACE_FEATURES_ADDITIONAL_SUPPORTED_EOTF_SRGB 1
#define NVT_DISPLAYID_INTERFACE_FEATURES_ADDITIONAL_SUPPORTED_EOTF_BT601 2
#define NVT_DISPLAYID_INTERFACE_FEATURES_ADDITIONAL_SUPPORTED_EOTF_BT709 3
#define NVT_DISPLAYID_INTERFACE_FEATURES_ADDITIONAL_SUPPORTED_EOTF_ADOBE_RGB 4
#define NVT_DISPLAYID_INTERFACE_FEATURES_ADDITIONAL_SUPPORTED_EOTF_DCI_P3 5
#define NVT_DISPLAYID_INTERFACE_FEATURES_ADDITIONAL_SUPPORTED_EOTF_BT2020 6
#define NVT_DISPLAYID_INTERFACE_FEATURES_ADDITIONAL_SUPPORTED_EOTF_GAMMA 7
#define NVT_DISPLAYID_INTERFACE_FEATURES_ADDITIONAL_SUPPORTED_EOTF_SMPTE_ST2084 8
#define NVT_DISPLAYID_INTERFACE_FEATURES_ADDITIONAL_SUPPORTED_EOTF_HYBRID_LOG 9
#define NVT_DISPLAYID_INTERFACE_FEATURES_ADDITIONAL_SUPPORTED_EOTF_CUSTOM 10
#ifdef __SUPPORTS_PACK_PRAGMA
#pragma pack()
#endif
#endif // __DISPLAYID_H_

View File

@@ -0,0 +1,701 @@
//*****************************************************************************
//
// SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: MIT
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File: displayid20.h
//
// Purpose: the template for DisplayID 2.0 parsing (future replacement for EDID)
//
//*****************************************************************************
#ifndef __DISPLAYID20_H_
#define __DISPLAYID20_H_
#include "nvtiming.h"
// The structures below must be tightly packed, in order to correctly
// overlay on the DisplayID 2.0 block bytes. Both MSVC and
// gcc support the pack() pragma for this.
#if defined(__GNUC__) || defined(_MSC_VER)
# define __SUPPORTS_PACK_PRAGMA 1
#else
# error "unrecognized compiler: displayid structures must be tightly packed"
#endif
#ifdef __SUPPORTS_PACK_PRAGMA
#pragma pack(1)
#endif
#define DISPLAYID_2_0_SECTION_SIZE_TOTAL(_pSectionHeader_) ((_pSectionHeader_).section_bytes + \
sizeof(DISPLAYID_2_0_SECTION_HEADER) + \
sizeof(NvU8))
#define DISPLAYID_2_0_DATA_BLOCK_SIZE_TOTAL(_pBlockHeader_) ((_pBlockHeader_)->data_bytes + \
sizeof(DISPLAYID_2_0_DATA_BLOCK_HEADER))
#define DISPLAYID_2_0_SECTION_SIZE_MAX 256
#define DISPLAYID_2_0_SECTION_DATA_SIZE_MAX (DISPLAYID_2_0_SECTION_SIZE_MAX - \
sizeof(DISPLAYID_2_0_SECTION_HEADER)
typedef struct _tagDISPLAYID_2_0_SECTION_HEADER
{
NvU8 revision:4; // displayID revision
NvU8 version:4; // displayID version
NvU8 section_bytes; // length of this displayID section excluding mandatory bytes [0, 251]
NvU8 product_type:4; // Display Product Primary Use Case
NvU8 reserved:4; // RESERVED
NvU8 extension_count; // Total extension count.
} DISPLAYID_2_0_SECTION_HEADER;
typedef struct _tagDISPLAYID_2_0_SECTION
{
DISPLAYID_2_0_SECTION_HEADER header;
NvU8 data[DISPLAYID_2_0_SECTION_SIZE_MAX]; // data blocks. Note, DisplayID has variable length
} DISPLAYID_2_0_SECTION;
#define DISPLAYID_2_0_VERSION 2
#define DISPLAYID_2_0_REVISION 0
#define DISPLAYID_2_0_PROD_EXTENSION 0 // Extension (same primary use case as base section)
#define DISPLAYID_2_0_PROD_TEST 1 // Test Structure/Test Equipment
#define DISPLAYID_2_0_PROD_GENERIC_DISPLAY 2 // None of the listed primary use cases; generic display
#define DISPLAYID_2_0_PROD_TELEVISION 3 // Television (TV) display
#define DISPLAYID_2_0_PROD_DESKTOP_PRODUCTIVITY_DISPLAY 4 // Desktop productivity display
#define DISPLAYID_2_0_PROD_DESKTOP_GAMING_DISPLAY 5 // Desktop gaming display
#define DISPLAYID_2_0_PROD_PRESENTATION_DISPLAY 6 // Presentation display
#define DISPLAYID_2_0_PROD_HMD_VR 7 // Head mounted Virtual Reality display
#define DISPLAYID_2_0_PROD_HMD_AR 8 // Head mounted Augmented Reality display
typedef struct _tagDISPLAYID_2_0_DATA_BLOCK_HEADER
{
NvU8 type; // Data block tag
NvU8 revision:3; // block revision
NvU8 reserved:5;
NvU8 data_bytes; // number of payload bytes in Block [ 0, 248]
} DISPLAYID_2_0_DATA_BLOCK_HEADER;
#define DISPLAYID_2_0_BLOCK_TYPE_PRODUCT_IDENTITY 0x20
#define DISPLAYID_2_0_BLOCK_TYPE_DISPLAY_PARAM 0x21
#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_VENDOR_SPEC 0x7E
#define DISPLAYID_2_0_BLOCK_TYPE_CTA_DATA 0x81
#define DISPLAYID_2_0_PRODUCT_NAME_STRING_MAX_LEN ((0xFB - 0xF) + 1)
typedef struct _tagDISPLAYID_2_0_PROD_IDENTIFICATION_BLOCK
{
// Product Identification Data Block (0x20)
// Number of payload bytes 12(0xC) - 248(0xF8)
DISPLAYID_2_0_DATA_BLOCK_HEADER header;
NvU8 vendor[3];
NvU8 product_code[2];
NvU8 serial_number[4];
NvU8 model_tag;
NvU8 model_year;
NvU8 product_name_string_size;
NvU8 product_name_string[DISPLAYID_2_0_PRODUCT_NAME_STRING_MAX_LEN];
} DISPLAYID_2_0_PROD_IDENTIFICATION_BLOCK;
typedef struct _tagDISPLAY_2_0_DISPLAY_PARAM_BLOCK_HEADER
{
NvU8 type; // Display Parameters Data Block (0x21)
NvU8 revision:3;
NvU8 reserved:4;
NvU8 image_size_multiplier:1;
NvU8 data_bytes; // number of payload bytes 29(0x1D)
} DISPLAY_2_0_DISPLAY_PARAM_BLOCK_HEADER;
typedef struct _tagDISPLAYID_2_0_COLOR_CHROMATICITY
{
NvU8 color_x_bits_low;
struct {
NvU8 color_x_bits_high:4;
NvU8 color_y_bits_low:4;
} color_bits_mid;
NvU8 color_y_bits_high;
} DISPLAYID_2_0_COLOR_CHROMATICITY;
typedef enum _tagDISPLAYID_2_0_NATIVE_COLOR_DEPTH
{
NATIVE_COLOR_NOT_DEFINED = 0,
NATIVE_COLOR_BPC_6 = 1,
NATIVE_COLOR_BPC_8 = 2,
NATIVE_COLOR_BPC_10 = 3,
NATIVE_COLOR_BPC_12 = 4,
NATIVE_COLOR_BPC_16 = 5,
} DISPLAYID_2_0_NATIVE_COLOR_DEPTH;
#define DISPLAYID_2_0_DISPLAY_PARAM_BLOCK_PAYLOAD_LENGTH 29
typedef struct _tagDISPLAYID_2_0_DISPLAY_PARAM_BLOCK
{
DISPLAY_2_0_DISPLAY_PARAM_BLOCK_HEADER header;
NvU8 horizontal_image_size[2];
NvU8 vertical_image_size[2];
NvU8 horizontal_pixel_count[2];
NvU8 vertical_pixel_count[2];
struct {
NvU8 scan_orientation :3;
NvU8 luminance_information :2;
NvU8 reserved :1;
NvU8 color_information :1;
NvU8 audio_speaker_information :1;
} feature;
DISPLAYID_2_0_COLOR_CHROMATICITY primary_color_1_chromaticity;
DISPLAYID_2_0_COLOR_CHROMATICITY primary_color_2_chromaticity;
DISPLAYID_2_0_COLOR_CHROMATICITY primary_color_3_chromaticity;
DISPLAYID_2_0_COLOR_CHROMATICITY white_point_chromaticity;
NvU8 max_luminance_full_coverage[2];
NvU8 max_luminance_1_percent_rectangular_coverage[2];
NvU8 min_luminance[2];
struct {
NvU8 color_depth :3;
NvU8 reserved0 :1;
NvU8 device_technology :3;
NvU8 device_theme_preference :1;
} color_depth_and_device_technology;
NvU8 gamma_EOTF;
} DISPLAYID_2_0_DISPLAY_PARAM_BLOCK;
#define DISPLAYID_2_0_SCAN_ORIENTATION_LRTB 0 // Left to right, top to bottom
#define DISPLAYID_2_0_SCAN_ORIENTATION_RLTB 1 // Right to left, top to bottom
#define DISPLAYID_2_0_SCAN_ORIENTATION_TBRL 2 // Top to bottom, right to left
#define DISPLAYID_2_0_SCAN_ORIENTATION_BTRL 3 // Bottom to top, right to left
#define DISPLAYID_2_0_SCAN_ORIENTATION_RLBT 4 // Right to left, bottom to top
#define DISPLAYID_2_0_SCAN_ORIENTATION_LRBT 5 // Left to right, bottom to top
#define DISPLAYID_2_0_SCAN_ORIENTATION_BTLR 6 // Bottom to top, left to right
#define DISPLAYID_2_0_SCAN_ORIENTATION_TBLR 7 // Top to bottom, left to right
#define DISPLAYID_2_0_COLOR_INFORMATION_1931_CIE 0
#define DISPLAYID_2_0_color_INFORMATION_1976_CIE 1
#define DISPLAYID_2_0_AUDIO_SPEAKER_INTEGRATED 0
#define DISPLAYID_2_0_AUDIO_SPEAKER_NOT_INTEGRATED 1
#define DISPLAYID_2_0_DEVICE_TECHNOLOGY_UNSPECIFIED 0
#define DISPLAYID_2_0_DEVICE_TECHNOLOGY_LCD 1
#define DISPLAYID_2_0_DEVICE_TECHNOLOGY_OLED 2
#define DISPLAYID_2_0_TYPE7_DSC_PASSTHRU_REVISION 1
#define DISPLAYID_2_0_TYPE7_YCC420_SUPPORT_REVISION 2
// DisplayID_v2.0 E5 - DSC Pass-Through timing
// DisplayID_v2.0 E7 - YCC420 and > 20 bytes per descriptor supported
typedef struct _tagDISPLAYID_2_0_TIMING_7_BLOCK_HEADER
{
NvU8 type; // Type VII Timing (0x22)
NvU8 revision :3;
NvU8 dsc_passthrough :1;
NvU8 payload_bytes_len :3;
NvU8 reserved :1;
NvU8 data_bytes; // Values range from 1(0x01) to 248(0xF8)
} DISPLAYID_2_0_TIMING_7_BLOCK_HEADER;
typedef struct _tag_DISPLAYID_2_0_TIMING_7_DESCRIPTOR
{
// Range is defined as 0.001 through 16,777.216 MP/s
NvU8 pixel_clock[3];
struct
{
NvU8 aspect_ratio : 4;
NvU8 interface_frame_scanning_type : 1;
NvU8 stereo_support : 2;
NvU8 is_preferred_or_ycc420 : 1;
}options;
struct
{
NvU8 active_image_pixels[2];
NvU8 blank_pixels[2];
NvU8 front_porch_pixels_low;
NvU8 front_porch_pixels_high : 7;
NvU8 sync_polarity : 1;
NvU8 sync_width_pixels[2];
}horizontal;
struct
{
NvU8 active_image_lines[2];
NvU8 blank_lines[2];
NvU8 front_porch_lines_low;
NvU8 front_porch_lines_high : 7;
NvU8 sync_polarity : 1;
NvU8 sync_width_lines[2];
}vertical;
} DISPLAYID_2_0_TIMING_7_DESCRIPTOR;
#define DISPLAYID_2_0_TIMING_7_MAX_DESCRIPTORS 12
typedef struct _tagDISPLAYID_2_0_TIMING_7_BLOCK
{
DISPLAYID_2_0_TIMING_7_BLOCK_HEADER header;
DISPLAYID_2_0_TIMING_7_DESCRIPTOR descriptors[DISPLAYID_2_0_TIMING_7_MAX_DESCRIPTORS];
} DISPLAYID_2_0_TIMING_7_BLOCK;
#define DISPLAYID_2_0_TIMING_DSC_PASSTHRU_TIMING 1
// the following fields apply to Timing Descriptors 7 (Not all of them are
// used per descriptor, but the format is the same
#define DISPLAYID_2_0_TIMING_ASPECT_RATIO_1_1 0
#define DISPLAYID_2_0_TIMING_ASPECT_RATIO_5_4 1
#define DISPLAYID_2_0_TIMING_ASPECT_RATIO_4_3 2
#define DISPLAYID_2_0_TIMING_ASPECT_RATIO_15_9 3
#define DISPLAYID_2_0_TIMING_ASPECT_RATIO_16_9 4
#define DISPLAYID_2_0_TIMING_ASPECT_RATIO_16_10 5
#define DISPLAYID_2_0_TIMING_ASPECT_RATIO_64_27 6
#define DISPLAYID_2_0_TIMING_ASPECT_RATIO_256_135 7
#define DISPLAYID_2_0_TIMING_ASPECT_RATIO_CALCULATE 8 // calculate using Horizontal and Vertical Active Image Pixels
#define DISPLAYID_2_0_TIMING_PROGRESSIVE_SCAN 0
#define DISPLAYID_2_0_TIMING_INTERLACED_SCAN 1
#define DISPLAYID_2_0_TIMING_3D_STEREO_MONO 0
#define DISPLAYID_2_0_TIMING_3D_STEREO_STEREO 1
#define DISPLAYID_2_0_TIMING_3D_STEREO_EITHER 2
#define DISPLAYID_2_0_TIMING_SYNC_POLARITY_NEGATIVE 0
#define DISPLAYID_2_0_TIMING_SYNC_POLARITY_POSITIVE 1
typedef struct _tagDISPLAYID_2_0_TIMING_8_BLOCK_HEADER
{
NvU8 type; // Type VIII Timing (0x23)
NvU8 revision :3;
NvU8 timing_code_size :1;
NvU8 reserved :1;
NvU8 is_support_yuv420 :1;
NvU8 timing_code_type :2;
NvU8 data_bytes; // Values range from 1(0x01) to 248(0xF8)
} DISPLAYID_2_0_TIMING_8_BLOCK_HEADER;
typedef struct _tagDISPLAYID_2_0_TIMING_8_ONE_BYTE_CODE
{
NvU8 timing_code;
} DISPLAYID_2_0_TIMING_8_ONE_BYTE_CODE;
typedef struct _tagDISPLAYID_2_0_TIMING_8_TWO_BYTE_CODE
{
NvU8 timing_code[2];
} DISPLAYID_2_0_TIMING_8_TWO_BYTE_CODE;
#define DISPLAYID_2_0_TIMING_8_MAX_CODES 248
typedef struct _tagDISPLAYID_2_0_TIMING_8_BLOCK
{
DISPLAYID_2_0_TIMING_8_BLOCK_HEADER header;
union
{
DISPLAYID_2_0_TIMING_8_ONE_BYTE_CODE timing_code_1[DISPLAYID_2_0_TIMING_8_MAX_CODES];
DISPLAYID_2_0_TIMING_8_TWO_BYTE_CODE timing_code_2[DISPLAYID_2_0_TIMING_8_MAX_CODES / 2];
};
} DISPLAYID_2_0_TIMING_8_BLOCK;
#define DISPLAYID_2_0_TIMING_CODE_DMT 0
#define DISPLAYID_2_0_TIMING_CODE_CTA_VIC 1
#define DISPLAYID_2_0_TIMING_CODE_HDMI_VIC 2
#define DISPLAYID_2_0_TIMING_CODE_RSERVED 3
#define DISPLAYID_2_0_TIMING_CODE_SIZE_1_BYTE 0
#define DISPLAYID_2_0_TIMING_CODE_SIZE_2_BYTE 1
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;
} options;
NvU8 horizontal_active_pixels[2];
NvU8 vertical_active_lines[2];
NvU8 refresh_rate; // 1 Hz to 256 Hz
} 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_9_MAX_DESCRIPTORS 41
typedef struct _tagDISPLAYID_2_0_TIMING_9_BLOCK
{
// Type IX Timing (0x24)
DISPLAYID_2_0_DATA_BLOCK_HEADER header;
DISPLAYID_2_0_TIMING_9_DESCRIPTOR descriptors[DISPLAYID_2_0_TIMING_9_MAX_DESCRIPTORS];
} DISPLAYID_2_0_TIMING_9_BLOCK;
#define DISPLAYID_2_0_TIMING_10_PAYLOAD_BYTES_6 0
#define DISPLAYID_2_0_TIMING_10_PAYLOAD_BYTES_7 1
typedef struct _tagDISPLAYID_2_0_TIMING_10_BLOCK_HEADER
{
NvU8 type; // Type X Timing (0x2A)
NvU8 revision :3;
NvU8 reserved0 :1;
NvU8 payload_bytes_len :3;
NvU8 reserved1 :1;
NvU8 payload_bytes;
} DISPLAYID_2_0_TIMING_10_BLOCK_HEADER;
typedef struct _DISPLAYID_2_0_TIMING_10_6BYTES_DESCRIPTOR
{
struct {
NvU8 timing_formula :3;
NvU8 reserved0 :1;
NvU8 vrr_or_hblank :1;
NvU8 stereo_support :2;
NvU8 ycc420_support :1;
} options;
NvU8 horizontal_active_pixels[2];
NvU8 vertical_active_lines[2];
NvU8 refresh_rate; // 1 Hz to 256 Hz
} DISPLAYID_2_0_TIMING_10_6BYTES_DESCRIPTOR;
typedef struct _DISPLAYID_2_0_TIMING_10_7BYTES_DESCRIPTOR
{
DISPLAYID_2_0_TIMING_10_6BYTES_DESCRIPTOR descriptor_6_bytes;
NvU8 refresh_rate_high :2;
NvU8 delta_hblank :3;
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
typedef struct _DISPLAYID_2_0_TIMING_10_BLOCK
{
DISPLAYID_2_0_TIMING_10_BLOCK_HEADER header;
NvU8 descriptors[120];
} DISPLAYID_2_0_TIMING_10_BLOCK;
#define DISPLAYID_2_0_RANGE_LIMITS_BLOCK_PAYLOAD_LENGTH 9
typedef struct _tagDISPLAYID_2_0_RANGE_LIMITS_BLOCK
{
DISPLAYID_2_0_DATA_BLOCK_HEADER header;
NvU8 pixel_clock_min[3];
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;
} dynamic_video_timing_range_support;
} DISPLAYID_2_0_RANGE_LIMITS_BLOCK;
#define DISPLAYID_2_0_SEAMLESS_DYNAMIC_VIDEO_TIMING_CHANGE_NOT_SUPPORTED 0
#define DISPLAYID_2_0_SEAMLESS_DYNAMIC_VIDEO_TIMING_CHANGE_SUPPORTED 1
#define DISPLAYID_2_0_INTERFACE_FEATURES_BLOCK_PAYLOAD_LENGTH_MIN 9
#define DISPLAYID_2_0_MAX_COLOR_SPACE_AND_EOTF 7
typedef struct _tagDISPLAYID_2_0_INTERFACE_FEATURES_BLOCK
{
// Display Interface Features Data Block (0x26)
DISPLAYID_2_0_DATA_BLOCK_HEADER header;
struct {
NvU8 bit_per_primary_6:1;
NvU8 bit_per_primary_8:1;
NvU8 bit_per_primary_10:1;
NvU8 bit_per_primary_12:1;
NvU8 bit_per_primary_14:1;
NvU8 bit_per_primary_16:1;
NvU8 reserved:2;
} interface_color_depth_rgb;
struct {
NvU8 bit_per_primary_6:1;
NvU8 bit_per_primary_8:1;
NvU8 bit_per_primary_10:1;
NvU8 bit_per_primary_12:1;
NvU8 bit_per_primary_14:1;
NvU8 bit_per_primary_16:1;
NvU8 reserved:2;
} interface_color_depth_ycbcr444;
struct {
NvU8 bit_per_primary_8:1;
NvU8 bit_per_primary_10:1;
NvU8 bit_per_primary_12:1;
NvU8 bit_per_primary_14:1;
NvU8 bit_per_primary_16:1;
NvU8 reserved:3;
} interface_color_depth_ycbcr422;
struct {
NvU8 bit_per_primary_8:1;
NvU8 bit_per_primary_10:1;
NvU8 bit_per_primary_12:1;
NvU8 bit_per_primary_14:1;
NvU8 bit_per_primary_16:1;
NvU8 reserved:3;
} interface_color_depth_ycbcr420;
NvU8 min_pixel_rate_ycbcr420; // x 74.25MP/s
struct {
NvU8 reserved:5;
NvU8 sample_rate_48_khz:1;
NvU8 sample_rate_44_1_khz:1;
NvU8 sample_rate_32_khz:1;
} audio_capability;
struct {
NvU8 color_space_srgb_eotf_srgb:1;
NvU8 color_space_bt601_eotf_bt601:1;
NvU8 color_space_bt709_eotf_bt1886:1;
NvU8 color_space_adobe_rgb_eotf_adobe_rgb:1;
NvU8 color_space_dci_p3_eotf_dci_p3:1;
NvU8 color_space_bt2020_eotf_bt2020:1;
NvU8 color_space_bt2020_eotf_smpte_st2084:1;
NvU8 reserved:1;
} color_space_and_eotf_1;
struct {
NvU8 reserved;
} color_space_and_eotf_2;
struct {
NvU8 count:3;
NvU8 reserved:5;
} additional_color_space_and_eotf_count;
struct {
NvU8 eotf:4;
NvU8 color_space:4;
} additional_color_space_and_eotf[DISPLAYID_2_0_MAX_COLOR_SPACE_AND_EOTF];
} DISPLAYID_2_0_INTERFACE_FEATURES_BLOCK;
#define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_COLORSPACE_NOT_DEFINED 0
#define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_COLORSPACE_SRGB 1
#define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_COLORSPACE_BT601 2
#define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_COLORSPACE_BT709 3
#define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_COLORSPACE_ADOBE_RGB 4
#define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_COLORSPACE_DCI_P3 5
#define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_COLORSPACE_BT2020 6
#define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_COLORSPACE_CUSTOM 7
#define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_EOTF_NOT_DEFINED 0
#define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_EOTF_SRGB 1
#define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_EOTF_BT601 2
#define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_EOTF_BT709 3
#define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_EOTF_ADOBE_RGB 4
#define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_EOTF_DCI_P3 5
#define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_EOTF_BT2020 6
#define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_EOTF_GAMMA 7
#define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_EOTF_SMPTE_ST2084 8
#define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_EOTF_HYBRID_LOG 9
#define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_EOTF_CUSTOM 10
typedef struct _tagDISPLAYID_2_0_STEREO_INTERFACE_BLOCK_HEADER
{
NvU8 type;
NvU8 revision:3;
NvU8 reserved:3;
NvU8 stereo_timing_support:2;
} DISPLAYID_2_0_STEREO_INTERFACE_BLOCK_HEADER;
typedef struct _tagDISPLAYID_2_0_STEREO_TIMING_DESCRIPTOR
{
NvU8 supported_timing_code_count:5;
NvU8 reserved:1;
NvU8 timing_code_type:2;
NvU8 timing_code[0x1F];
} DISPLAYID_2_0_STEREO_TIMING_DESCRIPTOR;
typedef struct _tagDISPLAYID_2_0_STEREO_FIELD_SEQUENTIAL_INTERFACE_DESCRIPTOR
{
NvU8 polarity_descriptor:1;
NvU8 reserved:7;
DISPLAYID_2_0_STEREO_TIMING_DESCRIPTOR timing_descriptor;
} DISPLAYID_2_0_STEREO_FIELD_SEQUENTIAL_INTERFACE_DESCRIPTOR;
typedef struct _tagDISPLAYID_2_0_STEREO_SIDE_BY_SIDE_INTERFACE_DESCRIPTOR
{
NvU8 view_identity_descriptor:1;
NvU8 reserved:7;
DISPLAYID_2_0_STEREO_TIMING_DESCRIPTOR timing_descriptor;
} DISPLAYID_2_0_STEREO_SIDE_BY_SIDE_INTERFACE_DESCRIPTOR;
typedef struct _tagDISPLAYID_2_0_STEREO_PIXEL_INTERLEAVED_DESCRIPTOR
{
NvU8 interleaved_pattern_descriptor[8];
DISPLAYID_2_0_STEREO_TIMING_DESCRIPTOR timing_descriptor;
} DISPLAYID_2_0_STEREO_PIXEL_INTERLEAVED_DESCRIPTOR;
typedef struct _tagDISPLAYID_2_0_STEREO_DUAL_INTERFACE_LEFT_AND_RIGHT_SEPARATE_DESCRIPTOR
{
NvU8 left_and_right_polarity_descriptor:1;
NvU8 mirroring_descriptor:2;
NvU8 reserved:5;
DISPLAYID_2_0_STEREO_TIMING_DESCRIPTOR timing_descriptor;
} DISPLAYID_2_0_STEREO_DUAL_INTERFACE_LEFT_AND_RIGHT_SEPARATE_DESCRIPTOR;
typedef struct _tagDISPLAYID_2_0_STEREO_MULTI_VIEW_DESCRIPTOR
{
NvU8 views_descriptors_count;
NvU8 view_interleaving_method_code_descriptor;
DISPLAYID_2_0_STEREO_TIMING_DESCRIPTOR timing_descriptor;
} DISPLAYID_2_0_STEREO_MULTI_VIEW_DESCRIPTOR;
typedef struct _tagDISPLAYID_2_0_STEREO_STACKED_FRAME_DESCRIPTOR
{
NvU8 view_identity_descriptor:1;
NvU8 reserved:7;
DISPLAYID_2_0_STEREO_TIMING_DESCRIPTOR timing_descriptor;
} DISPLAYID_2_0_STEREO_STACKED_FRAME_DESCRIPTOR;
typedef struct _tagDISPLAYID_2_0_STEREO_PROPRIETARY_DESCRIPTOR
{
DISPLAYID_2_0_STEREO_TIMING_DESCRIPTOR timing_descriptor;
} DISPLAYID_2_0_STEREO_PROPRIETARY_DESCRIPTOR;
typedef struct _tagDISPLAYID_2_0_STEREO_INTERFACE_METHOD_BLOCK
{
DISPLAYID_2_0_STEREO_INTERFACE_BLOCK_HEADER header;
NvU8 stereo_bytes;
NvU8 stereo_code;
union {
DISPLAYID_2_0_STEREO_FIELD_SEQUENTIAL_INTERFACE_DESCRIPTOR field_sequential;
DISPLAYID_2_0_STEREO_SIDE_BY_SIDE_INTERFACE_DESCRIPTOR side_by_side;
DISPLAYID_2_0_STEREO_PIXEL_INTERLEAVED_DESCRIPTOR pixel_interleaved;
DISPLAYID_2_0_STEREO_DUAL_INTERFACE_LEFT_AND_RIGHT_SEPARATE_DESCRIPTOR dual_interface;
DISPLAYID_2_0_STEREO_MULTI_VIEW_DESCRIPTOR multi_view;
DISPLAYID_2_0_STEREO_STACKED_FRAME_DESCRIPTOR stacked_frame;
DISPLAYID_2_0_STEREO_PROPRIETARY_DESCRIPTOR proprietary;
};
} DISPLAYID_2_0_STEREO_INTERFACE_METHOD_BLOCK;
#define DISPLAYID_2_0_STEREO_CODE_FIELD_SEQUENTIAL 0x0
#define DISPLAYID_2_0_STEREO_CODE_SIDE_BY_SIDE 0x1
#define DISPLAYID_2_0_STEREO_CODE_PIXEL_INTERLEAVED 0x2
#define DISPLAYID_2_0_STEREO_CODE_DUAL_INTERFACE 0x3
#define DISPLAYID_2_0_STEREO_CODE_MULTIVIEW 0x4
#define DISPLAYID_2_0_STEREO_CODE_STACKED_FRAME 0x5
#define DISPLAYID_2_0_STEREO_CODE_PROPRIETARY 0xFF
#define DISPLAYID_STEREO_MIRRORING 2:1
#define DISPLAYID_STEREO_POLARITY 0:0
#define DISPLAYID_2_0_TILED_DISPLAY_BLOCK_PAYLOAD_LENGTH 22
typedef struct _tagDISPLAYID_2_0_TILED_DISPLAY_BLOCK
{
DISPLAYID_2_0_DATA_BLOCK_HEADER header;
struct
{
NvU8 single_tile_behavior:3; // 0x03
NvU8 multi_tile_behavior:2; // 0x03
NvU8 rsvd :1; // 0x03
NvU8 has_bezel_info :1; // 0x03
NvU8 single_enclosure :1; // 0x03
} capability;
struct
{
NvU8 row :4; // 0x04
NvU8 col :4; // 0x04
} topo_low;
struct
{
NvU8 y :4; // 0x05
NvU8 x :4; // 0x05
} loc_low;
struct
{
NvU8 y :2; // 0x06
NvU8 x :2; // 0x06
NvU8 row :2; // 0x06
NvU8 col :2; // 0x06
} topo_loc_high;
struct
{
NvU8 width_low; // 0x07
NvU8 width_high; // 0x08
NvU8 height_low; // 0x09
NvU8 height_high; // 0X0A
} native_resolution;
struct
{
NvU8 pixel_density; // 0x0B
NvU8 top; // 0x0C
NvU8 bottom; // 0x0D
NvU8 right; // 0x0E
NvU8 left; // 0x0F
} bezel_info;
struct
{
NvU8 vendor_id[3]; // 0x10 ~ 0x12
NvU8 product_id[2]; // 0x13 ~ 0x14
NvU8 serial_number[4]; // 0x15 ~ 0x18
} topo_id;
} DISPLAYID_2_0_TILED_DISPLAY_BLOCK;
#define DISPLAYID_2_0_CONTAINERID_BLOCK_PAYLOAD_LENGTH 16
typedef struct _tagDISPLAYID_2_0_CONTAINERID_BLOCK
{
DISPLAYID_2_0_DATA_BLOCK_HEADER header;
NvU8 container_id[DISPLAYID_2_0_CONTAINERID_BLOCK_PAYLOAD_LENGTH];
} DISPLAYID_2_0_CONTAINERID_BLOCK;
typedef struct _tagDISPLAYID_2_0_VENDOR_SPECIFIC_BLOCK
{
DISPLAYID_2_0_DATA_BLOCK_HEADER header;
NvU8 vendor_id[3];
NvU8 vendor_specific_data[245];
} DISPLAYID_2_0_VENDOR_SPECIFIC_BLOCK;
typedef struct _tagDISPLAYID_2_0_CTA_BLOCK
{
DISPLAYID_2_0_DATA_BLOCK_HEADER header;
NvU8 cta_data[248];
} DISPLAYID_2_0_CTA_BLOCK;
#ifdef __SUPPORTS_PACK_PRAGMA
#pragma pack()
#endif
// Entry point functions both used in DID20 and DID20ext
NVT_STATUS parseDisplayId20DataBlock(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo);
NvU8 computeDisplayId20SectionCheckSum(const NvU8 *pSectionBytes, NvU32 length);
#endif // __DISPLAYID20_H_

View File

@@ -0,0 +1,373 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2016 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/*
===============================================================================
dp_sdp.cpp
Provide definition needed for display port secondary data packet.
================================================================================
*/
#ifndef __DPSDP_H__
#define __DPSDP_H__
#include "nvtypes.h"
#define DP_SDP_HEADER_SIZE 4
#define DP_SDP_DATA_SIZE 28
// TODO: needs to wait for RM to provide the enum. Therefore, hardcoded to 7, which is the packet type for VSC SDP
typedef enum tagSDP_PACKET_TYPE
{
SDP_PACKET_TYPE_VSC = 7,
} SDP_PACKET_TYPE;
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_COLOR,
SDP_VSC_REVNUM_STEREO_PR,
SDP_VSC_REVNUM_STEREO_PR_COLOR,
} SDP_VSC_REVNUM;
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_COLOR = 19,
SDP_VSC_VALID_DATA_BYTES_PR = 16,
SDP_VSC_VALID_DATA_BYTES_PR_COLOR = 19,
} SDP_VSC_VALID_DATA_BYTES;
typedef enum tagSDP_VSC_DYNAMIC_RANGE
{
SDP_VSC_DYNAMIC_RANGE_VESA,
SDP_VSC_DYNAMIC_RANGE_CEA,
} SDP_VSC_DYNAMIC_RANGE;
typedef enum tagSDP_VSC_PIX_ENC
{
SDP_VSC_PIX_ENC_RGB,
SDP_VSC_PIX_ENC_YCBCR444,
SDP_VSC_PIX_ENC_YCBCR422,
SDP_VSC_PIX_ENC_YCBCR420,
SDP_VSC_PIX_ENC_Y,
SDP_VSC_PIX_ENC_RAW,
} SDP_VSC_PIX_ENC;
typedef enum tagSDP_VSC_BIT_DEPTH_RGB
{
SDP_VSC_BIT_DEPTH_RGB_6BPC = 0,
SDP_VSC_BIT_DEPTH_RGB_8BPC,
SDP_VSC_BIT_DEPTH_RGB_10BPC,
SDP_VSC_BIT_DEPTH_RGB_12BPC,
SDP_VSC_BIT_DEPTH_RGB_16BPC,
} SDP_VSC_BIT_DEPTH_RGB;
typedef enum tagSDP_VSC_BIT_DEPTH_YCBCR
{
SDP_VSC_BIT_DEPTH_YCBCR_8BPC = 1,
SDP_VSC_BIT_DEPTH_YCBCR_10BPC,
SDP_VSC_BIT_DEPTH_YCBCR_12BPC,
SDP_VSC_BIT_DEPTH_YCBCR_16BPC,
} SDP_VSC_BIT_DEPTH_YCBCR;
typedef enum tagSDP_VSC_BIT_DEPTH_RAW
{
SDP_VSC_BIT_DEPTH_RAW_6BPC = 1,
SDP_VSC_BIT_DEPTH_RAW_7BPC,
SDP_VSC_BIT_DEPTH_RAW_8BPC,
SDP_VSC_BIT_DEPTH_RAW_10BPC,
SDP_VSC_BIT_DEPTH_RAW_12BPC,
SDP_VSC_BIT_DEPTH_RAW_14PC,
SDP_VSC_BIT_DEPTH_RAW_16PC,
} SDP_VSC_BIT_DEPTH_RAW;
typedef enum tagSDP_VSC_CONTENT_TYPE
{
SDP_VSC_CONTENT_TYPE_UNDEFINED = 0,
SDP_VSC_CONTENT_TYPE_GRAPHICS,
SDP_VSC_CONTENT_TYPE_PHOTO,
SDP_VSC_CONTENT_TYPE_VIDEO,
SDP_VSC_CONTENT_TYPE_GAMES,
} SDP_VSC_CONTENT_TYPE;
typedef enum tagSDP_VSC_COLOR_FMT_RGB_COLORIMETRY
{
SDP_VSC_COLOR_FMT_RGB_COLORIMETRY_SRGB = 0,
SDP_VSC_COLOR_FMT_RGB_COLORIMETRY_RGB_WIDE_GAMUT_FIXED,
SDP_VSC_COLOR_FMT_RGB_COLORIMETRY_RGB_SCRGB,
SDP_VSC_COLOR_FMT_RGB_COLORIMETRY_ADOBERGB,
SDP_VSC_COLOR_FMT_RGB_COLORIMETRY_DCI_P3,
SDP_VSC_COLOR_FMT_RGB_COLORIMETRY_CUSTOM,
SDP_VSC_COLOR_FMT_RGB_COLORIMETRY_ITU_R_BT2020_RGB,
} SDP_VSC_COLOR_FMT_RGB_COLORIMETRY;
typedef enum tagSDP_VSC_COLOR_FMT_YCBCR_COLORIMETRY
{
SDP_VSC_COLOR_FMT_YCBCR_COLORIMETRY_ITU_R_BT601 = 0,
SDP_VSC_COLOR_FMT_YCBCR_COLORIMETRY_ITU_R_BT709,
SDP_VSC_COLOR_FMT_YCBCR_COLORIMETRY_XVYCC601,
SDP_VSC_COLOR_FMT_YCBCR_COLORIMETRY_XVYCC709,
SDP_VSC_COLOR_FMT_YCBCR_COLORIMETRY_SYCC601,
SDP_VSC_COLOR_FMT_YCBCR_COLORIMETRY_ADOBEYCC601,
SDP_VSC_COLOR_FMT_YCBCR_COLORIMETRY_ITU_R_BT2020_YCCBCCRC,
SDP_VSC_COLOR_FMT_YCBCR_COLORIMETRY_ITU_R_BT2020_YCBCR,
} SDP_VSC_COLOR_FMT_YCBCR_COLORIMETRY;
typedef enum tagSDP_VSC_COLOR_FMT_RAW_COLORIMETRY
{
SDP_VSC_COLOR_FMT_RAW_COLORIMETRY_CUSTOM_COLOR_PROFILE = 0,
} SDP_VSC_COLOR_FMT_RAW;
typedef enum tagSDP_VSC_COLOR_FMT_Y_COLORIMETRY
{
SDP_VSC_COLOR_FMT_Y_COLORIMETRY_DICOM = 0,
} SDP_VSC_COLOR_FMT_Y;
// The struct element field hb and db fields are arranged to match the HW registers
// NV_PDISP_SF_DP_GENERIC_INFOFRAME_HEADER* and NV_PDISP_SF_DP_GENERIC_INFOFRAME_SUBPACK0_DB*
typedef struct tagDPSDP_DP_VSC_SDP_DESCRIPTOR
{
NvU8 dataSize; // the db data size
// header
struct
{
NvU8 hb0; // DP1.3 spec, the value = 0
NvU8 hb1; // DP1.3 spec, value = 7
NvU8 revisionNumber : 5;
NvU8 hb2Reserved : 3;
NvU8 numValidDataBytes : 5; // number of valid data bytes
NvU8 hb3Reserved : 3;
} hb;
// data content
struct
{
// 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.
NvU8 psrState : 1; //DB1
NvU8 psrUpdateRfb : 1;
NvU8 psrCrcValid : 1;
NvU8 psrSuValid : 1;
NvU8 psrSuFirstScanLine : 1;
NvU8 psrSuLastScanLine : 1;
NvU8 psrYCoordinateValid : 1;
NvU8 psrReserved : 1;
NvU8 db2;
NvU8 db3;
NvU8 db4;
NvU8 db5;
NvU8 db6;
NvU8 db7;
// DB8 - DB15 are undefined in DP 1.3 spec.
NvU8 db8;
NvU8 db9;
NvU8 db10;
NvU8 db11;
NvU8 db12;
NvU8 db13;
NvU8 db14;
NvU8 db15;
// 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
NvU8 bitDepth : 7; // DB17 infoframe per DP1.3 spec
NvU8 dynamicRange : 1; // DB17 infoframe per DP1.3 spec
NvU8 contentType : 3; // DB18 infoframe per DP1.3 spec
NvU8 db18Reserved : 5;
NvU8 db19;
NvU8 db20;
NvU8 db21;
NvU8 db22;
NvU8 db23;
NvU8 db24;
NvU8 db25;
NvU8 db26;
NvU8 db27;
} db;
} DPSDP_DP_VSC_SDP_DESCRIPTOR;
typedef struct tagDPSDP_DP_PR_VSC_SDP_DESCRIPTOR
{
NvU8 dataSize; // the db data size
// header
struct
{
NvU8 hb0; // DP1.3 spec, the value = 0
NvU8 hb1; // DP1.3 spec, value = 7
NvU8 revisionNumber : 5;
NvU8 hb2Reserved : 3;
NvU8 numValidDataBytes : 5; // number of valid data bytes
NvU8 hb3Reserved : 3;
} hb;
// data content
struct
{
// 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.
NvU8 prState : 1; // DB1
NvU8 prReserved : 1; // Always ZERO
NvU8 prCrcValid : 1;
NvU8 prSuValid : 1;
NvU8 prReservedEx : 4;
NvU8 db2;
NvU8 db3;
NvU8 db4;
NvU8 db5;
NvU8 db6;
NvU8 db7;
// DB8 - DB15 are undefined in DP 1.3 spec.
NvU8 db9;
NvU8 db10;
NvU8 db11;
NvU8 db12;
NvU8 db13;
NvU8 db14;
NvU8 db15;
// 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
NvU8 bitDepth : 7; // DB17 infoframe per DP1.3 spec
NvU8 dynamicRange : 1; // DB17 infoframe per DP1.3 spec
NvU8 contentType : 3; // DB18 infoframe per DP1.3 spec
NvU8 db18Reserved : 5;
NvU8 db19;
NvU8 db20;
NvU8 db21;
NvU8 db22;
NvU8 db23;
NvU8 db24;
NvU8 db25;
NvU8 db26;
NvU8 db27;
} db;
} DPSDP_DP_PR_VSC_SDP_DESCRIPTOR;
typedef struct tagDPSDP_DESCRIPTOR
{
NvU8 dataSize;
// header byte
struct
{
NvU8 hb0;
NvU8 hb1;
NvU8 hb2;
NvU8 hb3;
} hb;
// content byte
struct
{
NvU8 db0;
NvU8 db1;
NvU8 db2;
NvU8 db3;
NvU8 db4;
NvU8 db5;
NvU8 db6;
NvU8 db7;
NvU8 db8;
NvU8 db9;
NvU8 db10;
NvU8 db11;
NvU8 db12;
NvU8 db13;
NvU8 db14;
NvU8 db15;
NvU8 db16;
NvU8 db17;
NvU8 db18;
NvU8 db19;
NvU8 db20;
NvU8 db21;
NvU8 db22;
NvU8 db23;
NvU8 db24;
NvU8 db25;
NvU8 db26;
NvU8 db27;
NvU8 db28;
NvU8 db29;
NvU8 db30;
NvU8 db31;
} db;
} DPSDP_DESCRIPTOR;
// The following #defines are for RGB only
#define DP_VSC_SDP_BIT_DEPTH_RGB_6BPC 0
#define DP_VSC_SDP_BIT_DEPTH_RGB_8BPC 1
#define DP_VSC_SDP_BIT_DEPTH_RGB_10BPC 2
#define DP_VSC_SDP_BIT_DEPTH_RGB_12BPC 3
#define DP_VSC_SDP_BIT_DEPTH_RGB_16BPC 4
// The following #defines are for YUV only
#define DP_VSC_SDP_BIT_DEPTH_YUV_8BPC 1
#define DP_VSC_SDP_BIT_DEPTH_YUV_10BPC 2
#define DP_VSC_SDP_BIT_DEPTH_YUV_12BPC 3
#define DP_VSC_SDP_BIT_DEPTH_YUV_16BPC 4
// The following #defines are for RAW only
#define DP_VSC_SDP_BIT_DEPTH_RAW_6BPC 1
#define DP_VSC_SDP_BIT_DEPTH_RAW_7BPC 2
#define DP_VSC_SDP_BIT_DEPTH_RAW_8BPC 3
#define DP_VSC_SDP_BIT_DEPTH_RAW_10BPC 4
#define DP_VSC_SDP_BIT_DEPTH_RAW_12BPC 5
#define DP_VSC_SDP_BIT_DEPTH_RAW_14BPC 6
#define DP_VSC_SDP_BIT_DEPTH_RAW_16BPC 7
#define DP_INFOFRAME_SDP_V1_3_VERSION 0x13
#define DP_INFOFRAME_SDP_V1_3_HB3_VERSION_MASK 0xFC
#define DP_INFOFRAME_SDP_V1_3_HB3_VERSION_SHIFT 2
#define DP_INFOFRAME_SDP_V1_3_HB3_MSB_MASK 0x3
#define DP_INFOFRAME_SDP_V1_3_NON_AUDIO_SIZE 30
#endif // __DPSDP_H_

View File

@@ -0,0 +1,341 @@
//*****************************************************************************
//
// SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: MIT
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File: edid.h
//
// Purpose: the template for EDID parse
//
//*****************************************************************************
#ifndef __EDID_H_
#define __EDID_H_
#include "nvtiming.h"
#include "nvtiming_pvt.h"
// EDID 1.x detailed timing template
#define NVT_PVT_EDID_LDD_PAYLOAD_SIZE 13
typedef struct _tagEDID_LONG_DISPLAY_DESCRIPTOR
{
// the header
NvU8 prefix[2]; // 0x00 ~ 0x01
NvU8 rsvd; // 0x02
NvU8 tag; // 0x03
NvU8 rsvd2; // 0x04
// the payload
NvU8 data[NVT_PVT_EDID_LDD_PAYLOAD_SIZE]; // 0x05~0x11
}EDID_LONG_DISPLAY_DESCRIPTOR;
typedef struct _tagEDID_MONITOR_RANGE_GTF2
{
NvU8 reserved; // byte 0x0B: reserved as 00
NvU8 startFreq; // byte 0x0C: start frequency for secondary curve, hot. freq./2[kHz]
NvU8 C; // byte 0x0D: C*2 0 <= 127
NvU8 M_LSB; // byte 0x0E-0x0F: M (LSB) 0 <= M <= 65535
NvU8 M_MSB;
NvU8 K; // byte 0x10: K 0 <= K <= 255
NvU8 J; // byte 0x11: J*2 0 <= J <= 127
}EDID_MONITOR_RANGE_GTF2;
typedef struct _tagEDID_MONITOR_RANGE_CVT
{
NvU8 version; // byte 0x0B: cvt version
NvU8 pixel_clock; // byte 0x0C: [bits 7:2]pixel clock precision
// [bits 1:0]max active MSB
NvU8 max_active; // byte 0x0D: with byte 12 [bits 1:0], max active pixels per line
NvU8 aspect_supported; // byte 0x0E: supported aspect ratios
NvU8 aspect_preferred_blanking; // byte 0x0F: preferred aspect ratio / blanking style support
NvU8 scaling_support; // byte 0x10: display scaling support
NvU8 preferred_refresh_rate; // byte 0x11: preferred vertical refresh rate
}EDID_MONITOR_RANGE_CVT;
// cvt support in display range limit block
#define NVT_PVT_EDID_CVT_PIXEL_CLOCK_MASK 0xFC
#define NVT_PVT_EDID_CVT_PIXEL_CLOCK_SHIFT 2
#define NVT_PVT_EDID_CVT_ACTIVE_MSB_MASK 0x03
#define NVT_PVT_EDID_CVT_ACTIVE_MSB_SHIFT 8
#define NVT_PVT_EDID_CVT_ASPECT_SUPPORTED_MASK 0xF8
#define NVT_PVT_EDID_CVT_ASPECT_SUPPORTED_SHIFT 3
#define NVT_PVT_EDID_CVT_RESERVED0_MASK 0x07
#define NVT_PVT_EDID_CVT_RESERVED0_SHIFT 0
#define NVT_PVT_EDID_CVT_ASPECT_PREFERRED_MASK 0xE0
#define NVT_PVT_EDID_CVT_ASPECT_PREFERRED_SHIFT 5
#define NVT_PVT_EDID_CVT_BLANKING_MASK 0x18
#define NVT_PVT_EDID_CVT_BLANKING_SHIFT 3
#define NVT_PVT_EDID_CVT_RESERVED1_MASK 0x07
#define NVT_PVT_EDID_CVT_RESERVED1_SHIFT 0
#define NVT_PVT_EDID_CVT_SCALING_MASK 0xF0
#define NVT_PVT_EDID_CVT_SCALING_SHIFT 4
#define NVT_PVT_EDID_CVT_RESERVED2_MASK 0x0F
#define NVT_PVT_EDID_CVT_RESERVED2_SHIFT 0
typedef struct _tagEDID_MONITOR_RANGE_LIMIT
{
// the header in monitor descriptor data
NvU8 minVRate; // byte 0x05: min vertical rate
NvU8 maxVRate; // byte 0x06: max vertical rate
NvU8 minHRate; // byte 0x07: min horizontal rate
NvU8 maxHRate; // byte 0x08: max horizontal rate
NvU8 maxPClock10M; // byte 0x09: max pixel clock in 10M
NvU8 timing_support; // byte 0x0A: 2nd GTF / CVT timing formula support
union
{
EDID_MONITOR_RANGE_GTF2 gtf2; // bytes 0x0B-0x11
EDID_MONITOR_RANGE_CVT cvt; // ...
}u;
} EDID_MONITOR_RANGE_LIMIT;
// timing_support
#define NVT_PVT_EDID_RANGE_OFFSET_VER_MIN 0x01
#define NVT_PVT_EDID_RANGE_OFFSET_VER_MAX 0x02
#define NVT_PVT_EDID_RANGE_OFFSET_HOR_MIN 0x04
#define NVT_PVT_EDID_RANGE_OFFSET_HOR_MAX 0x08
#define NVT_PVT_EDID_RANGE_OFFSET_AMOUNT 255
typedef struct _tagEDID_CVT_3BYTE_BLOCK
{
NvU8 addressable_lines; // byte 0: 8 lsb of addressable lines
NvU8 lines_ratio; // byte 1 : [bits7:4] 4 msb of addressable lines [bits3:2] aspect ratio
NvU8 refresh_rates; // byte 2 : supported/preferred refresh rates
}EDID_CVT_3BYTE_BLOCK;
typedef struct _tagEDID_CVT_3BYTE
{
// the header in monitor descriptor data.
NvU8 version; // byte 0x05 : version code (0x01)
EDID_CVT_3BYTE_BLOCK block[NVT_EDID_DD_MAX_CVT3_PER_DESCRITPOR]; // bytes 0x06-0x11
}EDID_CVT_3BYTE;
// CVT 3byte
#define NVT_PVT_EDID_CVT3_LINES_MSB_MASK 0xF0
#define NVT_PVT_EDID_CVT3_LINES_MSB_SHIFT 4
#define NVT_PVT_EDID_CVT3_ASPECT_MASK 0x0C
#define NVT_PVT_EDID_CVT3_ASPECT_SHIFT 2
#define NVT_PVT_EDID_CVT3_PREFERRED_RATE_MASK 0x60
#define NVT_PVT_EDID_CVT3_PREFERRED_RATE_SHIFT 5
#define NVT_PVT_EDID_CVT3_SUPPORTED_RATE_MASK 0x1F
#define NVT_PVT_EDID_CVT3_SUPPORTED_RATE_SHIFT 0
typedef struct _tagEDID_COLOR_POINT_DATA
{
NvU8 wp1_index; // 0x05: white point index number
NvU8 wp1_x_y; // 0x06: [bits3:2] lsb of wp1_x [bits1:0] lsb of wp1_y
NvU8 wp1_x; // 0x07: msb of wp1_x
NvU8 wp1_y; // 0x08: msb of wp1_y
NvU8 wp1_gamma; // 0x09: (gamma x 100) - 100
NvU8 wp2_index; // 0x0A: ...
NvU8 wp2_x_y; // 0x0B: ...
NvU8 wp2_x; // 0x0C: ...
NvU8 wp2_y; // 0x0D: ...
NvU8 wp2_gamma; // 0x0E: ...
NvU8 line_feed; // 0x0F: reserved for line feed (0x0A)
NvU16 reserved0; // 0x10-0x11: reserved for space (0x2020)
}EDID_COLOR_POINT_DATA;
#define NVT_PVT_EDID_CPD_WP_X_MASK 0x0C
#define NVT_PVT_EDID_CPD_WP_X_SHIFT 2
#define NVT_PVT_EDID_CPD_WP_Y_MASK 0x03
#define NVT_PVT_EDID_CPD_WP_Y_SHIFT 0
typedef struct _tagEDID_STANDARD_TIMING_ID
{
NvU16 std_timing[NVT_EDID_DD_STI_NUM]; //0x05-0x10: 6 standard timings
NvU8 line_feed; //0x11: reserved for line feed (0x0A)
}EDID_STANDARD_TIMING_ID;
typedef struct _tagEDID_COLOR_MANAGEMENT_DATA
{
NvU8 version; //0x05: version (0x03)
NvU8 red_a3_lsb; //0x06: Red a3 LSB
NvU8 red_a3_msb; //0x07: Red a3 MSB
NvU8 red_a2_lsb; //0x08
NvU8 red_a2_msb; //0x09
NvU8 green_a3_lsb; //0x0A
NvU8 green_a3_msb; //0x0B
NvU8 green_a2_lsb; //0x0C
NvU8 green_a2_msb; //0x0D
NvU8 blue_a3_lsb; //0x0E
NvU8 blue_a3_msb; //0x0F
NvU8 blue_a2_lsb; //0x10
NvU8 blue_a2_msb; //0x11
}EDID_COLOR_MANAGEMENT_DATA;
typedef struct _tagEDID_EST_TIMINGS_III
{
NvU8 revision; //0x05: revision (0x0A)
NvU8 timing_byte[12]; //0x05-0x11: established timings III
}EDID_EST_TIMINGS_III;
typedef struct _tagDETAILEDTIMINGDESCRIPTOR
{
NvU16 wDTPixelClock; // 0x00
NvU8 bDTHorizontalActive; // 0x02
NvU8 bDTHorizontalBlanking; // 0x03
NvU8 bDTHorizActiveBlank; // 0x04
NvU8 bDTVerticalActive; // 0x05
NvU8 bDTVerticalBlanking; // 0x06
NvU8 bDTVertActiveBlank; // 0x07
NvU8 bDTHorizontalSync; // 0x08
NvU8 bDTHorizontalSyncWidth; // 0x09
NvU8 bDTVerticalSync; // 0x0A
NvU8 bDTHorizVertSyncOverFlow; // 0x0B
NvU8 bDTHorizontalImage; // 0x0C
NvU8 bDTVerticalImage; // 0x0D
NvU8 bDTHorizVertImage; // 0x0E
NvU8 bDTHorizontalBorder; // 0x0F
NvU8 bDTVerticalBorder; // 0x10
NvU8 bDTFlags; // 0x11
}DETAILEDTIMINGDESCRIPTOR;
// EDID 1.x basic block template
typedef struct _tagEDIDV1STRUC
{
NvU8 bHeader[8]; // 0x00-0x07
NvU16 wIDManufName; // 0x08
NvU16 wIDProductCode; // 0x0A
NvU32 dwIDSerialNumber; // 0x0C
NvU8 bWeekManuf; // 0x10
NvU8 bYearManuf; // 0x11
NvU8 bVersionNumber; // 0x12
NvU8 bRevisionNumber; // 0x13
NvU8 bVideoInputDef; // 0x14
NvU8 bMaxHorizImageSize; // 0x15
NvU8 bMaxVertImageSize; // 0x16
NvU8 bDisplayXferChar; // 0x17
NvU8 bFeatureSupport; // 0x18
NvU8 Chromaticity[10]; // 0x19-0x22
NvU8 bEstablishedTimings1; // 0x23
NvU8 bEstablishedTimings2; // 0x24
NvU8 bManufReservedTimings; // 0x25
NvU16 wStandardTimingID[8]; // 0x26
DETAILEDTIMINGDESCRIPTOR DetailedTimingDesc[4]; // 0x36
NvU8 bExtensionFlag; // 0x7E
NvU8 bChecksum; // 0x7F
}EDIDV1STRUC;
// EDID 2.x basic block template
typedef struct _tagEDIDV2STRUC
{
NvU8 bHeader; // 0x00
NvU16 wIDManufName; // 0x01
NvU16 wIDProductCode; // 0x03
NvU8 bWeekManuf; // 0x05
NvU16 wYearManuf; // 0x06
NvU8 bProductIDString[32]; // 0x08
NvU8 bSerialNumber[16]; // 0x28
NvU8 bReserved1[8]; // 0x38
NvU8 bPhysicalInterfaceType; // 0x40
NvU8 bVideoInterfaceType; // 0x41
NvU8 bInterfaceDataFormat[8]; // 0x42
NvU8 bInterfaceColor[5]; // 0x4A
NvU8 bDisplayTechType; // 0x4F
NvU8 bMajorDisplayChar; // 0x50
NvU8 bFeaturesSupported[3]; // 0x51
NvU16 wDisplayResponseTime; // 0x54
NvU32 dwDisplayXferChar; // 0x56
NvU32 dwMaxLuminance; // 0x5A
NvU8 bColorimetry[20]; // 0x5E
NvU16 wMaxHorizImageSize; // 0x72
NvU16 wMaxVertImageSize; // 0x74
NvU16 wMaxHorizAddressibility; // 0x76
NvU16 wMaxVertAddressibility; // 0x78
NvU8 bHorizPixelPitch; // 0x7A
NvU8 bVertPixelPitch; // 0x7B
NvU8 bReserved2; // 0x7C
NvU8 bGTFSupportInfo; // 0x7D
NvU16 wTimingInfoMap; // 0x7E
NvU8 bTableDescriptors[127]; // 0x80
NvU8 bChecksum; // 0xFF
}EDIDV2STRUC;
// EDID CEA/EIA-861 extension block template
typedef struct _tagEIA861EXTENSION
{
NvU8 tag; // 0x00
NvU8 revision; // 0x01
NvU8 offset; // 0x02
NvU8 misc; // 0x03
NvU8 data[NVT_CEA861_MAX_PAYLOAD]; // 0x04 - 0x7E
NvU8 checksum; // 0x7F
}EIA861EXTENSION;
typedef struct _tagVTBEXTENSION
{
NvU8 tag; // 0x00
NvU8 revision; // 0x01
NvU8 num_detailed; // 0x02
NvU8 num_cvt; // 0x03
NvU8 num_standard; // 0x04
NvU8 data[NVT_VTB_MAX_PAYLOAD]; // 0x05 - 0x7E
NvU8 checksum;
}VTBEXTENSION;
// video signal interface mask
#define NVT_PVT_EDID_INPUT_ISDIGITAL_MASK 0x80 // 0==analog
#define NVT_PVT_EDID_INPUT_ISDIGITAL_SHIFT 7
#define NVT_PVT_EDID_INPUT_ANALOG_ETC_MASK 0x7F
#define NVT_PVT_EDID_INPUT_ANALOG_ETC_SHIFT 0
#define NVT_PVT_EDID_INPUT_INTERFACE_MASK 0x0F
#define NVT_PVT_EDID_INPUT_INTERFACE_SHIFT 0
#define NVT_PVT_EDID_INPUT_BPC_MASK 0x70
#define NVT_PVT_EDID_INPUT_BPC_SHIFT 4
#define NVT_PVT_EDID_INPUT_BPC_UNDEF 0x00
#define NVT_PVT_EDID_INPUT_BPC_6 0x01
#define NVT_PVT_EDID_INPUT_BPC_8 0x02
#define NVT_PVT_EDID_INPUT_BPC_10 0x03
#define NVT_PVT_EDID_INPUT_BPC_12 0x04
#define NVT_PVT_EDID_INPUT_BPC_14 0x05
#define NVT_PVT_EDID_INPUT_BPC_16 0x06
// color characteristic
#define NVT_PVT_EDID_CC_RED_X1_X0_MASK 0xC0
#define NVT_PVT_EDID_CC_RED_X1_X0_SHIFT 6
#define NVT_PVT_EDID_CC_RED_Y1_Y0_MASK 0x30
#define NVT_PVT_EDID_CC_RED_Y1_Y0_SHIFT 4
#define NVT_PVT_EDID_CC_GREEN_X1_X0_MASK 0x0C
#define NVT_PVT_EDID_CC_GREEN_X1_X0_SHIFT 2
#define NVT_PVT_EDID_CC_GREEN_Y1_Y0_MASK 0x03
#define NVT_PVT_EDID_CC_GREEN_Y1_Y0_SHIFT 0
#define NVT_PVT_EDID_CC_BLUE_X1_X0_MASK 0xC0
#define NVT_PVT_EDID_CC_BLUE_X1_X0_SHIFT 6
#define NVT_PVT_EDID_CC_BLUE_Y1_Y0_MASK 0x30
#define NVT_PVT_EDID_CC_BLUE_Y1_Y0_SHIFT 4
#define NVT_PVT_EDID_CC_WHITE_X1_X0_MASK 0x0C
#define NVT_PVT_EDID_CC_WHITE_X1_X0_SHIFT 2
#define NVT_PVT_EDID_CC_WHITE_Y1_Y0_MASK 0x03
#define NVT_PVT_EDID_CC_WHITE_Y1_Y0_SHIFT 0
#endif // __EDID_H_

View File

@@ -0,0 +1,431 @@
//*****************************************************************************
//
// SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: MIT
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File: nvt_cvt.c
//
// Purpose: calculate CVT/CVT-RB timing
//
//*****************************************************************************
#include "nvBinSegment.h"
#include "nvmisc.h"
#include "nvtiming_pvt.h"
PUSH_SEGMENTS
CONS_SEGMENT(PAGE_CONS)
const NvU32 NVT_MAX_NVU32= (NvU32)(-1);
const NvU32 NVT_CVT_CELL_GRAN=8;
const NvU32 NVT_CVT_MIN_VSYNCBP=11; // in 550us (!!) [1000000:550 = 20000:11]
const NvU32 NVT_CVT_V_PORCH=3; // in pixels
const NvU32 NVT_CVT_C_PRIME=30; // value of (C' * 10)
const NvU32 NVT_CVT_M_PRIME_D_20=15; // value of (M' / 100)
const NvU32 NVT_CVT_CLOCK_STEP=25; // Pclk step, in 10kHz
const NvU32 NVT_CVT_H_SYNC_PER=8; // HSYNC percentage (8%)
const NvU32 NVT_CVT_RB_HBLANK_CELLS=20; // 160 fixed hblank for RB
const NvU32 NVT_CVT_RB_HFPORCH_CELLS=6; // 48 fixed hfporch for RB
const NvU32 NVT_CVT_RB_HSYNCW_CELLS=4; // 32 fixed hsyncwidth for RB
const NvU32 NVT_CVT_RB_MIN_VBLANK=23; // 460 lines (or 460 us?) [1000000:460 = 50000:23]
const NvU32 NVT_CVT_MIN_V_BPORCH=6;
// VESA CVT spec ver1.2:
//
// Page 24 : Table 5-4 : Delta between Original Reduced Blank Timing and Reduced Blanking Timing V2
#define NVT_CVT_RB2_CLOCK_STEP_KHZ 1
#define NVT_CVT_RB2_H_BLANK_PIXELS 80
#define NVT_CVT_RB2_H_SYNC_PIXELS 32
#define NVT_CVT_RB2_MIN_VBLANK_MICROSEC 460
#define NVT_CVT_RB2_V_FPORCH_MIN 1
#define NVT_CVT_RB2_V_BPORCH 6
// Page 16 : Table 3-2 : Vertical Sync Duration
#define NVT_CVT_RB2_V_SYNC_WIDTH 8
// Page 22: RB_MIN_VBI = RB_V_FPORCH + V_SYNC_RND + MIN_V_BPORCH
#define NVT_CVT_RB2_MIN_VBI NVT_CVT_RB2_V_SYNC_WIDTH + NVT_CVT_RB2_V_FPORCH_MIN + NVT_CVT_RB2_V_BPORCH
// Page 15 : The Horizontal Sync Pulse duration will in all cases be 32 pixel clocks in duration, with the position
// set so that the trailing edge of the Horizontal Sync Pulse is located in the center of the Horizontal
// Blanking period.This implies that for a fixed blank of 80 pixel clocks, the Horizontal Back Porch is
// fixed to(80 / 2) 40 pixel clocks and the Horizontal Front Porch is fixed to(80 - 40 - 32) = 8 clock cycles.
#define NVT_CVT_RB2_H_FPORCH 8
#define NVT_CVT_RB2_H_BPORCH 40
CODE_SEGMENT(PAGE_DD_CODE)
static NvU16 getCVTVSync(NvU32 XRes, NvU32 YRes)
{
// 4:3 modes
if(XRes * 3 == YRes * 4)
return 4;
// 16:9 modes
//if((XRes * 9 == YRes * 16) ||
// (XRes == 848 && YRes == 480) || // 53:30 = 1.76666
// (XRes == 1064 && YRes == 600) || // 133:75 = 1.77333
// (XRes == 1360 && YRes == 768) || // 85:48 = 1.77083
// (XRes == 1704 && YRes == 960) || // 71:40 = 1.775
// (XRes == 1864 && YRes == 1050) || // 832:525 = 1.77523809
// (XRes == 2128 && YRes == 1200) || // 133:75
// (XRes == 2728 && YRes == 1536) || // 341:192 = 1.7760416
// (XRes == 3408 && YRes == 1920) || // 71:40
// (XRes == 4264 && YRes == 2400)) // 533:300 = 1.77666
// return 5;
// NOTE: Because 16:9 modes are really a collection of mode of
// aspect ratio between 16:9 and 53:30, we will include
// all generic mode within this aspect ration range
if((XRes * 9 <= YRes * 16) && (XRes * 30 >= YRes * 53))
return 5;
// 16:10 modes
if((XRes * 5 == YRes * 8) ||
(XRes == 1224 && YRes == 768) ||
(XRes == 2456 && YRes == 1536))
return 6;
// Special 1280 modes
if((XRes == 1280 && YRes == 1024) ||
(XRes == 1280 && YRes == 768))
return 7;
// Failure value, for identification
return 10;
}
CODE_SEGMENT(PAGE_DD_CODE)
NVT_STATUS NvTiming_CalcCVT(NvU32 width, NvU32 height, NvU32 rr, NvU32 flag, NVT_TIMING *pT)
{
NvU32 dwXCells, dwVSyncBP, dwHBlankCells, dwPClk, dwHSyncCells, dwVSyncWidth;
NvU32 dwHPeriodEstimate_NUM, dwHPeroidEstimate_DEN;
NvU32 dwIdealDutyCycle_NUM, dwIdealDutyCycle_DEN;
// parameter check
if (pT == NULL)
return NVT_STATUS_ERR;
if (width == 0 || height == 0 || rr == 0 )
return NVT_STATUS_ERR;
// Check for valid input parameter
if (width < 300 || height < 200 || rr < 10)
return NVT_STATUS_ERR;//return NVT_STATUS_ERR_BACKOFF | NVT_STATUS_ERR_OUTOFRANGE;
NVMISC_MEMSET(pT, 0, sizeof(NVT_TIMING));
pT->etc.status = NVT_STATUS_CVT;
if ((width % NVT_CVT_CELL_GRAN)!=0)
{
width = (width + NVT_CVT_CELL_GRAN / 2) / NVT_CVT_CELL_GRAN * NVT_CVT_CELL_GRAN;
NVT_SET_TIMING_STATUS_MISMATCH(pT->etc.status, NVT_STATUS_TIMING_MISMATCH_ALIGNMENT);
}
// Calculate timing
dwXCells = width / NVT_CVT_CELL_GRAN; // Convert to number of cells
dwVSyncWidth = getCVTVSync(dwXCells * NVT_CVT_CELL_GRAN, height);
dwHPeriodEstimate_NUM = 20000 - NVT_CVT_MIN_VSYNCBP * rr;
dwHPeroidEstimate_DEN = rr * (height + NVT_CVT_V_PORCH);
dwVSyncBP = NVT_CVT_MIN_VSYNCBP * dwHPeroidEstimate_DEN / dwHPeriodEstimate_NUM +1;
if(dwVSyncBP < dwVSyncWidth + NVT_CVT_MIN_V_BPORCH)
dwVSyncBP = dwVSyncWidth + NVT_CVT_MIN_V_BPORCH;
// Check for overflow
//DBG_ASSERT(NVT_MAX_NVU32 / NVT_CVT_C_PRIME > dwHPeroidEstimate_DEN);
dwIdealDutyCycle_DEN = dwHPeroidEstimate_DEN;
dwIdealDutyCycle_NUM = NVT_CVT_C_PRIME * dwHPeroidEstimate_DEN - NVT_CVT_M_PRIME_D_20 * dwHPeriodEstimate_NUM;
if (dwIdealDutyCycle_NUM < dwIdealDutyCycle_DEN * 20)
{
dwIdealDutyCycle_NUM=20;
dwIdealDutyCycle_DEN=1;
}
// Check for overflow
if (NVT_MAX_NVU32 / dwXCells <= dwIdealDutyCycle_NUM)
{
dwIdealDutyCycle_NUM /= 10;
dwIdealDutyCycle_DEN /= 10;
}
dwHBlankCells = ((dwXCells * dwIdealDutyCycle_NUM)/(200*dwIdealDutyCycle_DEN - 2*dwIdealDutyCycle_NUM))*2;
// Check for overflow
//DBG_ASSERT(MAX_NVU32 / dwHPeroidEstimate_DEN > (dwXCells + dwHBlankCells)*CVT_CELL_GRAN);
dwPClk = ((dwXCells + dwHBlankCells) * NVT_CVT_CELL_GRAN * dwHPeroidEstimate_DEN * 2 / dwHPeriodEstimate_NUM / NVT_CVT_CLOCK_STEP) * NVT_CVT_CLOCK_STEP;
dwHSyncCells = (dwXCells + dwHBlankCells) * NVT_CVT_H_SYNC_PER / 100;
pT->HVisible = (NvU16)(dwXCells * NVT_CVT_CELL_GRAN);
pT->VVisible = (NvU16)height;
pT->HTotal = (NvU16)((dwXCells + dwHBlankCells) * NVT_CVT_CELL_GRAN);
pT->HFrontPorch = (NvU16)((dwHBlankCells/2 - dwHSyncCells) * NVT_CVT_CELL_GRAN);
pT->HSyncWidth = (NvU16)(dwHSyncCells * NVT_CVT_CELL_GRAN);
pT->VTotal = (NvU16)(height + dwVSyncBP + NVT_CVT_V_PORCH);
pT->VFrontPorch = (NvU16)(NVT_CVT_V_PORCH);
pT->VSyncWidth = getCVTVSync(dwXCells * NVT_CVT_CELL_GRAN, height);
pT->pclk = dwPClk;
pT->HSyncPol = NVT_H_SYNC_NEGATIVE;
pT->VSyncPol = NVT_V_SYNC_POSITIVE;
// Clear unused fields
pT->HBorder = pT->VBorder = 0;
pT->interlaced = NVT_PROGRESSIVE;
pT->etc.flag = 0;
pT->etc.rr = (NvU16)rr;
pT->etc.rrx1k = axb_div_c((NvU32)pT->pclk, (NvU32)10000*(NvU32)1000, (NvU32)pT->HTotal*(NvU32)pT->VTotal);
pT->etc.aspect = 0;
pT->etc.rep = 0x1;
NVT_SNPRINTF((char *)pT->etc.name, 40, "CVT:%dx%dx%dHz",width, height, rr);
pT->etc.name[39] = '\0';
// interlaced adjustment
if ((flag & NVT_PVT_INTERLACED_MASK) != 0)
{
if ((pT->VTotal & 0x1) != 0)
pT->interlaced = NVT_INTERLACED_EXTRA_VBLANK_ON_FIELD2;
else
pT->interlaced = NVT_INTERLACED_NO_EXTRA_VBLANK_ON_FIELD2;
pT->pclk >>= 1;
pT->VTotal >>= 1;
pT->VVisible = (pT->VVisible + 1) / 2;
}
pT->etc.rgb444.bpc.bpc8 = 1;
return NVT_STATUS_SUCCESS;
}
// CVT-RB timing calculation
CODE_SEGMENT(PAGE_DD_CODE)
NVT_STATUS NvTiming_CalcCVT_RB(NvU32 width, NvU32 height, NvU32 rr, NvU32 flag, NVT_TIMING *pT)
{
NvU32 dwXCells, dwPClk, dwVBILines, dwVSyncWidth;
// parameter check
if (pT == NULL)
return NVT_STATUS_ERR;
if (width == 0 || height == 0 || rr == 0 )
return NVT_STATUS_ERR;
// Check for valid input parameter
if (width < 300 || height < 200 || rr < 10)
return NVT_STATUS_ERR;//NVT_STATUS_ERR_BACKOFF | NVT_STATUS_ERR_OUTOFRANGE;
NVMISC_MEMSET(pT, 0, sizeof(NVT_TIMING));
pT->etc.status = NVT_STATUS_CVT_RB;
if ((width % NVT_CVT_CELL_GRAN)!=0)
{
width = (width + NVT_CVT_CELL_GRAN / 2) / NVT_CVT_CELL_GRAN * NVT_CVT_CELL_GRAN;
NVT_SET_TIMING_STATUS_MISMATCH(pT->etc.status, NVT_STATUS_TIMING_MISMATCH_ALIGNMENT);
}
// Calculate timing
dwXCells = width / NVT_CVT_CELL_GRAN; // Convert to number of cells
dwVSyncWidth = getCVTVSync(dwXCells * NVT_CVT_CELL_GRAN, height);
dwVBILines = (NVT_CVT_RB_MIN_VBLANK * height * rr) / (50000 - NVT_CVT_RB_MIN_VBLANK * rr) + 1;
if(dwVBILines < NVT_CVT_V_PORCH + dwVSyncWidth + NVT_CVT_MIN_V_BPORCH)
dwVBILines = NVT_CVT_V_PORCH + dwVSyncWidth + NVT_CVT_MIN_V_BPORCH;
dwPClk = rr * (height + dwVBILines) * (dwXCells + NVT_CVT_RB_HBLANK_CELLS) / (10000 / NVT_CVT_CELL_GRAN) / NVT_CVT_CLOCK_STEP;
dwPClk *= NVT_CVT_CLOCK_STEP;
pT->HVisible = (NvU16)(dwXCells * NVT_CVT_CELL_GRAN);
pT->VVisible = (NvU16)height;
pT->HTotal = (NvU16)((dwXCells + NVT_CVT_RB_HBLANK_CELLS) * NVT_CVT_CELL_GRAN);
pT->HFrontPorch = (NvU16)(NVT_CVT_RB_HFPORCH_CELLS * NVT_CVT_CELL_GRAN);
pT->HSyncWidth = (NvU16)(NVT_CVT_RB_HSYNCW_CELLS * NVT_CVT_CELL_GRAN);
pT->VTotal = (NvU16)(height + dwVBILines);
pT->VFrontPorch = (NvU16)(NVT_CVT_V_PORCH);
pT->VSyncWidth = (NvU16)dwVSyncWidth;
pT->pclk = dwPClk;
pT->HSyncPol = NVT_H_SYNC_POSITIVE;
pT->VSyncPol = NVT_V_SYNC_NEGATIVE;
// Clear unused fields
pT->HBorder = pT->VBorder = 0;
pT->interlaced = 0;
// fill in the extra timing info
pT->etc.flag = 0;
pT->etc.rr = (NvU16)rr;
pT->etc.rrx1k = axb_div_c((NvU32)pT->pclk, (NvU32)10000*(NvU32)1000, (NvU32)pT->HTotal*(NvU32)pT->VTotal);
pT->etc.aspect = 0;
pT->etc.rep = 0x1;
NVT_SNPRINTF((char *)pT->etc.name, 40, "CVT-RB:%dx%dx%dHz",width, height, rr);
pT->etc.name[39] = '\0';
// interlaced adjustment
if ((flag & NVT_PVT_INTERLACED_MASK) != 0)
{
if ((pT->VTotal & 0x1) != 0)
pT->interlaced = NVT_INTERLACED_EXTRA_VBLANK_ON_FIELD2;
else
pT->interlaced = NVT_INTERLACED_NO_EXTRA_VBLANK_ON_FIELD2;
pT->pclk >>= 1;
pT->VTotal >>= 1;
pT->VVisible = (pT->VVisible + 1) / 2;
}
return NVT_STATUS_SUCCESS;
}
// CVT-RB2 timing calculation
CODE_SEGMENT(PAGE_DD_CODE)
NVT_STATUS NvTiming_CalcCVT_RB2(NvU32 width, NvU32 height, NvU32 rr, NvBool is1000div1001, NVT_TIMING *pT)
{
NvU32 vbi, act_vbi_lines, total_v_lines, total_pixels, act_pixel_freq_khz;
// parameter check
if (pT == NULL || width == 0 || height == 0 || rr == 0)
return NVT_STATUS_ERR;
// Check for valid input parameter
if (width < 300 || height < 200 || rr < 10)
return NVT_STATUS_ERR;
NVMISC_MEMSET(pT, 0, sizeof(NVT_TIMING));
pT->etc.status = NVT_STATUS_CVT_RB_2;
// CVT spec1.2 - page 21 : 5.4 Computation of Reduced Blanking Timing Parameters
// 8. Estimate the Horizontal Period (kHz):
// H_PERIOD_EST = ((1000000 / (V_FIELD_RATE_RQD)) - RB_MIN_V_BLANK) / (V_LINES_RND +
// TOP_MARGIN + BOT_MARGIN)
// h_period_est = (1000000 / rr - NVT_CVT_RB2_MIN_VBLANK) / height;
// 9. Determine the number of lines in the vertical blanking interval :
// VBI_LINES = ROUNDDOWN(RB_MIN_V_BLANK / H_PERIOD_EST, 0) + 1
// vbi = NVT_CVT_RB2_MIN_VBLANK / h_period_est + 1;
// combining step 8, 9,
vbi = height * NVT_CVT_RB2_MIN_VBLANK_MICROSEC * rr / (1000000 - NVT_CVT_RB2_MIN_VBLANK_MICROSEC * rr) + 1;
// 10. Check Vertical Blanking is Sufficient :
// RB_MIN_VBI = RB_V_FPORCH + V_SYNC_RND + MIN_V_BPORCH
// ACT_VBI_LINES = IF(VBI_LINES < RB_MIN_VBI, RB_MIN_VBI, VBI_LINES)
act_vbi_lines = MAX(vbi, NVT_CVT_RB2_MIN_VBI);
// 11. Find total number of vertical lines :
// TOTAL_V_LINES = ACT_VBI_LINES + V_LINES_RND + TOP_MARGIN + BOT_MARGIN
// + INTERLACE
total_v_lines = act_vbi_lines + height; //+0.5 if interlaced
// 12. Find total number of pixel clocks per line :
// TOTAL_PIXELS = RB_H_BLANK + TOTAL_ACTIVE_PIXELS
total_pixels = NVT_CVT_RB2_H_BLANK_PIXELS + width;
// sanity check just in case of bad edid where the timing value could exceed the limit of NVT_TIMING structure which unfortunately is defined in NvU16
if (total_pixels > (NvU16)-1 || total_v_lines > (NvU16)-1)
return NVT_STATUS_INVALID_PARAMETER;
// 13. Calculate Pixel Clock Frequency to nearest CLOCK_STEP MHz :
// ACT_PIXEL_FREQ = CLOCK_STEP * ROUNDDOWN((V_FIELD_RATE_RQD * TOTAL_V_LINES *
// TOTAL_PIXELS / 1000000 * REFRESH_MULTIPLIER) / CLOCK_STEP, 0)
if (is1000div1001)
act_pixel_freq_khz = NVT_CVT_RB2_CLOCK_STEP_KHZ * (rr * total_v_lines * total_pixels / 1001 / NVT_CVT_RB2_CLOCK_STEP_KHZ);
else
act_pixel_freq_khz = NVT_CVT_RB2_CLOCK_STEP_KHZ * (rr * total_v_lines * total_pixels / 1000 / NVT_CVT_RB2_CLOCK_STEP_KHZ);
// 14. Find actual Horizontal Frequency(kHz) :
// ACT_H_FREQ = 1000 * ACT_PIXEL_FREQ / TOTAL_PIXELS
// 15. Find Actual Field Rate(Hz) :
// ACT_FIELD_RATE = 1000 * ACT_H_FREQ / TOTAL_V_LINES
// 16. Find actual Vertical Refresh Rate(Hz) :
// ACT_FRAME_RATE = IF(INT_RQD ? = "y", ACT_FIELD_RATE / 2, ACT_FI
// fill in the essential timing info for output
pT->HVisible = (NvU16)width;
pT->HTotal = (NvU16)(total_pixels);
pT->HFrontPorch = NVT_CVT_RB2_H_FPORCH;
pT->HSyncWidth = NVT_CVT_RB2_H_SYNC_PIXELS;
pT->VVisible = (NvU16)height;
pT->VTotal = (NvU16)total_v_lines;
pT->VSyncWidth = NVT_CVT_RB2_V_SYNC_WIDTH;
pT->VFrontPorch = (NvU16)(act_vbi_lines - NVT_CVT_RB2_V_SYNC_WIDTH - NVT_CVT_RB2_V_BPORCH);
pT->pclk = (act_pixel_freq_khz + 5) / 10; //convert to 10Khz
pT->HSyncPol = NVT_H_SYNC_POSITIVE;
pT->VSyncPol = NVT_V_SYNC_NEGATIVE;
pT->HBorder = pT->VBorder = 0; // not supported
pT->interlaced = 0; // not supported yet
// fill in the extra timing info
pT->etc.flag = 0;
pT->etc.rr = (NvU16)rr;
pT->etc.rrx1k = axb_div_c((NvU32)pT->pclk, (NvU32)10000 * (NvU32)1000, (NvU32)pT->HTotal*(NvU32)pT->VTotal);
pT->etc.aspect = 0;
pT->etc.rep = 0x1;
NVT_SNPRINTF((char *)pT->etc.name, 40, "CVT-RB2:%dx%dx%dHz", width, height, rr);
pT->etc.name[39] = '\0';
return NVT_STATUS_SUCCESS;
}
CODE_SEGMENT(PAGE_DD_CODE)
NvBool NvTiming_IsTimingCVTRB(const NVT_TIMING *pTiming)
{
// Check from the Timing Type
NvU32 reducedType = 0;
reducedType = NVT_GET_TIMING_STATUS_TYPE(pTiming->etc.status);
if (reducedType == NVT_TYPE_CVT_RB || reducedType == NVT_TYPE_CVT_RB_2)
{
return NV_TRUE;
}
// Manually Check for RB 1 and 2
// RB1 - HBlank = 160, and HSync = 32, HFrontPorch = 48, HBackPorch = 80
if (((pTiming->HTotal - pTiming->HVisible) == 160) && (pTiming->HSyncWidth == 32) && (pTiming->HFrontPorch == 48))
{
return NV_TRUE;
}
// RB2 - HBlank = 80, HSync = 32, HFrontPorch = 8, HBackPorch = 40
if (((pTiming->HTotal - pTiming->HVisible) == 80) && (pTiming->HSyncWidth == 32) && (pTiming->HFrontPorch == 8))
{
return NV_TRUE;
}
return NV_FALSE;
}
POP_SEGMENTS

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,272 @@
//*****************************************************************************
//
// SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: MIT
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File: nvt_dmt.c
//
// Purpose: calculate DMT/DMT-RB timing
//
//*****************************************************************************
#include "nvBinSegment.h"
#include "nvmisc.h"
#include "nvtiming_pvt.h"
PUSH_SEGMENTS
// DMT table
// Macro to declare a TIMING initializer for given parameters without border
#define DMT_TIMING(hv,hfp,hsw,ht,hsp,vv,vfp,vsw,vt,vsp,rr,pclk,id) \
{hv,0,hfp,hsw,ht,(hsp)=='-',vv,0,vfp,vsw,vt,(vsp)=='-',NVT_PROGRESSIVE,pclk,{0,rr,set_rrx1k(pclk,ht,vt),0,0x1,{0},{0},{0},{0},NVT_DEF_TIMING_STATUS(NVT_TYPE_DMT,id),"VESA DMT"}}
#define DMTRB_TIMING(hv,hfp,hsw,ht,hsp,vv,vfp,vsw,vt,vsp,rr,pclk,id) \
{hv,0,hfp,hsw,ht,(hsp)=='-',vv,0,vfp,vsw,vt,(vsp)=='-',NVT_PROGRESSIVE,pclk,{0,rr,set_rrx1k(pclk,ht,vt),0,0x1,{0},{0},{0},{0},NVT_DEF_TIMING_STATUS(NVT_TYPE_DMT_RB,id),"VESA DMT/RB"}}
#define DMTRB_2_TIMING(hv,hfp,hsw,ht,hsp,vv,vfp,vsw,vt,vsp,rr,pclk,id) \
{hv,0,hfp,hsw,ht,(hsp)=='-',vv,0,vfp,vsw,vt,(vsp)=='-',NVT_PROGRESSIVE,pclk,{0,rr,set_rrx1k(pclk,ht,vt),0,0x1,{0},{0},{0},{0},NVT_DEF_TIMING_STATUS(NVT_TYPE_DMT_RB_2,id),"VESA DMT/RB2"}}
DATA_SEGMENT(PAGE_DATA)
static NVT_TIMING DMT[] =
{
// VESA standard entries (ordered according to VESA DMT ID).
// hv,hfp,hsw, ht,hsp, vv,vfp,vsw, vt,vsp, rr,pclk , id
DMT_TIMING ( 640, 32, 64, 832,'+', 350, 32, 3, 445,'-', 85, 3150, 0x01),
DMT_TIMING ( 640, 32, 64, 832,'-', 400, 1, 3, 445,'+', 85, 3150, 0x02),
DMT_TIMING ( 720, 36, 72, 936,'-', 400, 1, 3, 446,'+', 85, 3550, 0x03),
DMT_TIMING ( 640, 8, 96, 800,'-', 480, 2, 2, 525,'-', 60, 2518, 0x04),
// 640x480x72Hz (VESA) - this entry have borders
{640,8,16,40,832,NVT_H_SYNC_NEGATIVE,480,8,1,3,520,NVT_V_SYNC_NEGATIVE,NVT_PROGRESSIVE,3150,{0,72,72000,0,1,{0},{0},{0},{0},NVT_DEF_TIMING_STATUS(NVT_TYPE_DMT,5),"VESA DMT"}},
DMT_TIMING ( 640, 16, 64, 840,'-', 480, 1, 3, 500,'-', 75, 3150, 0x06),
DMT_TIMING ( 640, 56, 56, 832,'-', 480, 1, 3, 509,'-', 85, 3600, 0x07),
DMT_TIMING ( 800, 24, 72,1024,'+', 600, 1, 2, 625,'+', 56, 3600, 0x08),
DMT_TIMING ( 800, 40,128,1056,'+', 600, 1, 4, 628,'+', 60, 4000, 0x09),
DMT_TIMING ( 800, 56,120,1040,'+', 600, 37, 6, 666,'+', 72, 5000, 0x0A),
DMT_TIMING ( 800, 16, 80,1056,'+', 600, 1, 3, 625,'+', 75, 4950, 0x0B),
DMT_TIMING ( 800, 32, 64,1048,'+', 600, 1, 3, 631,'+', 85, 5625, 0x0C),
DMTRB_TIMING( 800, 48, 32, 960,'+', 600, 3, 4, 636,'-',120, 7325, 0x0D),
DMT_TIMING ( 848, 16,112,1088,'+', 480, 6, 8, 517,'+', 60, 3375, 0x0E),
DMT_TIMING (1024, 8,176,1264,'+', 768, 0, 4, 817,'+', 43, 4490, 0x0F),
DMT_TIMING (1024, 24,136,1344,'-', 768, 3, 6, 806,'-', 60, 6500, 0x10),
DMT_TIMING (1024, 24,136,1328,'-', 768, 3, 6, 806,'-', 70, 7500, 0x11),
DMT_TIMING (1024, 16, 96,1312,'+', 768, 1, 3, 800,'+', 75, 7875, 0x12),
DMT_TIMING (1024, 48, 96,1376,'+', 768, 1, 3, 808,'+', 85, 9450, 0x13),
DMTRB_TIMING(1024, 48, 32,1184,'+', 768, 3, 4, 813,'-',120,11550, 0x14),
DMT_TIMING (1152, 64,128,1600,'+', 864, 1, 3, 900,'+', 75,10800, 0x15),
DMTRB_TIMING(1280, 48, 32,1440,'+', 768, 3, 7, 790,'-', 60, 6825, 0x16),
DMT_TIMING (1280, 64,128,1664,'-', 768, 3, 7, 798,'+', 60, 7950, 0x17),
DMT_TIMING (1280, 80,128,1696,'-', 768, 3, 7, 805,'+', 75,10225, 0x18),
DMT_TIMING (1280, 80,136,1712,'-', 768, 3, 7, 809,'+', 85,11750, 0x19),
DMTRB_TIMING(1280, 48, 32,1440,'+', 768, 3, 7, 813,'-',120,14025, 0x1A),
DMTRB_TIMING(1280, 48, 32,1440,'+', 800, 3, 6, 823,'-', 60, 7100, 0x1B),
DMT_TIMING (1280, 72,128,1680,'-', 800, 3, 6, 831,'+', 60, 8350, 0x1C),
DMT_TIMING (1280, 80,128,1696,'-', 800, 3, 6, 838,'+', 75,10650, 0x1D),
DMT_TIMING (1280, 80,136,1712,'-', 800, 3, 6, 843,'+', 85,12250, 0x1E),
DMTRB_TIMING(1280, 48, 32,1440,'+', 800, 3, 6, 847,'-',120,14625, 0x1F),
DMT_TIMING (1280, 96,112,1800,'+', 960, 1, 3,1000,'+', 60,10800, 0x20),
DMT_TIMING (1280, 64,160,1728,'+', 960, 1, 3,1011,'+', 85,14850, 0x21),
DMTRB_TIMING(1280, 48, 32,1440,'+', 960, 3, 4,1017,'-',120,17550, 0x22),
DMT_TIMING (1280, 48,112,1688,'+',1024, 1, 3,1066,'+', 60,10800, 0x23),
DMT_TIMING (1280, 16,144,1688,'+',1024, 1, 3,1066,'+', 75,13500, 0x24),
DMT_TIMING (1280, 64,160,1728,'+',1024, 1, 3,1072,'+', 85,15750, 0x25),
DMTRB_TIMING(1280, 48, 32,1440,'+',1024, 3, 7,1084,'-',120,18725, 0x26),
DMT_TIMING (1360, 64,112,1792,'+', 768, 3, 6, 795,'+', 60, 8550, 0x27),
DMTRB_TIMING(1360, 48, 32,1520,'+', 768, 3, 5, 813,'-',120,14825, 0x28),
DMTRB_TIMING(1400, 48, 32,1560,'+',1050, 3, 4,1080,'-', 60,10100, 0x29),
DMT_TIMING (1400, 88,144,1864,'-',1050, 3, 4,1089,'+', 60,12175, 0x2A),
DMT_TIMING (1400,104,144,1896,'-',1050, 3, 4,1099,'+', 75,15600, 0x2B),
DMT_TIMING (1400,104,152,1912,'-',1050, 3, 4,1105,'+', 85,17950, 0x2C),
DMTRB_TIMING(1400, 48, 32,1560,'+',1050, 3, 4,1050,'-',120,20800, 0x2D),
DMTRB_TIMING(1440, 48, 32,1600,'+', 900, 3, 6, 926,'-', 60, 8875, 0x2E),
DMT_TIMING (1440, 80,152,1904,'-', 900, 3, 6, 934,'+', 60,10650, 0x2F),
DMT_TIMING (1440, 96,152,1936,'-', 900, 3, 6, 942,'+', 75,13675, 0x30),
DMT_TIMING (1440,104,152,1952,'-', 900, 3, 6, 948,'+', 85,15700, 0x31),
DMTRB_TIMING(1440, 48, 32,1600,'+', 900, 3, 6, 953,'-',120,18275, 0x32),
DMT_TIMING (1600, 64,192,2160,'+',1200, 1, 3,1250,'+', 60,16200, 0x33),
DMT_TIMING (1600, 64,192,2160,'+',1200, 1, 3,1250,'+', 65,17550, 0x34),
DMT_TIMING (1600, 64,192,2160,'+',1200, 1, 3,1250,'+', 70,18900, 0x35),
DMT_TIMING (1600, 64,192,2160,'+',1200, 1, 3,1250,'+', 75,20250, 0x36),
DMT_TIMING (1600, 64,192,2160,'+',1200, 1, 3,1250,'+', 85,22950, 0x37),
DMTRB_TIMING(1600, 48, 32,1760,'+',1200, 3, 4,1271,'-',120,26825, 0x38),
DMTRB_TIMING(1680, 48, 32,1840,'+',1050, 3, 6,1080,'-', 60,11900, 0x39),
DMT_TIMING (1680,104,176,2240,'-',1050, 3, 6,1089,'+', 60,14625, 0x3A),
DMT_TIMING (1680,120,176,2272,'-',1050, 3, 6,1099,'+', 75,18700, 0x3B),
DMT_TIMING (1680,128,176,2288,'-',1050, 3, 6,1105,'+', 85,21475, 0x3C),
DMTRB_TIMING(1680, 48, 32,1840,'+',1050, 3, 6,1112,'-',120,24550, 0x3D),
DMT_TIMING (1792,128,200,2448,'-',1344, 1, 3,1394,'+', 60,20475, 0x3E),
DMT_TIMING (1792, 96,216,2456,'-',1344, 1, 3,1417,'+', 75,26100, 0x3F),
DMTRB_TIMING(1792, 48, 32,1952,'+',1344, 3, 4,1423,'-',120,33325, 0x40),
DMT_TIMING (1856, 96,224,2528,'-',1392, 1, 3,1439,'+', 60,21825, 0x41),
DMT_TIMING (1856,128,224,2560,'-',1392, 1, 3,1500,'+', 75,28800, 0x42),
DMTRB_TIMING(1856, 48, 32,2016,'+',1392, 3, 4,1474,'-',120,35650, 0x43),
DMTRB_TIMING(1920, 48, 32,2080,'+',1200, 3, 6,1235,'-', 60,15400, 0x44),
DMT_TIMING (1920,136,200,2592,'-',1200, 3, 6,1245,'+', 60,19325, 0x45),
DMT_TIMING (1920,136,208,2608,'-',1200, 3, 6,1255,'+', 75,24525, 0x46),
DMT_TIMING (1920,144,208,2624,'-',1200, 3, 6,1262,'+', 85,28125, 0x47),
DMTRB_TIMING(1920, 48, 32,2080,'+',1200, 3, 6,1271,'-',120,31700, 0x48),
DMT_TIMING (1920,128,208,2600,'-',1440, 1, 3,1500,'+', 60,23400, 0x49),
DMT_TIMING (1920,144,224,2640,'-',1440, 1, 3,1500,'+', 75,29700, 0x4A),
DMTRB_TIMING(1920, 48, 32,2080,'+',1440, 3, 4,1525,'-',120,38050, 0x4B),
DMTRB_TIMING(2560, 48, 32,2720,'+',1600, 3, 6,1646,'-', 60,26850, 0x4C),
DMT_TIMING (2560,192,280,3504,'-',1600, 3, 6,1658,'+', 60,34850, 0x4D),
DMT_TIMING (2560,208,280,3536,'-',1600, 3, 6,1672,'+', 75,44325, 0x4E),
DMT_TIMING (2560,208,280,3536,'-',1600, 3, 6,1682,'+', 85,50525, 0x4F),
DMTRB_TIMING(2560, 48, 32,2720,'+',1600, 3, 6,1694,'-',120,55275, 0x50),
DMT_TIMING (1366, 70,143,1792,'+',768 , 3, 3, 798,'+', 60, 8550, 0x51),//1366 x 768 @60 (non-interlaced) DMT ID: 51h
DMT_TIMING (1920, 88, 44,2200,'+',1080, 4, 5,1125,'+', 60,14850, 0x52),//1920 x 1080 @60 (non-interlaced) DMT ID: 52h
DMTRB_TIMING(1600, 24, 80,1800,'+', 900, 1, 3,1000,'+', 60,10800, 0x53),//1600 x 900 @60 (non-interlaced) DMT ID: 53h
DMTRB_TIMING(2048, 26, 80,2250,'+',1152, 1, 3,1200,'+', 60,16200, 0x54),//2048 x 1152 @60 (non-interlaced) DMT ID: 54h
DMT_TIMING (1280,110, 40,1650,'+', 720, 5, 5, 750,'+', 60, 7425, 0x55),//1280 x 720 @60 (non-interlaced) DMT ID: 55h
DMTRB_TIMING(1366, 14, 56,1500,'+', 768, 1, 3, 800,'+', 60, 7200, 0x56),//1366 x 768 @60 (non-interlaced) DMT ID: 56h
// Added timing definitions in DMT 1.3 Version 1.0, Rev. 13
DMTRB_2_TIMING(4096, 8, 56,4176,'+', 2160, 48, 8, 2222,'-', 60,55674, 0x57),//4096 x 2160 @60 (non-interlaced) DMT ID: 57h
DMTRB_2_TIMING(4096, 8, 56,4176,'+', 2160, 48, 8, 2222,'-', 59,55619, 0x58),//4096 x 2160 @60 (non-interlaced) DMT ID: 58h
// ********************************
// Additional non-standard entries.
// ********************************
// Settings for 640x400
// GTF timing for 640x400x60Hz has too low HFreq, this is a
// Specially constructed timing from 640x480, with extra blanking
// on top and bottom of the screen
DMT_TIMING(640,16,96,800,'-',400,50,2,525,'-',60,2518,0),
DMT_TIMING(640,16,96,800,'+',400,12,2,449,'-',70,2518,0),
// the end of table
NVT_TIMING_SENTINEL
};
static NvU32 MAX_DMT_FORMAT = sizeof(DMT)/sizeof(DMT[0]) - 1;
CODE_SEGMENT(PAGE_DD_CODE)
NVT_STATUS NvTiming_EnumDMT(NvU32 dmtId, NVT_TIMING *pT)
{
if ((pT == NULL) || (dmtId == 0))
{
return NVT_STATUS_ERR;
}
// The last entry is not used.
if (dmtId > MAX_DMT_FORMAT)
{
return NVT_STATUS_ERR;
}
// Make sure that the DMT ID matches according to the array index.
if (NVT_GET_TIMING_STATUS_SEQ(DMT[dmtId - 1].etc.status) == dmtId)
{
*pT = DMT[dmtId - 1];
pT->etc.rrx1k = axb_div_c((NvU32)pT->pclk,
(NvU32)10000*(NvU32)1000,
(NvU32)pT->HTotal*(NvU32)pT->VTotal);
NVT_SNPRINTF((char *)pT->etc.name, 40, "DMT:#%d:%dx%dx%dHz",
dmtId, pT->HVisible, pT->VVisible, pT->etc.rr);
((char *)pT->etc.name)[39] = '\0';
return NVT_STATUS_SUCCESS;
}
return NVT_STATUS_ERR;
}
CODE_SEGMENT(PAGE_DD_CODE)
NVT_STATUS NvTiming_CalcDMT(NvU32 width, NvU32 height, NvU32 rr, NvU32 flag, NVT_TIMING *pT)
{
NVT_TIMING *p = (NVT_TIMING *)DMT;
if (pT == NULL)
return NVT_STATUS_ERR;
if (width == 0 || height == 0 || rr == 0 )
return NVT_STATUS_ERR;
// no interlaced DMT timing
if ((flag & NVT_PVT_INTERLACED_MASK) != 0)
return NVT_STATUS_ERR;
while (p->HVisible != 0 && p->VVisible != 0)
{
if (NVT_GET_TIMING_STATUS_TYPE(p->etc.status) == NVT_TYPE_DMT)
{
if ((NvU32)p->HVisible == width &&
(NvU32)p->VVisible == height &&
(NvU32)p->etc.rr == rr)
{
NVMISC_MEMSET(pT, 0, sizeof(NVT_TIMING));
*pT = *p;
pT->etc.rrx1k = axb_div_c((NvU32)pT->pclk, (NvU32)10000*(NvU32)1000, (NvU32)pT->HTotal*(NvU32)pT->VTotal);
NVT_SNPRINTF((char *)pT->etc.name, 40, "DMT:%dx%dx%dHz",width, height, rr);
pT->etc.name[39] = '\0';
pT->etc.rgb444.bpc.bpc8 = 1;
return NVT_STATUS_SUCCESS;
}
}
p ++;
}
// if we couldn't find a DMT with regular blanking, try the DMT with reduced blanking next
return NvTiming_CalcDMT_RB(width, height, rr, flag, pT);
}
CODE_SEGMENT(PAGE_DD_CODE)
NVT_STATUS NvTiming_CalcDMT_RB(NvU32 width, NvU32 height, NvU32 rr, NvU32 flag, NVT_TIMING *pT)
{
NVT_TIMING *p = (NVT_TIMING *)DMT;
if (pT == NULL)
return NVT_STATUS_ERR;
if (width == 0 || height == 0 || rr == 0 )
return NVT_STATUS_ERR;
// no interlaced DMT timing
if ((flag & NVT_PVT_INTERLACED_MASK) != 0)
return NVT_STATUS_ERR;
while (p->HVisible != 0 && p->VVisible != 0)
{
// select only reduced-bandwidth timing.
if (NVT_GET_TIMING_STATUS_TYPE(p->etc.status) == NVT_TYPE_DMT_RB)
{
if ((NvU32)p->HVisible == width &&
(NvU32)p->VVisible == height &&
(NvU32)p->etc.rr == rr)
{
NVMISC_MEMSET(pT, 0, sizeof(NVT_TIMING));
*pT = *p;
pT->etc.rrx1k = axb_div_c((NvU32)pT->pclk, (NvU32)10000*(NvU32)1000, (NvU32)pT->HTotal*(NvU32)pT->VTotal);
NVT_SNPRINTF((char *)pT->etc.name, 40, "DMT-RB:%dx%dx%dHz",width, height, rr);
pT->etc.name[39] = '\0';
pT->etc.rgb444.bpc.bpc8 = 1;
return NVT_STATUS_SUCCESS;
}
}
p ++;
}
return NVT_STATUS_ERR;
}
POP_SEGMENTS

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,324 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2017-2019 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/*
===============================================================================
dsc_pps.h
Provide definition needed for DSC(Display Stream Compression) PPS(Picture Parameter Set)
================================================================================
*/
#ifndef __DSCPPS_H__
#define __DSCPPS_H__
/* ------------------------ Includes --------------------------------------- */
#include "nvtypes.h"
#include "nvtiming.h"
/* ------------------------ Macros ----------------------------------------- */
#define DSC_MAX_PPS_SIZE_DWORD 32
/* ------------------------ Datatypes -------------------------------------- */
#define DSC_CALLBACK_MODIFIED 1
#if defined(DSC_CALLBACK_MODIFIED)
typedef struct
{
// DSC - Callbacks
const void* clientHandle; // ClientHandle is only used when calling into HDMI lib's mallocCb/freeCb
void (*dscPrint) (const char* fmtstring, ...);
void *(*dscMalloc)(const void *clientHandle, NvLength size);
void (*dscFree) (const void *clientHandle, void * ptr);
} DSC_CALLBACK;
#else
typedef struct
{
// DSC - Callbacks
void (*dscPrint) (const char* fmtstring, ...);
void *(*dscMalloc)(NvLength size);
void (*dscFree) (void * ptr);
} DSC_CALLBACK;
#endif // DSC_CALLBACK_MODIFIED
typedef struct
{
NvU32 versionMajor;
NvU32 versionMinor;
} DSC_ALGORITHM_REV;
typedef struct
{
NvU64 pixelClockHz; // Requested pixel clock for the mode
NvU32 activeWidth; // Active Width
NvU32 activeHeight; // Active Height
NvU32 bitsPerComponent; // BPC value to be used
NVT_COLOR_FORMAT colorFormat; // Color format to be used for this modeset
//
// Whether to enable Dual mode for DSC.
// Dual mode specifies that 2 heads would be generating
// pixels for complete stream.
//
NvBool bDualMode;
//
// Whether to enable DROP mode for DSC.
// DROP mode specifies that instead of compressing the pixels, OR will drop
// the pixels of the right half frame to reduce the data rate by half.
// This mode is added for testing 2head1OR solution without a DSC panel
//
NvBool bDropMode;
} MODESET_INFO;
typedef struct
{
struct SINK_DSC_CAPS
{
// Mask of all color formats for which decoding supported by panel
NvU32 decoderColorFormatMask;
#define DSC_DECODER_COLOR_FORMAT_RGB (0x00000001)
#define DSC_DECODER_COLOR_FORMAT_Y_CB_CR_444 (0x00000002)
#define DSC_DECODER_COLOR_FORMAT_Y_CB_CR_SIMPLE_422 (0x00000004)
#define DSC_DECODER_COLOR_FORMAT_Y_CB_CR_NATIVE_422 (0x00000008)
#define DSC_DECODER_COLOR_FORMAT_Y_CB_CR_NATIVE_420 (0x00000010)
// e.g. 1/16, 1/8, 1/4, 1/2, 1bpp
NvU32 bitsPerPixelPrecision;
#define DSC_BITS_PER_PIXEL_PRECISION_1_16 (0x00000001)
#define DSC_BITS_PER_PIXEL_PRECISION_1_8 (0x00000002)
#define DSC_BITS_PER_PIXEL_PRECISION_1_4 (0x00000004)
#define DSC_BITS_PER_PIXEL_PRECISION_1_2 (0x00000008)
#define DSC_BITS_PER_PIXEL_PRECISION_1 (0x00000010)
// Maximum slice width supported by panel
NvU32 maxSliceWidth;
// Maximum number of horizontal slices supported
NvU32 maxNumHztSlices;
// Slice counts supported by the sink
NvU32 sliceCountSupportedMask;
#define DSC_DECODER_SLICES_PER_SINK_INVALID (0x00000000)
#define DSC_DECODER_SLICES_PER_SINK_1 (0x00000001)
#define DSC_DECODER_SLICES_PER_SINK_2 (0x00000002)
#define DSC_DECODER_SLICES_PER_SINK_4 (0x00000008)
#define DSC_DECODER_SLICES_PER_SINK_6 (0x00000010)
#define DSC_DECODER_SLICES_PER_SINK_8 (0x00000020)
#define DSC_DECODER_SLICES_PER_SINK_10 (0x00000040)
#define DSC_DECODER_SLICES_PER_SINK_12 (0x00000080)
#define DSC_DECODER_SLICES_PER_SINK_16 (0x00000100)
#define DSC_DECODER_SLICES_PER_SINK_20 (0x00000200)
#define DSC_DECODER_SLICES_PER_SINK_24 (0x00000400)
//
// Bit depth used by the Sink device to store the
// reconstructed pixels within the line buffer
//
NvU32 lineBufferBitDepth;
#define DSC_DECODER_LINE_BUFFER_BIT_DEPTH_MIN (0x00000008)
#define DSC_DECODER_LINE_BUFFER_BIT_DEPTH_MAX (0x0000000D)
NvU32 decoderColorDepthCaps; // Color depth supported by DSC decoder of panel
#define DSC_DECODER_COLOR_DEPTH_CAPS_8_BITS (0x00000001)
#define DSC_DECODER_COLOR_DEPTH_CAPS_10_BITS (0x00000002)
#define DSC_DECODER_COLOR_DEPTH_CAPS_12_BITS (0x00000004)
#define DSC_DECODER_COLOR_DEPTH_CAPS_16_BITS (0x00000008)
NvU32 decoderColorDepthMask;
DSC_ALGORITHM_REV algorithmRevision; // DSC algorithm revision that sink supports
NvBool bBlockPrediction; // Whether block prediction is supported or not.
// Peak throughput supported for 444 and simple 422 modes
NvU32 peakThroughputMode0;
#define DSC_DECODER_PEAK_THROUGHPUT_MODE0_INVALID (0x00000000)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE0_340 (0x00000001)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE0_400 (0x00000002)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE0_450 (0x00000003)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE0_500 (0x00000004)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE0_550 (0x00000005)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE0_600 (0x00000006)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE0_650 (0x00000007)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE0_700 (0x00000008)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE0_750 (0x00000009)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE0_800 (0x0000000A)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE0_850 (0x0000000B)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE0_900 (0x0000000C)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE0_950 (0x0000000D)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE0_1000 (0x0000000E)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE0_170 (0x0000000F)
// Peak throughput supported for native 422 and 420 modes
NvU32 peakThroughputMode1;
#define DSC_DECODER_PEAK_THROUGHPUT_MODE1_INVALID (0x00000000)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE1_340 (0x00000001)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE1_400 (0x00000002)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE1_450 (0x00000003)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE1_500 (0x00000004)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE1_550 (0x00000005)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE1_600 (0x00000006)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE1_650 (0x00000007)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE1_700 (0x00000008)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE1_750 (0x00000009)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE1_800 (0x0000000A)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE1_850 (0x0000000B)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE1_900 (0x0000000C)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE1_950 (0x0000000D)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE1_1000 (0x0000000E)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE1_170 (0x0000000F)
// Maximum bits_per_pixel supported by the DSC decompressor multiplied by 16
NvU32 maxBitsPerPixelX16;
}sinkCaps;
struct GPU_DSC_CAPS
{
// Mask of all color formats for which encoding supported by GPU
NvU32 encoderColorFormatMask;
#define DSC_ENCODER_COLOR_FORMAT_RGB (0x00000001)
#define DSC_ENCODER_COLOR_FORMAT_Y_CB_CR_444 (0x00000002)
#define DSC_ENCODER_COLOR_FORMAT_Y_CB_CR_NATIVE_422 (0x00000004)
#define DSC_ENCODER_COLOR_FORMAT_Y_CB_CR_NATIVE_420 (0x00000008)
//
// Size of line buffer inside DSC. Should be in number of pixels.
// this should be greater than or equal to active width
//
NvU32 lineBufferSize;
// e.g. 1/16, 1/8, 1/4, 1/2, 1bpp
NvU32 bitsPerPixelPrecision;
// Maximum number of horizontal slices supported
NvU32 maxNumHztSlices;
//
// Bit depth used by the GPU to store the
// reconstructed pixels within the line buffer
//
NvU32 lineBufferBitDepth;
}gpuCaps;
struct FORCED_DSC_PARAMS
{
// Forced Slice count
NvU32 sliceCount;
// Forced Slice width
NvU32 sliceWidth;
// Forced Slice height
NvU32 sliceHeight;
// Forced DSC Algorithm Revision
DSC_ALGORITHM_REV dscRevision;
}forcedDscParams;
} DSC_INFO;
typedef struct
{
NvU32 manufacturerID;
NvU32 productID;
NvU32 yearWeek;
} EDID_INFO;
typedef enum
{
DSC_DP,
DSC_HDMI
} DSC_CONNECTOR_TYPE;
typedef enum
{
DSC_DP_SST,
DSC_DP_MST
} DSC_DP_MODE;
typedef struct
{
DSC_CONNECTOR_TYPE connectorType;
struct DP_DATA
{
NvU64 linkRateHz;
NvU32 laneCount;
DSC_DP_MODE dpMode;
NvU32 hBlank;
}dpData;
} WAR_DATA;
/*
* Windows testbed compiles are done with warnings as errors
* with the maximum warning level. Here we turn off some
* of the problematic warnings.
*/
/* ------------------------ Global Variables ------------------------------- */
/* ------------------------ Static Variables ------------------------------- */
/* ------------------------ Private Functions ------------------------------ */
/* ------------------------ Public Functions ------------------------------- */
#ifdef __cplusplus
extern "C" {
#endif
/*
* @brief Initializes callbacks for print and assert
*
* @param[in] callback DSC callbacks
*
* @returns NVT_STATUS_SUCCESS if successful;
* NVT_STATUS_ERR if unsuccessful;
*/
NVT_STATUS DSC_InitializeCallback(DSC_CALLBACK callback);
/*
* @brief Calculate PPS parameters based on passed down Sink,
* GPU capability and modeset info
*
* @param[in] pDscInfo Includes Sink and GPU DSC capabilities
* @param[in] pModesetInfo Modeset related information
* @param[in] pWARData Data required for providing WAR for issues
* @param[in] availableBandwidthBitsPerSecond Available bandwidth for video
* transmission(After FEC/Downspread overhead consideration)
* @param[out] pps Calculated PPS parameter.
* The data can be send to SetDscPpsData* methods directly.
* @param[out] pBitsPerPixelX16 Bits per pixel multiplied by 16
*
* @returns NVT_STATUS_SUCCESS if successful;
* NVT_STATUS_ERR if unsuccessful;
*/
NVT_STATUS DSC_GeneratePPS(const DSC_INFO *pDscInfo,
const MODESET_INFO *pModesetInfo,
const WAR_DATA *pWARData,
NvU64 availableBandwidthBitsPerSecond,
NvU32 pps[DSC_MAX_PPS_SIZE_DWORD],
NvU32 *pBitsPerPixelX16);
#ifdef __cplusplus
}
#endif
#endif // __DSCPPS_H__

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,346 @@
//*****************************************************************************
//
// SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: MIT
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File: nvt_edidext_displayid20.c
//
// Purpose: the provide displayID 2.0 related services
//
//*****************************************************************************
#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);
/**
*
* @brief Parses a displayId20 EDID Extension block, with timings stored in p and
* other info stored in pInfo
* @param p The EDID Extension Block (With a DisplayID in it)
* @param size Size of the displayId Extension Block
* @param pEdidInfo EDID struct containing DisplayID information and
* the timings
*/
CODE_SEGMENT(PAGE_DD_CODE)
NVT_STATUS
getDisplayId20EDIDExtInfo(
NvU8 *p,
NvU32 size,
NVT_EDID_INFO *pEdidInfo)
{
DISPLAYID_2_0_SECTION *extSection = NULL;
if (p == NULL ||
size < sizeof(EDIDV1STRUC) ||
size > sizeof(EDIDV1STRUC) ||
p[0] != NVT_EDID_EXTENSION_DISPLAYID ||
pEdidInfo == NULL)
{
return NVT_STATUS_INVALID_PARAMETER;
}
// Calculate the All DisplayID20 Extension checksum
// 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);
}
extSection = (DISPLAYID_2_0_SECTION *)(p + 1);
return parseDisplayId20EDIDExtSection(extSection, pEdidInfo);
}
/*
* @brief DisplayId20 as EDID extension block's "Section" entry point functions
*/
CODE_SEGMENT(PAGE_DD_CODE)
NVT_STATUS
parseDisplayId20EDIDExtSection(
DISPLAYID_2_0_SECTION * extSection,
NVT_EDID_INFO *pEdidInfo)
{
NvU8 datablock_location = 0;
NvU8 datablock_length;
NvU8 remaining_length;
if ((extSection == NULL) ||
(extSection->header.section_bytes != 121))
{
return NVT_STATUS_ERR;
}
// It is based on the DisplayID v2.0 Errata E7
// First DisplayID2.0 section as EDID extension shall populate "Display Product Primary Use Case" byte with a value from 1h-8h based on the intended primary use case of the sink.
// Any subsequent DisplayID2.0 section EDID extension shall set the "Display Product Primary Use Case" byte to 0h.
pEdidInfo->total_did2_extensions++;
if (extSection->header.version == DISPLAYID_2_0_VERSION)
{
if (((pEdidInfo->total_did2_extensions == 1) && (extSection->header.product_type == 0 ||
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))
{
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;
pEdidInfo->ext_displayid20.as_edid_extension = NV_TRUE;
}
else
{
return NVT_STATUS_INVALID_PARAMETER;
}
// validate for section checksum before processing the data block
if (computeDisplayId20SectionCheckSum((const NvU8*)extSection, DISPLAYID_2_0_SECTION_SIZE_TOTAL(extSection->header)) != 0)
{
return NVT_STATUS_ERR;
}
remaining_length = extSection->header.section_bytes;
while (datablock_location < extSection->header.section_bytes)
{
DISPLAYID_2_0_DATA_BLOCK_HEADER * dbHeader = (DISPLAYID_2_0_DATA_BLOCK_HEADER *) (extSection->data + datablock_location);
NvU8 is_reserve = remaining_length > 3 && datablock_location == 0 && dbHeader->type == 0 && dbHeader->data_bytes > 0;
NvU8 i;
// Check the padding.
if (dbHeader->type == 0 && !is_reserve)
{
for (i = 1 ; i < remaining_length; i++)
{
// All remaining bytes must all be 0.
if (extSection->data[datablock_location + i] != 0)
{
return NVT_STATUS_ERR;
}
}
datablock_length = remaining_length;
}
else
{
if (parseDisplayId20EDIDExtDataBlocks(
dbHeader,
extSection->header.section_bytes - datablock_location,
&datablock_length,
pEdidInfo) != NVT_STATUS_SUCCESS)
return NVT_STATUS_ERR;
}
datablock_location += datablock_length;
remaining_length -= datablock_length;
}
return NVT_STATUS_SUCCESS;
}
/*
* @brief DisplayId20 as EDID extension block's "Data Block" entry point functions
*/
CODE_SEGMENT(PAGE_DD_CODE)
static NVT_STATUS
parseDisplayId20EDIDExtDataBlocks(
DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock,
NvU8 RemainSectionLength,
NvU8 *pCurrentDBLength,
NVT_EDID_INFO *pEdidInfo)
{
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))
return NVT_STATUS_ERR;
if (pDataBlock->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;
status = parseDisplayId20DataBlock(pDataBlock, pDisplayId20Info);
// 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)
{
case DISPLAYID_2_0_BLOCK_TYPE_INTERFACE_FEATURES:
pDisplayId20Info->valid_data_blocks.interface_feature_present = NV_TRUE;
// Supported - Color depth is supported for all supported timings. Supported timing includes all Display-ID exposed timings
// (that is timing exposed using DisplayID timing types and CTA VICs)
if (IS_BPC_SUPPORTED_COLORFORMAT(pDisplayId20Info->interface_features.yuv444.bpcs))
{
pDisplayId20Info->basic_caps |= NVT_DISPLAY_2_0_CAP_YCbCr_444;
}
if (IS_BPC_SUPPORTED_COLORFORMAT(pDisplayId20Info->interface_features.yuv422.bpcs))
{
pDisplayId20Info->basic_caps |= NVT_DISPLAY_2_0_CAP_YCbCr_422;
}
if (pDisplayId20Info->interface_features.audio_capability.support_48khz ||
pDisplayId20Info->interface_features.audio_capability.support_44_1khz ||
pDisplayId20Info->interface_features.audio_capability.support_32khz)
{
pDisplayId20Info->basic_caps |= NVT_DISPLAY_2_0_CAP_BASIC_AUDIO;
}
break;
// DisplayID_v2.0 E5 defined
// if inside CTA embedded block existed 420 VDB/CMDB, then we follow these two blocks only.
// * support for 420 pixel encoding is limited to the timings exposed in the restricted set exposed in the CTA data block.
// * field of "Mini Pixel Rate at YCbCr420" shall be set 00h
case DISPLAYID_2_0_BLOCK_TYPE_CTA_DATA:
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
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));
// If the CTA861 extension existed already, we need to transfer the revision/basic_caps to cta embedded in DID20.
if (pEdidInfo->ext861.revision >= NVT_CEA861_REV_B)
{
pDisplayId20Info->cta.cta861_info.revision = pEdidInfo->ext861.revision;
pDisplayId20Info->cta.cta861_info.basic_caps = pEdidInfo->ext861.basic_caps;
pDisplayId20Info->basic_caps = pEdidInfo->ext861.basic_caps;
}
// this is the DisplayID20 Extension, so we need to copy from what is the CTA raw data in DID20 to Edid's CTA block
NVMISC_MEMCPY(&pEdidInfo->ext861, &pDisplayId20Info->cta.cta861_info, sizeof(NVT_EDID_CEA861_INFO));
break;
case DISPLAYID_2_0_BLOCK_TYPE_DISPLAY_PARAM:
pDisplayId20Info->valid_data_blocks.parameters_present = NV_TRUE;
// EDID only supported 10bits chromaitcity to match the OS D3DKMDT_2DOFFSET 10bits, so we don't need to transfer it here.
pEdidInfo->input.u.digital.bpc = NVT_COLORDEPTH_HIGHEST_BPC(pDisplayId20Info->display_param.native_color_depth);
pEdidInfo->gamma = pDisplayId20Info->display_param.gamma_x100;
if (pDisplayId20Info->display_param.audio_speakers_integrated == AUDIO_SPEAKER_INTEGRATED_SUPPORTED)
{
pDisplayId20Info->basic_caps |= NVT_DISPLAY_2_0_CAP_BASIC_AUDIO;
}
break;
default:
break;
}
}
return status;
}
/* @brief Update the correct color format / attribute of timings from interface feature data block
*/
CODE_SEGMENT(PAGE_DD_CODE)
void
updateColorFormatForDisplayId20ExtnTimings(
NVT_EDID_INFO *pInfo,
NvU32 timingIdx)
{
// pDisplayId20Info parsed displayID20 info
NVT_DISPLAYID_2_0_INFO *pDisplayId20Info = &pInfo->ext_displayid20;
NVT_TIMING *pT= &pInfo->timing[timingIdx];
nvt_assert(timingIdx <= COUNT(pInfo->timing));
if (pDisplayId20Info->as_edid_extension)
{
if ((pInfo->input.u.digital.video_interface == NVT_EDID_DIGITAL_VIDEO_INTERFACE_STANDARD_HDMI_A_SUPPORTED ||
pInfo->input.u.digital.video_interface == NVT_EDID_DIGITAL_VIDEO_INTERFACE_STANDARD_HDMI_B_SUPPORTED ||
pInfo->ext861.valid.H14B_VSDB || pInfo->ext861.valid.H20_HF_VSDB) && pInfo->ext861.revision >= NVT_CEA861_REV_A)
{
UPDATE_BPC_FOR_COLORFORMAT(pT->etc.rgb444, 0,
1,
pDisplayId20Info->interface_features.rgb444.bpc.bpc10,
pDisplayId20Info->interface_features.rgb444.bpc.bpc12,
pDisplayId20Info->interface_features.rgb444.bpc.bpc14,
pDisplayId20Info->interface_features.rgb444.bpc.bpc16);
}
else
{
// rgb444 (always support 6bpc and 8bpc as per DP spec 5.1.1.1.1 RGB Colorimetry)
UPDATE_BPC_FOR_COLORFORMAT(pT->etc.rgb444, 1,
1,
pDisplayId20Info->interface_features.rgb444.bpc.bpc10,
pDisplayId20Info->interface_features.rgb444.bpc.bpc12,
pDisplayId20Info->interface_features.rgb444.bpc.bpc14,
pDisplayId20Info->interface_features.rgb444.bpc.bpc16);
}
// yuv444
UPDATE_BPC_FOR_COLORFORMAT(pT->etc.yuv444, 0, /* yuv444 does not support 6bpc */
pDisplayId20Info->interface_features.yuv444.bpc.bpc8,
pDisplayId20Info->interface_features.yuv444.bpc.bpc10,
pDisplayId20Info->interface_features.yuv444.bpc.bpc12,
pDisplayId20Info->interface_features.yuv444.bpc.bpc14,
pDisplayId20Info->interface_features.yuv444.bpc.bpc16);
// yuv422
UPDATE_BPC_FOR_COLORFORMAT(pT->etc.yuv422, 0, /* yuv422 does not support 6bpc */
pDisplayId20Info->interface_features.yuv422.bpc.bpc8,
pDisplayId20Info->interface_features.yuv422.bpc.bpc10,
pDisplayId20Info->interface_features.yuv422.bpc.bpc12,
pDisplayId20Info->interface_features.yuv422.bpc.bpc14,
pDisplayId20Info->interface_features.yuv422.bpc.bpc16);
if (!NVT_DID20_TIMING_IS_CTA861(pInfo->timing[timingIdx].etc.flag, pInfo->timing[timingIdx].etc.status))
{
// yuv420
UPDATE_BPC_FOR_COLORFORMAT(pT->etc.yuv420, 0, /* yuv420 does not support 6bpc */
pDisplayId20Info->interface_features.yuv420.bpc.bpc8,
pDisplayId20Info->interface_features.yuv420.bpc.bpc10,
pDisplayId20Info->interface_features.yuv420.bpc.bpc12,
pDisplayId20Info->interface_features.yuv420.bpc.bpc14,
pDisplayId20Info->interface_features.yuv420.bpc.bpc16);
}
}
}
POP_SEGMENTS

View File

@@ -0,0 +1,138 @@
//*****************************************************************************
//
// SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: MIT
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File: nvt_gtf.c
//
// Purpose: calculate gtf timing
//
//*****************************************************************************
#include "nvBinSegment.h"
#include "nvmisc.h"
#include "nvtiming_pvt.h"
// calculate GTF timing
PUSH_SEGMENTS
CONS_SEGMENT(PAGE_CONS)
const NvU32 NVT_GTF_CELL_GRAN=8;
const NvU32 NVT_GTF_MIN_VSYNCBP=11; // in 550us (!!) [1000000:550 = 20000:11]
const NvU32 NVT_GTF_MIN_VPORCH=1;
const NvU32 NVT_GTF_C_PRIME=30; // (gtf_C-gtf_J)*gtf_K/256+gtf_J;
const NvU32 NVT_GTF_M_PRIME=300; // NVT_GTFK/256*gtf_M;
const NvU32 NVT_GTF_VSYNC_RQD=3;
const NvU32 NVT_GTF_HSYNC_PERCENTAGE=8; // 8% HSync for GTF
CODE_SEGMENT(PAGE_DD_CODE)
NVT_STATUS NvTiming_CalcGTF(NvU32 width, NvU32 height, NvU32 rr, NvU32 flag, NVT_TIMING *pT)
{
NvU32 dwXCells, dwVSyncBP, dwVTotal, dwIdN, dwIdD, dwHBlank, dwHTCells, dwHSync, dwHFrontPorch, dwRefreshRate;
// parameter check
if (pT == NULL)
return NVT_STATUS_ERR;
if (width == 0 || height == 0 || rr == 0 )
return NVT_STATUS_ERR;
dwRefreshRate = rr;
dwXCells = a_div_b(width, NVT_GTF_CELL_GRAN);
if(dwRefreshRate * NVT_GTF_MIN_VSYNCBP >= 20000)
return NVT_STATUS_ERR;//NVT_STATUS_ERR_OUTOFRANGE; // H period estimate less than 0
dwVSyncBP = a_div_b((height + NVT_GTF_MIN_VPORCH) * NVT_GTF_MIN_VSYNCBP * dwRefreshRate,
(20000 - NVT_GTF_MIN_VSYNCBP * dwRefreshRate));
dwVTotal = dwVSyncBP + height + NVT_GTF_MIN_VPORCH;
// Calculate the numerator and denominator of Ideal Duty Cycle
// NOTE: here dwIdN/dwIdN = IdealDutyCycle/GTF_C_Prime
dwIdD = dwVTotal * dwRefreshRate;
if(dwIdD <= NVT_GTF_M_PRIME * 1000 / NVT_GTF_C_PRIME)
return NVT_STATUS_ERR;//NVT_STATUS_ERR_OUTOFRANGE; // Ideal duty cycle less than 0
dwIdN = dwIdD - NVT_GTF_M_PRIME * 1000 / NVT_GTF_C_PRIME;
// A proper way to calculate dwXCells*dwIdN/(100*dwIdD/GTF_C_PRIME-dwIdN)
dwHBlank = axb_div_c(dwIdN*3, dwXCells, 2*(300*dwIdD/NVT_GTF_C_PRIME - dwIdN*3));
dwHBlank = ( dwHBlank ) * 2 * NVT_GTF_CELL_GRAN;
dwHTCells = dwXCells + dwHBlank / NVT_GTF_CELL_GRAN;
dwHSync = a_div_b(dwHTCells * NVT_GTF_HSYNC_PERCENTAGE, 100) * NVT_GTF_CELL_GRAN;
if((dwHSync == 0) || (dwHSync*2 > dwHBlank))
return NVT_STATUS_ERR;//NVT_STATUS_ERR_OUTOFRANGE; // HSync too small or too big.
dwHFrontPorch = dwHBlank/2-dwHSync;
NVMISC_MEMSET(pT, 0, sizeof(NVT_TIMING));
pT->HVisible = (NvU16)(dwXCells*NVT_GTF_CELL_GRAN);
pT->VVisible = (NvU16)height;
pT->HTotal = (NvU16)(dwHTCells*NVT_GTF_CELL_GRAN);
pT->HFrontPorch = (NvU16)dwHFrontPorch;
pT->HSyncWidth = (NvU16)dwHSync;
pT->VTotal = (NvU16)dwVTotal;
pT->VFrontPorch = (NvU16)NVT_GTF_MIN_VPORCH;
pT->VSyncWidth = (NvU16)NVT_GTF_VSYNC_RQD;
// A proper way to calculate fixed HTotal*VTotal*Rr/10000
pT->pclk = axb_div_c(dwHTCells*dwVTotal, dwRefreshRate, 10000/NVT_GTF_CELL_GRAN);
pT->HSyncPol = NVT_H_SYNC_NEGATIVE;
pT->VSyncPol = NVT_V_SYNC_POSITIVE;
pT->interlaced = 0;
// fill in the extra timing info
pT->etc.flag = 0;
pT->etc.rr = (NvU16)rr;
pT->etc.rrx1k = axb_div_c((NvU32)pT->pclk, (NvU32)10000*(NvU32)1000, (NvU32)pT->HTotal*(NvU32)pT->VTotal);
pT->etc.aspect = 0;
pT->etc.rep = 0x1;
pT->etc.status = NVT_STATUS_GTF;
NVT_SNPRINTF((char *)pT->etc.name, 40, "GTF:%dx%dx%dHz",width, height, rr);
pT->etc.name[39] = '\0';
pT->etc.rgb444.bpc.bpc8 = 1;
// interlaced adjustment
if ((flag & NVT_PVT_INTERLACED_MASK) != 0)
{
if ((pT->VTotal & 0x1) != 0)
pT->interlaced = NVT_INTERLACED_EXTRA_VBLANK_ON_FIELD2;
else
pT->interlaced = NVT_INTERLACED_NO_EXTRA_VBLANK_ON_FIELD2;
pT->pclk >>= 1;
pT->VTotal >>= 1;
pT->VVisible = (pT->VVisible + 1) / 2;
}
return NVT_STATUS_SUCCESS;
}
POP_SEGMENTS

View File

@@ -0,0 +1,192 @@
//*****************************************************************************
//
// SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: MIT
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File: nvt_tv.c
//
// Purpose: calculate tv based timing timing
//
//*****************************************************************************
#include "nvBinSegment.h"
#include "nvtiming_pvt.h"
PUSH_SEGMENTS
CONS_SEGMENT(PAGE_CONS)
static const NVT_TIMING TV_TIMING[] =
{
{720, 0,21,66,894, NVT_H_SYNC_POSITIVE,240, 0,10,6,262, NVT_V_SYNC_POSITIVE,NVT_INTERLACED, 1407, {0,60,59940,0x0403,0x1,{0},{0},{0},{0},NVT_STATUS_SDTV_NTSC_M, "SDTV:NTSC_M"}},
{720, 0,21,66,894, NVT_H_SYNC_POSITIVE,240, 0,10,6,262, NVT_V_SYNC_POSITIVE,NVT_INTERLACED, 1407, {0,60,59940,0x0403,0x1,{0},{0},{0},{0},NVT_STATUS_SDTV_NTSC_J, "SDTV:NTSC_J"}},
{720, 0,21,66,894, NVT_H_SYNC_POSITIVE,288, 0,10,8,312, NVT_V_SYNC_POSITIVE,NVT_INTERLACED, 1397, {0,50,50000,0x0403,0x1,{0},{0},{0},{0},NVT_STATUS_SDTV_PAL_M, "SDTV:PAL_M"}},
{720, 0,21,66,894, NVT_H_SYNC_POSITIVE,288, 0,10,8,312, NVT_V_SYNC_POSITIVE,NVT_INTERLACED, 1397, {0,50,50000,0x0403,0x1,{0},{0},{0},{0},NVT_STATUS_SDTV_PAL_A, "SDTV:PAL_A"}},
{720, 0,21,66,894, NVT_H_SYNC_POSITIVE,288, 0,10,8,312, NVT_V_SYNC_POSITIVE,NVT_INTERLACED, 1397, {0,50,50000,0x0403,0x1,{0},{0},{0},{0},NVT_STATUS_SDTV_PAL_N, "SDTV:PAL_N"}},
{720, 0,21,66,894, NVT_H_SYNC_POSITIVE,288, 0,10,8,312, NVT_V_SYNC_POSITIVE,NVT_INTERLACED, 1397, {0,50,50000,0x0403,0x1,{0},{0},{0},{0},NVT_STATUS_SDTV_PAL_NC, "SDTV:PAL_NC"}},
{720, 0,21,66,894, NVT_H_SYNC_POSITIVE,240, 0,10,6,262, NVT_V_SYNC_POSITIVE,NVT_INTERLACED, 1407, {0,60,59940,0x0403,0x1,{0},{0},{0},{0},NVT_STATUS_HDTV_480I, "HDTV(analog):480i"}},
{720, 0,15,8, 858, NVT_H_SYNC_NEGATIVE,480, 0,10,4,525, NVT_V_SYNC_NEGATIVE,NVT_PROGRESSIVE,2700, {0,60,59940,0x0403,0x1,{0},{0},{0},{0},NVT_STATUS_HDTV_480P, "HDTV(analog):480p"}},
{720, 0,21,66,894, NVT_H_SYNC_POSITIVE,288, 0,10,8,312, NVT_V_SYNC_POSITIVE,NVT_INTERLACED, 1397, {0,50,50000,0x0403,0x1,{0},{0},{0},{0},NVT_STATUS_HDTV_576I, "HDTV(analog):576i"}},
{720, 0,10,8, 864, NVT_H_SYNC_NEGATIVE,576, 0,5, 4,625, NVT_V_SYNC_NEGATIVE,NVT_PROGRESSIVE,2700, {0,50,50000,0x0403,0x1,{0},{0},{0},{0},NVT_STATUS_HDTV_576P, "HDTV(analog):576p"}},
{1280,0,70,80, 1650,NVT_H_SYNC_NEGATIVE,720,0,5, 5,750, NVT_V_SYNC_NEGATIVE,NVT_PROGRESSIVE,7418, {0,60,59940,0x1009,0x1,{0},{0},{0},{0},NVT_STATUS_HDTV_720P, "HDTV(analog):720p"}},
{1920,0,44,88,2200,NVT_H_SYNC_NEGATIVE,540, 0,2, 5,562, NVT_V_SYNC_NEGATIVE,NVT_INTERLACED, 7418, {0,60,59940,0x1009,0x1,{0},{0},{0},{0},NVT_STATUS_HDTV_1080I, "HDTV(analog):1080i"}},
{1920,0,44,88,2200,NVT_H_SYNC_NEGATIVE,1080,0,4, 5,1125,NVT_V_SYNC_NEGATIVE,NVT_PROGRESSIVE,14835,{0,60,59940,0x1009,0x1,{0},{0},{0},{0},NVT_STATUS_HDTV_1080P, "HDTV(analog):1080p"}},
{1280,0,400,80,1980,NVT_H_SYNC_NEGATIVE,720,0,5, 5,750, NVT_V_SYNC_NEGATIVE,NVT_PROGRESSIVE,7425, {0,50,50000,0x1009,0x1,{0},{0},{0},{0},NVT_STATUS_HDTV_720P50, "HDTV(analog):720p50"}},
{1920,0,594,88,2750,NVT_H_SYNC_NEGATIVE,1080,0,4, 5,1125,NVT_V_SYNC_NEGATIVE,NVT_PROGRESSIVE,7425,{0,24,24000,0x1009,0x1,{0},{0},{0},{0},NVT_STATUS_HDTV_1080P24,"HDTV(analog):1080p24"}},
{1920,0,484,88,2640,NVT_H_SYNC_NEGATIVE,540, 0,4, 5,562, NVT_V_SYNC_NEGATIVE,NVT_INTERLACED, 7425,{0,50,50000,0x1009,0x1,{0},{0},{0},{0},NVT_STATUS_HDTV_1080I50,"HDTV(analog):1080i50"}},
{1920,0,484,88,2640,NVT_H_SYNC_NEGATIVE,1080,0,4, 5,1125,NVT_V_SYNC_NEGATIVE,NVT_PROGRESSIVE,14850,{0,50,50000,0x1009,0x1,{0},{0},{0},{0},NVT_STATUS_HDTV_1080P50,"HDTV(analog):1080p50"}},
{0,0,0,0,0,NVT_H_SYNC_NEGATIVE,0,0,0,0,0,NVT_V_SYNC_NEGATIVE,NVT_PROGRESSIVE,0,{0,0,0,0,0,{0},{0},{0},{0},0,""}}
};
//***********************************************
//** Wrapper Structure to store Fake EDID data **
//***********************************************
typedef struct tagFAKE_TV_EDID
{
NvU32 EdidType;
NvU32 EdidSize;
const NvU8* FakeEdid;
} FAKE_TV_EDID;
// calculate the backend TV timing
CODE_SEGMENT(PAGE_DD_CODE)
NVT_STATUS NvTiming_GetTvTiming(NvU32 width, NvU32 height, NvU32 rr, NvU32 flag, NvU32 tvFormat, NVT_TIMING *pT)
{
NvU32 i, j, k;
// input check
if (pT == NULL)
return NVT_STATUS_ERR;
if ((width == 0 || height == 0 || rr == 0) && tvFormat >= NVT_MAX_TV_FORMAT)
return NVT_STATUS_ERR;
// handle double scan
if (height <= NVT_PVT_DOUBLE_SCAN_HEIGHT)
{
width <<= 1;
height <<= 1;
}
// try the exact match first
if (tvFormat != NVT_AUTO_HDTV_FORMAT)
{
i = 0;
while (TV_TIMING[i].HVisible != 0)
{
if (NVT_GET_TIMING_STATUS_SEQ(TV_TIMING[i].etc.status) == tvFormat)
{
// find the match
*pT = TV_TIMING[i];
return NVT_STATUS_SUCCESS;
}
// move to the next entry
i++;
}
// unknown TV format, return failure here
*pT = TV_TIMING[0];
return NVT_STATUS_ERR;
}
// we are doing auto HDTV format binding here
i = 0;
j = k = sizeof(TV_TIMING)/sizeof(TV_TIMING[0]) - 1;
while (TV_TIMING[i].HVisible != 0)
{
// #1: try the exact resolution/refreshrate/interlaced match
if (width == TV_TIMING[i].HVisible &&
height == frame_height(TV_TIMING[i])&&
rr == TV_TIMING[i].etc.rr &&
!!(flag & NVT_PVT_INTERLACED_MASK) == !!TV_TIMING[i].interlaced &&
NVT_GET_TIMING_STATUS_TYPE(TV_TIMING[i].etc.status) == NVT_TYPE_HDTV)
{
// exact match, return from here
*pT = TV_TIMING[i];
return NVT_STATUS_SUCCESS;
}
// #2: try to closest match with interlaced check ON
if (!!(flag & NVT_PVT_INTERLACED_MASK) == !!TV_TIMING[i].interlaced &&
NVT_GET_TIMING_STATUS_TYPE(TV_TIMING[i].etc.status) == NVT_TYPE_HDTV)
{
if (abs_delta(width, TV_TIMING[i].HVisible) <= abs_delta(width, TV_TIMING[j].HVisible) &&
abs_delta(height, frame_height(TV_TIMING[i])) <= abs_delta(height, frame_height(TV_TIMING[j])) &&
abs_delta(rr, TV_TIMING[i].etc.rr) <= abs_delta(rr, TV_TIMING[j].etc.rr) &&
width <= TV_TIMING[i].HVisible &&
height <= frame_height(TV_TIMING[i]))
{
j = i;
}
}
// #3: try to closest match with interlaced check OFF
if (NVT_GET_TIMING_STATUS_TYPE(TV_TIMING[i].etc.status) == NVT_TYPE_HDTV)
{
if (abs_delta(width, TV_TIMING[i].HVisible) <= abs_delta(width, TV_TIMING[k].HVisible) &&
abs_delta(height, frame_height(TV_TIMING[i])) <= abs_delta(height, frame_height(TV_TIMING[k])) &&
abs_delta(rr, TV_TIMING[i].etc.rr) <= abs_delta(rr, TV_TIMING[j].etc.rr) &&
width <= TV_TIMING[i].HVisible &&
height <= frame_height(TV_TIMING[i]))
{
k = i;
}
}
// move to the next entry
i++;
}
// return the closest matched timing here
if (TV_TIMING[j].HVisible != 0)
{
*pT = TV_TIMING[j];
}
else if (TV_TIMING[k].HVisible != 0)
{
*pT = TV_TIMING[k];
}
else
{
*pT = TV_TIMING[0];
}
// set the mismatch status
if (pT->HVisible != width || frame_height(*pT) != height)
{
NVT_SET_TIMING_STATUS_MISMATCH(pT->etc.status, NVT_STATUS_TIMING_MISMATCH_SIZE);
}
if (pT->etc.rr != rr)
{
NVT_SET_TIMING_STATUS_MISMATCH(pT->etc.status, NVT_STATUS_TIMING_MISMATCH_RR);
}
if (!!pT->interlaced != !!(flag & NVT_PVT_INTERLACED_MASK))
{
NVT_SET_TIMING_STATUS_MISMATCH(pT->etc.status, NVT_STATUS_TIMING_MISMATCH_FORMAT);
}
return NVT_STATUS_SUCCESS;
}
POP_SEGMENTS

View File

@@ -0,0 +1,370 @@
//*****************************************************************************
//
// SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: MIT
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File: nvt_util.c
//
// Purpose: provide the utility functions for timing library
//
//*****************************************************************************
#include "nvBinSegment.h"
#include "nvtiming_pvt.h"
PUSH_SEGMENTS
CONS_SEGMENT(PAGE_CONS)
// The following table was generated w/ this program:
/*
#include <stdio.h>
#define CRC32_POLYNOMIAL 0xEDB88320
void main()
{
unsigned int crc = 0, i = 0, j = 0;
unsigned int CRCTable[256];
for (i = 0; i < 256 ; i++)
{
crc = i;
for (j = 8; j > 0; j--)
{
if (crc & 1)
crc = (crc >> 1) ^ CRC32_POLYNOMIAL;
else
crc >>= 1;
}
CRCTable[i] = crc;
}
printf("static const NvU32 s_CRCTable[256] = {");
for (i = 0; i < 256; i++)
{
printf("%s0x%08X%s",
((i % 10 == 0) ? "\n " : ""),
CRCTable[i],
((i != 255) ? ", " : " "));
}
printf("};\n");
}
*/
static const NvU32 s_CRCTable[256] = {
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4,
0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A,
0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6,
0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C,
0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8,
0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D };
CODE_SEGMENT(NONPAGE_DD_CODE)
NvU32 a_div_b(NvU32 a, NvU32 b)
{
if (b == 0)
return 0xFFFFFFFF;
return (a + b/2)/b;
}
CODE_SEGMENT(NONPAGE_DD_CODE)
NvU32 axb_div_c(NvU32 a, NvU32 b, NvU32 c)
{
NvU32 AhxBl, AlxBh;
NvU32 AxB_high, AxB_low;
NvU32 AxB_div_C_low;
if (c==0)
return 0xFFFFFFFF;
// calculate a*b
AhxBl = (a>>16)*(b&0xFFFF);
AlxBh = (a&0xFFFF)*(b>>16);
AxB_high = (a>>16) * (b>>16);
AxB_low = (a&0xFFFF) * (b&0xFFFF);
AxB_high += AlxBh >> 16;
AxB_high += AhxBl >> 16;
if ((AxB_low + (AlxBh<<16))< AxB_low)
AxB_high ++;
AxB_low += AlxBh << 16;
if ((AxB_low + (AhxBl<<16)) < AxB_low)
AxB_high ++;
AxB_low += AhxBl << 16;
AxB_div_C_low = AxB_low/c;
AxB_div_C_low += 0xFFFFFFFF / c * (AxB_high % c);
AxB_div_C_low += ((0xFFFFFFFF % c + 1) * (AxB_high % c) + (AxB_low % c) + c/2) / c;
return AxB_div_C_low;
}
CODE_SEGMENT(NONPAGE_DD_CODE)
NvU64 axb_div_c_64(NvU64 a, NvU64 b, NvU64 c)
{
// NvU64 arithmetic to keep precision and avoid floats
// a*b/c = (a/c)*b + ((a%c)*b + c/2)/c
return ((a/c)*b + ((a%c)*b + c/2)/c);
}
CODE_SEGMENT(PAGE_DD_CODE)
NvU32 calculateCRC32(NvU8* pBuf, NvU32 bufsize)
{
NvU32 crc32 = 0xFFFFFFFF, temp1, temp2, count = bufsize;
if (bufsize == 0 || pBuf == NULL)
{
return 0;
}
while (count-- != 0)
{
temp1 = (crc32 >> 8) & 0x00FFFFFF;
temp2 = s_CRCTable[(crc32 ^ *pBuf++) & 0xFF];
crc32 = temp1 ^ temp2;
}
crc32 ^= 0xFFFFFFFF;
return crc32;
}
CODE_SEGMENT(PAGE_DD_CODE)
NvBool isChecksumValid(NvU8 *pBuf)
{
NvU8 i;
NvU8 checksum = 0;
for (i= 0; i < NVT_EDID_BLOCK_SIZE; i++)
{
checksum += pBuf[i];
}
if ((checksum & 0xFF) == 0)
{
return NV_TRUE;
}
return NV_FALSE;
}
CODE_SEGMENT(PAGE_DD_CODE)
void patchChecksum(NvU8 *pBuf)
{
NvU8 i;
NvU8 chksum = 0;
for (i = 0; i < NVT_EDID_BLOCK_SIZE; i++)
{
chksum += pBuf[i];
}
chksum &= 0xFF;
// The 1-byte sum of all 128 bytes in this EDID block shall equal zero
// The Checksum Byte (at address 7Fh) shall contain a value such that a checksum of the entire
// 128-byte BASE EDID equals 00h.
if (chksum)
{
pBuf[127] = 0xFF & (pBuf[127] + (0x100 - chksum));
}
}
CODE_SEGMENT(PAGE_DD_CODE)
NVT_STATUS NvTiming_ComposeCustTimingString(NVT_TIMING *pT)
{
if (pT == NULL)
return NVT_STATUS_ERR;
NVT_SNPRINTF((char *)pT->etc.name, 40, "CUST:%dx%dx%d.%03dHz%s",pT->HVisible, (pT->interlaced ? 2 : 1)*pT->VVisible , pT->etc.rrx1k/1000, pT->etc.rrx1k%1000, (pT->interlaced ? "/i" : ""));
pT->etc.name[39] = '\0';
return NVT_STATUS_SUCCESS;
}
CODE_SEGMENT(PAGE_DD_CODE)
NvU16 NvTiming_CalcRR(NvU32 pclk, NvU16 interlaced, NvU16 HTotal, NvU16 VTotal)
{
NvU16 rr = 0;
if (interlaced)
{
NvU32 totalPixelsIn2Fields = (NvU32)HTotal * ((NvU32)VTotal * 2 + 1);
if (totalPixelsIn2Fields != 0)
{
rr = (NvU16)axb_div_c(pclk * 2, 10000, totalPixelsIn2Fields);
}
}
else
{
NvU32 totalPixels = (NvU32)HTotal * VTotal;
if (totalPixels != 0)
{
rr = (NvU16)axb_div_c(pclk, 10000, totalPixels);
}
}
return rr;
}
CODE_SEGMENT(PAGE_DD_CODE)
NvU32 NvTiming_CalcRRx1k(NvU32 pclk, NvU16 interlaced, NvU16 HTotal, NvU16 VTotal)
{
NvU32 rrx1k = 0;
if (interlaced)
{
NvU32 totalPixelsIn2Fields = (NvU32)HTotal * ((NvU32)VTotal * 2 + 1);
if (totalPixelsIn2Fields != 0)
{
rrx1k = (NvU32)axb_div_c(pclk * 2, 10000000, totalPixelsIn2Fields);
}
}
else
{
NvU32 totalPixels = (NvU32)HTotal * VTotal;
if (totalPixels != 0)
{
rrx1k = (NvU32)axb_div_c(pclk, 10000000, totalPixels);
}
}
return rrx1k;
}
CODE_SEGMENT(PAGE_DD_CODE)
NvU32 NvTiming_IsRoundedRREqual(NvU16 rr1, NvU32 rr1x1k, NvU16 rr2)
{
return ((rr1 >= (rr1x1k/1000)) && (rr1 <= (rr1x1k + 500) / 1000) &&
(rr2 >= (rr1x1k/1000)) && (rr2 <= (rr1x1k + 500) / 1000));
}
CODE_SEGMENT(NONPAGE_DD_CODE)
NvU32 NvTiming_IsTimingExactEqual(const NVT_TIMING *pT1, const NVT_TIMING *pT2)
{
if ((pT1 == NULL) || (pT2 == NULL))
{
return 0;
}
return (( pT1->HVisible == pT2->HVisible) &&
( pT1->HBorder == pT2->HBorder) &&
( pT1->HFrontPorch == pT2->HFrontPorch) &&
( pT1->HSyncWidth == pT2->HSyncWidth) &&
( pT1->HSyncPol == pT2->HSyncPol) &&
( pT1->HTotal == pT2->HTotal) &&
( pT1->VVisible == pT2->VVisible) &&
( pT1->VBorder == pT2->VBorder) &&
( pT1->VFrontPorch == pT2->VFrontPorch) &&
( pT1->VSyncWidth == pT2->VSyncWidth) &&
( pT1->VSyncPol == pT2->VSyncPol) &&
( pT1->VTotal == pT2->VTotal) &&
( pT1->etc.rr == pT2->etc.rr) &&
(!!pT1->interlaced == !!pT2->interlaced));
}
CODE_SEGMENT(NONPAGE_DD_CODE)
NvU32 NvTiming_IsTimingExactEqualEx(const NVT_TIMING *pT1, const NVT_TIMING *pT2)
{
NvU32 bIsTimingExactEqual = NvTiming_IsTimingExactEqual(pT1, pT2);
return (bIsTimingExactEqual && (pT1->etc.rrx1k == pT2->etc.rrx1k));
}
CODE_SEGMENT(NONPAGE_DD_CODE)
NvU32 NvTiming_IsTimingRelaxedEqual(const NVT_TIMING *pT1, const NVT_TIMING *pT2)
{
if ((pT1 == NULL) || (pT2 == NULL))
{
return 0;
}
return (( pT1->HVisible == pT2->HVisible) &&
( pT1->HBorder == pT2->HBorder) &&
( pT1->HFrontPorch == pT2->HFrontPorch) &&
( pT1->HSyncWidth == pT2->HSyncWidth) &&
//( pT1->HSyncPol == pT2->HSyncPol) && // skip the polarity check to tolerate mismatch h/v sync polarities in 18-byte DTD
( pT1->HTotal == pT2->HTotal) &&
( pT1->VVisible == pT2->VVisible) &&
( pT1->VBorder == pT2->VBorder) &&
( pT1->VFrontPorch == pT2->VFrontPorch) &&
( pT1->VSyncWidth == pT2->VSyncWidth) &&
//( pT1->VSyncPol == pT2->VSyncPol) && // skip the polarity check to tolerate mismatch h/v sync polarities in 18-byte DTD
( pT1->VTotal == pT2->VTotal) &&
( pT1->etc.rr == pT2->etc.rr) &&
(!!pT1->interlaced == !!pT2->interlaced));
}
CODE_SEGMENT(NONPAGE_DD_CODE)
NvU32 RRx1kToPclk (NVT_TIMING *pT)
{
return axb_div_c(pT->HTotal * (pT->VTotal + ((pT->interlaced != 0) ? (pT->VTotal + 1) : 0)),
pT->etc.rrx1k,
1000 * ((pT->interlaced != 0) ? 20000 : 10000));
}
CODE_SEGMENT(PAGE_DD_CODE)
NvU16 NvTiming_MaxFrameWidth(NvU16 HVisible, NvU16 repMask)
{
NvU16 minPixelRepeat;
if (repMask == 0)
{
return HVisible;
}
minPixelRepeat = 1;
while ((repMask & 1) == 0)
{
repMask >>= 1;
minPixelRepeat++;
}
return (HVisible / minPixelRepeat);
}
POP_SEGMENTS

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,142 @@
//*****************************************************************************
//
// SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: MIT
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File: nvtiming_pvt.h
//
// Purpose: the private functions/structures which are only used inside
// the nv timing library.
//
//*****************************************************************************
#ifndef __NVTIMING_PVT_H_
#define __NVTIMING_PVT_H_
#include "nvtiming.h"
#if defined(NVT_USE_NVKMS)
#include "nvidia-modeset-os-interface.h"
#define NVT_SNPRINTF nvkms_snprintf
#else
#include <string.h>
#include <stdio.h>
#define NVT_SNPRINTF snprintf
#endif
#define nvt_assert(p) ((void)0)
#include <stddef.h> // NULL
// EDID related private functions
NvU32 getEdidVersion(NvU8 *pData, NvU32 *pVer);
NvBool assignNextAvailableTiming(NVT_EDID_INFO *pInfo, const NVT_TIMING *pTiming);
void parseEdidCvtTiming(NVT_EDID_INFO *pInfo);
void parseEdidEstablishedTiming(NVT_EDID_INFO *pInfo);
void parseEdidStandardTiming(NVT_EDID_INFO *pInfo);
void parseEdidDetailedTiming(NvU8 *pEdid, NVT_EDID_INFO *pInfo);
NVT_STATUS parseEdidDetailedTimingDescriptor(NvU8 *pDTD, NVT_TIMING *pT);
void parseEdidCvt3ByteDescriptor(NvU8 *p, NVT_EDID_INFO *pInfo, NvU32 *vtbCount);
void parseEdidStandardTimingDescriptor(NvU16 timing, NVT_EDID_INFO *pInfo, NvU32 count, NVT_TIMING * pT);
void parseVTBExtension(NvU8 *pEdidExt, NVT_EDID_INFO *pInfo);
void updateHDMILLCDeepColorForTiming(NVT_EDID_INFO *pInfo, NvU32 index);
void updateBpcForTiming(NVT_EDID_INFO *pInfo, NvU32 index);
void updateColorFormatAndBpcTiming(NVT_EDID_INFO *pInfo);
// End EDID
// CTA861 related private functions
NVT_STATUS get861ExtInfo(NvU8 *pEdid, NvU32 edidSize, NVT_EDID_CEA861_INFO *p);
NVT_STATUS parseCta861DataBlockInfo(NvU8 *pEdid, NvU32 size, NVT_EDID_CEA861_INFO *p);
void parse861ExtDetailedTiming(NvU8 *pEdidExt, NvU8 basicCaps, NVT_EDID_INFO *pInfo);
void parse861bShortTiming(NVT_EDID_CEA861_INFO *pExt861, void *pRawInfo, NVT_CTA861_ORIGIN flag);
void parse861bShortYuv420Timing(NVT_EDID_CEA861_INFO *pExt861, void *pRawInfo, NVT_CTA861_ORIGIN flag);
void parse861bShortPreferredTiming(NVT_EDID_CEA861_INFO *pExt861, void *pRawInfo, NVT_CTA861_ORIGIN flag);
void parseCta861VsdbBlocks(NVT_EDID_CEA861_INFO *pExt861, void *pRawInfo, NVT_CTA861_ORIGIN flag);
void parseCta861HfScdb(NVT_EDID_CEA861_INFO *pExt861, void *pRawInfo, NVT_CTA861_ORIGIN flag);
void parseCta861HfEeodb(NVT_EDID_CEA861_INFO *pExt861, NvU32 *pTotalEdidExtensions);
void parseEdidMsftVsdbBlock(VSDB_DATA *pVsdb, MSFT_VSDB_PARSED_INFO *vsdbInfo);
void parseEdidHdmiLlcBasicInfo(VSDB_DATA *pVsdb, NVT_HDMI_LLC_INFO *pHdmiLlc);
void parseEdidHdmiForumVSDB(VSDB_DATA *pVsdb, NVT_HDMI_FORUM_INFO *pHdmiInfo);
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);
NvBool isMatchedCTA861Timing(NVT_EDID_INFO *pInfo, NVT_TIMING *pT);
NvU32 isHdmi3DStereoType(NvU8 StereoStructureType);
NvU32 getCEA861TimingAspectRatio(NvU32 vic);
void SetActiveSpaceForHDMI3DStereo(const NVT_TIMING *pTiming, NVT_EXT_TIMING *pExtTiming);
void AddModeToSupportMap(HDMI3DSUPPORTMAP * pMap, NvU8 vic, NvU8 structure, NvU8 Detail);
void getMonitorDescriptorString(NvU8 *pEdid, NvU8 tag, char *str, int onceOnly);
// End CTA861
// DispalyID base / extension related functions
NvU32 getDID2Version(NvU8 *pData, NvU32 *pVer);
NVT_STATUS getDisplayIdEDIDExtInfo(NvU8* pEdid, NvU32 edidSize, NVT_EDID_INFO* pEdidInfo);
NVT_STATUS getDisplayId20EDIDExtInfo(NvU8* pDisplayid, NvU32 edidSize, 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);
void updateColorFormatForDisplayId20Timings(NVT_DISPLAYID_2_0_INFO* pDisplayId2Info, NvU32 timingIdx);
// End DisplayID
NvU32 axb_div_c_old(NvU32 a, NvU32 b, NvU32 c);
#define NVT_EDID_BLOCK_SIZE 128
#define NVT_PVT_INTERLACED_MASK 0xF
#define NVT_PVT_DOUBLESCAN_MASK 0x10
#define NVT_PVT_RB_MASK 0x20
#define NVT_PVT_DOUBLE_SCAN_HEIGHT 384
#define NVT_PVT_DOUBLE_SCAN_HEIGHT_VGA 600
#define NVT_PVT_DOUBLE_SCAN_PCLK_MIN 1200 //in 10KHz
#define abs(a) ((a)>0?(a):-(a))
#define set_rrx1k(a,b,c) ((b)*(c)==0?(0):(NvU32)(((NvU64)(a)*10000*1000+(b)*(c)/2)/((b)*(c))))
#define frame_height(a) ((NvU32)((a).VVisible * ((a).interlaced!=0?2:1)))
#define nvt_is_wideaspect(width,height) ((width)*5 >= (height)*8)
#ifndef MIN
#define MIN(x, y) ((x)>(y) ? (y) : (x))
#endif
#ifndef MAX
#define MAX(x,y) ((x) > (y) ? (x) : (y))
#endif
#ifndef COUNT
#define COUNT(a) (sizeof(a)/sizeof(a[0]))
#endif
#ifndef offsetof
#define offsetof(st, m) ((size_t) ( (char *)&((st *)(0))->m - (char *)0 ))
#endif
#define nvt_nvu8_set_bits(d, s, m, shift) {(d)&=(NvU8)((NvU8)(m)^0xFFU);(d)|=((s)<<(shift))&(m);}
#define nvt_get_bits(d, m, shift) (((d)&(m))>>shift)
#define nvt_lowest_bit(n) ((n)&(~((n)-1)))
#define nvt_aspect_x(n) ((n)>>16)
#define nvt_aspect_y(n) ((n)&0xFFFF)
// Sentinel values for NVT_TIMING
#define NVT_TIMINGEXT_SENTINEL {0,0,0,0,0,{0},{0},{0},{0},0,""}
#define NVT_TIMING_SENTINEL {0,0,0,0,0,0,0,0,0,0,0,0,0,0,NVT_TIMINGEXT_SENTINEL}
#endif //__NVTIMING_PVT_H_