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