525.60.11

This commit is contained in:
Andy Ritger
2022-11-28 13:39:27 -08:00
parent 758b4ee818
commit 5f40a5aee5
113 changed files with 1408 additions and 723 deletions

View File

@@ -235,7 +235,6 @@ void nvUpdateCurrentHardwareColorSpaceAndRangeEvo(
NVEvoUpdateState *pUpdateState);
NvBool nvAssignSOREvo(NVConnectorEvoPtr pConnectorEvo, NvU32 sorExcludeMask);
void nvRestoreSORAssigmentsEvo(NVDevEvoRec *pDevEvo);
void nvSetSwapBarrierNotifyEvo(NVDispEvoPtr pDispEvo,
NvBool enable, NvBool isPre);
@@ -307,6 +306,9 @@ NvBool nvNeedsTmoLut(NVDevEvoPtr pDevEvo,
NvBool nvIsCscMatrixIdentity(const struct NvKmsCscMatrix *matrix);
void nvSuspendDevEvo(NVDevEvoRec *pDevEvo);
NvBool nvResumeDevEvo(NVDevEvoRec *pDevEvo);
#ifdef __cplusplus
};
#endif

View File

@@ -926,11 +926,6 @@ typedef struct _NVEvoDevRec {
NvU32 displayHandle;
/*!
* lastModesettingClient points to the pOpenDev of the client that
* performed the last modeset.
*/
const struct NvKmsPerOpenDev *lastModesettingClient;
/*!
* modesetOwner points to the pOpenDev of the client that called
@@ -938,6 +933,12 @@ typedef struct _NVEvoDevRec {
*/
const struct NvKmsPerOpenDev *modesetOwner;
/*!
* Indicates whether modeset ownership is changed since
* last modeset.
*/
NvBool modesetOwnerChanged;
/*!
* NVEvoDevRec::numSubDevices is the number of GPUs in the SLI
* device. This is the number of NVEvoSubDevPtrs in

View File

@@ -27,9 +27,11 @@
#include "nvtypes.h"
#include "nvkms-api.h"
#define NVKMS_KAPI_MAX_EVENT_CHANNELS 3
struct NvKmsKapiPrivAllocateChannelEventParams {
NvU32 hClient;
NvU32 hChannel;
NvU32 hChannels[NVKMS_KAPI_MAX_EVENT_CHANNELS];
};
struct NvKmsKapiPrivSurfaceParams {

View File

@@ -39,7 +39,7 @@ struct NvKmsKapiChannelEvent {
struct NvKmsKapiPrivAllocateChannelEventParams nvKmsParams;
NvHandle hCallback;
NvHandle hCallbacks[NVKMS_KAPI_MAX_EVENT_CHANNELS];
NVOS10_EVENT_KERNEL_CALLBACK_EX rmCallback;
};
@@ -50,6 +50,34 @@ static void ChannelEventHandler(void *arg1, void *arg2, NvHandle hEvent,
cb->proc(cb->data, 0);
}
void nvKmsKapiFreeChannelEvent
(
struct NvKmsKapiDevice *device,
struct NvKmsKapiChannelEvent *cb
)
{
int i;
if (device == NULL || cb == NULL) {
return;
}
for (i = 0; i < NVKMS_KAPI_MAX_EVENT_CHANNELS; ++i) {
if (!cb->hCallbacks[i]) {
continue;
}
nvRmApiFree(device->hRmClient,
device->hRmClient,
cb->hCallbacks[i]);
nvFreeUnixRmHandle(&device->handleAllocator,
cb->hCallbacks[i]);
}
nvKmsKapiFree(cb);
}
struct NvKmsKapiChannelEvent* nvKmsKapiAllocateChannelEvent
(
struct NvKmsKapiDevice *device,
@@ -59,11 +87,8 @@ struct NvKmsKapiChannelEvent* nvKmsKapiAllocateChannelEvent
NvU64 nvKmsParamsSize
)
{
int status;
NvU32 ret;
int status, i;
struct NvKmsKapiChannelEvent *cb = NULL;
NV0005_ALLOC_PARAMETERS eventParams = { };
if (device == NULL || proc == NULL) {
goto fail;
@@ -101,50 +126,45 @@ struct NvKmsKapiChannelEvent* nvKmsKapiAllocateChannelEvent
cb->rmCallback.func = ChannelEventHandler;
cb->rmCallback.arg = cb;
cb->hCallback = nvGenerateUnixRmHandle(&device->handleAllocator);
if (cb->hCallback == 0x0) {
nvKmsKapiLogDeviceDebug(device,
"Failed to allocate event callback handle");
goto fail;
}
for (i = 0; i < NVKMS_KAPI_MAX_EVENT_CHANNELS; ++i) {
NV0005_ALLOC_PARAMETERS eventParams = { };
NvU32 ret;
eventParams.hParentClient = cb->nvKmsParams.hClient;
eventParams.hClass = NV01_EVENT_KERNEL_CALLBACK_EX;
eventParams.notifyIndex = 0;
eventParams.data = NV_PTR_TO_NvP64(&cb->rmCallback);
if (!cb->nvKmsParams.hChannels[i]) {
continue;
}
ret = nvRmApiAlloc(device->hRmClient,
cb->nvKmsParams.hChannel,
cb->hCallback,
NV01_EVENT_KERNEL_CALLBACK_EX,
&eventParams);
if (ret != NVOS_STATUS_SUCCESS) {
nvKmsKapiLogDeviceDebug(device, "Failed to allocate event callback");
nvFreeUnixRmHandle(&device->handleAllocator, cb->hCallback);
goto fail;
cb->hCallbacks[i] = nvGenerateUnixRmHandle(&device->handleAllocator);
if (cb->hCallbacks[i] == 0x0) {
nvKmsKapiLogDeviceDebug(device,
"Failed to allocate event callback handle for channel 0x%x",
cb->nvKmsParams.hChannels[i]);
goto fail;
}
eventParams.hParentClient = cb->nvKmsParams.hClient;
eventParams.hClass = NV01_EVENT_KERNEL_CALLBACK_EX;
eventParams.notifyIndex = 0;
eventParams.data = NV_PTR_TO_NvP64(&cb->rmCallback);
ret = nvRmApiAlloc(device->hRmClient,
cb->nvKmsParams.hChannels[i],
cb->hCallbacks[i],
NV01_EVENT_KERNEL_CALLBACK_EX,
&eventParams);
if (ret != NVOS_STATUS_SUCCESS) {
nvKmsKapiLogDeviceDebug(device,
"Failed to allocate event callback for channel 0x%x",
cb->nvKmsParams.hChannels[i]);
nvFreeUnixRmHandle(&device->handleAllocator, cb->hCallbacks[i]);
cb->hCallbacks[i] = 0;
goto fail;
}
}
return cb;
fail:
nvKmsKapiFree(cb);
nvKmsKapiFreeChannelEvent(device, cb);
return NULL;
}
void nvKmsKapiFreeChannelEvent
(
struct NvKmsKapiDevice *device,
struct NvKmsKapiChannelEvent *cb
)
{
if (device == NULL || cb == NULL) {
return;
}
nvRmApiFree(device->hRmClient,
device->hRmClient,
cb->hCallback);
nvFreeUnixRmHandle(&device->handleAllocator, cb->hCallback);
nvKmsKapiFree(cb);
}

View File

@@ -3627,8 +3627,6 @@ NvBool nvAllocCoreChannelEvo(NVDevEvoPtr pDevEvo)
NvU32 dispIndex;
NvU32 head;
nvAssert(pDevEvo->lastModesettingClient == NULL);
/* Do nothing if the display was already allocated */
if (pDevEvo->displayHandle != 0) {
return TRUE;
@@ -3934,72 +3932,124 @@ NvBool nvAssignSOREvo(NVConnectorEvoPtr pConnectorEvo, NvU32 sorExcludeMask)
return TRUE;
}
void nvRestoreSORAssigmentsEvo(NVDevEvoRec *pDevEvo)
static void CacheSorAssignList(const NVDispEvoRec *pDispEvo,
const NVConnectorEvoRec *sorAssignList[NV0073_CTRL_CMD_DFP_ASSIGN_SOR_MAX_SORS])
{
const NVConnectorEvoRec *pConnectorEvo;
FOR_ALL_EVO_CONNECTORS(pConnectorEvo, pDispEvo) {
NvU32 i;
if (pConnectorEvo->or.type != NV0073_CTRL_SPECIFIC_OR_TYPE_SOR) {
continue;
}
FOR_EACH_INDEX_IN_MASK(32, i, pConnectorEvo->or.mask) {
/*
* RM populates same sor index into more than one connectors if
* they are are DCC partners, this checks make sure SOR
* assignment happens only for a single connector. The sor
* assignment call before modeset/dp-link-training makes sure
* assignment happens for the correct connector.
*/
if (sorAssignList[i] != NULL) {
continue;
}
sorAssignList[i] = pConnectorEvo;
} FOR_EACH_INDEX_IN_MASK_END
}
}
static void RestoreSorAssignList(NVDispEvoRec *pDispEvo,
const NVConnectorEvoRec *sorAssignList[NV0073_CTRL_CMD_DFP_ASSIGN_SOR_MAX_SORS])
{
NVDevEvoRec *pDevEvo = pDispEvo->pDevEvo;
NvU32 sorIndex;
for (sorIndex = 0;
sorIndex < NV0073_CTRL_CMD_DFP_ASSIGN_SOR_MAX_SORS; sorIndex++) {
if (sorAssignList[sorIndex] == NULL) {
continue;
}
NV0073_CTRL_DFP_ASSIGN_SOR_PARAMS params = {
.subDeviceInstance = pDispEvo->displayOwner,
.displayId = nvDpyIdToNvU32(sorAssignList[sorIndex]->displayId),
.sorExcludeMask = ~NVBIT(sorIndex),
};
NvU32 ret;
ret = nvRmApiControl(nvEvoGlobal.clientHandle,
pDevEvo->displayCommonHandle,
NV0073_CTRL_CMD_DFP_ASSIGN_SOR,
&params,
sizeof(params));
if (ret != NVOS_STATUS_SUCCESS) {
nvEvoLogDispDebug(pDispEvo,
EVO_LOG_ERROR,
"Failed to restore SOR-%u -> %s assignment.",
sorIndex, sorAssignList[sorIndex]->name);
} else {
RefreshSORAssignments(pDispEvo, &params);
}
}
}
NvBool nvResumeDevEvo(NVDevEvoRec *pDevEvo)
{
struct {
const NVConnectorEvoRec *
sorAssignList[NV0073_CTRL_CMD_DFP_ASSIGN_SOR_MAX_SORS];
} disp[NVKMS_MAX_SUBDEVICES] = { };
NVDispEvoRec *pDispEvo;
NvU32 dispIndex;
if (!NV0073_CTRL_SYSTEM_GET_CAP(pDevEvo->commonCapsBits,
if (NV0073_CTRL_SYSTEM_GET_CAP(pDevEvo->commonCapsBits,
NV0073_CTRL_SYSTEM_CAPS_CROSS_BAR_SUPPORTED)) {
return;
}
FOR_ALL_EVO_DISPLAYS(pDispEvo, dispIndex, pDevEvo) {
const NVConnectorEvoRec *
sorAssignList[NV0073_CTRL_CMD_DFP_ASSIGN_SOR_MAX_SORS] = { };
const NVConnectorEvoRec *pConnectorEvo;
NvU32 sorIndex;
FOR_ALL_EVO_CONNECTORS(pConnectorEvo, pDispEvo) {
NvU32 i;
if (pConnectorEvo->or.type != NV0073_CTRL_SPECIFIC_OR_TYPE_SOR) {
continue;
}
FOR_EACH_INDEX_IN_MASK(32, i, pConnectorEvo->or.mask) {
/*
* RM populates same sor index into more than one connectors if
* they are are DCC partners, this checks make sure SOR
* assignment happens only for a single connector. The sor
* assignment call before modeset/dp-link-training makes sure
* assignment happens for the correct connector.
*/
if (sorAssignList[i] != NULL) {
continue;
}
sorAssignList[i] = pConnectorEvo;
} FOR_EACH_INDEX_IN_MASK_END
}
for (sorIndex = 0; sorIndex < ARRAY_LEN(sorAssignList); sorIndex++) {
if (sorAssignList[sorIndex] == NULL) {
continue;
}
NV0073_CTRL_DFP_ASSIGN_SOR_PARAMS params = {
.subDeviceInstance = pDispEvo->displayOwner,
.displayId = nvDpyIdToNvU32(sorAssignList[sorIndex]->displayId),
.sorExcludeMask = ~NVBIT(sorIndex),
};
NvU32 ret;
ret = nvRmApiControl(nvEvoGlobal.clientHandle,
pDevEvo->displayCommonHandle,
NV0073_CTRL_CMD_DFP_ASSIGN_SOR,
&params,
sizeof(params));
if (ret != NVOS_STATUS_SUCCESS) {
nvEvoLogDispDebug(pDispEvo,
EVO_LOG_ERROR,
"Failed to restore SOR-%u -> %s assigment.",
sorIndex, sorAssignList[sorIndex]->name);
} else {
RefreshSORAssignments(pDispEvo, &params);
}
FOR_ALL_EVO_DISPLAYS(pDispEvo, dispIndex, pDevEvo) {
CacheSorAssignList(pDispEvo, disp[dispIndex].sorAssignList);
}
}
if (!nvAllocCoreChannelEvo(pDevEvo)) {
return FALSE;
}
/*
* During the hibernate-resume cycle vbios or GOP driver programs
* the display engine to lit up the boot display. In
* hibernate-resume path, doing NV0073_CTRL_CMD_DFP_ASSIGN_SOR
* rm-control call before the core channel allocation causes display
* channel hang because at that stage RM is not aware of the boot
* display actived by vbios and it ends up unrouting active SOR
* assignments. Therefore restore the SOR assignment only after the
* core channel allocation.
*/
if (NV0073_CTRL_SYSTEM_GET_CAP(pDevEvo->commonCapsBits,
NV0073_CTRL_SYSTEM_CAPS_CROSS_BAR_SUPPORTED)) {
/*
* Shutdown all heads before restoring the SOR assignments because in
* case of hibernate-resume the SOR, for which NVKMS is trying to
* restore the assignment, might be in use by the boot display setup
* by vbios/gop driver.
*/
nvShutDownHeads(pDevEvo, NULL /* pTestFunc, shut down all heads */);
FOR_ALL_EVO_DISPLAYS(pDispEvo, dispIndex, pDevEvo) {
RestoreSorAssignList(pDispEvo, disp[dispIndex].sorAssignList);
}
}
return TRUE;
}
void nvSuspendDevEvo(NVDevEvoRec *pDevEvo)
{
nvFreeCoreChannelEvo(pDevEvo);
}
static void ClearApiHeadState(NVDevEvoRec *pDevEvo)
@@ -4088,8 +4138,6 @@ void nvFreeCoreChannelEvo(NVDevEvoPtr pDevEvo)
nvFree(pDevEvo->gpus);
pDevEvo->gpus = NULL;
pDevEvo->lastModesettingClient = NULL;
}

View File

@@ -1078,15 +1078,12 @@ void nvHsConfigInitSwapGroup(
}
/*
*
* If (pDevEvo->modesetOwner != NULL) but
* (pDevEvo->lastModesettingClient != pDevEvo->modesetOwner) that
* means the modeset ownership is grabbed by the external client
* but it hasn't performed any modeset and the console is still
* active.
* pDevEvo->modesetOwnerChanged is TRUE, that means the modeset
* ownership is grabbed by the external client but it hasn't
* performed any modeset and the console is still active.
*/
if ((pDevEvo->modesetOwner != NULL) &&
(pDevEvo->lastModesettingClient != pDevEvo->modesetOwner)) {
if ((pDevEvo->modesetOwner != NULL) && pDevEvo->modesetOwnerChanged) {
continue;
}

View File

@@ -145,7 +145,7 @@ InheritPreviousModesetState(const NVDevEvoRec *pDevEvo,
const struct NvKmsPerOpenDev *pCurrentModesetOpenDev)
{
return (pCurrentModesetOpenDev != pDevEvo->pNvKmsOpenDev) &&
(pCurrentModesetOpenDev == pDevEvo->lastModesettingClient);
!pDevEvo->modesetOwnerChanged;
}
/*!
@@ -2824,7 +2824,7 @@ NvBool nvSetDispModeEvo(NVDevEvoPtr pDevEvo,
pDevEvo->skipConsoleRestore = FALSE;
pDevEvo->lastModesettingClient = pOpenDev;
pDevEvo->modesetOwnerChanged = FALSE;
FOR_ALL_EVO_DISPLAYS(pDispEvo, dispIndex, pDevEvo) {
NvU32 head;

View File

@@ -935,6 +935,7 @@ static NvBool GrabModesetOwnership(struct NvKmsPerOpenDev *pOpenDev)
}
pDevEvo->modesetOwner = pOpenDev;
pDevEvo->modesetOwnerChanged = TRUE;
AssignFullNvKmsFlipPermissions(pDevEvo, &pOpenDev->flipPermissions);
AssignFullNvKmsModesetPermissions(pDevEvo, &pOpenDev->modesetPermissions);
@@ -996,14 +997,6 @@ static void RevokePermissionsInternal(
}
}
static void ReallocCoreChannel(NVDevEvoRec *pDevEvo)
{
if (nvAllocCoreChannelEvo(pDevEvo)) {
nvDPSetAllowMultiStreaming(pDevEvo, TRUE /* allowMST */);
AllocSurfaceCtxDmasForAllOpens(pDevEvo);
}
}
static void RestoreConsole(NVDevEvoPtr pDevEvo)
{
// Try to issue a modeset and flip to the framebuffer console surface.
@@ -1016,7 +1009,10 @@ static void RestoreConsole(NVDevEvoPtr pDevEvo)
// Reallocate the core channel right after freeing it. This makes sure
// that it's allocated and ready right away if another NVKMS client is
// started.
ReallocCoreChannel(pDevEvo);
if (nvAllocCoreChannelEvo(pDevEvo)) {
nvDPSetAllowMultiStreaming(pDevEvo, TRUE /* allowMST */);
AllocSurfaceCtxDmasForAllOpens(pDevEvo);
}
}
}
@@ -1039,6 +1035,7 @@ static NvBool ReleaseModesetOwnership(struct NvKmsPerOpenDev *pOpenDev)
FreeSwapGroups(pOpenDev);
pDevEvo->modesetOwner = NULL;
pDevEvo->modesetOwnerChanged = TRUE;
pDevEvo->handleConsoleHotplugs = TRUE;
RestoreConsole(pDevEvo);
@@ -1489,7 +1486,6 @@ static void FreeDeviceReference(struct NvKmsPerOpen *pOpen,
ReleaseModesetOwnership(pOpenDev);
nvAssert(pOpenDev->pDevEvo->modesetOwner != pOpenDev);
nvAssert(pOpenDev->pDevEvo->lastModesettingClient != pOpenDev);
}
nvFreePerOpenDev(pOpen, pOpenDev);
@@ -5648,7 +5644,7 @@ void nvKmsSuspend(NvU32 gpuId)
FreeSurfaceCtxDmasForAllOpens(pDevEvo);
nvFreeCoreChannelEvo(pDevEvo);
nvSuspendDevEvo(pDevEvo);
}
}
@@ -5665,9 +5661,10 @@ void nvKmsResume(NvU32 gpuId)
FOR_ALL_EVO_DEVS(pDevEvo) {
nvEvoLogDevDebug(pDevEvo, EVO_LOG_INFO, "Resuming");
nvRestoreSORAssigmentsEvo(pDevEvo);
ReallocCoreChannel(pDevEvo);
if (nvResumeDevEvo(pDevEvo)) {
nvDPSetAllowMultiStreaming(pDevEvo, TRUE /* allowMST */);
AllocSurfaceCtxDmasForAllOpens(pDevEvo);
}
if (pDevEvo->modesetOwner == NULL) {
// Hardware state was lost, so we need to force a console