mirror of
https://github.com/NVIDIA/open-gpu-kernel-modules.git
synced 2026-02-04 23:29:58 +00:00
570.86.15
This commit is contained in:
@@ -48,6 +48,12 @@
|
||||
#include "class/clc670.h"
|
||||
#include "class/clc67d.h"
|
||||
#include "class/clc770.h"
|
||||
#include "class/clc870.h"
|
||||
#include "class/clc87d.h"
|
||||
#include "class/clc970.h"
|
||||
#include "class/clc97d.h"
|
||||
#include "class/clca70.h"
|
||||
#include "class/clca7d.h"
|
||||
|
||||
#include "hdmi_spec.h"
|
||||
|
||||
@@ -181,6 +187,36 @@ static const NVHDMIPKT_CLASS_HIERARCHY hierarchy[] =
|
||||
NVC770_DISPLAY, // displayClass
|
||||
NVC67D_CORE_CHANNEL_DMA // coreDmaClass
|
||||
},
|
||||
[NVHDMIPKT_C871_CLASS] = {// Index 9==NVHDMIPKT_C871_CLASS
|
||||
NVHDMIPKT_C871_CLASS, // classId
|
||||
NVHDMIPKT_C671_CLASS, // parentClassId
|
||||
NV_FALSE, // isRootClass
|
||||
initializeHdmiPktInterfaceC871, // initInterface
|
||||
hdmiConstructorC871, // constructor
|
||||
hdmiDestructorC871, // destructor
|
||||
NVC870_DISPLAY, // displayClass
|
||||
NVC87D_CORE_CHANNEL_DMA // coreDmaClass
|
||||
},
|
||||
[NVHDMIPKT_C971_CLASS] = {// Index 10==NVHDMIPKT_C971_CLASS
|
||||
NVHDMIPKT_C971_CLASS, // classId
|
||||
NVHDMIPKT_C871_CLASS, // parentClassId
|
||||
NV_FALSE, // isRootClass
|
||||
initializeHdmiPktInterfaceC971, // initInterface
|
||||
hdmiConstructorC971, // constructor
|
||||
hdmiDestructorC971, // destructor
|
||||
NVC970_DISPLAY, // displayClass
|
||||
NVC97D_CORE_CHANNEL_DMA // coreDmaClass
|
||||
},
|
||||
[NVHDMIPKT_CA71_CLASS] = {// Index 11==NVHDMIPKT_CA71_CLASS
|
||||
NVHDMIPKT_CA71_CLASS, // classId
|
||||
NVHDMIPKT_C971_CLASS, // parentClassId
|
||||
NV_FALSE, // isRootClass
|
||||
initializeHdmiPktInterfaceCA71, // initInterface
|
||||
hdmiConstructorCA71, // constructor
|
||||
hdmiDestructorCA71, // destructor
|
||||
NVCA70_DISPLAY, // displayClass
|
||||
NVCA7D_CORE_CHANNEL_DMA // coreDmaClass
|
||||
},
|
||||
};
|
||||
|
||||
/********************************** HDMI Library interfaces *************************************/
|
||||
@@ -262,6 +298,61 @@ NvHdmiPkt_PacketWrite(NvHdmiPkt_Handle libHandle,
|
||||
pPacket);
|
||||
}
|
||||
|
||||
/*
|
||||
* NvHdmiPkt_PacketRead
|
||||
*/
|
||||
NVHDMIPKT_RESULT
|
||||
NvHdmiPkt_PacketRead(NvHdmiPkt_Handle libHandle,
|
||||
NvU32 subDevice,
|
||||
NvU32 head,
|
||||
NVHDMIPKT_TYPE packetReg,
|
||||
NvU32 bufferLen,
|
||||
NvU8 *const pOutPktBuffer)
|
||||
{
|
||||
if (libHandle == NVHDMIPKT_INVALID_HANDLE)
|
||||
{
|
||||
return NVHDMIPKT_LIBRARY_INIT_FAIL;
|
||||
}
|
||||
|
||||
NVHDMIPKT_CLASS* pClass = fromHdmiPktHandle(libHandle);
|
||||
|
||||
if ((pOutPktBuffer == NULL) || (bufferLen == 0))
|
||||
{
|
||||
return NVHDMIPKT_INVALID_ARG;
|
||||
}
|
||||
|
||||
return pClass->hdmiPacketRead(pClass,
|
||||
subDevice,
|
||||
head,
|
||||
packetReg,
|
||||
bufferLen,
|
||||
pOutPktBuffer);
|
||||
}
|
||||
|
||||
/*
|
||||
* NvHdmiPkt_SetupAdvancedInfoframe
|
||||
*/
|
||||
NVHDMIPKT_RESULT
|
||||
NvHdmiPkt_SetupAdvancedInfoframe(NvHdmiPkt_Handle libHandle,
|
||||
NvU32 subDevice,
|
||||
NvU32 head,
|
||||
NVHDMIPKT_TYPE packetReg,
|
||||
ADVANCED_INFOFRAME const *pInfoframe)
|
||||
{
|
||||
if (libHandle == NVHDMIPKT_INVALID_HANDLE)
|
||||
{
|
||||
return NVHDMIPKT_LIBRARY_INIT_FAIL;
|
||||
}
|
||||
|
||||
NVHDMIPKT_CLASS* pClass = fromHdmiPktHandle(libHandle);
|
||||
|
||||
return pClass->programAdvancedInfoframe(pClass,
|
||||
subDevice,
|
||||
head,
|
||||
packetReg,
|
||||
pInfoframe);
|
||||
}
|
||||
|
||||
NVHDMIPKT_RESULT
|
||||
NvHdmi_AssessLinkCapabilities(NvHdmiPkt_Handle libHandle,
|
||||
NvU32 subDevice,
|
||||
|
||||
@@ -57,6 +57,8 @@ typedef enum
|
||||
NVHDMIPKT_ERR_GENERAL = 5,
|
||||
NVHDMIPKT_INSUFFICIENT_BANDWIDTH = 6,
|
||||
NVHDMIPKT_RETRY = 7,
|
||||
NVHDMIPKT_INSUFFICIENT_BUFFER = 8,
|
||||
NVHDMIPKT_DSC_PPS_ERROR = 9
|
||||
} NVHDMIPKT_RESULT;
|
||||
|
||||
// NVHDMIPKT_TYPE: HDMI Packet Enums
|
||||
@@ -75,7 +77,11 @@ typedef enum _NVHDMIPKT_TYPE
|
||||
NVHDMIPKT_TYPE_SHARED_GENERIC4 = 9,
|
||||
NVHDMIPKT_TYPE_SHARED_GENERIC5 = 10,
|
||||
NVHDMIPKT_TYPE_SHARED_GENERIC6 = 11,
|
||||
NVHDMIPKT_INVALID_PKT_TYPE = 12
|
||||
NVHDMIPKT_TYPE_SHARED_GENERIC7 = 12,
|
||||
NVHDMIPKT_TYPE_SHARED_GENERIC8 = 13,
|
||||
NVHDMIPKT_TYPE_SHARED_GENERIC9 = 14,
|
||||
NVHDMIPKT_TYPE_SHARED_GENERIC10 = 15,
|
||||
NVHDMIPKT_INVALID_PKT_TYPE = 16
|
||||
} NVHDMIPKT_TYPE;
|
||||
|
||||
// Hdmi packet TransmitControl defines. These definitions reflect the
|
||||
@@ -173,6 +179,23 @@ typedef enum _NVHDMIPKT_TC
|
||||
DRF_DEF(_HDMI_PKT, _TRANSMIT_CTRL, _LOC, _VBLANK)),
|
||||
} NVHDMIPKT_TC;
|
||||
|
||||
typedef enum _INFOFRAME_CTRL_RUN_MODE
|
||||
{
|
||||
INFOFRAME_CTRL_RUN_MODE_ALWAYS = 0,
|
||||
INFOFRAME_CTRL_RUN_MODE_ONCE,
|
||||
INFOFRAME_CTRL_RUN_MODE_FID_ALWAYS,
|
||||
INFOFRAME_CTRL_RUN_MODE_FID_ONCE,
|
||||
INFOFRAME_CTRL_RUN_MODE_FID_TRIGGER
|
||||
} INFOFRAME_CTRL_RUN_MODE;
|
||||
|
||||
typedef enum _INFOFRAME_CTRL_LOC
|
||||
{
|
||||
INFOFRAME_CTRL_LOC_VBLANK = 0,
|
||||
INFOFRAME_CTRL_LOC_VSYNC,
|
||||
INFOFRAME_CTRL_LOC_LINE,
|
||||
INFOFRAME_CTRL_LOC_LOADV
|
||||
} INFOFRAME_CTRL_LOC;
|
||||
|
||||
// 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
|
||||
@@ -260,6 +283,39 @@ typedef struct _tagNVHDMIPKT_CALLBACK
|
||||
} NVHDMIPKT_CALLBACK;
|
||||
|
||||
|
||||
/************************************************************************************************
|
||||
* runMode - specify one of the modes of operation*
|
||||
* location - vsync/line/vblank *
|
||||
* flipId - client to provide if FID mode of operation, 0 otherwise *
|
||||
* lineNum - if infoframe is sent at line border specify lineNum. 0 is default *
|
||||
* *
|
||||
* T239 chip more infoframe support *
|
||||
************************************************************************************************/
|
||||
typedef struct tagADVANCED_INFOFRAME
|
||||
{
|
||||
INFOFRAME_CTRL_RUN_MODE runMode;
|
||||
INFOFRAME_CTRL_LOC location;
|
||||
|
||||
NvU32 flipId;
|
||||
NvU32 lineNum;
|
||||
NvU32 numAdditionalInfoframes;
|
||||
|
||||
NvU32 packetLen; // client is expected to fill in 9 DWs for each infoframe, leaving unused bytes 0
|
||||
NvU8 const * pPacket; // (4 bytes header, 32 bytes max payload per infoframe) For SIZE > 0, pPacket is
|
||||
// continuous array of multiple infoframes each 9DW in size
|
||||
|
||||
// flags
|
||||
NvU32 isLargeInfoframe : 1; // set if client wants SIZE > 0. Default 0 = normal infoframe
|
||||
NvU32 lineIdReversed : 1; // set if client wants line Id reversed. Default 0 = not reversed
|
||||
NvU32 crcOverride : 1; // set if client uses CRC override. Default 0 = CRC override not used
|
||||
NvU32 asSdpOverride : 1; // set if client wants to enable AS SDP override in infoframe HW
|
||||
NvU32 hwChecksum : 1; // set if client wants HW checksum. Default 0 = SW checksum
|
||||
NvU32 matchFidMethodArmState : 1; // set if client wants HW to send infoframe when FID method's ARM state matches. Default 0 = send only when FID method Active state
|
||||
NvU32 winMethodCyaBroadcast : 1; // set if client will set up CYA reg for SF to decode directly. Default 0 = private precalc decode (SF decodes from precalc)
|
||||
NvU32 highAudioPriority : 1; // set if client wants high priority for audio. Default 0 = audio low priority
|
||||
NvU32 reserved : 24;
|
||||
} ADVANCED_INFOFRAME;
|
||||
|
||||
/*********************** HDMI Library interface to write hdmi ctrl/packet ***********************/
|
||||
typedef void* NvHdmiPkt_Handle;
|
||||
#define NVHDMIPKT_INVALID_HANDLE ((NvHdmiPkt_Handle)0)
|
||||
@@ -307,6 +363,44 @@ NvHdmiPkt_PacketWrite(NvHdmiPkt_Handle libHandle,
|
||||
NvU8 const *const pPacket);
|
||||
|
||||
|
||||
/************************************************************************************************
|
||||
* NvHdmiPkt_PacketRead - Returns HDMI NVHDMIPKT_RESULT. *
|
||||
* *
|
||||
* Parameters: *
|
||||
* libHandle - Hdmi library handle, provided on initializing the library. *
|
||||
* subDevice - Sub Device ID. *
|
||||
* head - Head number. *
|
||||
* packetReg - One of the NVHDMIPKT_TYPE types. *
|
||||
* bufferLen - Size of the client provided read out buffer *
|
||||
* pOutPktBuffer - buffer into which read packet data is to be written. *
|
||||
************************************************************************************************/
|
||||
NVHDMIPKT_RESULT
|
||||
NvHdmiPkt_PacketRead(NvHdmiPkt_Handle libHandle,
|
||||
NvU32 subDevice,
|
||||
NvU32 head,
|
||||
NVHDMIPKT_TYPE packetReg,
|
||||
NvU32 bufferLen,
|
||||
NvU8 *const pOutPktBuffer);
|
||||
|
||||
|
||||
/************************************************************************************************
|
||||
* NvHdmiPkt_SetupAdvancedInfoframe - Returns HDMI NVHDMIPKT_RESULT. *
|
||||
* *
|
||||
* Parameters: *
|
||||
* libHandle - Hdmi library handle, provided on initializing the library. *
|
||||
* subDevice - Sub Device ID. *
|
||||
* head - Head number. *
|
||||
* packetType - One of the NVHDMIPKT_TYPE types. *
|
||||
* pInfoframe - details about infoframe to be programmed - run mode/loc/etc and pkt bytes *
|
||||
************************************************************************************************/
|
||||
NVHDMIPKT_RESULT
|
||||
NvHdmiPkt_SetupAdvancedInfoframe(NvHdmiPkt_Handle libHandle,
|
||||
NvU32 subDevice,
|
||||
NvU32 head,
|
||||
NVHDMIPKT_TYPE packetReg,
|
||||
ADVANCED_INFOFRAME const *pInfoframe);
|
||||
|
||||
|
||||
/***************************** Interface to initialize HDMI Library *****************************/
|
||||
|
||||
/************************************************************************************************
|
||||
|
||||
@@ -359,6 +359,33 @@ hdmiClearFRLConfigDummy(NVHDMIPKT_CLASS *pThis,
|
||||
return NVHDMIPKT_SUCCESS;
|
||||
}
|
||||
|
||||
NVHDMIPKT_RESULT
|
||||
hdmiPacketReadDummy(NVHDMIPKT_CLASS* pThis,
|
||||
NvU32 subDevice,
|
||||
NvU32 head,
|
||||
NVHDMIPKT_TYPE packetReg,
|
||||
NvU32 bufferLen,
|
||||
NvU8 *const pOutPktBuffer)
|
||||
{
|
||||
NvHdmiPkt_Print(pThis, "ERROR - Dummy function hdmiPacketReadDummy called. "
|
||||
"Should never be called.");
|
||||
NvHdmiPkt_Assert(0);
|
||||
return NVHDMIPKT_SUCCESS;
|
||||
}
|
||||
|
||||
NVHDMIPKT_RESULT
|
||||
programAdvancedInfoframeDummy(NVHDMIPKT_CLASS* pThis,
|
||||
NvU32 subDevice,
|
||||
NvU32 head,
|
||||
NVHDMIPKT_TYPE packetReg,
|
||||
const ADVANCED_INFOFRAME* pInfoframe)
|
||||
{
|
||||
NvHdmiPkt_Print(pThis, "ERROR - Dummy function programAdvancedInfoframeDummy called. "
|
||||
"Should never be called.");
|
||||
NvHdmiPkt_Assert(0);
|
||||
return NVHDMIPKT_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* initializeHdmiPktInterface0073
|
||||
*/
|
||||
@@ -389,4 +416,7 @@ initializeHdmiPktInterface0073(NVHDMIPKT_CLASS* pClass)
|
||||
pClass->hdmiSetFRLConfig = hdmiSetFRLConfigDummy;
|
||||
pClass->hdmiClearFRLConfig = hdmiClearFRLConfigDummy;
|
||||
|
||||
// More (generic) infoframe support on T239+
|
||||
pClass->hdmiPacketRead = hdmiPacketReadDummy;
|
||||
pClass->programAdvancedInfoframe = programAdvancedInfoframeDummy;
|
||||
}
|
||||
|
||||
@@ -828,4 +828,7 @@ initializeHdmiPktInterface9171(NVHDMIPKT_CLASS* pClass)
|
||||
pClass->hdmiSetFRLConfig = hdmiSetFRLConfigDummy;
|
||||
pClass->hdmiClearFRLConfig = hdmiClearFRLConfigDummy;
|
||||
|
||||
// T239+
|
||||
pClass->hdmiPacketRead = hdmiPacketReadDummy;
|
||||
pClass->programAdvancedInfoframe = programAdvancedInfoframeDummy;
|
||||
}
|
||||
|
||||
@@ -360,7 +360,12 @@ static void populateDscCaps(HDMI_SRC_CAPS const * const pSrcCaps,
|
||||
pDscInfo->sinkCaps.algorithmRevision.versionMajor = 1;
|
||||
pDscInfo->sinkCaps.algorithmRevision.versionMinor = 2;
|
||||
pDscInfo->sinkCaps.peakThroughputMode0 = peakThroughput;
|
||||
pDscInfo->sinkCaps.peakThroughputMode1 = peakThroughput * 2;
|
||||
|
||||
// Per DSC v1.2 spec, native 422/420 per-slice peak throughput is approximately twice of RGB/444 peak throughput
|
||||
// HDMI has only one throughput cap reporting, no separate 422/420 throughput cap unlike for DP, so just double 444's value here.
|
||||
pDscInfo->sinkCaps.peakThroughputMode1 = (peakThroughput == DSC_DECODER_PEAK_THROUGHPUT_MODE0_340) ?
|
||||
DSC_DECODER_PEAK_THROUGHPUT_MODE1_650 : // closest approximation to 680Mhz
|
||||
DSC_DECODER_PEAK_THROUGHPUT_MODE1_800;
|
||||
}
|
||||
|
||||
// Fill in mode related info for DSC lib
|
||||
@@ -790,7 +795,7 @@ hdmiQueryFRLConfigC671(NVHDMIPKT_CLASS *pThis,
|
||||
(pClientCtrl->forceBppx16 && ((pClientCtrl->bitsPerPixelX16 < bppMinX16) || (pClientCtrl->bitsPerPixelX16 > bppMaxX16))) ||
|
||||
(pClientCtrl->forceBppx16 && !pSinkCaps->pHdmiForumInfo->dsc_All_bpp))
|
||||
{
|
||||
return NVHDMIPKT_FAIL;
|
||||
return NVHDMIPKT_INVALID_ARG;
|
||||
}
|
||||
|
||||
bTryUncompressedMode = (bCanUseDSC && (pClientCtrl->enableDSC ||
|
||||
@@ -1185,8 +1190,9 @@ frlQuery_Success:
|
||||
{
|
||||
NvHdmiPkt_Print(pThis, "ERROR - DSC PPS calculation failed.");
|
||||
NvHdmiPkt_Assert(0);
|
||||
result = NVHDMIPKT_FAIL;
|
||||
result = NVHDMIPKT_DSC_PPS_ERROR;
|
||||
}
|
||||
|
||||
if (pDscScratchBuffer != NULL)
|
||||
{
|
||||
pThis->callback.free(pThis->cbHandle, pDscScratchBuffer);
|
||||
|
||||
641
src/common/modeset/hdmipacket/nvhdmipkt_C871.c
Normal file
641
src/common/modeset/hdmipacket/nvhdmipkt_C871.c
Normal file
@@ -0,0 +1,641 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2023 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_C871.c
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nvhdmipkt_common.h"
|
||||
/*
|
||||
* Purpose: Provides packet write functions for HDMI library for T23+ chips
|
||||
*/
|
||||
#include "nvhdmipkt_class.h"
|
||||
#include "nvhdmipkt_internal.h"
|
||||
#include "hdmi_spec.h"
|
||||
#include "class/clc871.h"
|
||||
#include "ctrl/ctrl0073/ctrl0073specific.h"
|
||||
|
||||
#define NVHDMIPKT_C871_MAX_PKT_BYTES_AVI 21 // 3 bytes header + 18 bytes payload
|
||||
|
||||
extern void hdmiWriteAviPacket9171(NVHDMIPKT_CLASS* pThis,
|
||||
NvU32* pBaseReg,
|
||||
NvU32 head,
|
||||
NvU32 packetLen,
|
||||
NvU8 const *const pPacket);
|
||||
|
||||
/*
|
||||
* translatePacketTypeC871
|
||||
*/
|
||||
static NvU32
|
||||
translatePacketTypeC871(NVHDMIPKT_CLASS* pThis,
|
||||
NVHDMIPKT_TYPE packetType)
|
||||
{
|
||||
NvU32 typeC871 = NVHDMIPKT_INVALID_PKT_TYPE; // initialize to an invalid type enum
|
||||
|
||||
switch (packetType)
|
||||
{
|
||||
case NVHDMIPKT_TYPE_AVI_INFOFRAME:
|
||||
typeC871 = NVC871_SF_HDMI_INFO_IDX_AVI_INFOFRAME;
|
||||
break;
|
||||
case NVHDMIPKT_TYPE_GENERAL_CONTROL:
|
||||
typeC871 = NVC871_SF_HDMI_INFO_IDX_GCP;
|
||||
break;
|
||||
case NVHDMIPKT_TYPE_AUDIO_INFOFRAME:
|
||||
default:
|
||||
NvHdmiPkt_Print(pThis, "ERROR - translatePacketType wrong packet type for class C871: %0x.",
|
||||
packetType);
|
||||
NvHdmiPkt_Assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
return typeC871;
|
||||
}
|
||||
|
||||
/*
|
||||
* hdmiWriteAviPacketC871
|
||||
*/
|
||||
static void
|
||||
hdmiWriteAviPacketC871(NVHDMIPKT_CLASS* pThis,
|
||||
NvU32* pBaseReg,
|
||||
NvU32 head,
|
||||
NvU32 packetLen,
|
||||
NvU8 const *const pPacket)
|
||||
{
|
||||
NvU32 data = 0;
|
||||
|
||||
if (packetLen > NVHDMIPKT_C871_MAX_PKT_BYTES_AVI)
|
||||
{
|
||||
NvHdmiPkt_Print(pThis, "ERROR - input AVI packet length incorrect. Write will be capped to max allowable bytes");
|
||||
NvHdmiPkt_Assert(0);
|
||||
}
|
||||
|
||||
data = REG_RD32(pBaseReg, NVC871_SF_HDMI_AVI_INFOFRAME_SUBPACK2_LOW(head));
|
||||
data = FLD_SET_DRF_NUM(C871, _SF_HDMI_AVI_INFOFRAME_SUBPACK2_LOW, _PB14, pPacket[17], data);
|
||||
data = FLD_SET_DRF_NUM(C871, _SF_HDMI_AVI_INFOFRAME_SUBPACK2_LOW, _PB15, pPacket[18], data);
|
||||
data = FLD_SET_DRF_NUM(C871, _SF_HDMI_AVI_INFOFRAME_SUBPACK2_LOW, _PB16, pPacket[19], data);
|
||||
data = FLD_SET_DRF_NUM(C871, _SF_HDMI_AVI_INFOFRAME_SUBPACK2_LOW, _PB17, pPacket[20], data);
|
||||
REG_WR32(pBaseReg, NVC871_SF_HDMI_AVI_INFOFRAME_SUBPACK2_LOW(head), data);
|
||||
|
||||
// the lower 17 bytes remain the same as in 9171 class, call 9171 packet write function to program them
|
||||
hdmiWriteAviPacket9171(pThis,
|
||||
pBaseReg,
|
||||
head,
|
||||
17, // HB0-2 and PB0-14
|
||||
pPacket);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* hdmiWriteGeneralCtrlPacketC871
|
||||
*/
|
||||
static void
|
||||
hdmiWriteGeneralCtrlPacketC871(NVHDMIPKT_CLASS* pThis,
|
||||
NvU32* pBaseReg,
|
||||
NvU32 head,
|
||||
NvU32 packetLen,
|
||||
NvU8 const *const pPacket)
|
||||
{
|
||||
NvU32 data = 0;
|
||||
|
||||
// orIndexer info is ignored.
|
||||
data = REG_RD32(pBaseReg, NVC871_SF_HDMI_GCP_SUBPACK(head));
|
||||
data = FLD_SET_DRF_NUM(C871, _SF_HDMI_GCP_SUBPACK, _SB0, pPacket[3], data);
|
||||
data = FLD_SET_DRF_NUM(C871, _SF_HDMI_GCP_SUBPACK, _SB1, pPacket[4], data);
|
||||
data = FLD_SET_DRF_NUM(C871, _SF_HDMI_GCP_SUBPACK, _SB2, pPacket[5], data);
|
||||
REG_WR32(pBaseReg, NVC871_SF_HDMI_GCP_SUBPACK(head), data);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* hdmiPacketWriteC871
|
||||
*/
|
||||
static NVHDMIPKT_RESULT
|
||||
hdmiPacketWriteC871(NVHDMIPKT_CLASS* pThis,
|
||||
NvU32 subDevice,
|
||||
NvU32 displayId,
|
||||
NvU32 head,
|
||||
NVHDMIPKT_TYPE packetType,
|
||||
NVHDMIPKT_TC transmitControl,
|
||||
NvU32 packetLen,
|
||||
NvU8 const *const pPacketIn)
|
||||
{
|
||||
NVHDMIPKT_RESULT result = NVHDMIPKT_SUCCESS;
|
||||
NvU32* pBaseReg = (NvU32*)pThis->memMap[subDevice].pMemBase;
|
||||
NvU32 pktTypeC871 = pThis->translatePacketType(pThis, packetType);
|
||||
NvU32 tc = pThis->translateTransmitControl(pThis, transmitControl);
|
||||
NV0073_CTRL_SPECIFIC_CTRL_HDMI_PARAMS params = {0};
|
||||
|
||||
// packetIn can be of varying size. Use a fixed max size buffer for programing hw units to prevent out of bounds access
|
||||
NvU8 pPacket[NVHDMIPKT_CTAIF_MAX_PKT_BYTES] = {0};
|
||||
|
||||
if (pBaseReg == 0 || head >= NVC871_SF_HDMI_AVI_INFOFRAME_CTRL__SIZE_1 ||
|
||||
packetLen == 0 || pPacketIn == 0 || pktTypeC871 == NVHDMIPKT_INVALID_PKT_TYPE)
|
||||
{
|
||||
result = NVHDMIPKT_INVALID_ARG;
|
||||
NvHdmiPkt_Print(pThis, "Invalid arg");
|
||||
goto hdmiPacketWriteC871_exit;
|
||||
}
|
||||
|
||||
if (packetLen > NVHDMIPKT_CTAIF_MAX_PKT_BYTES)
|
||||
{
|
||||
NvHdmiPkt_Print(pThis, "ERROR - input packet length incorrect %d Packet write will be capped to max allowable bytes", packetLen);
|
||||
packetLen = NVHDMIPKT_CTAIF_MAX_PKT_BYTES;
|
||||
NvHdmiPkt_Assert(0);
|
||||
}
|
||||
|
||||
// input packet looks ok to use, copy over the bytes
|
||||
NVMISC_MEMCPY(pPacket, pPacketIn, packetLen);
|
||||
|
||||
// acquire mutex
|
||||
pThis->callback.acquireMutex(pThis->cbHandle);
|
||||
|
||||
// Disable this packet type.
|
||||
pThis->hdmiWritePacketCtrl(pThis, pBaseReg, head, pktTypeC871, tc, NV_TRUE);
|
||||
|
||||
// write the packet
|
||||
switch (pktTypeC871)
|
||||
{
|
||||
case NVC871_SF_HDMI_INFO_IDX_AVI_INFOFRAME:
|
||||
pThis->hdmiWriteAviPacket(pThis, pBaseReg, head, packetLen, pPacket);
|
||||
break;
|
||||
|
||||
case NVC871_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(¶ms, 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,
|
||||
¶ms,
|
||||
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,
|
||||
¶ms,
|
||||
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;
|
||||
|
||||
default:
|
||||
result = NVHDMIPKT_INVALID_ARG;
|
||||
break;
|
||||
}
|
||||
|
||||
// Enable this infoframe.
|
||||
pThis->hdmiWritePacketCtrl(pThis, pBaseReg, head, pktTypeC871, tc, NV_FALSE);
|
||||
|
||||
// release mutex
|
||||
pThis->callback.releaseMutex(pThis->cbHandle);
|
||||
hdmiPacketWriteC871_exit:
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
NvBool
|
||||
isInfoframeOffsetAvailable(NvU32* pBaseReg,
|
||||
NvU32 head,
|
||||
NvU32 requestedInfoframe)
|
||||
{
|
||||
NvU32 regAddr, regData = 0;
|
||||
NvU32 ifIndex, size;
|
||||
NvBool bResult = NV_TRUE;
|
||||
|
||||
for (ifIndex = 0; ifIndex < NVC871_SF_GENERIC_INFOFRAME_CTRL__SIZE_2; ifIndex++)
|
||||
{
|
||||
regAddr = NVC871_SF_GENERIC_INFOFRAME_CTRL(head, ifIndex);
|
||||
regData = REG_RD32(pBaseReg, regAddr);
|
||||
size = DRF_VAL(C871, _SF_GENERIC_INFOFRAME_CTRL, _SIZE, regData);
|
||||
|
||||
// if an infoframe is enabled and it's occupying the offset the requested infoframe would use,
|
||||
// we cannot allow programming this requested infoframe
|
||||
if (FLD_TEST_DRF(C871, _SF_GENERIC_INFOFRAME_CTRL, _ENABLE, _YES, regData) && (size > 0))
|
||||
{
|
||||
if ((ifIndex + size) > requestedInfoframe)
|
||||
{
|
||||
bResult = NV_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
/*
|
||||
* disableInfoframeC871
|
||||
*/
|
||||
|
||||
NVHDMIPKT_RESULT
|
||||
disableInfoframeC871(NVHDMIPKT_CLASS* pThis,
|
||||
NvU32* pBaseReg,
|
||||
NvU32 head,
|
||||
NvU32 ifIndex)
|
||||
{
|
||||
NVHDMIPKT_RESULT result = NVHDMIPKT_TIMEOUT;
|
||||
NvU32 regAddr, regData;
|
||||
|
||||
regAddr = NVC871_SF_GENERIC_INFOFRAME_CTRL(head, ifIndex);
|
||||
regData = REG_RD32(pBaseReg, regAddr);
|
||||
|
||||
// if infoframe is already disabled nothing to do
|
||||
if (FLD_TEST_DRF(C871, _SF_GENERIC_INFOFRAME_CTRL, _ENABLE, _NO, regData))
|
||||
{
|
||||
return NVHDMIPKT_SUCCESS;
|
||||
}
|
||||
|
||||
// engage timer callbacks to wait for HW register status change if timer callbacks are provided
|
||||
NvBool bWaitForIdle = NV_FALSE;
|
||||
if ((pThis->callback.setTimeout != 0) && (pThis->callback.checkTimeout != 0))
|
||||
{
|
||||
// wait until BUSY _NO if timer could be engaged successfully
|
||||
bWaitForIdle = (pThis->callback.setTimeout(pThis->cbHandle, NVHDMIPKT_STATUS_READ_TIMEOUT_IN_us) == NV_TRUE);
|
||||
}
|
||||
|
||||
// write ENABLE_NO
|
||||
regData = FLD_SET_DRF(C871, _SF_GENERIC_INFOFRAME_CTRL, _ENABLE, _NO, regData);
|
||||
REG_WR32(pBaseReg, regAddr, regData);
|
||||
|
||||
// if timer callbacks are available poll for disable done
|
||||
if (bWaitForIdle)
|
||||
{
|
||||
regData = REG_RD32(pBaseReg, regAddr);
|
||||
while(FLD_TEST_DRF(C871, _SF_GENERIC_INFOFRAME_CTRL, _BUSY, _YES, regData))
|
||||
{
|
||||
if (pThis->callback.checkTimeout(pThis->cbHandle) == NV_TRUE)
|
||||
{
|
||||
// timeout waiting for infoframe to get disabled
|
||||
NvHdmiPkt_Print(pThis, "MoreInfoframe: timeout waiting for infoframe to get disabled");
|
||||
goto disableInfoframe_exit;
|
||||
}
|
||||
regData = REG_RD32(pBaseReg, regAddr);
|
||||
}
|
||||
|
||||
NvHdmiPkt_Assert(FLD_TEST_DRF(C871, _SF_GENERIC_INFOFRAME_CTRL, _BUSY, _NO, regData));
|
||||
}
|
||||
else
|
||||
{
|
||||
NvHdmiPkt_Print(pThis, "MoreInfoframe: Clients must ideally provide timer callbacks to wait for enable/disable infoframes");
|
||||
NvHdmiPkt_Assert(0);
|
||||
}
|
||||
|
||||
result = NVHDMIPKT_SUCCESS;
|
||||
|
||||
disableInfoframe_exit:
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* programAdvancedInfoframeC871
|
||||
*/
|
||||
static NVHDMIPKT_RESULT
|
||||
programAdvancedInfoframeC871(NVHDMIPKT_CLASS *pThis,
|
||||
NvU32 subDevice,
|
||||
NvU32 head,
|
||||
NVHDMIPKT_TYPE packetReg,
|
||||
const ADVANCED_INFOFRAME *pInfoframe)
|
||||
{
|
||||
NVHDMIPKT_RESULT result = NVHDMIPKT_SUCCESS;
|
||||
NvU32* pBaseReg = (NvU32*)pThis->memMap[subDevice].pMemBase;
|
||||
|
||||
if ((packetReg < NVHDMIPKT_TYPE_SHARED_GENERIC1) || (packetReg >= NVHDMIPKT_INVALID_PKT_TYPE))
|
||||
{
|
||||
return NVHDMIPKT_INVALID_ARG;
|
||||
}
|
||||
|
||||
NvU32 ifIndex = packetReg - NVHDMIPKT_TYPE_SHARED_GENERIC1;
|
||||
NvU32 ifNum, dwordNum;
|
||||
|
||||
NvU32 regAddr = 0;
|
||||
NvU32 regData = 0;
|
||||
NvU32 numOfInfoframes = pInfoframe->isLargeInfoframe ? (pInfoframe->numAdditionalInfoframes + 1) : 1;
|
||||
|
||||
if (NV_FALSE == isInfoframeOffsetAvailable(pBaseReg, head, ifIndex))
|
||||
{
|
||||
NvHdmiPkt_Print(pThis, "MoreInfoframe: Client requested overwriting an active infoframe");
|
||||
}
|
||||
|
||||
// acquire mutex
|
||||
pThis->callback.acquireMutex(pThis->cbHandle);
|
||||
|
||||
// disable and wait for infoframe HW unit to be ready
|
||||
result = disableInfoframeC871(pThis, pBaseReg, head, ifIndex);
|
||||
if (result != NVHDMIPKT_SUCCESS)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
// write DATA_CTRL
|
||||
regData = 0;
|
||||
regAddr = NVC871_SF_GENERIC_INFOFRAME_DATA_CTRL(head);
|
||||
regData = FLD_SET_DRF_NUM(C871, _SF_GENERIC_INFOFRAME_DATA_CTRL, _OFFSET, ifIndex, regData);
|
||||
REG_WR32(pBaseReg, regAddr, regData);
|
||||
|
||||
// send header + payload
|
||||
NvHdmiPkt_Assert(pInfoframe->packetLen == (9 * sizeof(NvU32) * numOfInfoframes));
|
||||
|
||||
for (ifNum = 0; ifNum < numOfInfoframes; ifNum++)
|
||||
{
|
||||
const NvU8 *pPayload = pInfoframe->pPacket + (ifNum * 9 * sizeof(NvU32));
|
||||
|
||||
for (dwordNum = 0; dwordNum < 9; dwordNum++) // each infoframe is 9 DWORDs including the header
|
||||
{
|
||||
regData = 0;
|
||||
regData = FLD_SET_DRF_NUM(C871, _SF_GENERIC_INFOFRAME_DATA, _BYTE0, pPayload[4*dwordNum + 0], regData);
|
||||
regData = FLD_SET_DRF_NUM(C871, _SF_GENERIC_INFOFRAME_DATA, _BYTE1, pPayload[4*dwordNum + 1], regData);
|
||||
regData = FLD_SET_DRF_NUM(C871, _SF_GENERIC_INFOFRAME_DATA, _BYTE2, pPayload[4*dwordNum + 2], regData);
|
||||
regData = FLD_SET_DRF_NUM(C871, _SF_GENERIC_INFOFRAME_DATA, _BYTE3, pPayload[4*dwordNum + 3], regData);
|
||||
|
||||
REG_WR32(pBaseReg, NVC871_SF_GENERIC_INFOFRAME_DATA(head), regData);
|
||||
}
|
||||
}
|
||||
|
||||
// write GENERIC_CONFIG
|
||||
regData = 0;
|
||||
regAddr = NVC871_SF_GENERIC_INFOFRAME_CONFIG(head, ifIndex);
|
||||
regData = FLD_SET_DRF_NUM(C871, _SF_GENERIC_INFOFRAME_CONFIG, _FID, pInfoframe->flipId, regData);
|
||||
if (pInfoframe->location == INFOFRAME_CTRL_LOC_LINE)
|
||||
{
|
||||
regData = FLD_SET_DRF_NUM(C871, _SF_GENERIC_INFOFRAME_CONFIG, _LINE_ID, pInfoframe->lineNum, regData);
|
||||
regData = (pInfoframe->lineIdReversed) ?
|
||||
FLD_SET_DRF(C871, _SF_GENERIC_INFOFRAME_CONFIG, _LINE_ID_REVERSED, _YES, regData) :
|
||||
FLD_SET_DRF(C871, _SF_GENERIC_INFOFRAME_CONFIG, _LINE_ID_REVERSED, _NO, regData);
|
||||
}
|
||||
|
||||
regData = (pInfoframe->crcOverride) ?
|
||||
FLD_SET_DRF(C871, _SF_GENERIC_INFOFRAME_CONFIG, _CRC_OVERRIDE, _YES, regData) :
|
||||
FLD_SET_DRF(C871, _SF_GENERIC_INFOFRAME_CONFIG, _CRC_OVERRIDE, _NO, regData);
|
||||
|
||||
regData = (pInfoframe->matchFidMethodArmState) ?
|
||||
FLD_SET_DRF(C871, _SF_GENERIC_INFOFRAME_CONFIG, _MTD_STATE_CTRL, _ARM, regData) : // send Infoframe at LOC when matching FID found at channel's FID method's ARM state
|
||||
FLD_SET_DRF(C871, _SF_GENERIC_INFOFRAME_CONFIG, _MTD_STATE_CTRL, _ACT, regData); // default is when FID method is at ACTIVE state
|
||||
|
||||
// write reg
|
||||
REG_WR32(pBaseReg, regAddr, regData);
|
||||
|
||||
// ENABLE_YES to GENERIC_CTRL
|
||||
regData = 0;
|
||||
regAddr = NVC871_SF_GENERIC_INFOFRAME_CTRL(head, ifIndex);
|
||||
regData = FLD_SET_DRF_NUM(C871, _SF_GENERIC_INFOFRAME_CTRL, _RUN_MODE, pInfoframe->runMode, regData);
|
||||
regData = FLD_SET_DRF_NUM(C871, _SF_GENERIC_INFOFRAME_CTRL, _LOC, pInfoframe->location, regData);
|
||||
regData = FLD_SET_DRF_NUM(C871, _SF_GENERIC_INFOFRAME_CTRL, _OFFSET, ifIndex, regData);
|
||||
regData = FLD_SET_DRF_NUM(C871, _SF_GENERIC_INFOFRAME_CTRL, _SIZE, pInfoframe->numAdditionalInfoframes, regData);
|
||||
regData = FLD_SET_DRF (C871, _SF_GENERIC_INFOFRAME_CTRL, _ENABLE, _YES, regData);
|
||||
|
||||
// write reg
|
||||
REG_WR32(pBaseReg, regAddr, regData);
|
||||
|
||||
NvHdmiPkt_Print(pThis, "MoreInfoframe: Sent infoframe of length %d bytes, transmit ctrl 0x%x at offset %d head=%x subdev=%d",
|
||||
pInfoframe->packetLen, regData, ifIndex, head, subDevice);
|
||||
|
||||
// setup MSC_CTRL
|
||||
regData = 0;
|
||||
regAddr = NVC871_SF_GENERIC_INFOFRAME_MISC_CTRL(head);
|
||||
regData = pInfoframe->winMethodCyaBroadcast ?
|
||||
FLD_SET_DRF(C871, _SF_GENERIC_INFOFRAME_MISC_CTRL, _WIN_CHN_SEL, _PUBLIC, regData) :
|
||||
FLD_SET_DRF(C871, _SF_GENERIC_INFOFRAME_MISC_CTRL, _WIN_CHN_SEL, _PRIVATE, regData) ;
|
||||
regData = pInfoframe->highAudioPriority ?
|
||||
FLD_SET_DRF(C871, _SF_GENERIC_INFOFRAME_MISC_CTRL, _AUDIO_PRIORITY, _HIGH, regData) :
|
||||
FLD_SET_DRF(C871, _SF_GENERIC_INFOFRAME_MISC_CTRL, _AUDIO_PRIORITY, _LOW, regData);
|
||||
// write reg
|
||||
REG_WR32(pBaseReg, regAddr, regData);
|
||||
|
||||
|
||||
// release mutex
|
||||
pThis->callback.releaseMutex(pThis->cbHandle);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* hdmiWritePacketCtrlC871
|
||||
*/
|
||||
static NVHDMIPKT_RESULT
|
||||
hdmiWritePacketCtrlLegacyPktsC871(NVHDMIPKT_CLASS* pThis,
|
||||
NvU32* pBaseReg,
|
||||
NvU32 head,
|
||||
NvU32 pktTypeC871,
|
||||
NvU32 transmitControl,
|
||||
NvBool bDisable)
|
||||
{
|
||||
NVHDMIPKT_RESULT result = NVHDMIPKT_INVALID_ARG;
|
||||
NvU32 regOffset = 0;
|
||||
NvU32 hdmiCtrl = 0;
|
||||
|
||||
if (pBaseReg == 0 || head >= NVC871_SF_HDMI_INFO_CTRL__SIZE_1)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
switch (pktTypeC871)
|
||||
{
|
||||
case NVC871_SF_HDMI_INFO_IDX_AVI_INFOFRAME:
|
||||
case NVC871_SF_HDMI_INFO_IDX_GCP:
|
||||
regOffset = NVC871_SF_HDMI_INFO_CTRL(head, pktTypeC871);
|
||||
hdmiCtrl = REG_RD32(pBaseReg, regOffset);
|
||||
hdmiCtrl = (bDisable == NV_TRUE) ?
|
||||
(FLD_SET_DRF(C871, _SF_HDMI_INFO_CTRL, _ENABLE, _DIS, hdmiCtrl)) :
|
||||
(transmitControl);
|
||||
REG_WR32(pBaseReg, regOffset, hdmiCtrl);
|
||||
result = NVHDMIPKT_SUCCESS;
|
||||
break;
|
||||
default:
|
||||
NvHdmiPkt_Assert(0 && "Invalid pkt type!");
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* hdmiPacketReadC871
|
||||
*/
|
||||
static NVHDMIPKT_RESULT
|
||||
hdmiPacketReadC871(NVHDMIPKT_CLASS* pThis,
|
||||
NvU32 subDevice,
|
||||
NvU32 head,
|
||||
NVHDMIPKT_TYPE packetReg,
|
||||
NvU32 bufferLen,
|
||||
NvU8 *const pOutPktBuffer)
|
||||
{
|
||||
NvU32 ifIndex, ifNum, dw, regAddr, regData, numOfInfoframes;
|
||||
NVHDMIPKT_RESULT result = NVHDMIPKT_SUCCESS;
|
||||
NvU32* pBaseReg = (NvU32*)pThis->memMap[subDevice].pMemBase;
|
||||
|
||||
if ((packetReg < NVHDMIPKT_TYPE_SHARED_GENERIC1) || (packetReg >= NVHDMIPKT_INVALID_PKT_TYPE))
|
||||
{
|
||||
return NVHDMIPKT_INVALID_ARG;
|
||||
}
|
||||
|
||||
ifIndex = packetReg - NVHDMIPKT_TYPE_SHARED_GENERIC1;
|
||||
|
||||
// write infoframe Offset to DATA_CTRL
|
||||
regData = 0;
|
||||
regAddr = NVC871_SF_GENERIC_INFOFRAME_DATA_CTRL(head);
|
||||
regData = FLD_SET_DRF_NUM(C871, _SF_GENERIC_INFOFRAME_DATA_CTRL, _OFFSET, ifIndex, regData);
|
||||
REG_WR32(pBaseReg, regAddr, regData);
|
||||
|
||||
// read size of infoframe programmed at this Offset
|
||||
regAddr = NVC871_SF_GENERIC_INFOFRAME_CTRL(head, ifIndex);
|
||||
regData = REG_RD32(pBaseReg, regAddr);
|
||||
numOfInfoframes = DRF_VAL(C871, _SF_GENERIC_INFOFRAME_CTRL, _SIZE, regData) + 1; // total size is 1 more than SIZE field
|
||||
|
||||
NvU32 remainingBufSize = bufferLen;
|
||||
NvU8 *pBuffer = pOutPktBuffer;
|
||||
|
||||
for (ifNum = 0; ifNum < numOfInfoframes; ifNum++)
|
||||
{
|
||||
if (remainingBufSize == 0)
|
||||
{
|
||||
NvHdmiPkt_Assert(0 && "MoreInfoframe: Buffer size insufficient to copy read packet data");
|
||||
result = NVHDMIPKT_INSUFFICIENT_BUFFER;
|
||||
break;
|
||||
}
|
||||
|
||||
// a temporary buffer to read a 36 byte chunk of this infoframe
|
||||
NvU8 pktBytes[9 * sizeof(NvU32)];
|
||||
|
||||
for (dw = 0; dw < 9; dw++) // each infoframe is 9 DWORDs including the header
|
||||
{
|
||||
regData = REG_RD32(pBaseReg, NVC871_SF_GENERIC_INFOFRAME_DATA(head));
|
||||
|
||||
pktBytes[dw*4 + 0] = DRF_VAL(C871, _SF_GENERIC_INFOFRAME_DATA, _BYTE0, regData);
|
||||
pktBytes[dw*4 + 1] = DRF_VAL(C871, _SF_GENERIC_INFOFRAME_DATA, _BYTE1, regData);
|
||||
pktBytes[dw*4 + 2] = DRF_VAL(C871, _SF_GENERIC_INFOFRAME_DATA, _BYTE2, regData);
|
||||
pktBytes[dw*4 + 3] = DRF_VAL(C871, _SF_GENERIC_INFOFRAME_DATA, _BYTE3, regData);
|
||||
}
|
||||
|
||||
NvU32 bytesCopied = (remainingBufSize > 36) ? 36 : remainingBufSize;
|
||||
NVMISC_MEMCPY(pBuffer, &pktBytes, bytesCopied);
|
||||
|
||||
// move out buffer ptr by the copied bytes
|
||||
pBuffer += bytesCopied;
|
||||
// reduce remaining buffer size by the amount we copied
|
||||
remainingBufSize = remainingBufSize - bytesCopied;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* hdmiPacketCtrlC871
|
||||
*/
|
||||
static NVHDMIPKT_RESULT
|
||||
hdmiPacketCtrlC871(NVHDMIPKT_CLASS* pThis,
|
||||
NvU32 subDevice,
|
||||
NvU32 displayId,
|
||||
NvU32 head,
|
||||
NVHDMIPKT_TYPE packetType,
|
||||
NVHDMIPKT_TC transmitControl)
|
||||
{
|
||||
NvU32* pBaseReg = (NvU32*)pThis->memMap[subDevice].pMemBase;
|
||||
NvU32 tc = pThis->translateTransmitControl(pThis, transmitControl);
|
||||
|
||||
if ((pBaseReg == 0) || (head >= NVC871_SF_GENERIC_INFOFRAME_CTRL__SIZE_1) ||
|
||||
(packetType >= NVHDMIPKT_INVALID_PKT_TYPE))
|
||||
{
|
||||
return NVHDMIPKT_INVALID_ARG;
|
||||
}
|
||||
|
||||
if ((packetType == NVHDMIPKT_TYPE_VENDOR_SPECIFIC_INFOFRAME) ||
|
||||
(packetType == NVHDMIPKT_TYPE_GENERIC))
|
||||
{
|
||||
NvHdmiPkt_Print(pThis, "Generic and VSI registers removed in C871 HW. Call NvHdmiPkt_SetupAdvancedInfoframe to use one of the generic registers!");
|
||||
NvHdmiPkt_Assert(0);
|
||||
return NVHDMIPKT_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (packetType >= NVHDMIPKT_TYPE_SHARED_GENERIC1 && packetType <= NVHDMIPKT_TYPE_SHARED_GENERIC10)
|
||||
{
|
||||
// client is only expected to call packet ctrl interface to disable the infoframe, no support for other packet ctrl options
|
||||
// to reprogram/change run mode of a packet, call NvHdmiPkt_SetupAdvancedInfoframe interface
|
||||
NvHdmiPkt_Assert(FLD_TEST_DRF(_HDMI_PKT, _TRANSMIT_CTRL, _ENABLE, _DIS, transmitControl));
|
||||
|
||||
return disableInfoframeC871(pThis, pBaseReg, head, (packetType - NVHDMIPKT_TYPE_SHARED_GENERIC1));
|
||||
}
|
||||
|
||||
NvU32 pktTypeC871 = pThis->translatePacketType(pThis, packetType);
|
||||
return pThis->hdmiWritePacketCtrl(pThis, pBaseReg, head, pktTypeC871, tc, NV_FALSE);
|
||||
}
|
||||
|
||||
// non-HW - class utility/maintenance functions
|
||||
/*
|
||||
* hdmiConstructorC871
|
||||
*/
|
||||
NvBool
|
||||
hdmiConstructorC871(NVHDMIPKT_CLASS* pThis)
|
||||
{
|
||||
NvBool result = NV_TRUE;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* hdmiDestructorC871
|
||||
*/
|
||||
void
|
||||
hdmiDestructorC871(NVHDMIPKT_CLASS* pThis)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* initializeHdmiPktInterfaceC871
|
||||
*/
|
||||
void
|
||||
initializeHdmiPktInterfaceC871(NVHDMIPKT_CLASS* pClass)
|
||||
{
|
||||
// Update SF_USER data
|
||||
pClass->dispSfUserClassId = NVC871_DISP_SF_USER;
|
||||
pClass->dispSfUserSize = sizeof(NvC871DispSfUserMap);
|
||||
|
||||
pClass->translatePacketType = translatePacketTypeC871;
|
||||
pClass->hdmiWriteAviPacket = hdmiWriteAviPacketC871;
|
||||
pClass->hdmiWriteGeneralCtrlPacket = hdmiWriteGeneralCtrlPacketC871;
|
||||
pClass->hdmiPacketWrite = hdmiPacketWriteC871;
|
||||
pClass->hdmiPacketCtrl = hdmiPacketCtrlC871;
|
||||
pClass->hdmiWritePacketCtrl = hdmiWritePacketCtrlLegacyPktsC871;
|
||||
|
||||
// generic infoframe (shareable by DP and HDMI)
|
||||
pClass->hdmiPacketRead = hdmiPacketReadC871;
|
||||
pClass->programAdvancedInfoframe = programAdvancedInfoframeC871;
|
||||
}
|
||||
204
src/common/modeset/hdmipacket/nvhdmipkt_C971.c
Normal file
204
src/common/modeset/hdmipacket/nvhdmipkt_C971.c
Normal file
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2023 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_C971.c
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nvhdmipkt_common.h"
|
||||
/*
|
||||
* Purpose: Provides packet write functions for HDMI library for NVD5.0 chips
|
||||
*/
|
||||
#include "nvhdmipkt_class.h"
|
||||
#include "nvhdmipkt_internal.h"
|
||||
#include "class/clc971.h"
|
||||
|
||||
/*
|
||||
* programAdvancedInfoframeC971
|
||||
*/
|
||||
static NVHDMIPKT_RESULT
|
||||
programAdvancedInfoframeC971(NVHDMIPKT_CLASS *pThis,
|
||||
NvU32 subDevice,
|
||||
NvU32 head,
|
||||
NVHDMIPKT_TYPE packetReg,
|
||||
const ADVANCED_INFOFRAME *pInfoframe)
|
||||
{
|
||||
NVHDMIPKT_RESULT result = NVHDMIPKT_SUCCESS;
|
||||
NvU32* pBaseReg = (NvU32*)pThis->memMap[subDevice].pMemBase;
|
||||
|
||||
if ((packetReg < NVHDMIPKT_TYPE_SHARED_GENERIC1) || (packetReg >= NVHDMIPKT_INVALID_PKT_TYPE))
|
||||
{
|
||||
return NVHDMIPKT_INVALID_ARG;
|
||||
}
|
||||
|
||||
NvU32 ifIndex = packetReg - NVHDMIPKT_TYPE_SHARED_GENERIC1;
|
||||
NvU32 ifNum, dwordNum;
|
||||
|
||||
NvU32 regAddr = 0;
|
||||
NvU32 regData = 0;
|
||||
NvU32 numOfInfoframes = pInfoframe->isLargeInfoframe ? (pInfoframe->numAdditionalInfoframes + 1) : 1;
|
||||
|
||||
if (NV_FALSE == isInfoframeOffsetAvailable(pBaseReg, head, ifIndex))
|
||||
{
|
||||
NvHdmiPkt_Print(pThis, "MoreInfoframe: Client requested overwriting an active infoframe");
|
||||
}
|
||||
|
||||
NvHdmiPkt_Assert((pInfoframe->crcOverride == 0) &&
|
||||
"CRC Override bit not supported in Nvd 5.0");
|
||||
NvHdmiPkt_Assert((pInfoframe->winMethodCyaBroadcast == 0) &&
|
||||
"window channel priv reg control not supported in Nvd5.0");
|
||||
NvHdmiPkt_Assert((pInfoframe->location != INFOFRAME_CTRL_LOC_LOADV) &&
|
||||
"LoadV location not supported in Nvd5.0");
|
||||
|
||||
// acquire mutex
|
||||
pThis->callback.acquireMutex(pThis->cbHandle);
|
||||
|
||||
// disable and wait for infoframe HW unit to be ready
|
||||
// Note, C971 HW provides Clear option for SENT field, so we don't have to disable
|
||||
// just to make sure new data sending is successful. But we disable Infoframe
|
||||
// before reprogramming to avoid corrupting a payload that is actively being sent
|
||||
result = disableInfoframeC871(pThis, pBaseReg, head, ifIndex);
|
||||
if (result != NVHDMIPKT_SUCCESS)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
// write SENT bit to clear the SENT field
|
||||
regAddr = NVC971_SF_GENERIC_INFOFRAME_CTRL(head, ifIndex);
|
||||
regData = REG_RD32(pBaseReg, regAddr);
|
||||
regData = FLD_SET_DRF(C971, _SF_GENERIC_INFOFRAME_CTRL, _SENT, _CLEAR, regData);
|
||||
REG_WR32(pBaseReg, regAddr, regData);
|
||||
|
||||
// write DATA_CTRL
|
||||
regData = 0;
|
||||
regAddr = NVC971_SF_GENERIC_INFOFRAME_DATA_CTRL(head);
|
||||
regData = FLD_SET_DRF_NUM(C971, _SF_GENERIC_INFOFRAME_DATA_CTRL, _OFFSET, ifIndex, regData);
|
||||
REG_WR32(pBaseReg, regAddr, regData);
|
||||
|
||||
// send header + payload
|
||||
NvHdmiPkt_Assert(pInfoframe->packetLen == (9 * sizeof(NvU32) * numOfInfoframes));
|
||||
|
||||
for (ifNum = 0; ifNum < numOfInfoframes; ifNum++)
|
||||
{
|
||||
const NvU8 *pPayload = pInfoframe->pPacket + (ifNum * 9 * sizeof(NvU32));
|
||||
|
||||
for (dwordNum = 0; dwordNum < 9; dwordNum++) // each infoframe is 9 DWORDs including the header
|
||||
{
|
||||
regData = 0;
|
||||
regData = FLD_SET_DRF_NUM(C971, _SF_GENERIC_INFOFRAME_DATA, _BYTE0, pPayload[4*dwordNum + 0], regData);
|
||||
regData = FLD_SET_DRF_NUM(C971, _SF_GENERIC_INFOFRAME_DATA, _BYTE1, pPayload[4*dwordNum + 1], regData);
|
||||
regData = FLD_SET_DRF_NUM(C971, _SF_GENERIC_INFOFRAME_DATA, _BYTE2, pPayload[4*dwordNum + 2], regData);
|
||||
regData = FLD_SET_DRF_NUM(C971, _SF_GENERIC_INFOFRAME_DATA, _BYTE3, pPayload[4*dwordNum + 3], regData);
|
||||
|
||||
REG_WR32(pBaseReg, NVC971_SF_GENERIC_INFOFRAME_DATA(head), regData);
|
||||
}
|
||||
}
|
||||
|
||||
// write GENERIC_CONFIG
|
||||
regData = 0;
|
||||
regAddr = NVC971_SF_GENERIC_INFOFRAME_CONFIG(head, ifIndex);
|
||||
regData = FLD_SET_DRF_NUM(C971, _SF_GENERIC_INFOFRAME_CONFIG, _FID, pInfoframe->flipId, regData);
|
||||
if (pInfoframe->location == INFOFRAME_CTRL_LOC_LINE)
|
||||
{
|
||||
regData = FLD_SET_DRF_NUM(C971, _SF_GENERIC_INFOFRAME_CONFIG, _LINE_ID, pInfoframe->lineNum, regData);
|
||||
regData = (pInfoframe->lineIdReversed) ?
|
||||
FLD_SET_DRF(C971, _SF_GENERIC_INFOFRAME_CONFIG, _LINE_ID_REVERSED, _YES, regData) :
|
||||
FLD_SET_DRF(C971, _SF_GENERIC_INFOFRAME_CONFIG, _LINE_ID_REVERSED, _NO, regData);
|
||||
}
|
||||
|
||||
regData = (pInfoframe->asSdpOverride) ?
|
||||
FLD_SET_DRF(C971, _SF_GENERIC_INFOFRAME_CONFIG, _AS_SDP_OVERRIDE_EN, _YES, regData) :
|
||||
FLD_SET_DRF(C971, _SF_GENERIC_INFOFRAME_CONFIG, _AS_SDP_OVERRIDE_EN, _NO, regData);
|
||||
|
||||
regData = (pInfoframe->matchFidMethodArmState) ?
|
||||
FLD_SET_DRF(C971, _SF_GENERIC_INFOFRAME_CONFIG, _MTD_STATE_CTRL, _ARM, regData) :
|
||||
// send Infoframe at LOC when matching FID found at channel's FID method's ARM state
|
||||
FLD_SET_DRF(C971, _SF_GENERIC_INFOFRAME_CONFIG, _MTD_STATE_CTRL, _ACT, regData);
|
||||
// default is when FID method is at ACTIVE state
|
||||
|
||||
// write reg
|
||||
REG_WR32(pBaseReg, regAddr, regData);
|
||||
|
||||
// ENABLE_YES to GENERIC_CTRL
|
||||
regData = 0;
|
||||
regAddr = NVC971_SF_GENERIC_INFOFRAME_CTRL(head, ifIndex);
|
||||
regData = FLD_SET_DRF_NUM(C971, _SF_GENERIC_INFOFRAME_CTRL, _RUN_MODE, pInfoframe->runMode, regData);
|
||||
regData = FLD_SET_DRF_NUM(C971, _SF_GENERIC_INFOFRAME_CTRL, _LOC, pInfoframe->location, regData);
|
||||
regData = FLD_SET_DRF_NUM(C971, _SF_GENERIC_INFOFRAME_CTRL, _OFFSET, ifIndex, regData);
|
||||
regData = FLD_SET_DRF_NUM(C971, _SF_GENERIC_INFOFRAME_CTRL, _SIZE, pInfoframe->numAdditionalInfoframes, regData);
|
||||
regData = FLD_SET_DRF (C971, _SF_GENERIC_INFOFRAME_CTRL, _ENABLE, _YES, regData);
|
||||
|
||||
// write reg
|
||||
REG_WR32(pBaseReg, regAddr, regData);
|
||||
|
||||
NvHdmiPkt_Print(pThis, "MoreInfoframe: Sent infoframe of length %d bytes, transmit ctrl 0x%x at offset %d head=%x subdev=%d",
|
||||
pInfoframe->packetLen, regData, ifIndex, head, subDevice);
|
||||
|
||||
// setup MSC_CTRL
|
||||
regData = 0;
|
||||
regAddr = NVC971_SF_GENERIC_INFOFRAME_MISC_CTRL(head);
|
||||
regData = pInfoframe->highAudioPriority ?
|
||||
FLD_SET_DRF(C971, _SF_GENERIC_INFOFRAME_MISC_CTRL, _AUDIO_PRIORITY, _HIGH, regData) :
|
||||
FLD_SET_DRF(C971, _SF_GENERIC_INFOFRAME_MISC_CTRL, _AUDIO_PRIORITY, _LOW, regData);
|
||||
// write reg
|
||||
REG_WR32(pBaseReg, regAddr, regData);
|
||||
|
||||
// release mutex
|
||||
pThis->callback.releaseMutex(pThis->cbHandle);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// non-HW - class utility/maintenance functions
|
||||
/*
|
||||
* hdmiConstructorC971
|
||||
*/
|
||||
NvBool
|
||||
hdmiConstructorC971(NVHDMIPKT_CLASS* pThis)
|
||||
{
|
||||
NvBool result = NV_TRUE;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* hdmiDestructorC971
|
||||
*/
|
||||
void
|
||||
hdmiDestructorC971(NVHDMIPKT_CLASS* pThis)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* initializeHdmiPktInterfaceC971
|
||||
*/
|
||||
void
|
||||
initializeHdmiPktInterfaceC971(NVHDMIPKT_CLASS* pClass)
|
||||
{
|
||||
// Update SF_USER data
|
||||
pClass->dispSfUserClassId = NVC971_DISP_SF_USER;
|
||||
pClass->dispSfUserSize = sizeof(NvC971DispSfUserMap);
|
||||
|
||||
// generic infoframe (shareable by DP and HDMI)
|
||||
pClass->programAdvancedInfoframe = programAdvancedInfoframeC971;
|
||||
}
|
||||
65
src/common/modeset/hdmipacket/nvhdmipkt_CA71.c
Normal file
65
src/common/modeset/hdmipacket/nvhdmipkt_CA71.c
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2024 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_CA71.c
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nvhdmipkt_common.h"
|
||||
/*
|
||||
* Purpose: Provides packet write functions for HDMI library for NVD5.0 chips
|
||||
*/
|
||||
#include "nvhdmipkt_class.h"
|
||||
#include "nvhdmipkt_internal.h"
|
||||
#include "class/clca71.h"
|
||||
|
||||
// non-HW - class utility/maintenance functions
|
||||
/*
|
||||
* hdmiConstructorCA71
|
||||
*/
|
||||
NvBool
|
||||
hdmiConstructorCA71(NVHDMIPKT_CLASS* pThis)
|
||||
{
|
||||
NvBool result = NV_TRUE;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* hdmiDestructorCA71
|
||||
*/
|
||||
void
|
||||
hdmiDestructorCA71(NVHDMIPKT_CLASS* pThis)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* initializeHdmiPktInterfaceCA71
|
||||
*/
|
||||
void
|
||||
initializeHdmiPktInterfaceCA71(NVHDMIPKT_CLASS* pClass)
|
||||
{
|
||||
// Update SF_USER data
|
||||
pClass->dispSfUserClassId = NVCA71_DISP_SF_USER;
|
||||
pClass->dispSfUserSize = sizeof(NvCA71DispSfUserMap);
|
||||
}
|
||||
@@ -48,6 +48,9 @@ typedef enum
|
||||
NVHDMIPKT_C571_CLASS = 6, // TU102
|
||||
NVHDMIPKT_C671_CLASS = 7, // GA102, T234D
|
||||
NVHDMIPKT_C771_CLASS = 8, // AD10X
|
||||
NVHDMIPKT_C871_CLASS = 9, // T239
|
||||
NVHDMIPKT_C971_CLASS = 10, // NVD5.0
|
||||
NVHDMIPKT_CA71_CLASS = 11,
|
||||
NVHDMIPKT_INVALID_CLASS // Not to be used by client, and always the last entry here.
|
||||
} NVHDMIPKT_CLASS_ID;
|
||||
|
||||
@@ -85,6 +88,21 @@ struct tagNVHDMIPKT_CLASS
|
||||
NvU32 packetLen,
|
||||
NvU8 const *const pPacket);
|
||||
|
||||
NVHDMIPKT_RESULT
|
||||
(*hdmiPacketRead) (NVHDMIPKT_CLASS* pThis,
|
||||
NvU32 subDevice,
|
||||
NvU32 head,
|
||||
NVHDMIPKT_TYPE packetReg,
|
||||
NvU32 bufferLen,
|
||||
NvU8 *const pOutPktBuffer);
|
||||
|
||||
NVHDMIPKT_RESULT
|
||||
(*programAdvancedInfoframe) (NVHDMIPKT_CLASS* pThis,
|
||||
NvU32 subDevice,
|
||||
NvU32 head,
|
||||
NVHDMIPKT_TYPE packetReg,
|
||||
const ADVANCED_INFOFRAME* pInfoframe);
|
||||
|
||||
// HW functions - that read/write registers
|
||||
NvBool
|
||||
(*hdmiReadPacketStatus) (NVHDMIPKT_CLASS* pThis,
|
||||
|
||||
@@ -51,7 +51,9 @@ typedef struct tagNVHDMIPKT_MEM_MAP NVHDMIPKT_MEM_MAP;
|
||||
#define REG_WR32(reg, offset, data) ((*(((volatile NvU32*)(reg)) + ((offset)/4))) = (data))
|
||||
|
||||
#define NVHDMIPKT_INVALID_SUBDEV (0xFFFFFFFF)
|
||||
#if !defined (WINNT) && !defined(NVHDMIPKT_NVKMS)
|
||||
#define NVHDMIPKT_DONT_USE_TIMER
|
||||
#endif
|
||||
#define NVHDMIPKT_STATUS_READ_TIMEOUT_IN_us (1*1000*1000) /* us - micro second */
|
||||
|
||||
// Disp SF User memory map and handle structure
|
||||
@@ -110,4 +112,17 @@ extern NVHDMIPKT_RESULT hdmiClearFRLConfigDummy(NVHDMIPKT_CLASS *pThis,
|
||||
NvU32 subDevice,
|
||||
NvU32 displayId);
|
||||
|
||||
extern NVHDMIPKT_RESULT hdmiPacketReadDummy(NVHDMIPKT_CLASS* pThis,
|
||||
NvU32 subDevice,
|
||||
NvU32 head,
|
||||
NVHDMIPKT_TYPE packetReg,
|
||||
NvU32 bufferLen,
|
||||
NvU8 *const pOutPktBuffer);
|
||||
|
||||
extern NVHDMIPKT_RESULT programAdvancedInfoframeDummy(NVHDMIPKT_CLASS* pThis,
|
||||
NvU32 subDevice,
|
||||
NvU32 head,
|
||||
NVHDMIPKT_TYPE packetReg,
|
||||
const ADVANCED_INFOFRAME* pInfoframe);
|
||||
|
||||
#endif //_NVHDMIPKT_COMMON_H_
|
||||
|
||||
@@ -45,6 +45,9 @@ extern void initializeHdmiPktInterface9571(NVHDMIPKT_CLASS*);
|
||||
extern void initializeHdmiPktInterfaceC371(NVHDMIPKT_CLASS*);
|
||||
extern void initializeHdmiPktInterfaceC671(NVHDMIPKT_CLASS*);
|
||||
extern void initializeHdmiPktInterfaceC771(NVHDMIPKT_CLASS*);
|
||||
extern void initializeHdmiPktInterfaceC871(NVHDMIPKT_CLASS*);
|
||||
extern void initializeHdmiPktInterfaceC971(NVHDMIPKT_CLASS*);
|
||||
extern void initializeHdmiPktInterfaceCA71(NVHDMIPKT_CLASS*);
|
||||
|
||||
extern NvBool hdmiConstructor0073(NVHDMIPKT_CLASS*);
|
||||
extern void hdmiDestructor0073 (NVHDMIPKT_CLASS*);
|
||||
@@ -62,5 +65,18 @@ extern NvBool hdmiConstructorC671(NVHDMIPKT_CLASS*);
|
||||
extern void hdmiDestructorC671 (NVHDMIPKT_CLASS*);
|
||||
extern NvBool hdmiConstructorC771(NVHDMIPKT_CLASS*);
|
||||
extern void hdmiDestructorC771 (NVHDMIPKT_CLASS*);
|
||||
extern NvBool hdmiConstructorC871(NVHDMIPKT_CLASS*);
|
||||
extern void hdmiDestructorC871 (NVHDMIPKT_CLASS*);
|
||||
extern NvBool isInfoframeOffsetAvailable(NvU32* pBaseReg,
|
||||
NvU32 head,
|
||||
NvU32 requestedInfoframe);
|
||||
extern NVHDMIPKT_RESULT disableInfoframeC871(NVHDMIPKT_CLASS* pThis,
|
||||
NvU32* pBaseReg,
|
||||
NvU32 head,
|
||||
NvU32 ifIndex);
|
||||
extern NvBool hdmiConstructorC971(NVHDMIPKT_CLASS*);
|
||||
extern void hdmiDestructorC971 (NVHDMIPKT_CLASS*);
|
||||
extern NvBool hdmiConstructorCA71(NVHDMIPKT_CLASS*);
|
||||
extern void hdmiDestructorCA71 (NVHDMIPKT_CLASS*);
|
||||
|
||||
#endif //_NVHDMIPKT_INTERNAL_H_
|
||||
|
||||
@@ -49,7 +49,7 @@ 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_RB_MIN_VBLANK = 23; // 460 line s (or 460 us?) [1000000:460 = 50000:23]
|
||||
const NvU32 NVT_CVT_MIN_V_BPORCH = 6; // Minimum vertical back porch.
|
||||
|
||||
|
||||
@@ -154,6 +154,7 @@ NVT_STATUS NvTiming_CalcCVT(NvU32 width, NvU32 height, NvU32 rr, NvU32 flag, NVT
|
||||
|
||||
pT->etc.status = NVT_STATUS_CVT;
|
||||
|
||||
// For 1, 2, 3, 4 in Computation of common parameters
|
||||
// H_PIXELS_RND = ROUNDDOWN(H_PIXELS / CELL_GRAN_RND,0) * CELL_GRAN_RND
|
||||
if ((width % NVT_CVT_CELL_GRAN)!=0)
|
||||
{
|
||||
@@ -178,7 +179,8 @@ NVT_STATUS NvTiming_CalcCVT(NvU32 width, NvU32 height, NvU32 rr, NvU32 flag, NVT
|
||||
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)
|
||||
if (dwIdealDutyCycle_NUM < dwIdealDutyCycle_DEN * 20 ||
|
||||
(NVT_CVT_C_PRIME * dwHPeroidEstimate_DEN < NVT_CVT_M_PRIME_D_20 * dwHPeriodEstimate_NUM))
|
||||
{
|
||||
dwIdealDutyCycle_NUM=20;
|
||||
dwIdealDutyCycle_DEN=1;
|
||||
@@ -211,7 +213,8 @@ NVT_STATUS NvTiming_CalcCVT(NvU32 width, NvU32 height, NvU32 rr, NvU32 flag, NVT
|
||||
pT->VFrontPorch = (NvU16)(NVT_CVT_V_PORCH);
|
||||
pT->VSyncWidth = getCVTVSync(dwXCells * NVT_CVT_CELL_GRAN, height);
|
||||
|
||||
pT->pclk = dwPClk;
|
||||
pT->pclk = dwPClk;
|
||||
pT->pclk1khz = (dwPClk << 3) + (dwPClk << 1); // *10
|
||||
|
||||
pT->HSyncPol = NVT_H_SYNC_NEGATIVE;
|
||||
pT->VSyncPol = NVT_V_SYNC_POSITIVE;
|
||||
@@ -411,6 +414,7 @@ NVT_STATUS NvTiming_CalcCVT_RB2(NvU32 width, NvU32 height, NvU32 rr, NvBool is10
|
||||
pT->VSyncWidth = NVT_CVT_RB2_V_SYNC_WIDTH;
|
||||
pT->VFrontPorch = (NvU16)(act_vbi_lines - NVT_CVT_RB2_V_SYNC_WIDTH - NVT_CVT_RB2_MIN_V_BPORCH);
|
||||
pT->pclk = (act_pixel_freq_khz + 5) / 10; //convert to 10Khz
|
||||
pT->pclk1khz = act_pixel_freq_khz;
|
||||
pT->HSyncPol = NVT_H_SYNC_POSITIVE;
|
||||
pT->VSyncPol = NVT_V_SYNC_NEGATIVE;
|
||||
pT->HBorder = pT->VBorder = 0; // not supported
|
||||
@@ -610,6 +614,7 @@ NVT_STATUS NvTiming_CalcCVT_RB3(NvU32 width,
|
||||
pT->VSyncWidth = NVT_CVT_RB3_V_SYNC_WIDTH;
|
||||
pT->VFrontPorch = (NvU16)(act_v_blank_lines - NVT_CVT_RB3_V_SYNC_WIDTH - v_back_porch);
|
||||
pT->pclk = ((NvU32)act_pixel_freq_khz + 5) / 10; //convert to 10Khz
|
||||
pT->pclk1khz = act_pixel_freq_khz;
|
||||
pT->HSyncPol = NVT_H_SYNC_POSITIVE;
|
||||
pT->VSyncPol = NVT_V_SYNC_NEGATIVE;
|
||||
pT->HBorder = pT->VBorder = 0; // not supported
|
||||
|
||||
@@ -1552,9 +1552,9 @@ parseDisplayId20Timing7Descriptor(
|
||||
pDescriptor = (const DISPLAYID_2_0_TIMING_7_DESCRIPTOR *)pVoidDescriptor;
|
||||
|
||||
// pclk is in 1Khz
|
||||
pTiming->pclk = ((pDescriptor->pixel_clock[2] << 16 |
|
||||
pDescriptor->pixel_clock[1] << 8 |
|
||||
pDescriptor->pixel_clock[0]) + 1);
|
||||
pTiming->pclk1khz = ((pDescriptor->pixel_clock[2] << 16 |
|
||||
pDescriptor->pixel_clock[1] << 8 |
|
||||
pDescriptor->pixel_clock[0]) + 1);
|
||||
|
||||
pTiming->HBorder = 0;
|
||||
pTiming->VBorder = 0;
|
||||
@@ -1637,17 +1637,17 @@ parseDisplayId20Timing7Descriptor(
|
||||
pTiming->etc.aspect = 0;
|
||||
}
|
||||
|
||||
pTiming->etc.rr = NvTiming_CalcRR(pTiming->pclk,
|
||||
pTiming->etc.rr = NvTiming_CalcRR(pTiming->pclk1khz,
|
||||
pTiming->interlaced,
|
||||
pTiming->HTotal,
|
||||
pTiming->VTotal) / 10;
|
||||
pTiming->etc.rrx1k = NvTiming_CalcRRx1k(pTiming->pclk,
|
||||
pTiming->etc.rrx1k = NvTiming_CalcRRx1k(pTiming->pclk1khz,
|
||||
pTiming->interlaced,
|
||||
pTiming->HTotal,
|
||||
pTiming->VTotal) / 10;
|
||||
|
||||
// pclk change to 10k
|
||||
pTiming->pclk /= 10;
|
||||
// pclk change to 10kHz
|
||||
pTiming->pclk = pTiming->pclk1khz / 10;
|
||||
|
||||
pTiming->etc.status = NVT_STATUS_DISPLAYID_7N(++count);
|
||||
|
||||
|
||||
@@ -37,13 +37,13 @@ PUSH_SEGMENTS
|
||||
// DMT table 2-1
|
||||
// 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"}}
|
||||
{hv,0,hfp,hsw,ht,(hsp)=='-',vv,0,vfp,vsw,vt,(vsp)=='-',NVT_PROGRESSIVE,pclk,((pclk<<3)+(pclk<<1)),{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"}}
|
||||
{hv,0,hfp,hsw,ht,(hsp)=='-',vv,0,vfp,vsw,vt,(vsp)=='-',NVT_PROGRESSIVE,pclk,((pclk<<3)+(pclk<<1)),{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"}}
|
||||
{hv,0,hfp,hsw,ht,(hsp)=='-',vv,0,vfp,vsw,vt,(vsp)=='-',NVT_PROGRESSIVE,pclk,((pclk<<3)+(pclk<<1)),{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)
|
||||
|
||||
@@ -56,7 +56,7 @@ static NVT_TIMING DMT[] =
|
||||
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"}},
|
||||
{640,8,16,40,832,NVT_H_SYNC_NEGATIVE,480,8,1,3,520,NVT_V_SYNC_NEGATIVE,NVT_PROGRESSIVE,3150,31500,{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),
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "nvt_dsc_pps.h"
|
||||
#include "nvmisc.h"
|
||||
#include "displayport/displayport.h"
|
||||
#include "displayport/displayport2x.h"
|
||||
#include "nvctassert.h"
|
||||
#include <stddef.h>
|
||||
|
||||
@@ -104,6 +105,7 @@ typedef struct
|
||||
NvU32 multi_tile; // 1 = Multi-tile architecture, 0 = dsc single or dual mode without multi-tile
|
||||
NvU32 peak_throughput_mode0; // peak throughput supported by the sink for 444 and simple 422 modes.
|
||||
NvU32 peak_throughput_mode1; // peak throughput supported by the sink for native 422 and 420 modes.
|
||||
NvU32 eDP; // 1 = connector type is eDP, 0 otherwise.
|
||||
} DSC_INPUT_PARAMS;
|
||||
|
||||
//output pps parameters after calculation
|
||||
@@ -989,7 +991,6 @@ DSC_PpsCalcBase
|
||||
out->pps_identifier = 0;
|
||||
ENUM3_CHECK("bits_per_component", in->bits_per_component, 8, 10, 12);
|
||||
out->bits_per_component = in->bits_per_component;
|
||||
RANGE_CHECK("bits_per_pixelx16", in->bits_per_pixel, 8 * BPP_UNIT, (out->bits_per_component * 3) * BPP_UNIT);
|
||||
out->bits_per_pixel = in->bits_per_pixel;
|
||||
RANGE_CHECK("linebuf_depth", in->linebuf_depth, DSC_DECODER_LINE_BUFFER_BIT_DEPTH_MIN, DSC_DECODER_LINE_BUFFER_BIT_DEPTH_MAX);
|
||||
out->linebuf_depth = in->linebuf_depth;
|
||||
@@ -1598,22 +1599,74 @@ DSC_PpsCheckSliceHeight(DSC_OUTPUT_PARAMS *out)
|
||||
* NVT_STATUS_ERR if unsuccessful;
|
||||
*/
|
||||
static NVT_STATUS
|
||||
Dsc_PpsCalcHeight(DSC_OUTPUT_PARAMS *out)
|
||||
Dsc_PpsCalcHeight
|
||||
(
|
||||
const DSC_INPUT_PARAMS *in,
|
||||
DSC_OUTPUT_PARAMS *out
|
||||
)
|
||||
{
|
||||
if(out->slice_height == 0)
|
||||
//
|
||||
// From Blackwell and later, eDP we will try to use smallest slice height
|
||||
// if client has not asked for a specific slice height. Multi-tile is enabled
|
||||
// from Blackwell and so here we will use that condition for deciding on
|
||||
// slice height calculation. Minimum slice height will help with power savings
|
||||
// when eDP1.5 Selective Update is enabled.
|
||||
//
|
||||
if (in->multi_tile && in->eDP)
|
||||
{
|
||||
NvU32 i;
|
||||
for (i = 1 ; i <= 16; i++)
|
||||
if (out->slice_height == 0U)
|
||||
{
|
||||
out->slice_height = out->pic_height / i;
|
||||
if (out->pic_height != out->slice_height * i )
|
||||
continue;
|
||||
// Minimum area of slice should be 15000 as per VESA spec
|
||||
out->slice_height = (NvU32)NV_CEIL(15000U,(out->slice_width));
|
||||
while (out->pic_height > out->slice_height)
|
||||
{
|
||||
if (out->pic_height % out->slice_height == 0U)
|
||||
{
|
||||
if (DSC_PpsCheckSliceHeight(out) == NVT_STATUS_SUCCESS)
|
||||
{
|
||||
return NVT_STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
out->slice_height++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
out->slice_height++;
|
||||
}
|
||||
|
||||
if (DSC_PpsCheckSliceHeight(out) == NVT_STATUS_SUCCESS)
|
||||
return NVT_STATUS_SUCCESS;
|
||||
if (out->pic_height == out->slice_height)
|
||||
{
|
||||
if(DSC_PpsCheckSliceHeight(out) == NVT_STATUS_SUCCESS)
|
||||
{
|
||||
return NVT_STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NVT_STATUS_PPS_SLICE_HEIGHT_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(out->slice_height == 0)
|
||||
{
|
||||
NvU32 i;
|
||||
for (i = 1 ; i <= 16; i++)
|
||||
{
|
||||
out->slice_height = out->pic_height / i;
|
||||
if (out->pic_height != out->slice_height * i )
|
||||
continue;
|
||||
|
||||
if (DSC_PpsCheckSliceHeight(out) == NVT_STATUS_SUCCESS)
|
||||
return NVT_STATUS_SUCCESS;
|
||||
}
|
||||
// Error! can't find valid slice_height
|
||||
return NVT_STATUS_PPS_SLICE_HEIGHT_ERROR;
|
||||
}
|
||||
// Error! can't find valid slice_height
|
||||
return NVT_STATUS_PPS_SLICE_HEIGHT_ERROR;
|
||||
}
|
||||
|
||||
RANGE_CHECK("slice_height", out->slice_height, 8, out->pic_height);
|
||||
@@ -1677,7 +1730,7 @@ DSC_PpsCalc
|
||||
if (ret != NVT_STATUS_SUCCESS) return ret;
|
||||
ret = DSC_PpsCalcRcInitValue(out);
|
||||
if (ret != NVT_STATUS_SUCCESS) return ret;
|
||||
ret = Dsc_PpsCalcHeight(out);
|
||||
ret = Dsc_PpsCalcHeight(in, out);
|
||||
if (ret != NVT_STATUS_SUCCESS) return ret;
|
||||
ret = DSC_PpsCalcRcParam(out);
|
||||
return ret;
|
||||
@@ -1842,9 +1895,14 @@ _validateInput
|
||||
(pDscInfo->forcedDscParams.sliceCount != 1U) &&
|
||||
(pDscInfo->forcedDscParams.sliceCount != 2U) &&
|
||||
(pDscInfo->forcedDscParams.sliceCount != 4U) &&
|
||||
(pDscInfo->forcedDscParams.sliceCount != 8U))
|
||||
(pDscInfo->forcedDscParams.sliceCount != 8U) &&
|
||||
(pDscInfo->forcedDscParams.sliceCount != 10U) &&
|
||||
(pDscInfo->forcedDscParams.sliceCount != 12U) &&
|
||||
(pDscInfo->forcedDscParams.sliceCount != 16U) &&
|
||||
(pDscInfo->forcedDscParams.sliceCount != 20U) &&
|
||||
(pDscInfo->forcedDscParams.sliceCount != 24U))
|
||||
{
|
||||
// ERROR - Forced Slice Count has to be 1/2/4/8.
|
||||
// ERROR - Forced Slice Count has to be 1/2/4/8/10/12/16/20/24.
|
||||
return NVT_STATUS_DSC_SLICE_ERROR;
|
||||
}
|
||||
|
||||
@@ -2013,7 +2071,7 @@ _validateInput
|
||||
return NVT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!IS_VALID_LINKBW(pWARData->dpData.linkRateHz / DP_LINK_BW_FREQ_MULTI_MBPS))
|
||||
if (!IS_VALID_DP2_X_LINKBW(pWARData->dpData.linkRateHz))
|
||||
{
|
||||
// ERROR - Incorrect DP Link rate info sent with WAR data
|
||||
return NVT_STATUS_INVALID_PARAMETER;
|
||||
@@ -2084,7 +2142,6 @@ DSC_GeneratePPSWithSliceCountMask
|
||||
NvU32 sliceArrayCount;
|
||||
NvU32 i;
|
||||
DSC_INFO localDscInfo;
|
||||
NvU32* ppsOut = NULL;
|
||||
NVT_STATUS status;
|
||||
DSC_GENERATE_PPS_OPAQUE_WORKAREA scratchBuffer;
|
||||
|
||||
@@ -2166,27 +2223,19 @@ DSC_GeneratePPSWithSliceCountMask
|
||||
//
|
||||
if (possibleSliceCountMask)
|
||||
{
|
||||
NvU32 minSliceCountOut = 0;
|
||||
localDscInfo = *pDscInfo;
|
||||
|
||||
for(i = 0U ; i < sliceArrayCount; i++)
|
||||
{
|
||||
if (possibleSliceCountMask & DSC_SliceCountMaskforSliceNum(validSliceNum[i]))
|
||||
{
|
||||
ppsOut = NULL;
|
||||
// Use the forced bits per pixel, if any
|
||||
NvU32 bitsPerPixelX16Local = *pBitsPerPixelX16;
|
||||
localDscInfo.forcedDscParams.sliceCount = validSliceNum[i];
|
||||
if (localDscInfo.forcedDscParams.sliceCount == minSliceCount)
|
||||
{
|
||||
//
|
||||
// We need to return PPS with minimum slice count if client
|
||||
// has not forced any slice count even though we generate
|
||||
// pps with all other possible slice counts to validate them.
|
||||
//
|
||||
ppsOut = pps;
|
||||
}
|
||||
status = DSC_GeneratePPS(&localDscInfo, pModesetInfo, pWARData,
|
||||
availableBandwidthBitsPerSecond, &scratchBuffer,
|
||||
ppsOut, pBitsPerPixelX16);
|
||||
|
||||
NULL, &bitsPerPixelX16Local);
|
||||
if (status == NVT_STATUS_SUCCESS)
|
||||
{
|
||||
//
|
||||
@@ -2200,9 +2249,30 @@ DSC_GeneratePPSWithSliceCountMask
|
||||
// corresponding bit index.
|
||||
//
|
||||
validSliceCountMask |= NVBIT32((validSliceNum[i]) - 1U);
|
||||
if ((minSliceCountOut == 0) || (minSliceCountOut > validSliceNum[i]))
|
||||
{
|
||||
minSliceCountOut = validSliceNum[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (minSliceCountOut != 0)
|
||||
{
|
||||
//
|
||||
// We need to return PPS with minimum slice count if client
|
||||
// has not forced any slice count even though we generate
|
||||
// pps with all other possible slice counts to validate them.
|
||||
//
|
||||
localDscInfo.forcedDscParams.sliceCount = minSliceCountOut;
|
||||
status = DSC_GeneratePPS(&localDscInfo, pModesetInfo, pWARData,
|
||||
availableBandwidthBitsPerSecond, &scratchBuffer,
|
||||
pps, pBitsPerPixelX16);
|
||||
if (status != NVT_STATUS_SUCCESS)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2390,7 +2460,14 @@ DSC_GeneratePPS
|
||||
|
||||
dscOverhead = minSliceCount * 2U;
|
||||
|
||||
dataRate = pWARData->dpData.linkRateHz;
|
||||
if(pWARData->dpData.bIs128b132bChannelCoding)
|
||||
{
|
||||
dataRate = LINK_RATE_TO_DATA_RATE_128B_132B(pWARData->dpData.linkRateHz);
|
||||
}
|
||||
else
|
||||
{
|
||||
dataRate = LINK_RATE_TO_DATA_RATE_8B_10B(pWARData->dpData.linkRateHz);
|
||||
}
|
||||
if ((pWARData->dpData.hBlank * dataRate / pModesetInfo->pixelClockHz) <
|
||||
(protocolOverhead + dscOverhead + 3U))
|
||||
{
|
||||
@@ -2408,6 +2485,7 @@ DSC_GeneratePPS
|
||||
in->bits_per_pixel = i;
|
||||
}
|
||||
}
|
||||
in->eDP = (pWARData->dpData.bIsEdp == NV_TRUE) ? 1 : 0;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -253,11 +253,13 @@ typedef struct
|
||||
NvU32 laneCount;
|
||||
DSC_DP_MODE dpMode;
|
||||
NvU32 hBlank;
|
||||
NvBool bIsEdp;
|
||||
NvBool bIs128b132bChannelCoding;
|
||||
}dpData;
|
||||
} WAR_DATA;
|
||||
|
||||
typedef struct {
|
||||
NvU8 data[496U]; // total size of DSC_IN/OUTPUT_PARAMS
|
||||
NvU8 data[500U]; // total size of DSC_IN/OUTPUT_PARAMS
|
||||
} DSC_GENERATE_PPS_OPAQUE_WORKAREA;
|
||||
|
||||
/*
|
||||
|
||||
@@ -38,7 +38,7 @@ PUSH_SEGMENTS
|
||||
|
||||
// Macro to declare a TIMING initializer for given parameters without border
|
||||
#define EST_TIMING(hv,hfp,hsw,ht,hsp,vv,vfp,vsw,vt,vsp,rr,pclk,format) \
|
||||
{hv,0,hfp,hsw,ht,(hsp)=='-',vv,0,vfp,vsw,vt,(vsp)=='-',NVT_PROGRESSIVE,pclk,{0,rr,set_rrx1k(pclk,ht,vt),0,1,{0},{0},{0},{0},format,"VESA Established"}}
|
||||
{hv,0,hfp,hsw,ht,(hsp)=='-',vv,0,vfp,vsw,vt,(vsp)=='-',NVT_PROGRESSIVE,pclk,((pclk<<3)+(pclk<<1)),{0,rr,set_rrx1k(pclk,ht,vt),0,1,{0},{0},{0},{0},format,"VESA Established"}}
|
||||
|
||||
DATA_SEGMENT(PAGE_DATA)
|
||||
#if !defined(NV_WSA)
|
||||
@@ -53,12 +53,12 @@ static const NVT_TIMING EDID_EST[] =
|
||||
{
|
||||
EST_TIMING( 720, 0, 0, 720,'-', 400, 0,0, 400,'-',70, 0,NVT_STATUS_EDID_EST), // 720x400x70Hz (IBM, VGA)
|
||||
EST_TIMING( 720, 0, 0, 720,'-', 400, 0,0, 400,'-',88, 0,NVT_STATUS_EDID_EST), // 720x400x88Hz (IBM, XGA2)
|
||||
{640,0,16,96,800,NVT_H_SYNC_NEGATIVE,480,0,10,2,525,NVT_V_SYNC_NEGATIVE,NVT_PROGRESSIVE,2518,{0,60,60000,0,1,{0},{0},{0},{0},NVT_STATUS_EDID_EST,"EDID_Established"}},
|
||||
{640,0,16,96,800,NVT_H_SYNC_NEGATIVE,480,0,10,2,525,NVT_V_SYNC_NEGATIVE,NVT_PROGRESSIVE,2518,25180,{0,60,60000,0,1,{0},{0},{0},{0},NVT_STATUS_EDID_EST,"EDID_Established"}},
|
||||
|
||||
EST_TIMING( 640, 0, 0, 640,'-', 480, 0,0, 480,'-',67, 0,NVT_STATUS_EDID_EST), // 640x480x67Hz (Apple, Mac II)
|
||||
|
||||
// 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_STATUS_EDID_EST,"EDID_Established"}},
|
||||
{640,8,16,40,832,NVT_H_SYNC_NEGATIVE,480,8,1,3,520,NVT_V_SYNC_NEGATIVE,NVT_PROGRESSIVE,3150,31500,{0,72,72000,0,1,{0},{0},{0},{0},NVT_STATUS_EDID_EST,"EDID_Established"}},
|
||||
EST_TIMING( 640,16, 64, 840,'-', 480, 1,3, 500,'-',75, 3150,NVT_STATUS_EDID_EST), // 640x480x75Hz (VESA)
|
||||
EST_TIMING( 800,24, 72,1024,'+', 600, 1,2, 625,'+',56, 3600,NVT_STATUS_EDID_EST), // 800x600x56Hz (VESA)
|
||||
EST_TIMING( 800,40,128,1056,'+', 600, 1,4, 628,'+',60, 4000,NVT_STATUS_EDID_EST), // 800x600x60Hz (VESA)
|
||||
@@ -564,7 +564,8 @@ NVT_STATUS parseEdidDetailedTimingDescriptor(NvU8 *p, NVT_TIMING *pT)
|
||||
pT->VSyncWidth = (NvU16)((pDTD->bDTVerticalSync & 0x0F) + ((pDTD->bDTHorizVertSyncOverFlow & 0x03) << 4));
|
||||
|
||||
// pixel clock
|
||||
pT->pclk = (NvU32)pDTD->wDTPixelClock;
|
||||
pT->pclk = (NvU32)pDTD->wDTPixelClock;
|
||||
pT->pclk1khz = (NvU32)((pT->pclk << 3) + (pT->pclk << 1));
|
||||
|
||||
// sync polarities
|
||||
if ((pDTD->bDTFlags & 0x18) == 0x18)
|
||||
@@ -2964,7 +2965,7 @@ NvU32 NvTiming_CalculateCommonEDIDCRC32(NvU8* pEDIDBuffer, NvU32 edidVersion)
|
||||
CommonEDIDBuffer[0x7F] = 0;
|
||||
CommonEDIDBuffer[0xFF] = 0;
|
||||
|
||||
// We also need to zero out any "EDID Other Monitor Descriptors" (http://en.wikipedia.org/wiki/Extended_display_identification_data)
|
||||
// We also need to zero out any "EDID Other Monitor Descriptors" (https://en.wikipedia.org/wiki/Extended_display_identification_data)
|
||||
for (edidBufferIndex = 54; edidBufferIndex <= 108; edidBufferIndex += 18)
|
||||
{
|
||||
if (CommonEDIDBuffer[edidBufferIndex] == 0 && CommonEDIDBuffer[edidBufferIndex+1] == 0)
|
||||
|
||||
@@ -38,15 +38,15 @@ PUSH_SEGMENTS
|
||||
|
||||
#define EIA_TIMING(hv,hfp,hsw,ht,hsp,vv,vfp,vsw,vt,vsp,rrx1k,ip,aspect,rep,format) \
|
||||
{hv,0,hfp,hsw,ht,(hsp)=='-',vv,0,vfp,vsw,vt,(vsp)=='-',(ip)=='i' ? NVT_INTERLACED:NVT_PROGRESSIVE,\
|
||||
0,{0,((rrx1k)+500)/1000,rrx1k,((1?aspect)<<16)|(0?aspect),rep,{0},{0},{0},{0},NVT_STATUS_EDID_861STn(format),"CEA-861B:#"#format""}}
|
||||
0,0,{0,((rrx1k)+500)/1000,rrx1k,((1?aspect)<<16)|(0?aspect),rep,{0},{0},{0},{0},NVT_STATUS_EDID_861STn(format),"CEA-861B:#"#format""}}
|
||||
|
||||
#define NVT_TIMING(hv,hfp,hsw,ht,hsp,vv,vfp,vsw,vt,vsp,rrx1k,ip,aspect,rep,format,name) \
|
||||
{hv,0,hfp,hsw,ht,(hsp)=='-',vv,0,vfp,vsw,vt,(vsp)=='-',(ip)=='i' ? NVT_INTERLACED:NVT_PROGRESSIVE,\
|
||||
0,{0,((rrx1k)+500)/1000,rrx1k,((1?aspect)<<16)|(0?aspect),rep,{0},{0},{0},{0},NVT_TYPE_NV_PREDEFINEDn(format),name}}
|
||||
0,0,{0,((rrx1k)+500)/1000,rrx1k,((1?aspect)<<16)|(0?aspect),rep,{0},{0},{0},{0},NVT_TYPE_NV_PREDEFINEDn(format),name}}
|
||||
|
||||
#define HDMI_EXT_TIMING(hv,hfp,hsw,ht,hsp,vv,vfp,vsw,vt,vsp,rrx1k,ip,aspect,rep,format,name) \
|
||||
{hv,0,hfp,hsw,ht,(hsp)=='-',vv,0,vfp,vsw,vt,(vsp)=='-',(ip)=='i' ? NVT_INTERLACED:NVT_PROGRESSIVE,\
|
||||
0,{0,((rrx1k)+500)/1000,rrx1k,((1?aspect)<<16)|(0?aspect),rep,{0},{0},{0},{0},NVT_STATUS_HDMI_EXTn(format),name}}
|
||||
0,0,{0,((rrx1k)+500)/1000,rrx1k,((1?aspect)<<16)|(0?aspect),rep,{0},{0},{0},{0},NVT_STATUS_HDMI_EXTn(format),name}}
|
||||
|
||||
#define RID_MODE(hv, hsp, vv, vsp, ip, aspect, rid) \
|
||||
{hv, (hsp)=='-', vv, (vsp)=='-',(ip)=='i'? NVT_INTERLACED:NVT_PROGRESSIVE,((1?aspect)<<16)|(0?aspect), rid}
|
||||
@@ -261,7 +261,7 @@ static const NVT_TIMING EIA861B[]=
|
||||
EIA_TIMING( 7680,2352,176,10800,'+',4320,16,20,4400,'+', 50000,'p', 16:9,0x1,198),// 7680 x 4320p @50 (Format 198)
|
||||
EIA_TIMING( 7680, 552,176, 9000,'+',4320,16,20,4400,'+', 59940,'p', 16:9,0x1,199),// 7680 x 4320p @59.94/60 (Format 199)
|
||||
EIA_TIMING( 7680,2112,176,10560,'+',4320,16,20,4500,'+',100000,'p', 16:9,0x1,200),// 7680 x 4320p @100 (Format 200)
|
||||
EIA_TIMING( 7680, 352,176, 8000,'+',4320,16,20,4500,'+',119880,'p', 16:9,0x1,201),// 7680 x 4320p @119.88/120 (Format 201)
|
||||
EIA_TIMING( 7680, 352,176, 8800,'+',4320,16,20,4500,'+',119880,'p', 16:9,0x1,201),// 7680 x 4320p @119.88/120 (Format 201)
|
||||
EIA_TIMING( 7680,2552,176,11000,'+',4320,16,20,4500,'+', 23976,'p', 64:27,0x1,202),// 7680 x 4320p @23.98/24 (Format 202)
|
||||
EIA_TIMING( 7680,2352,176,10800,'+',4320,16,20,4400,'+', 25000,'p', 64:27,0x1,203),// 7680 x 4320p @25 (Format 203)
|
||||
EIA_TIMING( 7680, 552,176, 9000,'+',4320,16,20,4400,'+', 29970,'p', 64:27,0x1,204),// 7680 x 4320p @29.97/30 (Format 204)
|
||||
@@ -269,12 +269,12 @@ static const NVT_TIMING EIA861B[]=
|
||||
EIA_TIMING( 7680,2352,176,10800,'+',4320,16,20,4400,'+', 50000,'p', 64:27,0x1,206),// 7680 x 4320p @50 (Format 206)
|
||||
EIA_TIMING( 7680, 552,176, 9000,'+',4320,16,20,4400,'+', 59940,'p', 64:27,0x1,207),// 7680 x 4320p @59.94/60 (Format 207)
|
||||
EIA_TIMING( 7680,2112,176,10560,'+',4320,16,20,4500,'+',100000,'p', 64:27,0x1,208),// 7680 x 4320p @100 (Format 208)
|
||||
EIA_TIMING( 7680, 352,176, 8800,'+',4500,16,20,4950,'+',119880,'p', 64:27,0x1,209),// 7680 x 4320p @119.88/120 (Format 209)
|
||||
EIA_TIMING( 7680, 352,176, 8800,'+',4320,16,20,4500,'+',119880,'p', 64:27,0x1,209),// 7680 x 4320p @119.88/120 (Format 209)
|
||||
EIA_TIMING(10240,1492,176,12500,'+',4320,16,20,4950,'+', 23976,'p', 64:27,0x1,210),//10240 x 4320p @23.98/24 (Format 210)
|
||||
EIA_TIMING(10240,2492,176,13500,'+',4320,16,20,4400,'+', 25000,'p', 64:27,0x1,211),//10240 x 4320p @25 (Format 211)
|
||||
EIA_TIMING(10240, 288,176,11000,'+',4320,16,20,4500,'+', 29970,'p', 64:27,0x1,212),//10240 x 4320p @29.97/30 (Format 212)
|
||||
EIA_TIMING(10240,1492,176,12500,'+',4320,16,20,4950,'+', 47950,'p', 64:27,0x1,213),//10240 x 4320p @47.95/48 (Format 213)
|
||||
EIA_TIMING(10240,2492,176,13500,'+',4320,16,20,4400,'+', 44000,'p', 64:27,0x1,214),//10240 x 4320p @50 (Format 214)
|
||||
EIA_TIMING(10240,2492,176,13500,'+',4320,16,20,4400,'+', 50000,'p', 64:27,0x1,214),//10240 x 4320p @50 (Format 214)
|
||||
EIA_TIMING(10240, 288,176,11000,'+',4320,16,20,4500,'+', 59940,'p', 64:27,0x1,215),//10240 x 4320p @59.94/60 (Format 215)
|
||||
EIA_TIMING(10240,2192,176,13200,'+',4320,16,20,4500,'+',100000,'p', 64:27,0x1,216),//10240 x 4320p @100 (Format 216)
|
||||
EIA_TIMING(10240, 288,176,11000,'+',4320,16,20,4500,'+',119880,'p', 64:27,0x1,217),//10240 x 4320p @119.88/120 (Format 217)
|
||||
@@ -649,7 +649,8 @@ void parse861bShortTiming(NVT_EDID_CEA861_INFO *pExt861,
|
||||
}
|
||||
|
||||
// calculate the pixel clock
|
||||
newTiming.pclk = RRx1kToPclk(&newTiming);
|
||||
newTiming.pclk = RRx1kToPclk(&newTiming);
|
||||
newTiming.pclk1khz = (newTiming.pclk << 3) + (newTiming.pclk << 1); // *10
|
||||
|
||||
if ((vic <= 64) && (pVic[i] & NVT_CTA861_VIDEO_NATIVE_MASK))
|
||||
{
|
||||
@@ -790,7 +791,8 @@ void parseCta861VideoFormatDataBlock(NVT_EDID_CEA861_INFO *pExt861, void *pRawIn
|
||||
pInfo->hdmiForumInfo.dc_48bit_420);
|
||||
}
|
||||
|
||||
newTiming.etc.flag |= NVT_FLAG_CTA_OVT_TIMING;
|
||||
newTiming.etc.aspect = RID[pVFDOneByte->rid].aspect;
|
||||
newTiming.etc.flag |= NVT_FLAG_CTA_OVT_TIMING;
|
||||
if (pExt861->vfdb[vfdb_idx].info.ntsc)
|
||||
{
|
||||
newTiming.etc.flag |= NVT_FLAG_CTA_OVT_FRR_TIMING;
|
||||
@@ -924,7 +926,8 @@ void parse861bShortYuv420Timing(NVT_EDID_CEA861_INFO *pExt861,
|
||||
}
|
||||
|
||||
// calculate the pixel clock
|
||||
newTiming.pclk = RRx1kToPclk(&newTiming);
|
||||
newTiming.pclk = RRx1kToPclk(&newTiming);
|
||||
newTiming.pclk1khz = (newTiming.pclk << 3) + (newTiming.pclk << 1); // *10
|
||||
|
||||
// From CTA-861-F: By default, Y420VDB SVDs, when present in the EDID, shall be less preferred than all regular Video Data Block SVDs.
|
||||
// So it should use normal VIC code without native flag.
|
||||
@@ -2161,7 +2164,8 @@ NVT_STATUS NvTiming_EnumCEA861bTiming(NvU32 ceaFormat, NVT_TIMING *pT)
|
||||
*pT = EIA861B[ceaFormat - 1];
|
||||
|
||||
// calculate the pixel clock
|
||||
pT->pclk = RRx1kToPclk (pT);
|
||||
pT->pclk = RRx1kToPclk (pT);
|
||||
pT->pclk1khz = (pT->pclk << 3) + (pT->pclk << 1); // *10
|
||||
NVT_SET_CEA_FORMAT(pT->etc.status, ceaFormat);
|
||||
|
||||
NVT_SNPRINTF((char *)pT->etc.name, sizeof(pT->etc.name), "CTA-861G:#%3d:%dx%dx%3d.%03dHz/%s", (int)ceaFormat, (int)pT->HVisible, (int)((pT->interlaced ? 2 : 1)*pT->VVisible), (int)pT->etc.rrx1k/1000, (int)pT->etc.rrx1k%1000, (pT->interlaced ? "I":"P"));
|
||||
@@ -2270,7 +2274,8 @@ NVT_STATUS NvTiming_CalcCEA861bTiming(NvU32 width, NvU32 height, NvU32 rr, NvU32
|
||||
*pT = EIA861B[i];
|
||||
|
||||
// calculate the pixel clock
|
||||
pT->pclk = RRx1kToPclk (pT);
|
||||
pT->pclk = RRx1kToPclk (pT);
|
||||
pT->pclk1khz = (pT->pclk << 3) + (pT->pclk << 1); // *10
|
||||
|
||||
NVT_SET_CEA_FORMAT(pT->etc.status, NVT_GET_TIMING_STATUS_SEQ(pT->etc.status));
|
||||
|
||||
@@ -2336,8 +2341,8 @@ NVT_STATUS NvTiming_ConstructVideoInfoframeCtrl(const NVT_TIMING *pTiming, NVT_V
|
||||
ridIdx = 10 * (pTiming->etc.name[10] - '0') + (pTiming->etc.name[11] - '0');
|
||||
}
|
||||
|
||||
if (ridIdx > NVT_CTA861_RID_1280x720p_16x9 &&
|
||||
ridIdx < NVT_CTA861_RID_20480x8640p_64x27)
|
||||
if (ridIdx >= NVT_CTA861_RID_1280x720p_16x9 &&
|
||||
ridIdx < NVT_CTA861_RID_EXCEED_RESOLUTION)
|
||||
{
|
||||
pCtrl->rid = ridIdx;
|
||||
}
|
||||
@@ -2472,7 +2477,7 @@ NVT_STATUS NvTiming_ConstructVideoInfoframeCtrl(const NVT_TIMING *pTiming, NVT_V
|
||||
}
|
||||
else
|
||||
{
|
||||
// default to no data, to cover other non-cea modes
|
||||
// default to no data if there is no match, to cover other non-cta modes
|
||||
pCtrl->pic_aspect_ratio = NVT_VIDEO_INFOFRAME_BYTE2_M1M0_NO_DATA;
|
||||
}
|
||||
}
|
||||
@@ -2839,13 +2844,13 @@ NVT_STATUS NvTiming_ConstructVendorSpecificInfoframe(NVT_EDID_INFO *pEdidInfo, N
|
||||
nvt_nvu8_set_bits(pInfoFrame->Header.version, NVT_HDMI_VS_HB1_VALUE, NVT_HDMI_VS_HB1_MASK, NVT_HDMI_VS_HB1_SHIFT);
|
||||
nvt_nvu8_set_bits(pInfoFrame->Header.length, NVT_HDMI_VS_HB2_VALUE, NVT_HDMI_VS_HB2_MASK, NVT_HDMI_VS_HB2_SHIFT);
|
||||
|
||||
if (pCtrl->HDMIRevision == 14)
|
||||
if (pCtrl->VSIFVersion == NVT_VSIF_VERSION_H14B_VSIF)
|
||||
{
|
||||
nvt_nvu8_set_bits(pInfoFrame->Data.byte1, NVT_HDMI_VS_BYTE1_OUI_VER_1_4, NVT_HDMI_VS_BYTE1_OUI_MASK, NVT_HDMI_VS_BYTE1_OUI_SHIFT);
|
||||
nvt_nvu8_set_bits(pInfoFrame->Data.byte2, NVT_HDMI_VS_BYTE2_OUI_VER_1_4, NVT_HDMI_VS_BYTE2_OUI_MASK, NVT_HDMI_VS_BYTE2_OUI_SHIFT);
|
||||
nvt_nvu8_set_bits(pInfoFrame->Data.byte3, NVT_HDMI_VS_BYTE3_OUI_VER_1_4, NVT_HDMI_VS_BYTE3_OUI_MASK, NVT_HDMI_VS_BYTE3_OUI_SHIFT);
|
||||
}
|
||||
else if (pCtrl->HDMIRevision >= 20)
|
||||
else if (pCtrl->VSIFVersion == NVT_VSIF_VERSION_HF_VSIF)
|
||||
{
|
||||
nvt_nvu8_set_bits(pInfoFrame->Data.byte1, NVT_HDMI_VS_BYTE1_OUI_VER_2_0, NVT_HDMI_VS_BYTE1_OUI_MASK, NVT_HDMI_VS_BYTE1_OUI_SHIFT);
|
||||
nvt_nvu8_set_bits(pInfoFrame->Data.byte2, NVT_HDMI_VS_BYTE2_OUI_VER_2_0, NVT_HDMI_VS_BYTE2_OUI_MASK, NVT_HDMI_VS_BYTE2_OUI_SHIFT);
|
||||
@@ -3106,7 +3111,7 @@ void NvTiming_ConstructAdaptiveSyncSDP(
|
||||
NVT_DP_ADAPTIVE_SYNC_SDP_DB3_TARGET_RR_LSB_MASK,
|
||||
NVT_DP_ADAPTIVE_SYNC_SDP_DB3_TARGET_RR_LSB_SHIFT);
|
||||
|
||||
nvt_nvu8_set_bits(pSdp->payload.db4, pCtrl->targetRefreshRate & 0x1,
|
||||
nvt_nvu8_set_bits(pSdp->payload.db4, (pCtrl->targetRefreshRate & 0x300) >> 8,
|
||||
NVT_DP_ADAPTIVE_SYNC_SDP_DB4_TARGET_RR_MSB_MASK,
|
||||
NVT_DP_ADAPTIVE_SYNC_SDP_DB4_TARGET_RR_MSB_SHIFT);
|
||||
}
|
||||
@@ -3158,7 +3163,8 @@ NVT_STATUS NvTiming_EnumNvPsfTiming(NvU32 nvPsfFormat, NVT_TIMING *pT)
|
||||
*pT = PSF_TIMING[nvPsfFormat - 1];
|
||||
|
||||
// calculate the pixel clock
|
||||
pT->pclk = RRx1kToPclk (pT);
|
||||
pT->pclk = RRx1kToPclk (pT);
|
||||
pT->pclk1khz = (pT->pclk << 3) + (pT->pclk << 1); // *10
|
||||
|
||||
return NVT_STATUS_SUCCESS;
|
||||
}
|
||||
@@ -3267,7 +3273,9 @@ void NvTiming_GetHDMIStereoTimingFrom2DTiming(const NVT_TIMING *pTiming, NvU8 St
|
||||
}
|
||||
}
|
||||
// calculate the pixel clock
|
||||
pExtTiming->timing.pclk = RRx1kToPclk (&(pExtTiming->timing));
|
||||
pExtTiming->timing.pclk = RRx1kToPclk (&(pExtTiming->timing));
|
||||
pExtTiming->timing.pclk1khz = (pExtTiming->timing.pclk << 3) + (pExtTiming->timing.pclk << 1); // *10;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3491,7 +3499,8 @@ void parseEdidHDMILLCTiming(NVT_EDID_INFO *pInfo, VSDB_DATA *pVsdb, NvU32 *pMapS
|
||||
sizeof(newTiming));
|
||||
|
||||
// Fill in the pixel clock
|
||||
newTiming.pclk = RRx1kToPclk(&newTiming);
|
||||
newTiming.pclk = RRx1kToPclk(&newTiming);
|
||||
newTiming.pclk1khz = (newTiming.pclk << 3) + (newTiming.pclk << 1); // *10
|
||||
|
||||
if (!assignNextAvailableTiming(pInfo, &newTiming))
|
||||
{
|
||||
@@ -3638,7 +3647,8 @@ NVT_STATUS NvTiming_EnumHdmiVsdbExtendedTiming(NvU32 hdmi_vic, NVT_TIMING *pT)
|
||||
return NVT_STATUS_ERR;
|
||||
}
|
||||
*pT = HDMI_EXT_4Kx2K_TIMING[hdmi_vic - 1];
|
||||
pT->pclk = RRx1kToPclk(pT);
|
||||
pT->pclk = RRx1kToPclk(pT);
|
||||
pT->pclk1khz = (pT->pclk << 3) + (pT->pclk << 1); // *10
|
||||
return NVT_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -264,6 +264,7 @@ NVT_STATUS NvTiming_CalcOVT(NvU32 width, NvU32 height, NvU32 refreshRate, NVT_TI
|
||||
pT->VSyncWidth = (NvU16)NVT_OVT_V_SYNC_WIDTH;
|
||||
pT->VFrontPorch = (NvU16)(vBlank - vSyncPosition);
|
||||
pT->pclk = (NvU32)(pixelClockRate /*Hz*/ / 1000 + 5) / 10; //convert to 10Khz
|
||||
pT->pclk1khz = (NvU32)(pixelClockRate /*Hz*/ / 1000); //convert to 1Khz
|
||||
pT->HSyncPol = NVT_H_SYNC_POSITIVE;
|
||||
pT->VSyncPol = NVT_V_SYNC_POSITIVE;
|
||||
pT->HBorder = pT->VBorder = 0; // not supported
|
||||
|
||||
@@ -37,24 +37,24 @@ 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,""}}
|
||||
{720, 0,21,66,894, NVT_H_SYNC_POSITIVE,240, 0,10, 6,262, NVT_V_SYNC_POSITIVE,NVT_INTERLACED, 1407 , 14070, {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 , 14070, {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 , 13970, {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 , 13970, {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 , 13970, {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 , 13970, {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 , 14070, {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 , 27000, {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 , 13970, {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 , 27000, {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 , 74180, {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 , 74180, {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,148350, {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 , 74250, {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 , 74250, {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 , 74250, {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 ,148500, {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},0,""}}
|
||||
};
|
||||
|
||||
//***********************************************
|
||||
|
||||
@@ -343,9 +343,9 @@ NvU32 NvTiming_IsTimingRelaxedEqual(const NVT_TIMING *pT1, const NVT_TIMING *pT2
|
||||
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));
|
||||
return (NvU32)axb_div_c_64(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)
|
||||
|
||||
@@ -189,6 +189,7 @@ typedef struct tagNVT_TIMING
|
||||
|
||||
NvU16 interlaced; //1-interlaced, 0-progressive
|
||||
NvU32 pclk; //pixel clock in 10KHz
|
||||
NvU32 pclk1khz; //pixel clock in 1kHz for Type7, CVT RB2, CVT RB3
|
||||
|
||||
//other timing related extras
|
||||
NVT_TIMINGEXT etc;
|
||||
@@ -774,6 +775,7 @@ typedef enum NVT_TV_FORMAT
|
||||
#define NVT_CTA861_RID_15360x8640p_16x9 26
|
||||
#define NVT_CTA861_RID_15360x8640p_64x27 27
|
||||
#define NVT_CTA861_RID_20480x8640p_64x27 28
|
||||
#define NVT_CTA861_RID_EXCEED_RESOLUTION NVT_CTA861_RID_NONE
|
||||
|
||||
// Table 12 - AVI InfoFrame Video Format Frame Rate
|
||||
#define NVT_CTA861_FR_NO_DATA NVT_INFOFRAME_CTRL_DONTCARE
|
||||
@@ -3060,7 +3062,7 @@ typedef struct tagNVT_AUDIO_INFOFRAME_CTRL
|
||||
typedef struct tagNVT_VENDOR_SPECIFIC_INFOFRAME_CTRL
|
||||
{
|
||||
NvU8 Enable;
|
||||
NvU8 HDMIRevision;
|
||||
NvU8 VSIFVersion;
|
||||
NvU8 HDMIFormat;
|
||||
NvU8 HDMI_VIC;
|
||||
NvBool ALLMEnable;
|
||||
@@ -3073,6 +3075,10 @@ typedef struct tagNVT_VENDOR_SPECIFIC_INFOFRAME_CTRL
|
||||
} NVT_VENDOR_SPECIFIC_INFOFRAME_CTRL;
|
||||
#define NVT_3D_METADTATA_TYPE_PARALAX 0x00
|
||||
#define NVT_3D_METADTATA_PARALAX_LEN 0x08
|
||||
#define NVT_VSIF_VERSION_NONE 0
|
||||
#define NVT_VSIF_VERSION_H14B_VSIF 14
|
||||
#define NVT_VSIF_VERSION_HF_VSIF 20
|
||||
|
||||
|
||||
#define NVT_EXTENDED_METADATA_PACKET_INFOFRAME_VER_HDMI21 0x0
|
||||
#define NVT_EXTENDED_METADATA_PACKET_INFOFRAME_VER_HDMI21A 0x1
|
||||
@@ -3210,6 +3216,7 @@ typedef struct tagNVT_VIDEO_INFOFRAME
|
||||
#define NVT_VIDEO_INFOFRAME_BYTE1_Y2Y1Y0_YCbCr444 2
|
||||
#define NVT_VIDEO_INFOFRAME_BYTE1_Y2Y1Y0_YCbCr420 3
|
||||
#define NVT_VIDEO_INFOFRAME_BYTE1_Y2Y1Y0_FUTURE 3 // nvlEscape still uses this line 4266
|
||||
// CTA-861I new requirement
|
||||
#define NVT_VIDEO_INFOFRAME_BYTE1_Y2Y1Y0_IDODEFINED 7
|
||||
// CEA-861-F - Unix still used this one
|
||||
#define NVT_VIDEO_INFOFRAME_BYTE1_Y1Y0_MASK 0x60
|
||||
@@ -4005,7 +4012,7 @@ typedef struct tagNVT_EXTENDED_METADATA_PACKET_INFOFRAME
|
||||
#define NVT_DP_ADAPTIVE_SYNC_SDP_DB3_TARGET_RR_LSB_MASK 0xff
|
||||
#define NVT_DP_ADAPTIVE_SYNC_SDP_DB3_TARGET_RR_LSB_SHIFT 0
|
||||
|
||||
#define NVT_DP_ADAPTIVE_SYNC_SDP_DB4_TARGET_RR_MSB_MASK 0x01
|
||||
#define NVT_DP_ADAPTIVE_SYNC_SDP_DB4_TARGET_RR_MSB_MASK 0x03
|
||||
#define NVT_DP_ADAPTIVE_SYNC_SDP_DB4_TARGET_RR_MSB_SHIFT 0
|
||||
|
||||
#define NVT_DP_ADAPTIVE_SYNC_SDP_DB4_RSVD_MASK 0x1c
|
||||
|
||||
@@ -164,7 +164,7 @@ NvU32 axb_div_c_old(NvU32 a, NvU32 b, NvU32 c);
|
||||
|
||||
// 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}
|
||||
#define NVT_TIMING_SENTINEL {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,NVT_TIMINGEXT_SENTINEL}
|
||||
|
||||
#endif //__NVTIMING_PVT_H_
|
||||
|
||||
|
||||
Reference in New Issue
Block a user