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