520.61.05

This commit is contained in:
Andy Ritger
2022-10-10 14:59:24 -07:00
parent fe0728787f
commit 90eb10774f
758 changed files with 88383 additions and 26493 deletions

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-FileCopyrightText: Copyright (c) 1993-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -260,6 +260,9 @@ namespace DisplayPort
virtual bool isMSAOverMSTCapable() = 0;
virtual bool isFakedMuxDevice() = 0;
virtual bool setPanelReplayConfig(panelReplayConfig prcfg) = 0;
virtual bool isPanelReplaySupported() = 0;
protected:
virtual ~Device() {}

View File

@@ -315,14 +315,6 @@ namespace DisplayPort
//
bool bDscMstCapBug3143315;
//
// Enable DSC Pass through support in driver based on regkey.
//
bool bDscMstEnablePassThrough;
// Reduce number of 2H1OR LTs which fixes bug 3534707
bool bDscOptimizeLTBug3534707;
//
// Synaptics branch device doesn't support Virtual Peer Devices so DSC
// capability of downstream device should be decided based on device's own

View File

@@ -173,6 +173,8 @@ namespace DisplayPort
bool bIsFakedMuxDevice;
bool bIsPreviouslyFakedMuxDevice;
bool bisMarkedForDeletion;
bool bIgnoreMsaCap;
bool bIgnoreMsaCapCached;
//
// Device doing the DSC decompression for this device. This could be device itself
@@ -194,6 +196,7 @@ namespace DisplayPort
TriState bSdpExtCapable;
bool bMSAOverMSTCapable;
bool bDscPassThroughColorFormatWar;
DeviceImpl(DPCDHAL * hal, ConnectorImpl * connector, DeviceImpl * parent);
~DeviceImpl();
@@ -349,15 +352,9 @@ namespace DisplayPort
return true;
}
bool getIgnoreMSACap()
{
return hal->getMsaTimingparIgnored();
}
bool getIgnoreMSACap();
AuxRetry::status setIgnoreMSAEnable(bool msaTimingParamIgnoreEn)
{
return hal->setIgnoreMSATimingParamters(msaTimingParamIgnoreEn);
}
AuxRetry::status setIgnoreMSAEnable(bool msaTimingParamIgnoreEn);
bool isVirtualPeerDevice()
{

View File

@@ -308,7 +308,9 @@ namespace DisplayPort
static const NvU8 ddcAddrList[] = {EDID_DDC_ADR0, EDID_DDC_ADR1, EDID_DDC_ADR2};
const NvU8 ddcAddrListSize = sizeof(ddcAddrList)/sizeof(NvU8);
const NvU8 EDID_READ_MAX_RETRY_COUNT = 6;
// HDMI 1.4 Section 8.5: HDMI Sink can have up to 100ms to get EDID ready.
const NvU8 EDID_READ_RETRY_TIMEOUT_MS = 100;
const NvU8 EDID_MAX_AUX_RETRIES = 10;
const NvU8 EDID_AUX_WAIT_TIME = 1;
NvU8 getEDIDBlockChecksum(const Buffer &);

View File

@@ -68,8 +68,6 @@ namespace DisplayPort
Watermark watermarks; // Cached watermark calculations
} timeslot;
bool bIsCurrentModesetGroup; // Group that is getting attached
GroupImpl(ConnectorImpl * parent, bool isFirmwareGroup = false)
: parent(parent),
streamValidationDone(true),
@@ -82,7 +80,6 @@ namespace DisplayPort
dscModeActive(DSC_MODE_NONE),
singleHeadMultiStreamID(DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID_PRIMARY),
singleHeadMultiStreamMode(DP_SINGLE_HEAD_MULTI_STREAM_MODE_NONE),
bIsCurrentModesetGroup(false),
headAttached(false)
{
timeslot.count = 0;

View File

@@ -145,6 +145,7 @@ namespace DisplayPort
EDP_3_24GHZ = 324000000,
EDP_4_32GHZ = 432000000,
HBR2 = 540000000,
EDP_6_75GHZ = 675000000,
HBR3 = 810000000
};

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2010-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-FileCopyrightText: Copyright (c) 2010-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2020-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-FileCopyrightText: Copyright (c) 2020-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -65,12 +65,6 @@
//
#define NV_DP_DSC_MST_CAP_BUG_3143315 "DP_DSC_MST_CAP_BUG_3143315"
// Enable DSC Pass through support in MST mode.
#define NV_DP_DSC_MST_ENABLE_PASS_THROUGH "DP_DSC_MST_ENABLE_PASS_THROUGH"
// Regkey to reduce number of 2H1OR LTs which fixes bug 3534707
#define NV_DP_DSC_OPTIMIZE_LT_BUG_3534707 "DP_DSC_OPTIMIZE_LT_BUG_3534707"
#define NV_DP_REGKEY_NO_REPLY_TIMER_FOR_BUSY_WAITING "NO_REPLY_TIMER_FOR_BUSY_WAITING"
#define NV_DP_REGKEY_DPCD_PROBING_FOR_BUSY_WAITING "DP_DPCD_PROBING_FOR_BUSY_WAITING"
@@ -106,8 +100,6 @@ struct DP_REGKEY_DATABASE
bool bOptLinkKeptAliveSst;
bool bBypassEDPRevCheck;
bool bDscMstCapBug3143315;
bool bDscMstEnablePassThrough;
bool bDscOptimizeLTBug3534707;
bool bNoReplyTimerForBusyWaiting;
bool bDpcdProbingForBusyWaiting;
};

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-FileCopyrightText: Copyright (c) 1993-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -188,8 +188,6 @@ void ConnectorImpl::applyRegkeyOverrides(const DP_REGKEY_DATABASE& dpRegkeyDatab
this->bDisableSSC = dpRegkeyDatabase.bSscDisabled;
this->bEnableFastLT = dpRegkeyDatabase.bFastLinkTrainingEnabled;
this->bDscMstCapBug3143315 = dpRegkeyDatabase.bDscMstCapBug3143315;
this->bDscMstEnablePassThrough = dpRegkeyDatabase.bDscMstEnablePassThrough;
this->bDscOptimizeLTBug3534707 = dpRegkeyDatabase.bDscOptimizeLTBug3534707;
}
void ConnectorImpl::setPolicyModesetOrderMitigation(bool enabled)
@@ -633,27 +631,56 @@ create:
newDev->queryGUID2();
}
// Read panel DSC support only if GPU supports DSC
bool bGpuDscSupported;
main->getDscCaps(&bGpuDscSupported);
if (bGpuDscSupported)
if (!linkAwaitingTransition)
{
if (newDev->getDSCSupport())
{
// Read and parse DSC caps only if panel supports DSC
newDev->readAndParseDSCCaps();
//
// When link is awaiting SST<->MST transition, DSC caps read from downstream
// DSC branch device might be wrong. DSC Caps exposed by DSC MST branch depends
// on the current link state. If it is in SST mode ie MST_EN (0x111[bit 0]) is 0 and
// panel connected behind it supports DSC, then branch will expose the DSC caps
// of the panel connected down stream rather than it's own. This is because source
// will have no other way to read the caps of the downstream panel. In fact when
// MST_EN = 0 and UP_REQ_EN (0x111 [bit 1]) = 1 source can read the caps of the
// downstream panel using REMOTE_DPCD_READ but branch device's behavior depends
// only on MST_EN bit. Similarly in SST, if the panel connected downstream to branch
// does not support DSC, DSC MST branch will expose it's own DSC caps.
// During boot since VBIOS drives display in SST mode and when driver takes over,
// linkAwaitingTransition will be true. DpLib does link assessment and topology
// discovery by setting UP_REQ_EN to true while still keeping MST_EN to false.
// This is to ensure we detach the head and active modeset groups that are in SST mode
// before switching the link to MST mode. When processNewDevice is called at this
// point to create new devices we should not read DSC caps due to above mentioned reason.
// As long as linkIsAwaitingTransition is true, Dplib will not report new Devices to
// to client since isPendingNewDevice() will be false even though DPlib discovered
// new devices. After Dplib completes topology discovery, DD initiates notifyDetachBegin/End
// to remove active groups from the link and notifyDetachEnd calls assessLink
// where we toggle the link state. Only after this we should read DSC caps in this case.
// Following this assesslink calls fireEvents() which will report
// the new devies to clients and client will have the correct DSC caps.
//
bool bGpuDscSupported;
// Read and Parse Branch Specific DSC Caps
if (!newDev->isVideoSink() && !newDev->isAudioSink())
// Check GPU DSC Support
main->getDscCaps(&bGpuDscSupported);
if (bGpuDscSupported)
{
if (newDev->getDSCSupport())
{
newDev->readAndParseBranchSpecificDSCCaps();
}
}
// Read and parse DSC caps only if panel supports DSC
newDev->readAndParseDSCCaps();
if (!processedEdid.WARFlags.bIgnoreDscCap)
{
// Check if DSC is possible for the device and if so, set DSC Decompression device.
newDev->setDscDecompressionDevice(this->bDscCapBasedOnParent);
// Read and Parse Branch Specific DSC Caps
if (!newDev->isVideoSink() && !newDev->isAudioSink())
{
newDev->readAndParseBranchSpecificDSCCaps();
}
}
if (!processedEdid.WARFlags.bIgnoreDscCap)
{
// Check if DSC is possible for the device and if so, set DSC Decompression device.
newDev->setDscDecompressionDevice(this->bDscCapBasedOnParent);
}
}
}
@@ -675,6 +702,8 @@ create:
newDev->bMSAOverMSTCapable = false;
}
newDev->applyOUIOverrides();
fireEvents();
}
@@ -1194,6 +1223,40 @@ bool ConnectorImpl::compoundQueryAttach(Group * target,
DP_LOG(("Current version is 1.1"));
}
if ((dev->devDoingDscDecompression == dev) && dev->parent)
{
if (dev->parent->bDscPassThroughColorFormatWar)
{
//
// Bug 3692417
// Color format should only depend on device doing DSC decompression when DSC is enabled according to DP Spec.
// But when Synaptics VMM5320 is the parent of the device doing DSC decompression, if a certain color
// format is not supported by Synaptics Virtual Peer Device decoder(parent), even though it is pass through mode
// and panel supports the color format, panel cannot light up. Once Synaptics fixes this issue, we will modify
// the WAR to be applied only before the firmware version that fixes it.
//
if ((modesetParams.colorFormat == dpColorFormat_RGB && !dev->parent->dscCaps.dscDecoderColorFormatCaps.bRgb) ||
(modesetParams.colorFormat == dpColorFormat_YCbCr444 && !dev->parent->dscCaps.dscDecoderColorFormatCaps.bYCbCr444) ||
(modesetParams.colorFormat == dpColorFormat_YCbCr422 && !dev->parent->dscCaps.dscDecoderColorFormatCaps.bYCbCrSimple422))
{
if (pDscParams->forceDsc == DSC_FORCE_ENABLE)
{
// If DSC is force enabled then return failure here
compoundQueryResult = false;
pDscParams->bEnableDsc = false;
return false;
}
else
{
// We should check if mode is possible without DSC.
pDscParams->bEnableDsc = false;
lc.enableFEC(false);
goto nonDscDpIMP;
}
}
}
}
availableBandwidthBitsPerSecond = lc.minRate * 8 * lc.lanes;
warData.dpData.linkRateHz = lc.peakRate;
@@ -2550,7 +2613,6 @@ bool ConnectorImpl::notifyAttachBegin(Group * target, // Gr
}
GroupImpl* targetImpl = (GroupImpl*)target;
targetImpl->bIsCurrentModesetGroup = true;
if (bEnableDsc)
{
@@ -2667,7 +2729,6 @@ bool ConnectorImpl::notifyAttachBegin(Group * target, // Gr
NV_DPTRACE_INFO(NOTIFY_ATTACH_BEGIN_STATUS, bLinkTrainingStatus);
bFromResumeToNAB = false;
targetImpl->bIsCurrentModesetGroup = false;
return bLinkTrainingStatus;
}
@@ -3283,6 +3344,7 @@ bool ConnectorImpl::trainSingleHeadMultipleSSTLinkNotAlive(GroupImpl *pGroupAtta
void ConnectorImpl::assessLink(LinkTrainingType trainType)
{
this->bSkipLt = false; // Assesslink should never skip LT, so let's reset it in case it was set.
bool bLinkStateToggle = false;
if (bSkipAssessLinkForPCon)
{
@@ -3409,6 +3471,7 @@ void ConnectorImpl::assessLink(LinkTrainingType trainType)
linkState = hal->getSupportsMultistream() ?
DP_TRANSPORT_MODE_MULTI_STREAM : DP_TRANSPORT_MODE_SINGLE_STREAM;
linkAwaitingTransition = false;
bLinkStateToggle = true;
}
else
{
@@ -3517,6 +3580,30 @@ done:
{
disableFlush();
}
if (bLinkStateToggle)
{
DP_LOG(("DP> Link state toggled, reading DSC caps now"));
// Read panel DSC support only if GPU supports DSC
bool bGpuDscSupported;
main->getDscCaps(&bGpuDscSupported);
if (bGpuDscSupported)
{
for (Device * i = enumDevices(0); i; i=enumDevices(i))
{
DeviceImpl * dev = (DeviceImpl *)i;
if(dev->getDSCSupport())
{
// Read and parse DSC caps only if panel and GPU supports DSC
dev->readAndParseDSCCaps();
}
if (!(dev->processedEdid.WARFlags.bIgnoreDscCap))
{
dev->setDscDecompressionDevice(this->bDscCapBasedOnParent);
}
}
}
}
}
bool ConnectorImpl::handleCPIRQ()
@@ -3902,36 +3989,21 @@ bool ConnectorImpl::trainLinkOptimized(LinkConfiguration lConfig)
GroupImpl * groupAttached = 0;
for (ListElement * e = activeGroups.begin(); e != activeGroups.end(); e = e->next)
{
DP_ASSERT(bIsUefiSystem);
DP_ASSERT(bIsUefiSystem || linkUseMultistream() || (!groupAttached && "Multiple attached heads"));
groupAttached = (GroupImpl * )e;
if (bDscOptimizeLTBug3534707)
if ((groupAttached->dscModeRequest == DSC_DUAL) && (groupAttached->dscModeActive != DSC_DUAL))
{
if ((groupAttached->dscModeRequest == DSC_DUAL) && (groupAttached->dscModeActive != DSC_DUAL))
{
//
// If current modeset group requires 2Head1OR and
// - group is not active yet (first modeset on the group)
// - group is active but not in 2Head1OR mode (last modeset on the group did not require 2Head1OR)
// then re-train the link
// This is because for 2Head1OR mode, we need to set some LT parametes for slave SOR after
// successful LT on primary SOR without which 2Head1OR modeset will lead to HW hang.
//
bTwoHeadOneOrLinkRetrain = true;
break;
}
}
else
{
if (groupAttached->lastModesetInfo.mode == DSC_DUAL && groupAttached->bIsCurrentModesetGroup)
{
//
// If current modeset group requires 2Head1OR mode, we should retrain link.
// For SST, there will be only one group per connector.
// For MST, we need to re-run LT in case the current modeset group requires DSC_DUAL.
bTwoHeadOneOrLinkRetrain = true;
break;
}
//
// If current modeset group requires 2Head1OR and
// - group is not active yet (first modeset on the group)
// - group is active but not in 2Head1OR mode (last modeset on the group did not require 2Head1OR)
// then re-train the link
// This is because for 2Head1OR mode, we need to set some LT parametes for slave SOR after
// successful LT on primary SOR without which 2Head1OR modeset will lead to HW hang.
//
bTwoHeadOneOrLinkRetrain = true;
break;
}
}
@@ -4018,9 +4090,9 @@ bool ConnectorImpl::trainLinkOptimized(LinkConfiguration lConfig)
//
// Check if we are already trained to the desired link config?
// Make sure requested FEC state matches with the current FEC state of link.
// If 2Head1OR mode is requested, retrain if group is not active or
// last modeset on active group was not in 2Head1OR mode.
// bTwoHeadOneOrLinkRetrain tracks this requirement.
// If 2Head1OR mode is requested, retrain if group is not active or
// last modeset on active group was not in 2Head1OR mode.
// bTwoHeadOneOrLinkRetrain tracks this requirement.
//
//
@@ -4033,8 +4105,7 @@ bool ConnectorImpl::trainLinkOptimized(LinkConfiguration lConfig)
if ((activeLinkConfig == lowestSelected) &&
(!isLinkInD3()) &&
(!isLinkLost()) &&
((!bDscOptimizeLTBug3534707 && !this->bFECEnable) ||
(bDscOptimizeLTBug3534707 && (this->bFECEnable == activeLinkConfig.bEnableFEC))) &&
(this->bFECEnable == activeLinkConfig.bEnableFEC) &&
!bTwoHeadOneOrLinkRetrain)
{
if (bSkipRedundantLt || main->isInternalPanelDynamicMuxCapable())
@@ -4151,8 +4222,8 @@ bool ConnectorImpl::trainLinkOptimized(LinkConfiguration lConfig)
//
// Make sure link is physically active and healthy, otherwise re-train.
// Make sure requested FEC state matches with the current FEC state of link.
// If 2Head1OR mode is requested, retrain if group is not active or last modeset on active group
// was not in 2Head1OR mode. bTwoHeadOneOrLinkRetrain tracks this requirement.
// If 2Head1OR mode is requested, retrain if group is not active or last modeset on active group
// was not in 2Head1OR mode. bTwoHeadOneOrLinkRetrain tracks this requirement.
//
bRetrainToEnsureLinkStatus = (isLinkActive() && isLinkInD3()) ||
isLinkLost() ||
@@ -6143,6 +6214,13 @@ void ConnectorImpl::notifyShortPulse()
}
}
// If DPCD access is not available, skip trying to restore link configuration.
hal->updateDPCDOffline();
if (hal->isDpcdOffline())
{
return;
}
DP_LOG(("DP> Link not alive, Try to restore link configuration"));
if (trainSingleHeadMultipleSSTLinkNotAlive(getActiveGroupForSST()))

View File

@@ -91,7 +91,10 @@ DeviceImpl::DeviceImpl(DPCDHAL * hal, ConnectorImpl * connector, DeviceImpl * pa
bIsFakedMuxDevice(false),
bIsPreviouslyFakedMuxDevice(false),
bisMarkedForDeletion(false),
bSdpExtCapable(Indeterminate)
bIgnoreMsaCap(false),
bIgnoreMsaCapCached(false),
bSdpExtCapable(Indeterminate),
bDscPassThroughColorFormatWar(false)
{
bandwidth.enum_path.dataValid = false;
shadow.plugged = false;
@@ -921,6 +924,7 @@ void DeviceImpl::applyOUIOverrides()
(buffer[8] == 0x31 || buffer[8] == 0x20))
{
this->bSdpExtCapable = False;
this->bDscPassThroughColorFormatWar = true;
//
// Check firmware version
@@ -1026,7 +1030,7 @@ bool DeviceImpl::getSDPExtnForColorimetrySupported()
_YES, byte) ? True : False;
}
}
this->applyOUIOverrides();
if (parentDevice && (this->bSdpExtCapable == True))
{
//
@@ -1458,11 +1462,6 @@ NvBool DeviceImpl::getDSCSupport()
{
dscCaps.bDSCSupported = true;
}
if (FLD_TEST_DRF(_DPCD20, _DSC_SUPPORT, _PASS_THROUGH_SUPPORT, _YES, byte))
{
dscCaps.bDSCPassThroughSupported = true;
}
}
else
@@ -1572,6 +1571,11 @@ bool DeviceImpl::parseDscCaps(const NvU8 *buffer, NvU32 bufferSize)
return false;
}
if (FLD_TEST_DRF(_DPCD20, _DSC_SUPPORT, _PASS_THROUGH_SUPPORT, _YES, buffer[0x0]))
{
dscCaps.bDSCPassThroughSupported = true;
}
dscCaps.versionMajor = DRF_VAL(_DPCD14, _DSC_ALGORITHM_REVISION, _MAJOR, buffer[0x1]);
dscCaps.versionMinor = DRF_VAL(_DPCD14, _DSC_ALGORITHM_REVISION, _MINOR, buffer[0x1]);
@@ -1758,6 +1762,21 @@ bool DeviceImpl::readAndParseDSCCaps()
return parseDscCaps(&rawDscCaps[0], sizeof(rawDscCaps));
}
bool DeviceImpl::readAndParseBranchSpecificDSCCaps()
{
unsigned sizeCompleted = 0;
unsigned nakReason = NakUndefined;
NvU8 rawBranchSpecificDscCaps[3];
if(AuxBus::success != this->getDpcdData(NV_DPCD20_BRANCH_DSC_OVERALL_THROUGHPUT_MODE_0,
&rawBranchSpecificDscCaps[0], sizeof(rawBranchSpecificDscCaps), &sizeCompleted, &nakReason))
{
return false;
}
return parseBranchSpecificDscCaps(&rawBranchSpecificDscCaps[0], sizeof(rawBranchSpecificDscCaps));
}
void DeviceImpl::queryGUID2()
{
unsigned sizeCompleted = 0;
@@ -1779,21 +1798,6 @@ void DeviceImpl::queryGUID2()
}
}
bool DeviceImpl::readAndParseBranchSpecificDSCCaps()
{
unsigned sizeCompleted = 0;
unsigned nakReason = NakUndefined;
NvU8 rawBranchSpecificDscCaps[3];
if(AuxBus::success != this->getDpcdData(NV_DPCD20_BRANCH_DSC_OVERALL_THROUGHPUT_MODE_0,
&rawBranchSpecificDscCaps[0], sizeof(rawBranchSpecificDscCaps), &sizeCompleted, &nakReason))
{
return false;
}
return parseBranchSpecificDscCaps(&rawBranchSpecificDscCaps[0], sizeof(rawBranchSpecificDscCaps));
}
bool DeviceImpl::getDscEnable(bool *pEnable)
{
AuxBus::status status = AuxBus::success;
@@ -1928,7 +1932,8 @@ bool DeviceImpl::setDscEnable(bool enable)
unsigned nakReason = NakUndefined;
bool bCurrDscEnable = false;
bool bDscPassThrough = false;
bool bDscPassThroughUpdated = true;
AuxBus::status dscEnableStatus = AuxBus::success;
AuxBus::status dscPassThroughStatus = AuxBus::success;
Address::StringBuffer buffer;
DP_USED(buffer);
@@ -1938,7 +1943,7 @@ bool DeviceImpl::setDscEnable(bool enable)
return false;
}
if ((this->devDoingDscDecompression == this) && !this->isLogical() && this->parent != NULL && this->connector->bDscMstEnablePassThrough)
if ((this->devDoingDscDecompression == this) && !this->isLogical() && this->parent != NULL)
{
//
// If the device has a parent, that means the sink is on a MST link and
@@ -1948,20 +1953,18 @@ bool DeviceImpl::setDscEnable(bool enable)
//
bDscPassThrough = true;
}
else
//
// Get Current DSC Enable State
// Ideally we don't need to check the current state but Synaptics DSC device,
// which was used for inital DSC code developement did not follow spec and so
// we have added this code. Overwriting the same value should not have any
// impact as per the spec. Will remove this check once all DSC devices follow spec.
//
if (!getDscEnable(&bCurrDscEnable))
{
//
// Get Current DSC Enable State
// Ideally we don't need to check the current state but Synaptics DSC device,
// which was used for inital DSC code developement did not follow spec and so
// we have added this code. Overwriting the same value should not have any
// impact as per the spec. Will remove this check once all DSC devices follow spec.
//
if (!getDscEnable(&bCurrDscEnable))
{
DP_LOG(("DP-DEV> Not able to get DSC Enable State!"));
return false;
}
DP_LOG(("DP-DEV> Not able to get DSC Enable State!"));
return false;
}
if(enable)
@@ -1970,7 +1973,7 @@ bool DeviceImpl::setDscEnable(bool enable)
{
dscPassthroughByte = FLD_SET_DRF(_DPCD20, _DSC_PASS_THROUGH, _ENABLE, _YES, dscPassthroughByte);
DP_LOG(("DP-DEV> Enabling DSC Pass through on branch device - %s",
this->parent->getTopologyAddress().toString(buffer)));
this->parent->getTopologyAddress().toString(buffer)));
}
if (!bCurrDscEnable)
@@ -1983,7 +1986,6 @@ bool DeviceImpl::setDscEnable(bool enable)
{
DP_LOG(("DP-DEV> DSC decompression is already enabled on device - %s",
this->devDoingDscDecompression->getTopologyAddress().toString(buffer)));
return true;
}
}
else
@@ -2005,22 +2007,40 @@ bool DeviceImpl::setDscEnable(bool enable)
{
DP_LOG(("DP-DEV> DSC decompression is already disabled on device - %s",
this->devDoingDscDecompression->getTopologyAddress().toString(buffer)));
return true;
}
}
if (bDscPassThrough)
{
if(this->parent->setDpcdData(NV_DPCD20_DSC_PASS_THROUGH,
&dscPassthroughByte, sizeof dscPassthroughByte, &size, &nakReason))
dscPassThroughStatus = this->parent->setDpcdData(NV_DPCD20_DSC_PASS_THROUGH,
&dscPassthroughByte, sizeof dscPassthroughByte, &size, &nakReason);
if (dscPassThroughStatus != AuxBus::success)
{
DP_LOG(("DP-DEV> Setting DSC Passthrough state on parent branch failed"));
bDscPassThroughUpdated = false;
DP_LOG(("DP-DEV> Setting DSC Passthrough on parent branch %s failed",
this->parent->getTopologyAddress().toString(buffer)));
}
}
return (!this->devDoingDscDecompression->setDpcdData(NV_DPCD14_DSC_ENABLE,
&dscEnableByte, sizeof dscEnableByte, &size, &nakReason)) && bDscPassThroughUpdated;
if (enable != bCurrDscEnable)
{
dscEnableStatus = this->devDoingDscDecompression->setDpcdData(NV_DPCD14_DSC_ENABLE,
&dscEnableByte, sizeof dscEnableByte, &size, &nakReason);
if (dscEnableStatus != AuxBus::success)
{
DP_LOG(("DP-DEV> Setting DSC Enable on sink %s failed",
this->devDoingDscDecompression->getTopologyAddress().toString(buffer)));
}
}
if ((dscPassThroughStatus != AuxBus::success) || (dscEnableStatus != AuxBus::success))
{
return false;
}
else
{
return true;
}
}
unsigned DeviceImpl::getDscVersionMajor()
@@ -2236,6 +2256,124 @@ bool DeviceImpl::getPCONCaps(PCONCaps *pPCONCaps)
return true;
}
bool DeviceImpl::getIgnoreMSACap()
{
NvU8 byte = 0;
unsigned size = 0;
unsigned nakReason = NakUndefined;
AuxBus::status status;
if (bIgnoreMsaCapCached)
{
return bIgnoreMsaCap;
}
if (this->isMultistream())
{
status = this->getDpcdData(NV_DPCD_DOWN_STREAM_PORT,
&byte, sizeof byte, &size, &nakReason);
if (status == AuxBus::success)
{
if(FLD_TEST_DRF(_DPCD, _DOWN_STREAM_PORT, _MSA_TIMING_PAR_IGNORED, _YES, byte))
{
if (this->parent && this->parent->isVirtualPeerDevice())
{
byte = 0;
size = 0;
nakReason = NakUndefined;
status = this->parent->getDpcdData(NV_DPCD_DOWN_STREAM_PORT,
&byte, sizeof byte, &size, &nakReason);
if (status == AuxBus::success)
{
if(FLD_TEST_DRF(_DPCD, _DOWN_STREAM_PORT, _MSA_TIMING_PAR_IGNORED, _YES, byte))
{
bIgnoreMsaCap = true;
}
else
{
bIgnoreMsaCap = false;
}
bIgnoreMsaCapCached = true;
}
else
{
DP_LOG(("DP-DEV> Aux Read from DPCD offset 0x7 failed!"));
return false;
}
}
else
{
bIgnoreMsaCap = true;
bIgnoreMsaCapCached = true;
}
}
else
{
bIgnoreMsaCap = false;
bIgnoreMsaCapCached = true;
}
}
else
{
DP_LOG(("DP-DEV> Aux Read from DPCD offset 0x7 failed!"));
return false;
}
}
else
{
bIgnoreMsaCap = hal->getMsaTimingparIgnored();
bIgnoreMsaCapCached = true;
}
return bIgnoreMsaCap;
}
AuxRetry::status DeviceImpl::setIgnoreMSAEnable(bool msaTimingParamIgnoreEn)
{
NvU8 byte = 0;
unsigned size = 0;
unsigned nakReason = NakUndefined;
AuxBus::status status;
if (this->isMultistream())
{
status = this->getDpcdData(NV_DPCD_DOWNSPREAD_CTRL,
&byte, sizeof byte, &size, &nakReason);
if (status == AuxBus::success)
{
if (msaTimingParamIgnoreEn)
{
byte = FLD_SET_DRF(_DPCD, _DOWNSPREAD_CTRL, _MSA_TIMING_PAR_IGNORED, _TRUE, byte);
}
else
{
byte = FLD_SET_DRF(_DPCD, _DOWNSPREAD_CTRL, _MSA_TIMING_PAR_IGNORED, _FALSE, byte);
}
status = this->setDpcdData(NV_DPCD_DOWNSPREAD_CTRL,
&byte, sizeof byte, &size, &nakReason);
if (status == AuxBus::success)
{
return AuxRetry::ack;
}
else
{
DP_LOG(("DP-DEV> Aux Write to DPCD offset 0x107 failed!"));
return AuxRetry::nack;
}
}
else
{
DP_LOG(("DP-DEV> Aux Read from DPCD offset 0x7 failed!"));
return AuxRetry::nack;
}
}
else
{
return hal->setIgnoreMSATimingParamters(msaTimingParamIgnoreEn);
}
}
void
DeviceHDCPDetection::start()

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-FileCopyrightText: Copyright (c) 1993-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -94,8 +94,6 @@ const struct
{NV_DP_REGKEY_KEEP_OPT_LINK_ALIVE_SST, &dpRegkeyDatabase.bOptLinkKeptAliveSst, DP_REG_VAL_BOOL},
{NV_DP_REGKEY_FORCE_EDP_ILR, &dpRegkeyDatabase.bBypassEDPRevCheck, DP_REG_VAL_BOOL},
{NV_DP_DSC_MST_CAP_BUG_3143315, &dpRegkeyDatabase.bDscMstCapBug3143315, DP_REG_VAL_BOOL},
{NV_DP_DSC_MST_ENABLE_PASS_THROUGH, &dpRegkeyDatabase.bDscMstEnablePassThrough, DP_REG_VAL_BOOL},
{NV_DP_DSC_OPTIMIZE_LT_BUG_3534707, &dpRegkeyDatabase.bDscOptimizeLTBug3534707, DP_REG_VAL_BOOL},
{NV_DP_REGKEY_NO_REPLY_TIMER_FOR_BUSY_WAITING, &dpRegkeyDatabase.bNoReplyTimerForBusyWaiting, DP_REG_VAL_BOOL},
{NV_DP_REGKEY_DPCD_PROBING_FOR_BUSY_WAITING, &dpRegkeyDatabase.bDpcdProbingForBusyWaiting, DP_REG_VAL_BOOL}
};
@@ -1048,6 +1046,7 @@ bool EvoMainLink::train(const LinkConfiguration & link, bool force,
case EDP_3_24GHZ:
case EDP_4_32GHZ:
case HBR2:
case EDP_6_75GHZ:
case HBR3:
linkBw = linkrate / DP_LINK_BW_FREQ_MULTI_MBPS;
dpCtrlData = FLD_SET_DRF_NUM(0073_CTRL, _DP_DATA, _SET_LINK_BW,
@@ -1797,6 +1796,7 @@ bool EvoMainLink::configureLinkRateTable
case linkBW_3_24Gbps:
case linkBW_4_32Gbps:
case linkBW_5_40Gbps:
case linkBW_6_75Gbps:
case linkBW_8_10Gbps:
pLinkRates->import(params.linkBwTbl[i]);
break;

View File

@@ -177,12 +177,59 @@ void GroupImpl::remove(Device * dev)
void GroupImpl::destroy()
{
ConnectorImpl* parent = NULL;
for (Device * i = enumDevices(0); i; i = enumDevices(i))
remove(i);
// Cancel any queue the auth callback.
cancelHdcpCallbacks();
parent = this->parent;
if (parent)
{
if (!parent->activeGroups.isEmpty())
{
for (ListElement * i = parent->activeGroups.begin(); i != parent->activeGroups.end(); i = i->next)
{
GroupImpl * group = (GroupImpl *)i;
if (group == this)
{
parent->activeGroups.remove(this);
DP_LOG(("DP-GRP> Deleted group 0x%x from active group!", this));
break;
}
}
}
if (!parent->inactiveGroups.isEmpty())
{
for (ListElement * i = parent->inactiveGroups.begin(); i != parent->inactiveGroups.end(); i = i->next)
{
GroupImpl * group = (GroupImpl *)i;
if (group == this)
{
parent->inactiveGroups.remove(this);
DP_LOG(("DP-GRP> Deleted group 0x%x from inactive group!", this));
break;
}
}
}
if (parent->intransitionGroups.contains(this))
{
parent->intransitionGroups.remove(this);
DP_LOG(("DP-GRP> Deleted group 0x%x from intransition group!", this));
}
if (parent->addStreamMSTIntransitionGroups.contains(this))
{
parent->addStreamMSTIntransitionGroups.remove(this);
DP_LOG(("DP-GRP> Deleted group 0x%x from addStreamMSTIntransitionGroups group!", this));
}
}
delete this;
}

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2010-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-FileCopyrightText: Copyright (c) 2010-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2010-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-FileCopyrightText: Copyright (c) 2010-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -240,10 +240,13 @@ bool DisplayPort::EdidReadSST(Edid & edid, AuxBus * auxBus, Timer* timer,
Edid previousEdid;
Buffer *buffer;
bool status;
bool firstTrial = true;
NvU64 startTime, elapsedTime;
for (unsigned i = 0; i < ddcAddrListSize; i++)
{
for (unsigned j = 0; j < EDID_READ_MAX_RETRY_COUNT; j++)
startTime = timer->getTimeUs();
elapsedTime = 0;
do
{
//
// Client asks to use RM control code to fetch EDID.
@@ -312,9 +315,10 @@ bool DisplayPort::EdidReadSST(Edid & edid, AuxBus * auxBus, Timer* timer,
}
else
{
if (j == 0) // first failure?
if (firstTrial) // first failure?
{
previousEdid.swap(edid);
firstTrial = false;
}
else
{
@@ -327,7 +331,9 @@ bool DisplayPort::EdidReadSST(Edid & edid, AuxBus * auxBus, Timer* timer,
}
}
}
}
elapsedTime = timer->getTimeUs() - startTime;
timer->sleep(1);
} while (elapsedTime < (EDID_READ_RETRY_TIMEOUT_MS * 1000));
}
DP_LOG(("EDID> Failed to ping sst DDC addresses"));