1 /* 2 * SPDX-FileCopyrightText: Copyright (c) 1993-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 * SPDX-License-Identifier: MIT 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be included in 13 * all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 24 /******************************* DisplayPort********************************\ 25 * * 26 * Module: dp_evoadapter.cpp * 27 * Interface for low level access to the aux bus. * 28 * This is the synchronous version of the interface. * 29 * * 30 \***************************************************************************/ 31 #include "dp_internal.h" 32 #include "dp_evoadapter.h" 33 #include "dp_auxdefs.h" 34 #include "dp_tracing.h" 35 #include "dp_vrr.h" 36 #include <nvmisc.h> 37 38 #include <ctrl/ctrl0073/ctrl0073specific.h> 39 #include <ctrl/ctrl0073/ctrl0073system.h> 40 #include <ctrl/ctrl5070/ctrl5070or.h> 41 42 using namespace DisplayPort; 43 44 // 45 // Evo hardcodes the relationship between stream and head # 46 // Head#x is always stream x+1 47 // 48 #define STREAM_TO_HEAD_ID(s) ((s) - 1) 49 #define HEAD_TO_STREAM_ID(s) ((s) + 1) 50 51 // 52 // Data Base used to store all the regkey values. 53 // The type is defined in dp_regkeydatabase.h. 54 // All entries set to 0 before initialized by the first EvoMainLink constructor. 55 // The first EvoMainLink constructor will populate that data base. 56 // Later EvoMainLink will use values from that data base. 57 // 58 static struct DP_REGKEY_DATABASE dpRegkeyDatabase = {0}; 59 60 enum DP_REG_VAL_TYPE 61 { 62 DP_REG_VAL_BOOL = 0, 63 DP_REG_VAL_U32 = 1, 64 DP_REG_VAL_U16 = 2, 65 DP_REG_VAL_U8 = 3 66 }; 67 68 const struct 69 { 70 const char* pName; 71 void* pValue; 72 DP_REG_VAL_TYPE valueType; 73 } DP_REGKEY_TABLE [] = 74 { 75 {NV_DP_REGKEY_ENABLE_AUDIO_BEYOND_48K, &dpRegkeyDatabase.bAudioBeyond48kEnabled, DP_REG_VAL_BOOL}, 76 {NV_DP_REGKEY_OVERRIDE_DPCD_REV, &dpRegkeyDatabase.dpcdRevOveride, DP_REG_VAL_U32}, 77 {NV_DP_REGKEY_DISABLE_SSC, &dpRegkeyDatabase.bSscDisabled, DP_REG_VAL_BOOL}, 78 {NV_DP_REGKEY_ENABLE_FAST_LINK_TRAINING, &dpRegkeyDatabase.bFastLinkTrainingEnabled, DP_REG_VAL_BOOL}, 79 {NV_DP_REGKEY_DISABLE_MST, &dpRegkeyDatabase.bMstDisabled, DP_REG_VAL_BOOL}, 80 {NV_DP_REGKEY_ENABLE_INBAND_STEREO_SIGNALING, &dpRegkeyDatabase.bInbandStereoSignalingEnabled, DP_REG_VAL_BOOL}, 81 {NV_DP_REGKEY_SKIP_POWEROFF_EDP_IN_HEAD_DETACH, &dpRegkeyDatabase.bPoweroffEdpInHeadDetachSkipped, DP_REG_VAL_BOOL}, 82 {NV_DP_REGKEY_ENABLE_OCA_LOGGING, &dpRegkeyDatabase.bOcaLoggingEnabled, DP_REG_VAL_BOOL}, 83 {NV_DP_REGKEY_REPORT_DEVICE_LOST_BEFORE_NEW, &dpRegkeyDatabase.bReportDeviceLostBeforeNew, DP_REG_VAL_BOOL}, 84 {NV_DP_REGKEY_APPLY_LINK_BW_OVERRIDE_WAR, &dpRegkeyDatabase.bLinkBwOverrideWarApplied, DP_REG_VAL_BOOL}, 85 {NV_DP_REGKEY_APPLY_MAX_LINK_RATE_OVERRIDES, &dpRegkeyDatabase.applyMaxLinkRateOverrides, DP_REG_VAL_U32}, 86 {NV_DP_REGKEY_DISABLE_DSC, &dpRegkeyDatabase.bDscDisabled, DP_REG_VAL_BOOL}, 87 {NV_DP_REGKEY_SKIP_ASSESSLINK_FOR_EDP, &dpRegkeyDatabase.bAssesslinkForEdpSkipped, DP_REG_VAL_BOOL}, 88 {NV_DP_REGKEY_HDCP_AUTH_ONLY_ON_DEMAND, &dpRegkeyDatabase.bHdcpAuthOnlyOnDemand, DP_REG_VAL_BOOL}, 89 {NV_DP_REGKEY_ENABLE_MSA_OVER_MST, &dpRegkeyDatabase.bMsaOverMstEnabled, DP_REG_VAL_BOOL}, 90 {NV_DP_REGKEY_KEEP_OPT_LINK_ALIVE, &dpRegkeyDatabase.bOptLinkKeptAlive, DP_REG_VAL_BOOL}, 91 {NV_DP_REGKEY_KEEP_OPT_LINK_ALIVE_MST, &dpRegkeyDatabase.bOptLinkKeptAliveMst, DP_REG_VAL_BOOL}, 92 {NV_DP_REGKEY_KEEP_OPT_LINK_ALIVE_SST, &dpRegkeyDatabase.bOptLinkKeptAliveSst, DP_REG_VAL_BOOL}, 93 {NV_DP_REGKEY_FORCE_EDP_ILR, &dpRegkeyDatabase.bBypassEDPRevCheck, DP_REG_VAL_BOOL}, 94 {NV_DP_DSC_MST_CAP_BUG_3143315, &dpRegkeyDatabase.bDscMstCapBug3143315, DP_REG_VAL_BOOL}, 95 {NV_DP_REGKEY_POWER_DOWN_PHY, &dpRegkeyDatabase.bPowerDownPhyBeforeD3, DP_REG_VAL_BOOL}, 96 {NV_DP_REGKEY_REASSESS_MAX_LINK, &dpRegkeyDatabase.bReassessMaxLink, DP_REG_VAL_BOOL}, 97 {NV_DP_REGKEY_MST_PCON_CAPS_READ_DISABLED, &dpRegkeyDatabase.bMSTPCONCapsReadDisabled, DP_REG_VAL_BOOL}, 98 {NV_DP_REGKEY_FORCE_DSC_ON_SINK, &dpRegkeyDatabase.bForceDscOnSink, DP_REG_VAL_BOOL}, 99 }; 100 101 EvoMainLink::EvoMainLink(EvoInterface * provider, Timer * timer) : 102 provider(provider), 103 timer(timer), 104 displayId(provider->getDisplayId()), 105 subdeviceIndex(provider->getSubdeviceIndex()) 106 { 107 // 108 // Process GPU caps (This needs to be replaced with a control call caps interface) 109 // 110 NvU32 code; 111 112 // Initialize shared regkey data base, and apply the overrides 113 this->initializeRegkeyDatabase(); 114 this->applyRegkeyOverrides(); 115 116 _isDynamicMuxCapable = false; 117 _isLTPhyRepeaterSupported = true; 118 _rmPhyRepeaterCount = 0; 119 dpMemZero(&_DSC, sizeof(_DSC)); 120 dpMemZero(&dfpParams, sizeof(dfpParams)); 121 dpMemZero(&dpParams, sizeof(dpParams)); 122 123 // 124 // Tell RM to hands off on the DisplayPort hardware 125 // 126 NV0073_CTRL_CMD_DP_SET_MANUAL_DISPLAYPORT_PARAMS setManualParams = {0}; 127 setManualParams.subDeviceInstance = subdeviceIndex; 128 code = provider->rmControl0073(NV0073_CTRL_CMD_DP_SET_MANUAL_DISPLAYPORT, &setManualParams, sizeof setManualParams); 129 DP_ASSERT (code == NVOS_STATUS_SUCCESS && "Unable to enable library mode"); 130 131 // 132 // Get the mask of valid heads 133 // 134 NV0073_CTRL_SPECIFIC_GET_ALL_HEAD_MASK_PARAMS allHeadMaskParams; 135 dpMemZero(&allHeadMaskParams, sizeof allHeadMaskParams); 136 allHeadMaskParams.subDeviceInstance = subdeviceIndex; 137 code = provider->rmControl0073(NV0073_CTRL_CMD_SPECIFIC_GET_ALL_HEAD_MASK, &allHeadMaskParams, sizeof(allHeadMaskParams)); 138 139 if (code != NVOS_STATUS_SUCCESS) 140 { 141 DP_ASSERT(0 && "Unable to get head mask"); 142 allHeadMask = 3; 143 } 144 else 145 { 146 allHeadMask = allHeadMaskParams.headMask; 147 } 148 } 149 150 151 bool EvoMainLink::vrrRunEnablementStage(unsigned stage, NvU32 *status) 152 { 153 NV0073_CTRL_CMD_DP_ENABLE_VRR_PARAMS params = {0}; 154 params.subDeviceInstance = subdeviceIndex; 155 params.displayId = this->displayId; 156 157 switch (stage) 158 { 159 case VRR_ENABLE_STAGE_MONITOR_ENABLE_BEGIN: 160 params.cmd |= DRF_DEF(0073_CTRL_DP_CMD, _ENABLE_VRR_CMD, _STAGE, _MONITOR_ENABLE_BEGIN); 161 break; 162 case VRR_ENABLE_STAGE_MONITOR_ENABLE_CHALLENGE: 163 params.cmd |= DRF_DEF(0073_CTRL_DP_CMD, _ENABLE_VRR_CMD, _STAGE, _MONITOR_ENABLE_CHALLENGE); 164 break; 165 case VRR_ENABLE_STAGE_MONITOR_ENABLE_CHECK: 166 params.cmd |= DRF_DEF(0073_CTRL_DP_CMD, _ENABLE_VRR_CMD, _STAGE, _MONITOR_ENABLE_CHECK); 167 break; 168 case VRR_ENABLE_STAGE_DRIVER_ENABLE_BEGIN: 169 params.cmd |= DRF_DEF(0073_CTRL_DP_CMD, _ENABLE_VRR_CMD, _STAGE, _DRIVER_ENABLE_BEGIN); 170 break; 171 case VRR_ENABLE_STAGE_DRIVER_ENABLE_CHALLENGE: 172 params.cmd |= DRF_DEF(0073_CTRL_DP_CMD, _ENABLE_VRR_CMD, _STAGE, _DRIVER_ENABLE_CHALLENGE); 173 break; 174 case VRR_ENABLE_STAGE_DRIVER_ENABLE_CHECK: 175 params.cmd |= DRF_DEF(0073_CTRL_DP_CMD, _ENABLE_VRR_CMD, _STAGE, _DRIVER_ENABLE_CHECK); 176 break; 177 case VRR_ENABLE_STAGE_RESET_MONITOR: 178 params.cmd |= DRF_DEF(0073_CTRL_DP_CMD, _ENABLE_VRR_CMD, _STAGE, _RESET_MONITOR); 179 break; 180 case VRR_ENABLE_STAGE_INIT_PUBLIC_INFO: 181 params.cmd |= DRF_DEF(0073_CTRL_DP_CMD, _ENABLE_VRR_CMD, _STAGE, _INIT_PUBLIC_INFO); 182 break; 183 case VRR_ENABLE_STAGE_GET_PUBLIC_INFO: 184 params.cmd |= DRF_DEF(0073_CTRL_DP_CMD, _ENABLE_VRR_CMD, _STAGE, _GET_PUBLIC_INFO); 185 break; 186 case VRR_ENABLE_STAGE_STATUS_CHECK: 187 params.cmd |= DRF_DEF(0073_CTRL_DP_CMD, _ENABLE_VRR_CMD, _STAGE, _STATUS_CHECK); 188 break; 189 default: 190 DP_ASSERT(0 && "Undefined VRR Enablement Stage."); 191 return false; 192 } 193 NvU32 retVal = provider->rmControl0073(NV0073_CTRL_CMD_DP_ENABLE_VRR, ¶ms, sizeof(params)); 194 if (status) 195 { 196 *status = params.result; 197 } 198 if (retVal != NVOS_STATUS_SUCCESS) 199 { 200 return false; 201 } 202 return true; 203 } 204 205 bool EvoMainLink::getEdpPowerData(bool *panelPowerOn, bool *dpcdPowerStateD0) 206 { 207 NV0073_CTRL_DP_GET_EDP_DATA_PARAMS params; 208 params.subDeviceInstance = subdeviceIndex; 209 params.displayId = this->displayId; 210 NvU32 code = provider->rmControl0073(NV0073_CTRL_CMD_DP_GET_EDP_DATA, ¶ms, sizeof(params)); 211 212 if (code != NVOS_STATUS_SUCCESS) 213 { 214 DP_ASSERT(0 && "Unable to get eDP power data, assuming panel off."); 215 if (panelPowerOn) 216 { 217 *panelPowerOn = false; 218 } 219 if (dpcdPowerStateD0) 220 { 221 *dpcdPowerStateD0 = false; 222 } 223 return false; 224 } 225 else 226 { 227 if (panelPowerOn) 228 { 229 *panelPowerOn = FLD_TEST_DRF(0073_CTRL_DP, _GET_EDP_DATA, _PANEL_POWER, _ON, 230 params.data); 231 } 232 if (dpcdPowerStateD0) 233 { 234 *dpcdPowerStateD0 = FLD_TEST_DRF(0073_CTRL_DP, _GET_EDP_DATA, _DPCD_POWER_STATE, _D0, 235 params.data); 236 } 237 return true; 238 } 239 } 240 241 NvU32 EvoMainLink::streamToHead(NvU32 streamId, DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID streamIdentifier) 242 { 243 NvU32 headIndex = 0; 244 NvU32 maxHeads = allHeadMask; 245 NUMSETBITS_32(maxHeads); 246 headIndex = DP_MST_STREAMID_TO_HEAD(streamId, streamIdentifier, maxHeads); 247 248 return headIndex; 249 } 250 251 NvU32 EvoMainLink::headToStream(NvU32 head, DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID streamIdentifier) 252 { 253 NvU32 streamIndex = 0; 254 255 NvU32 maxHeads = allHeadMask; 256 NUMSETBITS_32(maxHeads); 257 streamIndex = DP_MST_HEAD_TO_STREAMID(head, streamIdentifier, maxHeads); 258 259 return streamIndex; 260 } 261 262 bool EvoMainLink::queryGPUCapability() 263 { 264 dpMemZero(&dpParams, sizeof(dpParams)); 265 dpParams.subDeviceInstance = subdeviceIndex; 266 dpParams.sorIndex = provider->getSorIndex(); 267 NvU32 code = provider->rmControl0073(NV0073_CTRL_CMD_DP_GET_CAPS, &dpParams, sizeof(dpParams)); 268 if (code != NVOS_STATUS_SUCCESS) 269 { 270 DP_ASSERT(0 && "Unable to process GPU caps"); 271 return false; 272 } 273 // 274 // Check if MST feature needs to be disabled by regkey. This is requirement by few OEMs, they don't want to support 275 // MST feature on particular sku, whenever requested through INF. 276 // 277 _hasMultistream = (dpParams.bIsMultistreamSupported == NV_TRUE) && !_isMstDisabledByRegkey; 278 279 _gpuSupportedDpVersions = dpParams.dpVersionsSupported; 280 281 _isStreamCloningEnabled = (dpParams.bIsSCEnabled == NV_TRUE) ? true : false; 282 _hasIncreasedWatermarkLimits = (dpParams.bHasIncreasedWatermarkLimits == NV_TRUE) ? true : false; 283 284 _isFECSupported = (dpParams.bFECSupported == NV_TRUE) ? true : false; 285 286 _useDfpMaxLinkRateCaps = (dpParams.bOverrideLinkBw == NV_TRUE) ? true : false; 287 288 _isLTPhyRepeaterSupported = (dpParams.bIsTrainPhyRepeater == NV_TRUE) ? true : false; 289 290 if (FLD_TEST_DRF(0073, _CTRL_CMD_DP_GET_CAPS, _MAX_LINK_RATE, _1_62, dpParams.maxLinkRate)) 291 _maxLinkRateSupportedGpu = RBR; //in Hz 292 else if (FLD_TEST_DRF(0073, _CTRL_CMD_DP_GET_CAPS, _MAX_LINK_RATE, _2_70, dpParams.maxLinkRate)) 293 _maxLinkRateSupportedGpu = HBR; //in Hz 294 else if (FLD_TEST_DRF(0073, _CTRL_CMD_DP_GET_CAPS, _MAX_LINK_RATE, _5_40, dpParams.maxLinkRate)) 295 _maxLinkRateSupportedGpu = HBR2; //in Hz 296 else if (FLD_TEST_DRF(0073, _CTRL_CMD_DP_GET_CAPS, _MAX_LINK_RATE, _8_10, dpParams.maxLinkRate)) 297 _maxLinkRateSupportedGpu = HBR3; //in Hz 298 else 299 { 300 DP_ASSERT(0 && "Unable to get max link rate"); 301 // Assume that we can at least support RBR. 302 _maxLinkRateSupportedGpu = RBR; 303 } 304 305 if (!_isDscDisabledByRegkey) 306 { 307 _DSC.isDscSupported = dpParams.DSC.bDscSupported ? true : false; 308 _DSC.encoderColorFormatMask = dpParams.DSC.encoderColorFormatMask; 309 _DSC.lineBufferSizeKB = dpParams.DSC.lineBufferSizeKB; 310 _DSC.rateBufferSizeKB = dpParams.DSC.rateBufferSizeKB; 311 _DSC.bitsPerPixelPrecision = dpParams.DSC.bitsPerPixelPrecision; 312 _DSC.maxNumHztSlices = dpParams.DSC.maxNumHztSlices; 313 _DSC.lineBufferBitDepth = dpParams.DSC.lineBufferBitDepth; 314 } 315 return true; 316 } 317 318 void EvoMainLink::triggerACT() 319 { 320 NV0073_CTRL_CMD_DP_SEND_ACT_PARAMS params = {0}; 321 params.subDeviceInstance = this->subdeviceIndex; 322 params.displayId = this->displayId; 323 324 provider->rmControl0073(NV0073_CTRL_CMD_DP_SEND_ACT, ¶ms, sizeof params); 325 } 326 327 void EvoMainLink::configureHDCPRenegotiate(NvU64 cN, NvU64 cKSV, bool bForceReAuth, bool bRxIDMsgPending){} 328 void EvoMainLink::configureHDCPGetHDCPState(HDCPState &hdcpState) 329 { 330 // HDCP Not Supported 331 hdcpState.HDCP_State_Repeater_Capable = false; 332 hdcpState.HDCP_State_22_Capable = false; 333 hdcpState.HDCP_State_Encryption = false; 334 hdcpState.HDCP_State_Authenticated = false; 335 } 336 337 void EvoMainLink::configureSingleStream(NvU32 head, 338 NvU32 hBlankSym, 339 NvU32 vBlankSym, 340 bool bEnhancedFraming, 341 NvU32 tuSize, 342 NvU32 waterMark, 343 DP_COLORFORMAT colorFormat, 344 DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID streamId, 345 DP_SINGLE_HEAD_MULTI_STREAM_MODE singleHeadMultiStreamMode, 346 bool bAudioOverRightPanel, 347 bool bEnable2Head1Or) 348 { 349 NV0073_CTRL_CMD_DP_CONFIG_STREAM_PARAMS params = {0}; 350 params.subDeviceInstance = this->subdeviceIndex; 351 params.head = head; 352 params.sorIndex = provider->getSorIndex(); 353 params.bEnableTwoHeadOneOr = bEnable2Head1Or; 354 355 if (singleHeadMultiStreamMode == DP_SINGLE_HEAD_MULTI_STREAM_MODE_SST) 356 { 357 // In 2-SST mode configure Head-SF on primary link, so primary link configuration 358 // gets copied to secondary link. 359 params.dpLink = streamId; 360 } 361 else 362 { 363 params.dpLink = provider->getLinkIndex(); 364 } 365 366 params.bEnableOverride = NV_TRUE; 367 params.bMST = NV_FALSE; 368 params.hBlankSym = hBlankSym; 369 params.vBlankSym = vBlankSym; 370 params.colorFormat = colorFormat; 371 372 params.SST.bEnhancedFraming = bEnhancedFraming; 373 params.SST.tuSize = tuSize; 374 params.SST.waterMark = waterMark; 375 params.SST.bEnableAudioOverRightPanel = bAudioOverRightPanel; 376 377 provider->rmControl0073(NV0073_CTRL_CMD_DP_CONFIG_STREAM, ¶ms, sizeof params); 378 } 379 380 void EvoMainLink::configureSingleHeadMultiStreamMode(NvU32 displayIDs[], 381 NvU32 numStreams, 382 NvU32 mode, 383 bool bSetConfig, 384 NvU8 vbiosPrimaryDispIdIndex) 385 { 386 NV0073_CTRL_CMD_DP_CONFIG_SINGLE_HEAD_MULTI_STREAM_PARAMS params = {0}; 387 params.subDeviceInstance = this->subdeviceIndex; 388 389 for (NvU32 pipelineID = 0; pipelineID < numStreams; pipelineID++) 390 { 391 params.displayIDs[pipelineID] = displayIDs[pipelineID]; 392 } 393 params.mode = mode; 394 params.bSetConfig = bSetConfig; 395 params.numStreams = numStreams; 396 params.vbiosPrimaryDispIdIndex = vbiosPrimaryDispIdIndex; 397 398 provider->rmControl0073(NV0073_CTRL_CMD_DP_CONFIG_SINGLE_HEAD_MULTI_STREAM, 399 ¶ms, 400 sizeof params); 401 } 402 403 void EvoMainLink::configureMultiStream(NvU32 head, 404 NvU32 hBlankSym, 405 NvU32 vBlankSym, 406 NvU32 slotStart, 407 NvU32 slotEnd, 408 NvU32 PBN, 409 NvU32 Timeslice, 410 DP_COLORFORMAT colorFormat, 411 DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID streamIdentifier, 412 DP_SINGLE_HEAD_MULTI_STREAM_MODE singleHeadMultistreamMode, 413 bool bAudioOverRightPanel, 414 bool bEnable2Head1Or) 415 { 416 NV0073_CTRL_CMD_DP_CONFIG_STREAM_PARAMS params = {0}; 417 params.head = head; 418 params.subDeviceInstance = this->subdeviceIndex; 419 params.sorIndex = provider->getSorIndex(); 420 params.dpLink = provider->getLinkIndex(); 421 params.bEnableOverride = NV_TRUE; 422 params.bMST = NV_TRUE; 423 params.hBlankSym = hBlankSym; 424 params.vBlankSym = vBlankSym; 425 params.colorFormat = colorFormat; 426 params.bEnableTwoHeadOneOr = bEnable2Head1Or; 427 params.singleHeadMultistreamMode = singleHeadMultistreamMode; 428 429 params.MST.slotStart = slotStart; 430 params.MST.slotEnd = slotEnd; 431 params.MST.PBN = PBN; 432 params.MST.Timeslice = Timeslice; 433 params.MST.singleHeadMSTPipeline = streamIdentifier; 434 params.MST.bEnableAudioOverRightPanel = bAudioOverRightPanel; 435 436 provider->rmControl0073(NV0073_CTRL_CMD_DP_CONFIG_STREAM, ¶ms, sizeof params); 437 } 438 439 void EvoMainLink::configureMsScratchRegisters(NvU32 address, 440 NvU32 hopCount, 441 NvU32 dpMsDevAddrState) 442 { 443 NV0073_CTRL_CMD_DP_CONFIG_RAD_SCRATCH_REG_PARAMS params = {0}; 444 params.subDeviceInstance = this->subdeviceIndex; 445 params.displayId = this->displayId; 446 params.activeDevAddr = address; 447 params.sorIndex = provider->getSorIndex(); 448 params.dpLink = provider->getLinkIndex(); 449 params.hopCount = hopCount; 450 params.dpMsDevAddrState = dpMsDevAddrState; 451 452 provider->rmControl0073(NV0073_CTRL_CMD_DP_CONFIG_RAD_SCRATCH_REG, ¶ms, sizeof params); 453 } 454 455 // 456 // EvoMainLink::setDpStereoMSAParameters does the DP library Stereo override for 457 // In-band signaling through the MSA MISC1 field and keeps the rest of the MSA 458 // params the same. 459 // 460 // On GK110 and later, when stereo is enabled, we send the stereo eye 461 // information to the sink device through the MSA MISC1 bits 2:1. Certain 462 // DP 1.2 non-compliant DP->VGA dongles cannot handle this information, and 463 // lose all signal when these bits are non-zero. This WAR uses a RM control 464 // to override those MSA bits to zero. It should be called whenever a DP->VGA 465 // dongle is in use. 466 // 467 bool EvoMainLink::setDpStereoMSAParameters(bool bStereoEnable, const NV0073_CTRL_CMD_DP_SET_MSA_PROPERTIES_PARAMS &msaparams) 468 { 469 NV0073_CTRL_CMD_DP_SET_STEREO_MSA_PROPERTIES_PARAMS params = {0}; 470 params.subDeviceInstance = this->subdeviceIndex; 471 params.displayId = msaparams.displayId; 472 //clubbing the MSA params passed by DD with Dp Library Stereo Override 473 params.bStereoPhaseInverse = msaparams.bStereoPhaseInverse; 474 params.featureValues.misc[1] = msaparams.featureValues.misc[1]; 475 476 if (bStereoEnable) { 477 params.bEnableMSA = NV_TRUE | msaparams.bEnableMSA; 478 params.featureMask.miscMask[1] = DRF_SHIFTMASK(NV_DP_MSA_PROPERTIES_MISC1_STEREO) | msaparams.featureMask.miscMask[1]; 479 } else { 480 params.bEnableMSA = NV_FALSE | msaparams.bEnableMSA; 481 params.featureMask.miscMask[1] |= msaparams.featureMask.miscMask[1]; 482 } 483 484 NvU32 ret = provider->rmControl0073(NV0073_CTRL_CMD_DP_SET_STEREO_MSA_PROPERTIES, ¶ms, sizeof params); 485 486 // 487 // NV0073_CTRL_CMD_DP_SET_MSA_PROPERTIES is only implemented on GK110 and 488 // later, but this WAR is unnecessary on other GPUs, so ignore 489 // ERROR_NOT_SUPPORTED. 490 // 491 // XXX This may fail if a future GPU requires this WAR but does not 492 // implement this rmcontrol. To avoid that, this class would need to be 493 // aware of which evo display HAL is in use. 494 // 495 if (ret != NVOS_STATUS_SUCCESS && ret != NVOS_STATUS_ERROR_NOT_SUPPORTED) { 496 DP_ASSERT(!"Enabling MSA stereo override failed!"); 497 return false; 498 } 499 500 return true; 501 } 502 503 // 504 // EvoMainLink::setDpMSAParameters clubs MSA parameters passed by DD for format YCbCr4:2:0 505 // with DP library Stereo override for In-band signaling through the MSA MISC1 field. 506 // 507 // On GK110 and later, when stereo is enabled, we send the stereo eye 508 // information to the sink device through the MSA MISC1 bits 2:1. Certain 509 // DP 1.2 non-compliant DP->VGA dongles cannot handle this information, and 510 // lose all signal when these bits are non-zero. This WAR uses a RM control 511 // to override those MSA bits to zero. It should be called whenever a DP->VGA 512 // dongle is in use. 513 // 514 bool EvoMainLink::setDpMSAParameters(bool bStereoEnable, const NV0073_CTRL_CMD_DP_SET_MSA_PROPERTIES_PARAMS &msaparams) 515 { 516 NV0073_CTRL_CMD_DP_SET_MSA_PROPERTIES_PARAMS params = {0}; 517 params.subDeviceInstance = this->subdeviceIndex; 518 params.displayId = msaparams.displayId; 519 //clubbing the MSA params passed by DD with Dp Library Stereo Override 520 params.bStereoPhaseInverse = msaparams.bStereoPhaseInverse; 521 params.bCacheMsaOverrideForNextModeset = true; 522 params.featureValues.misc[0] = msaparams.featureValues.misc[0]; 523 params.featureValues.misc[1] = msaparams.featureValues.misc[1]; 524 params.featureMask.miscMask[0] = msaparams.featureMask.miscMask[0]; 525 526 params.featureValues.rasterTotalHorizontal = msaparams.featureValues.rasterTotalHorizontal; 527 params.featureValues.rasterTotalVertical = msaparams.featureValues.rasterTotalVertical; 528 params.featureValues.activeStartHorizontal = msaparams.featureValues.activeStartHorizontal; 529 params.featureValues.activeStartVertical = msaparams.featureValues.activeStartVertical; 530 params.featureValues.surfaceTotalHorizontal = msaparams.featureValues.surfaceTotalHorizontal; 531 params.featureValues.surfaceTotalVertical = msaparams.featureValues.surfaceTotalVertical; 532 params.featureValues.syncWidthHorizontal = msaparams.featureValues.syncWidthHorizontal; 533 params.featureValues.syncPolarityHorizontal = msaparams.featureValues.syncPolarityHorizontal; 534 params.featureValues.syncHeightVertical = msaparams.featureValues.syncHeightVertical; 535 params.featureValues.syncPolarityVertical = msaparams.featureValues.syncPolarityVertical; 536 537 params.featureMask.bRasterTotalHorizontal = msaparams.featureMask.bRasterTotalHorizontal; 538 params.featureMask.bRasterTotalVertical = msaparams.featureMask.bRasterTotalVertical; 539 params.featureMask.bActiveStartHorizontal = msaparams.featureMask.bActiveStartHorizontal; 540 params.featureMask.bActiveStartVertical = msaparams.featureMask.bActiveStartVertical; 541 params.featureMask.bSurfaceTotalHorizontal = msaparams.featureMask.bSurfaceTotalHorizontal; 542 params.featureMask.bSurfaceTotalVertical = msaparams.featureMask.bSurfaceTotalVertical; 543 params.featureMask.bSyncWidthHorizontal = msaparams.featureMask.bSyncWidthHorizontal; 544 params.featureMask.bSyncPolarityHorizontal = msaparams.featureMask.bSyncPolarityHorizontal; 545 params.featureMask.bSyncHeightVertical = msaparams.featureMask.bSyncHeightVertical; 546 params.featureMask.bSyncPolarityVertical = msaparams.featureMask.bSyncPolarityVertical; 547 548 params.featureValues.reserved[0] = msaparams.featureValues.reserved[0]; 549 params.featureValues.reserved[1] = msaparams.featureValues.reserved[1]; 550 params.featureValues.reserved[2] = msaparams.featureValues.reserved[2]; 551 552 params.pFeatureDebugValues = msaparams.pFeatureDebugValues; 553 554 if (bStereoEnable) { 555 params.bEnableMSA = NV_TRUE | msaparams.bEnableMSA; 556 params.featureMask.miscMask[1] = DRF_SHIFTMASK(NV_DP_MSA_PROPERTIES_MISC1_STEREO) | msaparams.featureMask.miscMask[1]; 557 } else { 558 params.bEnableMSA = NV_FALSE | msaparams.bEnableMSA; 559 params.featureMask.miscMask[1] |= msaparams.featureMask.miscMask[1]; 560 } 561 562 NvU32 ret = provider->rmControl0073(NV0073_CTRL_CMD_DP_SET_MSA_PROPERTIES, ¶ms, sizeof params); 563 564 // 565 // NV0073_CTRL_CMD_DP_SET_MSA_PROPERTIES is only implemented on GK110 and 566 // later, but this WAR is unnecessary on other GPUs, so ignore 567 // ERROR_NOT_SUPPORTED. 568 // 569 // XXX This may fail if a future GPU requires this WAR but does not 570 // implement this rmcontrol. To avoid that, this class would need to be 571 // aware of which evo display HAL is in use. 572 // 573 if (ret != NVOS_STATUS_SUCCESS && ret != NVOS_STATUS_ERROR_NOT_SUPPORTED) { 574 DP_ASSERT(!"Enabling MSA stereo override failed!"); 575 return false; 576 } 577 578 return true; 579 } 580 581 bool EvoMainLink::setFlushMode() 582 { 583 NV5070_CTRL_SET_SOR_FLUSH_MODE_PARAMS params; 584 dpMemZero(¶ms, sizeof(params)); 585 586 params.bFireAndForget = NV_FALSE; 587 588 params.base.subdeviceIndex = subdeviceIndex; 589 params.sorNumber = provider->getSorIndex(); 590 params.bEnable = NV_TRUE; 591 params.bForceRgDiv = NV_FALSE; 592 params.bImmediate = NV_FALSE; 593 params.headMask = 0; 594 595 NvU32 ret = provider->rmControl5070(NV5070_CTRL_CMD_SET_SOR_FLUSH_MODE, ¶ms, sizeof params); 596 597 DP_ASSERT((ret == NVOS_STATUS_SUCCESS) && "Enabling flush mode failed!"); 598 599 return ret == NVOS_STATUS_SUCCESS; 600 } 601 602 void EvoMainLink::clearFlushMode(unsigned headMask, bool testMode) 603 { 604 NV5070_CTRL_SET_SOR_FLUSH_MODE_PARAMS params; 605 dpMemZero(¶ms, sizeof(params)); 606 607 params.bFireAndForget = NV_FALSE; 608 params.base.subdeviceIndex = subdeviceIndex; 609 params.sorNumber = provider->getSorIndex(); 610 params.bEnable = NV_FALSE; 611 params.bImmediate = NV_FALSE; 612 params.headMask = headMask; 613 params.bForceRgDiv = testMode; 614 615 NvU32 ret = provider->rmControl5070(NV5070_CTRL_CMD_SET_SOR_FLUSH_MODE, ¶ms, sizeof params); 616 if (ret != NVOS_STATUS_SUCCESS) 617 { 618 DP_LOG(("DP_EVO> Disabling flush mode failed!")); 619 } 620 } 621 622 623 bool EvoMainLink::physicalLayerSetTestPattern(PatternInfo * patternInfo) 624 { 625 // Main parameter 626 NV0073_CTRL_DP_SET_TESTPATTERN_PARAMS params; 627 628 // To identify which test pattern to transmit. 629 NV0073_CTRL_DP_TESTPATTERN ctrlPattern; 630 631 dpMemZero(¶ms, sizeof(params)); 632 dpMemZero(&ctrlPattern, sizeof(ctrlPattern)); 633 634 switch (patternInfo->lqsPattern) 635 { 636 case LINK_QUAL_DISABLED: ctrlPattern.testPattern = NV0073_CTRL_DP_TESTPATTERN_DATA_NONE; break; 637 case LINK_QUAL_D10_2: ctrlPattern.testPattern = NV0073_CTRL_DP_TESTPATTERN_DATA_D10_2; break; 638 case LINK_QUAL_SYM_ERROR: ctrlPattern.testPattern = NV0073_CTRL_DP_TESTPATTERN_DATA_SERMP; break; 639 case LINK_QUAL_PRBS7: ctrlPattern.testPattern = NV0073_CTRL_DP_TESTPATTERN_DATA_PRBS_7; break; 640 case LINK_QUAL_CP2520PAT3: ctrlPattern.testPattern = NV0073_CTRL_DP_TESTPATTERN_DATA_CP2520PAT3; break; 641 case LINK_QUAL_80BIT_CUST: 642 { 643 ctrlPattern.testPattern = NV0073_CTRL_DP_TESTPATTERN_DATA_CSTM; 644 645 params.cstm.field_31_0 = patternInfo->ctsmLower; 646 params.cstm.field_63_32 = patternInfo->ctsmMiddle; 647 params.cstm.field_95_64 = patternInfo->ctsmUpper; 648 break; 649 } 650 #ifdef NV0073_CTRL_DP_TESTPATTERN_DATA_HBR2COMPLIANCE 651 case LINK_QUAL_HBR2_COMPLIANCE_EYE: 652 { 653 ctrlPattern.testPattern = NV0073_CTRL_DP_TESTPATTERN_DATA_HBR2COMPLIANCE; 654 params.cstm.field_31_0 = 0; 655 params.cstm.field_63_32 = 0; 656 params.cstm.field_95_64 = 0; 657 break; 658 } 659 #endif 660 default: 661 DP_ASSERT(0 && "Unknown Phy Pattern"); 662 return false; 663 } 664 665 params.subDeviceInstance = subdeviceIndex; 666 params.displayId = displayId; 667 params.testPattern = ctrlPattern; 668 669 // 670 // Set the appropriate laneMask based on the current lane count. The laneMask is used for GF119+ chips 671 // only so it doesn't matter if we populate it for all chips. It is set to all lanes since 672 // setting the test pattern on a lane that is off is effectively a nop. 673 // The laneMask allows for setting the pattern on specific lanes to check for cross-talk, which is the 674 // phenomenon of observing the signal crossing over to a different lane where it's not set. 675 // 676 params.laneMask = 0xf; 677 678 NvU32 code = provider->rmControl0073(NV0073_CTRL_CMD_DP_SET_TESTPATTERN, ¶ms, sizeof(params)); 679 680 return code == NVOS_STATUS_SUCCESS; 681 } 682 683 AuxBus::status EvoAuxBus::transaction(Action action, Type type, int address, 684 NvU8 * buffer, unsigned sizeRequested, 685 unsigned * sizeCompleted, 686 unsigned *pNakReason, 687 NvU8 offset, NvU8 nWriteTransactions) 688 { 689 NV0073_CTRL_DP_AUXCH_CTRL_PARAMS params; 690 691 DP_ASSERT(sizeRequested <= NV0073_CTRL_DP_AUXCH_MAX_DATA_SIZE); 692 693 dpMemZero(¶ms, sizeof(params)); 694 params.subDeviceInstance = subdeviceIndex; 695 params.displayId = displayId; 696 697 params.cmd = 0; 698 699 if (type == native) 700 params.cmd |= DRF_DEF(0073_CTRL, _DP, _AUXCH_CMD_TYPE, _AUX); 701 else 702 params.cmd |= DRF_DEF(0073_CTRL, _DP, _AUXCH_CMD_TYPE, _I2C); 703 704 if (type == i2cMot) 705 params.cmd |= DRF_DEF(0073_CTRL, _DP, _AUXCH_CMD_I2C_MOT, _TRUE); 706 else 707 params.cmd |= DRF_DEF(0073_CTRL, _DP, _AUXCH_CMD_I2C_MOT, _FALSE); 708 709 if (action == read) 710 params.cmd |= DRF_DEF(0073_CTRL, _DP, _AUXCH_CMD_REQ_TYPE, _READ); 711 else if (action == write) 712 { 713 params.cmd |= DRF_DEF(0073_CTRL, _DP, _AUXCH_CMD_REQ_TYPE, _WRITE); 714 dpMemCopy(params.data, buffer, sizeRequested); 715 } 716 else if (action == writeStatusUpdateRequest) 717 params.cmd |= DRF_DEF(0073_CTRL, _DP, _AUXCH_CMD_REQ_TYPE, _WRITE_STATUS); 718 else 719 DP_ASSERT(0 && "Unknown action"); 720 721 params.addr = address; 722 723 // 724 // By definition, an I2C-write-over-AUX request with 725 // zero bytes of data is an "address-only" transaction. 726 // 727 if ((sizeRequested == 0) && (type & (i2cMot | i2c)) && (action == write)) 728 { 729 DP_LOG(("DP> Client requested address-only transaction")); 730 params.bAddrOnly = NV_TRUE; 731 } 732 else if ((sizeRequested == 0) && (type == native)) 733 { 734 // Native aux transactions with size requested zero are not allowed. 735 DP_ASSERT(0 && "Native Aux transactions shouldn't have zero size requested"); 736 return nack; 737 } 738 739 // Control call is taking size as 0-based. 740 if (sizeRequested == 0) 741 { 742 // 743 // I2c transactions with size requested zero. Decrementing by 1 will 744 // lead to 0xffffff(RM_INVALID_DATA). So keep size as zero only. 745 // 746 params.size = 0; 747 } 748 else 749 { 750 params.size = sizeRequested - 1; 751 } 752 753 NvU32 code = 0; 754 NvU8 retries = 0; 755 do 756 { 757 retries++; 758 params.retryTimeMs = 0; 759 code = provider->rmControl0073(NV0073_CTRL_CMD_DP_AUXCH_CTRL, ¶ms, sizeof(params)); 760 // eDP is not fully powered up yet. Should not access the panel too early. 761 if (params.retryTimeMs > 0) 762 { 763 timer->sleep(params.retryTimeMs); 764 } 765 } while (NVOS_STATUS_SUCCESS != code && params.retryTimeMs && retries < 3); 766 767 if (pNakReason != NULL) 768 { 769 *pNakReason = params.replyType; 770 } 771 772 if (action == writeStatusUpdateRequest && code == NVOS_STATUS_ERROR_NOT_SUPPORTED) 773 { 774 // 775 // On some chips write status requests are generated implicitly by the 776 // hardware. So while the RmControl() will fail with a "not supported" 777 // error, the request still went out on the DPAUX channel as part of 778 // the last IC-over-AUX write transaction. So the error should be ignored. 779 // 780 DP_LOG(("DP> %s: Ignore ERROR_NOT_SUPPORTED for writeStatusUpdateRequest. Returning Success", __FUNCTION__)); 781 return AuxBus::success; 782 } 783 784 // In case of Timeout we need to retry again for minimum no. of times 785 if (code != NVOS_STATUS_SUCCESS && code != NVOS_STATUS_ERROR_TIMEOUT) 786 { 787 if (devicePlugged) 788 { 789 DP_LOG(("DP> AuxChCtl Failing, if a device is connected you shouldn't be seeing this")); 790 } 791 return nack; 792 } 793 else if (code == NVOS_STATUS_ERROR_TIMEOUT) 794 { 795 return AuxBus::defer; 796 } 797 798 *sizeCompleted = params.size; 799 800 // Reset sizeCompleted if transaction failed. 801 if (params.replyType == NV0073_CTRL_DP_AUXCH_REPLYTYPE_DEFER || 802 params.replyType == NV0073_CTRL_DP_AUXCH_REPLYTYPE_I2CDEFER) 803 *sizeCompleted = 0; 804 805 if (params.replyType == NV0073_CTRL_DP_AUXCH_REPLYTYPE_ACK) 806 { 807 // if it was read operation copy read data to buffer 808 if (action == read) 809 { 810 // Check the size of data to be copied. Should not be 811 // more than available buffer 812 if (params.size > sizeRequested) 813 { 814 params.size = sizeRequested; 815 } 816 dpMemCopy(buffer, params.data, params.size); 817 } 818 819 return AuxBus::success; 820 } 821 822 if (params.replyType == NV0073_CTRL_DP_AUXCH_REPLYTYPE_NACK || 823 params.replyType == NV0073_CTRL_DP_AUXCH_REPLYTYPE_I2CNACK || 824 params.replyType == NV0073_CTRL_DP_AUXCH_REPLYTYPE_TIMEOUT) 825 return AuxBus::nack; 826 827 if (params.replyType == NV0073_CTRL_DP_AUXCH_REPLYTYPE_DEFER || 828 params.replyType == NV0073_CTRL_DP_AUXCH_REPLYTYPE_I2CDEFER) 829 return AuxBus::defer; 830 831 DP_ASSERT(0 && "Unknown reply type"); 832 return AuxBus::nack; 833 } 834 835 unsigned EvoAuxBus::transactionSize() 836 { 837 return NV0073_CTRL_DP_AUXCH_MAX_DATA_SIZE; 838 } 839 840 void EvoAuxBus::setDevicePlugged(bool plugged) 841 { 842 devicePlugged = plugged; 843 } 844 845 void EvoMainLink::preLinkTraining(NvU32 head) 846 { 847 provider->preLinkTraining(head); 848 } 849 850 void EvoMainLink::postLinkTraining(NvU32 head) 851 { 852 provider->postLinkTraining(head); 853 } 854 855 void EvoMainLink::initializeRegkeyDatabase() 856 { 857 NvU32 i; 858 if (dpRegkeyDatabase.bInitialized) 859 return; 860 for (i = 0; i < sizeof(DP_REGKEY_TABLE)/sizeof(DP_REGKEY_TABLE[0]); i++) 861 { 862 NvU32 tempValue = 0; 863 tempValue = provider->getRegkeyValue(DP_REGKEY_TABLE[i].pName); 864 switch (DP_REGKEY_TABLE[i].valueType) 865 { 866 case DP_REG_VAL_U32: 867 *(NvU32*)(DP_REGKEY_TABLE[i].pValue) = tempValue; 868 break; 869 case DP_REG_VAL_U16: 870 *(NvU16*)(DP_REGKEY_TABLE[i].pValue) = tempValue & 0xFFFF; 871 break; 872 case DP_REG_VAL_U8: 873 *(NvU8*)(DP_REGKEY_TABLE[i].pValue) = tempValue & 0xFF; 874 break; 875 case DP_REG_VAL_BOOL: 876 *(bool*)(DP_REGKEY_TABLE[i].pValue) = !!tempValue; 877 break; 878 } 879 } 880 dpRegkeyDatabase.bInitialized = true; 881 } 882 883 void EvoMainLink::applyRegkeyOverrides() 884 { 885 if (!dpRegkeyDatabase.bInitialized) 886 { 887 DP_ASSERT(0 && "dpRegkeyDatabase is not initialized before calling applyRegkeyOverrides."); 888 this->initializeRegkeyDatabase(); 889 } 890 _isMstDisabledByRegkey = dpRegkeyDatabase.bMstDisabled; 891 _isDscDisabledByRegkey = dpRegkeyDatabase.bDscDisabled; 892 _skipPowerdownEDPPanelWhenHeadDetach = dpRegkeyDatabase.bPoweroffEdpInHeadDetachSkipped; 893 _applyLinkBwOverrideWarRegVal = dpRegkeyDatabase.bLinkBwOverrideWarApplied; 894 _enableMSAOverrideOverMST = dpRegkeyDatabase.bMsaOverMstEnabled; 895 _isMSTPCONCapsReadDisabled = dpRegkeyDatabase.bMSTPCONCapsReadDisabled; 896 } 897 898 NvU32 EvoMainLink::getRegkeyValue(const char *key) 899 { 900 NvU32 i; 901 if (!dpRegkeyDatabase.bInitialized) 902 { 903 DP_ASSERT(0 && "dpRegkeyDatabase is not initialized before calling getRegkeyValue."); 904 initializeRegkeyDatabase(); 905 } 906 if (key == NULL || key[0] == '\0') 907 return 0; 908 909 for (i = 0; i < sizeof(DP_REGKEY_TABLE)/sizeof(DP_REGKEY_TABLE[0]); i++) 910 { 911 NvU32 j = 0; 912 bool strSame = true; 913 while (key[j] != '\0' && DP_REGKEY_TABLE[i].pName[j] != '\0') 914 { 915 if (key[j] != DP_REGKEY_TABLE[i].pName[j]) 916 { 917 strSame = false; 918 break; 919 } 920 ++j; 921 } 922 if (strSame && key[j] == '\0' && DP_REGKEY_TABLE[i].pName[j] == '\0') 923 { 924 switch (DP_REGKEY_TABLE[i].valueType) 925 { 926 case DP_REG_VAL_U32: 927 return *(NvU32*)(DP_REGKEY_TABLE[i].pValue); 928 case DP_REG_VAL_U16: 929 return (NvU32)*(NvU16*)(DP_REGKEY_TABLE[i].pValue); 930 case DP_REG_VAL_U8: 931 return (NvU32)*(NvU8*)(DP_REGKEY_TABLE[i].pValue); 932 case DP_REG_VAL_BOOL: 933 return (NvU32)*(bool*)(DP_REGKEY_TABLE[i].pValue); 934 } 935 } 936 } 937 DP_ASSERT(0 && "Requested regkey not found in dpRegkeyDatabase."); 938 return 0; 939 } 940 941 const DP_REGKEY_DATABASE& EvoMainLink::getRegkeyDatabase() 942 { 943 return dpRegkeyDatabase; 944 } 945 946 NvU32 EvoMainLink::getSorIndex() 947 { 948 return provider->getSorIndex(); 949 } 950 951 bool EvoMainLink::isInbandStereoSignalingSupported() 952 { 953 return provider->isInbandStereoSignalingSupported(); 954 } 955 956 bool EvoMainLink::train(const LinkConfiguration & link, bool force, 957 LinkTrainingType linkTrainingType, 958 LinkConfiguration *retLink, bool bSkipLt, 959 bool isPostLtAdjRequestGranted, unsigned phyRepeaterCount) 960 { 961 NvU32 targetIndex; 962 NvU32 ltCounter = retLink->getLTCounter(); 963 bool bTrainPhyRepeater = 964 (!link.bDisableLTTPR) && (_isLTPhyRepeaterSupported); 965 966 if (provider->getSorIndex() == DP_INVALID_SOR_INDEX) 967 { 968 // bail out and Skip LT since SOR is not allocated for this displayID 969 return false; 970 } 971 NvU32 err = 0; 972 973 NvU32 dpCtrlCmd = DRF_DEF(0073_CTRL, _DP_CMD, _SET_LANE_COUNT, _TRUE) | 974 DRF_DEF(0073_CTRL, _DP_CMD, _SET_LINK_BW, _TRUE); 975 976 if (link.multistream) 977 dpCtrlCmd |= DRF_DEF(0073_CTRL, _DP_CMD, _SET_FORMAT_MODE, _MULTI_STREAM ); 978 979 if(link.bEnableFEC) 980 dpCtrlCmd |= DRF_DEF(0073_CTRL, _DP_CMD, _ENABLE_FEC, _TRUE); 981 982 if (isPostLtAdjRequestGranted) 983 dpCtrlCmd |= DRF_DEF(0073_CTRL, _DP_CMD, _POST_LT_ADJ_REQ_GRANTED, _YES ); 984 985 if (link.enhancedFraming) 986 dpCtrlCmd |= DRF_DEF(0073_CTRL, _DP_CMD, _SET_ENHANCED_FRAMING, _TRUE ); 987 if (bSkipLt) 988 dpCtrlCmd |= DRF_DEF(0073_CTRL, _DP_CMD, _SKIP_HW_PROGRAMMING, _YES ); 989 if (force) 990 dpCtrlCmd |= DRF_DEF(0073_CTRL, _DP_CMD, _FAKE_LINK_TRAINING, _DONOT_TOGGLE_TRANSMISSION ); 991 992 if (linkTrainingType == NO_LINK_TRAINING) 993 dpCtrlCmd |= DRF_DEF(0073_CTRL, _DP_CMD, _NO_LINK_TRAINING, _YES ); 994 else if (linkTrainingType == FAST_LINK_TRAINING) 995 dpCtrlCmd |= DRF_DEF(0073_CTRL, _DP_CMD, _FAST_LINK_TRAINING, _YES ); 996 997 targetIndex = NV0073_CTRL_DP_DATA_TARGET_SINK; 998 if (bTrainPhyRepeater && (_rmPhyRepeaterCount != phyRepeaterCount)) 999 { 1000 // If LTTPR count is out of sync between DPLib and RM, do not link train LTTPRs. 1001 bTrainPhyRepeater = false; 1002 } 1003 1004 if (bTrainPhyRepeater) 1005 { 1006 1007 dpCtrlCmd |= DRF_DEF(0073_CTRL, _DP_CMD, _TRAIN_PHY_REPEATER, _YES ); 1008 // 1009 // Start from the one closest to GPU. Note this is 1-based index. 1010 // 1011 targetIndex = phyRepeaterCount; 1012 } 1013 1014 NV_DPTRACE_INFO(LINK_TRAINING_START, link.multistream, link.peakRate, link.lanes, 1015 phyRepeaterCount, _rmPhyRepeaterCount, bTrainPhyRepeater, targetIndex); 1016 1017 NvU32 status = 0; 1018 NvU8 retries = 0; 1019 bool fallback = false; 1020 1021 // 1022 // Limited attempts to unblock infinite LT loop while CR failure restores 1023 // high rate and lanes for EQ failure 1024 // 1025 NvU32 crHighRateFallbackCount = 0; 1026 1027 // 1028 // The rate and lane count we send to RM might be different than what client 1029 // sent to us since fallback might happen. 1030 // 1031 LinkConfiguration requestRmLC = link; 1032 do 1033 { 1034 NvU32 dpCtrlData = 0; 1035 NvU64 linkrate = requestRmLC.peakRate; 1036 NvU64 linkBw = 0; 1037 1038 switch (linkrate) 1039 { 1040 case RBR: 1041 case EDP_2_16GHZ: 1042 case EDP_2_43GHZ: 1043 case HBR: 1044 case EDP_3_24GHZ: 1045 case EDP_4_32GHZ: 1046 case HBR2: 1047 case HBR3: 1048 linkBw = linkrate / DP_LINK_BW_FREQ_MULTI_MBPS; 1049 dpCtrlData = FLD_SET_DRF_NUM(0073_CTRL, _DP_DATA, _SET_LINK_BW, 1050 linkBw, dpCtrlData); 1051 break; 1052 default: 1053 if (requestRmLC.lanes != 0) 1054 { 1055 DP_ASSERT(0 && "Unknown rate"); 1056 return false; 1057 } 1058 break; 1059 } 1060 1061 dpCtrlData = FLD_SET_DRF_NUM(0073_CTRL, _DP_DATA, _SET_LANE_COUNT, 1062 requestRmLC.lanes, dpCtrlData); 1063 1064 if (requestRmLC.lanes == 0) 1065 { 1066 // Only need to target sink when powering down the link. 1067 targetIndex = NV0073_CTRL_DP_DATA_TARGET_SINK; 1068 } 1069 1070 dpCtrlData = FLD_SET_DRF_NUM(0073_CTRL, _DP_DATA, _TARGET, 1071 targetIndex, dpCtrlData); 1072 1073 // Properly wait eDP to power up before link training. 1074 status = 0; 1075 retries = 0; 1076 fallback = false; 1077 dpCtrlCmd = FLD_SET_DRF(0073_CTRL, _DP_CMD, _FALLBACK_CONFIG, _FALSE, dpCtrlCmd); 1078 do 1079 { 1080 NV0073_CTRL_DP_CTRL_PARAMS params; 1081 1082 dpMemZero(¶ms, sizeof(params)); 1083 params.subDeviceInstance = subdeviceIndex; 1084 params.displayId = displayId; 1085 params.cmd = dpCtrlCmd; 1086 params.data = dpCtrlData; 1087 1088 retries++; 1089 params.retryTimeMs = 0; 1090 status = provider->rmControl0073(NV0073_CTRL_CMD_DP_CTRL, ¶ms, sizeof(params)); 1091 ltCounter++; 1092 err = params.err; 1093 1094 if (params.retryTimeMs > 0) 1095 { 1096 timer->sleep(params.retryTimeMs); 1097 } 1098 1099 if (status == NVOS_STATUS_SUCCESS || bSkipLt) 1100 { 1101 // if LT failed when bSkipLt was marked, no point in attempting LT again. 1102 break; 1103 } 1104 1105 if (!params.retryTimeMs || retries >= 3) 1106 { 1107 break; 1108 } 1109 1110 } while (true); 1111 1112 if (NVOS_STATUS_SUCCESS == status) 1113 { 1114 if (targetIndex != NV0073_CTRL_DP_DATA_TARGET_SINK) 1115 { 1116 targetIndex -= 1; 1117 continue; 1118 } 1119 else 1120 { 1121 // all done, leave the loop. 1122 break; 1123 } 1124 } 1125 1126 if (requestRmLC.policy.skipFallback() || bSkipLt) 1127 { 1128 // 1129 // if LT failed when bSkipLT was marked, no point in falling back as the issue 1130 // is not with LinkConfig. 1131 // 1132 break; 1133 } 1134 1135 if (FLD_TEST_DRF(0073_CTRL_DP, _CMD, _TRAIN_PHY_REPEATER, _YES, dpCtrlCmd) && 1136 FLD_TEST_DRF(0073_CTRL_DP, _ERR, _INVALID_PARAMETER, _ERR, err) && 1137 FLD_TEST_DRF(0073_CTRL_DP, _ERR, _TRAIN_PHY_REPEATER, _ERR, err)) 1138 { 1139 // 1140 // RM has less LTTPR than DPLib expected. 1141 // - Force to do transparent mode. 1142 // 1143 targetIndex = NV0073_CTRL_DP_DATA_TARGET_SINK; 1144 dpCtrlCmd = FLD_SET_DRF(0073_CTRL, _DP_CMD, _TRAIN_PHY_REPEATER, 1145 _NO, dpCtrlCmd); 1146 continue; 1147 } 1148 1149 dpCtrlCmd |= DRF_DEF(0073_CTRL, _DP_CMD, _FALLBACK_CONFIG, _TRUE); 1150 1151 if (FLD_TEST_DRF(0073_CTRL_DP, _ERR, _CLOCK_RECOVERY, _ERR, err)) 1152 { 1153 // If failed CR, check if we need to fallback. 1154 if (requestRmLC.peakRate != RBR) 1155 { 1156 // 1157 // We need to fallback on link rate if the following conditions are met: 1158 // 1. CR or EQ phase failed. 1159 // 2. The request link bandwidth is NOT RBR 1160 // 1161 if (!requestRmLC.lowerConfig()) 1162 { 1163 // If no valid link config could be found, break here. 1164 break; 1165 } 1166 fallback = true; 1167 } 1168 else 1169 { 1170 // Already RBR 1171 // Check how many lanes is done. 1172 requestRmLC.lanes = DRF_VAL(0073_CTRL_DP, _ERR, _CR_DONE_LANE, err); 1173 1174 while (!IS_VALID_LANECOUNT(requestRmLC.lanes)) 1175 { 1176 requestRmLC.lanes--; 1177 } 1178 1179 if (requestRmLC.lanes == 0) 1180 { 1181 // This is to WAR some system that doesn't set CR_DONE or EQ_DONE at all. 1182 // In this case, we just simply try half of lanes. 1183 requestRmLC.lanes = DRF_VAL(0073_CTRL, _DP_DATA, _SET_LANE_COUNT, dpCtrlData) / 2; 1184 if (requestRmLC.lanes == 0) 1185 { 1186 // Nothing to try. Bail out. 1187 break; 1188 } 1189 } 1190 // Set back to original desired rate. 1191 requestRmLC.peakRate = link.peakRate; 1192 fallback = true; 1193 crHighRateFallbackCount++; 1194 } 1195 } 1196 if (FLD_TEST_DRF(0073_CTRL_DP, _ERR, _CHANNEL_EQUALIZATION, _ERR, err)) 1197 { 1198 // 1199 // If Channel equalization fails, we need to use the fallback policy 1200 // of reducing the lane count vs link rate, but in the special case 1201 // when all lanes have failed CR, we resort to lowering link rate instead 1202 // (this address the new Fallback SCR v2.0) 1203 // 1204 if (FLD_TEST_DRF(0073_CTRL_DP, _ERR, _CR_DONE_LANE, _0_LANE, err)) 1205 { 1206 //Per spec, if link rate has already been reduced to RBR, exit fallback 1207 if(requestRmLC.peakRate == RBR || !requestRmLC.lowerConfig()) 1208 break; 1209 } 1210 else 1211 { 1212 if(!requestRmLC.lowerConfig(true)) // bReduceLaneCnt = true 1213 break; 1214 } 1215 fallback = true; 1216 } 1217 if (fallback == false) 1218 { 1219 // Nothing to fallback, give up. 1220 break; 1221 } 1222 if ((phyRepeaterCount > 0) && (bTrainPhyRepeater)) 1223 { 1224 // If fallback, need to start from beginning. 1225 targetIndex = phyRepeaterCount; 1226 } 1227 } while (crHighRateFallbackCount < NV_DP_RBR_FALLBACK_MAX_TRIES); 1228 1229 // 1230 // Result should be checked for only the control call status. 'err' 1231 // doesn't represent failure in LT - some compliance tests such as 700.1.1.2 1232 // intentionally test against unexpected sink caps 1233 // 1234 bool result = (status == NVOS_STATUS_SUCCESS); 1235 retLink->setLaneRate(requestRmLC.peakRate, result ? requestRmLC.lanes : 0); 1236 retLink->setLTCounter(ltCounter); 1237 1238 if (requestRmLC.bEnableFEC && (FLD_TEST_DRF(0073_CTRL_DP, _ERR, _ENABLE_FEC, _ERR, err))) 1239 { 1240 retLink->bEnableFEC = false; 1241 DP_ASSERT(0); 1242 } 1243 1244 NV_DPTRACE_INFO(LINK_TRAINING_DONE, status, requestRmLC.peakRate, requestRmLC.lanes); 1245 1246 return result; 1247 } 1248 1249 bool EvoMainLink::retrieveRingBuffer(NvU8 dpRingBuffertype, NvU32 numRecords) 1250 { 1251 return false; 1252 } 1253 1254 // Return the current mux state. Returns false if device is not mux capable 1255 bool EvoMainLink::getDynamicMuxState(NvU32 *muxState) 1256 { 1257 bool bIsMuxCapable = false; 1258 NvU32 ret = 0; 1259 NV0073_CTRL_CMD_DFP_GET_DISP_MUX_STATUS_PARAMS muxStatusParams; 1260 1261 if (!muxState) 1262 return false; 1263 1264 *muxState = 0; 1265 1266 if (!isDynamicMuxCapable()) 1267 return false; 1268 1269 dpMemZero(&muxStatusParams, sizeof(muxStatusParams)); 1270 muxStatusParams.subDeviceInstance = subdeviceIndex; 1271 muxStatusParams.displayId = displayId; 1272 muxStatusParams.muxStatus = 0; 1273 1274 ret = provider->rmControl0073(NV0073_CTRL_CMD_DFP_GET_DISP_MUX_STATUS, 1275 &muxStatusParams, sizeof(muxStatusParams)); 1276 if (ret == NV_OK && 1277 DRF_VAL(0073, _CTRL_DFP_DISP_MUX, _STATE, muxStatusParams.muxStatus) != NV0073_CTRL_DFP_DISP_MUX_STATE_INVALID) 1278 { 1279 bIsMuxCapable = true; 1280 *muxState = muxStatusParams.muxStatus; 1281 } 1282 1283 return bIsMuxCapable; 1284 } 1285 1286 bool EvoMainLink::aquireSema() 1287 { 1288 NV0073_CTRL_DP_AUXCH_SET_SEMA_PARAMS params; 1289 1290 dpMemZero(¶ms, sizeof(params)); 1291 params.subDeviceInstance = subdeviceIndex; 1292 params.displayId = displayId; 1293 params.owner = NV0073_CTRL_DP_AUXCH_SET_SEMA_OWNER_RM; 1294 1295 NvU32 code = provider->rmControl0073(NV0073_CTRL_CMD_DP_AUXCH_SET_SEMA, ¶ms, sizeof(params)); 1296 1297 return code == NVOS_STATUS_SUCCESS; 1298 } 1299 1300 void EvoMainLink::releaseSema() 1301 { 1302 NV0073_CTRL_DP_AUXCH_SET_SEMA_PARAMS params; 1303 1304 dpMemZero(¶ms, sizeof(params)); 1305 params.subDeviceInstance = subdeviceIndex; 1306 params.displayId = displayId; 1307 params.owner = NV0073_CTRL_DP_AUXCH_SET_SEMA_OWNER_RELEASE; 1308 1309 NvU32 code = provider->rmControl0073(NV0073_CTRL_CMD_DP_AUXCH_SET_SEMA, ¶ms, sizeof(params)); 1310 1311 DP_USED(code); 1312 DP_ASSERT(code == NVOS_STATUS_SUCCESS); 1313 } 1314 1315 void EvoMainLink::configurePowerState(bool bPowerUp) 1316 { 1317 NV0073_CTRL_DP_MAIN_LINK_CTRL_PARAMS params; 1318 1319 dpMemZero(¶ms, sizeof(params)); 1320 params.subDeviceInstance = subdeviceIndex; 1321 params.displayId = displayId; 1322 params.ctrl = bPowerUp ? NV0073_CTRL_DP_MAIN_LINK_CTRL_POWER_STATE_POWERUP : 1323 NV0073_CTRL_DP_MAIN_LINK_CTRL_POWER_STATE_POWERDOWN; 1324 1325 NvU32 code = provider->rmControl0073(NV0073_CTRL_CMD_DP_MAIN_LINK_CTRL, ¶ms, sizeof(params)); 1326 1327 DP_ASSERT(code == NVOS_STATUS_SUCCESS); 1328 } 1329 1330 void EvoMainLink::getLinkConfig(unsigned &laneCount, NvU64 & linkRate) 1331 { 1332 NV0073_CTRL_DP_GET_LINK_CONFIG_PARAMS params; 1333 dpMemZero(¶ms, sizeof(params)); 1334 1335 params.subDeviceInstance = subdeviceIndex; 1336 params.displayId = displayId; 1337 1338 NvU32 code = provider->rmControl0073(NV0073_CTRL_CMD_DP_GET_LINK_CONFIG, ¶ms, sizeof(params)); 1339 1340 if (code == NVOS_STATUS_SUCCESS) 1341 { 1342 laneCount = params.laneCount; 1343 1344 if (params.linkBW != 0) 1345 { 1346 // BUG: Beware, turbo mode need to be taken into account 1347 linkRate = ((NvU64)params.linkBW) * DP_LINK_BW_FREQ_MULTI_MBPS; 1348 } 1349 else 1350 { 1351 // No link rate available. 1352 linkRate = 0; 1353 } 1354 } 1355 else 1356 { 1357 laneCount = 0; 1358 linkRate = 0; 1359 } 1360 } 1361 1362 bool EvoMainLink::getMaxLinkConfigFromUefi(NvU8 &linkRate, NvU8 &laneCount) 1363 { 1364 if (provider->getMaxLinkConfigFromUefi(linkRate, laneCount)) 1365 { 1366 if (IS_VALID_LANECOUNT(laneCount) && IS_VALID_LINKBW(linkRate)) 1367 { 1368 return true; 1369 } 1370 } 1371 return false; 1372 } 1373 1374 bool EvoMainLink::queryAndUpdateDfpParams() 1375 { 1376 NvU32 dfpFlags; 1377 dpMemZero(&dfpParams, sizeof(dfpParams)); 1378 dfpParams.subDeviceInstance = subdeviceIndex; 1379 dfpParams.displayId = displayId; 1380 1381 NvU32 code = provider->rmControl0073(NV0073_CTRL_CMD_DFP_GET_INFO, &dfpParams, sizeof(dfpParams)); 1382 1383 if (code != NVOS_STATUS_SUCCESS) 1384 { 1385 DP_ASSERT(0 && "Unable to query DFP params."); 1386 return false; 1387 } 1388 1389 dfpFlags = dfpParams.flags; 1390 _isEDP = DRF_VAL(0073, _CTRL_DFP_FLAGS, _EMBEDDED_DISPLAYPORT, dfpFlags) == 1391 NV0073_CTRL_DFP_FLAGS_EMBEDDED_DISPLAYPORT_TRUE; 1392 1393 if (_isLTPhyRepeaterSupported) 1394 { 1395 _rmPhyRepeaterCount = DRF_VAL(0073_CTRL_DFP, _FLAGS, 1396 _DP_PHY_REPEATER_COUNT, dfpFlags); 1397 } 1398 1399 _needForceRmEdid = DRF_VAL(0073, _CTRL_DFP_FLAGS, _DP_FORCE_RM_EDID ,dfpFlags) == 1400 NV0073_CTRL_DFP_FLAGS_DP_FORCE_RM_EDID_TRUE; 1401 1402 _isPC2Disabled = DRF_VAL(0073, _CTRL_DFP_FLAGS, _DP_POST_CURSOR2_DISABLED, dfpFlags) == 1403 NV0073_CTRL_DFP_FLAGS_DP_POST_CURSOR2_DISABLED_TRUE; 1404 1405 1406 switch(DRF_VAL(0073, _CTRL_DFP_FLAGS, _DP_LINK_BW, dfpFlags)) 1407 { 1408 default: 1409 DP_ASSERT(0 && "maxLinkRate is set improperly in dfp object."); 1410 // intentionally fall-thru. 1411 case NV0073_CTRL_DFP_FLAGS_DP_LINK_BW_1_62GBPS: 1412 _maxLinkRateSupportedDfp = RBR; 1413 break; 1414 case NV0073_CTRL_DFP_FLAGS_DP_LINK_BW_2_70GBPS: 1415 _maxLinkRateSupportedDfp = HBR; 1416 break; 1417 case NV0073_CTRL_DFP_FLAGS_DP_LINK_BW_5_40GBPS: 1418 _maxLinkRateSupportedDfp = HBR2; 1419 break; 1420 case NV0073_CTRL_DFP_FLAGS_DP_LINK_BW_8_10GBPS: 1421 _maxLinkRateSupportedDfp = HBR3; 1422 break; 1423 } 1424 1425 1426 _isDynamicMuxCapable = FLD_TEST_DRF(0073, _CTRL_DFP_FLAGS, _DYNAMIC_MUX_CAPABLE, _TRUE, dfpFlags); 1427 1428 return true; 1429 } 1430 1431 bool EvoMainLink::fetchEdidByRmCtrl(NvU8* edidBuffer, NvU32 bufferSize) 1432 { 1433 NV0073_CTRL_SPECIFIC_GET_EDID_V2_PARAMS *pEdidParams; 1434 pEdidParams = (NV0073_CTRL_SPECIFIC_GET_EDID_V2_PARAMS*) dpMalloc(sizeof(*pEdidParams)); 1435 1436 if (pEdidParams == NULL) { 1437 return false; 1438 } 1439 1440 dpMemZero(pEdidParams, sizeof(*pEdidParams)); 1441 pEdidParams->subDeviceInstance = subdeviceIndex; 1442 pEdidParams->displayId = displayId; 1443 pEdidParams->flags = 0; // use default settings. 1444 1445 NvU32 code = provider->rmControl0073(NV0073_CTRL_CMD_SPECIFIC_GET_EDID_V2, pEdidParams, sizeof(*pEdidParams)); 1446 1447 if (code == NVOS_STATUS_SUCCESS) 1448 { 1449 // Silently dropping part of a too-large output buffer matches the 1450 // behavior of the "V1" of this control. 1451 // But it may make sense to revisit this behavior now that it's under 1452 // control of this client. 1453 NvU32 copySize = NV_MIN(pEdidParams->bufferSize, bufferSize); 1454 dpMemCopy(edidBuffer, pEdidParams->edidBuffer, copySize); 1455 } else { 1456 DP_ASSERT(0 && "Unable to read EDID."); 1457 } 1458 1459 dpFree(pEdidParams); 1460 return code == NVOS_STATUS_SUCCESS; 1461 } 1462 1463 bool EvoMainLink::applyEdidOverrideByRmCtrl(NvU8* edidBuffer, NvU32 bufferSize) 1464 { 1465 NV0073_CTRL_SPECIFIC_APPLY_EDID_OVERRIDE_V2_PARAMS *pEdidOverrideParams = 1466 (NV0073_CTRL_SPECIFIC_APPLY_EDID_OVERRIDE_V2_PARAMS *) 1467 dpMalloc(sizeof(*pEdidOverrideParams)); 1468 1469 if (pEdidOverrideParams == NULL) { 1470 return false; 1471 } 1472 1473 dpMemZero(pEdidOverrideParams, sizeof(*pEdidOverrideParams)); 1474 pEdidOverrideParams->subDeviceInstance = subdeviceIndex; 1475 pEdidOverrideParams->displayId = displayId; 1476 if (bufferSize > sizeof(pEdidOverrideParams->edidBuffer)) { 1477 DP_ASSERT(0 && "EDID override too large for edidBuffer"); 1478 dpFree(pEdidOverrideParams); 1479 return false; 1480 } 1481 pEdidOverrideParams->bufferSize = bufferSize; 1482 dpMemCopy(&pEdidOverrideParams->edidBuffer, edidBuffer, bufferSize); 1483 1484 NvU32 code = provider->rmControl0073(NV0073_CTRL_CMD_SPECIFIC_APPLY_EDID_OVERRIDE_V2, 1485 pEdidOverrideParams, 1486 sizeof(*pEdidOverrideParams)); 1487 if (code != NVOS_STATUS_SUCCESS) 1488 { 1489 DP_ASSERT(0 && "Unable to apply EDID override."); 1490 dpFree(pEdidOverrideParams); 1491 return false; 1492 } 1493 1494 DP_ASSERT(pEdidOverrideParams->bufferSize == bufferSize); 1495 dpMemCopy(edidBuffer, &pEdidOverrideParams->edidBuffer, bufferSize); 1496 1497 dpFree(pEdidOverrideParams); 1498 1499 return true; 1500 1501 } 1502 1503 bool EvoMainLink::isEDP() 1504 { 1505 return _isEDP; 1506 } 1507 1508 bool EvoMainLink::supportMSAOverMST() 1509 { 1510 return _enableMSAOverrideOverMST; 1511 } 1512 1513 bool EvoMainLink::skipPowerdownEdpPanelWhenHeadDetach() 1514 { 1515 return _skipPowerdownEDPPanelWhenHeadDetach; 1516 } 1517 1518 bool EvoMainLink::isMSTPCONCapsReadDisabled() 1519 { 1520 return _isMSTPCONCapsReadDisabled; 1521 } 1522 1523 bool EvoMainLink::isActive() 1524 { 1525 NV0073_CTRL_SYSTEM_GET_ACTIVE_PARAMS params; 1526 1527 for (int i = 0; i < 32; i++) 1528 { 1529 // 1530 // Skip floorswept heads 1531 // 1532 if (!(allHeadMask & (1 << i))) 1533 { 1534 continue; 1535 } 1536 1537 dpMemZero(¶ms, sizeof params); 1538 params.subDeviceInstance = 0; 1539 params.head = i; 1540 1541 NvU32 code = provider->rmControl0073(NV0073_CTRL_CMD_SYSTEM_GET_ACTIVE, ¶ms, sizeof(params)); 1542 1543 if (code != NVOS_STATUS_SUCCESS) 1544 { 1545 DP_ASSERT(0 && "We can't get active displays, RM bug!"); 1546 } 1547 else if (params.displayId & displayId) 1548 { 1549 return true; 1550 } 1551 } 1552 1553 return false; 1554 } 1555 1556 bool EvoMainLink::controlRateGoverning(NvU32 head, bool enable, bool updateNow) 1557 { 1558 NV0073_CTRL_CMD_DP_SET_RATE_GOV_PARAMS params = {0}; 1559 params.subDeviceInstance = this->subdeviceIndex; 1560 params.head = head; 1561 params.sorIndex = provider->getSorIndex(); 1562 1563 if (enable) 1564 { 1565 params.flags |= DRF_DEF(0073_CTRL, _CMD_DP_SET_RATE_GOV_FLAGS, _ENABLE_RG, _ON); 1566 } 1567 else 1568 { 1569 params.flags |= DRF_DEF(0073_CTRL, _CMD_DP_SET_RATE_GOV_FLAGS, _ENABLE_RG, _OFF); 1570 } 1571 if (updateNow) 1572 { 1573 params.flags |= DRF_DEF(0073_CTRL, _CMD_DP_SET_RATE_GOV_FLAGS, _TRIGGER_MODE, _IMMEDIATE); 1574 } 1575 else 1576 { 1577 params.flags |= DRF_DEF(0073_CTRL, _CMD_DP_SET_RATE_GOV_FLAGS, _TRIGGER_MODE, _LOADV); 1578 } 1579 1580 provider->rmControl0073(NV0073_CTRL_CMD_DP_SET_RATE_GOV, ¶ms, sizeof params); 1581 1582 return true; 1583 } 1584 1585 bool EvoMainLink::getDpTestPattern(NV0073_CTRL_DP_TESTPATTERN * testPattern) 1586 { 1587 NV0073_CTRL_DP_GET_TESTPATTERN_PARAMS params = {0}; 1588 1589 params.subDeviceInstance = this->subdeviceIndex; 1590 params.displayId = this->displayId; 1591 1592 if (!(provider->rmControl0073(NV0073_CTRL_CMD_DP_GET_TESTPATTERN, ¶ms, sizeof params))) 1593 { 1594 testPattern->testPattern = params.testPattern.testPattern; 1595 return true; 1596 } 1597 else 1598 return false; 1599 } 1600 1601 bool EvoMainLink::setDpTestPattern(NV0073_CTRL_DP_TESTPATTERN testPattern, NvU8 laneMask, NV0073_CTRL_DP_CSTM cstm, NvBool bIsHBR2, NvBool bSkipLaneDataOverride) 1602 { 1603 NV0073_CTRL_DP_SET_TESTPATTERN_PARAMS params = {0}; 1604 1605 params.subDeviceInstance = this->subdeviceIndex; 1606 params.displayId = this->displayId; 1607 params.testPattern = testPattern; 1608 params.laneMask = laneMask; 1609 params.cstm = cstm; 1610 params.bIsHBR2 = bIsHBR2; 1611 params.bSkipLaneDataOverride = bSkipLaneDataOverride; 1612 1613 if (!(provider->rmControl0073(NV0073_CTRL_CMD_DP_SET_TESTPATTERN, ¶ms, sizeof params))) 1614 return true; 1615 else 1616 return false; 1617 } 1618 1619 bool EvoMainLink::getDpLaneData(NvU32 *numLanes, NvU32 *data) 1620 { 1621 NV0073_CTRL_DP_LANE_DATA_PARAMS params = {0}; 1622 1623 params.subDeviceInstance = this->subdeviceIndex; 1624 params.displayId = this->displayId; 1625 1626 if (!(provider->rmControl0073(NV0073_CTRL_CMD_DP_GET_LANE_DATA, ¶ms, sizeof params))) 1627 { 1628 *numLanes = params.numLanes; 1629 dpMemCopy(data, params.data, NV0073_CTRL_MAX_LANES*4); 1630 return true; 1631 } 1632 else 1633 return false; 1634 } 1635 1636 bool EvoMainLink::setDpLaneData(NvU32 numLanes, NvU32 *data) 1637 { 1638 NV0073_CTRL_DP_LANE_DATA_PARAMS params = {0}; 1639 1640 params.subDeviceInstance = this->subdeviceIndex; 1641 params.displayId = this->displayId; 1642 params.numLanes = numLanes; 1643 dpMemCopy(params.data, data, NV0073_CTRL_MAX_LANES*4); 1644 1645 if (!(provider->rmControl0073(NV0073_CTRL_CMD_DP_SET_LANE_DATA, ¶ms, sizeof params))) 1646 return true; 1647 else 1648 return false; 1649 } 1650 1651 NvU32 EvoMainLink::monitorDenylistInfo(NvU32 ManufacturerID, NvU32 ProductID, DpMonitorDenylistData *pDenylistData) 1652 { 1653 return provider->monitorDenylistInfo(ManufacturerID, ProductID, pDenylistData); 1654 } 1655 bool EvoMainLink::rmUpdateDynamicDfpCache(NvU32 headIndex, RmDfpCache* dfpCache, NvBool bResetDfp) 1656 { 1657 NV0073_CTRL_DFP_UPDATE_DYNAMIC_DFP_CACHE_PARAMS params = {0}; 1658 params.headIndex = headIndex; 1659 params.bcaps = dfpCache->bcaps; 1660 for (unsigned i=0; i<5; i++) 1661 params.bksv[i] = dfpCache->bksv[i]; 1662 1663 params.bHdcpCapable = dfpCache->hdcpCapable; 1664 params.subDeviceInstance = subdeviceIndex; 1665 params.updateMask = dfpCache->updMask; 1666 if (bResetDfp) 1667 params.bResetDfp = NV_TRUE; 1668 1669 if (!(provider->rmControl0073(NV0073_CTRL_CMD_DFP_UPDATE_DYNAMIC_DFP_CACHE, ¶ms, sizeof params))) 1670 return true; 1671 else 1672 return false; 1673 } 1674 1675 NvU32 EvoMainLink::allocDisplayId() 1676 { 1677 NV0073_CTRL_CMD_DP_TOPOLOGY_ALLOCATE_DISPLAYID_PARAMS params = {0}; 1678 1679 params.subDeviceInstance = subdeviceIndex; 1680 params.displayId = displayId; 1681 1682 NvU32 ret = provider->rmControl0073(NV0073_CTRL_CMD_DP_TOPOLOGY_ALLOCATE_DISPLAYID, ¶ms, sizeof(params)); 1683 if (ret == NVOS_STATUS_SUCCESS) 1684 { 1685 return params.displayIdAssigned; 1686 } 1687 1688 return 0; 1689 } 1690 1691 bool EvoMainLink::freeDisplayId(NvU32 displayId) 1692 { 1693 NV0073_CTRL_CMD_DP_TOPOLOGY_FREE_DISPLAYID_PARAMS params = {0}; 1694 1695 params.subDeviceInstance = subdeviceIndex; 1696 params.displayId = displayId; 1697 1698 NvU32 ret = provider->rmControl0073(NV0073_CTRL_CMD_DP_TOPOLOGY_FREE_DISPLAYID, ¶ms, sizeof(params)); 1699 return ret == NVOS_STATUS_SUCCESS; 1700 } 1701 1702 void EvoMainLink::configureTriggerSelect(NvU32 head, DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID streamIdentifier) 1703 { 1704 NV0073_CTRL_CMD_DP_SET_TRIGGER_SELECT_PARAMS params = {0}; 1705 params.head = head; 1706 params.subDeviceInstance = subdeviceIndex; 1707 params.sorIndex = provider->getSorIndex(); 1708 params.singleHeadMSTPipeline = streamIdentifier; 1709 provider->rmControl0073(NV0073_CTRL_CMD_DP_SET_TRIGGER_SELECT, ¶ms, sizeof params); 1710 } 1711 1712 void EvoMainLink::configureTriggerAll(NvU32 head, bool enable) 1713 { 1714 NV0073_CTRL_CMD_DP_SET_TRIGGER_ALL_PARAMS params = {0}; 1715 params.head = head; 1716 params.subDeviceInstance = subdeviceIndex; 1717 params.enable = enable; 1718 provider->rmControl0073(NV0073_CTRL_CMD_DP_SET_TRIGGER_ALL, ¶ms, sizeof params); 1719 } 1720 1721 MainLink * DisplayPort::MakeEvoMainLink(EvoInterface * provider, Timer * timer) 1722 { 1723 return new EvoMainLink(provider, timer); 1724 } 1725 1726 AuxBus * DisplayPort::MakeEvoAuxBus(EvoInterface * provider, Timer * timer) 1727 { 1728 return new EvoAuxBus(provider, timer); 1729 } 1730 1731 bool EvoMainLink::dscCrcTransaction(NvBool bEnable, gpuDscCrc *data, NvU16 *headIndex) 1732 { 1733 NV0073_CTRL_DFP_DSC_CRC_CONTROL_PARAMS params; 1734 NvU32 code; 1735 1736 dpMemZero(¶ms, sizeof(params)); 1737 params.bEnable = bEnable ? NV_TRUE : NV_FALSE; 1738 params.subDeviceInstance = subdeviceIndex; 1739 params.headIndex = *headIndex; 1740 1741 // see if setup or querying needs to be specified 1742 if (data == NULL) 1743 { 1744 params.cmd = DRF_DEF(0073_CTRL, _DP_CRC_CONTROL, _CMD, _SETUP); 1745 } 1746 else 1747 { 1748 params.cmd = DRF_DEF(0073_CTRL, _DP_CRC_CONTROL, _CMD, _QUERY); 1749 } 1750 1751 // GPU part of the call 1752 code = provider->rmControl0073(NV0073_CTRL_CMD_DFP_DSC_CRC_CONTROL, ¶ms, sizeof(params)); 1753 if (code != NVOS_STATUS_SUCCESS) 1754 { 1755 DP_LOG(("DP> Crc control failed.")); 1756 return false; 1757 } 1758 1759 // if the command is setup, return immediately 1760 if (data != NULL) 1761 { 1762 data->gpuCrc0 = params.gpuCrc0; 1763 data->gpuCrc1 = params.gpuCrc1; 1764 data->gpuCrc2 = params.gpuCrc2; 1765 } 1766 1767 return true; 1768 } 1769 1770 // 1771 // @brief This is to request RM to setup/reset link rate table, and save valid 1772 // link rates for use. 1773 // 1774 // @param pLinkRateTable Pointer to link rate table to configure 1775 // @param pLinkRates Pointer to LinkRates to keep valid link rates 1776 // @return 1777 // true Link rate table configured with at least one valid link rate 1778 // false Otherwise 1779 // 1780 bool EvoMainLink::configureLinkRateTable 1781 ( 1782 const NvU16 *pLinkRateTable, 1783 LinkRates *pLinkRates 1784 ) 1785 { 1786 NV0073_CTRL_CMD_DP_CONFIG_INDEXED_LINK_RATES_PARAMS params; 1787 dpMemZero(¶ms, sizeof(params)); 1788 1789 params.subDeviceInstance = subdeviceIndex; 1790 params.displayId = displayId; 1791 1792 // Setup provided link rate table, otherwise it will be reset 1793 if (pLinkRateTable) 1794 { 1795 for (NvU32 i = 0; i < NV0073_CTRL_DP_MAX_INDEXED_LINK_RATES; i++) 1796 { 1797 params.linkRateTbl[i] = pLinkRateTable[i]; 1798 } 1799 } 1800 1801 NvU32 code = provider->rmControl0073( 1802 NV0073_CTRL_CMD_DP_CONFIG_INDEXED_LINK_RATES, 1803 ¶ms, sizeof(params)); 1804 1805 if ((pLinkRates != NULL ) && (code == NVOS_STATUS_SUCCESS) && 1806 (params.linkBwCount <= NV0073_CTRL_DP_MAX_INDEXED_LINK_RATES)) 1807 { 1808 pLinkRates->clear(); 1809 for (int i = 0; i < params.linkBwCount; i++) 1810 { 1811 switch (params.linkBwTbl[i]) 1812 { 1813 case linkBW_1_62Gbps: 1814 case linkBW_2_16Gbps: 1815 case linkBW_2_43Gbps: 1816 case linkBW_2_70Gbps: 1817 case linkBW_3_24Gbps: 1818 case linkBW_4_32Gbps: 1819 case linkBW_5_40Gbps: 1820 case linkBW_8_10Gbps: 1821 pLinkRates->import((NvU8)params.linkBwTbl[i]); 1822 break; 1823 default: 1824 DP_LOG(("DP_EVO> %s: Unsupported link rate received", 1825 __FUNCTION__)); 1826 DP_ASSERT(0); 1827 break; 1828 } 1829 } 1830 return true; 1831 } 1832 return false; 1833 } 1834 1835 // 1836 // @brief This is to request RM to enable/disable Fec 1837 // 1838 // @param enableFec Indicates if enable/disable is requested 1839 // @return 1840 // true If FEC was configured successfully 1841 // false Otherwise 1842 // 1843 bool EvoMainLink::configureFec 1844 ( 1845 const bool bEnableFec 1846 ) 1847 { 1848 NV0073_CTRL_CMD_DP_CONFIGURE_FEC_PARAMS params; 1849 dpMemZero(¶ms, sizeof(params)); 1850 1851 params.subDeviceInstance = subdeviceIndex; 1852 params.displayId = displayId; 1853 params.bEnableFec = bEnableFec; 1854 1855 NvU32 code = provider->rmControl0073( 1856 NV0073_CTRL_CMD_DP_CONFIGURE_FEC, 1857 ¶ms, sizeof(params)); 1858 1859 if (code == NVOS_STATUS_SUCCESS) 1860 { 1861 return true; 1862 } 1863 1864 return false; 1865 } 1866