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_wardatabase.cpp                                                *
27 *         EDID and OUI based workarounds for panel/TCON issues              *
28 *                                                                           *
29 \***************************************************************************/
30 #include "dp_wardatabase.h"
31 #include "dp_edid.h"
32 #include "dp_connectorimpl.h"
33 
34 using namespace DisplayPort;
35 
36 void ConnectorImpl::applyOuiWARs()
37 {
38     switch (ouiId)
39     {
40         // Megachips Mystique
41         case 0xE18000:
42             if (((modelName[0] == 'D') && (modelName[1] == 'p') && (modelName[2] == '1') &&
43                         (modelName[3] == '.') && (modelName[4] == '1')))
44             {
45                 //
46                 // Mystique based link box for HTC Vive has a peculiar behaviour
47                 // of sending a link retraining pulse if the link is powered down in the absence
48                 // of an active stream. Bug# 1793084. Set the flag so that link is not powered down.
49                 //
50                 bKeepOptLinkAlive = true;
51             }
52 
53             if (((modelName[0] == 'D') && (modelName[1] == 'p') && (modelName[2] == '1') &&
54                         (modelName[3] == '.') && (modelName[4] == '2')))
55             {
56                 //
57                 // ASUS monitor loses link sometimes during assessing link or link training.
58                 // So if we retrain link by lowering config from HBR2 to HBR we see black screen
59                 // Set the flag so that we first retry link training with same link config
60                 // before following link training fallback. Bug #1846925
61                 //
62                 bNoFallbackInPostLQA = true;
63             }
64             break;
65 
66         // Synaptics
67         case 0x24CC90:
68             if ((modelName[0] == 'S') && (modelName[1] == 'Y') && (modelName[2] == 'N') &&
69                 (modelName[3] == 'A') && (modelName[4] == 'S') &&
70                 ((modelName[5] == '1') || (modelName[5] == '2') ||
71                  (modelName[5] == '3') || (modelName[5] == '#') ||
72                  (modelName[5] == '\"')))
73             {
74                 //
75                 // Extended latency from link-train end to FEC enable pattern
76                 // to avoid link lost or blank screen with Synaptics branch.
77                 // (Bug 2561206)
78                 //
79                 // Dock SKU ID:
80                 // Dell    Salomon-WD19TB SYNAS1
81                 // HP      Hook           SYNAS3
82                 // HP      Adira-A        SYNAS#
83                 // Lenovo                 SYNAS" / SYNAS2
84                 //
85                 LT2FecLatencyMs = 57;
86 
87                 if (bDscMstCapBug3143315)
88                 {
89                     //
90                     // Synaptics branch device doesn't support Virtual Peer Devices so DSC
91                     // capability of downstream device should be decided based on device's own
92                     // and its parent's DSC capability
93                     //
94                     bDscCapBasedOnParent = true;
95                 }
96             }
97             break;
98     }
99 }
100 
101 void Edid::applyEdidWorkArounds(NvU32 warFlag, const DpMonitorDenylistData *pDenylistData)
102 {
103 
104     unsigned ManufacturerID = this->getManufId();
105     unsigned ProductID = this->getProductId();
106     unsigned YearWeek = this->getYearWeek();
107 
108     //
109     // Work around EDID problems, using manufacturer, product ID, and date of manufacture,
110     // to identify each case.
111     //
112     switch (ManufacturerID)
113     {
114         // Apple
115         case 0x1006:
116             if (0x9227 == ProductID)
117             {
118                 this->WARFlags.powerOnBeforeLt = true;
119                 DP_LOG(("DP-WAR> WAR for Apple thunderbolt J29 panel"));
120                 DP_LOG(("DP-WAR>     - Monitor needs to be powered up before LT. Bug 933051"));
121             }
122             break;
123 
124         // Acer
125         case 0x7204:
126             // Bug 451868: Acer AL1512 monitor has a wrong extension count:
127             if(0xad15 == ProductID && YearWeek <= 0x0d01)
128             {
129                 // clear the extension count
130                 buffer.data[0x7E] = 0;
131                 this->WARFlags.extensionCountDisabled = true;
132                 this->WARFlags.dataForced = true;
133                 DP_LOG(("DP-WAR> Edid override on Acer AL1512"));
134                 DP_LOG(("DP-WAR>     - Disabling extension count.Bug 451868"));
135             }
136             break;
137 
138         // Westinghouse
139         case 0x855C:
140 
141             // Westinghouse 37" 1080p TV.  LVM-37w3  (Port DVI1 EDID).
142             // Westinghouse 42" 1080p TV.  LVM-42w2  (Port DVI1 EDID).
143             if (ProductID == 0x3703 || ProductID == 0x4202)
144             {
145                 // Claims HDMI support, but audio causes picture corruption.
146                 // Removing HDMI extension block
147 
148                 if (buffer.getLength() > 0x80 &&
149                     buffer.data[0x7E] == 1 &&             // extension block present
150                     buffer.data[0x80] == 0x02 &&          // CEA block
151                     buffer.data[0x81] == 0x03 &&          //    revision 3
152                     !(buffer.data[0x83] & 0x40))          //  No basic audio, must not be the HDMI port
153                 {
154                     // clear the extension count
155                     buffer.data[0x7E] = 0;
156                     this->WARFlags.extensionCountDisabled = true;
157                     this->WARFlags.dataForced = true;
158                     DP_LOG(("DP-WAR> Edid overrid on Westinghouse AL1512 LVM- <37/42> w <2/3>"));
159                     DP_LOG(("DP-WAR>     - Disabling extension count."));
160                 }
161             }
162             break;
163 
164         // IBM
165         case 0x4D24:
166             if(ProductID == 0x1A03)
167             {
168                 // 2001 Week 50
169                 if (YearWeek == 0x0B32)
170                 {
171                     // Override IBM T210. IBM T210 reports 2048x1536x60Hz in the edid but it's
172                     // actually 2048x1536x40Hz. See bug 76347. This hack was, earlier, in disp driver
173                     // Now it's being moved down to keep all overrides in same place.
174                     // This hack was also preventing disp driver from comparing entire edid when
175                     // trying to figure out whether or not the edid for some device has changed.
176                     buffer.data[0x36] = 0x32;
177                     buffer.data[0x37] = 0x3E;
178                     this->WARFlags.dataForced = true;
179                     DP_LOG(("DP-WAR> Edid overrid on IBM T210"));
180                     DP_LOG(("DP-WAR>    2048x1536x60Hz(misreported) -> 2048x1536x40Hz. Bug 76347"));
181                 }
182             }
183             break;
184         // GWY (Gateway) or EMA (eMachines)
185         case 0xF91E: // GWY
186         case 0xA115: // EMA
187             // Some Gateway monitors present the eMachines mfg code, so these two cases are combined.
188             // Future fixes may require the two cases to be separated.
189             // Fix for Bug 343870.  NOTE: Problem found on G80; fix applied to all GPUs.
190             if ((ProductID >= 0x0776 ) && (ProductID <= 0x0779)) // Product id's range from decimal 1910 to 1913
191             {
192                 // if detailed pixel clock frequency = 106.50MHz
193                 if ( (buffer.data[0x36] == 0x9A) &&
194                      (buffer.data[0x37] == 0x29) )
195                 {
196                     // then change detailed pixel clock frequency to 106.54MHz to fix bug 343870
197                     buffer.data[0x36] = 0x9E;
198                     buffer.data[0x37] = 0x29;
199                     this->WARFlags.dataForced = true;
200                     DP_LOG(("DP-WAR> Edid overrid on GWY/EMA"));
201                     DP_LOG(("DP-WAR>   106.50MHz(misreported) -> 106.50MHz.Bug 343870"));
202                 }
203             }
204             break;
205 
206         // INX
207         case 0x2C0C:
208             // INX L15CX monitor has an invalid detailed timing 10x311 @ 78Hz.
209             if( ProductID == 0x1502)
210             {
211                 // remove detailed timing #4: zero out the first 3 bytes of DTD#4 block
212                 buffer.data[0x6c] = 0x0;
213                 buffer.data[0x6d] = 0x0;
214                 buffer.data[0x6e] = 0x0;
215                 this->WARFlags.dataForced = true;
216                 DP_LOG(("DP-WAR> Edid overrid on INX L15CX"));
217                 DP_LOG(("DP-WAR>   Removing invalid detailed timing 10x311 @ 78Hz"));
218             }
219             break;
220 
221         // AUO
222         case 0xAF06:
223             if ((ProductID == 0x103C) || (ProductID == 0x113C))
224             {
225                 //
226                 // Acer have faulty AUO eDP panels which have
227                 // wrong HBlank in the EDID. Correcting it here.
228                 //
229                 buffer.data[0x39] = 0x4B; // new hblank width: 75
230                 buffer.data[0x3F] = 0x1B; // new hsync pulse width: 27
231                 this->WARFlags.dataForced = true;
232                 DP_LOG(("DP-WAR> Edid overrid on AUO eDP panel"));
233                 DP_LOG(("DP-WAR> Modifying HBlank and HSync pulse width."));
234                 DP_LOG(("DP-WAR> Bugs 907998, 1001160"));
235             }
236             else if (ProductID == 0x109B || ProductID == 0x119B)
237             {
238                 this->WARFlags.useLegacyAddress = true;
239                 DP_LOG(("DP-WAR> AUO eDP"));
240                 DP_LOG(("implements only Legacy interrupt address range"));
241 
242                 // Bug 1792962 - Panel got glitch on D3 write, apply this WAR.
243                 this->WARFlags.disableDpcdPowerOff = true;
244                 DP_LOG(("DP-WAR> Disable DPCD Power Off"));
245             }
246             break;
247 
248         // LPL
249         case 0x0C32:
250             if (ProductID == 0x0000)
251             {
252                 //
253                 // Patch EDID for Quanta - Toshiba LG 1440x900 panel.  See Bug 201428
254                 // Must 1st verify that we have that panel.  It has MFG id 32, 0C
255                 //    BUT product ID for this (and other different LG panels) are 0000.
256                 //    So verify that the last "Custom Timing" area of the EDID has
257                 //    a "Monitor Description" of type FE = "ASCII Data String" which
258                 //    has this panel's name = "LP171WX2-A4K5".
259                 //
260                 if ( (buffer.data[0x71] == 0x4C) &&
261                     (buffer.data[0x72] == 0x50) &&
262                     (buffer.data[0x73] == 0x31) &&
263                     (buffer.data[0x74] == 0x37) &&
264                     (buffer.data[0x75] == 0x31) &&
265                     (buffer.data[0x76] == 0x57) &&
266                     (buffer.data[0x77] == 0x58) &&
267                     (buffer.data[0x78] == 0x32) &&
268                     (buffer.data[0x79] == 0x2D) &&
269                     (buffer.data[0x7A] == 0x41) &&
270                     (buffer.data[0x7B] == 0x34) &&
271                     (buffer.data[0x7C] == 0x4B) &&
272                     (buffer.data[0x7D] == 0x35) )
273                 {
274                     //
275                     // Was 0x95, 0x25 = -> 0x2595 = 9621 or 96.21 Mhz.
276                     //     96,210,000 / 1760 / 912 = 59.939 Hz
277                     // Want 60 * 1760 * 912 ~= 9631 or 96.31 MHz
278                     //     9631 = 0x259F -> 0x9F 0x25.
279                     // So, change byte 36 from 0x95 to 0x9F.
280                     //
281                     buffer.data[0x36] = 0x9F;
282                     this->WARFlags.dataForced = true;
283                     DP_LOG(("DP-WAR> Edid overrid on Quanta - Toshiba LG 1440x900"));
284                     DP_LOG(("DP-WAR>   Correcting pclk. Bug 201428"));
285                 }
286             }
287             else
288             if (ProductID == 0xE300)
289             {
290                 //
291                 // Patch EDID for MSI - LG LPL 1280x800 panel.  See Bug 359313
292                 // Must 1st verify that we have that panel.  It has MFG id 32, 0C
293                 //    BUT product ID for this (and other different LG panels) are E300.
294                 //    So verify that the last "Custom Timing" area of the EDID has
295                 //    a "Monitor Description" of type FE = "ASCII Data String" which
296                 //    has this panel's name = "LP154WX4-TLC3".
297                 //
298                 if ( (buffer.data[0x71] == 0x4C) &&
299                     (buffer.data[0x72] == 0x50) &&
300                     (buffer.data[0x73] == 0x31) &&
301                     (buffer.data[0x74] == 0x35) &&
302                     (buffer.data[0x75] == 0x34) &&
303                     (buffer.data[0x76] == 0x57) &&
304                     (buffer.data[0x77] == 0x58) &&
305                     (buffer.data[0x78] == 0x34) &&
306                     (buffer.data[0x79] == 0x2D) &&
307                     (buffer.data[0x7A] == 0x54) &&
308                     (buffer.data[0x7B] == 0x4C) &&
309                     (buffer.data[0x7C] == 0x43) &&
310                     (buffer.data[0x7D] == 0x33) )
311                 {
312                     //
313                     // Was 0xBC, 0x1B = -> 0x1BBC = 7100 or 71.00 Mhz.
314                     //     71,000,000 / 1488 / 826 = 59.939 Hz
315                     // Want 60 * 1488 * 826 ~= 7111 or 71.11 MHz
316                     //     7111 = 0x1BC7 -> 0xC7 0x1B.
317                     // So, change byte 36 from 0xBC to 0xC7.
318                     //
319                     buffer.data[0x36] = 0xC7;
320                     this->WARFlags.dataForced = true;
321                     DP_LOG(("DP-WAR> Edid overrid on  MSI - LG LPL 1280x800"));
322                     DP_LOG(("DP-WAR>   Correcting pclk. Bug 359313"));
323                 }
324             }
325             break;
326 
327        // SKY
328        case 0x794D:
329             if (ProductID == 0x9880)
330             {
331                 //
332                 // Override for Haier TV to remove resolution
333                 // 1366x768 from EDID data. Refer bug 351680 & 327891
334                 // Overriding 18 bytes from offset 0x36.
335                 //
336                 buffer.data[0x36] = 0x01;
337                 buffer.data[0x37] = 0x1D;
338                 buffer.data[0x38] = 0x00;
339                 buffer.data[0x39] = 0x72;
340                 buffer.data[0x3A] = 0x51;
341                 buffer.data[0x3B] = 0xD0;
342                 buffer.data[0x3C] = 0x1E;
343                 buffer.data[0x3D] = 0x20;
344                 buffer.data[0x3E] = 0x6E;
345                 buffer.data[0x3F] = 0x28;
346                 buffer.data[0x40] = 0x55;
347                 buffer.data[0x41] = 0x00;
348                 buffer.data[0x42] = 0xC4;
349                 buffer.data[0x43] = 0x8E;
350                 buffer.data[0x44] = 0x21;
351                 buffer.data[0x45] = 0x00;
352                 buffer.data[0x46] = 0x00;
353                 buffer.data[0x47] = 0x1E;
354 
355                 this->WARFlags.dataForced = true;
356                 DP_LOG(("DP-WAR> Edid overrid on  Haier TV."));
357                 DP_LOG(("DP-WAR>   Removing 1366x768. bug 351680 & 327891"));
358 
359             }
360             break;
361         // HP
362         case 0xF022:
363             switch (ProductID)
364             {
365                 case 0x192F:
366                     //
367                     // WAR for bug 1643712 - Issue specific to HP Z1 G2 (Zeus) All-In-One
368                     // Putting the Rx in power save mode before BL_EN is deasserted, makes this specific sink unhappy
369                     // Bug 1559465 will address the right power down sequence. We need to revisit this WAR once Bug 1559465 is fixed.
370                     //
371                     this->WARFlags.disableDpcdPowerOff = true;
372                     DP_LOG(("DP-WAR> Disable DPCD Power Off"));
373                     DP_LOG(("DP-WAR> HP Z1 G2 (Zeus) AIO Bug 1643712"));
374                     break;
375             }
376             break;
377 
378         // Sharp
379         case 0x104d:
380             switch (ProductID)
381             {
382                 case 0x141c: // HP Valor QHD+ N15P-Q3 Sharp EDP
383                     //
384                     // HP Valor QHD+ N15P-Q3 EDP needs 50 ms delay
385                     // after D3 to avoid black screen issues.
386                     //
387                     this->WARFlags.delayAfterD3 = true;
388                     DP_LOG(("DP-WAR> HP Valor QHD+ N15P-Q3 Sharp EDP needs 50 ms after D3"));
389                     DP_LOG(("DP-WAR> bug 1520011"));
390                     break;
391 
392                 //Sharp EDPs that declares DP1.2 but doesn't implement ESI address space
393                 case 0x1414:
394                 case 0x1430:
395                 case 0x1445:
396                 case 0x1446:
397                 case 0x144C:
398                 case 0x1450:
399                 case 0x1467:
400                 case 0x145e:
401                     //
402                     // Use Legacy address space for DP1.2 panel
403                     //
404                     this->WARFlags.useLegacyAddress = true;
405                     DP_LOG(("DP-WAR> Sharp EDP implements only Legacy interrupt address range"));
406                     break;
407 
408                 case 0x143B:
409                     //
410                     // Bug 200113041
411                     // Need to be unique to identify this Sharp panel. Besides
412                     // manufacturer ID and ProductID, we have to add the mode
413                     // name to make this happen as LQ156D1JW05 in ASCII.
414                     //
415                     if ((buffer.data[0x71] == 0x4C) &&
416                         (buffer.data[0x72] == 0x51) &&
417                         (buffer.data[0x73] == 0x31) &&
418                         (buffer.data[0x74] == 0x35) &&
419                         (buffer.data[0x75] == 0x36) &&
420                         (buffer.data[0x76] == 0x44) &&
421                         (buffer.data[0x77] == 0x31) &&
422                         (buffer.data[0x78] == 0x4A) &&
423                         (buffer.data[0x79] == 0x57) &&
424                         (buffer.data[0x7A] == 0x30) &&
425                         (buffer.data[0x7B] == 0x35) &&
426                         (buffer.data[0x7C] == 0x0A) &&
427                         (buffer.data[0x7D] == 0x20))
428                     {
429                         this->WARFlags.useLegacyAddress = true;
430                         DP_LOG(("DP-WAR> Sharp EDP implements only Legacy interrupt address range"));
431                     }
432                     break;
433             }
434             break;
435 
436         // EIZO
437         case 0xc315:
438             if (ProductID == 0x2227)
439             {
440                 //
441                 // The EIZO FlexScan SX2762W generates a redundant long HPD
442                 // pulse after a modeset, which triggers another modeset on GPUs
443                 // without flush mode, triggering an infinite link training
444                 // loop.
445                 //
446                 this->WARFlags.ignoreRedundantHotplug = true;
447                 DP_LOG(("DP-WAR> EIZO FlexScan SX2762W generates redundant"));
448                 DP_LOG(("DP-WAR> hotplugs (bug 1048796)"));
449                 break;
450             }
451             break;
452 
453         // MEI-Panasonic
454         case 0xa934:
455             if (ProductID == 0x96a2)
456             {
457                 //
458                 // Bug 200113041
459                 // Need to be unique to identify this MEI-Panasonic panel.
460                 // Besides manufacturer ID and ProductID, we have to add the
461                 // model name to make this happen as VVX17P051J00^ in ASCII.
462                 //
463                 if ((buffer.data[0x71] == 0x56) &&
464                     (buffer.data[0x72] == 0x56) &&
465                     (buffer.data[0x73] == 0x58) &&
466                     (buffer.data[0x74] == 0x31) &&
467                     (buffer.data[0x75] == 0x37) &&
468                     (buffer.data[0x76] == 0x50) &&
469                     (buffer.data[0x77] == 0x30) &&
470                     (buffer.data[0x78] == 0x35) &&
471                     (buffer.data[0x79] == 0x31) &&
472                     (buffer.data[0x7A] == 0x4A) &&
473                     (buffer.data[0x7B] == 0x30) &&
474                     (buffer.data[0x7C] == 0x30) &&
475                     (buffer.data[0x7D] == 0x0A))
476                 {
477                     this->WARFlags.useLegacyAddress = true;
478                     DP_LOG(("DP-WAR> MEI-Panasonic EDP"));
479                     DP_LOG(("implements only Legacy interrupt address range"));
480                 }
481             }
482             break;
483 
484         // LG
485         case 0xE430:
486             if (ProductID == 0x0469)
487             {
488                 //
489                 // The LG display can't be driven at FHD with 2*RBR.
490                 // Force max link config
491                 //
492                 this->WARFlags.forceMaxLinkConfig = true;
493                 DP_LOG(("DP-WAR> Force maximum link config WAR required on LG panel."));
494                 DP_LOG(("DP-WAR>   bug 1649626"));
495                 break;
496             }
497             break;
498         case 0x8F34:
499             if (ProductID == 0xAA55)
500             {
501                 this->WARFlags.forceMaxLinkConfig = true;
502                 DP_LOG(("DP-WAR> Force maximum link config WAR required on Sharp-CerebrEx panel."));
503             }
504             break;
505 
506         // Dell
507         case 0xAC10:
508             // Dell U2713H has problem with LQA. Disable it.
509             if ((ProductID == 0xA092) || (ProductID == 0xF046))
510             {
511                 this->WARFlags.reassessMaxLink = true;
512             }
513             break;
514 
515         // CMN
516         case 0xAE0D:
517             if (ProductID == 0x1747)
518             {
519                 this->WARFlags.useLegacyAddress = true;
520                 DP_LOG(("DP-WAR> CMN eDP"));
521                 DP_LOG(("implements only Legacy interrupt address range"));
522             }
523             break;
524 
525         // BenQ
526         case 0xD109:
527             if ((ProductID == 0x7F2B) || (ProductID == 0x7F2F))
528             {
529                 this->WARFlags.ignoreRedundantHotplug = true;
530                 DP_LOG(("DP-WAR> BenQ GSync power on/off redundant hotplug"));
531             }
532             break;
533 
534         // MSI
535         case 0x834C:
536             if (ProductID == 0x4C48)
537             {
538                 this->WARFlags.useLegacyAddress = true;
539                 DP_LOG(("DP-WAR> MSI eDP\n"));
540                 DP_LOG(("implements only Legacy interrupt address range\n"));
541             }
542             break;
543 
544         // Unigraf
545         case 0xC754:
546         case 0x1863:
547             {
548                 DP_LOG(("DP-WAR> Unigraf device, keep link alive during detection\n"));
549                 this->WARFlags.keepLinkAlive = true;
550             }
551             break;
552 
553         // BOE
554         case 0xE509:
555             if ((ProductID == 0x977) || (ProductID == 0x974) || (ProductID == 0x9D9))
556             {
557                 this->WARFlags.bIgnoreDscCap = true;
558                 DP_LOG(("DP-WAR> BOE panels incorrectly exposing DSC capability. Ignoring it."));
559             }
560             break;
561 
562         // NCP
563         case 0x7038:
564             if ((ProductID == 0x005F))
565             {
566                 this->WARFlags.bIgnoreDscCap = true;
567                 DP_LOG(("DP-WAR> NCP panels incorrectly exposing DSC capability. Ignoring it."));
568             }
569             break;
570 
571         //
572         // This panel advertise DSC capabilities, but panel doesn't support DSC
573         // So ignoring DSC capability on this panel
574         //
575         case 0x6F0E:
576             if (ProductID == 0x1609)
577             {
578                 this->WARFlags.bIgnoreDscCap = true;
579                 DP_LOG(("DP-WAR> Ignoring DSC capability on Lenovo CSOT 1609 Panel."));
580                 DP_LOG(("DP-WAR> Bug 3444252"));
581             }
582             break;
583 
584         // Asus
585         case 0x6D1E:
586             if(ProductID == 0x7707)
587             {
588                 this->WARFlags.bIgnoreDscCap = true;
589                 DP_LOG(("DP-WAR> Panel incorrectly exposing DSC capability. Ignoring it."));
590                 DP_LOG(("DP-WAR> Bug 3543158"));
591             }
592             break;
593 
594         default:
595             break;
596     }
597 
598     // Find out if the monitor needs a WAR to applied.
599     if (warFlag)
600     {
601         if (warFlag & DP_MONITOR_CAPABILITY_DP_SKIP_REDUNDANT_LT)
602         {
603             this->WARFlags.skipRedundantLt = true;
604         }
605 
606         if (warFlag & DP_MONITOR_CAPABILITY_DP_SKIP_CABLE_BW_CHECK)
607         {
608             this->WARFlags.skipCableBWCheck = true;
609             this->WARData.maxLaneAtHighRate = pDenylistData->dpSkipCheckLink.maxLaneAtHighRate;
610             this->WARData.maxLaneAtLowRate = pDenylistData->dpSkipCheckLink.maxLaneAtLowRate;
611         }
612 
613         if (warFlag & DP_MONITOR_CAPABILITY_DP_WRITE_0x600_BEFORE_LT)
614         {
615             // all HP monitors need to be powered up before link training
616             this->WARFlags.powerOnBeforeLt = true;
617             DP_LOG(("DP-WAR> HP monitors need to be powered up before LT"));
618         }
619 
620         if (warFlag & DP_MONITOR_CAPABILITY_DP_OVERRIDE_OPTIMAL_LINK_CONFIG)
621         {
622             //
623             // Instead of calculating the optimum link config
624             // based on timing, bpc etc. just used a default
625             // fixed link config for the monitor for all modes
626             //
627             this->WARFlags.overrideOptimalLinkCfg = true;
628             // Force the fix max LT
629             this->WARFlags.forceMaxLinkConfig = true;
630             this->WARData.optimalLinkRate = pDenylistData->dpOverrideOptimalLinkConfig.linkRate;
631             this->WARData.optimalLaneCount = pDenylistData->dpOverrideOptimalLinkConfig.laneCount;
632             DP_LOG(("DP-WAR> Overriding optimal link config on Dell U2410."));
633             DP_LOG(("DP-WAR>   bug 632801"));
634         }
635 
636         if (warFlag & DP_MONITOR_CAPABILITY_DP_OVERRIDE_MAX_LANE_COUNT)
637         {
638             //
639             // Some monitors claim more lanes than they actually support.
640             // This particular Lenovo monitos has just 2 lanes, but its DPCD says 4.
641             // This WAR is to override the max lane count read from DPCD.
642             //
643             this->WARFlags.overrideMaxLaneCount = true;
644             this->WARData.maxLaneCount = pDenylistData->dpMaxLaneCountOverride;
645             DP_LOG(("DP-WAR> Overriding max lane count on Lenovo L2440x."));
646             DP_LOG(("DP-WAR>   bug 687952"));
647         }
648     }
649 
650     if (this->WARFlags.dataForced)
651     {
652         DP_LOG(("DP-WAR> EDID was overridden for some data. Patching CRC."));
653         this->patchCrc();
654     }
655 }
656