515.43.04

This commit is contained in:
Andy Ritger
2022-05-09 13:18:59 -07:00
commit 1739a20efc
2519 changed files with 1060036 additions and 0 deletions

View File

@@ -0,0 +1,284 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_address.h *
* Basic class for AUX Address *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_ADDRESS_H
#define INCLUDED_DP_ADDRESS_H
#include "dp_internal.h"
namespace DisplayPort
{
class Address
{
public:
enum
{
maxHops = 15, // update DP_MAX_ADDRESS_HOPS when changed (in displayportCommon.h)
maxHopsHDCP = 7,
maxPortCount = 15
};
Address()
{
clear();
}
Address(unsigned hop0)
{
clear();
hop[hops++] = hop0;
}
Address(unsigned hop0, unsigned hop1)
{
clear();
hop[hops++] = hop0;
hop[hops++] = hop1;
}
Address(const Address & other)
{
clear();
for(unsigned i = 0; i < other.size(); i++)
{
append(other[i]);
}
}
void clear()
{
hops = 0;
for (unsigned i = 0; i < maxHops; i++)
{
hop[i] = 0;
}
}
Address parent() const
{
DP_ASSERT(hops != 0);
Address addr = *this;
addr.hops --;
return addr;
}
unsigned tail() const
{
if (hops == 0)
{
DP_ASSERT(hops != 0);
return 0;
}
return hop[hops-1];
}
void append(unsigned port)
{
if (hops >= maxHops)
{
DP_ASSERT(0);
return;
}
hop[hops++] = port;
}
void prepend(unsigned port)
{
if (hops >= maxHops)
{
DP_ASSERT(0);
return;
}
hops++;
for (unsigned i = hops - 1; i > 0; i--)
hop[i] = hop[i-1];
hop[0] = port;
}
void pop()
{
if (hops == 0)
{
DP_ASSERT(0);
return;
}
hops--;
}
// Just to keep clear copy
Address & operator = (const Address & other)
{
clear();
for(unsigned i = 0; i < other.size(); i++)
{
append(other[i]);
}
return *this;
}
bool operator == (const Address & other) const
{
if (other.size() != size())
return false;
for (unsigned i = 0; i < hops; i++)
if (other[i] != (*this)[i])
return false;
return true;
}
//
// Sort by size first, then "alphabetically" (lexicographical see wikipedia)
//
bool operator > (const Address & other) const
{
if (size() > other.size())
return true;
else if (size() < other.size())
return false;
for (unsigned i = 0; i < hops; i++)
{
if ((*this)[i] > other[i])
return true;
else if ((*this)[i] < other[i])
return false;
}
return false;
}
//
// Sort by size first, then "alphabetically" (lexicographical see wikipedia)
//
bool operator < (const Address & other) const
{
if (size() < other.size())
return true;
else if (size() > other.size())
return false;
for (unsigned i = 0; i < hops; i++)
{
if ((*this)[i] < other[i])
return true;
else if ((*this)[i] > other[i])
return false;
}
return false;
}
bool operator >= (const Address & other) const
{
return !((*this) < other);
}
bool operator <= (const Address & other) const
{
return !((*this) > other);
}
bool operator != (const Address & other) const
{
return !((*this) == other);
}
unsigned size() const
{
return hops;
}
unsigned & operator [](unsigned index)
{
DP_ASSERT(index < hops);
return hop[index];
}
const unsigned & operator [](unsigned index) const
{
DP_ASSERT(index < hops);
return hop[index];
}
bool under(const Address & root) const
{
if (size() < root.size())
return false;
for (unsigned i = 0; i < root.size(); i++)
if ((*this)[i] != root[i])
return false;
return true;
}
typedef char StringBuffer[maxHops*3+1];
char * toString(StringBuffer & buffer, bool removeLeadingZero = false) const
{
char * p = &buffer[0];
int hopsWritten = 0;
for (unsigned i = 0; i < hops; i++)
{
if (i == 0 && hop[0] == 0 && removeLeadingZero)
continue;
if (hopsWritten > 0)
*p++ = '.';
if (hop[i] >= 10)
*p++ = (char)(hop[i] / 10 +'0');
*p++ = (char)(hop[i] % 10 + '0');
hopsWritten++;
}
*p++= 0;
return (char *)&buffer[0];
}
// Large enough to fit 4 hops into every NvU32
typedef NvU32 NvU32Buffer[(maxHops-1)/4+1 < 4 ? 4 : (maxHops-1)/4+1];
NvU32 * toNvU32Buffer(NvU32Buffer & buffer) const
{
for (unsigned i = 0; i < hops; i++)
{
buffer[i/4] |= ((NvU8) hop[i]) << (i % 4) * 8;
}
return (NvU32 *)&buffer[0];
}
private:
unsigned hop[maxHops];
unsigned hops;
};
}
#endif //INCLUDED_DP_ADDRESS_H

View File

@@ -0,0 +1,80 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_auxbus.h *
* Interface for low level access to the aux bus. *
* This is the synchronous version of the interface. *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_AUXBUS_H
#define INCLUDED_DP_AUXBUS_H
namespace DisplayPort
{
class AuxBus : virtual public Object
{
public:
enum status
{
success,
defer,
nack,
unSupported,
};
enum Action
{
read,
write,
writeStatusUpdateRequest, // I2C only
};
enum Type
{
native,
i2c,
i2cMot
};
virtual status transaction(Action action, Type type, int address,
NvU8 * buffer, unsigned sizeRequested,
unsigned * sizeCompleted,
unsigned * pNakReason = NULL,
NvU8 offset = 0, NvU8 nWriteTransactions = 0) = 0;
virtual unsigned transactionSize() = 0;
virtual status fecTransaction(NvU8 *fecStatus, NvU16 **fecErrorCount, NvU32 flags) { return nack; }
virtual void setDevicePlugged(bool) {}
virtual ~AuxBus() {}
};
//
// Wraps an auxbus interface with one that prints all the input and output
//
AuxBus * CreateAuxLogger(AuxBus * auxBus);
}
#endif //INCLUDED_DP_AUXBUS_H

View File

@@ -0,0 +1,97 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2010-2021 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_auxdefs.h *
* Definitions for DPCD AUX offsets *
* Should be used sparingly (DPCD HAL preferred) *
* *
\***************************************************************************/
#ifndef __DP_AUXDEFS_H__
#define __DP_AUXDEFS_H__
#define DPCD_MESSAGEBOX_SIZE 48
//
// This definitions are being used for orin Hdcp opensourcing. Ideally this
// should be replaced with build flags. Bug ID: 200733434
//
#define DP_OPTION_HDCP_SUPPORT_ENABLE 1 /* HDCP Enable */
#define DP_OPTION_HDCP_12_ENABLED 1 /* DP1.2 HDCP ENABLE */
#define DP_OPTION_QSE_ENABLED 1 /* Remove here when QSE p4r check-in */
//
// If a message is outstanding for at least 4 seconds
// assume no reply is coming through
//
#define DPCD_MESSAGE_REPLY_TIMEOUT 4000
#define DPCD_LINK_ADDRESS_MESSAGE_RETRIES 20 // 20 retries
#define DPCD_LINK_ADDRESS_MESSAGE_COOLDOWN 10 // 10ms between attempts
// pointing to the defaults for LAM settings to start with
#define DPCD_REMOTE_DPCD_WRITE_MESSAGE_RETRIES DPCD_LINK_ADDRESS_MESSAGE_RETRIES
#define DPCD_REMOTE_DPCD_WRITE_MESSAGE_COOLDOWN DPCD_LINK_ADDRESS_MESSAGE_COOLDOWN
#define DPCD_REMOTE_DPCD_READ_MESSAGE_RETRIES 7 // 7 retries
#define DPCD_REMOTE_DPCD_READ_MESSAGE_COOLDOWN DPCD_LINK_ADDRESS_MESSAGE_COOLDOWN
#define DPCD_REMOTE_DPCD_READ_MESSAGE_COOLDOWN_BKSV 20 // 20ms between attempts
#define DPCD_QUERY_STREAM_MESSAGE_RETRIES 7 // 7 retries
#define DPCD_QUERY_STREAM_MESSAGE_COOLDOWN 20 // 20ms between attempts
#define MST_EDID_RETRIES 20
#define MST_EDID_COOLDOWN 10
#define MST_ALLOCATE_RETRIES 10
#define MST_ALLOCATE_COOLDOWN 10
#define HDCP_AUTHENTICATION_RETRIES 6 // 6 retries
#define HDCP_CPIRQ_RXSTAUS_RETRIES 3
#define HDCP_AUTHENTICATION_COOLDOWN 1000// 1 sec between attempts
#define HDCP22_AUTHENTICATION_COOLDOWN 2000// 2 sec between attempts
#define HDCP_AUTHENTICATION_COOLDOWN_HPD 3000// 3 sec for first stream Add
#define HDCP_CPIRQ_RXSTATUS_COOLDOWN 20 // 20ms between attempts
// Need to re-submit Stream Validation request to falcon microcontroller after 1 sec if current request fails
#define HDCP_STREAM_VALIDATION_RESUBMIT_COOLDOWN 1000
//
// Wait till 8secs for completion of the KSV and Stream Validation, if that doesn't complete
// then timeout.
//
#define HDCP_STREAM_VALIDATION_REQUEST_COOLDOWN 8000
#define DPCD_OUI_NVIDIA 0x00044B
//
// Define maximum retry count that checking Payload ID table updated before
// trigger ACT sequence.
//
#define PAYLOADIDTABLE_UPDATED_CHECK_RETRIES 300
#endif // __DP_AUXDEFS_H__

View File

@@ -0,0 +1,181 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_auxretry.h *
* Adapter interface for friendlier AuxBus *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_AUXRETRY_H
#define INCLUDED_DP_AUXRETRY_H
#include "dp_auxbus.h"
#include "dp_timeout.h"
namespace DisplayPort
{
enum
{
minimumRetriesOnDefer = 7
};
class AuxRetry
{
AuxBus * aux;
public:
AuxRetry(AuxBus * aux = 0)
: aux(aux)
{
}
AuxBus * getDirect()
{
return aux;
}
enum status
{
ack,
nack,
unsupportedRegister,
defer
};
//
// Perform an aux read transaction.
// - Automatically handles defers up to retry limit
// - Retries on partial read
//
virtual status readTransaction(int address, NvU8 * buffer, unsigned size, unsigned retries = minimumRetriesOnDefer);
//
// Similar to readTransaction except that it supports reading
// larger spans than AuxBus::transactionSize()
//
virtual status read(int address, NvU8 * buffer, unsigned size, unsigned retries = minimumRetriesOnDefer);
//
// Perform an aux write transaction.
// - Automatically handles defers up to retry limit
// - Retries on partial write
//
virtual status writeTransaction(int address, NvU8 * buffer, unsigned size, unsigned retries = minimumRetriesOnDefer);
//
// Similar to writeTransaction except that it supports writin
// larger spans than AuxBus::transactionSize()
//
virtual status write(int address, NvU8 * buffer, unsigned size, unsigned retries = minimumRetriesOnDefer);
};
class AuxLogger : public AuxBus
{
AuxBus * bus;
char hex[256];
char hex_body[256];
char hint[128];
public:
AuxLogger(AuxBus * bus) : bus(bus)
{
}
const char * getAction(Action action)
{
if (action == read)
return "rd ";
else if (action == write)
return "wr ";
else if (action == writeStatusUpdateRequest)
return "writeStatusUpdateRequest ";
else
DP_ASSERT(0);
return "???";
}
const char * getType(Type typ)
{
if (typ == native)
return "";
else if (typ == i2c)
return "i2c ";
else if (typ == i2cMot)
return "i2cMot ";
else
DP_ASSERT(0);
return "???";
}
const char * getStatus(status stat)
{
if (stat == success)
return "";
else if (stat == nack)
return "(nack) ";
else if (stat == defer)
return "(defer) ";
else
DP_ASSERT(0);
return "???";
}
const char * getRequestId(unsigned requestIdentifier)
{
switch(requestIdentifier)
{
case 0x1: return "LINK_ADDRESS";
case 0x4: return "CLEAR_PAT";
case 0x10: return "ENUM_PATH";
case 0x11: return "ALLOCATE";
case 0x12: return "QUERY";
case 0x20: return "DPCD_READ";
case 0x21: return "DPCD_WRITE";
case 0x22: return "I2C_READ";
case 0x23: return "I2C_WRITE";
case 0x24: return "POWER_UP_PHY";
case 0x25: return "POWER_DOWN_PHY";
case 0x38: return "HDCP_STATUS";
default: return "";
}
}
virtual status transaction(Action action, Type type, int address,
NvU8 * buffer, unsigned sizeRequested,
unsigned * sizeCompleted, unsigned * pNakReason,
NvU8 offset, NvU8 nWriteTransactions);
virtual unsigned transactionSize()
{
return bus->transactionSize();
}
virtual status fecTransaction(NvU8 *fecStatus, NvU16 **fecErrorCount, NvU32 flags)
{
return bus->fecTransaction(fecStatus, fecErrorCount, flags);
}
};
}
#endif //INCLUDED_DP_AUXRETRY_H

View File

@@ -0,0 +1,98 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_bitstream.h *
* This is an implementation of the big endian bit stream *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_BITSTREAM_H
#define INCLUDED_DP_BITSTREAM_H
#include "dp_buffer.h"
namespace DisplayPort
{
//
// Bitstream reader interface
// - reads a packed stream of bits in Big Endian format
// - handles alignment, buffering, and buffer bounds checking
//
class BitStreamReader
{
Buffer * sourceBuffer;
unsigned bitsOffset;
unsigned bitsEnd;
public:
// Read 1-32 bits from the stream into *value. Returns true on success
bool read(unsigned * value, unsigned bits);
// Read 1-32 bits from stream. Returns 'default' on failure.
unsigned readOrDefault(unsigned bits, unsigned defaultValue);
// Skip bits until we're aligned to the power of two alignment
bool align(unsigned align);
unsigned offset();
Buffer * buffer();
BitStreamReader(Buffer * buffer, unsigned bitsOffset, unsigned bitsCount);
};
//
// Bitstream writer interface
//
class BitStreamWriter
{
Buffer * targetBuffer;
unsigned bitsOffset;
public:
//
// Create a bitstream writer at a specific bit offset
// into an already existing buffer
//
BitStreamWriter(Buffer * buffer, unsigned bitsOffset = 0);
//
// Write n bits to the buffer in big endian format.
// No buffering is performed.
//
bool write(unsigned value, unsigned bits);
//
// Emit zero's until the offset is divisible by align.
// CAVEAT: align must be a power of 2 (eg 8)
//
bool align(unsigned align);
//
// Get current offset and buffer target
//
unsigned offset();
Buffer * buffer();
};
}
#endif //INCLUDED_DP_BITSTREAM_H

View File

@@ -0,0 +1,97 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2010-2021 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_buffer.h *
* Resizable byte buffer and stream classes *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_BUFFER_H
#define INCLUDED_DP_BUFFER_H
#include "dp_internal.h"
namespace DisplayPort
{
class Buffer
{
public:
NvU8 *data; // Data buffer
unsigned length; // bytes used
unsigned capacity; // size of allocation
bool errorState; // did we lose a malloc in there?
public:
//
// Write will only fail if we're unable to reallocate the buffer. In this case
// the buffer will be reset to its empty state.
//
const NvU8 * getData() const { return data; }
NvU8 * getData() { return data; }
bool resize(unsigned newSize);
void memZero();
void reset();
unsigned getLength() const { return length; }
// Is in error state? This happens if malloc fails. Error state is
// held until reset is called.
bool isError() const;
Buffer(const Buffer & other);
Buffer(NvU8 * data, unsigned size);
Buffer & operator = (const Buffer & other);
Buffer();
~Buffer();
void swap(Buffer & other) {
swap_args(other.data, data);
swap_args(other.length, length);
swap_args(other.capacity, capacity);
swap_args(other.errorState, errorState);
}
bool operator== (const Buffer & other) const;
};
class Stream
{
protected:
Buffer * parent;
unsigned byteOffset;
public:
Stream(Buffer * buffer);
bool seek(unsigned where);
bool read(NvU8 * buffer, unsigned size);
bool write(NvU8 * buffer, unsigned size);
// returns error state of buffer
bool isError() const;
unsigned remaining();
unsigned offset();
};
void swapBuffers(Buffer & left, Buffer & right);
}
#endif //INCLUDED_DP_BUFFER_H

View File

@@ -0,0 +1,535 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_configcaps.h *
* Abstraction for basic caps registers *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_CONFIGCAPS_H
#define INCLUDED_DP_CONFIGCAPS_H
#include "dp_connector.h"
#include "dp_auxretry.h"
#include "dp_linkconfig.h"
#include "dp_regkeydatabase.h"
namespace DisplayPort
{
enum PowerState
{
PowerStateD0 = 1,
PowerStateD3 = 2,
PowerStateD3AuxOn = 5
};
// Extended caps = offset 0x80
enum DwnStreamPortType
{
DISPLAY_PORT = 0,
ANALOG_VGA,
DVI,
HDMI,
WITHOUT_EDID,
DISPLAY_PORT_PLUSPLUS
} ;
enum DwnStreamPortAttribute
{
RESERVED = 0,
IL_720_480_60HZ,
IL_720_480_50HZ,
IL_1920_1080_60HZ,
IL_1920_1080_50HZ,
PG_1280_720_60HZ,
PG_1280_720_50_HZ,
} ;
// DPCD Offset 102 enums
enum TrainingPatternSelectType
{
TRAINING_DISABLED,
TRAINING_PAT_ONE,
TRAINING_PAT_TWO,
TRAINING_PAT_THREE,
};
enum SymbolErrorSelectType
{
DISPARITY_ILLEGAL_SYMBOL_ERROR,
DISPARITY_ERROR,
ILLEGAL_SYMBOL_ERROR,
};
// DPCD Offset 1A1 enums
enum MultistreamHotplugMode
{
HPD_LONG_PULSE,
IRQ_HPD,
};
// DPCD Offset 220
enum TestPatternType
{
NO_PATTERN,
COLOR_RAMPS,
BLACK_WHITE,
COLOR_SQUARE,
} ;
// DPCD Offset 232, 233
enum ColorFormatType
{
RGB,
YCbCr_422,
YCbCr_444,
} ;
enum DynamicRangeType
{
VESA,
CEA,
} ;
enum YCBCRCoeffType
{
ITU601,
ITU709,
} ;
#define HDCP_BCAPS_SIZE (0x1)
#define HDCP_VPRIME_SIZE (0x14)
#define HDCP_KSV_FIFO_SIZE (0xF)
#define HDCP_KSV_FIFO_WINDOWS_RETRY (0x3)
#define HDCP22_BCAPS_SIZE (0x1)
// Bstatus DPCD offset 0x68029
#define HDCPREADY (0x1)
#define R0PRIME_AVAILABLE (0x2)
#define LINK_INTEGRITY_FAILURE (0x4)
#define REAUTHENTICATION_REQUEST (0x8)
struct BInfo
{
bool maxCascadeExceeded;
unsigned depth;
bool maxDevsExceeded;
unsigned deviceCount;
};
struct BCaps
{
bool repeater;
bool HDCPCapable;
};
enum
{
PHYSICAL_PORT_START = 0x0,
PHYSICAL_PORT_END = 0x7,
LOGICAL_PORT_START = 0x8,
LOGICAL_PORT_END = 0xF
};
class LaneStatus
{
public:
//
// Lane Status
// CAUTION: Only updated on IRQ/HPD right now
//
virtual bool getLaneStatusClockRecoveryDone(int lane) = 0; // DPCD offset 202, 203
virtual bool getLaneStatusSymbolLock(int lane)= 0;
virtual bool getInterlaneAlignDone() = 0;
virtual bool getDownStreamPortStatusChange() = 0;
};
class TestRequest
{
public:
virtual bool getPendingTestRequestTraining() = 0; // DPCD offset 218
virtual void getTestRequestTraining(LinkRate & rate, unsigned & lanes) = 0; // DPCD offset 219, 220
virtual bool getPendingAutomatedTestRequest() = 0; // DPCD offset 218
virtual bool getPendingTestRequestEdidRead() = 0; // DPCD offset 218
virtual bool getPendingTestRequestPhyCompliance() = 0; // DPCD offset 218
virtual LinkQualityPatternType getPhyTestPattern() = 0; // DPCD offset 248
virtual AuxRetry::status setTestResponse(bool ack, bool edidChecksumWrite = false) = 0;
virtual AuxRetry::status setTestResponseChecksum(NvU8 checksum) = 0;
};
class LegacyPort
{
public:
virtual DwnStreamPortType getDownstreamPortType() = 0;
virtual DwnStreamPortAttribute getDownstreamNonEDIDPortAttribute() = 0;
// For port type = HDMI
virtual NvU64 getMaxTmdsClkRate() = 0;
};
class LinkState
{
public:
//
// Link state
//
virtual bool isPostLtAdjustRequestSupported() = 0;
virtual void setPostLtAdjustRequestGranted(bool bGrantPostLtRequest) = 0;
virtual bool getIsPostLtAdjRequestInProgress() = 0; // DPCD offset 204
virtual TrainingPatternSelectType getTrainingPatternSelect() = 0; // DPCD offset 102
virtual bool setTrainingMultiLaneSet(NvU8 numLanes,
NvU8 *voltSwingSet,
NvU8 *preEmphasisSet) = 0;
virtual bool readTraining(NvU8* voltageSwingLane,
NvU8* preemphasisLane = 0,
NvU8* trainingScoreLane = 0,
NvU8* postCursor = 0,
NvU8 activeLaneCount = 0) = 0;
virtual bool isLaneSettingsChanged(NvU8* oldVoltageSwingLane,
NvU8* newVoltageSwingLane,
NvU8* oldPreemphasisLane,
NvU8* newPreemphasisLane,
NvU8 activeLaneCount) = 0;
virtual AuxRetry::status setIgnoreMSATimingParamters(bool msaTimingParamIgnoreEn) = 0;
virtual AuxRetry::status setLinkQualLaneSet(unsigned lane, LinkQualityPatternType linkQualPattern) = 0;
virtual AuxRetry::status setLinkQualPatternSet(LinkQualityPatternType linkQualPattern, unsigned laneCount = 0) = 0;
};
class LinkCapabilities
{
public:
//
// Physical layer feature set
//
virtual NvU64 getMaxLinkRate() = 0; // Maximum byte-block in Hz
virtual unsigned getMaxLaneCount() = 0; // DPCD offset 2
virtual unsigned getMaxLaneCountSupportedAtLinkRate(LinkRate linkRate) = 0;
virtual bool getEnhancedFraming() = 0;
virtual bool getSupportsNoHandshakeTraining() = 0;
virtual bool getMsaTimingparIgnored() = 0;
virtual bool getDownstreamPort(NvU8 *portType) = 0; // DPCD offset 5
virtual bool getSupportsMultistream() = 0; // DPCD offset 21h
virtual bool getNoLinkTraining() = 0; // DPCD offset 330h
virtual unsigned getPhyRepeaterCount() = 0; // DPCD offset F0002h
};
class OUI
{
public:
virtual bool getOuiSupported() = 0;
virtual AuxRetry::status setOuiSource(unsigned ouiId, const char * model, size_t modelNameLength, NvU8 chipRevision) = 0;
virtual bool getOuiSink(unsigned &ouiId, char * modelName, size_t modelNameBufferSize, NvU8 & chipRevision) = 0;
};
class HDCP
{
public:
virtual bool getBKSV(NvU8 *bKSV) = 0; // DPCD offset 0x68000
virtual bool getBCaps(BCaps &bCaps, NvU8 * rawByte = 0) = 0; // DPCD offset 0x68028
virtual bool getHdcp22BCaps(BCaps &bCaps, NvU8 * rawByte = 0) = 0; // DPCD offset 0x6921D
virtual bool getBinfo(BInfo &bInfo) = 0; // DPCD offset 0x6802A
// Generic interfaces for HDCP 1.x / 2.2
virtual bool getRxStatus(const HDCPState &hdcpState, NvU8 *data) = 0;
};
class DPCDHAL :
virtual public Object,
public TestRequest,
public LaneStatus,
public LinkState,
public LinkCapabilities,
public OUI,
public HDCP
{
public:
//
// Notifications of external events
// We sent IRQ/HPD events to the HAL so that it knows
// when to re-read the registers. All the remaining
// calls are either accessors to cached state (caps),
// or DPCD get/setters
//
virtual void notifyIRQ() = 0;
virtual void notifyHPD(bool status, bool bSkipDPCDRead = false) = 0;
virtual void populateFakeDpcd() = 0;
// DPCD override routines
virtual void overrideMaxLinkRate(NvU32 overrideMaxLinkRate) = 0;
virtual void overrideMaxLaneCount(NvU32 maxLaneCount) = 0;
virtual void skipCableBWCheck(NvU32 maxLaneAtHighRate, NvU32 maxLaneAtLowRate) = 0;
virtual void overrideOptimalLinkCfg(LinkRate optimalLinkRate, NvU32 optimalLaneCount) = 0;
virtual void overrideOptimalLinkRate(LinkRate optimalLinkRate) = 0;
virtual bool isDpcdOffline() = 0;
virtual void setAuxBus(AuxBus * bus) = 0;
virtual NvU32 getVideoFallbackSupported() = 0;
//
// Cached CAPS
// These are only re-read when notifyHPD is called
//
virtual unsigned getRevisionMajor() = 0;
virtual unsigned getRevisionMinor() = 0;
virtual unsigned lttprGetRevisionMajor() = 0;
virtual unsigned lttprGetRevisionMinor() = 0;
virtual bool getSDPExtnForColorimetry() = 0;
bool isAtLeastVersion(unsigned major, unsigned minor)
{
if (getRevisionMajor() > major)
return true;
if (getRevisionMajor() < major)
return false;
return getRevisionMinor() >= minor;
}
bool isVersion(unsigned major, unsigned minor)
{
if ((getRevisionMajor() == major) &&
(getRevisionMinor() == minor))
return true;
return false;
}
bool lttprIsAtLeastVersion(unsigned major, unsigned minor)
{
if (lttprGetRevisionMajor() > major)
return true;
if (lttprGetRevisionMinor() < major)
return false;
return lttprGetRevisionMinor() >= minor;
}
bool lttprIsVersion(unsigned major, unsigned minor)
{
if ((lttprGetRevisionMajor() == major) &&
(lttprGetRevisionMinor() == minor))
return true;
return false;
}
// Convert Link Bandwidth read from DPCD register to Linkrate
NvU64 mapLinkBandiwdthToLinkrate(NvU32 linkBandwidth)
{
if (FLD_TEST_DRF(_DPCD, _MAX_LINK_BANDWIDTH, _VAL, _1_62_GBPS, linkBandwidth))
return RBR;
else if (FLD_TEST_DRF(_DPCD, _MAX_LINK_BANDWIDTH, _VAL, _2_70_GBPS, linkBandwidth))
return HBR;
else if (FLD_TEST_DRF(_DPCD, _MAX_LINK_BANDWIDTH, _VAL, _5_40_GBPS, linkBandwidth))
return HBR2;
else if (FLD_TEST_DRF(_DPCD14, _MAX_LINK_BANDWIDTH, _VAL, _8_10_GBPS, linkBandwidth))
return HBR3;
else
{
DP_ASSERT(0 && "Unknown link bandwidth. Assuming HBR");
return HBR;
}
}
//
// Native aux transaction size (16 for AUX)
//
virtual size_t getTransactionSize() = 0;
//
// SST Branching device/dongle/repeater
// - Describes downstream port limitations
// - Not for use with MST
// - Primarily used for dongles (look at port 0 for pclk limits)
//
virtual LegacyPort * getLegacyPort(unsigned index) = 0;
virtual unsigned getLegacyPortCount() = 0;
virtual PCONCaps * getPCONCaps() = 0;
//
// Single stream specific caps
//
virtual unsigned getNumberOfAudioEndpoints() = 0;
virtual int getSinkCount() = 0;
virtual void setSinkCount(int sinkCount) = 0;
//
// MISC
//
virtual bool isPC2Disabled() = 0;
virtual void setPC2Disabled(bool disabled) = 0;
virtual void setDPCDOffline(bool enable) = 0;
virtual void updateDPCDOffline() = 0;
virtual void setSupportsESI(bool bIsESISupported) = 0;
virtual void setLttprSupported(bool isLttprSupported) = 0;
//
// Intermediate Link Rate (eDP ILR)
//
virtual void setIndexedLinkrateEnabled(bool newVal) = 0;
virtual bool isIndexedLinkrateEnabled() = 0;
virtual bool isIndexedLinkrateCapable() = 0;
virtual NvU16 *getLinkRateTable() = 0;
virtual bool getRawLinkRateTable(NvU8 *buffer = NULL) = 0;
//
// Link power state management
//
virtual bool setPowerState(PowerState newState) = 0;
virtual PowerState getPowerState() = 0;
//
// Multistream
//
virtual bool getGUID(GUID & guid) = 0; // DPCD offset 30
virtual AuxRetry::status setGUID(GUID & guid) = 0;
virtual AuxRetry::status setMessagingEnable(bool uprequestEnable, bool upstreamIsSource) = 0;
virtual AuxRetry::status setMultistreamLink(bool bMultistream) = 0;
virtual void payloadTableClearACT() = 0;
virtual bool payloadWaitForACTReceived() = 0;
virtual bool payloadAllocate(unsigned streamId, unsigned begin, unsigned count) = 0;
virtual bool clearPendingMsg() = 0;
virtual bool isMessagingEnabled() = 0;
//
// If set to IRQ we'll receive CSN messages on hotplugs (which are actually easy to miss).
// If set to HPD mode we'll always receive an HPD whenever the topology changes.
// The library supports using both modes.
//
virtual AuxRetry::status setMultistreamHotplugMode(MultistreamHotplugMode notifyType) = 0;
//
// Interrupts
//
virtual bool interruptContentProtection() = 0;
virtual void clearInterruptContentProtection() = 0;
virtual bool intteruptMCCS() = 0;
virtual void clearInterruptMCCS() = 0;
virtual bool interruptDownReplyReady() = 0;
virtual void clearInterruptDownReplyReady() = 0;
virtual bool interruptUpRequestReady() = 0;
virtual void clearInterruptUpRequestReady() = 0;
virtual bool interruptCapabilitiesChanged() = 0;
virtual void clearInterruptCapabilitiesChanged() = 0;
virtual bool getLinkStatusChanged() = 0;
virtual void clearLinkStatusChanged() = 0;
virtual bool getHdmiLinkStatusChanged() = 0;
virtual void clearHdmiLinkStatusChanged() = 0;
virtual bool getStreamStatusChanged() = 0;
virtual void clearStreamStatusChanged() =0;
virtual void setDirtyLinkStatus(bool dirty) = 0;
virtual void refreshLinkStatus() = 0;
virtual bool isLinkStatusValid(unsigned lanes) = 0;
virtual void getCustomTestPattern(NvU8 *testPattern) = 0; // DPCD offset 250 - 259
//
// Message Boxes
//
virtual AuxRetry::status writeDownRequestMessageBox(NvU8 * data, size_t length) = 0;
virtual size_t getDownRequestMessageBoxSize() = 0;
virtual AuxRetry::status writeUpReplyMessageBox(NvU8 * data, size_t length) = 0;
virtual size_t getUpReplyMessageBoxSize() = 0;
virtual AuxRetry::status readDownReplyMessageBox(NvU32 offset, NvU8 * data, size_t length) = 0;
virtual size_t getDownReplyMessageBoxSize() = 0;
virtual AuxRetry::status readUpRequestMessageBox(NvU32 offset, NvU8 * data, size_t length) = 0;
virtual size_t getUpRequestMessageBoxSize() = 0;
// MST<->SST override
virtual void overrideMultiStreamCap(bool mstCapable) = 0;
virtual bool getMultiStreamCapOverride() = 0;
virtual bool getDpcdMultiStreamCap(void) = 0;
// Set GPU DP support capability
virtual void setGpuDPSupportedVersions(bool supportDp1_2, bool supportDp1_4) = 0;
// Set GPU FEC support capability
virtual void setGpuFECSupported(bool bSupportFEC) = 0;
virtual void applyRegkeyOverrides(const DP_REGKEY_DATABASE& dpRegkeyDatabase) = 0;
// PCON configuration
// Reset PCON (to default state)
virtual void resetProtocolConverter() = 0;
// Source control mode and FRL/HDMI mode selection.
virtual bool setSourceControlMode(bool bEnableSourceControlMode, bool bEnableFRLMode) = 0;
virtual bool checkPCONFrlReady(bool *bFrlReady) = 0;
virtual bool setupPCONFrlLinkAssessment(NvU32 linkBw,
bool bEnableExtendLTMode = false,
bool bEnableConcurrentMode = false) = 0;
virtual bool checkPCONFrlLinkStatus(NvU32 *frlRate) = 0;
virtual bool queryHdmiLinkStatus(bool *bLinkActive, bool *bLinkReady) = 0;
virtual NvU32 restorePCONFrlLink(NvU32 linkBwMask,
bool bEnableExtendLTMode = false,
bool bEnableConcurrentMode = false) = 0;
virtual void readPsrCapabilities(vesaPsrSinkCaps *caps) = 0;
virtual bool updatePsrConfiguration(vesaPsrConfig config) = 0;
virtual bool readPsrConfiguration(vesaPsrConfig *config) = 0;
virtual bool readPsrState(vesaPsrState *psrState) = 0;
virtual bool readPsrDebugInfo(vesaPsrDebugStatus *psrDbgState) = 0;
virtual bool writePsrErrorStatus(vesaPsrErrorStatus psrErr) = 0;
virtual bool readPsrErrorStatus(vesaPsrErrorStatus *psrErr) = 0;
virtual bool writePsrEvtIndicator(vesaPsrEventIndicator psrErr) = 0;
virtual bool readPsrEvtIndicator(vesaPsrEventIndicator *psrErr) = 0;
virtual ~DPCDHAL() {}
};
//
// Implement interface
//
DPCDHAL * MakeDPCDHAL(AuxBus * bus, Timer * timer);
}
#endif //INCLUDED_DP_CONFIGCAPS_H

View File

@@ -0,0 +1,678 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_connector.h *
* This is the primary client interface. *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_CONNECTOR_H
#define INCLUDED_DP_CONNECTOR_H
#include "dp_auxdefs.h"
#include "dp_object.h"
#include "dp_mainlink.h"
#include "dp_auxbus.h"
#include "dp_address.h"
#include "dp_guid.h"
#include "dp_evoadapter.h"
#include "dp_auxbus.h"
#include "dp_auxretry.h"
#include "displayport.h"
#include "dp_vrr.h"
#include "../../modeset/timing/nvt_dsc_pps.h"
#include "ctrl/ctrl0073/ctrl0073dp.h"
namespace DisplayPort
{
class EvoInterface;
typedef enum
{
DP_TESTMESSAGE_STATUS_SUCCESS = 0,
DP_TESTMESSAGE_STATUS_ERROR = 0xDEADBEEF,
DP_TESTMESSAGE_STATUS_ERROR_INSUFFICIENT_INPUT_BUFFER = 0xDEADBEED,
DP_TESTMESSAGE_STATUS_ERROR_INVALID_PARAM = 0xDEADBEEC
// new error code should be here
} DP_TESTMESSAGE_STATUS;
typedef enum
{
False = 0,
True = 1,
Indeterminate = 2
} TriState;
enum ConnectorType
{
connectorDisplayPort,
connectorHDMI,
connectorDVI,
connectorVGA
};
typedef struct portMap
{
NvU16 validMap; // port i is valid = bit i is high
NvU16 inputMap; // port i is input port = bit i is high && validMap bit i is high
NvU16 internalMap; // port i is internal = bit i is high && validMap bit i is high
} PortMap;
enum ForceDsc
{
DSC_DEFAULT,
DSC_FORCE_ENABLE,
DSC_FORCE_DISABLE
};
struct DpModesetParams
{
unsigned headIndex;
ModesetInfo modesetInfo;
DP_COLORFORMAT colorFormat;
NV0073_CTRL_CMD_DP_SET_MSA_PROPERTIES_PARAMS msaparams;
DpModesetParams() : headIndex(0), modesetInfo(), colorFormat(dpColorFormat_Unknown), msaparams() {}
DpModesetParams(unsigned newHeadIndex,
ModesetInfo newModesetInfo,
DP_COLORFORMAT newColorFormat = dpColorFormat_Unknown) :
headIndex(newHeadIndex),
modesetInfo(newModesetInfo),
colorFormat(newColorFormat),
msaparams() {}
DpModesetParams(unsigned newHeadIndex,
ModesetInfo *newModesetInfo,
DP_COLORFORMAT newColorFormat = dpColorFormat_Unknown) :
headIndex(newHeadIndex),
modesetInfo(*newModesetInfo),
colorFormat(newColorFormat),
msaparams() {}
};
struct DscOutParams
{
unsigned PPS[DSC_MAX_PPS_SIZE_DWORD]; // Out - PPS SDP data
};
struct DscParams
{
bool bCheckWithDsc; // [IN] - Client telling DP Library to check with DSC.
ForceDsc forceDsc; // [IN] - Client telling DP Library to force enable/disable DSC
DSC_INFO::FORCED_DSC_PARAMS* forcedParams; // [IN] - Client telling DP Library to force certain DSC params.
bool bEnableDsc; // [OUT] - DP Library telling client that DSC is needed for this mode.
unsigned bitsPerPixelX16; // [IN/OUT] - Bits per pixel value multiplied by 16
DscOutParams *pDscOutParams; // [OUT] - DSC parameters
DscParams() : bCheckWithDsc(false), forceDsc(DSC_DEFAULT), forcedParams(NULL), bEnableDsc(false), bitsPerPixelX16(0), pDscOutParams(NULL) {}
};
class Group;
bool SetConfigSingleHeadMultiStreamMode(Group **targets, // Array of group pointers given for getting configured in single head multistream mode.
NvU32 displayIDs[], // Array of displayIDs given for getting configured in single head multistream mode.
NvU32 numStreams, // Number of streams driven out from single head.
DP_SINGLE_HEAD_MULTI_STREAM_MODE mode, // Configuration mode : SST or MST
bool bSetConfig, // Set or clear the configuration.
NvU8 vbiosPrimaryDispIdIndex = DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID_PRIMARY, // VBIOS primary display ID index in displayIDs[] array
bool bEnableAudioOverRightPanel = false); // Audio MUX config : right or left panel
//
// Device object
// This object represents a displayport device. Devices are not reported
// to clients until the EDID is already on file.
//
class Device : virtual public Object
{
public:
virtual bool isPlugged() = 0;
virtual bool isVideoSink() = 0; // Invariant: won't change once reported
virtual bool isAudioSink() = 0; // Invariant
virtual bool isLoop() = 0; // the address starts and ends at th same device
virtual bool isRedundant() = 0;
virtual bool isMustDisconnect() = 0; // Is this monitor's head being attach preventing
// us from enumerating other panels?
virtual bool isZombie() = 0; // Head is attached but we're not connected
virtual bool isCableOk() = 0; // cable can be not ok, whenwe saw hpd, device connected, but can't talk over aux
virtual bool isLogical() = 0; // Is device connected to logical port
virtual Address getTopologyAddress() const = 0; // Invariant
virtual bool isMultistream() = 0;
virtual ConnectorType getConnectorType() = 0; // Invariant
virtual unsigned getEDIDSize() const= 0; // Invariant
// Copies EDID into client buffer. Fails if the buffer is too small
virtual bool getEDID(char * buffer, unsigned size) const = 0;
virtual unsigned getRawEDIDSize() const= 0;
// Copies RawEDID into client buffer. Fails if the buffer is too small
virtual bool getRawEDID(char * buffer, unsigned size) const = 0;
virtual bool getPCONCaps(PCONCaps *pPCONCaps) = 0;
virtual bool isFallbackEdid() = 0; // is the device edid a fallback one?
virtual GUID getGUID() const = 0; // Returns the GUID for the device
virtual bool isPowerSuspended() = 0;
virtual bool isActive() = 0; // Whether the device has a head attached to it
virtual TriState hdcpAvailableHop() = 0; // Whether the device support HDCP,
// regardless of whether the path leading to it supports HDCP.
virtual TriState hdcpAvailable() = 0; // Whether HDCP can be enabled.
// Note this checks that the entire path to the node support HDCP.
virtual PortMap getPortMap() const = 0;
virtual void setPanelPowerParams(bool bSinkPowerStateD0, bool bPanelPowerStateOn) = 0;
virtual Group * getOwningGroup() = 0; // Return the group this device is currently a member of
virtual AuxBus * getRawAuxChannel() = 0; // No automatic retry on DEFER. See limitations in dp_auxbus.h
virtual AuxRetry * getAuxChannel() = 0; // User friendly AUX interface
virtual Device * getParent() = 0;
virtual Device * getChild(unsigned portNumber) = 0;
virtual void dpcdOverrides() = 0; // Apply DPCD overrides if required
virtual bool getDpcdRevision(unsigned * major, unsigned * minor) = 0; // get the dpcd revision (maybe cached)
virtual bool getSDPExtnForColorimetrySupported() = 0;
virtual bool getIgnoreMSACap() = 0;
virtual AuxRetry::status setIgnoreMSAEnable(bool msaTimingParamIgnoreEn) = 0;
virtual NvBool isDSCPossible() = 0;
virtual NvBool isDSCSupported() = 0;
virtual DscCaps getDscCaps() = 0;
//
// This function returns the device itself or its parent device that is doing
// DSC decompression for it.
//
virtual Device* getDevDoingDscDecompression() = 0;
virtual void markDeviceForDeletion() = 0;
virtual bool getRawDscCaps(NvU8 *buffer, NvU32 bufferSize) = 0;
// This interface is still nascent. Please don't use it. Read size limit is 16 bytes.
virtual AuxBus::status getDpcdData(unsigned offset, NvU8 * buffer,
unsigned sizeRequested,
unsigned * sizeCompleted,
unsigned * pNakReason = NULL) = 0;
virtual AuxBus::status setDpcdData(unsigned offset, NvU8 * buffer,
unsigned sizeRequested,
unsigned * sizeCompleted,
unsigned * pNakReason = NULL) = 0;
virtual AuxBus::status dscCrcControl(NvBool bEnable, gpuDscCrc *gpuData, sinkDscCrc *sinkData) = 0;
virtual AuxBus::status queryFecData(NvU8 *fecStatus, NvU16 **fecErrorCount, NvU32 flags) = 0;
//
// The address send here will be right shifted by the library. DD should
// send the DDC address without the shift.
// Parameter bForceMot in both getI2cData and setI2cData is used to forfully set
// the MOT bit. It is needed for some special cases where the MOT bit shouldn't
// be set but some customers need it to please their monitors.
//
virtual bool getI2cData(unsigned offset, NvU8 * buffer, unsigned sizeRequested, unsigned * sizeCompleted, bool bForceMot = false) = 0;
virtual bool setI2cData(unsigned offset, NvU8 * buffer, unsigned sizeRequested, unsigned * sizeCompleted, bool bForceMot = false) = 0;
//
// Calls VRR enablement implementation in dp_vrr.cpp.
// The enablement steps include interaction over DPAux in the vendor specific
// DPCD space.
//
virtual bool startVrrEnablement() = 0; // VF: calls actual enablement code.
virtual void resetVrrEnablement() = 0; // VF: resets enablement state.
virtual bool isVrrMonitorEnabled() = 0; // VF: gets monitor enablement state.
virtual bool isVrrDriverEnabled() = 0; // VF: gets driver enablement state.
// If the sink support MSA override in MST environment.
virtual bool isMSAOverMSTCapable() = 0;
virtual bool isFakedMuxDevice() = 0;
protected:
virtual ~Device() {}
};
class Group : virtual public Object
{
public:
//
// Routines for changing which panels are in a group. To move a stream to a new
// monitor without a modeset:
// remove(old_panel)
// insert(new_panel)
// The library will automatically switch over to the new configuration
//
virtual void insert(Device * dev) = 0;
virtual void remove(Device * dev) = 0;
//
// group->enumDevices(0) - Get first element
// group->enumDevices(i) - Get next element
//
// for (Device * i = group->enumDevices(0); i; i = group->enumDevices(i))
//
virtual Device * enumDevices(Device * previousDevice) = 0;
virtual void destroy() = 0; // Destroy the group object
// Toggles the encryption status for the stream.
// Returns whether encryption is currently enabled.
virtual bool hdcpGetEncrypted() = 0;
protected:
virtual ~Group() {}
};
class Connector : virtual public Object
{
public:
//
// Normally the Connector::EventSink callsback can occur in response to the following
// 1. Timer callbacks
// 2. notifyLongPulse/notifyShortPulse
//
class EventSink
{
public:
virtual void newDevice(Device * dev) = 0; // New device appears in topology
virtual void lostDevice(Device * dev) = 0; // Lost device from topology
// Device object ceases to exist after this call
virtual void notifyMustDisconnect(Group * grp) = 0; // Notification that an attached head is preventing
// us from completing detection of a newly connected device
virtual void notifyDetectComplete() = 0; // Rolling call. Happens every time we've done another full
// detect on the topology
virtual void bandwidthChangeNotification(Device * dev, bool isComplianceMode) = 0; // Available bandwidth to panel has changed, or panel has
// become a zombie
virtual void notifyZombieStateChange(Device * dev, bool zombied) = 0; // Notification that zombie device was attached or dettached
virtual void notifyCableOkStateChange(Device * dev, bool cableOk) = 0; // Notification that device got cable state chagne (true - cable is good, false - cables is bad)
virtual void notifyHDCPCapDone(Device * dev, bool hdcpCap) = 0; // Notification that device's HDCP cap detection is done and get state change.
virtual void notifyMCCSEvent(Device * dev) = 0; // Notification that an MCCS event is coming
};
// Query current Device topology
virtual Device * enumDevices(Device * previousDevice) = 0;
// Called before system enters an S3 state
virtual void pause() = 0;
// Get maximum link configuration
virtual LinkConfiguration getMaxLinkConfig() = 0;
// Get currently active link configuration
virtual LinkConfiguration getActiveLinkConfig() = 0;
// Get Current link configuration
virtual void getCurrentLinkConfig(unsigned & laneCount, NvU64 & linkRate) = 0;
// Get the clock calculation supported by the panel
virtual unsigned getPanelDataClockMultiplier() = 0;
// Get the clock calculation supported by the GPU
virtual unsigned getGpuDataClockMultiplier() = 0;
// Resume from standby/initial boot notification
// The library is considered to start up in the suspended state. You must make this
// API call to enable the library. None of the library APIs are functional before
// this call.
//
// Returns the group representing the firmware panel if any is active.
//
// plugged Does RM report the root-port DisplayId in
// its plugged connector mask
//
// firmwareLinkHandsOff RM does NOT report the rootport displayId as active,
// but one of the active panels shares the same SOR.
//
// firmwareDPActive RM reports the rootport displayId in the active device list
// but display-driver hasn't yet performed its first modeset.
//
// isUefiSystem DD tells the library whether this system is a UEFI based
// one so that the library can get the current and max link config
// from RM/UEFI instead of trying to determine them on its own.
//
// firmwareHead Head being used to drive the firmware
// display, if firmwareDPActive is true.
//
// bFirmwareLinkUseMultistream
// Specifies whether the firmware connector is being driven in SST
// (false) or MST (true) mode.
//
// bDisableVbiosScratchRegisterUpdate
// Disables update of
// NV_PDISP_SOR_DP_SCRATCH_RAD/MISC scratch
// pad registers with last lit up display
// address. This address is used by VBIOS in
// case of driver unload or BSOD.
//
// bAllowMST Allow/Disallow Multi-streaming
//
virtual Group * resume(bool firmwareLinkHandsOff,
bool firmwareDPActive,
bool plugged,
bool isUefiSystem = false,
unsigned firmwareHead = 0,
bool bFirmwareLinkUseMultistream = false,
bool bDisableVbiosScratchRegisterUpdate = false,
bool bAllowMST = true) = 0;
// The display-driver should enable hands off mode when attempting
// to use a shared resource (such as the SOR) in a non-DP configuration.
virtual void enableLinkHandsOff() = 0;
virtual void releaseLinkHandsOff() = 0;
// Usage scenario:
// beginCompoundQuery()
// compoundQueryAttach(1280x1024)
// compoundQueryAttach(1920x1080)
// .endCompoundQuery()
// Will tell you if you have sufficient bandwidth to operate
// two panels at 1920x1080 and 1280x1024 assuming all currently
// attached panels are detached.
virtual void beginCompoundQuery() = 0;
//
// twoChannelAudioHz
// If you need 192khz stereo specify 192000 here.
//
// eightChannelAudioHz
// Same setting for multi channel audio.
// DisplayPort encodes 3-8 channel streams as 8 channel
//
// pixelClockHz
// Requested pixel clock for the mode
//
// depth
// Requested color depth
//
virtual bool compoundQueryAttach(Group * target,
unsigned twoChannelAudioHz,
unsigned eightChannelAudioHz,
NvU64 pixelClockHz,
unsigned rasterWidth,
unsigned rasterHeight,
unsigned rasterBlankStartX,
unsigned rasterBlankEndX,
unsigned depth) = 0;
virtual bool compoundQueryAttach(Group * target,
const DpModesetParams &modesetParams, // Modeset info
DscParams *pDscParams) = 0; // DSC parameters
virtual bool endCompoundQuery() = 0;
// Interface to indicate if clients need to perform a head shutdown before a modeset
virtual bool isHeadShutDownNeeded(Group * target, // Group of panels we're attaching to this head
unsigned headIndex,
unsigned twoChannelAudioHz, // if you need 192khz stereo specify 192000 here
unsigned eightChannelAudioHz, // Same setting for multi channel audio.
// DisplayPort encodes 3-8 channel streams as 8 channel
NvU64 pixelClockHz, // Requested pixel clock for the mode
unsigned rasterWidth,
unsigned rasterHeight,
unsigned rasterBlankStartX,
unsigned rasterBlankEndX,
unsigned depth) = 0;
// Interface to indicate if clients need to perform a head shutdown before a modeset
virtual bool isHeadShutDownNeeded(Group * target, // Group of panels we're attaching to this head
unsigned headIndex,
ModesetInfo modesetInfo) = 0; // Modeset info relevant DSC data
//
// Interface for clients to query library if the link is going to be trained during notifyAttachBegin(modeset).
// Note: This API is not intended to know if a link training will be performed during assessment of the link.
// This API is added to see if library can avoid link training during modeset so that client can take necessary decision
// to avoid a destructive modeset from UEFI mode at post to a GPU driver detected mode
// (thus prevent a visible glitch - i.e. Smooth Transition)
//
// How isLinkTrainingNeededForModeset API is different from isHeadShutDownNeeded API -
// In case of MST : we always shutdown head and link train if link is inactive, so both APIs return TRUE
// In case of SST :
// - If requested link config < active link config, we shutdown head to prevent overflow
// as head will still be driving at higher mode during link training to lower mode
// So both APIs return TRUE
// - If requested link config >= active link config, we don't need a head shutdown since
// SOR clocks can be changed by entering flush mode but will need to link train for mode change
// So isHeadShutDownNeeded returns FALSE and isLinkTrainingNeededForModeset returns TRUE
//
virtual bool isLinkTrainingNeededForModeset (ModesetInfo modesetInfo) = 0;
// Notify library before/after modeset (update)
virtual bool notifyAttachBegin(Group * target, // Group of panels we're attaching to this head
unsigned headIndex,
unsigned twoChannelAudioHz, // if you need 192khz stereo specify 192000 here
unsigned eightChannelAudioHz, // Same setting for multi channel audio.
// DisplayPort encodes 3-8 channel streams as 8 channel
NvU64 pixelClockHz, // Requested pixel clock for the mode
unsigned rasterWidth,
unsigned rasterHeight,
unsigned rasterBlankStartX,
unsigned rasterBlankEndX,
unsigned depth) = 0;
// Group of panels we're attaching to this head
virtual bool notifyAttachBegin(Group * target, const DpModesetParams &modesetParams) = 0;
virtual void readRemoteHdcpCaps() = 0;
// modeset might be cancelled when NAB failed
virtual void notifyAttachEnd(bool modesetCancelled) = 0;
//
// Client needs to be notified about the SST<->MST transition,
// based on which null modeset will be sent.
//
virtual bool isLinkAwaitingTransition() = 0;
virtual void resetLinkTrainingCounter() = 0;
// Notify library before/after shutdown (update)
virtual void notifyDetachBegin(Group * target) = 0;
virtual void notifyDetachEnd(bool bKeepOdAlive = false) = 0;
// Notify library to assess PCON link capability
virtual bool assessPCONLinkCapability(PCONLinkControl *params) = 0;
// Notify library of hotplug/IRQ
virtual void notifyLongPulse(bool statusConnected) = 0;
virtual void notifyShortPulse() = 0;
// Notify Library when ACPI initialization is done
virtual void notifyAcpiInitDone() = 0;
// Notify Library when GPU capability changes. Usually because power event.
virtual void notifyGPUCapabilityChange() = 0;
virtual void notifyHBR2WAREngage() = 0;
// Create a new Group. Note that if you wish to do a modeset but send the
// stream nowhere, you may do a modeset with an EMPTY group. This is expected
// to be the mechanism by which monitor faking is implemented.
virtual Group * newGroup() = 0;
// Shutdown and the destroy the connector manager
virtual void destroy() = 0;
virtual void createFakeMuxDevice(const NvU8 *buffer, NvU32 bufferSize) = 0;
virtual void deleteFakeMuxDevice() = 0;
virtual bool getRawDscCaps(NvU8 *buffer, NvU32 bufferSize) = 0;
//
// OS Modeset Order mitigation causes the library to delay the reporting
// of new devices until they can be safely turned on.
// When enabled the library client will not see connection events until
// MustDisconnect messages are processed.
//
// Policy state should be set before the library is brought out of
// the suspended state.
//
// Important Note: This option changes the definition of QueryMode.
// Without OS order mitigation query mode assumes that you will
// deatach all of the heads from any zombied monitors *before*
// activating the new panel. If your driver cannot guarantee
// this invariant, then it must enable order mitigation.
//
virtual void setPolicyModesetOrderMitigation(bool enabled) = 0;
//
// force LT at NAB for compliance test (Power Management) in Win10 RS2+ (WDDM 2.2)
//
// RS2 no longer sends an explicit call for setPanelPowerParams during the Resume.
// It does that by specifying an additional flag during the call to SetTimings. Due to
// this DP lib doesn't get chance to perform this transition from setPanelPowerParams
// and since it was already skipping LT in NAB/modeswitch, so LT get missed out on the
// compliance device during resume from S3/S4.
//
virtual void setPolicyForceLTAtNAB(bool enabled) = 0;
//
// There are cases where OS does not detach heads from connector immediately after hot-unplug,
// on next hot-plug there is no guarantee that newly connected sink is capable to drive existing
// raster timings. Flush mode has following restriction
// When exiting flush mode S/W should ensure that the final
// link clock & lane count should be able to support existing raster.
// If we run into this situation and use flush mode then that will cause display engine to hang.
// This variable ensures to assess link safely in this situation and instead of using flush mode ask
// DD to detach/reattach heads for link training.
//
virtual void setPolicyAssessLinkSafely(bool enabled) = 0;
//
// These interfaces are meant to be used *ONLY* for tool purposes.
// Clients should *NOT* use them for their own implementation.
//
// Sets the preferred link config which the tool has requested to train to.
// Each set call should be paired with a reset call. Also, preferred link configs won't persist across HPDs.
// It is advisable to do compound queries before setting a mode on a preferred config.
// Compound queries and notify attaches(link train) would use the preferred link config unless it is reset again.
// (not advisable to leave a preferred link config always ON).
//
virtual bool setPreferredLinkConfig(LinkConfiguration & lc, bool commit,
bool force = false,
LinkTrainingType forceTrainType = NORMAL_LINK_TRAINING) = 0;
//
// Resets the preferred link config and lets the library go back to default LT policy.
// Should follow a previous set call.
//
virtual bool resetPreferredLinkConfig(bool force=false) = 0;
//
// These interfaces are used by client to allow/disallow
// Multi-streaming.
//
// If connected sink is MST capable then:
// Client should detach all active MST video/audio streams before
// disallowing MST, vise-versa client should detach active SST
// stream before allowing MST.
//
virtual void setAllowMultiStreaming(bool bAllowMST) = 0;
virtual bool getAllowMultiStreaming(void) = 0;
// This function reads sink MST capability from DPCD register(s).
virtual bool getSinkMultiStreamCap(void) = 0;
// These interfaces are Deprecated, use setAllowMultiStreaming()
virtual void setDp11ProtocolForced() = 0;
virtual void resetDp11ProtocolForced() = 0;
virtual bool isDp11ProtocolForced() = 0;
virtual bool getHDCPAbortCodesDP12(NvU32 &hdcpAbortCodesDP12) = 0;
virtual bool getOuiSink(unsigned &ouiId, char * modelName,
size_t modelNameBufferSize, NvU8 & chipRevision) = 0;
virtual bool getIgnoreSourceOuiHandshake() = 0;
virtual void setIgnoreSourceOuiHandshake(bool bIgnore) = 0;
//
// The following function is to be used to get the capability bit that tells the client whether the connector
// can do multistream.
//
virtual bool isMultiStreamCapable() = 0;
virtual bool isFlushSupported() = 0;
virtual bool isStreamCloningEnabled() = 0;
virtual NvU32 maxLinkRateSupported() = 0;
virtual bool isFECSupported() = 0;
virtual bool isFECCapable() = 0;
// Following APIs are for link test/config for DP Test Utility
virtual bool getTestPattern(NV0073_CTRL_DP_TESTPATTERN *pTestPattern) = 0;
virtual bool setTestPattern(NV0073_CTRL_DP_TESTPATTERN testPattern,
NvU8 laneMask, NV0073_CTRL_DP_CSTM cstm,
NvBool bIsHBR2, NvBool bSkipLaneDataOverride) = 0;
// "data" is an array of NV0073_CTRL_MAX_LANES unsigned ints
virtual bool getLaneConfig(NvU32 *numLanes, NvU32 *data) = 0;
// "data" is an array of NV0073_CTRL_MAX_LANES unsigned ints
virtual bool setLaneConfig(NvU32 numLanes, NvU32 *data) = 0;
virtual DP_TESTMESSAGE_STATUS sendDPTestMessage(void *pBuffer,
NvU32 requestSize,
NvU32 *pDpStatus) = 0;
virtual DP_TESTMESSAGE_STATUS getStreamIDs(NvU32 *pStreamIDs, NvU32 *pCount) = 0;
// Function to configure power up/down for DP Main Link
virtual void configurePowerState(bool bPowerUp) = 0;
virtual void readPsrCapabilities(vesaPsrSinkCaps *caps) = 0;
virtual bool updatePsrConfiguration(vesaPsrConfig config) = 0;
virtual bool readPsrConfiguration(vesaPsrConfig *config) = 0;
virtual bool readPsrState(vesaPsrState *psrState) = 0;
virtual bool readPsrDebugInfo(vesaPsrDebugStatus *psrDbgState) = 0;
virtual bool writePsrErrorStatus(vesaPsrErrorStatus psrErr) = 0;
virtual bool readPsrErrorStatus(vesaPsrErrorStatus *psrErr) = 0;
virtual bool writePsrEvtIndicator(vesaPsrEventIndicator psrErr) = 0;
virtual bool readPsrEvtIndicator(vesaPsrEventIndicator *psrErr) = 0;
virtual bool updatePsrLinkState(bool bTrainLink) = 0;
protected:
virtual ~Connector() {}
};
//
// Library routine to create primary port interface
// (Not intended to be used by display driver)
Connector * createConnector(MainLink * mainInterface, // DisplayDriver implemented MainLink object
AuxBus * auxInterface, // DisplayDriver implemented AuxRetry wrapper
Timer * timerInterface, // DisplayDriver provided Timer services
Connector::EventSink * sink); // Interface to notify DisplayDriver of events
}
#endif //INCLUDED_DP_CONNECTOR_H

View File

@@ -0,0 +1,632 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_connectorimpl.cpp *
* DP connector implementation *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_CONNECTORIMPL_H
#define INCLUDED_DP_CONNECTORIMPL_H
#include "dp_internal.h"
#include "dp_guid.h"
#include "dp_connector.h"
#include "dp_configcaps.h"
#include "dp_list.h"
#include "dp_buffer.h"
#include "dp_auxdefs.h"
#include "dp_watermark.h"
#include "dp_edid.h"
#include "dp_discovery.h"
#include "dp_groupimpl.h"
#include "dp_deviceimpl.h"
#include "./dptestutil/dp_testmessage.h"
// HDCP abort codes
#define HDCP_FLAGS_ABORT_DEVICE_REVOKED 0x00000800 // Abort due to a revoked device in DP1.2 topology
#define HDCP_FLAGS_ABORT_DEVICE_INVALID 0x00080000 // Abort due to an invalid device in DP1.2 topology
#define HDCP_FLAGS_ABORT_HOP_LIMIT_EXCEEDED 0x80000000 // Abort, number of devices in DP1.2 topology exceeds supported limit
static inline unsigned getDataClockMultiplier(NvU64 linkRate, NvU64 laneCount)
{
//
// To get the clock multiplier:
// - Convert the linkRate from Hz to 10kHz by dividing it by 10000.
// - Multiply the 10kHz linkRate by the laneCount.
// - Multiply by 10.0/8, to account for the 8b/10b encoding overhead in the DP protocol layer.
//
// Avoid floating point in the arithmetic in the calculation
// through the following conversions:
// linkRate/10000.0 * laneCount * 10.0/8
// (linkRate * laneCount * 10) / (10000 * 8)
// (linkRate * laneCount) / (1000 * 8)
//
return (unsigned) DisplayPort::axb_div_c_64(linkRate, laneCount, 8000);
}
namespace DisplayPort
{
typedef enum
{
DP_TRANSPORT_MODE_INIT = 0,
DP_TRANSPORT_MODE_SINGLE_STREAM = 1,
DP_TRANSPORT_MODE_MULTI_STREAM = 2,
} DP_TRANSPORT_MODE;
struct ConnectorImpl : public Connector, DiscoveryManager::DiscoveryManagerEventSink, Timer::TimerCallback, MessageManager::MessageReceiver::MessageReceiverEventSink
{
// DPCD HAL Layer - We should use this in place of direct register accesses
DPCDHAL * hal;
MainLink * main; // Main link controls
AuxBus * auxBus;
TestMessage testMessage; // TestMessage instance
Timer * timer; // OS provided timer services
Connector::EventSink * sink; // Event Sink
unsigned ouiId; // Sink ouiId
char modelName[NV_DPCD_SOURCE_DEV_ID_STRING__SIZE + 1]; // Device Model-name
bool bIgnoreSrcOuiHandshake; // Skip writing source OUI
LinkPolicy linkPolicy;
bool linkGuessed; // True when link was "guessed" during HPD in TMDS mode
bool isLinkQuiesced; // True when link was set to quiet mode by TMDS modeset
bool bNoLtDoneAfterHeadDetach; // True when head is disconnected in NDE
bool isDP12AuthCap; // To tell whether this DP1.2 connector/ upmost device has the authentication Cap.
bool isHDCPAuthOn; // To tell whether this connector has the authentication on.
bool isHDCPReAuthPending; // To tell whether HDCP Auth is pending (at every stream addition and cleared at handler).
bool isHDCPAuthTriggered; // To tell whether HDCP Auth is triggered and only cleared at unplug/device detach for MST.
bool isHopLimitExceeded; // To tell the current topology is over limitation.
bool bIsDiscoveryDetectActive; // To tell device discovery is active ( isDiscoveryDetectComplete is also used as DD notify and not want to impacts that. )
bool isDiscoveryDetectComplete; // To tell device discovery is finished.
bool bDeferNotifyLostDevice; // To tell if we should defer notify lost device event to client.
HDCPValidateData hdcpValidateData; // Cache the HDCP ValidateData.
unsigned authRetries; // Retry counter for the authentication.
unsigned retryLT; // Retry counter for link training in case of link lost in PostLQA
unsigned hdcpCapsRetries; // Retry counter for Hdcp Caps read.
unsigned hdcpCpIrqRxStatusRetries; // Retry counter for CPIRQ RxStatus read.
bool bLTPhyRepeater; // Link Train PHY Repeaters between Source and Sink
bool bFromResumeToNAB; // True if from resume to NAB, WAR flag for unblocking GA1.5
bool bAttachOnResume; // True if notifyLongPulse is called for resume (reboot/S3/S4)
bool bSkipAssessLinkForEDP; // Skip assessLink() for eDP. Assuming max is reachable.
bool bPConConnected; // HDMI2.1-Protocol Converter (Support SRC control mode) connected.
bool bSkipAssessLinkForPCon; // Skip assessLink() for PCON. DD will call assessFRLLink later.
bool bHdcpAuthOnlyOnDemand; // True if only initiate Hdcp authentication on demand and MST won't auto-trigger authenticate at device attach.
bool constructorFailed;
//
// OS Modeset Order mitigation causes the library to delay the reporting
// of new devices until they can be safely turned on.
// When enabled the library client will not see connection events until
// MustDisconnect messages are processed.
//
// Policy state should be set before the library is brought out of
// the suspended state.
//
bool policyModesetOrderMitigation;
//
// force LT at NAB for compliance test (Power Management) in Win10 RS2+ (WDDM 2.2)
//
// RS2 no longer sends an explicit call for setPanelPowerParams during the Resume.
// It does that by specifying an additional flag during the call to SetTimings. Due to
// this DP lib doesn't get chance to perform this transition from setPanelPowerParams
// and since it was already skipping LT in NAB/modeswitch, so LT get missed out on the
// compliance device during resume from S3/S4.
//
bool policyForceLTAtNAB;
//
// There are cases where OS does not detach heads from connector immediately after hot-unplug,
// on next hot-plug there is no guarantee that newly connected sink is capable to drive existing
// raster timings. Flush mode has following restriction
// When exiting flush mode S/W should ensure that the final
// link clock & lane count should be able to support existing raster.
// If we run into this situation and use flush mode then that will cause display engine to hang.
// This variable ensures to assess link safely in this situation: if newly connected sink is
// not capable to drive existing raster then just restore link configuration which was there
// before enabling flush mode, through fake link training.
//
bool policyAssessLinkSafely;
bool bDisableVbiosScratchRegisterUpdate;
// Only works when policyModesetOrderMitigation is true.
// To record if we should report newDevice.
bool modesetOrderMitigation;
List deviceList;
List activeGroups;
LinkedList<GroupImpl> intransitionGroups;
LinkedList<GroupImpl> addStreamMSTIntransitionGroups;
List inactiveGroups;
// Compound query
bool compoundQueryActive;
bool compoundQueryResult;
unsigned compoundQueryCount;
unsigned compoundQueryLocalLinkPBN;
unsigned freeSlots, maximumSlots;
// Multistream messaging
MessageManager * messageManager;
DiscoveryManager * discoveryManager;
// Multistream timeslot management (on local link)
LinkConfiguration highestAssessedLC; // As of last assess, the highest possible link configuration
LinkConfiguration activeLinkConfig; // Current link config.
// this is the link config requested by a client.
// can be set and reset by the client for a given operation.
LinkConfiguration preferredLinkConfig;
//
// Desired link configuration of single head multiple sst secondary connector.
//
LinkConfiguration oneHeadSSTSecPrefLnkCfg;
// All possible link configs
LinkConfiguration * allPossibleLinkCfgs;
unsigned numPossibleLnkCfg;
PCONLinkControl activePConLinkControl;
//
// We're waiting for an MST<->SST transition
// The transition cannot be made without the DD
// disconnecting all heads. All devices are reported
// as must_disconnect. Once the last device blocking
// the transition is deattached from a head - we transition.
//
bool linkAwaitingTransition;
// Unless we're awaiting transition this is identical to hal->getSupportsMultistream()
DP_TRANSPORT_MODE linkState;
bool bAudioOverRightPanel;
bool previousPlugged;
bool connectorActive; // Keep track of if connector is active to serve any IRQ
Group * firmwareGroup; // The group used for book-keeping when we're in firmware mode
List pendingEdidReads; // List of DevicePendingEDIDRead structures.
// This list tracks the currently in progress MST Edid Reads
Device * lastDeviceSetForVbios;
// Flag which gets set when ACPI init is done. DD calls notifyAcpiInitDone to tell client that ACPI init is completed
// & client can now initiate DDC EDID read for a device which supports EDID through SBIOS
bool bAcpiInitDone;
// Flag to check if the system is UEFI.
bool bIsUefiSystem;
// Flag to check if LT should be skipped.
bool bSkipLt;
// Flag to make sure that zombie gets triggred when a powerChange event happens
bool bMitigateZombie;
//
// HP Valor QHD+ N15P-Q3 EDP needs 50ms delay after D3
// during trainLinkOptimized to come up on S4
//
bool bDelayAfterD3;
//
// ASUS and Samsung monitors have inconsistent behavior when
// DPCD 0x600 updated to D3. Skip D3 only in case these monitors
// are driven in SST config
//
bool bKeepLinkAlive;
//
// HP Trump dock link training is unstable during S4 resume, which causes
// system to hang. Keep the link alive to increase stability.
// See Bug 2109823.
//
bool bKeepLinkAliveMST;
// Keep the link alive when connector is in SST
bool bKeepLinkAliveSST;
//
// HTC Vive Link box is not happy when we power down the link
// during link training when there is no stream present. It requests
// for a link retraining pulse which is not required.
// WAR to address this - NV Bug# 1793084
//
bool bKeepOptLinkAlive;
// Keep both DP and FRL link alive to save time.
bool bKeepLinkAliveForPCON;
//
// Remote HDCP DCPD access should be D0 but won't introduce extra Dx
// state toggle. Use the counter to avoid powerdownlink when HDCP probe.
//
unsigned pendingRemoteHdcpDetections;
//
// ASUS PQ 321 tiled monitor sometimes loses link while assessing link
// or link training .So if we lower config from HBR2 to HBR and when
// we retrain the link , we see black screen.
// So WAR is to retry link training with same config for 3 times before
// lowering link config. NV Bug #1846925
//
bool bNoFallbackInPostLQA;
bool bReportDeviceLostBeforeNew;
bool bEnableAudioBeyond48K;
bool bDisableSSC;
bool bEnableFastLT;
NvU32 maxLinkRateFromRegkey;
//
// Latency(ms) to apply between link-train and FEC enable for bug
// 2561206.
//
NvU32 LT2FecLatencyMs;
//
// Dual SST Partner connector object pointer
ConnectorImpl *pCoupledConnector;
// Set to true when a DSC mode is requested.
bool bFECEnable;
// Save link config before entering PSR.
LinkConfiguration psrLinkConfig;
//
// Apply MST DSC caps WAR based on OUI ID of sink
//
bool bDscMstCapBug3143315;
//
// Enable DSC Pass through support in driver based on regkey.
//
bool bDscMstEnablePassThrough;
//
// 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
//
bool bDscCapBasedOnParent;
void sharedInit();
ConnectorImpl(MainLink * main, AuxBus * auxBus, Timer * timer, Connector::EventSink * sink);
void setPolicyModesetOrderMitigation(bool enabled);
void setPolicyForceLTAtNAB(bool enabled);
void setPolicyAssessLinkSafely(bool enabled);
void discoveryDetectComplete();
void discoveryNewDevice(const DiscoveryManager::Device & device);
void discoveryLostDevice(const Address & address);
void processNewDevice(const DiscoveryManager::Device & device,
const Edid & edid,
bool isMultistream,
DwnStreamPortType portType,
DwnStreamPortAttribute portAttribute,
bool isCompliance = false);
void applyEdidWARs(Edid & edid, DiscoveryManager::Device device);
void applyRegkeyOverrides(const DP_REGKEY_DATABASE& dpRegkeyDatabase);
ResStatusNotifyMessage ResStatus;
void messageProcessed(MessageManager::MessageReceiver * from);
~ConnectorImpl();
//
// Utility functions
//
virtual void hardwareWasReset();
virtual LinkConfiguration getMaxLinkConfig();
virtual LinkConfiguration getActiveLinkConfig();
virtual void powerdownLink(bool bPowerdownPanel = false);
GroupImpl * getActiveGroupForSST();
bool detectSinkCountChange();
bool handlePhyPatternRequest();
void applyOuiWARs();
bool linkUseMultistream()
{
return (linkState == DP_TRANSPORT_MODE_MULTI_STREAM);
}
void populateAllDpConfigs();
//
// Suspend resume API
//
virtual Group * resume(bool firmwareLinkHandsOff,
bool firmwareDPActive,
bool plugged,
bool isUefiSystem = false,
unsigned firmwareHead = 0,
bool bFirmwareLinkUseMultistream = false,
bool bDisableVbiosScratchRegisterUpdate = false,
bool bAllowMST = true);
virtual void pause();
virtual Device * enumDevices(Device * previousDevice) ;
virtual void beginCompoundQuery() ;
virtual bool compoundQueryAttach(Group * target,
unsigned twoChannelAudioHz, // if you need 192khz stereo specify 192000 here
unsigned eightChannelAudioHz, // Same setting for multi channel audio.
// DisplayPort encodes 3-8 channel streams as 8 channel
NvU64 pixelClockHz, // Requested pixel clock for the mode
unsigned rasterWidth,
unsigned rasterHeight,
unsigned rasterBlankStartX,
unsigned rasterBlankEndX,
unsigned depth);
virtual bool compoundQueryAttach(Group * target,
const DpModesetParams &modesetParams, // Modeset info
DscParams *pDscParams = NULL); // DSC parameters
virtual bool endCompoundQuery();
//
// Timer callback tags.
// (we pass the address of these variables as context to ::expired)
char tagFireEvents;
char tagDelayedLinkTrain;
char tagHDCPReauthentication;
char tagDelayedHdcpCapRead;
char tagDelayedHDCPCPIrqHandling;
//
// Enable disable TMDS mode
//
virtual void enableLinkHandsOff();
virtual void releaseLinkHandsOff();
//
// Timer callback for event management
// Uses: fireEvents()
virtual void expired(const void * tag);
// Generate Events.
// useTimer specifies whether we fire the events on the timer
// context, or this context.
void fireEvents();
// returns the number of pending notifications.
void fireEventsInternal();
virtual bool isHeadShutDownNeeded(Group * target, // Group of panels we're attaching to this head
unsigned headIndex,
ModesetInfo modesetInfo);
virtual bool isLinkTrainingNeededForModeset(ModesetInfo modesetInfo);
virtual bool notifyAttachBegin(Group * target, // Group of panels we're attaching to this head
const DpModesetParams &modesetParams);
virtual bool isHeadShutDownNeeded(Group * target, // Group of panels we're attaching to this head
unsigned headIndex,
unsigned twoChannelAudioHz, // if you need 192khz stereo specify 192000 here
unsigned eightChannelAudioHz, // Same setting for multi channel audio. DisplayPort encodes 3-8 channel streams as 8 channel
NvU64 pixelClockHz, // Requested pixel clock for the mode
unsigned rasterWidth,
unsigned rasterHeight,
unsigned rasterBlankStartX,
unsigned rasterBlankEndX,
unsigned depth) ;
virtual bool notifyAttachBegin(Group * target, // Group of panels we're attaching to this head
unsigned headIndex,
unsigned twoChannelAudioHz, // if you need 192khz stereo specify 192000 here
unsigned eightChannelAudioHz, // Same setting for multi channel audio.
// DisplayPort encodes 3-8 channel streams as 8 channel
NvU64 pixelClockHz, // Requested pixel clock for the mode
unsigned rasterWidth,
unsigned rasterHeight,
unsigned rasterBlankStartX,
unsigned rasterBlankEndX,
unsigned depth) ;
virtual void readRemoteHdcpCaps();
virtual void notifyAttachEnd(bool modesetCancelled);
virtual void notifyDetachBegin(Group * target);
virtual void notifyDetachEnd(bool bKeepOdAlive = false);
bool performIeeeOuiHandshake();
void setIgnoreSourceOuiHandshake(bool bIgnore);
bool getIgnoreSourceOuiHandshake();
bool willLinkSupportModeSST(const LinkConfiguration & linkConfig, const ModesetInfo & modesetInfo);
void forceLinkTraining();
void assessLink(LinkTrainingType trainType = NORMAL_LINK_TRAINING);
bool isLinkInD3();
bool isLinkActive();
bool isLinkLost();
bool trainSingleHeadMultipleSSTLinkNotAlive(GroupImpl *pGroupAttached);
bool isLinkAwaitingTransition();
bool isNoActiveStreamAndPowerdown();
void incPendingRemoteHdcpDetection()
{
pendingRemoteHdcpDetections++;
}
void decPendingRemoteHdcpDetection()
{
if (pendingRemoteHdcpDetections > 0)
{
pendingRemoteHdcpDetections--;
}
}
bool trainLinkOptimized(LinkConfiguration lConfig);
bool trainLinkOptimizedSingleHeadMultipleSST(GroupImpl * group);
bool getValidLowestLinkConfig(LinkConfiguration & lConfig, LinkConfiguration & lowestSelected, ModesetInfo queryModesetInfo);
bool postLTAdjustment(const LinkConfiguration &, bool force);
void populateUpdatedLaneSettings(NvU8* voltageSwingLane, NvU8* preemphasisLane, NvU32 *data);
void populateDscCaps(DSC_INFO* dscInfo, DeviceImpl * dev, DSC_INFO::FORCED_DSC_PARAMS* forcedParams);
void populateDscGpuCaps(DSC_INFO* dscInfo);
void populateForcedDscParams(DSC_INFO* dscInfo, DSC_INFO::FORCED_DSC_PARAMS* forcedParams);
void populateDscSinkCaps(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);
bool validateLinkConfiguration(const LinkConfiguration & lConfig);
virtual bool assessPCONLinkCapability(PCONLinkControl *params);
bool trainPCONFrlLink(PCONLinkControl *pConControl);
// Set Device DSC state based on current DSC state of all active devices on this connector
bool setDeviceDscState(Device * dev, bool bEnableDsc);
// the lowest level function(nearest to the hal) for the connector.
bool rawTrain(const LinkConfiguration & lConfig, bool force, LinkTrainingType linkTrainingType);
bool enableFlush();
bool beforeAddStream(GroupImpl * group, bool force=false, bool forFlushMode = false);
void afterAddStream(GroupImpl * group);
void beforeDeleteStream(GroupImpl * group, bool forFlushMode = false);
void afterDeleteStream(GroupImpl * group);
void disableFlush(bool test=false);
bool beforeAddStreamMST(GroupImpl * group, bool force = false, bool forFlushMode = false);
bool deleteAllVirtualChannels();
void clearTimeslices();
bool allocateTimeslice(GroupImpl * targetGroup);
void freeTimeslice(GroupImpl * targetGroup);
void flushTimeslotsToHardware();
bool getHDCPAbortCodesDP12(NvU32 &hdcpAbortCodesDP12);
bool getOuiSink(unsigned &ouiId, char * modelName, size_t modelNameBufferSize, NvU8 & chipRevision);
bool hdcpValidateKsv(const NvU8 *ksv, NvU32 Size);
void cancelHdcpCallbacks();
bool handleCPIRQ();
void handleSSC();
void handleMCCSIRQ();
void handleHdmiLinkStatusChanged();
void sortActiveGroups(bool ascending);
void configInit();
virtual DeviceImpl* findDeviceInList(const Address & address);
virtual void disconnectDeviceList();
void notifyLongPulseInternal(bool statusConnected);
virtual void notifyLongPulse(bool status);
virtual void notifyShortPulse();
virtual Group * newGroup() ;
virtual void destroy();
virtual void createFakeMuxDevice(const NvU8 *buffer, NvU32 bufferSize);
virtual void deleteFakeMuxDevice();
virtual bool getRawDscCaps(NvU8 *buffer, NvU32 bufferSize);
virtual bool isMultiStreamCapable();
virtual bool isFlushSupported();
virtual bool isStreamCloningEnabled();
virtual bool isFECSupported();
virtual bool isFECCapable();
virtual NvU32 maxLinkRateSupported();
virtual bool setPreferredLinkConfig(LinkConfiguration & lc, bool commit, bool force = false, LinkTrainingType trainType = NORMAL_LINK_TRAINING);
virtual bool resetPreferredLinkConfig(bool force = false);
virtual void setAllowMultiStreaming(bool bAllowMST);
virtual bool getAllowMultiStreaming(void);
virtual bool getSinkMultiStreamCap(void);
virtual void setDp11ProtocolForced();
virtual void resetDp11ProtocolForced();
virtual bool isDp11ProtocolForced();
bool isAcpiInitDone();
virtual void notifyAcpiInitDone();
Group * createFirmwareGroup();
virtual void notifyGPUCapabilityChange();
virtual void notifyHBR2WAREngage();
bool getTestPattern(NV0073_CTRL_DP_TESTPATTERN *testPattern);
bool setTestPattern(NV0073_CTRL_DP_TESTPATTERN testPattern, NvU8 laneMask, NV0073_CTRL_DP_CSTM cstm, NvBool bIsHBR2, NvBool bSkipLaneDataOverride = false);
bool getLaneConfig(NvU32 *numLanes, NvU32 *data); // "data" is an array of NV0073_CTRL_MAX_LANES unsigned ints
bool setLaneConfig(NvU32 numLanes, NvU32 *data); // "data" is an array of NV0073_CTRL_MAX_LANES unsigned ints
void getCurrentLinkConfig(unsigned & laneCount, NvU64 & linkRate); // CurrentLink Configuration
unsigned getPanelDataClockMultiplier();
unsigned getGpuDataClockMultiplier();
void configurePowerState(bool bPowerUp);
virtual void readPsrCapabilities(vesaPsrSinkCaps *caps);
virtual bool updatePsrConfiguration(vesaPsrConfig config);
virtual bool readPsrConfiguration(vesaPsrConfig *config);
virtual bool readPsrDebugInfo(vesaPsrDebugStatus *psrDbgState);
virtual bool writePsrErrorStatus(vesaPsrErrorStatus psrErr);
virtual bool readPsrErrorStatus(vesaPsrErrorStatus *psrErr);
virtual bool writePsrEvtIndicator(vesaPsrEventIndicator psrErr);
virtual bool readPsrEvtIndicator(vesaPsrEventIndicator *psrErr);
virtual bool readPsrState(vesaPsrState *psrState);
virtual bool updatePsrLinkState(bool bTrainLink);
// for dp test utility. pBuffer is the request buffer of type DP_STATUS_REQUEST_xxxx
DP_TESTMESSAGE_STATUS sendDPTestMessage(void *pBuffer,
NvU32 requestSize,
NvU32 *pDpStatus);
DP_TESTMESSAGE_STATUS getStreamIDs(NvU32 *pStreamIDs, NvU32 *pCount); // for dp test utility, called by DD
// Reset link training counter for the active link configuration.
virtual void resetLinkTrainingCounter()
{
activeLinkConfig.setLTCounter(0);
}
};
//
// New devices do not get a DeviceImpl created until after
// the EDID read has completed. This object is used
// to track the necessary state.
//
struct DevicePendingEDIDRead : protected EdidReadMultistream::EdidReadMultistreamEventSink, public ListElement
{
EdidReadMultistream reader;
DiscoveryManager::Device device;
ConnectorImpl * parent;
void mstEdidCompleted(EdidReadMultistream * from);
void mstEdidReadFailed(EdidReadMultistream * from);
public:
DevicePendingEDIDRead(ConnectorImpl * _parent, MessageManager * manager, DiscoveryManager::Device dev)
: reader(_parent->timer, manager, this, dev.address), device(dev), parent(_parent)
{
}
};
}
#endif //INCLUDED_DP_CONNECTORIMPL_H

View File

@@ -0,0 +1,41 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_crc.h *
* CRC Algorithms for the messaging subsystem. *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_CRC_H
#define INCLUDED_DP_CRC_H
#include "dp_bitstream.h"
namespace DisplayPort
{
unsigned dpCalculateHeaderCRC(BitStreamReader * reader);
unsigned dpCalculateBodyCRC(BitStreamReader * writer);
}
#endif //INCLUDED_DP_CRC_H

View File

@@ -0,0 +1,498 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_connector.cpp *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_DEVICEIMPL_H
#define INCLUDED_DP_DEVICEIMPL_H
#include "dp_connector.h"
#include "dp_internal.h"
#include "dp_edid.h"
#include "dp_list.h"
#include "dp_auxdefs.h"
#include "dp_vrr.h"
namespace DisplayPort
{
#define PREDEFINED_DSC_MST_BPPX16 160;
#define HDCP_BCAPS_DDC_OFFSET 0x40
#define HDCP_BCAPS_DDC_EN_BIT 0x80
#define HDCP_BCAPS_DP_EN_BIT 0x01
#define HDCP_I2C_CLIENT_ADDR 0x74
struct GroupImpl;
struct ConnectorImpl;
class DeviceHDCPDetection;
class VrrEnablement;
struct DeviceImpl : public Device,
public AuxBus,
public ListElement
{
//
// Shadow state: This is the last state delivered to DD.
// see the ConnectorImpl::fireEvents() function for handling.
//
// State is double buffered to allow for allow announces
// to happen at the end of the state updates. We assume
// the DD can call any Connector API in response to the
// event.
//
struct Shadow
{
bool plugged;
bool zombie;
bool cableOk;
bool mustDisconnect;
bool hdcpCapDone;
LinkConfiguration highestAssessedLC;
} shadow;
struct BandWidth
{
struct _Enum_Path
{
unsigned total, free;
bool bPathFECCapable;
bool dataValid; // Is the cache valid?
} enum_path;
struct Compound_Query_State
{
unsigned totalTimeSlots; // Total timeslots available for allocation across this node
unsigned timeslots_used_by_query; // Timeslots accounted for.
unsigned bandwidthAllocatedForIndex; // Compound query is compromised of several
// qeuery attaches. These query attaches
// may have more than one device associated.
// this mask keeps track of which queryAttach's
// have already had the stream "rounted" past
// this node.
} compound_query_state;
LinkConfiguration lastHopLinkConfig; // inferred from enum_path.total
} bandwidth;
enum rawEprState
{
software,
hardware
};
void resetCacheInferredLink();
LinkConfiguration * inferLeafLink(unsigned * totalLinkSlots);
DeviceImpl * parent; // Upstream parent device
DeviceImpl * children[16];
PortMap portMap;
Edid rawEDID;
Edid processedEdid;
Edid ddcEdid;
DPCDHAL * hal;
GroupImpl * activeGroup;
ConnectorImpl * connector;
ConnectorType connectorType;
Address address;
GUID guid;
NvU8 peerDevice;
NvU8 dpcdRevisionMajor;
NvU8 dpcdRevisionMinor;
bool multistream;
bool videoSink, audioSink;
bool plugged;
AuxRetry friendlyAux;
bool payloadAllocated; // did the allocate payload go through?
unsigned char BCAPS[HDCP_BCAPS_SIZE]; // Hdcp1.x bCaps raw data
unsigned char BKSV[HDCP_KSV_SIZE]; // Hdcp1.x bKsv raw data
unsigned char nvBCaps[HDCP_BCAPS_SIZE]; // NV generic HDCP BCAPS including 1.x, 2.2, ...
NvU64 maxTmdsClkRate;
bool isPendingNewDevice();
bool isPendingLostDevice();
bool isPendingZombie();
bool isPendingCableOk();
bool isPendingBandwidthChange();
bool isPendingHDCPCapDone();
TriState isHDCPCap;
bool isDeviceHDCPDetectionAlive;
DeviceHDCPDetection * deviceHDCPDetection;
PCONCaps pconCaps;
// this flag signifies that the compliance device has requested EDID read test and may follow
// hidden and lazy zombie policy.
bool complianceDeviceEdidReadTest;
bool lazyExitNow;
// VRR Enablement structure
VrrEnablement *vrrEnablement;
// DSC fields
NvU8 rawDscCaps[16];
DscCaps dscCaps;
// Panel replay Caps
PanelReplayCaps prCaps;
bool bIsFakedMuxDevice;
bool bIsPreviouslyFakedMuxDevice;
bool bisMarkedForDeletion;
//
// Device doing the DSC decompression for this device. This could be device itself
// or its parent
//
DeviceImpl* devDoingDscDecompression;
//
// If DSC stream can be sent to this device or not. Either device itself or it's
// parent can do DSC decompression
//
bool bDSCPossible;
bool bFECSupported;
bool bFECUncorrectedSupported;
bool bFECCorrectedSupported;
bool bFECBitSupported;
bool bFECParityBlockSupported;
bool bFECParitySupported;
TriState bSdpExtCapable;
bool bMSAOverMSTCapable;
DeviceImpl(DPCDHAL * hal, ConnectorImpl * connector, DeviceImpl * parent);
~DeviceImpl();
virtual bool isCableOk();
virtual bool isLogical();
virtual bool isZombie();
virtual unsigned getEDIDSize() const;
virtual bool getEDID(char * buffer, unsigned size) const;
virtual unsigned getRawEDIDSize() const;
virtual bool getRawEDID(char * buffer, unsigned size) const;
virtual bool getPCONCaps(PCONCaps *pPCONCaps);
virtual Group * getOwningGroup()
{
return (Group *)activeGroup;
}
bool isActive();
void applyOUIOverrides();
virtual Device * getParent()
{
return parent;
}
virtual Device * getChild(unsigned portNumber)
{
return children[portNumber];
}
virtual bool isMultistream() // Sink supports multistream, remember we can have 1.1 targets
{
return address.size() != 0;
}
virtual bool isNativeDPCD()
{
return (address.size() < 2);
}
virtual bool isVideoSink()
{
return videoSink;
}
virtual bool isAudioSink()
{
return audioSink;
}
virtual bool isLoop()
{
DP_LOG(("isLoop implementation is pending (bug 791059)"));
return false;
}
virtual bool isRedundant()
{
DP_LOG(("isRedundant implementation is pending (bug 791059)"));
return false;
}
virtual bool isMustDisconnect();
virtual bool isPlugged()
{
return plugged;
}
virtual Address getTopologyAddress() const
{
return address;
}
virtual ConnectorType getConnectorType()
{
return connectorType;
}
virtual bool isFallbackEdid()
{
return this->processedEdid.isFallbackEdid();
}
virtual GUID getGUID() const
{
return guid;
}
virtual PortMap getPortMap() const
{
return portMap;
}
virtual TriState hdcpAvailableHop();
virtual TriState hdcpAvailable();
virtual bool isMSAOverMSTCapable()
{
return bMSAOverMSTCapable;
}
virtual bool isFakedMuxDevice();
virtual bool isPreviouslyFakedMuxDevice();
bool bypassDpcdPowerOff()
{
return processedEdid.WARFlags.disableDpcdPowerOff;
}
bool powerOnMonitorBeforeLt()
{
return processedEdid.WARFlags.powerOnBeforeLt;
}
bool forceMaxLinkConfig()
{
return processedEdid.WARFlags.forceMaxLinkConfig;
}
bool skipRedundantLt()
{
return processedEdid.WARFlags.skipRedundantLt;
}
bool ignoreRedundantHotplug()
{
return processedEdid.WARFlags.ignoreRedundantHotplug;
}
bool isOptimalLinkConfigOverridden()
{
return processedEdid.WARFlags.overrideOptimalLinkCfg;
}
// Apply DPCD overrides if required
void dpcdOverrides();
bool getDpcdRevision(unsigned * major, unsigned * minor)
{
if (!major || !minor)
{
DP_ASSERT(0 && "Null pointers passed in.");
return false;
}
*major = this->dpcdRevisionMajor;
*minor = this->dpcdRevisionMinor;
return true;
}
bool getIgnoreMSACap()
{
return hal->getMsaTimingparIgnored();
}
AuxRetry::status setIgnoreMSAEnable(bool msaTimingParamIgnoreEn)
{
return hal->setIgnoreMSATimingParamters(msaTimingParamIgnoreEn);
}
virtual bool getSDPExtnForColorimetrySupported();
virtual bool isPowerSuspended();
virtual void setPanelPowerParams(bool bSinkPowerStateD0, bool bPanelPowerStateOn);
virtual status transaction(Action action, Type type, int address,
NvU8 * buffer, unsigned sizeRequested,
unsigned * sizeCompleted,
unsigned *pNakReason= NULL,
NvU8 offset= 0, NvU8 nWriteTransactions= 0);
virtual unsigned transactionSize();
// default behaviour is querying first three registers for every lane --> flags = 0x7
virtual status fecTransaction(NvU8 *fecStatus, NvU16 **fecErrorCount, NvU32 flags = NV_DP_FEC_FLAGS_SELECT_ALL);
virtual AuxBus * getRawAuxChannel() { return this; }
virtual AuxRetry * getAuxChannel() { return &friendlyAux; }
virtual AuxBus::status getDpcdData(unsigned offset, NvU8 * buffer,
unsigned sizeRequested,
unsigned * sizeCompleted,
unsigned * pNakReason=NULL);
virtual AuxBus::status setDpcdData(unsigned offset, NvU8 * buffer,
unsigned sizeRequested,
unsigned * sizeCompleted,
unsigned * pNakReason=NULL);
virtual AuxBus::status queryFecData(NvU8 *fecStatus, NvU16 **fecErrorCount, NvU32 flags);
virtual DscCaps getDscCaps();
//
// This function returns the device itself or its parent device that is doing
// DSC decompression for it.
//
virtual Device* getDevDoingDscDecompression();
virtual void markDeviceForDeletion() {bisMarkedForDeletion = true;};
virtual bool isMarkedForDeletion() {return bisMarkedForDeletion;};
virtual bool getRawDscCaps(NvU8 *buffer, NvU32 bufferSize);
virtual AuxBus::status dscCrcControl(NvBool bEnable, gpuDscCrc *dataGpu, sinkDscCrc *dataSink);
//
// Parameter bForceMot in both getI2cData and setI2cData is used to forfully set
// the MOT bit. It is needed for some special cases where the MOT bit shouldn't
// be set but some customers need it to please their monitors.
//
virtual bool getI2cData(unsigned offset, NvU8 * buffer, unsigned sizeRequested, unsigned * sizeCompleted, bool bForceMot = false);
virtual bool setI2cData(unsigned offset, NvU8 * buffer, unsigned sizeRequested, unsigned * sizeCompleted, bool bForceMot = false);
virtual bool getRawEpr(unsigned * totalEpr, unsigned * freeEpr, rawEprState eprState);
void switchToComplianceFallback();
// VRR Display Enablement Functions
bool startVrrEnablement(void);
void resetVrrEnablement(void);
bool isVrrMonitorEnabled(void);
bool isVrrDriverEnabled(void);
// Panel replay related functions
bool isPanelReplaySupported(void);
void getPanelReplayCaps(void);
bool setPanelReplayConfig(panelReplayConfig prcfg);
NvBool getDSCSupport();
bool getFECSupport();
NvBool isDSCPassThroughSupported();
NvBool isDSCSupported();
NvBool isDSCPossible();
bool isFECSupported();
bool readAndParseDSCCaps();
bool parseDscCaps(const NvU8 *buffer, NvU32 bufferSize);
bool setDscEnable(bool enable);
bool getDscEnable(bool *pEnable);
unsigned getDscVersionMajor();
unsigned getDscVersionMinor();
unsigned getDscRcBufferSize();
unsigned getDscRcBufferBlockSize();
unsigned getDscMaxSlicesPerSink();
unsigned getDscLineBufferBitDepth();
NvBool isDscBlockPredictionSupported();
unsigned getDscMaxBitsPerPixel();
NvBool isDscRgbSupported();
NvBool isDscYCbCr444Supported();
NvBool isDscYCbCrSimple422Supported();
NvBool isDscYCbCr422NativeSupported();
NvBool isDscYCbCr420NativeSupported();
unsigned getDscPeakThroughputMode0();
unsigned getDscPeakThroughputModel();
unsigned getDscMaxSliceWidth();
unsigned getDscDecoderColorDepthSupportMask();
};
class DeviceHDCPDetection : public Object, MessageManager::Message::MessageEventSink, Timer::TimerCallback
{
DeviceImpl* parent;
RemoteDpcdReadMessage remoteBKSVReadMessage;
RemoteDpcdReadMessage remoteBCapsReadMessage;
RemoteDpcdReadMessage remote22BCapsReadMessage;
MessageManager * messageManager; // For transmit and receive
Timer * timer;
bool bksvReadCompleted;
bool bCapsReadCompleted;
bool isValidBKSV;
bool isBCapsHDCP;
unsigned retriesRemoteBKSVReadMessage;
unsigned retriesRemoteBCapsReadMessage;
unsigned retriesRemote22BCapsReadMessage;
bool retryRemoteBKSVReadMessage;
bool retryRemoteBCapsReadMessage;
bool retryRemote22BCapsReadMessage;
bool bBKSVReadMessagePending;
bool bBCapsReadMessagePending;
public:
DeviceHDCPDetection(DeviceImpl * parent, MessageManager * messageManager, Timer * timer)
: bksvReadCompleted(false),bCapsReadCompleted(false),isValidBKSV(false),
isBCapsHDCP(false), retriesRemoteBKSVReadMessage(0), retriesRemoteBCapsReadMessage(0),
retriesRemote22BCapsReadMessage(0), retryRemoteBKSVReadMessage(false),
retryRemoteBCapsReadMessage(false), retryRemote22BCapsReadMessage(false),
bBKSVReadMessagePending(false), bBCapsReadMessagePending(false)
{
this->parent = parent;
this->messageManager = messageManager;
this->timer = timer;
}
~DeviceHDCPDetection();
void expired(const void * tag);
void start();
void waivePendingHDCPCapDoneNotification();
bool hdcpValidateKsv(const NvU8 *ksv, NvU32 Size);
void handleRemoteDpcdReadDownReply(MessageManager::Message * from);
void messageFailed(MessageManager::Message * from, NakData * nakData);
void messageCompleted(MessageManager::Message * from);
};
}
#endif //INCLUDED_DP_DEVICEIMPL_H

View File

@@ -0,0 +1,328 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2010-2021 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_discovery.h *
* Class definition for discovery manager. *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_DISCOVERY_H
#define INCLUDED_DP_DISCOVERY_H
#include "dp_address.h"
#include "dp_list.h"
#include "dp_messages.h"
#include "dp_messagecodings.h"
namespace DisplayPort
{
class DiscoveryManager : virtual public Object
{
public:
struct Device
{
Address address; // direct topology address
bool legacy; // legacy (NON DP) device emulated on this port
bool branch; // DP 1.2 style branching device
PeerDevice peerDevice; // connector type of the device on this port
unsigned dpcdRevisionMajor;
unsigned dpcdRevisionMinor;
GUID peerGuid; // device guid
unsigned SDPStreams; // maximum number of audio streams supported
unsigned SDPStreamSinks; // number of outputs to select from
bool dirty; // got updates for the same device
PortMap portMap;
bool videoSink; // Should be true when a video sink is supported
NvU64 maxTmdsClkRate;
Device():peerDevice(None),SDPStreams(0),SDPStreamSinks(0),dirty(false),videoSink(false)
{
portMap.validMap = portMap.inputMap = portMap.internalMap = 0;
}
~Device(){}
};
struct ReceiverSink :
virtual public Object,
public MessageManager::MessageReceiver::MessageReceiverEventSink
{
DiscoveryManager * parent;
// will handle CSN (up_req) and generate a up_reply for it.
virtual void messageProcessed(MessageManager::MessageReceiver * from);
void handleCSN(MessageManager::MessageReceiver * from);
ReceiverSink(DiscoveryManager * parent)
:parent(parent)
{}
virtual ~ReceiverSink()
{}
};
// This will account for upreplies and their failures/retries.
struct CsnUpReplyContainer : ListElement, Timer::TimerCallback, MessageManager::Message::MessageEventSink
{
struct CsnUpReply: public GenericUpReplyMessage
{
CsnUpReplyContainer * container;
CsnUpReply(CsnUpReplyContainer * container, const Address & target)
: GenericUpReplyMessage(target, 0x2), container(container)
{}
~CsnUpReply()
{}
};
DiscoveryManager * parent;
CsnUpReply upReplyMessage;
unsigned delayInUsec;
unsigned retries;
Address target;
virtual void messageFailed(MessageManager::Message * from, NakData * nakData)
{
// if reason of failure is not timeout or defer; just forget trying again.
if (!(nakData->reason == NakDefer || nakData->reason == NakTimeout))
{
messageCompleted(from);
return;
}
// queue a callback to reset and send again
queueUpReply();
return;
}
virtual void messageCompleted(MessageManager::Message * from)
{
// don't delete now. Queue callback to delete later
retries = 0;
parent->timer->queueCallback(this, "CSNF", 5000);
}
void queueUpReply()
{
parent->timer->queueCallback(this, "CSNF", delayInUsec/1000);
}
void postUpReply()
{
upReplyMessage.set(target);
parent->messageManager->postReply(&this->upReplyMessage, this);
}
virtual void expired(const void * tag)
{
if (retries)
retries--;
if (retries)
postUpReply();
else
{
// enough retries. wrap up.
delete this;
}
}
CsnUpReplyContainer(DiscoveryManager * parent)
:parent(parent), upReplyMessage(this, target), delayInUsec(200000), retries(4), target(Address(0))
{}
virtual ~CsnUpReplyContainer()
{
// remove self from queue and delete
// cancel all pending callbacks
parent->timer->cancelCallbacks(this);
parent->pendingCsnUpReplies.remove(this);
}
};
ReceiverSink receiverSink;
ConnStatusNotifyMessage connectionStatusNotifyProcessor;
GUIDBuilder guidBuilder;
List pendingCsnUpReplies;
public:
struct DiscoveryManagerEventSink
{
virtual void discoveryDetectComplete() = 0; // reply to processDetect
virtual void discoveryNewDevice(const DiscoveryManager::Device & device) = 0; // these can go out anytime
virtual void discoveryLostDevice(const Address & address) = 0;
};
enum {
maximumTopologyNodes = 128
};
Device currentDevices[maximumTopologyNodes];
unsigned currentDevicesCount;
Device * findDevice(const Address & address);
Device * findDevice(GUID & guid);
void addDevice(const Device & device);
void removeDevice(Device * device);
void removeDeviceTree(const Address & prefix);
Device * findChildDeviceForBranchWithGuid(GUID guid, unsigned port, Address & childAddr);
//
// This is responsible for a "complete" detection of a sink. Specifically using remote dpcd reads and writes
//
struct SinkDetection : MessageManager::Message::MessageEventSink, ListElement, Timer::TimerCallback
{
Device device;
Address address;
RemoteDpcdWriteMessage remoteDpcdWriteMessage;
RemoteDpcdReadMessage remoteDpcdReadMessage;
PowerUpPhyMessage powerUpPhyMessage;
LinkAddressMessage linkAddressMessage;
DiscoveryManager * parent;
bool completed;
unsigned retriesRemoteDpcdWriteMessage;
bool retryRemoteDpcdWriteMessage;
unsigned retriesRemoteDpcdReadMessage;
bool retryRemoteDpcdReadMessage;
unsigned retriesLinkAddressMessage;
bool retryLinkAddressMessage;
bool bFromCSN;
SinkDetection(DiscoveryManager * parent, const Device & device, bool bFromCSN)
: device(device), address(device.address), parent(parent), completed(false),
retriesRemoteDpcdWriteMessage(0), retryRemoteDpcdWriteMessage(false),
retriesRemoteDpcdReadMessage(0), retryRemoteDpcdReadMessage(false),
bFromCSN(bFromCSN)
{}
~SinkDetection();
void expired(const void * tag);
void start();
void detectCompleted(bool passed);
void messageFailed(MessageManager::Message * from, NakData * nakData);
void handleRemoteDpcdReadDownReply();
void handleRemoteDpcdWriteDownReply();
void handleLinkAddressDownReply();
void messageCompleted(MessageManager::Message * from);
};
//
// This object represents an address in some stage of detection
//
struct BranchDetection : MessageManager::Message::MessageEventSink, ListElement, Timer::TimerCallback
{
Device parentDevice;
Address address;
LinkAddressMessage::Result child[16];
unsigned childCount;
LinkAddressMessage linkAddressMessage;
RemoteDpcdWriteMessage remoteDpcdWriteMessage;
DiscoveryManager * parent;
bool completed;
bool retryLinkAddressMessage;
unsigned retriesLinkAddressMessage;
unsigned retriesRemoteDpcdWriteMessage;
bool retryRemoteDpcdWriteMessage;
BranchDetection(DiscoveryManager * parent, const Device & device)
: parentDevice(device), address(parentDevice.address),
parent(parent), completed(false),
retryLinkAddressMessage(false), retriesLinkAddressMessage(0),
retriesRemoteDpcdWriteMessage(0), retryRemoteDpcdWriteMessage(false)
{}
void expired(const void * tag);
void start();
~BranchDetection();
void detectCompleted(bool present);
void messageFailed(MessageManager::Message * from, NakData * nakData) ;
void handleLinkAddressDownReply();
void handleRemoteDpcdReadDownReply();
void messageCompleted(MessageManager::Message * from);
};
void detect(const Address & address);
void detectBranch(Device device);
void detectSink(Device newDevice, bool bFromCSN);
public:
List outstandingBranchDetections;
List outstandingSinkDetections;
DiscoveryManagerEventSink * sink; // To call NotifyDetectComplete()
MessageManager * messageManager; // For transmit and receive
Timer * timer;
DPCDHAL * hal;
DiscoveryManager(MessageManager * messageManager, DiscoveryManagerEventSink * sink, Timer * timer, DPCDHAL * hal)
: receiverSink(this),
connectionStatusNotifyProcessor(&receiverSink),
guidBuilder(timer, 0x10DE9070),
currentDevicesCount(0),
sink(sink),
messageManager(messageManager),
timer(timer),
hal(hal)
{
//
// Register to filter all the upmessages. We want to know when
// connection status notify events are on their way.
//
messageManager->registerReceiver(&connectionStatusNotifyProcessor);
}
~DiscoveryManager()
{
while (!this->outstandingBranchDetections.isEmpty())
delete this->outstandingBranchDetections.front();
while (!this->outstandingSinkDetections.isEmpty())
delete this->outstandingSinkDetections.front();
while (!this->pendingCsnUpReplies.isEmpty())
delete this->pendingCsnUpReplies.front();
}
void notifyLongPulse(bool status);
};
}
#endif //INCLUDED_DP_DISCOVERY_H

View File

@@ -0,0 +1,321 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2010-2021 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_edid.h *
* reading EDID from SST/MST Device *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_EDID_H
#define INCLUDED_DP_EDID_H
#include "dp_buffer.h"
#include "dp_auxbus.h"
#include "dp_address.h"
#include "dp_messages.h"
#include "dp_messagecodings.h"
#include "dp_timer.h"
namespace DisplayPort
{
class Edid;
//
// Shared utility object for MST/SST edid reading.
// This object handles the retry, CRC validating,
// identification of EDID length, DDC ping, etc.
//
// It's designed as an asynchronous state machine
// because of the way MST EDID reads are built.
//
class EdidAssembler
{
public:
EdidAssembler(Edid * const edid, bool bPatchCrc = false);
//
// returns false - when existing data in Edid is invalid
// returns seg - segment from which to read next block
// returns offset - offset within block from which to start reading next block
//
bool readNextRequest(NvU8 & seg, NvU8 & offset);
// returns false when Edid read is completed
void postReply(const Buffer & buffer, unsigned sizeCompleted, bool success);
void postReply(unsigned char * data, unsigned sizeCompleted, bool success);
// returns true when it read all the required blocks
bool readIsComplete();
void reset();
private:
Edid * edid;
Stream stream;
NvU8 oldBlockChecksum;
unsigned blocksRead;
unsigned totalBlockCnt;
unsigned retriesCount;
bool bPatchCrc;
};
//
// EDID
//
class Edid
{
public:
Edid();
~Edid();
Buffer * getBuffer() const { return &buffer; }
NvU8 getFirstPageChecksum(); // Get checksum byte
NvU8 getLastPageChecksum(); // Get checksum byte for last block
bool verifyCRC();
unsigned getEdidVersion();
unsigned getBlockCount();
const char * getName() const;
unsigned getEdidSize() const;
bool isChecksumValid() const;
bool isJunkEdid() const;
bool isFallbackEdid() const;
void swap(Edid & right);
void applyEdidWorkArounds(NvU32 warFlag, const DpMonitorDenylistData *pDenylistData);
void patchCrc();
void setForcedEdidChecksum(bool set)
{
this->forcedCheckSum = set;
}
void setFallbackFlag(bool set)
{
this->fallbackEdid = set;
}
void setPatchedChecksum(bool set)
{
this->patchedChecksum = set;
}
bool isPatchedChecksum() const
{
return this->patchedChecksum;
}
bool isValidHeader() const
{
NvU8 validHeaderData[8] = {
0x00, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x00};
if (buffer.getLength() < 0x8)
return false;
for (unsigned i = 0; i < 8; i++)
{
if (buffer.data[i] != validHeaderData[i])
{
DP_LOG(("DP-EDID> Invalid EDID Header"));
return false;
}
}
return true;
}
unsigned getManufId() const
{
if (buffer.getLength() < 0xa)
return 0;
return ((buffer.data[0x9] << 8) | (buffer.data[0x8]));
}
unsigned getProductId() const
{
if (buffer.getLength() < 0xc)
return 0;
return ((buffer.data[0xb] << 8) | (buffer.data[0xa]));
}
unsigned getYearWeek() const
{
if (buffer.getLength() < 0x12)
return 0;
return ((buffer.data[0x11] << 8) | (buffer.data[0x10]));
}
typedef struct
{
bool extensionCountDisabled;
bool dataForced;
bool disableDpcdPowerOff;
bool forceMaxLinkConfig;
bool powerOnBeforeLt;
bool skipRedundantLt;
bool skipCableBWCheck;
bool overrideOptimalLinkCfg;
bool overrideMaxLaneCount;
bool ignoreRedundantHotplug;
bool delayAfterD3;
bool keepLinkAlive;
bool useLegacyAddress;
bool reassessMaxLink;
bool bIgnoreDscCap; // Ignore DSC even if sink reports DSC capability
}_WARFlags;
_WARFlags WARFlags;
typedef struct
{
unsigned maxLaneCount; // Max lane count value to override
unsigned maxLaneAtHighRate; // Max lane count supported at HBR
unsigned maxLaneAtLowRate; // Max lane count supported at RBR
unsigned optimalLinkRate; // Optimal link rate value to override
unsigned optimalLaneCount; // Optimal lane count value to override
}_WARData;
_WARData WARData;
void resetData()
{
buffer.reset();
checkSumValid = false;
forcedCheckSum = false;
fallbackEdid = false;
// clear the WARFlags
_WARFlags temp = {0};
WARFlags = temp;
}
bool operator== (const Edid & other)
{
return (buffer == other.buffer);
}
bool operator!= (const Edid & other)
{
return !(buffer == other.buffer);
}
private:
void validateCheckSum();
mutable Buffer buffer;
bool checkSumValid;
bool forcedCheckSum;
bool fallbackEdid;
bool patchedChecksum;
};
//
// SST EDID Read API
//
bool EdidReadSST(Edid & edid, AuxBus * aux, Timer * timer, bool pendingTestRequestEdidRead = false, bool bBypassAssembler = false, MainLink *main = NULL);
enum EDID_DDC
{
EDID_DDC_NONE = 0x00,
EDID_DDC_ADR0 = 0xA0,
EDID_DDC_ADR1 = 0xA2,
EDID_DDC_ADR2 = 0xA6,
EDID_SEG_SELECTOR_OFFSET = 0x60,
};
EDID_DDC sstDDCPing(AuxBus & dpAux);
//
// MST EDID Read API
//
class EdidReadMultistream : public Object, protected MessageManager::Message::MessageEventSink, Timer::TimerCallback
{
public:
class EdidReadMultistreamEventSink // Connector will inherit from this
{
public:
virtual void mstEdidCompleted(EdidReadMultistream * from) = 0;
virtual void mstEdidReadFailed(EdidReadMultistream * from) = 0;
};
EdidReadMultistream(Timer * timer, MessageManager * manager, EdidReadMultistream::EdidReadMultistreamEventSink * sink, Address topologyAddress)
: topologyAddress(topologyAddress), manager(manager), edidReaderManager(&edid), ddcIndex(0),
retries(0), timer(timer), sink(sink)
{
startReadingEdid();
}
Edid edid;
Address topologyAddress;
~EdidReadMultistream();
private:
void startReadingEdid();
MessageManager * manager;
RemoteI2cReadMessage remoteI2cRead;
EdidAssembler edidReaderManager; // come up another word besides edidReaderManager eg Manager
NvU8 DDCAddress;
NvU8 ddcIndex;
unsigned retries;
Timer * timer;
void readNextBlock(NvU8 seg, NvU8 offset);
void failedToReadEdid();
void expired(const void * tag);
EdidReadMultistreamEventSink * sink;
virtual void messageFailed(MessageManager::Message * from, NakData * nakData);
virtual void messageCompleted(MessageManager::Message * from);
void edidAttemptDone(bool succeeded);
};
//
// Useful defines
//
enum
{
EDID_BLOCK_SIZE = 0x80,
EDID_SEGMENT_SIZE = 2*EDID_BLOCK_SIZE,
EDID_POLICY_BLOCK_READ_MAX_RETRY_COUNT = 3,
// DID EDID CTS v1.3 d12 currently outlines that Source shall support up to 16 blocks of EDID data.
EDID_MAX_BLOCK_COUNT = 16,
};
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;
const NvU8 EDID_MAX_AUX_RETRIES = 10;
const NvU8 EDID_AUX_WAIT_TIME = 1;
NvU8 getEDIDBlockChecksum(const Buffer &);
void makeEdidFallback(Edid & edid, NvU32 fallbackFormatSupported = 0);
void makeEdidFallbackVGA(Edid & edid);
}
#endif //INCLUDED_DP_EDID_H

View File

@@ -0,0 +1,410 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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.
*/
/******************************* List **************************************\
* *
* Module: dp_evoadapter.h *
* Interface for low level access to the aux bus. *
* This is the synchronous version of the interface. *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_EVOADAPTER_H
#define INCLUDED_DP_EVOADAPTER_H
#include "dp_timer.h"
#include "dp_auxbus.h"
#include "dp_mainlink.h"
#include "dp_wardatabase.h"
#include "dp_auxdefs.h"
#include "dp_regkeydatabase.h"
#include <nvos.h>
#define HDCP_DUMMY_CN (0x1)
#define HDCP_DUMMY_CKSV (0xFFFFF)
namespace DisplayPort
{
class EvoInterface
{
public:
//
// IOCTL access to RM class DISPLAY_COMMON and NV50_DISPLAY
//
virtual NvU32 rmControl0073(NvU32 command, void * params, NvU32 paramSize) = 0;
virtual NvU32 rmControl5070(NvU32 command, void * params, NvU32 paramSize) = 0;
virtual bool getMaxLinkConfigFromUefi(NvU8 &linkRate, NvU8 &laneCount)
{
linkRate = 0; laneCount = 0;
return true;
}
//
// Call to tell DD that linkTraining will be performed.
// Required when head is attached & we enter in flush mode GPUs.
// Required to enable/disable Audio.
//
// Derived classes that override these functions must call down to
// DisplayPort::EvoInterface::pre/postLinkTraining() to inherit this
// implementation.
//
virtual void preLinkTraining(NvU32 head)
{
}
virtual void postLinkTraining(NvU32 head)
{
}
virtual NvU32 getSubdeviceIndex() = 0;
virtual NvU32 getDisplayId() = 0;
virtual NvU32 getSorIndex() = 0;
virtual NvU32 getLinkIndex() = 0; // Link A = 0, Link B = 1
//
// Query the value of a registry key. Implementations should return 0
// if the regkey is not set.
//
virtual NvU32 getRegkeyValue(const char *key)
{
return 0;
}
virtual NvU32 monitorDenylistInfo(NvU32 manufId, NvU32 productId, DpMonitorDenylistData *pDenylistData)
{
return 0;
}
virtual bool isInbandStereoSignalingSupported()
{
return false;
}
};
MainLink * MakeEvoMainLink(EvoInterface * provider, Timer * timer);
AuxBus * MakeEvoAuxBus(EvoInterface * provider, Timer * timer);
class EvoAuxBus : public AuxBus
{
public:
EvoAuxBus(EvoInterface * provider, Timer * timer)
: provider(provider),
timer(timer),
displayId(provider->getDisplayId()),
subdeviceIndex(provider->getSubdeviceIndex()),
devicePlugged(false)
{
}
virtual status transaction(Action action, Type type, int address, NvU8 * buffer,
unsigned sizeRequested, unsigned * sizeCompleted,
unsigned * pNakReason = NULL,
NvU8 offset = 0, NvU8 nWriteTransactions = 0);
virtual unsigned transactionSize();
virtual void setDevicePlugged(bool);
private:
EvoInterface * provider;
Timer * timer;
NvU32 displayId;
NvU32 subdeviceIndex;
bool devicePlugged;
};
class EvoMainLink : public MainLink
{
EvoInterface * provider;
Timer * timer;
NvU32 displayId;
NvU32 subdeviceIndex;
NvU32 _maxLinkRateSupportedGpu;
NvU32 _maxLinkRateSupportedDfp;
unsigned allHeadMask;
bool _hasIncreasedWatermarkLimits;
bool _hasMultistream;
bool _isPC2Disabled;
bool _isEDP;
bool _isDP1_2Supported;
bool _isDP1_4Supported;
bool _isStreamCloningEnabled;
bool _needForceRmEdid;
bool _skipPowerdownEDPPanelWhenHeadDetach;
bool _isDscDisabledByRegkey;
bool _isMstDisabledByRegkey;
bool _isFECSupported;
bool _useDfpMaxLinkRateCaps;
bool _applyLinkBwOverrideWarRegVal;
bool _isDynamicMuxCapable;
bool _enableMSAOverrideOverMST;
bool _isLTPhyRepeaterSupported;
//
// LTTPR count reported by RM, it might not be the same with DPLib probe
// For example, some Intel LTTPR might not be ready to response 0xF0000 probe
// done by RM, but when DPLib checks the same DPCD offsets it responses
// properly. This will cause serious LT problem.
//
unsigned _rmPhyRepeaterCount;
struct DSC
{
bool isDscSupported;
unsigned encoderColorFormatMask;
unsigned lineBufferSizeKB;
unsigned rateBufferSizeKB;
unsigned bitsPerPixelPrecision;
unsigned maxNumHztSlices;
unsigned lineBufferBitDepth;
}_DSC;
private:
virtual void initializeRegkeyDatabase();
virtual void applyRegkeyOverrides();
public:
EvoMainLink(EvoInterface * provider, Timer * timer);
virtual bool hasIncreasedWatermarkLimits()
{
return _hasIncreasedWatermarkLimits;
}
virtual bool hasMultistream()
{
return _hasMultistream;
}
virtual bool isPC2Disabled()
{
return _isPC2Disabled;
}
virtual bool isDP1_2Supported()
{
return _isDP1_2Supported;
}
virtual bool isDP1_4Supported()
{
return _isDP1_4Supported;
}
virtual bool isFECSupported()
{
return _isFECSupported;
}
virtual bool isStreamCloningEnabled()
{
return _isStreamCloningEnabled;
}
virtual NvU32 maxLinkRateSupported()
{
//
// For cases where RM asks dplib to honor the maxLinkRate limit defined in DCB, always use
// this as the limit. Regkey has no meaning in this case.
// In other cases, based on regkey either honor the dcb limit or the max link rate for the
// specific GPU architecture. This is needed to avoid regressions on existing chips.
//
if ((_applyLinkBwOverrideWarRegVal || _useDfpMaxLinkRateCaps) &&
(_maxLinkRateSupportedDfp < _maxLinkRateSupportedGpu))
{
return _maxLinkRateSupportedDfp;
}
return _maxLinkRateSupportedGpu;
}
virtual bool isForceRmEdidRequired()
{
return _needForceRmEdid;
}
virtual bool fetchEdidByRmCtrl(NvU8* edidBuffer, NvU32 bufferSize);
virtual bool applyEdidOverrideByRmCtrl(NvU8* edidBuffer, NvU32 bufferSize);
virtual bool isDynamicMuxCapable()
{
return _isDynamicMuxCapable;
}
virtual bool isInternalPanelDynamicMuxCapable()
{
return (_isDynamicMuxCapable && _isEDP);
}
// Get GPU DSC capabilities
virtual void getDscCaps(bool *pbDscSupported,
unsigned *pEncoderColorFormatMask,
unsigned *pLineBufferSizeKB,
unsigned *pRateBufferSizeKB,
unsigned *pBitsPerPixelPrecision,
unsigned *pMaxNumHztSlices,
unsigned *pLineBufferBitDepth)
{
if (pbDscSupported)
{
*pbDscSupported = _DSC.isDscSupported;
}
if (pEncoderColorFormatMask)
{
*pEncoderColorFormatMask = _DSC.encoderColorFormatMask;
}
if (pLineBufferSizeKB)
{
*pLineBufferSizeKB = _DSC.lineBufferSizeKB;
}
if (pRateBufferSizeKB)
{
*pRateBufferSizeKB = _DSC.rateBufferSizeKB;
}
if (pBitsPerPixelPrecision)
{
*pBitsPerPixelPrecision = _DSC.bitsPerPixelPrecision;
}
if (pMaxNumHztSlices)
{
*pMaxNumHztSlices = _DSC.maxNumHztSlices;
}
if (pLineBufferBitDepth)
{
*pLineBufferBitDepth = _DSC.lineBufferBitDepth;
}
}
virtual NvU32 getRootDisplayId()
{
return this->displayId;
}
virtual bool isLttprSupported()
{
return this->_isLTPhyRepeaterSupported;
}
// Return the current mux state. Returns false if device is not mux capable
bool getDynamicMuxState(NvU32 *muxState);
virtual bool aquireSema();
virtual void releaseSema();
virtual bool physicalLayerSetTestPattern(PatternInfo * patternInfo);
virtual void preLinkTraining(NvU32 head);
virtual void postLinkTraining(NvU32 head);
virtual NvU32 getRegkeyValue(const char *key);
virtual const DP_REGKEY_DATABASE& getRegkeyDatabase();
virtual NvU32 getSorIndex();
virtual bool isInbandStereoSignalingSupported();
virtual bool train(const LinkConfiguration & link, bool force, LinkTrainingType linkTrainingType,
LinkConfiguration *retLink, bool bSkipLt = false, bool isPostLtAdjRequestGranted = false,
unsigned phyRepeaterCount = 0);
virtual bool retrieveRingBuffer(NvU8 dpRingBuffertype, NvU32 numRecords);
virtual void getLinkConfig(unsigned & laneCount, NvU64 & linkRate);
virtual bool getMaxLinkConfigFromUefi(NvU8 &linkRate, NvU8 &laneCount);
virtual bool setDpMSAParameters(bool bStereoEnable, const NV0073_CTRL_CMD_DP_SET_MSA_PROPERTIES_PARAMS &msaparams);
virtual bool setDpStereoMSAParameters(bool bStereoEnable, const NV0073_CTRL_CMD_DP_SET_MSA_PROPERTIES_PARAMS &msaparams);
virtual bool setFlushMode();
virtual void clearFlushMode(unsigned headMask, bool testMode=false);
virtual bool dscCrcTransaction(NvBool bEnable, gpuDscCrc *data, NvU16 *headIndex);
void triggerACT();
void configureHDCPRenegotiate(NvU64 cN = HDCP_DUMMY_CN, NvU64 cKsv = HDCP_DUMMY_CKSV, bool bForceReAuth = false,
bool bRxIDMsgPending = false);
void configureHDCPGetHDCPState(HDCPState &hdcpState);
bool rmUpdateDynamicDfpCache(NvU32 headIndex, RmDfpCache * dfpCache, NvBool bResetDfp);
virtual NvU32 streamToHead(NvU32 streamId, DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID streamIdentifier = DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID_PRIMARY);
virtual NvU32 headToStream(NvU32 head, DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID streamIdentifier = DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID_PRIMARY);
void configureSingleStream(NvU32 head,
NvU32 hBlankSym,
NvU32 vBlankSym,
bool bEnhancedFraming,
NvU32 tuSize,
NvU32 waterMark,
DP_COLORFORMAT colorFormat,
DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID streamId = DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID_PRIMARY,
DP_SINGLE_HEAD_MULTI_STREAM_MODE singleHeadMultistreamMode = DP_SINGLE_HEAD_MULTI_STREAM_MODE_NONE,
bool bEnableAudioOverRightPanel = false,
bool bEnable2Head1Or = false);
void configureMultiStream(NvU32 head,
NvU32 hBlankSym,
NvU32 vBlankSym,
NvU32 slotStart,
NvU32 slotEnd,
NvU32 PBN,
NvU32 Timeslice,
DP_COLORFORMAT colorFormat,
DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID streamIdentifier = DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID_PRIMARY,
DP_SINGLE_HEAD_MULTI_STREAM_MODE singleHeadMultistreamMode = DP_SINGLE_HEAD_MULTI_STREAM_MODE_NONE,
bool bEnableAudioOverRightPanel = false,
bool bEnable2Head1Or = false);
void configureSingleHeadMultiStreamMode(NvU32 displayIDs[],
NvU32 numStreams,
NvU32 mode,
bool bSetConfig,
NvU8 vbiosPrimaryDispIdIndex = DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID_PRIMARY);
void configureMsScratchRegisters(NvU32 address,
NvU32 hopCount,
NvU32 driverState);
bool isActive();
bool isEDP();
bool skipPowerdownEdpPanelWhenHeadDetach();
bool supportMSAOverMST();
bool queryAndUpdateDfpParams();
bool controlRateGoverning(NvU32 head, bool enable, bool updateNow);
bool getDpTestPattern(NV0073_CTRL_DP_TESTPATTERN *testPattern);
bool setDpTestPattern(NV0073_CTRL_DP_TESTPATTERN testPattern,
NvU8 laneMask, NV0073_CTRL_DP_CSTM cstm,
NvBool bIsHBR2, NvBool bSkipLaneDataOverride);
bool getDpLaneData(NvU32 *numLanes, NvU32 *data);
bool setDpLaneData(NvU32 numLanes, NvU32 *data);
void configurePowerState(bool bPowerUp);
NvU32 monitorDenylistInfo(NvU32 ManufacturerID, NvU32 ProductID, DpMonitorDenylistData *pDenylistData);
NvU32 allocDisplayId();
bool freeDisplayId(NvU32 displayId);
void queryGPUCapability();
bool getEdpPowerData(bool *panelPowerOn, bool *dpcdPowerStateD0);
virtual bool vrrRunEnablementStage(unsigned stage, NvU32 *status);
void configureTriggerSelect(NvU32 head,
DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID streamIdentifier = DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID_PRIMARY);
void configureTriggerAll(NvU32 head, bool enable);
bool configureLinkRateTable(const NvU16 *pLinkRateTable, LinkRates *pLinkRates);
bool configureFec(const bool bEnableFec);
};
}
#endif //INCLUDED_DP_EVOADAPTER_H

View File

@@ -0,0 +1,121 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_groupimpl.h *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_GROUPIMPL_H
#define INCLUDED_DP_GROUPIMPL_H
#include "dp_connector.h"
#include "dp_deviceimpl.h"
#include "dp_linkedlist.h"
#include "dp_watermark.h"
#include "dp_auxdefs.h"
namespace DisplayPort
{
struct GroupImpl : public Group, ListElement, Timer::TimerCallback
{
ConnectorImpl * parent;
LinkedList<Device> members;
List elements;
unsigned headIndex;
unsigned streamIndex;
bool streamValidationDone;
bool headInFirmware; // Set if this is a firmware run mode. If set lastModesetInfo is NOT valid
bool bIsHeadShutdownNeeded; // Set if head shutdown is requested during modeset
bool hdcpEnabled;
bool hdcpPreviousStatus;
bool bWaitForDeAllocACT;
bool bDeferredPayloadAlloc;
ModesetInfo lastModesetInfo;
DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID singleHeadMultiStreamID;
DP_SINGLE_HEAD_MULTI_STREAM_MODE singleHeadMultiStreamMode;
DP_COLORFORMAT colorFormat;
struct
{
unsigned PBN;
int count;
int begin;
bool hardwareDirty; // Does the configureStream need to be called again?
Watermark watermarks; // Cached watermark calculations
} timeslot;
bool bIsCurrentModesetGroup; // Group that is getting attached
GroupImpl(ConnectorImpl * parent, bool isFirmwareGroup = false)
: parent(parent),
streamValidationDone(true),
headInFirmware(false),
bIsHeadShutdownNeeded(true),
hdcpEnabled(false),
hdcpPreviousStatus(false),
bWaitForDeAllocACT(false),
singleHeadMultiStreamID(DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID_PRIMARY),
singleHeadMultiStreamMode(DP_SINGLE_HEAD_MULTI_STREAM_MODE_NONE),
bIsCurrentModesetGroup(false),
headAttached(false)
{
timeslot.count = 0;
}
~GroupImpl()
{
}
virtual void insert(Device * dev);
virtual void remove(Device * dev);
void update(Device * dev, bool allocationState); // send the allocatepayload/deallocatepayload message
bool contains(Device * dev) { return members.contains(dev); }
virtual Device * enumDevices(Device * previousDevice);
void updateVbiosScratchRegister(Device * lastDevice); // Update the VBIOS scratch register with last lit display
//
// Timer callback tags.
// (we pass the address of these variables as context to ::expired)
//
char tagHDCPReauthentication;
char tagStreamValidation;
unsigned authRetries; // Retry counter for the authentication.
virtual void expired(const void * tag);
virtual bool hdcpGetEncrypted();
virtual void destroy();
void cancelHdcpCallbacks();
bool isHeadAttached() { return headAttached; }
void setHeadAttached(bool attached);
private:
bool headAttached; // True if modeset started (during NAB). Sets back to False during NDE
};
}
#endif //INCLUDED_DP_GROUPIMPL_H

View File

@@ -0,0 +1,120 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_guid.h *
* GUID struct and builder class *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_GUID_H
#define INCLUDED_DP_GUID_H
#include "dp_internal.h"
#include "dp_timer.h"
namespace DisplayPort
{
#define DPCD_GUID_SIZE 16
struct GUID
{
NvU8 data[DPCD_GUID_SIZE];
GUID()
{
dpMemZero(&data, sizeof(data));
}
bool isGuidZero()
{
for (unsigned i = 0 ; i < DPCD_GUID_SIZE; i++)
if (data[i])
return false;
return true;
}
bool operator == (const GUID & other) const
{
for (unsigned i = 0 ; i < DPCD_GUID_SIZE; i++)
if (data[i] != other.data[i])
return false;
return true;
}
bool operator != (const GUID & other) const
{
return !((*this) == other);
}
void copyFrom(const NvU8 * buffer)
{
dpMemCopy(&this->data[0], buffer, sizeof data);
}
// XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
// Two Xs per byte, plus four dashes and a NUL byte.
typedef char StringBuffer[DPCD_GUID_SIZE*2 + 5];
char * toString(StringBuffer & buffer) const
{
char *p = &buffer[0];
for (unsigned i = 0; i < DPCD_GUID_SIZE; i++) {
dpByteToHexChar(p, data[i]);
p += 2;
if (i == 3 || i == 5 || i == 7 || i == 9)
*p++ = '-';
}
*p++ = '\0';
DP_ASSERT(p == buffer + sizeof(buffer));
return buffer;
}
};
class GUIDBuilder
{
NvU32 salt;
NvU32 previousRandom;
Timer * source;
//
// Linear congruential random number generator
// Seed values chosen from numerical methods
//
NvU32 random();
public:
GUIDBuilder(Timer * source, NvU32 salt);
void makeGuid(GUID & guid);
};
}
#endif //INCLUDED_DP_GUID_H

View File

@@ -0,0 +1,55 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2015-2021 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_hostimp.h *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_HOSTIMP_H
#define INCLUDED_DP_HOSTIMP_H
#include "nvtypes.h"
#include "dp_tracing.h"
extern "C" void * dpMalloc(NvLength size);
extern "C" void dpFree(void * ptr);
extern "C" void dpDebugBreakpoint();
// Note: dpPrint() implementations are expected to append a newline themselves.
extern "C" void dpPrint(const char * formatter, ...);
extern "C" void dpTraceEvent(NV_DP_TRACING_EVENT event,
NV_DP_TRACING_PRIORITY priority, NvU32 numArgs, ...);
#if defined(_DEBUG) || defined(DEBUG)
#define NV_DP_ASSERT_ENABLED 1
#else
#define NV_DP_ASSERT_ENABLED 0
#endif
#if NV_DP_ASSERT_ENABLED
extern "C" void dpAssert(const char *expression, const char *file,
const char *function, int line);
#endif
#endif // INCLUDED_DP_HOSTIMP_H

View File

@@ -0,0 +1,139 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_internal.h *
* RM stubs to allow unit testing. *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_INTERNAL_H
#define INCLUDED_DP_INTERNAL_H
//
// Clients should not include this file
// This file provides the private malloc implementation.
//
#include <nvtypes.h>
#include <stddef.h> // size_t
#include "dp_object.h"
#include "dp_ringbuffer.h"
static inline void dpByteToHexChar(char *output, NvU8 c)
{
char dig = (c>>4) & 0xF;
output[0] = dig < 10 ? dig + '0' : dig + 'A' - 10;
dig = c & 0xF;
output[1] = dig < 10 ? dig + '0' : dig + 'A' - 10;
}
static inline void dpHexDump(char * output, unsigned outSize, NvU8 * buffer, unsigned size)
{
char * tail = output;
if (outSize < size * 3 + 1)
return;
for (unsigned i = 0; i < size; i++)
{
dpByteToHexChar(tail, buffer[i]);
tail += 2;
*tail++ = ' ';
}
*tail = 0;
}
namespace DisplayPort
{
template <class T>
inline void swap_args(T & left, T & right)
{
T temp = left;
left = right;
right = temp;
}
inline NvU64 divide_ceil(NvU64 a, NvU64 b)
{
return (a + b - 1) / b;
}
inline NvU64 divide_floor(NvU64 a, NvU64 b)
{
return a / b;
}
inline NvU64 axb_div_c_64(NvU64 a, NvU64 b, NvU64 c)
{
// NvU64 arithmetic to keep precision and avoid floats
// a*b/c = (a/c)*b + ((a%c)*b + c/2)/c
return ((a/c)*b + ((a%c)*b + c/2)/c);
}
}
#define DP_MIN(x,y) ((x)<(y)?(x):(y))
#define DP_MAX(x,y) ((x)<(y)?(y):(x))
//
// Macro to suppress unused local variable
//
template <class T> void dp_used(const T & /*x*/) {}
#define DP_USED(x) dp_used(x)
//
// Basic debug logging facility
//
#if NV_DP_ASSERT_ENABLED
#define DP_LOG(x) \
do \
{ \
dpPrint x; \
addDpLogRecord x; \
}while (false)
#define DP_ASSERT(x) \
if (!(x)) \
{ \
addDpAssertRecord(); \
dpAssert(#x, __FILE__, __FUNCTION__, __LINE__); \
dpDebugBreakpoint(); \
}
#else
#define DP_LOG(x)
#define DP_ASSERT(x) \
{ \
DP_USED(x); \
if (!(x)) \
{ \
addDpAssertRecord(); \
} \
}
#endif
#endif //INCLUDED_DP_INTERNAL_H

View File

@@ -0,0 +1,449 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2010-2021 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.
*/
/******************************* List **************************************\
* *
* Module: dp_linkconfig.h *
* Link Configuration object implementation *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_LINKCONFIG_H
#define INCLUDED_DP_LINKCONFIG_H
#include "dp_auxdefs.h"
#include "dp_internal.h"
#include "dp_watermark.h"
#include "ctrl/ctrl0073/ctrl0073specific.h" // NV0073_CTRL_HDCP_VPRIME_SIZE
#include "displayport.h"
namespace DisplayPort
{
typedef NvU64 LinkRate;
class LinkRates : virtual public Object
{
public:
// Store link rate in multipler of 270MBPS to save space
NvU8 element[NV_DPCD_SUPPORTED_LINK_RATES__SIZE];
NvU8 entries;
LinkRates() : entries(0) {}
void clear()
{
entries = 0;
for (int i = 0; i < NV_DPCD_SUPPORTED_LINK_RATES__SIZE; i++)
{
element[i] = 0;
}
}
bool import(NvU8 linkBw)
{
if (entries < NV_DPCD_SUPPORTED_LINK_RATES__SIZE)
{
element[entries] = linkBw;
entries++;
return true;
}
else
return false;
}
NvU8 getNumLinkRates()
{
return entries;
}
LinkRate getLowerRate(LinkRate rate)
{
int i;
NvU8 linkBw = (NvU8)(rate / DP_LINK_BW_FREQ_MULTI_MBPS);
if ((entries == 0) || (linkBw <= element[0]))
return 0;
for (i = entries - 1; i > 0; i--)
{
if (linkBw > element[i])
break;
}
rate = (LinkRate)element[i] * DP_LINK_BW_FREQ_MULTI_MBPS;
return rate;
}
LinkRate getMaxRate()
{
LinkRate rate = 0;
if ((entries > 0) &&
(entries <= NV_DPCD_SUPPORTED_LINK_RATES__SIZE))
{
rate = (LinkRate)element[entries - 1] * DP_LINK_BW_FREQ_MULTI_MBPS;
}
return rate;
}
};
class LinkPolicy : virtual public Object
{
bool bNoFallback; // No fallback when LT fails
LinkRates linkRates;
public:
LinkPolicy() : bNoFallback(false)
{
}
bool skipFallback()
{
return bNoFallback;
}
void setSkipFallBack(bool bSkipFallback)
{
bNoFallback = bSkipFallback;
}
LinkRates *getLinkRates()
{
return &linkRates;
}
};
enum
{
totalTimeslots = 64,
totalUsableTimeslots = totalTimeslots - 1
};
// in MBps
enum
{
RBR = 162000000,
EDP_2_16GHZ = 216000000,
EDP_2_43GHZ = 243000000,
HBR = 270000000,
EDP_3_24GHZ = 324000000,
EDP_4_32GHZ = 432000000,
HBR2 = 540000000,
HBR3 = 810000000
};
struct HDCPState
{
bool HDCP_State_Encryption;
bool HDCP_State_1X_Capable;
bool HDCP_State_22_Capable;
bool HDCP_State_Authenticated;
bool HDCP_State_Repeater_Capable;
};
struct HDCPValidateData
{
};
typedef enum
{
DP_SINGLE_HEAD_MULTI_STREAM_MODE_NONE,
DP_SINGLE_HEAD_MULTI_STREAM_MODE_SST,
DP_SINGLE_HEAD_MULTI_STREAM_MODE_MST,
}DP_SINGLE_HEAD_MULTI_STREAM_MODE;
#define HEAD_INVALID_STREAMS 0
#define HEAD_DEFAULT_STREAMS 1
typedef enum
{
DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID_PRIMARY = 0,
DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID_SECONDARY = 1,
DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID_MAX = DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID_SECONDARY,
} DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID;
#define DP_INVALID_SOR_INDEX 0xFFFFFFFF
#define DSC_DEPTH_FACTOR 16
class LinkConfiguration : virtual public Object
{
public:
LinkPolicy policy;
unsigned lanes;
LinkRate peakRatePossible;
LinkRate peakRate;
LinkRate minRate;
bool enhancedFraming;
bool multistream;
bool disablePostLTRequest;
bool bEnableFEC;
bool bDisableLTTPR;
//
// The counter to record how many times link training happens.
// Client can reset the counter by calling setLTCounter(0)
//
unsigned linkTrainCounter;
LinkConfiguration() :
lanes(0), peakRatePossible(0), peakRate(0), minRate(0),
enhancedFraming(false), multistream(false), disablePostLTRequest(false),
bEnableFEC(false), bDisableLTTPR(false), linkTrainCounter(0) {};
LinkConfiguration(LinkPolicy * p, unsigned lanes, LinkRate peakRate,
bool enhancedFraming, bool MST, bool disablePostLTRequest = false,
bool bEnableFEC = false, bool bDisableLTTPR = false) :
lanes(lanes), peakRatePossible(peakRate), peakRate(peakRate),
enhancedFraming(enhancedFraming), multistream(MST),
disablePostLTRequest(disablePostLTRequest),
bEnableFEC(bEnableFEC), bDisableLTTPR(bDisableLTTPR),
linkTrainCounter(0)
{
// downrate for spread and FEC
minRate = linkOverhead(peakRate);
if (p)
{
policy = *p;
}
}
void setLTCounter(unsigned counter)
{
linkTrainCounter = counter;
}
unsigned getLTCounter()
{
return linkTrainCounter;
}
NvU64 linkOverhead(NvU64 rate)
{
if(bEnableFEC)
{
// if FEC is enabled, we have to account for 3% overhead
// for FEC+downspread according to DP 1.4 spec
return rate - 3 * rate/ 100;
}
else
{
// if FEC is not enabled, link overhead comprises only of
// 0.05% downspread.
return rate - 5 * rate/ 1000;
}
}
void enableFEC(bool setFEC)
{
bEnableFEC = setFEC;
// If FEC is enabled, update minRate with FEC+downspread overhead.
minRate = linkOverhead(peakRate);
}
LinkConfiguration(unsigned long TotalLinkPBN)
: enhancedFraming(true),
multistream(true),
disablePostLTRequest(false),
bEnableFEC(false),
bDisableLTTPR(false),
linkTrainCounter(0)
{
// Reverse engineer a link configuration from Total TotalLinkPBN
// Note that HBR2 twice HBR. The table below treats HBR2x1 and HBRx2, etc.
//
// BW Effective Lanes Total TotalLinkPBN
// 165 1 195.5555556
// 165 2 391.1111111
// 165 4 782.2222222
// 270 1 320
// 270 2 640
// 270 4 1280
// 270 8 2560
//
if (TotalLinkPBN <= 90)
peakRatePossible = peakRate = RBR, minRate = linkOverhead(RBR), lanes=0; // FAIL
if (TotalLinkPBN <= 195)
peakRatePossible = peakRate = RBR, minRate = linkOverhead(RBR), lanes=1;
else if (TotalLinkPBN <= 320)
peakRatePossible = peakRate = HBR, minRate=linkOverhead(HBR), lanes = 1;
else if (TotalLinkPBN <= 391)
peakRatePossible = peakRate = RBR, minRate=linkOverhead(RBR), lanes = 2;
else if (TotalLinkPBN <= 640)
peakRatePossible = peakRate = HBR, minRate=linkOverhead(HBR), lanes = 2; // could be HBR2x1, but TotalLinkPBN works out same
else if (TotalLinkPBN <= 782)
peakRatePossible = peakRate = RBR, minRate=linkOverhead(RBR), lanes = 4;
else if (TotalLinkPBN <= 960)
peakRatePossible = peakRate = HBR3, minRate=linkOverhead(HBR3), lanes = 1;
else if (TotalLinkPBN <= 1280)
peakRatePossible = peakRate = HBR, minRate=linkOverhead(HBR), lanes = 4; // could be HBR2x2
else if (TotalLinkPBN <= 1920)
peakRatePossible = peakRate = HBR3, minRate=linkOverhead(HBR3), lanes = 2; // could be HBR2x
else if (TotalLinkPBN <= 2560)
peakRatePossible = peakRate = HBR2, minRate=linkOverhead(HBR2), lanes = 4;
else if (TotalLinkPBN <= 3840)
peakRatePossible = peakRate = HBR3, minRate=linkOverhead(HBR3), lanes = 4;
else {
peakRatePossible = peakRate = RBR, minRate = linkOverhead(RBR), lanes = 0; // FAIL
DP_ASSERT(0 && "Unknown configuration");
}
}
void setEnhancedFraming(bool newEnhancedFraming)
{
enhancedFraming = newEnhancedFraming;
}
bool isValid()
{
return lanes != laneCount_0;
}
bool lowerConfig(bool bReduceLaneCnt = false)
{
//
// TODO: bReduceLaneCnt is set to fallback to 4 lanes with lower
// valid link rate. But we should reset to max lane count
// sink supports instead.
//
LinkRate lowerRate = policy.getLinkRates()->getLowerRate(peakRate);
if(bReduceLaneCnt)
{
// Reduce laneCount before reducing linkRate
if(lanes == laneCount_1)
{
if (lowerRate)
{
lanes = laneCount_4;
peakRate = lowerRate;
}
else
{
lanes = laneCount_0;
}
}
else
{
lanes /= 2;
}
}
else
{
// Reduce the link rate instead of lane count
if (lowerRate)
{
peakRate = lowerRate;
}
else
{
lanes /= 2;
}
}
minRate = linkOverhead(peakRate);
return lanes != laneCount_0;
}
void setLaneRate(LinkRate newRate, unsigned newLanes)
{
peakRate = newRate;
lanes = newLanes;
minRate = linkOverhead(peakRate);
}
unsigned pbnTotal()
{
return PBNForSlots(totalUsableTimeslots);
}
void pbnRequired(const ModesetInfo & modesetInfo, unsigned & base_pbn, unsigned & slots, unsigned & slots_pbn)
{
base_pbn = pbnForMode(modesetInfo);
slots = slotsForPBN(base_pbn);
slots_pbn = PBNForSlots(slots);
}
NvU32 slotsForPBN(NvU32 allocatedPBN, bool usable = false)
{
NvU64 bytes_per_pbn = 54 * 1000000 / 64; // this comes out exact
NvU64 bytes_per_timeslot = peakRate * lanes / 64;
if (bytes_per_timeslot == 0)
return (NvU32)-1;
if (usable)
{
// round down to find the usable integral slots for a given value of PBN.
NvU32 slots = (NvU32)divide_floor(allocatedPBN * bytes_per_pbn, bytes_per_timeslot);
DP_ASSERT(slots <= 64);
return slots;
}
else
return (NvU32)divide_ceil(allocatedPBN * bytes_per_pbn, bytes_per_timeslot);
}
NvU32 PBNForSlots(NvU32 slots) // Rounded down
{
NvU64 bytes_per_pbn = 54 * 1000000 / 64; // this comes out exact
NvU64 bytes_per_timeslot = peakRate * lanes / 64;
return (NvU32)(bytes_per_timeslot * slots/ bytes_per_pbn);
}
bool operator!= (const LinkConfiguration & right) const
{
return !(*this == right);
}
bool operator== (const LinkConfiguration & right) const
{
return (this->lanes == right.lanes &&
this->peakRate == right.peakRate &&
this->enhancedFraming == right.enhancedFraming &&
this->multistream == right.multistream &&
this->bEnableFEC == right.bEnableFEC);
}
bool operator< (const LinkConfiguration & right) const
{
NvU64 leftMKBps = peakRate * lanes;
NvU64 rightMKBps = right.peakRate * right.lanes;
if (leftMKBps == rightMKBps)
{
return (lanes < right.lanes);
}
else
{
return (leftMKBps < rightMKBps);
}
}
};
}
#endif //INCLUDED_DP_LINKCONFIG_H

View File

@@ -0,0 +1,143 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2015-2021 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_linkedlist.h *
* A linked list that uses DislayPort::List as a backend, but which *
* allocates the list backbone dynamically. *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_LINKEDLIST_H
#define INCLUDED_DP_LINKEDLIST_H
#include "dp_list.h"
namespace DisplayPort
{
template<typename T>
class LinkedList : public Object
{
// The Element class forms the list backbone and contains pointers to
// each item in the list.
class Element : public ListElement
{
public:
Element(T *item) : item(item) { }
T *item;
};
List list;
// No public copy constructor.
LinkedList(LinkedList &other) { }
// Find the Element containing an item.
Element *containing(T *item)
{
for (ListElement *le = list.begin(); le != list.end(); le = le->next)
{
Element *e = static_cast<Element *>(le);
if (e->item == item)
return e;
}
return NULL;
}
public:
// The list starts out empty.
LinkedList() { }
// Insert an item at the front of the list.
void insertFront(T *item)
{
// Construct an element and add it to the list.
Element *e = new Element(item);
DP_ASSERT(e);
if (e)
{
list.insertFront(e);
}
}
// Remove an item from the list.
// O(n) to find the item to remove.
// It is an error to try to remove an item that is not in the list.
void remove(T *item)
{
Element *e = containing(item);
DP_ASSERT(e && "Item was not a member of the list");
delete e;
}
// Find the next item in the list after the specified item. If item is
// NULL, this returns the first item.
T *next(T *prev)
{
if (list.isEmpty())
return NULL;
// If prev is NULL or not in the list, return the first item.
Element *e = containing(prev);
if (!e)
{
e = static_cast<Element *>(list.begin());
return e->item;
}
else if (e->next != list.end())
{
e = static_cast<Element *>(e->next);
return e->item;
}
else
{
// prev was the last element in the list.
return NULL;
}
}
// Query whether an item is a member of the list.
// O(n)
bool contains(T *item)
{
Element *e = containing(item);
return e != NULL;
}
bool isEmpty()
{
return list.isEmpty();
}
T *pop()
{
DP_ASSERT(!list.isEmpty());
Element *e = static_cast<Element *>(list.last());
T *item = e->item;
delete e;
return item;
}
};
}
#endif // INCLUDED_DP_LINKEDLIST_H

View File

@@ -0,0 +1,84 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_list.h *
* Simple doubly linked list queue *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_LIST_H
#define INCLUDED_DP_LIST_H
#include "dp_object.h"
namespace DisplayPort
{
//
// List is an intrusive container, it may
// only contain elements that derive from ListElement
//
// NOTE! Deleting an element automatically unlinks it
// from the enclosing container.
//
struct ListElement : virtual public Object
{
ListElement * next, * prev;
ListElement();
virtual ~ListElement();
};
class List : public ListElement
{
public:
bool isEmpty();
void insertFront(ListElement * item);
void insertBack(ListElement * item);
void insertBefore(ListElement * insertBeforeThis, ListElement * item);
void clear();
ListElement* front();
ListElement* last();
ListElement* begin() { return this->next; }
ListElement* end() { return this; }
static ListElement * remove(ListElement * item); // Removes but does not delete
bool contains(ListElement * item);
ListElement * replace(ListElement * replacement, ListElement * replacee);
List();
~List();
unsigned size()
{
unsigned count = 0;
for (ListElement * i = begin(); i!=end(); i = i->next)
count++;
return count;
}
};
}
#endif //INCLUDED_DP_LIST_H

View File

@@ -0,0 +1,265 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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.
*/
/******************************* List **************************************\
* *
* Module: dp_mainlink.h *
* Mainlink interface implemented by client. *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_MAINLINK_H
#define INCLUDED_DP_MAINLINK_H
#include "dp_linkconfig.h"
#include "dp_vrr.h"
#include "dp_wardatabase.h"
#include "dp_auxdefs.h"
#include "displayport.h"
#include "ctrl/ctrl0073/ctrl0073dp.h"
#include "dp_regkeydatabase.h"
#define HDCP_DUMMY_CN (0x1)
#define HDCP_DUMMY_CKSV (0xFFFFF)
namespace DisplayPort
{
typedef enum
{
NONE, //Abort it manually
UNTRUST, //Abort due to Kp mismatch
UNRELBL, //Abort due to repeated link failure
KSV_LEN, //Abort due to KSV length
KSV_SIG, //Abort due to KSV signature
SRM_SIG, //Abort due to SRM signature
SRM_REV, //Abort due to SRM revocation
NORDY, //Abort due to repeater not ready
KSVTOP, //Abort due to KSV topology error
BADBKSV //Abort due to invalid Bksv
}AbortAuthReason;
// This is also used for DPCD offset 10B. 249
enum LinkQualityPatternType
{
LINK_QUAL_DISABLED,
LINK_QUAL_D10_2,
LINK_QUAL_SYM_ERROR,
LINK_QUAL_PRBS7,
LINK_QUAL_80BIT_CUST,
LINK_QUAL_HBR2_COMPLIANCE_EYE,
LINK_QUAL_CP2520PAT3,
};
typedef struct
{
LinkQualityPatternType lqsPattern;
//
// 80 bits DP CSTM Test Pattern data;
// ctsmLower takes bits 31:0 (lowest 32 bits)
// ctsmMiddle takes bits 63:32 (middle 32 bits)
// ctsmUpper takes bits 79:64 (highest 16 bits)
//
int ctsmLower;
int ctsmMiddle;
int ctsmUpper;
} PatternInfo;
typedef struct
{
unsigned char bcaps;
unsigned char bksv[5];
bool hdcpCapable;
unsigned char updMask;
}RmDfpCache;
typedef enum
{
NORMAL_LINK_TRAINING, // full LT
NO_LINK_TRAINING,
FAST_LINK_TRAINING,
}LinkTrainingType;
class MainLink : virtual public Object
{
private:
virtual void initializeRegkeyDatabase() = 0;
virtual void applyRegkeyOverrides() = 0;
public:
virtual bool physicalLayerSetTestPattern(PatternInfo * patternInfo) = 0;
//
// Wrappers for existing link training RM control calls
//
virtual bool train(const LinkConfiguration & link, bool force, LinkTrainingType linkTrainingType,
LinkConfiguration *retLink, bool bSkipLt = false, bool isPostLtAdjRequestGranted = false,
unsigned phyRepeaterCount = 0) = 0;
// RM control call to retrieve buffer from RM for DP Library to dump logs
virtual bool retrieveRingBuffer(NvU8 dpRingBuffertype, NvU32 numRecords) = 0;
//
// Requests to DD to perform pre & post link training steps
// which may disconnect and later reconnect the head (For Pre-gf119 GPUs)
//
virtual void preLinkTraining(NvU32 head) = 0;
virtual void postLinkTraining(NvU32 head) = 0;
virtual NvU32 getRegkeyValue(const char *key) = 0;
virtual const DP_REGKEY_DATABASE& getRegkeyDatabase() = 0;
virtual NvU32 getSorIndex() = 0;
virtual bool isInbandStereoSignalingSupported() = 0;
virtual bool isEDP() = 0;
virtual bool supportMSAOverMST() = 0;
virtual bool isForceRmEdidRequired() = 0;
virtual bool fetchEdidByRmCtrl(NvU8* edidBuffer, NvU32 bufferSize) = 0;
virtual bool applyEdidOverrideByRmCtrl(NvU8* edidBuffer, NvU32 bufferSize) = 0;
// Return if Panel is Dynamic MUX capable
virtual bool isDynamicMuxCapable() = 0;
// Return the current mux state. Returns false if not mux capable
virtual bool getDynamicMuxState(NvU32 *muxState) = 0;
// Return if Internal panel is Dynamic Mux capable
virtual bool isInternalPanelDynamicMuxCapable() = 0;
// Check if we should skip power down eDP when head detached.
virtual bool skipPowerdownEdpPanelWhenHeadDetach() = 0;
// Get GPU DSC capabilities
virtual void getDscCaps(bool *pbDscSupported = NULL,
unsigned *pEncoderColorFormatMask = NULL,
unsigned *pLineBufferSizeKB = NULL,
unsigned *pRateBufferSizeKB = NULL,
unsigned *pBitsPerPixelPrecision = NULL,
unsigned *pMaxNumHztSlices = NULL,
unsigned *pLineBufferBitDepth = NULL) = 0;
//
// Get the current link config.
// (Used for the boot case where EFI/VBIOS may have already trained
// the link. We need this to confirm the programming since
// we cannot rely on the DPCD registers being correct or sane)
//
virtual void getLinkConfig(unsigned &laneCount, NvU64 & linkRate) = 0;
// Get the max link config from UEFI.
virtual bool getMaxLinkConfigFromUefi(NvU8 &linkRate, NvU8 &laneCount) = 0;
//
// Query if a head is attached to this DisplayId
//
virtual bool isActive() = 0;
virtual bool hasIncreasedWatermarkLimits() = 0;
virtual bool hasMultistream() = 0;
virtual bool isPC2Disabled() = 0;
virtual bool isDP1_2Supported() = 0;
virtual bool isDP1_4Supported() = 0;
virtual bool isStreamCloningEnabled() = 0;
virtual NvU32 maxLinkRateSupported() = 0;
virtual bool isLttprSupported() = 0;
virtual bool isFECSupported() = 0;
virtual bool setDpMSAParameters(bool bStereoEnable, const NV0073_CTRL_CMD_DP_SET_MSA_PROPERTIES_PARAMS &msaparams) = 0;
virtual bool setDpStereoMSAParameters(bool bStereoEnable, const NV0073_CTRL_CMD_DP_SET_MSA_PROPERTIES_PARAMS &msaparams) = 0;
virtual bool setFlushMode() = 0;
virtual void clearFlushMode(unsigned headMask, bool testMode=false) = 0;
//
// HDCP Renegotiate and trigger ACT.
//
virtual void configureHDCPRenegotiate(NvU64 cN = HDCP_DUMMY_CN, NvU64 cKsv = HDCP_DUMMY_CKSV, bool bForceReAuth = false, bool bRxIDMsgPending = false) = 0;
virtual void triggerACT() = 0;
virtual void configureHDCPGetHDCPState(HDCPState &hdcpState) = 0;
virtual NvU32 streamToHead(NvU32 streamId,
DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID streamIdentifier = DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID_PRIMARY) = 0;
virtual NvU32 headToStream(NvU32 head,
DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID streamIdentifier = DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID_PRIMARY) = 0;
virtual void configureSingleStream(NvU32 head,
NvU32 hBlankSym,
NvU32 vBlankSym,
bool bEnhancedFraming,
NvU32 tuSize,
NvU32 waterMark,
DP_COLORFORMAT colorFormat,
DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID streamId = DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID_PRIMARY,
DP_SINGLE_HEAD_MULTI_STREAM_MODE singleHeadMultistreamMode = DP_SINGLE_HEAD_MULTI_STREAM_MODE_NONE,
bool bEnableAudioOverRightPanel = false,
bool bEnable2Head1Or = false)= 0;
virtual void configureMultiStream(NvU32 head,
NvU32 hBlankSym,
NvU32 vBlankSym,
NvU32 slotStart,
NvU32 slotEnd,
NvU32 PBN,
NvU32 Timeslice,
DP_COLORFORMAT colorFormat,
DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID streamIdentifier = DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID_PRIMARY,
DP_SINGLE_HEAD_MULTI_STREAM_MODE singleHeadMultistreamMode = DP_SINGLE_HEAD_MULTI_STREAM_MODE_NONE,
bool bEnableAudioOverRightPanel = false,
bool bEnable2Head1Or = false)= 0;
virtual void configureSingleHeadMultiStreamMode(NvU32 displayIDs[],
NvU32 numStreams,
NvU32 mode,
bool bSetConfig,
NvU8 vbiosPrimaryDispIdIndex = DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID_PRIMARY)= 0;
virtual void configureMsScratchRegisters(NvU32 address,
NvU32 hopCount,
NvU32 driverState) = 0;
virtual bool controlRateGoverning(NvU32 head, bool enable, bool updateNow = true) = 0;
virtual bool getDpTestPattern(NV0073_CTRL_DP_TESTPATTERN * testPattern) = 0;
virtual bool setDpTestPattern(NV0073_CTRL_DP_TESTPATTERN testPattern,
NvU8 laneMask, NV0073_CTRL_DP_CSTM cstm,
NvBool bIsHBR2, NvBool bSkipLaneDataOverride = false) = 0;
virtual bool getDpLaneData(NvU32 *numLanes, NvU32 *data) = 0;
virtual bool setDpLaneData(NvU32 numLanes, NvU32 *data) = 0;
virtual bool rmUpdateDynamicDfpCache(NvU32 headIndex, RmDfpCache * dfpCache, NvBool bResetDfp) = 0;
virtual void configurePowerState(bool bPowerUp) = 0;
virtual NvU32 monitorDenylistInfo(NvU32 ManufacturerID, NvU32 ProductID, DpMonitorDenylistData *pDenylistData) = 0;
virtual NvU32 getRootDisplayId() = 0;
virtual NvU32 allocDisplayId() = 0;
virtual bool freeDisplayId(NvU32 displayId) = 0;
virtual void queryGPUCapability() = 0;
virtual bool queryAndUpdateDfpParams() = 0;
virtual bool getEdpPowerData(bool *panelPowerOn, bool *bDPCDPowerStateD0) = 0;
virtual bool vrrRunEnablementStage(unsigned stage, NvU32 *status) = 0;
virtual void configureTriggerSelect(NvU32 head,
DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID streamIdentifier = DP_SINGLE_HEAD_MULTI_STREAM_PIPELINE_ID_PRIMARY) = 0;
virtual void configureTriggerAll(NvU32 head, bool enable) = 0;
virtual bool dscCrcTransaction(NvBool bEnable, gpuDscCrc *data, NvU16 *headIndex){ return false; }
virtual bool configureLinkRateTable(const NvU16 *pLinkRateTable, LinkRates *pLinkRates) = 0;
virtual bool configureFec(const bool bEnableFec) = 0;
};
}
#endif //INCLUDED_DP_MAINLINK_H

View File

@@ -0,0 +1,148 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_merger.h *
* Asynchronous Message merger *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_MERGER_H
#define INCLUDED_DP_MERGER_H
#include "dp_list.h"
#include "dp_auxretry.h"
#include "dp_timer.h"
#include "dp_bitstream.h"
#include "dp_address.h"
#include "dp_messageheader.h"
#include "dp_configcaps.h"
namespace DisplayPort
{
// after 4 secs delete dead transactions
#define DP_INCOMPLETE_MESSAGE_TIMEOUT_USEC 4000000
struct EncodedMessage;
class MessageTransactionMerger : virtual public Object
{
class IncompleteMessage : public ListElement
{
public:
EncodedMessage message;
NvU64 lastUpdated;
};
List incompleteMessages;
Timer * timer;
NvU64 incompleteMessageTimeoutMs;
IncompleteMessage * freeOnNextCall; // we don't need to delete it on destruct
// since this is ALSO a member of the list we own
IncompleteMessage * getTransactionRecord(const Address & address, unsigned messageNumber);
public:
MessageTransactionMerger(Timer * timer, unsigned incompleteMessageTimeoutMs)
: timer(timer), incompleteMessageTimeoutMs(incompleteMessageTimeoutMs), freeOnNextCall(0)
{
}
//
// Pushes data into the queue and returns an encoded
// message if an entire message is assembled.
//
EncodedMessage * pushTransaction(MessageHeader * header, Buffer * data);
};
class IncomingTransactionManager : virtual public Object
{
public:
class IncomingTransactionManagerEventSink
{
public:
virtual void messagedReceived(IncomingTransactionManager * from, EncodedMessage * message) = 0;
};
void mailboxInterrupt();
//
// Create a message merger object
// - sink is called whenever a new message is received
// Callback::fired is passed an IncompleteMessage as the data arg.
//
IncomingTransactionManager(Timer * timerInterface, const Address & addressPrefix, IncomingTransactionManagerEventSink * sink);
virtual ~IncomingTransactionManager();
protected:
virtual AuxRetry::status readMessageBox(NvU32 offset, NvU8 * data, size_t length) = 0;
virtual size_t getMessageBoxSize() = 0;
virtual size_t getTransactionSize() = 0;
virtual void clearMessageBoxInterrupt() = 0;
private:
MessageTransactionMerger incompleteMessages; // List<IncompleteMessage>
Buffer localWindow;
Timer * timer;
IncomingTransactionManagerEventSink * sink;
Address addressPrefix; // This is the aux address of the downstream port
// This field will be prepended to the address decoded.
};
class DownReplyManager : public IncomingTransactionManager
{
public:
DownReplyManager(DPCDHAL * hal, Timer * timer, const Address & addressPrefix, IncomingTransactionManagerEventSink * sink)
: IncomingTransactionManager(timer, addressPrefix, sink), hal(hal)
{
}
virtual ~DownReplyManager() {}
protected:
DPCDHAL * hal;
virtual AuxRetry::status readMessageBox(NvU32 offset, NvU8 * data, size_t length);
virtual size_t getMessageBoxSize();
virtual size_t getTransactionSize();
virtual void clearMessageBoxInterrupt();
};
class UpRequestManager : public IncomingTransactionManager
{
public:
UpRequestManager(DPCDHAL * hal, Timer * timer, const Address & addressPrefix, IncomingTransactionManagerEventSink * sink)
: IncomingTransactionManager(timer, addressPrefix, sink), hal(hal)
{
}
virtual ~UpRequestManager() {}
protected:
DPCDHAL * hal;
virtual AuxRetry::status readMessageBox(NvU32 offset, NvU8 * data, size_t length);
virtual size_t getMessageBoxSize();
virtual size_t getTransactionSize();
virtual void clearMessageBoxInterrupt();
};
}
#endif //INCLUDED_DP_MERGER_H

View File

@@ -0,0 +1,559 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2010-2021 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_messagecodings.h *
* Encoding routines for various messages. *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_MESSAGECODINGS_H
#define INCLUDED_DP_MESSAGECODINGS_H
#include "dp_messages.h"
#include "displayport.h"
#include "dp_auxdefs.h"
/* Fields for the HDCP stream status */
#define NV_DP_HDCP_STREAM_STATE 1:0
#define NV_DP_HDCP_STREAM_STATE_NO_EXIST (0x00000000)
#define NV_DP_HDCP_STREAM_STATE_NOT_ACTIVE (0x00000001)
#define NV_DP_HDCP_STREAM_STATE_ACTIVE (0x00000002)
#define NV_DP_HDCP_STREAM_STATE_ERROR (0x00000003)
#define NV_DP_HDCP_STREAM_REPEATER 2:2
#define NV_DP_HDCP_STREAM_REPEATER_SIMPLE (0x00000000)
#define NV_DP_HDCP_STREAM_REPEATER_REPEATER (0x00000001)
#define NV_DP_HDCP_STREAM_ENCRYPTION 3:3
#define NV_DP_HDCP_STREAM_ENCRYPTION_OFF (0x00000000)
#define NV_DP_HDCP_STREAM_ENCRYPTION_ON (0x00000001)
#define NV_DP_HDCP_STREAM_AUTHENTICATION 4:4
#define NV_DP_HDCP_STREAM_AUTHENTICATION_OFF (0x00000000)
#define NV_DP_HDCP_STREAM_AUTHENTICATION_IP (0x00000000)
#define NV_DP_HDCP_STREAM_AUTHENTICATION_ON (0x00000001)
#define NV_DP_HDCP_STREAM_OUTPUT_SINK_LEGACY 8:8
#define NV_DP_HDCP_STREAM_OUTPUT_SINK_LEGACY_NO (0x00000000)
#define NV_DP_HDCP_STREAM_OUTPUT_SINK_LEGACY_YES (0x00000001)
#define NV_DP_HDCP_STREAM_OUTPUT_SINK_NON_DP1_2_CP 9:9
#define NV_DP_HDCP_STREAM_OUTPUT_SINK_NON_DP1_2_CP_NO (0x00000000)
#define NV_DP_HDCP_STREAM_OUTPUT_SINK_NON_DP1_2_CP_YES (0x00000001)
#define NV_DP_HDCP_STREAM_OUTPUT_SINK_MULTI 10:10
#define NV_DP_HDCP_STREAM_OUTPUT_SINK_MULTI_NO (0x00000000)
#define NV_DP_HDCP_STREAM_OUTPUT_SINK_MULTI_YES (0x00000001)
#define NV_DP_HDCP_STREAM_OUTPUT_CP_TYPE_HDCP1X 11:11
#define NV_DP_HDCP_STREAM_OUTPUT_CP_TYPE_HDCP1X_NO (0x00000000)
#define NV_DP_HDCP_STREAM_OUTPUT_CP_TYPE_HDCP1X_YES (0x00000001)
#define NV_DP_HDCP_STREAM_OUTPUT_CP_TYPE_HDCP2X 12:12
#define NV_DP_HDCP_STREAM_OUTPUT_CP_TYPE_HDCP2X_NO (0x00000000)
#define NV_DP_HDCP_STREAM_OUTPUT_CP_TYPE_HDCP2X_YES (0x00000001)
namespace DisplayPort
{
typedef NakData Message_NakData;
enum
{
REMOTE_READ_BUFFER_SIZE = 128,
};
typedef enum
{
None,
UpstreamSourceOrSSTBranch,
DownstreamBranch,
DownstreamSink,
Dongle
}PeerDevice;
struct I2cWriteTransaction
{
I2cWriteTransaction(unsigned WriteI2cDeviceId, unsigned NumBytes,
unsigned char * buffer, bool NoStopBit = false,
unsigned I2cTransactionDelay = 0);
I2cWriteTransaction();
unsigned WriteI2cDeviceId;
unsigned NumBytes;
unsigned char *I2cData;
bool NoStopBit;
unsigned I2cTransactionDelay;
};
typedef enum
{
DoesNotExist = 0,
NotActive = 1,
Active = 2,
}StreamState;
typedef enum
{
CP_IRQ_ON = 0,
No_EVENT = 1
}StreamEvent;
typedef enum
{
STREAM_BEHAVIOUR_MASK_OFF = 0,
STREAM_BEHAVIOUR_MASK_ON = 1
}StreamBehaviorMask;
typedef enum
{
STREAM_EVENT_MASK_OFF = 0,
STREAM_EVENT_MASK_ON = 1
}StreamEventMask;
typedef enum
{
Force_Reauth = 0,
BlockFlow = 1
}StreamBehavior;
typedef enum
{
StreamUnconnected = 0,
NonAuthLegacyDevice = 1, // TV or CRT
DP_MST = 4
}OutputSinkType;
typedef enum
{
HDCP1x = 1,
HDCP2x = 2
}OutputCPType;
typedef enum
{
SinkEvent0,
SinkEvent255 = 0xFF
}SinkEvent;
//
// LINK_ADDRESS 0x1
//
class LinkAddressMessage : public MessageManager::Message
{
public:
struct Result
{
bool isInputPort;
PeerDevice peerDeviceType;
unsigned portNumber;
bool hasMessaging;
bool dpPlugged;
bool legacyPlugged;
unsigned dpcdRevisionMajor;
unsigned dpcdRevisionMinor;
GUID peerGUID;
unsigned SDPStreams;
unsigned SDPStreamSinks;
};
virtual ParseResponseStatus parseResponseAck(EncodedMessage * message,
BitStreamReader * reader);
private:
struct
{
GUID guid; // originating branch device
unsigned numberOfPorts;
Result res[16];
} reply;
public:
LinkAddressMessage() : Message(NV_DP_SBMSG_REQUEST_ID_LINK_ADDRESS,
NV_DP_SBMSG_PRIORITY_LEVEL_2)
{
dpMemZero(&reply, sizeof(reply));
}
// Second stage init kept separate from constructor (reusable message)
void set(const Address & target);
void getGUID(GUID & guid){guid = reply.guid;}
// Number of ports described
unsigned resultCount(){return reply.numberOfPorts;}
const Result * result(unsigned index)
{
return &reply.res[index];
}
};
//
// CONNECTION_STATUS_NOTIFY 0x2
//
class ConnStatusNotifyMessage : public MessageManager::MessageReceiver
{
public:
typedef struct
{
GUID guid;
unsigned port;
bool legacyPlugged;
bool devicePlugged;
bool messagingCapability;
bool isInputPort;
PeerDevice peerDeviceType;
}Request;
protected:
Request request;
public:
Request * getUpRequestData(){ return &request; }
virtual bool processByType(EncodedMessage * message, BitStreamReader * reader);
ConnStatusNotifyMessage(MessageReceiverEventSink * sink);
};
//
// GENERIC_UP_REPLY 0xnn
//
class GenericUpReplyMessage : public MessageManager::Message
{
virtual ParseResponseStatus parseResponseAck(EncodedMessage * message,
BitStreamReader * reader);
virtual void expired(const void * tag)
{ }
public:
GenericUpReplyMessage(const Address & target, unsigned requestId,
bool bReplyIsNack = false, bool bBroadcast = true,
bool bPath = false);
GenericUpReplyMessage(unsigned requestId, bool bReplyIsNack,
bool bBroadcast, bool bPath);
void set(const Address & target, bool bReplyIsNack = false,
bool bBroadcast = true, bool bPath = false);
};
//
// CLEAR_PAYLOAD_ID_TABLE 0x14
//
class ClearPayloadIdTableMessage : public MessageManager::Message
{
virtual ParseResponseStatus parseResponseAck(EncodedMessage * message,
BitStreamReader * reader);
virtual ParseResponseStatus parseResponse(EncodedMessage * message);
public:
ClearPayloadIdTableMessage();
};
//
// ENUM_PATH_RESOURCES 0x10
//
class EnumPathResMessage : public MessageManager::Message
{
virtual ParseResponseStatus parseResponseAck(EncodedMessage * message,
BitStreamReader * reader);
public:
struct
{
unsigned portNumber;
bool bFECCapability;
unsigned TotalPBN;
unsigned FreePBN;
} reply;
EnumPathResMessage(const Address & target, unsigned port, bool point);
};
//
// ALLOCATE_PAYLOAD 0x11
//
class AllocatePayloadMessage : public MessageManager::Message
{
virtual ParseResponseStatus parseResponseAck(EncodedMessage * message,
BitStreamReader * reader);
private:
struct
{
unsigned portNumber;
unsigned PBN;
unsigned virtualChannelPayloadId;
}reply;
public:
AllocatePayloadMessage() : Message(NV_DP_SBMSG_REQUEST_ID_ALLOCATE_PAYLOAD,
NV_DP_SBMSG_PRIORITY_LEVEL_4)
{
dpMemZero(&reply, sizeof(reply));
}
void set(const Address & target,
unsigned port,
unsigned nSDPStreams,
unsigned vcPayloadId,
unsigned PBN,
unsigned* SDPStreamSink,
bool entirePath);
unsigned replyPortNumber(){return reply.portNumber;}
unsigned replyPBN(){return reply.PBN;}
unsigned replyVirtualChannelPayloadId(){return reply.virtualChannelPayloadId;}
};
//
// QUERY_PAYLOAD 0x12
//
class QueryPayloadMessage : public MessageManager::Message
{
virtual ParseResponseStatus parseResponseAck(EncodedMessage * message,
BitStreamReader * reader);
private:
struct
{
unsigned portNumber;
unsigned allocatedPBN;
} reply;
public:
QueryPayloadMessage(const Address & target,
unsigned port,
unsigned vcPayloadId);
unsigned replyPortNumber() {return reply.portNumber;}
unsigned replyAllocatedPBN() {return reply.allocatedPBN;}
};
//
// RESOURCE_STATUS_NOTIFY 0x13
//
class ResStatusNotifyMessage : public MessageManager::MessageReceiver
{
virtual bool processByType(EncodedMessage * message,
BitStreamReader * reader);
public:
struct
{
unsigned port;
GUID guid;
unsigned PBN;
} request;
public:
ResStatusNotifyMessage(MessageReceiverEventSink * sink);
};
//
// REMOTE_DPCD_READ 0x20
//
class RemoteDpcdReadMessage : public MessageManager::Message
{
virtual ParseResponseStatus parseResponseAck(EncodedMessage * message,
BitStreamReader * reader);
private:
struct
{
unsigned portNumber;
unsigned numBytesReadDPCD;
unsigned char readData[REMOTE_READ_BUFFER_SIZE]; // Buffer
} reply;
public:
void set(const Address & target,
unsigned port,
unsigned dpcdAddress,
unsigned nBytesToRead);
RemoteDpcdReadMessage() : Message(NV_DP_SBMSG_REQUEST_ID_REMOTE_DPCD_READ,
NV_DP_SBMSG_PRIORITY_LEVEL_3)
{
dpMemZero(&reply, sizeof(reply));
}
unsigned replyPortNumber(){return reply.portNumber;}
unsigned replyNumOfBytesReadDPCD(){return reply.numBytesReadDPCD;}
const NvU8 * replyGetData()
{
return reply.readData;
}
};
//
// REMOTE_DPCD_WRITE 0x21
//
class RemoteDpcdWriteMessage : public MessageManager::Message
{
virtual ParseResponseStatus parseResponseAck(EncodedMessage * message,
BitStreamReader * reader);
public:
void set(const Address & target,
unsigned port,
unsigned dpcdAddress,
unsigned nBytesToWrite,
const NvU8 * writeData);
RemoteDpcdWriteMessage() : Message(NV_DP_SBMSG_REQUEST_ID_REMOTE_DPCD_WRITE,
NV_DP_SBMSG_PRIORITY_LEVEL_3) {}
};
//
// REMOTE_I2C_READ 0x22
//
class RemoteI2cReadMessage : public MessageManager::Message
{
virtual ParseResponseStatus parseResponseAck(EncodedMessage * message,
BitStreamReader * reader);
private:
struct
{
unsigned portNumber;
unsigned numBytesReadI2C;
unsigned char readData[REMOTE_READ_BUFFER_SIZE];
} reply;
public:
RemoteI2cReadMessage() : Message(NV_DP_SBMSG_REQUEST_ID_REMOTE_I2C_READ,
NV_DP_SBMSG_PRIORITY_LEVEL_3)
{
dpMemZero(&reply, sizeof(reply));
}
void set(const Address & target,
unsigned nWriteTransactions,
unsigned port,
I2cWriteTransaction* transactions,
unsigned readI2cDeviceId,
unsigned nBytesToRead);
unsigned replyPortNumber(){return reply.portNumber;}
unsigned replyNumOfBytesReadI2C(){return reply.numBytesReadI2C;}
unsigned char* replyGetI2CData(unsigned* numBytes)
{
*numBytes = this->replyNumOfBytesReadI2C();
return reply.readData;
}
};
//
// REMOTE_I2C_WRITE 0x23
//
class RemoteI2cWriteMessage : public MessageManager::Message
{
virtual ParseResponseStatus parseResponseAck(EncodedMessage * message,
BitStreamReader * reader);
private:
struct
{
unsigned portNumber;
} reply;
public:
RemoteI2cWriteMessage() : Message(NV_DP_SBMSG_REQUEST_ID_REMOTE_I2C_WRITE,
NV_DP_SBMSG_PRIORITY_LEVEL_3)
{
dpMemZero(&reply, sizeof(reply));
}
void set(const Address & target,
unsigned port,
unsigned writeI2cDeviceId,
unsigned nBytesToWrite,
unsigned char* writeData);
unsigned replyPortNumber() {return reply.portNumber;}
};
//
// POWER_UP_PHY 0x24
//
class PowerUpPhyMessage : public MessageManager::Message
{
virtual ParseResponseStatus parseResponseAck(EncodedMessage * message,
BitStreamReader * reader);
private:
struct
{
unsigned portNumber;
} reply;
public:
PowerUpPhyMessage() : Message(NV_DP_SBMSG_REQUEST_ID_POWER_UP_PHY,
NV_DP_SBMSG_PRIORITY_LEVEL_3)
{
dpMemZero(&reply, sizeof(reply));
}
void set(const Address & target,
unsigned port,
bool entirePath);
unsigned replyPortNumber(){return reply.portNumber;}
};
//
// POWER_DOWN_PHY 0x25
//
class PowerDownPhyMessage : public MessageManager::Message
{
virtual ParseResponseStatus parseResponseAck(EncodedMessage * message,
BitStreamReader * reader);
private:
struct
{
unsigned portNumber;
} reply;
public:
PowerDownPhyMessage() : Message(NV_DP_SBMSG_REQUEST_ID_POWER_DOWN_PHY,
NV_DP_SBMSG_PRIORITY_LEVEL_3)
{
dpMemZero(&reply, sizeof(reply));
}
void set(const Address & target,
unsigned port,
bool entirePath);
unsigned replyPortNumber(){return reply.portNumber;}
};
//
// SINK_EVENT_NOTIFY 0x30
//
class SinkEventNotifyMessage : public MessageManager::MessageReceiver
{
virtual bool processByType(EncodedMessage * message, BitStreamReader * reader);
public:
SinkEventNotifyMessage(MessageReceiverEventSink * sink, unsigned requestId);
};
}
#endif //INCLUDED_DP_MESSAGECODINGS_H

View File

@@ -0,0 +1,94 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_messageheader.h *
* DP message header parser *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_MESSAGEHEADER_H
#define INCLUDED_DP_MESSAGEHEADER_H
#include "dp_internal.h"
#include "dp_list.h"
#include "dp_auxretry.h"
#include "dp_timer.h"
#include "dp_bitstream.h"
#include "dp_address.h"
namespace DisplayPort
{
//
// User filled message structure
//
#define MAX_MESSAGE_SIZE 64
struct EncodedMessage : public Object
{
unsigned messageNumber; // 0 or 1
Address address; // target device for message (source for reply)
Buffer buffer;
bool isBroadcast;
bool isPathMessage;
EncodedMessage()
: messageNumber(0), isBroadcast(false), isPathMessage(false)
{}
void swap(EncodedMessage & other)
{
swap_args(messageNumber, other.messageNumber);
swap_args(address, other.address);
swap_args(isBroadcast, other.isBroadcast);
swap_args(isPathMessage, other.isPathMessage);
buffer.swap(other.buffer);
}
};
//
// Decoded message header
//
struct MessageHeader
{
Address address;
unsigned messageNumber;
unsigned payloadBytes;
bool isBroadcast;
bool isPathMessage;
bool isTransactionStart;
bool isTransactionEnd;
unsigned headerSizeBits;
};
bool decodeHeader(BitStreamReader * reader, MessageHeader * header, const Address & address);
//
// Routines for maintaining a list of partially complete messages
//
// after 4 secs delete dead transactions
#define DP_INCOMPLETE_MESSAGE_TIMEOUT_USEC 4000000
}
#endif //INCLUDED_DP_MESSAGEHEADER_H

View File

@@ -0,0 +1,322 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2010-2021 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_messages.h *
* Encoding routines for aux common messages. *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_MESSAGES_H
#define INCLUDED_DP_MESSAGES_H
#include "dp_address.h"
#include "dp_bitstream.h"
#include "dp_splitter.h"
#include "dp_merger.h"
#include "dp_crc.h"
#include "dp_list.h"
#include "dp_connector.h"
#include "dp_messageheader.h"
#include "dp_auxdefs.h"
namespace DisplayPort
{
bool extractGUID(BitStreamReader * reader, GUID * guid);
typedef enum
{
NakUndefined,
NakWriteFailure,
NakInvalidRAD,
NakCrcFailure,
NakBadParam,
NakDefer,
NakLinkFailure,
NakNoResources,
NakDpcdFail,
NakI2cNak,
NakAllocateFail,
// Extensions
NakTimeout = 0x100 // Message was unable to be transmitted
} NakReason;
typedef struct
{
GUID guid;
NakReason reason;
unsigned nak_data;
} NakData;
typedef enum
{
ParseResponseSuccess,
ParseResponseFailed,
ParseResponseWrong
} ParseResponseStatus;
//
// Priority levels are defined to prioritize SBMs for DP1.4 (Highest Priority - LEVEL1, Lowest Priority - DEFAULT)
// Current implementation has the following priority levels
// CLEAR_PAYLOAD_ID_TABLE = NV_DP_SBMSG_PRIORITY_LEVEL_1
// LINK_ADDRESS = NV_DP_SBMSG_PRIORITY_LEVEL_2
// REMOTE_DPCD_READ, REMOTE_DPCD_WRITE = NV_DP_SBMSG_PRIORITY_LEVEL_3
// REMOTE_I2C_READ, REMOTE_I2C_WRITE = NV_DP_SBMSG_PRIORITY_LEVEL_3
// POWER_UP_PHY, POWER_DOWN_PHY = NV_DP_SBMSG_PRIORITY_LEVEL_3
// ENUM_PATH_RESOURCES, ALLOCATE_PAYLOAD = NV_DP_SBMSG_PRIORITY_LEVEL_4
// All other messages = NV_DP_SBMSG_PRIORITY_LEVEL_DEFAULT
//
// However, Message::setMessagePriority can be used to override this priority levels, if required.
//
typedef enum
{
NV_DP_SBMSG_PRIORITY_LEVEL_DEFAULT,
NV_DP_SBMSG_PRIORITY_LEVEL_4,
NV_DP_SBMSG_PRIORITY_LEVEL_3,
NV_DP_SBMSG_PRIORITY_LEVEL_2,
NV_DP_SBMSG_PRIORITY_LEVEL_1,
} DPSideBandMessagePriority;
//
// CLASS: MessageManager
//
class MessageManager :
virtual public Object,
IncomingTransactionManager::IncomingTransactionManagerEventSink
{
Timer * timer;
DPCDHAL * hal;
DownRequestManager splitterDownRequest;
UpReplyManager splitterUpReply;
UpRequestManager mergerUpRequest;
DownReplyManager mergerDownReply;
bool isBeingDestroyed;
bool isPaused;
List messageReceivers;
List notYetSentDownRequest; // Down Messages yet to be processed
List notYetSentUpReply; // Up Reply Messages yet to be processed
List awaitingReplyDownRequest; // Transmitted, Split, but not yet replied to
void onUpRequestReceived(bool status, EncodedMessage * message);
void onDownReplyReceived(bool status, EncodedMessage * message);
void transmitAwaitingDownRequests();
void transmitAwaitingUpReplies();
// IncomingTransactionManager
void messagedReceived(IncomingTransactionManager * from, EncodedMessage * message);
public:
class Message;
void cancelAllByType(unsigned type);
void cancelAll(Message * message);
void pause()
{
isPaused = true;
}
void clearPendingMsg()
{
hal->clearPendingMsg();
}
void IRQUpReqest()
{
mergerUpRequest.mailboxInterrupt();
}
void IRQDownReply()
{
mergerDownReply.mailboxInterrupt();
}
MessageManager(DPCDHAL * hal, Timer * timer)
: timer(timer), hal(hal),
splitterDownRequest(hal, timer),
splitterUpReply(hal, timer),
mergerUpRequest(hal, timer, Address(0), this),
mergerDownReply(hal, timer, Address(0), this),
isBeingDestroyed(false)
{
}
//
// CLASS: MessageReceiver
//
class MessageReceiver : public ListElement, OutgoingTransactionManager::OutgoingTransactionManagerEventSink
{
public:
class MessageReceiverEventSink
{
public:
virtual void messageProcessed(MessageReceiver * from) = 0;
};
// Returns false if the message should be passed to the next receiver
virtual bool process(EncodedMessage * message);
// per message type should implement this
virtual bool processByType(EncodedMessage * message, BitStreamReader * reader) = 0;
unsigned getRequestId() {return requestId;}
Address & getAddress() {return address;}
MessageReceiver(MessageReceiverEventSink* sink, unsigned requestId)
: sink(sink),
requestId(requestId),
bProcessed(true),
address(0) // 0 to start with
{}
virtual void splitterFailed(OutgoingTransactionManager * from)
{
DP_ASSERT(0 && "why did we send a reply");
}
virtual void splitterTransmitted(OutgoingTransactionManager * from)
{
DP_ASSERT(0 && "why did we send a reply");
}
protected:
MessageReceiverEventSink * sink;
unsigned requestId;
bool bProcessed;
Address address;
MessageManager * parent;
};
//
// CLASS: Message
//
class Message : public ListElement,
OutgoingTransactionManager::OutgoingTransactionManagerEventSink,
Timer::TimerCallback /* countdown timer for reply */
{
public:
class MessageEventSink
{
public:
virtual void messageFailed(Message * from, NakData * nakData) = 0;
virtual void messageCompleted(Message * from) = 0;
};
unsigned getMsgType() {return requestIdentifier;}
unsigned getSinkPort() {return sinkPort;}
protected:
// Encoded message body (set in dp_messagecodings)
// this data structure is invalidated on post
// as the data gets swapped into the transmit buffer.
EncodedMessage encodedMessage;
MessageEventSink * sink;
MessageManager * parent;
bool transmitReply;
bool bTransmitted;
unsigned requestIdentifier;
unsigned messagePriority;
unsigned sinkPort;
// State updated by post operation
struct {
unsigned messageNumber;
Address target;
} state;
virtual ParseResponseStatus parseResponseAck(
EncodedMessage * message, BitStreamReader * reader) = 0;
virtual ParseResponseStatus parseResponse(EncodedMessage * message);
virtual void splitterFailed(OutgoingTransactionManager * from);
virtual void expired(const void * tag);
virtual void splitterTransmitted(OutgoingTransactionManager * from);
public:
friend class MessageManager;
Message(int requestIdentifier, int messagePriority)
: sink(0),
parent(0),
transmitReply(false),
bTransmitted(false),
requestIdentifier(requestIdentifier),
messagePriority(messagePriority),
sinkPort(0xFF)
{
}
void clear()
{
if (parent) {
parent->timer->cancelCallbacks(this);
parent->splitterDownRequest.cancel(this);
}
parent = 0;
List::remove(this);
encodedMessage.buffer.reset();
}
// This function can be used to override the already set priority of the message from it's constructor.
void setMessagePriority(DPSideBandMessagePriority priorityLevel)
{
this->messagePriority = priorityLevel;
return;
}
protected:
~Message()
{
clear();
}
};
//
// Register new receiver for unpair messages
// (eg. broadcast messages or sink->source messages)
//
void registerReceiver(MessageReceiver * receiver);
// Post a message to be asynchronously transmitted
void post(Message * message, Message::MessageEventSink * sink, bool isReply = false);
void postReply(Message * message, Message::MessageEventSink * sink);
void cancel(Message * message);
bool send(Message * message, NakData & nakData);
friend class Message;
~MessageManager();
};
struct GenericMessageCompletion : public MessageManager::Message::MessageEventSink
{
bool failed;
bool completed;
NakData nakData;
GenericMessageCompletion();
void messageFailed(MessageManager::Message * from, NakData * data);
void messageCompleted(MessageManager::Message * from);
};
}
#endif //INCLUDED_DP_MESSAGES_H

View File

@@ -0,0 +1,132 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2011-2021 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_object.h *
* This is the object from which all other dynamically-allocated objects *
* must inherit. *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_OBJECT_H
#define INCLUDED_DP_OBJECT_H
#include "nvtypes.h"
#include "stddef.h"
#include "dp_hostimp.h"
static inline void dpMemCopy(void * target, const void * source, size_t len)
{
NvU8 * t = (NvU8 *)target;
const NvU8 * s = (const NvU8 *)source;
while (len--)
*t++=*s++;
}
static inline void dpMemZero(void * target, size_t len)
{
NvU8 * t = (NvU8 *)target;
while (len--)
*t++=0;
}
static inline bool dpMemCmp(void *pvBuf1, void *pvBuf2, size_t size)
{
NvU8 *pBuf1 = (NvU8 *)pvBuf1;
NvU8 *pBuf2 = (NvU8 *)pvBuf2;
if(!pBuf1 || !pBuf2 || !size)
return false;
do
{
if(*pBuf1++ == *pBuf2++)
continue;
else
break;
}while(--size);
if(!size)
return true;
else
return false;
}
namespace DisplayPort
{
//
// Any object allocated through "new" must virtually inherit from this type.
// This guarantees that the memory allocation goes through dpMalloc/dpFree.
// Leak detection is implemented only on allocations of this type. Data
// structures may assume 0 initialization if allocated off the heap.
//
// You must use virtual inheritance because objects that inherit from
// multiple Object-derived classes would otherwise cause ambiguity when
// someone tries to use new or delete on them.
//
struct Object
{
virtual ~Object() {}
void *operator new(size_t sz)
{
void * block = dpMalloc(sz);
if (block)
{
dpMemZero(block, sz);
}
return block;
}
void *operator new[](size_t sz)
{
void * block = dpMalloc(sz);
if (block)
{
dpMemZero(block, sz);
}
return block;
}
void operator delete(void * ptr)
{
if (ptr)
{
dpFree(ptr);
}
}
void operator delete[](void * ptr)
{
if (ptr)
{
dpFree(ptr);
}
}
};
}
#endif // INCLUDED_DP_OBJECT_H

View File

@@ -0,0 +1,108 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2020-2021 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_regkeydatabase.h *
* Definition of the DP_REGKEY_DATABASE *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_REGKEYDATABASE_H
#define INCLUDED_DP_REGKEYDATABASE_H
#include "dp_auxdefs.h"
// Regkey Names
#define NV_DP_REGKEY_ENABLE_AUDIO_BEYOND_48K "ENABLE_AUDIO_BEYOND48K"
#define NV_DP_REGKEY_OVERRIDE_DPCD_REV "OVERRIDE_DPCD_REV"
#define NV_DP_REGKEY_DISABLE_SSC "DISABLE_SSC"
#define NV_DP_REGKEY_ENABLE_FAST_LINK_TRAINING "ENABLE_FAST_LINK_TRAINING"
#define NV_DP_REGKEY_DISABLE_MST "DISABLE_MST"
#define NV_DP_REGKEY_ENABLE_INBAND_STEREO_SIGNALING "ENABLE_INBAND_STEREO_SIGNALING"
#define NV_DP_REGKEY_SKIP_POWEROFF_EDP_IN_HEAD_DETACH "SKIP_POWEROFF_EDP_IN_HEAD_DETACH"
#define NV_DP_REGKEY_ENABLE_OCA_LOGGING "ENABLE_OCA_LOGGING"
#define NV_DP_REGKEY_REPORT_DEVICE_LOST_BEFORE_NEW "HP_WAR_1707690"
#define NV_DP_REGKEY_APPLY_LINK_BW_OVERRIDE_WAR "APPLY_LINK_BW_OVERRIDE_WAR"
#define NV_DP_REGKEY_APPLY_MAX_LINK_RATE_OVERRIDES "APPLY_OVERRIDES_FOR_BUG_2489143"
#define NV_DP_REGKEY_DISABLE_DSC "DISABLE_DSC"
#define NV_DP_REGKEY_SKIP_ASSESSLINK_FOR_EDP "HP_WAR_2189772"
#define NV_DP_REGKEY_HDCP_AUTH_ONLY_ON_DEMAND "DP_HDCP_AUTH_ONLY_ON_DEMAND"
#define NV_DP_REGKEY_ENABLE_MSA_OVER_MST "ENABLE_MSA_OVER_MST"
// Keep link alive for SST and MST
#define NV_DP_REGKEY_KEEP_OPT_LINK_ALIVE "DP_KEEP_OPT_LINK_ALIVE"
// Keep link alive when connector is in MST
#define NV_DP_REGKEY_KEEP_OPT_LINK_ALIVE_MST "DP_KEEP_OPT_LINK_ALIVE_MST"
// Keep link alive when connector is in SST
#define NV_DP_REGKEY_KEEP_OPT_LINK_ALIVE_SST "DP_KEEP_OPT_LINK_ALIVE_SST"
#define NV_DP_REGKEY_FORCE_EDP_ILR "DP_BYPASS_EDP_ILR_REV_CHECK"
//
// DSC capability of downstream device should be decided based on device's own
// and its parent's DSC capability.
//
#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"
//
// Data Base used to store all the regkey values.
// The actual data base is declared statically in dp_evoadapter.cpp.
// All entries set to 0 before initialized by the first EvoMainLink constructor.
// The first EvoMainLink constructor will populate that data base.
// Later EvoMainLink will use values from that data base.
//
struct DP_REGKEY_DATABASE
{
bool bInitialized; // set to true after the first EvoMainLink instance is constructed
// Below are regkey values
bool bAudioBeyond48kEnabled;
NvU32 dpcdRevOveride;
bool bSscDisabled;
bool bFastLinkTrainingEnabled;
bool bMstDisabled;
bool bInbandStereoSignalingEnabled;
bool bPoweroffEdpInHeadDetachSkipped;
bool bOcaLoggingEnabled;
bool bReportDeviceLostBeforeNew;
bool bLinkBwOverrideWarApplied;
NvU32 applyMaxLinkRateOverrides;
bool bDscDisabled;
bool bAssesslinkForEdpSkipped;
bool bHdcpAuthOnlyOnDemand;
bool bMsaOverMstEnabled;
bool bOptLinkKeptAlive;
bool bOptLinkKeptAliveMst;
bool bOptLinkKeptAliveSst;
bool bBypassEDPRevCheck;
bool bDscMstCapBug3143315;
bool bDscMstEnablePassThrough;
};
#endif //INCLUDED_DP_REGKEYDATABASE_H

View File

@@ -0,0 +1,33 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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.
*/
#include <nvtypes.h>
#include <dpringbuffertypes.h>
#include "dp_object.h"
#define addToRingBufferCollection(x) {}
#define addDpLogRecord(x, ...) {}
#define addDpAssertRecord() {}
#define queryDpLogRecords(a, b, c) {}
#define resetDpAssertRingBuffer() {}

View File

@@ -0,0 +1,156 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_splitter.h *
* Asynchronous Message splitter *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_SPLITTER_H
#define INCLUDED_DP_SPLITTER_H
#include "dp_list.h"
#include "dp_auxretry.h"
#include "dp_timer.h"
#include "dp_auxdefs.h"
#include "dp_messageheader.h"
namespace DisplayPort
{
struct EncodedMessage;
class DPCDHAL;
class MessageTransactionSplitter
{
EncodedMessage * messageOutstanding; // If set we've pulled an item out of the downQueue queue.
// One or more transactions have been sent as a result
// messageOutstanding->messageOffset show how far into
// the message we are.
unsigned assemblyTransmitted;
public:
void set(EncodedMessage * messageOutstanding)
{
this->messageOutstanding = messageOutstanding;
assemblyTransmitted = 0;
}
//
// Encode the next transaction.
// returns false if there are no more transactions
//
bool get(Buffer & assemblyBuffer);
MessageTransactionSplitter()
{}
};
class OutgoingTransactionManager:
virtual public Object,
private Timer::TimerCallback
{
public:
class OutgoingTransactionManagerEventSink
{
public:
virtual void splitterFailed(OutgoingTransactionManager * from) = 0; // Sink DEFER the writes
virtual void splitterTransmitted(OutgoingTransactionManager * from) = 0; // message was sent (may NACK later)
};
// Send the encoded message. This call is destructive to the EncodedMessage
// passed in
bool send( EncodedMessage & payload, OutgoingTransactionManagerEventSink * sink);
OutgoingTransactionManager(Timer * timer);
virtual ~OutgoingTransactionManager() { timer->cancelCallbacks(this); }
// Do not make any calls to the event sink
void cancel(OutgoingTransactionManagerEventSink * sink);
protected:
virtual AuxRetry::status writeMessageBox(NvU8 * data, size_t length) = 0;
virtual size_t getMessageBoxSize() = 0;
private:
void writeToWindow( bool firstAttempt);
void split();
void expired(const void * tag); // timer callback
unsigned retriesLeft;
Buffer assemblyBuffer;
MessageTransactionSplitter transactionSplitter;
//
// List of outgoing messages
//
struct OutgoingMessage : ListElement
{
OutgoingTransactionManagerEventSink* eventSink;
EncodedMessage message;
};
List queuedMessages;
//
// Message currently assembled in transactionSplitter
// (if any)
//
OutgoingMessage * activeMessage;
Timer * timer;
};
class DownRequestManager : public OutgoingTransactionManager
{
public:
DownRequestManager(DPCDHAL * hal, Timer * timer)
: OutgoingTransactionManager(timer), hal(hal)
{
}
virtual ~DownRequestManager() {}
protected:
DPCDHAL * hal;
virtual AuxRetry::status writeMessageBox(NvU8 * data, size_t length);
virtual size_t getMessageBoxSize();
};
class UpReplyManager : public OutgoingTransactionManager
{
public:
UpReplyManager(DPCDHAL * hal, Timer * timer)
: OutgoingTransactionManager(timer), hal(hal)
{
}
virtual ~UpReplyManager() {}
protected:
DPCDHAL * hal;
virtual AuxRetry::status writeMessageBox(NvU8 * data, size_t length);
virtual size_t getMessageBoxSize();
};
}
#endif //INCLUDED_DP_SPLITTER_H

View File

@@ -0,0 +1,74 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_timeout.h *
* Local timeout management *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_TIMEOUT_H
#define INCLUDED_DP_TIMEOUT_H
#include "dp_timer.h"
namespace DisplayPort
{
//
// Timeout management
//
class Timeout : virtual public Object
{
Timer * timer;
NvU64 timeoutTime; // What time to trigger the timeout at
public:
Timeout(Timer * _timer, int timeoutMilliseconds)
: timer(_timer), timeoutTime(_timer->getTimeUs() + timeoutMilliseconds*1000 + 1 /* counter could be about to roll */)
{
}
NvS64 remainingUs()
{
NvS64 remaining = (NvS64)(timeoutTime - timer->getTimeUs());
// Rollover check
if (remaining < 0)
{
remaining = 0;
}
DP_ASSERT(remaining < ((NvS64)1000000*3600) && "Timeout remaining over an hour");
return remaining;
}
bool valid()
{
return remainingUs() > 0;
}
};
}
#endif //INCLUDED_DP_TIMEOUT_H

View File

@@ -0,0 +1,104 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_timer.h *
* Local timer interface *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_TIMER_H
#define INCLUDED_DP_TIMER_H
#include "dp_list.h"
namespace DisplayPort
{
//
// RawTimer
// This API is expected to be implemented by the
// library client.
//
class RawTimer : virtual public Object
{
public:
struct Callback : virtual public Object
{
virtual void expired() = 0;
};
virtual void queueCallback(Callback * callback, int milliseconds) = 0;
virtual NvU64 getTimeUs() = 0;
virtual void sleep(int milliseconds) = 0;
};
//
// Timer
//
class Timer : public RawTimer::Callback
{
public:
struct TimerCallback
{
virtual void expired(const void * context) = 0;
};
private:
RawTimer * raw;
NvU64 nextTimestamp;
List pending;
struct PendingCallback : ListElement
{
TimerCallback * target;
const void * context;
NvU64 timestamp; // in usec
bool executeInSleep;
};
virtual void expired();
unsigned fire(bool fromSleep);
void _pump(unsigned milliseconds, bool fromSleep);
public:
Timer(RawTimer * raw) : raw(raw) {}
virtual ~Timer() {}
//
// Queue a timer callback.
// Unless the dont-execute-in-sleep flag is
//
void queueCallback(Timer::TimerCallback * target, const void * context, unsigned milliseconds, bool executeInSleep = true);
NvU64 getTimeUs();
void sleep(unsigned milliseconds);
void cancelCallbacks(Timer::TimerCallback * to);
void cancelCallback(Timer::TimerCallback * to, const void * context);
void queueCallbackInOrder(Timer::TimerCallback * target, const void * context, unsigned milliseconds, bool executeInSleep);
void cancelCallbacksWithoutContext(const void * context);
void cancelAllCallbacks();
bool checkCallbacksOfSameContext(const void * context);
};
}
#endif //INCLUDED_DP_TIMER_H

View File

@@ -0,0 +1,128 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2018-2021 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_tracing.h *
* Header file for support of tracing, implemented by a host provider *
* Because this is platform-agnostic, the tracing API *
* is left up to the host interface. *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_TRACING_H
#define INCLUDED_DP_TRACING_H
#include "nvtypes.h"
typedef enum NV_DP_TRACING_EVENT
{
TRACE_DP_ID_HOTPLUG,
TRACE_DP_ID_NEW_SINK_DETECTED,
TRACE_DP_ID_NEW_SINK_REPORTED,
TRACE_DP_ID_NEW_MST_DEVICE,
TRACE_DP_ID_LOST_DEVICE,
TRACE_DP_ID_LINK_ASSESSMENT,
TRACE_DP_ID_LINK_TRAINING_START,
TRACE_DP_ID_LINK_TRAINING_DONE,
TRACE_DP_ID_NOTIFY_ATTACH_BEGIN,
TRACE_DP_ID_NOTIFY_ATTACH_BEGIN_STATUS,
TRACE_DP_ID_NOTIFY_ATTACH_END,
TRACE_DP_ID_NOTIFY_DETACH_BEGIN,
TRACE_DP_ID_NOTIFY_DETACH_END,
TRACE_DP_ID_MESSAGE_EXPIRED
} NV_DP_TRACING_EVENT;
typedef enum NV_DP_TRACING_PRIORITY
{
TRACE_DP_PRIORITY_ERROR,
TRACE_DP_PRIORITY_WARNING,
TRACE_DP_PRIORITY_INFO
} NV_DP_TRACING_PRIORITY;
#define NV_DPTRACE_MAX_PARAMS 8
#define _NV_DPTRACE_EXPAND_HELPER(x) x
#define _NV_DPTRACE_EXPAND(x) _NV_DPTRACE_EXPAND_HELPER(x)
//
// _COUNT_ARGS: Counts the size of an argument list.
//
// For example, if the argument list is two-arguments "A, B", then call it like this:
// _COUNT_ARGS(_placeholder, A, B, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
//
// which maps to the argument names like this:
// _COUNT_ARGS(_0=_placeholder, _1=A, _2=B, _3=9, _4=8, _5=7, _6=6, _7=5, _8=4,, _9=3, _10=2, ...)
//
// and thus _COUNT_ARGS will return 2, the correct size of the argument list.
//
#define _NV_DPTRACE_COUNT_ARGS(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, ...) _10
#define NV_DPTRACE_ERROR(...) NV_DPTRACE_EVENT(TRACE_DP_PRIORITY_ERROR, __VA_ARGS__)
#define NV_DPTRACE_WARNING(...) NV_DPTRACE_EVENT(TRACE_DP_PRIORITY_WARNING, __VA_ARGS__)
#define NV_DPTRACE_INFO(...) NV_DPTRACE_EVENT(TRACE_DP_PRIORITY_INFO, __VA_ARGS__)
//
// When ##__VA_ARGS__ is used, it will delete a preceding comma (',') when
// __VA_ARGS__ is blank (i.e. zero-length argument list). This allows
// the zero-argument case to work without resulting in a syntax error.
//
// We have a placeholder argument as the first parameter to _COUNT_ARGS
// so that we can take advantage of this comma-deleting behavior.
//
// However, there shouldn't be a zero-arg case as of now, because the first arg is the event.
//
#define NV_DPTRACE_EVENT(priority, ...) \
_NV_DPTRACE_SEND(priority, _NV_DPTRACE_EXPAND(_NV_DPTRACE_COUNT_ARGS(_0, ##__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)), __VA_ARGS__)
#define _NV_DPTRACE_SEND(priority, argc, ...) _NV_DPTRACE_EXPAND(_NV_DPTRACE_SEND_N(priority, argc, __VA_ARGS__))
#define _NV_DPTRACE_SEND_N(priority, argc, ...) _NV_DPTRACE_EXPAND(_NV_DPTRACE_##argc(priority, __VA_ARGS__))
// The first argument is the event - macro number is one higher than num args passed to dpTraceEvent
#define _NV_DPTRACE_1(priority, event) \
dpTraceEvent(TRACE_DP_ID_##event, priority, 0);
#define _NV_DPTRACE_2(priority, event, p1) \
dpTraceEvent(TRACE_DP_ID_##event, priority, 1, p1);
#define _NV_DPTRACE_3(priority, event, p1, p2) \
dpTraceEvent(TRACE_DP_ID_##event, priority, 2, p1, p2);
#define _NV_DPTRACE_4(priority, event, p1, p2, p3) \
dpTraceEvent(TRACE_DP_ID_##event, priority, 3, p1, p2, p3);
#define _NV_DPTRACE_5(priority, event, p1, p2, p3, p4) \
dpTraceEvent(TRACE_DP_ID_##event, priority, 4, p1, p2, p3, p4);
#define _NV_DPTRACE_6(priority, event, p1, p2, p3, p4, p5) \
dpTraceEvent(TRACE_DP_ID_##event, priority, 5, p1, p2, p3, p4, p5);
#define _NV_DPTRACE_7(priority, event, p1, p2, p3, p4, p5, p6) \
dpTraceEvent(TRACE_DP_ID_##event, priority, 6, p1, p2, p3, p4, p5, p6);
#define _NV_DPTRACE_8(priority, event, p1, p2, p3, p4, p5, p6, p7) \
dpTraceEvent(TRACE_DP_ID_##event, priority, 7, p1, p2, p3, p4, p5, p6, p7);
#define _NV_DPTRACE_9(priority, event, p1, p2, p3, p4, p5, p6, p7, p8) \
dpTraceEvent(TRACE_DP_ID_##event, priority, 8, p1, p2, p3, p4, p5, p6, p7, p8);
#endif // INCLUDED_DP_TRACING_H

View File

@@ -0,0 +1,95 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_vrr.h *
* Prototypes and definitions related to VRR enablement *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_VRR_H
#define INCLUDED_DP_VRR_H
#include "dp_object.h"
// Worstcase VRR enablement handshake timeout of 600ms (40x15ms)
#define VRR_ENABLE_STATUS_TIMEOUT_THRESHOLD 40
#define VRR_ENABLE_STATUS_TIMEOUT_INTERVAL_MS 15
// Retry enablement threshold in notifyShortPulse()
#define VRR_MAX_RETRIES 3
namespace DisplayPort
{
enum VrrEnableStage
{
VRR_ENABLE_STAGE_MONITOR_ENABLE_BEGIN,
VRR_ENABLE_STAGE_MONITOR_ENABLE_CHALLENGE,
VRR_ENABLE_STAGE_MONITOR_ENABLE_CHECK,
VRR_ENABLE_STAGE_DRIVER_ENABLE_BEGIN,
VRR_ENABLE_STAGE_DRIVER_ENABLE_CHALLENGE,
VRR_ENABLE_STAGE_DRIVER_ENABLE_CHECK,
VRR_ENABLE_STAGE_RESET_MONITOR,
VRR_ENABLE_STAGE_INIT_PUBLIC_INFO,
VRR_ENABLE_STAGE_GET_PUBLIC_INFO,
VRR_ENABLE_STAGE_STATUS_CHECK,
};
struct DeviceImpl;
class VrrEnablement : virtual public Object
{
private:
DeviceImpl *parent;
bool bMonitorEnabled;
bool vrrGetPublicInfo(void);
bool vrrWaitOnEnableStatus(void);
bool vrrEnableMonitor(void);
bool vrrEnableDriver(void);
public:
VrrEnablement(DeviceImpl *parent)
: parent(parent)
{
reset();
}
~VrrEnablement()
{
parent = NULL;
reset();
}
bool start(void);
void reset(void)
{
bMonitorEnabled = false;
}
bool isMonitorEnabled(void);
bool isDriverEnabled(void);
};
}
#endif

View File

@@ -0,0 +1,75 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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.h *
* EDID and OUI based workarounds for panel/TCON issues *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_WARDATABASE_H
#define INCLUDED_DP_WARDATABASE_H
#include "dp_object.h"
namespace DisplayPort
{
#define WAR_MAX_REASSESS_ATTEMPT 3
#define WAR_MAX_RETRAIN_ATTEMPT 3
typedef enum
{
DP_MONITOR_CAPABILITY_DP_SKIP_REDUNDANT_LT = (1 << 0), // Do not train if the link B/W and lane count are already set to the desired quantities
DP_MONITOR_CAPABILITY_DP_SKIP_CABLE_BW_CHECK = (1 << 1), // Skip the link training attempts to test cable bandwidth in CheckDpLink
DP_MONITOR_CAPABILITY_DP_MULTI_WRITE_DPCD_0x600 = (1 << 2), // Repeatedly write 0x1 to 0x600 with extra delays until the read verifies the write
DP_MONITOR_CAPABILITY_DP_WRITE_0x600_BEFORE_LT = (1 << 3), // Power on a monitor before every link training
DP_MONITOR_CAPABILITY_DP_OVERRIDE_OPTIMAL_LINK_CONFIG = (1 << 4), // Override optimal link config
DP_MONITOR_CAPABILITY_DP_OVERRIDE_MAX_LANE_COUNT = (1 << 5), // WAR for some DP monitors which claims more lane count than it really supports. It may generate interrupt storm if unsupported lane count is applied
DP_MONITOR_CAPABILITY_DP_AVOID_UPDATE_POWER_STATE = (1 << 6), // Don't update panel power state when head detach or lid closed
} DP_MONITOR_CAPABILITY;
struct DpMonitorDenylistData: virtual public Object
{
// Max lane count supported override value
unsigned int dpMaxLaneCountOverride;
// Link rate and Lane count value overrides
// when we need to skip BW check
struct
{
unsigned int maxLaneAtHighRate;
unsigned int maxLaneAtLowRate;
} dpSkipCheckLink;
// Link rate and Lane count value overrides
// when we need to force optimal link config
struct
{
unsigned int linkRate;
unsigned int laneCount;
} dpOverrideOptimalLinkConfig;
};
}
#endif // INCLUDED_DP_WARDATABASE_H

View File

@@ -0,0 +1,134 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_watermark.h *
* DP watermark IsModePossible calculations. *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_WATERMARK_H
#define INCLUDED_DP_WATERMARK_H
#include "displayport.h"
#define WAR_AUDIOCLAMPING_FREQ 48000 // Audio freq. more than 48KHz are currently clamped due to bug 925211
namespace DisplayPort
{
class LinkConfiguration;
struct ModesetInfo
{
unsigned twoChannelAudioHz; // if you need 192khz stereo specify 192000 here
unsigned eightChannelAudioHz; // Same setting for multi channel audio.
// DisplayPort encodes 3-8 channel streams as 8 channel
NvU64 pixelClockHz; // Requested pixel clock for the mode
unsigned rasterWidth;
unsigned rasterHeight;
unsigned surfaceWidth; // RasterBlankStartX - newRasterBlankEndX
unsigned surfaceHeight; // Active region height
unsigned depth;
unsigned rasterBlankStartX;
unsigned rasterBlankEndX;
unsigned bitsPerComponent; // Bits per component
bool bEnableDsc; // bEnableDsc=1 indicates DSC would be enabled for the mode
DSC_MODE mode; // DSC Mode
ModesetInfo(): twoChannelAudioHz(0),
eightChannelAudioHz(0),
pixelClockHz(0),
rasterWidth(0),
rasterHeight(0),
surfaceWidth(0),
surfaceHeight(0),
depth(0),
rasterBlankStartX(0),
rasterBlankEndX(0),
bitsPerComponent(0),
bEnableDsc(false),
mode(DSC_SINGLE) {}
ModesetInfo(unsigned newTwoChannelAudioHz, unsigned newEightChannelAudioHz, NvU64 newPixelClockHz,
unsigned newRasterWidth, unsigned newRasterHeight,
unsigned newSurfaceWidth, unsigned newSurfaceHeight, unsigned newDepth,
unsigned newRasterBlankStartX=0, unsigned newRasterBlankEndX=0, bool newBEnableDsc = false,
DSC_MODE newMode = DSC_SINGLE):
twoChannelAudioHz(newTwoChannelAudioHz),
eightChannelAudioHz(newEightChannelAudioHz),
pixelClockHz(newPixelClockHz),
rasterWidth(newRasterWidth),
rasterHeight(newRasterHeight),
surfaceWidth(newSurfaceWidth),
surfaceHeight(newSurfaceHeight),
depth(newDepth),
rasterBlankStartX(newRasterBlankStartX),
rasterBlankEndX(newRasterBlankEndX),
bitsPerComponent(0),
bEnableDsc(newBEnableDsc),
mode(newMode){}
};
struct Watermark
{
unsigned waterMark;
unsigned tuSize;
unsigned hBlankSym;
unsigned vBlankSym;
};
bool isModePossibleSST
(
const LinkConfiguration & linkConfig,
const ModesetInfo & modesetInfo,
Watermark * dpInfo,
bool bUseIncreasedWatermarkLimits = false
);
bool isModePossibleMST
(
const LinkConfiguration & linkConfig,
const ModesetInfo & modesetInfo,
Watermark * dpInfo
);
bool isModePossibleSSTWithFEC
(
const LinkConfiguration & linkConfig,
const ModesetInfo & modesetInfo,
Watermark * dpInfo,
bool bUseIncreasedWatermarkLimits = false
);
bool isModePossibleMSTWithFEC
(
const LinkConfiguration & linkConfig,
const ModesetInfo & modesetInfo,
Watermark * dpInfo
);
// Return Payload Bandwidth Number(PBN)for requested mode
unsigned pbnForMode(const ModesetInfo & modesetInfo);
}
#endif //INCLUDED_DP_WATERMARK_H

View File

@@ -0,0 +1,122 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_testmessage.h *
* *
\***************************************************************************/
#ifndef INCLUDED_DP_TESTMESSAGE_H
#define INCLUDED_DP_TESTMESSAGE_H
#include "dp_auxdefs.h"
#include "dp_connector.h"
#define DP_LPRIME_SIZE 20
namespace DisplayPort
{
// test request status, for DP and nvapi
typedef enum
{
DP_TESTMESSAGE_REQUEST_STATUS_PENDING = 0, // the request is still be processing
DP_TESTMESSAGE_REQUEST_STATUS_DONE = 1, // request has been processed
DP_TESTMESSAGE_REQUEST_STATUS_ERROR = 2, // error, Dp lib busy with other request
DP_TESTMESSAGE_REQUEST_STATUS_NEWREQUEST = 3, // new request for user
} DP_TESTMESSAGE_REQUEST_STATUS;
// Request type enum.
typedef enum
{
} DP_TESTMESSAGE_REQUEST_TYPE;
class TestMessage;
struct ConnectorImpl;
struct DPTestMessageCompletion : public MessageManager::Message::MessageEventSink
{
TestMessage *parent;
public:
void setParent(TestMessage *parent)
{
this->parent = parent;
}
// call back function if message fails, the status of the dp lib(testMessageStatus)
// need to be set to DONE
void messageFailed(MessageManager::Message * from, NakData * data);
// call back function if message complete, the status of the dp lib(testMessageStatus)
// need to be set to DONE.
// If a message has a reply, it is necessary to record the reply in the dp lib to
// send back to user later
void messageCompleted(MessageManager::Message * from);
};
class TestMessage : virtual public Object
{
private:
ConnectorImpl *pConnector;
// check if the user provided request struct is of valid size
inline bool isValidStruct(DP_TESTMESSAGE_REQUEST_TYPE requestType, NvU32 structSize)
{
switch (requestType)
{
default:
return false;
}
}
MessageManager *pMsgManager;
DPTestMessageCompletion diagCompl;
// Data Structure for Generic Message.
NvU32 replyBytes;
public:
DP_TESTMESSAGE_REQUEST_STATUS testMessageStatus;
TestMessage() : testMessageStatus(DP_TESTMESSAGE_REQUEST_STATUS_DONE)
{
diagCompl.setParent(this);
pConnector = 0;
pMsgManager = 0;
replyBytes = 0;
}
DP_TESTMESSAGE_STATUS sendDPTestMessage(void *pBuffer,
NvU32 requestSize,
NvU32 *pDpStatus);
MessageManager * getMessageManager();
void setupTestMessage(MessageManager *msgManager, ConnectorImpl *connector)
{
pMsgManager = msgManager;
pConnector = connector;
}
};
}
#endif

View File

@@ -0,0 +1,315 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_auxretry.cpp *
* Interface implemented by library client. *
* *
\***************************************************************************/
#include "dp_internal.h"
#include "dp_auxbus.h"
#include "dp_auxretry.h"
#include "dp_messageheader.h"
#include "displayport.h"
using namespace DisplayPort;
//
// Read a DPCD address.
// - allows size greater than single transaction/burst size
// - handles defer retries
// - handles nacks with incomplete data
//
AuxRetry::status AuxRetry::readTransaction(int address, NvU8 * buffer, unsigned size, unsigned retries)
{
unsigned completed;
AuxBus::status s;
DP_ASSERT( size <= aux->transactionSize() );
do
{
s = aux->transaction(AuxBus::read, AuxBus::native, address, buffer, size, &completed);
//
// Got success & requested data. Also size of returned data is
// expected & non zero.
//
if ((s == AuxBus::success) && (completed == size) && (completed != 0))
{
return ack;
}
else
{
//
// Handle defer case with a simple retry
//
if (s == AuxBus::defer)
{
if (retries)
{
--retries;
continue;
}
return defer;
}
//
// Nack shouldn't happen in general. Unsupported registers
// are supposed to ACK with size of 0.
//
if ( s == AuxBus::nack )
{
return nack;
}
if ( completed == 0 )
{
return unsupportedRegister;
}
//
// We got less data back than we requested...
// It's unclear when this might happen in the spec.
// We can either
// 1. Split the read into multiple pieces
// (Dangerous since we may receive non-atomic updates)
// 2. Retry
//
if ( completed < size )
{
//
// Retry
//
if (retries)
{
--retries;
continue;
}
else
{
// Closest approximation is a defer
return defer;
}
}
}
} while(retries);
if ((s == AuxBus::defer) || (completed < size))
{
return defer;
}
return ack;
}
//
// Write a DPCD address.
// - allows size greater than single transaction/burst size
// - handles defer retries
// - handles nacks with incomplete data
//
AuxRetry::status AuxRetry::writeTransaction(int address, NvU8 * buffer, unsigned size, unsigned retries)
{
unsigned completed;
AuxBus::status s;
DP_ASSERT( size <= aux->transactionSize() );
do
{
s = aux->transaction(AuxBus::write, AuxBus::native, address, buffer, size, &completed);
//
// Got success & requested data. Also size of returned data is
// expected & non zero.
//
if ((s == AuxBus::success) && (completed == size) && (completed != 0))
{
return ack;
}
else
{
//
// Handle defer case with a simple retry
//
if (s == AuxBus::defer)
{
if (retries)
{
--retries;
continue;
}
return defer;
}
//
// Nack shouldn't happen in general. Unsupported registers
// are supposed to ACK with size of 0.
//
if ( s == AuxBus::nack )
{
return nack;
}
DP_ASSERT( s == AuxBus::success);
if ( completed == 0 )
{
return unsupportedRegister;
}
//
// Incomplete write?
// Shouldn't happen. Just retry if it does
//
if ( completed < size )
{
//
// Retry
//
if (retries)
{
--retries;
continue;
}
else
{
// Closest approximation is a defer
return defer;
}
}
}
} while(retries);
if ((s == AuxBus::defer) || (completed < size))
{
return defer;
}
return ack;
}
//
// Similar to readTransaction except that it supports reading
// larger spans than AuxBus::transactionSize()
//
AuxRetry::status AuxRetry::read(int address, NvU8 * buffer, unsigned size, unsigned retries)
{
for (unsigned i = 0 ; i < size; )
{
int todo = DP_MIN(size - i, aux->transactionSize());
status s = readTransaction(address+i, buffer+i, todo, retries);
if (s != ack)
{
return s;
}
i += todo;
}
return ack;
}
//
// Similar to writeTransaction except that it supports writing
// larger spans than AuxBus::transactionSize()
//
AuxRetry::status AuxRetry::write(int address, NvU8 * buffer, unsigned size, unsigned retries)
{
for (unsigned i = 0 ; i < size; )
{
int todo = DP_MIN(size - i, aux->transactionSize());
status s = writeTransaction(address+i, buffer+i, todo, retries);
if (s != ack)
{
return s;
}
i += todo;
}
return ack;
}
AuxBus::status AuxLogger::transaction(Action action, Type type, int address,
NvU8 * buffer, unsigned sizeRequested,
unsigned * sizeCompleted, unsigned * pNakReason,
NvU8 offset, NvU8 nWriteTransactions)
{
AuxBus::status result = bus->transaction(action, type, address, buffer, sizeRequested, sizeCompleted);
hint[0] = 0;
//
// Do the hex dump.
// - We can't make library calls
// - We need to do this in one printf
if (result == success)
{
if (type == native)
if (address == NV_DPCD_MBOX_DOWN_REQ || address == NV_DPCD_MBOX_UP_REP ||
address == NV_DPCD_MBOX_DOWN_REP || address == NV_DPCD_MBOX_UP_REQ)
{
unsigned len = *sizeCompleted;
Buffer storage(buffer, len);
BitStreamReader reader(&storage, 0, len*8);
MessageHeader header;
DisplayPort::decodeHeader(&reader, &header, Address(1));
Address::StringBuffer sb;
DP_USED(sb);
dpHexDump(&hex[0], sizeof(hex), buffer, header.headerSizeBits/8);
dpHexDump(&hex_body[0], sizeof(hex), buffer + header.headerSizeBits/8, len - header.headerSizeBits/8);
#if defined(_DEBUG) || defined(DEBUG)
const char * name = "";
if (header.isTransactionStart && action==write && len > header.headerSizeBits/8)
name = getRequestId(buffer[header.headerSizeBits/8]);
DP_LOG(("DP-AUX> %s%s%s%s%04Xh hint(to:%s %s%s %s #%d) { %s| %s}",
sizeRequested == *sizeCompleted ? "" : "INCOMPLETE ", getStatus(result),
getAction(action), getType(type), address,
header.address.toString(sb), header.isTransactionStart ? "S" : "",
header.isTransactionEnd ? "E" : "", name, header.messageNumber,
hex, hex_body));
#endif
return result;
}
}
else
hex[0] = 0;
dpHexDump(&hex[0], sizeof(hex), buffer, *sizeCompleted);
DP_LOG(("DP-AUX> %s%s%s%s%04Xh { %s }", sizeRequested == *sizeCompleted ? "" : "INCOMPLETE ",
getStatus(result), getAction(action), getType(type), address, hex));
return result;
}
AuxBus * DisplayPort::CreateAuxLogger(AuxBus * auxBus)
{
return new AuxLogger(auxBus);
}

View File

@@ -0,0 +1,204 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_bitstream.c *
* Implementation of Big Endian bit streams. *
* *
\***************************************************************************/
#include "dp_internal.h"
#include "dp_bitstream.h"
using namespace DisplayPort;
bool BitStreamReader::read(unsigned * value, unsigned bits)
{
unsigned topbit = (7- (this->bitsOffset & 7));
if (this->bitsOffset + bits > this->bitsEnd)
{
return false;
}
//
// We're filling the byte down from 'topbit' towards 0.
// Can we fit all of the bits starting at topbit before
// overflowing to the next byte?
//
if (bits <= (topbit+1))
{
int bottombit = topbit - (bits-1);
*value = (this->buffer()->data[this->bitsOffset / 8] >> bottombit) & ((1 << bits)-1);
this->bitsOffset+=bits;
return true;
}
//
// We're either reading too many bits or we're straddling
// a byte boundary. Serialize bit by bit.
// NOTE: This scenario is entire unlikely. Don't optimize.
//
*value = 0;
while (bits)
{
unsigned bit;
if (!read(&bit, 1))
{
return false;
}
*value = *value * 2 + bit;
bits--;
}
return true;
}
unsigned BitStreamReader::readOrDefault(unsigned bits, unsigned defaultValue)
{
unsigned value;
if (read(&value, bits))
{
return value;
}
else
{
return defaultValue;
}
}
bool BitStreamReader::align(unsigned align)
{
// Verify alignment is a power of two
if (!(align && ((align & (align - 1)) == 0)))
{
DP_ASSERT(0);
}
else
{
if (this->bitsOffset & (align - 1))
{
this->bitsOffset = (this->bitsOffset + align) &~ (align - 1);
}
}
return this->bitsOffset <= this->bitsEnd;
}
bool BitStreamWriter::write(unsigned value, unsigned bits)
{
DP_ASSERT((value < (1ULL << bits)) && "Value out of range");
unsigned topbit = (7- (this->bitsOffset & 7));
if (this->bitsOffset + bits > this->buffer()->length * 8)
{
this->buffer()->resize((this->bitsOffset + bits+7)/8);
}
//
// We're filling the byte down from 'topbit' towards 0.
// Can we fit all of the bits starting at topbit before
// overflowing to the next byte?
//
if (bits <= (topbit+1))
{
int bottombit = topbit - (bits-1);
NvU8 clearmask = ((1 << bits)-1) << bottombit;
this->buffer()->data[this->bitsOffset / 8] = (NvU8)((this->buffer()->data[this->bitsOffset / 8] &~ clearmask) | (value << bottombit));
this->bitsOffset+=bits;
return true;
}
//
// We're either writing too many bits or we're straddling
// a byte boundary. Serialize bit by bit.
// NOTE: This scenario is entire unlikely. Don't optimize.
//
while (bits)
{
bits --;
if (!write( (value >> bits) & 1, 1))
{
return false;
}
}
return true;
}
bool BitStreamWriter::align(unsigned align)
{
// Verify alignment is a power of two
if (!(align && ((align & (align - 1)) == 0)))
{
DP_ASSERT(0);
}
else
{
if (this->bitsOffset & (align - 1))
return this->write(0, align - (this->bitsOffset & (align - 1)));
}
return true;
}
unsigned BitStreamReader::offset()
{
return this->bitsOffset;
}
unsigned BitStreamWriter::offset()
{
return this->bitsOffset;
}
Buffer * BitStreamWriter::buffer()
{
return this->targetBuffer;
}
Buffer * BitStreamReader::buffer()
{
return this->sourceBuffer;
}
BitStreamWriter::BitStreamWriter(Buffer * buffer, unsigned bitsOffset)
{
this->targetBuffer = buffer;
this->bitsOffset = bitsOffset;
}
BitStreamReader::BitStreamReader(Buffer * buffer, unsigned bitsOffset, unsigned bitsCount)
{
this->sourceBuffer = buffer;
this->bitsOffset = bitsOffset;
this->bitsEnd = bitsCount + bitsOffset;
}

View File

@@ -0,0 +1,267 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_buffer.cpp *
* Resizable byte buffer and stream operations *
* *
\***************************************************************************/
#include "dp_internal.h"
#include "dp_buffer.h"
using namespace DisplayPort;
void DisplayPort::swapBuffers(Buffer & left, Buffer & right)
{
NvU8 *tmpData = left.data;
unsigned tmpLength = left.length;
unsigned tmpCapacity = left.capacity;
bool tmpErrorState = left.errorState;
left.data = right.data;
left.length = right.length;
left.capacity = right.capacity;
left.errorState = right.errorState;
right.data = tmpData;
right.length = tmpLength;
right.capacity = tmpCapacity;
right.errorState= tmpErrorState;
}
bool Stream::seek(unsigned where)
{
//
// Allow seek to any position in the file INCLUDING
// the first byte past the end of the file.
//
if (where > this->parent->length)
{
return false;
}
this->byteOffset = where;
return true;
}
bool Stream::read(NvU8 * buffer, unsigned size)
{
unsigned stopReadAt = this->byteOffset + size;
if (stopReadAt > this->parent->length)
{
return false;
}
dpMemCopy(buffer, this->parent->data + this->byteOffset, size);
this->byteOffset = stopReadAt;
return true;
}
bool Buffer::resize(unsigned stopWriteAt)
{
bool mustIncrease = stopWriteAt > this->capacity;
if (mustIncrease || (stopWriteAt * 4 < this->capacity) )
{
unsigned newCapacity;
NvU8 * newBuffer;
newCapacity = 32;
while (newCapacity <= stopWriteAt)
{
newCapacity *= 2;
}
if (newCapacity == this->capacity) {
this->length = stopWriteAt;
return true;
}
newBuffer = (NvU8 *)dpMalloc(sizeof(NvU8) * newCapacity);
if (!newBuffer)
{
if (mustIncrease)
{
if (this->data)
{
dpFree(this->data);
}
this->errorState = true;
this->data = 0;
this->capacity = 0;
this->length = 0;
}
else
newCapacity = this->capacity;
return false;
}
if (this->data)
{
dpMemCopy(newBuffer, this->data, DP_MIN(newCapacity, this->length));
dpFree(this->data);
}
this->data = newBuffer;
this->capacity = newCapacity;
}
this->length = stopWriteAt;
return true;
}
void Buffer::memZero()
{
if (this->data)
dpMemZero(this->data, this->length);
}
bool Stream::write(NvU8 * buffer, unsigned size)
{
unsigned stopWriteAt = this->byteOffset + size;
if (stopWriteAt > this->parent->length)
{
this->parent->resize(stopWriteAt);
}
if (isError())
return false;
dpMemCopy( this->parent->data + this->byteOffset, buffer, size);
this->byteOffset = stopWriteAt;
this->parent->length = DP_MAX(this->parent->length, stopWriteAt);
return true;
}
unsigned Stream::remaining()
{
return this->parent->length - this->byteOffset;
}
unsigned Stream::offset()
{
return this->byteOffset;
}
Buffer::~Buffer()
{
reset();
}
void Buffer::reset()
{
if (this->data)
{
dpFree(this->data);
}
length = 0;
capacity = 0;
data = 0;
errorState = false;
}
bool Buffer::isError() const
{
return this->errorState;
}
Stream::Stream(Buffer * buffer)
: parent(buffer), byteOffset(0)
{
}
bool Stream::isError() const
{
return this->parent->errorState;
}
Buffer::Buffer()
: data(0), length(0), capacity(0), errorState(false)
{
}
Buffer::Buffer(NvU8 * src, unsigned size)
: data(0), length(0), capacity(0), errorState(false)
{
if (src && size && resize(size) && data)
dpMemCopy(data, src, size);
}
Buffer::Buffer(const Buffer & other)
: data(0), length(0), capacity(0), errorState(false)
{
if (other.isError())
{
errorState = true;
}
else
{
if (resize(other.getLength()) && other.getData())
dpMemCopy(getData(), other.getData(), getLength());
}
}
Buffer & Buffer::operator = (const Buffer & other)
{
if (other.isError())
{
errorState = true;
}
else
{
if (resize(other.getLength()))
dpMemCopy(getData(), other.getData(), getLength());
}
return *this;
}
bool Buffer::operator== (const Buffer & other) const
{
if (length != other.length)
return false;
for (unsigned i = 0; i < length; i++)
{
if (data[i] != other.data[i])
return false;
}
return true;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,93 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_crc.cpp *
* CRC Algorithms for the messaging subsystem. *
* *
\***************************************************************************/
#include "dp_internal.h"
#include "dp_bitstream.h"
#include "dp_crc.h"
using namespace DisplayPort;
//
// DP CRC for transactions headers
//
unsigned DisplayPort::dpCalculateHeaderCRC(BitStreamReader * reader)
{
unsigned remainder = 0;
unsigned bit, i;
while (reader->read(&bit, 1))
{
remainder <<= 1;
remainder |= bit;
if ((remainder & 0x10) == 0x10)
{
remainder ^= 0x13;
}
}
for (i = 4; i != 0; i--)
{
remainder <<= 1;
if ((remainder & 0x10) != 0)
{
remainder ^= 0x13;
}
}
return remainder & 0xF;
}
//
// DP CRC for body
//
unsigned DisplayPort::dpCalculateBodyCRC(BitStreamReader * reader)
{
unsigned remainder = 0;
unsigned bit, i;
while (reader->read(&bit, 1))
{
remainder <<= 1;
remainder |= bit;
if ((remainder & 0x100) == 0x100)
{
remainder ^= 0xD5;
}
}
for (i = 8; i != 0; i--)
{
remainder <<= 1;
if ((remainder & 0x100) != 0)
{
remainder ^= 0xD5;
}
}
return remainder & 0xFF;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,928 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2010-2021 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_discovery.cpp *
* The DP MST discovery manager. *
* *
\***************************************************************************/
#include "dp_discovery.h"
#include "dp_messages.h"
#include "dp_tracing.h"
using namespace DisplayPort;
void DiscoveryManager::notifyLongPulse(bool status)
{
if (status)
{
Device device;
device.address = Address(0);
device.branch = hal->getSupportsMultistream();
device.legacy = false;
detectBranch(device);
}
else if (!status)
{
removeDeviceTree(Address());
}
}
void DiscoveryManager::detectBranch(Device device)
{
Address::StringBuffer sb;
DP_USED(sb);
//
// 1. Create a LINK_ADDRESS_MESSAGE to send to this target so that we can find who he is
// 2. Create a REMOTE_DPCD_WRITE to set the GUID for this target
// *alternatively* we may have to use the local DPCD HAL to write this
// 3. Enumerate any children that we may wish to queue detect on.
//
DP_LOG(("%s(): target = %s", __FUNCTION__, device.address.toString(sb)));
BranchDetection * branchDetection = new BranchDetection(this, device);
outstandingBranchDetections.insertBack(branchDetection);
branchDetection->start();
}
void DiscoveryManager::detectSink(DiscoveryManager::Device device, bool bFromCSN)
{
Address::StringBuffer sb;
DP_USED(sb);
DP_LOG(("%s(): target = %s", __FUNCTION__, device.address.toString(sb)));
SinkDetection * sinkDetection = new SinkDetection(this, device, bFromCSN);
sinkDetection->start();
}
DiscoveryManager::Device * DiscoveryManager::findDevice(const Address & address)
{
for (unsigned i = 0; i < currentDevicesCount; i++)
if (currentDevices[i].address == address)
{
if (currentDevices[i].peerGuid.isGuidZero() && currentDevices[i].peerDevice != Dongle &&
(currentDevices[i].dpcdRevisionMajor >= 1 && currentDevices[i].dpcdRevisionMinor >= 2))
{
DP_ASSERT(0 && "Zero guid for device even though its not a dongle type.");
}
return &currentDevices[i];
}
return 0;
}
DiscoveryManager::Device * DiscoveryManager::findDevice(GUID & guid)
{
if (guid.isGuidZero())
{
DP_ASSERT(0 && "zero guid search");
return 0;
}
for (unsigned i = 0; i < currentDevicesCount; i++)
{
if (currentDevices[i].dpcdRevisionMajor <= 1 && currentDevices[i].dpcdRevisionMinor < 2)
continue;
if (currentDevices[i].peerGuid == guid)
return &currentDevices[i];
}
return 0;
}
void DiscoveryManager::addDevice(const DiscoveryManager::Device & device)
{
Address::StringBuffer sb;
DP_USED(sb);
GUID guid = device.peerGuid;
if (guid.isGuidZero() &&
(device.peerDevice != Dongle) &&
(device.dpcdRevisionMajor >= 1 && device.dpcdRevisionMinor >= 2))
{
DP_ASSERT(0 && "GUID missing for the device");
}
DP_ASSERT(!findDevice(device.address) && "Redundant add");
sink->discoveryNewDevice(device);
DP_LOG(("DP-DM> New device '%s' %s %s %s", device.address.toString(sb),
device.branch ? "Branch" : "", device.legacy ? "Legacy" : "",
device.peerDevice == Dongle ? "Dongle" :
device.peerDevice == DownstreamSink ? "DownstreamSink" : ""));
Address::NvU32Buffer addrBuffer;
dpMemZero(addrBuffer, sizeof(addrBuffer));
device.address.toNvU32Buffer(addrBuffer);
NV_DPTRACE_INFO(NEW_MST_DEVICE, device.address.size(), addrBuffer[0], addrBuffer[1],
addrBuffer[2], addrBuffer[3], device.branch, device.legacy, device.peerDevice);
if (currentDevicesCount < maximumTopologyNodes)
{
currentDevices[currentDevicesCount++] = device;
}
}
void DiscoveryManager::removeDevice(Device * device)
{
Address::StringBuffer sb;
DP_USED(sb);
DP_LOG(("DP-DM> Lost device '%s' %s %s %s", device->address.toString(sb),
device->branch ? "Branch" : "", device->legacy ? "Legacy" : "",
device->peerDevice == Dongle ? "Dongle" :
device->peerDevice == DownstreamSink ? "DownstreamSink" : ""));
sink->discoveryLostDevice(device->address);
for (unsigned i = (unsigned)(device-&currentDevices[0]); i < currentDevicesCount - 1; i++)
currentDevices[i] = currentDevices[i+1];
currentDevicesCount--;
}
void DiscoveryManager::removeDeviceTree(const Address & prefix)
{
for (unsigned i = 0; i < currentDevicesCount;)
if (currentDevices[i].address.under(prefix))
removeDevice(&currentDevices[i]);
else
i++;
}
DiscoveryManager::Device * DiscoveryManager::findChildDeviceForBranchWithGuid
(
GUID guid,
unsigned port,
Address & childAddr
)
{
// Find it in relevant parent's device list
DiscoveryManager::Device * parentDevice = findDevice(guid);
if (!parentDevice)
{
DP_LOG(("DM> No Parent present for the device in DB."));
return 0;
}
childAddr = parentDevice->address;
childAddr.append(port);
return (findDevice(childAddr));
}
void DiscoveryManager::SinkDetection::detectCompleted(bool passed)
{
// we could not read or write the guid
if (!passed)
{
//
// DP1.2 monitors that do not support GUID get filtered and dropped as 'not present'.
// Instead we demote such monitors to DP1.1 and continue sink detection so that end
// user at least gets active display scanout on such monitors (albeit reduced to DP1.1).
//
if (device.dpcdRevisionMajor > 1 || device.dpcdRevisionMinor >= 2)
{
Address::StringBuffer sb;
DP_USED(sb);
DP_LOG(("DP-DM> sink at '%s' failed GUID identification, demote to 1.1 sink.",
address.toString(sb)));
device.dpcdRevisionMajor = 1;
device.dpcdRevisionMinor = 1;
}
else
{
// Had it previously been reported as present?
if (Device * device = parent->findDevice(address))
parent->removeDevice(device);
delete this;
return;
}
}
// at this point we are sure that we have a device GUID.
// We need to check whether the device is new to the DB.
// Had we previously reported the device?
Device * oldDevice = parent->findDevice(device.address);
if (!oldDevice)
{
// completely new device
parent->addDevice(device);
}
// If it was a branch and now isn't.. delete the tree of devices under it
else if (oldDevice && oldDevice->branch && !device.branch)
{
parent->removeDeviceTree(device.address);
}
// It changed, delete the previously reported
else if (oldDevice && (oldDevice->legacy != device.legacy ||
oldDevice->dpcdRevisionMajor!= device.dpcdRevisionMajor ||
oldDevice->dpcdRevisionMinor!= device.dpcdRevisionMinor ||
oldDevice->peerDevice != device.peerDevice||
oldDevice->peerGuid != device.peerGuid ||
oldDevice->SDPStreams != device.SDPStreams||
oldDevice->SDPStreamSinks != device.SDPStreamSinks ||
oldDevice->videoSink != device.videoSink))
{
parent->removeDevice(oldDevice);
}
// otherwise.. it already existed, and still does
// We're done
completed = true;
delete this;
}
void DiscoveryManager::BranchDetection::detectCompleted(bool present)
{
//
// Handle device not present
//
if (!present)
{
// Had it previously been reported as present?
if (Device * device = parent->findDevice(address))
parent->removeDevice(device);
delete this;
return;
}
//
// We've got a linkAddressMessage and we were able to program the GUID!
// Report the branch and queue any children that were enumerated for detection
//
parent->addDevice(parentDevice);
unsigned portsToDelete = (1 << (Address::maxPortCount+1)) - 1; // 16 ports
for (unsigned i = 0; i < childCount; i++)
{
Device newDevice;
newDevice.address = address;
newDevice.address.append(child[i].portNumber);
//
// Input port? Nothing plugged in? Delete the tree of all devices under this one
// DP 1.2 Spec : 2.11.9.5.x
//
if (child[i].isInputPort || !child[i].dpPlugged) {
continue;
}
portsToDelete &= ~(1 << child[i].portNumber);
newDevice.peerDevice = child[i].peerDeviceType;
newDevice.legacy = child[i].legacyPlugged && (newDevice.peerDevice == Dongle);
newDevice.dpcdRevisionMajor = child[i].dpcdRevisionMajor;
newDevice.dpcdRevisionMinor = child[i].dpcdRevisionMinor;
// if internal device; use parent's GUID which we ourselves generated or got from the LAM.
if (child[i].portNumber > PHYSICAL_PORT_END)
newDevice.peerGuid = parentDevice.peerGuid;
else
newDevice.peerGuid = child[i].peerGUID;
newDevice.SDPStreams = child[i].SDPStreams;
newDevice.SDPStreamSinks = child[i].SDPStreamSinks;
if (child[i].peerDeviceType == DownstreamBranch &&
child[i].hasMessaging)
{
newDevice.branch = true;
newDevice.videoSink = false;
}
else
{
newDevice.branch = false;
newDevice.videoSink = ((child[i].peerDeviceType == Dongle) ?
child[i].legacyPlugged : true);
}
//
// Had we previously reported the device?
//
Device * oldDevice = parent->findDevice(newDevice.address);
// If it was a branch and now isn't.. delete the tree of devices under it
if (oldDevice && oldDevice->branch && !newDevice.branch)
{
parent->removeDeviceTree(newDevice.address);
}
// It changed, delete
else if (oldDevice && (oldDevice->legacy != newDevice.legacy ||
oldDevice->dpcdRevisionMajor!= newDevice.dpcdRevisionMajor ||
oldDevice->dpcdRevisionMinor!= newDevice.dpcdRevisionMinor ||
oldDevice->peerDevice != newDevice.peerDevice||
oldDevice->peerGuid != newDevice.peerGuid ||
oldDevice->SDPStreams != newDevice.SDPStreams||
oldDevice->SDPStreamSinks != newDevice.SDPStreamSinks ||
oldDevice->videoSink != newDevice.videoSink))
{
parent->removeDevice(oldDevice);
}
// otherwise.. it already existed, and still does
if (newDevice.branch)
{
parent->detectBranch(newDevice);
}
else
{
// the new device is a sink. It may or may not have a guid.
// write the guid if needed.
parent->detectSink(newDevice, false);
}
}
for (unsigned i = 0; i <= Address::maxPortCount; i++)
if ((portsToDelete >> i) & 1)
{
Address a = address;
a.append(i);
parent->removeDeviceTree(a);
}
// We're done
completed = true;
delete this;
}
void DiscoveryManager::BranchDetection::expired(const void * tag)
{
if (retryLinkAddressMessage)
{
Address::StringBuffer sb;
DP_USED(sb);
DP_LOG(("DP-DM> Requeing LINK_ADDRESS_MESSAGE to %s", address.toString(sb)));
retryLinkAddressMessage = false;
linkAddressMessage.set(address);
parent->messageManager->post(&linkAddressMessage, this);
}
else if (retryRemoteDpcdWriteMessage)
{
Address parentAddress = address;
parentAddress.pop();
Address::StringBuffer sb;
DP_USED(sb);
DP_LOG(("DP-DM> Requeing REMOTE_DPCD_WRITE_MESSAGE to %s", parentAddress.toString(sb)));
retryRemoteDpcdWriteMessage = false;
remoteDpcdWriteMessage.set(parentAddress, parentAddress.tail(), NV_DPCD_GUID, sizeof(GUID), (NvU8 *)&parentDevice.peerGuid);
DP_LOG(("DP-DM> Setting GUID (remotely) for '%s' sent REMOTE_DPCD_WRITE {%p}", address.toString(sb), &remoteDpcdWriteMessage));
parent->messageManager->post(&remoteDpcdWriteMessage, this);
}
}
void DiscoveryManager::SinkDetection::expired(const void * tag)
{
if (retryLinkAddressMessage)
{
Address parentAddress = address;
parentAddress.pop();
Address::StringBuffer sb;
DP_USED(sb);
DP_LOG(("DP-DM> Requeueing LAM message to %s", parentAddress.toString(sb)));
retryLinkAddressMessage = false;
linkAddressMessage.set(parentAddress);
parent->messageManager->post(&linkAddressMessage, this);
}
else if (retryRemoteDpcdReadMessage)
{
Address parentAddress = address;
parentAddress.pop();
Address::StringBuffer sb;
DP_USED(sb);
DP_LOG(("DP-DM> Requeueing REMOTE_DPCD_READ_MESSAGE to %s", parentAddress.toString(sb)));
retryRemoteDpcdReadMessage = false;
remoteDpcdReadMessage.set(parentAddress, parentAddress.tail(), NV_DPCD_GUID, sizeof(GUID));
DP_LOG(("DP-DM> Setting GUID (remotely) for '%s' sent REMOTE_DPCD_READ {%p}", address.toString(sb), &remoteDpcdReadMessage));
parent->messageManager->post(&remoteDpcdReadMessage, this);
}
else if (retryRemoteDpcdWriteMessage)
{
Address parentAddress = address;
parentAddress.pop();
Address::StringBuffer sb;
DP_USED(sb);
DP_LOG(("DP-DM> Requeueing REMOTE_DPCD_WRITE_MESSAGE to %s", parentAddress.toString(sb)));
retryRemoteDpcdWriteMessage = false;
remoteDpcdWriteMessage.set(parentAddress,
parentAddress.tail(),
NV_DPCD_GUID, sizeof(GUID),
(NvU8 *)&device.peerGuid);
DP_LOG(("DP-DM> Setting GUID (remotely) for '%s' sent REMOTE_DPCD_WRITE {%p}", address.toString(sb), &remoteDpcdWriteMessage));
parent->messageManager->post(&remoteDpcdWriteMessage, this);
}
}
void DiscoveryManager::BranchDetection::messageFailed(MessageManager::Message * from, NakData * nakData)
{
//
// If any of our messages fail, we've completed detection on this buzzard.
// The only exception is if we get a DEFER - then we retry indefinitely
//
if (from == &linkAddressMessage)
{
if (retriesLinkAddressMessage < DPCD_LINK_ADDRESS_MESSAGE_RETRIES &&
(nakData->reason == NakDefer || nakData->reason == NakTimeout))
{
retriesLinkAddressMessage++;
retryLinkAddressMessage = true;
parent->timer->queueCallback(this, "DISC", DPCD_LINK_ADDRESS_MESSAGE_COOLDOWN);
return;
}
}
if (from == &remoteDpcdWriteMessage)
{
if ((retriesRemoteDpcdWriteMessage < DPCD_REMOTE_DPCD_WRITE_MESSAGE_RETRIES) &&
(nakData->reason == NakDefer || nakData->reason == NakTimeout))
{
retriesRemoteDpcdWriteMessage++;
retryRemoteDpcdWriteMessage = true;
parent->timer->queueCallback(this, "DISC", DPCD_REMOTE_DPCD_WRITE_MESSAGE_COOLDOWN);
return;
}
}
Address::StringBuffer sb;
DP_USED(sb);
DP_LOG(("DP-DM> Message %s {%p} at '%s' failed. Device marked not present.",
from == &linkAddressMessage ? "LINK_ADDRESS_MESSAGE" :
from == &remoteDpcdWriteMessage ? "REMOTE_DPCD_WRITE(GUID)" : "???",
from, address.toString(sb)));
//
// Detection is done and branch doesn't exist.
// (Note this automatically removes self from any list we're in)
//
detectCompleted(false);
}
void DiscoveryManager::SinkDetection::messageFailed(MessageManager::Message * from, NakData * nakData)
{
if (from == &remoteDpcdReadMessage)
{
if ((retriesRemoteDpcdReadMessage < DPCD_REMOTE_DPCD_READ_MESSAGE_RETRIES) &&
(nakData->reason == NakDefer || nakData->reason == NakTimeout))
{
retriesRemoteDpcdReadMessage++;
retryRemoteDpcdReadMessage = true;
parent->timer->queueCallback(this, "DISC", DPCD_REMOTE_DPCD_READ_MESSAGE_COOLDOWN);
return;
}
}
if (from == &remoteDpcdWriteMessage)
{
if ((retriesRemoteDpcdWriteMessage < DPCD_REMOTE_DPCD_WRITE_MESSAGE_RETRIES) &&
(nakData->reason == NakDefer || nakData->reason == NakTimeout))
{
retriesRemoteDpcdWriteMessage++;
retryRemoteDpcdWriteMessage = true;
parent->timer->queueCallback(this, "DISC", DPCD_REMOTE_DPCD_WRITE_MESSAGE_COOLDOWN);
return;
}
}
if (from == &linkAddressMessage)
{
if ((retriesLinkAddressMessage < DPCD_LINK_ADDRESS_MESSAGE_RETRIES) &&
(nakData->reason == NakDefer || nakData->reason == NakTimeout))
{
retriesLinkAddressMessage++;
retryLinkAddressMessage = true;
parent->timer->queueCallback(this, "DISC", DPCD_LINK_ADDRESS_MESSAGE_COOLDOWN);
return;
}
}
Address::StringBuffer sb;
DP_USED(sb);
DP_LOG(("DP-DM> Message %s {%p} at '%s' failed.",
from == &remoteDpcdWriteMessage ? "REMOTE_DPCD_WRITE(GUID)" :
from == &remoteDpcdReadMessage ? "REMOTE_DPCD_READ(GUID)" :
from == &linkAddressMessage ? "LINK_ADDRESS_MESSAGE" : "???",
from, address.toString(sb)));
detectCompleted(false);
}
void DiscoveryManager::SinkDetection::handleLinkAddressDownReply()
{
Address::StringBuffer sb;
DP_USED(sb);
LinkAddressMessage::Result child;
child = *linkAddressMessage.result(address.tail());
device.peerDevice = child.peerDeviceType;
device.dpcdRevisionMajor = child.dpcdRevisionMajor;
device.dpcdRevisionMinor = child.dpcdRevisionMinor;
if (device.dpcdRevisionMajor == 0)
{
device.dpcdRevisionMajor = 1;
device.dpcdRevisionMinor = 1;
}
device.portMap.inputMap |= (1 << child.portNumber);
DP_LOG(("DP-DM> handleLinkAddressDownReply for sink device on '%s': DPCD Rev = %d.%d",
address.toString(sb), device.dpcdRevisionMajor, device.dpcdRevisionMinor));
// Check if the device already has a GUID
// or it is a dongle or on a logical port ; in which case no GUID is required.
if ((!device.peerGuid.isGuidZero()) ||
(device.peerDevice == Dongle) ||
(device.dpcdRevisionMajor <= 1 && device.dpcdRevisionMinor < 2) ||
(device.address.tail() > PHYSICAL_PORT_END))
{
parent->addDevice(device);
delete this;
return;
}
Address parentAddress = address.parent();
remoteDpcdReadMessage.set(parentAddress, address.tail(), NV_DPCD_GUID, sizeof(GUID));
parent->messageManager->post(&remoteDpcdReadMessage, this);
}
void DiscoveryManager::SinkDetection::handleRemoteDpcdReadDownReply()
{
Address::StringBuffer sb;
DP_USED(sb);
DP_LOG(("DP-DM> REMOTE_DPCD_READ {%p} at '%s' completed",
(MessageManager::Message *)&remoteDpcdReadMessage,
address.toString(sb)));
if (remoteDpcdReadMessage.replyNumOfBytesReadDPCD() != sizeof(GUID))
{
DP_ASSERT(0 && "Incomplete GUID in remote DPCD read message");
detectCompleted(false);
return;
}
DP_ASSERT(remoteDpcdReadMessage.replyPortNumber() == address.tail());
device.peerGuid.copyFrom(remoteDpcdReadMessage.replyGetData());
if (!device.peerGuid.isGuidZero())
{
// we got the GUID ... handle device add/remove
detectCompleted(true);
}
else
{
//
// We need to give ourselves a non-zero GUID!
//
parent->guidBuilder.makeGuid(device.peerGuid);
Address parentAddress = address.parent();
remoteDpcdWriteMessage.set(parentAddress,
address.tail(),
NV_DPCD_GUID, sizeof(GUID),
(NvU8 *)&device.peerGuid);
DP_LOG(("DP-DM> Setting GUID (remotely) for '%s' sent REMOTE_DPCD_WRITE {%p}",
address.toString(sb), &remoteDpcdWriteMessage));
parent->messageManager->post(&remoteDpcdWriteMessage, this);
}
}
void DiscoveryManager::BranchDetection::handleLinkAddressDownReply()
{
Address::StringBuffer sb;
DP_USED(sb);
//
// Copy link address results out of the structure
// - We cannot process the contents until after
// we've programmed the GUID. The reasoning is
// that we need to make sure we do not enumerate
// devices not yet in a usable state.
//
childCount = linkAddressMessage.resultCount();
for (unsigned i = 0; i < childCount; i++)
{
child[i] = *linkAddressMessage.result(i);
// also update the portmap
parentDevice.portMap.internalMap = 0xFF00; // ports 0x8 to 0xF are internal
parentDevice.portMap.validMap |= (1 << child[i].portNumber);
if (child[i].isInputPort)
{
parentDevice.peerDevice = child[i].peerDeviceType;
parentDevice.dpcdRevisionMajor = child[i].dpcdRevisionMajor;
parentDevice.dpcdRevisionMinor = child[i].dpcdRevisionMinor;
parentDevice.portMap.inputMap |= (1 << child[i].portNumber);
}
}
linkAddressMessage.getGUID(parentDevice.peerGuid);
if (parentDevice.peerGuid.isGuidZero())
{
//
// We need to give ourselves a non-zero GUID!
//
parent->guidBuilder.makeGuid(parentDevice.peerGuid);
if (address == Address(0))
{
DP_LOG(("DP-DM> Setting GUID (locally) for '%s'", address.toString(sb)));
//
// We're locally connected, use the DPCD HAL to write the new GUID
//
if (AuxRetry::ack != parent->hal->setGUID(parentDevice.peerGuid))
{
detectCompleted(false);
return;
}
detectCompleted(true);
}
else
{
//
// Let's build a remote DPCD request. Remember the target is the *parent*
// of the device we want to talk to
//
Address parentAddress = address;
parentAddress.pop();
remoteDpcdWriteMessage.set(parentAddress, address.tail(),
NV_DPCD_GUID, sizeof(GUID),
(NvU8 *)&parentDevice.peerGuid);
DP_LOG(("DP-DM> Setting GUID (remotely) for '%s' sent REMOTE_DPCD_WRITE {%p}",
address.toString(sb), &remoteDpcdWriteMessage));
parent->messageManager->post(&remoteDpcdWriteMessage, this);
}
}
else
{
//
// Already had a GUID
//
detectCompleted(true);
}
}
void DiscoveryManager::BranchDetection::messageCompleted(MessageManager::Message * from)
{
if (from == &linkAddressMessage)
handleLinkAddressDownReply();
else if (from == &remoteDpcdWriteMessage)
detectCompleted(true);
}
void DiscoveryManager::SinkDetection::messageCompleted(MessageManager::Message * from)
{
if (from == &remoteDpcdReadMessage)
handleRemoteDpcdReadDownReply();
else if (from == &linkAddressMessage)
handleLinkAddressDownReply();
else if (from == &remoteDpcdWriteMessage)
detectCompleted(true);
}
void DiscoveryManager::BranchDetection::start()
{
//
// 1. Create a LINK_ADDRESS_MESSAGE to send to this target so that we can find who he is
// 2. Create a REMOTE_DPCD_WRITE to set the GUID for this target
// *alternatively* we may have to use the local DPCD HAL to write this
// 3. Enumerate any children that we may wish to queue detect on.
//
linkAddressMessage.set(address);
Address::StringBuffer sb;
DP_USED(sb);
DP_LOG(("DP-DM> Detecting '%s' (sending LINK_ADDRESS_MESSAGE {%p})",
address.toString(sb),
(MessageManager::Message *)&linkAddressMessage));
parent->messageManager->post(&linkAddressMessage, this);
}
void DiscoveryManager::SinkDetection::start()
{
//
// Per DP1.4 requirement:
// Send PowerUpPhy message first, to make sure device is ready to work
//
NakData nakData;
powerUpPhyMessage.set(address.parent(), address.tail(), NV_TRUE);
parent->messageManager->send(&powerUpPhyMessage, nakData);
Address::StringBuffer sb;
DP_USED(sb);
// The sink is found in CSN, missing dpcd revision
if (bFromCSN)
{
parent->outstandingSinkDetections.insertBack(this);
// Create a LINK_ADDRESS_MESSAGE to send to parent of this target
linkAddressMessage.set(address.parent());
DP_LOG(("DP-DM> Detecting '%s' (sending LINK_ADDRESS_MESSAGE {%p})",
address.toString(sb),
(MessageManager::Message *)&linkAddressMessage));
parent->messageManager->post(&linkAddressMessage, this);
}
else // The sink is found in LAM sent for branch, and with DPCD rev.
{
// Check if the device already has a GUID
// or it is a dongle or on a logical port ; in which case no GUID is required.
if ((!device.peerGuid.isGuidZero()) ||
(device.peerDevice == Dongle) ||
(device.dpcdRevisionMajor <= 1 && device.dpcdRevisionMinor < 2) ||
(device.address.tail() > PHYSICAL_PORT_END))
{
parent->addDevice(device);
delete this;
return;
}
parent->outstandingSinkDetections.insertBack(this);
Address parentAddress = address.parent();
remoteDpcdReadMessage.set(parentAddress, address.tail(), NV_DPCD_GUID, sizeof(GUID));
parent->messageManager->post(&remoteDpcdReadMessage, this);
}
}
DiscoveryManager::BranchDetection::~BranchDetection()
{
List::remove(this);
if (parent->outstandingSinkDetections.isEmpty() &&
parent->outstandingBranchDetections.isEmpty())
parent->sink->discoveryDetectComplete();
parent->timer->cancelCallbacks(this);
}
DiscoveryManager::SinkDetection::~SinkDetection()
{
List::remove(this);
if (parent->outstandingSinkDetections.isEmpty() &&
parent->outstandingBranchDetections.isEmpty())
parent->sink->discoveryDetectComplete();
parent->timer->cancelCallbacks(this);
}
void DiscoveryManager::ReceiverSink::messageProcessed(MessageManager::MessageReceiver * from)
{
DP_ASSERT((from->getRequestId() == 0x2) && "This receiver is only meant for CSNs");
// CSNs are broadcast messages. So replies will always go to immediate downstream branch
CsnUpReplyContainer * csnReplyContainer = new CsnUpReplyContainer(parent);
parent->pendingCsnUpReplies.insertBack(csnReplyContainer);
//Send acknowledgement to the CSN sender.
csnReplyContainer->postUpReply();
ConnStatusNotifyMessage* csnMessage = static_cast<ConnStatusNotifyMessage*>(from);
if (csnMessage->getUpRequestData()->isInputPort)
{
DP_LOG(("Concentrator?? Got CSN for an upstream port!"));
return;
}
Address childAddr;
DiscoveryManager::Device * oldDevice = parent->findChildDeviceForBranchWithGuid(csnMessage->getUpRequestData()->guid,
csnMessage->getUpRequestData()->port, childAddr);
if (!csnMessage->getUpRequestData()->devicePlugged) // some device was unplugged or powered off
{
if (oldDevice)
parent->removeDeviceTree(childAddr);
return;
}
handleCSN(from);
}
void DiscoveryManager::ReceiverSink::handleCSN(MessageManager::MessageReceiver * from)
{
ConnStatusNotifyMessage* csnMessage = static_cast<ConnStatusNotifyMessage*>(from);
// There is no point in serving an upRequest when no device is present.
if (parent->currentDevicesCount == 0)
{
DP_ASSERT(0 && "DM> No Device in the Topology");
return;
}
//
// Check for non-zero GUID in CSN message. It is mandatory to find respective parent
// Branch should not send CSN with Zero GUID as a unique GUID is set before CSN
//
if ((csnMessage->getUpRequestData()->guid).isGuidZero())
{
DP_ASSERT(0 && "Ignoring CSN. Invalid parent device due to zero-GUID.");
return;
}
Address childAddr;
unsigned port = csnMessage->getUpRequestData()->port;
DiscoveryManager::Device * oldDevice =
parent->findChildDeviceForBranchWithGuid(csnMessage->getUpRequestData()->guid,
port,
childAddr);
// Check if we already have a device
if (oldDevice)
{
oldDevice->dirty = true;
// Set the videoSink status of oldDevice again as old device might be a legacy dongle
// and a video sink is now added with it
oldDevice->videoSink = ((csnMessage->getUpRequestData()->peerDeviceType == Dongle) ?
csnMessage->getUpRequestData()->legacyPlugged : true);
parent->sink->discoveryNewDevice(*oldDevice);
return;
}
// Exit if no valid address matched for further detection.
if ((childAddr.size() == 0) ||
(childAddr.size() > Address::maxHops))
{
DP_ASSERT(0 && "Ignoring CSN. Invalid parent device due to GUID not found in discovered topology");
return;
}
DiscoveryManager::Device newDevice;
newDevice.address = childAddr;
newDevice.branch = (csnMessage->getUpRequestData()->messagingCapability == true) &&
(csnMessage->getUpRequestData()->peerDeviceType == DownstreamBranch);
newDevice.peerDevice = csnMessage->getUpRequestData()->peerDeviceType;
newDevice.legacy = csnMessage->getUpRequestData()->legacyPlugged == true;
newDevice.SDPStreams = newDevice.SDPStreamSinks = 0;
if (csnMessage->getUpRequestData()->devicePlugged) // Check for a new device only if it's plugged
{
if (newDevice.branch)
{
newDevice.videoSink = false;
// send a LAM and the whole nine yards
DP_ASSERT(newDevice.legacy == false);
parent->detectBranch(newDevice);
return;
}
else
{
newDevice.SDPStreams = newDevice.SDPStreamSinks = 1;
newDevice.videoSink = ((csnMessage->getUpRequestData()->peerDeviceType == Dongle) ?
csnMessage->getUpRequestData()->legacyPlugged : true);
parent->detectSink(newDevice, true);
return;
}
}
}

View File

@@ -0,0 +1,625 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2010-2021 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_edid.c *
* Implementation of SST/MST EDID reader *
* *
\***************************************************************************/
#include "dp_buffer.h"
#include "dp_internal.h"
#include "dp_edid.h"
using namespace DisplayPort;
EdidAssembler::EdidAssembler(Edid * const edid, bool bPatchCrc):
edid(edid), stream(edid->getBuffer()), oldBlockChecksum(0x00),
blocksRead(0), totalBlockCnt(0), retriesCount(0),
bPatchCrc(bPatchCrc) {}
bool EdidAssembler::readIsComplete()
{
return (blocksRead > 0 && blocksRead == totalBlockCnt);
}
void EdidAssembler::reset()
{
oldBlockChecksum = 0x00;
blocksRead = 0;
totalBlockCnt = 0;
retriesCount = 0;
stream.seek(0);
}
void EdidAssembler::postReply(const Buffer & buffer, unsigned sizeCompleted, bool success)
{
if (!success || buffer.isError())
{
retriesCount++;
return;
}
//
// For SST:
// Check the Checksum Error Per Block reading, mark the EDID as "patched" if
// CRC is wrong. DPLib will return fallback EDID.
//
blocksRead++;
stream.write(buffer.data, sizeCompleted);
if (getEDIDBlockChecksum(buffer))
{
if (bPatchCrc)
edid->patchCrc();
edid->setPatchedChecksum(true);
}
return;
}
void EdidAssembler::postReply(unsigned char * data, unsigned sizeCompleted, bool success)
{
//
// For MST: When read of edid block failed, library will attempt to read
// same block again, but not more than EDID_POLICY_BLOCK_READ_MAX_RETRY_COUNT times
//
if (!success)
{
retriesCount++;
return;
}
//
// Check the Checksum Error Per Block reading,
// library will attempt to read same block again,
// but not more than EDID_POLICY_BLOCK_READ_MAX_RETRY_COUNT times.
//
Buffer buffer(data, EDID_BLOCK_SIZE);
if (buffer.isError())
{
retriesCount++;
return;
}
NvU8 newBlockChecksum = getEDIDBlockChecksum(buffer);
if (newBlockChecksum)
{
if (this->oldBlockChecksum != newBlockChecksum) //First failure?
{
this->oldBlockChecksum = newBlockChecksum;
retriesCount++;
return;
}
}
this->oldBlockChecksum = 0;
retriesCount = 0;
blocksRead++;
stream.write(data, sizeCompleted);
}
bool EdidAssembler::readNextRequest(NvU8 & seg, NvU8 & offset)
{
//
// cache totalBlockCnt,
// In EDID 1.3 HF-EEODB, it might changes after 1 extension block read.
//
if ((blocksRead == 1) || (blocksRead == 2))
totalBlockCnt = edid->getBlockCount();
//
// will return false in two scenarios
// 1. EDID read is complete, all extension blocks were read
// 2. First EDID block was corrupted, then totalBlockCnt = 0
//
if (blocksRead >= totalBlockCnt)
return false;
// Retry count exceeded for particular block?
if (retriesCount > EDID_POLICY_BLOCK_READ_MAX_RETRY_COUNT)
return false;
seg = NvU8(blocksRead >> 1);
offset = NvU8((blocksRead & 0x1) * EDID_BLOCK_SIZE);
return true;
}
enum
{
EDID_V1_IDX_EXTENSION = 0x7E,
EDID_V1_IDX_HEADER0 = 0x00,
EDID_V1_HEADER0 = 0x00,
EDID_V1_IDX_HEADER1 = 0x01,
EDID_V1_HEADER1 = 0xFF,
EDID_V1_IDX_VERSION = 0x12,
EDID_V1_VERSION_1 = 0x01,
EDID_V2_IDX_VERREV = 0x00,
//
// from od_edid.h RM to identify VER 2, use 7:4 bits.
// #define EDID_V2_VERREV_VERSION 7:4 /* RW--F */
// #define EDID_V2_VERREV_VERSION_2 0x02 /* RWI-V */
//
// Avoiding FLD_* macros, thus shift VER2 value 4 bits to left
//
EDID_V2_VERREV_VERSION_2 = 0x02 << 4,
EDID_FLAGS_CHKSUM_ATTEMPTS_DP = 0x5,
};
enum
{
// EDID CTA-EXT (CTA 861 Extension) block defines
EDID_CTA_EXT_HEADER_OFFSET = 0x00,
EDID_CTA_EXT_HEADER = 0x02,
EDID_CTA_EXT_VERSION_OFFSET = 0x01,
EDID_CTA_EXT_VERSION_3 = 0x03,
EDID_CTA_EXT_DATA_BLOCK_HEADER_OFFSET = 0x04,
EDID_CTA_EXT_DATA_BLOCK_HEADER_HF_EEODB = 0xE2,
EDID_CTA_EXT_DATA_BLOCK_TAG_OFFSET = 0x05,
EDID_CTA_EXT_DATA_BLOCK_TAG_HF_EEODB = 0x78,
EDID_CTA_EXT_DATA_BLOCK_EXT_COUNT_OFFSET = 0x06,
};
Edid::Edid(): buffer()
{
// fill EDID buffer with zeroes
this->buffer.memZero();
checkSumValid = false;
forcedCheckSum = false;
fallbackEdid = false;
patchedChecksum = false;
// clear the WARFlags
_WARFlags temp = {0};
WARFlags = temp;
}
Edid::~Edid()
{
}
bool Edid::verifyCRC()
{
if (getEdidSize() > 0)
{
this->validateCheckSum();
return this->checkSumValid;
}
else
return false;
}
// this routine patches the edid crc after it has been overridden for WARs.
void Edid::patchCrc()
{
// we always override some bytes within the first 128
// recalculate and fix the checksum for the first page only.
unsigned chksum = 0;
for (unsigned i = 0; i < 128; i++)
{
chksum += buffer.data[i];
}
chksum = chksum & 0xFF;
if (chksum)
buffer.data[127] = 0xFF & (buffer.data[127] + (0x100 - chksum));
}
bool Edid::isChecksumValid() const
{
// return checksum valid if it is.
// else return checksum is valid if checksum wasn't valid but we will assume it to be.
return (checkSumValid || forcedCheckSum);
}
bool Edid::isFallbackEdid() const
{
return fallbackEdid;
}
NvU8 Edid::getFirstPageChecksum()
{
DP_ASSERT(buffer.getLength() >= 128);
if (buffer.getLength() < 128)
return 0;
else
return buffer.data[127];
}
NvU8 Edid::getLastPageChecksum()
{
NvU32 bufferSize = buffer.getLength();
NvU32 checksumLocation = this->getBlockCount() * 128 - 1;
if (bufferSize == 0 || bufferSize < (this->getBlockCount() * 128))
{
DP_LOG(("DP-EDID> Edid length is 0 or less than required"));
return 0;
}
if (bufferSize % 128 != 0)
{
DP_LOG(("DP-EDID> Edid length is not a multiple of 128"));
return 0;
}
return buffer.data[checksumLocation];
}
void Edid::validateCheckSum()
{
// Each page has its own checksum
checkSumValid = false;
for (unsigned chunk = 0; chunk < this->buffer.length; chunk += 128)
{
unsigned chksum = 0;
for (unsigned i = 0; i < 128; i++)
{
chksum += buffer.data[i+chunk];
}
if ((chksum & 0xFF) != 0)
return;
}
checkSumValid = true;
}
unsigned Edid::getEdidVersion()
{
if (buffer.isError() || buffer.length < EDID_BLOCK_SIZE)
{
return 0;
}
// 0 version is "unknown"
unsigned version = 0;
// Check for Version 1 EDID
if (this->buffer.data[EDID_V1_IDX_VERSION] == EDID_V1_VERSION_1)
{
version = 1;
}
// Check for version 2 EDID
else if (this->buffer.data[EDID_V2_IDX_VERREV] & EDID_V2_VERREV_VERSION_2)
{
//
// Version 2 has 256 bytes by default.
// There is a note about an extra 256 byte block if byte 0x7E
// bit 7 is set but there's no definition for it listed in
// the EDID Version 3 (971113). So, let's just skip it for now.
//
version = 2;
}
else
{
DP_ASSERT(version && "Unknown EDID version");
}
return version;
}
const char * Edid::getName() const
{
static char decodedName[16] = {0};
int tail = 0;
if (buffer.length < 128)
return "?";
for (int i = 0; i < 4; i++)
if (buffer.data[0x39 + i * 18 + 0] == 0xFC)
{
for (int j = 0; j < 13; j++)
decodedName[tail++] = buffer.data[0x39 + i*18 + 2 + j];
break;
}
decodedName[tail++] = 0;
return decodedName;
}
unsigned Edid::getBlockCount()
{
if (buffer.isError() || buffer.length < EDID_BLOCK_SIZE)
{
return 0;
}
unsigned version = getEdidVersion();
if (version == 1)
{
NvU32 blockCount = (unsigned) this->buffer.data[EDID_V1_IDX_EXTENSION]+1;
if (blockCount > EDID_MAX_BLOCK_COUNT)
{
DP_LOG(("DPEDID> %s: DDC read returned questionable results: "
"Total block Count too high: %d",
__FUNCTION__, blockCount));
return 1;
}
//
// Check for the HF-EEODB defined in HDMI 2.1 specification.
// 1. It is EDID version 1.3 and the extension block count is 1 (total block count = 2)
// 2. The 1st EDID extension block is already read. (buffer.length > block size)
// 3. The 1st EDID extension block is CTA extension block.
// 4. It has HF-EEODB (1st extension block: byte4 == 0xE2 and byte5 == 0x78)
//
if ((blockCount == 2) && (buffer.length >= EDID_BLOCK_SIZE * 2))
{
NvU8 *pExt = &(this->buffer.data[EDID_BLOCK_SIZE]);
//
// If it's a CTA-EXT block version 3 and has HF-EEODB
// defined, update the total block count.
//
if ((pExt[EDID_CTA_EXT_HEADER_OFFSET] == EDID_CTA_EXT_HEADER) &&
(pExt[EDID_CTA_EXT_VERSION_OFFSET] == EDID_CTA_EXT_VERSION_3) &&
(pExt[EDID_CTA_EXT_DATA_BLOCK_HEADER_OFFSET] == EDID_CTA_EXT_DATA_BLOCK_HEADER_HF_EEODB) &&
(pExt[EDID_CTA_EXT_DATA_BLOCK_TAG_OFFSET] == EDID_CTA_EXT_DATA_BLOCK_TAG_HF_EEODB))
{
blockCount = pExt[EDID_CTA_EXT_DATA_BLOCK_EXT_COUNT_OFFSET] + 1;
}
}
return blockCount;
}
else if (version == 2)
{
//
// Version 2 has 256 bytes by default.
// There is a note about an extra 256 byte block
// if byte 0x7E bit 7 is set, but there's no
// definition for it listed in the
// EDID Version 3 (971113) So, let's just skip
// it for now.
//
return 2;
}
else
{
// Unknown EDID version. Skip it.
DP_LOG(("DPEDID> %s: Unknown EDID Version!",__FUNCTION__));
DP_ASSERT(0 && "Unknown EDID version!");
return 1;
}
}
unsigned Edid::getEdidSize() const
{
return this->buffer.length;
}
void DisplayPort::Edid::swap(Edid & right)
{
swapBuffers(buffer, right.buffer);
validateCheckSum();
}
const NvU8 fallbackEdidModes[5][EDID_BLOCK_SIZE] = {
// ID Manufacturer Name: NVD
// VIDEO INPUT DEFINITION:
// Digital Signal
// VESA DFP 1.x Compatible
//
// The first 4 entries are for NV_DPCD_SINK_VIDEO_FALLBACK_FORMATS (DPCD 0x20)
// 1024x768x60Hz: defined in bit 0.
// 1280x720x60Hz: defined in bit 1.
// 1920x1080x60Hz: defined in bit 2. [Mandatory]
//
{
// Bit 2: 1920x1080x60 only
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
0x3A, 0xC4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x04, 0xA5, 0x00, 0x00, 0x64,
0xEE, 0x91, 0xA3, 0x54, 0x4C, 0x99, 0x26, 0x0F,
0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3A,
0x80, 0x18, 0x71, 0x38, 0x2D, 0x40, 0x58, 0x2C,
0x43, 0x00, 0xC0, 0x1C, 0x32, 0x00, 0x00, 0x1C,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDB
},
{
// bit 2 + bit 0: 1920x1080x60 + 1024x768x60
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
0x3A, 0xC4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x04, 0xA5, 0x00, 0x00, 0x64,
0xEE, 0x91, 0xA3, 0x54, 0x4C, 0x99, 0x26, 0x0F,
0x50, 0x54, 0x00, 0x00, 0x08, 0x00, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3A,
0x80, 0x18, 0x71, 0x38, 0x2D, 0x40, 0x58, 0x2C,
0x43, 0x00, 0xC0, 0x1C, 0x32, 0x00, 0x00, 0x1C,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD3
},
{
// bit 2 + bit 1: 1920x1080x60 + 1280x720x60
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
0x3A, 0xC4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x04, 0xA5, 0x00, 0x00, 0x64,
0xEE, 0x91, 0xA3, 0x54, 0x4C, 0x99, 0x26, 0x0F,
0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x81, 0xC0,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3A,
0x80, 0x18, 0x71, 0x38, 0x2D, 0x40, 0x58, 0x2C,
0x43, 0x00, 0xC0, 0x1C, 0x32, 0x00, 0x00, 0x1C,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C
},
{
// bit2 + bit 1 + bit 0: All 3 modes.
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
0x3A, 0xC4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x04, 0xA5, 0x00, 0x00, 0x64,
0xEE, 0x91, 0xA3, 0x54, 0x4C, 0x99, 0x26, 0x0F,
0x50, 0x54, 0x00, 0x00, 0x08, 0x00, 0x81, 0xC0,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3A,
0x80, 0x18, 0x71, 0x38, 0x2D, 0x40, 0x58, 0x2C,
0x43, 0x00, 0xC0, 0x1C, 0x32, 0x00, 0x00, 0x1C,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94
},
{
// ESTABLISHED TIMING I:
// 640 X 480 @ 60Hz (IBM,VGA)
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
0x3A, 0xC4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x04, 0x95, 0x00, 0x00, 0x78,
0xEE, 0x91, 0xA3, 0x54, 0x4C, 0x99, 0x26, 0x0F,
0x50, 0x54, 0x00, 0x20, 0x00, 0x00, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92
}
};
//
// Definition of DPCD 0x20:
// 1024x768x60Hz: defined in bit 0.
// 1280x720x60Hz: defined in bit 1.
// 1920x1080x60Hz: defined in bit 2. [Mandatory]
// MIN value is 4 (only 1920x1080 supported)
// MAX value is 7 (supports all 3 modes)
//
#define SINK_VIDEO_FALLBACK_FORMATS_MIN_VALUE (0x00000004)
#define SINK_VIDEO_FALLBACK_FORMATS_MAX_VALUE (0x00000007)
void DisplayPort::makeEdidFallback(Edid & edid, NvU32 fallbackFormatSupported)
{
const NvU8 *data;
// fallbackFormatSupported valid values = 4~7
if (fallbackFormatSupported > SINK_VIDEO_FALLBACK_FORMATS_MAX_VALUE ||
fallbackFormatSupported < SINK_VIDEO_FALLBACK_FORMATS_MIN_VALUE)
{
// 4 is default fallback mode. (only 640x480)
data = fallbackEdidModes[4];
}
else
{
data = fallbackEdidModes[fallbackFormatSupported-4];
}
if (!edid.getBuffer()->resize(EDID_BLOCK_SIZE))
return;
dpMemCopy(edid.getBuffer()->getData(), (const NvU8*)data, EDID_BLOCK_SIZE);
DP_ASSERT(edid.verifyCRC());
edid.setFallbackFlag(true);
}
/*
Fake EDID for DP2VGA dongle when the EDID of the real monitor is not available
Established Timings [20 CE 00]
640 x 480 @ 60Hz
800 x 600 @ 72Hz
800 x 600 @ 75Hz
1024 x 768 @ 60Hz
1024 x 768 @ 70Hz
1024 x 768 @ 75Hz
Standard Timings
Timing [3159] : 640 x 480 @ 85Hz (4:3)
Timing [4559] : 800 x 600 @ 85Hz (4:3)
Timing [6159] : 1024 x 768 @ 85Hz (4:3)
Timing [714F] : 1152 x 864 @ 75Hz (4:3)
Detailed Timing [DTD] 1280 x 1024 @ 60.02Hz
Pixel Clock : 108.00Mhz
HBlank, HBorder : 408, 0
HSyncStart, HSyncWidth : 48, 112
VBlank, VBorder : 42, 0
VSyncStart, VSyncWidth : 1, 3
Image size : 376mm x 301mm
DigitalSeparate +/+
*/
void DisplayPort::makeEdidFallbackVGA(Edid & edid)
{
const NvU8 data[] = {
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x3A, 0xC4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x13, 0x01, 0x03, 0x80, 0x26, 0x1E, 0x78, 0xEE, 0xCB, 0x05, 0xA3, 0x58, 0x4C, 0x9B, 0x25,
0x13, 0x50, 0x54, 0x20, 0xCE, 0x00, 0x31, 0x59, 0x45, 0x59, 0x61, 0x59, 0x71, 0x4F, 0x81, 0x40,
0x81, 0x80, 0x01, 0x01, 0x01, 0x01, 0x30, 0x2A, 0x00, 0x98, 0x51, 0x00, 0x2A, 0x40, 0x30, 0x70,
0x13, 0x00, 0x78, 0x2D, 0x11, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x30, 0x55, 0x1F,
0x52, 0x0E, 0x00, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x4C,
0x43, 0x44, 0x5F, 0x56, 0x47, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8
};
if (!edid.getBuffer()->resize(sizeof(data)))
return;
dpMemCopy(edid.getBuffer()->getData(), (const NvU8*)data, sizeof data);
DP_ASSERT(edid.verifyCRC());
edid.setFallbackFlag(true);
}
NvU8 DisplayPort::getEDIDBlockChecksum(const Buffer & buffer)
{
DP_ASSERT(buffer.getLength() == 128);
unsigned chksum = 0;
for (unsigned i = 0; i < buffer.getLength(); i++)
{
chksum += buffer.data[i];
}
chksum = chksum & 0xFF;
return (NvU8)chksum;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,331 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_groupimpl.cpp *
* DP device group implementation *
* *
\***************************************************************************/
#include "dp_internal.h"
#include "dp_connector.h"
#include "dp_list.h"
#include "dp_auxdefs.h"
#include "dp_deviceimpl.h"
#include "dp_groupimpl.h"
#include "dp_connectorimpl.h"
using namespace DisplayPort;
void GroupImpl::update(Device * dev, bool allocationState)
{
Address::StringBuffer sb;
Address devAddress = dev->getTopologyAddress();
DP_USED(sb);
// Do not map a stream that is not yet turned on in the gpu. An update shall be sent later during NAE.
if (allocationState && !this->isHeadAttached())
return;
//
// Do not enable the stream on an unplugged device but take care of
// detached devices. We need to clear PBNs allocated by such devices
//
if (allocationState && !((DeviceImpl *)dev)->plugged)
return;
//
// Check if Parent's messageManager exist or not. This is required for cases
// where parent branch itself has been unplugged. No message can be sent in this case.
//
if (!parent->messageManager)
return;
if (timeslot.count == 0 ||
((DeviceImpl *)dev)->payloadAllocated == allocationState)
return;
if (!dev->getParent() || !((dev->getParent())->isPlugged()))
{
DeviceImpl * parentDev = NULL;
//
// Send ALLOCATE_PAYLOAD with pbn 0 to parent port of previous branch
// Find first plugged parent branch & send message to it
//
while(devAddress.size() > 2)
{
devAddress.pop();
parentDev = parent->findDeviceInList(devAddress.parent());
if (parentDev && parentDev->isPlugged())
break;
}
// If no parent found simply return as we don't have a valid address to send message
if (!parentDev)
return;
}
NakData nakData;
for (int retries = 0 ; retries < 7; retries++)
{
AllocatePayloadMessage allocate;
unsigned sink = 0; // hardcode the audio sink to 0th in the device.
allocate.set(devAddress.parent(), devAddress.tail(),
dev->isAudioSink() ? 1 : 0, streamIndex, allocationState ? timeslot.PBN : 0,
&sink, true);
// Trigger a refetch of epr
((DeviceImpl *)dev)->bandwidth.enum_path.dataValid = false;
DeviceImpl * tail = (DeviceImpl *) dev;
while (tail && tail->getParent())
{
tail->bandwidth.enum_path.dataValid = false;
tail = (DeviceImpl *)tail->getParent();
}
if (parent->messageManager->send(&allocate, nakData))
{
if (allocationState)
{
DP_LOG(("DP-TM> Attached stream:%d to %s", streamIndex, dev->getTopologyAddress().toString(sb)));
}
else
{
DP_LOG(("DP-TM> Detached stream:%d from %s", streamIndex, dev->getTopologyAddress().toString(sb)));
}
((DeviceImpl *)dev)->payloadAllocated = allocationState;
return;
}
}
// we should not have ideally reached here unless allocate payload failed.
if (allocationState)
{
DP_LOG(("DP-TM> Allocate_payload: Failed to ATTACH stream:%d to %s", streamIndex, dev->getTopologyAddress().toString(sb)));
DP_ASSERT(0);
}
else
{
DP_LOG(("DP-TM> Allocate_payload: Failed to DETACH stream:%d from %s", streamIndex, dev->getTopologyAddress().toString(sb)));
DP_ASSERT(0);
}
}
void GroupImpl::insert(Device * dev)
{
DP_ASSERT(!headInFirmware && "Cannot add or remove from a firmware group. You must perform a modeset away from the device");
DeviceImpl * di = (DeviceImpl *)dev;
if (isHeadAttached())
{
if (di->activeGroup && di->activeGroup != this)
{
DP_ASSERT(0 && "Device already in active group, cannot add to another active group!");
return;
}
di->activeGroup = this;
}
members.insertFront(di);
update(dev, true);
}
void GroupImpl::remove(Device * dev)
{
DP_ASSERT(!headInFirmware && "Cannot add or remove from a firmware group. You must perform a modeset away from the device");
DeviceImpl * di = (DeviceImpl *)dev;
if (isHeadAttached())
{
di->activeGroup = 0;
}
members.remove(di);
update(dev, false);
updateVbiosScratchRegister(dev);
}
void GroupImpl::destroy()
{
for (Device * i = enumDevices(0); i; i = enumDevices(i))
remove(i);
// Cancel any queue the auth callback.
cancelHdcpCallbacks();
delete this;
}
void GroupImpl::cancelHdcpCallbacks()
{
authRetries = 0;
parent->timer->cancelCallback(this, &tagHDCPReauthentication);
parent->timer->cancelCallback(this, &tagStreamValidation);
}
Device * GroupImpl::enumDevices(Device * previousDevice)
{
return members.next(previousDevice);
}
void GroupImpl::expired(const void * tag)
{
if (tag == &tagHDCPReauthentication)
{
HDCPState hdcpState = {0};
parent->main->configureHDCPGetHDCPState(hdcpState);
if (authRetries < HDCP_AUTHENTICATION_RETRIES)
{
this->hdcpEnabled = hdcpState.HDCP_State_Encryption;
if (hdcpState.HDCP_State_Authenticated)
{
parent->isHDCPAuthOn = true;
authRetries = 0;
}
else
{
unsigned authDelay = (hdcpState.HDCP_State_22_Capable ?
HDCP22_AUTHENTICATION_COOLDOWN : HDCP_AUTHENTICATION_COOLDOWN);
authRetries++;
parent->main->configureHDCPRenegotiate();
parent->isHDCPAuthOn = false;
parent->timer->queueCallback(this, &tagHDCPReauthentication,
authDelay);
}
}
else
{
parent->isHDCPAuthOn = this->hdcpEnabled = false;
}
}
else if ( tag == &tagStreamValidation)
{
if (!(this->streamValidationDone))
{
// If we are here we need to debug what has caused the problem for not getting notification from DD.
DP_ASSERT(0 && "DP> Didn't get final notification." );
}
}
}
bool GroupImpl::hdcpGetEncrypted()
{
//
// Returns whether encryption is currently enabled
//
if (parent->isHDCPAuthOn)
{
return this->hdcpEnabled;
}
else
{
return false;
}
}
void GroupImpl::updateVbiosScratchRegister(Device * lastDev)
{
if (!parent->bDisableVbiosScratchRegisterUpdate &&
parent->lastDeviceSetForVbios == lastDev)
{
// Take a device which is part of a group
for (ListElement * e = parent->deviceList.begin();
e != parent->deviceList.end(); e = e->next)
{
DeviceImpl * dev = (DeviceImpl *)e;
if (dev->activeGroup && dev->activeGroup->isHeadAttached())
{
NvU32 address = 0;
NvU32 addrSize = dev->getTopologyAddress().size();
// Set the MS_SCRATCH_REGISTER for lighted up display
for (NvU32 i = addrSize; i; --i)
{
address |= ((dev->address[i-1] & 0xF) << ((addrSize - i)*4));
}
parent->main->configureMsScratchRegisters(address, addrSize, 3);
parent->lastDeviceSetForVbios = (Device *)dev;
return;
}
}
}
}
//
// Helper function for attaching and detaching heads.
//
// For attach, we will assert if group already has head attached but for
// some device in the group, active group did not point to current group.
// For detach, we will assert if the group does not have head attached but
// some device in group has an active group OR head is marked attached but
// not all devies in the group have the current group as active group.
// This also sets or clears dev->activeGroup for each contained
// device.
//
void GroupImpl::setHeadAttached(bool attached)
{
for (Device * i = enumDevices(0); i; i = enumDevices(i))
{
DeviceImpl *di = (DeviceImpl *)i;
if (attached)
{
if (headAttached)
{
DP_ASSERT(di->activeGroup == this);
}
di->activeGroup = this;
}
else
{
if (!headAttached)
{
DP_ASSERT(di->activeGroup == NULL);
}
else
{
DP_ASSERT(di->activeGroup == this);
}
di->activeGroup = NULL;
}
}
headAttached = attached;
}

View File

@@ -0,0 +1,81 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_guid.cpp *
* *
\***************************************************************************/
#include "dp_internal.h"
#include "dp_guid.h"
#include "dp_buffer.h"
using namespace DisplayPort;
//
// Linear congruential random number generator
// Seed values chosen from numerical methods
//
NvU32 GUIDBuilder::random()
{
previousRandom = static_cast<NvU32>(( ((NvU64)1664525 * previousRandom + 1013904223) & 0xFFFFFFFF) & 0xFF);
return previousRandom;
}
GUIDBuilder::GUIDBuilder(Timer * source, NvU32 salt)
: salt(salt), source(source)
{
previousRandom = static_cast<NvU32>(( source->getTimeUs() & 0xFFFFFFFF) & 0xFF);
}
void GUIDBuilder::makeGuid(GUID & guid)
{
NvU64 currentTimer = source->getTimeUs();
guid.data[0] = static_cast<NvU8>(( salt >> 24) & 0xFF);
guid.data[1] = static_cast<NvU8>(( salt >> 16) & 0xFF);
guid.data[2] = static_cast<NvU8>(( salt >> 8) & 0xFF);
guid.data[3] = static_cast<NvU8>(( salt) & 0xFF);
guid.data[4] = static_cast<NvU8>(( currentTimer >> 56) & 0xFF);
guid.data[5] = static_cast<NvU8>(( currentTimer >> 48) & 0xFF);
guid.data[6] = static_cast<NvU8>(( currentTimer >> 40) & 0xFF);
guid.data[7] = static_cast<NvU8>(( currentTimer >> 32) & 0xFF);
guid.data[8] = static_cast<NvU8>(( currentTimer >> 24) & 0xFF);
guid.data[9] = static_cast<NvU8>(( currentTimer >> 16) & 0xFF);
guid.data[10] = static_cast<NvU8>(( currentTimer >> 8) & 0xFF);
guid.data[11] = static_cast<NvU8>(( currentTimer) & 0xFF);
unsigned rnd = random();
guid.data[12] = static_cast<NvU8>(( rnd >> 24) & 0xFF);
guid.data[13] = static_cast<NvU8>(( rnd >> 16) & 0xFF);
guid.data[14] = static_cast<NvU8>(( rnd >> 8) & 0xFF);
guid.data[15] = static_cast<NvU8>(( rnd) & 0xFF);
//
// Spin until we get a new timer counter
// This guarantees a monotonitically increased counter
//
while (source->getTimeUs() == currentTimer)
;
}

View File

@@ -0,0 +1,159 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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.
*/
/******************************* List **************************************\
* *
* Module: dp_list.cpp *
* Simple doubly linked list *
* *
\***************************************************************************/
#include "dp_internal.h"
#include "dp_list.h"
using namespace DisplayPort;
ListElement::ListElement()
: next(0),
prev(0)
{
}
ListElement::~ListElement()
{
if (this->next)
{
this->prev->next = this->next;
this->next->prev = this->prev;
this->next = 0;
}
}
List::List()
{
this->next = this;
this->prev = this;
}
void List::clear()
{
while(!isEmpty())
delete begin();
}
List::~List()
{
clear();
this->next = this;
this->prev = this;
}
bool List::isEmpty()
{
return this->next == this;
}
void List::insertFront(ListElement * item)
{
DP_ASSERT(item->next == 0 && "Attempt to insert when it's already in a list");
item->prev = this;
item->next = this->next;
item->prev->next = item;
item->next->prev = item;
}
void List::insertBack(ListElement * item)
{
DP_ASSERT(item->next == 0 && "Attempt to insert when it's already in a list");
item->prev = this->prev;
item->next = this;
item->prev->next = item;
item->next->prev = item;
}
void List::insertBefore(ListElement * insertBeforeThis, ListElement * item)
{
DP_ASSERT(item->next == 0 && "Attempt to insert when it's already in a list");
item->next = insertBeforeThis;
item->prev = insertBeforeThis->prev;
insertBeforeThis->prev->next = item;
insertBeforeThis->prev = item;
}
ListElement* List::front()
{
DP_ASSERT(!isEmpty());
return this->next;
}
ListElement* List::last()
{
DP_ASSERT(!isEmpty());
return this->prev;
}
ListElement * List::remove(ListElement * item)
{
// Skip if its not already in a list
if (!item->next)
return item;
item->prev->next = item->next;
item->next->prev = item->prev;
item->next = 0;
item->prev = 0;
return item;
}
bool List::contains(ListElement * item)
{
for (ListElement * i = begin(); i!=end(); i = i->next)
{
if (i == item)
return true;
}
return false;
}
ListElement * List::replace(ListElement * replacement, ListElement * replacee)
{
if (!(replacement && replacee))
{
DP_ASSERT(0 && "replacement or replaces is NULL pointer");
return 0;
}
DP_ASSERT(replacement->next && replacement->prev);
// we are assuming replacee does exist in the list.
replacement->next = replacee->next;
replacement->prev = replacee->prev;
if (replacement->next)
replacement->next->prev = replacement;
if (replacement->prev)
replacement->prev->next = replacement;
return replacee;
}

View File

@@ -0,0 +1,310 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_merger.cpp *
* Asynchronous Message merger *
* *
\***************************************************************************/
#include "dp_internal.h"
#include "dp_bitstream.h"
#include "dp_merger.h"
#include "dp_auxdefs.h"
#include "dp_crc.h"
#include "dp_messageheader.h"
using namespace DisplayPort;
EncodedMessage * MessageTransactionMerger::pushTransaction(MessageHeader * header, Buffer * data)
{
if (freeOnNextCall)
{
delete freeOnNextCall;
freeOnNextCall = 0;
}
IncompleteMessage * imsg = getTransactionRecord(header->address, header->messageNumber);
if (!imsg)
{
DP_LOG(("DP-MM> Ignore message due to OOM"));
return 0;
}
if (header->isTransactionStart)
{
imsg->message.isPathMessage = header->isPathMessage;
imsg->message.isBroadcast = header->isBroadcast;
}
else
{
if (imsg->message.buffer.length == 0)
{
DP_LOG(("DP-MM> Expected transaction-start, ignoring message transaction"));
return 0;
}
if (imsg->message.isPathMessage != header->isPathMessage ||
imsg->message.isBroadcast != header->isBroadcast)
{
DP_ASSERT(0 && "Message type changed during transmission");
}
}
//
// Check for redundant start
//
if (header->isTransactionStart && imsg->message.buffer.length)
{
DP_LOG(("DP-MM> Unexpected repeated transaction-start, resetting message state."));
// We must have seen a previous incomplete transaction from this device
// they've begun a new packet. Forget about the old thing
imsg->message.buffer.reset();
}
//
// Kill the buffer if we've got less payload than we should
//
if (header->payloadBytes > data->length)
{
freeOnNextCall = imsg;
imsg->message.buffer.reset();
DP_LOG(("DP-MM> Received truncated or corrupted message transaction"));
return 0;
}
//
// Verify transaction CRC
//
BitStreamReader bsr(data, header->headerSizeBits, (header->payloadBytes-1)*8);
NvU8 dataCrc = (NvU8)dpCalculateBodyCRC(&bsr);
DP_ASSERT(header->headerSizeBits % 8 == 0 && "Header must be byte aligned");
if (dataCrc != data->data[header->headerSizeBits/8 + header->payloadBytes - 1] ||
header->payloadBytes == 0)
{
DP_LOG(("DP-MM> Received corruption message transactions"));
freeOnNextCall = imsg;
imsg->message.buffer.reset();
return 0;
}
// Discount the processed CRC from the payload count
header->payloadBytes--;
//
// Append active buffer
//
unsigned i = imsg->message.buffer.length;
imsg->message.buffer.resize(i + header->payloadBytes);
dpMemCopy(&imsg->message.buffer.data[i], &data->data[header->headerSizeBits/8], header->payloadBytes);
//
// Check for end of message transaction
//
if (header->isTransactionEnd)
{
freeOnNextCall = imsg;
return &imsg->message;
}
return 0;
}
MessageTransactionMerger::IncompleteMessage * MessageTransactionMerger::getTransactionRecord(const Address & address, unsigned messageNumber)
{
IncompleteMessage * msg;
NvU64 currentTime = this->timer->getTimeUs();
//
// Search for existing record
//
for (ListElement * i = incompleteMessages.begin();i != incompleteMessages.end();)
{
msg = (IncompleteMessage *)i;
i = i->next;
if (msg->message.address == address && msg->message.messageNumber == messageNumber)
{
goto found;
}
//
// Found a stale message in the list
//
if (msg->lastUpdated + incompleteMessageTimeoutMs < currentTime)
delete msg;
}
//
// None exists? Add a new one
//
msg = new IncompleteMessage();
msg->message.address = address;
msg->message.messageNumber = messageNumber;
this->incompleteMessages.insertFront(msg);
found:
//
// Update the timestamp
//
msg->lastUpdated = currentTime;
return msg;
}
void IncomingTransactionManager::mailboxInterrupt()
{
MessageHeader msg;
unsigned totalSize;
AuxRetry::status result;
unsigned txSize = (unsigned)getTransactionSize();
//
// Size the static aux window
//
this->localWindow.resize(DP_MAX((unsigned)getTransactionSize(), (unsigned)getMessageBoxSize()));
if (this->localWindow.isError())
return;
//
// Read one aux-transaction worth of data
//
result = readMessageBox(0, &this->localWindow.data[0], txSize);
DP_ASSERT( result != AuxRetry::defer && "Unexpected?!" );
if (result != AuxRetry::ack)
return;
BitStreamReader reader(&this->localWindow, 0, 8*txSize);
//
// Before decoding the header, start with the downstream
// ports address prefix
//
if (!decodeHeader(&reader, &msg, addressPrefix))
{
//
// It's possible we should be NACKing here. Ignoring for now
// to allow the message originator to time out (can take seconds).
//
DP_ASSERT(0 && "Not yet implemented");
return;
}
//
// Let's get the entire sideband message in the localWindow
//
totalSize = (msg.headerSizeBits / 8) + msg.payloadBytes;
if (totalSize > txSize)
{
if (totalSize > DPCD_MESSAGEBOX_SIZE)
{
//
// Corrupt packet - total packet can't be larger than the window
//
return;
}
if (AuxRetry::ack!=readMessageBox(txSize, &this->localWindow.data[txSize], totalSize - txSize))
{
//
// Failed to read second half of message
//
return;
}
}
clearMessageBoxInterrupt();
EncodedMessage * em = incompleteMessages.pushTransaction(&msg, &this->localWindow);
if (em)
{
this->sink->messagedReceived(this, em);
}
}
IncomingTransactionManager::~IncomingTransactionManager()
{
}
IncomingTransactionManager::IncomingTransactionManager(Timer * timer, const Address & addressPrefix, IncomingTransactionManagerEventSink * sink)
: incompleteMessages(timer, DP_INCOMPLETE_MESSAGE_TIMEOUT_USEC), addressPrefix(addressPrefix)
{
this->sink = sink;
this->timer = timer;
}
AuxRetry::status DownReplyManager::readMessageBox(NvU32 offset, NvU8 * data, size_t length)
{
return hal->readDownReplyMessageBox(offset, data, length);
}
size_t DownReplyManager::getMessageBoxSize()
{
return hal->getDownReplyMessageBoxSize();
}
size_t DownReplyManager::getTransactionSize()
{
return hal->getTransactionSize();
}
void DownReplyManager::clearMessageBoxInterrupt()
{
hal->clearInterruptDownReplyReady();
}
AuxRetry::status UpRequestManager::readMessageBox(NvU32 offset, NvU8 * data, size_t length)
{
return hal->readUpRequestMessageBox(offset, data, length);
}
size_t UpRequestManager::getMessageBoxSize()
{
return hal->getUpRequestMessageBoxSize();
}
size_t UpRequestManager::getTransactionSize()
{
return hal->getTransactionSize();
}
void UpRequestManager::clearMessageBoxInterrupt()
{
hal->clearInterruptUpRequestReady();
}

View File

@@ -0,0 +1,692 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2010-2021 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_messagecodings.cpp *
* Encoding routines for various messages *
* *
\***************************************************************************/
#include "dp_internal.h"
#include "dp_messagecodings.h"
#include "dp_auxdefs.h"
using namespace DisplayPort;
//
// LINK_ADDRESS 0x1
//
void LinkAddressMessage::set(const Address & target)
{
clear();
BitStreamWriter writer(&encodedMessage.buffer, 0);
//
// Write request identifier
//
writer.write(0 /*zero*/, 1);
writer.write(requestIdentifier, 7);
encodedMessage.isPathMessage = false;
encodedMessage.isBroadcast = false;
encodedMessage.address = target;
}
ParseResponseStatus LinkAddressMessage::parseResponseAck(EncodedMessage * message, BitStreamReader * reader)
{
DisplayPort::extractGUID(reader, &reply.guid);
reader->readOrDefault(4 /*zeroes*/, 0);
reply.numberOfPorts = reader->readOrDefault(4 /*Number_Of_Ports*/, 0xF);
for (unsigned i = 0; i < reply.numberOfPorts; i++)
{
reply.res[i].isInputPort = !!reader->readOrDefault(1 /*Input_Port*/, 1);
reply.res[i].peerDeviceType = (PeerDevice) reader->readOrDefault(3 /*Peer_Device_Type*/, 0x0);
reply.res[i].portNumber = reader->readOrDefault(4 /*Port_Number*/, 0xF);
reply.res[i].hasMessaging = !!reader->readOrDefault(1 /*Messaging_Capability_Status*/, 0x1);
reply.res[i].dpPlugged = !!reader->readOrDefault(1 /*DisplayPort_Device_Plug_Status*/, 0x1);
if (reply.res[i].isInputPort == false)
{
reply.res[i].legacyPlugged = !!reader->readOrDefault(1 /*Legacy_Device_Plug_Status*/, 0x1);
reader->readOrDefault(5 /*zeroes*/, 0x0);
unsigned ver = reader->readOrDefault(8/*DPCD_Revision*/, 0);
reply.res[i].dpcdRevisionMajor = ver >> 4;
reply.res[i].dpcdRevisionMinor = ver & 0xF;
DisplayPort::extractGUID(reader, &reply.res[i].peerGUID);
reply.res[i].SDPStreams = reader->readOrDefault(4 /*Number_SDP_Streams*/, 0xF);
reply.res[i].SDPStreamSinks = reader->readOrDefault(4 /*Number_SDP_Stream_Sinks*/, 0xF);
}
else
{
reader->readOrDefault(6 /*zeroes*/, 0x0);
reply.res[i].dpcdRevisionMajor = 1;
reply.res[i].dpcdRevisionMinor = 2;
}
}
return ParseResponseSuccess;
}
//
// CONNECTION_STATUS_NOTIFY 0x2
//
ConnStatusNotifyMessage::ConnStatusNotifyMessage(MessageReceiverEventSink * sink)
: MessageReceiver(sink, NV_DP_SBMSG_REQUEST_ID_CONNECTION_STATUS_NOTIFY /*request id*/)
{
}
bool ConnStatusNotifyMessage::processByType(EncodedMessage * message, BitStreamReader * reader)
{
// read the request body
request.port = reader->readOrDefault(4/*Port_Number*/, 0xF);
reader->readOrDefault(4/*zeroes*/, 0);
bool status = DisplayPort::extractGUID(reader/*GUID of the originating branch device*/, &request.guid);
reader->readOrDefault(1/*zero*/, 0);
request.legacyPlugged = !!reader->readOrDefault(1/*Legacy_Device_Plug_Status*/, 0);
request.devicePlugged = !!reader->readOrDefault(1/*DisplayPort_Device_Plug_Status*/, 0);
request.messagingCapability = !!reader->readOrDefault(1/*Messaging_Capability_Status*/, 0);
request.isInputPort = !!reader->readOrDefault(1/*Input_Port*/, 0);
request.peerDeviceType = (PeerDevice) reader->readOrDefault(3/*Peer_Device_Type*/, 0);
// action will be implemented by evensink
this->sink->messageProcessed(this);
return status;
}
//
// GENERIC_UP_REPLY 0xnn
//
void GenericUpReplyMessage::set(const Address & target,
bool bReplyIsNack,
bool bBroadcast,
bool bPath)
{
clear();
BitStreamWriter writer(&encodedMessage.buffer, 0);
writer.write(bReplyIsNack?1:0, 1);
writer.write(requestIdentifier, 7);
encodedMessage.isPathMessage = bPath;
encodedMessage.isBroadcast = bBroadcast;
encodedMessage.address = target;
}
GenericUpReplyMessage::GenericUpReplyMessage(unsigned requestId, bool bReplyIsNack, bool bBroadcast, bool bPath)
: Message(requestId, NV_DP_SBMSG_PRIORITY_LEVEL_DEFAULT)
{
BitStreamWriter writer(&encodedMessage.buffer, 0);
//
// Write request identifier
//
writer.write(bReplyIsNack?1:0, 1);
writer.write(requestId, 7);
encodedMessage.isPathMessage = bPath;
encodedMessage.isBroadcast = bBroadcast;
}
GenericUpReplyMessage::GenericUpReplyMessage(const Address & target, unsigned requestId, bool bReplyIsNack, bool bBroadcast, bool bPath)
: Message(requestId, NV_DP_SBMSG_PRIORITY_LEVEL_DEFAULT)
{
BitStreamWriter writer(&encodedMessage.buffer, 0);
//
// Write request identifier
//
writer.write(bReplyIsNack?1:0, 1);
writer.write(requestId, 7);
encodedMessage.isPathMessage = bPath;
encodedMessage.isBroadcast = bBroadcast;
encodedMessage.address = target;
}
ParseResponseStatus GenericUpReplyMessage::parseResponseAck(EncodedMessage * message, BitStreamReader * reader)
{
//
// we are not expecting any replies here
// Since the corresponding post for this kind of message is of reply type;
// message manager won't queue an awaiting down reply for the same.
//
DP_ASSERT(0 && "We shouldn't be here!!");
return ParseResponseSuccess;
}
//
// CLEAR_PAYLOAD_ID_TABLE 0x14
//
ClearPayloadIdTableMessage::ClearPayloadIdTableMessage()
: Message(NV_DP_SBMSG_REQUEST_ID_CLEAR_PAYLOAD_ID_TABLE /* request id */, NV_DP_SBMSG_PRIORITY_LEVEL_1)
{
BitStreamWriter writer(&encodedMessage.buffer, 0);
// Write request identifier
writer.write(0/*zero*/, 1);
writer.write(requestIdentifier, 7);
encodedMessage.isPathMessage = true;
encodedMessage.isBroadcast = true;
encodedMessage.address = Address();
}
ParseResponseStatus ClearPayloadIdTableMessage::parseResponseAck(EncodedMessage * message, BitStreamReader * reader)
{
return ParseResponseSuccess;
}
ParseResponseStatus ClearPayloadIdTableMessage::parseResponse(EncodedMessage * message)
{
sink->messageCompleted(this);
return ParseResponseSuccess;
}
//
// ENUM_PATH_RESOURCES 0x10
//
EnumPathResMessage::EnumPathResMessage(const Address & target, unsigned port, bool point)
: Message(NV_DP_SBMSG_REQUEST_ID_ENUM_PATH_RESOURCES /* request identifier */,
NV_DP_SBMSG_PRIORITY_LEVEL_4)
{
BitStreamWriter writer(&encodedMessage.buffer, 0);
// Write request identifier
writer.write(0/*zereo*/, 1);
writer.write(requestIdentifier, 7);
writer.write(port, 4);
writer.write(0/*zeroes*/, 4);
encodedMessage.isPathMessage = !point;
encodedMessage.isBroadcast = false;
encodedMessage.address = target;
sinkPort = port;
dpMemZero(&reply, sizeof(reply));
}
ParseResponseStatus EnumPathResMessage::parseResponseAck(EncodedMessage * message, BitStreamReader * reader)
{
reply.portNumber = reader->readOrDefault(4 /*Port_Number*/, 0xF);
reader->readOrDefault(3 /*zeroes*/, 0);
reply.bFECCapability = (reader->readOrDefault(1 /*FEC*/, 0x0) == 1) ? true : false;
reply.TotalPBN = reader->readOrDefault(16 /*PBN*/, 0xFFFF);
reply.FreePBN = reader->readOrDefault(16 /*PBN*/, 0xFFFF);
if (this->getSinkPort() != reply.portNumber)
return ParseResponseWrong;
return ParseResponseSuccess;
}
//
// ALLOCATE_PAYLOAD 0x11
//
void AllocatePayloadMessage::set
(
const Address & target,
unsigned port,
unsigned nSDPStreams,
unsigned vcPayloadId,
unsigned PBN,
unsigned* SDPStreamSink,
bool entirePath
)
{
clear();
BitStreamWriter writer(&encodedMessage.buffer, 0);
// Write request identifier
writer.write(0/*zero*/, 1);
writer.write(requestIdentifier, 7);
DP_ASSERT(SDPStreamSink || (!nSDPStreams));
// Write message request body
writer.write(port, 4);
writer.write(nSDPStreams, 4);
writer.write(0/*zero*/, 1);
writer.write(vcPayloadId, 7);
writer.write(PBN, 16);
for (unsigned i=0; i<nSDPStreams; i++)
{
writer.write(SDPStreamSink[i], 4);
}
// emit 0s until byte aligned.
writer.align(8);
encodedMessage.isPathMessage = entirePath;
encodedMessage.isBroadcast = false;
encodedMessage.address = target;
sinkPort = port;
}
ParseResponseStatus AllocatePayloadMessage::parseResponseAck(EncodedMessage * message, BitStreamReader * reader)
{
reply.portNumber = reader->readOrDefault(4 /*Port_Number*/, 0xF);
reader->readOrDefault(5 /*zeroes*/, 0);
reply.virtualChannelPayloadId = reader->readOrDefault(7 /*Virtual_Channel_Payload_Identifier*/, 0x0);
reply.PBN = reader->readOrDefault(16 /*PBN*/, 0xFFFF);
if (this->getSinkPort() != reply.portNumber)
return ParseResponseWrong;
return ParseResponseSuccess;
}
//
// QUERY_PAYLOAD 0x12
//
QueryPayloadMessage::QueryPayloadMessage
(
const Address & target,
unsigned port,
unsigned vcPayloadId
)
: Message(NV_DP_SBMSG_REQUEST_ID_QUERY_PAYLOAD /* request identifier*/,
NV_DP_SBMSG_PRIORITY_LEVEL_DEFAULT)
{
BitStreamWriter writer(&encodedMessage.buffer, 0);
// Write request identifier
writer.write(0 /*zero*/, 1);
writer.write(requestIdentifier, 7);
// Write message request
writer.write(port, 4);
writer.write(0 /*zeroes*/, 5);
writer.write(vcPayloadId, 7);
encodedMessage.isPathMessage = false;
encodedMessage.isBroadcast = false;
encodedMessage.address = target;
sinkPort = port;
dpMemZero(&reply, sizeof(reply));
}
ParseResponseStatus QueryPayloadMessage::parseResponseAck(EncodedMessage * message, BitStreamReader * reader)
{
reply.portNumber = reader->readOrDefault(4 /*Port_Number*/, 0xF);
reader->readOrDefault(4 /*zeroes*/, 0);
reply.allocatedPBN = reader->readOrDefault(16 /*Allocated_PBN*/, 0xFFFF);
if (this->getSinkPort() != reply.portNumber)
return ParseResponseWrong;
return ParseResponseSuccess;
}
//
// RESOURCE_STATUS_NOTIFY 0x13
//
ResStatusNotifyMessage::ResStatusNotifyMessage(MessageReceiverEventSink * sink)
: MessageReceiver(sink, NV_DP_SBMSG_REQUEST_ID_RESOURCE_STATUS_NOTIFY /*request id*/)
{
dpMemZero(&request, sizeof(request));
}
bool ResStatusNotifyMessage::processByType(EncodedMessage * message, BitStreamReader * reader)
{
bool status;
// read the request body
request.port = reader->readOrDefault(4/*Port_Number*/, 0xF);
reader->readOrDefault(4/*zeroes*/, 0);
status = DisplayPort::extractGUID(reader, &request.guid);
request.PBN = reader->readOrDefault(16/*Available_PBN*/, 0);
// action will be implemented by evensink
this->sink->messageProcessed(this);
return status;
}
//
// REMOTE_DPCD_READ 0x20
//
void RemoteDpcdReadMessage::set
(
const Address & target,
unsigned port,
unsigned dpcdAddress,
unsigned nBytesToRead
)
{
clear();
BitStreamWriter writer(&encodedMessage.buffer, 0);
// Write request identifier
writer.write(0/*zero*/, 1);
writer.write(requestIdentifier, 7);
// write request data
writer.write(port, 4);
writer.write(dpcdAddress, 20);
writer.write(nBytesToRead, 8);
encodedMessage.isPathMessage = false;
encodedMessage.isBroadcast = false;
encodedMessage.address = target;
sinkPort = port;
}
ParseResponseStatus RemoteDpcdReadMessage::parseResponseAck(EncodedMessage * message, BitStreamReader * reader)
{
reader->readOrDefault(4 /*zeroes*/, 0);
reply.portNumber = reader->readOrDefault(4 /*Port_Number*/, 0xF);
reply.numBytesReadDPCD = reader->readOrDefault(8 /*Num_Of_Bytes_Read*/, 0x0);
for (unsigned i=0; i<reply.numBytesReadDPCD; i++)
{
reply.readData[i] = (NvU8)reader->readOrDefault(8 /*data*/, 0x0);
}
if (this->getSinkPort() != reply.portNumber)
return ParseResponseWrong;
return ParseResponseSuccess;
}
//
// REMOTE_DPCD_WRITE 0x21
//
void RemoteDpcdWriteMessage::set
(
const Address & target,
unsigned port,
unsigned dpcdAddress,
unsigned nBytesToWrite,
const NvU8 * writeData
)
{
clear();
BitStreamWriter writer(&encodedMessage.buffer, 0);
DP_ASSERT(writeData || (!nBytesToWrite));
// Write request identifier
writer.write(0/*zero*/, 1);
writer.write(requestIdentifier, 7);
// write request data
writer.write(port, 4);
writer.write(dpcdAddress, 20);
writer.write(nBytesToWrite, 8);
for (unsigned i=0; i<nBytesToWrite; i++)
{
writer.write(writeData[i], 8);
}
encodedMessage.isPathMessage = false;
encodedMessage.isBroadcast = false;
encodedMessage.address = target;
sinkPort = port;
}
ParseResponseStatus RemoteDpcdWriteMessage::parseResponseAck(EncodedMessage * message, BitStreamReader * reader)
{
reader->readOrDefault(4 /*zeroes*/, 0);
unsigned portNumber = reader->readOrDefault(4 /*Port_Number*/, 0xF);
DP_ASSERT(portNumber == this->sinkPort);
DP_USED(portNumber);
if (this->getSinkPort() != portNumber)
return ParseResponseWrong;
return ParseResponseSuccess;
}
//
// REMOTE_I2C_READ 0x22
//
void RemoteI2cReadMessage::set
(
const Address & target,
unsigned nWriteTransactions,
unsigned port,
I2cWriteTransaction* transactions,
unsigned readI2cDeviceId,
unsigned nBytesToRead
)
{
clear();
BitStreamWriter writer(&encodedMessage.buffer, 0);
DP_ASSERT(transactions || (!nWriteTransactions));
// Write request identifier
writer.write(0 /*zero*/, 1);
writer.write(requestIdentifier, 7);
// write request specific data
writer.write(port, 4);
writer.write(0/*zeroes*/, 2);
writer.write(nWriteTransactions, 2);
for (unsigned i=0; i<nWriteTransactions; i++)
{
writer.write(0/*zero*/, 1);
writer.write(transactions[i].WriteI2cDeviceId, 7);
writer.write(transactions[i].NumBytes, 8);
for(unsigned j=0; j<transactions[i].NumBytes; j++)
{
writer.write(transactions[i].I2cData[j], 8);
}
writer.write(0/*zeroes*/, 3);
writer.write(transactions[i].NoStopBit ? 1 : 0, 1);
writer.write(transactions[i].I2cTransactionDelay, 4);
}
writer.write(0/*zero*/, 1);
writer.write(readI2cDeviceId, 7);
writer.write(nBytesToRead, 8);
encodedMessage.isPathMessage = false;
encodedMessage.isBroadcast = false;
encodedMessage.address = target;
sinkPort = port;
}
ParseResponseStatus RemoteI2cReadMessage::parseResponseAck(EncodedMessage * message, BitStreamReader * reader)
{
reader->readOrDefault(4 /*zeroes*/, 0);
reply.portNumber = reader->readOrDefault(4 /*Port_Number*/, 0xF);
reply.numBytesReadI2C = reader->readOrDefault(8 /*Num_Of_Bytes_Read*/, 0x0);
for (unsigned i=0; i<reply.numBytesReadI2C; i++)
{
reply.readData[i] = (NvU8)reader->readOrDefault(8 /*data*/, 0x0);
}
if (this->getSinkPort() != reply.portNumber)
return ParseResponseWrong;
return ParseResponseSuccess;
}
//
// REMOTE_I2C_WRITE 0x23
//
void RemoteI2cWriteMessage::set
(
const Address & target,
unsigned port,
unsigned writeI2cDeviceId,
unsigned nBytesToWrite,
unsigned char* writeData
)
{
clear();
BitStreamWriter writer(&encodedMessage.buffer, 0);
DP_ASSERT(writeData || (!nBytesToWrite));
// Write request identifier
writer.write(0 /*zero*/, 1);
writer.write(requestIdentifier, 7);
// write request data
writer.write(port, 4);
writer.write(0/*zero*/, 5);
writer.write(writeI2cDeviceId, 7);
writer.write(nBytesToWrite, 8);
for (unsigned i=0; i<nBytesToWrite; i++)
{
writer.write(writeData[i], 8);
}
encodedMessage.isPathMessage = false;
encodedMessage.isBroadcast = false;
encodedMessage.address = target;
sinkPort = port;
}
ParseResponseStatus RemoteI2cWriteMessage::parseResponseAck(EncodedMessage * message, BitStreamReader * reader)
{
reader->readOrDefault(4 /*zeroes*/, 0);
reply.portNumber = reader->readOrDefault(4 /*Port_Number*/, 0xF);
if (this->getSinkPort() != reply.portNumber)
return ParseResponseWrong;
return ParseResponseSuccess;
}
//
// POWER_UP_PHY 0x24
//
void PowerUpPhyMessage::set
(
const Address & target,
unsigned port,
bool entirePath
)
{
clear();
BitStreamWriter writer(&encodedMessage.buffer, 0);
// Write request identifier
writer.write(0 /*zero*/, 1);
writer.write(requestIdentifier, 7);
// write request specific data
writer.write(port, 4);
writer.write(0 /*zero*/, 4);
encodedMessage.isPathMessage = entirePath;
encodedMessage.isBroadcast = false;
encodedMessage.address = target;
sinkPort = port;
}
//
// POWER_DOWN_PHY 0x25
//
ParseResponseStatus PowerUpPhyMessage::parseResponseAck(EncodedMessage * message, BitStreamReader * reader)
{
reply.portNumber = reader->readOrDefault(4 /*Port_Number*/, 0xF);
reader->readOrDefault(4 /*zeroes*/, 0);
if (this->getSinkPort() != reply.portNumber)
return ParseResponseWrong;
return ParseResponseSuccess;
}
void PowerDownPhyMessage::set
(
const Address & target,
unsigned port,
bool entirePath
)
{
BitStreamWriter writer(&encodedMessage.buffer, 0);
// Write request identifier
writer.write(0 /*zero*/, 1);
writer.write(requestIdentifier, 7);
// write request specific data
writer.write(port, 4);
writer.write(0/*zeros*/, 4);
encodedMessage.isPathMessage = entirePath;
encodedMessage.isBroadcast = false;
encodedMessage.address = target;
sinkPort = port;
}
ParseResponseStatus PowerDownPhyMessage::parseResponseAck(EncodedMessage * message, BitStreamReader * reader)
{
reply.portNumber = reader->readOrDefault(4 /*Port_Number*/, 0xF);
reader->readOrDefault(4 /*zeroes*/, 0);
if (this->getSinkPort() != reply.portNumber)
return ParseResponseWrong;
return ParseResponseSuccess;
}
//
// SINK_EVENT_NOTIFY 0x30
//
SinkEventNotifyMessage::SinkEventNotifyMessage(MessageReceiverEventSink * sink, unsigned requestId)
: MessageReceiver(sink, 0x30 /*request id*/)
{
}
bool SinkEventNotifyMessage::processByType(EncodedMessage * message, BitStreamReader * reader)
{
return true;
}
I2cWriteTransaction::I2cWriteTransaction
(
unsigned WriteI2cDeviceId,
unsigned NumBytes,
unsigned char * buffer,
bool NoStopBit,
unsigned I2cTransactionDelay
)
{
this->WriteI2cDeviceId = WriteI2cDeviceId;
this->NumBytes = NumBytes;
this->NoStopBit = NoStopBit;
this->I2cTransactionDelay = I2cTransactionDelay;
this->I2cData = buffer;
}
I2cWriteTransaction::I2cWriteTransaction():
WriteI2cDeviceId(0), NumBytes(0), I2cData(0), NoStopBit(0), I2cTransactionDelay(0)
{
}

View File

@@ -0,0 +1,85 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_messageheader.cpp *
* DP message header parser *
* *
\***************************************************************************/
#include "dp_internal.h"
#include "dp_bitstream.h"
#include "dp_crc.h"
#include "dp_messageheader.h"
bool DisplayPort::decodeHeader(BitStreamReader * reader, MessageHeader * header, const Address & address)
{
unsigned startOffset = reader->offset();
int LCT, i;
//
// Read the RAD
//
LCT = reader->readOrDefault( 4, 0);
reader->readOrDefault( 4, 0);
header->address = address;
for (i = 0; i < LCT - 1; i++)
{
header->address.append(reader->readOrDefault( 4, 0));
}
reader->align( 8);
//
// Read flags
//
header->isBroadcast = !!reader->readOrDefault( 1, 0);
header->isPathMessage = !!reader->readOrDefault( 1, 0);
header->payloadBytes = reader->readOrDefault( 6, 0) ;
header->isTransactionStart = !!reader->readOrDefault( 1, 0);
header->isTransactionEnd = !!reader->readOrDefault( 1, 0);
reader->readOrDefault( 1, 0);
header->messageNumber = reader->readOrDefault( 1, 0);
// Build a bit reader for the slice of header we just processed
BitStreamReader crcReader(reader->buffer(), startOffset, reader->offset());
if (reader->readOrDefault( 4, (NvU32)~0) != dpCalculateHeaderCRC(&crcReader))
{
// Corrupt packet received
char buffer[48*3+1];
dpHexDump(&buffer[0], sizeof(buffer), (NvU8*)reader->buffer() + startOffset, reader->offset() - startOffset);
DP_LOG(("DP-MM> Corrupt message transaction. Expected CRC %d. Message = {%s}", dpCalculateHeaderCRC(&crcReader), buffer));
return false;
}
header->headerSizeBits = reader->offset() - startOffset;
return true;
}

View File

@@ -0,0 +1,606 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2010-2021 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_messages.cpp *
* Encoding for aux common messages. *
* *
\***************************************************************************/
#include "dp_internal.h"
#include "dp_bitstream.h"
#include "dp_splitter.h"
#include "dp_messages.h"
#include "dp_merger.h"
#include "dp_list.h"
#include "dp_tracing.h"
using namespace DisplayPort;
namespace DisplayPort
{
GenericMessageCompletion::GenericMessageCompletion() :
failed(false), completed(false) {}
void GenericMessageCompletion::messageFailed(MessageManager::Message * from, NakData * data)
{
nakData = *data;
failed = true;
completed = true;
}
void GenericMessageCompletion::messageCompleted(MessageManager::Message * from)
{
failed = false;
completed = true;
}
};
//
// Transmit a message and wait for the response in place.
//
bool MessageManager::send(MessageManager::Message * message, NakData & nakData)
{
GenericMessageCompletion completion;
Address::StringBuffer sb;
DP_USED(sb);
NvU64 startTime, elapsedTime;
post(message, &completion);
startTime = timer->getTimeUs();
do
{
hal->notifyIRQ();
if (hal->interruptDownReplyReady())
IRQDownReply();
if (completion.completed)
{
nakData = completion.nakData;
break;
}
elapsedTime = timer->getTimeUs() - startTime;
if (elapsedTime > (DPCD_MESSAGE_REPLY_TIMEOUT * 1000))
{
message->expired(NULL);
nakData.reason = NakTimeout;
break;
}
// Sleep while processing timer callbacks
timer->sleep(1);
} while(true);
return !completion.failed;
}
bool DisplayPort::extractGUID(BitStreamReader * reader, GUID * guid)
{
for (unsigned i=0; i < 128; i += 8)
{
unsigned data;
if (!reader->read(&data, 8))
{
return false;
}
guid->data[i/8] = (NvU8)data;
}
return true;
}
void MessageManager::messagedReceived(IncomingTransactionManager * from, EncodedMessage * message)
{
if (from == &mergerUpRequest)
{
onUpRequestReceived(true, message);
}
else
{
onDownReplyReceived(true, message);
}
}
void MessageManager::Message::splitterFailed(OutgoingTransactionManager * from)
{
//
// Message failed
//
NakData nakData;
nakData.reason = NakTimeout;
MessageManager * parent = this->parent;
if (sink)
sink->messageFailed(this, &nakData);
if (from == &parent->splitterDownRequest)
{
//
// Tell the message manager he may begin sending the next message
//
parent->transmitAwaitingDownRequests();
}
else
{
parent->transmitAwaitingUpReplies();
}
}
void MessageManager::Message::splitterTransmitted(OutgoingTransactionManager * from)
{
bTransmitted = true;
MessageManager * parent = this->parent;
if (from == &parent->splitterDownRequest)
{
//
// 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
{
if (sink)
sink->messageCompleted(this); // This is the end for an up reply
parent->transmitAwaitingUpReplies();
}
}
// Since transmit DPCD_MESSAGE_REPLY_TIMEOUT time has elapsed.
// - Let's assume the message was not replied to
void MessageManager::Message::expired(const void * tag)
{
Address::StringBuffer sb;
DP_USED(sb);
DP_LOG(("DP-MM> Message transmit time expired on message %p (ID = %02X, target = %s)",
(Message*)this, ((Message*)this)->requestIdentifier, (((Message*)this)->state.target).toString(sb)));
Address::NvU32Buffer addrBuffer;
dpMemZero(addrBuffer, sizeof(addrBuffer));
(((Message*)this)->state.target).toNvU32Buffer(addrBuffer);
NV_DPTRACE_WARNING(MESSAGE_EXPIRED, ((Message*)this)->requestIdentifier, (((Message*)this)->state.target).size(),
addrBuffer[0], addrBuffer[1], addrBuffer[2], addrBuffer[3]);
NakData nakData;
nakData.reason = NakTimeout;
MessageManager * parent = this->parent;
DP_ASSERT(parent);
if (parent && !parent->isBeingDestroyed)
{
parent->awaitingReplyDownRequest.remove(this);
parent->clearPendingMsg();
parent->transmitAwaitingDownRequests();
parent->transmitAwaitingUpReplies();
}
if (sink)
sink->messageFailed(this, &nakData);
}
//
// Enqueue the next message to the splitterDownRequest
//
void MessageManager::transmitAwaitingDownRequests()
{
for (ListElement * i = notYetSentDownRequest.begin(); i!=notYetSentDownRequest.end(); )
{
Message * m = (Message *)i;
i = i->next; // Do this first since we may unlink the current node
if (awaitingReplyDownRequest.isEmpty())
{
//
// Set the message number, and unlink from the outgoing queue
//
m->encodedMessage.messageNumber = 0;
m->state.messageNumber = 0;
notYetSentDownRequest.remove(m);
awaitingReplyDownRequest.insertBack(m);
//
// This call can cause transmitAwaitingDownRequests to be called again
//
bool sent = splitterDownRequest.send(m->encodedMessage, m);
DP_ASSERT(sent);
return;
}
}
}
//
// Enqueue the next message to the splitterUpReply
//
void MessageManager::transmitAwaitingUpReplies()
{
for (ListElement * i = notYetSentUpReply.begin(); i!=notYetSentUpReply.end(); )
{
Message * m = (Message *)i;
i = i->next; // Do this first since we may unlink the current node
notYetSentUpReply.remove(m);
//
// This call can cause transmitAwaitingUpReplies to be called again
//
bool sent = splitterUpReply.send(m->encodedMessage, m);
DP_ASSERT(sent);
}
}
void MessageManager::postReply(Message * message, Message::MessageEventSink * sink)
{
post(message, sink, true);
}
void MessageManager::cancelAllByType(unsigned type)
{
for (ListElement * i = notYetSentDownRequest.begin(); i!=notYetSentDownRequest.end(); )
{
Message * m = (Message *)i;
i = i->next;
if (m->requestIdentifier == type)
notYetSentDownRequest.remove(m);
}
for (ListElement * i = awaitingReplyDownRequest.begin(); i!=awaitingReplyDownRequest.end(); )
{
Message * m = (Message *)i;
i = i->next;
if (m->requestIdentifier == type)
awaitingReplyDownRequest.remove(m);
}
}
void MessageManager::cancelAll(Message * message)
{
for (ListElement * i = notYetSentDownRequest.begin(); i!=notYetSentDownRequest.end(); )
{
Message * m = (Message *)i;
i = i->next;
if (m == message && m->requestIdentifier == message->requestIdentifier)
notYetSentDownRequest.remove(m);
}
for (ListElement * i = awaitingReplyDownRequest.begin(); i!=awaitingReplyDownRequest.end(); )
{
Message * m = (Message *)i;
i = i->next;
if (m == message && m->requestIdentifier == message->requestIdentifier)
awaitingReplyDownRequest.remove(m);
}
}
void MessageManager::post(Message * message, Message::MessageEventSink * sink, bool transmitReply)
{
DP_ASSERT(!isBeingDestroyed && "You may not post messages in response to a shutdown");
if (isPaused)
return;
//
// Initialize the fields
//
message->sink = sink;
message->bTransmitted = false;
//
// Queue the message for the outgoing queue.
// Later on we'll walk to the queue and make sure
// we have at most two outstanding messages PER
// target address. This is how the message
// number is decided.
//
message->parent = this;
message->transmitReply = transmitReply;
if (message->encodedMessage.isBroadcast)
{
// if its a broadcast message; the target would be the immediate branch.
Address addr;
addr.clear();
addr.append(0);
message->state.target = addr;
}
else
message->state.target = message->encodedMessage.address;
if ( transmitReply )
{
notYetSentUpReply.insertBack(message);
transmitAwaitingUpReplies();
}
else
{
//
// If the list is empty or the incoming message has the least priority possible (DEFAULT priority),
// then just add the incoming message to the back of the list.
// Otherwise, find the right location by traversing the list.
//
if(message->messagePriority == NV_DP_SBMSG_PRIORITY_LEVEL_DEFAULT || notYetSentDownRequest.isEmpty())
{
notYetSentDownRequest.insertBack(message);
}
else
{
ListElement *tmp = notYetSentDownRequest.last();
Message *msg = (Message*) notYetSentDownRequest.last();
while((msg->prev != tmp) && (msg->messagePriority < message->messagePriority))
{
msg = (Message*)msg->prev;
}
notYetSentDownRequest.insertBefore(msg->next, message);
}
transmitAwaitingDownRequests();
}
}
void MessageManager::onUpRequestReceived(bool status, EncodedMessage * message)
{
if (!status)
{
return;
}
//
// Broadcast the up-request message to all
// the receivers on messageReceivers
//
for (ListElement * i = messageReceivers.begin(); i!=messageReceivers.end(); i=i->next)
{
MessageReceiver * rcr = (MessageReceiver *)i;
if (rcr->process((EncodedMessage *)message))
{
return;
}
}
DP_ASSERT(0 && "Warning: Unknown upstream UP_REQ message");
}
void MessageManager::onDownReplyReceived(bool status, EncodedMessage * message)
{
if (!status)
{
return;
}
//
// Broadcast the down-request message to all
// the receivers on awaitingReplyDownRequest
//
for (ListElement * i = awaitingReplyDownRequest.begin(); i!=awaitingReplyDownRequest.end(); i=i->next)
{
Message * messageAwaitingReply = (Message *)i;
if( messageAwaitingReply->state.target == message->address &&
messageAwaitingReply->state.messageNumber == message->messageNumber)
{
awaitingReplyDownRequest.remove(messageAwaitingReply);
if (messageAwaitingReply->parseResponse(message) == ParseResponseWrong)
{
//
// parseResponse() returns ParseResposeWrong when 'Request_Identifier' of down request
// message and down reply message are mis-matched. So insert message in waiting queue
// and wait for correct down reply message.
//
awaitingReplyDownRequest.insertBack(messageAwaitingReply);
}
goto nextMessage;
}
}
DP_LOG(("DPMM> Warning: Unmatched reply message"));
nextMessage:
transmitAwaitingUpReplies();
transmitAwaitingDownRequests();
}
MessageManager::~MessageManager()
{
// This causes any posts they may attempt to do to fail
isBeingDestroyed = true;
//
// The message manager should not be shut down until
// all outgoing messages are in the cancelled state
//
NakData nakUndef;
nakUndef.reason = NakUndefined;
for (ListElement * i = notYetSentDownRequest.begin(); i!=notYetSentDownRequest.end(); )
{
ListElement * next = i->next;
if (((Message *)i)->sink)
((Message *)i)->sink->messageFailed(((Message *)i), &nakUndef);
i = next;
}
if (!notYetSentDownRequest.isEmpty())
{
for (ListElement * i = notYetSentDownRequest.begin(); i!=notYetSentDownRequest.end(); )
{
ListElement * next = i->next;
DP_LOG(("Down request message type 0x%x client is not cleaning up.", ((Message *)i)->requestIdentifier));
i = next;
}
}
for (ListElement * i = notYetSentUpReply.begin(); i!=notYetSentUpReply.end();)
{
ListElement * next = i->next;
if (((Message *)i)->sink)
((Message *)i)->sink->messageFailed(((Message *)i), &nakUndef);
i = next;
}
if (!notYetSentUpReply.isEmpty())
{
for (ListElement * i = notYetSentUpReply.begin(); i!=notYetSentUpReply.end(); )
{
ListElement * next = i->next;
DP_LOG(("Up reply message type 0x%x client is not cleaning up.", ((Message *)i)->requestIdentifier));
i = next;
}
}
for (ListElement * i = awaitingReplyDownRequest.begin(); i!=awaitingReplyDownRequest.end(); )
{
ListElement * next = i->next;
if (((Message *)i)->sink)
((Message *)i)->sink->messageFailed(((Message *)i), &nakUndef);
i = next;
}
if (!awaitingReplyDownRequest.isEmpty())
{
for (ListElement * i = awaitingReplyDownRequest.begin(); i!=awaitingReplyDownRequest.end(); )
{
ListElement * next = i->next;
DP_LOG(("Down request message type 0x%x client is not cleaning up.", ((Message *)i)->requestIdentifier));
i = next;
}
}
// Do not reclaim the memory of our registered receivers
while (!messageReceivers.isEmpty())
messageReceivers.remove(messageReceivers.front());
}
ParseResponseStatus MessageManager::Message::parseResponse(EncodedMessage * message)
{
BitStreamReader reader(&message->buffer, 0, message->buffer.length*8);
// Read ReplyType
bool replyNacked = !!reader.readOrDefault(1, true);
// Read RequestIdentifier
unsigned requestId = reader.readOrDefault(7, 0);
if (requestId != requestIdentifier)
{
DP_LOG(("DP-MM> Requested = %x Received = %x", requestId, requestIdentifier));
DP_ASSERT(0 && "Reply type doesn't match");
return ParseResponseWrong;
}
if (replyNacked)
{
NakData nakData;
// failure handler will parse the NAK response and do the required action
if (DisplayPort::extractGUID(&reader, &nakData.guid) == false)
{
DP_ASSERT(0 && "Invalid GUID in NAK");
}
nakData.reason = (NakReason)reader.readOrDefault(8, 0);
nakData.nak_data = reader.readOrDefault(8, 0);
// call specific handler after parsing.
parent->timer->cancelCallbacks(this);
MessageManager * parent = this->parent;
if (sink)
sink->messageFailed(this, &nakData);
parent->transmitAwaitingDownRequests();
return ParseResponseSuccess;
}
ParseResponseStatus parseResult = parseResponseAck(message, &reader);
if (parseResult == ParseResponseSuccess)
{
parent->timer->cancelCallbacks(this);
if (this->sink)
{
MessageEventSink * msgSink = this->sink;
msgSink->messageCompleted(this);
}
}
return parseResult;
}
void MessageManager::Message::MessageEventSink::messageFailed(Message * from, NakData * nakData)
{
}
void MessageManager::registerReceiver(MessageReceiver * receiver)
{
messageReceivers.insertBack(receiver);
}
bool MessageManager::MessageReceiver::process(EncodedMessage * message)
{
BitStreamReader reader(&message->buffer, 0, message->buffer.length*8);
// Read RequestIdentifier
reader.readOrDefault(1, 0);
unsigned reqId = reader.readOrDefault(7, 0);
if (reqId != this->getRequestId())
{
//
// This receiver is not meant for this message;
// let the next in the queue handle it.
//
return false;
}
this->address = message->address;
// processByType should parse the request, create a response and queue it if needed
bool status = processByType(message, &reader);
if (!status)
{
//
// if we are here; we could get a receiver to handle the request
// but something else went wrong.
//
DP_ASSERT(0);
}
return true;
}

View File

@@ -0,0 +1,188 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2010-2021 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_mst_edid.c *
* Implementation Multi Stream EDID reads *
* *
\***************************************************************************/
#include "dp_internal.h"
#include "dp_edid.h"
#include "dp_address.h"
#include "dp_messagecodings.h"
#include "dp_messages.h"
using namespace DisplayPort;
EdidReadMultistream::~EdidReadMultistream()
{
timer->cancelCallbacks(this);
}
void EdidReadMultistream::startReadingEdid()
{
NvU8 offset = 0;
I2cWriteTransaction i2cWriteTransactions[1];
Address::StringBuffer buffer;
DP_USED(buffer);
DP_LOG(("%s(): start for %s", __FUNCTION__,
topologyAddress.toString(buffer)));
edidReaderManager.reset();
edid.resetData();
DDCAddress = ddcAddrList[ddcIndex];
// set offset within segment 0, no need to set segment, because we're starting reading EDID
i2cWriteTransactions[0] = I2cWriteTransaction(DDCAddress >> 1,
sizeof(offset),
&offset,
true);
NvU8 nWriteTransactions = 1;
remoteI2cRead.set(topologyAddress.parent(), // topology Address
nWriteTransactions, // number of write transactions
topologyAddress.tail(), // port of Device
i2cWriteTransactions, // list of write transactions
DDCAddress >> 1, // right shifted DDC Address (request identifier in spec)
EDID_BLOCK_SIZE); // requested size
manager->post(&remoteI2cRead, this);
}
void EdidReadMultistream::messageCompleted(MessageManager::Message * from)
{
RemoteI2cReadMessage* I2CReadMessage = (RemoteI2cReadMessage*)from;
unsigned char * data = 0;
unsigned numBytesRead;
Address::StringBuffer buffer;
DP_USED(buffer);
NvU8 seg;
NvU8 offset;
DP_LOG(("%s for %s", __FUNCTION__, topologyAddress.toString(buffer)));
DP_ASSERT(DDCAddress && "DDCAddress is 0, it is wrong");
data = I2CReadMessage->replyGetI2CData(&numBytesRead);
DP_ASSERT(data);
// this is not required, but I'd like to keep things simple at first submission
DP_ASSERT(numBytesRead == EDID_BLOCK_SIZE);
edidReaderManager.postReply(data, numBytesRead, true);
if (edidReaderManager.readNextRequest(seg, offset))
{
readNextBlock(seg, offset);
}
else // EDID read is finished or failed.
{
edidAttemptDone(edidReaderManager.readIsComplete() && edid.verifyCRC());
}
}
void EdidReadMultistream::edidAttemptDone(bool succeeded)
{
if (succeeded)
sink->mstEdidCompleted(this);
else if (ddcIndex + 1 < ddcAddrListSize)
{
ddcIndex++;
startReadingEdid();
}
else
sink->mstEdidReadFailed(this);
}
void EdidReadMultistream::readNextBlock(NvU8 seg, NvU8 offset)
{
I2cWriteTransaction i2cWriteTransactions[2];
Address::StringBuffer buffer;
DP_USED(buffer);
// ensure that init function for i2cWriteTranscation for segment and offset won't break
DP_ASSERT(sizeof(seg) == 1);
DP_ASSERT(sizeof(offset) == 1);
DP_LOG(("%s(): for %s (seg/offset) = %d/%d", __FUNCTION__,
topologyAddress.toString(buffer),
seg, offset));
unsigned nWriteTransactions = 2;
if (seg)
{
// select segment
i2cWriteTransactions[0] = I2cWriteTransaction(EDID_SEG_SELECTOR_OFFSET >> 1,
1, &seg, true);
// set offset within segment
i2cWriteTransactions[1] = I2cWriteTransaction(DDCAddress >> 1,
1, &offset, true);
}
else
{
// set offset within segment 0
i2cWriteTransactions[0] = I2cWriteTransaction(DDCAddress >> 1, 1, &offset, true);
nWriteTransactions = 1;
}
remoteI2cRead.set(topologyAddress.parent(), // topology Address
nWriteTransactions, // number of write transactions
topologyAddress.tail(), // port of Device
i2cWriteTransactions, // list of write transactions
DDCAddress >> 1, // right shifted DDC Address (request identifier in spec)
EDID_BLOCK_SIZE); // requested size
manager->post(&remoteI2cRead, this, false);
}
void EdidReadMultistream::expired(const void * tag)
{
Address::StringBuffer buffer;
DP_USED(buffer);
DP_LOG(("%s on %s", __FUNCTION__, topologyAddress.toString(buffer)));
startReadingEdid();
}
void EdidReadMultistream::messageFailed(MessageManager::Message * from, NakData * nakData)
{
Address::StringBuffer buffer;
DP_USED(buffer);
DP_LOG(("%s on %s", __FUNCTION__, topologyAddress.toString(buffer)));
if (nakData->reason == NakDefer || nakData->reason == NakTimeout)
{
if (retries < MST_EDID_RETRIES)
{
++retries;
timer->queueCallback(this, "EDID", MST_EDID_COOLDOWN);
}
else
edidAttemptDone(false /* failed */);
}
else
{
edidAttemptDone(false /* failed */);
}
}

View File

@@ -0,0 +1,314 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_splitter.cpp *
* Asynchronous Message Splitter *
* *
\***************************************************************************/
#include "dp_internal.h"
#include "dp_bitstream.h"
#include "dp_splitter.h"
#include "dp_auxdefs.h"
#include "dp_crc.h"
#include "dp_configcaps.h"
using namespace DisplayPort;
#define DP_MAX_HEADER_SIZE 16
// timeout after 110ms with a retry recurring every 5ms for 10 times
#define DOWNSTREAM_RETRY_ON_DEFER_TIMEOUT 110
#define DOWNSTREAM_RETRY_ON_DEFER_PERIOD 5
#define DOWNSTREAM_RETRY_ON_DEFER_COUNT 10
bool MessageTransactionSplitter::get(Buffer & assemblyBuffer)
{
unsigned i;
unsigned payloadSize;
bool isTransactionStart, isTransactionEnd;
Address address;
unsigned LCT;
unsigned LCR;
unsigned headerSizeBits;
assemblyBuffer.reset();
//
// Done?
//
if (this->messageOutstanding->buffer.length == this->assemblyTransmitted)
{
return false;
}
address = this->messageOutstanding->address;
if (this->messageOutstanding->isBroadcast)
{
// no RAD
address.clear();
LCT = 1;
}
else
{
LCT = address.size();
}
// Calculate header size
headerSizeBits = 8 + // LCT/LCR
(((4 * (LCT -1)) + 4) &~ 7) + // byte aligned RAD
16;
//
// Pick how much data to send. Header+payloadSize <= 48 bytes.
//
payloadSize = DP_MIN(DPCD_MESSAGEBOX_SIZE - (headerSizeBits+7)/8, /*crc*/1 + this->messageOutstanding->buffer.length - this->assemblyTransmitted);
//
// Is the first or last transaction in the sequence?
//
isTransactionStart = assemblyTransmitted == 0;
isTransactionEnd = (assemblyTransmitted + payloadSize - 1) == messageOutstanding->buffer.length;
BitStreamWriter writer(&assemblyBuffer, 0);
//
// Write the header
//
writer.write(LCT, 4);
LCR = this->messageOutstanding->isBroadcast ? 6 : LCT > 1 ? LCT - 1 : 0;
writer.write(LCR, 4);
// port at i=0 is the outport of source/gpu which should not be included in the RAD in outgoing message header
// if this is a broadcast message; LCT would be 1; hence no RAD.
for (i = 1; i < LCT; i++)
writer.write(address[i], 4);
writer.align(8);
writer.write(this->messageOutstanding->isBroadcast, 1);
writer.write(this->messageOutstanding->isPathMessage, 1);
writer.write(payloadSize, 6);
writer.write(isTransactionStart, 1);
writer.write(isTransactionEnd, 1);
writer.write(0, 1);
DP_ASSERT(messageOutstanding->messageNumber == 0 || messageOutstanding->messageNumber == 1);
writer.write(messageOutstanding->messageNumber, 1);
//
// Generate 4 bit CRC. (Nibble-wise CRC of previous values)
//
BitStreamReader reader(&assemblyBuffer, 0, writer.offset());
writer.write(dpCalculateHeaderCRC(&reader), 4);
DP_ASSERT(writer.offset() == headerSizeBits && "Header size mismatch");
DP_ASSERT((writer.offset() & 7) == 0 && "Packet header must end byte aligned");
//
// Generate body CRC
//
BitStreamReader bodyReader(&this->messageOutstanding->buffer, this->assemblyTransmitted * 8, (payloadSize - 1) * 8);
NvU8 bodyCrc = (NvU8)dpCalculateBodyCRC(&bodyReader);
// Copy in remaining buffer (leaving room for the CRC)
for (i = 0; i < payloadSize - 1; ++i)
writer.write(this->messageOutstanding->buffer.data[i + this->assemblyTransmitted], 8);
writer.write(bodyCrc, 8);
this->assemblyTransmitted += payloadSize - 1;
return true;
}
void OutgoingTransactionManager::expired(const void * tag)
{
writeToWindow(false);
}
void OutgoingTransactionManager::cancel(OutgoingTransactionManagerEventSink * sink)
{
if (activeMessage && activeMessage->eventSink == sink)
activeMessage->eventSink = 0;
for (ListElement * el = queuedMessages.begin(); el && el!=queuedMessages.end(); el = el->next)
if (((OutgoingMessage *)el)->eventSink == sink)
((OutgoingMessage *)el)->eventSink = 0;
}
bool OutgoingTransactionManager::send( EncodedMessage & payload, OutgoingTransactionManagerEventSink * sink)
{
OutgoingMessage * om = new OutgoingMessage();
if (!om)
{
return false;
}
om->eventSink = sink;
om->message.swap(payload);
if (!activeMessage)
{
activeMessage = om;
transactionSplitter.set(&om->message);
transactionSplitter.get(this->assemblyBuffer);
writeToWindow(true);
}
else
{
queuedMessages.insertBack(om);
}
return true;
}
void OutgoingTransactionManager::writeToWindow( bool firstAttempt)
{
AuxRetry::status result;
if (!activeMessage || !activeMessage->eventSink)
goto findNextMessage;
result = this->writeMessageBox(assemblyBuffer.data, assemblyBuffer.length);
if (result == AuxRetry::defer)
{
//
// if retries left; queue one.
//
if (firstAttempt || retriesLeft )
{
if (firstAttempt)
{
// initialize retriesLeft
retriesLeft = DOWNSTREAM_RETRY_ON_DEFER_COUNT;
}
retriesLeft--;
DP_LOG(("DP-MM> Messagebox write defer-ed. Q-ing retry."));
this->timer->queueCallback(this, "SPDE", DOWNSTREAM_RETRY_ON_DEFER_PERIOD);
return;
}
//
// Notify message sender of failure. Keep in mind sender
// might turn around immediately with a queue'd send.
//
if (activeMessage)
{
activeMessage->eventSink->splitterFailed(this);
}
goto findNextMessage;
}
else if (result == AuxRetry::ack)
{
//
// Split off another chunk and transmit
//
if (transactionSplitter.get(assemblyBuffer))
{
writeToWindow(true);
}
else
{
//
// Notify message sender of success. Keep in mind sender
// might turn around immediately with a queue'd send.
//
if (activeMessage)
{
activeMessage->eventSink->splitterTransmitted(this);
}
goto findNextMessage;
}
return;
}
//
// Notify message sender of failure. Keep in mind sender
// might turn around immediately with a queued send.
//
if (activeMessage)
{
activeMessage->eventSink->splitterFailed(this);
}
findNextMessage:
//
// The old transaction is complete. Free the memory
//
delete activeMessage;
activeMessage = 0;
//
// Look for the next transaction
//
if (queuedMessages.isEmpty())
{
return;
}
else
{
activeMessage = (OutgoingMessage *)queuedMessages.begin();
queuedMessages.remove(activeMessage);
transactionSplitter.set(&activeMessage->message);
transactionSplitter.get(this->assemblyBuffer);
writeToWindow(true);
}
}
OutgoingTransactionManager::OutgoingTransactionManager(Timer * timer)
: timer(timer)
{
this->activeMessage = 0;
}
AuxRetry::status DownRequestManager::writeMessageBox(NvU8 * data, size_t length)
{
return hal->writeDownRequestMessageBox(data, length);
}
size_t DownRequestManager::getMessageBoxSize()
{
return hal->getDownRequestMessageBoxSize();
}
AuxRetry::status UpReplyManager::writeMessageBox(NvU8 * data, size_t length)
{
return hal->writeUpReplyMessageBox(data, length);
}
size_t UpReplyManager::getMessageBoxSize()
{
return hal->getUpReplyMessageBoxSize();
}

View File

@@ -0,0 +1,336 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2010-2021 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_sst_edid.c *
* Implementation Single Stream EDID reads *
* *
\***************************************************************************/
#include "dp_buffer.h"
#include "dp_auxbus.h"
#include "dp_internal.h"
#include "dp_edid.h"
using namespace DisplayPort;
/*
* seg -> 256 segment of EDID
* offset -> offset within segment
*/
static bool readNextBlock(AuxBus * auxBus, NvU8 seg, NvU8 offset, Buffer & buffer, unsigned & totalRead, unsigned DDCAddress, Timer * timer)
{
AuxBus::Type type = AuxBus::i2cMot;
AuxBus::status auxStatus;
unsigned retries = 0;
unsigned sizeRequested;
unsigned sizeCompleted;
unsigned transactionSize = auxBus->transactionSize();
totalRead = 0;
DP_ASSERT(auxBus);
DP_ASSERT(transactionSize > 0);
// ASSERT if edidOffset offset wasn't increased in block len sizes
DP_ASSERT(offset == 0 || offset == EDID_BLOCK_SIZE);
sizeRequested = transactionSize;
if (!buffer.resize(EDID_BLOCK_SIZE))
{
return false;
}
DP_ASSERT(sizeof(seg) == 1);
DP_ASSERT(sizeof(offset) == 1);
// only set segment if it is required
if (seg)
{
// start EDID read by specifying appropriate Edid segment id
for (unsigned retry = 0; retry < EDID_MAX_AUX_RETRIES; retry++)
{
auxStatus = auxBus->transaction(AuxBus::write, AuxBus::i2cMot, EDID_SEG_SELECTOR_OFFSET >> 1,
&seg, sizeof(seg), &sizeCompleted);
if (auxStatus == AuxBus::success)
break;
// If deferred due to timeout
if (auxStatus == AuxBus::defer)
{
// Wait for sometime between retries
timer->sleep(EDID_AUX_WAIT_TIME);
continue;
}
return false;
}
}
auxStatus = AuxBus::nack;
for (retries = 0; totalRead < EDID_BLOCK_SIZE;)
{
//
// For retry, rewrite the Offset for the internal read pointer
// except when the previous Read auxstatus was an Aux::defer
// since in that case, the offset was never incremented by sink
//
if ((auxStatus != AuxBus::success) && (auxStatus != AuxBus::defer))
{
// start from this offset, need to verify with display with multiple edid blocks
for (unsigned retry = 0; retry < EDID_MAX_AUX_RETRIES; retry++)
{
auxStatus = auxBus->transaction(AuxBus::write, AuxBus::i2cMot, DDCAddress >> 1,
(NvU8*)(&offset), sizeof(offset), &sizeCompleted);
if (auxStatus == AuxBus::success)
break;
// If deferred due to timeout
if (auxStatus == AuxBus::defer)
{
// Wait for sometime between retries
timer->sleep(EDID_AUX_WAIT_TIME);
continue;
}
return false;
}
// if retries exceed EDID_MAX_AUX_RETRIES, give up
if (auxStatus != AuxBus::success)
{
return false;
}
}
// need to change to I2C (not MOT) to read just one last part of EDID block
if (totalRead + transactionSize >= EDID_BLOCK_SIZE)
type = AuxBus::i2c;
sizeRequested = DP_MIN(transactionSize, EDID_BLOCK_SIZE - totalRead);
auxStatus = auxBus->transaction(AuxBus::read, type, DDCAddress >> 1,
&(buffer.data[totalRead]), sizeRequested, &sizeCompleted);
if (AuxBus::success != auxStatus || (sizeRequested && (sizeCompleted == 0)))
{
if (retries >= EDID_MAX_AUX_RETRIES)
return false;
DP_LOG(("DisplayPort: %s: Retrying at totalRead 0x%08x (replyType %x, size %x)",
__FUNCTION__, totalRead, auxStatus, sizeRequested));
// Wait for sometime between retries
timer->sleep(EDID_AUX_WAIT_TIME);
retries++;
continue;
}
// Assert when size mismatches and it is not last block
if ((sizeRequested != sizeCompleted) &&
(totalRead + transactionSize < EDID_BLOCK_SIZE))
{
DP_LOG(("DisplayPort: %s: dpAux returned edid block smaller than expected. Read from totalRead 0x%08x (replyType %x, size %x)",
__FUNCTION__, totalRead, auxStatus, sizeRequested));
DP_ASSERT(0);
}
retries = 0; // reset the number of retries
totalRead += sizeCompleted;
offset += (NvU8)sizeCompleted;
}
return true;
}
/*!
* @return: true => EDID read is success, false => read is failure
*/
static bool sstReadEdid(AuxBus * auxBus, Edid & edid, unsigned DDCAddr, Timer * timer, bool pendingTestRequestEdidRead)
{
//
// If there is pending test request for edid read,
// ask edidReaderManager to take whatever posted,
// instead of discarding bytes read by a failed read.
// Because cert devices may need to see the checksum of these bytes,
// even if they seem corrupted.
//
EdidAssembler edidReaderManager(&edid, pendingTestRequestEdidRead);
NvU32 retryCount = 0;
Buffer buffer;
if (!buffer.resize(EDID_BLOCK_SIZE))
{
return false;
}
DP_ASSERT(auxBus);
do
{
NvU8 seg = 0;
NvU8 offset = 0;
unsigned totalRead = 0;
edidReaderManager.reset();
// start by reading first EDID block, posting it and analyzing for next request
do
{
bool success = readNextBlock(auxBus, seg, offset, buffer, totalRead, DDCAddr, timer);
edidReaderManager.postReply(buffer, totalRead, success);
}
while (edidReaderManager.readNextRequest(seg, offset));
if (!edid.isPatchedChecksum())
break;
} while (retryCount++ < EDID_POLICY_BLOCK_READ_MAX_RETRY_COUNT);
//
// EDID read is successful when
// 1. read was done to the end (i.e. no corruption, no blocks exceeding retry count)
// 2. EDID CRC is correct
//
return edidReaderManager.readIsComplete();
}
EDID_DDC DisplayPort::sstDDCPing(AuxBus & dpAux)
{
unsigned sizeRequested = 0, sizeCompleted;
AuxBus::status auxStatus = AuxBus::nack;
NvU8 offset = 0;
unsigned ddcAddrIdx;
for (ddcAddrIdx = 0; ddcAddrIdx < ddcAddrListSize; ddcAddrIdx++)
{
//
// Don't use an I2C write. Some devices erroneously ACK on the write
//
auxStatus = dpAux.transaction(AuxBus::read, AuxBus::i2c, ddcAddrList[ddcAddrIdx] >> 1,
&offset, sizeRequested, &sizeCompleted);
if (AuxBus::success == auxStatus)
return (EDID_DDC)ddcAddrList[ddcAddrIdx];
}
return EDID_DDC_NONE;
}
bool DisplayPort::EdidReadSST(Edid & edid, AuxBus * auxBus, Timer* timer,
bool pendingTestRequestEdidRead, bool bBypassAssembler,
MainLink * main)
{
Edid previousEdid;
Buffer *buffer;
bool status;
for (unsigned i = 0; i < ddcAddrListSize; i++)
{
for (unsigned j = 0; j < EDID_READ_MAX_RETRY_COUNT; j++)
{
//
// Client asks to use RM control code to fetch EDID.
//
if (bBypassAssembler && main)
{
unsigned blockCnt;
buffer = edid.getBuffer();
if (!buffer->resize(EDID_BLOCK_SIZE))
{
return false;
}
status = main->fetchEdidByRmCtrl(buffer->getData(), buffer->getLength());
if (status)
{
blockCnt = edid.getBlockCount();
// If read successfully, check if there are two or more blocks.
if (blockCnt != 1)
{
if (!buffer->resize(EDID_BLOCK_SIZE * blockCnt))
{
return false;
}
status = main->fetchEdidByRmCtrl(buffer->getData(), buffer->getLength());
}
}
if (!status)
{
//
// If fetchEdidByRmCtrl fails for some reasons:
// Try to read again using DPLib read function.
// One reason client to request read from RM is to making sure
// the EDID is overridden (regkey or others). So call the RM
// control call to apply the EDID overrides.
//
status = sstReadEdid(auxBus, edid, ddcAddrList[i], timer,
pendingTestRequestEdidRead);
if (status)
{
main->applyEdidOverrideByRmCtrl(buffer->getData(),
buffer->getLength());
}
else
{
DP_LOG(("EDID> Failed to read EDID from RM and DPLib"));
}
}
}
else
{
//
// If there is pending test request for edid read, make sure we get the raw bytes without check.
// Because cert devices may need to see the checksum of whatever is read for edid, even if they seem corrupted.
//
status = sstReadEdid(auxBus, edid, ddcAddrList[i], timer, pendingTestRequestEdidRead);
}
if (status)
{
if (edid.verifyCRC())
{
return true;
}
else
{
if (j == 0) // first failure?
{
previousEdid.swap(edid);
}
else
{
if (previousEdid == edid)
{
// we got the same invalid checksum again; we will assume it is valid.
edid.setForcedEdidChecksum(true);
return true;
}
}
}
}
}
}
DP_LOG(("EDID> Failed to ping sst DDC addresses"));
return false;
}

View File

@@ -0,0 +1,199 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2010-2021 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_timer.cpp *
* *
\***************************************************************************/
#include "dp_internal.h"
#include "dp_timer.h"
using namespace DisplayPort;
void Timer::expired()
{
fire(false);
}
// Take care, this function is re-entrant.
// Consider that sleep() is effectively a call to fire().
// Clients may sleep in response to a timer callback.
unsigned Timer::fire(bool fromSleep) // returns min time to next item to be fired
{
restart:
NvU64 now = getTimeUs();
NvU64 nearest = (NvU64)-1;
for (PendingCallback * i = (PendingCallback*)pending.begin(); i!=pending.end(); )
{
if (fromSleep && !i->executeInSleep) {
i = (PendingCallback*)i->next;
continue;
}
if (now >= i->timestamp)
{
const void * context = i->context;
TimerCallback * target = i->target;
delete i;
if (target)
target->expired(context); // Take care, the client may have made
// a recursive call to fire in here.
// Easy solution: Restart at front of list.
// current time may have also changed
// drastically from a nested sleep
goto restart;
}
else
{
if (i->timestamp < nearest)
nearest = i->timestamp;
i = (PendingCallback*)i->next;
}
}
unsigned minleft = (unsigned)((nearest - now + 999)/ 1000);
return minleft;
}
void Timer::_pump(unsigned milliseconds, bool fromSleep)
{
do
{
unsigned amt = fire(fromSleep);
if (amt >= milliseconds) {
raw->sleep(milliseconds);
return;
}
raw->sleep(amt);
milliseconds-=amt;
} while(milliseconds);
}
//
// Queue a timer callback.
// Unless the dont-execute-in-sleep flag is set
//
void Timer::queueCallback(Timer::TimerCallback * target, const void * context, unsigned milliseconds, bool executeInSleep)
{
NvU64 now = getTimeUs();
PendingCallback * callback = new PendingCallback();
if (callback == NULL)
{
DP_LOG(("DP> %s: Failed to allocate callback",
__FUNCTION__));
return;
}
callback->target = target;
callback->context = context;
callback->timestamp = now + milliseconds * 1000;
callback->executeInSleep = executeInSleep;
pending.insertBack(callback);
raw->queueCallback(this, milliseconds);
}
NvU64 Timer::getTimeUs()
{
return raw->getTimeUs();
}
// Sleep a number of milliseconds.
// timer callbacks will be serviced!
void Timer::sleep(unsigned milliseconds)
{
_pump(milliseconds, true);
}
void Timer::cancelCallbacks(Timer::TimerCallback * to)
{
if (!to)
return;
for (PendingCallback * i = (PendingCallback*)pending.begin(); i!=pending.end(); i = (PendingCallback *)i->next)
if (i->target == to)
i->target = 0;
}
void Timer::cancelCallback(Timer::TimerCallback * to, const void * context)
{
if (!to)
return;
for (PendingCallback * i = (PendingCallback *)pending.begin(); i!=pending.end(); i = (PendingCallback*)i->next)
if (i->target == to && i->context == context)
i->target = 0;
}
// Queue callbacks in order.
void Timer::queueCallbackInOrder(Timer::TimerCallback * target, const void * context, unsigned milliseconds, bool executeInSleep)
{
NvU64 now = getTimeUs();
PendingCallback * callback = new PendingCallback();
callback->target = target;
callback->context = context;
callback->timestamp = now + milliseconds * 1000;
callback->executeInSleep = executeInSleep;
//Figure out where to insert the current callback
Timer::PendingCallback* i;
for (i = (PendingCallback*)pending.begin(); i != pending.end();)
{
// only for the given context.
if(i->context == context)
{
if(i->timestamp > callback->timestamp)
break;
}
i = (PendingCallback*) i->next;
}
if (i == pending.end())
{
pending.insertBack(callback);
}
else
{
pending.insertBefore(i, callback);
}
raw->queueCallback(this, milliseconds);
}
void Timer::cancelAllCallbacks()
{
for (PendingCallback * i = (PendingCallback*)pending.begin(); i!=pending.end(); i = (PendingCallback *)i->next)
i->target = 0;
}
void Timer::cancelCallbacksWithoutContext(const void * context)
{
for (PendingCallback * i = (PendingCallback*)pending.begin(); i!=pending.end(); i = (PendingCallback *)i->next)
if(i->context != context)
i->target = 0;
}
bool Timer::checkCallbacksOfSameContext(const void * context)
{
for (PendingCallback * i = (PendingCallback*)pending.begin(); i!=pending.end(); i = (PendingCallback *)i->next)
if(i->context == context)
return true;
return false;
}

View File

@@ -0,0 +1,247 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_vrr.cpp *
* Implementation of VRR enablement *
* *
\***************************************************************************/
#include "dp_connectorimpl.h"
#include "dp_vrr.h"
using namespace DisplayPort;
bool VrrEnablement::start()
{
bool rc;
DP_LOG(("DPHAL_VRR_ENABLE> **** VRR Enablement Started ****"));
rc = vrrGetPublicInfo();
if(rc)
{
rc = vrrEnableMonitor();
if(rc != true)
{
return false;
}
rc = vrrEnableDriver();
if(rc != true)
{
return false;
}
}
else
{
return false;
}
DP_LOG(("DPHAL_VRR_ENABLE> **** VRR Enablement Ends ****"));
return true;
}
bool VrrEnablement::vrrGetPublicInfo()
{
MainLink *main = this->parent->connector->main;
if (main->vrrRunEnablementStage(VRR_ENABLE_STAGE_INIT_PUBLIC_INFO, NULL) != true)
{
return false;
}
if (main->vrrRunEnablementStage(VRR_ENABLE_STAGE_RESET_MONITOR, NULL) != true)
{
return false;
}
else
{
if (vrrWaitOnEnableStatus() != true)
{
return false;
}
}
if (main->vrrRunEnablementStage(VRR_ENABLE_STAGE_GET_PUBLIC_INFO, NULL) != true)
{
return false;
}
return vrrWaitOnEnableStatus();
}
bool VrrEnablement::vrrEnableMonitor()
{
MainLink *main = this->parent->connector->main;
DP_LOG(("DPHAL_VRR_ENABLE> ** VRR_MON_ENABLE starts **"));
// Always set the enable F/W state m/c to a known state.
if(main->vrrRunEnablementStage(VRR_ENABLE_STAGE_RESET_MONITOR, NULL) != true)
{
return false;
}
// Wait for VRR to be 'ready'.
if (vrrWaitOnEnableStatus() != true)
{
return false;
}
if(main->vrrRunEnablementStage(VRR_ENABLE_STAGE_MONITOR_ENABLE_BEGIN, NULL) != true)
{
return false;
}
// Wait for VRR to be 'ready'.
if (vrrWaitOnEnableStatus() != true)
{
return false;
}
main->vrrRunEnablementStage(VRR_ENABLE_STAGE_MONITOR_ENABLE_CHALLENGE, NULL);
// Wait for VRR to be ready.
if (vrrWaitOnEnableStatus() != true)
{
return false;
}
// Compare and enable on successful comparison.
if(main->vrrRunEnablementStage(VRR_ENABLE_STAGE_MONITOR_ENABLE_CHECK, NULL) == true)
{
this->bMonitorEnabled = true;
}
DP_LOG(("DPHAL_VRR_ENABLE> ** VRR_MON_ENABLE ends **"));
return this->bMonitorEnabled;
}
bool VrrEnablement::vrrEnableDriver()
{
NvU32 enableResult;
MainLink *main = this->parent->connector->main;
DP_LOG(("DPHAL_VRR_ENABLE> ** VRR_DRV_ENABLE starts **"));
// Always set the enable F/W state m/c to a known state.
if(main->vrrRunEnablementStage(VRR_ENABLE_STAGE_RESET_MONITOR, NULL) != true)
{
return false;
}
// Wait for VRR to be 'ready'.
if (vrrWaitOnEnableStatus() != true)
{
return false;
}
if (main->vrrRunEnablementStage(VRR_ENABLE_STAGE_DRIVER_ENABLE_BEGIN, &enableResult) != true)
{
return false;
}
if (enableResult == NV0073_CTRL_DP_CMD_ENABLE_VRR_STATUS_PENDING)
{
// Wait for VRR to be ready.
if (vrrWaitOnEnableStatus() != true)
{
return false;
}
}
else if (enableResult == NV0073_CTRL_DP_CMD_ENABLE_VRR_STATUS_OK)
{
return true;
}
if (main->vrrRunEnablementStage(VRR_ENABLE_STAGE_DRIVER_ENABLE_CHALLENGE, NULL) != true)
{
return false;
}
// Wait for VRR to be 'ready'.
if (vrrWaitOnEnableStatus() != true)
{
return false;
}
if (main->vrrRunEnablementStage(VRR_ENABLE_STAGE_DRIVER_ENABLE_CHECK, NULL) != true)
{
return false;
}
DP_LOG(("DPHAL_VRR_ENABLE> ** VRR_DRV_ENABLE ends **"));
return true;
}
bool VrrEnablement::vrrWaitOnEnableStatus(void)
{
NvU32 timeout = VRR_ENABLE_STATUS_TIMEOUT_THRESHOLD;
NvU32 enableResult;
MainLink *main = this->parent->connector->main;
ConnectorImpl *connector = this->parent->connector;
do
{
if (main->vrrRunEnablementStage(VRR_ENABLE_STAGE_STATUS_CHECK, &enableResult) == true)
{
return true;
}
else
{
if (enableResult == NV0073_CTRL_DP_CMD_ENABLE_VRR_STATUS_READ_ERROR)
{
return false;
}
else if (enableResult == NV0073_CTRL_DP_CMD_ENABLE_VRR_STATUS_PENDING)
{
Timeout timeout(connector->timer, VRR_ENABLE_STATUS_TIMEOUT_INTERVAL_MS);
while(timeout.valid());
continue;
}
else
{
return false;
}
}
}while(--timeout);
return false;
}
bool VrrEnablement::isMonitorEnabled(void)
{
return (this->bMonitorEnabled);
}
bool VrrEnablement::isDriverEnabled(void)
{
NvU32 enableResult;
MainLink *main = this->parent->connector->main;
if (main->vrrRunEnablementStage(VRR_ENABLE_STAGE_DRIVER_ENABLE_CHECK,
&enableResult) == true)
{
return true;
}
return false;
}

View File

@@ -0,0 +1,645 @@
/*
* 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
* 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"
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] == '\"')))
{
//
// Extended latency from link-train end to FEC enable pattern
// to avoid link lost or blank screen with Synaptics branch.
// (Bug 2561206)
//
// Dock SKU ID:
// Dell Salomon-WD19TB SYNAS1
// HP Hook SYNAS3
// HP Adira-A SYNAS#
// Lenovo SYNAS" / SYNAS2
//
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 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_LOG(("DP-WAR> WAR for Apple thunderbolt J29 panel"));
DP_LOG(("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_LOG(("DP-WAR> Edid override on Acer AL1512"));
DP_LOG(("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_LOG(("DP-WAR> Edid overrid on Westinghouse AL1512 LVM- <37/42> w <2/3>"));
DP_LOG(("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_LOG(("DP-WAR> Edid overrid on IBM T210"));
DP_LOG(("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_LOG(("DP-WAR> Edid overrid on GWY/EMA"));
DP_LOG(("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_LOG(("DP-WAR> Edid overrid on INX L15CX"));
DP_LOG(("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_LOG(("DP-WAR> Edid overrid on AUO eDP panel"));
DP_LOG(("DP-WAR> Modifying HBlank and HSync pulse width."));
DP_LOG(("DP-WAR> Bugs 907998, 1001160"));
}
else if (ProductID == 0x109B || ProductID == 0x119B)
{
this->WARFlags.useLegacyAddress = true;
DP_LOG(("DP-WAR> AUO eDP"));
DP_LOG(("implements only Legacy interrupt address range"));
// Bug 1792962 - Panel got glitch on D3 write, apply this WAR.
this->WARFlags.disableDpcdPowerOff = true;
DP_LOG(("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_LOG(("DP-WAR> Edid overrid on Quanta - Toshiba LG 1440x900"));
DP_LOG(("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_LOG(("DP-WAR> Edid overrid on MSI - LG LPL 1280x800"));
DP_LOG(("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_LOG(("DP-WAR> Edid overrid on Haier TV."));
DP_LOG(("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_LOG(("DP-WAR> Disable DPCD Power Off"));
DP_LOG(("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_LOG(("DP-WAR> HP Valor QHD+ N15P-Q3 Sharp EDP needs 50 ms after D3"));
DP_LOG(("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_LOG(("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_LOG(("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_LOG(("DP-WAR> EIZO FlexScan SX2762W generates redundant"));
DP_LOG(("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_LOG(("DP-WAR> MEI-Panasonic EDP"));
DP_LOG(("implements only Legacy interrupt address range"));
}
}
break;
// LG
case 0xE430:
if (ProductID == 0x0469)
{
//
// The LG display can't be driven at FHD with 2*RBR.
// Force max link config
//
this->WARFlags.forceMaxLinkConfig = true;
DP_LOG(("DP-WAR> Force maximum link config WAR required on LG panel."));
DP_LOG(("DP-WAR> bug 1649626"));
break;
}
break;
case 0x8F34:
if (ProductID == 0xAA55)
{
this->WARFlags.forceMaxLinkConfig = true;
DP_LOG(("DP-WAR> Force maximum link config WAR required on Sharp-CerebrEx panel."));
}
break;
// Dell
case 0xAC10:
// Dell U2713H has problem with LQA. Disable it.
if ((ProductID == 0xA092) || (ProductID == 0xF046))
{
this->WARFlags.reassessMaxLink = true;
}
break;
// CMN
case 0xAE0D:
if (ProductID == 0x1747)
{
this->WARFlags.useLegacyAddress = true;
DP_LOG(("DP-WAR> CMN eDP"));
DP_LOG(("implements only Legacy interrupt address range"));
}
break;
// BenQ
case 0xD109:
if ((ProductID == 0x7F2B) || (ProductID == 0x7F2F))
{
this->WARFlags.ignoreRedundantHotplug = true;
DP_LOG(("DP-WAR> BenQ GSync power on/off redundant hotplug"));
}
break;
// MSI
case 0x834C:
if (ProductID == 0x4C48)
{
this->WARFlags.useLegacyAddress = true;
DP_LOG(("DP-WAR> MSI eDP\n"));
DP_LOG(("implements only Legacy interrupt address range\n"));
}
break;
// Unigraf
case 0xC754:
case 0x1863:
{
DP_LOG(("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_LOG(("DP-WAR> BOE panels incorrectly exposing DSC capability. Ignoring it."));
}
break;
// NCP
case 0x7038:
if ((ProductID == 0x005F))
{
this->WARFlags.bIgnoreDscCap = true;
DP_LOG(("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_LOG(("DP-WAR> Ignoring DSC capability on Lenovo CSOT 1609 Panel."));
DP_LOG(("DP-WAR> Bug 3444252"));
}
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_LOG(("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_LOG(("DP-WAR> Overriding optimal link config on Dell U2410."));
DP_LOG(("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_LOG(("DP-WAR> Overriding max lane count on Lenovo L2440x."));
DP_LOG(("DP-WAR> bug 687952"));
}
}
if (this->WARFlags.dataForced)
{
DP_LOG(("DP-WAR> EDID was overridden for some data. Patching CRC."));
this->patchCrc();
}
}

View File

@@ -0,0 +1,872 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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_watermark.cpp *
* DP watermark IsModePossible calculations *
* *
\***************************************************************************/
#include "dp_internal.h"
#include "dp_watermark.h"
#include "dp_linkconfig.h"
#include "displayport.h"
#define FEC_TOTAL_SYMBOLS_PER_BLK(lanes) ((NvU32)((lanes == 1) ? 512U : 256U))
#define FEC_PARITY_SYMBOLS_PER_BLK(lanes) ((NvU32)((lanes == 1) ? 12U : 6U))
//return max number of FEC parity symbols in x link clock cycles
#define FEC_PARITY_SYM_SST(lanes, x) (DP_MIN((NvU32)(x) % FEC_TOTAL_SYMBOLS_PER_BLK(lanes), FEC_PARITY_SYMBOLS_PER_BLK(lanes)) + (NvU32)(x) / FEC_TOTAL_SYMBOLS_PER_BLK(lanes) * FEC_PARITY_SYMBOLS_PER_BLK(lanes) + FEC_PARITY_SYMBOLS_PER_BLK(lanes) + 1U)
#define FEC_PARITY_SYM_MST(lanes, x) (DP_MIN((NvU32)(x) % FEC_TOTAL_SYMBOLS_PER_BLK(lanes), FEC_PARITY_SYMBOLS_PER_BLK(lanes)) + (NvU32)(x) / FEC_TOTAL_SYMBOLS_PER_BLK(lanes) * FEC_PARITY_SYMBOLS_PER_BLK(lanes) + 1U)
bool DisplayPort::isModePossibleMST
(
const LinkConfiguration & linkConfig,
const ModesetInfo & modesetInfo,
Watermark * dpInfo
)
{
//
// For MST, use downspread 0.6%
//
NvU64 linkFreq = linkConfig.peakRate * 994 / 1000;
//
// This function is for multistream only!
//
DP_ASSERT( linkConfig.multistream );
if(!modesetInfo.pixelClockHz || !modesetInfo.depth)
{
DP_ASSERT(0 && "INVALID PIXEL CLOCK and DEPTH sent by the client ");
return false;
}
// depth is multiplied by 16 in case of DSC enable
unsigned DSC_FACTOR = modesetInfo.bEnableDsc ? 16 : 1;
// Extra bits that we need to send
//(hActiveDiv4Remainder > 0 ? (4- hActiveDiv4Remainder) : 0) -->
// Number of extra pixels that we need to insert due to mapping pixels
// to the DP lanes. (4 lanes for MS)
//
// 160 --> Extra bits that we need to send during horizontal blanking
// (BS+VBID+MVID+MAUD+BE) => 5*8*num_lanes
//
// 6 * 4 --> Pixel padding worst case
//
NvU32 minHBlank = ( ((modesetInfo.surfaceWidth % 4) > 0) ? ((4-(modesetInfo.surfaceWidth % 4)) * modesetInfo.depth)/ DSC_FACTOR : 0 ) + (160 + 6 * 4);
// Rounding to nearest multiple of 32 since we always send 32 bits in one time slice
minHBlank = minHBlank + (32 - minHBlank % 32);
// bpp - 1 --> Rounding
minHBlank = ((minHBlank * DSC_FACTOR) + modesetInfo.depth - (1 * DSC_FACTOR))/modesetInfo.depth;
if (minHBlank > modesetInfo.rasterWidth - modesetInfo.surfaceWidth)
{
DP_LOG(("NVRM: %s:", __FUNCTION__));
DP_LOG(("\t\tERROR: Blanking Width is smaller than minimum permissible value."));
return false;
}
// Bug 702290 - Active Width should be greater than 60
if (modesetInfo.surfaceWidth <= 60)
{
DP_LOG(("NVRM: %s:", __FUNCTION__));
DP_LOG(("\t\tERROR: Minimum Horizontal Active Width <= 60 not supported."));
return false;
}
NvS32 vblank_symbols;
NvS32 hblank_symbols = (NvS32)(((NvU64)(modesetInfo.rasterWidth - modesetInfo.surfaceWidth - minHBlank) * linkFreq) / modesetInfo.pixelClockHz);
//reduce HBlank Symbols to account for secondary data packet
hblank_symbols -= 1; //Stuffer latency to send BS
hblank_symbols -= 3; //SPKT latency to send data to stuffer
hblank_symbols -= linkConfig.lanes == 1 ? 9 : linkConfig.lanes == 2 ? 6 : 3;
dpInfo->hBlankSym = (hblank_symbols < 0) ? 0 : hblank_symbols;
//
// Audio IMP calculations
// Perform the related audio calculation to determine the number of extra symbols needed.
//
NvU32 twoChannelAudio_symbols = 0;
if (modesetInfo.twoChannelAudioHz != 0)
{
// 1-2 channel case
NvU32 samples = (NvU32)divide_ceil(modesetInfo.twoChannelAudioHz * modesetInfo.rasterWidth, modesetInfo.pixelClockHz);
// Round to the next even sample to account for stuffing (2 ch, 4 lanes)
samples = samples + (2 - samples % 2);
// Convert sample count to symbols
twoChannelAudio_symbols = 10 * samples + 16;
}
NvU32 eightChannelAudio_symbols = 0;
if (modesetInfo.eightChannelAudioHz != 0)
{
// 3-8 channel case
NvU32 samples = (NvU32)divide_ceil(modesetInfo.eightChannelAudioHz * modesetInfo.rasterWidth, modesetInfo.pixelClockHz);
// Convert sample count to symbols
eightChannelAudio_symbols = 40 * samples + 16;
}
if (dpInfo->hBlankSym < DP_MAX(twoChannelAudio_symbols, eightChannelAudio_symbols))
{
return false;
}
// Refer to dev_disp.ref for more information.
// # symbols/vblank = ((SetRasterBlankEnd.X + SetRasterSize.Width - SetRasterBlankStart.X - 40) * link_clk / pclk) - Y - 1;
// where Y = (# lanes == 4) 12 : (# lanes == 2) ? 21 : 39
if (modesetInfo.surfaceWidth < 40)
{
vblank_symbols = 0;
}
else
{
vblank_symbols = (NvS32)(((NvU64)(modesetInfo.surfaceWidth - 40) * linkFreq) / modesetInfo.pixelClockHz) - 1;
vblank_symbols -= linkConfig.lanes == 1 ? 39 : linkConfig.lanes == 2 ? 21 : 12;
}
dpInfo->vBlankSym = (vblank_symbols < 0) ? 0 : vblank_symbols;
return true;
}
bool DisplayPort::isModePossibleSST
(
const LinkConfiguration & linkConfig,
const ModesetInfo & modesetInfo,
Watermark * dpInfo,
bool bUseIncreasedWatermarkLimits
)
{
//
// This function is for single stream only!
//
DP_ASSERT( !linkConfig.multistream );
unsigned watermarkAdjust = DP_CONFIG_WATERMARK_ADJUST;
unsigned watermarkMinimum = DP_CONFIG_WATERMARK_LIMIT;
// depth is multiplied by 16 in case of DSC enable
unsigned DSC_FACTOR = modesetInfo.bEnableDsc ? 16 : 1;
if(bUseIncreasedWatermarkLimits)
{
watermarkAdjust = DP_CONFIG_INCREASED_WATERMARK_ADJUST;
watermarkMinimum = DP_CONFIG_INCREASED_WATERMARK_LIMIT;
}
if(!modesetInfo.pixelClockHz || !modesetInfo.depth)
{
DP_ASSERT(0 && "INVALID PIXEL CLOCK or DEPTH sent by the client ");
return false;
}
// number of link clocks per line.
int vblank_symbols = 0;
NvU64 PrecisionFactor, ratioF, watermarkF;
NvU32 numLanesPerLink = linkConfig.lanes;
DP_ASSERT(!linkConfig.multistream && "MST!");
// Check if we have a valid laneCount as currently we support only up to 4-lanes
if (!IS_VALID_LANECOUNT(linkConfig.lanes))
{
//
// Print debug message and Assert. All calculations assume a max of 8 lanes
// & any increase in lanes should cause these calculation to be updated
//
DP_LOG(("NVRM: %s: ERROR: LaneCount - %d is not supported for waterMark calculations.",
__FUNCTION__, linkConfig.lanes));
DP_LOG(("Current support is only up to 4-Lanes & any change/increase in supported lanes "
"should be reflected in waterMark calculations algorithm. "
"Ex: See calc for minHBlank variable below"));
DP_ASSERT(0);
return false;
}
if ((modesetInfo.pixelClockHz * modesetInfo.depth) >= (8 * linkConfig.minRate * linkConfig.lanes * DSC_FACTOR))
{
return false;
}
//
// For DSC, if (pclk * bpp) < (1/64 * orclk * 8 * lanes) then some TU may end up with
// 0 active symbols. This may cause HW hang. Bug 200379426
//
if ((modesetInfo.bEnableDsc) &&
((modesetInfo.pixelClockHz * modesetInfo.depth) < ((8 * linkConfig.minRate * linkConfig.lanes * DSC_FACTOR) / 64)))
{
return false;
}
//
// Perform the SST calculation.
// For auto mode the watermark calculation does not need to track accumulated error the
// formulas for manual mode will not work. So below calculation was extracted from the DTB.
//
dpInfo->tuSize = 64;
PrecisionFactor = 100000;
ratioF = ((NvU64)modesetInfo.pixelClockHz * modesetInfo.depth * PrecisionFactor) / DSC_FACTOR;
ratioF /= 8 * (NvU64) linkConfig.minRate * linkConfig.lanes;
if (PrecisionFactor < ratioF) // Assert if we will end up with a negative number in below
return false;
watermarkF = ratioF * dpInfo->tuSize * (PrecisionFactor - ratioF) / PrecisionFactor;
dpInfo->waterMark = (unsigned)(watermarkAdjust + ((2 * (modesetInfo.depth * PrecisionFactor / (8 * numLanesPerLink * DSC_FACTOR)) + watermarkF) / PrecisionFactor));
//
// Bounds check the watermark
//
NvU32 numSymbolsPerLine = (modesetInfo.surfaceWidth * modesetInfo.depth) / (8 * linkConfig.lanes * DSC_FACTOR);
if (dpInfo->waterMark > 39 || dpInfo->waterMark > numSymbolsPerLine)
{
DP_LOG(("NVRM: %s:", __FUNCTION__));
DP_LOG(("\t\tERROR: watermark should not be greater than 39."));
return false;
}
//
// Clamp the low side
//
if (dpInfo->waterMark < watermarkMinimum)
dpInfo->waterMark = watermarkMinimum;
//Bits to send BS/BE/Extra symbols due to pixel padding
//Also accounts for enhanced framing.
NvU32 BlankingBits = 3*8*numLanesPerLink + (linkConfig.enhancedFraming ? 3*8*numLanesPerLink : 0);
//VBID/MVID/MAUD sent 4 times all the time
BlankingBits += 3*8*4;
NvU32 surfaceWidthPerLink = modesetInfo.surfaceWidth;
//Extra bits sent due to pixel steering
NvU32 PixelSteeringBits = (surfaceWidthPerLink % numLanesPerLink) ? (((numLanesPerLink - surfaceWidthPerLink % numLanesPerLink) * modesetInfo.depth) / DSC_FACTOR) : 0;
BlankingBits += PixelSteeringBits;
NvU64 NumBlankingLinkClocks = (NvU64)BlankingBits * PrecisionFactor / (8 * numLanesPerLink);
NvU32 MinHBlank = (NvU32)(NumBlankingLinkClocks * modesetInfo.pixelClockHz/ linkConfig.minRate / PrecisionFactor);
MinHBlank += 12;
if (MinHBlank > modesetInfo.rasterWidth - modesetInfo.surfaceWidth)
{
DP_LOG(("NVRM: %s:", __FUNCTION__));
DP_LOG(("\t\tERROR: Blanking Width is smaller than minimum permissible value."));
return false;
}
// Bug 702290 - Active Width should be greater than 60
if (modesetInfo.surfaceWidth <= 60)
{
DP_LOG(("NVRM: %s:", __FUNCTION__));
DP_LOG(("\t\tERROR: Minimum Horizontal Active Width <= 60 not supported."));
return false;
}
NvS32 hblank_symbols = (NvS32)(((NvU64)(modesetInfo.rasterWidth - modesetInfo.surfaceWidth - MinHBlank) * linkConfig.minRate) / modesetInfo.pixelClockHz);
//reduce HBlank Symbols to account for secondary data packet
hblank_symbols -= 1; //Stuffer latency to send BS
hblank_symbols -= 3; //SPKT latency to send data to stuffer
hblank_symbols -= numLanesPerLink == 1 ? 9 : numLanesPerLink == 2 ? 6 : 3;
dpInfo->hBlankSym = (hblank_symbols < 0) ? 0 : hblank_symbols;
//
// Audio IMP calculations
//
// From dev_disp.ref:
// The packet generation logic needs to know the length of the hblank period. If there is no room
// in the current hblank for a new packet, it will be delayed until the next blanking period. This
// field should be programmed during the second Supervisor interrupt based on the new raster
// dimensions.
// ...
// --------------------------------------
// The following formulas can be used to calculate the maximum audio sampling rate that can
// be supported by DisplayPort given the current raster dimensions. DisplayPort has much more
// bandwidth during blanking periods than HDMI has, so hblank size is less of an issue.
// ...
// Size of a packet for 2ch audio = 20 symbols (up to 2 samples)
// Size of a packet for 8ch audio = 40 symbols
// Size of an audio packet header plus control symbols = 2*#lanes + 8 symbols (assuming < 32 samples per line)
// number of packets/hblank for 2ch audio = Floor ((number of free symbols/hblank - (2*#lanes + 8) / 20)
// number of packets/hblank for 8ch audio = Floor ((number of free symbols/hblank - (2*#lanes + 8) / 40)
// Maximum audio sample rate possible:
// number of audio samples/line = SetRasterSize.Width * audio_fs / pclk
// number of audio packets needed for 2ch audio = Ceiling(SetRasterSize.Width * audio_fs / (pclk*2))
// number of audio packets needed for 3-8ch audio = SetRasterSize.Width * audio_fs / pclk
// If number of audio packets needed > number of packets/hblank, then you cannot support that audio frequency
// Note that the hBlankSym calculated is per lane. So the number of symbols available for audio is
// (number of lanes * hBlankSym).
// The calculation of audio packets per Hblank needs to account for the following -
// 2 symbols for SS and SE; 8 symbols for header; and additional 2 symbols to account for actual values used by HW.
// --------------------------------------
if (modesetInfo.twoChannelAudioHz != 0)
{
if ((dpInfo->hBlankSym * numLanesPerLink) < (2 * numLanesPerLink + 8))
{
// There aren't enough symbols/hblank available.
return false;
}
NvU32 twoChannelAudioPacketsPerHBlank = (NvU32)divide_floor(((dpInfo->hBlankSym * numLanesPerLink) - (2 * numLanesPerLink) - 8 - (2 * numLanesPerLink)), 20);
NvU32 twoChannelAudioPackets = (NvU32)divide_ceil(modesetInfo.twoChannelAudioHz * modesetInfo.rasterWidth, modesetInfo.pixelClockHz * 2);
if (twoChannelAudioPackets > twoChannelAudioPacketsPerHBlank)
{
// There aren't enough packets/hblank available.
return false;
}
}
if (modesetInfo.eightChannelAudioHz != 0)
{
if ((dpInfo->hBlankSym * numLanesPerLink) < (2 * numLanesPerLink + 8))
{
// There aren't enough symbols/hblank available.
return false;
}
NvU32 eightChannelAudioPacketsPerHBlank = (NvU32)divide_floor(((dpInfo->hBlankSym * numLanesPerLink) - (2 * numLanesPerLink) - 8 - (2 * numLanesPerLink)), 40);
NvU32 eightChannelAudioPackets = (NvU32)divide_ceil(modesetInfo.eightChannelAudioHz * modesetInfo.rasterWidth, modesetInfo.pixelClockHz);
if (eightChannelAudioPackets > eightChannelAudioPacketsPerHBlank)
{
// There aren't enough packets/hblank available.
return false;
}
}
// Refer to dev_disp.ref for more information.
// # symbols/vblank = ((SetRasterBlankEnd.X + SetRasterSize.Width - SetRasterBlankStart.X - 40) * link_clk / pclk) - Y - 1;
// where Y = (# lanes == 4) 12 : (# lanes == 2) ? 21 : 39
if (modesetInfo.surfaceWidth < 40)
{
vblank_symbols = 0;
}
else
{
vblank_symbols = (NvS32)(((NvU64)(modesetInfo.surfaceWidth - 40) * linkConfig.minRate) / modesetInfo.pixelClockHz) - 1;
vblank_symbols -= numLanesPerLink == 1 ? 39 : numLanesPerLink == 2 ? 21 : 12;
}
dpInfo->vBlankSym = (vblank_symbols < 0) ? 0 : vblank_symbols;
return true;
}
bool DisplayPort::isModePossibleSSTWithFEC
(
const LinkConfiguration & linkConfig,
const ModesetInfo & modesetInfo,
Watermark * dpInfo,
bool bUseIncreasedWatermarkLimits
)
{
//
// This function is for single stream only!
// Refer to Bug 200406501 and 200401850 for algorithm
//
DP_ASSERT( !linkConfig.multistream );
unsigned watermarkAdjust = DP_CONFIG_WATERMARK_ADJUST;
unsigned watermarkMinimum = DP_CONFIG_WATERMARK_LIMIT;
// depth is multiplied by 16 in case of DSC enable
unsigned DSC_FACTOR = modesetInfo.bEnableDsc ? 16 : 1;
if(bUseIncreasedWatermarkLimits)
{
watermarkAdjust = DP_CONFIG_INCREASED_WATERMARK_ADJUST;
watermarkMinimum = DP_CONFIG_INCREASED_WATERMARK_LIMIT;
}
if(!modesetInfo.pixelClockHz || !modesetInfo.depth)
{
DP_ASSERT(0 && "INVALID PIXEL CLOCK or DEPTH sent by the client ");
return false;
}
// number of link clocks per line.
int vblank_symbols = 0;
NvU64 PrecisionFactor, ratioF, watermarkF;
NvS32 w0, s;
NvU32 numLanesPerLink = linkConfig.lanes;
DP_ASSERT(!linkConfig.multistream && "MST!");
// Check if we have a valid laneCount as currently we support only up to 4-lanes
if (!IS_VALID_LANECOUNT(linkConfig.lanes))
{
//
// Print debug message and Assert. All calculations assume a max of 8 lanes
// & any increase in lanes should cause these calculation to be updated
//
DP_LOG(("NVRM: %s: ERROR: LaneCount - %d is not supported for waterMark calculations.",
__FUNCTION__, linkConfig.lanes));
DP_LOG(("Current support is only up to 4-Lanes & any change/increase in supported lanes "
"should be reflected in waterMark calculations algorithm. "
"Ex: See calc for minHBlank variable below"));
DP_ASSERT(0);
return false;
}
if ((modesetInfo.pixelClockHz * modesetInfo.depth) >= (8 * linkConfig.minRate * linkConfig.lanes * DSC_FACTOR))
{
return false;
}
//
// For DSC, if (pclk * bpp) < (1/64 * orclk * 8 * lanes) then some TU may end up with
// 0 active symbols. This may cause HW hang. Bug 200379426
//
if ((modesetInfo.bEnableDsc) &&
((modesetInfo.pixelClockHz * modesetInfo.depth) < ((8 * linkConfig.minRate * linkConfig.lanes * DSC_FACTOR) / 64)))
{
return false;
}
//
// Perform the SST calculation.
// For auto mode the watermark calculation does not need to track accumulated error the
// formulas for manual mode will not work. So below calculation was extracted from the DTB.
//
dpInfo->tuSize = 64;
PrecisionFactor = 100000;
ratioF = ((NvU64)modesetInfo.pixelClockHz * modesetInfo.depth * PrecisionFactor) / DSC_FACTOR;
ratioF /= 8 * (NvU64)linkConfig.minRate * linkConfig.lanes;
if (PrecisionFactor < ratioF) // Assert if we will end up with a negative number in below
return false;
watermarkF = (ratioF * dpInfo->tuSize * (PrecisionFactor - ratioF)) / PrecisionFactor;
w0 = (8 / linkConfig.lanes);
if (linkConfig.bEnableFEC)
{
s = (linkConfig.lanes == 1) ? 15 : 10;
}
else
{
s = 3 - w0;
}
dpInfo->waterMark = (unsigned)(watermarkAdjust + ((3 * (modesetInfo.depth * PrecisionFactor / (8 * numLanesPerLink * DSC_FACTOR)) + watermarkF) / PrecisionFactor) + w0 + 3);
s = ((NvS32)ratioF * s);
dpInfo->waterMark = (unsigned)((NvS32)dpInfo->waterMark + (s / (NvS32)PrecisionFactor));
//
// Bounds check the watermark
//
NvU32 numSymbolsPerLine = (modesetInfo.surfaceWidth * modesetInfo.depth) / (8 * linkConfig.lanes * DSC_FACTOR);
if (dpInfo->waterMark > numSymbolsPerLine)
{
DP_LOG(("NVRM: %s:", __FUNCTION__));
DP_LOG(("\t\tERROR: watermark = %d should not be greater than numSymbolsPerLine = %d.", dpInfo->waterMark, numSymbolsPerLine));
return false;
}
//
// Clamp the low side
//
if (dpInfo->waterMark < watermarkMinimum)
dpInfo->waterMark = watermarkMinimum;
unsigned MinHBlank = 0;
unsigned MinHBlankFEC = 0;
NvU32 BlankingBits = 0;
NvU32 BlankingSymbolsPerLane = 0;
BlankingBits = (3U * 8U * 4U) + (2U * 8U * numLanesPerLink);
if (modesetInfo.bEnableDsc)
{
NvU32 sliceCount, sliceWidth, chunkSize;
sliceCount = (modesetInfo.mode == DSC_DUAL) ? 8U : 4U;
sliceWidth = (NvU32)divide_ceil(modesetInfo.surfaceWidth, sliceCount);
chunkSize = (NvU32)divide_ceil(modesetInfo.depth * sliceWidth, 8U * DSC_FACTOR);
if(((NvU64)(chunkSize + 1U) * sliceCount * modesetInfo.pixelClockHz) < (NvU64)(linkConfig.minRate * numLanesPerLink * modesetInfo.surfaceWidth))
{
// BW is plenty, this is common case.
//EOC symbols, when BW enough, only last EOC needs to be considered.
BlankingBits += 8U * numLanesPerLink; //+BlankingBits_DSC_EOC
BlankingBits += (chunkSize * 8U) - (sliceWidth * modesetInfo.depth / DSC_FACTOR); //+BlankingBits_DSC_bytePadding, only need to consider last slice
BlankingBits += (NvU32)(sliceCount * 8U * (divide_ceil(chunkSize, numLanesPerLink) * numLanesPerLink - chunkSize)); //+BlankingBits_DSC_lane_padding
}
else
{ // no extra room in link BW
//EOC symbols, EOC will be accumulated until hblank period.
BlankingBits += (sliceCount * 8U * numLanesPerLink); //+BlankingBits_EOC
//padding, can also use simplified but pessimistic version : BlankingBits += SliceNum * (logic_lanes *8-1);
BlankingBits += (NvU32)(sliceCount * ((divide_ceil(chunkSize, numLanesPerLink) * numLanesPerLink * 8U) - (NvU32)(sliceWidth * modesetInfo.depth / DSC_FACTOR))); //+BlankingBits_DSC_padding
}
}
else
{
NvU32 surfaceWidthPerLink = modesetInfo.surfaceWidth;
NvU32 surfaceWidthPerLane = (NvU32)divide_ceil(surfaceWidthPerLink, numLanesPerLink);
// Padding
BlankingBits += (NvU32)divide_ceil(surfaceWidthPerLane * modesetInfo.depth, 8U) * 8U * numLanesPerLink - (NvU32)(surfaceWidthPerLink * modesetInfo.depth); //+BlankingBits_nonDSC_padding
}
BlankingSymbolsPerLane = (NvU32)divide_ceil(BlankingBits , (8U * numLanesPerLink)); //in symbols per lane
BlankingSymbolsPerLane += (linkConfig.enhancedFraming ? 3U : 0U);
if (linkConfig.bEnableFEC)
{
//
// In worst case, FEC symbols fall into a narrow Hblank period,
// we have to consider this in HBlank checker, see bug 200496977
// but we don't have to consider this in the calculation of hblank_symbols
//
MinHBlankFEC = FEC_PARITY_SYM_SST(numLanesPerLink, BlankingSymbolsPerLane); //in symbols
BlankingSymbolsPerLane += MinHBlankFEC;
}
// BlankingSymbolsPerLane is the MinHBlank in link clock cycles,
MinHBlank = (unsigned)(divide_ceil(BlankingSymbolsPerLane * modesetInfo.pixelClockHz,
linkConfig.peakRate)); //in pclk cycles
MinHBlank += 3U; //add some margin
NvU32 HBlank = (modesetInfo.rasterWidth - modesetInfo.surfaceWidth);
if (MinHBlank > HBlank)
{
DP_LOG(("NVRM: %s:", __FUNCTION__));
DP_LOG(("\t\tERROR: Blanking Width is smaller than minimum permissible value."));
return false;
}
// Bug 702290 - Active Width should be greater than 60
if (modesetInfo.surfaceWidth <= 60)
{
DP_LOG(("NVRM: %s:", __FUNCTION__));
DP_LOG(("\t\tERROR: Minimum Horizontal Active Width <= 60 not supported."));
return false;
}
NvU32 total_hblank_symbols = (NvS32)divide_ceil((HBlank * linkConfig.peakRate), modesetInfo.pixelClockHz);
NvS32 hblank_symbols = (NvS32)(((NvU64)(HBlank - MinHBlank) * linkConfig.peakRate) / modesetInfo.pixelClockHz);
if (linkConfig.bEnableFEC)
{
hblank_symbols -= (FEC_PARITY_SYM_SST(numLanesPerLink, total_hblank_symbols));
hblank_symbols += MinHBlankFEC;
}
//reduce HBlank Symbols to account for secondary data packet
hblank_symbols -= 1; //Stuffer latency to send BS
hblank_symbols -= 3; //SPKT latency to send data to stuffer
hblank_symbols -= 3; //add some margin
dpInfo->hBlankSym = (hblank_symbols < 0) ? 0 : hblank_symbols;
//
// Audio IMP calculations
//
// From dev_disp.ref:
// The packet generation logic needs to know the length of the hblank period. If there is no room
// in the current hblank for a new packet, it will be delayed until the next blanking period. This
// field should be programmed during the second Supervisor interrupt based on the new raster
// dimensions.
// ...
// --------------------------------------
// The following formulas can be used to calculate the maximum audio sampling rate that can
// be supported by DisplayPort given the current raster dimensions. DisplayPort has much more
// bandwidth during blanking periods than HDMI has, so hblank size is less of an issue.
// ...
// Size of a packet for 2ch audio = 20 symbols (up to 2 samples)
// Size of a packet for 8ch audio = 40 symbols
// Size of an audio packet header plus control symbols = 2*#lanes + 8 symbols (assuming < 32 samples per line)
// number of packets/hblank for 2ch audio = Floor ((number of free symbols/hblank - (2*#lanes + 8) / 20)
// number of packets/hblank for 8ch audio = Floor ((number of free symbols/hblank - (2*#lanes + 8) / 40)
// Maximum audio sample rate possible:
// number of audio samples/line = SetRasterSize.Width * audio_fs / pclk
// number of audio packets needed for 2ch audio = Ceiling(SetRasterSize.Width * audio_fs / (pclk*2))
// number of audio packets needed for 3-8ch audio = SetRasterSize.Width * audio_fs / pclk
// If number of audio packets needed > number of packets/hblank, then you cannot support that audio frequency
// Note that the hBlankSym calculated is per lane. So the number of symbols available for audio is
// (number of lanes * hBlankSym).
// The calculation of audio packets per Hblank needs to account for the following -
// 2 symbols for SS and SE; 8 symbols for header; and additional 2 symbols to account for actual values used by HW.
// --------------------------------------
if (modesetInfo.twoChannelAudioHz != 0)
{
if ((dpInfo->hBlankSym * numLanesPerLink) < ((2 * numLanesPerLink) + 8))
{
// There aren't enough symbols/hblank available.
return false;
}
NvU32 twoChannelAudioPacketsPerHBlank = (NvU32)divide_floor(((dpInfo->hBlankSym * numLanesPerLink) - (2 * numLanesPerLink) - 8 - (2 * numLanesPerLink)), 20);
NvU32 twoChannelAudioPackets = (NvU32)divide_ceil(modesetInfo.twoChannelAudioHz * modesetInfo.rasterWidth, modesetInfo.pixelClockHz * 2);
if (twoChannelAudioPackets > twoChannelAudioPacketsPerHBlank)
{
// There aren't enough packets/hblank available.
return false;
}
}
if (modesetInfo.eightChannelAudioHz != 0)
{
if ((dpInfo->hBlankSym * numLanesPerLink) < (2 * numLanesPerLink + 8))
{
// There aren't enough symbols/hblank available.
return false;
}
NvU32 eightChannelAudioPacketsPerHBlank = (NvU32)divide_floor(((dpInfo->hBlankSym * numLanesPerLink) - (2 * numLanesPerLink) - 8 - (2 * numLanesPerLink)), 40);
NvU32 eightChannelAudioPackets = (NvU32)divide_ceil(modesetInfo.eightChannelAudioHz * modesetInfo.rasterWidth, modesetInfo.pixelClockHz);
if (eightChannelAudioPackets > eightChannelAudioPacketsPerHBlank)
{
// There aren't enough packets/hblank available.
return false;
}
}
// Refer to dev_disp.ref for more information.
// # symbols/vblank = ((SetRasterBlankEnd.X + SetRasterSize.Width - SetRasterBlankStart.X - 40) * link_clk / pclk) - Y - 1;
// where Y = (# lanes == 4) 12 : (# lanes == 2) ? 21 : 39
if (modesetInfo.surfaceWidth < 40)
{
vblank_symbols = 0;
}
else
{
vblank_symbols = (NvS32)(((NvU64)(modesetInfo.surfaceWidth - 3) * linkConfig.peakRate) / modesetInfo.pixelClockHz);
//
// The active region transmission is delayed because of lane fifo storage.
// compare to the negedge of hblank, all the BE will be delayed by watermark/ratio cycles.
// compare to the posedge of hblank(i.e. the time of sending out BS symbols in vblank period),
// all the BS after active pixels will be delayed by maximum 1.5 TU cycles,
// the delay of the BS will cause the 1st vblank line shorter than expected,
// but it will squeeze hblank period first,
// if hblank is short, the BS will be in hactive period and impact vblank_symbols.
//
NvS32 squeezed_symbols = (dpInfo->tuSize * 3 / 2) - hblank_symbols;
squeezed_symbols = DP_MAX(squeezed_symbols, 0);
NvS32 msa_symbols = (36 / numLanesPerLink) + 3;
//
// MSA can't be in the 1st vblank line, except v_front_porch=0
// if we know v_front_porch != 0,
// we can use MAX(squeezed_symbols, msa_symbols) instead of squeezed_symbols+msa_symbols
//
vblank_symbols -= (squeezed_symbols + msa_symbols);
if (linkConfig.bEnableFEC)
{
vblank_symbols -= FEC_PARITY_SYM_SST(numLanesPerLink, vblank_symbols);
}
vblank_symbols -= 3U; //add some margin
}
dpInfo->vBlankSym = (vblank_symbols < 0) ? 0 : vblank_symbols;
if (modesetInfo.bEnableDsc)
{
//
// For DSC enabled case, the vblank_symbols must be large enough to accommodate DSC PPS SDP, see bug 2760673
// For 1 lane, it requires at least 170+13 symbols
// For 2 lane, it requires at least 86+3 symbols
// For 4 lane, it requires at least 44+3 symbols
// normally, no need to check this, except in some small resolution test case.
//
if ((numLanesPerLink == 1U) && (dpInfo->vBlankSym < 183U))
{
return false;
}
else if ((numLanesPerLink == 2U) && (dpInfo->vBlankSym < 89U))
{
return false;
}
if ((numLanesPerLink == 4U) && (dpInfo->vBlankSym <47U))
{
return false;
}
}
return true;
}
bool DisplayPort::isModePossibleMSTWithFEC
(
const LinkConfiguration & linkConfig,
const ModesetInfo & modesetInfo,
Watermark * dpInfo
)
{
//
// This function is for multistream only!
// Refer to Bug 200406501 and 200401850 for algorithm
//
DP_ASSERT(linkConfig.multistream);
if (!modesetInfo.pixelClockHz || !modesetInfo.depth)
{
DP_ASSERT(0 && "INVALID PIXEL CLOCK and DEPTH sent by the client ");
return false;
}
if (linkConfig.lanes == 0)
{
DP_ASSERT(0 && "No Active link / link train failed ");
return false;
}
// depth is multiplied by 16 in case of DSC enable
unsigned DSC_FACTOR = modesetInfo.bEnableDsc ? 16 : 1;
dpInfo->tuSize = 64;
NvU32 BlankingBits, BlankingSymbolsPerLane;
NvU32 numLanesPerLink = 4U;
NvU32 MinHBlank;
BlankingBits = (3U * 8U * 4U) + (2U * 8U * numLanesPerLink);
if(modesetInfo.bEnableDsc)
{
NvU32 sliceCount, sliceWidth, chunkSize;
sliceCount = (modesetInfo.mode == DSC_DUAL) ? 8U : 4U;
sliceWidth = (NvU32)divide_ceil(modesetInfo.surfaceWidth, sliceCount);
chunkSize = (NvU32)divide_ceil(modesetInfo.depth * sliceWidth, 8U * DSC_FACTOR);
//EOC symbols, EOC will be accumulated until hblank period.
BlankingBits += (sliceCount * 8U * numLanesPerLink); //+BlankingBits_EOC
//+BlankingBits_DSC_padding
BlankingBits += (NvU32)(sliceCount * ((divide_ceil(chunkSize, numLanesPerLink) * numLanesPerLink * 8U) - (NvU32)(sliceWidth * modesetInfo.depth / DSC_FACTOR)));
}
else
{
NvU32 surfaceWidthPerLane = (NvU32)divide_ceil(modesetInfo.surfaceWidth, numLanesPerLink);
//Extra bits sent due to pixel steering
BlankingBits = (NvU32)divide_ceil(surfaceWidthPerLane * modesetInfo.depth, 8U) * 8U * numLanesPerLink - (NvU32)(modesetInfo.surfaceWidth * modesetInfo.depth); //+BlankingBits_nonDSC_padding
}
BlankingSymbolsPerLane = (NvU32)divide_ceil(BlankingBits, (8U * numLanesPerLink)); //in symbols per lane
MinHBlank = (NvU32)divide_ceil(BlankingSymbolsPerLane * 8U * numLanesPerLink * DSC_FACTOR, modesetInfo.depth);
MinHBlank += 3U; //add some margin
NvU32 HBlank = (modesetInfo.rasterWidth - modesetInfo.surfaceWidth);
if (MinHBlank > HBlank)
{
DP_LOG(("NVRM: %s:", __FUNCTION__));
DP_LOG(("\t\tERROR: Blanking Width is smaller than minimum permissible value."));
return false;
}
// Bug 702290 - Active Width should be greater than 60
if (modesetInfo.surfaceWidth <= 60)
{
DP_LOG(("NVRM: %s:", __FUNCTION__));
DP_LOG(("\t\tERROR: Minimum Horizontal Active Width <= 60 not supported."));
return false;
}
// MST can do SDP splitting so all audio configuration are possible.
dpInfo->hBlankSym = 0U;
dpInfo->vBlankSym = 0U;
return true;
}
unsigned DisplayPort::pbnForMode(const ModesetInfo & modesetInfo)
{
//
// Calculate PBN in terms of 54/64 mbyte/sec
// round up by .6% for spread de-rate. Note: if we're not spreading our link
// this MUST still be counted. It's also to allow downstream links to be spread.
//
unsigned pbnForMode = (NvU32)(divide_ceil(modesetInfo.pixelClockHz * modesetInfo.depth * 1006 * 64 / 8,
(NvU64)54000000 *1000));
if(modesetInfo.bEnableDsc)
{
//
// When DSC is enabled consider depth will multiplied by 16 and also 3% FEC Overhead
// as per DP1.4 spec
pbnForMode = (NvU32)(divide_ceil(pbnForMode * 100, 97 * DSC_DEPTH_FACTOR));
}
return pbnForMode;
}

View File

@@ -0,0 +1,94 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2010-2021 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_testmessage.cpp *
* Used for DP Test Utility *
* *
\***************************************************************************/
#include "dp_internal.h"
#include "dp_auxdefs.h"
#include "dp_messages.h"
#include "dp_testmessage.h"
#include "dp_connectorimpl.h"
using namespace DisplayPort;
// the dp lib status must be set to DONE indicating there is no pending message
void DPTestMessageCompletion::messageFailed(MessageManager::Message * from, NakData * data)
{
parent->testMessageStatus = DP_TESTMESSAGE_REQUEST_STATUS_DONE;
{
{
DP_ASSERT(0 && "unknown msg type when msg failed");
}
}
}
void DPTestMessageCompletion::messageCompleted(MessageManager::Message * from)
{
parent->testMessageStatus = DP_TESTMESSAGE_REQUEST_STATUS_DONE;
{
{
DP_ASSERT(0 && "unknown msg type when msg complete");
}
}
}
MessageManager * TestMessage::getMessageManager()
{
return pMsgManager;
}
//
// The function request that the request struct size should be check first to ensure the right structure is used and
// no BSOD will happen.
//
// For each request type, the DP lib status for that type should be check in case of request conflict. At one time,
// for each request type, only ONE instance could be processed
//
DP_TESTMESSAGE_STATUS TestMessage::sendDPTestMessage
(
void *pBuffer,
NvU32 requestSize,
NvU32 *pDpStatus
)
{
DP_ASSERT(pBuffer);
DP_TESTMESSAGE_REQUEST_TYPE type;
// the buffer must contain a requestType field at least
if (requestSize < sizeof(DP_TESTMESSAGE_REQUEST_TYPE))
return DP_TESTMESSAGE_STATUS_ERROR_INVALID_PARAM;
type = *(DP_TESTMESSAGE_REQUEST_TYPE *)pBuffer;
if (!isValidStruct(type, requestSize))
return DP_TESTMESSAGE_STATUS_ERROR_INVALID_PARAM;
*pDpStatus = DP_TESTMESSAGE_REQUEST_STATUS_ERROR;
return DP_TESTMESSAGE_STATUS_ERROR;
}

View File

@@ -0,0 +1,628 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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.
*/
#ifndef _DISPLAYPORT_H_
#define _DISPLAYPORT_H_
#include "nvmisc.h"
#include "dpcd.h"
#include "dpcd14.h"
#include "dpcd20.h"
/**************** Resource Manager Defines and Structures ******************\
* *
* Module: DISPLAYPORT.H *
* Defines DISPLAYPORT V1.2 *
* *
\***************************************************************************/
// Displayport interoperability with HDMI dongle i2c addr
#define DP2HDMI_DONGLE_I2C_ADDR 0x80
#define DP2HDMI_DONGLE_DDC_BUFFER_ID_LEN 16
#define DP2HDMI_DONGLE_CAP_BUFFER_LEN 32
// Offset to read the dongle identifier
#define NV_DP2HDMI_DONGLE_IDENTIFIER (0x00000010)
#define NV_DP2HDMI_DONGLE_IDENTIFIER_ADAPTER_REV 2:0
#define NV_DP2HDMI_DONGLE_IDENTIFIER_ADAPTER_REV_TYPE2 (0x00000000)
#define NV_DP2HDMI_DONGLE_IDENTIFIER_ADAPTER_ID 7:4
#define NV_DP2HDMI_DONGLE_IDENTIFIER_ADAPTER_ID_TYPE2 (0x0000000A)
// Offset to read the dongle TMDS clock rate
#define NV_DP2HDMI_DONGLE_TMDS_CLOCK_RATE (0x0000001D)
// HDMI dongle types
#define DP2HDMI_DONGLE_TYPE_1 0x1
#define DP2HDMI_DONGLE_TYPE_2 0x2
// HDMI dongle frequency limits
#define DP2HDMI_DONGLE_TYPE_1_PCLK_LIMIT 165*1000*1000
#define DP2HDMI_DONGLE_TYPE_2_PCLK_LIMIT 300*1000*1000
#define DPCD_VERSION_12 0x12
#define DPCD_VERSION_13 0x13
#define DPCD_VERSION_14 0x14
#define DP_LINKINDEX_0 0x0
#define DP_LINKINDEX_1 0x1
// Two Head One OR
#define NV_PRIMARY_HEAD_INDEX_0 0
#define NV_SECONDARY_HEAD_INDEX_1 1
#define NV_PRIMARY_HEAD_INDEX_2 2
#define NV_SECONDARY_HEAD_INDEX_3 3
typedef enum
{
displayPort_Lane0 = 0,
displayPort_Lane1 = 1,
displayPort_Lane2 = 2,
displayPort_Lane3 = 3,
displayPort_Lane4 = 4,
displayPort_Lane5 = 5,
displayPort_Lane6 = 6,
displayPort_Lane7 = 7,
displayPort_LaneSupported
} DP_LANE;
typedef enum
{
laneCount_0 = 0x0,
laneCount_1 = 0x1,
laneCount_2 = 0x2,
laneCount_4 = 0x4,
laneCount_8 = 0x8,
laneCount_Supported
} DP_LANE_COUNT;
typedef enum
{
linkBW_1_62Gbps = 0x06,
linkBW_2_16Gbps = 0x08,
linkBW_2_43Gbps = 0x09,
linkBW_2_70Gbps = 0x0A,
linkBW_3_24Gbps = 0x0C,
linkBW_4_32Gbps = 0x10,
linkBW_5_40Gbps = 0x14,
linkBW_8_10Gbps = 0x1E,
linkBW_Supported
} DP_LINK_BANDWIDTH;
typedef enum
{
linkSpeedId_1_62Gbps = 0x00,
linkSpeedId_2_70Gbps = 0x01,
linkSpeedId_5_40Gbps = 0x02,
linkSpeedId_8_10Gbps = 0x03,
linkSpeedId_2_16Gbps = 0x04,
linkSpeedId_2_43Gbps = 0x05,
linkSpeedId_3_24Gbps = 0x06,
linkSpeedId_4_32Gbps = 0x07,
linkSpeedId_Supported
} DP_LINK_SPEED_INDEX;
typedef enum
{
postCursor2_Level0 = 0,
postCursor2_Level1 = 1,
postCursor2_Level2 = 2,
postCursor2_Level3 = 3,
postCursor2_Supported
} DP_POSTCURSOR2;
typedef enum
{
preEmphasis_Disabled = 0,
preEmphasis_Level1 = 1,
preEmphasis_Level2 = 2,
preEmphasis_Level3 = 3,
preEmphasis_Supported
} DP_PREEMPHASIS;
typedef enum
{
driveCurrent_Level0 = 0,
driveCurrent_Level1 = 1,
driveCurrent_Level2 = 2,
driveCurrent_Level3 = 3,
driveCurrent_Supported
} DP_DRIVECURRENT;
typedef enum
{
trainingPattern_Disabled = 0x0,
trainingPattern_1 = 0x1,
trainingPattern_2 = 0x2,
trainingPattern_3 = 0x3,
trainingPattern_4 = 0xB
} DP_TRAININGPATTERN;
typedef enum
{
dpOverclock_Percentage_0 = 0,
dpOverclock_Percentage_10 = 10,
dpOverclock_Percentage_20 = 20
}DP_OVERCLOCKPERCENTAGE;
typedef enum
{
dpColorFormat_RGB = 0,
dpColorFormat_YCbCr444 = 0x1,
dpColorFormat_YCbCr422 = 0x2,
dpColorFormat_YCbCr420 = 0x3,
dpColorFormat_Unknown = 0xF
} DP_COLORFORMAT;
typedef enum
{
dp_pktType_VideoStreamconfig = 0x7,
dp_pktType_CeaHdrMetaData = 0x21,
dp_pktType_SRInfoFrame = 0x7f, // Self refresh infoframe for eDP enter/exit self refresh, SRS 1698
dp_pktType_Cea861BInfoFrame = 0x80,
dp_pktType_VendorSpecInfoFrame = 0x81,
dp_pktType_AviInfoFrame = 0x82,
dp_pktType_AudioInfoFrame = 0x84,
dp_pktType_SrcProdDescInfoFrame = 0x83,
dp_pktType_MpegSrcInfoFrame = 0x85,
dp_pktType_DynamicRangeMasteringInfoFrame = 0x87
} DP_PACKET_TYPE;
typedef enum
{
DSC_SLICES_PER_SINK_1 = 1,
DSC_SLICES_PER_SINK_2 = 2,
DSC_SLICES_PER_SINK_4 = 4,
DSC_SLICES_PER_SINK_6 = 6,
DSC_SLICES_PER_SINK_8 = 8,
DSC_SLICES_PER_SINK_10 = 10,
DSC_SLICES_PER_SINK_12 = 12,
DSC_SLICES_PER_SINK_16 = 16,
DSC_SLICES_PER_SINK_20 = 20,
DSC_SLICES_PER_SINK_24 = 24
} DscSliceCount;
typedef enum
{
DSC_BITS_PER_COLOR_MASK_8 = 1,
DSC_BITS_PER_COLOR_MASK_10 = 2,
DSC_BITS_PER_COLOR_MASK_12 = 4
}DscBitsPerColorMask;
enum DSC_MODE
{
DSC_SINGLE,
DSC_DUAL,
DSC_DROP,
DSC_MODE_NONE
};
typedef enum
{
BITS_PER_PIXEL_PRECISION_1_16 = 0,
BITS_PER_PIXEL_PRECISION_1_8 = 1,
BITS_PER_PIXEL_PRECISION_1_4 = 2,
BITS_PER_PIXEL_PRECISION_1_2 = 3,
BITS_PER_PIXEL_PRECISION_1 = 4
}BITS_PER_PIXEL_INCREMENT;
typedef enum
{
NV_DP_FEC_UNCORRECTED = 0,
NV_DP_FEC_CORRECTED = 1,
NV_DP_FEC_BIT = 2,
NV_DP_FEC_PARITY_BLOCK = 3,
NV_DP_FEC_PARITY_BIT = 4
}FEC_ERROR_COUNTER;
typedef struct DscCaps
{
NvBool bDSCSupported;
NvBool bDSCPassThroughSupported;
unsigned versionMajor, versionMinor;
unsigned rcBufferBlockSize;
unsigned rcBuffersize;
unsigned maxSlicesPerSink;
unsigned lineBufferBitDepth;
NvBool bDscBlockPredictionSupport;
unsigned maxBitsPerPixelX16;
unsigned sliceCountSupportedMask;
struct
{
NvBool bRgb;
NvBool bYCbCr444;
NvBool bYCbCrSimple422;
NvBool bYCbCrNative422;
NvBool bYCbCrNative420;
}dscDecoderColorFormatCaps;
unsigned dscDecoderColorDepthMask;
unsigned dscPeakThroughputMode0;
unsigned dscPeakThroughputMode1;
unsigned dscMaxSliceWidth;
BITS_PER_PIXEL_INCREMENT dscBitsPerPixelIncrement;
} DscCaps;
typedef struct GpuDscCrc
{
NvU16 gpuCrc0;
NvU16 gpuCrc1;
NvU16 gpuCrc2;
} gpuDscCrc;
typedef struct SinkDscCrc
{
NvU16 sinkCrc0;
NvU16 sinkCrc1;
NvU16 sinkCrc2;
} sinkDscCrc;
typedef struct
{
NvBool bSourceControlModeSupported;
NvBool bConcurrentLTSupported;
NvU8 maxTmdsClkRate;
NvU8 maxBpc;
NvU8 maxHdmiLinkBandwidthGbps;
} PCONCaps;
typedef enum
{
PCON_HDMI_LINK_BW_FRL_9GBPS = 0,
PCON_HDMI_LINK_BW_FRL_18GBPS,
PCON_HDMI_LINK_BW_FRL_24GBPS,
PCON_HDMI_LINK_BW_FRL_32GBPS,
PCON_HDMI_LINK_BW_FRL_40GBPS,
PCON_HDMI_LINK_BW_FRL_48GBPS,
PCON_HDMI_LINK_BW_FRL_INVALID
} PCONHdmiLinkBw;
typedef enum
{
NV_DP_PCON_CONTROL_STATUS_SUCCESS = 0,
NV_DP_PCON_CONTROL_STATUS_ERROR_TIMEOUT = 0x80000001,
NV_DP_PCON_CONTROL_STATUS_ERROR_FRL_LT_FAILURE = 0x80000002,
NV_DP_PCON_CONTROL_STATUS_ERROR_FRL_NOT_SUPPORTED = 0x80000003,
NV_DP_PCON_CONTROL_STATUS_ERROR_GENERIC = 0x8000000F
} NV_DP_PCON_CONTROL_STATUS;
//
// Poll HDMI-Link Status change and FRL Ready.
// Spec says it should be done in 500ms, we give it 20% extra time:
// 60 times with interval 10ms.
//
#define NV_PCON_SOURCE_CONTROL_MODE_TIMEOUT_THRESHOLD (60)
#define NV_PCON_SOURCE_CONTROL_MODE_TIMEOUT_INTERVAL_MS (10)
//
// Poll HDMI-Link Status change IRQ and Link Status.
// Spec says it should be done in 250ms, we give it 20% extra time:
// 30 times with interval 10ms.
//
#define NV_PCON_FRL_LT_TIMEOUT_THRESHOLD (30)
#define NV_PCON_FRL_LT_TIMEOUT_INTERVAL_MS (10)
typedef struct _PCONLinkControl
{
struct
{
// This struct is being passed in for assessPCONLink I/F
NvU32 bAssessLink : 1;
// Specify if client wants to use src control - set it false DPLib can just do DP LT alone.
// By default it should be true.
NvU32 bSourceControlMode : 1;
// Default is sequential mode, set this to choose concurrent mode
NvU32 bConcurrentMode : 1;
// Default is normal link training mode (stop once FRL-LT succeed).
// Set this to link train all requested FRL Bw in allowedFrlBwMask.
NvU32 bExtendedLTMode : 1;
// Keep PCON links (DP and FRL link) alive
NvU32 bKeepPCONLinkAlive : 1;
// Default DPLib will fallback to autonomous mode and perform DP assessLink.
NvU32 bSkipFallback : 1;
} flags;
// Input: Clients use this to specify the FRL BW PCON should try.
NvU32 frlHdmiBwMask;
struct
{
NV_DP_PCON_CONTROL_STATUS status;
PCONHdmiLinkBw maxFrlBwTrained;
NvU32 trainedFrlBwMask;
} result;
} PCONLinkControl;
static NV_INLINE PCONHdmiLinkBw getMaxFrlBwFromMask(NvU32 frlRateMask)
{
if (frlRateMask == 0)
{
// Nothing is set. Assume TMDS
return PCON_HDMI_LINK_BW_FRL_INVALID;
}
// find highest set bit (destructive operation)
HIGHESTBITIDX_32(frlRateMask);
return (PCONHdmiLinkBw)frlRateMask;
}
/*
EDP VESA PSR defines
*/
// PSR state transitions
typedef enum
{
vesaPsrStatus_Inactive = 0,
vesaPsrStatus_Transition2Active = 1,
vesaPsrStatus_DisplayFromRfb = 2,
vesaPsrStatus_CaptureAndDisplay = 3,
vesaPsrStatus_Transition2Inactive = 4,
vesaPsrStatus_Undefined5 = 5,
vesaPsrStatus_Undefined6 = 6,
vesaPsrStatus_SinkError = 7
} vesaPsrState;
typedef struct VesaPsrConfig
{
NvU8 psrCfgEnable : 1;
NvU8 srcTxEnabledInPsrActive : 1;
NvU8 crcVerifEnabledInPsrActive : 1;
NvU8 frameCaptureSecondActiveFrame : 1;
NvU8 selectiveUpdateOnSecondActiveline : 1;
NvU8 enableHpdIrqOnCrcMismatch : 1;
NvU8 enablePsr2 : 1;
NvU8 reserved : 1;
} vesaPsrConfig;
typedef struct VesaPsrDebugStatus
{
NvBool lastSdpPsrState;
NvBool lastSdpUpdateRfb;
NvBool lastSdpCrcValid;
NvBool lastSdpSuValid;
NvBool lastSdpFirstSURcvd;
NvBool lastSdpLastSURcvd;
NvBool lastSdpYCoordValid;
NvU8 maxResyncFrames;
NvU8 actualResyncFrames;
} vesaPsrDebugStatus;
typedef struct VesaPsrErrorStatus
{
NvU8 linkCrcError : 1;
NvU8 rfbStoreError : 1;
NvU8 vscSdpError : 1;
NvU8 rsvd : 5;
} vesaPsrErrorStatus;
typedef struct VesaPsrEventIndicator
{
NvU8 sinkCapChange : 1;
NvU8 rsvd : 7;
} vesaPsrEventIndicator;
#pragma pack(1)
typedef struct VesaPsrSinkCaps
{
NvU8 psrVersion;
NvU8 linkTrainingRequired : 1;
NvU8 psrSetupTime : 3;
NvU8 yCoordinateRequired : 1;
NvU8 psr2UpdateGranularityRequired : 1;
NvU8 reserved : 2;
NvU16 suXGranularity;
NvU8 suYGranularity;
} vesaPsrSinkCaps;
#pragma pack()
typedef struct PanelReplayCaps
{
NvBool panelReplaySupported;
} panelReplayCaps;
typedef struct PanelReplayConfig
{
NvBool enablePanelReplay;
} panelReplayConfig;
// Multiplier constant to get link frequency in KHZ
// Maximum link rate of Main Link lanes = Value x 270M.
// To get it to KHz unit, we need to multiply 270K.
#define DP_LINK_BW_FREQUENCY_MULTIPLIER_KHZ (270*1000)
// Multiplier constant to get link rate table's in KHZ
#define DP_LINK_RATE_TABLE_MULTIPLIER_KHZ 200
//
// Multiplier constant to get link frequency (multiplier of 270MHz) in MBps
// a * 270 * 1000 * 1000(270Mhz) * (8 / 10)(8b/10b) / 8(Byte)
// = a * 27000000
//
#define DP_LINK_BW_FREQ_MULTI_MBPS 27000000
//
// Get link rate in multiplier of 270MHz from KHz:
// a * 1000(KHz) / 270 * 1000 * 1000(270Mhz)
//
#define LINK_RATE_KHZ_TO_MULTP(a) ((a) / 270000)
//
// Get link rate in MBps from KHz:
// a * 1000 * (8 / 10)(8b/10b) / 8(Byte)
// = a * 100
//
#define LINK_RATE_KHZ_TO_MBPS(a) ((a) * 100)
#define DP_MAX_LANES 8 // This defines the maximum number of lanes supported on a chip.
#define DP_MAX_LANES_PER_LINK 4 // This defines the maximum number of lanes per link in a chip.
#define DP_AUX_CHANNEL_MAX_BYTES 16
#define DP_CLOCK_RECOVERY_TOT_TRIES 10
#define DP_CLOCK_RECOVERY_MAX_TRIES 5
#define DP_CH_EQ_MAX_RETRIES 5
#define DP_LT_MAX_FOR_MST_MAX_RETRIES 3
#define DP_READ_EDID_MAX_RETRIES 7
#define DP_AUX_CHANNEL_DEFAULT_DEFER_MAX_TRIES 7
#define DP_AUX_CHANNEL_TIMEOUT_MAX_TRIES 2
#define DP_SET_POWER_D0_NORMAL_MAX_TRIES 3
#define DP_SW_AUTO_READ_REQ_SIZE 6
#define NV_DP_RBR_FALLBACK_MAX_TRIES 3
#define DP_EXTENDED_DPRX_SLEEP_WAKE_TIMEOUT_DEFAULT_MS 1
#define DP_AUX_CHANNEL_TIMEOUT_WAITIDLE 400 // source is required to wait at least 400us before it considers the AUX transaction to have timed out.
#define DP_AUX_CHANNEL_TIMEOUT_VALUE_DEFAULT 400
#define DP_AUX_CHANNEL_TIMEOUT_VALUE_MAX 3200
#define DP_PHY_REPEATER_INDEX_FOR_SINK 0xFFFFFFFF
#define DP_MESSAGEBOX_SIZE 48
#define DP_POST_LT_ADJ_REQ_LIMIT 6
#define DP_POST_LT_ADJ_REQ_TIMER 200000
#define DP_AUX_HYBRID_TIMEOUT 600
#define DP_AUX_SEMA_ACQUIRE_TIMEOUT 20000
#define DP_CONFIG_WATERMARK_ADJUST 2
#define DP_CONFIG_WATERMARK_LIMIT 20
#define DP_CONFIG_INCREASED_WATERMARK_ADJUST 8
#define DP_CONFIG_INCREASED_WATERMARK_LIMIT 22
#define NV_DP_MSA_PROPERTIES_MISC1_STEREO 2:1
#define DP_LANE_STATUS_ARRAY_SIZE ((displayPort_LaneSupported + 1) / 2)
#define DP_LANE_STATUS_ARRAY_INDEX(lane) ((lane) < displayPort_LaneSupported ? ((lane) / 2) : 0)
#define IS_VALID_LANECOUNT(val) (((NvU32)(val)==0) || ((NvU32)(val)==1) || \
((NvU32)(val)==2) || ((NvU32)(val)==4) || \
((NvU32)(val)==8))
#define IS_STANDARD_LINKBW(val) (((NvU32)(val)==linkBW_1_62Gbps) || \
((NvU32)(val)==linkBW_2_70Gbps) || \
((NvU32)(val)==linkBW_5_40Gbps) || \
((NvU32)(val)==linkBW_8_10Gbps))
#define IS_INTERMEDIATE_LINKBW(val) (((NvU32)(val)==linkBW_2_16Gbps) || \
((NvU32)(val)==linkBW_2_43Gbps) || \
((NvU32)(val)==linkBW_3_24Gbps) || \
((NvU32)(val)==linkBW_4_32Gbps))
#define IS_VALID_LINKBW(val) (IS_STANDARD_LINKBW(val) || \
IS_INTERMEDIATE_LINKBW(val))
//
// Phy Repeater count read from DPCD offset F0002h is an
// 8 bit value where each bit represents the total count
// 80h = 1 repeater, 40h = 2 , 20h = 3 ... 01h = 8
// This function maps it to decimal system
//
static NV_INLINE NvU32 mapPhyRepeaterVal(NvU32 value)
{
switch (value)
{
case NV_DPCD14_PHY_REPEATER_CNT_VAL_0:
return 0;
case NV_DPCD14_PHY_REPEATER_CNT_VAL_1:
return 1;
case NV_DPCD14_PHY_REPEATER_CNT_VAL_2:
return 2;
case NV_DPCD14_PHY_REPEATER_CNT_VAL_3:
return 3;
case NV_DPCD14_PHY_REPEATER_CNT_VAL_4:
return 4;
case NV_DPCD14_PHY_REPEATER_CNT_VAL_5:
return 5;
case NV_DPCD14_PHY_REPEATER_CNT_VAL_6:
return 6;
case NV_DPCD14_PHY_REPEATER_CNT_VAL_7:
return 7;
case NV_DPCD14_PHY_REPEATER_CNT_VAL_8:
return 8;
default:
return 0;
}
}
// HDCP specific definitions
#define HDCP22_RTX_SIMPLE_PATTERN 0x12345678
#define HDCP22_TX_CAPS_PATTERN_BIG_ENDIAN {0x02, 0x00, 0x00}
#define DP_MST_HEAD_TO_STREAMID(head, pipeId, numHeads) ((head) + 1 + (pipeId) * (numHeads))
#define DP_MST_STREAMID_TO_HEAD(streamid, pipeId, numHeads) ((streamid) - 1 - ((pipeId) * (numHeads)))
#define DP_MST_STREAMID_TO_PIPE(streamid, head, numHeads) (((streamid) - (head) - 1) / (numHeads))
typedef enum
{
NV_DP_SBMSG_REQUEST_ID_GET_MESSAGE_TRANSACTION_VERSION = 0x00,
NV_DP_SBMSG_REQUEST_ID_LINK_ADDRESS = 0x01,
NV_DP_SBMSG_REQUEST_ID_CONNECTION_STATUS_NOTIFY = 0x02,
NV_DP_SBMSG_REQUEST_ID_ENUM_PATH_RESOURCES = 0x10,
NV_DP_SBMSG_REQUEST_ID_ALLOCATE_PAYLOAD = 0x11,
NV_DP_SBMSG_REQUEST_ID_QUERY_PAYLOAD = 0x12,
NV_DP_SBMSG_REQUEST_ID_RESOURCE_STATUS_NOTIFY = 0x13,
NV_DP_SBMSG_REQUEST_ID_CLEAR_PAYLOAD_ID_TABLE = 0x14,
NV_DP_SBMSG_REQUEST_ID_REMOTE_DPCD_READ = 0x20,
NV_DP_SBMSG_REQUEST_ID_REMOTE_DPCD_WRITE = 0x21,
NV_DP_SBMSG_REQUEST_ID_REMOTE_I2C_READ = 0x22,
NV_DP_SBMSG_REQUEST_ID_REMOTE_I2C_WRITE = 0x23,
NV_DP_SBMSG_REQUEST_ID_POWER_UP_PHY = 0x24,
NV_DP_SBMSG_REQUEST_ID_POWER_DOWN_PHY = 0x25,
NV_DP_SBMSG_REQUEST_ID_SINK_EVENT_NOTIFY = 0x30,
NV_DP_SBMSG_REQUEST_ID_QUERY_STREAM_ENCRYPTION_STATUS = 0x38,
NV_DP_SBMSG_REQUEST_ID_UNDEFINED = 0xFF,
} NV_DP_SBMSG_REQUEST_ID;
// FEC
#define NV_DP_FEC_FLAGS_SELECT_ALL 0x7
#define NV_DP_ERROR_COUNTERS_PER_LANE 5
#define NV_DP_MAX_NUM_OF_LANES 4
#define NV_DP_FEC_ERROR_COUNT_INVALID 0xbadf
#define NV_DP_UNCORRECTED_ERROR NV_DP_FEC_UNCORRECTED : NV_DP_FEC_UNCORRECTED
#define NV_DP_CORRECTED_ERROR NV_DP_FEC_CORRECTED : NV_DP_FEC_CORRECTED
#define NV_DP_BIT_ERROR NV_DP_FEC_BIT : NV_DP_FEC_BIT
#define NV_DP_PARITY_BLOCK_ERROR NV_DP_FEC_PARITY_BLOCK : NV_DP_FEC_PARITY_BLOCK
#define NV_DP_PARITY_BIT_ERROR NV_DP_FEC_PARITY_BIT : NV_DP_FEC_PARITY_BIT
#define NV_DP_UNCORRECTED_ERROR_NO 0
#define NV_DP_UNCORRECTED_ERROR_YES 1
#define NV_DP_CORRECTED_ERROR_NO 0
#define NV_DP_CORRECTED_ERROR_YES 1
#define NV_DP_BIT_ERROR_NO 0
#define NV_DP_BIT_ERROR_YES 1
#define NV_DP_PARITY_BLOCK_ERROR_NO 0
#define NV_DP_PARITY_BLOCK_ERROR_YES 1
#define NV_DP_PARITY_BIT_ERROR_NO 0
#define NV_DP_PARITY_BIT_ERROR_YES 1
#endif // #ifndef _DISPLAYPORT_H_

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,790 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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.
*/
#ifndef _DISPLAYPORT14_H_
#define _DISPLAYPORT14_H_
#define NV_DPCD14_EXTEND_CAP_BASE (0x00002200)
#define NV_DPCD14_MAX_LINK_BANDWIDTH (0x00000001) /* R-XUR */
#define NV_DPCD14_MAX_LINK_BANDWIDTH_VAL 7:0 /* R-XUF */
#define NV_DPCD14_MAX_LINK_BANDWIDTH_VAL_8_10_GBPS (0x0000001E) /* R-XUV */
#define NV_DPCD14_MAX_DOWNSPREAD (0x00000003) /* R-XUR */
#define NV_DPCD14_MAX_DOWNSPREAD_TPS4_SUPPORTED 7:7 /* R-XUF */
#define NV_DPCD14_MAX_DOWNSPREAD_TPS4_SUPPORTED_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_MAX_DOWNSPREAD_TPS4_SUPPORTED_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_TRAINING_AUX_RD_INTERVAL (0x0000000E) /* R-XUR */
#define NV_DPCD14_TRAINING_AUX_RD_INTERVAL_EXTENDED_RX_CAP 7:7 /* R-XUF */
#define NV_DPCD14_TRAINING_AUX_RD_INTERVAL_EXTENDED_RX_CAP_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_TRAINING_AUX_RD_INTERVAL_EXTENDED_RX_CAP_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_DSC_SUPPORT (0x00000060) /* R-XUR */
#define NV_DPCD14_DSC_SUPPORT_DSC_SUPPORT 0:0 /* R-XUF */
#define NV_DPCD14_DSC_SUPPORT_DSC_SUPPORT_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_DSC_SUPPORT_DSC_SUPPORT_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_DSC_ALGORITHM_REVISION (0x00000061) /* R-XUR */
#define NV_DPCD14_DSC_ALGORITHM_REVISION_MAJOR 3:0 /* R-XUF */
#define NV_DPCD14_DSC_ALGORITHM_REVISION_MINOR 7:4 /* R-XUF */
#define NV_DPCD14_DSC_RC_BUFFER_BLOCK (0x00000062) /* R-XUR */
#define NV_DPCD14_DSC_RC_BUFFER_BLOCK_SIZE 1:0 /* R-XUF */
#define NV_DPCD14_DSC_RC_BUFFER_BLOCK_SIZE_1KB (0x00000000) /* R-XUV */
#define NV_DPCD14_DSC_RC_BUFFER_BLOCK_SIZE_4KB (0x00000001) /* R-XUV */
#define NV_DPCD14_DSC_RC_BUFFER_BLOCK_SIZE_16KB (0x00000002) /* R-XUV */
#define NV_DPCD14_DSC_RC_BUFFER_BLOCK_SIZE_64KB (0x00000003) /* R-XUV */
#define NV_DPCD14_DSC_RC_BUFFER (0x00000063) /* R-XUR */
#define NV_DPCD14_DSC_RC_BUFFER_SIZE 7:0 /* R-XUF */
#define NV_DPCD14_DSC_SLICE_CAPABILITIES_1 (0x00000064) /* R-XUR */
#define NV_DPCD14_DSC_SLICE_CAPABILITIES_1_SLICES_PER_SINK_1 0:0 /* R-XUF */
#define NV_DPCD14_DSC_SLICE_CAPABILITIES_1_SLICES_PER_SINK_1_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_DSC_SLICE_CAPABILITIES_1_SLICES_PER_SINK_1_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_DSC_SLICE_CAPABILITIES_1_SLICES_PER_SINK_2 1:1 /* R-XUF */
#define NV_DPCD14_DSC_SLICE_CAPABILITIES_1_SLICES_PER_SINK_2_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_DSC_SLICE_CAPABILITIES_1_SLICES_PER_SINK_2_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_DSC_SLICE_CAPABILITIES_1_SLICES_PER_SINK_4 3:3 /* R-XUF */
#define NV_DPCD14_DSC_SLICE_CAPABILITIES_1_SLICES_PER_SINK_4_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_DSC_SLICE_CAPABILITIES_1_SLICES_PER_SINK_4_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_DSC_SLICE_CAPABILITIES_1_SLICES_PER_SINK_6 4:4 /* R-XUF */
#define NV_DPCD14_DSC_SLICE_CAPABILITIES_1_SLICES_PER_SINK_6_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_DSC_SLICE_CAPABILITIES_1_SLICES_PER_SINK_6_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_DSC_SLICE_CAPABILITIES_1_SLICES_PER_SINK_8 5:5 /* R-XUF */
#define NV_DPCD14_DSC_SLICE_CAPABILITIES_1_SLICES_PER_SINK_8_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_DSC_SLICE_CAPABILITIES_1_SLICES_PER_SINK_8_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_DSC_SLICE_CAPABILITIES_1_SLICES_PER_SINK_10 6:6 /* R-XUF */
#define NV_DPCD14_DSC_SLICE_CAPABILITIES_1_SLICES_PER_SINK_10_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_DSC_SLICE_CAPABILITIES_1_SLICES_PER_SINK_10_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_DSC_SLICE_CAPABILITIES_1_SLICES_PER_SINK_12 7:7 /* R-XUF */
#define NV_DPCD14_DSC_SLICE_CAPABILITIES_1_SLICES_PER_SINK_12_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_DSC_SLICE_CAPABILITIES_1_SLICES_PER_SINK_12_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_DSC_LINE_BUFFER (0x00000065) /* R-XUR */
#define NV_DPCD14_DSC_LINE_BUFFER_BIT_DEPTH 3:0 /* R-XUF */
#define NV_DPCD14_DSC_LINE_BUFFER_BIT_DEPTH_9 (0x00000000) /* R-XUV */
#define NV_DPCD14_DSC_LINE_BUFFER_BIT_DEPTH_10 (0x00000001) /* R-XUV */
#define NV_DPCD14_DSC_LINE_BUFFER_BIT_DEPTH_11 (0x00000002) /* R-XUV */
#define NV_DPCD14_DSC_LINE_BUFFER_BIT_DEPTH_12 (0x00000003) /* R-XUV */
#define NV_DPCD14_DSC_LINE_BUFFER_BIT_DEPTH_13 (0x00000004) /* R-XUV */
#define NV_DPCD14_DSC_LINE_BUFFER_BIT_DEPTH_14 (0x00000005) /* R-XUV */
#define NV_DPCD14_DSC_LINE_BUFFER_BIT_DEPTH_15 (0x00000006) /* R-XUV */
#define NV_DPCD14_DSC_LINE_BUFFER_BIT_DEPTH_16 (0x00000007) /* R-XUV */
#define NV_DPCD14_DSC_LINE_BUFFER_BIT_DEPTH_8 (0x00000008) /* R-XUV */
#define NV_DPCD14_DSC_BLOCK_PREDICTION (0x00000066) /* R-XUR */
#define NV_DPCD14_DSC_BLOCK_PREDICTION_SUPPORT 0:0 /* R-XUF */
#define NV_DPCD14_DSC_BLOCK_PREDICTION_SUPPORT_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_DSC_BLOCK_PREDICTION_SUPPORT_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_DSC_MAXIMUM_BITS_PER_PIXEL_1 (0x00000067) /* R-XUR */
#define NV_DPCD14_DSC_MAXIMUM_BITS_PER_PIXEL_1_LSB 7:0 /* R-XUF */
#define NV_DPCD14_DSC_MAXIMUM_BITS_PER_PIXEL_2 (0x00000068) /* R-XUR */
#define NV_DPCD14_DSC_MAXIMUM_BITS_PER_PIXEL_2_MSB 1:0 /* R-XUF */
#define NV_DPCD14_DSC_DECODER_COLOR_FORMAT_CAPABILITIES (0x00000069) /* R-XUR */
#define NV_DPCD14_DSC_DECODER_COLOR_FORMAT_CAPABILITIES_RGB 0:0 /* R-XUF */
#define NV_DPCD14_DSC_DECODER_COLOR_FORMAT_CAPABILITIES_RGB_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_DSC_DECODER_COLOR_FORMAT_CAPABILITIES_RGB_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_DSC_DECODER_COLOR_FORMAT_CAPABILITIES_YCbCr_444 1:1 /* R-XUF */
#define NV_DPCD14_DSC_DECODER_COLOR_FORMAT_CAPABILITIES_YCbCr_444_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_DSC_DECODER_COLOR_FORMAT_CAPABILITIES_YCbCr_444_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_DSC_DECODER_COLOR_FORMAT_CAPABILITIES_YCbCr_SIMPLE_422 2:2 /* R-XUF */
#define NV_DPCD14_DSC_DECODER_COLOR_FORMAT_CAPABILITIES_YCbCr_SIMPLE_422_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_DSC_DECODER_COLOR_FORMAT_CAPABILITIES_YCbCr_SIMPLE_422_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_DSC_DECODER_COLOR_FORMAT_CAPABILITIES_YCbCr_NATIVE_422 3:3 /* R-XUF */
#define NV_DPCD14_DSC_DECODER_COLOR_FORMAT_CAPABILITIES_YCbCr_NATIVE_422_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_DSC_DECODER_COLOR_FORMAT_CAPABILITIES_YCbCr_NATIVE_422_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_DSC_DECODER_COLOR_FORMAT_CAPABILITIES_YCbCr_NATIVE_420 4:4 /* R-XUF */
#define NV_DPCD14_DSC_DECODER_COLOR_FORMAT_CAPABILITIES_YCbCr_NATIVE_420_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_DSC_DECODER_COLOR_FORMAT_CAPABILITIES_YCbCr_NATIVE_420_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_DSC_DECODER_COLOR_DEPTH_CAPABILITIES (0x0000006A) /* R-XUR */
#define NV_DPCD14_DSC_DECODER_COLOR_DEPTH_CAPABILITIES_8_BITS_PER_COLOR 1:1 /* R-XUF */
#define NV_DPCD14_DSC_DECODER_COLOR_DEPTH_CAPABILITIES_8_BITS_PER_COLOR_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_DSC_DECODER_COLOR_DEPTH_CAPABILITIES_8_BITS_PER_COLOR_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_DSC_DECODER_COLOR_DEPTH_CAPABILITIES_10_BITS_PER_COLOR 2:2 /* R-XUF */
#define NV_DPCD14_DSC_DECODER_COLOR_DEPTH_CAPABILITIES_10_BITS_PER_COLOR_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_DSC_DECODER_COLOR_DEPTH_CAPABILITIES_10_BITS_PER_COLOR_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_DSC_DECODER_COLOR_DEPTH_CAPABILITIES_12_BITS_PER_COLOR 3:3 /* R-XUF */
#define NV_DPCD14_DSC_DECODER_COLOR_DEPTH_CAPABILITIES_12_BITS_PER_COLOR_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_DSC_DECODER_COLOR_DEPTH_CAPABILITIES_12_BITS_PER_COLOR_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_DSC_PEAK_THROUGHPUT (0x0000006B) /* R-XUR */
#define NV_DPCD14_DSC_PEAK_THROUGHPUT_MODE0 3:0 /* R-XUF */
#define NV_DPCD14_DSC_PEAK_THROUGHPUT_MODE0_340 (0x00000001) /* R-XUV */
#define NV_DPCD14_DSC_PEAK_THROUGHPUT_MODE0_400 (0x00000002) /* R-XUV */
#define NV_DPCD14_DSC_PEAK_THROUGHPUT_MODE0_450 (0x00000003) /* R-XUV */
#define NV_DPCD14_DSC_PEAK_THROUGHPUT_MODE0_500 (0x00000004) /* R-XUV */
#define NV_DPCD14_DSC_PEAK_THROUGHPUT_MODE0_550 (0x00000005) /* R-XUV */
#define NV_DPCD14_DSC_PEAK_THROUGHPUT_MODE0_600 (0x00000006) /* R-XUV */
#define NV_DPCD14_DSC_PEAK_THROUGHPUT_MODE0_650 (0x00000007) /* R-XUV */
#define NV_DPCD14_DSC_PEAK_THROUGHPUT_MODE0_700 (0x00000008) /* R-XUV */
#define NV_DPCD14_DSC_PEAK_THROUGHPUT_MODE0_750 (0x00000009) /* R-XUV */
#define NV_DPCD14_DSC_PEAK_THROUGHPUT_MODE0_800 (0x0000000A) /* R-XUV */
#define NV_DPCD14_DSC_PEAK_THROUGHPUT_MODE0_850 (0x0000000B) /* R-XUV */
#define NV_DPCD14_DSC_PEAK_THROUGHPUT_MODE0_900 (0x0000000C) /* R-XUV */
#define NV_DPCD14_DSC_PEAK_THROUGHPUT_MODE0_950 (0x0000000D) /* R-XUV */
#define NV_DPCD14_DSC_PEAK_THROUGHPUT_MODE0_1000 (0x0000000E) /* R-XUV */
#define NV_DPCD14_DSC_PEAK_THROUGHPUT_MODE1 7:4 /* R-XUF */
#define NV_DPCD14_DSC_PEAK_THROUGHPUT_MODE1_340 (0x00000001) /* R-XUV */
#define NV_DPCD14_DSC_PEAK_THROUGHPUT_MODE1_400 (0x00000002) /* R-XUV */
#define NV_DPCD14_DSC_PEAK_THROUGHPUT_MODE1_450 (0x00000003) /* R-XUV */
#define NV_DPCD14_DSC_PEAK_THROUGHPUT_MODE1_500 (0x00000004) /* R-XUV */
#define NV_DPCD14_DSC_PEAK_THROUGHPUT_MODE1_550 (0x00000005) /* R-XUV */
#define NV_DPCD14_DSC_PEAK_THROUGHPUT_MODE1_600 (0x00000006) /* R-XUV */
#define NV_DPCD14_DSC_PEAK_THROUGHPUT_MODE1_650 (0x00000007) /* R-XUV */
#define NV_DPCD14_DSC_PEAK_THROUGHPUT_MODE1_700 (0x00000008) /* R-XUV */
#define NV_DPCD14_DSC_PEAK_THROUGHPUT_MODE1_750 (0x00000009) /* R-XUV */
#define NV_DPCD14_DSC_PEAK_THROUGHPUT_MODE1_800 (0x0000000A) /* R-XUV */
#define NV_DPCD14_DSC_PEAK_THROUGHPUT_MODE1_850 (0x0000000B) /* R-XUV */
#define NV_DPCD14_DSC_PEAK_THROUGHPUT_MODE1_900 (0x0000000C) /* R-XUV */
#define NV_DPCD14_DSC_PEAK_THROUGHPUT_MODE1_950 (0x0000000D) /* R-XUV */
#define NV_DPCD14_DSC_PEAK_THROUGHPUT_MODE1_1000 (0x0000000E) /* R-XUV */
#define NV_DPCD14_DSC_MAXIMUM_SLICE_WIDTH (0x0000006C) /* R-XUR */
#define NV_DPCD14_DSC_MAXIMUM_SLICE_WIDTH_MAX 7:0 /* R-XUF */
#define NV_DPCD14_DSC_SLICE_CAPABILITIES_2 (0x0000006D) /* R-XUR */
#define NV_DPCD14_DSC_SLICE_CAPABILITIES_2_SLICES_PER_SINK_16 0:0 /* R-XUF */
#define NV_DPCD14_DSC_SLICE_CAPABILITIES_2_SLICES_PER_SINK_16_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_DSC_SLICE_CAPABILITIES_2_SLICES_PER_SINK_16_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_DSC_SLICE_CAPABILITIES_2_SLICES_PER_SINK_20 1:1 /* R-XUF */
#define NV_DPCD14_DSC_SLICE_CAPABILITIES_2_SLICES_PER_SINK_20_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_DSC_SLICE_CAPABILITIES_2_SLICES_PER_SINK_20_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_DSC_SLICE_CAPABILITIES_2_SLICES_PER_SINK_24 2:2 /* R-XUF */
#define NV_DPCD14_DSC_SLICE_CAPABILITIES_2_SLICES_PER_SINK_24_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_DSC_SLICE_CAPABILITIES_2_SLICES_PER_SINK_24_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_DSC_BITS_PER_PIXEL_INCREMENT (0x0000006F) /* R-XUR */
#define NV_DPCD14_DSC_BITS_PER_PIXEL_INCREMENT_SUPPORTED 2:0 /* R-XUF */
#define NV_DPCD14_DSC_BITS_PER_PIXEL_INCREMENT_SUPPORTED_1_16 (0x00000000) /* R-XUV */
#define NV_DPCD14_DSC_BITS_PER_PIXEL_INCREMENT_SUPPORTED_1_8 (0x00000001) /* R-XUV */
#define NV_DPCD14_DSC_BITS_PER_PIXEL_INCREMENT_SUPPORTED_1_4 (0x00000002) /* R-XUV */
#define NV_DPCD14_DSC_BITS_PER_PIXEL_INCREMENT_SUPPORTED_1_2 (0x00000003) /* R-XUV */
#define NV_DPCD14_DSC_BITS_PER_PIXEL_INCREMENT_SUPPORTED_1 (0x00000004) /* R-XUV */
// Field definition only used only with 128b/132b for DP2.0+
#define NV_DPCD20_TRAINING_LANE_SET(i) (0x00000103+(i)) /* RW-1A */
#define NV_DPCD20_TRAINING_LANE_SET__SIZE 4 /* RW--S */
#define NV_DPCD20_TRAINING_LANE_SET_TX_FFE_PRESET_VALUE 3:0 /* RWXUF */
#define NV_DPCD14_DSC_ENABLE (0x00000160) /* R-XUR */
#define NV_DPCD14_DSC_ENABLE_SINK 0:0 /* R-XUF */
#define NV_DPCD14_DSC_ENABLE_SINK_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_DSC_ENABLE_SINK_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_FEC_CAPABILITY (0x00000090) /* R-XUR */
#define NV_DPCD14_FEC_CAPABILITY_FEC_CAPABLE 0:0 /* R-XUF */
#define NV_DPCD14_FEC_CAPABILITY_FEC_CAPABLE_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_FEC_CAPABILITY_FEC_CAPABLE_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_FEC_CAPABILITY_UNCORRECTED_BLOCK_ERROR_COUNT_CAPABLE 1:1 /* R-XUF */
#define NV_DPCD14_FEC_CAPABILITY_UNCORRECTED_BLOCK_ERROR_COUNT_CAPABLE_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_FEC_CAPABILITY_UNCORRECTED_BLOCK_ERROR_COUNT_CAPABLE_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_FEC_CAPABILITY_CORRECTED_BLOCK_ERROR_COUNT_CAPABLE 2:2 /* R-XUF */
#define NV_DPCD14_FEC_CAPABILITY_CORRECTED_BLOCK_ERROR_COUNT_CAPABLE_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_FEC_CAPABILITY_CORRECTED_BLOCK_ERROR_COUNT_CAPABLE_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_FEC_CAPABILITY_BIT_ERROR_COUNT_CAPABLE 3:3 /* R-XUF */
#define NV_DPCD14_FEC_CAPABILITY_BIT_ERROR_COUNT_CAPABLE_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_FEC_CAPABILITY_BIT_ERROR_COUNT_CAPABLE_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_FEC_CAPABILITY_PARITY_BLOCK_ERROR_COUNT_CAPABLE 4:4 /* R-XUF */
#define NV_DPCD14_FEC_CAPABILITY_PARITY_BLOCK_ERROR_COUNT_CAPABLE_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_FEC_CAPABILITY_PARITY_BLOCK_ERROR_COUNT_CAPABLE_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_FEC_CAPABILITY_PARITY_ERROR_COUNT_CAPABLE 5:5 /* R-XUF */
#define NV_DPCD14_FEC_CAPABILITY_PARITY_ERROR_COUNT_CAPABLE_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_FEC_CAPABILITY_PARITY_ERROR_COUNT_CAPABLE_YES (0x00000001) /* R-XUV */
// Bit 6 : RESERVED. Read 0
#define NV_DPCD14_FEC_CAPABILITY_FEC_ERROR_REPORTING_POLICY_SUPPORTED 7:7 /* R-XUF */
#define NV_DPCD14_FEC_CAPABILITY_FEC_ERROR_REPORTING_POLICY_SUPPORTED_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_FEC_CAPABILITY_FEC_ERROR_REPORTING_POLICY_SUPPORTED_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_TRAINING_PATTERN_SET (0x00000102) /* RWXUR */
#define NV_DPCD14_TRAINING_PATTERN_SET_TPS 3:0 /* RWXUF */
#define NV_DPCD14_TRAINING_PATTERN_SET_TPS_NONE (0x00000000) /* RWXUV */
#define NV_DPCD14_TRAINING_PATTERN_SET_TPS_TP1 (0x00000001) /* RWXUV */
#define NV_DPCD14_TRAINING_PATTERN_SET_TPS_TP2 (0x00000002) /* RWXUV */
#define NV_DPCD14_TRAINING_PATTERN_SET_TPS_TP3 (0x00000003) /* RWXUV */
#define NV_DPCD14_TRAINING_PATTERN_SET_TPS_TP4 (0x00000007) /* RWXUV */
#define NV_DPCD14_TRAINING_PATTERN_SET_RECOVERED_CLOCK_OUT_EN 4:4 /* RWXUF */
#define NV_DPCD14_TRAINING_PATTERN_SET_RECOVERED_CLOCK_OUT_EN_NO (0x00000000) /* RWXUV */
#define NV_DPCD14_TRAINING_PATTERN_SET_RECOVERED_CLOCK_OUT_EN_YES (0x00000001) /* RWXUV */
#define NV_DPCD14_TRAINING_PATTERN_SET_SCRAMBLING_DISABLED 5:5 /* RWXUF */
#define NV_DPCD14_TRAINING_PATTERN_SET_SCRAMBLING_DISABLED_FALSE (0x00000000) /* RWXUV */
#define NV_DPCD14_TRAINING_PATTERN_SET_SCRAMBLING_DISABLED_TRUE (0x00000001) /* RWXUV */
#define NV_DPCD14_TRAINING_PATTERN_SET_SYM_ERR_SEL 7:6 /* RWXUF */
#define NV_DPCD14_TRAINING_PATTERN_SET_SYM_ERR_SEL_DISPARITY_ILLEGAL_SYMBOL_ERROR (0x00000000) /* RWXUV */
#define NV_DPCD14_TRAINING_PATTERN_SET_SYM_ERR_SEL_DISPARITY_ERROR (0x00000001) /* RWXUV */
#define NV_DPCD14_TRAINING_PATTERN_SET_SYM_ERR_SEL_ILLEGAL_SYMBOL_ERROR (0x00000002) /* RWXUV */
// Field definition only used only with 128b/132b for DP2.0+
#define NV_DPCD20_128B_132B_TRAINING_PATTERN (0x00000102) /* RWXUR */
#define NV_DPCD20_128B_132B_TRAINING_PATTERN_SELECT 3:0 /* RWXUF */
#define NV_DPCD20_128B_132B_TRAINING_PATTERN_SELECT_NONE (0x00000000) /* RWXUV */
#define NV_DPCD20_128B_132B_TRAINING_PATTERN_SELECT_TPS1 (0x00000001) /* RWXUV */
#define NV_DPCD20_128B_132B_TRAINING_PATTERN_SELECT_TPS2 (0x00000002) /* RWXUV */
#define NV_DPCD20_128B_132B_TRAINING_PATTERN_SELECT_TPS2_CDS (0x00000003) /* RWXUV */
// Note: Bit 7:4 are reserved for 128b/132b. Driver should keep them 0
#define NV_DPCD14_LINK_QUAL_LANE_SET(i) (0x0000010B+(i)) /* RW-1A */
#define NV_DPCD14_LINK_QUAL_LANE_SET__SIZE 4 /* R---S */
#define NV_DPCD14_LINK_QUAL_LANE_SET_LQS 2:0 /* RWXUF */
#define NV_DPCD14_LINK_QUAL_LANE_SET_LQS_CP2520PAT3 (0x00000007) /* RWXUV */
#define NV_DPCD14_FEC_CONFIGURATION (0x00000120) /* RWXUR */
#define NV_DPCD14_FEC_CONFIGURATION_FEC_READY 0:0 /* RWXUF */
#define NV_DPCD14_FEC_CONFIGURATION_FEC_READY_NO (0x00000000) /* RWXUV */
#define NV_DPCD14_FEC_CONFIGURATION_FEC_READY_YES (0x00000001) /* RWXUV */
#define NV_DPCD14_FEC_CONFIGURATION_FEC_ERROR_COUNT_SEL 3:1 /* RWXUF */
#define NV_DPCD14_FEC_CONFIGURATION_FEC_ERROR_COUNT_SEL_FEC_ERROR_COUNT_DIS (0x00000000) /* RWXUV */
#define NV_DPCD14_FEC_CONFIGURATION_FEC_ERROR_COUNT_SEL_UNCORRECTED_BLOCK_ERROR_COUNT (0x00000001) /* RWXUV */
#define NV_DPCD14_FEC_CONFIGURATION_FEC_ERROR_COUNT_SEL_CORRECTED_BLOCK_ERROR_COUNT (0x00000002) /* RWXUV */
#define NV_DPCD14_FEC_CONFIGURATION_FEC_ERROR_COUNT_SEL_BIT_ERROR_COUNT (0x00000003) /* RWXUV */
#define NV_DPCD14_FEC_CONFIGURATION_FEC_ERROR_COUNT_SEL_PARITY_BLOCK_ERROR_COUNT (0x00000004) /* RWXUV */
#define NV_DPCD14_FEC_CONFIGURATION_FEC_ERROR_COUNT_SEL_PARITY_BIT_ERROR_COUNT (0x00000005) /* RWXUV */
#define NV_DPCD14_FEC_CONFIGURATION_LANE_SELECT 5:4 /* RWXUF */
#define NV_DPCD14_FEC_CONFIGURATION_LANE_SELECT_LANE_0 (0x00000000) /* RWXUV */
#define NV_DPCD14_FEC_CONFIGURATION_LANE_SELECT_LANE_1 (0x00000001) /* RWXUV */
#define NV_DPCD14_FEC_CONFIGURATION_LANE_SELECT_LANE_2 (0x00000002) /* RWXUV */
#define NV_DPCD14_FEC_CONFIGURATION_LANE_SELECT_LANE_3 (0x00000003) /* RWXUV */
// Field definition only used only with 128b/132b for DP2.0+
#define NV_DPCD20_LANE_ALIGN_STATUS_UPDATED (0x00000204) /* R-XUR */
#define NV_DPCD20_LANE_ALIGN_STATUS_UPDATED_128B_132B_DPRX_EQ_INTERLANE_ALIGN_DONE 2:2 /* R-XUF */
#define NV_DPCD20_LANE_ALIGN_STATUS_UPDATED_128B_132B_DPRX_EQ_INTERLANE_ALIGN_DONE_NO (0x00000000) /* R-XUV */
#define NV_DPCD20_LANE_ALIGN_STATUS_UPDATED_128B_132B_DPRX_EQ_INTERLANE_ALIGN_DONE_YES (0x00000001) /* R-XUV */
#define NV_DPCD20_LANE_ALIGN_STATUS_UPDATED_128B_132B_DPRX_CDS_INTERLANE_ALIGN_DONE 3:3 /* R-XUF */
#define NV_DPCD20_LANE_ALIGN_STATUS_UPDATED_128B_132B_DPRX_CDS_INTERLANE_ALIGN_DONE_NO (0x00000000) /* R-XUV */
#define NV_DPCD20_LANE_ALIGN_STATUS_UPDATED_128B_132B_DPRX_CDS_INTERLANE_ALIGN_DONE_YES (0x00000001) /* R-XUV */
#define NV_DPCD20_LANE_ALIGN_STATUS_UPDATED_128B_132B_LT_FAILED 4:4 /* R-XUF */
#define NV_DPCD20_LANE_ALIGN_STATUS_UPDATED_128B_132B_LT_FAILED_NO (0x00000000) /* R-XUV */
#define NV_DPCD20_LANE_ALIGN_STATUS_UPDATED_128B_132B_LT_FAILED_YES (0x00000001) /* R-XUV */
// Field definition for 0x0206/0x0207h (ADJUST_REQUEST_LANEX), only used only with 128b/132b for DP2.0+
#define NV_DPCD20_LANEX_XPLUS1_ADJUST_REQ_LANEX_TX_FFE_PRESET_VALUE 3:0 /* R-XUF */
#define NV_DPCD20_LANEX_XPLUS1_ADJUST_REQ_LANEXPLUS1_TX_FFE_PRESET_VALUE 7:4 /* R-XUF */
// PANEL REPLAY RELATED DPCD
#define NV_DPCD20_PANEL_REPLAY_CAPABILITY (0x000000B0)
#define NV_DPCD20_PANEL_REPLAY_CAPABILITY_SUPPORTED 0:0
#define NV_DPCD20_PANEL_REPLAY_CAPABILITY_SUPPORTED_NO (0x00000000)
#define NV_DPCD20_PANEL_REPLAY_CAPABILITY_SUPPORTED_YES (0x00000001)
#define NV_DPCD20_PANEL_REPLAY_CAPABILITY_SEL_UPDATE 1:1
#define NV_DPCD20_PANEL_REPLAY_CAPABILITY_SEL_UPDATE_NO (0x00000000)
#define NV_DPCD20_PANEL_REPLAY_CAPABILITY_SEL_UPDATE_YES (0x00000001)
#define NV_DPCD20_PANEL_REPLAY_CONFIGURATION (0x000001B0)
#define NV_DPCD20_PANEL_REPLAY_CONFIGURATION_ENABLE_PR_MODE 0:0
#define NV_DPCD20_PANEL_REPLAY_CONFIGURATION_ENABLE_PR_MODE_NO (0x00000000)
#define NV_DPCD20_PANEL_REPLAY_CONFIGURATION_ENABLE_PR_MODE_YES (0x00000001)
#define NV_DPCD14_PHY_TEST_PATTERN (0x00000248) /* R-XUR */
#define NV_DPCD14_PHY_TEST_PATTERN_SEL_CP2520PAT3 (0x00000007) /* R-XUV */
#define NV_DPCD14_DSC_CRC_0 (0x00000262) /* R-XUR */
#define NV_DPCD14_DSC_CRC_0_LOW_BYTE NV_DPCD14_DSC_CRC_0
#define NV_DPCD14_DSC_CRC_0_HIGH_BYTE (0x00000263) /* R-XUR */
#define NV_DPCD14_DSC_CRC_1 (0x00000264) /* R-XUR */
#define NV_DPCD14_DSC_CRC_1_LOW_BYTE NV_DPCD14_DSC_CRC_1
#define NV_DPCD14_DSC_CRC_1_HIGH_BYTE (0x00000265) /* R-XUR */
#define NV_DPCD14_DSC_CRC_2 (0x00000266) /* R-XUR */
#define NV_DPCD14_DSC_CRC_2_LOW_BYTE NV_DPCD14_DSC_CRC_2
#define NV_DPCD14_DSC_CRC_2_HIGH_BYTE (0x00000267) /* R-XUR */
#define NV_DPCD14_FEC_STATUS (0x00000280) /* R-XUR */
#define NV_DPCD14_FEC_STATUS_FEC_DECODE_EN_DETECTED 0:0 /* R-XUF */
#define NV_DPCD14_FEC_STATUS_FEC_DECODE_EN_DETECTED_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_FEC_STATUS_FEC_DECODE_EN_DETECTED_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_FEC_STATUS_FEC_DECODE_DIS_DETECTED 1:1 /* R-XUF */
#define NV_DPCD14_FEC_STATUS_FEC_DECODE_DIS_DETECTED_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_FEC_STATUS_FEC_DECODE_DIS_DETECTED_YES (0x00000001) /* R-XUV */
// Bits 7-2: RESERVED.
#define NV_DPCD14_FEC_STATUS_CLEAR (0x00000001)
#define NV_DPCD14_FEC_ERROR_COUNT (0x00000281) /* R-XUR */
#define NV_DPCD14_FEC_ERROR_COUNT_FEC_ERROR_COUNT_LOW_BYTE NV_DPCD14_FEC_ERROR_COUNT
#define NV_DPCD14_FEC_ERROR_COUNT_FEC_ERROR_COUNT_HIGH_BYTE (0x00000282) /* R-XUR */
#define NV_DPCD14_FEC_ERROR_COUNT_FEC_ERROR_COUNT_VALID 7:7 /* R-XUF */
#define NV_DPCD14_FEC_ERROR_COUNT_FEC_ERROR_COUNT_VALID_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_FEC_ERROR_COUNT_FEC_ERROR_COUNT_VALID_YES (0x00000001) /* R-XUV */
// Field definition for 0x0200E (LANE_ALIGN_STATUS_UPDATED_ESI), used only when DP2.0+ 128b/132b is enabled.
#define NV_DPCD20_LANE_ALIGN_STATUS_UPDATED_ESI (0x0000200E) /* R-XUR */
#define NV_DPCD20_LANE_ALIGN_STATUS_UPDATED_ESI_128B_132B_DPRX_EQ_INTERLANE_ALIGN_DONE 2:2 /* R-XUF */
#define NV_DPCD20_LANE_ALIGN_STATUS_UPDATED_ESI_128B_132B_DPRX_EQ_INTERLANE_ALIGN_DONE_NO (0x00000000) /* R-XUV */
#define NV_DPCD20_LANE_ALIGN_STATUS_UPDATED_ESI_128B_132B_DPRX_EQ_INTERLANE_ALIGN_DONE_YES (0x00000001) /* R-XUV */
#define NV_DPCD20_LANE_ALIGN_STATUS_UPDATED_ESI_128B_132B_DPRX_CDS_INTERLANE_ALIGN_DONE 3:3 /* R-XUF */
#define NV_DPCD20_LANE_ALIGN_STATUS_UPDATED_ESI_128B_132B_DPRX_CDS_INTERLANE_ALIGN_DONE_NO (0x00000000) /* R-XUV */
#define NV_DPCD20_LANE_ALIGN_STATUS_UPDATED_ESI_128B_132B_DPRX_CDS_INTERLANE_ALIGN_DONE_YES (0x00000001) /* R-XUV */
#define NV_DPCD20_LANE_ALIGN_STATUS_UPDATED_ESI_128B_132B_LT_FAILED 4:4 /* R-XUF */
#define NV_DPCD20_LANE_ALIGN_STATUS_UPDATED_ESI_128B_132B_LT_FAILED_NO (0x00000000) /* R-XUV */
#define NV_DPCD20_LANE_ALIGN_STATUS_UPDATED_ESI_128B_132B_LT_FAILED_YES (0x00000001) /* R-XUV */
// Field definition for 0x0200F (SINK_STATUS_ESI), used only when DP2.0+ 128b/132b is enabled.
#define NV_DPCD20_SINK_STATUS_ESI (0x0000200F) /* R-XUR */
#define NV_DPCD20_SINK_STATUS_ESI_INTRA_HOP_AUX_REPLY 3:3 /* R-XUF */
#define NV_DPCD20_SINK_STATUS_ESI_INTRA_HOP_AUX_REPLY_DPRX (0x00000000) /* R-XUV */
#define NV_DPCD20_SINK_STATUS_ESI_INTRA_HOP_AUX_REPLY_LTTPR (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_REV (0x00002200) /* R-XUR */
#define NV_DPCD14_EXTENDED_REV_MAJOR 7:4 /* R-XUF */
#define NV_DPCD14_EXTENDED_REV_MAJOR_1 (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_REV_MINOR 3:0 /* R-XUF */
#define NV_DPCD14_EXTENDED_REV_MINOR_4 (0x00000004) /* R-XUV */
#define NV_DPCD14_EXTENDED_MAX_LINK_BANDWIDTH (0x00002201) /* R-XUR */
#define NV_DPCD14_EXTENDED_MAX_LINK_BANDWIDTH_VAL 7:0 /* R-XUF */
#define NV_DPCD14_EXTENDED_MAX_LINK_BANDWIDTH_VAL_8_10_GBPS (0x0000001E) /* R-XUV */
#define NV_DPCD14_EXTENDED_MAX_LANE_COUNT (0x00002202) /* R-XUR */
#define NV_DPCD14_EXTENDED_MAX_LANE_COUNT_LANE 4:0 /* R-XUF */
#define NV_DPCD14_EXTENDED_MAX_LANE_COUNT_LANE_1 (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_MAX_LANE_COUNT_LANE_2 (0x00000002) /* R-XUV */
#define NV_DPCD14_EXTENDED_MAX_LANE_COUNT_LANE_4 (0x00000004) /* R-XUV */
#define NV_DPCD14_EXTENDED_MAX_LANE_COUNT_POST_LT_ADJ_REQ_SUPPORT 5:5 /* R-XUF */
#define NV_DPCD14_EXTENDED_MAX_LANE_COUNT_POST_LT_ADJ_REQ_SUPPORT_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_MAX_LANE_COUNT_POST_LT_ADJ_REQ_SUPPORT_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_MAX_LANE_COUNT_TPS3_SUPPORTED 6:6 /* R-XUF */
#define NV_DPCD14_EXTENDED_MAX_LANE_COUNT_TPS3_SUPPORTED_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_MAX_LANE_COUNT_TPS3_SUPPORTED_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_MAX_LANE_COUNT_ENHANCED_FRAMING 7:7 /* R-XUF */
#define NV_DPCD14_EXTENDED_MAX_LANE_COUNT_ENHANCED_FRAMING_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_MAX_LANE_COUNT_ENHANCED_FRAMING_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_MAX_DOWNSPREAD (0x00002203) /* R-XUR */
#define NV_DPCD14_EXTENDED_MAX_DOWNSPREAD_VAL 0:0 /* R-XUF */
#define NV_DPCD14_EXTENDED_MAX_DOWNSPREAD_VAL_NONE (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_MAX_DOWNSPREAD_VAL_0_5_PCT (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_MAX_DOWNSPREAD_NO_AUX_HANDSHAKE_LT 6:6 /* R-XUF */
#define NV_DPCD14_EXTENDED_MAX_DOWNSPREAD_NO_AUX_HANDSHAKE_LT_FALSE (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_MAX_DOWNSPREAD_NO_AUX_HANDSHAKE_LT_TRUE (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_MAX_DOWNSPREAD_TPS4_SUPPORTED 7:7 /* R-XUF */
#define NV_DPCD14_EXTENDED_MAX_DOWNSPREAD_TPS4_SUPPORTED_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_MAX_DOWNSPREAD_TPS4_SUPPORTED_YES (0x00000001) /* R-XUV */
// NORP = Number of Receiver Ports = Value + 1
#define NV_DPCD14_EXTENDED_NORP (0x00002204) /* R-XUR */
#define NV_DPCD14_EXTENDED_NORP_VAL 0:0 /* R-XUF */
#define NV_DPCD14_EXTENDED_NORP_VAL_ONE (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_NORP_VAL_TWO (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_NORP_VAL_SST_MAX (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_NORP_DP_PWR_CAP_5V 5:5 /* R-XUF */
#define NV_DPCD14_EXTENDED_NORP_DP_PWR_CAP_12V 6:6 /* R-XUF */
#define NV_DPCD14_EXTENDED_NORP_DP_PWR_CAP_18V 7:7 /* R-XUF */
#define NV_DPCD14_EXTENDED_DOWNSTREAMPORT (0x00002205) /* R-XUR */
#define NV_DPCD14_EXTENDED_DOWNSTREAMPORT_PRESENT 0:0 /* R-XUF */
#define NV_DPCD14_EXTENDED_DOWNSTREAMPORT_PRESENT_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_DOWNSTREAMPORT_PRESENT_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_DOWNSTREAMPORT_TYPE 2:1 /* R-XUF */
#define NV_DPCD14_EXTENDED_DOWNSTREAMPORT_TYPE_DISPLAYPORT (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_DOWNSTREAMPORT_TYPE_ANALOG (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_DOWNSTREAMPORT_TYPE_HDMI_DVI (0x00000002) /* R-XUV */
#define NV_DPCD14_EXTENDED_DOWNSTREAMPORT_TYPE_OTHERS (0x00000003) /* R-XUV */
#define NV_DPCD14_EXTENDED_DOWNSTREAMPORT_FORMAT_CONVERSION 3:3 /* R-XUF */
#define NV_DPCD14_EXTENDED_DOWNSTREAMPORT_FORMAT_CONVERSION_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_DOWNSTREAMPORT_FORMAT_CONVERSION_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_DOWNSTREAMPORT_DETAILED_CAP_INFO_AVAILABLE 4:4 /* R-XUF */
#define NV_DPCD14_EXTENDED_DOWNSTREAMPORT_DETAILED_CAP_INFO_AVAILABLE_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_DOWNSTREAMPORT_DETAILED_CAP_INFO_AVAILABLE_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_MAIN_LINK_CHANNEL_CODING (0x00002206) /* R-XUR */
#define NV_DPCD14_EXTENDED_MAIN_LINK_CHANNEL_CODING_ANSI_8B_10B 0:0 /* R-XUF */
#define NV_DPCD14_EXTENDED_MAIN_LINK_CHANNEL_CODING_ANSI_8B_10B_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_MAIN_LINK_CHANNEL_CODING_ANSI_8B_10B_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_MAIN_LINK_CHANNEL_CODING_ANSI_128B_132B 1:1 /* R-XUF */
#define NV_DPCD14_EXTENDED_MAIN_LINK_CHANNEL_CODING_ANSI_128B_132B_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_MAIN_LINK_CHANNEL_CODING_ANSI_128B_132B_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_DOWN_STREAM_PORT (0x00002207) /* R-XUR */
#define NV_DPCD14_EXTENDED_DOWN_STREAM_PORT_COUNT 3:0 /* R-XUF */
#define NV_DPCD14_EXTENDED_DOWN_STREAM_PORT_MSA_TIMING_PAR_IGNORED 6:6 /* R-XUF */
#define NV_DPCD14_EXTENDED_DOWN_STREAM_PORT_MSA_TIMING_PAR_IGNORED_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_DOWN_STREAM_PORT_MSA_TIMING_PAR_IGNORED_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_DOWN_STREAM_PORT_OUI_SUPPORT 7:7 /* R-XUF */
#define NV_DPCD14_EXTENDED_DOWN_STREAM_PORT_OUI_SUPPORT_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_DOWN_STREAM_PORT_OUI_SUPPORT_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_RECEIVE_PORT0_CAP_0 (0x00002208) /* R-XUR */
#define NV_DPCD14_EXTENDED_RECEIVE_PORT1_CAP_0 (0x0000220A) /* R-XUR */
#define NV_DPCD14_EXTENDED_RECEIVE_PORTX_CAP_0_LOCAL_EDID 1:1 /* R-XUF */
#define NV_DPCD14_EXTENDED_RECEIVE_PORTX_CAP_0_LOCAL_EDID_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_RECEIVE_PORTX_CAP_0_LOCAL_EDID_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_RECEIVE_PORTX_CAP_0_ASSO_TO_PRECEDING_PORT 2:2 /* R-XUF */
#define NV_DPCD14_EXTENDED_RECEIVE_PORTX_CAP_0_ASSO_TO_PRECEDING_PORT_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_RECEIVE_PORTX_CAP_0_ASSO_TO_PRECEDING_PORT_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_RECEIVE_PORTX_CAP_0_HBLANK_EXPANSION_CAPABLE 3:3 /* R-XUF */
#define NV_DPCD14_EXTENDED_RECEIVE_PORTX_CAP_0_HBLANK_EXPANSION_CAPABLE_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_RECEIVE_PORTX_CAP_0_HBLANK_EXPANSION_CAPABLE_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_RECEIVE_PORTX_CAP_0_BUFFER_SIZE_UNIT 4:4 /* R-XUF */
#define NV_DPCD14_EXTENDED_RECEIVE_PORTX_CAP_0_BUFFER_SIZE_UNIT_PIXEL (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_RECEIVE_PORTX_CAP_0_BUFFER_SIZE_UNIT_BYTE (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_RECEIVE_PORTX_CAP_0_BUFFER_SIZE_PER_PORT 5:5 /* R-XUF */
#define NV_DPCD14_EXTENDED_RECEIVE_PORTX_CAP_0_BUFFER_SIZE_PER_PORT_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_RECEIVE_PORTX_CAP_0_BUFFER_SIZE_PER_PORT_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_RECEIVE_PORT0_CAP_1 (0x00002209) /* R-XUR */
#define NV_DPCD14_EXTENDED_RECEIVE_PORT1_CAP_1 (0x0000220B) /* R-XUR */
#define NV_DPCD14_EXTENDED_RECEIVE_PORTX_CAP_1_BUFFER_SIZE 7:0 /* R-XUF */
#define NV_DPCD14_EXTENDED_I2C_CTRL_CAP (0x0000220C) /* R-XUR */
#define NV_DPCD14_EXTENDED_I2C_CTRL_CAP_SPEED 7:0 /* R-XUF */
#define NV_DPCD14_EXTENDED_I2C_CTRL_CAP_SPEED_1K (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_I2C_CTRL_CAP_SPEED_5K (0x00000002) /* R-XUV */
#define NV_DPCD14_EXTENDED_I2C_CTRL_CAP_SPEED_10K (0x00000004) /* R-XUV */
#define NV_DPCD14_EXTENDED_I2C_CTRL_CAP_SPEED_100K (0x00000008) /* R-XUV */
#define NV_DPCD14_EXTENDED_I2C_CTRL_CAP_SPEED_400K (0x00000010) /* R-XUV */
#define NV_DPCD14_EXTENDED_I2C_CTRL_CAP_SPEED_1M (0x00000020) /* R-XUV */
#define NV_DPCD14_EXTENDED_EDP_CONFIG_CAP (0x0000220D) /* R-XUR */
#define NV_DPCD14_EXTENDED_EDP_CONFIG_CAP_ALTERNATE_SCRAMBLER_RESET 0:0 /* R-XUF */
#define NV_DPCD14_EXTENDED_EDP_CONFIG_CAP_ALTERNATE_SCRAMBLER_RESET_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_EDP_CONFIG_CAP_ALTERNATE_SCRAMBLER_RESET_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_TRAINING_AUX_RD_INTERVAL (0x0000220E) /* R-XUR */
#define NV_DPCD14_EXTENDED_TRAINING_AUX_RD_INTERVAL_VAL 6:0 /* R-XUF */
#define NV_DPCD14_EXTENDED_TRAINING_AUX_RD_INTERVAL_VAL_DEFAULT (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_TRAINING_AUX_RD_INTERVAL_VAL_4MS (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_TRAINING_AUX_RD_INTERVAL_VAL_8MS (0x00000002) /* R-XUV */
#define NV_DPCD14_EXTENDED_TRAINING_AUX_RD_INTERVAL_VAL_12MS (0x00000003) /* R-XUV */
#define NV_DPCD14_EXTENDED_TRAINING_AUX_RD_INTERVAL_VAL_16MS (0x00000004) /* R-XUV */
#define NV_DPCD14_EXTENDED_TRAINING_AUX_RD_INTERVAL_EXTENDED_RECEIVER_CAP 7:7 /* R-XUF */
#define NV_DPCD14_EXTENDED_TRAINING_AUX_RD_INTERVAL_EXTENDED_RECEIVER_CAP_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_TRAINING_AUX_RD_INTERVAL_EXTENDED_RECEIVER_CAP_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_ADAPTER_CAP (0x0000220F) /* R-XUR */
#define NV_DPCD14_EXTENDED_ADAPTER_CAP_FORCE_LOAD_SENSE 0:0 /* R-XUF */
#define NV_DPCD14_EXTENDED_ADAPTER_CAP_FORCE_LOAD_SENSE_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_ADAPTER_CAP_FORCE_LOAD_SENSE_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_ADAPTER_CAP_ALT_I2C_PATTERN 1:1 /* R-XUF */
#define NV_DPCD14_EXTENDED_ADAPTER_CAP_ALT_I2C_PATTERN_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_ADAPTER_CAP_ALT_I2C_PATTERN_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_DPRX_FEATURE_ENUM_LIST (0x00002210) /* R-XUR */
#define NV_DPCD14_EXTENDED_DPRX_FEATURE_ENUM_LIST_GTC_CAP 0:0 /* R-XUF */
#define NV_DPCD14_EXTENDED_DPRX_FEATURE_ENUM_LIST_GTC_CAP_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_DPRX_FEATURE_ENUM_LIST_GTC_CAP_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_DPRX_FEATURE_ENUM_LIST_AV_SYNC_CAP 2:2 /* R-XUF */
#define NV_DPCD14_EXTENDED_DPRX_FEATURE_ENUM_LIST_AV_SYNC_CAP_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_DPRX_FEATURE_ENUM_LIST_AV_SYNC_CAP_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_DPRX_FEATURE_ENUM_LIST_VSC_SDP_EXT_FOR_COLORIMETRY 3:3 /* R-XUF */
#define NV_DPCD14_EXTENDED_DPRX_FEATURE_ENUM_LIST_VSC_SDP_EXT_FOR_COLORIMETRY_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_DPRX_FEATURE_ENUM_LIST_VSC_SDP_EXT_FOR_COLORIMETRY_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_DPRX_FEATURE_ENUM_LIST_VSC_EXT_VESA_SDP 4:4 /* R-XUF */
#define NV_DPCD14_EXTENDED_DPRX_FEATURE_ENUM_LIST_VSC_EXT_VESA_SDP_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_DPRX_FEATURE_ENUM_LIST_VSC_EXT_VESA_SDP_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_DPRX_FEATURE_ENUM_LIST_VSC_EXT_VESA_SDP_CHAINING 5:5 /* R-XUF */
#define NV_DPCD14_EXTENDED_DPRX_FEATURE_ENUM_LIST_VSC_EXT_VESA_SDP_CHAINING_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_DPRX_FEATURE_ENUM_LIST_VSC_EXT_VESA_SDP_CHAINING_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_DPRX_FEATURE_ENUM_LIST_VSC_EXT_CTA_SDP 6:6 /* R-XUF */
#define NV_DPCD14_EXTENDED_DPRX_FEATURE_ENUM_LIST_VSC_EXT_CTA_SDP_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_DPRX_FEATURE_ENUM_LIST_VSC_EXT_CTA_SDP_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_DPRX_FEATURE_ENUM_LIST_VSC_EXT_CTA_SDP_CHAINING 7:7 /* R-XUF */
#define NV_DPCD14_EXTENDED_DPRX_FEATURE_ENUM_LIST_VSC_EXT_CTA_SDP_CHAINING_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_DPRX_FEATURE_ENUM_LIST_VSC_EXT_CTA_SDP_CHAINING_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_DPRX_SLEEP_WAKE_TIMEOUT_REQUEST (0x00002211) /* R-XUR */
#define NV_DPCD14_EXTENDED_DPRX_SLEEP_WAKE_TIMEOUT_REQUEST_PERIOD 7:0 /* R-XUF */
#define NV_DPCD14_EXTENDED_DPRX_SLEEP_WAKE_TIMEOUT_REQUEST_PERIOD_1MS (0x00000000) /* R-XUV */
#define NV_DPCD14_EXTENDED_DPRX_SLEEP_WAKE_TIMEOUT_REQUEST_PERIOD_20MS (0x00000001) /* R-XUV */
#define NV_DPCD14_EXTENDED_DPRX_SLEEP_WAKE_TIMEOUT_REQUEST_PERIOD_40MS (0x00000002) /* R-XUV */
#define NV_DPCD14_EXTENDED_DPRX_SLEEP_WAKE_TIMEOUT_REQUEST_PERIOD_60MS (0x00000003) /* R-XUV */
#define NV_DPCD14_EXTENDED_DPRX_SLEEP_WAKE_TIMEOUT_REQUEST_PERIOD_80MS (0x00000004) /* R-XUV */
#define NV_DPCD14_EXTENDED_DPRX_SLEEP_WAKE_TIMEOUT_REQUEST_PERIOD_100MS (0x00000005) /* R-XUV */
#define NV_DPCD14_EXTENDED_VSC_EXT_VESA_SDP_MAX_CHAINING (0x00002212) /* R-XUR */
#define NV_DPCD14_EXTENDED_VSC_EXT_VESA_SDP_MAX_CHAINING_VAL 7:0 /* R-XUF */
#define NV_DPCD14_EXTENDED_VSC_EXT_CTA_SDP_MAX_CHAINING (0x00002213) /* R-XUR */
#define NV_DPCD14_EXTENDED_VSC_EXT_CTA_SDP_MAX_CHAINING_VAL 7:0 /* R-XUF */
#define NV_DPCD14_DPRX_FEATURE_ENUM_LIST (0x00002214) /* R-XUR */
#define NV_DPCD14_DPRX_FEATURE_ENUM_LIST_ADAPTIVE_SYNC_SDP_SUPPORTED 0:0 /* R-XUF */
#define NV_DPCD14_DPRX_FEATURE_ENUM_LIST_ADAPTIVE_SYNC_SDP_SUPPORTED_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_DPRX_FEATURE_ENUM_LIST_ADAPTIVE_SYNC_SDP_SUPPORTED_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_DPRX_FEATURE_ENUM_LIST_VSC_EXT_FRAMEWORK_V1_SUPPORTED 4:4 /* R-XUF */
#define NV_DPCD14_DPRX_FEATURE_ENUM_LIST_VSC_EXT_FRAMEWORK_V1_SUPPORTED_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_DPRX_FEATURE_ENUM_LIST_VSC_EXT_FRAMEWORK_V1_SUPPORTED_YES (0x00000001) /* R-XUV */
#define NV_DPCD20_128B_132B_SUPPORTED_LINK_RATES (0x00002215) /* R-XUR */
#define NV_DPCD20_128B_132B_SUPPORTED_LINK_RATES_UHBR10 0:0 /* R-XUF */
#define NV_DPCD20_128B_132B_SUPPORTED_LINK_RATES_UHBR10_NO (0x00000000) /* R-XUV */
#define NV_DPCD20_128B_132B_SUPPORTED_LINK_RATES_UHBR10_YES (0x00000001) /* R-XUV */
#define NV_DPCD20_128B_132B_SUPPORTED_LINK_RATES_UHBR20 1:1 /* R-XUF */
#define NV_DPCD20_128B_132B_SUPPORTED_LINK_RATES_UHBR20_NO (0x00000000) /* R-XUV */
#define NV_DPCD20_128B_132B_SUPPORTED_LINK_RATES_UHBR20_YES (0x00000001) /* R-XUV */
#define NV_DPCD20_128B_132B_SUPPORTED_LINK_RATES_UHBR13_5 2:2 /* R-XUF */
#define NV_DPCD20_128B_132B_SUPPORTED_LINK_RATES_UHBR13_5_NO (0x00000000) /* R-XUV */
#define NV_DPCD20_128B_132B_SUPPORTED_LINK_RATES_UHBR13_5_YES (0x00000001) /* R-XUV */
//
// The interval is (128b/132b_TRAINING_AUX_RD_INTERVAL value + 1) * INTERVAL_UNIT.
// The maximum is 256 ms.
//
#define NV_DPCD20_128B_132B_TRAINING_AUX_RD_INTERVAL (0x00002216) /* R-XUR */
#define NV_DPCD20_128B_132B_TRAINING_AUX_RD_INTERVAL_VAL 6:0 /* R-XUF */
#define NV_DPCD20_128B_132B_TRAINING_AUX_RD_INTERVAL_UNIT 7:7 /* R-XUF */
#define NV_DPCD20_128B_132B_TRAINING_AUX_RD_INTERVAL_UNIT_2MS (0x00000000) /* R-XUV */
#define NV_DPCD20_128B_132B_TRAINING_AUX_RD_INTERVAL_UNIT_1MS (0x00000001) /* R-XUV */
#define NV_DPCD20_128B_132B_TRAINING_AUX_RD_INTERVAL_MAX_MS 256
#define NV_DPCD20_PCON_HDMI_LINK_CONFIG_STATUS (0x00003036) /* R-XUR */
#define NV_DPCD20_PCON_HDMI_LINK_CONFIG_STATUS_MODE 0:0 /* R-XUF */
#define NV_DPCD20_PCON_HDMI_LINK_CONFIG_STATUS_MODE_TMDS (0x00000000) /* R-XUV */
#define NV_DPCD20_PCON_HDMI_LINK_CONFIG_STATUS_MODE_FRL (0x00000001) /* R-XUV */
#define NV_DPCD20_PCON_HDMI_LINK_CONFIG_STATUS_LT_RESULT 6:1 /* R-XUF */
#define NV_DPCD20_PCON_HDMI_LINK_CONFIG_STATUS_LT_RES_9G 1:1 /* R-XUF */
#define NV_DPCD20_PCON_HDMI_LINK_CONFIG_STATUS_LT_RES_9G_NO (0x00000000) /* R-XUV */
#define NV_DPCD20_PCON_HDMI_LINK_CONFIG_STATUS_LT_RES_9G_YES (0x00000001) /* R-XUV */
#define NV_DPCD20_PCON_HDMI_LINK_CONFIG_STATUS_LT_RES_18G 2:2 /* R-XUF */
#define NV_DPCD20_PCON_HDMI_LINK_CONFIG_STATUS_LT_RES_18G_NO (0x00000000) /* R-XUV */
#define NV_DPCD20_PCON_HDMI_LINK_CONFIG_STATUS_LT_RES_18G_YES (0x00000001) /* R-XUV */
#define NV_DPCD20_PCON_HDMI_LINK_CONFIG_STATUS_LT_RES_24G 3:3 /* R-XUF */
#define NV_DPCD20_PCON_HDMI_LINK_CONFIG_STATUS_LT_RES_24G_NO (0x00000000) /* R-XUV */
#define NV_DPCD20_PCON_HDMI_LINK_CONFIG_STATUS_LT_RES_24G_YES (0x00000001) /* R-XUV */
#define NV_DPCD20_PCON_HDMI_LINK_CONFIG_STATUS_LT_RES_32G 4:4 /* R-XUF */
#define NV_DPCD20_PCON_HDMI_LINK_CONFIG_STATUS_LT_RES_32G_NO (0x00000000) /* R-XUV */
#define NV_DPCD20_PCON_HDMI_LINK_CONFIG_STATUS_LT_RES_32G_YES (0x00000001) /* R-XUV */
#define NV_DPCD20_PCON_HDMI_LINK_CONFIG_STATUS_LT_RES_40G 5:5 /* R-XUF */
#define NV_DPCD20_PCON_HDMI_LINK_CONFIG_STATUS_LT_RES_40G_NO (0x00000000) /* R-XUV */
#define NV_DPCD20_PCON_HDMI_LINK_CONFIG_STATUS_LT_RES_40G_YES (0x00000001) /* R-XUV */
#define NV_DPCD20_PCON_HDMI_LINK_CONFIG_STATUS_LT_RES_48G 6:6 /* R-XUF */
#define NV_DPCD20_PCON_HDMI_LINK_CONFIG_STATUS_LT_RES_48G_NO (0x00000000) /* R-XUV */
#define NV_DPCD20_PCON_HDMI_LINK_CONFIG_STATUS_LT_RES_48G_YES (0x00000001) /* R-XUV */
#define NV_DPCD20_PCON_DOWNSTREAM_LINK_ERROR_LANE(i) (0x00003037+(i)) /* RW-1A */
#define NV_DPCD20_PCON_DOWNSTREAM_LINK_ERROR_LANE__SIZE 4 /* R---S */
#define NV_DPCD20_PCON_DOWNSTREAM_LINK_ERROR_LANE_COUNT 3:0 /* R-XUF */
#define NV_DPCD20_PCON_DOWNSTREAM_LINK_ERROR_LANE_COUNT_ZERO (0x00000000) /* R-XUV */
#define NV_DPCD20_PCON_DOWNSTREAM_LINK_ERROR_LANE_COUNT_THREE (0x00000001) /* R-XUV */
#define NV_DPCD20_PCON_DOWNSTREAM_LINK_ERROR_LANE_COUNT_TEN (0x00000002) /* R-XUV */
#define NV_DPCD20_PCON_DOWNSTREAM_LINK_ERROR_LANE_COUNT_HUNDRED (0x00000004) /* R-XUV */
#define NV_DPCD20_PCON_HDMI_TX_LINK_STATUS (0x0000303B) /* R-XUR */
#define NV_DPCD20_PCON_HDMI_TX_LINK_STATUS_LINK_ACTIVE 0:0 /* R-XUF */
#define NV_DPCD20_PCON_HDMI_TX_LINK_STATUS_LINK_ACTIVE_NO (0x00000000) /* R-XUV */
#define NV_DPCD20_PCON_HDMI_TX_LINK_STATUS_LINK_ACTIVE_YES (0x00000001) /* R-XUV */
#define NV_DPCD20_PCON_HDMI_TX_LINK_STATUS_LINK_READY 1:1 /* R-XUF */
#define NV_DPCD20_PCON_HDMI_TX_LINK_STATUS_LINK_READY_NO (0x00000000) /* R-XUV */
#define NV_DPCD20_PCON_HDMI_TX_LINK_STATUS_LINK_READY_YES (0x00000001) /* R-XUV */
#define NV_DPCD20_PCON_CONTROL_0 (0x00003050) /* RWXUR */
#define NV_DPCD20_PCON_CONTROL_0_OUTPUT_CONFIG 0:0 /* RWXUF */
#define NV_DPCD20_PCON_CONTROL_0_OUTPUT_CONFIG_DVI (0x00000000) /* RWXUV */
#define NV_DPCD20_PCON_CONTROL_0_OUTPUT_CONFIG_HDMI (0x00000001) /* RWXUV */
#define NV_DPCD20_PCON_CONTROL_1 (0x00003051) /* RWXUR */
#define NV_DPCD20_PCON_CONTROL_1_CONVERT_YCBCR420 0:0 /* RWXUF */
#define NV_DPCD20_PCON_CONTROL_1_CONVERT_YCBCR420_DISABLE (0x00000000) /* RWXUV */
#define NV_DPCD20_PCON_CONTROL_1_CONVERT_YCBCR420_ENABLE (0x00000001) /* RWXUV */
#define NV_DPCD20_PCON_CONTROL_1_DISABLE_HDMI_EDID_PROCESS 1:1 /* RWXUF */
#define NV_DPCD20_PCON_CONTROL_1_DISABLE_HDMI_EDID_PROCESS_NO (0x00000000) /* RWXUV */
#define NV_DPCD20_PCON_CONTROL_1_DISABLE_HDMI_EDID_PROCESS_YES (0x00000001) /* RWXUV */
#define NV_DPCD20_PCON_CONTROL_1_DISABLE_HDMI_AUTO_SCRAMBLING 2:2 /* RWXUF */
#define NV_DPCD20_PCON_CONTROL_1_DISABLE_HDMI_AUTO_SCRAMBLING_NO (0x00000000) /* RWXUV */
#define NV_DPCD20_PCON_CONTROL_1_DISABLE_HDMI_AUTO_SCRAMBLING_YES (0x00000001) /* RWXUV */
#define NV_DPCD20_PCON_CONTROL_1_DISABLE_HDMI_FORCE_SCRAMBLING 3:3 /* RWXUF */
#define NV_DPCD20_PCON_CONTROL_1_DISABLE_HDMI_FORCE_SCRAMBLING_NO (0x00000000) /* RWXUV */
#define NV_DPCD20_PCON_CONTROL_1_DISABLE_HDMI_FORCE_SCRAMBLING_YES (0x00000001) /* RWXUV */
#define NV_DPCD20_PCON_CONTROL_2 (0x00003052) /* RWXUR */
#define NV_DPCD20_PCON_CONTROL_2_CONVERT_YCBCR422 0:0 /* RWXUF */
#define NV_DPCD20_PCON_CONTROL_2_CONVERT_YCBCR422_DISABLE (0x00000000) /* RWXUV */
#define NV_DPCD20_PCON_CONTROL_2_CONVERT_YCBCR422_ENABLE (0x00000001) /* RWXUV */
#define NV_DPCD20_PCON_CONTROL_3 (0x00003053) /* RWXUR */
#define NV_DPCD20_PCON_CONTROL_3_COMPONENT_BIT_DEPTH 1:0 /* RWXUF */
#define NV_DPCD20_PCON_CONTROL_3_COMPONENT_BIT_DEPTH_SAME_AS_INC (0x00000000) /* RWXUV */
#define NV_DPCD20_PCON_CONTROL_3_COMPONENT_BIT_DEPTH_8BPC (0x00000001) /* RWXUV */
#define NV_DPCD20_PCON_CONTROL_3_COMPONENT_BIT_DEPTH_10BPC (0x00000002) /* RWXUV */
#define NV_DPCD20_PCON_CONTROL_3_COMPONENT_BIT_DEPTH_12BPC (0x00000003) /* RWXUV */
#define NV_DPCD14_OUTPUT_HTOTAL_LOW (0x00003054) /* RWXUR */
#define NV_DPCD14_OUTPUT_HTOTAL_HIGH (0x00003055) /* RWXUR */
#define NV_DPCD14_OUTPUT_HSTART_LOW (0x00003056) /* RWXUR */
#define NV_DPCD14_OUTPUT_HSTART_HIGH (0x00003057) /* RWXUR */
#define NV_DPCD14_OUTPUT_HSP_HSW_LOW (0x00003056) /* RWXUR */
#define NV_DPCD14_OUTPUT_HSP_HSW_HIGH (0x00003057) /* RWXUR */
#define NV_DPCD14_OUTPUT_HSP_HSW_HIGH_VAL 6:0 /* RWXUF */
#define NV_DPCD14_OUTPUT_HSP_HSW_HIGH_OUTPUT_HSP 7:7 /* RWXUF */
#define NV_DPCD14_OUTPUT_HSP_HSW_HIGH_OUTPUT_HSP_POSITIVE (0x00000000) /* RWXUV */
#define NV_DPCD14_OUTPUT_HSP_HSW_HIGH_OUTPUT_HSP_NEGATIVE (0x00000001) /* RWXUV */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_1 (0x0000305A) /* RWXUR */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_1_MAX_LINK_BW 2:0 /* RWXUF */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_1_MAX_LINK_BW_ZERO (0x00000000) /* RWXUV */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_1_MAX_LINK_BW_9G (0x00000001) /* RWXUV */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_1_MAX_LINK_BW_18G (0x00000002) /* RWXUV */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_1_MAX_LINK_BW_24G (0x00000003) /* RWXUV */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_1_MAX_LINK_BW_32G (0x00000004) /* RWXUV */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_1_MAX_LINK_BW_40G (0x00000005) /* RWXUV */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_1_MAX_LINK_BW_48G (0x00000006) /* RWXUV */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_1_SRC_CONTROL_MODE 3:3 /* RWXUF */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_1_SRC_CONTROL_MODE_DISABLE (0x00000000) /* RWXUV */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_1_SRC_CONTROL_MODE_ENABLE (0x00000001) /* RWXUV */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_1_CONCURRENT_LT_MODE 4:4 /* RWXUF */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_1_CONCURRENT_LT_MODE_DISABLE (0x00000000) /* RWXUV */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_1_CONCURRENT_LT_MODE_ENABLE (0x00000001) /* RWXUV */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_1_LINK_FRL_MODE 5:5 /* RWXUF */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_1_LINK_FRL_MODE_DISABLE (0x00000000) /* RWXUV */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_1_LINK_FRL_MODE_ENABLE (0x00000001) /* RWXUV */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_1_IRQ_LINK_FRL_MODE 6:6 /* RWXUF */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_1_IRQ_LINK_FRL_MODE_DISABLE (0x00000000) /* RWXUV */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_1_IRQ_LINK_FRL_MODE_ENABLE (0x00000001) /* RWXUV */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_1_HDMI_LINK 7:7 /* RWXUF */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_1_HDMI_LINK_DISABLE (0x00000000) /* RWXUV */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_1_HDMI_LINK_ENABLE (0x00000001) /* RWXUV */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_2 (0x0000305B) /* RWXUR */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_2_LINK_BW_MASK 5:0 /* RWXUF */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_2_LINK_BW_MASK_9G (0x00000001) /* RWXUV */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_2_LINK_BW_MASK_18G (0x00000002) /* RWXUV */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_2_LINK_BW_MASK_24G (0x00000004) /* RWXUV */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_2_LINK_BW_MASK_32G (0x00000008) /* RWXUV */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_2_LINK_BW_MASK_40G (0x00000010) /* RWXUV */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_2_LINK_BW_MASK_48G (0x00000020) /* RWXUV */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_2_FRL_LT_CONTROL 6:6 /* RWXUF */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_2_FRL_LT_CONTROL_NORMAL (0x00000000) /* RWXUV */
#define NV_DPCD20_PCON_FRL_LINK_CONFIG_2_FRL_LT_CONTROL_EXTENDED (0x00000001) /* RWXUV */
// LT Tunable Repeater Related offsets
#define NV_DPCD14_LT_TUNABLE_PHY_REPEATER_REV (0x000F0000) /* R-XUR */
#define NV_DPCD14_LT_TUNABLE_PHY_REPEATER_REV_MINOR 3:0 /* R-XUF */
#define NV_DPCD14_LT_TUNABLE_PHY_REPEATER_REV_MINOR_0 (0x00000000) /* R-XUV */
#define NV_DPCD14_LT_TUNABLE_PHY_REPEATER_REV_MAJOR 7:4 /* R-XUF */
#define NV_DPCD14_LT_TUNABLE_PHY_REPEATER_REV_MAJOR_1 (0x00000001) /* R-XUV */
#define NV_DPCD14_MAX_LINK_RATE_PHY_REPEATER (0x000F0001) /* R-XUR */
#define NV_DPCD14_MAX_LINK_RATE_PHY_REPEATER_VAL 7:0 /* R-XUF */
#define NV_DPCD14_MAX_LINK_RATE_PHY_REPEATER_VAL_1_62_GBPS (0x00000006) /* R-XUV */
#define NV_DPCD14_MAX_LINK_RATE_PHY_REPEATER_VAL_2_70_GBPS (0x0000000A) /* R-XUV */
#define NV_DPCD14_MAX_LINK_RATE_PHY_REPEATER_VAL_5_40_GBPS (0x00000014) /* R-XUV */
#define NV_DPCD14_MAX_LINK_RATE_PHY_REPEATER_VAL_8_10_GBPS (0x0000001E) /* R-XUV */
#define NV_DPCD14_PHY_REPEATER_CNT (0x000F0002) /* R-XUR */
#define NV_DPCD14_PHY_REPEATER_CNT_VAL 7:0 /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_CNT_VAL_0 (0x00000000) /* R-XUV */
#define NV_DPCD14_PHY_REPEATER_CNT_VAL_1 (0x00000080) /* R-XUV */
#define NV_DPCD14_PHY_REPEATER_CNT_VAL_2 (0x00000040) /* R-XUV */
#define NV_DPCD14_PHY_REPEATER_CNT_VAL_3 (0x00000020) /* R-XUV */
#define NV_DPCD14_PHY_REPEATER_CNT_VAL_4 (0x00000010) /* R-XUV */
#define NV_DPCD14_PHY_REPEATER_CNT_VAL_5 (0x00000008) /* R-XUV */
#define NV_DPCD14_PHY_REPEATER_CNT_VAL_6 (0x00000004) /* R-XUV */
#define NV_DPCD14_PHY_REPEATER_CNT_VAL_7 (0x00000002) /* R-XUV */
#define NV_DPCD14_PHY_REPEATER_CNT_VAL_8 (0x00000001) /* R-XUV */
#define NV_DPCD14_PHY_REPEATER_CNT_MAX 8
#define NV_DPCD14_PHY_REPEATER_MODE (0x000F0003) /* R-XUR */
#define NV_DPCD14_PHY_REPEATER_MODE_VAL_TRANSPARENT (0x00000055) /* R-XUV */
#define NV_DPCD14_PHY_REPEATER_MODE_VAL_NON_TRANSPARENT (0x000000AA) /* R-XUV */
#define NV_DPCD14_MAX_LANE_COUNT_PHY_REPEATER (0x000F0004) /* R-XUR */
#define NV_DPCD14_MAX_LANE_COUNT_PHY_REPEATER_VAL 4:0 /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_EXTENDED_WAKE_TIMEOUT (0x000F0005) /* RWXUR */
#define NV_DPCD14_PHY_REPEATER_EXTENDED_WAKE_TIMEOUT_REQ 6:0 /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_EXTENDED_WAKE_TIMEOUT_GRANT 7:7 /* RWXUF */
#define NV_DPCD14_PHY_REPEATER_MAIN_LINK_CHANNEL_CODING (0x000F0006) /* RWXUR */
#define NV_DPCD14_PHY_REPEATER_MAIN_LINK_CHANNEL_CODING_128B_132B_SUPPORTED 0:0 /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_MAIN_LINK_CHANNEL_CODING_128B_132B_SUPPORTED_NO (0x00000000) /* RWXUF */
#define NV_DPCD14_PHY_REPEATER_MAIN_LINK_CHANNEL_CODING_128B_132B_SUPPORTED_YES (0x00000001) /* RWXUF */
#define NV_DPCD14_PHY_REPEATER_128B_132B_RATES (0x000F0007) /* R-XUR */
#define NV_DPCD14_PHY_REPEATER_128B_132B_RATES_10G_SUPPORTED 0:0 /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_128B_132B_RATES_10G_SUPPORTED_NO (0x00000000) /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_128B_132B_RATES_10G_SUPPORTED_YES (0x00000001) /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_128B_132B_RATES_20G_SUPPORTED 1:1 /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_128B_132B_RATES_20G_SUPPORTED_NO (0x00000000) /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_128B_132B_RATES_20G_SUPPORTED_YES (0x00000001) /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_128B_132B_RATES_13_5G_SUPPORTED 2:2 /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_128B_132B_RATES_13_5G_SUPPORTED_NO (0x00000000) /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_128B_132B_RATES_13_5G_SUPPORTED_YES (0x00000001) /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_EQ_DONE (0x000F0008) /* R-XUR */
#define NV_DPCD14_PHY_REPEATER_EQ_DONE_LTTPR(i) (i):(i) /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_EQ_DONE_LTTPR_NO (0x00000000) /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_EQ_DONE_LTTPR_YES (0x00000001) /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_EQ_DONE_LTTPR_0 0:0 /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_EQ_DONE_LTTPR_0_NO (0x00000000) /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_EQ_DONE_LTTPR_0_YES (0x00000001) /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_EQ_DONE_LTTPR_1 1:1 /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_EQ_DONE_LTTPR_1_NO (0x00000000) /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_EQ_DONE_LTTPR_1_YES (0x00000001) /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_EQ_DONE_LTTPR_2 2:2 /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_EQ_DONE_LTTPR_2_NO (0x00000000) /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_EQ_DONE_LTTPR_2_YES (0x00000001) /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_EQ_DONE_LTTPR_3 3:3 /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_EQ_DONE_LTTPR_3_NO (0x00000000) /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_EQ_DONE_LTTPR_3_YES (0x00000001) /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_EQ_DONE_LTTPR_4 4:4 /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_EQ_DONE_LTTPR_4_NO (0x00000000) /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_EQ_DONE_LTTPR_4_YES (0x00000001) /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_EQ_DONE_LTTPR_5 5:5 /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_EQ_DONE_LTTPR_5_NO (0x00000000) /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_EQ_DONE_LTTPR_5_YES (0x00000001) /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_EQ_DONE_LTTPR_6 6:6 /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_EQ_DONE_LTTPR_6_NO (0x00000000) /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_EQ_DONE_LTTPR_6_YES (0x00000001) /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_EQ_DONE_LTTPR_7 7:7 /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_EQ_DONE_LTTPR_7_NO (0x00000000) /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_EQ_DONE_LTTPR_7_YES (0x00000001) /* R-XUF */
#define NV_DPCD14_PHY_REPEATER_START(i) (0x000F0010+(i)*0x50) /* RW-1A */
#define NV_DPCD14_PHY_REPEATER_START__SIZE 8 /* R---S */
// Following defines are offsets
#define NV_DPCD14_TRAINING_PATTERN_SET_PHY_REPEATER (0x00000000) /* RWXUV */
#define NV_DPCD14_TRAINING_LANE0_SET_PHY_REPEATER (0x00000001) /* RWXUV */
#define NV_DPCD14_TRAINING_LANE1_SET_PHY_REPEATER (0x00000002) /* RWXUV */
#define NV_DPCD14_TRAINING_LANE2_SET_PHY_REPEATER (0x00000003) /* RWXUV */
#define NV_DPCD14_TRAINING_LANE3_SET_PHY_REPEATER (0x00000004) /* RWXUV */
#define NV_DPCD14_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER (0x00000010) /* R-XUR */
#define NV_DPCD14_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER_VAL 6:0 /* R-XUF */
#define NV_DPCD14_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER_VAL_4MS (0x00000001) /* R-XUV */
#define NV_DPCD14_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER_VAL_8MS (0x00000002) /* R-XUV */
#define NV_DPCD14_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER_VAL_12MS (0x00000003) /* R-XUV */
#define NV_DPCD14_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER_VAL_16MS (0x00000004) /* R-XUV */
#define NV_DPCD14_TRANSMITTER_CAP_PHY_REPEATER (0x00000011) /* R-XUR */
#define NV_DPCD14_TRANSMITTER_CAP_PHY_REPEATER_VOLTAGE_SWING_3 0:0 /* R-XUF */
#define NV_DPCD14_TRANSMITTER_CAP_PHY_REPEATER_VOLTAGE_SWING_3_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_TRANSMITTER_CAP_PHY_REPEATER_VOLTAGE_SWING_3_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_TRANSMITTER_CAP_PHY_REPEATER_PRE_EMPHASIS_3 1:1 /* R-XUF */
#define NV_DPCD14_TRANSMITTER_CAP_PHY_REPEATER_PRE_EMPHASIS_3_NO (0x00000000) /* R-XUV */
#define NV_DPCD14_TRANSMITTER_CAP_PHY_REPEATER_PRE_EMPHASIS_3_YES (0x00000001) /* R-XUV */
#define NV_DPCD14_LANE0_1_STATUS_PHY_REPEATER (0x00000020) /* R-XUR */
#define NV_DPCD14_LANE2_3_STATUS_PHY_REPEATER (0x00000021) /* R-XUR */
#define NV_DPCD14_LANE_ALIGN_STATUS_UPDATED_PHY_REPEATER (0x00000022) /* R-XUR */
#define NV_DPCD14_ADJUST_REQUEST_LANE0_1_PHY_REPEATER (0x00000023) /* R-XUR */
#define NV_DPCD14_ADJUST_REQUEST_LANE2_3_PHY_REPEATER (0x00000024) /* R-XUR */
#endif // #ifndef _DISPLAYPORT14_H_

View File

@@ -0,0 +1,46 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 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.
*/
#define NV_DPCD20_DSC_SUPPORT (0x00000060) /* R-XUR */
#define NV_DPCD20_DSC_SUPPORT_PASS_THROUGH_SUPPORT 1:1 /* R-XUF */
#define NV_DPCD20_DSC_SUPPORT_PASS_THROUGH_SUPPORT_NO (0x00000000) /* R-XUV */
#define NV_DPCD20_DSC_SUPPORT_PASS_THROUGH_SUPPORT_YES (0x00000001) /* R-XUV */
#define NV_DPCD20_DSC_PASS_THROUGH (0x00000160) /* R-XUR */
#define NV_DPCD20_DSC_PASS_THROUGH_ENABLE 1:1 /* R-XUF */
#define NV_DPCD20_DSC_PASS_THROUGH_ENABLE_NO (0x00000000) /* R-XUV */
#define NV_DPCD20_DSC_PASS_THROUGH_ENABLE_YES (0x00000001) /* R-XUV */
// PANEL REPLAY RELATED DPCD
#define NV_DPCD20_PANEL_REPLAY_CAPABILITY (0x000000B0)
#define NV_DPCD20_PANEL_REPLAY_CAPABILITY_SUPPORTED 0:0
#define NV_DPCD20_PANEL_REPLAY_CAPABILITY_SUPPORTED_NO (0x00000000)
#define NV_DPCD20_PANEL_REPLAY_CAPABILITY_SUPPORTED_YES (0x00000001)
#define NV_DPCD20_PANEL_REPLAY_CAPABILITY_SEL_UPDATE 1:1
#define NV_DPCD20_PANEL_REPLAY_CAPABILITY_SEL_UPDATE_NO (0x00000000)
#define NV_DPCD20_PANEL_REPLAY_CAPABILITY_SEL_UPDATE_YES (0x00000001)
#define NV_DPCD20_PANEL_REPLAY_CONFIGURATION (0x000001B0)
#define NV_DPCD20_PANEL_REPLAY_CONFIGURATION_ENABLE_PR_MODE 0:0
#define NV_DPCD20_PANEL_REPLAY_CONFIGURATION_ENABLE_PR_MODE_NO (0x00000000)
#define NV_DPCD20_PANEL_REPLAY_CONFIGURATION_ENABLE_PR_MODE_YES (0x00000001)

View File

@@ -0,0 +1,86 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2019 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.
*/
#ifndef _HDMI_SPEC_H_
#define _HDMI_SPEC_H_
/**************** Resource Manager Defines and Structures ******************\
* *
* Module: HDMI_SPEC.H *
* Defines Common HDMI flags *
* *
\***************************************************************************/
/*
* RM will be moving to separate packet types for DP and HDMI
* since the SDP packet type differ between HDMI and DP. Going forward
* clients are expected to use the respective packet type. Once all the
* clients move to the new data types, we can remove the redundant
* PACKET_TYPE definition.
*/
typedef enum
{
pktType_AudioClkRegeneration = 0x01,
pktType_GeneralControl = 0x03,
pktType_GamutMetadata = 0x0a,
pktType_SRInfoFrame = 0x7f, // Self refresh infoframe for eDP enter/exit self refresh, SRS 1698
pktType_Cea861BInfoFrame = 0x80,
pktType_VendorSpecInfoFrame = 0x81,
pktType_AviInfoFrame = 0x82,
pktType_AudioInfoFrame = 0x84,
pktType_SrcProdDescInfoFrame = 0x83,
pktType_MpegSrcInfoFrame = 0x85,
pktType_DynamicRangeMasteringInfoFrame = 0x87
} PACKET_TYPE;
typedef enum
{
hdmi_pktType_AudioClkRegeneration = 0x01,
hdmi_pktType_GeneralControl = 0x03,
hdmi_pktType_GamutMetadata = 0x0a,
hdmi_pktType_ExtendedMetadata = 0x7f,
hdmi_pktType_Cea861BInfoFrame = 0x80,
hdmi_pktType_VendorSpecInfoFrame = 0x81,
hdmi_pktType_AviInfoFrame = 0x82,
hdmi_pktType_AudioInfoFrame = 0x84,
hdmi_pktType_SrcProdDescInfoFrame = 0x83,
hdmi_pktType_MpegSrcInfoFrame = 0x85,
hdmi_pktType_DynamicRangeMasteringInfoFrame = 0x87
} HDMI_PACKET_TYPE;
#define HDMI_PKT_HDR_SIZE 3
#define HDMI_PKT_AVI_NUM_DBYTES 14
#define HDMI_PKT_AUDIO_NUM_DBYTES 11
#define HDMI_PKT_GENCTRL_NUM_DBYTES 7
#define HDMI_PKT_ACR_NUM_DBYTES 7
#define HDMI_PKT_GAMUT_METADATA_NUM_DBYTES 28
#define HDMI_PKT_VS_MAX_NUM_DBYTES 28
#define HDMI_GENCTRL_PACKET_MUTE_ENABLE 0x01
#define HDMI_GENCTRL_PACKET_MUTE_DISABLE 0x10
#endif // #ifndef _HDMI_SPEC_H_

View File

@@ -0,0 +1,36 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2021 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.
*/
#ifndef NVBINSEGMENT_H
#define NVBINSEGMENT_H
#define PUSH_SEGMENTS
#define POP_SEGMENTS
#define CODE_SEGMENT(__seg)
#define DATA_SEGMENT(__seg)
#define BSS_SEGMENT(__seg)
#define CONS_SEGMENT(__seg)
#define PAGE_SEGMENT
#define NONPAGE_SEGMENT
#endif // NVBINSEGMENT_H

72
src/common/inc/nvBldVer.h Normal file
View File

@@ -0,0 +1,72 @@
#ifndef _NVBLDVER_H_
#define _NVBLDVER_H_
#ifndef NVBLDVER_STRINGIZE
#define NVBLDVER_STRINGIZE(t) #t
#endif
#ifndef STRINGIZE
#define STRINGIZE(t) NVBLDVER_STRINGIZE(t)
#endif
// These variables can be overridden using ENV vars, see nvCommon.nvmk.
// If no env vars are set, then the defaults seen here will be used.
// In DVS builds, the ENV vars are used to control these values.
// Note- the value of NV_BUILD_CL and NV_BUILD_TYPE_NON_BM is only used in
// non-buildmeister builds, see override section below.
// DVS_SW_CHANGELIST has been added to ENV vars in bug 1486673
#ifndef DVS_SW_CHANGELIST
#define DVS_SW_CHANGELIST 0
#endif
#ifndef NV_BUILD_CL
#define NV_BUILD_CL (DVS_SW_CHANGELIST)
#endif
#if NV_BUILD_CL == 0
#define NV_BUILD_CL (DVS_SW_CHANGELIST)
#endif
#ifndef NV_BUILD_TYPE_NON_BM
#define NV_BUILD_TYPE_NON_BM Private
#endif
#ifndef NV_BUILD_AUTHOR
#define NV_BUILD_AUTHOR unknown
#endif
// End ENV var section
// The values of the following strings are set via a buildmeister python script,
// and then checked back in. You cannot make changes to these sections without
// corresponding changes to the buildmeister script
#ifndef NV_BUILD_BRANCH
#define NV_BUILD_BRANCH r515_95
#endif
#ifndef NV_PUBLIC_BRANCH
#define NV_PUBLIC_BRANCH r515_95
#endif
#if defined(NV_LINUX) || defined(NV_BSD) || defined(NV_SUNOS)
#define NV_BUILD_BRANCH_VERSION "rel/gpu_drv/r515/r515_95-155"
#define NV_BUILD_CHANGELIST_NUM (31261195)
#define NV_BUILD_TYPE "Official"
#define NV_BUILD_NAME "rel/gpu_drv/r515/r515_95-155"
#define NV_LAST_OFFICIAL_CHANGELIST_NUM (31261195)
#else /* Windows builds */
#define NV_BUILD_BRANCH_VERSION "r515_95-3"
#define NV_BUILD_CHANGELIST_NUM (31249857)
#define NV_BUILD_TYPE "Official"
#define NV_BUILD_NAME "516.01"
#define NV_LAST_OFFICIAL_CHANGELIST_NUM (31249857)
#endif
// End buildmeister python edited section
// A few of the values are defined differently for non-buildmeister builds,
// this section redefines those defines
#ifndef NV_BUILDMEISTER_BLD
#undef NV_BUILD_TYPE
#define NV_BUILD_TYPE STRINGIZE(NV_BUILD_TYPE_NON_BM)
#undef NV_BUILD_CHANGELIST_NUM
#define NV_BUILD_CHANGELIST_NUM NV_BUILD_CL
#endif
#define NV_DISPLAY_DRIVER_TITLE NV_BUILD_TYPE " " STRINGIZE(NV_BUILD_BRANCH) " " NV_BUILD_NAME " " STRINGIZE(NV_BUILD_AUTHOR)
#endif

View File

@@ -0,0 +1,44 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2015-2021 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.
*/
#ifndef _NV_CPU_UUID_H_
#define _NV_CPU_UUID_H_
#define NV_UUID_LEN 16
typedef struct nv_uuid
{
NvU8 uuid[NV_UUID_LEN];
} NvUuid;
#define NV_UUID_HI(pUuid) (*((NvU64*)((pUuid)->uuid + (NV_UUID_LEN >> 1))))
#define NV_UUID_LO(pUuid) (*((NvU64*)((pUuid)->uuid + 0)))
typedef NvUuid NvSystemUuid;
typedef NvUuid NvProcessorUuid;
extern const NvProcessorUuid NV_PROCESSOR_UUID_CPU_DEFAULT;
#endif // _NV_CPU_UUID_H_

View File

@@ -0,0 +1,134 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2022 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.
*/
/** @file nvHdmiFrlCommon.h
* @brief This file defines data needed for and returned by HDMI 2.1 spec FRL calculations
* It meant to be a spec layer within HDMI lib, without carrying any
* driver/hw related information
*/
#ifndef _NVHDMIFRLCOMMON_H_
#define _NVHDMIFRLCOMMON_H_
#include "nvmisc.h"
//******************************************************************************
// Constants/Structures
//******************************************************************************
#define MAX_RECONSTRUCTED_HACTIVE_PIXELS 2720
// HDMI_BPC: Bits per component enums.
typedef enum tagHDMI_BPC
{
HDMI_BPC8 = 8,
HDMI_BPC10 = 10,
HDMI_BPC12 = 12,
HDMI_BPC16 = 16
} HDMI_BPC;
// HDMI_PIXEL_PACKING: Pixel packing type enums
typedef enum tagHDMI_PIXEL_PACKING
{
HDMI_PIXEL_PACKING_RGB = 0,
HDMI_PIXEL_PACKING_YCbCr444,
HDMI_PIXEL_PACKING_YCbCr422,
HDMI_PIXEL_PACKING_YCbCr420
} HDMI_PIXEL_PACKING;
// HDMI_FRL_DATA_RATE: FRL mode enums
typedef enum tagHDMI_FRL_DATA_RATE
{
HDMI_FRL_DATA_RATE_NONE,
HDMI_FRL_DATA_RATE_3LANES_3GBPS,
HDMI_FRL_DATA_RATE_3LANES_6GBPS,
HDMI_FRL_DATA_RATE_4LANES_6GBPS,
HDMI_FRL_DATA_RATE_4LANES_8GBPS,
HDMI_FRL_DATA_RATE_4LANES_10GBPS,
HDMI_FRL_DATA_RATE_4LANES_12GBPS,
HDMI_FRL_DATA_RATE_UNSPECIFIED
} HDMI_FRL_DATA_RATE;
typedef enum tagAUDIO_PKTTYPE
{
AUDIO_PKTTYPE_LPCM_SAMPLE = 0,
AUDIO_PKTTYPE_ONE_BIT_LPCM_SAMPLE,
AUDIO_PKTTYPE_DST_AUDIO,
AUDIO_PKTTYPE_HBR_AUDIO,
AUDIO_PKTTYPE_MULTI_STREAM_AUDIO,
AUDIO_PKTTYPE_ONE_BIT_MULTI_STREAM_AUDIO,
AUDIO_PKTTYPE_3D_AUDIO,
AUDIO_PKTTYPE_ONE_BIT_3D_AUDIO,
NO_AUDIO
} AUDIO_PKTTYPE;
typedef struct tagFRL_CAPACITY_COMPUTATION_PARAMS
{
NvU32 numLanes;
NvU32 frlBitRateGbps;
NvU32 pclk10KHz;
NvU32 hTotal;
NvU32 hActive;
NvU32 bpc;
HDMI_PIXEL_PACKING pixelPacking;
AUDIO_PKTTYPE audioType;
NvU32 numAudioChannels;
NvU32 audioFreqKHz;
struct
{
NvU32 bppTargetx16;
NvU32 hSlices;
NvU32 sliceWidth;
NvU32 dscTotalChunkKBytes;
} compressionInfo;
} FRL_CAPACITY_COMPUTATION_PARAMS;
typedef struct tagFRL_COMPUTATION_RESULT
{
HDMI_FRL_DATA_RATE frlRate;
NvU32 bppTargetx16;
NvBool engageCompression;
NvBool isAudioSupported;
NvBool dataFlowDisparityReqMet;
NvBool dataFlowMeteringReqMet;
NvBool isVideoTransportSupported;
NvU32 triBytesBorrowed; // uncompressed mode: num of active Tri-bytes to be transmitted at HBlank
NvU32 hcActiveBytes; // compressed mode: num of FRL character bytes in active region
NvU32 hcActiveTriBytes; // compressed mode: num of FRL tri-bytes in active region
NvU32 hcBlankTriBytes; // compressed mode: num of FRL tri-bytes in blanking region
NvU32 tBlankToTTotalX1k; // compressed mode: ratio of time spent on blanking to the total line time
} FRL_COMPUTATION_RESULT;
typedef struct tagFRL_PRE_CALC_CONFIG
{
NvU32 vic;
HDMI_PIXEL_PACKING packing;
HDMI_BPC bpc;
HDMI_FRL_DATA_RATE frlRate;
NvU32 bppX16;
NvBool bCompressedMode;
} FRL_PRE_CALC_CONFIG;
#endif // _NVHDMIFRLCOMMON_H_

View File

@@ -0,0 +1,556 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2009 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.
*/
/*
* This header file contains the 3-character Plug and Play Vendor IDs and
* their translation into Vendor names.
*
* If the includer defines NV_PNP_VENDOR_IDS_USE_TCHAR, then
* PNPVendorID::vendorName will have type const TCHAR*; otherwise, it will have
* type const char*.
*
* References:
* http://www.uefi.org/pnp_id_list
*
*/
#ifndef __NV_PNP_VENDOR_IDS_H__
#define __NV_PNP_VENDOR_IDS_H__
#if defined(NV_PNP_VENDOR_IDS_USE_TCHAR)
#define _VENDOR_NAME_TYPE const TCHAR
#define _VENDOR_NAME_ENTRY(x) _T(x)
#else
#define _VENDOR_NAME_TYPE const char
#define _VENDOR_NAME_ENTRY(x) (x)
#endif
typedef struct tagPNPVendorID
{
char vendorId[4]; // PNP Vendor ID (example: "SNY")
_VENDOR_NAME_TYPE* vendorName; // Vendor name for display (example: "Sony")
} PNPVendorId;
/*
* The PNPVendorIds[] table maps between the 3-character Plug and
* Play Vendor Identifiers and user-friendly vendor names
*/
static const PNPVendorId PNPVendorIds[] =
{
{ "___", _VENDOR_NAME_ENTRY("Targa") },
{ "@@@", _VENDOR_NAME_ENTRY("Sangyo") },
{ "AAC", _VENDOR_NAME_ENTRY("Acer") },
{ "ABC", _VENDOR_NAME_ENTRY("AboCom System Inc") },
{ "ABP", _VENDOR_NAME_ENTRY("Advanced System Products") },
{ "ACE", _VENDOR_NAME_ENTRY("ACME") },
{ "ACC", _VENDOR_NAME_ENTRY("ACCTON") },
{ "ACI", _VENDOR_NAME_ENTRY("Ancor Communications Inc") },
{ "ACK", _VENDOR_NAME_ENTRY("ACKSYS") },
{ "ACN", _VENDOR_NAME_ENTRY("ACON") },
{ "ACR", _VENDOR_NAME_ENTRY("Acer") },
{ "ACS", _VENDOR_NAME_ENTRY("Altos/ACS") },
{ "ACT", _VENDOR_NAME_ENTRY("Actebis/Targa") },
{ "ADI", _VENDOR_NAME_ENTRY("ADI") },
{ "ADP", _VENDOR_NAME_ENTRY("Adaptec") },
{ "ADT", _VENDOR_NAME_ENTRY("ADTEK") },
{ "ADV", _VENDOR_NAME_ENTRY("AMD") },
{ "ADX", _VENDOR_NAME_ENTRY("ADAX") },
{ "AEI", _VENDOR_NAME_ENTRY("AIR") },
{ "AEM", _VENDOR_NAME_ENTRY("AEM") },
{ "AEO", _VENDOR_NAME_ENTRY("UHC") },
{ "AGI", _VENDOR_NAME_ENTRY("Artish Graphics") },
{ "AKB", _VENDOR_NAME_ENTRY("Akebia") },
{ "AIC", _VENDOR_NAME_ENTRY("Arnos Instruments") },
{ "AIR", _VENDOR_NAME_ENTRY("Advanced Integrated Research") },
{ "AKB", _VENDOR_NAME_ENTRY("Akebia") },
{ "ALA", _VENDOR_NAME_ENTRY("Alacron") },
{ "ALR", _VENDOR_NAME_ENTRY("Advanced Logic Research") },
{ "AMC", _VENDOR_NAME_ENTRY("Attachmate") },
{ "AMD", _VENDOR_NAME_ENTRY("Amdek") },
{ "AMI", _VENDOR_NAME_ENTRY("American Megatrends") },
{ "AMP", _VENDOR_NAME_ENTRY("Amptron") },
{ "AMT", _VENDOR_NAME_ENTRY("Amtrans") },
{ "ANC", _VENDOR_NAME_ENTRY("Ancot") },
{ "ANI", _VENDOR_NAME_ENTRY("Anigma") },
{ "AOC", _VENDOR_NAME_ENTRY("AOC") },
{ "APD", _VENDOR_NAME_ENTRY("Applidata") },
{ "API", _VENDOR_NAME_ENTRY("AcerView") },
{ "APP", _VENDOR_NAME_ENTRY("Apple") },
{ "APS", _VENDOR_NAME_ENTRY("Autologic") },
{ "ARC", _VENDOR_NAME_ENTRY("Alta Research") },
{ "ART", _VENDOR_NAME_ENTRY("ArtMedia") },
{ "ASE", _VENDOR_NAME_ENTRY("ASEM") },
{ "ASI", _VENDOR_NAME_ENTRY("Ahead Systems") },
{ "AST", _VENDOR_NAME_ENTRY("AST Research") },
{ "ASU", _VENDOR_NAME_ENTRY("ASUS") },
{ "ATI", _VENDOR_NAME_ENTRY("Allied Telesis") },
{ "ATO", _VENDOR_NAME_ENTRY("ASTRO DESIGN, INC.") },
{ "ATT", _VENDOR_NAME_ENTRY("AT&T") },
{ "ATX", _VENDOR_NAME_ENTRY("Athenix") },
{ "AUO", _VENDOR_NAME_ENTRY("AU Optronics Corporation") },
{ "AVI", _VENDOR_NAME_ENTRY("AIR") },
{ "AVO", _VENDOR_NAME_ENTRY("Avocent Corporation") },
{ "AZU", _VENDOR_NAME_ENTRY("Azura") },
{ "BAN", _VENDOR_NAME_ENTRY("Banyan") },
{ "BCC", _VENDOR_NAME_ENTRY("Beaver Computer Corporation") },
{ "BCD", _VENDOR_NAME_ENTRY("Dr. Seufert GmbH") },
{ "BEO", _VENDOR_NAME_ENTRY("Bang & Olufsen") },
{ "BGT", _VENDOR_NAME_ENTRY("Budzetron") },
{ "BMM", _VENDOR_NAME_ENTRY("MAG Technology") },
{ "BNQ", _VENDOR_NAME_ENTRY("BenQ") },
{ "BOE", _VENDOR_NAME_ENTRY("BOE Technology Group Co., Ltd") },
{ "BRG", _VENDOR_NAME_ENTRY("Bridge") },
{ "BTC", _VENDOR_NAME_ENTRY("Bit 3") },
{ "BTE", _VENDOR_NAME_ENTRY("Brilliant Technology") },
{ "BUS", _VENDOR_NAME_ENTRY("BusTek") },
{ "CAL", _VENDOR_NAME_ENTRY("Acon") },
{ "CCI", _VENDOR_NAME_ENTRY("Cache") },
{ "CCP", _VENDOR_NAME_ENTRY("Epson") },
{ "CDP", _VENDOR_NAME_ENTRY("CalComp") },
{ "CFG", _VENDOR_NAME_ENTRY("Atlantis") },
{ "CHA", _VENDOR_NAME_ENTRY("Chase Research") },
{ "CIP", _VENDOR_NAME_ENTRY("Ciprico") },
{ "CLO", _VENDOR_NAME_ENTRY("Clone Computers/Analogy") },
{ "CLT", _VENDOR_NAME_ENTRY("automated computer control systems")},
{ "CMD", _VENDOR_NAME_ENTRY("CMD Technology") },
{ "CMO", _VENDOR_NAME_ENTRY("Chi Mei Optoelectronics corp.") },
{ "CNI", _VENDOR_NAME_ENTRY("Connect International") },
{ "CNT", _VENDOR_NAME_ENTRY("CNet Technology") },
{ "COM", _VENDOR_NAME_ENTRY("Comtrol") },
{ "CPC", _VENDOR_NAME_ENTRY("Ciprico") },
{ "CPD", _VENDOR_NAME_ENTRY("CompuAdd") },
{ "CPG", _VENDOR_NAME_ENTRY("DFI") },
{ "CPI", _VENDOR_NAME_ENTRY("Computer Peripherals") },
{ "CPL", _VENDOR_NAME_ENTRY("Compal") },
{ "CPQ", _VENDOR_NAME_ENTRY("Compaq") },
{ "CPT", _VENDOR_NAME_ENTRY("cPATH") },
{ "CPX", _VENDOR_NAME_ENTRY("Powermatic Data Systems") },
{ "CRD", _VENDOR_NAME_ENTRY("Cardinal Technologies") },
{ "CRN", _VENDOR_NAME_ENTRY("Cornerstone") },
{ "CRS", _VENDOR_NAME_ENTRY("Cisco") },
{ "CSE", _VENDOR_NAME_ENTRY("Compu Shack") },
{ "CSI", _VENDOR_NAME_ENTRY("Cabletron") },
{ "CSS", _VENDOR_NAME_ENTRY("CSS Laboratories") },
{ "CTN", _VENDOR_NAME_ENTRY("Computone") },
{ "CTX", _VENDOR_NAME_ENTRY("Chuntex/CTX") },
{ "CUB", _VENDOR_NAME_ENTRY("Cubix") },
{ "CUI", _VENDOR_NAME_ENTRY("CUI") },
{ "CYB", _VENDOR_NAME_ENTRY("CyberVision") },
{ "DBI", _VENDOR_NAME_ENTRY("DigiBoard") },
{ "DBL", _VENDOR_NAME_ENTRY("Doble Engineering") },
{ "DCC", _VENDOR_NAME_ENTRY("Dale Computer") },
{ "DCE", _VENDOR_NAME_ENTRY("Mylex") },
{ "DCM", _VENDOR_NAME_ENTRY("DCM Data Products") },
{ "DEC", _VENDOR_NAME_ENTRY("DEC") },
{ "DEI", _VENDOR_NAME_ENTRY("Deico Electronics") },
{ "DEL", _VENDOR_NAME_ENTRY("Dell") },
{ "DFI", _VENDOR_NAME_ENTRY("DFI") },
{ "DGC", _VENDOR_NAME_ENTRY("Data General") },
{ "DGS", _VENDOR_NAME_ENTRY("Diagsoft") },
{ "DIA", _VENDOR_NAME_ENTRY("Diadem") },
{ "DIO", _VENDOR_NAME_ENTRY("DIO") },
{ "DIS", _VENDOR_NAME_ENTRY("Diseda") },
{ "DIT", _VENDOR_NAME_ENTRY("Dragon Information Technology") },
{ "DLK", _VENDOR_NAME_ENTRY("D-Link") },
{ "DLO", _VENDOR_NAME_ENTRY("Dlodlo Technologies Co., Ltd") },
{ "DMB", _VENDOR_NAME_ENTRY("Digicom Systems") },
{ "DMS", _VENDOR_NAME_ENTRY("DOME imaging systems") },
{ "DNV", _VENDOR_NAME_ENTRY("NexView") },
{ "DOM", _VENDOR_NAME_ENTRY("Dome Imaging Systems") },
{ "DON", _VENDOR_NAME_ENTRY("DENON, Ltd.") },
{ "DPC", _VENDOR_NAME_ENTRY("Delta") },
{ "DPI", _VENDOR_NAME_ENTRY("DocuPoint") },
{ "DPL", _VENDOR_NAME_ENTRY("Digital Projection Limited") },
{ "DPN", _VENDOR_NAME_ENTRY("Shanghai Lexiang Technology Limited") },
{ "DPT", _VENDOR_NAME_ENTRY("DPT") },
{ "DRT", _VENDOR_NAME_ENTRY("Digital Research") },
{ "DSJ", _VENDOR_NAME_ENTRY("VR Technology Holdings Limited") },
{ "DSM", _VENDOR_NAME_ENTRY("DSM Digial Services") },
{ "DTC", _VENDOR_NAME_ENTRY("Data Technology") },
{ "DTI", _VENDOR_NAME_ENTRY("Diversified Technology") },
{ "DTK", _VENDOR_NAME_ENTRY("DTK Computer") },
{ "DTX", _VENDOR_NAME_ENTRY("Data Translation") },
{ "DVC", _VENDOR_NAME_ENTRY("DecaView") },
{ "DWE", _VENDOR_NAME_ENTRY("Daewoo") },
{ "ECS", _VENDOR_NAME_ENTRY("EliteGroup/ECS") },
{ "ENC", _VENDOR_NAME_ENTRY("Eizo") },
{ "EGO", _VENDOR_NAME_ENTRY("Ergo Electronics") },
{ "EKC", _VENDOR_NAME_ENTRY("Kodak") },
{ "EHJ", _VENDOR_NAME_ENTRY("Epson") },
{ "EIZ", _VENDOR_NAME_ENTRY("Eizo") },
{ "ELI", _VENDOR_NAME_ENTRY("Edsun") },
{ "ELS", _VENDOR_NAME_ENTRY("ELSA") },
{ "ELX", _VENDOR_NAME_ENTRY("Elonex") },
{ "EMC", _VENDOR_NAME_ENTRY("ProView/EMC") },
{ "ENC", _VENDOR_NAME_ENTRY("Eizo") },
{ "EPI", _VENDOR_NAME_ENTRY("Envision") },
{ "EQX", _VENDOR_NAME_ENTRY("Equinox") },
{ "ERG", _VENDOR_NAME_ENTRY("Ergo") },
{ "ERP", _VENDOR_NAME_ENTRY("EURAPLAN") },
{ "ESI", _VENDOR_NAME_ENTRY("Extended Systems") },
{ "ETT", _VENDOR_NAME_ENTRY("E-Tech Research") },
{ "EVX", _VENDOR_NAME_ENTRY("Everex") },
{ "EXP", _VENDOR_NAME_ENTRY("Data Export") },
{ "FCB", _VENDOR_NAME_ENTRY("Furukawa Electric") },
{ "FCM", _VENDOR_NAME_ENTRY("Funai") },
{ "FCT", _VENDOR_NAME_ENTRY("Free Computer Technology") },
{ "FDC", _VENDOR_NAME_ENTRY("Future Domain") },
{ "FDX", _VENDOR_NAME_ENTRY("Findex, Inc. ") },
{ "FGL", _VENDOR_NAME_ENTRY("Fujitsu") },
{ "FIC", _VENDOR_NAME_ENTRY("First International") },
{ "FOR", _VENDOR_NAME_ENTRY("Formac") },
{ "FOV", _VENDOR_NAME_ENTRY("FOVE INC") },
{ "FRC", _VENDOR_NAME_ENTRY("FORCE Computers") },
{ "FRI", _VENDOR_NAME_ENTRY("Fibernet Research") },
{ "FTN", _VENDOR_NAME_ENTRY("Fountain Technologies") },
{ "FUJ", _VENDOR_NAME_ENTRY("Fujitsu") },
{ "GAG", _VENDOR_NAME_ENTRY("Gage Applied Sciences") },
{ "GCI", _VENDOR_NAME_ENTRY("Gateway Communications") },
{ "GEN", _VENDOR_NAME_ENTRY("Genesys") },
{ "GMX", _VENDOR_NAME_ENTRY("GMX") },
{ "GRA", _VENDOR_NAME_ENTRY("Graphica") },
{ "GSM", _VENDOR_NAME_ENTRY("LG Electronics") },
{ "GVC", _VENDOR_NAME_ENTRY("GVC") },
{ "GWY", _VENDOR_NAME_ENTRY("Gateway") },
{ "HCL", _VENDOR_NAME_ENTRY("HCL") },
{ "HCP", _VENDOR_NAME_ENTRY("Hitachi") },
{ "HCW", _VENDOR_NAME_ENTRY("Hauppauge") },
{ "HDL", _VENDOR_NAME_ENTRY("Headland") },
{ "HEC", _VENDOR_NAME_ENTRY("Hisense") },
{ "HEI", _VENDOR_NAME_ENTRY("Hyundai") },
{ "HIT", _VENDOR_NAME_ENTRY("Hitachi/HINT") },
{ "HMX", _VENDOR_NAME_ENTRY("HUMAX Co., Ltd.") },
{ "HSD", _VENDOR_NAME_ENTRY("HannStar Display Corp") },
{ "HSL", _VENDOR_NAME_ENTRY("Hansol") },
{ "HTC", _VENDOR_NAME_ENTRY("Hitachi") },
{ "HVR", _VENDOR_NAME_ENTRY("HTC Corporation") },
{ "HWD", _VENDOR_NAME_ENTRY("HighWater Designs") },
{ "HWP", _VENDOR_NAME_ENTRY("HP") },
{ "HYL", _VENDOR_NAME_ENTRY("Hypereal") },
{ "HYP", _VENDOR_NAME_ENTRY("Hyphen Limited") },
{ "HWV", _VENDOR_NAME_ENTRY("Huawei Technologies Co., Ltd") },
{ "IBC", _VENDOR_NAME_ENTRY("IBS") },
{ "IBM", _VENDOR_NAME_ENTRY("IBM") },
{ "ICC", _VENDOR_NAME_ENTRY("BICC Data Networks") },
{ "ICL", _VENDOR_NAME_ENTRY("Fujitsu/ICL") },
{ "ICN", _VENDOR_NAME_ENTRY("Sanyo/Icon") },
{ "ICU", _VENDOR_NAME_ENTRY("Intel") },
{ "IDS", _VENDOR_NAME_ENTRY("Intellistor") },
{ "IFT", _VENDOR_NAME_ENTRY("Informtech") },
{ "IGM", _VENDOR_NAME_ENTRY("IGM Communications") },
{ "III", _VENDOR_NAME_ENTRY("Intelligent Instrumentation") },
{ "IIN", _VENDOR_NAME_ENTRY("Intel") },
{ "IMA", _VENDOR_NAME_ENTRY("Imagraph") },
{ "IMC", _VENDOR_NAME_ENTRY("IMC Networks") },
{ "IMP", _VENDOR_NAME_ENTRY("Impression") },
{ "INF", _VENDOR_NAME_ENTRY("Inframetrics") },
{ "INL", _VENDOR_NAME_ENTRY("InnoLux Display Corporation") },
{ "INP", _VENDOR_NAME_ENTRY("Interphase") },
{ "INS", _VENDOR_NAME_ENTRY("Ines") },
{ "INT", _VENDOR_NAME_ENTRY("Intel") },
{ "IOD", _VENDOR_NAME_ENTRY("IODATA") },
{ "ISA", _VENDOR_NAME_ENTRY("ISA") },
{ "ISI", _VENDOR_NAME_ENTRY("Interface Solutions") },
{ "ISL", _VENDOR_NAME_ENTRY("Isolation Systems") },
{ "ITA", _VENDOR_NAME_ENTRY("Itausa") },
{ "ITC", _VENDOR_NAME_ENTRY("ITK") },
{ "ITN", _VENDOR_NAME_ENTRY("NTI Group/ASUS") },
{ "ITK", _VENDOR_NAME_ENTRY("NTI Group") },
{ "IVK", _VENDOR_NAME_ENTRY("Iiyama") },
{ "IVM", _VENDOR_NAME_ENTRY("Idek Iiyama") },
{ "IVR", _VENDOR_NAME_ENTRY("Inlife-Handnet Co., Ltd.") },
{ "IWR", _VENDOR_NAME_ENTRY("Icuiti Corporation") },
{ "JDI", _VENDOR_NAME_ENTRY("Japan Display Inc") },
{ "JEN", _VENDOR_NAME_ENTRY("Jean") },
{ "JKC", _VENDOR_NAME_ENTRY("JVC Kenwood Corporation") },
{ "JVC", _VENDOR_NAME_ENTRY("JVC") },
{ "KDS", _VENDOR_NAME_ENTRY("Korea Data Systems") },
{ "KDK", _VENDOR_NAME_ENTRY("Kodiak") },
{ "KES", _VENDOR_NAME_ENTRY("Kesa Crop") },
{ "KFC", _VENDOR_NAME_ENTRY("KFC Computek") },
{ "KPC", _VENDOR_NAME_ENTRY("King Phoenix") },
{ "KSC", _VENDOR_NAME_ENTRY("Kinetic Systems") },
{ "KTC", _VENDOR_NAME_ENTRY("Kingston Technology") },
{ "KTG", _VENDOR_NAME_ENTRY("KayserThrede") },
{ "KTR", _VENDOR_NAME_ENTRY("IMRI") },
{ "KYC", _VENDOR_NAME_ENTRY("Kyocera") },
{ "LAG", _VENDOR_NAME_ENTRY("Laguna Systems") },
{ "LCD", _VENDOR_NAME_ENTRY("Toshiba Matsushita Display Technology Co., Ltd")},
{ "LCS", _VENDOR_NAME_ENTRY("Longshine Electronics") },
{ "LEF", _VENDOR_NAME_ENTRY("Leaf Systems") },
{ "LEN", _VENDOR_NAME_ENTRY("Lenovo Group Limited") },
{ "LGE", _VENDOR_NAME_ENTRY("LG Electronics") },
{ "LKM", _VENDOR_NAME_ENTRY("Likom/LKM") },
{ "LNK", _VENDOR_NAME_ENTRY("Link Technologies") },
{ "LTI", _VENDOR_NAME_ENTRY("Longshine") },
{ "LTN", _VENDOR_NAME_ENTRY("Lite-On") },
{ "MAG", _VENDOR_NAME_ENTRY("MAG Technology") },
{ "MAX", _VENDOR_NAME_ENTRY("Maxdata/Belinea") },
{ "MAY", _VENDOR_NAME_ENTRY("Maynard Electronics") },
{ "MBC", _VENDOR_NAME_ENTRY("MBC") },
{ "MCC", _VENDOR_NAME_ENTRY("MCCI") },
{ "MCD", _VENDOR_NAME_ENTRY("McDATA") },
{ "MCI", _VENDOR_NAME_ENTRY("Micronics") },
{ "MCR", _VENDOR_NAME_ENTRY("Marina Communications") },
{ "MCS", _VENDOR_NAME_ENTRY("Micro Computer Systems") },
{ "MCT", _VENDOR_NAME_ENTRY("Microtec") },
{ "MDD", _VENDOR_NAME_ENTRY("Modis") },
{ "MDG", _VENDOR_NAME_ENTRY("Madge Networks") },
{ "MDS", _VENDOR_NAME_ENTRY("Micro Display Systems") },
{ "MDT", _VENDOR_NAME_ENTRY("Magus Data") },
{ "MED", _VENDOR_NAME_ENTRY("Medion") },
{ "MEI", _VENDOR_NAME_ENTRY("Panasonic") },
{ "MEL", _VENDOR_NAME_ENTRY("Mitsubishi") },
{ "MET", _VENDOR_NAME_ENTRY("Metheus") },
{ "MFG", _VENDOR_NAME_ENTRY("Microfield Graphics") },
{ "MGC", _VENDOR_NAME_ENTRY("CompuAdd") },
{ "MGT", _VENDOR_NAME_ENTRY("Megatech") },
{ "MIC", _VENDOR_NAME_ENTRY("Micronics") },
{ "MIR", _VENDOR_NAME_ENTRY("Miro") },
{ "MJI", _VENDOR_NAME_ENTRY("MARANTZ JAPAN, INC.") },
{ "MLX", _VENDOR_NAME_ENTRY("Mylex") },
{ "MMX", _VENDOR_NAME_ENTRY("MAG Technology") },
{ "MOR", _VENDOR_NAME_ENTRY("Morse Technology") },
{ "MSI", _VENDOR_NAME_ENTRY("Microstep") },
{ "MSV", _VENDOR_NAME_ENTRY("Mosgi") },
{ "MTC", _VENDOR_NAME_ENTRY("Mitac") },
{ "MTI", _VENDOR_NAME_ENTRY("Morse Technology") },
{ "MTQ", _VENDOR_NAME_ENTRY("Mountain Computer") },
{ "MTS", _VENDOR_NAME_ENTRY("Multi-Tech Systems") },
{ "MTX", _VENDOR_NAME_ENTRY("Matrox") },
{ "MVD", _VENDOR_NAME_ENTRY("Microvitec PLC") },
{ "MVN", _VENDOR_NAME_ENTRY("META COMPANY") },
{ "MWY", _VENDOR_NAME_ENTRY("Microway") },
{ "MYA", _VENDOR_NAME_ENTRY("Monydata") },
{ "MYL", _VENDOR_NAME_ENTRY("Mylex") },
{ "MYX", _VENDOR_NAME_ENTRY("Micronyx") },
{ "MZI", _VENDOR_NAME_ENTRY("Mozo") },
{ "NAN", _VENDOR_NAME_ENTRY("Nanao") },
{ "NCA", _VENDOR_NAME_ENTRY("Siemens Nixdorf") },
{ "NCD", _VENDOR_NAME_ENTRY("NCD") },
{ "NCS", _VENDOR_NAME_ENTRY("Northgate") },
{ "NDC", _VENDOR_NAME_ENTRY("National DataComm") },
{ "NDS", _VENDOR_NAME_ENTRY("Nokia") },
{ "NEC", _VENDOR_NAME_ENTRY("NEC") },
{ "NIC", _VENDOR_NAME_ENTRY("National Instruments") },
{ "NIT", _VENDOR_NAME_ENTRY("Network Info Technology") },
{ "NOK", _VENDOR_NAME_ENTRY("Nokia") },
{ "NPI", _VENDOR_NAME_ENTRY("Network Peripherals") },
{ "NSC", _VENDOR_NAME_ENTRY("National Semiconductor") },
{ "NSS", _VENDOR_NAME_ENTRY("Newport Systems") },
{ "NTI", _VENDOR_NAME_ENTRY("New Tech") },
{ "NVD", _VENDOR_NAME_ENTRY("NVIDIA") },
{ "NVL", _VENDOR_NAME_ENTRY("Novell") },
{ "NXG", _VENDOR_NAME_ENTRY("Nexgen") },
{ "OAS", _VENDOR_NAME_ENTRY("OAsys") },
{ "OCN", _VENDOR_NAME_ENTRY("Olfan") },
{ "OEC", _VENDOR_NAME_ENTRY("Daytek") },
{ "OLC", _VENDOR_NAME_ENTRY("Olicom") },
{ "OLI", _VENDOR_NAME_ENTRY("Olivetti") },
{ "OKI", _VENDOR_NAME_ENTRY("OKI Electric Industrial Company Ltd") },
{ "ONK", _VENDOR_NAME_ENTRY("ONKYO Corporation") },
{ "OPT", _VENDOR_NAME_ENTRY("OPTi") },
{ "OQI", _VENDOR_NAME_ENTRY("Optiquest") },
{ "OTI", _VENDOR_NAME_ENTRY("Orchid Technology") },
{ "OVR", _VENDOR_NAME_ENTRY("Oculus VR Inc.") },
{ "OZO", _VENDOR_NAME_ENTRY("Zoom Telephonics") },
{ "PAR", _VENDOR_NAME_ENTRY("Parallan Comp Inc") },
{ "PBE", _VENDOR_NAME_ENTRY("Packard Bell") },
{ "PBI", _VENDOR_NAME_ENTRY("Pitney Bowes") },
{ "PBN", _VENDOR_NAME_ENTRY("Packard Bell") },
{ "PCI", _VENDOR_NAME_ENTRY("Pioneer Computer") },
{ "PCP", _VENDOR_NAME_ENTRY("Procomp") },
{ "PDR", _VENDOR_NAME_ENTRY("Pure Data") },
{ "PEA", _VENDOR_NAME_ENTRY("Peacock") },
{ "PGS", _VENDOR_NAME_ENTRY("Princeton Graphics") },
{ "PHI", _VENDOR_NAME_ENTRY("Phillips") },
{ "PHL", _VENDOR_NAME_ENTRY("Philips") },
{ "PIO", _VENDOR_NAME_ENTRY("Pioneer Electronic Corporation") },
{ "PI0", _VENDOR_NAME_ENTRY("Pioneer") },
{ "PIR", _VENDOR_NAME_ENTRY("Pico Technology Inc") },
{ "PJD", _VENDOR_NAME_ENTRY("Projectiondesign AS") },
{ "PLB", _VENDOR_NAME_ENTRY("PLB") },
{ "PLX", _VENDOR_NAME_ENTRY("Ocean Office Automation") },
{ "PMC", _VENDOR_NAME_ENTRY("PMC Consumer Electronics") },
{ "PMV", _VENDOR_NAME_ENTRY("MAG Technology") },
{ "PNR", _VENDOR_NAME_ENTRY("Planar Systems, Inc.") },
{ "PRO", _VENDOR_NAME_ENTRY("Proteon") },
{ "PSI", _VENDOR_NAME_ENTRY("PSI Perceptive Solutions") },
{ "PTS", _VENDOR_NAME_ENTRY("ProView/EMC/PTS") },
{ "PVR", _VENDOR_NAME_ENTRY("Pimax Tech Co., Ltd") },
{ "QDI", _VENDOR_NAME_ENTRY("Quantum Data Incorporated") },
{ "QDM", _VENDOR_NAME_ENTRY("Quadram") },
{ "QTD", _VENDOR_NAME_ENTRY("Quantum 3D Inc") },
{ "QTM", _VENDOR_NAME_ENTRY("Quantum") },
{ "RAC", _VENDOR_NAME_ENTRY("Racore Computer Products") },
{ "RCE", _VENDOR_NAME_ENTRY("RCE") },
{ "RCI", _VENDOR_NAME_ENTRY("RC International") },
{ "REL", _VENDOR_NAME_ENTRY("Relisys") },
{ "REM", _VENDOR_NAME_ENTRY("REM") },
{ "RII", _VENDOR_NAME_ENTRY("Racal Interlan") },
{ "RMP", _VENDOR_NAME_ENTRY("Research Machines") },
{ "ROK", _VENDOR_NAME_ENTRY("Rockwell") },
{ "RTI", _VENDOR_NAME_ENTRY("Rancho Technology") },
{ "RUN", _VENDOR_NAME_ENTRY("RUNCO International") },
{ "SAM", _VENDOR_NAME_ENTRY("Samsung") },
{ "SAN", _VENDOR_NAME_ENTRY("Sanyo Electric Co.,Ltd.") },
{ "SCC", _VENDOR_NAME_ENTRY("SORD") },
{ "SCD", _VENDOR_NAME_ENTRY("Sanyo") },
{ "SDI", _VENDOR_NAME_ENTRY("Samtron/Sigma Designs") },
{ "SDT", _VENDOR_NAME_ENTRY("Siemens AG") },
{ "SEA", _VENDOR_NAME_ENTRY("Segate") },
{ "SEC", _VENDOR_NAME_ENTRY("Seiko/Epson") },
{ "SEN", _VENDOR_NAME_ENTRY("Sencore") },
{ "SGT", _VENDOR_NAME_ENTRY("Stargate Technology/AT&T") },
{ "SGX", _VENDOR_NAME_ENTRY("SGI") },
{ "SHP", _VENDOR_NAME_ENTRY("Sharp") },
{ "SIB", _VENDOR_NAME_ENTRY("Sanyo") },
{ "SIE", _VENDOR_NAME_ENTRY("Siemens Nixdorf") },
{ "SII", _VENDOR_NAME_ENTRY("Silicon Image, Inc.") },
{ "SIS", _VENDOR_NAME_ENTRY("SiS/Modula Tech") },
{ "SIT", _VENDOR_NAME_ENTRY("Sitintel") },
{ "SIX", _VENDOR_NAME_ENTRY("Zuniq Data") },
{ "SKD", _VENDOR_NAME_ENTRY("Schneider & Koch") },
{ "SKW", _VENDOR_NAME_ENTRY("Skyworth") },
{ "SKY", _VENDOR_NAME_ENTRY("SKYDATA S.P.A.") },
{ "SLB", _VENDOR_NAME_ENTRY("Shlumberger Ltd") },
{ "SLT", _VENDOR_NAME_ENTRY("Salt Internatioinal Corp.") },
{ "SLX", _VENDOR_NAME_ENTRY("Specialix") },
{ "SMC", _VENDOR_NAME_ENTRY("Standard Microsystems") },
{ "SMI", _VENDOR_NAME_ENTRY("Smile") },
{ "SML", _VENDOR_NAME_ENTRY("Smile") },
{ "SMS", _VENDOR_NAME_ENTRY("Silicon Multimedia Systems") },
{ "SNI", _VENDOR_NAME_ENTRY("Siemens Nixdorf") },
{ "SNY", _VENDOR_NAME_ENTRY("Sony") },
{ "SOB", _VENDOR_NAME_ENTRY("Sanyo") },
{ "SPE", _VENDOR_NAME_ENTRY("SPEA") },
{ "SPT", _VENDOR_NAME_ENTRY("Sceptre") },
{ "SRC", _VENDOR_NAME_ENTRY("Shamrock/SunRiver") },
{ "SSS", _VENDOR_NAME_ENTRY("S3") },
{ "STA", _VENDOR_NAME_ENTRY("Stesa") },
{ "STB", _VENDOR_NAME_ENTRY("STB Systems") },
{ "STC", _VENDOR_NAME_ENTRY("Sampo/STAC") },
{ "STP", _VENDOR_NAME_ENTRY("Sceptre") },
{ "STR", _VENDOR_NAME_ENTRY("Starlight Networks") },
{ "SUK", _VENDOR_NAME_ENTRY("Schneider & Koch") },
{ "SUP", _VENDOR_NAME_ENTRY("Supra/Diamond Media") },
{ "SUR", _VENDOR_NAME_ENTRY("Surenam") },
{ "SVR", _VENDOR_NAME_ENTRY("Sensics Inc.") },
{ "SYL", _VENDOR_NAME_ENTRY("Sylvania") },
{ "SYN", _VENDOR_NAME_ENTRY("Synaptics Inc") },
{ "TAI", _VENDOR_NAME_ENTRY("Toshiba") },
{ "TAT", _VENDOR_NAME_ENTRY("Tatung") },
{ "TAX", _VENDOR_NAME_ENTRY("Taxan") },
{ "TCC", _VENDOR_NAME_ENTRY("Tandon") },
{ "TCI", _VENDOR_NAME_ENTRY("Tulip") },
{ "TCL", _VENDOR_NAME_ENTRY("Tech Concepts") },
{ "TCM", _VENDOR_NAME_ENTRY("Techmedia/3Com") },
{ "TCO", _VENDOR_NAME_ENTRY("Thomas Conrad") },
{ "TCR", _VENDOR_NAME_ENTRY("Thomson Consumer Electronics") },
{ "TCS", _VENDOR_NAME_ENTRY("Tatung") },
{ "TDS", _VENDOR_NAME_ENTRY("Tri Data Systems") },
{ "TDT", _VENDOR_NAME_ENTRY("TDT") },
{ "TDY", _VENDOR_NAME_ENTRY("Tandy") },
{ "TEA", _VENDOR_NAME_ENTRY("Teac") },
{ "TEC", _VENDOR_NAME_ENTRY("Tecmar") },
{ "TEI", _VENDOR_NAME_ENTRY("TECO") },
{ "TGI", _VENDOR_NAME_ENTRY("TriGem") },
{ "TGS", _VENDOR_NAME_ENTRY("Torus") },
{ "TOS", _VENDOR_NAME_ENTRY("Toshiba") },
{ "TRI", _VENDOR_NAME_ENTRY("Tricord") },
{ "TRM", _VENDOR_NAME_ENTRY("Tekram") },
{ "TRL", _VENDOR_NAME_ENTRY("Royal") },
{ "TRS", _VENDOR_NAME_ENTRY("Torus") },
{ "TRU", _VENDOR_NAME_ENTRY("Aashima/Truevision") },
{ "TSB", _VENDOR_NAME_ENTRY("Toshiba") },
{ "TSC", _VENDOR_NAME_ENTRY("Sanyo") },
{ "TSI", _VENDOR_NAME_ENTRY("TeleVideo") },
{ "TST", _VENDOR_NAME_ENTRY("Transtream Inc") },
{ "TTC", _VENDOR_NAME_ENTRY("Telecommunications Techniques") },
{ "TTK", _VENDOR_NAME_ENTRY("Totoku") },
{ "TTX", _VENDOR_NAME_ENTRY("TTX") },
{ "TVI", _VENDOR_NAME_ENTRY("TeleVideo/Truevision") },
{ "TVM", _VENDOR_NAME_ENTRY("TVM") },
{ "TWA", _VENDOR_NAME_ENTRY("Tidewater") },
{ "TWE", _VENDOR_NAME_ENTRY("Kontron") },
{ "TXN", _VENDOR_NAME_ENTRY("Texas Instruments") },
{ "TYN", _VENDOR_NAME_ENTRY("Tyan Computer") },
{ "UBI", _VENDOR_NAME_ENTRY("Ungermann Bass") },
{ "UFO", _VENDOR_NAME_ENTRY("UFO Systems") },
{ "UNA", _VENDOR_NAME_ENTRY("Unisys") },
{ "UNI", _VENDOR_NAME_ENTRY("Unisys") },
{ "UNM", _VENDOR_NAME_ENTRY("Unisys") },
{ "UNO", _VENDOR_NAME_ENTRY("Unisys") },
{ "UNS", _VENDOR_NAME_ENTRY("Unisys") },
{ "UNT", _VENDOR_NAME_ENTRY("Unisys") },
{ "USC", _VENDOR_NAME_ENTRY("UltraStor") },
{ "USR", _VENDOR_NAME_ENTRY("US Robotics") },
{ "UTB", _VENDOR_NAME_ENTRY("Utobia") },
{ "VES", _VENDOR_NAME_ENTRY("Vestel") },
{ "VIK", _VENDOR_NAME_ENTRY("Viking") },
{ "VLV", _VENDOR_NAME_ENTRY("Valve Corporation") },
{ "VMI", _VENDOR_NAME_ENTRY("Vermont MicroSystems") },
{ "VOB", _VENDOR_NAME_ENTRY("Vobis") },
{ "VRG", _VENDOR_NAME_ENTRY("VRgineers, Inc. ") },
{ "VRT", _VENDOR_NAME_ENTRY("Varjo Technologies") },
{ "VSC", _VENDOR_NAME_ENTRY("ViewSonic") },
{ "WAC", _VENDOR_NAME_ENTRY("Wacom Tech") },
{ "WDC", _VENDOR_NAME_ENTRY("Western Digital") },
{ "WDE", _VENDOR_NAME_ENTRY("Westinghouse Digital Electronics") },
{ "WIL", _VENDOR_NAME_ENTRY("WIPRO") },
{ "WTC", _VENDOR_NAME_ENTRY("Wen Technology") },
{ "WYS", _VENDOR_NAME_ENTRY("Wyse Technology") },
{ "YMH", _VENDOR_NAME_ENTRY("Yamaha Corporation") },
{ "YHQ", _VENDOR_NAME_ENTRY("Yokogawa") },
{ "ZCM", _VENDOR_NAME_ENTRY("Zenith") },
{ "ZDS", _VENDOR_NAME_ENTRY("Zenith") },
{ "ZYT", _VENDOR_NAME_ENTRY("Zytex") },
};
#endif /* __NV_PNP_VENDOR_IDS_H__ */

390
src/common/inc/nvSha1.h Normal file
View File

@@ -0,0 +1,390 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2007-2012 NVIDIA CORPORATION & AFFILIATES
* 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.
*/
/*!
* Utility header file to generate a one-way hash from an arbitrary
* byte array, using the Secure Hashing Algorithm 1 (SHA-1) as defined
* in FIPS PUB 180-1 published April 17, 1995:
*
* http://www.itl.nist.gov/fipspubs/fip180-1.htm
*
* Some common test cases (see Appendices A and B of the above document):
*
* SHA1("abc") =
* A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
*
* SHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") =
* 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
*/
#ifndef __NV_SHA1_H__
#define __NV_SHA1_H__
#include "nvtypes.h"
/*!
* @brief Structure used by the SHA-1 functions to maintain the state of the
* calculations.
*/
typedef struct
{
NvU32 state[5];
NvU32 count;
NvU8 buffer[128];
} Sha1Context;
/*!
* @brief Pointer to a memory accessor function for use by the SHA-1 hash
* function.
*
* Due to memory constraints in some environments where this code is executed
* (e.g., the PMU/DPU), the data that needs to be processed by the SHA-1 hash
* function may not be readily available. This function is responsible for
* copying the data into a buffer to be used by the SHA-1 function.
*
* Besides, SHA1 library can be used by many different clients, so we need to
* provide the memory accessor functions which can work in client's environment.
*
* @param[out] pBuff The buffer to copy the new data to.
* @param[in] index The desired offset to begin copying from.
* @param[in] size The requested number of bytes to be copied.
* @param[in] info Pointer to the data passed into GenerateSha1 as pData.
*
* @return The actual number of bytes copied into the buffer.
*/
typedef NvU32 Sha1CopyFunc(NvU8 *pBuff, NvU32 index, NvU32 size, void *pInfo);
/*
* The following values are defined by the SHA-1 algorithm for initial values.
*/
#define SHA1_INIT_H0 0x67452301 //!< Initial H0 value
#define SHA1_INIT_H1 0xEFCDAB89 //!< Initial H1 value
#define SHA1_INIT_H2 0x98BADCFE //!< Initial H2 value
#define SHA1_INIT_H3 0x10325476 //!< Initial H3 value
#define SHA1_INIT_H4 0xC3D2E1F0 //!< Initial H4 value
/*!
* @brief Reverses the byte order of a word; that is, switching the endianness
* of the word.
*
* @param[in] a A 32-bit word
*
* @returns The 32-bit word with its byte order reversed.
*/
#define REVERSE_BYTE_ORDER(a) \
(((a) >> 24) | ((a) << 24) | (((a) >> 8) & 0xFF00) | (((a) << 8) & 0xFF0000))
/*!
* @brief Computation step as defined by SHA-1.
*
* Unlike the 64 byte buffer version outlined in the SHA-1 algorithm, this
* function uses a 128 byte buffer to minimize the calculation needed to
* index the data.
*
* @param[in,out] pState
* Pointer to State word array.
*
* @param[in] pBuffer
* Data to operate on. 128 bytes in length. No length checking is done,
* and is assumed to have been done by the calling function.
*/
static void
_sha1Transform
(
NvU32 *pState,
NvU8 *pBuffer
)
{
NvU32 a = pState[0];
NvU32 b = pState[1];
NvU32 c = pState[2];
NvU32 d = pState[3];
NvU32 e = pState[4];
NvU32 *pBuf = (NvU32 *)pBuffer;
NvU32 *p;
NvU32 i;
NvU32 j;
NvU32 k;
for (i = 0; i < 80; i++)
{
p = &pBuf[i & 0xf];
j = p[0];
if (i < 16)
{
j = REVERSE_BYTE_ORDER(j);
}
else
{
j ^= p[2] ^ p[8] ^ p[13];
j = (j << 1) + (j >> 31);
}
p[0] = p[16] = j;
if (i < 40)
{
if (i < 20)
{
k = 0x5a827999 + ((b & (c ^ d)) ^ d);
}
else
{
k = 0x6ed9eba1 + (b ^ c ^ d);
}
}
else
{
if (i < 60)
{
k = 0x8f1bbcdc + (((b | c) & d) | (b & c));
}
else
{
k = 0xca62c1d6 + (b ^ c ^ d);
}
}
j += (a << 5) + (a >> 27) + e + k;
e = d;
d = c;
c = (b << 30) + (b >> 2);
b = a;
a = j;
}
pState[0] += a;
pState[1] += b;
pState[2] += c;
pState[3] += d;
pState[4] += e;
}
/*!
* Initializes the SHA-1 context.
*
* @param[out] pContext
* Pointer to the context to initialize.
*/
static void
_sha1Initialize
(
Sha1Context *pContext
)
{
pContext->count = 0;
pContext->state[0] = SHA1_INIT_H0;
pContext->state[1] = SHA1_INIT_H1;
pContext->state[2] = SHA1_INIT_H2;
pContext->state[3] = SHA1_INIT_H3;
pContext->state[4] = SHA1_INIT_H4;
}
/*!
* @brief Divides the input buffer into multiple 64-byte buffers and computes
* the message digest for each.
*
* @param[in] pContext
* Pointer to a Sha1Context.
*
* @param[in] pData
* Pointer to the data array to compute the message digest.
*
* @param[in] len
* Size of the data.
*
* @param[in] copyFunc
* Copy routine to use.
*/
static void
_sha1Update
(
Sha1Context *pContext,
void *pData,
NvU32 len,
Sha1CopyFunc copyFunc
)
{
NvU32 buffer_offset = (pContext->count & 63);
NvU32 copy_size;
NvU32 idx = 0;
pContext->count += len;
while ((buffer_offset + len) > 63)
{
copy_size = 64 - buffer_offset;
copyFunc(&pContext->buffer[buffer_offset], idx, copy_size, pData);
_sha1Transform(pContext->state, pContext->buffer);
buffer_offset = 0;
idx += copy_size;
len -= copy_size;
}
if (len > 0)
{
copyFunc(&pContext->buffer[buffer_offset], idx, len, pData);
}
}
/*!
* @brief fill memory with zero; not all environments in which this
* code runs have memset(3).
*
* @param[out] pData
* The memory to be filled with zero
*
* @param[in] nBytes
* The number of bytes of memory to fill with zero
*/
static NV_INLINE void
_sha1MemZero
(
NvU8 *pData,
NvU32 nBytes
)
{
NvU32 i;
for (i = 0; i < nBytes; i++) {
pData[i] = 0;
}
}
/*!
* @brief Pads the message as specified by the SHA-1 algorithm and computes
* the message digest on the final message chunk(s).
*
* @param[out] pDigest
* The SHA-1 hash values.
*
* @param[in] pContext
* Pointer to a Sha1Context.
*/
static void
_sha1Final
(
NvU8 *pDigest,
Sha1Context *pContext
)
{
NvU32 i;
NvU32 bufferOffset = (pContext->count & 63);
NvU8 *pBuffer = (NvU8*)&pContext->buffer[bufferOffset];
NvU32 *pCount;
NvU32 *pDig32;
// append padding pattern to the end of input
*pBuffer++ = 0x80;
if (bufferOffset < 56)
{
_sha1MemZero(pBuffer, 59 - bufferOffset);
}
else
{
// need an extra sha1_transform
if (bufferOffset < 63)
{
_sha1MemZero(pBuffer, 63 - bufferOffset);
}
_sha1Transform(pContext->state, pContext->buffer);
_sha1MemZero(pContext->buffer, 60);
}
// set final count (this is the number of *bits* not *bytes*)
pCount = (NvU32*)&pContext->buffer[15 << 2];
*pCount = REVERSE_BYTE_ORDER(pContext->count << 3);
_sha1Transform(pContext->state, pContext->buffer);
// output hash with each dword in big endian
if (pDigest)
{
pDig32 = (NvU32*) pDigest;
for (i = 0; i < 5; i++)
{
pDig32[i] = REVERSE_BYTE_ORDER(pContext->state[i]);
}
}
}
/*!
* @brief Generates the SHA-1 hash value on the data provided.
*
* The function does not manipulate the source data directly, as it may not
* have direct access to it. Therefore, it relies upon the copy function to
* copy segments of the data into a local buffer before any manipulation takes
* place.
*
* @param[out] pHash
* Pointer to store the hash array. The buffer must be 20 bytes in
* length, and the result is stored in big endian format.
*
* @param[in] pData
* The source data array to transform. The actual values and make-up
* of this parameter are dependent on the copy function.
*
* @param[in] nBytes
* The size, in bytes, of the source data.
*
* @param[in] copyFunc
* The function responsible for copying data from the source
* for use by the sha1 function. It is possible for the data
* to exist outside the current execution environment (e.g.,
* the PMU, and the data to hash are in system memory), so
* the function will never directly manipulate the source
* data.
*/
#define NV_SHA1_BLOCK_LENGTH 64
#define NV_SHA1_DIGEST_LENGTH 20
static void
sha1Generate
(
NvU8 pHash[NV_SHA1_DIGEST_LENGTH],
void *pData,
NvU32 nBytes,
Sha1CopyFunc copyFunc
)
{
Sha1Context context;
_sha1Initialize(&context);
_sha1Update(&context, pData, nBytes, copyFunc);
_sha1Final(pHash, &context);
}
#endif /* __NV_SHA1_H__ */

70
src/common/inc/nvSha256.h Normal file
View File

@@ -0,0 +1,70 @@
/*
* FIPS 180-2 SHA-224/256/384/512 implementation
* Last update: 02/02/2007
* Issue date: 04/30/2005
*
* Copyright (C) 2005, 2007 Olivier Gay <olivier.gay@a3.epfl.ch>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/** \file SHA256.h
* \brief SHA256 definitions.
* \author Steven A. Fontana Sr.
* \date September 4 2009
*/
#ifndef NV_SHA2_H
#define NV_SHA2_H
#include <nvtypes.h>
#define NV_SHA256_DIGEST_SIZE ( 256 / 8)
#define NV_SHA256_BLOCK_SIZE ( 512 / 8)
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
NvU32 tot_len;
NvU32 len;
NvU8 block[2 * NV_SHA256_BLOCK_SIZE];
NvU32 h[8];
} nv_sha256_ctx;
void nv_sha256_init(nv_sha256_ctx * ctx);
void nv_sha256_update(nv_sha256_ctx *ctx, const NvU8 *message, NvU32 len);
void nv_sha256_final(nv_sha256_ctx *ctx, NvU8 *digest);
void nv_sha256_noPad(nv_sha256_ctx *ctx, NvU8 *digest);
void nv_sha256(const NvU8 *message, NvU32 len, NvU8 *digest);
#ifdef __cplusplus
}
#endif
#endif /* !NV_SHA2_H */

View File

@@ -0,0 +1,15 @@
#ifndef __NV_UNIX_VERSION_H__
#define __NV_UNIX_VERSION_H__
#if defined(NV_LINUX) || defined(NV_BSD) || defined(NV_SUNOS) || defined(NV_VMWARE) || defined(NV_QNX) || defined(NV_INTEGRITY) || \
(defined(RMCFG_FEATURE_PLATFORM_GSP) && RMCFG_FEATURE_PLATFORM_GSP == 1)
#define NV_VERSION_STRING "515.43.04"
#else
#error "nvUnixVersion.h should only be included in UNIX builds"
#endif
#endif /* __NV_UNIX_VERSION_H__ */

17
src/common/inc/nvVer.h Normal file
View File

@@ -0,0 +1,17 @@
// nvVer.h - Versions of NV drivers
#define NV_COMPANY_NAME_STRING_SHORT "NVIDIA"
#define NV_COMPANY_NAME_STRING_FULL "NVIDIA Corporation"
#define NV_COMPANY_NAME_STRING NV_COMPANY_NAME_STRING_FULL
#define NV_COPYRIGHT_YEAR "2022"
#define NV_COPYRIGHT "(C) " NV_COPYRIGHT_YEAR " NVIDIA Corporation. All rights reserved." // Please do not use the non-ascii copyright symbol for (C).
#if defined(NV_LINUX) || defined(NV_BSD) || defined(NV_SUNOS) || defined(NV_VMWARE) || defined(NV_QNX) || defined(NV_INTEGRITY) || \
(defined(RMCFG_FEATURE_PLATFORM_GSP) && RMCFG_FEATURE_PLATFORM_GSP == 1)
// All Version numbering for Unix builds has moved. (Source should be re-directed to directly include that header.)
#include "nvUnixVersion.h"
#else
#endif

558
src/common/inc/nv_list.h Normal file
View File

@@ -0,0 +1,558 @@
/*
* Copyright © 2010 Intel Corporation
* Copyright © 2010 Francisco Jerez <currojerez@riseup.net>
* Copyright © 2012 NVIDIA Corporation
*
* 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 (including the next
* paragraph) 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.
*
*/
/*
* This file was copied from the X.Org X server source at commit
* 5884e7dedecdd82ddbb037360cf9c85143e094b5 and modified to match NVIDIA's X
* driver code style.
*/
#ifndef _NV_LIST_H_
#define _NV_LIST_H_
#ifdef __cplusplus
extern "C" {
#endif //__cplusplus
#include "nvmisc.h"
#define HAVE_TYPEOF 1
/**
* @file Classic doubly-link circular list implementation.
* For real usage examples of the linked list, see the file test/list.c
*
* Example:
* We need to keep a list of struct foo in the parent struct bar, i.e. what
* we want is something like this.
*
* struct bar {
* ...
* struct foo *list_of_foos; -----> struct foo {}, struct foo {}, struct foo{}
* ...
* }
*
* We need one list head in bar and a list element in all list_of_foos (both are of
* data type 'NVListRec').
*
* struct bar {
* ...
* NVListRec list_of_foos;
* ...
* }
*
* struct foo {
* ...
* NVListRec entry;
* ...
* }
*
* Now we initialize the list head:
*
* struct bar bar;
* ...
* nvListInit(&bar.list_of_foos);
*
* Then we create the first element and add it to this list:
*
* struct foo *foo = malloc(...);
* ....
* nvListAdd(&foo->entry, &bar.list_of_foos);
*
* Repeat the above for each element you want to add to the list. Deleting
* works with the element itself.
* nvListDel(&foo->entry);
* free(foo);
*
* Note: calling nvListDel(&bar.list_of_foos) will set bar.list_of_foos to an empty
* list again.
*
* Looping through the list requires a 'struct foo' as iterator and the
* name of the field the subnodes use.
*
* struct foo *iterator;
* nvListForEachEntry(iterator, &bar.list_of_foos, entry) {
* if (iterator->something == ...)
* ...
* }
*
* Note: You must not call nvListDel() on the iterator if you continue the
* loop. You need to run the safe for-each loop instead:
*
* struct foo *iterator, *next;
* nvListForEachEntry_safe(iterator, next, &bar.list_of_foos, entry) {
* if (...)
* nvListDel(&iterator->entry);
* }
*
*/
/**
* The linkage struct for list nodes. This struct must be part of your
* to-be-linked struct. NVListRec is required for both the head of the
* list and for each list node.
*
* Position and name of the NVListRec field is irrelevant.
* There are no requirements that elements of a list are of the same type.
* There are no requirements for a list head, any NVListRec can be a list
* head.
*/
typedef struct NVList {
struct NVList *next, *prev;
} NVListRec, *NVListPtr;
/**
* Initialize the list as an empty list.
*
* Example:
* nvListInit(&bar->list_of_foos);
*
* @param The list to initialized.
*/
static NV_INLINE void
nvListInit(NVListPtr list)
{
list->next = list->prev = list;
}
/**
* Initialize the list as an empty list.
*
* This is functionally the same as nvListInit, but can be used for
* initialization of global variables.
*
* Example:
* static NVListRec list_of_foos = NV_LIST_INIT(&list_of_foos);
*
* @param The list to initialized.
*/
#define NV_LIST_INIT(head) { .prev = (head), .next = (head) }
static NV_INLINE void
__nvListAdd(NVListPtr entry, NVListPtr prev, NVListPtr next)
{
next->prev = entry;
entry->next = next;
entry->prev = prev;
prev->next = entry;
}
/**
* Insert a new element after the given list head. The new element does not
* need to be initialised as empty list.
* The list changes from:
* head -> some element -> ...
* to
* head -> new element -> older element -> ...
*
* Example:
* struct foo *newfoo = malloc(...);
* nvListAdd(&newfoo->entry, &bar->list_of_foos);
*
* @param entry The new element to prepend to the list.
* @param head The existing list.
*/
static NV_INLINE void
nvListAdd(NVListPtr entry, NVListPtr head)
{
__nvListAdd(entry, head, head->next);
}
/**
* Append a new element to the end of the list given with this list head.
*
* The list changes from:
* head -> some element -> ... -> lastelement
* to
* head -> some element -> ... -> lastelement -> new element
*
* Example:
* struct foo *newfoo = malloc(...);
* nvListAppend(&newfoo->entry, &bar->list_of_foos);
*
* @param entry The new element to prepend to the list.
* @param head The existing list.
*/
static NV_INLINE void
nvListAppend(NVListPtr entry, NVListPtr head)
{
__nvListAdd(entry, head->prev, head);
}
static NV_INLINE void
__nvListDel(NVListPtr prev, NVListPtr next)
{
next->prev = prev;
prev->next = next;
}
/**
* Remove the element from the list it is in. Using this function will reset
* the pointers to/from this element so it is removed from the list. It does
* NOT free the element itself or manipulate it otherwise.
*
* Using nvListDel on a pure list head (like in the example at the top of
* this file) will NOT remove the first element from
* the list but rather reset the list as empty list.
*
* Example:
* nvListDel(&foo->entry);
*
* @param entry The element to remove.
*/
static NV_INLINE void
nvListDel(NVListPtr entry)
{
__nvListDel(entry->prev, entry->next);
nvListInit(entry);
}
/**
* Check if the list is empty.
*
* Example:
* nvListIsEmpty(&bar->list_of_foos);
*
* @return True if the list contains one or more elements or False otherwise.
*/
static NV_INLINE NvBool
nvListIsEmpty(const NVListRec *head)
{
return head->next == head;
}
static NV_INLINE int
nvListCount(const NVListRec *head)
{
NVListPtr next;
int count = 0;
for (next = head->next; next != head; next = next->next) {
count++;
}
return count;
}
/**
* Check if entry is present in the list.
*
* Example:
* nvListPresent(&foo->entry, &bar->list_of_foos);
*
* @return 1 if the list contains the specified entry; otherwise, return 0.
*/
static NV_INLINE NvBool
nvListPresent(const NVListRec *entry, const NVListRec *head)
{
const NVListRec *next;
for (next = head->next; next != head; next = next->next) {
if (next == entry) {
return NV_TRUE;
}
}
return NV_FALSE;
}
/**
* Returns a pointer to the container of this list element.
*
* Example:
* struct foo* f;
* f = nv_container_of(&foo->entry, struct foo, entry);
* assert(f == foo);
*
* @param ptr Pointer to the NVListRec.
* @param type Data type of the list element.
* @param member Member name of the NVListRec field in the list element.
* @return A pointer to the data struct containing the list head.
*/
#ifndef nv_container_of
#define nv_container_of(ptr, type, member) \
(type *)((char *)(ptr) - NV_OFFSETOF(type, member))
#endif
/**
* Alias of nv_container_of
*/
#define nvListEntry(ptr, type, member) \
nv_container_of(ptr, type, member)
/**
* Retrieve the first list entry for the given list pointer.
*
* Example:
* struct foo *first;
* first = nvListFirstEntry(&bar->list_of_foos, struct foo, list_of_foos);
*
* @param ptr The list head
* @param type Data type of the list element to retrieve
* @param member Member name of the NVListRec field in the list element.
* @return A pointer to the first list element.
*/
#define nvListFirstEntry(ptr, type, member) \
nvListEntry((ptr)->next, type, member)
/**
* Retrieve the last list entry for the given listpointer.
*
* Example:
* struct foo *first;
* first = nvListLastEntry(&bar->list_of_foos, struct foo, list_of_foos);
*
* @param ptr The list head
* @param type Data type of the list element to retrieve
* @param member Member name of the NVListRec field in the list element.
* @return A pointer to the last list element.
*/
#define nvListLastEntry(ptr, type, member) \
nvListEntry((ptr)->prev, type, member)
#ifdef HAVE_TYPEOF
#define __nv_container_of(ptr, sample, member) \
nv_container_of(ptr, __typeof__(*sample), member)
#else
/* This implementation of __nv_container_of has undefined behavior according
* to the C standard, but it works in many cases. If your compiler doesn't
* support __typeof__() and fails with this implementation, please try a newer
* compiler.
*/
#define __nv_container_of(ptr, sample, member) \
(void *)((char *)(ptr) \
- ((char *)&(sample)->member - (char *)(sample)))
#endif
/**
* Loop through the list given by head and set pos to struct in the list.
*
* Example:
* struct foo *iterator;
* nvListForEachEntry(iterator, &bar->list_of_foos, entry) {
* [modify iterator]
* }
*
* This macro is not safe for node deletion. Use nvListForEachEntry_safe
* instead.
*
* @param pos Iterator variable of the type of the list elements.
* @param head List head
* @param member Member name of the NVListRec in the list elements.
*
*/
#ifdef HAVE_TYPEOF
#define __NV_LIST_SET(x, y) x = y
#else
static NV_INLINE void __nvListSet(void **x, void *y)
{
*x = y;
}
#define __NV_LIST_SET(x, y) __nvListSet((void **) &x, (void *) (y))
#endif
#define nvListForEachEntry(pos, head, member) \
for (__NV_LIST_SET(pos, __nv_container_of((head)->next, pos, member)); \
&pos->member != (head); \
__NV_LIST_SET(pos, __nv_container_of(pos->member.next, pos, member)))
/**
* Loop through the list, keeping a backup pointer to the element. This
* macro allows for the deletion of a list element while looping through the
* list.
*
* See nvListForEachEntry for more details.
*/
#define nvListForEachEntry_safe(pos, tmp, head, member) \
for (__NV_LIST_SET(pos, __nv_container_of((head)->next, pos, member)), \
__NV_LIST_SET(tmp, __nv_container_of(pos->member.next, pos, member)); \
&pos->member != (head); \
__NV_LIST_SET(pos, tmp), \
__NV_LIST_SET(tmp, __nv_container_of(pos->member.next, tmp, member)))
/* NULL-Terminated List Interface
*
* The interface below does _not_ use the NVListRec as described above.
* It is mainly for legacy structures that cannot easily be switched to
* NVListRec.
*
* This interface is for structs like
* struct foo {
* [...]
* struct foo *next;
* [...]
* };
*
* The position and field name of "next" are arbitrary.
*/
/**
* Init the element as null-terminated list.
*
* Example:
* struct foo *list = malloc();
* nvNTListInit(list, next);
*
* @param list The list element that will be the start of the list
* @param member Member name of the field pointing to next struct
*/
#define nvNTListInit(_list, _member) \
(_list)->_member = NULL
/**
* Returns the next element in the list or NULL on termination.
*
* Example:
* struct foo *element = list;
* while ((element = nvNTListNext(element, next)) { }
*
* This macro is not safe for node deletion. Use nvListForEachEntry_safe
* instead.
*
* @param list The list or current element.
* @param member Member name of the field pointing to next struct.
*/
#define nvNTListNext(_list, _member) \
(_list)->_member
/**
* Iterate through each element in the list.
*
* Example:
* struct foo *iterator;
* nvNTListForEachEntry(iterator, list, next) {
* [modify iterator]
* }
*
* @param entry Assigned to the current list element
* @param list The list to iterate through.
* @param member Member name of the field pointing to next struct.
*/
#define nvNTListForEachEntry(_entry, _list, _member) \
for (_entry = _list; _entry; _entry = (_entry)->_member)
/**
* Iterate through each element in the list, keeping a backup pointer to the
* element. This macro allows for the deletion of a list element while
* looping through the list.
*
* See nvNTListForEachEntry for more details.
*
* @param entry Assigned to the current list element
* @param tmp The pointer to the next element
* @param list The list to iterate through.
* @param member Member name of the field pointing to next struct.
*/
#define nvNTListForEachEntrySafe(_entry, _tmp, _list, _member) \
for (_entry = _list, _tmp = (_entry) ? (_entry)->_member : NULL;\
_entry; \
_entry = _tmp, _tmp = (_tmp) ? (_tmp)->_member: NULL)
/**
* Append the element to the end of the list. This macro may be used to
* merge two lists.
*
* Example:
* struct foo *elem = malloc(...);
* nvNTListInit(elem, next)
* nvNTListAppend(elem, list, struct foo, next);
*
* Resulting list order:
* list_item_0 -> list_item_1 -> ... -> elem_item_0 -> elem_item_1 ...
*
* @param entry An entry (or list) to append to the list
* @param list The list to append to. This list must be a valid list, not
* NULL.
* @param type The list type
* @param member Member name of the field pointing to next struct
*/
#define nvNTListAppend(_entry, _list, _type, _member) \
do { \
_type *__iterator = _list; \
while (__iterator->_member) { __iterator = __iterator->_member;}\
__iterator->_member = _entry; \
} while (0)
/**
* Insert the element at the next position in the list. This macro may be
* used to insert a list into a list.
*
* struct foo *elem = malloc(...);
* nvNTListInit(elem, next)
* nvNTListInsert(elem, list, struct foo, next);
*
* Resulting list order:
* list_item_0 -> elem_item_0 -> elem_item_1 ... -> list_item_1 -> ...
*
* @param entry An entry (or list) to append to the list
* @param list The list to insert to. This list must be a valid list, not
* NULL.
* @param type The list type
* @param member Member name of the field pointing to next struct
*/
#define nvNTListInsert(_entry, _list, _type, _member) \
do { \
nvNTListAppend((_list)->_member, _entry, _type, _member); \
(_list)->_member = _entry; \
} while (0)
/**
* Delete the entry from the list by iterating through the list and
* removing any reference from the list to the entry.
*
* Example:
* struct foo *elem = <assign to right element>
* nvNTListDel(elem, list, struct foo, next);
*
* @param entry The entry to delete from the list. entry is always
* re-initialized as a null-terminated list.
* @param list The list containing the entry, set to the new list without
* the removed entry.
* @param type The list type
* @param member Member name of the field pointing to the next entry
*/
#define nvNTListDel(_entry, _list, _type, _member) \
do { \
_type *__e = _entry; \
if (__e == NULL || _list == NULL) break; \
if ((_list) == __e) { \
_list = __e->_member; \
} else { \
_type *__prev = _list; \
while (__prev->_member && __prev->_member != __e) \
__prev = nvNTListNext(__prev, _member); \
if (__prev->_member) \
__prev->_member = __e->_member; \
} \
nvNTListInit(__e, _member); \
} while(0)
#ifdef __cplusplus
}
#endif //__cplusplus
#endif /* _NV_LIST_H_ */

View File

@@ -0,0 +1,219 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2018 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.
*/
/*
* NVIDIA GPZ vulnerability mitigation definitions.
*/
/*
* There are two copies of this file for legacy reasons:
*
* P4: <$NV_SOURCE/>drivers/common/inc/nv_speculation_barrier.h
* Git: <tegra/core/>include/nv_speculation_barrier.h
*
* Both files need to be kept in sync if any changes are required.
*/
#ifndef _NV_SPECULATION_BARRIER_H_
#define _NV_SPECULATION_BARRIER_H_
#define NV_SPECULATION_BARRIER_VERSION 2
/*
* GNU-C/MSC/clang - x86/x86_64 : x86_64, __i386, __i386__
* GNU-C - THUMB mode : __GNUC__, __thumb__
* GNU-C - ARM modes : __GNUC__, __arm__, __aarch64__
* armclang - THUMB mode : __ARMCC_VERSION, __thumb__
* armclang - ARM modes : __ARMCC_VERSION, __arm__, __aarch64__
* GHS - THUMB mode : __ghs__, __THUMB__
* GHS - ARM modes : __ghs__, __ARM__, __ARM64__
*/
#if defined(_M_IX86) || defined(__i386__) || defined(__i386) \
|| defined(__x86_64) || defined(AMD64) || defined(_M_AMD64)
/* All x86 */
#define NV_SPECULATION_BARRIER_x86
#elif defined(macintosh) || defined(__APPLE__) \
|| defined(__powerpc) || defined(__powerpc__) || defined(__powerpc64__) \
|| defined(__POWERPC__) || defined(__ppc) || defined(__ppc__) \
|| defined(__ppc64__) || defined(__PPC__) \
|| defined(__PPC64__) || defined(_ARCH_PPC) || defined(_ARCH_PPC64)
/* All PowerPC */
#define NV_SPECULATION_BARRIER_PPC
#elif (defined(__GNUC__) && defined(__thumb__)) \
|| (defined(__ARMCC_VERSION) && defined(__thumb__)) \
|| (defined(__ghs__) && defined(__THUMB__))
/* ARM-thumb mode(<=ARMv7)/T32 (ARMv8) */
#define NV_SPECULATION_BARRIER_ARM_COMMON
#define NV_SPEC_BARRIER_CSDB ".inst.w 0xf3af8014\n"
#elif (defined(__GNUC__) && defined(__arm__)) \
|| (defined(__ARMCC_VERSION) && defined(__arm__)) \
|| (defined(__ghs__) && defined(__ARM__))
/* aarch32(ARMv8) / arm(<=ARMv7) mode */
#define NV_SPECULATION_BARRIER_ARM_COMMON
#define NV_SPEC_BARRIER_CSDB ".inst 0xe320f014\n"
#elif (defined(__GNUC__) && defined(__aarch64__)) \
|| (defined(__ARMCC_VERSION) && defined(__aarch64__)) \
|| (defined(__ghs__) && defined(__ARM64__))
/* aarch64(ARMv8) mode */
#define NV_SPECULATION_BARRIER_ARM_COMMON
#define NV_SPEC_BARRIER_CSDB "HINT #20\n"
#elif defined(NVCPU_NVRISCV64) && NVOS_IS_LIBOS
# define nv_speculation_barrier()
#else
#error "Unknown compiler/chip family"
#endif
/*
* nv_speculation_barrier -- General-purpose speculation barrier
*
* This approach provides full protection against variant-1 vulnerability.
* However, the recommended approach is detailed below (See:
* nv_array_index_no_speculate)
*
* Semantics:
* Any memory read that is sequenced after a nv_speculation_barrier(),
* and contained directly within the scope of nv_speculation_barrier() or
* directly within a nested scope, will not speculatively execute until all
* conditions for entering that scope have been architecturally resolved.
*
* Example:
* if (untrusted_index_from_user < bound) {
* ...
* nv_speculation_barrier();
* ...
* x = array1[untrusted_index_from_user];
* bit = x & 1;
* y = array2[0x100 * bit];
* }
*/
#if defined(NV_SPECULATION_BARRIER_x86)
// Delete after all references are changed to nv_speculation_barrier
#define speculation_barrier() nv_speculation_barrier()
static inline void nv_speculation_barrier(void)
{
#if defined(__GNUC__) || defined(__clang__)
__asm__ __volatile__ ("lfence" : : : "memory");
#endif
}
#elif defined(NV_SPECULATION_BARRIER_PPC)
static inline void nv_speculation_barrier(void)
{
asm volatile("ori 31,31,0");
}
#elif defined(NV_SPECULATION_BARRIER_ARM_COMMON)
/* Note: Cortex-A9 GNU-assembler seems to complain about DSB SY */
#define nv_speculation_barrier() \
asm volatile \
( \
"DSB sy\n" \
"ISB\n" \
: : : "memory" \
)
#endif
/*
* nv_array_index_no_speculate -- Recommended variant-1 mitigation approach
*
* The array-index-no-speculate approach "de-speculates" an array index that
* has already been bounds-checked.
*
* This approach is preferred over nv_speculation_barrier due to the following
* reasons:
* - It is just as effective as the general-purpose speculation barrier.
* - It clearly identifies what array index is being de-speculated and is thus
* self-commenting, whereas the general-purpose speculation barrier requires
* an explanation of what array index is being de-speculated.
* - It performs substantially better than the general-purpose speculation
* barrier on ARM Cortex-A cores (the difference is expected to be tens of
* cycles per invocation). Within tight loops, this difference may become
* noticeable.
*
* Semantics:
* Provided count is non-zero and the caller has already validated or otherwise
* established that index < count, any speculative use of the return value will
* use a speculative value that is less than count.
*
* Example:
* if (untrusted_index_from_user < bound) {
* untrusted_index_from_user = nv_array_index_no_speculate(
* untrusted_index_from_user, bound);
* ...
* x = array1[untrusted_index_from_user];
* ...
* }
*
* The use of nv_array_index_no_speculate() in the above example ensures that
* subsequent uses of untrusted_index_from_user will not execute speculatively
* (they will wait for the bounds check to complete).
*/
static inline unsigned long nv_array_index_no_speculate(unsigned long index,
unsigned long count)
{
#if defined(NV_SPECULATION_BARRIER_x86) && (defined(__GNUC__) || defined(__clang__))
unsigned long mask;
__asm__ __volatile__
(
"CMP %2, %1 \n"
"SBB %0, %0 \n"
: "=r"(mask) : "r"(index), "r"(count) : "cc"
);
return (index & mask);
#elif defined(NV_SPECULATION_BARRIER_ARM_COMMON)
unsigned long mask;
asm volatile
(
"CMP %[ind], %[cnt] \n"
"SBC %[res], %[cnt], %[cnt] \n"
NV_SPEC_BARRIER_CSDB
: [res] "=r" (mask) : [ind] "r" (index), [cnt] "r" (count): "cc"
);
return (index & mask);
/* Fallback to generic speculation barrier for unsupported platforms */
#else
nv_speculation_barrier();
return index;
#endif
}
#endif //_NV_SPECULATION_BARRIER_H_

189
src/common/inc/nvctassert.h Normal file
View File

@@ -0,0 +1,189 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1997-2019 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.
*/
#ifndef __NV_CTASSERT_H
#define __NV_CTASSERT_H
/*****************************************************************************/
/* Compile Time assert
* -------------------
* Use ct_assert(b) instead of assert(b) whenever the condition 'b' is constant,
* i.e. when 'b' can be determined at compile time.
*
* e.g.: check array size:
* ct_assert(__GL_ARRAYSIZE(arrayName) == constArraySize);
* e.g.: check struct size alignment:
* ct_assert(sizeof(struct xy) % 64 == 0);
*
* When available, standard C or C++ language constructs are used:
* - ISO C++11 defines the static_assert keyword
* - ISO C11 defines the _Static_assert keyword
*
* Note that recent versions of Clang support _Static_assert in all compiler modes
* - not just C11 mode - so we test for that in addition to checking explicitly for
* C11 and C++11 support.
*
* Those new language standards aren't available on all supported platforms; an
* alternate method which involves array declarations is employed in that case,
* described below.
*
* In C, there is a restriction where ct_assert() can be placed:
* It can be placed wherever a variable declaration can be placed, i.e.:
* - either anywhere at file scope
* - or inside a function at the beginning of any {} block; it may be mixed
* with variable declarations.
* e.g.:
* void function()
* {
* ct_assert(...); <-- ok \
* int a; |
* ct_assert(...); <-- ok | declaration section
* int b; |
* ct_assert(...); <-- ok /
*
* a = 0; -- first statement
*
* int c; <-- error
* ct_assert(...); <-- error
*
* {ct_assert(...);} <-- ok (uses its own block for ct_assert())
* }
*
* In CPP, there is no such restriction, i.e. it can be placed at file scope
* or anywhere inside a function or namespace or class (i.e., wherever
* a variable declaration may be placed).
*
* For C code, the mechanism of this ct_assert() is to declare a prototype
* of a function (e.g. compile_time_assertion_failed_in_line_555, if current
* line number is 555), which gets an array as argument:
* (1) the size of this array is +1, if b != 0 (ok)
* (2) the size of this array is -1, if b == 0 (error)
*
* In case (2) the compiler throws an error.
* e.g. msvc compiler:
* error C2118: negative subscript or subscript is too large
* e.g. gcc 2.95.3:
* size of array `_compile_time_assertion_failed_in_line_555' is negative
*
* In case the condition 'b' is not constant, the msvc compiler throws
* an error:
* error C2057: expected constant expression
* In this case the run time assert() must be used.
*
* For C++ code, we use a different technique because the function prototype
* declaration can have function linkage conflicts. If a single compilation
* unit has ct_assert() statements on the same line number in two different
* files, we would have:
*
* compile_time_assertion_failed_in_line_777(...); from xxx.cpp
* compile_time_assertion_failed_in_line_777(...); from xxx.h
*
* That is valid C++. But if either declaration were in an extern "C" block,
* the same function would be declared with two different linkage types and an
* error would ensue.
*
* Instead, ct_assert() for C++ simply declares an array typedef. As in the C
* version, we will get a compilation error if a typedef with a negative size
* is specified. Line numbers are not needed because C++ allows redundant
* typedefs as long as they are all defined the same way. But we tack them on
* anyway in case the typedef name is reported in compiler errors. C does not
* permit redundant typedefs, so this version should not be used in true C
* code. It can be used in extern "C" blocks of C++ code, however. As with
* the C version, MSVC will throw a "negative subscript" or "expected constant
* expression" error if the expression asserted is false or non-constant.
*
* Notes:
* - This ct_assert() does *not* generate any code or variable.
* Therefore there is no need to define it away for RELEASE builds.
* - The integration of the current source file number (__LINE__) ...
* ... would be required in C++ to allow multiple use inside the same
* class/namespace (if we used the C-style expansion), because the id
* must be unique.
* ... is nice to have in C or C++ if the compiler's error message contains
* the id (this is not the case for msvc)
* - Using three nested macros instead of only one is necessary to get the id
* compile_time_assertion_failed_in_line_555
* instead of
* compile_time_assertion_failed_in_line___LINE__
*/
#if defined(__clang__)
# ifndef __has_extension
# define __has_extension __has_feature // Compatibility with Clang pre-3.0 compilers.
# endif
# define CLANG_C_STATIC_ASSERT __has_extension(c_static_assert)
#else
# define CLANG_C_STATIC_ASSERT 0
#endif
// Adding this macro to fix MISRA 2012 rule 20.12
#define NV_CTASSERT_STRINGIFY_MACRO(b) #b
#if !defined(NVOC) && ((defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || CLANG_C_STATIC_ASSERT)
// ISO C11 defines the _Static_assert keyword
# define ct_assert(b) _Static_assert((b), "Compile time assertion failed: " NV_CTASSERT_STRINGIFY_MACRO(b))
# define ct_assert_i(b,line) _Static_assert((b), "Compile time assertion failed: " NV_CTASSERT_STRINGIFY_MACRO(b)NV_CTASSERT_STRINGIFY_MACRO(line))
#elif (defined(__cplusplus) && __cplusplus >= 201103L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L)
// ISO C++11 defines the static_assert keyword
# define ct_assert(b) static_assert((b), "Compile time assertion failed: " NV_CTASSERT_STRINGIFY_MACRO(b))
# define ct_assert_i(b,line) static_assert((b), "Compile time assertion failed: " NV_CTASSERT_STRINGIFY_MACRO(b)NV_CTASSERT_STRINGIFY_MACRO(line))
#else
// For compilers which don't support ISO C11 or C++11, we fall back to an
// array (type) declaration
# define ct_assert(b) ct_assert_i(b,__LINE__)
# define ct_assert_i(b,line) ct_assert_ii(b,line)
# ifdef __cplusplus
# define ct_assert_ii(b,line) typedef char compile_time_assertion_failed_in_line_##line[(b)?1:-1]
# else
/*
* The use of a function prototype "void compile_time_assertion_failed_in_line_##line(..)
* above violates MISRA-C 2012 Rule 8.6 since the rule disallows a function
* declaration without a definition. To fix the MISRA rule, the cplusplus style
* 'typdef char compile_time_assertion_failed_in_line_##line'
* is acceptable, but doesn't work for typical C code since there can be duplicate
* line numbers leading to duplicate typedefs which C doesn't allow.
*
* The following macro uses the predefined macro __COUNTER__ to create unique
* typedefs that fixes the MISRA violations. However, not all C compilers support
* that macro and even for compilers that support it, the underlying code makes
* use of variably modified identifiers in ct_assert that makes the use of this
* unviable.
*
* For now restrict the use of MACRO only on
* i) GCC 4.3.0 and above that supports __COUNTER__ macro
* ii) Specifically the Falcon port of the compiler since the use of variably
* modified identifiers have been removed on those projects
*
* TBD: Enable the macro on MSVC and CLANG pending
*/
# if defined(__GNUC__) && ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 40300) && defined(GCC_FALCON)
# define ct_assert_ii(b,line) ct_assert_iii(b,line,__COUNTER__)
# define ct_assert_iii(b,line,cntr) ct_assert_cntr(b,line,cntr)
# define ct_assert_cntr(b,line,cntr) typedef char cnt##cntr##_compile_time_assertion_failed_in_line_##line[(b)?1:-1] __attribute__((unused))
# else
# define ct_assert_ii(b,line) void compile_time_assertion_failed_in_line_##line(int _compile_time_assertion_failed_in_line_##line[(b) ? 1 : -1])
# endif
# endif
#endif
#endif // __NV_CTASSERT_H

View File

@@ -0,0 +1,183 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2018-2019 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.
*/
#ifndef _NVEGPUCONFIG_H_
#define _NVEGPUCONFIG_H_
#include <nvtypes.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
#define EGPU_INLINE NV_FORCEINLINE
#else //!__cplusplus
#if defined(NV_UNIX) || defined(NVCPU_RISCV64) || defined(NV_MODS)
#define EGPU_INLINE static NV_INLINE
#else //NV_UNIX
#define EGPU_INLINE NV_INLINE
#endif //NV_UNIX
#endif //!__cplusplus
// Surprise removal capable TB3 and TB2 BUS Device ID
#define BUS_DEVICE_ID_TB3_ALPINE_RIDGE_01 0x1578
#define BUS_DEVICE_ID_TB3_02 0x1576
#define BUS_DEVICE_ID_TB3_03 0x15C0
#define BUS_DEVICE_ID_TB3_04 0x15D3
#define BUS_DEVICE_ID_TB3_05 0x15DA
#define BUS_DEVICE_ID_TB3_06 0x15EA
#define BUS_DEVICE_ID_TB3_07 0x15E7
#define BUS_DEVICE_ID_TB3_08 0x15EF
#define BUS_DEVICE_ID_TB3_09 0x1133
#define BUS_DEVICE_ID_TB3_10 0x1136
// IceLake-U TB3 device ids. Below TB3 would be integrated to CPU.
#define BUS_DEVICE_ID_ICELAKE_TB3_01 0x8A1D
#define BUS_DEVICE_ID_ICELAKE_TB3_02 0x8A1F
#define BUS_DEVICE_ID_ICELAKE_TB3_03 0x8A21
#define BUS_DEVICE_ID_ICELAKE_TB3_04 0x8A23
#define BUS_DEVICE_ID_ICELAKE_TB3_05 0x8A0D
#define BUS_DEVICE_ID_ICELAKE_TB3_06 0x8A17
// TigerLake Thunderbolt device ids.
#define BUS_DEVICE_ID_TIGERLAKE_TB3_01 0x9A1B
#define BUS_DEVICE_ID_TIGERLAKE_TB3_02 0x9A1D
#define BUS_DEVICE_ID_TIGERLAKE_TB3_03 0x9A1F
#define BUS_DEVICE_ID_TIGERLAKE_TB3_04 0x9A21
#define BUS_DEVICE_ID_TIGERLAKE_TB3_05 0x9A23
#define BUS_DEVICE_ID_TIGERLAKE_TB3_06 0x9A25
#define BUS_DEVICE_ID_TIGERLAKE_TB3_07 0x9A27
#define BUS_DEVICE_ID_TIGERLAKE_TB3_08 0x9A29
#define BUS_DEVICE_ID_TIGERLAKE_TB3_09 0x9A2B
#define BUS_DEVICE_ID_TIGERLAKE_TB3_10 0x9A2D
//#define BUS_DEVICE_ID_TB2_FALCON_RIDGE_DSL5520_01 0X156C // obsolete
#define BUS_DEVICE_ID_TB2_FALCON_RIDGE_DSL5520_02 0X156D
#define BUS_DEVICE_ID_TB2_03 0x157E
#define BUS_DEVICE_ID_TB2_04 0x156B
#define BUS_DEVICE_ID_TB2_05 0x1567
#define BUS_DEVICE_ID_TB2_06 0x1569
//#define BUS_DEVICE_ID_TB2_07 0x1548 // obsolete
#define BUS_DEVICE_ID_TB2_08 0x151B
#define BUS_DEVICE_ID_TB2_09 0x1549
#define BUS_DEVICE_ID_TB2_10 0x1513
//*****************************************************************************
// Function: isTB3DeviceID
//
// Routine Description:
//
// Function to match the specified Device ID with the known TB3 BUS's
// device IDs.
//
// Arguments:
//
// deviceID[IN]: Device ID to match with the TB3 Bus
//
// Return Value:
//
// true: When the passed Dev ID match with TB3's BUS Device ID
// false: When the passed Dev ID is not matching with known TB3's
// BUS Device ID
//*****************************************************************************
EGPU_INLINE NvBool isTB3DeviceID(NvU16 deviceID)
{
NvU32 index;
NvU16 tb3DeviceIDList[]={ BUS_DEVICE_ID_TB3_ALPINE_RIDGE_01,
BUS_DEVICE_ID_TB3_02,
BUS_DEVICE_ID_TB3_03,
BUS_DEVICE_ID_TB3_04,
BUS_DEVICE_ID_TB3_05,
BUS_DEVICE_ID_TB3_06,
BUS_DEVICE_ID_TB3_07,
BUS_DEVICE_ID_TB3_08,
BUS_DEVICE_ID_TB3_09,
BUS_DEVICE_ID_TB3_10,
BUS_DEVICE_ID_ICELAKE_TB3_01,
BUS_DEVICE_ID_ICELAKE_TB3_02,
BUS_DEVICE_ID_ICELAKE_TB3_03,
BUS_DEVICE_ID_ICELAKE_TB3_04,
BUS_DEVICE_ID_ICELAKE_TB3_05,
BUS_DEVICE_ID_ICELAKE_TB3_06,
BUS_DEVICE_ID_TIGERLAKE_TB3_01,
BUS_DEVICE_ID_TIGERLAKE_TB3_02,
BUS_DEVICE_ID_TIGERLAKE_TB3_03,
BUS_DEVICE_ID_TIGERLAKE_TB3_04,
BUS_DEVICE_ID_TIGERLAKE_TB3_05,
BUS_DEVICE_ID_TIGERLAKE_TB3_06,
BUS_DEVICE_ID_TIGERLAKE_TB3_07,
BUS_DEVICE_ID_TIGERLAKE_TB3_08,
BUS_DEVICE_ID_TIGERLAKE_TB3_09,
BUS_DEVICE_ID_TIGERLAKE_TB3_10
};
for (index = 0; index < (sizeof(tb3DeviceIDList)/sizeof(NvU16)); index++)
{
if (deviceID == tb3DeviceIDList[index])
{
return NV_TRUE;
}
}
return NV_FALSE;
} // isTB3DeviceID
//*****************************************************************************
// Function: isTB2DeviceID
//
// Routine Description:
//
// Function to match the specified Device ID with the known TB2 BUS's
// device IDs.
//
// Arguments:
//
// deviceID[IN]: Device ID to match with the TB2 Bus
//
// Return Value:
//
// true: When the passed Dev ID match with TB2's BUS Device ID
// false: When the passed Dev ID is not matching with known TB2's
// BUS Device ID
//*****************************************************************************
EGPU_INLINE NvBool isTB2DeviceID(NvU16 deviceID)
{
NvU32 index;
NvU16 tb2DeviceIDList[]={ BUS_DEVICE_ID_TB2_FALCON_RIDGE_DSL5520_02,
BUS_DEVICE_ID_TB2_03, BUS_DEVICE_ID_TB2_04,
BUS_DEVICE_ID_TB2_05, BUS_DEVICE_ID_TB2_06,
BUS_DEVICE_ID_TB2_08, BUS_DEVICE_ID_TB2_09,
BUS_DEVICE_ID_TB2_10
};
for (index = 0; index < (sizeof(tb2DeviceIDList)/sizeof(NvU16)); index++)
{
if (deviceID == tb2DeviceIDList[index])
{
return NV_TRUE;
}
}
return NV_FALSE;
} // isTB2DeviceID
#ifdef __cplusplus
}
#endif
#endif //_NVEGPUCONFIG_H_

529
src/common/inc/nvlog_defs.h Normal file
View File

@@ -0,0 +1,529 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2012-2021 NVIDIA CORPORATION & AFFILIATES
* 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.
*/
#ifndef _NVLOG_DEFS_H_
#define _NVLOG_DEFS_H_
#include "nvtypes.h"
/******************* Common Debug & Trace Defines ***************************\
* *
* Module: NVLOG_DEFS.H *
* *
\****************************************************************************/
#define NVLOG_MAX_DBG_MODULES 256
/********************************/
/********* Structures *********/
/********************************/
// Forward declaration, so it can be used in the function type definition.
/**
* @brief Struct representing a buffer in NvLog
*
* All logging (Print, Regtrace, etc) use these buffers.
*/
typedef struct _NVLOG_BUFFER NVLOG_BUFFER;
/**
* @brief Type of the 'push' function for NvLog buffers
*
* Function called whenever pushing something to an NvLog buffer
*/
typedef NvBool (*NVLOG_BUFFER_PUSHFUNC) (NVLOG_BUFFER *, NvU8 *, NvU32);
/**
* @brief Fields specific to ring buffers
*/
typedef struct _NVLOG_RING_BUFFER_EXTRA_FIELDS
{
/** How many times the ring buffer has overflown */
NvU32 overflow;
} NVLOG_RING_BUFFER_EXTRA_FIELDS;
/**
* @brief Struct representing a buffer in NvLog
*
* All logging (Print, Regtrace, etc) use these buffers.
*/
struct _NVLOG_BUFFER
{
/** Function to call when writing to this buffer */
union
{
NVLOG_BUFFER_PUSHFUNC fn;
// Pad this union to prevent struct size from varying between 32/64 bit platforms
NvP64 padding;
} push;
/** Size of the buffer data section */
NvU32 size;
/** Buffer tag, for easier identification in a dump */
NvU32 tag;
/** Flags of the buffer, following NVLOG_BUFFER_FLAGS_* DRF's */
NvU32 flags;
/** Position of the next available byte in the buffer */
NvU32 pos;
/** Number of threads currently writing to this buffer */
volatile NvS32 threadCount;
/** Specific buffer types will define their fields here */
union
{
NVLOG_RING_BUFFER_EXTRA_FIELDS ring;
} extra;
/** Buffer data. */
NvU8 data[1];
};
#define NVLOG_MAX_BUFFERS_v11 16
#define NVLOG_MAX_BUFFERS_v12 256
#if NVOS_IS_UNIX
#define NVLOG_MAX_BUFFERS NVLOG_MAX_BUFFERS_v12
#define NVLOG_LOGGER_VERSION 12 // v1.2
#else
#define NVLOG_MAX_BUFFERS NVLOG_MAX_BUFFERS_v11
#define NVLOG_LOGGER_VERSION 11 // v1.1
#endif // NVOS_IS_UNIX
//
// Due to this file's peculiar location, NvPort may or may not be includable
// This hack will go away when NvLog is moved into common/shared
//
#if NVOS_IS_MACINTOSH
#if !PORT_IS_KERNEL_BUILD
typedef struct PORT_SPINLOCK PORT_SPINLOCK;
#else
#include "nvport/nvport.h"
#endif
#elif !defined(PORT_IS_KERNEL_BUILD)
typedef struct PORT_SPINLOCK PORT_SPINLOCK;
#else
#include "nvport/nvport.h"
#endif
/**
* @brief Information about the entire NvLog system
*/
typedef struct _NVLOG_LOGGER
{
/** NvLog logger version */
NvU32 version;
/** Logging buffers */
NVLOG_BUFFER * pBuffers[NVLOG_MAX_BUFFERS];
/** Index of the first unallocated buffer */
NvU32 nextFree;
/** Total number of free buffer slots */
NvU32 totalFree;
/** Lock for all buffer oprations */
PORT_SPINLOCK* mainLock;
} NVLOG_LOGGER;
extern NVLOG_LOGGER NvLogLogger;
//
// Buffer flags
//
// Logging to this buffer is disabled
#define NVLOG_BUFFER_FLAGS_DISABLED 0:0
#define NVLOG_BUFFER_FLAGS_DISABLED_NO 0
#define NVLOG_BUFFER_FLAGS_DISABLED_YES 1
#define NVLOG_BUFFER_FLAGS_TYPE 2:1
#define NVLOG_BUFFER_FLAGS_TYPE_RING 0
#define NVLOG_BUFFER_FLAGS_TYPE_NOWRAP 1
#define NVLOG_BUFFER_FLAGS_TYPE_SYSTEMLOG 2
// Expand buffer when full
#define NVLOG_BUFFER_FLAGS_EXPANDABLE 3:3
#define NVLOG_BUFFER_FLAGS_EXPANDABLE_NO 0
#define NVLOG_BUFFER_FLAGS_EXPANDABLE_YES 1
// Allocate buffer in non paged memory
#define NVLOG_BUFFER_FLAGS_NONPAGED 4:4
#define NVLOG_BUFFER_FLAGS_NONPAGED_NO 0
#define NVLOG_BUFFER_FLAGS_NONPAGED_YES 1
//
// Type of buffer locking to use
// NONE - No locking performed, for buffers that are inherently single threaded
// STATE - Lock only during state change, do memory copying unlocked
// Don't use with tiny buffers that overflow every write or two.
// FULL - Keep everything locked for the full duration of the write
//
#define NVLOG_BUFFER_FLAGS_LOCKING 6:5
#define NVLOG_BUFFER_FLAGS_LOCKING_NONE 0
#define NVLOG_BUFFER_FLAGS_LOCKING_STATE 1
#define NVLOG_BUFFER_FLAGS_LOCKING_FULL 2
// Store this buffer in OCA minidumps
#define NVLOG_BUFFER_FLAGS_OCA 7:7
#define NVLOG_BUFFER_FLAGS_OCA_NO 0
#define NVLOG_BUFFER_FLAGS_OCA_YES 1
// Buffer format (not included in registry key)
#define NVLOG_BUFFER_FLAGS_FORMAT 10:8
#define NVLOG_BUFFER_FLAGS_FORMAT_PRINTF 0
#define NVLOG_BUFFER_FLAGS_FORMAT_LIBOS_LOG 1
#define NVLOG_BUFFER_FLAGS_FORMAT_MEMTRACK 2
// Buffer GPU index
#define NVLOG_BUFFER_FLAGS_GPU_INSTANCE 31:24
typedef NvU32 NVLOG_BUFFER_HANDLE;
//
// Utility macros
//
#define NVLOG_IS_RING_BUFFER(pBuffer) \
FLD_TEST_DRF(LOG_BUFFER, _FLAGS, _TYPE, _RING, pBuffer->flags)
#define NVLOG_IS_NOWRAP_BUFFER(pBuffer) \
FLD_TEST_DRF(LOG_BUFFER, _FLAGS, _TYPE, _NOWRAP, pBuffer->flags)
#define NVLOG_PRINT_BUFFER_SIZE(pBuffer) ((pBuffer)->size)
#define NVLOG_BUFFER_SIZE(pBuffer) \
(NV_OFFSETOF(NVLOG_BUFFER, data) + NVLOG_PRINT_BUFFER_SIZE(pBuffer))
/********************************/
/********* Filtering **********/
/********************************/
// TODO - Remove all this once tools are updated
#define NVLOG_FILTER_INVALID (~0)
#define NVLOG_FILTER_VALUE_SIMPLE_NO 0x0
#define NVLOG_FILTER_VALUE_SIMPLE_YES 0x1
#define NVLOG_FILTER_VALUE_EXPLICIT_NO 0x2
#define NVLOG_FILTER_VALUE_EXPLICIT_YES 0x3
#define NVLOG_FILTER_PRINT_LEVEL_REGTRACE 1:0
#define NVLOG_FILTER_PRINT_LEVEL_INFO 3:2
#define NVLOG_FILTER_PRINT_LEVEL_NOTICE 5:4
#define NVLOG_FILTER_PRINT_LEVEL_WARNINGS 7:6
#define NVLOG_FILTER_PRINT_LEVEL_ERRORS 9:8
#define NVLOG_FILTER_PRINT_LEVEL_HW_ERROR 11:10
#define NVLOG_FILTER_PRINT_LEVEL_FATAL 13:12
#define NVLOG_FILTER_PRINT_BUFFER 18:14
#define NVLOG_FILTER_REGTRACE_BUFFER 22:19
#define NVLOG_FILTER_REGTRACE_LOG_READ 25:23
#define NVLOG_FILTER_REGTRACE_LOG_WRITE 27:26
#define NVLOG_FILTER_REGTRACE_BREAK_READ 29:28
#define NVLOG_FILTER_REGTRACE_BREAK_WRITE 31:30
#define NVLOG_FILTER_VALUE_IS_NO(val) ((val & 0x1) == 0)
#define NVLOG_FILTER_VALUE_IS_YES(val) (val & 0x1)
#define NVLOG_FILTER_PRINT_GET_VALUE(level, num) ((num >> (level*2)) & 0x3)
/**
* @brief Type representing a value of a given 16bit range.
*/
typedef struct _NVLOG_RANGE_16
{
NvU16 low;
NvU16 high;
NvU32 value;
} NVLOG_RANGE_16;
/**
* @brief Type representing a value of a given 32bit range.
*/
typedef struct _NVLOG_RANGE_32
{
NvU32 low;
NvU32 high;
NvU32 value;
} NVLOG_RANGE_32;
//
// Maximum number of files that have a filter assigned to them.
//
#define NVLOG_MAX_FILES 1
//
// Maximum number of line rules (both single line and range) allowed per file
//
#define NVLOG_FILELINE_FILTER_MAX_RANGES 1
/**
* @brief Internal type for NVLOG_FILELINE_FILTER.
*
* Contains filtering info for a single file.
*/
typedef struct _NVLOG_FILELINE_FILTER_FILEHASH
{
/** ID of the file (24bit MD5) */
NvU32 fileId;
/** Number of elements in the array 'ranges' */
NvU32 numElems;
/** Value to use if the given value isn't found in the range array */
NvU32 defaultValue;
/** Array of ranges representing lines in the file */
NVLOG_RANGE_16 ranges[NVLOG_FILELINE_FILTER_MAX_RANGES];
} NVLOG_FILELINE_FILTER_FILEHASH;
/**
* @brief Filter that contains rules that depend on the file and line number.
*/
typedef struct _NVLOG_FILELINE_FILTER
{
/** Number of elements in the fileHash array */
NvU32 numFiles;
/** Value to use if a given file isn't found */
NvU32 defaultValue;
/** Array of file entries, ordered as a hash table */
NVLOG_FILELINE_FILTER_FILEHASH fileHash[NVLOG_MAX_FILES];
} NVLOG_FILELINE_FILTER;
/********************************/
/********* Print Logger *********/
/********************************/
#define NVLOG_PRINT_LOGGER_VERSION 11 // v1.1
// Max buffers cannot be over 32.
#define NVLOG_PRINT_MAX_BUFFERS 8
#define NVLOG_PRINT_BUFFER_PRIMARY 1
#define NVLOG_PRINT_BUFFER_SECONDARY 2
#define NVLOG_PRINT_BUFFER_SYSTEMLOG 3
#define NVLOG_PRINT_DESC1_FILEID 23:0
#define NVLOG_PRINT_DESC1_GPUID 28:24 // 2^5 = 32 possible
#define NVLOG_PRINT_DESC1_MAGIC 31:29
#define NVLOG_PRINT_DESC1_MAGIC_VALUE 5
#define NVLOG_PRINT_DESC2_LINEID 15:0
#define NVLOG_PRINT_DESC2_GROUPID 17:16
#define NVLOG_PRINT_DESC2_GROUPID_RM 0
#define NVLOG_PRINT_DESC2_GROUPID_PMU 1
#define NVLOG_PRINT_DESC2_OPT_DATA_COUNT 24:18 // number of dwords
#define NVLOG_PRINT_DESC2_OPT_DATA_COUNT_MAX 0x7F
#define NVLOG_PRINT_DESC2_RESERVED 28:25
#define NVLOG_PRINT_DESC2_MAGIC 31:29
#define NVLOG_PRINT_DESC2_MAGIC_VALUE 6
#define NVLOG_UNKNOWN_GPU_INSTANCE 0x1f
#define NVLOG_PRINT_MODULE_FILTER_VALUE 1:0
#define NVLOG_PRINT_MODULE_FILTER_BUFFER 6:2
#define NVLOG_PRINT_MODULE_FILTER_ENABLED 7:7
//
// Regkey fields - These are copied directly from nvRmReg.h
// A copy is necessary as these might be needed on systems that don't
// have nvRmReg.h, such as DVS builds for NvWatch
//
#ifndef NV_REG_STR_RM_NVLOG
#define NV_REG_STR_RM_NVLOG "RMNvLog"
#define NV_REG_STR_RM_NVLOG_BUFFER_FLAGS 7:0
#define NV_REG_STR_RM_NVLOG_BUFFER_SIZE 23:8
#define NV_REG_STR_RM_NVLOG_BUFFER_SIZE_DEFAULT ((NVOS_IS_WINDOWS||NVOS_IS_MACINTOSH)?8:250)
#define NV_REG_STR_RM_NVLOG_BUFFER_SIZE_DISABLE 0
#define NV_REG_STR_RM_NVLOG_RUNTIME_LEVEL 28:25
#define NV_REG_STR_RM_NVLOG_TIMESTAMP 30:29
#define NV_REG_STR_RM_NVLOG_TIMESTAMP_NONE 0
#define NV_REG_STR_RM_NVLOG_TIMESTAMP_32 1
#define NV_REG_STR_RM_NVLOG_TIMESTAMP_64 2
#define NV_REG_STR_RM_NVLOG_TIMESTAMP_32_DIFF 3
#define NV_REG_STR_RM_NVLOG_INITED 31:31
#define NV_REG_STR_RM_NVLOG_INITED_NO 0
#define NV_REG_STR_RM_NVLOG_INITED_YES 1
#endif // NV_REG_STR_RM_NVLOG
//
// Arg types:
// 0: Special meaning. End of argument list.
// 1: d, u, x, X, i, o - Integer type
// 2: lld, llu, llx, llX, lli, llo - Long long integer type
// 3: s - string type (size is 0)
// 4: p - pointer type
// 5: c - char type
// 6: f, g, e, F, G, E - floating point type
// 7-14: Unused at the moment, default value is 0
// 15: Special meaning. Error value - unsupported type.
//
#define NVLOG_PRINT_MAX_ARG_TYPES 0x10
#define NVLOG_PRINT_ARG_TYPE_ARGLIST_END 0x0
#define NVLOG_PRINT_ARG_TYPE_INT 0x1
#define NVLOG_PRINT_ARG_TYPE_LONGLONG 0x2
#define NVLOG_PRINT_ARG_TYPE_STRING 0x3
#define NVLOG_PRINT_ARG_TYPE_POINTER 0x4
#define NVLOG_PRINT_ARG_TYPE_CHAR 0x5
#define NVLOG_PRINT_ARG_TYPE_FLOAT 0x6
#define NVLOG_PRINT_ARG_TYPE_ERROR 0xf
/**
* @brief Signature of the database required to decode the print logs
*
* The sig1-sig3 values are generated randomly at compile time.
*/
typedef struct _NVLOG_DB_SIGNATURE
{
NvU32 timestamp;
NvU32 sig1;
NvU32 sig2;
NvU32 sig3;
} NVLOG_DB_SIGNATURE;
/**
* @brief Filter that contains all rules used to filter DBG_PRINTF calls
*/
typedef struct _NVLOG_PRINT_FILTER
{
/** Same file:line filter is shared with the Regtrace system */
NVLOG_FILELINE_FILTER *pFileLineFilter;
/** Filter based on debug levels. Uses NVLOG_FILTER_PRINT_LEVEL_* DRF's */
NvU32 runtimePrintLevelFilter;
/** Filter based on debug modules. Uses NVLOG_PRINT_MODULE_FILTER_* DRF's */
NvU8 runtimePrintModuleFilter[NVLOG_MAX_DBG_MODULES];
} NVLOG_PRINT_FILTER;
/**
* @brief Enum representing all possible argument types to DBG_PRINTF
*/
typedef enum _NVLOG_ARGTYPE
{
NVLOG_ARGTYPE_NONE,
NVLOG_ARGTYPE_INT,
NVLOG_ARGTYPE_LONG_LONG_INT,
NVLOG_ARGTYPE_STRING,
NVLOG_ARGTYPE_POINTER,
NVLOG_ARGTYPE_FLOAT,
NVLOG_ARGTYPE__COUNT
} NVLOG_ARGTYPE;
/**
* @brief General info about the NvLog Print system
*/
typedef struct _NVLOG_PRINT_LOGGER
{
/** NvLog print logger version */
NvU32 version;
/** Runtime argument sizes (16 different arglist values) */
NvU8 runtimeSizes[NVLOG_PRINT_MAX_ARG_TYPES];
/** Database signature for decoding */
NVLOG_DB_SIGNATURE signature;
/** Filter buffer for print statements */
NVLOG_PRINT_FILTER filter;
/** Flags for all NvLog print buffers */
NvU32 flags;
/** Buffer indices for all nvlog buffers. buffers[1] is default. */
NvU32 buffers[NVLOG_PRINT_MAX_BUFFERS];
/** Initialized flag, set to true after nvlogPrintInit has executed */
NvBool initialized;
/** Paused flag, set to true after nvlogPrintInit has executed */
NvBool paused;
} NVLOG_PRINT_LOGGER;
extern NVLOG_PRINT_LOGGER NvLogPrintLogger;
#define NVLOG_PRINT_BUFFER_TAG(_i) NvU32_BUILD('t','r','p','0' + (_i))
/********************************/
/********** Regtrace **********/
/********************************/
#define NVLOG_REGTRACE_LOGGER_VERSION 10 // v1.0
#define NVLOG_REGTRACE_MAX_BUFFERS 4
#define NVLOG_REGTRACE_READ 0
#define NVLOG_REGTRACE_WRITE 1
#define NVLOG_REGTRACE_DESC1_FILEID NVLOG_PRINT_DESC1_FILEID
#define NVLOG_REGTRACE_DESC1_GPUID NVLOG_PRINT_DESC1_GPUID
#define NVLOG_REGTRACE_DESC1_MAGIC NVLOG_PRINT_DESC1_MAGIC
#define NVLOG_REGTRACE_DESC1_MAGIC_VALUE (NVLOG_PRINT_DESC1_MAGIC_VALUE-1)
#define NVLOG_REGTRACE_DESC2_LINEID 15:0
#define NVLOG_REGTRACE_DESC2_READWRITE 16:16
#define NVLOG_REGTRACE_DESC2_READWRITE_READ NVLOG_REGTRACE_READ
#define NVLOG_REGTRACE_DESC2_READWRITE_WRITE NVLOG_REGTRACE_WRITE
#define NVLOG_REGTRACE_DESC2_REGSIZE 18:17
#define NVLOG_REGTRACE_DESC2_REGSIZE_8 0
#define NVLOG_REGTRACE_DESC2_REGSIZE_16 1
#define NVLOG_REGTRACE_DESC2_REGSIZE_32 2
#define NVLOG_REGTRACE_DESC2_REGSIZE_64 3
#define NVLOG_REGTRACE_DESC2_THREADID 28:19
#define NVLOG_REGTRACE_DESC2_MAGIC 31:29
#define NVLOG_REGTRACE_DESC2_MAGIC_VALUE 3
/**
* @brief Single entry in an NvLog Regtrace buffer.
*/
typedef struct _NVLOG_REGTRACE_RECORD
{
/** Uses NVLOG_REGTRACE_DESC1_* DRF's */
NvU32 desc1;
/** Uses NVLOG_REGTRACE_DESC1_* DRF's */
NvU32 desc2;
/** Address of the register being accessed */
NvU32 address;
/** Value that was read/written */
NvU32 value;
} NVLOG_REGTRACE_RECORD;
#define NVLOG_REGTRACE_FILTER_MAX_RANGES 256
// Regtrace shares the file:line filter with print
/**
* @brief Filter that contains all rules used to filter register access logging
*/
typedef struct _NVLOG_REGTRACE_FILTER
{
/** Number of elements in the 'ranges' array */
NvU32 numRanges;
/** File:line based filter. Shared with NvLog print system */
NVLOG_FILELINE_FILTER *pFileLineFilter;
/** Range array for filtering based on register addresses */
NVLOG_RANGE_32 ranges[NVLOG_REGTRACE_FILTER_MAX_RANGES];
} NVLOG_REGTRACE_FILTER;
/**
* @brief General info about the NvLog Regtrace system
*/
typedef struct _NVLOG_REGTRACE_LOGGER
{
/** NvLog regtrace logger version */
NvU32 version;
/** Filter buffer for regtrace statements */
NVLOG_REGTRACE_FILTER filter;
/** Buffer indices for all NvLog buffers. First element is default buffer */
NvU32 buffers[NVLOG_REGTRACE_MAX_BUFFERS];
} NVLOG_REGTRACE_LOGGER;
#endif // _NVLOG_DEFS_H_

View File

@@ -0,0 +1,39 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2012-2016 NVIDIA CORPORATION & AFFILIATES
* 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.
*/
//
// This file must not have include guards, it is supposed to be included
// multiple times - Once in a precompiled header, once through noprecomp.h
//
// WAR for a GCC precompiled headers problem
#if !defined(NV_RM_PRECOMPILED_HEADER)
#include "nvlog_inc2.h"
//
// If noprecomp is not included, this will not expand and will result in an
// undefined identifier. Hopefully, the meaningful name will hint at the
// underlying problem.
//
#define ___please_include_noprecomp_h___
#endif

View File

@@ -0,0 +1,46 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2013,2016-2017,2020-2020 NVIDIA CORPORATION & AFFILIATES
* 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.
*/
#ifndef _NVLOG_INC2_H_
#define _NVLOG_INC2_H_
//
// Include the auto-generated g_$(filename)-nvlog.h header. The file contains
// information about the trace statements that was pulled out by the NvLog preprocessor.
// NVLOG_INCLUDE is defined by make at compile time, for every source file.
//
// The four lines of macros is some trickiness needed to make it work.
//
#if (defined(NVLOG_ENABLED) || defined(NV_MODS)) && defined(NVLOG_INCLUDE) && !defined(NVLOG_PARSING)
#if NVLOG_ENABLED || defined(NV_MODS)
#ifndef NVLOG_FILEID // Acts as an include guard
#define NVLOG_INCLUDE3(a) #a
#define NVLOG_INCLUDE2(a) NVLOG_INCLUDE3 a
#define NVLOG_INCLUDE1 NVLOG_INCLUDE2((NVLOG_INCLUDE))
#include NVLOG_INCLUDE1
#endif // NVLOG_FILEID
#endif // NVLOG_ENABLED
#endif // defined(NVLOG_ENABLED) && defined(NVLOG_INCLUDE)
#endif // _NVLOG_INC2_H_

278
src/common/inc/prbrt.h Normal file
View File

@@ -0,0 +1,278 @@
/*
* Lightweight protocol buffers.
*
* Based on code taken from
* https://code.google.com/archive/p/lwpb/source/default/source
*
* The code there is licensed as Apache 2.0. However, NVIDIA has received the
* code from the original author under MIT license terms.
*
*
* Copyright 2009 Simon Kallweit
* Copyright 2010-2018 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*
* 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.
*/
/*
* This file contains the definitions used by the code generated
* by the protobuf compiler.
*/
#ifndef __PRBRT_H__
#define __PRBRT_H__
// Maximum depth of message embedding
#ifndef PRB_MAX_DEPTH
#define PRB_MAX_DEPTH 8
#endif
// Maximum number of required fields in a message
#ifndef PRB_MAX_REQUIRED_FIELDS
#define PRB_MAX_REQUIRED_FIELDS 16
#endif
// Provide enum names as strings
#ifndef PRB_ENUM_NAMES
#define PRB_ENUM_NAMES 0
#endif
#if PRB_ENUM_NAMES
#define PRB_MAYBE_ENUM_NAME(n) n,
#else
#define PRB_MAYBE_ENUM_NAME(n)
#endif
// Provide field names as strings
#ifndef PRB_FIELD_NAMES
#define PRB_FIELD_NAMES 0
#endif
#if PRB_FIELD_NAMES
#define PRB_MAYBE_FIELD_NAME(n) n,
#else
#define PRB_MAYBE_FIELD_NAME(n)
#endif
// Provide field default values
#ifndef PRB_FIELD_DEFAULTS
#define PRB_FIELD_DEFAULTS 0
#endif
#if PRB_FIELD_DEFAULTS
#define PRB_MAYBE_FIELD_DEFAULT_DEF(n) n
#define PRB_MAYBE_FIELD_DEFAULT(n) n,
#else
#define PRB_MAYBE_FIELD_DEFAULT_DEF(n)
#define PRB_MAYBE_FIELD_DEFAULT(n)
#endif
// Provide message names as strings
#ifndef PRB_MESSAGE_NAMES
#define PRB_MESSAGE_NAMES 0
#endif
#if PRB_MESSAGE_NAMES
#define PRB_MAYBE_MESSAGE_NAME(n) n,
#else
#define PRB_MAYBE_MESSAGE_NAME(n)
#endif
// Provide method names as strings
#ifndef PRB_METHOD_NAMES
#define PRB_METHOD_NAMES 0
#endif
#if PRB_METHOD_NAMES
#define PRB_MAYBE_METHOD_NAME(n) n,
#else
#define PRB_MAYBE_METHOD_NAME(n)
#endif
// Provide service names as strings
#ifndef PRB_SERVICE_NAMES
#define PRB_SERVICE_NAMES 0
#endif
#if PRB_SERVICE_NAMES
#define PRB_MAYBE_SERVICE_NAME(n) n,
#else
#define PRB_MAYBE_SERVICE_NAME(n)
#endif
// Field labels
#define PRB_REQUIRED 0
#define PRB_OPTIONAL 1
#define PRB_REPEATED 2
// Field value types
#define PRB_DOUBLE 0
#define PRB_FLOAT 1
#define PRB_INT32 2
#define PRB_INT64 3
#define PRB_UINT32 4
#define PRB_UINT64 5
#define PRB_SINT32 6
#define PRB_SINT64 7
#define PRB_FIXED32 8
#define PRB_FIXED64 9
#define PRB_SFIXED32 10
#define PRB_SFIXED64 11
#define PRB_BOOL 12
#define PRB_ENUM 13
#define PRB_STRING 14
#define PRB_BYTES 15
#define PRB_MESSAGE 16
// Field flags
#define PRB_HAS_DEFAULT (1 << 0)
#define PRB_IS_PACKED (1 << 1)
#define PRB_IS_DEPRECATED (1 << 2)
typedef struct
{
unsigned int label : 2;
unsigned int typ : 6;
unsigned int flags : 8;
} PRB_FIELD_OPTS;
// Protocol buffer wire types
typedef enum
{
WT_VARINT = 0,
WT_64BIT = 1,
WT_STRING = 2,
WT_32BIT = 5
} WIRE_TYPE;
// Protocol buffer wire values
typedef union
{
NvU64 varint;
NvU64 int64;
struct {
NvU64 len;
const void *data;
} string;
NvU32 int32;
} WIRE_VALUE;
typedef struct
{
char *str;
NvU32 len;
} PRB_VALUE_STRING;
typedef struct
{
NvU8 *data;
NvU32 len;
} PRB_VALUE_BYTES;
typedef struct
{
void *data;
NvU32 len;
} PRB_VALUE_MESSAGE;
typedef union
{
NvF64 double_;
NvF32 float_;
NvS32 int32;
NvS64 int64;
NvU32 uint32;
NvU64 uint64;
NvBool bool_;
PRB_VALUE_STRING string;
PRB_VALUE_BYTES bytes;
PRB_VALUE_MESSAGE message;
int enum_;
int null;
} PRB_VALUE;
typedef struct
{
int value;
#if PRB_ENUM_NAMES
const char *name;
#endif
} PRB_ENUM_MAPPING;
typedef struct
{
const PRB_ENUM_MAPPING *mappings;
NvU32 count;
#if PRB_ENUM_NAMES
const char *name;
#endif
} PRB_ENUM_DESC;
struct PRB_MSG_DESC;
//* Protocol buffer field descriptor
typedef struct PRB_FIELD_DESC
{
NvU32 number;
PRB_FIELD_OPTS opts;
const struct PRB_MSG_DESC *msg_desc;
const PRB_ENUM_DESC *enum_desc;
#if PRB_FIELD_NAMES
const char *name;
#endif
#if PRB_FIELD_DEFAULTS
const PRB_VALUE *def;
#endif
} PRB_FIELD_DESC;
//* Protocol buffer message descriptor
typedef struct PRB_MSG_DESC
{
NvU32 num_fields;
const PRB_FIELD_DESC *fields;
#if PRB_MESSAGE_NAMES
const char *name;
#endif
} PRB_MSG_DESC;
// Forward declaration
struct PRB_SERVICE_DESC;
// Protocol buffer method descriptor
struct PRB_METHOD_DESC
{
const struct PRB_SERVICE_DESC *service;
const PRB_MSG_DESC *req_desc;
const PRB_MSG_DESC *res_desc;
#if PRB_METHOD_NAMES
const char *name;
#endif
};
// Protocol buffer service descriptor
typedef struct PRB_SERVICE_DESC
{
NvU32 num_methods;
const struct PRB_METHOD_DESC *methods;
#if PRB_SERVICE_NAMES
const char *name;
#endif
} PRB_SERVICE_DESC;
#endif

43
src/common/inc/rmosxfac.h Normal file
View File

@@ -0,0 +1,43 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2003 NVIDIA CORPORATION & AFFILIATES
* 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.
*/
#ifndef _RMOSXFAC_H_
#define _RMOSXFAC_H_
/**************** Resource Manager Defines and Structures ******************\
* *
* Module: RMOSXFAC.H *
* Declarations for common OS interface functions. *
* *
\***************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
extern NvS32 RmInitRm(void);
extern NvS32 RmDestroyRm(void);
#ifdef __cplusplus
}
#endif
#endif // _RMOSXFAC_H_

View File

@@ -0,0 +1,45 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2003-2022 NVIDIA CORPORATION & AFFILIATES
* 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.
*/
#ifndef __ga100_dev_boot_h__
#define __ga100_dev_boot_h__
#define NV_PMC 0x00000fff:0x00000000 /* RW--D */
#define NV_PMC_BOOT_0 0x00000000 /* R--4R */
#define NV_PMC_ENABLE 0x00000200 /* RW-4R */
#define NV_PMC_ENABLE_DEVICE(i) (i):(i) /* */
#define NV_PMC_ENABLE_DEVICE__SIZE_1 32 /* */
#define NV_PMC_ENABLE_DEVICE_DISABLE 0x00000000 /* */
#define NV_PMC_ENABLE_DEVICE_ENABLE 0x00000001 /* */
#define NV_PMC_ENABLE_NVDEC 15:15 /* */
#define NV_PMC_ENABLE_NVDEC_DISABLED 0x00000000 /* */
#define NV_PMC_ENABLE_NVDEC_ENABLED 0x00000001 /* */
#define NV_PMC_DEVICE_ENABLE(i) (0x000000600+(i)*4) /* RW-4A */
#define NV_PMC_DEVICE_ENABLE__SIZE_1 1 /* */
#define NV_PMC_DEVICE_ENABLE__PRIV_LEVEL_MASK 0x00000084 /* */
#define NV_PMC_DEVICE_ENABLE_STATUS 31:0 /* RWIVF */
#define NV_PMC_DEVICE_ENABLE_STATUS_DISABLE_ALL 0x00000000 /* RWI-V */
#define NV_PMC_DEVICE_ENABLE_STATUS_BIT(i) (i):(i) /* */
#define NV_PMC_DEVICE_ENABLE_STATUS_BIT__SIZE_1 32 /* */
#define NV_PMC_DEVICE_ENABLE_STATUS_BIT_DISABLE 0x00000000 /* */
#define NV_PMC_DEVICE_ENABLE_STATUS_BIT_ENABLE 0x00000001 /* */
#endif // __ga100_dev_boot_h__

View File

@@ -0,0 +1,32 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES
* 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.
*/
#ifndef ga100_dev_nv_bus_h
#define ga100_dev_nv_bus_h
#define NV_PBUS_SW_SCRATCH(i) (0x00001400+(i)*4) /* RW-4A */
#define NV_PBUS_SW_SCRATCH__SIZE_1 64 /* */
#define NV_PBUS_SW_SCRATCH_FIELD 31:0 /* RWIVF */
#define NV_PBUS_SW_SCRATCH_FIELD_INIT 0x00000000 /* RWI-V */
#endif // ga100_dev_nv_bus_h

View File

@@ -0,0 +1,31 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES
* 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.
*/
#ifndef ga100_dev_nv_bus_addendum_h
#define ga100_dev_nv_bus_addendum_h
#define NV_PBUS_SW_SCRATCH1_SMC_MODE 15:15
#define NV_PBUS_SW_SCRATCH1_SMC_MODE_OFF 0x00000000
#define NV_PBUS_SW_SCRATCH1_SMC_MODE_ON 0x00000001
#endif // ga100_dev_nv_bus_addendum_h

View File

@@ -0,0 +1,33 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2003-2021 NVIDIA CORPORATION & AFFILIATES
* 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.
*/
#ifndef __ga100_dev_ce_h__
#define __ga100_dev_ce_h__
#define NV_CE_PCE_MAP 0x00104028 /* R--4R */
#define NV_CE_PCE2LCE_CONFIG__SIZE_1 18 /* */
#define NV_CE_PCE2LCE_CONFIG_PCE_ASSIGNED_LCE_NONE 0x0000000f /* RW--V */
#define NV_CE_GRCE_CONFIG__SIZE_1 2 /* */
#define NV_CE_GRCE_CONFIG_SHARED_LCE 3:0 /* RWIVF */
#define NV_CE_GRCE_CONFIG_SHARED_LCE_NONE 0xf /* RW--V */
#define NV_CE_GRCE_CONFIG_SHARED 30:30 /* RWIVF */
#endif

View File

@@ -0,0 +1,28 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2003-2021 NVIDIA CORPORATION & AFFILIATES
* 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.
*/
#ifndef __ga100_dev_ctrl_h__
#define __ga100_dev_ctrl_h__
#define NV_CTRL_VF_DOORBELL_VECTOR 11:0 /* -WXUF */
#define NV_CTRL_VF_DOORBELL_RUNLIST_ID 22:16 /* -WXUF */
#endif // __ga100_dev_ctrl_h__

View File

@@ -0,0 +1,124 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2003-2022 NVIDIA CORPORATION & AFFILIATES
* 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.
*/
#ifndef __ga100_dev_falcon_v4_h__
#define __ga100_dev_falcon_v4_h__
#define NV_PFALCON_FALCON_IRQSCLR 0x00000004 /* -W-4R */
#define NV_PFALCON_FALCON_IRQSCLR_HALT 4:4 /* -WXVF */
#define NV_PFALCON_FALCON_IRQSCLR_HALT_SET 0x00000001 /* -W--V */
#define NV_PFALCON_FALCON_IRQSCLR_SWGEN0 6:6 /* -WXVF */
#define NV_PFALCON_FALCON_IRQSCLR_SWGEN0_SET 0x00000001 /* -W--V */
#define NV_PFALCON_FALCON_IRQSCLR_SWGEN1 7:7 /* -WXVF */
#define NV_PFALCON_FALCON_IRQSCLR_SWGEN1_SET 0x00000001 /* -W--V */
#define NV_PFALCON_FALCON_IRQSTAT 0x00000008 /* R--4R */
#define NV_PFALCON_FALCON_IRQSTAT_HALT 4:4 /* R-IVF */
#define NV_PFALCON_FALCON_IRQSTAT_HALT_TRUE 0x00000001 /* R---V */
#define NV_PFALCON_FALCON_IRQSTAT_SWGEN0 6:6 /* R-IVF */
#define NV_PFALCON_FALCON_IRQSTAT_SWGEN0_TRUE 0x00000001 /* R---V */
#define NV_PFALCON_FALCON_IRQSTAT_SWGEN1 7:7 /* R-IVF */
#define NV_PFALCON_FALCON_IRQSTAT_SWGEN1_TRUE 0x00000001 /* R---V */
#define NV_PFALCON_FALCON_IRQMSET 0x00000010 /* -W-4R */
#define NV_PFALCON_FALCON_IRQMCLR 0x00000014 /* -W-4R */
#define NV_PFALCON_FALCON_IRQMASK 0x00000018 /* R--4R */
#define NV_PFALCON_FALCON_IRQDEST 0x0000001c /* RW-4R */
#define NV_PFALCON_FALCON_INTR_RETRIGGER(i) (0x000003e8+(i)*4) /* -W-4A */
#define NV_PFALCON_FALCON_INTR_RETRIGGER__SIZE_1 2 /* */
#define NV_PFALCON_FALCON_INTR_RETRIGGER_TRIGGER 0:0 /* -W-VF */
#define NV_PFALCON_FALCON_INTR_RETRIGGER_TRIGGER_TRUE 0x00000001 /* -W--V */
#define NV_PFALCON_FALCON_MAILBOX0 0x00000040 /* RW-4R */
#define NV_PFALCON_FALCON_MAILBOX1 0x00000044 /* RW-4R */
#define NV_PFALCON_FALCON_OS 0x00000080 /* RW-4R */
#define NV_PFALCON_FALCON_RM 0x00000084 /* RW-4R */
#define NV_PFALCON_FALCON_DEBUGINFO 0x00000094 /* RW-4R */
#define NV_PFALCON_FALCON_CPUCTL 0x00000100 /* RW-4R */
#define NV_PFALCON_FALCON_CPUCTL_STARTCPU 1:1 /* -WXVF */
#define NV_PFALCON_FALCON_CPUCTL_STARTCPU_TRUE 0x00000001 /* -W--V */
#define NV_PFALCON_FALCON_CPUCTL_STARTCPU_FALSE 0x00000000 /* -W--V */
#define NV_PFALCON_FALCON_CPUCTL_HALTED 4:4 /* R-XVF */
#define NV_PFALCON_FALCON_CPUCTL_HALTED_TRUE 0x00000001 /* R---V */
#define NV_PFALCON_FALCON_CPUCTL_ALIAS_EN 6:6 /* RWIVF */
#define NV_PFALCON_FALCON_CPUCTL_ALIAS_EN_TRUE 0x00000001 /* RW--V */
#define NV_PFALCON_FALCON_CPUCTL_ALIAS_EN_FALSE 0x00000000 /* RW--V */
#define NV_PFALCON_FALCON_CPUCTL_ALIAS 0x00000130 /* -W-4R */
#define NV_PFALCON_FALCON_CPUCTL_ALIAS_STARTCPU 1:1 /* -WXVF */
#define NV_PFALCON_FALCON_CPUCTL_ALIAS_STARTCPU_TRUE 0x00000001 /* -W--V */
#define NV_PFALCON_FALCON_CPUCTL_ALIAS_STARTCPU_FALSE 0x00000000 /* -W--V */
#define NV_PFALCON_FALCON_BOOTVEC 0x00000104 /* RW-4R */
#define NV_PFALCON_FALCON_HWCFG 0x00000108 /* R--4R */
#define NV_PFALCON_FALCON_HWCFG_IMEM_SIZE 8:0 /* R--VF */
#define NV_PFALCON_FALCON_HWCFG2 0x000000f4 /* R--4R */
#define NV_PFALCON_FALCON_HWCFG2_RISCV 10:10 /* R--VF */
#define NV_PFALCON_FALCON_HWCFG2_RISCV_ENABLE 0x00000001 /* R---V */
#define NV_PFALCON_FALCON_DMACTL 0x0000010c /* RW-4R */
#define NV_PFALCON_FALCON_DMACTL_REQUIRE_CTX 0:0 /* RWIVF */
#define NV_PFALCON_FALCON_DMACTL_REQUIRE_CTX_FALSE 0x00000000 /* RW--V */
#define NV_PFALCON_FALCON_DMACTL_DMEM_SCRUBBING 1:1 /* R--VF */
#define NV_PFALCON_FALCON_DMACTL_DMEM_SCRUBBING_DONE 0x00000000 /* R---V */
#define NV_PFALCON_FALCON_DMACTL_IMEM_SCRUBBING 2:2 /* R--VF */
#define NV_PFALCON_FALCON_DMACTL_IMEM_SCRUBBING_DONE 0x00000000 /* R---V */
#define NV_PFALCON_FALCON_DMATRFBASE 0x00000110 /* RW-4R */
#define NV_PFALCON_FALCON_DMATRFBASE_BASE 31:0 /* RWIVF */
#define NV_PFALCON_FALCON_DMATRFMOFFS 0x00000114 /* RW-4R */
#define NV_PFALCON_FALCON_DMATRFMOFFS_OFFS 23:0 /* RWIVF */
#define NV_PFALCON_FALCON_DMATRFCMD 0x00000118 /* RW-4R */
#define NV_PFALCON_FALCON_DMATRFCMD_FULL 0:0 /* R-XVF */
#define NV_PFALCON_FALCON_DMATRFCMD_FULL_TRUE 0x00000001 /* R---V */
#define NV_PFALCON_FALCON_DMATRFCMD_IDLE 1:1 /* R-XVF */
#define NV_PFALCON_FALCON_DMATRFCMD_IDLE_FALSE 0x00000000 /* R---V */
#define NV_PFALCON_FALCON_DMATRFCMD_SEC 3:2 /* RWXVF */
#define NV_PFALCON_FALCON_DMATRFCMD_IMEM 4:4 /* RWXVF */
#define NV_PFALCON_FALCON_DMATRFCMD_IMEM_TRUE 0x00000001 /* RW--V */
#define NV_PFALCON_FALCON_DMATRFCMD_IMEM_FALSE 0x00000000 /* RW--V */
#define NV_PFALCON_FALCON_DMATRFCMD_WRITE 5:5 /* RWXVF */
#define NV_PFALCON_FALCON_DMATRFCMD_WRITE_TRUE 0x00000001 /* RW--V */
#define NV_PFALCON_FALCON_DMATRFCMD_WRITE_FALSE 0x00000000 /* RW--V */
#define NV_PFALCON_FALCON_DMATRFCMD_SIZE 10:8 /* RWXVF */
#define NV_PFALCON_FALCON_DMATRFCMD_SIZE_256B 0x00000006 /* RW--V */
#define NV_PFALCON_FALCON_DMATRFCMD_CTXDMA 14:12 /* RWXVF */
#define NV_PFALCON_FALCON_DMATRFCMD_SET_DMTAG 16:16 /* RWIVF */
#define NV_PFALCON_FALCON_DMATRFCMD_SET_DMTAG_TRUE 0x00000001 /* RW--V */
#define NV_PFALCON_FALCON_DMATRFFBOFFS 0x0000011c /* RW-4R */
#define NV_PFALCON_FALCON_DMATRFFBOFFS_OFFS 31:0 /* RWIVF */
#define NV_PFALCON_FALCON_DMATRFBASE1 0x00000128 /* RW-4R */
#define NV_PFALCON_FALCON_DMATRFBASE1_BASE 8:0 /* RWIVF */
#define NV_PFALCON_FALCON_IMEMC(i) (0x00000180+(i)*16) /* RW-4A */
#define NV_PFALCON_FALCON_IMEMC_OFFS 7:2 /* RWIVF */
#define NV_PFALCON_FALCON_IMEMC_BLK 23:8 /* RWIVF */
#define NV_PFALCON_FALCON_IMEMC_AINCW 24:24 /* RWIVF */
#define NV_PFALCON_FALCON_IMEMC_AINCW_TRUE 0x00000001 /* RW--V */
#define NV_PFALCON_FALCON_IMEMC_AINCW_FALSE 0x00000000 /* RW--V */
#define NV_PFALCON_FALCON_IMEMC_SECURE 28:28 /* RWIVF */
#define NV_PFALCON_FALCON_IMEMD(i) (0x00000184+(i)*16) /* RW-4A */
#define NV_PFALCON_FALCON_IMEMD_DATA 31:0 /* RW-VF */
#define NV_PFALCON_FALCON_IMEMT(i) (0x00000188+(i)*16) /* RW-4A */
#define NV_PFALCON_FALCON_IMEMT_TAG 15:0 /* RW-VF */
#define NV_PFALCON_FALCON_DMEMC(i) (0x000001c0+(i)*8) /* RW-4A */
#define NV_PFALCON_FALCON_DMEMC_OFFS 7:2 /* RWIVF */
#define NV_PFALCON_FALCON_DMEMC_BLK 23:8 /* RWIVF */
#define NV_PFALCON_FALCON_DMEMC_AINCW 24:24 /* RWIVF */
#define NV_PFALCON_FALCON_DMEMC_AINCW_TRUE 0x00000001 /* RW--V */
#define NV_PFALCON_FALCON_DMEMC_AINCW_FALSE 0x00000000 /* RW--V */
#define NV_PFALCON_FALCON_DMEMD(i) (0x000001c4+(i)*8) /* RW-4A */
#define NV_PFALCON_FALCON_DMEMD_DATA 31:0 /* RW-VF */
#endif // __ga100_dev_falcon_v4_h__

View File

@@ -0,0 +1,47 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2003-2022 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.
*/
#ifndef __ga100_dev_fb_h__
#define __ga100_dev_fb_h__
#define NV_PFB_NISO_FLUSH_SYSMEM_ADDR 0x00100C10 /* RW-4R */
#define NV_PFB_NISO_FLUSH_SYSMEM_ADDR_SHIFT 8 /* */
#define NV_PFB_NISO_FLUSH_SYSMEM_ADDR_ADR_39_08 31:0 /* RWIVF */
#define NV_PFB_NISO_FLUSH_SYSMEM_ADDR_ADR_39_08_INIT 0x00000000 /* RWI-V */
#define NV_PFB_NISO_FLUSH_SYSMEM_ADDR_HI 0x00100C40 /* RW-4R */
#define NV_PFB_NISO_FLUSH_SYSMEM_ADDR_HI_MASK 0x7F /* */
#define NV_PFB_NISO_FLUSH_SYSMEM_ADDR_HI_ADR_63_40 23:0 /* RWIVF */
#define NV_PFB_FBHUB_POISON_INTR_VECTOR 0x00100A24 /* R--4R */
#define NV_PFB_FBHUB_POISON_INTR_VECTOR_HW 7:0 /* R-IVF */
#define NV_PFB_FBHUB_POISON_INTR_VECTOR_HW_INIT 135 /* R-I-V */
#define NV_PFB_PRI_MMU_LOCK_CFG_PRIV_LEVEL_MASK 0x001FA7C8 /* RW-4R */
#define NV_PFB_PRI_MMU_LOCK_CFG_PRIV_LEVEL_MASK_READ_PROTECTION_LEVEL0 0:0 /* */
#define NV_PFB_PRI_MMU_LOCK_CFG_PRIV_LEVEL_MASK_READ_PROTECTION_LEVEL0_ENABLE 0x00000001 /* */
#define NV_PFB_PRI_MMU_LOCK_CFG_PRIV_LEVEL_MASK_READ_PROTECTION_LEVEL0_DISABLE 0x00000000 /* */
#define NV_PFB_PRI_MMU_LOCK_ADDR_LO 0x001FA82C /* RW-4R */
#define NV_PFB_PRI_MMU_LOCK_ADDR_LO__PRIV_LEVEL_MASK 0x001FA7C8 /* */
#define NV_PFB_PRI_MMU_LOCK_ADDR_LO_VAL 31:4 /* RWEVF */
#define NV_PFB_PRI_MMU_LOCK_ADDR_LO_ALIGNMENT 0x0000000c /* */
#define NV_PFB_PRI_MMU_LOCK_ADDR_HI 0x001FA830 /* RW-4R */
#define NV_PFB_PRI_MMU_LOCK_ADDR_HI_VAL 31:4 /* RWEVF */
#define NV_PFB_PRI_MMU_LOCK_ADDR_HI_ALIGNMENT 0x0000000c /* */
#endif // __ga100_dev_fb_h__

View File

@@ -0,0 +1,37 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2003-2022 NVIDIA CORPORATION & AFFILIATES
* 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.
*/
#ifndef __ga100_dev_fbif_v4_h__
#define __ga100_dev_fbif_v4_h__
#define NV_PFALCON_FBIF_TRANSCFG(i) (0x00000000+(i)*4) /* RW-4A */
#define NV_PFALCON_FBIF_TRANSCFG__SIZE_1 8 /* */
#define NV_PFALCON_FBIF_TRANSCFG_TARGET 1:0 /* RWIVF */
#define NV_PFALCON_FBIF_TRANSCFG_TARGET_COHERENT_SYSMEM 0x00000001 /* R---V */
#define NV_PFALCON_FBIF_TRANSCFG_MEM_TYPE 2:2 /* RWIVF */
#define NV_PFALCON_FBIF_TRANSCFG_MEM_TYPE_PHYSICAL 0x00000001 /* R---V */
#define NV_PFALCON_FBIF_CTL 0x00000024 /* RW-4R */
#define NV_PFALCON_FBIF_CTL_ALLOW_PHYS_NO_CTX 7:7 /* RWIVF */
#define NV_PFALCON_FBIF_CTL_ALLOW_PHYS_NO_CTX_ALLOW 0x00000001 /* RW--V */
#endif // __ga100_dev_fbif_v4_h__

View File

@@ -0,0 +1,133 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2003-2022 NVIDIA CORPORATION & AFFILIATES
* 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.
*/
#ifndef __ga100_dev_fuse_h__
#define __ga100_dev_fuse_h__
#define NV_FUSE_OPT_SECURE_GSP_DEBUG_DIS 0x0082074C /* RW-4R */
#define NV_FUSE_OPT_SECURE_GSP_DEBUG_DIS_DATA 0:0 /* RWIVF */
#define NV_FUSE_OPT_SECURE_GSP_DEBUG_DIS_DATA_NO 0x00000000 /* RW--V */
#define NV_FUSE_OPT_SECURE_GSP_DEBUG_DIS_DATA_YES 0x00000001 /* RW--V */
#define NV_FUSE_OPT_NVDEC_DISABLE 0x00820378 /* RW-4R */
#define NV_FUSE_OPT_NVDEC_DISABLE_DATA 4:0 /* RWIVF */
#define NV_FUSE_OPT_NVDEC_DISABLE_DATA_INIT 0x00000000 /* RWI-V */
#define NV_FUSE_OPT_FPF_NVDEC_UCODE1_VERSION 0x00824100 /* RW-4R */
#define NV_FUSE_OPT_FPF_NVDEC_UCODE1_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_NVDEC_UCODE2_VERSION 0x00824104 /* RW-4R */
#define NV_FUSE_OPT_FPF_NVDEC_UCODE2_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_NVDEC_UCODE3_VERSION 0x00824108 /* RW-4R */
#define NV_FUSE_OPT_FPF_NVDEC_UCODE3_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_NVDEC_UCODE4_VERSION 0x0082410C /* RW-4R */
#define NV_FUSE_OPT_FPF_NVDEC_UCODE4_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_NVDEC_UCODE5_VERSION 0x00824110 /* RW-4R */
#define NV_FUSE_OPT_FPF_NVDEC_UCODE5_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_NVDEC_UCODE6_VERSION 0x00824114 /* RW-4R */
#define NV_FUSE_OPT_FPF_NVDEC_UCODE6_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_NVDEC_UCODE7_VERSION 0x00824118 /* RW-4R */
#define NV_FUSE_OPT_FPF_NVDEC_UCODE7_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_NVDEC_UCODE8_VERSION 0x0082411C /* RW-4R */
#define NV_FUSE_OPT_FPF_NVDEC_UCODE8_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_NVDEC_UCODE9_VERSION 0x00824120 /* RW-4R */
#define NV_FUSE_OPT_FPF_NVDEC_UCODE9_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_NVDEC_UCODE10_VERSION 0x00824124 /* RW-4R */
#define NV_FUSE_OPT_FPF_NVDEC_UCODE10_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_NVDEC_UCODE11_VERSION 0x00824128 /* RW-4R */
#define NV_FUSE_OPT_FPF_NVDEC_UCODE11_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_NVDEC_UCODE12_VERSION 0x0082412C /* RW-4R */
#define NV_FUSE_OPT_FPF_NVDEC_UCODE12_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_NVDEC_UCODE13_VERSION 0x00824130 /* RW-4R */
#define NV_FUSE_OPT_FPF_NVDEC_UCODE13_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_NVDEC_UCODE14_VERSION 0x00824134 /* RW-4R */
#define NV_FUSE_OPT_FPF_NVDEC_UCODE14_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_NVDEC_UCODE15_VERSION 0x00824138 /* RW-4R */
#define NV_FUSE_OPT_FPF_NVDEC_UCODE15_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_NVDEC_UCODE16_VERSION 0x0082413C /* RW-4R */
#define NV_FUSE_OPT_FPF_NVDEC_UCODE16_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_SEC2_UCODE1_VERSION 0x00824140 /* RW-4R */
#define NV_FUSE_OPT_FPF_SEC2_UCODE1_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_SEC2_UCODE2_VERSION 0x00824144 /* RW-4R */
#define NV_FUSE_OPT_FPF_SEC2_UCODE2_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_SEC2_UCODE3_VERSION 0x00824148 /* RW-4R */
#define NV_FUSE_OPT_FPF_SEC2_UCODE3_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_SEC2_UCODE4_VERSION 0x0082414C /* RW-4R */
#define NV_FUSE_OPT_FPF_SEC2_UCODE4_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_SEC2_UCODE5_VERSION 0x00824150 /* RW-4R */
#define NV_FUSE_OPT_FPF_SEC2_UCODE5_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_SEC2_UCODE6_VERSION 0x00824154 /* RW-4R */
#define NV_FUSE_OPT_FPF_SEC2_UCODE6_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_SEC2_UCODE7_VERSION 0x00824158 /* RW-4R */
#define NV_FUSE_OPT_FPF_SEC2_UCODE7_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_SEC2_UCODE8_VERSION 0x0082415C /* RW-4R */
#define NV_FUSE_OPT_FPF_SEC2_UCODE8_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_SEC2_UCODE9_VERSION 0x00824160 /* RW-4R */
#define NV_FUSE_OPT_FPF_SEC2_UCODE9_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_SEC2_UCODE10_VERSION 0x00824164 /* RW-4R */
#define NV_FUSE_OPT_FPF_SEC2_UCODE10_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_SEC2_UCODE11_VERSION 0x00824168 /* RW-4R */
#define NV_FUSE_OPT_FPF_SEC2_UCODE11_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_SEC2_UCODE12_VERSION 0x0082416C /* RW-4R */
#define NV_FUSE_OPT_FPF_SEC2_UCODE12_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_SEC2_UCODE13_VERSION 0x00824170 /* RW-4R */
#define NV_FUSE_OPT_FPF_SEC2_UCODE13_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_SEC2_UCODE14_VERSION 0x00824174 /* RW-4R */
#define NV_FUSE_OPT_FPF_SEC2_UCODE14_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_SEC2_UCODE15_VERSION 0x00824178 /* RW-4R */
#define NV_FUSE_OPT_FPF_SEC2_UCODE15_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_SEC2_UCODE16_VERSION 0x0082417C /* RW-4R */
#define NV_FUSE_OPT_FPF_SEC2_UCODE16_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_GSP_UCODE1_VERSION 0x008241C0 /* RW-4R */
#define NV_FUSE_OPT_FPF_GSP_UCODE1_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_GSP_UCODE2_VERSION 0x008241C4 /* RW-4R */
#define NV_FUSE_OPT_FPF_GSP_UCODE2_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_GSP_UCODE3_VERSION 0x008241C8 /* RW-4R */
#define NV_FUSE_OPT_FPF_GSP_UCODE3_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_GSP_UCODE4_VERSION 0x008241CC /* RW-4R */
#define NV_FUSE_OPT_FPF_GSP_UCODE4_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_GSP_UCODE5_VERSION 0x008241D0 /* RW-4R */
#define NV_FUSE_OPT_FPF_GSP_UCODE5_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_GSP_UCODE6_VERSION 0x008241D4 /* RW-4R */
#define NV_FUSE_OPT_FPF_GSP_UCODE6_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_GSP_UCODE7_VERSION 0x008241D8 /* RW-4R */
#define NV_FUSE_OPT_FPF_GSP_UCODE7_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_GSP_UCODE8_VERSION 0x008241DC /* RW-4R */
#define NV_FUSE_OPT_FPF_GSP_UCODE8_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_GSP_UCODE9_VERSION 0x008241E0 /* RW-4R */
#define NV_FUSE_OPT_FPF_GSP_UCODE9_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_GSP_UCODE10_VERSION 0x008241E4 /* RW-4R */
#define NV_FUSE_OPT_FPF_GSP_UCODE10_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_GSP_UCODE11_VERSION 0x008241E8 /* RW-4R */
#define NV_FUSE_OPT_FPF_GSP_UCODE11_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_GSP_UCODE12_VERSION 0x008241EC /* RW-4R */
#define NV_FUSE_OPT_FPF_GSP_UCODE12_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_GSP_UCODE13_VERSION 0x008241F0 /* RW-4R */
#define NV_FUSE_OPT_FPF_GSP_UCODE13_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_GSP_UCODE14_VERSION 0x008241F4 /* RW-4R */
#define NV_FUSE_OPT_FPF_GSP_UCODE14_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_GSP_UCODE15_VERSION 0x008241F8 /* RW-4R */
#define NV_FUSE_OPT_FPF_GSP_UCODE15_VERSION_DATA 15:0 /* RWIVF */
#define NV_FUSE_OPT_FPF_GSP_UCODE16_VERSION 0x008241FC /* RW-4R */
#define NV_FUSE_OPT_FPF_GSP_UCODE16_VERSION_DATA 15:0 /* RWIVF */
#endif // __ga100_dev_fuse_h__

View File

@@ -0,0 +1,99 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2003-2022 NVIDIA CORPORATION & AFFILIATES
* 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.
*/
#ifndef __ga100_dev_mmu_h__
#define __ga100_dev_mmu_h__
#define NV_MMU_PDE_APERTURE_BIG (0*32+1):(0*32+0) /* RWXVF */
#define NV_MMU_PDE_APERTURE_BIG_INVALID 0x00000000 /* RW--V */
#define NV_MMU_PDE_APERTURE_BIG_VIDEO_MEMORY 0x00000001 /* RW--V */
#define NV_MMU_PDE_APERTURE_BIG_SYSTEM_COHERENT_MEMORY 0x00000002 /* RW--V */
#define NV_MMU_PDE_APERTURE_BIG_SYSTEM_NON_COHERENT_MEMORY 0x00000003 /* RW--V */
#define NV_MMU_PDE_SIZE (0*32+3):(0*32+2) /* RWXVF */
#define NV_MMU_PDE_SIZE_FULL 0x00000000 /* RW--V */
#define NV_MMU_PDE_SIZE_HALF 0x00000001 /* RW--V */
#define NV_MMU_PDE_SIZE_QUARTER 0x00000002 /* RW--V */
#define NV_MMU_PDE_SIZE_EIGHTH 0x00000003 /* RW--V */
#define NV_MMU_PDE_ADDRESS_BIG_SYS (0*32+31):(0*32+4) /* RWXVF */
#define NV_MMU_PDE_ADDRESS_BIG_VID (0*32+31-3):(0*32+4) /* RWXVF */
#define NV_MMU_PDE_APERTURE_SMALL (1*32+1):(1*32+0) /* RWXVF */
#define NV_MMU_PDE_APERTURE_SMALL_INVALID 0x00000000 /* RW--V */
#define NV_MMU_PDE_APERTURE_SMALL_VIDEO_MEMORY 0x00000001 /* RW--V */
#define NV_MMU_PDE_APERTURE_SMALL_SYSTEM_COHERENT_MEMORY 0x00000002 /* RW--V */
#define NV_MMU_PDE_APERTURE_SMALL_SYSTEM_NON_COHERENT_MEMORY 0x00000003 /* RW--V */
#define NV_MMU_PDE_VOL_SMALL (1*32+2):(1*32+2) /* RWXVF */
#define NV_MMU_PDE_VOL_SMALL_TRUE 0x00000001 /* RW--V */
#define NV_MMU_PDE_VOL_SMALL_FALSE 0x00000000 /* RW--V */
#define NV_MMU_PDE_VOL_BIG (1*32+3):(1*32+3) /* RWXVF */
#define NV_MMU_PDE_VOL_BIG_TRUE 0x00000001 /* RW--V */
#define NV_MMU_PDE_VOL_BIG_FALSE 0x00000000 /* RW--V */
#define NV_MMU_PDE_ADDRESS_SMALL_SYS (1*32+31):(1*32+4) /* RWXVF */
#define NV_MMU_PDE_ADDRESS_SMALL_VID (1*32+31-3):(1*32+4) /* RWXVF */
#define NV_MMU_PDE_ADDRESS_SHIFT 0x0000000c /* */
#define NV_MMU_PDE__SIZE 8
#define NV_MMU_PTE_VALID (0*32+0):(0*32+0) /* RWXVF */
#define NV_MMU_PTE_VALID_TRUE 0x1 /* RW--V */
#define NV_MMU_PTE_VALID_FALSE 0x0 /* RW--V */
#define NV_MMU_PTE_PRIVILEGE (0*32+1):(0*32+1) /* RWXVF */
#define NV_MMU_PTE_PRIVILEGE_TRUE 0x1 /* RW--V */
#define NV_MMU_PTE_PRIVILEGE_FALSE 0x0 /* RW--V */
#define NV_MMU_PTE_READ_ONLY (0*32+2):(0*32+2) /* RWXVF */
#define NV_MMU_PTE_READ_ONLY_TRUE 0x1 /* RW--V */
#define NV_MMU_PTE_READ_ONLY_FALSE 0x0 /* RW--V */
#define NV_MMU_PTE_ENCRYPTED (0*32+3):(0*32+3) /* RWXVF */
#define NV_MMU_PTE_ENCRYPTED_TRUE 0x00000001 /* R---V */
#define NV_MMU_PTE_ENCRYPTED_FALSE 0x00000000 /* R---V */
#define NV_MMU_PTE_ADDRESS_SYS (0*32+31):(0*32+4) /* RWXVF */
#define NV_MMU_PTE_ADDRESS_VID (0*32+31-3):(0*32+4) /* RWXVF */
#define NV_MMU_PTE_ADDRESS_VID_PEER (0*32+31):(0*32+32-3) /* RWXVF */
#define NV_MMU_PTE_ADDRESS_VID_PEER_0 0x00000000 /* RW--V */
#define NV_MMU_PTE_ADDRESS_VID_PEER_1 0x00000001 /* RW--V */
#define NV_MMU_PTE_ADDRESS_VID_PEER_2 0x00000002 /* RW--V */
#define NV_MMU_PTE_ADDRESS_VID_PEER_3 0x00000003 /* RW--V */
#define NV_MMU_PTE_ADDRESS_VID_PEER_4 0x00000004 /* RW--V */
#define NV_MMU_PTE_ADDRESS_VID_PEER_5 0x00000005 /* RW--V */
#define NV_MMU_PTE_ADDRESS_VID_PEER_6 0x00000006 /* RW--V */
#define NV_MMU_PTE_ADDRESS_VID_PEER_7 0x00000007 /* RW--V */
#define NV_MMU_PTE_VOL (1*32+0):(1*32+0) /* RWXVF */
#define NV_MMU_PTE_VOL_TRUE 0x00000001 /* RW--V */
#define NV_MMU_PTE_VOL_FALSE 0x00000000 /* RW--V */
#define NV_MMU_PTE_APERTURE (1*32+2):(1*32+1) /* RWXVF */
#define NV_MMU_PTE_APERTURE_VIDEO_MEMORY 0x00000000 /* RW--V */
#define NV_MMU_PTE_APERTURE_PEER_MEMORY 0x00000001 /* RW--V */
#define NV_MMU_PTE_APERTURE_SYSTEM_COHERENT_MEMORY 0x00000002 /* RW--V */
#define NV_MMU_PTE_APERTURE_SYSTEM_NON_COHERENT_MEMORY 0x00000003 /* RW--V */
#define NV_MMU_PTE_LOCK (1*32+3):(1*32+3) /* RWXVF */
#define NV_MMU_PTE_LOCK_TRUE 0x1 /* RW--V */
#define NV_MMU_PTE_LOCK_FALSE 0x0 /* RW--V */
#define NV_MMU_PTE_COMPTAGLINE (1*32+20+11):(1*32+12) /* RWXVF */
#define NV_MMU_PTE_READ_DISABLE (1*32+30):(1*32+30) /* RWXVF */
#define NV_MMU_PTE_READ_DISABLE_TRUE 0x1 /* RW--V */
#define NV_MMU_PTE_READ_DISABLE_FALSE 0x0 /* RW--V */
#define NV_MMU_PTE_WRITE_DISABLE (1*32+31):(1*32+31) /* RWXVF */
#define NV_MMU_PTE_WRITE_DISABLE_TRUE 0x1 /* RW--V */
#define NV_MMU_PTE_WRITE_DISABLE_FALSE 0x0 /* RW--V */
#define NV_MMU_PTE_ADDRESS_SHIFT 0x0000000c /* */
#define NV_MMU_PTE__SIZE 8
#define NV_MMU_PTE_KIND (1*32+11):(1*32+4) /* RWXVF */
#define NV_MMU_PTE_KIND_GENERIC_MEMORY_COMPRESSIBLE_DISABLE_PLC 0x09 /* R---V */
#define NV_MMU_PTE_KIND_SMSKED_MESSAGE 0x0F /* R---V */
#endif // __ga100_dev_mmu_h__

View File

@@ -0,0 +1,29 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2003-2021 NVIDIA CORPORATION & AFFILIATES
* 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.
*/
#ifndef __ga100_dev_nv_xve_h__
#define __ga100_dev_nv_xve_h__
#define NV_PCFG 0x00088FFF:0x00088000 /* RW--D */
#define NV_XVE_LINK_CONTROL_STATUS 0x00000088 /* RW-4R */
#define NV_XVE_LINK_CONTROL_STATUS_LINK_SPEED 19:16 /* R--VF */
#endif

View File

@@ -0,0 +1,45 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2003-2021 NVIDIA CORPORATION & AFFILIATES
* 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.
*/
#ifndef __ga100_dev_nv_xve_addendum_h__
#define __ga100_dev_nv_xve_addendum_h__
//
// Extra config bits that can be emulated by the hypervisor for passthrough.
// This offset is unused in HW and HW returns 0x0 on read.
//
#define NV_XVE_PASSTHROUGH_EMULATED_CONFIG 0xE8
//
// On GA100, we need to be able to detect the case where the GPU is running at
// gen4, but the root port is at gen3. On baremetal, we just check the root
// port directly, but for passthrough root port is commonly completely hidden
// or fake. To handle this case we support the hypervisor explicitly
// communicating the speed to us through emulated config space. The
// ROOT_PORT_SPEED field follows the usual link speed encoding with the
// numerical value matching the gen speed, i.e. gen3 is 0x3.
// See bug 2927491 for more details.
//
#define NV_XVE_PASSTHROUGH_EMULATED_CONFIG_ROOT_PORT_SPEED 3:0
#endif

View File

@@ -0,0 +1,29 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2003-2022 NVIDIA CORPORATION & AFFILIATES
* 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.
*/
#ifndef __ga100_dev_nvdec_addendum_h__
#define __ga100_dev_nvdec_addendum_h__
#define NV_PNVDEC_FBIF_BASE(dev) (0x00848600+(dev)*16384)
#endif // __ga100_dev_nvdec_addendum_h__

View File

@@ -0,0 +1,28 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2003-2022 NVIDIA CORPORATION & AFFILIATES
* 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.
*/
#ifndef __ga100_dev_nvdec_pri_h__
#define __ga100_dev_nvdec_pri_h__
#define NV_PNVDEC(dev) 0x0084bfff+(dev)*16384:0x00848000+(dev)*16384 /* RW--D */
#endif // __ga100_dev_nvdec_pri_h__

View File

@@ -0,0 +1,39 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2003-2021 NVIDIA CORPORATION & AFFILIATES
* 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.
*/
#ifndef __ga100_dev_ram_h__
#define __ga100_dev_ram_h__
#define NV_RAMIN_ALLOC_SIZE 4096 /* */
#define NV_RAMRL_ENTRY_CHAN_USERD_PTR_LO (31+0*32):(8+0*32) /* RWXUF */
#define NV_RAMRL_ENTRY_CHAN_USERD_PTR_HI_HW (7+1*32):(0+1*32) /* RWXUF */
#define NV_RAMRL_ENTRY_BASE_SHIFT 12 /* */
#define NV_RAMUSERD_PUT (16*32+31):(16*32+0) /* RW-UF */
#define NV_RAMUSERD_GET (17*32+31):(17*32+0) /* RW-UF */
#define NV_RAMUSERD_REF (18*32+31):(18*32+0) /* RW-UF */
#define NV_RAMUSERD_PUT_HI (19*32+31):(19*32+0) /* RW-UF */
#define NV_RAMUSERD_TOP_LEVEL_GET (22*32+31):(22*32+0) /* RW-UF */
#define NV_RAMUSERD_TOP_LEVEL_GET_HI (23*32+31):(23*32+0) /* RW-UF */
#define NV_RAMUSERD_GET_HI (24*32+31):(24*32+0) /* RW-UF */
#define NV_RAMUSERD_GP_GET (34*32+31):(34*32+0) /* RW-UF */
#define NV_RAMUSERD_GP_PUT (35*32+31):(35*32+0) /* RW-UF */
#endif // __ga100_dev_ram_h__

Some files were not shown because too many files have changed in this diff Show More