1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 1993-2022 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_configcaps.h                                                   *
27 *    Abstraction for basic caps registers                                   *
28 *                                                                           *
29 \***************************************************************************/
30 
31 #ifndef INCLUDED_DP_CONFIGCAPS_H
32 #define INCLUDED_DP_CONFIGCAPS_H
33 
34 #include "dp_connector.h"
35 #include "dp_auxretry.h"
36 #include "dp_linkconfig.h"
37 #include "dp_regkeydatabase.h"
38 
39 namespace DisplayPort
40 {
41     enum PowerState
42     {
43         PowerStateD0 = 1,
44         PowerStateD3 = 2,
45         PowerStateD3AuxOn = 5
46     };
47 
48     // Extended caps = offset 0x80
49     enum DwnStreamPortType
50     {
51         DISPLAY_PORT = 0,
52         ANALOG_VGA,
53         DVI,
54         HDMI,
55         WITHOUT_EDID,
56         DISPLAY_PORT_PLUSPLUS
57     } ;
58 
59     enum DwnStreamPortAttribute
60     {
61         RESERVED = 0,
62         IL_720_480_60HZ,
63         IL_720_480_50HZ,
64         IL_1920_1080_60HZ,
65         IL_1920_1080_50HZ,
66         PG_1280_720_60HZ,
67         PG_1280_720_50_HZ,
68     } ;
69 
70     // DPCD Offset 102 enums
71     enum TrainingPatternSelectType
72     {
73         TRAINING_DISABLED,
74         TRAINING_PAT_ONE,
75         TRAINING_PAT_TWO,
76         TRAINING_PAT_THREE,
77     };
78 
79     enum SymbolErrorSelectType
80     {
81         DISPARITY_ILLEGAL_SYMBOL_ERROR,
82         DISPARITY_ERROR,
83         ILLEGAL_SYMBOL_ERROR,
84     };
85 
86     // DPCD Offset 1A1 enums
87     enum MultistreamHotplugMode
88     {
89         HPD_LONG_PULSE,
90         IRQ_HPD,
91     };
92 
93     // DPCD Offset 220
94     enum TestPatternType
95     {
96         NO_PATTERN,
97         COLOR_RAMPS,
98         BLACK_WHITE,
99         COLOR_SQUARE,
100     } ;
101 
102     // DPCD Offset 232, 233
103     enum ColorFormatType
104     {
105         RGB,
106         YCbCr_422,
107         YCbCr_444,
108     } ;
109 
110     enum DynamicRangeType
111     {
112         VESA,
113         CEA,
114     } ;
115 
116     enum YCBCRCoeffType
117     {
118         ITU601,
119         ITU709,
120     } ;
121 
122     #define HDCP_BCAPS_SIZE                 (0x1)
123     #define HDCP_VPRIME_SIZE                (0x14)
124     #define HDCP_KSV_FIFO_SIZE              (0xF)
125     #define HDCP_KSV_FIFO_WINDOWS_RETRY     (0x3)
126     #define HDCP22_BCAPS_SIZE               (0x1)
127 
128     // Bstatus DPCD offset 0x68029
129     #define HDCPREADY                       (0x1)
130     #define R0PRIME_AVAILABLE               (0x2)
131     #define LINK_INTEGRITY_FAILURE          (0x4)
132     #define REAUTHENTICATION_REQUEST        (0x8)
133 
134     struct BInfo
135     {
136         bool maxCascadeExceeded;
137         unsigned depth;
138         bool maxDevsExceeded;
139         unsigned deviceCount;
140     };
141 
142     struct BCaps
143     {
144         bool repeater;
145         bool HDCPCapable;
146     };
147 
148     enum
149     {
150         PHYSICAL_PORT_START = 0x0,
151         PHYSICAL_PORT_END   = 0x7,
152         LOGICAL_PORT_START  = 0x8,
153         LOGICAL_PORT_END    = 0xF
154     };
155 
156     class LaneStatus
157     {
158     public:
159         //
160         //  Lane Status
161         //      CAUTION: Only updated on IRQ/HPD right now
162         //
163         virtual bool     getLaneStatusClockRecoveryDone(int lane) = 0;                // DPCD offset 202, 203
164         virtual bool     getLaneStatusSymbolLock(int lane)= 0;
165         virtual bool     getInterlaneAlignDone() = 0;
166         virtual bool     getDownStreamPortStatusChange() = 0;
167     };
168 
169     class TestRequest
170     {
171     public:
172         virtual bool getPendingTestRequestTraining() = 0;                              // DPCD offset 218
173         virtual void getTestRequestTraining(LinkRate & rate, unsigned & lanes) = 0;    // DPCD offset 219, 220
174         virtual bool getPendingAutomatedTestRequest() = 0;                             // DPCD offset 218
175         virtual bool getPendingTestRequestEdidRead() = 0;                              // DPCD offset 218
176         virtual bool getPendingTestRequestPhyCompliance() = 0;                         // DPCD offset 218
177         virtual LinkQualityPatternType getPhyTestPattern() = 0;                        // DPCD offset 248
178         virtual AuxRetry::status setTestResponse(bool ack, bool edidChecksumWrite = false) = 0;
179         virtual AuxRetry::status setTestResponseChecksum(NvU8 checksum) = 0;
180     };
181 
182     class LegacyPort
183     {
184     public:
185         virtual DwnStreamPortType      getDownstreamPortType() = 0;
186         virtual DwnStreamPortAttribute getDownstreamNonEDIDPortAttribute() = 0;
187 
188         // For port type = HDMI
189         virtual NvU64                  getMaxTmdsClkRate() = 0;
190     };
191 
192     class LinkState
193     {
194     public:
195         //
196         //  Link state
197         //
198         virtual bool             isPostLtAdjustRequestSupported() = 0;
199         virtual void             setPostLtAdjustRequestGranted(bool bGrantPostLtRequest) = 0;
200         virtual bool             getIsPostLtAdjRequestInProgress() = 0;                     // DPCD offset 204
201         virtual TrainingPatternSelectType getTrainingPatternSelect() = 0;                   // DPCD offset 102
202 
203         virtual bool setTrainingMultiLaneSet(NvU8 numLanes,
204                                              NvU8 *voltSwingSet,
205                                              NvU8 *preEmphasisSet) = 0;
206 
207         virtual bool readTraining(NvU8* voltageSwingLane,
208                                   NvU8* preemphasisLane = 0,
209                                   NvU8* trainingScoreLane = 0,
210                                   NvU8* postCursor = 0,
211                                   NvU8 activeLaneCount = 0) = 0;
212 
213         virtual bool isLaneSettingsChanged(NvU8* oldVoltageSwingLane,
214                                            NvU8* newVoltageSwingLane,
215                                            NvU8* oldPreemphasisLane,
216                                            NvU8* newPreemphasisLane,
217                                            NvU8 activeLaneCount) = 0;
218 
219         virtual AuxRetry::status setIgnoreMSATimingParamters(bool msaTimingParamIgnoreEn) = 0;
220         virtual AuxRetry::status setLinkQualLaneSet(unsigned lane, LinkQualityPatternType linkQualPattern) = 0;
221         virtual AuxRetry::status setLinkQualPatternSet(LinkQualityPatternType linkQualPattern, unsigned laneCount = 0) = 0;
222     };
223 
224     class LinkCapabilities
225     {
226     public:
227 
228         //
229         //  Physical layer feature set
230         //
231         virtual NvU64    getMaxLinkRate() = 0;                                // Maximum byte-block in Hz
232         virtual unsigned getMaxLaneCount() = 0;                               // DPCD offset 0x0002h
233         virtual unsigned getMaxLaneCountSupportedAtLinkRate(LinkRate linkRate) = 0;
234         virtual bool     getEnhancedFraming() = 0;
235         virtual bool     getSupportsNoHandshakeTraining() = 0;
236         virtual bool     getMsaTimingparIgnored() = 0;
237         virtual bool     getDownstreamPort(NvU8 *portType) = 0;               // DPCD offset 0x0005h
238         virtual bool     getSupportsMultistream() = 0;                        // DPCD offset 0x0021h
239         virtual bool     getNoLinkTraining() = 0;                             // DPCD offset 0x0330h
240         virtual unsigned getPhyRepeaterCount() = 0;                           // DPCD offset 0xF0002h
241     };
242 
243     class OUI
244     {
245     public:
246         virtual bool             getOuiSupported() = 0;
247         virtual AuxRetry::status setOuiSource(unsigned ouiId, const char * model, size_t modelNameLength, NvU8 chipRevision) = 0;
248         virtual bool             getOuiSource(unsigned &ouiId, char * modelName, size_t modelNameBufferSize, NvU8 & chipRevision) = 0;
249         virtual bool             getOuiSink(unsigned &ouiId, char * modelName, size_t modelNameBufferSize, NvU8 & chipRevision) = 0;
250     };
251 
252     class HDCP
253     {
254     public:
255         virtual bool getBKSV(NvU8 *bKSV) = 0;                                   // DPCD offset 0x68000
256         virtual bool getBCaps(BCaps &bCaps, NvU8 * rawByte = 0) = 0;            // DPCD offset 0x68028
257         virtual bool getHdcp22BCaps(BCaps &bCaps, NvU8 * rawByte = 0) = 0;      // DPCD offset 0x6921D
258         virtual bool getBinfo(BInfo &bInfo) = 0;                                // DPCD offset 0x6802A
259 
260         // Generic interfaces for HDCP 1.x / 2.2
261         virtual bool getRxStatus(const HDCPState &hdcpState, NvU8 *data) = 0;
262     };
263 
264     class DPCDHAL :
265         virtual public Object,
266         public TestRequest,
267         public LaneStatus,
268         public LinkState,
269         public LinkCapabilities,
270         public OUI,
271         public HDCP
272     {
273     public:
274         //
275         //  Notifications of external events
276         //      We sent IRQ/HPD events to the HAL so that it knows
277         //      when to re-read the registers.  All the remaining
278         //      calls are either accessors to cached state (caps),
279         //      or DPCD get/setters
280         //
281         virtual void notifyIRQ() = 0;
282         virtual void notifyHPD(bool status, bool bSkipDPCDRead = false) = 0;
283 
284         virtual void populateFakeDpcd() = 0;
285 
286         // DPCD override routines
287         virtual void overrideMaxLinkRate(NvU32 overrideMaxLinkRate) = 0;
288         virtual void overrideMaxLaneCount(NvU32 maxLaneCount) = 0;
289         virtual void skipCableBWCheck(NvU32 maxLaneAtHighRate, NvU32 maxLaneAtLowRate) = 0;
290         virtual void overrideOptimalLinkCfg(LinkRate optimalLinkRate, NvU32 optimalLaneCount) = 0;
291         virtual void overrideOptimalLinkRate(LinkRate optimalLinkRate) = 0;
292 
293         virtual bool isDpcdOffline() = 0;
294         virtual void setAuxBus(AuxBus * bus) = 0;
295         virtual NvU32 getVideoFallbackSupported() = 0;
296         //
297         //  Cached CAPS
298         //    These are only re-read when notifyHPD is called
299         //
300         virtual unsigned getRevisionMajor() = 0;
301         virtual unsigned getRevisionMinor() = 0;
302 
303         virtual unsigned lttprGetRevisionMajor() = 0;
304         virtual unsigned lttprGetRevisionMinor() = 0;
305 
306         virtual bool getSDPExtnForColorimetry() = 0;
307         virtual bool getRootAsyncSDPSupported() = 0;
308 
isAtLeastVersion(unsigned major,unsigned minor)309         bool isAtLeastVersion(unsigned major, unsigned minor)
310         {
311             if (getRevisionMajor() > major)
312                 return true;
313 
314             if (getRevisionMajor() < major)
315                 return false;
316 
317             return getRevisionMinor() >= minor;
318         }
319 
isVersion(unsigned major,unsigned minor)320         bool isVersion(unsigned major, unsigned minor)
321         {
322             if ((getRevisionMajor() == major) &&
323                 (getRevisionMinor() == minor))
324                 return true;
325 
326             return false;
327         }
328 
lttprIsAtLeastVersion(unsigned major,unsigned minor)329         bool lttprIsAtLeastVersion(unsigned major, unsigned minor)
330         {
331             if (lttprGetRevisionMajor() > major)
332                 return true;
333 
334             if (lttprGetRevisionMinor() < major)
335                 return false;
336 
337             return lttprGetRevisionMinor() >= minor;
338         }
339 
lttprIsVersion(unsigned major,unsigned minor)340         bool lttprIsVersion(unsigned major, unsigned minor)
341         {
342             if ((lttprGetRevisionMajor() == major) &&
343                 (lttprGetRevisionMinor() == minor))
344                 return true;
345 
346             return false;
347         }
348 
349         // Convert Link Bandwidth read from DPCD register to Linkrate
mapLinkBandiwdthToLinkrate(NvU32 linkBandwidth)350         NvU64 mapLinkBandiwdthToLinkrate(NvU32 linkBandwidth)
351         {
352             if (FLD_TEST_DRF(_DPCD, _MAX_LINK_BANDWIDTH, _VAL, _1_62_GBPS, linkBandwidth))
353                 return RBR;
354             else if (FLD_TEST_DRF(_DPCD, _MAX_LINK_BANDWIDTH, _VAL, _2_70_GBPS, linkBandwidth))
355                 return HBR;
356             else if (FLD_TEST_DRF(_DPCD, _MAX_LINK_BANDWIDTH, _VAL, _5_40_GBPS, linkBandwidth))
357                 return HBR2;
358             else if (FLD_TEST_DRF(_DPCD14, _MAX_LINK_BANDWIDTH, _VAL, _8_10_GBPS, linkBandwidth))
359                 return HBR3;
360             else
361             {
362                 DP_ASSERT(0 && "Unknown link bandwidth. Assuming HBR");
363                 return HBR;
364             }
365         }
366 
367         //
368         //  Native aux transaction size (16 for AUX)
369         //
370         virtual size_t   getTransactionSize() = 0;
371 
372         //
373         //  SST Branching device/dongle/repeater
374         //     - Describes downstream port limitations
375         //     - Not for use with MST
376         //     - Primarily used for dongles (look at port 0 for pclk limits)
377         //
378         virtual LegacyPort     * getLegacyPort(unsigned index) = 0;
379         virtual unsigned         getLegacyPortCount() = 0;
380 
381         virtual PCONCaps       * getPCONCaps() = 0;
382 
383         //
384         //  Single stream specific caps
385         //
386         virtual unsigned getNumberOfAudioEndpoints() = 0;
387         virtual int      getSinkCount() = 0;
388         virtual void     setSinkCount(int sinkCount) = 0;
389 
390         //
391         //  MISC
392         //
393         virtual bool isPC2Disabled() = 0;
394         virtual void setPC2Disabled(bool disabled) = 0;
395 
396         virtual void setDPCDOffline(bool enable) = 0;
397         virtual void updateDPCDOffline() = 0;
398 
399         virtual void setSupportsESI(bool bIsESISupported) = 0;
400         virtual void setLttprSupported(bool isLttprSupported) = 0;
401 
402         //
403         // Intermediate Link Rate (eDP ILR)
404         //
405         virtual void setIndexedLinkrateEnabled(bool newVal) = 0;
406         virtual bool isIndexedLinkrateEnabled() = 0;
407         virtual bool isIndexedLinkrateCapable() = 0;
408         virtual NvU16 *getLinkRateTable() = 0;
409         virtual bool getRawLinkRateTable(NvU8 *buffer = NULL) = 0;
410 
411         //
412         //  Link power state management
413         //
414         virtual bool setPowerState(PowerState newState) = 0;
415         virtual PowerState getPowerState() = 0;
416         //
417         //  Multistream
418         //
419         virtual bool             getGUID(GUID & guid) = 0;                    // DPCD offset 30
420         virtual AuxRetry::status setGUID(GUID & guid) = 0;
421         virtual AuxRetry::status setMessagingEnable(bool uprequestEnable, bool upstreamIsSource) = 0;
422         virtual AuxRetry::status setMultistreamLink(bool bMultistream) = 0;
423         virtual void             payloadTableClearACT() = 0;
424         virtual bool             payloadWaitForACTReceived() = 0;
425         virtual bool             payloadAllocate(unsigned streamId, unsigned begin, unsigned count) = 0;
426         virtual bool             clearPendingMsg() = 0;
427         virtual bool             isMessagingEnabled() = 0;
428 
429         //
430         //    If set to IRQ we'll receive CSN messages on hotplugs (which are actually easy to miss).
431         //    If set to HPD mode we'll always receive an HPD whenever the topology changes.
432         //    The library supports using both modes.
433         //
434         virtual AuxRetry::status     setMultistreamHotplugMode(MultistreamHotplugMode notifyType) = 0;
435 
436         //
437         //  Interrupts
438         //
439         virtual bool             interruptContentProtection() = 0;
440         virtual void             clearInterruptContentProtection() = 0;
441 
442         virtual bool             intteruptMCCS() = 0;
443         virtual void             clearInterruptMCCS() = 0;
444 
445         virtual bool             interruptDownReplyReady() = 0;
446         virtual void             clearInterruptDownReplyReady() = 0;
447 
448         virtual bool             interruptUpRequestReady() = 0;
449         virtual void             clearInterruptUpRequestReady() = 0;
450 
451         virtual bool             interruptCapabilitiesChanged() = 0;
452         virtual void             clearInterruptCapabilitiesChanged() = 0;
453 
454         virtual bool             getLinkStatusChanged() = 0;
455         virtual void             clearLinkStatusChanged() = 0;
456 
457         virtual bool             isPanelReplayErrorSet() = 0;
458         virtual void             clearPanelReplayError() = 0;
459         virtual void             readPanelReplayError() = 0;
460 
461         virtual bool             getHdmiLinkStatusChanged() = 0;
462         virtual void             clearHdmiLinkStatusChanged() = 0;
463 
464         virtual bool             getStreamStatusChanged() = 0;
465         virtual void             clearStreamStatusChanged() =0;
466 
467         virtual void             setDirtyLinkStatus(bool dirty) = 0;
468         virtual void             refreshLinkStatus() = 0;
469         virtual bool             isLinkStatusValid(unsigned lanes) = 0;
470 
471         virtual void getCustomTestPattern(NvU8 *testPattern) = 0;                         // DPCD offset 250 - 259
472 
473         //
474         //  Message Boxes
475         //
476         virtual AuxRetry::status    writeDownRequestMessageBox(NvU8 * data, size_t length) = 0;
477         virtual size_t              getDownRequestMessageBoxSize() = 0;
478 
479         virtual AuxRetry::status    writeUpReplyMessageBox(NvU8 * data, size_t length) = 0;
480         virtual size_t              getUpReplyMessageBoxSize() = 0;
481 
482         virtual AuxRetry::status    readDownReplyMessageBox(NvU32 offset, NvU8 * data, size_t length) = 0;
483         virtual size_t              getDownReplyMessageBoxSize() = 0;
484 
485         virtual AuxRetry::status    readUpRequestMessageBox(NvU32 offset, NvU8 * data, size_t length) = 0;
486         virtual size_t              getUpRequestMessageBoxSize() = 0;
487 
488         // MST<->SST override
489         virtual void overrideMultiStreamCap(bool mstCapable) = 0;
490         virtual bool getMultiStreamCapOverride() = 0;
491 
492         virtual bool getDpcdMultiStreamCap(void) = 0;
493 
494         // Set GPU DP support capability
495         virtual void setGpuDPSupportedVersions(NvU32 gpuDPSupportedVersions) = 0;
496 
497         // Set GPU FEC support capability
498         virtual void setGpuFECSupported(bool bSupportFEC) = 0;
499 
500         virtual void applyRegkeyOverrides(const DP_REGKEY_DATABASE& dpRegkeyDatabase) = 0;
501 
502         // PCON configuration
503 
504         // Reset PCON (to default state)
505         virtual void resetProtocolConverter() = 0;
506         // Source control mode and FRL/HDMI mode selection.
507         virtual bool setSourceControlMode(bool bEnableSourceControlMode, bool bEnableFRLMode) = 0;
508 
509         virtual bool checkPCONFrlReady(bool *bFrlReady) = 0;
510         virtual bool setupPCONFrlLinkAssessment(NvU32   linkBw,
511                                                 bool    bEnableExtendLTMode     = false,
512                                                 bool    bEnableConcurrentMode   = false) = 0;
513 
514         virtual bool checkPCONFrlLinkStatus(NvU32 *frlRate) = 0;
515 
516         virtual bool queryHdmiLinkStatus(bool *bLinkActive, bool *bLinkReady) = 0;
517         virtual NvU32 restorePCONFrlLink(NvU32   linkBwMask,
518                                          bool    bEnableExtendLTMode     = false,
519                                          bool    bEnableConcurrentMode   = false) = 0;
520 
521         virtual void readPsrCapabilities(vesaPsrSinkCaps *caps) = 0;
522         virtual bool updatePsrConfiguration(vesaPsrConfig config) = 0;
523         virtual bool readPsrConfiguration(vesaPsrConfig *config) = 0;
524         virtual bool readPsrState(vesaPsrState *psrState) = 0;
525         virtual bool readPsrDebugInfo(vesaPsrDebugStatus *psrDbgState) = 0;
526         virtual bool writePsrErrorStatus(vesaPsrErrorStatus psrErr) = 0;
527         virtual bool readPsrErrorStatus(vesaPsrErrorStatus *psrErr) = 0;
528         virtual bool writePsrEvtIndicator(vesaPsrEventIndicator psrErr) = 0;
529         virtual bool readPsrEvtIndicator(vesaPsrEventIndicator *psrErr) = 0;
530         virtual bool readPrSinkDebugInfo(panelReplaySinkDebugInfo *prDbgInfo) = 0;
531 
~DPCDHAL()532         virtual ~DPCDHAL() {}
533 
534     };
535 
536     //
537     //  Implement interface
538     //
539     DPCDHAL * MakeDPCDHAL(AuxBus *  bus, Timer * timer);
540 }
541 
542 #endif //INCLUDED_DP_CONFIGCAPS_H
543