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