580.95.05

This commit is contained in:
Maneet Singh
2025-09-30 12:52:14 -07:00
parent 87c0b12473
commit 2b436058a6
147 changed files with 56986 additions and 55176 deletions

View File

@@ -54,6 +54,7 @@ CFLAGS += -D__NO_CTYPE
CFLAGS += -DNV_CPU_INTRINSICS_KERNEL
CFLAGS += -DNVHDMIPKT_RM_CALLS_INTERNAL=0
CFLAGS += -DNVHDMIPKT_NVKMS
# XXX it would be nice to only define these for appropriate files...
CFLAGS += -DSOFTFLOAT_ROUND_ODD

View File

@@ -39,8 +39,6 @@ void nvDPNotifyShortPulse(NVDPLibConnectorPtr pNVDpLibConnector);
void nvDPDestroyConnector(NVDPLibConnectorPtr pNVDpLibConnector);
NvBool nvDPIsLinkAwaitingTransition(NVConnectorEvoPtr pConnectorEvo);
NVDPLibModesetStatePtr nvDPLibCreateModesetState(
const NVDispEvoRec *pDispEvo,
const NvU32 head,

View File

@@ -28,5 +28,6 @@
void nvHandleHotplugEventDeferredWork(void *dataPtr, NvU32 dataU32);
void nvHandleDPIRQEventDeferredWork(void *dataPtr, NvU32 dataU32);
void nvHandleHDMIFRLRetrainEventDeferredWork(void *dataPtr, NvU32 dataU32);
#endif /* __NVKMS_EVENT_H__ */

View File

@@ -61,14 +61,14 @@ void nvTeardownHdmiLibrary(NVDevEvoRec *pDevEvo);
NvBool nvHdmiFrlAssessLink(NVDpyEvoPtr pDpyEvo);
NvBool nvHdmiDpySupportsFrl(const NVDpyEvoRec *pDpyEvo);
NvBool nvHdmiFrlQueryConfig(const NVDpyEvoRec *pDpyEvo,
const NvModeTimings *pModeTimings,
const NVHwModeTimingsEvo *pHwTimings,
NVDpyAttributeColor *pDpyColor,
const NvBool b2Heads1Or,
const struct NvKmsModeValidationParams *pValidationParams,
HDMI_FRL_CONFIG *pConfig,
NVDscInfoEvoRec *pDscInfo);
NvBool nvHdmiFrlQueryConfigOneColorSpaceAndBpc(const NVDpyEvoRec *pDpyEvo,
const NvModeTimings *pModeTimings,
const NVHwModeTimingsEvo *pHwTimings,
const NVDpyAttributeColor *pDpyColor,
const NvBool b2Heads1Or,
const struct NvKmsModeValidationParams *pValidationParams,
HDMI_FRL_CONFIG *pConfig,
NVDscInfoEvoRec *pDscInfo);
void nvHdmiFrlClearConfig(NVDispEvoRec *pDispEvo, NvU32 activeRmId);
void nvHdmiFrlSetConfig(NVDispEvoRec *pDispEvo, NvU32 head);
@@ -80,6 +80,12 @@ NvBool nvHdmiIsTmdsPossible(const NVDpyEvoRec *pDpyEvo,
const NVHwModeTimingsEvo *pHwTimings,
const NVDpyAttributeColor *pDpyColor);
static inline NvBool nvHdmiIsFrlPossible(const NVDpyEvoRec *pDpyEvo)
{
return nvHdmiDpySupportsFrl(pDpyEvo) &&
(pDpyEvo->hdmi.sinkCaps.linkMaxFRLRate != HDMI_FRL_DATA_RATE_NONE);
}
static inline NvBool nvHdmiDpySupportsDsc(const NVDpyEvoRec *pDpyEvo)
{
return nvDpyIsHdmiEvo(pDpyEvo) &&

View File

@@ -277,7 +277,7 @@ typedef struct _NVHsChannelEvoRec {
*/
NVRgLine1CallbackPtr pRgIntrCallback;
#if NVKMS_PROCFS_ENABLE
#if NVKMS_HEADSURFACE_STATS
/*
* We track statistics differently for SwapGroup and non-SwapGroup
@@ -342,7 +342,7 @@ typedef struct _NVHsChannelEvoRec {
} statistics;
#else
#define NVKMS_HEADSURFACE_STATS_MAX_SEMAPHORES 0
#endif /* NVKMS_PROCFS_ENABLE */
#endif /* NVKMS_HEADSURFACE_STATS */
/*
* We need one semaphore for the non-stall interrupt following rendering to

View File

@@ -123,7 +123,7 @@ NVSurfaceEvoRec *nvHsGetNvKmsSurface(const NVDevEvoRec *pDevEvo,
NvKmsSurfaceHandle surfaceHandle,
const NvBool requireDisplayHardwareAccess);
#if NVKMS_PROCFS_ENABLE
#if NVKMS_HEADSURFACE_STATS
void nvHsProcFs(
NVEvoInfoStringRec *pInfoString,
NVDevEvoRec *pDevEvo,

View File

@@ -66,9 +66,13 @@ extern "C" {
#include "nv_smg.h"
#if defined(DEBUG) || defined(DEVELOP)
#define NVKMS_PROCFS_ENABLE 1
#define NVKMS_HEADSURFACE_STATS 1
#define NVKMS_PROCFS_OBJECT_DUMP 1
#define NVKMS_PROCFS_CRCS 1
#else
#define NVKMS_PROCFS_ENABLE 0
#define NVKMS_HEADSURFACE_STATS 0
#define NVKMS_PROCFS_OBJECT_DUMP 0
#define NVKMS_PROCFS_CRCS 0
#endif
#define NV_DMA_EVO_PUSH_BUFFER_SIZE (4 * 1024)
@@ -2041,8 +2045,10 @@ typedef struct _NVDispEvoRec {
NVDevEvoPtr pDevEvo;
NvU32 hotplugEventHandle;
NvU32 DPIRQEventHandle;
NvU32 HDMIFRLRetrainEventHandle;
NVOS10_EVENT_KERNEL_CALLBACK_EX rmHotplugCallback;
NVOS10_EVENT_KERNEL_CALLBACK_EX rmDPIRQCallback;
NVOS10_EVENT_KERNEL_CALLBACK_EX rmHDMIFRLRetrainCallback;
NVDispHeadStateEvoRec headState[NVKMS_MAX_HEADS_PER_DISP];
NVDispApiHeadStateEvoRec apiHeadState[NVKMS_MAX_HEADS_PER_DISP];
@@ -2296,6 +2302,8 @@ typedef struct _NVDpyEvoRec {
struct {
HDMI_SRC_CAPS srcCaps;
HDMI_SINK_CAPS sinkCaps;
NvBool reassessFrlLinkCaps : 1;
} hdmi;
struct {
@@ -2831,7 +2839,7 @@ struct _NVSurfaceEvoRec {
NvU64 rmRefCnt;
NvU64 structRefCnt;
#if NVKMS_PROCFS_ENABLE
#if NVKMS_PROCFS_OBJECT_DUMP
NvBool procFsFlag;
#endif
@@ -3288,6 +3296,7 @@ typedef const struct _nv_evo_hal {
NvU32 supportsDPAudio192KHz :1;
NvU32 supportsInputColorSpace :1;
NvU32 supportsInputColorRange :1;
NvU32 supportsYCbCr422OverHDMIFRL :1;
NvU32 supportedDitheringModes;
size_t impStructSize;

View File

@@ -279,7 +279,7 @@ void nvEvoDestroyApiHandles(NVEvoApiHandlesPtr pEvoApiHandles);
(_pointer) = nvEvoGetPointerFromApiHandleNext(_pEvoApiHandles, \
&(_handle)))
NvBool nvDoDebugLogging(void);
#ifdef __cplusplus
};

View File

@@ -667,7 +667,9 @@ enum NvKmsInputTf {
enum NvKmsOutputColorimetry {
NVKMS_OUTPUT_COLORIMETRY_DEFAULT = 0,
NVKMS_OUTPUT_COLORIMETRY_BT2100 = 1,
NVKMS_OUTPUT_COLORIMETRY_BT601 = 1,
NVKMS_OUTPUT_COLORIMETRY_BT709 = 2,
NVKMS_OUTPUT_COLORIMETRY_BT2100 = 3,
};
enum NvKmsOutputTf {

View File

@@ -119,6 +119,7 @@ NvBool nvkms_vblank_sem_control(void);
NvBool nvkms_opportunistic_display_sync(void);
enum NvKmsDebugForceColorSpace nvkms_debug_force_color_space(void);
NvBool nvkms_enable_overlay_layers(void);
NvBool nvkms_debug_logging(void);
void nvkms_call_rm (void *ops);
void* nvkms_alloc (size_t size,

View File

@@ -151,16 +151,6 @@ void nvDPDestroyConnector(NVDPLibConnectorPtr pNVDpLibConnector)
nvFree(pNVDpLibConnector);
}
NvBool nvDPIsLinkAwaitingTransition(NVConnectorEvoPtr pConnectorEvo)
{
if (nvConnectorUsesDPLib(pConnectorEvo)) {
DisplayPort::Connector *c = pConnectorEvo->pDpLibConnector->connector;
return c->isLinkAwaitingTransition();
}
return FALSE;
}
/*!
* Create a new DisplayPort group and populate it with the devices specified by
* dpyIdList. For MST groups, this allocates a dynamic RM display ID.
@@ -1128,10 +1118,11 @@ void nvDPSetAllowMultiStreamingOneConnector(
pDpLibConnector->connector->setAllowMultiStreaming(allowMST);
}
static NvBool IsDpSinkMstCapableForceSst(const NVDispEvoRec *pDispEvo,
const NvU32 apiHead,
void *pData)
static NvBool IsDpSinkMstTransitionNeeded(const NVDispEvoRec *pDispEvo,
const NvU32 apiHead,
void *pData)
{
const NvBool *pAllowMST = reinterpret_cast<const NvBool*>(pData);
const NVDispApiHeadStateEvoRec *pApiHeadState =
&pDispEvo->apiHeadState[apiHead];
const NVDpyEvoRec *pDpyEvo =
@@ -1147,49 +1138,24 @@ static NvBool IsDpSinkMstCapableForceSst(const NVDispEvoRec *pDispEvo,
DisplayPort::Connector *c =
pConnectorEvo->pDpLibConnector->connector;
return (c->getSinkMultiStreamCap() && !c->getAllowMultiStreaming());
}
return c->isLinkAwaitingTransition() ||
(c->getSinkMultiStreamCap() &&
c->getAllowMultiStreaming() != *pAllowMST);
static NvBool IsDpLinkTransitionWaitingForHeadShutDown(
const NVDispEvoRec *pDispEvo,
const NvU32 apiHead,
void *pData)
{
const NVDispApiHeadStateEvoRec *pApiHeadState =
&pDispEvo->apiHeadState[apiHead];
const NVDpyEvoRec *pDpyEvo =
nvGetOneArbitraryDpyEvo(pApiHeadState->activeDpys, pDispEvo);
return (pDpyEvo != NULL) &&
nvDPIsLinkAwaitingTransition(pDpyEvo->pConnectorEvo);
}
void nvDPSetAllowMultiStreaming(NVDevEvoPtr pDevEvo, NvBool allowMST)
{
NvBool needUpdate = FALSE;
NVDispEvoPtr pDispEvo;
NvU32 dispIndex;
FOR_ALL_EVO_DISPLAYS(pDispEvo, dispIndex, pDevEvo) {
NVConnectorEvoPtr pConnectorEvo;
FOR_ALL_EVO_CONNECTORS(pConnectorEvo, pDispEvo) {
NVDPLibConnectorPtr pDpLibConnector =
pConnectorEvo->pDpLibConnector;
if (pDpLibConnector &&
pDpLibConnector->connector->getAllowMultiStreaming()
!= allowMST) {
needUpdate = TRUE;
}
}
}
if (!needUpdate) {
return;
}
/*
* Shut down any heads that are driving SST and need to transition to MST,
* and any heads where we're toggling the value of allowMST.
*/
nvShutDownApiHeads(pDevEvo, pDevEvo->pNvKmsOpenDev,
IsDpSinkMstCapableForceSst, NULL /* pData */,
IsDpSinkMstTransitionNeeded,
reinterpret_cast<void *>(&allowMST),
TRUE /* doRasterLock */);
/*
@@ -1214,15 +1180,10 @@ void nvDPSetAllowMultiStreaming(NVDevEvoPtr pDevEvo, NvBool allowMST)
}
}
/* Shut down all DisplayPort heads that need to transition to/from SST. */
nvShutDownApiHeads(pDevEvo, pDevEvo->pNvKmsOpenDev,
IsDpLinkTransitionWaitingForHeadShutDown,
NULL /* pData */,
TRUE /* doRasterLock */);
/*
* Handle any pending timers the DP library scheduled to notify us
* about changes in the connected device list.
* about changes to MST devices on connectors that now allow or disallow
* MST.
*/
nvDPFireExpiredTimers(pDevEvo);
}

View File

@@ -63,6 +63,8 @@ void dpPrintf(DP_LOG_LEVEL severity, const char *format, ...)
{
if (severity == DP_SILENT) return;
if (!nvDoDebugLogging()) return;
va_list ap;
va_start(ap, format);
nvVEvoLog(dpSeverityToNvkmsMap(severity), NV_INVALID_GPU_LOG_INDEX, format, ap);

View File

@@ -644,22 +644,13 @@ static void DpyPostColorSpaceOrRangeSetEvo(NVDpyEvoPtr pDpyEvo)
colorSpaceChanged = (pApiHeadState->attributes.color.format != colorSpace);
colorBpcChanged = (pApiHeadState->attributes.color.bpc != colorBpc);
/* For DP, neither color space nor bpc can be changed without a modeset */
if (nvConnectorUsesDPLib(pDpyEvo->pConnectorEvo) &&
/* For DP and HDMI FRL, neither color space nor bpc can be changed without a modeset */
if ((nvConnectorUsesDPLib(pDpyEvo->pConnectorEvo) ||
(pApiHeadState->timings.protocol == NVKMS_PROTOCOL_SOR_HDMI_FRL)) &&
(colorSpaceChanged || colorBpcChanged)) {
return;
}
/*
* Hardware does not support HDMI FRL with YUV422, and it is not possible
* to downgrade current color bpc on HDMI FRL at this point.
*/
if ((pApiHeadState->timings.protocol == NVKMS_PROTOCOL_SOR_HDMI_FRL) &&
((colorSpace == NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr422) ||
(pApiHeadState->attributes.color.bpc > colorBpc))) {
return;
}
if (nvDpyIsHdmiEvo(pDpyEvo) &&
(colorBpc > pApiHeadState->attributes.color.bpc)) {
NVDpyAttributeColor tmpDpyColor = pApiHeadState->attributes.color;

View File

@@ -24,6 +24,7 @@
#include "dp/nvdp-device.h"
#include "dp/nvdp-connector-event-sink.h"
#include "nvkms-api-types.h"
#include "nvkms-evo.h"
#include "nvkms-dpy.h"
#include "nvkms-dpy-override.h"
@@ -44,6 +45,7 @@
#include "timing/dpsdp.h"
#include "displayport/displayport.h"
#include "timing/nvtiming.h"
#include <ctrl/ctrl0073/ctrl0073dfp.h> // NV0073_CTRL_DFP_FLAGS_*
#include <ctrl/ctrl0073/ctrl0073dp.h> // NV0073_CTRL_CMD_DP_GET_LINK_CONFIG_*
@@ -100,23 +102,6 @@ static void DpyDisconnectEvo(NVDpyEvoPtr pDpyEvo, const NvBool bSendHdmiCapsToRm
ClearEdid(pDpyEvo, bSendHdmiCapsToRm);
}
static void HdmiFrlSetConfig(NVDpyEvoRec *pDpyEvo)
{
NVDispEvoRec *pDispEvo = pDpyEvo->pDispEvo;
NvU32 head;
if ((pDpyEvo->apiHead == NV_INVALID_HEAD) || !nvDpyIsHdmiEvo(pDpyEvo) ||
!nvHdmiDpySupportsFrl(pDpyEvo)) {
return;
}
head = nvGetPrimaryHwHead(pDispEvo, pDpyEvo->apiHead);
nvAssert(head != NV_INVALID_HEAD);
nvHdmiFrlSetConfig(pDispEvo, head);
}
static NvBool DpyConnectEvo(
NVDpyEvoPtr pDpyEvo,
struct NvKmsQueryDpyDynamicDataParams *pParams)
@@ -140,8 +125,6 @@ static NvBool DpyConnectEvo(
nvUpdateInfoFrames(pDpyEvo);
HdmiFrlSetConfig(pDpyEvo);
return TRUE;
}
@@ -682,7 +665,20 @@ static void ReadAndApplyEdidEvo(
&infoString);
} else {
nvFree(edid.buffer);
if (nvDpyIsHdmiEvo(pDpyEvo) &&
nvHdmiDpySupportsFrl(pDpyEvo) &&
pDpyEvo->hdmi.reassessFrlLinkCaps) {
/*
* Although theres no change in EDID, if there was a HPD or
* re-training request, reassess the FRL Link.
*/
nvHdmiFrlAssessLink(pDpyEvo);
}
}
pDpyEvo->hdmi.reassessFrlLinkCaps = FALSE;
nvFree(pParsedEdid);
}
@@ -2593,6 +2589,8 @@ void nvConstructDpVscSdp(const NVDispHeadInfoFrameStateEvoRec *pInfoFrame,
sdp->db.colorimetryFormat =
SDP_VSC_COLOR_FMT_RGB_COLORIMETRY_ITU_R_BT2020_RGB;
break;
case NVKMS_OUTPUT_COLORIMETRY_BT601:
case NVKMS_OUTPUT_COLORIMETRY_BT709:
case NVKMS_OUTPUT_COLORIMETRY_DEFAULT:
sdp->db.colorimetryFormat =
SDP_VSC_COLOR_FMT_RGB_COLORIMETRY_SRGB;
@@ -2622,6 +2620,14 @@ void nvConstructDpVscSdp(const NVDispHeadInfoFrameStateEvoRec *pInfoFrame,
sdp->db.colorimetryFormat =
SDP_VSC_COLOR_FMT_YCBCR_COLORIMETRY_ITU_R_BT2020_YCBCR;
break;
case NVKMS_OUTPUT_COLORIMETRY_BT601:
sdp->db.colorimetryFormat =
SDP_VSC_COLOR_FMT_YCBCR_COLORIMETRY_ITU_R_BT601;
break;
case NVKMS_OUTPUT_COLORIMETRY_BT709:
sdp->db.colorimetryFormat =
SDP_VSC_COLOR_FMT_YCBCR_COLORIMETRY_ITU_R_BT709;
break;
case NVKMS_OUTPUT_COLORIMETRY_DEFAULT:
sdp->db.colorimetryFormat =
(pInfoFrame->hdTimings ?
@@ -2674,6 +2680,7 @@ static void UpdateDpVscSdpInfoFrame(
&pDispEvo->headState[head];
NV0073_CTRL_SPECIFIC_SET_OD_PACKET_PARAMS params = { 0 };
NVDevEvoPtr pDevEvo = pDispEvo->pDevEvo;
DPSDP_DP_VSC_SDP_DESCRIPTOR *sdp;
NvU32 ret;
/*
@@ -2687,31 +2694,23 @@ static void UpdateDpVscSdpInfoFrame(
params.subDeviceInstance = pDispEvo->displayOwner;
params.displayId = pHeadState->activeRmId;
if ((pDpyColor->format == NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr420) ||
(pDpyColor->colorimetry == NVKMS_OUTPUT_COLORIMETRY_BT2100)) {
// DPSDP_DP_VSC_SDP_DESCRIPTOR has a (dataSize, hb, db) layout, while
// NV0073_CTRL_SPECIFIC_SET_OD_PACKET_PARAMS.aPacket needs to contain
// (hb, db) without dataSize, so this makes sdp->hb align with aPacket.
sdp = (DPSDP_DP_VSC_SDP_DESCRIPTOR *)(params.aPacket -
offsetof(DPSDP_DP_VSC_SDP_DESCRIPTOR, hb));
// DPSDP_DP_VSC_SDP_DESCRIPTOR has a (dataSize, hb, db) layout, while
// NV0073_CTRL_SPECIFIC_SET_OD_PACKET_PARAMS.aPacket needs to contain
// (hb, db) without dataSize, so this makes sdp->hb align with aPacket.
DPSDP_DP_VSC_SDP_DESCRIPTOR *sdp =
(DPSDP_DP_VSC_SDP_DESCRIPTOR *)(params.aPacket -
offsetof(DPSDP_DP_VSC_SDP_DESCRIPTOR, hb));
nvAssert((void *)&sdp->hb == (void *)params.aPacket);
nvAssert((void *)&sdp->hb == (void *)params.aPacket);
nvConstructDpVscSdp(pInfoFrame, pDpyColor, sdp);
nvConstructDpVscSdp(pInfoFrame, pDpyColor, sdp);
params.packetSize = sizeof(sdp->hb) + sdp->hb.numValidDataBytes;
params.packetSize = sizeof(sdp->hb) + sdp->hb.numValidDataBytes;
params.transmitControl =
DRF_DEF(0073_CTRL_SPECIFIC, _SET_OD_PACKET_TRANSMIT_CONTROL, _ENABLE, _YES) |
DRF_DEF(0073_CTRL_SPECIFIC, _SET_OD_PACKET_TRANSMIT_CONTROL, _OTHER_FRAME, _DISABLE) |
DRF_DEF(0073_CTRL_SPECIFIC, _SET_OD_PACKET_TRANSMIT_CONTROL, _SINGLE_FRAME, _DISABLE) |
DRF_DEF(0073_CTRL_SPECIFIC, _SET_OD_PACKET_TRANSMIT_CONTROL, _ON_HBLANK, _DISABLE);
} else {
params.transmitControl =
DRF_DEF(0073_CTRL_SPECIFIC, _SET_OD_PACKET_TRANSMIT_CONTROL, _ENABLE, _NO);
}
params.transmitControl =
DRF_DEF(0073_CTRL_SPECIFIC, _SET_OD_PACKET_TRANSMIT_CONTROL, _ENABLE, _YES) |
DRF_DEF(0073_CTRL_SPECIFIC, _SET_OD_PACKET_TRANSMIT_CONTROL, _OTHER_FRAME, _DISABLE) |
DRF_DEF(0073_CTRL_SPECIFIC, _SET_OD_PACKET_TRANSMIT_CONTROL, _SINGLE_FRAME, _DISABLE) |
DRF_DEF(0073_CTRL_SPECIFIC, _SET_OD_PACKET_TRANSMIT_CONTROL, _ON_HBLANK, _DISABLE);
ret = nvRmApiControl(nvEvoGlobal.clientHandle,
pDevEvo->displayCommonHandle,
@@ -3360,10 +3359,10 @@ NvKmsDpyOutputColorFormatInfo nvDpyGetOutputColorFormatInfo(
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8;
}
} else if (nvConnectorUsesDPLib(pDpyEvo->pConnectorEvo)) {
const NVT_EDID_INFO *info = &pDpyEvo->parsedEdid.info;
if (pDpyEvo->parsedEdid.valid &&
pDpyEvo->parsedEdid.info.input.isDigital &&
pDpyEvo->parsedEdid.info.version >= NVT_EDID_VER_1_4) {
info->input.isDigital && info->version >= NVT_EDID_VER_1_4) {
if (pDpyEvo->parsedEdid.info.input.u.digital.bpc >= 10) {
colorFormatsInfo.rgb444.maxBpc =
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_10;
@@ -3407,6 +3406,39 @@ NvKmsDpyOutputColorFormatInfo nvDpyGetOutputColorFormatInfo(
colorFormatsInfo.rgb444.minBpc =
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8;
}
if (pDpyEvo->parsedEdid.valid && info->input.isDigital &&
(info->input.u.digital.video_interface ==
NVT_EDID_DIGITAL_VIDEO_INTERFACE_STANDARD_HDMI_A_SUPPORTED ||
info->input.u.digital.video_interface ==
NVT_EDID_DIGITAL_VIDEO_INTERFACE_STANDARD_HDMI_B_SUPPORTED)) {
/*
* Prevent RGB 444 @ 6 BPC on active DP-to-HDMI adapters since
* HDMI does not support RGB 444 @ 6 BPC.
*/
if (colorFormatsInfo.rgb444.minBpc ==
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_6) {
colorFormatsInfo.rgb444.minBpc =
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8;
}
// Prevent >=10 BPC on active DP-to-HDMI adapters, if the dc_30_bit is not set
if ((info->version < NVT_EDID_VER_1_4 ||
!info->hdmiLlcInfo.dc_30_bit) &&
colorFormatsInfo.rgb444.maxBpc !=
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_UNKNOWN) {
colorFormatsInfo.rgb444.maxBpc =
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8;
}
if ((info->version < NVT_EDID_VER_1_4 ||
!info->hdmiLlcInfo.dc_30_bit) &&
colorFormatsInfo.yuv444.maxBpc !=
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_UNKNOWN) {
colorFormatsInfo.yuv444.maxBpc =
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8;
}
}
} else {
colorFormatsInfo.rgb444.maxBpc =
nvDpyIsHdmiDepth30Evo(pDpyEvo) ?

View File

@@ -31,6 +31,7 @@
#include "nvkms-utils.h"
#include "nvkms-private.h"
#include "nvkms-evo.h"
#include "nvkms-hdmi.h"
/*
* Handle a display device hotplug event.
@@ -180,6 +181,10 @@ nvHandleHotplugEventDeferredWork(void *dataPtr, NvU32 dataU32)
} else {
nvSendDpyEventEvo(pDpyEvo, NVKMS_EVENT_TYPE_DPY_CHANGED);
}
if (nvDpyIsHdmiEvo(pDpyEvo)) {
pDpyEvo->hdmi.reassessFrlLinkCaps = TRUE;
}
}
}
@@ -205,3 +210,14 @@ nvHandleDPIRQEventDeferredWork(void *dataPtr, NvU32 dataU32)
}
}
}
void
nvHandleHDMIFRLRetrainEventDeferredWork(void *dataPtr, NvU32 dataU32)
{
NVDispEvoPtr pDispEvo = dataPtr;
NVDpyId id = nvNvU32ToDpyId(dataU32);
NVDpyEvoRec *pDpyEvo = nvGetDpyEvoFromDispEvo(pDispEvo, id);
nvSendDpyEventEvo(pDpyEvo, NVKMS_EVENT_TYPE_DPY_CHANGED);
pDpyEvo->hdmi.reassessFrlLinkCaps = TRUE;
}

View File

@@ -1025,10 +1025,8 @@ void nvEvoSetDpVscSdp(NVDispEvoPtr pDispEvo,
nvPushEvoSubDevMaskDisp(pDispEvo);
if (((pDpyColor->format == NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr420) ||
(pDpyColor->colorimetry == NVKMS_OUTPUT_COLORIMETRY_BT2100)) &&
((pTimings->protocol == NVKMS_PROTOCOL_SOR_DP_A) ||
(pTimings->protocol == NVKMS_PROTOCOL_SOR_DP_B))) {
if (pTimings->protocol == NVKMS_PROTOCOL_SOR_DP_A ||
pTimings->protocol == NVKMS_PROTOCOL_SOR_DP_B) {
DPSDP_DP_VSC_SDP_DESCRIPTOR sdp = { };
nvConstructDpVscSdp(pInfoFrame, pDpyColor, &sdp);
pDevEvo->hal->SetDpVscSdp(pDispEvo, head, &sdp, updateState);
@@ -3048,12 +3046,23 @@ void nvUpdateCurrentHardwareColorSpaceAndRangeEvo(
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr444:
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr422:
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr420:
if (pDpyColor->colorimetry == NVKMS_OUTPUT_COLORIMETRY_BT2100) {
switch (pDpyColor->colorimetry) {
case NVKMS_OUTPUT_COLORIMETRY_BT2100:
pHeadState->procAmp.colorimetry = NVT_COLORIMETRY_BT2020YCC;
} else if (nvEvoIsHDQualityVideoTimings(&pHeadState->timings)) {
break;
case NVKMS_OUTPUT_COLORIMETRY_BT709:
pHeadState->procAmp.colorimetry = NVT_COLORIMETRY_YUV_709;
} else {
break;
case NVKMS_OUTPUT_COLORIMETRY_BT601:
pHeadState->procAmp.colorimetry = NVT_COLORIMETRY_YUV_601;
break;
case NVKMS_OUTPUT_COLORIMETRY_DEFAULT:
if (nvEvoIsHDQualityVideoTimings(&pHeadState->timings)) {
pHeadState->procAmp.colorimetry = NVT_COLORIMETRY_YUV_709;
} else {
pHeadState->procAmp.colorimetry = NVT_COLORIMETRY_YUV_601;
}
break;
}
break;
default:
@@ -6867,10 +6876,19 @@ ConstructHwModeTimingsViewPort(const NVDispEvoRec *pDispEvo,
}
static NvBool GetDefaultFrlDpyColor(
static NvBool FrlOverrideForYCbCr422(
const NVDevEvoRec *pDevEvo,
const NvKmsDpyOutputColorFormatInfo *pColorFormatsInfo,
NVDpyAttributeColor *pDpyColor)
{
/*
* If the hardware natively supports YCbCr422 + FRL,
* there is nothing to do.
*/
if (pDevEvo->hal->caps.supportsYCbCr422OverHDMIFRL) {
return TRUE;
}
nvkms_memset(pDpyColor, 0, sizeof(*pDpyColor));
pDpyColor->colorimetry = NVKMS_OUTPUT_COLORIMETRY_DEFAULT;
@@ -6916,14 +6934,18 @@ static NvBool GetDfpHdmiProtocol(
NVKMS_MODE_VALIDATION_REQUIRE_BOOT_CLOCKS) == 0) &&
(!nvHdmiIsTmdsPossible(pDpyEvo, pTimings, pDpyColor) ||
nvGetPreferHdmiFrlMode(pDevEvo, pValidationParams)) &&
/* If FRL is supported... */
nvHdmiDpySupportsFrl(pDpyEvo)) {
/* If FRL is possible... */
nvHdmiIsFrlPossible(pDpyEvo)) {
/* Hardware does not support HDMI FRL with YUV422 */
if ((pDpyColor->format ==
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr422) &&
!GetDefaultFrlDpyColor(&colorFormatsInfo, pDpyColor)) {
return FALSE;
/*
* Not all hardware configurations support YCbCr422 with FRL;
* override if necessary, or fail FRL.
*/
if (pDpyColor->format ==
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr422) {
if (!FrlOverrideForYCbCr422(pDevEvo, &colorFormatsInfo, pDpyColor)) {
return FALSE;
}
}
*pTimingsProtocol = NVKMS_PROTOCOL_SOR_HDMI_FRL;

View File

@@ -4098,6 +4098,7 @@ NVEvoHAL nvEvo97 = {
FALSE, /* supportsDPAudio192KHz */
FALSE, /* supportsInputColorSpace */
FALSE, /* supportsInputColorRange */
FALSE, /* supportsYCbCr422OverHDMIFRL */
NV_EVO2_SUPPORTED_DITHERING_MODES, /* supportedDitheringModes */
sizeof(NV5070_CTRL_CMD_IS_MODE_POSSIBLE_PARAMS), /* impStructSize */
NV_EVO_SCALER_1TAP, /* minScalerTaps */
@@ -4196,6 +4197,7 @@ NVEvoHAL nvEvo94 = {
FALSE, /* supportsDPAudio192KHz */
FALSE, /* supportsInputColorSpace */
FALSE, /* supportsInputColorRange */
FALSE, /* supportsYCbCr422OverHDMIFRL */
NV_EVO2_SUPPORTED_DITHERING_MODES, /* supportedDitheringModes */
sizeof(NV5070_CTRL_CMD_IS_MODE_POSSIBLE_PARAMS), /* impStructSize */
NV_EVO_SCALER_1TAP, /* minScalerTaps */

View File

@@ -8146,6 +8146,7 @@ NVEvoHAL nvEvoC3 = {
FALSE, /* supportsDPAudio192KHz */
FALSE, /* supportsInputColorSpace */
FALSE, /* supportsInputColorRange */
FALSE, /* supportsYCbCr422OverHDMIFRL */
NV_EVO3_SUPPORTED_DITHERING_MODES, /* supportedDitheringModes */
sizeof(NVC372_CTRL_IS_MODE_POSSIBLE_PARAMS), /* impStructSize */
NV_EVO_SCALER_2TAPS, /* minScalerTaps */
@@ -8244,6 +8245,7 @@ NVEvoHAL nvEvoC5 = {
FALSE, /* supportsDPAudio192KHz */
TRUE, /* supportsInputColorSpace */
TRUE, /* supportsInputColorRange */
FALSE, /* supportsYCbCr422OverHDMIFRL */
NV_EVO3_SUPPORTED_DITHERING_MODES, /* supportedDitheringModes */
sizeof(NVC372_CTRL_IS_MODE_POSSIBLE_PARAMS), /* impStructSize */
NV_EVO_SCALER_2TAPS, /* minScalerTaps */
@@ -8342,6 +8344,7 @@ NVEvoHAL nvEvoC6 = {
FALSE, /* supportsDPAudio192KHz */
TRUE, /* supportsInputColorSpace */
TRUE, /* supportsInputColorRange */
FALSE, /* supportsYCbCr422OverHDMIFRL */
NV_EVO3_SUPPORTED_DITHERING_MODES, /* supportedDitheringModes */
sizeof(NVC372_CTRL_IS_MODE_POSSIBLE_PARAMS), /* impStructSize */
NV_EVO_SCALER_2TAPS, /* minScalerTaps */

View File

@@ -3140,6 +3140,7 @@ NVEvoHAL nvEvoC9 = {
TRUE, /* supportsDPAudio192KHz */
TRUE, /* supportsInputColorSpace */
TRUE, /* supportsInputColorRange */
TRUE, /* supportsYCbCr422OverHDMIFRL */
NV_EVO3_SUPPORTED_DITHERING_MODES, /* supportedDitheringModes */
sizeof(NVC372_CTRL_IS_MODE_POSSIBLE_PARAMS), /* impStructSize */
NV_EVO_SCALER_2TAPS, /* minScalerTaps */
@@ -3238,6 +3239,7 @@ NVEvoHAL nvEvoCA = {
TRUE, /* supportsDPAudio192KHz */
TRUE, /* supportsInputColorSpace */
TRUE, /* supportsInputColorRange */
TRUE, /* supportsYCbCr422OverHDMIFRL */
NV_EVO3_SUPPORTED_DITHERING_MODES, /* supportedDitheringModes */
sizeof(NVC372_CTRL_IS_MODE_POSSIBLE_PARAMS), /* impStructSize */
NV_EVO_SCALER_2TAPS, /* minScalerTaps */

View File

@@ -51,6 +51,19 @@
#define CAP_HDMI_SUPPORT_MONITOR_36_BPP 0x00000008
#define CAP_HDMI_SUPPORT_MONITOR_30_BPP 0x00000010
#define SRC_TEST_CONFIG_DSC_FRL_MAX_OFFSET 6
#define SRC_TEST_CONFIG_FRL_MAX_OFFSET 7
typedef enum {
FORCE_NONE,
FORCE_MAX_FRL_RATE,
FORCE_MAX_DSC_FRL_RATE,
} NVForceMaxFrlRateType;
static NVForceMaxFrlRateType GetForceMaxFrlRateType(
const NVDpyEvoRec *pDpyEvo,
const NVDpyId displayId);
static inline const NVT_EDID_CEA861_INFO *GetExt861(const NVParsedEdidEvoRec *pParsedEdid,
int extIndex)
{
@@ -102,6 +115,8 @@ static void CalculateVideoInfoFrameColorFormat(
pCtrl->extended_colorimetry =
NVT_VIDEO_INFOFRAME_BYTE3_EC_BT2020RGBYCC;
break;
case NVKMS_OUTPUT_COLORIMETRY_BT601:
case NVKMS_OUTPUT_COLORIMETRY_BT709:
case NVKMS_OUTPUT_COLORIMETRY_DEFAULT:
pCtrl->colorimetry = NVT_VIDEO_INFOFRAME_BYTE2_C1C0_NO_DATA;
break;
@@ -115,6 +130,12 @@ static void CalculateVideoInfoFrameColorFormat(
pCtrl->extended_colorimetry =
NVT_VIDEO_INFOFRAME_BYTE3_EC_BT2020RGBYCC;
break;
case NVKMS_OUTPUT_COLORIMETRY_BT601:
pCtrl->colorimetry = NVT_VIDEO_INFOFRAME_BYTE2_C1C0_SMPTE170M_ITU601;
break;
case NVKMS_OUTPUT_COLORIMETRY_BT709:
pCtrl->colorimetry = NVT_VIDEO_INFOFRAME_BYTE2_C1C0_ITU709;
break;
case NVKMS_OUTPUT_COLORIMETRY_DEFAULT:
pCtrl->colorimetry =
(hdTimings ? NVT_VIDEO_INFOFRAME_BYTE2_C1C0_ITU709 :
@@ -1869,11 +1890,13 @@ static void HdmiLibPrint(
{
NVDevEvoRec *pDevEvo = handle;
if (!nvDoDebugLogging()) return;
va_list ap;
va_start(ap, format);
/* The HDMI library doesn't have log levels, but currently only logs in
* debug builds. It's pretty chatty (e.g., it prints "Initialize Success"
* when it inits), so hardcode it to INFO level for now. */
/* The HDMI library doesn't have log levels. It's pretty chatty (e.g., it
* prints "Initialize Success" when it inits), so hardcode it to INFO level
* for now. */
nvVEvoLog(EVO_LOG_INFO, pDevEvo->gpuLogIndex, format, ap);
va_end(ap);
}
@@ -1962,19 +1985,40 @@ NvBool nvHdmiFrlAssessLink(NVDpyEvoPtr pDpyEvo)
NVDevEvoPtr pDevEvo = pDispEvo->pDevEvo;
NVHDMIPKT_RESULT ret;
const NvU32 displayId = nvDpyIdToNvU32(pDpyEvo->pConnectorEvo->displayId);
NvBool bIsDisplayActive = NV_FALSE;
NvBool bPerformLinkTrainingToAssess = NV_TRUE;
HDMI_FRL_DATA_RATE currFRLRate = HDMI_FRL_DATA_RATE_NONE;
nvAssert(nvDpyIsHdmiEvo(pDpyEvo));
nvAssert(nvDpyIsHdmiEvo(pDpyEvo) && nvHdmiDpySupportsFrl(pDpyEvo));
if (pDpyEvo->apiHead != NV_INVALID_HEAD) {
const NvU32 head =
nvGetPrimaryHwHead(pDispEvo, pDpyEvo->apiHead);
const NVDispHeadStateEvoRec *pHeadState = &pDispEvo->headState[head];
const HDMI_FRL_CONFIG *pFrlConfig = &pHeadState->hdmiFrlConfig;
bIsDisplayActive = NV_TRUE;
if (pFrlConfig->frlRate == HDMI_FRL_DATA_RATE_NONE) {
bPerformLinkTrainingToAssess = NV_FALSE;
} else {
bPerformLinkTrainingToAssess = NV_TRUE;
}
currFRLRate = pFrlConfig->frlRate;
}
/* HDMI dpys not dynamic dpy so its connector should have a dpyId. */
nvAssert(displayId != 0);
nvAssert(pDpyEvo->parsedEdid.valid);
ret = NvHdmi_AssessLinkCapabilities(pDevEvo->hdmiLib.handle,
pDispEvo->displayOwner,
displayId,
&pDpyEvo->parsedEdid.info,
&pDpyEvo->hdmi.srcCaps,
&pDpyEvo->hdmi.sinkCaps);
ret = NvHdmi_AssessLinkCapabilities2(pDevEvo->hdmiLib.handle,
pDispEvo->displayOwner,
displayId,
&pDpyEvo->parsedEdid.info,
bPerformLinkTrainingToAssess,
bIsDisplayActive,
currFRLRate,
&pDpyEvo->hdmi.srcCaps,
&pDpyEvo->hdmi.sinkCaps);
if (ret != NVHDMIPKT_SUCCESS) {
nvAssert(ret == NVHDMIPKT_SUCCESS);
return FALSE;
@@ -2120,7 +2164,7 @@ static NvU64 GetHdmiFrlLinkRate(HDMI_FRL_DATA_RATE frlRate)
return hdmiLinkRate;
}
static NvBool nvHdmiFrlQueryConfigOneBpc(
NvBool nvHdmiFrlQueryConfigOneColorSpaceAndBpc(
const NVDpyEvoRec *pDpyEvo,
const NvModeTimings *pModeTimings,
const NVHwModeTimingsEvo *pHwTimings,
@@ -2130,8 +2174,11 @@ static NvBool nvHdmiFrlQueryConfigOneBpc(
HDMI_FRL_CONFIG *pConfig,
NVDscInfoEvoRec *pDscInfo)
{
const NVConnectorEvoRec *pConnectorEvo = pDpyEvo->pConnectorEvo;
const NVDispEvoRec *pDispEvo = pDpyEvo->pDispEvo;
const NVDevEvoRec *pDevEvo = pDispEvo->pDevEvo;
const NVForceMaxFrlRateType forceMaxFrlType =
GetForceMaxFrlRateType(pDpyEvo, pConnectorEvo->displayId);
HDMI_VIDEO_TRANSPORT_INFO videoTransportInfo = { };
HDMI_QUERY_FRL_CLIENT_CONTROL clientControl = { };
const NVT_TIMING *pNvtTiming;
@@ -2145,7 +2192,7 @@ static NvBool nvHdmiFrlQueryConfigOneBpc(
}
nvAssert(nvDpyIsHdmiEvo(pDpyEvo));
nvAssert(nvHdmiDpySupportsFrl(pDpyEvo));
nvAssert(nvHdmiIsFrlPossible(pDpyEvo));
nvAssert(!nvHdmiIsTmdsPossible(pDpyEvo, pHwTimings, pDpyColor) ||
nvGetPreferHdmiFrlMode(pDevEvo, pValidationParams));
@@ -2202,21 +2249,32 @@ static NvBool nvHdmiFrlQueryConfigOneBpc(
return FALSE;
}
/* TODO: support YUV/YCbCr 444 and 422 packing modes. */
switch (pModeTimings->yuv420Mode) {
case NV_YUV420_MODE_NONE:
switch (pDpyColor->format) {
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB:
videoTransportInfo.packing = HDMI_PIXEL_PACKING_RGB;
break;
case NV_YUV420_MODE_SW:
/*
* Don't bother implementing this with FRL.
* HDMI FRL and HW YUV420 support were both added in nvdisplay 4.0
* hardware, so if the hardware supports FRL it should support
* YUV420_MODE_HW.
*/
return FALSE;
case NV_YUV420_MODE_HW:
videoTransportInfo.packing = HDMI_PIXEL_PACKING_YCbCr420;
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr422:
nvAssert(pDevEvo->hal->caps.supportsYCbCr422OverHDMIFRL);
videoTransportInfo.packing = HDMI_PIXEL_PACKING_YCbCr422;
break;
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr444:
videoTransportInfo.packing = HDMI_PIXEL_PACKING_YCbCr444;
break;
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr420:
switch (pModeTimings->yuv420Mode) {
case NV_YUV420_MODE_NONE:
case NV_YUV420_MODE_SW:
/*
* Don't bother implementing this with FRL.
* HDMI FRL and HW YUV420 support were both added in nvdisplay 4.0
* hardware, so if the hardware supports FRL it should support
* YUV420_MODE_HW.
*/
return FALSE;
case NV_YUV420_MODE_HW:
videoTransportInfo.packing = HDMI_PIXEL_PACKING_YCbCr420;
break;
}
break;
}
@@ -2224,8 +2282,32 @@ static NvBool nvHdmiFrlQueryConfigOneBpc(
clientControl.option = HDMI_QUERY_FRL_HIGHEST_PIXEL_QUALITY;
if (pValidationParams->dscMode == NVKMS_DSC_MODE_FORCE_ENABLE) {
clientControl.enableDSC = TRUE;
switch (pValidationParams->dscMode) {
case NVKMS_DSC_MODE_FORCE_DISABLE:
clientControl.forceDisableDSC = TRUE;
break;
case NVKMS_DSC_MODE_FORCE_ENABLE:
clientControl.enableDSC = TRUE;
break;
case NVKMS_DSC_MODE_DEFAULT:
clientControl.forceFRLRate = (forceMaxFrlType != FORCE_NONE);
switch (forceMaxFrlType) {
case FORCE_MAX_FRL_RATE:
clientControl.forceDisableDSC = TRUE;
clientControl.frlRate =
NV_MIN(pDpyEvo->hdmi.srcCaps.linkMaxFRLRate,
pDpyEvo->hdmi.sinkCaps.linkMaxFRLRate);
break;
case FORCE_MAX_DSC_FRL_RATE:
clientControl.enableDSC = TRUE;
clientControl.frlRate =
NV_MIN(pDpyEvo->hdmi.srcCaps.linkMaxFRLRate,
pDpyEvo->hdmi.sinkCaps.linkMaxFRLRateDSC);
break;
case FORCE_NONE:
break;
}
break;
}
/*
@@ -2233,7 +2315,7 @@ static NvBool nvHdmiFrlQueryConfigOneBpc(
* but YUV420 is not, force DSC.
*/
if (b2Heads1Or && (pHwTimings->yuv420Mode != NV_YUV420_MODE_HW)) {
if (pValidationParams->dscMode == NVKMS_DSC_MODE_FORCE_DISABLE) {
if (clientControl.forceDisableDSC) {
return FALSE;
}
clientControl.enableDSC = TRUE;
@@ -2334,34 +2416,48 @@ void nvHdmiFrlClearConfig(NVDispEvoRec *pDispEvo, NvU32 activeRmId)
}
}
NvBool nvHdmiFrlQueryConfig(
static NVForceMaxFrlRateType GetForceMaxFrlRateType(
const NVDpyEvoRec *pDpyEvo,
const NvModeTimings *pModeTimings,
const NVHwModeTimingsEvo *pHwTimings,
NVDpyAttributeColor *pDpyColor,
const NvBool b2Heads1Or,
const struct NvKmsModeValidationParams *pValidationParams,
HDMI_FRL_CONFIG *pConfig,
NVDscInfoEvoRec *pDscInfo)
const NVDpyId displayId)
{
const NvKmsDpyOutputColorFormatInfo supportedColorFormats =
nvDpyGetOutputColorFormatInfo(pDpyEvo);
NVDpyAttributeColor dpyColor = *pDpyColor;
do {
if (nvHdmiFrlQueryConfigOneBpc(pDpyEvo,
pModeTimings,
pHwTimings,
&dpyColor,
b2Heads1Or,
pValidationParams,
pConfig,
pDscInfo)) {
*pDpyColor = dpyColor;
return TRUE;
}
} while(nvDowngradeColorBpc(&supportedColorFormats, &dpyColor) &&
(dpyColor.bpc >= NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8));
return FALSE;
const NVDispEvoRec *pDispEvo = pDpyEvo->pDispEvo;
const NVDevEvoRec *pDevEvo = pDispEvo->pDevEvo;
const NVParsedEdidEvoRec *pParsedEdid = &pDpyEvo->parsedEdid;
const NVT_HDMI_FORUM_INFO *pHdmiInfo = &pParsedEdid->info.hdmiForumInfo;
NvBool bTestMaxFrlRate;
NvBool bTestMaxDscFrlRate;
NvU32 ret;
if (!pHdmiInfo->scdc_present) {
return FORCE_NONE;
}
NV0073_CTRL_SPECIFIC_GET_HDMI_SCDC_DATA_PARAMS scdcParams;
nvkms_memset(&scdcParams, 0, sizeof(scdcParams));
scdcParams.subDeviceInstance = 0;
scdcParams.displayId = nvDpyIdToNvU32(displayId);
scdcParams.offset = NV0073_CTRL_CMD_SPECIFIC_GET_HDMI_SCDC_DATA_OFFSET_SOURCE_TEST_CONFIGURATION;
ret = nvRmApiControl(nvEvoGlobal.clientHandle,
pDevEvo->displayCommonHandle,
NV0073_CTRL_CMD_SPECIFIC_GET_HDMI_SCDC_DATA,
&scdcParams,
sizeof(scdcParams));
if (ret != NVOS_STATUS_SUCCESS) {
return FORCE_NONE;
}
bTestMaxFrlRate = !!(scdcParams.data & NVBIT(SRC_TEST_CONFIG_FRL_MAX_OFFSET));
bTestMaxDscFrlRate = !!(scdcParams.data & NVBIT(SRC_TEST_CONFIG_DSC_FRL_MAX_OFFSET));
if (bTestMaxFrlRate != bTestMaxDscFrlRate) {
return bTestMaxFrlRate ? FORCE_MAX_FRL_RATE : FORCE_MAX_DSC_FRL_RATE;
}
return FORCE_NONE;
}
void nvHdmiFrlSetConfig(NVDispEvoRec *pDispEvo, NvU32 head)

View File

@@ -1257,7 +1257,7 @@ static inline NvGpuSemaphore *Hs3dGetSemaphore(
return (NvGpuSemaphore *) pNotifier;
}
#if NVKMS_PROCFS_ENABLE
#if NVKMS_HEADSURFACE_STATS
/*!
* Get the semaphore index (e.g., to be passed into
* nvPushGetNotifierGpuAddress()) for an (eye, slot) pair.
@@ -1358,7 +1358,7 @@ static void Hs3dStatisticsComputeFps(
}
}
#endif /* NVKMS_PROCFS_ENABLE */
#endif /* NVKMS_HEADSURFACE_STATS */
/*!
* Collect statistics on headSurface rendering.
@@ -1380,7 +1380,7 @@ static void Hs3dStatisticsBefore(
const NvU8 eye,
const NvU8 slot)
{
#if NVKMS_PROCFS_ENABLE
#if NVKMS_HEADSURFACE_STATS
NVHsChannelStatisticsOneEyeRec *pPerEye =
&pHsChannel->statistics.perEye[eye][slot];
@@ -1438,7 +1438,7 @@ done:
semIndex + NVKMS_HEADSURFACE_STATS_SEMAPHORE_BEFORE,
pPerEye->nFrames);
#endif /* NVKMS_PROCFS_ENABLE */
#endif /* NVKMS_HEADSURFACE_STATS */
}
static void Hs3dStatisticsAfter(
@@ -1446,7 +1446,7 @@ static void Hs3dStatisticsAfter(
const NvU8 eye,
const NvU8 slot)
{
#if NVKMS_PROCFS_ENABLE
#if NVKMS_HEADSURFACE_STATS
NVHsChannelStatisticsOneEyeRec *pPerEye =
&pHsChannel->statistics.perEye[eye][slot];
const NvU8 semIndex = Hs3dGetStatisticsSemaphoreIndex(eye, slot);
@@ -1458,7 +1458,7 @@ static void Hs3dStatisticsAfter(
pPerEye->nFrames++;
#endif /* NVKMS_PROCFS_ENABLE */
#endif /* NVKMS_HEADSURFACE_STATS */
}
/*!

View File

@@ -1866,7 +1866,7 @@ static void HsProcFsRecordScanline(
const NVDispEvoRec *pDispEvo,
const NvU32 apiHead)
{
#if NVKMS_PROCFS_ENABLE
#if NVKMS_HEADSURFACE_STATS
NVHsChannelEvoRec *pHsChannel = pDispEvo->pHsChannel[apiHead];
NvU16 scanLine = 0;
NvBool inBlankingPeriod = FALSE;
@@ -1890,13 +1890,13 @@ static void HsProcFsRecordScanline(
scanLine, pHsChannel->statistics.scanLine.vVisible);
}
}
#endif /* NVKMS_PROCFS_ENABLE */
#endif /* NVKMS_HEADSURFACE_STATS */
}
static void HsProcFsRecordPreviousFrameNotDone(
NVHsChannelEvoPtr pHsChannel)
{
#if NVKMS_PROCFS_ENABLE
#if NVKMS_HEADSURFACE_STATS
pHsChannel->statistics.nPreviousFrameNotDone++;
#endif
}
@@ -1905,19 +1905,19 @@ static void HsProcFsRecordFullscreenSgFrames(
NVHsChannelEvoPtr pHsChannel,
NvBool isFullscreen)
{
#if NVKMS_PROCFS_ENABLE
#if NVKMS_HEADSURFACE_STATS
if (isFullscreen) {
pHsChannel->statistics.nFullscreenSgFrames++;
} else {
pHsChannel->statistics.nNonFullscreenSgFrames++;
}
#endif /* NVKMS_PROCFS_ENABLE */
#endif /* NVKMS_HEADSURFACE_STATS */
}
static void HsProcFsRecordOmittedNonSgHsUpdate(
NVHsChannelEvoPtr pHsChannel)
{
#if NVKMS_PROCFS_ENABLE
#if NVKMS_HEADSURFACE_STATS
pHsChannel->statistics.nOmittedNonSgHsUpdates++;
#endif
}
@@ -2416,7 +2416,7 @@ void nvHsRemoveVBlankCallback(NVHsChannelEvoPtr pHsChannel)
void nvHsAllocStatistics(
NVHsChannelEvoRec *pHsChannel)
{
#if NVKMS_PROCFS_ENABLE
#if NVKMS_HEADSURFACE_STATS
const NVDispEvoRec *pDispEvo = pHsChannel->pDispEvo;
const NvU32 apiHead = pHsChannel->apiHead;
const NVHwModeTimingsEvo *pTimings =
@@ -2430,19 +2430,19 @@ void nvHsAllocStatistics(
n = pHsChannel->statistics.scanLine.vVisible + 1;
pHsChannel->statistics.scanLine.pHistogram = nvCalloc(1, sizeof(NvU64) * n);
#endif /* NVKMS_PROCFS_ENABLE */
#endif /* NVKMS_HEADSURFACE_STATS */
}
void nvHsFreeStatistics(
NVHsChannelEvoRec *pHsChannel)
{
#if NVKMS_PROCFS_ENABLE
#if NVKMS_HEADSURFACE_STATS
nvFree(pHsChannel->statistics.scanLine.pHistogram);
nvkms_memset(&pHsChannel->statistics, 0, sizeof(pHsChannel->statistics));
#endif /* NVKMS_PROCFS_ENABLE */
#endif /* NVKMS_HEADSURFACE_STATS */
}
#if NVKMS_PROCFS_ENABLE
#if NVKMS_HEADSURFACE_STATS
static const struct {
const char *before;
@@ -2972,4 +2972,4 @@ void nvHsProcFs(
HsProcFsScanLine(pInfoString, pHsChannel);
}
#endif /* NVKMS_PROCFS_ENABLE */
#endif /* NVKMS_HEADSURFACE_STATS */

View File

@@ -1714,18 +1714,27 @@ static NvBool ValidateMode(NVDpyEvoPtr pDpyEvo,
b2Heads1Or = nvEvoUse2Heads1OR(pDpyEvo, pTimingsEvo, pParams);
if (nvDpyIsHdmiEvo(pDpyEvo)) {
if (!nvHdmiFrlQueryConfig(pDpyEvo,
&pKmsMode->timings,
pTimingsEvo,
&dpyColor,
b2Heads1Or,
pParams,
pHdmiFrlConfig,
pDscInfo)) {
NvBool foundFrlConfig = FALSE;
do {
if (nvHdmiFrlQueryConfigOneColorSpaceAndBpc(pDpyEvo,
&pKmsMode->timings,
pTimingsEvo,
&dpyColor,
b2Heads1Or,
pParams,
pHdmiFrlConfig,
pDscInfo)) {
foundFrlConfig = TRUE;
break;
}
} while (nvDowngradeColorSpaceAndBpc(pDpyEvo, &supportedColorFormats, &dpyColor));
if (!foundFrlConfig) {
LogModeValidationEnd(pDispEvo, pInfoString,
"Unable to determine HDMI 2.1 Fixed Rate Link configuration.");
goto done;
}
} else {
if (!nvDPValidateModeEvo(pDpyEvo, pTimingsEvo, &dpyColor, b2Heads1Or,
pDscInfo, pParams)) {

View File

@@ -102,6 +102,14 @@
#include "nvkms-attributes.h"
#include "nvkms-headsurface-config.h"
static NvBool
AssignProposedHdmiFrlConfig(
NVProposedModeSetStateOneApiHead *pProposedApiHead,
NVProposedModeSetHwStateOneHead *pProposedPrimaryHead,
const struct NvKmsSetModeOneHeadRequest *pRequestHead,
const NVDispEvoRec *pDispEvo,
const NVDpyEvoRec *pDpyEvo);
static NvBool
GetColorSpaceAndColorRange(
const NVDispEvoRec *pDispEvo,
@@ -1367,15 +1375,11 @@ AssignProposedModeSetHwState(NVDevEvoRec *pDevEvo,
* proposed modeset state, to broadcast it onto all hardware heads
* during modeset.
*/
if (!nvHdmiFrlQueryConfig(pDpyEvo,
&pRequestHead->mode.timings,
&pProposedApiHead->timings,
&pProposedApiHead->attributes.color,
(nvPopCount32(pProposedApiHead->hwHeadsMask) > 1)
/* b2Heads1Or */,
&pProposedApiHead->modeValidationParams,
&pProposedPrimaryHead->hdmiFrlConfig,
&pProposedApiHead->dscInfo)) {
if (!AssignProposedHdmiFrlConfig(pProposedApiHead,
pProposedPrimaryHead,
pRequestHead,
pDispEvo,
pDpyEvo)) {
pReply->disp[sd].head[apiHead].status =
NVKMS_SET_MODE_ONE_HEAD_STATUS_INVALID_MODE;
ret = FALSE;
@@ -1763,6 +1767,31 @@ static NvBool DowngradeColorSpaceAndBpcOneConnectorEvo(
return FALSE;
}
static NvBool AssignProposedHdmiFrlConfig(
NVProposedModeSetStateOneApiHead *pProposedApiHead,
NVProposedModeSetHwStateOneHead *pProposedPrimaryHead,
const struct NvKmsSetModeOneHeadRequest *pRequestHead,
const NVDispEvoRec *pDispEvo,
const NVDpyEvoRec *pDpyEvo)
{
do {
if (nvHdmiFrlQueryConfigOneColorSpaceAndBpc(pDpyEvo,
&pRequestHead->mode.timings,
&pProposedApiHead->timings,
&pProposedApiHead->attributes.color,
(nvPopCount32(pProposedApiHead->hwHeadsMask) > 1)
/* b2Heads1Or */,
&pProposedApiHead->modeValidationParams,
&pProposedPrimaryHead->hdmiFrlConfig,
&pProposedApiHead->dscInfo)) {
return TRUE;
}
} while (DowngradeColorSpaceAndBpcOneHead(pDispEvo, pProposedApiHead));
return FALSE;
}
static NvBool ValidateProposedModeSetHwStateOneConnectorDPlib(
const NVConnectorEvoRec *pConnectorEvo,
NVProposedModeSetHwStateOneDisp *pProposedDisp,

View File

@@ -1584,6 +1584,19 @@ static void ReceiveDPIRQEvent(void *arg, void *pEventDataVoid, NvU32 hEvent,
0);
}
static void ReceiveHDMIFRLRetrainEvent(void *arg, void *pEventDataVoid, NvU32 hEvent,
NvU32 Data, NV_STATUS Status)
{
Nv2080HdmiFrlRequestNotification *pEventData =
(Nv2080HdmiFrlRequestNotification *) pEventDataVoid;
(void) nvkms_alloc_timer_with_ref_ptr(
nvHandleHDMIFRLRetrainEventDeferredWork, /* callback */
arg, /* argument (this is a ref_ptr to a pDispEvo) */
pEventData->displayId, /* dataU32 */
0);
}
NvBool nvRmRegisterCallback(const NVDevEvoRec *pDevEvo,
NVOS10_EVENT_KERNEL_CALLBACK_EX *cb,
struct nvkms_ref_ptr *ref_ptr,
@@ -1820,6 +1833,35 @@ enum NvKmsAllocDeviceStatus nvRmAllocDisplays(NVDevEvoPtr pDevEvo)
}
}
// Allocate a handler for the HDMI "FRL Retraining" event, which is signaled
// when there's a FRL retraining request from the sink.
FOR_ALL_EVO_DISPLAYS(pDispEvo, sd, pDevEvo) {
NV2080_CTRL_EVENT_SET_NOTIFICATION_PARAMS setEventParams = { };
NvU32 subDevice, ret;
subDevice = pDevEvo->pSubDevices[pDispEvo->displayOwner]->handle;
pDispEvo->HDMIFRLRetrainEventHandle =
nvGenerateUnixRmHandle(&pDevEvo->handleAllocator);
if (!RegisterDispCallback(&pDispEvo->rmHDMIFRLRetrainCallback, pDispEvo,
pDispEvo->HDMIFRLRetrainEventHandle, ReceiveHDMIFRLRetrainEvent,
NV2080_NOTIFIERS_HDMI_FRL_RETRAINING_REQUEST)) {
nvEvoLogDev(pDevEvo, EVO_LOG_WARN,
"Failed to register HDMI FRL retrain event");
}
// Enable HDMI FRL retrain event notifications for this subdevice.
setEventParams.event = NV2080_NOTIFIERS_HDMI_FRL_RETRAINING_REQUEST;
setEventParams.action = NV2080_CTRL_EVENT_SET_NOTIFICATION_ACTION_REPEAT;
if ((ret = nvRmApiControl(nvEvoGlobal.clientHandle,
subDevice,
NV2080_CTRL_CMD_EVENT_SET_NOTIFICATION,
&setEventParams,
sizeof(setEventParams)))
!= NVOS_STATUS_SUCCESS) {
nvEvoLogDev(pDevEvo, EVO_LOG_WARN,
"Failed to enable HDMI FRL retrain notifications (subdevice: %d) (error: 0x%x)", sd, ret);
}
}
FOR_ALL_EVO_DISPLAYS(pDispEvo, sd, pDevEvo) {
ProbeBootDisplays(pDispEvo);
@@ -1850,7 +1892,7 @@ void nvRmDestroyDisplays(NVDevEvoPtr pDevEvo)
nvFreeVrrEvo(pDevEvo);
FOR_ALL_EVO_DISPLAYS(pDispEvo, dispIndex, pDevEvo) {
const NvU32 subDevice = pDevEvo->pSubDevices[pDispEvo->displayOwner]->handle;
// Before freeing anything, dump anything left in the RM's DisplayPort
// AUX channel log.
if (pDispEvo->dpAuxLoggingEnabled) {
@@ -1882,6 +1924,31 @@ void nvRmDestroyDisplays(NVDevEvoPtr pDevEvo)
pDispEvo->hotplugEventHandle);
pDispEvo->hotplugEventHandle = 0;
}
// Free the HDMI FRL retrain event
if (pDispEvo->HDMIFRLRetrainEventHandle != 0) {
NV2080_CTRL_EVENT_SET_NOTIFICATION_PARAMS setEventParams = { };
// Disable HDMI FRL retrain notifications for this subdevice
setEventParams.event = NV2080_NOTIFIERS_HDMI_FRL_RETRAINING_REQUEST;
setEventParams.action = NV2080_CTRL_EVENT_SET_NOTIFICATION_ACTION_DISABLE;
if ((ret = nvRmApiControl(nvEvoGlobal.clientHandle,
subDevice,
NV2080_CTRL_CMD_EVENT_SET_NOTIFICATION,
&setEventParams,
sizeof(setEventParams))
!= NVOS_STATUS_SUCCESS)) {
nvEvoLogDev(pDevEvo, EVO_LOG_WARN,
"Failed to disable HDMI FRL retrain notifications (subdevice: %d) (error: 0x%x)", dispIndex, ret);
}
nvRmApiFree(nvEvoGlobal.clientHandle,
nvEvoGlobal.clientHandle,
pDispEvo->HDMIFRLRetrainEventHandle);
nvFreeUnixRmHandle(&pDevEvo->handleAllocator,
pDispEvo->HDMIFRLRetrainEventHandle);
pDispEvo->HDMIFRLRetrainEventHandle = 0;
}
}
FOR_ALL_EVO_DISPLAYS(pDispEvo, dispIndex, pDevEvo) {

View File

@@ -801,3 +801,14 @@ void nvDebugAssert(const char *expString, const char *filenameString,
}
#endif /* DEBUG */
NvBool nvDoDebugLogging(void)
{
#if defined(DEBUG)
/* Always do debug logging in debug builds. */
return TRUE;
#endif
/* Otherwise, do debug logging if the kernel module is enabled. */
return nvkms_debug_logging();
}

View File

@@ -5345,7 +5345,7 @@ fail:
extern const char *const pNV_KMS_ID;
#if NVKMS_PROCFS_ENABLE
#if NVKMS_PROCFS_OBJECT_DUMP
static const char *ProcFsPerOpenTypeString(
enum NvKmsPerOpenType type)
@@ -5713,44 +5713,6 @@ ProcFsPrintSurfaces(
}
}
static void
ProcFsPrintHeadSurface(
void *data,
char *buffer,
size_t size,
nvkms_procfs_out_string_func_t *outString)
{
NVDevEvoPtr pDevEvo;
NVDispEvoPtr pDispEvo;
NvU32 dispIndex, apiHead;
NVEvoInfoStringRec infoString;
FOR_ALL_EVO_DEVS(pDevEvo) {
nvInitInfoString(&infoString, buffer, size);
nvEvoLogInfoString(&infoString,
"pDevEvo (deviceId:%02d) : %p",
pDevEvo->deviceId.rmDeviceId, pDevEvo);
outString(data, buffer);
FOR_ALL_EVO_DISPLAYS(pDispEvo, dispIndex, pDevEvo) {
nvInitInfoString(&infoString, buffer, size);
nvEvoLogInfoString(&infoString,
" pDispEvo (dispIndex:%02d) : %p",
dispIndex, pDispEvo);
outString(data, buffer);
for (apiHead = 0; apiHead < pDevEvo->numApiHeads; apiHead++) {
nvInitInfoString(&infoString, buffer, size);
nvHsProcFs(&infoString, pDevEvo, dispIndex, apiHead);
nvEvoLogInfoString(&infoString, "");
outString(data, buffer);
}
}
}
}
static const char *SwapGroupPerEyeStereoString(const NvU32 request)
{
const NvU32 value =
@@ -5942,6 +5904,50 @@ ProcFsPrintDeferredRequestFifos(
}
}
#endif /* NVKMS_PROCFS_OBJECT_DUMP */
#if NVKMS_HEADSURFACE_STATS
static void
ProcFsPrintHeadSurface(
void *data,
char *buffer,
size_t size,
nvkms_procfs_out_string_func_t *outString)
{
NVDevEvoPtr pDevEvo;
NVDispEvoPtr pDispEvo;
NvU32 dispIndex, apiHead;
NVEvoInfoStringRec infoString;
FOR_ALL_EVO_DEVS(pDevEvo) {
nvInitInfoString(&infoString, buffer, size);
nvEvoLogInfoString(&infoString,
"pDevEvo (deviceId:%02d) : %p",
pDevEvo->deviceId.rmDeviceId, pDevEvo);
outString(data, buffer);
FOR_ALL_EVO_DISPLAYS(pDispEvo, dispIndex, pDevEvo) {
nvInitInfoString(&infoString, buffer, size);
nvEvoLogInfoString(&infoString,
" pDispEvo (dispIndex:%02d) : %p",
dispIndex, pDispEvo);
outString(data, buffer);
for (apiHead = 0; apiHead < pDevEvo->numApiHeads; apiHead++) {
nvInitInfoString(&infoString, buffer, size);
nvHsProcFs(&infoString, pDevEvo, dispIndex, apiHead);
nvEvoLogInfoString(&infoString, "");
outString(data, buffer);
}
}
}
}
#endif /* NVKMS_HEADSURFACE_STATS */
#if NVKMS_PROCFS_CRCS
static void
ProcFsPrintDpyCrcs(
void *data,
@@ -6024,17 +6030,37 @@ ProcFsPrintDpyCrcs(
}
}
}
#endif /* NVKMS_PROCFS_CRCS */
static const char *
SignalFormatString(NvKmsConnectorSignalFormat signalFormat)
SignalFormatString(const enum nvKmsTimingsProtocol protocol)
{
switch (signalFormat) {
case NVKMS_CONNECTOR_SIGNAL_FORMAT_VGA: return "VGA";
case NVKMS_CONNECTOR_SIGNAL_FORMAT_LVDS: return "LVDS";
case NVKMS_CONNECTOR_SIGNAL_FORMAT_TMDS: return "TMDS";
case NVKMS_CONNECTOR_SIGNAL_FORMAT_DP: return "DP";
case NVKMS_CONNECTOR_SIGNAL_FORMAT_DSI: return "DSI";
case NVKMS_CONNECTOR_SIGNAL_FORMAT_UNKNOWN: break;
switch (protocol) {
case NVKMS_PROTOCOL_DAC_RGB:
return "VGA";
case NVKMS_PROTOCOL_SOR_SINGLE_TMDS_A:
case NVKMS_PROTOCOL_SOR_SINGLE_TMDS_B:
return "TMDS";
case NVKMS_PROTOCOL_SOR_DUAL_TMDS:
return "Dual TMDS";
case NVKMS_PROTOCOL_SOR_DP_A:
case NVKMS_PROTOCOL_SOR_DP_B:
return "DP";
case NVKMS_PROTOCOL_SOR_LVDS_CUSTOM:
return "LVDS";
case NVKMS_PROTOCOL_SOR_HDMI_FRL:
return "HDMI FRL";
case NVKMS_PROTOCOL_DSI:
return "DSI";
case NVKMS_PROTOCOL_PIOR_EXT_TMDS_ENC:
return "EXT TMDS";
}
return "unknown";
@@ -6070,27 +6096,24 @@ ProcFsPrintHeads(
nvInitInfoString(&infoString, buffer, size);
nvEvoLogInfoString(&infoString,
"pDevEvo (deviceId:%02d) : %p",
pDevEvo->deviceId.rmDeviceId, pDevEvo);
"deviceId : %02d",
pDevEvo->deviceId.rmDeviceId);
outString(data, buffer);
FOR_ALL_EVO_DISPLAYS(pDispEvo, dispIndex, pDevEvo) {
const NVLockGroup *pLockGroup = pDispEvo->pLockGroup;
nvInitInfoString(&infoString, buffer, size);
nvEvoLogInfoString(&infoString,
" pDispEvo (dispIndex:%02d) : %p",
dispIndex, pDispEvo);
if (pLockGroup != NULL) {
const NvBool flipLocked = nvIsLockGroupFlipLocked(pLockGroup);
nvInitInfoString(&infoString, buffer, size);
nvEvoLogInfoString(&infoString,
" pLockGroup : %p",
" pLockGroup : %p",
pLockGroup);
nvEvoLogInfoString(&infoString,
" flipLock : %s",
" flipLock : %s",
flipLocked ? "yes" : "no");
outString(data, buffer);
}
outString(data, buffer);
if (pDevEvo->coreInitMethodsPending) {
/* If the core channel has been allocated but no mode has yet
@@ -6098,7 +6121,7 @@ ProcFsPrintHeads(
* driven by the console, but data like the mode timings will
* be bogus. */
nvInitInfoString(&infoString, buffer, size);
nvEvoLogInfoString(&infoString, " (not yet initialized)");
nvEvoLogInfoString(&infoString, " (not yet initialized)");
outString(data, buffer);
continue;
}
@@ -6114,29 +6137,43 @@ ProcFsPrintHeads(
nvInitInfoString(&infoString, buffer, size);
if (pConnectorEvo == NULL) {
nvEvoLogInfoString(&infoString,
" head %d : inactive",
" head %d : inactive",
head);
} else {
const NvU32 refreshRate10kHz =
nvGetRefreshRate10kHz(pHwModeTimings);
const NVDpyEvoRec *pDpyEvo;
/* Find the dpy driven by this head. Multiple heads may be
* driving the same dpy with 2head1or, but a head should
* only drive one dpy at a time. */
FOR_ALL_EVO_DPYS(pDpyEvo, pDispEvo->validDisplays, pDispEvo) {
const NvU32 apiHead = pDpyEvo->apiHead;
if (apiHead == NV_INVALID_HEAD) {
continue;
}
if (pDispEvo->apiHeadState[apiHead].hwHeadsMask &
NVBIT(head)) {
nvEvoLogInfoString(&infoString,
" head %d : %s",
head, pDpyEvo->name);
break;
}
}
nvEvoLogInfoString(&infoString,
" head %d : %s",
head, pConnectorEvo->name);
" protocol : %s",
SignalFormatString(pHwModeTimings->protocol));
nvEvoLogInfoString(&infoString,
" protocol : %s",
SignalFormatString(pConnectorEvo->signalFormat));
nvEvoLogInfoString(&infoString,
" mode : %u x %u @ %u.%04u Hz",
" mode : %u x %u @ %u.%04u Hz",
nvEvoVisibleWidth(pHwModeTimings),
nvEvoVisibleHeight(pHwModeTimings),
refreshRate10kHz / 10000,
refreshRate10kHz % 10000);
nvEvoLogInfoString(&infoString,
" depth : %s",
" depth : %s",
PixelDepthString(pHeadState->pixelDepth));
}
outString(data, buffer);
@@ -6145,25 +6182,107 @@ ProcFsPrintHeads(
}
}
#endif /* NVKMS_PROCFS_ENABLE */
/*
* Dump all dpys for all devices, grouped by connector.
* With DP MST there may be multiple dpys on the same connector.
*/
static void
ProcFsPrintDpys(
void *data,
char *buffer,
size_t size,
nvkms_procfs_out_string_func_t *outString)
{
const NVDevEvoRec *pDevEvo;
const NVDispEvoRec *pDispEvo;
NvU32 dispIndex;
NVEvoInfoStringRec infoString;
FOR_ALL_EVO_DEVS(pDevEvo) {
nvInitInfoString(&infoString, buffer, size);
nvEvoLogInfoString(&infoString,
"deviceId : %02d",
pDevEvo->deviceId.rmDeviceId);
outString(data, buffer);
FOR_ALL_EVO_DISPLAYS(pDispEvo, dispIndex, pDevEvo) {
const NVConnectorEvoRec *pConnectorEvo;
FOR_ALL_EVO_CONNECTORS(pConnectorEvo, pDispEvo) {
const NVDpyEvoRec *pDpyEvo;
nvInitInfoString(&infoString, buffer, size);
nvEvoLogInfoString(&infoString,
" connector : %s",
pConnectorEvo->name);
outString(data, buffer);
FOR_ALL_EVO_DPYS(pDpyEvo, pDispEvo->validDisplays, pDispEvo) {
const char *name;
if (pDpyEvo->pConnectorEvo != pConnectorEvo) {
continue;
}
nvInitInfoString(&infoString, buffer, size);
if (nvDpyIdIsInDpyIdList(pDpyEvo->id,
pDispEvo->connectedDisplays)) {
name = pDpyEvo->name;
} else {
name = "(not connected)";
}
nvEvoLogInfoString(&infoString,
" dpy : %s", name);
if (pDpyEvo->edid.length) {
NvU32 i;
const NvU8 *buf = pDpyEvo->edid.buffer;
nvEvoLogInfoStringRaw(&infoString,
" edid :");
for (i = 0; i < pDpyEvo->edid.length; i++) {
if (i % 16 == 0) {
nvEvoLogInfoStringRaw(&infoString, "\n ");
}
if (i % 8 == 0) {
nvEvoLogInfoStringRaw(&infoString, " ");
}
nvEvoLogInfoStringRaw(&infoString, " %02x",
buf[i]);
}
nvEvoLogInfoStringRaw(&infoString, "\n");
}
outString(data, buffer);
}
}
}
}
}
void nvKmsGetProcFiles(const nvkms_procfs_file_t **ppProcFiles)
{
#if NVKMS_PROCFS_ENABLE
static const nvkms_procfs_file_t procFiles[] = {
#if NVKMS_PROCFS_OBJECT_DUMP
{ "clients", ProcFsPrintClients },
{ "surfaces", ProcFsPrintSurfaces },
{ "headsurface", ProcFsPrintHeadSurface },
{ "deferred-request-fifos", ProcFsPrintDeferredRequestFifos },
#endif
#if NVKMS_HEADSURFACE_STATS
{ "headsurface", ProcFsPrintHeadSurface },
#endif
#if NVKMS_PROCFS_CRCS
{ "crcs", ProcFsPrintDpyCrcs },
#endif
{ "heads", ProcFsPrintHeads },
{ "dpys", ProcFsPrintDpys },
{ NULL, NULL },
};
*ppProcFiles = procFiles;
#else
*ppProcFiles = NULL;
#endif
}
static void FreeGlobalState(void)