mirror of
https://github.com/NVIDIA/open-gpu-kernel-modules.git
synced 2026-02-10 10:09:58 +00:00
515.48.07
This commit is contained in:
@@ -320,6 +320,9 @@ namespace DisplayPort
|
||||
//
|
||||
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
|
||||
@@ -505,6 +508,7 @@ namespace DisplayPort
|
||||
void populateDscGpuCaps(DSC_INFO* dscInfo);
|
||||
void populateForcedDscParams(DSC_INFO* dscInfo, DSC_INFO::FORCED_DSC_PARAMS* forcedParams);
|
||||
void populateDscSinkCaps(DSC_INFO* dscInfo, DeviceImpl * dev);
|
||||
void populateDscBranchCaps(DSC_INFO* dscInfo, DeviceImpl * dev);
|
||||
void populateDscModesetInfo(MODESET_INFO * pModesetInfo, const DpModesetParams * pModesetParams);
|
||||
|
||||
bool train(const LinkConfiguration & lConfig, bool force, LinkTrainingType trainType = NORMAL_LINK_TRAINING);
|
||||
|
||||
@@ -425,7 +425,9 @@ namespace DisplayPort
|
||||
NvBool isDSCPossible();
|
||||
bool isFECSupported();
|
||||
bool readAndParseDSCCaps();
|
||||
bool readAndParseBranchSpecificDSCCaps();
|
||||
bool parseDscCaps(const NvU8 *buffer, NvU32 bufferSize);
|
||||
bool parseBranchSpecificDscCaps(const NvU8 *buffer, NvU32 bufferSize);
|
||||
bool setDscEnable(bool enable);
|
||||
bool getDscEnable(bool *pEnable);
|
||||
unsigned getDscVersionMajor();
|
||||
|
||||
@@ -53,6 +53,8 @@ namespace DisplayPort
|
||||
bool bWaitForDeAllocACT;
|
||||
bool bDeferredPayloadAlloc;
|
||||
ModesetInfo lastModesetInfo;
|
||||
DSC_MODE dscModeRequest; // DSC mode requested during NAB
|
||||
DSC_MODE dscModeActive; // DSC mode currently active, set in NAE
|
||||
DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID singleHeadMultiStreamID;
|
||||
DP_SINGLE_HEAD_MULTI_STREAM_MODE singleHeadMultiStreamMode;
|
||||
DP_COLORFORMAT colorFormat;
|
||||
@@ -76,6 +78,8 @@ namespace DisplayPort
|
||||
hdcpEnabled(false),
|
||||
hdcpPreviousStatus(false),
|
||||
bWaitForDeAllocACT(false),
|
||||
dscModeRequest(DSC_MODE_NONE),
|
||||
dscModeActive(DSC_MODE_NONE),
|
||||
singleHeadMultiStreamID(DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID_PRIMARY),
|
||||
singleHeadMultiStreamMode(DP_SINGLE_HEAD_MULTI_STREAM_MODE_NONE),
|
||||
bIsCurrentModesetGroup(false),
|
||||
|
||||
@@ -116,6 +116,8 @@ namespace DisplayPort
|
||||
bool isBeingDestroyed;
|
||||
bool isPaused;
|
||||
|
||||
bool bNoReplyTimerForBusyWaiting;
|
||||
|
||||
List messageReceivers;
|
||||
List notYetSentDownRequest; // Down Messages yet to be processed
|
||||
List notYetSentUpReply; // Up Reply Messages yet to be processed
|
||||
@@ -153,6 +155,13 @@ namespace DisplayPort
|
||||
mergerDownReply.mailboxInterrupt();
|
||||
}
|
||||
|
||||
void applyRegkeyOverrides(const DP_REGKEY_DATABASE& dpRegkeyDatabase)
|
||||
{
|
||||
DP_ASSERT(dpRegkeyDatabase.bInitialized &&
|
||||
"All regkeys are invalid because dpRegkeyDatabase is not initialized!");
|
||||
bNoReplyTimerForBusyWaiting = dpRegkeyDatabase.bNoReplyTimerForBusyWaiting;
|
||||
}
|
||||
|
||||
MessageManager(DPCDHAL * hal, Timer * timer)
|
||||
: timer(timer), hal(hal),
|
||||
splitterDownRequest(hal, timer),
|
||||
@@ -236,6 +245,7 @@ namespace DisplayPort
|
||||
MessageManager * parent;
|
||||
bool transmitReply;
|
||||
bool bTransmitted;
|
||||
bool bBusyWaiting;
|
||||
unsigned requestIdentifier;
|
||||
unsigned messagePriority;
|
||||
unsigned sinkPort;
|
||||
@@ -261,6 +271,7 @@ namespace DisplayPort
|
||||
parent(0),
|
||||
transmitReply(false),
|
||||
bTransmitted(false),
|
||||
bBusyWaiting(false),
|
||||
requestIdentifier(requestIdentifier),
|
||||
messagePriority(messagePriority),
|
||||
sinkPort(0xFF)
|
||||
|
||||
@@ -65,11 +65,13 @@
|
||||
//
|
||||
#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"
|
||||
//
|
||||
// Data Base used to store all the regkey values.
|
||||
// The actual data base is declared statically in dp_evoadapter.cpp.
|
||||
@@ -102,6 +104,8 @@ struct DP_REGKEY_DATABASE
|
||||
bool bBypassEDPRevCheck;
|
||||
bool bDscMstCapBug3143315;
|
||||
bool bDscMstEnablePassThrough;
|
||||
bool bDscOptimizeLTBug3534707;
|
||||
bool bNoReplyTimerForBusyWaiting;
|
||||
};
|
||||
|
||||
#endif //INCLUDED_DP_REGKEYDATABASE_H
|
||||
|
||||
@@ -189,6 +189,7 @@ void ConnectorImpl::applyRegkeyOverrides(const DP_REGKEY_DATABASE& dpRegkeyDatab
|
||||
this->bEnableFastLT = dpRegkeyDatabase.bFastLinkTrainingEnabled;
|
||||
this->bDscMstCapBug3143315 = dpRegkeyDatabase.bDscMstCapBug3143315;
|
||||
this->bDscMstEnablePassThrough = dpRegkeyDatabase.bDscMstEnablePassThrough;
|
||||
this->bDscOptimizeLTBug3534707 = dpRegkeyDatabase.bDscOptimizeLTBug3534707;
|
||||
}
|
||||
|
||||
void ConnectorImpl::setPolicyModesetOrderMitigation(bool enabled)
|
||||
@@ -630,6 +631,12 @@ create:
|
||||
{
|
||||
// Read and parse DSC caps only if panel supports DSC
|
||||
newDev->readAndParseDSCCaps();
|
||||
|
||||
// Read and Parse Branch Specific DSC Caps
|
||||
if (!newDev->isVideoSink() && !newDev->isAudioSink())
|
||||
{
|
||||
newDev->readAndParseBranchSpecificDSCCaps();
|
||||
}
|
||||
}
|
||||
|
||||
// Decide if DSC stream can be sent to new device
|
||||
@@ -655,13 +662,13 @@ create:
|
||||
if (this->bDscMstEnablePassThrough)
|
||||
{
|
||||
//
|
||||
// Check the device's own and its parent's DSC capability.
|
||||
// - Sink device will do DSC cecompression when
|
||||
// Check the device's own and its parent's DSC capability.
|
||||
// - Sink device will do DSC cecompression when
|
||||
// 1. Sink device is capable of DSC decompression and parent
|
||||
// supports DSC pass through.
|
||||
//
|
||||
// - Sink device's parent will do DSC decompression
|
||||
// 1. If sink device supports DSC decompression but it's parent does not support
|
||||
// - Sink device's parent will do DSC decompression
|
||||
// 1. If sink device supports DSC decompression but it's parent does not support
|
||||
// DSC Pass through, but supports DSC decompression.
|
||||
// 2. If the device does not support DSC decompression, but parent supports it.
|
||||
//
|
||||
@@ -672,7 +679,7 @@ create:
|
||||
if (newDev->parent->isDSCPassThroughSupported())
|
||||
{
|
||||
//
|
||||
// This condition takes care of DSC capable sink devices
|
||||
// This condition takes care of DSC capable sink devices
|
||||
// connected behind a DSC Pass through capable branch
|
||||
//
|
||||
newDev->devDoingDscDecompression = newDev;
|
||||
@@ -681,12 +688,12 @@ create:
|
||||
else if (newDev->parent->isDSCSupported())
|
||||
{
|
||||
//
|
||||
// This condition takes care of DSC capable sink devices
|
||||
// This condition takes care of DSC capable sink devices
|
||||
// connected behind a branch device that is not capable
|
||||
// of DSC pass through but can do DSC decompression.
|
||||
//
|
||||
newDev->bDSCPossible = true;
|
||||
newDev->devDoingDscDecompression = newDev->parent;
|
||||
newDev->devDoingDscDecompression = newDev->parent;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -695,11 +702,11 @@ create:
|
||||
newDev->devDoingDscDecompression = newDev;
|
||||
newDev->bDSCPossible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (newDev->parent && newDev->parent->isDSCSupported())
|
||||
{
|
||||
//
|
||||
// This condition takes care of sink devices not capable of DSC
|
||||
// This condition takes care of sink devices not capable of DSC
|
||||
// but parent is capable of DSC decompression.
|
||||
//
|
||||
newDev->bDSCPossible = true;
|
||||
@@ -709,7 +716,7 @@ create:
|
||||
else
|
||||
{
|
||||
//
|
||||
// Revert to old code if DSC Pass through support is not requested.
|
||||
// Revert to old code if DSC Pass through support is not requested.
|
||||
// This code will be deleted once DSC Pass through support will be enabled
|
||||
// by default which will be done when 2Head1OR MST (GR-133) will be in production.
|
||||
//
|
||||
@@ -1726,6 +1733,15 @@ void ConnectorImpl::populateDscGpuCaps(DSC_INFO* dscInfo)
|
||||
dscInfo->gpuCaps.lineBufferBitDepth = lineBufferBitDepth;
|
||||
}
|
||||
|
||||
void ConnectorImpl::populateDscBranchCaps(DSC_INFO* dscInfo, DeviceImpl * dev)
|
||||
{
|
||||
dscInfo->branchCaps.overallThroughputMode0 = dev->dscCaps.branchDSCOverallThroughputMode0;
|
||||
dscInfo->branchCaps.overallThroughputMode1 = dev->dscCaps.branchDSCOverallThroughputMode1;
|
||||
dscInfo->branchCaps.maxLineBufferWidth = dev->dscCaps.branchDSCMaximumLineBufferWidth;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void ConnectorImpl::populateDscSinkCaps(DSC_INFO* dscInfo, DeviceImpl * dev)
|
||||
{
|
||||
// Early return if dscInfo or dev is NULL
|
||||
@@ -1846,6 +1862,12 @@ void ConnectorImpl::populateDscCaps(DSC_INFO* dscInfo, DeviceImpl * dev, DSC_INF
|
||||
// Sink DSC capabilities
|
||||
populateDscSinkCaps(dscInfo, dev);
|
||||
|
||||
// Branch Specific DSC Capabilities
|
||||
if (!dev->isVideoSink() && !dev->isAudioSink())
|
||||
{
|
||||
populateDscBranchCaps(dscInfo, dev);
|
||||
}
|
||||
|
||||
// GPU DSC capabilities
|
||||
populateDscGpuCaps(dscInfo);
|
||||
|
||||
@@ -2621,11 +2643,6 @@ bool ConnectorImpl::notifyAttachBegin(Group * target, // Gr
|
||||
}
|
||||
}
|
||||
|
||||
if (bEnableDsc)
|
||||
{
|
||||
DP_LOG(("DPCONN> DSC Mode = %s", (modesetParams.modesetInfo.mode == DSC_SINGLE) ? "SINGLE" : "DUAL"));
|
||||
}
|
||||
|
||||
for (Device * dev = target->enumDevices(0); dev; dev = target->enumDevices(dev))
|
||||
{
|
||||
Address::StringBuffer buffer;
|
||||
@@ -2641,6 +2658,12 @@ bool ConnectorImpl::notifyAttachBegin(Group * target, // Gr
|
||||
GroupImpl* targetImpl = (GroupImpl*)target;
|
||||
targetImpl->bIsCurrentModesetGroup = true;
|
||||
|
||||
if (bEnableDsc)
|
||||
{
|
||||
DP_LOG(("DPCONN> DSC Mode = %s", (modesetParams.modesetInfo.mode == DSC_SINGLE) ? "SINGLE" : "DUAL"));
|
||||
targetImpl->dscModeRequest = modesetParams.modesetInfo.mode;
|
||||
}
|
||||
|
||||
DP_ASSERT(!(targetImpl->isHeadAttached() && targetImpl->bIsHeadShutdownNeeded) && "Head should have been shut down but it is still active!");
|
||||
|
||||
targetImpl->headInFirmware = false;
|
||||
@@ -2788,6 +2811,10 @@ void ConnectorImpl::notifyAttachEnd(bool modesetCancelled)
|
||||
currentModesetDeviceGroup->setHeadAttached(false);
|
||||
}
|
||||
|
||||
// set dscModeActive to what was requested in NAB and clear dscModeRequest
|
||||
currentModesetDeviceGroup->dscModeActive = currentModesetDeviceGroup->dscModeRequest;
|
||||
currentModesetDeviceGroup->dscModeRequest = DSC_MODE_NONE;
|
||||
|
||||
currentModesetDeviceGroup->setHeadAttached(true);
|
||||
RmDfpCache dfpCache = {0};
|
||||
dfpCache.updMask = 0;
|
||||
@@ -2934,6 +2961,7 @@ void ConnectorImpl::notifyDetachEnd(bool bKeepOdAlive)
|
||||
dpMemZero(¤tModesetDeviceGroup->lastModesetInfo, sizeof(ModesetInfo));
|
||||
currentModesetDeviceGroup->setHeadAttached(false);
|
||||
currentModesetDeviceGroup->headInFirmware = false;
|
||||
currentModesetDeviceGroup->dscModeActive = DSC_MODE_NONE;
|
||||
|
||||
// Mark head as disconnected
|
||||
bNoLtDoneAfterHeadDetach = true;
|
||||
@@ -3980,18 +4008,36 @@ bool ConnectorImpl::trainLinkOptimized(LinkConfiguration lConfig)
|
||||
GroupImpl * groupAttached = 0;
|
||||
for (ListElement * e = activeGroups.begin(); e != activeGroups.end(); e = e->next)
|
||||
{
|
||||
DP_ASSERT(bIsUefiSystem || (!groupAttached && "Multiple attached heads"));
|
||||
DP_ASSERT(bIsUefiSystem);
|
||||
groupAttached = (GroupImpl * )e;
|
||||
|
||||
if ((groupAttached->lastModesetInfo.mode == DSC_DUAL) && groupAttached->bIsCurrentModesetGroup)
|
||||
if (bDscOptimizeLTBug3534707)
|
||||
{
|
||||
//
|
||||
// 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 ((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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4077,10 +4123,10 @@ bool ConnectorImpl::trainLinkOptimized(LinkConfiguration lConfig)
|
||||
{
|
||||
//
|
||||
// Check if we are already trained to the desired link config?
|
||||
// Even if we are, we need to redo LT if FEC is enabled or DSC mode is DSC_DUAL
|
||||
// since if current modeset requires 2H1OR, LT done during assessLink will not
|
||||
// have 2H1Or flag set or if last modeset required DSC but not 2H1OR, still 2H1Or
|
||||
// flag will not be set and modeset will lead to HW hang.
|
||||
// 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.
|
||||
//
|
||||
|
||||
//
|
||||
@@ -4093,7 +4139,8 @@ bool ConnectorImpl::trainLinkOptimized(LinkConfiguration lConfig)
|
||||
if ((activeLinkConfig == lowestSelected) &&
|
||||
(!isLinkInD3()) &&
|
||||
(!isLinkLost()) &&
|
||||
!(this->bFECEnable) &&
|
||||
((!bDscOptimizeLTBug3534707 && !this->bFECEnable) ||
|
||||
(bDscOptimizeLTBug3534707 && (this->bFECEnable == activeLinkConfig.bEnableFEC))) &&
|
||||
!bTwoHeadOneOrLinkRetrain)
|
||||
{
|
||||
if (bSkipRedundantLt || main->isInternalPanelDynamicMuxCapable())
|
||||
@@ -4209,11 +4256,9 @@ bool ConnectorImpl::trainLinkOptimized(LinkConfiguration lConfig)
|
||||
|
||||
//
|
||||
// Make sure link is physically active and healthy, otherwise re-train.
|
||||
// We need to retrain if the link is in 2Head1OR MST mode. For example,
|
||||
// if we plug in a 2Head1OR panel to an active link that is already driving
|
||||
// a MST panel in DSC mode, RM will assign a secondary OR to the 2Head1OR panel.
|
||||
// But since there is no change required in linkConfig DPlib will skip
|
||||
// LT, resutling in not adding secondary OR to LT; this will lead to HW hang.
|
||||
// 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.
|
||||
//
|
||||
bRetrainToEnsureLinkStatus = (isLinkActive() && isLinkInD3()) ||
|
||||
isLinkLost() ||
|
||||
@@ -5660,7 +5705,7 @@ void ConnectorImpl::notifyLongPulseInternal(bool statusConnected)
|
||||
if (hal->getSupportsMultistream() && main->hasMultistream())
|
||||
{
|
||||
bool bDeleteFirmwareVC = false;
|
||||
|
||||
const DP_REGKEY_DATABASE& dpRegkeyDatabase = main->getRegkeyDatabase();
|
||||
DP_LOG(("DP> Multistream panel detected, building message manager"));
|
||||
|
||||
//
|
||||
@@ -5669,6 +5714,7 @@ void ConnectorImpl::notifyLongPulseInternal(bool statusConnected)
|
||||
//
|
||||
messageManager = new MessageManager(hal, timer);
|
||||
messageManager->registerReceiver(&ResStatus);
|
||||
messageManager->applyRegkeyOverrides(dpRegkeyDatabase);
|
||||
|
||||
//
|
||||
// Create a discovery manager to initiate detection
|
||||
|
||||
@@ -1687,6 +1687,50 @@ bool DeviceImpl::parseDscCaps(const NvU8 *buffer, NvU32 bufferSize)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeviceImpl::parseBranchSpecificDscCaps(const NvU8 *buffer, NvU32 bufferSize)
|
||||
{
|
||||
if (bufferSize < 3)
|
||||
{
|
||||
DP_LOG((" Branch DSC caps buffer must be greater than or equal to 3"));
|
||||
return false;
|
||||
}
|
||||
|
||||
dscCaps.branchDSCOverallThroughputMode0 = DRF_VAL(_DPCD20, _BRANCH_DSC_OVERALL_THROUGHPUT_MODE_0, _VALUE, buffer[0x0]);
|
||||
if (dscCaps.branchDSCOverallThroughputMode0 == 1)
|
||||
{
|
||||
dscCaps.branchDSCOverallThroughputMode0 = 680;
|
||||
}
|
||||
else if (dscCaps.branchDSCOverallThroughputMode0 >= 2)
|
||||
{
|
||||
dscCaps.branchDSCOverallThroughputMode0 = 600 + dscCaps.branchDSCOverallThroughputMode0 * 50;
|
||||
}
|
||||
|
||||
dscCaps.branchDSCOverallThroughputMode1 = DRF_VAL(_DPCD20, _BRANCH_DSC_OVERALL_THROUGHPUT_MODE_1, _VALUE, buffer[0x1]);
|
||||
if (dscCaps.branchDSCOverallThroughputMode1 == 1)
|
||||
{
|
||||
dscCaps.branchDSCOverallThroughputMode1 = 680;
|
||||
}
|
||||
else if (dscCaps.branchDSCOverallThroughputMode1 >= 2)
|
||||
{
|
||||
dscCaps.branchDSCOverallThroughputMode1 = 600 + dscCaps.branchDSCOverallThroughputMode1 * 50;
|
||||
}
|
||||
|
||||
dscCaps.branchDSCMaximumLineBufferWidth = DRF_VAL(_DPCD20, _BRANCH_DSC_MAXIMUM_LINE_BUFFER_WIDTH, _VALUE, buffer[0x2]);
|
||||
if (dscCaps.branchDSCMaximumLineBufferWidth != 0)
|
||||
{
|
||||
if (dscCaps.branchDSCMaximumLineBufferWidth >= 16)
|
||||
{
|
||||
dscCaps.branchDSCMaximumLineBufferWidth = dscCaps.branchDSCMaximumLineBufferWidth * 320;
|
||||
}
|
||||
else
|
||||
{
|
||||
dscCaps.branchDSCMaximumLineBufferWidth = 0;
|
||||
DP_LOG(("Value of branch DSC maximum line buffer width is invalid, so setting it to 0."));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeviceImpl::readAndParseDSCCaps()
|
||||
{
|
||||
// Allocate a buffer of 16 bytes to read DSC caps
|
||||
@@ -1703,6 +1747,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));
|
||||
}
|
||||
|
||||
bool DeviceImpl::getDscEnable(bool *pEnable)
|
||||
{
|
||||
AuxBus::status status = AuxBus::success;
|
||||
|
||||
@@ -94,7 +94,9 @@ 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_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}
|
||||
};
|
||||
|
||||
EvoMainLink::EvoMainLink(EvoInterface * provider, Timer * timer) :
|
||||
|
||||
@@ -63,6 +63,11 @@ bool MessageManager::send(MessageManager::Message * message, NakData & nakData)
|
||||
DP_USED(sb);
|
||||
|
||||
NvU64 startTime, elapsedTime;
|
||||
|
||||
if (bNoReplyTimerForBusyWaiting)
|
||||
{
|
||||
message->bBusyWaiting = true;
|
||||
}
|
||||
post(message, &completion);
|
||||
startTime = timer->getTimeUs();
|
||||
do
|
||||
@@ -152,14 +157,13 @@ void MessageManager::Message::splitterTransmitted(OutgoingTransactionManager * f
|
||||
|
||||
if (from == &parent->splitterDownRequest)
|
||||
{
|
||||
//
|
||||
// Start the countdown timer for the reply
|
||||
//
|
||||
parent->timer->queueCallback(this, "SPLI", DPCD_MESSAGE_REPLY_TIMEOUT);
|
||||
|
||||
//
|
||||
// Client will busy-waiting for the message to complete, we don't need the countdown timer.
|
||||
if (!bBusyWaiting)
|
||||
{
|
||||
// Start the countdown timer for the reply
|
||||
parent->timer->queueCallback(this, "SPLI", DPCD_MESSAGE_REPLY_TIMEOUT);
|
||||
}
|
||||
// Tell the message manager he may begin sending the next message
|
||||
//
|
||||
parent->transmitAwaitingDownRequests();
|
||||
}
|
||||
else // UpReply
|
||||
|
||||
Reference in New Issue
Block a user