1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 1993-2024 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_connectorimpl.cpp                                              *
27 *    DP connector implementation                                            *
28 *                                                                           *
29 \***************************************************************************/
30 #ifndef INCLUDED_DP_CONNECTORIMPL_H
31 #define INCLUDED_DP_CONNECTORIMPL_H
32 
33 #include "dp_internal.h"
34 #include "dp_guid.h"
35 #include "dp_connector.h"
36 #include "dp_configcaps.h"
37 #include "dp_list.h"
38 #include "dp_buffer.h"
39 #include "dp_auxdefs.h"
40 #include "dp_watermark.h"
41 #include "dp_edid.h"
42 #include "dp_discovery.h"
43 #include "dp_groupimpl.h"
44 #include "dp_deviceimpl.h"
45 #include "./dptestutil/dp_testmessage.h"
46 
47 // HDCP abort codes
48 #define    HDCP_FLAGS_ABORT_DEVICE_REVOKED     0x00000800 // Abort due to a revoked device in DP1.2 topology
49 #define    HDCP_FLAGS_ABORT_DEVICE_INVALID     0x00080000 // Abort due to an invalid device in DP1.2 topology
50 #define    HDCP_FLAGS_ABORT_HOP_LIMIT_EXCEEDED 0x80000000 // Abort, number of devices in DP1.2 topology exceeds supported limit
51 
52 #define    DP_TUNNEL_REQUEST_BW_MAX_TIME_MS          (1000U)
53 #define    DP_TUNNEL_REQUEST_BW_POLLING_INTERVAL_MS    (10U)
54 
getDataClockMultiplier(NvU64 linkRate,NvU64 laneCount)55 static inline unsigned getDataClockMultiplier(NvU64 linkRate, NvU64 laneCount)
56 {
57     //
58     // To get the clock multiplier:
59     // - Convert the linkRate from Hz to 10kHz by dividing it by 10000.
60     // - Multiply the 10kHz linkRate by the laneCount.
61     // - Multiply by 10.0/8, to account for the 8b/10b encoding overhead in the DP protocol layer.
62     //
63     // Avoid floating point in the arithmetic in the calculation
64     // through the following conversions:
65     //   linkRate/10000.0 * laneCount * 10.0/8
66     //   (linkRate * laneCount * 10) / (10000 * 8)
67     //   (linkRate * laneCount) / (1000 * 8)
68     //
69     return (unsigned) DisplayPort::axb_div_c_64(linkRate, laneCount, 8000);
70 }
71 
72 namespace DisplayPort
73 {
74 
75     typedef enum
76     {
77         DP_TRANSPORT_MODE_INIT          = 0,
78         DP_TRANSPORT_MODE_SINGLE_STREAM = 1,
79         DP_TRANSPORT_MODE_MULTI_STREAM  = 2,
80     } DP_TRANSPORT_MODE;
81 
82     // Information required during compound query attach for MST
83     typedef struct _CompoundQueryAttachMSTInfo
84     {
85         ModesetInfo         localModesetInfo;
86         LinkConfiguration   lc;
87     } CompoundQueryAttachMSTInfo;
88 
89     struct ConnectorImpl : public Connector, DiscoveryManager::DiscoveryManagerEventSink, Timer::TimerCallback, MessageManager::MessageReceiver::MessageReceiverEventSink
90     {
91         // DPCD HAL Layer - We should use this in place of direct register accesses
92         DPCDHAL * hal;
93 
94         MainLink * main;                        // Main link controls
95         AuxBus * auxBus;
96 
97         TestMessage testMessage;                // TestMessage instance
98 
99         Timer * timer;                          // OS provided timer services
100         Connector::EventSink * sink;            // Event Sink
101 
102         // Cached Source OUI for restoring eDP OUI when powering up
103         unsigned cachedSourceOUI;
104         char     cachedSourceModelName[NV_DPCD_SOURCE_DEV_ID_STRING__SIZE + 1];
105         NvU8     cachedSourceChipRevision;
106         bool     bOuiCached;
107 
108         unsigned ouiId;                                                   // Sink ouiId
109         unsigned char modelName[NV_DPCD_SOURCE_DEV_ID_STRING__SIZE + 1];  // Device Model-name
110         bool    bIgnoreSrcOuiHandshake;                                   // Skip writing source OUI
111 
112         LinkPolicy    linkPolicy;
113 
114         bool    linkGuessed;                    // True when link was "guessed" during HPD in TMDS mode
115         bool    isLinkQuiesced;                 // True when link was set to quiet mode by TMDS modeset
116 
117         bool    bNoLtDoneAfterHeadDetach;       // True when head is disconnected in NDE
118 
119         bool    isDP12AuthCap;                  // To tell whether this DP1.2 connector/ upmost device has the authentication Cap.
120         bool    isHDCPAuthOn;                   // To tell whether this connector has the authentication on.
121         bool    isHDCPReAuthPending;            // To tell whether HDCP Auth is pending (at every stream addition and cleared at handler).
122         bool    isHDCPAuthTriggered;            // To tell whether HDCP Auth is triggered and only cleared at unplug/device detach for MST.
123         bool    isHopLimitExceeded;             // To tell the current topology is over limitation.
124         bool    bIsDiscoveryDetectActive;       // To tell device discovery is active ( isDiscoveryDetectComplete is also used as DD notify and not want to impacts that. )
125         bool    isDiscoveryDetectComplete;      // To tell device discovery is finished.
126         bool    bDeferNotifyLostDevice;         // To tell if we should defer notify lost device event to client.
127 
128         HDCPValidateData hdcpValidateData;      // Cache the HDCP ValidateData.
129         unsigned authRetries;                   // Retry counter for the authentication.
130         unsigned retryLT;                       // Retry counter for link training in case of link lost in PostLQA
131         unsigned hdcpCapsRetries;               // Retry counter for Hdcp Caps read.
132         unsigned hdcpCpIrqRxStatusRetries;      // Retry counter for CPIRQ RxStatus read.
133         bool    bLTPhyRepeater;                 // Link Train PHY Repeaters between Source and Sink
134         bool    bFromResumeToNAB;               // True if from resume to NAB, WAR flag for unblocking GA1.5
135         bool    bAttachOnResume;                // True if notifyLongPulse is called for resume (reboot/S3/S4)
136         bool    bSkipAssessLinkForEDP;          // Skip assessLink() for eDP. Assuming max is reachable.
137         bool    bPConConnected;                 // HDMI2.1-Protocol Converter (Support SRC control mode) connected.
138         bool    bSkipAssessLinkForPCon;         // Skip assessLink() for PCON. DD will call assessFRLLink later.
139         bool    bHdcpAuthOnlyOnDemand;          // True if only initiate Hdcp authentication on demand and MST won't auto-trigger authenticate at device attach.
140         bool    bReassessMaxLink;               // Retry assessLink() if the first assessed link config is lower than the panel max config.
141 
142         bool    constructorFailed;
143 
144         //
145         //  OS Modeset Order mitigation causes the library to delay the reporting
146         //   of new devices until they can be safely turned on.
147         //  When enabled the library client will not see connection events until
148         //    MustDisconnect messages are processed.
149         //
150         //   Policy state should be set before the library is brought out of
151         //   the suspended state.
152         //
153         bool policyModesetOrderMitigation;
154 
155         //
156         //  force LT at NAB for compliance test (Power Management) in Win10 RS2+ (WDDM 2.2)
157         //
158         //  RS2 no longer sends an explicit call for setPanelPowerParams during the Resume.
159         //  It does that by specifying an additional flag during the call to SetTimings. Due to
160         //  this DP lib doesn't get chance to perform this transition from setPanelPowerParams
161         //  and since it was already skipping LT in NAB/modeswitch, so LT get missed out on the
162         //  compliance device during resume from S3/S4.
163         //
164         bool policyForceLTAtNAB;
165 
166         //
167         //  There are cases where OS does not detach heads from connector immediately after hot-unplug,
168         //  on next hot-plug there is no guarantee that newly connected sink is capable to drive existing
169         //  raster timings. Flush mode has following restriction
170         //      When exiting flush mode S/W should ensure that the final
171         //      link clock & lane count should be able to support existing raster.
172         //  If we run into this situation and use flush mode then that will cause display engine to hang.
173         //  This variable ensures to assess link safely in this situation: if newly connected sink is
174         //  not capable to drive existing raster then just restore link configuration which was there
175         //  before enabling flush mode, through fake link training.
176         //
177         bool policyAssessLinkSafely;
178 
179         bool bDisableVbiosScratchRegisterUpdate;
180 
181         // Only works when policyModesetOrderMitigation is true.
182         // To record if we should report newDevice.
183         bool modesetOrderMitigation;
184 
185         List deviceList;
186         List activeGroups;
187         LinkedList<GroupImpl> intransitionGroups;
188         LinkedList<GroupImpl> addStreamMSTIntransitionGroups;
189         List inactiveGroups;
190 
191         LinkedList<Device> dscEnabledDevices;
192 
193         // Compound query
194         bool compoundQueryActive;
195         bool compoundQueryResult;
196         unsigned compoundQueryCount;
197         unsigned compoundQueryLocalLinkPBN;
198         NvU64 compoundQueryUsedTunnelingBw;
199         bool compoundQueryForceEnableFEC;
200 
201         unsigned freeSlots;
202         unsigned maximumSlots;
203         int firstFreeSlot;
204 
205         // Multistream messaging
206         MessageManager *    messageManager;
207         DiscoveryManager *  discoveryManager;
208 
209         // Multistream timeslot management (on local link)
210         LinkConfiguration highestAssessedLC;    // As of last assess, the highest possible link configuration
211 
212         LinkConfiguration activeLinkConfig;     // Current link config.
213 
214         // this is the link config requested by a client.
215         // can be set and reset by the client for a given operation.
216         LinkConfiguration preferredLinkConfig;
217         bool forcePreferredLinkConfig;
218 
219         //
220         // Desired link configuration of single head multiple sst secondary connector.
221         //
222         LinkConfiguration oneHeadSSTSecPrefLnkCfg;
223 
224         // All possible link configs
225         LinkConfiguration * allPossibleLinkCfgs;
226         unsigned numPossibleLnkCfg;
227 
228         PCONLinkControl activePConLinkControl;
229 
230         //
231         // We're waiting for an MST<->SST transition
232         // The transition cannot be made without the DD
233         // disconnecting all heads.  All devices are reported
234         // as must_disconnect.  Once the last device blocking
235         // the transition is deattached from a head - we transition.
236         //
237         bool              linkAwaitingTransition;
238 
239         // Unless we're awaiting transition this is identical to hal->getSupportsMultistream()
240         DP_TRANSPORT_MODE linkState;
241 
242         bool              bAudioOverRightPanel;
243 
244         bool previousPlugged;
245         bool connectorActive;                    // Keep track of if connector is active to serve any IRQ
246 
247         Group           * firmwareGroup;         // The group used for book-keeping when we're in firmware mode
248 
249         List pendingEdidReads;                   // List of DevicePendingEDIDRead structures.
250                                                  // This list tracks the currently in progress MST Edid Reads
251 
252         Device          * lastDeviceSetForVbios;
253 
254         // Flag which gets set when ACPI init is done. DD calls notifyAcpiInitDone to tell client that ACPI init is completed
255         // & client can now initiate DDC EDID read for a device which supports EDID through SBIOS
256         bool        bAcpiInitDone;
257 
258         // Flag to check if the system is UEFI.
259         bool        bIsUefiSystem;
260 
261         // Flag to check if LT should be skipped.
262         bool        bSkipLt;
263 
264         // Flag to make sure that zombie gets triggred when a powerChange event happens
265         bool bMitigateZombie;
266 
267         //
268         // HP Valor QHD+ N15P-Q3 EDP needs 50ms delay after D3
269         // during trainLinkOptimized to come up on S4
270         //
271         bool        bDelayAfterD3;
272 
273         //
274         // ASUS and Samsung monitors have inconsistent behavior when
275         // DPCD 0x600 updated to D3. Skip D3 only in case these monitors
276         // are driven in SST config
277         //
278         bool        bKeepLinkAlive;
279 
280         //
281         // HP Trump dock link training is unstable during S4 resume, which causes
282         // system to hang. Keep the link alive to increase stability.
283         // See Bug 2109823.
284         //
285         bool        bKeepLinkAliveMST;
286 
287         // Keep the link alive when connector is in SST
288         bool        bKeepLinkAliveSST;
289 
290         //
291         // HTC Vive Link box is not happy when we power down the link
292         // during link training when there is no stream present. It requests
293         // for a link retraining pulse which is not required.
294         // WAR to address this - NV Bug# 1793084
295         //
296         bool        bKeepOptLinkAlive;
297 
298         // Keep both DP and FRL link alive to save time.
299         bool        bKeepLinkAliveForPCON;
300 
301         //
302         // Remote HDCP DCPD access should be D0 but won't introduce extra Dx
303         // state toggle. Use the counter to avoid powerdownlink when HDCP probe.
304         //
305         unsigned   pendingRemoteHdcpDetections;
306 
307         //
308         // ASUS PQ 321 tiled monitor sometimes loses link while assessing link
309         // or link training .So if we lower config from HBR2 to HBR and when
310         // we retrain the link , we see black screen.
311         // So WAR is to retry link training with same config for 3 times before
312         // lowering link config. NV Bug #1846925
313         //
314         bool        bNoFallbackInPostLQA;
315 
316         bool        bReportDeviceLostBeforeNew;
317         bool        bDisableSSC;
318         bool        bEnableFastLT;
319         NvU32       maxLinkRateFromRegkey;
320         bool        bFlushTimeslotWhenDirty;
321 
322         //
323         // Latency(ms) to apply between link-train and FEC enable for bug
324         // 2561206.
325         //
326         NvU32       LT2FecLatencyMs;
327 
328         //
329         // Dual SST Partner connector object pointer
330         ConnectorImpl *pCoupledConnector;
331 
332         // Set to true when a DSC mode is requested.
333         bool bFECEnable;
334 
335         // Save link config before entering PSR.
336         LinkConfiguration psrLinkConfig;
337 
338         //
339         // Apply MST DSC caps WAR based on OUI ID of sink
340         //
341         bool        bDscMstCapBug3143315;
342 
343         //
344         // Synaptics branch device doesn't support Virtual Peer Devices so DSC
345         // capability of downstream device should be decided based on device's own
346         // and its parent's DSC capability
347         //
348         bool        bDscCapBasedOnParent;
349 
350         //
351         // MST device connnected to dock may issue IRQ for link lost.
352         // Send PowerDown path msg to suppress that.
353         //
354         bool        bPowerDownPhyBeforeD3;
355 
356         //
357         // Reset the MSTM_CTRL registers on branch device irrespective of
358         // IRQ VECTOR register having stale message. Certain branch devices
359         // need to reset the topology before issuing new discovery commands
360         // as there can be case where previous is still in process and a
361         // possibility that clearPendingMessage() might not be able to catch
362         // the stale messages from previous discovery.
363         //
364         bool        bForceClearPendingMsg;
365         NvU64       allocatedDpTunnelBw;
366         NvU64       allocatedDpTunnelBwShadow;
367         bool        bForceDisableTunnelBwAllocation;
368 
369         Group *perHeadAttachedGroup[NV_MAX_HEADS];
370         NvU32 inTransitionHeadMask;
371 
372         void sharedInit();
373         ConnectorImpl(MainLink * main, AuxBus * auxBus, Timer * timer, Connector::EventSink * sink);
374         void setPolicyModesetOrderMitigation(bool enabled);
375         void setPolicyForceLTAtNAB(bool enabled);
376         void setPolicyAssessLinkSafely(bool enabled);
377 
378         void discoveryDetectComplete();
379         void discoveryNewDevice(const DiscoveryManager::Device &device);
380         void discoveryLostDevice(const Address &address);
381         void processNewDevice(const DiscoveryManager::Device &device,
382             const Edid &edid,
383             bool isMultistream,
384             DwnStreamPortType portType,
385             DwnStreamPortAttribute portAttribute,
386             bool isCompliance = false);
387 
388         void applyEdidWARs(Edid &edid, DiscoveryManager::Device device);
389         void applyRegkeyOverrides(const DP_REGKEY_DATABASE& dpRegkeyDatabase);
390 
391         ResStatusNotifyMessage ResStatus;
392 
393         void messageProcessed(MessageManager::MessageReceiver * from);
394 
395         ~ConnectorImpl();
396 
397         //
398         //  Utility functions
399         //
400         virtual void hardwareWasReset();
401         virtual LinkConfiguration getMaxLinkConfig();
402         virtual LinkConfiguration getActiveLinkConfig();
403         virtual void powerdownLink(bool bPowerdownPanel = false);
404 
405         GroupImpl * getActiveGroupForSST();
406         bool detectSinkCountChange();
407         bool handlePhyPatternRequest();
408         void applyOuiWARs();
linkUseMultistreamConnectorImpl409         bool linkUseMultistream()
410         {
411             return (linkState == DP_TRANSPORT_MODE_MULTI_STREAM);
412         }
413 
414         void populateAllDpConfigs();
415         virtual LinkRates* importDpLinkRates();
416 
417         //
418         //  Suspend resume API
419         //
420         virtual Group * resume(bool firmwareLinkHandsOff,
421                                bool firmwareDPActive,
422                                bool plugged,
423                                bool isUefiSystem = false,
424                                unsigned firmwareHead = 0,
425                                bool bFirmwareLinkUseMultistream = false,
426                                bool bDisableVbiosScratchRegisterUpdate = false,
427                                bool bAllowMST = true);
428         virtual void    pause();
429 
430         virtual Device * enumDevices(Device * previousDevice) ;
431 
432 
433         virtual void beginCompoundQuery(const bool bForceEnableFEC = false) ;
434         virtual bool compoundQueryAttach(Group * target,
435             unsigned twoChannelAudioHz,         // if you need 192khz stereo specify 192000 here
436             unsigned eightChannelAudioHz,       // Same setting for multi channel audio.
437                                                 //  DisplayPort encodes 3-8 channel streams as 8 channel
438             NvU64 pixelClockHz,                 // Requested pixel clock for the mode
439             unsigned rasterWidth,
440             unsigned rasterHeight,
441             unsigned rasterBlankStartX,
442             unsigned rasterBlankEndX,
443             unsigned depth,
444             DP_IMP_ERROR *errorStatus = NULL);
445 
446         virtual bool compoundQueryAttach(Group * target,
447                                          const DpModesetParams &modesetParams,      // Modeset info
448                                          DscParams *pDscParams = NULL,              // DSC parameters
449                                          DP_IMP_ERROR *pErrorCode = NULL);          // Error Status code
450         virtual bool compoundQueryAttachTunneling(const DpModesetParams &modesetParams,
451                                                   DscParams *pDscParams = NULL,
452                                                   DP_IMP_ERROR *pErrorCode = NULL);
453 
454         virtual bool endCompoundQuery();
455 
456         virtual bool dpLinkIsModePossible(const DpLinkIsModePossibleParams &params);
457 
458         virtual bool compoundQueryAttachMST(Group * target,
459                                             const DpModesetParams &modesetParams,      // Modeset info
460                                             DscParams *pDscParams = NULL,              // DSC parameters
461                                             DP_IMP_ERROR *pErrorCode = NULL);          // Error Status code
462 
463         virtual bool compoundQueryAttachMSTIsDscPossible
464         (
465             Group * target,
466             const DpModesetParams &modesetParams,      // Modeset info
467             DscParams *pDscParams = NULL               // DSC parameters
468         );
469 
470         // Calculate and Configure SW state based on DSC
471         virtual bool compoundQueryAttachMSTDsc
472         (
473             Group * target,
474             const DpModesetParams &modesetParams,      // Modeset info
475             CompoundQueryAttachMSTInfo * info,         // local info to update for later use
476             DscParams *pDscParams = NULL,              // DSC parameters
477             DP_IMP_ERROR *pErrorCode = NULL            // Error Status code
478         );
479 
480         // General part of CQA MST for DSC/non-DSC
481         virtual bool compoundQueryAttachMSTGeneric
482         (
483             Group * target,
484             const DpModesetParams &modesetParams,       // Modeset info
485             CompoundQueryAttachMSTInfo * info,          // local info with updates for DSC
486             DscParams *pDscParams = NULL,               // DSC parameters
487             DP_IMP_ERROR *pErrorCode = NULL             // Error Status code
488         );
489 
490         virtual bool compoundQueryAttachSST(Group * target,
491                                             const DpModesetParams &modesetParams,      // Modeset info
492                                             DscParams *pDscParams = NULL,              // DSC parameters
493                                             DP_IMP_ERROR *pErrorCode = NULL);          // Error Status code
494 
495 
496         //
497         //  Timer callback tags.
498         //   (we pass the address of these variables as context to ::expired)
499         char tagFireEvents;
500         char tagDelayedLinkTrain;
501         char tagHDCPReauthentication;
502         char tagDelayedHdcpCapRead;
503         char tagDelayedHDCPCPIrqHandling;
504         char tagDpBwAllocationChanged;
505 
506         //
507         //  Enable disable TMDS mode
508         //
509         virtual void enableLinkHandsOff();
510         virtual void releaseLinkHandsOff();
511 
512         //
513         //  Timer callback for event management
514         //      Uses: fireEvents()
515         virtual void expired(const void * tag);
516 
517         // Generate Events.
518         //      useTimer specifies whether we fire the events on the timer
519         //      context, or this context.
520         void fireEvents();
521 
522         // returns the number of pending notifications.
523         void fireEventsInternal();
524 
525         virtual bool isHeadShutDownNeeded(Group * target,   // Group of panels we're attaching to this head
526             unsigned headIndex,
527             ModesetInfo modesetInfo);
528 
529         virtual bool isLinkTrainingNeededForModeset(ModesetInfo modesetInfo);
530 
531         virtual bool notifyAttachBegin(Group * target,      // Group of panels we're attaching to this head
532             const DpModesetParams &modesetParams);
533 
534         bool needToEnableFEC(const DpPreModesetParams &params);
535 
536         virtual void dpPreModeset(const DpPreModesetParams &modesetParams);
537         virtual void dpPostModeset(void);
538 
539         virtual bool isHeadShutDownNeeded(Group * target,   // Group of panels we're attaching to this head
540             unsigned headIndex,
541             unsigned twoChannelAudioHz,         // if you need 192khz stereo specify 192000 here
542             unsigned eightChannelAudioHz,       // Same setting for multi channel audio. DisplayPort encodes 3-8 channel streams as 8 channel
543             NvU64 pixelClockHz,                 // Requested pixel clock for the mode
544             unsigned rasterWidth,
545             unsigned rasterHeight,
546             unsigned rasterBlankStartX,
547             unsigned rasterBlankEndX,
548             unsigned depth) ;
549 
550         virtual bool notifyAttachBegin(Group * target,      // Group of panels we're attaching to this head
551             unsigned headIndex,
552             unsigned twoChannelAudioHz,                     // if you need 192khz stereo specify 192000 here
553             unsigned eightChannelAudioHz,                   // Same setting for multi channel audio.
554                                                             // DisplayPort encodes 3-8 channel streams as 8 channel
555             NvU64 pixelClockHz,                             // Requested pixel clock for the mode
556             unsigned rasterWidth,
557             unsigned rasterHeight,
558             unsigned rasterBlankStartX,
559             unsigned rasterBlankEndX,
560             unsigned depth) ;
561 
562         virtual void readRemoteHdcpCaps();
563         virtual void notifyAttachEnd(bool modesetCancelled);
564         virtual void notifyDetachBegin(Group * target);
565         virtual void notifyDetachEnd(bool bKeepOdAlive = false);
566         virtual bool willLinkSupportModeSST(const LinkConfiguration &linkConfig, const ModesetInfo &modesetInfo);
567 
568         bool performIeeeOuiHandshake();
569         void setIgnoreSourceOuiHandshake(bool bIgnore);
570         bool getIgnoreSourceOuiHandshake();
571         void forceLinkTraining();
572 
573         bool     updateDpTunnelBwAllocation();
574         TriState requestDpTunnelBw(NvU8 requestedBw);
575         bool     allocateDpTunnelBw(NvU64 bandwidth);
576         bool     allocateMaxDpTunnelBw();
577         NvU64    getMaxTunnelBw();
578         void     enableDpTunnelingBwAllocationSupport();
579 
580         void assessLink(LinkTrainingType trainType = NORMAL_LINK_TRAINING);
581 
582         bool isLinkInD3();
583         bool isLinkActive();
584         bool isLinkLost();
585         bool trainSingleHeadMultipleSSTLinkNotAlive(GroupImpl *pGroupAttached);
586         bool isLinkAwaitingTransition();
587         bool isNoActiveStreamAndPowerdown();
incPendingRemoteHdcpDetectionConnectorImpl588         void incPendingRemoteHdcpDetection()
589         {
590             pendingRemoteHdcpDetections++;
591         }
decPendingRemoteHdcpDetectionConnectorImpl592         void decPendingRemoteHdcpDetection()
593         {
594             if (pendingRemoteHdcpDetections > 0)
595             {
596                 pendingRemoteHdcpDetections--;
597             }
598         }
599         bool trainLinkOptimized(LinkConfiguration lConfig);
600         bool trainLinkOptimizedSingleHeadMultipleSST(GroupImpl * group);
601         bool getValidLowestLinkConfig(LinkConfiguration &lConfig, LinkConfiguration &lowestSelected, ModesetInfo queryModesetInfo);
602         bool postLTAdjustment(const LinkConfiguration &, bool force);
603         void populateUpdatedLaneSettings(NvU8* voltageSwingLane, NvU8* preemphasisLane, NvU32 *data);
604         void populateDscCaps(DSC_INFO* dscInfo, DeviceImpl * dev, DSC_INFO::FORCED_DSC_PARAMS* forcedParams);
605         void populateDscGpuCaps(DSC_INFO* dscInfo);
606         void populateForcedDscParams(DSC_INFO* dscInfo, DSC_INFO::FORCED_DSC_PARAMS* forcedParams);
607         void populateDscSinkCaps(DSC_INFO* dscInfo, DeviceImpl * dev);
608         void populateDscBranchCaps(DSC_INFO* dscInfo, DeviceImpl * dev);
609         void populateDscModesetInfo(MODESET_INFO * pModesetInfo, const DpModesetParams * pModesetParams);
610 
611         virtual bool train(const LinkConfiguration &lConfig, bool force, LinkTrainingType trainType = NORMAL_LINK_TRAINING);
612         virtual bool validateLinkConfiguration(const LinkConfiguration &lConfig);
613 
614         virtual bool assessPCONLinkCapability(PCONLinkControl *params);
615         bool trainPCONFrlLink(PCONLinkControl *pConControl);
616 
617         // Set Device DSC state based on current DSC state of all active devices on this connector
618         bool setDeviceDscState(Device * dev, bool bEnableDsc);
619 
620         // the lowest level function(nearest to the hal) for the connector.
621         bool rawTrain(const LinkConfiguration &lConfig, bool force, LinkTrainingType linkTrainingType);
622 
623         virtual bool enableFlush();
624         virtual bool beforeAddStream(GroupImpl * group, bool force=false, bool forFlushMode = false);
625         virtual void afterAddStream(GroupImpl * group);
626         virtual void beforeDeleteStream(GroupImpl * group, bool forFlushMode = false);
627         virtual void afterDeleteStream(GroupImpl * group);
628         virtual void disableFlush(bool test=false);
629 
630         bool beforeAddStreamMST(GroupImpl * group, bool force = false, bool forFlushMode = false);
631 
632         virtual bool checkIsModePossibleMST(GroupImpl * group);
633 
634         bool deleteAllVirtualChannels();
635         void clearTimeslices();
636         virtual bool allocateTimeslice(GroupImpl * targetGroup);
637         void freeTimeslice(GroupImpl * targetGroup);
638         void flushTimeslotsToHardware();
639         bool getHDCPAbortCodesDP12(NvU32 &hdcpAbortCodesDP12);
640         bool getOuiSink(unsigned &ouiId, unsigned char * modelName, size_t modelNameBufferSize, NvU8 &chipRevision);
641         bool hdcpValidateKsv(const NvU8 *ksv, NvU32 Size);
642         void cancelHdcpCallbacks();
643         bool handleCPIRQ();
644         void handleSSC();
645         void handleMCCSIRQ();
646         void handleDpTunnelingIrq();
647         void handleHdmiLinkStatusChanged();
648         void sortActiveGroups(bool ascending);
649         void configInit();
650         void handlePanelReplayError();
651 
652         virtual DeviceImpl* findDeviceInList(const Address &address);
653         virtual void disconnectDeviceList();
654         void notifyLongPulseInternal(bool statusConnected);
655         virtual void notifyLongPulse(bool status);
656         virtual void notifyShortPulse();
657         virtual Group * newGroup();
658         virtual void destroy();
659         virtual void createFakeMuxDevice(const NvU8 *buffer, NvU32 bufferSize);
660         virtual void deleteFakeMuxDevice();
661         virtual bool getRawDscCaps(NvU8 *buffer, NvU32 bufferSize);
662         virtual bool isMultiStreamCapable();
663         virtual bool isFlushSupported();
664         virtual bool isStreamCloningEnabled();
665         virtual bool isFECSupported();
666         virtual bool isFECCapable();
667         virtual NvU32 maxLinkRateSupported();
668         bool setPreferredLinkConfig(LinkConfiguration &lc, bool commit,
669                                     bool force = false,
670                                     LinkTrainingType trainType = NORMAL_LINK_TRAINING,
671                                     bool forcePreferredLinkConfig = false);
672         virtual bool resetPreferredLinkConfig(bool force = false);
673         virtual void setAllowMultiStreaming(bool bAllowMST);
674         virtual bool getAllowMultiStreaming(void);
675         virtual bool getSinkMultiStreamCap(void);
676         virtual void setDp11ProtocolForced();
677         virtual void resetDp11ProtocolForced();
678         virtual bool isDp11ProtocolForced();
679 
680         bool isAcpiInitDone();
681         virtual void notifyAcpiInitDone();
682         Group * createFirmwareGroup();
683         virtual void notifyGPUCapabilityChange();
684         virtual void notifyHBR2WAREngage();
685         bool dpUpdateDscStream(Group *target, NvU32 dscBpp);
686 
687         bool getTestPattern(NV0073_CTRL_DP_TESTPATTERN *testPattern);
688         bool setTestPattern(NV0073_CTRL_DP_TESTPATTERN testPattern, NvU8 laneMask, NV0073_CTRL_DP_CSTM cstm, NvBool bIsHBR2, NvBool bSkipLaneDataOverride = false);
689         bool getLaneConfig(NvU32 *numLanes, NvU32 *data);    // "data" is an array of NV0073_CTRL_MAX_LANES unsigned ints
690         bool setLaneConfig(NvU32 numLanes, NvU32 *data);    // "data" is an array of NV0073_CTRL_MAX_LANES unsigned ints
691         void getCurrentLinkConfig(unsigned &laneCount, NvU64 &linkRate);  // CurrentLink Configuration
692         unsigned getPanelDataClockMultiplier();
693         unsigned getGpuDataClockMultiplier();
694         void configurePowerState(bool bPowerUp);
695         virtual void readPsrCapabilities(vesaPsrSinkCaps *caps);
696         virtual bool updatePsrConfiguration(vesaPsrConfig config);
697         virtual bool readPsrConfiguration(vesaPsrConfig *config);
698         virtual bool readPsrDebugInfo(vesaPsrDebugStatus *psrDbgState);
699         virtual bool writePsrErrorStatus(vesaPsrErrorStatus psrErr);
700         virtual bool readPsrErrorStatus(vesaPsrErrorStatus *psrErr);
701         virtual bool writePsrEvtIndicator(vesaPsrEventIndicator psrErr);
702         virtual bool readPsrEvtIndicator(vesaPsrEventIndicator *psrErr);
703         virtual bool readPsrState(vesaPsrState *psrState);
704         virtual bool updatePsrLinkState(bool bTurnOnLink);
705 
706         virtual bool readPrSinkDebugInfo(panelReplaySinkDebugInfo *prDbgInfo);
707 
708         // for dp test utility. pBuffer is the request buffer of type DP_STATUS_REQUEST_xxxx
709         DP_TESTMESSAGE_STATUS sendDPTestMessage(void *pBuffer,
710                                                 NvU32 requestSize,
711                                                 NvU32 *pDpStatus);
712 
713         DP_TESTMESSAGE_STATUS getStreamIDs(NvU32 *pStreamIDs, NvU32 *pCount);  // for dp test utility, called by DD
714 
715         // Reset link training counter for the active link configuration.
resetLinkTrainingCounterConnectorImpl716         virtual void resetLinkTrainingCounter()
717         {
718             activeLinkConfig.setLTCounter(0);
719         }
720     };
721 
722     //
723     //  New devices do not get a DeviceImpl created until after
724     //   the EDID read has completed.  This object is used
725     //   to track the necessary state.
726     //
727     struct DevicePendingEDIDRead : protected EdidReadMultistream::EdidReadMultistreamEventSink, public ListElement
728     {
729         ConnectorImpl *          parent;
730         DiscoveryManager::Device device;
731         EdidReadMultistream      reader;
732 
733         void mstEdidCompleted(EdidReadMultistream * from);
734         void mstEdidReadFailed(EdidReadMultistream * from);
735 
736     public:
DevicePendingEDIDReadDevicePendingEDIDRead737         DevicePendingEDIDRead(ConnectorImpl *  _parent, MessageManager * manager, DiscoveryManager::Device dev)
738             : parent(_parent), device(dev), reader(_parent->timer, manager, this, dev.address)
739         {
740         }
741     };
742 }
743 
744 #endif //INCLUDED_DP_CONNECTORIMPL_H
745