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