525.47.07

This commit is contained in:
russellcnv
2023-02-03 00:13:22 -08:00
parent 65bd98c238
commit 1a970827d6
91 changed files with 1943 additions and 666 deletions

View File

@@ -31,6 +31,9 @@ extern "C" {
#endif
void nvDpyProbeMaxPixelClock(NVDpyEvoPtr pDpyEvo);
NVEvoPassiveDpDongleType nvDpyGetPassiveDpDongleType(
const NVDpyEvoRec *pDpyEvo,
NvU32 *passiveDpDongleMaxPclkKHz);
void nvDpySetValidSyncsEvo(const NVDpyEvoRec *pDpyEvo,
struct NvKmsModeValidationValidSyncs *pValidSyncs);
NVDpyEvoPtr nvAllocDpyEvo(NVDispEvoPtr pDispEvo,

View File

@@ -59,6 +59,7 @@ NvBool nvInitHdmiLibrary(NVDevEvoRec *pDevEvo);
void nvTeardownHdmiLibrary(NVDevEvoRec *pDevEvo);
NvBool nvHdmiFrlAssessLink(NVDpyEvoPtr pDpyEvo);
NvBool nvHdmiDpySupportsFrl(const NVDpyEvoRec *pDpyEvo);
NvBool nvHdmiFrlQueryConfig(const NVDpyEvoRec *pDpyEvo,
const NvModeTimings *pModeTimings,
NVHwModeTimingsEvo *pTimings,

View File

@@ -54,9 +54,6 @@ static void DpyGetDynamicDfpProperties(
NVDpyEvoPtr pDpyEvo,
const NvBool disableACPIBrightnessHotkeys);
static NVEvoPassiveDpDongleType
DpyGetPassiveDpDongleType(const NVDpyEvoRec *pDpyEvo,
NvU32 *passiveDpDongleMaxPclkKHz);
static void
CreateParsedEdidFromNVT_TIMING(NVT_TIMING *pTimings,
NvU8 bpc,
@@ -676,53 +673,37 @@ void nvDpyProbeMaxPixelClock(NVDpyEvoPtr pDpyEvo)
nvkms_memset(&pDpyEvo->hdmi.srcCaps, 0, sizeof(pDpyEvo->hdmi.srcCaps));
nvkms_memset(&pDpyEvo->hdmi.sinkCaps, 0, sizeof(pDpyEvo->hdmi.sinkCaps));
if (pDevEvo->hal->caps.supportsHDMIFRL) {
if (nvHdmiDpySupportsFrl(pDpyEvo)) {
/*
* This function is called multiple times for each pDpyEvo:
* - Once when the dpy is created
* - Once when the dpy is connected
* - Once when the dpy is disconnected
* In the first and third cases, we don't yet have an EDID so
* we don't know if the sink supports HDMI FRL. Assume it
* doesn't, since if we try to set a mode anyway there won't be
* a sink to do link training with.
* An SOR needs to be assigned temporarily to do FRL training.
*
* Since the only other SORs in use at the moment (if any) are
* those driving heads, we don't need to exclude RM from
* selecting any SOR, so an sorExcludeMask of 0 is appropriate.
*/
if (pDpyEvo->parsedEdid.valid &&
pDpyEvo->parsedEdid.info.hdmiForumInfo.max_FRL_Rate) {
if (nvAssignSOREvo(pConnectorEvo, 0) &&
nvHdmiFrlAssessLink(pDpyEvo)) {
/*
* An SOR needs to be assigned temporarily to do FRL
* training.
* Since the only other SORs in use at the moment (if any)
* are those driving heads, we don't need to exclude RM
* from selecting any SOR, so an sorExcludeMask of 0 is
* appropriate.
* Note that although we "assessed" the link above, the
* maximum pixel clock set here doesn't take that into
* account -- it's the maximum the GPU hardware is capable
* of on the most capable link, mostly for reporting
* purposes.
*
* The calculation for if a given mode can fit in the
* assessed FRL configuration is complex and depends on
* things like the amount of blanking, rather than a simple
* pclk cutoff. So, we query the hdmi library when
* validating each individual mode, when we know actual
* timings.
*/
if (nvAssignSOREvo(pConnectorEvo, 0)) {
if (nvHdmiFrlAssessLink(pDpyEvo)) {
/*
* Note that although we "assessed" the link above,
* the maximum pixel clock set here doesn't take
* that into account -- it's the maximum the GPU
* hardware is capable of on the most capable link,
* mostly for reporting purposes.
*
* The calculation for if a given mode can fit in
* the assessed FRL configuration is complex and
* depends on things like the amount of blanking,
* rather than a simple pclk cutoff. So, we query
* the hdmi library when validating each individual
* mode, when we know actual timings.
*/
pDpyEvo->maxPixelClockKHz =
/*
* This comes from the Windows display driver:
* (4 lanes * 12Gb per lane *
* FRL encoding i.e 16/18) / 1K
*/
((4 * 12 * 1000 * 1000 * 16) / 18);
}
}
/*
* This comes from the Windows display driver: (4 lanes *
* 12Gb per lane * FRL encoding i.e 16/18) / 1K
*/
pDpyEvo->maxPixelClockKHz =
((4 * 12 * 1000 * 1000 * 16) / 18);
}
}
} else {
@@ -754,8 +735,8 @@ void nvDpyProbeMaxPixelClock(NVDpyEvoPtr pDpyEvo)
* restrictive than the one described above. Check whether one of
* these dongles is in use, and override the limit accordingly.
*/
passiveDpDongleType = DpyGetPassiveDpDongleType(pDpyEvo,
&passiveDpDongleMaxPclkKHz);
passiveDpDongleType =
nvDpyGetPassiveDpDongleType(pDpyEvo, &passiveDpDongleMaxPclkKHz);
if (passiveDpDongleType != NV_EVO_PASSIVE_DP_DONGLE_UNUSED) {
pDpyEvo->maxPixelClockKHz = NV_MIN(passiveDpDongleMaxPclkKHz,
@@ -832,9 +813,9 @@ static NvBool IsConnectorTMDS(NVConnectorEvoPtr pConnectorEvo)
* Query RM for the passive Displayport dongle type; this can influence
* the maximum pixel clock allowed on that display.
*/
static NVEvoPassiveDpDongleType
DpyGetPassiveDpDongleType(const NVDpyEvoRec *pDpyEvo,
NvU32 *passiveDpDongleMaxPclkKHz)
NVEvoPassiveDpDongleType
nvDpyGetPassiveDpDongleType(const NVDpyEvoRec *pDpyEvo,
NvU32 *passiveDpDongleMaxPclkKHz)
{
NV0073_CTRL_DFP_GET_DISPLAYPORT_DONGLE_INFO_PARAMS params = { 0 };
NvU32 ret;

View File

@@ -1866,6 +1866,8 @@ NvBool nvHdmiFrlAssessLink(NVDpyEvoPtr pDpyEvo)
NVHDMIPKT_RESULT ret;
const NvU32 displayId = nvDpyIdToNvU32(pDpyEvo->pConnectorEvo->displayId);
nvAssert(nvDpyIsHdmiEvo(pDpyEvo));
/* HDMI dpys not dynamic dpy so its connector should have a dpyId. */
nvAssert(displayId != 0);
nvAssert(pDpyEvo->parsedEdid.valid);
@@ -1884,33 +1886,54 @@ NvBool nvHdmiFrlAssessLink(NVDpyEvoPtr pDpyEvo)
return pDpyEvo->hdmi.sinkCaps.linkMaxFRLRate != HDMI_FRL_DATA_RATE_NONE;
}
/* Determine if HDMI FRL is needed to drive the given timings on the given dpy. */
static NvBool TimingsNeedFRL(const NVDpyEvoRec *pDpyEvo,
const NVHwModeTimingsEvo *pTimings)
/*
* Determine if the given HDMI dpy supports FRL.
*
* Returns TRUE if the dpy supports FRL, or FALSE otherwise.
*/
NvBool nvHdmiDpySupportsFrl(const NVDpyEvoRec *pDpyEvo)
{
NvU32 passiveDpDongleMaxPclkKHz;
const NVDevEvoRec *pDevEvo = pDpyEvo->pDispEvo->pDevEvo;
/* Can't use FRL if the display hardware doesn't support it */
nvAssert(nvDpyIsHdmiEvo(pDpyEvo));
/* Can't use FRL if the display hardware doesn't support it. */
if (!pDevEvo->hal->caps.supportsHDMIFRL) {
return FALSE;
}
/* Can only use FRL for HDMI devices. */
if (!nvDpyIsHdmiEvo(pDpyEvo)) {
return FALSE;
}
/* Can only use FRL if the HDMI sink supports it. */
/* Can't use FRL if the HDMI sink doesn't support it. */
if (!pDpyEvo->parsedEdid.valid ||
!pDpyEvo->parsedEdid.info.hdmiForumInfo.max_FRL_Rate) {
return FALSE;
}
/* Can't use FRL if we are using a passive DP to HDMI dongle. */
if (nvDpyGetPassiveDpDongleType(pDpyEvo, &passiveDpDongleMaxPclkKHz) !=
NV_EVO_PASSIVE_DP_DONGLE_UNUSED) {
return FALSE;
}
return TRUE;
}
/*
* Determine if HDMI FRL is needed to drive timings with the given pixel clock
* on the given dpy.
*
* Returns TRUE if FRL is needed, or FALSE otherwise.
* */
static NvBool HdmiTimingsNeedFrl(const NVDpyEvoRec *pDpyEvo,
const NvU32 pixelClock)
{
nvAssert(nvDpyIsHdmiEvo(pDpyEvo));
/*
* For HDMI, maxSingleLinkPixelClockKHz is the maximum non-FRL rate.
* If the rate is higher than that, try to use FRL for the mode.
*/
return pTimings->pixelClock > pDpyEvo->maxSingleLinkPixelClockKHz;
return pixelClock > pDpyEvo->maxSingleLinkPixelClockKHz;
}
NvBool nvHdmiFrlQueryConfig(
@@ -1927,10 +1950,15 @@ NvBool nvHdmiFrlQueryConfig(
NVT_TIMING nvtTiming = { };
NVHDMIPKT_RESULT ret;
if (!TimingsNeedFRL(pDpyEvo, pHwTimings)) {
if (!nvDpyIsHdmiEvo(pDpyEvo) ||
!HdmiTimingsNeedFrl(pDpyEvo, pHwTimings->pixelClock)) {
return TRUE;
}
if (!nvHdmiDpySupportsFrl(pDpyEvo)) {
return FALSE;
}
/* See if we can find an NVT_TIMING for this mode from the EDID. */
pNvtTiming = nvFindEdidNVT_TIMING(pDpyEvo, pModeTimings, pValidationParams);