1 /* 2 * SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_connector.cpp * 27 * * 28 \***************************************************************************/ 29 #ifndef INCLUDED_DP_DEVICEIMPL_H 30 #define INCLUDED_DP_DEVICEIMPL_H 31 32 #include "dp_connector.h" 33 #include "dp_internal.h" 34 #include "dp_edid.h" 35 #include "dp_list.h" 36 #include "dp_auxdefs.h" 37 #include "dp_vrr.h" 38 39 namespace DisplayPort 40 { 41 #define PREDEFINED_DSC_MST_BPPX16 160; 42 #define HDCP_BCAPS_DDC_OFFSET 0x40 43 #define HDCP_BCAPS_DDC_EN_BIT 0x80 44 #define HDCP_BCAPS_DP_EN_BIT 0x01 45 #define HDCP_I2C_CLIENT_ADDR 0x74 46 47 struct GroupImpl; 48 struct ConnectorImpl; 49 class DeviceHDCPDetection; 50 class VrrEnablement; 51 52 struct DeviceImpl : public Device, 53 public AuxBus, 54 public ListElement 55 { 56 // 57 // Shadow state: This is the last state delivered to DD. 58 // see the ConnectorImpl::fireEvents() function for handling. 59 // 60 // State is double buffered to allow for allow announces 61 // to happen at the end of the state updates. We assume 62 // the DD can call any Connector API in response to the 63 // event. 64 // 65 struct Shadow 66 { 67 bool plugged; 68 bool zombie; 69 bool cableOk; 70 bool mustDisconnect; 71 bool hdcpCapDone; 72 LinkConfiguration highestAssessedLC; 73 } shadow; 74 75 struct BandWidth 76 { 77 struct _Enum_Path 78 { 79 unsigned availableStreams, total, free; 80 bool bPathFECCapable; 81 bool dataValid; // Is the cache valid? 82 } enum_path; 83 84 struct Compound_Query_State 85 { 86 unsigned totalTimeSlots; // Total timeslots available for allocation across this node 87 88 unsigned timeslots_used_by_query; // Timeslots accounted for. 89 90 unsigned bandwidthAllocatedForIndex; // Compound query is compromised of several 91 // qeuery attaches. These query attaches 92 // may have more than one device associated. 93 // this mask keeps track of which queryAttach's 94 // have already had the stream "rounted" past 95 // this node. 96 } compound_query_state; 97 98 LinkConfiguration lastHopLinkConfig; // inferred from enum_path.total 99 100 } bandwidth; 101 102 enum rawEprState 103 { 104 software, 105 hardware 106 }; 107 108 void resetCacheInferredLink(); 109 LinkConfiguration * inferLeafLink(unsigned * totalLinkSlots); 110 111 112 DeviceImpl * parent; // Upstream parent device 113 DeviceImpl * children[16]; 114 PortMap portMap; 115 116 Edid rawEDID; 117 Edid processedEdid; 118 Edid ddcEdid; 119 DPCDHAL * hal; 120 GroupImpl * activeGroup; 121 ConnectorImpl * connector; 122 ConnectorType connectorType; 123 Address address; 124 GUID guid; 125 GUID guid2; 126 bool bVirtualPeerDevice; 127 NvU8 peerDevice; 128 NvU8 dpcdRevisionMajor; 129 NvU8 dpcdRevisionMinor; 130 bool multistream; 131 bool videoSink, audioSink; 132 bool plugged; 133 134 135 AuxRetry friendlyAux; 136 bool payloadAllocated; // did the allocate payload go through? 137 138 unsigned char BCAPS[HDCP_BCAPS_SIZE]; // Hdcp1.x bCaps raw data 139 unsigned char BKSV[HDCP_KSV_SIZE]; // Hdcp1.x bKsv raw data 140 unsigned char nvBCaps[HDCP_BCAPS_SIZE]; // NV generic HDCP BCAPS including 1.x, 2.2, ... 141 NvU64 maxTmdsClkRate; 142 143 144 bool isPendingNewDevice(); 145 bool isPendingLostDevice(); 146 bool isPendingZombie(); 147 bool isPendingCableOk(); 148 bool isPendingBandwidthChange(); 149 bool isPendingHDCPCapDone(); 150 151 TriState isHDCPCap; 152 bool isDeviceHDCPDetectionAlive; 153 DeviceHDCPDetection * deviceHDCPDetection; 154 155 PCONCaps pconCaps; 156 157 // this flag signifies that the compliance device has requested EDID read test and may follow 158 // hidden and lazy zombie policy. 159 bool complianceDeviceEdidReadTest; 160 161 bool lazyExitNow; 162 163 // VRR Enablement structure 164 VrrEnablement *vrrEnablement; 165 166 // DSC fields 167 NvU8 rawDscCaps[16]; 168 DscCaps dscCaps; 169 170 // Panel replay Caps 171 PanelReplayCaps prCaps; 172 173 bool bIsFakedMuxDevice; 174 bool bIsPreviouslyFakedMuxDevice; 175 bool bisMarkedForDeletion; 176 bool bIgnoreMsaCap; 177 bool bIgnoreMsaCapCached; 178 179 // 180 // Device doing the DSC decompression for this device. This could be device itself 181 // or its parent 182 // 183 DeviceImpl* devDoingDscDecompression; 184 // 185 // If DSC stream can be sent to this device or not. Either device itself or it's 186 // parent can do DSC decompression 187 // 188 bool bDSCPossible; 189 190 bool bFECSupported; 191 bool bFECUncorrectedSupported; 192 bool bFECCorrectedSupported; 193 bool bFECBitSupported; 194 bool bFECParityBlockSupported; 195 bool bFECParitySupported; 196 197 TriState bSdpExtCapable; 198 TriState bAsyncSDPCapable; 199 bool bMSAOverMSTCapable; 200 bool bDscPassThroughColorFormatWar; 201 202 DeviceImpl(DPCDHAL * hal, ConnectorImpl * connector, DeviceImpl * parent); 203 ~DeviceImpl(); 204 205 virtual bool isCableOk(); 206 virtual bool isLogical(); 207 virtual bool isZombie(); 208 209 virtual unsigned getEDIDSize() const; 210 virtual bool getEDID(char * buffer, unsigned size) const; 211 virtual unsigned getRawEDIDSize() const; 212 virtual bool getRawEDID(char * buffer, unsigned size) const; 213 214 virtual bool getPCONCaps(PCONCaps *pPCONCaps); 215 216 virtual Group * getOwningGroup() 217 { 218 return (Group *)activeGroup; 219 } 220 221 bool isActive(); 222 223 void applyOUIOverrides(); 224 225 virtual Device * getParent() 226 { 227 return parent; 228 } 229 230 virtual Device * getChild(unsigned portNumber) 231 { 232 return children[portNumber]; 233 } 234 235 virtual bool isMultistream() // Sink supports multistream, remember we can have 1.1 targets 236 { 237 return address.size() != 0; 238 } 239 240 virtual bool isNativeDPCD() 241 { 242 return (address.size() < 2); 243 } 244 245 virtual bool isVideoSink() 246 { 247 return videoSink; 248 } 249 250 virtual bool isAudioSink() 251 { 252 return audioSink; 253 } 254 255 virtual bool isLoop() 256 { 257 DP_LOG(("isLoop implementation is pending (bug 791059)")); 258 return false; 259 } 260 261 virtual bool isRedundant() 262 { 263 DP_LOG(("isRedundant implementation is pending (bug 791059)")); 264 return false; 265 } 266 267 virtual bool isMustDisconnect(); 268 269 virtual bool isPlugged() 270 { 271 return plugged; 272 } 273 274 virtual Address getTopologyAddress() const 275 { 276 return address; 277 } 278 279 virtual ConnectorType getConnectorType() 280 { 281 return connectorType; 282 } 283 284 virtual bool isFallbackEdid() 285 { 286 return this->processedEdid.isFallbackEdid(); 287 } 288 289 virtual GUID getGUID() const 290 { 291 return guid; 292 } 293 294 virtual PortMap getPortMap() const 295 { 296 return portMap; 297 } 298 299 virtual TriState hdcpAvailableHop(); 300 virtual TriState hdcpAvailable(); 301 302 virtual bool isMSAOverMSTCapable() 303 { 304 return bMSAOverMSTCapable; 305 } 306 307 virtual bool isFakedMuxDevice(); 308 virtual bool isPreviouslyFakedMuxDevice(); 309 310 bool bypassDpcdPowerOff() 311 { 312 return processedEdid.WARFlags.disableDpcdPowerOff; 313 } 314 315 bool powerOnMonitorBeforeLt() 316 { 317 return processedEdid.WARFlags.powerOnBeforeLt; 318 } 319 320 bool forceMaxLinkConfig() 321 { 322 return processedEdid.WARFlags.forceMaxLinkConfig; 323 } 324 325 bool skipRedundantLt() 326 { 327 return processedEdid.WARFlags.skipRedundantLt; 328 } 329 330 bool ignoreRedundantHotplug() 331 { 332 return processedEdid.WARFlags.ignoreRedundantHotplug; 333 } 334 335 bool isOptimalLinkConfigOverridden() 336 { 337 return processedEdid.WARFlags.overrideOptimalLinkCfg; 338 } 339 340 // Apply DPCD overrides if required 341 void dpcdOverrides(); 342 343 bool getDpcdRevision(unsigned * major, unsigned * minor) 344 { 345 if (!major || !minor) 346 { 347 DP_ASSERT(0 && "Null pointers passed in."); 348 return false; 349 } 350 351 *major = this->dpcdRevisionMajor; 352 *minor = this->dpcdRevisionMinor; 353 return true; 354 } 355 356 bool getIgnoreMSACap(); 357 358 AuxRetry::status setIgnoreMSAEnable(bool msaTimingParamIgnoreEn); 359 360 bool isVirtualPeerDevice() 361 { 362 return bVirtualPeerDevice; 363 } 364 365 bool isBranchDevice() 366 { 367 return !isVideoSink() && !isAudioSink(); 368 } 369 370 bool isAtLeastVersion(unsigned major, unsigned minor) 371 { 372 if (dpcdRevisionMajor > major) 373 return true; 374 375 if (dpcdRevisionMajor < major) 376 return false; 377 378 return dpcdRevisionMinor >= minor; 379 } 380 381 virtual void queryGUID2(); 382 383 virtual bool getSDPExtnForColorimetrySupported(); 384 virtual bool getAsyncSDPSupported(); 385 386 virtual bool getPanelFwRevision(NvU16 *revision); 387 388 virtual bool isPowerSuspended(); 389 390 virtual void setPanelPowerParams(bool bSinkPowerStateD0, bool bPanelPowerStateOn); 391 392 virtual status transaction(Action action, Type type, int address, 393 NvU8 * buffer, unsigned sizeRequested, 394 unsigned * sizeCompleted, 395 unsigned *pNakReason= NULL, 396 NvU8 offset= 0, NvU8 nWriteTransactions= 0); 397 virtual unsigned transactionSize(); 398 // default behaviour is querying first three registers for every lane --> flags = 0x7 399 virtual status fecTransaction(NvU8 *fecStatus, NvU16 **fecErrorCount, NvU32 flags = NV_DP_FEC_FLAGS_SELECT_ALL); 400 virtual AuxBus * getRawAuxChannel() { return this; } 401 virtual AuxRetry * getAuxChannel() { return &friendlyAux; } 402 virtual AuxBus::status getDpcdData(unsigned offset, NvU8 * buffer, 403 unsigned sizeRequested, 404 unsigned * sizeCompleted, 405 unsigned * pNakReason=NULL); 406 virtual AuxBus::status setDpcdData(unsigned offset, NvU8 * buffer, 407 unsigned sizeRequested, 408 unsigned * sizeCompleted, 409 unsigned * pNakReason=NULL); 410 virtual AuxBus::status queryFecData(NvU8 *fecStatus, NvU16 **fecErrorCount, NvU32 flags); 411 412 virtual DscCaps getDscCaps(); 413 414 // 415 // This function returns the device itself or its parent device that is doing 416 // DSC decompression for it. 417 // 418 virtual Device* getDevDoingDscDecompression(); 419 virtual void markDeviceForDeletion() {bisMarkedForDeletion = true;}; 420 virtual bool isMarkedForDeletion() {return bisMarkedForDeletion;}; 421 virtual bool getRawDscCaps(NvU8 *buffer, NvU32 bufferSize); 422 423 virtual AuxBus::status dscCrcControl(NvBool bEnable, gpuDscCrc *dataGpu, sinkDscCrc *dataSink); 424 425 // 426 // Parameter bForceMot in both getI2cData and setI2cData is used to forfully set 427 // the MOT bit. It is needed for some special cases where the MOT bit shouldn't 428 // be set but some customers need it to please their monitors. 429 // 430 virtual bool getI2cData(unsigned offset, NvU8 * buffer, unsigned sizeRequested, unsigned * sizeCompleted, bool bForceMot = false); 431 virtual bool setI2cData(unsigned offset, NvU8 * buffer, unsigned sizeRequested, unsigned * sizeCompleted, bool bForceMot = false); 432 virtual bool getRawEpr(unsigned * totalEpr, unsigned * freeEpr, rawEprState eprState); 433 434 void switchToComplianceFallback(); 435 436 // VRR Display Enablement Functions 437 bool startVrrEnablement(void); 438 void resetVrrEnablement(void); 439 bool isVrrMonitorEnabled(void); 440 bool isVrrDriverEnabled(void); 441 442 // Panel replay related functions 443 bool isPanelReplaySupported(void); 444 void getPanelReplayCaps(void); 445 bool setPanelReplayConfig(panelReplayConfig prcfg); 446 bool getPanelReplayStatus(PanelReplayStatus *pPrStatus); 447 448 NvBool getDSCSupport(); 449 bool getFECSupport(); 450 NvBool isDSCPassThroughSupported(); 451 NvBool isDSCSupported(); 452 NvBool isDSCDecompressionSupported(); 453 NvBool isDSCPossible(); 454 bool isFECSupported(); 455 bool readAndParseDSCCaps(); 456 bool readAndParseBranchSpecificDSCCaps(); 457 bool parseDscCaps(const NvU8 *buffer, NvU32 bufferSize); 458 bool parseBranchSpecificDscCaps(const NvU8 *buffer, NvU32 bufferSize); 459 bool setDscEnable(bool enable); 460 bool setDscEnableDPToHDMIPCON(bool bDscEnable, bool bEnablePassThroughForPCON); 461 bool getDscEnable(bool *pEnable); 462 unsigned getDscVersionMajor(); 463 unsigned getDscVersionMinor(); 464 unsigned getDscRcBufferSize(); 465 unsigned getDscRcBufferBlockSize(); 466 unsigned getDscMaxSlicesPerSink(); 467 unsigned getDscLineBufferBitDepth(); 468 NvBool isDscBlockPredictionSupported(); 469 unsigned getDscMaxBitsPerPixel(); 470 NvBool isDscRgbSupported(); 471 NvBool isDscYCbCr444Supported(); 472 NvBool isDscYCbCrSimple422Supported(); 473 NvBool isDscYCbCr422NativeSupported(); 474 NvBool isDscYCbCr420NativeSupported(); 475 unsigned getDscPeakThroughputMode0(); 476 unsigned getDscPeakThroughputModel(); 477 unsigned getDscMaxSliceWidth(); 478 unsigned getDscDecoderColorDepthSupportMask(); 479 void setDscDecompressionDevice(bool bDscCapBasedOnParent); 480 }; 481 class DeviceHDCPDetection : public Object, MessageManager::Message::MessageEventSink, Timer::TimerCallback 482 { 483 DeviceImpl* parent; 484 RemoteDpcdReadMessage remoteBKSVReadMessage; 485 RemoteDpcdReadMessage remoteBCapsReadMessage; 486 RemoteDpcdReadMessage remote22BCapsReadMessage; 487 MessageManager * messageManager; // For transmit and receive 488 Timer * timer; 489 bool bksvReadCompleted; 490 bool bCapsReadCompleted; 491 bool isValidBKSV; 492 bool isBCapsHDCP; 493 unsigned retriesRemoteBKSVReadMessage; 494 unsigned retriesRemoteBCapsReadMessage; 495 unsigned retriesRemote22BCapsReadMessage; 496 bool retryRemoteBKSVReadMessage; 497 bool retryRemoteBCapsReadMessage; 498 bool retryRemote22BCapsReadMessage; 499 bool bBKSVReadMessagePending; 500 bool bBCapsReadMessagePending; 501 502 public: 503 504 DeviceHDCPDetection(DeviceImpl * parent, MessageManager * messageManager, Timer * timer) 505 : bksvReadCompleted(false),bCapsReadCompleted(false),isValidBKSV(false), 506 isBCapsHDCP(false), retriesRemoteBKSVReadMessage(0), retriesRemoteBCapsReadMessage(0), 507 retriesRemote22BCapsReadMessage(0), retryRemoteBKSVReadMessage(false), 508 retryRemoteBCapsReadMessage(false), retryRemote22BCapsReadMessage(false), 509 bBKSVReadMessagePending(false), bBCapsReadMessagePending(false) 510 511 { 512 this->parent = parent; 513 this->messageManager = messageManager; 514 this->timer = timer; 515 } 516 517 ~DeviceHDCPDetection(); 518 void expired(const void * tag); 519 void start(); 520 void waivePendingHDCPCapDoneNotification(); 521 522 bool hdcpValidateKsv(const NvU8 *ksv, NvU32 Size); 523 void handleRemoteDpcdReadDownReply(MessageManager::Message * from); 524 void messageFailed(MessageManager::Message * from, NakData * nakData); 525 void messageCompleted(MessageManager::Message * from); 526 }; 527 } 528 529 #endif //INCLUDED_DP_DEVICEIMPL_H 530 531