Files
open-gpu-kernel-modules/src/common/displayport/src/dp_wardatabase.cpp
russellcnv e2dbb3d99c 580.94.06
2025-10-27 13:41:40 -07:00

763 lines
32 KiB
C++

/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/******************************* DisplayPort *******************************\
* *
* Module: dp_wardatabase.cpp *
* EDID and OUI based workarounds for panel/TCON issues *
* *
\***************************************************************************/
#include "dp_wardatabase.h"
#include "dp_edid.h"
#include "dp_connectorimpl.h"
#include "dp_connectorimpl2x.h"
#include "dp_printf.h"
using namespace DisplayPort;
void ConnectorImpl::applyOuiWARs()
{
switch (ouiId)
{
// Megachips Mystique
case 0xE18000:
if (((modelName[0] == 'D') && (modelName[1] == 'p') && (modelName[2] == '1') &&
(modelName[3] == '.') && (modelName[4] == '1')))
{
//
// Mystique based link box for HTC Vive has a peculiar behaviour
// of sending a link retraining pulse if the link is powered down in the absence
// of an active stream. Bug# 1793084. Set the flag so that link is not powered down.
//
bKeepOptLinkAlive = true;
}
if (((modelName[0] == 'D') && (modelName[1] == 'p') && (modelName[2] == '1') &&
(modelName[3] == '.') && (modelName[4] == '2')))
{
//
// ASUS monitor loses link sometimes during assessing link or link training.
// So if we retrain link by lowering config from HBR2 to HBR we see black screen
// Set the flag so that we first retry link training with same link config
// before following link training fallback. Bug #1846925
//
bNoFallbackInPostLQA = true;
}
break;
// Synaptics
case 0x24CC90:
if ((modelName[0] == 'S') && (modelName[1] == 'Y') && (modelName[2] == 'N') &&
(modelName[3] == 'A') && (((modelName[4] == 'S') &&
((modelName[5] == '1') || (modelName[5] == '2') ||
(modelName[5] == '3') || (modelName[5] == '#') ||
(modelName[5] == '\"')))||((modelName[4] == 0x84) &&
(modelName[5] == '0'))))
{
//
// Extended latency from link-train end to FEC enable pattern
// to avoid link lost or blank screen with Synaptics branch.
//
LT2FecLatencyMs = 57;
if (bDscMstCapBug3143315)
{
//
// Synaptics branch device doesn't support Virtual Peer Devices so DSC
// capability of downstream device should be decided based on device's own
// and its parent's DSC capability
//
bDscCapBasedOnParent = true;
}
}
break;
}
}
void ConnectorImpl2x::applyOuiWARs()
{
switch (ouiId)
{
// Novatek Microelectronics Corp.
case 0x11EC38:
if((modelName[0] == 'N') && (modelName[1] == 'T') && (modelName[2] == '6'))
{
NvU8 portType;
if (hal->getSupportsMultistream() &&
hal->isDp2xChannelCodingCapable() &&
!hal->getDownstreamPort(&portType))
{
bMstTimeslotBug4968411 = true;
hal->setMainLinkChannelCoding(ChannelCoding128B132B);
}
}
break;
case 0xAD6000:
if ((modelName[0] == 'M') &&
(modelName[1] == 'C') &&
(modelName[2] == '2') &&
(modelName[3] == '9') &&
(modelName[4] == '0'))
{
bForceHeadShutdownPerMonitor = true;
bApplyStuffDummySymbolsWAR = true;
bStuffDummySymbolsFor128b132b = false;
bStuffDummySymbolsFor8b10b = true;
}
break;
}
}
void Edid::applyEdidWorkArounds(NvU32 warFlag, const DpMonitorDenylistData *pDenylistData)
{
unsigned ManufacturerID = this->getManufId();
unsigned ProductID = this->getProductId();
unsigned YearWeek = this->getYearWeek();
//
// Work around EDID problems, using manufacturer, product ID, and date of manufacture,
// to identify each case.
//
switch (ManufacturerID)
{
// Apple
case 0x1006:
if (0x9227 == ProductID)
{
this->WARFlags.powerOnBeforeLt = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> WAR for Apple thunderbolt J29 panel");
DP_PRINTF(DP_NOTICE, "DP-WAR> - Monitor needs to be powered up before LT. Bug 933051");
}
break;
// Acer
case 0x7204:
// Bug 451868: Acer AL1512 monitor has a wrong extension count:
if(0xad15 == ProductID && YearWeek <= 0x0d01)
{
// clear the extension count
buffer.data[0x7E] = 0;
this->WARFlags.extensionCountDisabled = true;
this->WARFlags.dataForced = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> Edid override on Acer AL1512");
DP_PRINTF(DP_NOTICE, "DP-WAR> - Disabling extension count.Bug 451868");
}
break;
// Westinghouse
case 0x855C:
// Westinghouse 37" 1080p TV. LVM-37w3 (Port DVI1 EDID).
// Westinghouse 42" 1080p TV. LVM-42w2 (Port DVI1 EDID).
if (ProductID == 0x3703 || ProductID == 0x4202)
{
// Claims HDMI support, but audio causes picture corruption.
// Removing HDMI extension block
if (buffer.getLength() > 0x80 &&
buffer.data[0x7E] == 1 && // extension block present
buffer.data[0x80] == 0x02 && // CEA block
buffer.data[0x81] == 0x03 && // revision 3
!(buffer.data[0x83] & 0x40)) // No basic audio, must not be the HDMI port
{
// clear the extension count
buffer.data[0x7E] = 0;
this->WARFlags.extensionCountDisabled = true;
this->WARFlags.dataForced = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> Edid overrid on Westinghouse AL1512 LVM- <37/42> w <2/3>");
DP_PRINTF(DP_NOTICE, "DP-WAR> - Disabling extension count.");
}
}
break;
// IBM
case 0x4D24:
if(ProductID == 0x1A03)
{
// 2001 Week 50
if (YearWeek == 0x0B32)
{
// Override IBM T210. IBM T210 reports 2048x1536x60Hz in the edid but it's
// actually 2048x1536x40Hz. See bug 76347. This hack was, earlier, in disp driver
// Now it's being moved down to keep all overrides in same place.
// This hack was also preventing disp driver from comparing entire edid when
// trying to figure out whether or not the edid for some device has changed.
buffer.data[0x36] = 0x32;
buffer.data[0x37] = 0x3E;
this->WARFlags.dataForced = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> Edid overrid on IBM T210");
DP_PRINTF(DP_NOTICE, "DP-WAR> 2048x1536x60Hz(misreported) -> 2048x1536x40Hz. Bug 76347");
}
}
break;
// GWY (Gateway) or EMA (eMachines)
case 0xF91E: // GWY
case 0xA115: // EMA
// Some Gateway monitors present the eMachines mfg code, so these two cases are combined.
// Future fixes may require the two cases to be separated.
// Fix for Bug 343870. NOTE: Problem found on G80; fix applied to all GPUs.
if ((ProductID >= 0x0776 ) && (ProductID <= 0x0779)) // Product id's range from decimal 1910 to 1913
{
// if detailed pixel clock frequency = 106.50MHz
if ((buffer.data[0x36] == 0x9A) &&
(buffer.data[0x37] == 0x29) )
{
// then change detailed pixel clock frequency to 106.54MHz to fix bug 343870
buffer.data[0x36] = 0x9E;
buffer.data[0x37] = 0x29;
this->WARFlags.dataForced = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> Edid overrid on GWY/EMA");
DP_PRINTF(DP_NOTICE, "DP-WAR> 106.50MHz(misreported) -> 106.50MHz.Bug 343870");
}
}
break;
// INX
case 0x2C0C:
// INX L15CX monitor has an invalid detailed timing 10x311 @ 78Hz.
if( ProductID == 0x1502)
{
// remove detailed timing #4: zero out the first 3 bytes of DTD#4 block
buffer.data[0x6c] = 0x0;
buffer.data[0x6d] = 0x0;
buffer.data[0x6e] = 0x0;
this->WARFlags.dataForced = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> Edid overrid on INX L15CX");
DP_PRINTF(DP_NOTICE, "DP-WAR> Removing invalid detailed timing 10x311 @ 78Hz");
}
break;
// AUO
case 0xAF06:
if ((ProductID == 0x103C) || (ProductID == 0x113C))
{
//
// Acer have faulty AUO eDP panels which have
// wrong HBlank in the EDID. Correcting it here.
//
buffer.data[0x39] = 0x4B; // new hblank width: 75
buffer.data[0x3F] = 0x1B; // new hsync pulse width: 27
this->WARFlags.dataForced = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> Edid overrid on AUO eDP panel");
DP_PRINTF(DP_NOTICE, "DP-WAR> Modifying HBlank and HSync pulse width.");
DP_PRINTF(DP_NOTICE, "DP-WAR> Bugs 907998, 1001160");
}
else if (ProductID == 0x109B || ProductID == 0x119B)
{
this->WARFlags.useLegacyAddress = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> AUO eDP");
DP_PRINTF(DP_NOTICE, "implements only Legacy interrupt address range");
// Bug 1792962 - Panel got glitch on D3 write, apply this WAR.
this->WARFlags.disableDpcdPowerOff = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> Disable DPCD Power Off");
}
break;
// LPL
case 0x0C32:
if (ProductID == 0x0000)
{
//
// Patch EDID for Quanta - Toshiba LG 1440x900 panel. See Bug 201428
// Must 1st verify that we have that panel. It has MFG id 32, 0C
// BUT product ID for this (and other different LG panels) are 0000.
// So verify that the last "Custom Timing" area of the EDID has
// a "Monitor Description" of type FE = "ASCII Data String" which
// has this panel's name = "LP171WX2-A4K5".
//
if ((buffer.data[0x71] == 0x4C) &&
(buffer.data[0x72] == 0x50) &&
(buffer.data[0x73] == 0x31) &&
(buffer.data[0x74] == 0x37) &&
(buffer.data[0x75] == 0x31) &&
(buffer.data[0x76] == 0x57) &&
(buffer.data[0x77] == 0x58) &&
(buffer.data[0x78] == 0x32) &&
(buffer.data[0x79] == 0x2D) &&
(buffer.data[0x7A] == 0x41) &&
(buffer.data[0x7B] == 0x34) &&
(buffer.data[0x7C] == 0x4B) &&
(buffer.data[0x7D] == 0x35) )
{
//
// Was 0x95, 0x25 = -> 0x2595 = 9621 or 96.21 Mhz.
// 96,210,000 / 1760 / 912 = 59.939 Hz
// Want 60 * 1760 * 912 ~= 9631 or 96.31 MHz
// 9631 = 0x259F -> 0x9F 0x25.
// So, change byte 36 from 0x95 to 0x9F.
//
buffer.data[0x36] = 0x9F;
this->WARFlags.dataForced = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> Edid overrid on Quanta - Toshiba LG 1440x900");
DP_PRINTF(DP_NOTICE, "DP-WAR> Correcting pclk. Bug 201428");
}
}
else
if (ProductID == 0xE300)
{
//
// Patch EDID for MSI - LG LPL 1280x800 panel. See Bug 359313
// Must 1st verify that we have that panel. It has MFG id 32, 0C
// BUT product ID for this (and other different LG panels) are E300.
// So verify that the last "Custom Timing" area of the EDID has
// a "Monitor Description" of type FE = "ASCII Data String" which
// has this panel's name = "LP154WX4-TLC3".
//
if ((buffer.data[0x71] == 0x4C) &&
(buffer.data[0x72] == 0x50) &&
(buffer.data[0x73] == 0x31) &&
(buffer.data[0x74] == 0x35) &&
(buffer.data[0x75] == 0x34) &&
(buffer.data[0x76] == 0x57) &&
(buffer.data[0x77] == 0x58) &&
(buffer.data[0x78] == 0x34) &&
(buffer.data[0x79] == 0x2D) &&
(buffer.data[0x7A] == 0x54) &&
(buffer.data[0x7B] == 0x4C) &&
(buffer.data[0x7C] == 0x43) &&
(buffer.data[0x7D] == 0x33) )
{
//
// Was 0xBC, 0x1B = -> 0x1BBC = 7100 or 71.00 Mhz.
// 71,000,000 / 1488 / 826 = 59.939 Hz
// Want 60 * 1488 * 826 ~= 7111 or 71.11 MHz
// 7111 = 0x1BC7 -> 0xC7 0x1B.
// So, change byte 36 from 0xBC to 0xC7.
//
buffer.data[0x36] = 0xC7;
this->WARFlags.dataForced = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> Edid overrid on MSI - LG LPL 1280x800");
DP_PRINTF(DP_NOTICE, "DP-WAR> Correcting pclk. Bug 359313");
}
}
break;
// SKY
case 0x794D:
if (ProductID == 0x9880)
{
//
// Override for Haier TV to remove resolution
// 1366x768 from EDID data. Refer bug 351680 & 327891
// Overriding 18 bytes from offset 0x36.
//
buffer.data[0x36] = 0x01;
buffer.data[0x37] = 0x1D;
buffer.data[0x38] = 0x00;
buffer.data[0x39] = 0x72;
buffer.data[0x3A] = 0x51;
buffer.data[0x3B] = 0xD0;
buffer.data[0x3C] = 0x1E;
buffer.data[0x3D] = 0x20;
buffer.data[0x3E] = 0x6E;
buffer.data[0x3F] = 0x28;
buffer.data[0x40] = 0x55;
buffer.data[0x41] = 0x00;
buffer.data[0x42] = 0xC4;
buffer.data[0x43] = 0x8E;
buffer.data[0x44] = 0x21;
buffer.data[0x45] = 0x00;
buffer.data[0x46] = 0x00;
buffer.data[0x47] = 0x1E;
this->WARFlags.dataForced = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> Edid overrid on Haier TV.");
DP_PRINTF(DP_NOTICE, "DP-WAR> Removing 1366x768. bug 351680 & 327891");
}
break;
// HP
case 0xF022:
switch (ProductID)
{
case 0x192F:
//
// WAR for bug 1643712 - Issue specific to HP Z1 G2 (Zeus) All-In-One
// Putting the Rx in power save mode before BL_EN is deasserted, makes this specific sink unhappy
// Bug 1559465 will address the right power down sequence. We need to revisit this WAR once Bug 1559465 is fixed.
//
this->WARFlags.disableDpcdPowerOff = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> Disable DPCD Power Off");
DP_PRINTF(DP_NOTICE, "DP-WAR> HP Z1 G2 (Zeus) AIO Bug 1643712");
break;
}
break;
// Sharp
case 0x104d:
switch (ProductID)
{
case 0x141c: // HP Valor QHD+ N15P-Q3 Sharp EDP
//
// HP Valor QHD+ N15P-Q3 EDP needs 50 ms delay
// after D3 to avoid black screen issues.
//
this->WARFlags.delayAfterD3 = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> HP Valor QHD+ N15P-Q3 Sharp EDP needs 50 ms after D3");
DP_PRINTF(DP_NOTICE, "DP-WAR> bug 1520011");
break;
//Sharp EDPs that declares DP1.2 but doesn't implement ESI address space
case 0x1414:
case 0x1430:
case 0x1445:
case 0x1446:
case 0x144C:
case 0x1450:
case 0x1467:
case 0x145e:
//
// Use Legacy address space for DP1.2 panel
//
this->WARFlags.useLegacyAddress = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> Sharp EDP implements only Legacy interrupt address range");
break;
case 0x143B:
//
// Bug 200113041
// Need to be unique to identify this Sharp panel. Besides
// manufacturer ID and ProductID, we have to add the mode
// name to make this happen as LQ156D1JW05 in ASCII.
//
if ((buffer.data[0x71] == 0x4C) &&
(buffer.data[0x72] == 0x51) &&
(buffer.data[0x73] == 0x31) &&
(buffer.data[0x74] == 0x35) &&
(buffer.data[0x75] == 0x36) &&
(buffer.data[0x76] == 0x44) &&
(buffer.data[0x77] == 0x31) &&
(buffer.data[0x78] == 0x4A) &&
(buffer.data[0x79] == 0x57) &&
(buffer.data[0x7A] == 0x30) &&
(buffer.data[0x7B] == 0x35) &&
(buffer.data[0x7C] == 0x0A) &&
(buffer.data[0x7D] == 0x20))
{
this->WARFlags.useLegacyAddress = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> Sharp EDP implements only Legacy interrupt address range");
}
break;
}
break;
// EIZO
case 0xc315:
if (ProductID == 0x2227)
{
//
// The EIZO FlexScan SX2762W generates a redundant long HPD
// pulse after a modeset, which triggers another modeset on GPUs
// without flush mode, triggering an infinite link training
// loop.
//
this->WARFlags.ignoreRedundantHotplug = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> EIZO FlexScan SX2762W generates redundant");
DP_PRINTF(DP_NOTICE, "DP-WAR> hotplugs (bug 1048796)");
break;
}
break;
// MEI-Panasonic
case 0xa934:
if (ProductID == 0x96a2)
{
//
// Bug 200113041
// Need to be unique to identify this MEI-Panasonic panel.
// Besides manufacturer ID and ProductID, we have to add the
// model name to make this happen as VVX17P051J00^ in ASCII.
//
if ((buffer.data[0x71] == 0x56) &&
(buffer.data[0x72] == 0x56) &&
(buffer.data[0x73] == 0x58) &&
(buffer.data[0x74] == 0x31) &&
(buffer.data[0x75] == 0x37) &&
(buffer.data[0x76] == 0x50) &&
(buffer.data[0x77] == 0x30) &&
(buffer.data[0x78] == 0x35) &&
(buffer.data[0x79] == 0x31) &&
(buffer.data[0x7A] == 0x4A) &&
(buffer.data[0x7B] == 0x30) &&
(buffer.data[0x7C] == 0x30) &&
(buffer.data[0x7D] == 0x0A))
{
this->WARFlags.useLegacyAddress = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> MEI-Panasonic EDP");
DP_PRINTF(DP_NOTICE, "implements only Legacy interrupt address range");
}
}
break;
// LG
case 0xE430:
switch (ProductID)
{
case 0x0469:
{
//
// The LG display can't be driven at FHD with 2*RBR.
// Force max link config
//
this->WARFlags.forceMaxLinkConfig = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> Force maximum link config WAR required on LG panel.");
DP_PRINTF(DP_NOTICE, "DP-WAR> bug 1649626");
break;
}
case 0x06DB:
{
this->WARFlags.useLegacyAddress = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> LG eDP implements only Legacy interrupt address range");
break;
}
}
break;
case 0x8F34:
if (ProductID == 0xAA55)
{
this->WARFlags.forceMaxLinkConfig = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> Force maximum link config WAR required on Sharp-CerebrEx panel.");
}
break;
// CMN
case 0xAE0D:
if (ProductID == 0x1747)
{
this->WARFlags.useLegacyAddress = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> CMN eDP");
DP_PRINTF(DP_NOTICE, "implements only Legacy interrupt address range");
}
break;
// BenQ
case 0xD109:
if ((ProductID == 0x7F2B) || (ProductID == 0x7F2F))
{
this->WARFlags.ignoreRedundantHotplug = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> BenQ GSync power on/off redundant hotplug");
}
break;
// MSI
case 0x834C:
if (ProductID == 0x4C48)
{
this->WARFlags.useLegacyAddress = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> MSI eDP\n");
DP_PRINTF(DP_NOTICE, "implements only Legacy interrupt address range\n");
}
break;
// Unigraf
case 0xC754:
case 0x1863:
{
DP_PRINTF(DP_NOTICE, "DP-WAR> Unigraf device, keep link alive during detection\n");
this->WARFlags.keepLinkAlive = true;
}
break;
// BOE
case 0xE509:
if ((ProductID == 0x977) || (ProductID == 0x974) || (ProductID == 0x9D9))
{
this->WARFlags.bIgnoreDscCap = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> BOE panels incorrectly exposing DSC capability. Ignoring it.");
}
break;
// NCP
case 0x7038:
if (ProductID == 0x005F)
{
this->WARFlags.bIgnoreDscCap = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> NCP panels incorrectly exposing DSC capability. Ignoring it.");
}
break;
//
// This panel advertise DSC capabilities, but panel doesn't support DSC
// So ignoring DSC capability on this panel
//
case 0x6F0E:
if (ProductID == 0x1609)
{
this->WARFlags.bIgnoreDscCap = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> Ignoring DSC capability on Lenovo CSOT 1609 Panel.");
DP_PRINTF(DP_NOTICE, "DP-WAR> Bug 3444252");
}
break;
// Asus
case 0x6D1E:
if (ProductID == 0x7707)
{
this->WARFlags.bIgnoreDscCap = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> Panel incorrectly exposing DSC capability. Ignoring it.");
DP_PRINTF(DP_NOTICE, "DP-WAR> Bug 3543158");
}
else if (ProductID == 0x5B9A)
{
this->WARFlags.bDisableDscMaxBppLimit = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> Disable DSC max BPP limit of 16 for DSC.");
}
else if (ProductID == 0x5CA7 || ProductID == 0x9E9D || ProductID == 0x9EA0 || ProductID == 0x9EA5 || ProductID == 0x5CB7 ||
ProductID == 0x9EA8 || ProductID == 0x9EAF || ProductID == 0x7846 || ProductID == 0x7849 || ProductID == 0x5CB5 ||
ProductID == 0x77E0 || ProductID == 0x9EB9)
{
this->WARFlags.bForceHeadShutdownOnModeTransition = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> Force head shutdown on Mode transition.");
}
break;
case 0xB306:
if (ProductID == 0x3228)
{
// ASUS PG32UQXR does not set DPCD 0x2217 to reflect correct CableID.
this->WARFlags.bSkipCableIdCheck = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> Panel does not expose cable capability. Ignoring it. Bug 4968411");
}
else if(ProductID == 0x24b5 || ProductID == 0x32f2 || ProductID == 0x27BC)
{
//
// Asus ROG PG248QP (0x24b5) Bug 5100062
// Asus ROG PG32UCDM (0x32f2) Bug 5088957
// Asus ROG PG27AQN (0x27BC) Bug 5300665
this->WARFlags.bForceHeadShutdown = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> Force head shutdown.");
}
break;
// Samsung
case 0x2D4C:
if (ProductID == 0x7474)
{
//
// Samsung Odyssey Neo 57 G9 needs manual allocation of timeslots when directly connected to upstream source
// Do not allocate manual timeslot when under a separate branch. This is checked with branch OUI.
//
this->WARFlags.bAllocateManualTimeslots = true;
this->WARFlags.bDP2XPreferNonDSCForLowPClk = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> Panel needs allocation of manual timeslot. Bug 4958974");
}
if (ProductID == 0x7256)
{
this->WARFlags.bDisableDownspread = true;
}
break;
case 0x545A: // VRT Varjo XR3
if (ProductID == 0x5841 || ProductID == 0x5842 || ProductID == 0x5843)
{
this->WARFlags.bDisableDownspread = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> VRT monitor does not work with GB20x when downspread is enabled. Disabling downspread.");
}
break;
case 0xD94D: // Sony
if (ProductID == 0x07EE) // Sony SDM27Q10S
{
this->WARFlags.bSkipResetMSTMBeforeLt = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> Sony SDM27Q10S needs to skip reset MST_EN before LT");
}
break;
case 0xAC10:
switch (ProductID)
{
case 0x42AD:
case 0x42AC:
this->WARFlags.bApplyStuffDummySymbolsWAR = true;
this->WARData.bStuffDummySymbolsFor128b132b = true;
this->WARData.bStuffDummySymbolsFor8b10b = false;
break;
case 0xA21F:
this->WARFlags.bForceHeadShutdown = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> Force head shutdown for Dell AW2524H.");
break;
}
break;
default:
break;
}
// Find out if the monitor needs a WAR to applied.
if (warFlag)
{
if (warFlag & DP_MONITOR_CAPABILITY_DP_SKIP_REDUNDANT_LT)
{
this->WARFlags.skipRedundantLt = true;
}
if (warFlag & DP_MONITOR_CAPABILITY_DP_SKIP_CABLE_BW_CHECK)
{
this->WARFlags.skipCableBWCheck = true;
this->WARData.maxLaneAtHighRate = pDenylistData->dpSkipCheckLink.maxLaneAtHighRate;
this->WARData.maxLaneAtLowRate = pDenylistData->dpSkipCheckLink.maxLaneAtLowRate;
}
if (warFlag & DP_MONITOR_CAPABILITY_DP_WRITE_0x600_BEFORE_LT)
{
// all HP monitors need to be powered up before link training
this->WARFlags.powerOnBeforeLt = true;
DP_PRINTF(DP_NOTICE, "DP-WAR> HP monitors need to be powered up before LT");
}
if (warFlag & DP_MONITOR_CAPABILITY_DP_OVERRIDE_OPTIMAL_LINK_CONFIG)
{
//
// Instead of calculating the optimum link config
// based on timing, bpc etc. just used a default
// fixed link config for the monitor for all modes
//
this->WARFlags.overrideOptimalLinkCfg = true;
// Force the fix max LT
this->WARFlags.forceMaxLinkConfig = true;
this->WARData.optimalLinkRate = pDenylistData->dpOverrideOptimalLinkConfig.linkRate;
this->WARData.optimalLaneCount = pDenylistData->dpOverrideOptimalLinkConfig.laneCount;
DP_PRINTF(DP_NOTICE, "DP-WAR> Overriding optimal link config on Dell U2410.");
DP_PRINTF(DP_NOTICE, "DP-WAR> bug 632801");
}
if (warFlag & DP_MONITOR_CAPABILITY_DP_OVERRIDE_MAX_LANE_COUNT)
{
//
// Some monitors claim more lanes than they actually support.
// This particular Lenovo monitos has just 2 lanes, but its DPCD says 4.
// This WAR is to override the max lane count read from DPCD.
//
this->WARFlags.overrideMaxLaneCount = true;
this->WARData.maxLaneCount = pDenylistData->dpMaxLaneCountOverride;
DP_PRINTF(DP_NOTICE, "DP-WAR> Overriding max lane count on Lenovo L2440x.");
DP_PRINTF(DP_NOTICE, "DP-WAR> bug 687952");
}
}
if (this->WARFlags.dataForced)
{
DP_PRINTF(DP_NOTICE, "DP-WAR> EDID was overridden for some data. Patching CRC.");
this->patchCrc();
}
}