570.124.04

This commit is contained in:
Bernhard Stoeckner
2025-02-27 17:32:23 +01:00
parent 81fe4fb417
commit 129479b1b7
141 changed files with 102245 additions and 100070 deletions

View File

@@ -50,7 +50,8 @@ void nvEvo1SendHdmiInfoFrame(const NVDispEvoRec *pDispEvo,
const NvU32 head,
const NvEvoInfoFrameTransmitControl transmitCtrl,
const NVT_INFOFRAME_HEADER *pInfoFrameHeader,
const NvU32 infoframeSize);
const NvU32 infoframeSize,
NvBool needChecksum);
void nvEvo1DisableHdmiInfoFrame(const NVDispEvoRec *pDispEvo,
const NvU32 head,

View File

@@ -34,7 +34,8 @@ void nvEvoRegisterSurface(NVDevEvoPtr pDevEvo,
void nvEvoUnregisterSurface(NVDevEvoPtr pDevEvo,
struct NvKmsPerOpenDev *pOpenDev,
NvKmsSurfaceHandle surfaceHandle,
NvBool skipUpdate);
NvBool skipUpdate,
NvBool skipSync);
void nvEvoReleaseSurface(NVDevEvoPtr pDevEvo,
struct NvKmsPerOpenDev *pOpenDev,
NvKmsSurfaceHandle surfaceHandle);
@@ -49,6 +50,9 @@ void nvEvoDecrementSurfaceStructRefCnt(NVSurfaceEvoPtr pSurfaceEvo);
void nvEvoIncrementSurfaceRefCnts(NVSurfaceEvoPtr pSurfaceEvo);
void nvEvoDecrementSurfaceRefCnts(NVDevEvoPtr pDevEvo,
NVSurfaceEvoPtr pSurfaceEvo);
void nvEvoDecrementSurfaceRefCntsWithSync(NVDevEvoPtr pDevEvo,
NVSurfaceEvoPtr pSurfaceEvo,
NvBool skipSync);
NvBool nvEvoSurfaceRefCntsTooLarge(const NVSurfaceEvoRec *pSurfaceEvo);

View File

@@ -3194,7 +3194,8 @@ typedef const struct _nv_evo_hal {
const NvU32 head,
const NvEvoInfoFrameTransmitControl transmitCtrl,
const NVT_INFOFRAME_HEADER *pInfoFrameHeader,
const NvU32 infoFrameSize);
const NvU32 infoFrameSize,
NvBool needChecksum);
void (*DisableHdmiInfoFrame)(const NVDispEvoRec *pDispEvo,
const NvU32 head,
const NvU8 nvtInfoFrameType);

View File

@@ -2483,6 +2483,16 @@ struct NvKmsRegisterSurfaceParams {
struct NvKmsUnregisterSurfaceRequest {
NvKmsDeviceHandle deviceHandle;
NvKmsSurfaceHandle surfaceHandle;
/*
* Normally, when a surface is unregistered, nvkms will sync any
* outstanding flips to ensure the surface is no longer referenced by
* display hardware before being torn down.
*
* To improve performance with GSP firmware, when checking if this sync is
* necessary a trusted kernel-mode client who knows it is safe to do so
* may indicate to nvkms that the sync is unneeded.
*/
NvBool skipSync;
};
struct NvKmsUnregisterSurfaceReply {

View File

@@ -2339,6 +2339,13 @@ static void DestroySurface
paramsUnreg.request.deviceHandle = device->hKmsDevice;
paramsUnreg.request.surfaceHandle = surface->hKmsHandle;
/*
* Since we are unregistering this surface from KAPI we know that this is
* primarily happens from nv_drm_framebuffer_destroy and access to this
* framebuffer has been externally synchronized, we are done with it.
* Because of that we do not need to synchronize this unregister.
*/
paramsUnreg.request.skipSync = NV_TRUE;
status = nvkms_ioctl_from_kapi(device->pKmsOpen,
NVKMS_IOCTL_UNREGISTER_SURFACE,

View File

@@ -126,6 +126,7 @@
*/
typedef struct _NVDIFRStateEvoRec {
NVDevEvoPtr pDevEvo;
NvU32 copyEngineClass;
NvU32 copyEngineType;
/*
@@ -471,11 +472,6 @@ static NvBool AllocDIFRCopyEngine(NVDIFRStateEvoPtr pDifr)
return NV_FALSE;
}
// XXX Disabled DIFR on GB20x due to bug 5026524 and bug 5002540
if (ceClass == BLACKWELL_DMA_COPY_B) {
return NV_FALSE;
}
pDifr->prefetchEngine = nvGenerateUnixRmHandle(&pDevEvo->handleAllocator);
if (pDifr->prefetchEngine == 0) {
return NV_FALSE;
@@ -496,6 +492,9 @@ static NvBool AllocDIFRCopyEngine(NVDIFRStateEvoPtr pDifr)
return NV_FALSE;
}
// For Ampere vs Blackwell+ differentiation later
pDifr->copyEngineClass = ceClass;
return NV_TRUE;
}
@@ -523,6 +522,7 @@ static NvU32 PrefetchSingleSurface(NVDIFRStateEvoPtr pDifr,
const NvKmsSurfaceMemoryFormatInfo *finfo =
nvKmsGetSurfaceMemoryFormatInfo(pParams->surfFormat);
NvU32 componentSizes;
NvU32 dataTransferType;
NvU32 line_length_in;
NvU32 line_count;
NvU64 starttime;
@@ -626,10 +626,21 @@ static NvU32 PrefetchSingleSurface(NVDIFRStateEvoPtr pDifr,
nvPushSetMethodData(p, line_count);
nvAssert(pParams->surfPitchBytes * line_count == pParams->surfSizeBytes);
if (pDifr->copyEngineClass != AMPERE_DMA_COPY_B) {
nvPushMethod(p, NVA06F_SUBCHANNEL_COPY_ENGINE, NVCAB5_REQ_ATTR, 1);
nvPushSetMethodData
(p, DRF_DEF(CAB5, _REQ_ATTR, _PREFETCH_L2_CLASS, _EVICT_LAST));
dataTransferType = DRF_DEF(CAB5, _LAUNCH_DMA, _DATA_TRANSFER_TYPE, _PREFETCH);
} else
{
dataTransferType = DRF_DEF(A0B5, _LAUNCH_DMA, _DATA_TRANSFER_TYPE, _PIPELINED);
}
nvPushMethod(p, NVA06F_SUBCHANNEL_COPY_ENGINE, NVA0B5_LAUNCH_DMA, 1);
nvPushSetMethodData
(p,
DRF_DEF(A0B5, _LAUNCH_DMA, _DATA_TRANSFER_TYPE, _PIPELINED) |
dataTransferType |
DRF_DEF(A0B5, _LAUNCH_DMA, _FLUSH_ENABLE, _TRUE) |
DRF_DEF(A0B5, _LAUNCH_DMA, _SEMAPHORE_TYPE, _NONE) |
DRF_DEF(A0B5, _LAUNCH_DMA, _INTERRUPT_TYPE, _NONE) |

View File

@@ -8978,7 +8978,8 @@ NvBool nvFreeDevEvo(NVDevEvoPtr pDevEvo)
nvEvoUnregisterSurface(pDevEvo, pDevEvo->pNvKmsOpenDev,
pDevEvo->fbConsoleSurfaceHandle,
TRUE /* skipUpdate */);
TRUE /* skipUpdate */,
FALSE /* skipSync */);
pDevEvo->fbConsoleSurfaceHandle = 0;
}

View File

@@ -586,25 +586,38 @@ NvBool nvEvo1NvtToHdmiInfoFramePacketType(const NvU32 srcType, NvU8 *pDstType)
}
static NVHDMIPKT_TC EvoInfoFrameToHdmiLibTransmitCtrl(
NvEvoInfoFrameTransmitControl src)
NvEvoInfoFrameTransmitControl src,
NvBool needChecksum)
{
NVHDMIPKT_TC hdmiLibTransmitCtrl =
NVHDMIPKT_TRANSMIT_CONTROL_ENABLE_EVERY_FRAME;
switch (src) {
case NV_EVO_INFOFRAME_TRANSMIT_CONTROL_SINGLE_FRAME:
return NVHDMIPKT_TRANSMIT_CONTROL_ENABLE_SINGLE_FRAME;
hdmiLibTransmitCtrl = NVHDMIPKT_TRANSMIT_CONTROL_ENABLE_SINGLE_FRAME;
break;
case NV_EVO_INFOFRAME_TRANSMIT_CONTROL_EVERY_FRAME:
return NVHDMIPKT_TRANSMIT_CONTROL_ENABLE_EVERY_FRAME;
hdmiLibTransmitCtrl = NVHDMIPKT_TRANSMIT_CONTROL_ENABLE_EVERY_FRAME;
break;
}
return NVHDMIPKT_TRANSMIT_CONTROL_ENABLE_EVERY_FRAME;
if (!needChecksum) {
hdmiLibTransmitCtrl &=
~DRF_DEF(_HDMI_PKT, _TRANSMIT_CTRL, _CHKSUM_HW, _EN);
}
return hdmiLibTransmitCtrl;
}
void nvEvo1SendHdmiInfoFrame(const NVDispEvoRec *pDispEvo,
const NvU32 head,
const NvEvoInfoFrameTransmitControl transmitCtrl,
const NVT_INFOFRAME_HEADER *pInfoFrameHeader,
const NvU32 infoframeSize)
const NvU32 infoframeSize,
NvBool needChecksum)
{
NVHDMIPKT_TC hdmiLibTransmitCtrl =
EvoInfoFrameToHdmiLibTransmitCtrl(transmitCtrl);
EvoInfoFrameToHdmiLibTransmitCtrl(transmitCtrl, needChecksum);
const NVDispHeadStateEvoRec *pHeadState = &pDispEvo->headState[head];
NVDevEvoPtr pDevEvo = pDispEvo->pDevEvo;
NVHDMIPKT_TYPE hdmiLibType;
@@ -614,8 +627,6 @@ void nvEvo1SendHdmiInfoFrame(const NVDispEvoRec *pDispEvo,
NvU32 i;
const NvU8 *pPayload;
size_t headerSize;
NvBool needChecksum = (hdmiLibTransmitCtrl &
DRF_DEF(_HDMI_PKT, _TRANSMIT_CTRL, _CHKSUM_HW, _EN));
/*
* The 'type' the timing library is not the type that the HDMI
@@ -679,6 +690,11 @@ void nvEvo1SendHdmiInfoFrame(const NVDispEvoRec *pDispEvo,
nvkms_memcpy(&infoframe[1], &((const NvU8*) pInfoFrameHeader)[1],
headerSize - 1);
/*
* XXX Redundant since needsChecksum implies
* _HDMI_PKT_TRANSMIT_CTRL_CHKSUM_HW_EN via
* EvoInfoFrameToHdmiLibTransmitCtrl()?
*/
if (needChecksum) {
/* PB0: checksum */
checksum = 0;

View File

@@ -2504,6 +2504,7 @@ static NvBool ConstructAdvancedInfoFramePacket(
const NVT_INFOFRAME_HEADER *pInfoFrameHeader,
const NvU32 infoframeSize,
const NvBool needChecksum,
const NvBool swChecksum,
NvU8 *pPacket,
const NvU32 packetLen)
{
@@ -2535,7 +2536,7 @@ static NvBool ConstructAdvancedInfoFramePacket(
(const NVT_EXTENDED_METADATA_PACKET_INFOFRAME_HEADER *)
pInfoFrameHeader;
pPacket[1] = pExtMetadataHeader->type; /* HB1 */
pPacket[1] = pExtMetadataHeader->firstLast; /* HB1 */
pPacket[2] = pExtMetadataHeader->sequenceIndex; /* HB2 */
pPayload = (const NvU8 *)(pExtMetadataHeader + 1);
@@ -2550,16 +2551,26 @@ static NvBool ConstructAdvancedInfoFramePacket(
}
pPacket[3] = 0; /* HB3, reserved */
nvkms_memcpy(&pPacket[5], pPayload, payloadLen); /* PB1~ */
pPacket[4] = 0; /* PB0: checksum */
if (needChecksum) {
NvU8 checksum = 0;
pPacket[4] = 0; /* PB0: checksum */
for (NvU32 i = 0; i < packetLen; i++) {
checksum += pPacket[i];
/*
* XXX Redundant since we always call with swChecksum=FALSE and
* _HDMI_PKT_TRANSMIT_CTRL_CHKSUM_HW_EN
*/
if (swChecksum) {
NvU8 checksum = 0;
for (NvU32 i = 0; i < packetLen; i++) {
checksum += pPacket[i];
}
pPacket[4] = ~checksum + 1;
}
pPacket[4] = ~checksum + 1;
nvkms_memcpy(&pPacket[5], pPayload, payloadLen); /* PB1~ */
} else {
nvAssert(!swChecksum);
nvkms_memcpy(&pPacket[4], pPayload, payloadLen); /* PB0~ */
}
return TRUE;
@@ -2569,7 +2580,8 @@ static void SendHdmiInfoFrameCA(const NVDispEvoRec *pDispEvo,
const NvU32 head,
const NvEvoInfoFrameTransmitControl transmitCtrl,
const NVT_INFOFRAME_HEADER *pInfoFrameHeader,
const NvU32 infoFrameSize)
const NvU32 infoFrameSize,
NvBool needChecksum)
{
NVDevEvoPtr pDevEvo = pDispEvo->pDevEvo;
NVHDMIPKT_TYPE hdmiLibType;
@@ -2589,7 +2601,7 @@ static void SendHdmiInfoFrameCA(const NVDispEvoRec *pDispEvo,
if (!NvtToHdmiLibGenericInfoFramePktType(pInfoFrameHeader->type,
&hdmiLibType)) {
nvEvo1SendHdmiInfoFrame(pDispEvo, head, transmitCtrl, pInfoFrameHeader,
infoFrameSize);
infoFrameSize, needChecksum);
return;
}
@@ -2602,12 +2614,12 @@ static void SendHdmiInfoFrameCA(const NVDispEvoRec *pDispEvo,
break;
}
advancedInfoFrame.location = INFOFRAME_CTRL_LOC_VBLANK;
advancedInfoFrame.hwChecksum = TRUE;
advancedInfoFrame.hwChecksum = needChecksum;
if (!ConstructAdvancedInfoFramePacket(pInfoFrameHeader,
infoFrameSize,
!advancedInfoFrame.hwChecksum
/* needChecksum */,
needChecksum,
FALSE /* swChecksum */,
packet,
sizeof(packet))) {
return;

View File

@@ -421,8 +421,9 @@ static void SendVideoInfoFrame(const NVDispEvoRec *pDispEvo,
head,
NV_EVO_INFOFRAME_TRANSMIT_CONTROL_EVERY_FRAME,
(NVT_INFOFRAME_HEADER *) &VideoInfoFrame,
/* header length */ sizeof(NVT_INFOFRAME_HEADER) +
/* payload length */ VideoInfoFrame.length);
(/* header length */ sizeof(NVT_INFOFRAME_HEADER) +
/* payload length */ VideoInfoFrame.length),
TRUE /* needChecksum */);
}
/*
@@ -477,8 +478,9 @@ SendHDMI3DVendorSpecificInfoFrame(const NVDispEvoRec *pDispEvo,
head,
NV_EVO_INFOFRAME_TRANSMIT_CONTROL_EVERY_FRAME,
&vendorInfoFrame.Header,
/* header length */ sizeof(vendorInfoFrame.Header) +
/* payload length */ vendorInfoFrame.Header.length);
(/* header length */ sizeof(vendorInfoFrame.Header) +
/* payload length */ vendorInfoFrame.Header.length),
TRUE /* needChecksum */);
}
static void
@@ -541,8 +543,9 @@ SendHDRInfoFrame(const NVDispEvoRec *pDispEvo, const NvU32 head,
head,
transmitCtrl,
(NVT_INFOFRAME_HEADER *) &hdrInfoFrame.header,
/* header length */ sizeof(hdrInfoFrame.header) +
/* payload length */ hdrInfoFrame.header.length);
(/* header length */ sizeof(hdrInfoFrame.header) +
/* payload length */ hdrInfoFrame.header.length),
TRUE /* needChecksum */);
}
@@ -1745,7 +1748,8 @@ void nvHdmiSetVRR(NVDispEvoPtr pDispEvo, NvU32 head, NvBool enable)
head,
transmitCtrl,
(NVT_INFOFRAME_HEADER *) &empInfoFrame,
sizeof(empInfoFrame));
sizeof(empInfoFrame),
FALSE /* needChecksum */);
}
/*

View File

@@ -228,7 +228,8 @@ void nvHsFreeSurface(
nvEvoUnregisterSurface(pDevEvo,
pDevEvo->pNvKmsOpenDev,
pHsSurface->nvKmsHandle,
FALSE /* skipUpdate */);
FALSE /* skipUpdate */,
FALSE /* skipSync */);
}
nvFree(pHsSurface);
@@ -1078,7 +1079,8 @@ static void FreeNotifiers(NVHsDeviceEvoRec *pHsDevice)
nvEvoUnregisterSurface(pDevEvo,
pDevEvo->pNvKmsOpenDev,
pNotifiers->nvKmsHandle,
FALSE /* skipUpdate */);
FALSE /* skipUpdate */,
FALSE /* skipSync */);
pNotifiers->pSurfaceEvo = NULL;
}

View File

@@ -45,7 +45,8 @@ static void FreeLutSurfaceEvo(NVDevEvoPtr pDevEvo, NVSurfaceEvoPtr pSurfEvo)
nvEvoUnregisterSurface(pDevEvo,
pDevEvo->pNvKmsOpenDev,
pSurfEvo->owner.surfaceHandle,
TRUE /* skipUpdate */);
TRUE /* skipUpdate */,
FALSE /* skipSync */);
}
static NVSurfaceEvoPtr RegisterLutSurfaceEvo(NVDevEvoPtr pDevEvo, NvU32 memoryHandle)

View File

@@ -4765,7 +4765,8 @@ void nvRmUnmapFbConsoleMemory(NVDevEvoPtr pDevEvo)
// Free the NVKMS surface.
nvEvoUnregisterSurface(pDevEvo, pDevEvo->pNvKmsOpenDev,
pDevEvo->fbConsoleSurfaceHandle,
TRUE /* skipUpdate */);
TRUE /* skipUpdate */,
FALSE /* skipSync */);
pDevEvo->fbConsoleSurfaceHandle = 0;
}

View File

@@ -1068,7 +1068,8 @@ void nvEvoFreeClientSurfaces(NVDevEvoPtr pDevEvo,
void nvEvoUnregisterSurface(NVDevEvoPtr pDevEvo,
struct NvKmsPerOpenDev *pOpenDev,
NvKmsSurfaceHandle surfaceHandle,
NvBool skipUpdate)
NvBool skipUpdate,
NvBool skipSync)
{
NVEvoApiHandlesRec *pOpenDevSurfaceHandles =
nvGetSurfaceHandlesFromOpenDev(pOpenDev);
@@ -1102,7 +1103,7 @@ void nvEvoUnregisterSurface(NVDevEvoPtr pDevEvo,
/* Remove the handle from the calling client's namespace. */
nvEvoDestroyApiHandle(pOpenDevSurfaceHandles, surfaceHandle);
nvEvoDecrementSurfaceRefCnts(pDevEvo, pSurfaceEvo);
nvEvoDecrementSurfaceRefCntsWithSync(pDevEvo, pSurfaceEvo, skipSync);
}
void nvEvoReleaseSurface(NVDevEvoPtr pDevEvo,
@@ -1142,6 +1143,13 @@ void nvEvoIncrementSurfaceRefCnts(NVSurfaceEvoPtr pSurfaceEvo)
void nvEvoDecrementSurfaceRefCnts(NVDevEvoPtr pDevEvo,
NVSurfaceEvoPtr pSurfaceEvo)
{
nvEvoDecrementSurfaceRefCntsWithSync(pDevEvo, pSurfaceEvo, NV_FALSE);
}
void nvEvoDecrementSurfaceRefCntsWithSync(NVDevEvoPtr pDevEvo,
NVSurfaceEvoPtr pSurfaceEvo,
NvBool skipSync)
{
nvAssert(pSurfaceEvo->rmRefCnt >= 1);
pSurfaceEvo->rmRefCnt--;
@@ -1154,7 +1162,7 @@ void nvEvoDecrementSurfaceRefCnts(NVDevEvoPtr pDevEvo,
* GLS hasn't had the opportunity to release semaphores with pending
* flips. (Bug 2050970)
*/
if (pSurfaceEvo->requireDisplayHardwareAccess) {
if (!skipSync && pSurfaceEvo->requireDisplayHardwareAccess) {
nvEvoClearSurfaceUsage(pDevEvo, pSurfaceEvo);
}

View File

@@ -2720,9 +2720,16 @@ static NvBool UnregisterSurface(struct NvKmsPerOpen *pOpen,
return FALSE;
}
/* Fail the ioctl if a non-privileged client sets this */
if (pOpen->clientType != NVKMS_CLIENT_KERNEL_SPACE &&
pParams->request.skipSync) {
return FALSE;
}
nvEvoUnregisterSurface(pOpenDev->pDevEvo, pOpenDev,
pParams->request.surfaceHandle,
FALSE /* skipUpdate */);
FALSE /* skipUpdate */,
pParams->request.skipSync);
return TRUE;
}