mirror of
https://github.com/NVIDIA/open-gpu-kernel-modules.git
synced 2026-02-02 14:37:43 +00:00
525.47.06
This commit is contained in:
@@ -58,6 +58,9 @@ static inline NvU32 nvKmsSizeOfNotifier(enum NvKmsNIsoFormat format,
|
||||
}
|
||||
}
|
||||
|
||||
void nvKmsSetNotifier(enum NvKmsNIsoFormat format, NvBool overlay,
|
||||
NvU32 index, void *base, NvU64 timeStamp);
|
||||
|
||||
void nvKmsResetNotifier(enum NvKmsNIsoFormat format, NvBool overlay,
|
||||
NvU32 index, void *base);
|
||||
|
||||
|
||||
@@ -75,46 +75,59 @@ static void GetNotifierTimeStamp(volatile const NvU32 *notif,
|
||||
} while (1);
|
||||
}
|
||||
|
||||
static void ResetNotifierLegacy(NvBool overlay, volatile void *in)
|
||||
static void SetNotifierLegacy(NvBool overlay, volatile void *in, NvBool begun,
|
||||
NvU64 timeStamp)
|
||||
{
|
||||
volatile NvU32 *notif = in;
|
||||
|
||||
if (overlay) {
|
||||
notif[NV_DISP_NOTIFICATION_2_INFO16_3] =
|
||||
notif[NV_DISP_NOTIFICATION_2_INFO16_3] = begun ?
|
||||
DRF_DEF(_DISP, _NOTIFICATION_2__3, _STATUS, _BEGUN) :
|
||||
DRF_DEF(_DISP, _NOTIFICATION_2__3, _STATUS, _NOT_BEGUN);
|
||||
|
||||
notif[NV_DISP_NOTIFICATION_2_TIME_STAMP_0] =
|
||||
notif[NV_DISP_NOTIFICATION_2_TIME_STAMP_0] = begun ? NvU64_LO32(timeStamp) :
|
||||
NVKMS_LIB_SYNC_NOTIFIER_TIMESTAMP_LO_INVALID;
|
||||
notif[NV_DISP_NOTIFICATION_2_TIME_STAMP_1] = begun ? NvU64_HI32(timeStamp) :
|
||||
NVKMS_LIB_SYNC_NOTIFIER_TIMESTAMP_HI_INVALID;
|
||||
} else {
|
||||
notif[NV_DISP_BASE_NOTIFIER_1__0] =
|
||||
notif[NV_DISP_BASE_NOTIFIER_1__0] = begun ?
|
||||
DRF_DEF(_DISP, _BASE_NOTIFIER_1__0, _STATUS, _BEGUN) :
|
||||
DRF_DEF(_DISP, _BASE_NOTIFIER_1__0, _STATUS, _NOT_BEGUN);
|
||||
}
|
||||
}
|
||||
|
||||
static void ResetNotifierFourWord(volatile void *in)
|
||||
static void SetNotifierFourWord(volatile void *in, NvBool begun,
|
||||
NvU64 timeStamp)
|
||||
{
|
||||
volatile NvU32 *notif = in;
|
||||
|
||||
notif[NV_DISP_NOTIFICATION_2_INFO16_3] =
|
||||
notif[NV_DISP_NOTIFICATION_2_INFO16_3] = begun ?
|
||||
DRF_DEF(_DISP, _NOTIFICATION_2__3, _STATUS, _BEGUN) :
|
||||
DRF_DEF(_DISP, _NOTIFICATION_2__3, _STATUS, _NOT_BEGUN);
|
||||
|
||||
notif[NV_DISP_NOTIFICATION_2_TIME_STAMP_0] =
|
||||
notif[NV_DISP_NOTIFICATION_2_TIME_STAMP_0] = begun ? NvU64_LO32(timeStamp) :
|
||||
NVKMS_LIB_SYNC_NOTIFIER_TIMESTAMP_LO_INVALID;
|
||||
notif[NV_DISP_NOTIFICATION_2_TIME_STAMP_1] = begun ? NvU64_HI32(timeStamp) :
|
||||
NVKMS_LIB_SYNC_NOTIFIER_TIMESTAMP_HI_INVALID;
|
||||
}
|
||||
|
||||
static void ResetNotifierFourWordNVDisplay(volatile void *in)
|
||||
static void SetNotifierFourWordNVDisplay(volatile void *in, NvBool begun,
|
||||
NvU64 timeStamp)
|
||||
{
|
||||
volatile NvU32 *notif = in;
|
||||
|
||||
notif[NV_DISP_NOTIFIER__0] =
|
||||
notif[NV_DISP_NOTIFIER__0] = begun ?
|
||||
DRF_DEF(_DISP, _NOTIFIER__0, _STATUS, _BEGUN) :
|
||||
DRF_DEF(_DISP, _NOTIFIER__0, _STATUS, _NOT_BEGUN);
|
||||
|
||||
notif[NV_DISP_NOTIFIER__2] =
|
||||
notif[NV_DISP_NOTIFIER__2] = begun ? NvU64_LO32(timeStamp) :
|
||||
NVKMS_LIB_SYNC_NOTIFIER_TIMESTAMP_LO_INVALID;
|
||||
notif[NV_DISP_NOTIFIER__3] = begun ? NvU64_HI32(timeStamp) :
|
||||
NVKMS_LIB_SYNC_NOTIFIER_TIMESTAMP_HI_INVALID;
|
||||
}
|
||||
|
||||
void nvKmsResetNotifier(enum NvKmsNIsoFormat format, NvBool overlay,
|
||||
NvU32 index, void *base)
|
||||
static void SetNotifier(enum NvKmsNIsoFormat format, NvBool overlay,
|
||||
NvU32 index, void *base, NvBool begun, NvU64 timeStamp)
|
||||
{
|
||||
const NvU32 sizeInBytes = nvKmsSizeOfNotifier(format, overlay);
|
||||
void *notif =
|
||||
@@ -122,17 +135,29 @@ void nvKmsResetNotifier(enum NvKmsNIsoFormat format, NvBool overlay,
|
||||
|
||||
switch (format) {
|
||||
case NVKMS_NISO_FORMAT_LEGACY:
|
||||
ResetNotifierLegacy(overlay, notif);
|
||||
SetNotifierLegacy(overlay, notif, begun, timeStamp);
|
||||
break;
|
||||
case NVKMS_NISO_FORMAT_FOUR_WORD:
|
||||
ResetNotifierFourWord(notif);
|
||||
SetNotifierFourWord(notif, begun, timeStamp);
|
||||
break;
|
||||
case NVKMS_NISO_FORMAT_FOUR_WORD_NVDISPLAY:
|
||||
ResetNotifierFourWordNVDisplay(notif);
|
||||
SetNotifierFourWordNVDisplay(notif, begun, timeStamp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void nvKmsSetNotifier(enum NvKmsNIsoFormat format, NvBool overlay,
|
||||
NvU32 index, void *base, NvU64 timeStamp)
|
||||
{
|
||||
SetNotifier(format, overlay, index, base, NV_TRUE, timeStamp);
|
||||
}
|
||||
|
||||
void nvKmsResetNotifier(enum NvKmsNIsoFormat format, NvBool overlay,
|
||||
NvU32 index, void *base)
|
||||
{
|
||||
SetNotifier(format, overlay, index, base, NV_FALSE, 0);
|
||||
}
|
||||
|
||||
static void ParseNotifierLegacy(NvBool overlay, volatile const void *in,
|
||||
struct nvKmsParsedNotifier *out)
|
||||
{
|
||||
|
||||
@@ -325,13 +325,6 @@ static NvBool HsIoctlFlipValidateOneHwState(
|
||||
const NVFlipChannelEvoHwState *pHwState,
|
||||
const NvU32 sd)
|
||||
{
|
||||
/* HeadSurface does not support completion notifiers, yet. */
|
||||
|
||||
if ((pHwState->completionNotifier.surface.pSurfaceEvo != NULL) ||
|
||||
(pHwState->completionNotifier.awaken)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* The semaphore surface must have a CPU mapping. */
|
||||
|
||||
if (!pHwState->syncObject.usingSyncpt) {
|
||||
@@ -406,6 +399,17 @@ static NvBool HsIoctlFlipAssignHwStateOneHead(
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* HeadSurface only supports client notifiers when running in
|
||||
* swapgroup mode where each flip IOCTL will result in a real
|
||||
* flip in HW.
|
||||
*/
|
||||
if (((pFlipState->layer[layer].completionNotifier.surface.pSurfaceEvo != NULL) ||
|
||||
pFlipState->layer[layer].completionNotifier.awaken) &&
|
||||
!pHsChannel->config.neededForSwapGroup) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!HsIoctlFlipValidateOneHwState(&pFlipState->layer[layer], sd)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1960,6 +1960,53 @@ static NvBool IsPreviousFrameDone(NVHsChannelEvoPtr pHsChannel)
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* If the client provided a notifier surface with a real flip
|
||||
* request while swap groups were enabled, write to that
|
||||
* notifier with the BEGUN status and the most recent
|
||||
* headsurface notifier timestamp to emulate what the client
|
||||
* would observe if their notifier was used in hardware.
|
||||
*/
|
||||
static void HsUpdateClientNotifier(NVHsChannelEvoPtr pHsChannel)
|
||||
{
|
||||
const NVDispEvoRec *pDispEvo = pHsChannel->pDispEvo;
|
||||
const NvU32 apiHead = pHsChannel->apiHead;
|
||||
const NvU32 sd = pDispEvo->displayOwner;
|
||||
const NVHsDeviceEvoRec *pHsDevice = pDispEvo->pDevEvo->pHsDevice;
|
||||
const NVHsNotifiersRec *pHsNotifiers = &pHsDevice->notifiers;
|
||||
const NVHsNotifiersOneSdRec *pHsNotifiersOneSd = pHsNotifiers->sd[sd].ptr;
|
||||
const NvU8 nextSlot = pHsNotifiers->sd[sd].apiHead[apiHead].nextSlot;
|
||||
struct nvKmsParsedNotifier parsed = { };
|
||||
NVFlipNIsoSurfaceEvoHwState *pClientNotifier =
|
||||
&pHsChannel->flipQueue[NVKMS_MAIN_LAYER].current.completionNotifier.surface;
|
||||
|
||||
if (pClientNotifier->pSurfaceEvo == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
const NvU8 prevSlot =
|
||||
A_minus_b_with_wrap_U8(nextSlot, 1,
|
||||
NVKMS_HEAD_SURFACE_MAX_NOTIFIERS_PER_HEAD);
|
||||
|
||||
nvKmsParseNotifier(pHsNotifiers->nIsoFormat, FALSE /* overlay */,
|
||||
prevSlot, pHsNotifiersOneSd->notifier[apiHead], &parsed);
|
||||
|
||||
nvAssert(parsed.status == NVKMS_NOTIFIER_STATUS_BEGUN);
|
||||
|
||||
/*
|
||||
* XXX NVKMS HEADSURFACE TODO: Get valid timestamp through other means to
|
||||
* support this on platforms with legacy HW semaphores without valid
|
||||
* HW notifier timestamps in the main channel.
|
||||
*/
|
||||
nvAssert(parsed.timeStampValid);
|
||||
|
||||
nvKmsSetNotifier(pClientNotifier->format,
|
||||
FALSE /* overlay */,
|
||||
pClientNotifier->offsetInWords / 4,
|
||||
pClientNotifier->pSurfaceEvo->cpuAddress[sd],
|
||||
parsed.timeStamp);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Check if all flips completed for this SwapGroup. If so, release the
|
||||
* SwapGroup.
|
||||
@@ -2004,8 +2051,9 @@ static void HsCheckSwapGroupFlipDone(
|
||||
}
|
||||
|
||||
/*
|
||||
* The SwapGroup is ready: increment nextIndex for all active heads, so that
|
||||
* subsequent frames of headSurface render to the next buffer.
|
||||
* The SwapGroup is ready: update client notifiers if necessary and
|
||||
* increment nextIndex for all active heads, so that subsequent frames of
|
||||
* headSurface render to the next buffer.
|
||||
*/
|
||||
FOR_ALL_EVO_DISPLAYS(pDispEvo, dispIndex, pDevEvo) {
|
||||
NvU32 apiHead;
|
||||
@@ -2022,6 +2070,7 @@ static void HsCheckSwapGroupFlipDone(
|
||||
nvAssert(pHsChannel->config.neededForSwapGroup);
|
||||
nvAssert(IsPreviousFlipDone(pHsChannel));
|
||||
|
||||
HsUpdateClientNotifier(pHsChannel);
|
||||
HsIncrementNextIndex(pHsDevice, pHsChannel);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user