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 isDynamicPPSSupported();
453         NvBool isDynamicDscToggleSupported();
454         NvBool isDSCSupported();
455         NvBool isDSCDecompressionSupported();
456         NvBool isDSCPossible();
457         bool isFECSupported();
458         bool readAndParseDSCCaps();
459         bool readAndParseBranchSpecificDSCCaps();
460         bool parseDscCaps(const NvU8 *buffer, NvU32 bufferSize);
461         bool parseBranchSpecificDscCaps(const NvU8 *buffer, NvU32 bufferSize);
462         bool setDscEnable(bool enable);
463         bool setDscEnableDPToHDMIPCON(bool bDscEnable, bool bEnablePassThroughForPCON);
464         bool getDscEnable(bool *pEnable);
465         unsigned getDscVersionMajor();
466         unsigned getDscVersionMinor();
467         unsigned getDscRcBufferSize();
468         unsigned getDscRcBufferBlockSize();
469         unsigned getDscMaxSlicesPerSink();
470         unsigned getDscLineBufferBitDepth();
471         NvBool   isDscBlockPredictionSupported();
472         unsigned getDscMaxBitsPerPixel();
473         NvBool   isDscRgbSupported();
474         NvBool   isDscYCbCr444Supported();
475         NvBool   isDscYCbCrSimple422Supported();
476         NvBool   isDscYCbCr422NativeSupported();
477         NvBool   isDscYCbCr420NativeSupported();
478         unsigned getDscPeakThroughputMode0();
479         unsigned getDscPeakThroughputModel();
480         unsigned getDscMaxSliceWidth();
481         unsigned getDscDecoderColorDepthSupportMask();
482         void setDscDecompressionDevice(bool bDscCapBasedOnParent);
483     };
484     class DeviceHDCPDetection : public Object, MessageManager::Message::MessageEventSink, Timer::TimerCallback
485     {
486             DeviceImpl*              parent;
487             RemoteDpcdReadMessage    remoteBKSVReadMessage;
488             RemoteDpcdReadMessage    remoteBCapsReadMessage;
489             RemoteDpcdReadMessage    remote22BCapsReadMessage;
490             MessageManager *         messageManager;     // For transmit and receive
491             Timer *                  timer;
492             bool                     bksvReadCompleted;
493             bool                     bCapsReadCompleted;
494             bool                     isValidBKSV;
495             bool                     isBCapsHDCP;
496             unsigned                 retriesRemoteBKSVReadMessage;
497             unsigned                 retriesRemoteBCapsReadMessage;
498             unsigned                 retriesRemote22BCapsReadMessage;
499             bool                     retryRemoteBKSVReadMessage;
500             bool                     retryRemoteBCapsReadMessage;
501             bool                     retryRemote22BCapsReadMessage;
502             bool                     bBKSVReadMessagePending;
503             bool                     bBCapsReadMessagePending;
504 
505         public:
506 
507             DeviceHDCPDetection(DeviceImpl * parent, MessageManager * messageManager, Timer * timer)
508                 : bksvReadCompleted(false),bCapsReadCompleted(false),isValidBKSV(false),
509                   isBCapsHDCP(false), retriesRemoteBKSVReadMessage(0), retriesRemoteBCapsReadMessage(0),
510                   retriesRemote22BCapsReadMessage(0), retryRemoteBKSVReadMessage(false),
511                   retryRemoteBCapsReadMessage(false), retryRemote22BCapsReadMessage(false),
512                   bBKSVReadMessagePending(false), bBCapsReadMessagePending(false)
513 
514             {
515                 this->parent = parent;
516                 this->messageManager = messageManager;
517                 this->timer = timer;
518             }
519 
520             ~DeviceHDCPDetection();
521             void expired(const void * tag);
522             void start();
523             void waivePendingHDCPCapDoneNotification();
524 
525             bool hdcpValidateKsv(const NvU8 *ksv, NvU32 Size);
526             void handleRemoteDpcdReadDownReply(MessageManager::Message * from);
527             void messageFailed(MessageManager::Message * from, NakData * nakData);
528             void messageCompleted(MessageManager::Message * from);
529     };
530 }
531 
532 #endif //INCLUDED_DP_DEVICEIMPL_H
533 
534