1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2015-2020 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3  * SPDX-License-Identifier: MIT
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23 
24 #include "nvkms-dma.h"
25 #include "nvkms-evo.h"
26 #include "nvkms-rm.h"
27 #include "nvkms-rmapi.h"
28 #include "nvkms-vrr.h"
29 #include "dp/nvdp-connector-event-sink.h"
30 #include "nvkms-hdmi.h"
31 #include "nvkms-dpy.h"
32 #include "nvkms-sync.h"
33 
34 #include <ctrl/ctrl0000/ctrl0000unix.h>
35 #include <class/cl0040.h> /* NV01_MEMORY_LOCAL_USER */
36 #include <class/cl2080.h> /* NV20_SUBDEVICE_0 */
37 #include <ctrl/ctrl2080/ctrl2080event.h> /* NV2080_CTRL_CMD_EVENT_SET_NOTIFICATION */
38 
39 #define MAX_VRR_NOTIFIER_SLOTS_PER_HEAD 4
40 #define MAX_NOTIFIER_SIZE 0x10
41 #define NOTIFIER_BYTES_PER_HEAD \
42     (MAX_VRR_NOTIFIER_SLOTS_PER_HEAD * MAX_NOTIFIER_SIZE)
43 
44 #define MAX_VRR_FLIP_DELAY_TIME_RETRY_COUNT 5
45 
46 typedef struct _vrrSurfaceNotifier
47 {
48     NvU8 notifier[NV_MAX_HEADS][NOTIFIER_BYTES_PER_HEAD];
49 } vrrSurfaceNotifier, *vrrSurfaceNotifierPtr;
50 
51 /*!
52  * This file contains routines for handling Variable Refresh Rate (VRR) display
53  * mode, also known as G-SYNC (not to be confused with the feature formerly
54  * known as G-SYNC, which is now called Quadro Sync).
55  *
56  * VRR in NVKMS is handled in several phases:
57  *
58  *  1. During modeset, if NvKmsSetModeRequest::allowVrr is true and VRR-capable
59  *     dpys are present, VRR is "enabled". This means that
60  *
61  *     a. VRR is disabled, if it was enabled before.
62  *     b. The raster timings are adjusted by extending the back porch by 2
63  *        lines. This signals to the monitor that it should enter G-SYNC mode.
64  *     c. The mode is set.
65  *     d. (EVO only) The RM VRR state machine is initialized, but left in
66  *        "suspended" mode.
67  *     e. Raster lock and frame lock are disabled.
68  *
69  *     pDevEvo->vrr.enabled indicates whether VRR was enabled successfully at
70  *     modeset time.
71  *
72  *  2. At flip time, if NvKmsFlipRequest::allowVrr is true, VRR is "activated".
73  *
74  *     a. Stall lock is enabled.
75  *     b. (NVDisplay only) The RG is switched from continuous mode to one-shot
76  *        mode.
77  *     c. (EVO only) RM's VRR state machine is enabled.
78  *     d. (EVO only) The NVKMS client is told to release a special frame ready
79  *        semaphore which tells RM to unstall the head.
80  *     e. (NVDisplay only) The window channel flip is submitted with
81  *        NVC37E_UPDATE_RELEASE_ELV_TRUE to trigger an unstall when the frame is
82  *        ready.
83  *
84  *     pDevEvo->vrr.active (not to be confused with pDevEvo->vrr.enabled,
85  *     described above) indicates whether VRR was activated successfully at flip
86  *     time.
87  *
88  *  3. Also at flip time, if NvKmsFlipRequest::allowVrr is false, VRR is
89  *     "deactivated".
90  *
91  *     a. Stall lock is disabled.
92  *     b. (NVDisplay only) the RG is switched from one-shot mode to continuous
93  *        mode.
94  *     c. (EVO only) RM's VRR state machine is suspended.
95  */
96 
97 static NvBool SetVrrActivePriv(NVDevEvoPtr pDevEvo, NvBool active);
98 static void ConfigVrrPstateSwitch(NVDispEvoPtr pDispEvo,
99                                   NvBool vrrEnabled,
100                                   NvBool vrrState,
101                                   NvBool vrrDirty,
102                                   NvU32 head);
103 
104 
105 /*!
106  * Allocate the VRR semaphore surface.
107  *
108  * Only one array of VRR semaphores is needed per "head group", which for our
109  * purposes means a pDevEvo.  This array is allocated when the device is
110  * initialized and kept around for the lifetime of the pDevEvo.
111  */
112 void nvAllocVrrEvo(NVDevEvoPtr pDevEvo)
113 {
114     NvU32 handle;
115     NvU64 size = NVKMS_VRR_SEMAPHORE_SURFACE_SIZE;
116 
117     /* On GPUs that support the HEAD_SET_DISPLAY_RATE method (nvdisplay), we
118      * don't need a VRR semaphore surface. */
119     if (pDevEvo->hal->caps.supportsDisplayRate) {
120         return;
121     }
122 
123     handle = nvGenerateUnixRmHandle(&pDevEvo->handleAllocator);
124 
125     if (nvRmAllocSysmem(pDevEvo, handle, NULL, &pDevEvo->vrr.pSemaphores,
126                         size, NVKMS_MEMORY_NISO)) {
127         pDevEvo->vrr.semaphoreHandle = handle;
128     } else {
129         nvEvoLogDev(pDevEvo, EVO_LOG_ERROR,
130                     "Failed to allocate G-SYNC semaphore memory");
131         nvFreeUnixRmHandle(&pDevEvo->handleAllocator, handle);
132     }
133 }
134 
135 void nvFreeVrrEvo(NVDevEvoPtr pDevEvo)
136 {
137     if (pDevEvo->vrr.semaphoreHandle != 0) {
138         if (pDevEvo->vrr.pSemaphores != NULL) {
139             nvRmApiUnmapMemory(nvEvoGlobal.clientHandle,
140                                pDevEvo->deviceHandle,
141                                pDevEvo->vrr.semaphoreHandle,
142                                pDevEvo->vrr.pSemaphores,
143                                0);
144             pDevEvo->vrr.pSemaphores = NULL;
145         }
146         nvRmApiFree(nvEvoGlobal.clientHandle, pDevEvo->deviceHandle,
147                     pDevEvo->vrr.semaphoreHandle);
148         nvFreeUnixRmHandle(&pDevEvo->handleAllocator,
149                            pDevEvo->vrr.semaphoreHandle);
150         pDevEvo->vrr.semaphoreHandle = 0;
151     }
152 }
153 
154 NvBool nvExportVrrSemaphoreSurface(const NVDevEvoRec *pDevEvo, int fd)
155 {
156     // Export the memory as an FD.
157     NV0000_CTRL_OS_UNIX_EXPORT_OBJECT_TO_FD_PARAMS exportParams = { };
158     const NvU32 hMemory = pDevEvo->vrr.semaphoreHandle;
159     NvU32 status;
160 
161     if (hMemory == 0) {
162         return FALSE;
163     }
164 
165     exportParams.fd = fd;
166     exportParams.object.type = NV0000_CTRL_OS_UNIX_EXPORT_OBJECT_TYPE_RM;
167     exportParams.object.data.rmObject.hDevice = pDevEvo->deviceHandle;
168     exportParams.object.data.rmObject.hObject = hMemory;
169 
170     status = nvRmApiControl(nvEvoGlobal.clientHandle,
171                            nvEvoGlobal.clientHandle,
172                            NV0000_CTRL_CMD_OS_UNIX_EXPORT_OBJECT_TO_FD,
173                            &exportParams, sizeof(exportParams));
174 
175     return status == NVOS_STATUS_SUCCESS;
176 }
177 
178 /*!
179  * Return TRUE dpy support G-SYNC.
180  */
181 static NvBool DpyIsGsync(const NVDpyEvoRec *pDpyEvo)
182 {
183     return pDpyEvo->vrr.type == NVKMS_DPY_VRR_TYPE_GSYNC;
184 }
185 
186 static NvBool IsAdaptiveSyncDpyVrrType(enum NvKmsDpyVRRType type)
187 {
188     return ((type == NVKMS_DPY_VRR_TYPE_ADAPTIVE_SYNC_DEFAULTLISTED) ||
189             (type == NVKMS_DPY_VRR_TYPE_ADAPTIVE_SYNC_NON_DEFAULTLISTED));
190 }
191 
192 
193 static NvBool AnyEnabledAdaptiveSyncDpys(const NVDevEvoRec *pDevEvo)
194 {
195     NVDispEvoPtr pDispEvo;
196     NvU32 dispIndex;
197 
198     FOR_ALL_EVO_DISPLAYS(pDispEvo, dispIndex, pDevEvo) {
199         NvU32 head;
200 
201         for (head = 0; head < pDevEvo->numHeads; head++) {
202             const NVDispHeadStateEvoRec *pHeadState =
203                 &pDispEvo->headState[head];
204 
205             if (IsAdaptiveSyncDpyVrrType(pHeadState->timings.vrr.type)) {
206                 return TRUE;
207             }
208         }
209     }
210 
211     return FALSE;
212 }
213 
214 static NvBool DpyAllowsAdaptiveSync(
215     const NVDpyEvoRec *pDpyEvo,
216     const enum NvKmsAllowAdaptiveSync allowAdaptiveSync,
217     const NvModeTimings *pTimings)
218 {
219     /*
220      * HDMI VRR and HDMI 3D both use the vendor specific infoframe in HW,
221      * so disallow HDMI VRR when attempting to set an HDMI 3D mode.
222      */
223 
224     if (pTimings->hdmi3D) {
225         return FALSE;
226     }
227 
228     return ((allowAdaptiveSync ==
229              NVKMS_ALLOW_ADAPTIVE_SYNC_DEFAULTLISTED_ONLY) &&
230             (pDpyEvo->vrr.type ==
231              NVKMS_DPY_VRR_TYPE_ADAPTIVE_SYNC_DEFAULTLISTED)) ||
232            ((allowAdaptiveSync == NVKMS_ALLOW_ADAPTIVE_SYNC_ALL) &&
233             nvDpyIsAdaptiveSync(pDpyEvo));
234 }
235 
236 NvBool nvDispSupportsVrr(const NVDispEvoRec *pDispEvo)
237 {
238     // Don't allow VRR if a framelock device is present.
239     // (In other words, don't allow G-SYNC with Quadro Sync).
240     return !pDispEvo->pFrameLockEvo;
241 }
242 
243 enum NvKmsDpyVRRType
244 nvGetAllowedDpyVrrType(const NVDpyEvoRec *pDpyEvo,
245                        const NvModeTimings *pTimings,
246                        enum NvKmsStereoMode stereoMode,
247                        const NvBool allowGsync,
248                        const enum NvKmsAllowAdaptiveSync allowAdaptiveSync)
249 {
250     /*
251      * Mark these mode timings as indicating a VRR mode, even if the timings
252      * don't need to be adjusted; this is used to distinguish between VRR and
253      * non-VRR heads elsewhere.
254      */
255 
256     if ((stereoMode == NVKMS_STEREO_DISABLED) &&
257         ((allowGsync && DpyIsGsync(pDpyEvo)) ||
258          DpyAllowsAdaptiveSync(pDpyEvo, allowAdaptiveSync, pTimings))) {
259         return pDpyEvo->vrr.type;
260     }
261 
262     return NVKMS_DPY_VRR_TYPE_NONE;
263 }
264 
265 /*! Adjust mode timings as necessary for VRR. */
266 void nvAdjustHwModeTimingsForVrrEvo(NVHwModeTimingsEvoPtr pTimings,
267                                     const enum NvKmsDpyVRRType vrrType,
268                                     const NvU32 edidTimeoutMicroseconds,
269                                     const NvU32 vrrOverrideMinRefreshRate,
270                                     const NvBool needsSwFramePacing)
271 {
272     if (vrrType == NVKMS_DPY_VRR_TYPE_NONE) {
273         return;
274     }
275 
276     /*
277      * On G-SYNC panels, the back porch extension is used to indicate to
278      * the monitor that VRR is enabled.  It is not necessary on
279      * Adaptive-Sync displays.
280      */
281     if (vrrType == NVKMS_DPY_VRR_TYPE_GSYNC) {
282         pTimings->rasterSize.y += 2;
283         pTimings->rasterBlankEnd.y += 2;
284         pTimings->rasterBlankStart.y += 2;
285     }
286 
287     // Allow overriding the EDID min refresh rate on Adaptive-Sync
288     // displays.
289     if (IsAdaptiveSyncDpyVrrType(vrrType) && vrrOverrideMinRefreshRate) {
290         NvU32 minMinRefreshRate, maxMinRefreshRate;
291         NvU32 clampedMinRefreshRate;
292 
293         nvGetDpyMinRefreshRateValidValues(pTimings,
294                                           vrrType,
295                                           edidTimeoutMicroseconds,
296                                           &minMinRefreshRate,
297                                           &maxMinRefreshRate);
298 
299         clampedMinRefreshRate =
300             NV_MAX(vrrOverrideMinRefreshRate, minMinRefreshRate);
301 
302         clampedMinRefreshRate =
303             NV_MIN(clampedMinRefreshRate, maxMinRefreshRate);
304 
305         pTimings->vrr.timeoutMicroseconds = 1000000 /
306             clampedMinRefreshRate;
307     } else {
308         pTimings->vrr.timeoutMicroseconds = edidTimeoutMicroseconds;
309     }
310     pTimings->vrr.needsSwFramePacing = needsSwFramePacing;
311     pTimings->vrr.type = vrrType;
312 }
313 
314 static void TellRMAboutVrrHead(NVDispEvoPtr pDispEvo,
315                                NVDispHeadStateEvoRec *pHeadState,
316                                NvBool vrrPossible)
317 {
318     if (pHeadState->activeRmId != 0) {
319         NV0073_CTRL_SYSTEM_VRR_DISPLAY_INFO_PARAMS params = { };
320         NvU32 ret;
321 
322         params.subDeviceInstance = pDispEvo->displayOwner;
323         params.displayId = pHeadState->activeRmId;
324         params.bAddition = vrrPossible;
325 
326         ret = nvRmApiControl(nvEvoGlobal.clientHandle,
327                              pDispEvo->pDevEvo->displayCommonHandle,
328                              NV0073_CTRL_CMD_SYSTEM_VRR_DISPLAY_INFO,
329                              &params, sizeof(params));
330         if (ret != NVOS_STATUS_SUCCESS) {
331             nvEvoLogDispDebug(pDispEvo, EVO_LOG_WARN,
332                 "NV0073_CTRL_CMD_SYSTEM_VRR_DISPLAY_INFO failed");
333         }
334     }
335 }
336 
337 static void RmDisableVrr(NVDevEvoPtr pDevEvo)
338 {
339     NVDispEvoPtr pDispEvo;
340     NvU32 head, dispIndex;
341 
342     FOR_ALL_EVO_DISPLAYS(pDispEvo, dispIndex, pDevEvo) {
343         for (head = 0; head < pDevEvo->numHeads; head++) {
344             ConfigVrrPstateSwitch(pDispEvo, FALSE /* vrrEnabled */,
345                                   FALSE /* vrrState */,
346                                   TRUE /* vrrDirty */,
347                                   head);
348         }
349     }
350     nvAssert(pDevEvo->hal->caps.supportsDisplayRate);
351 }
352 
353 NvU16 nvPrepareNextVrrNotifier(NVEvoChannelPtr pChannel, NvU32 sd, NvU32 head)
354 {
355     enum NvKmsNIsoFormat nIsoFormat = NVKMS_NISO_FORMAT_FOUR_WORD_NVDISPLAY;
356 
357     vrrSurfaceNotifierPtr pNotifiers = pChannel->notifiersDma[sd].subDeviceAddress[sd];
358 
359     const NvU32 notifierSize =
360         nvKmsSizeOfNotifier(nIsoFormat, FALSE /* overlay */);
361 
362     const NvU8 nextSlot =
363             pChannel->notifiersDma[sd].vrrNotifierHead[head].vrrNotifierNextSlot;
364 
365     const NvU8 *headBase = pNotifiers->notifier[head];
366 
367     const NvU8 offsetInBytes =
368         (headBase - ((const NvU8 *) pNotifiers)) + (notifierSize * nextSlot);
369 
370     nvAssert(notifierSize <= MAX_NOTIFIER_SIZE);
371 
372     nvKmsResetNotifier(nIsoFormat, FALSE /* overlay */,
373                        nextSlot, pNotifiers->notifier[head]);
374 
375     pChannel->notifiersDma[sd].vrrNotifierHead[head].vrrNotifierNextSlot =
376         (nextSlot + 1) % MAX_VRR_NOTIFIER_SLOTS_PER_HEAD;
377 
378     return offsetInBytes / 4;
379 }
380 
381 static void SetTimeoutPerFrame(void *dataPtr, NvU32 dataU32)
382 {
383     // Set the timeout after which the current frame will self-refresh.
384     NVDispEvoPtr pDispEvo = dataPtr;
385     NVDevEvoPtr pDevEvo = pDispEvo->pDevEvo;
386     NVEvoUpdateState updateState = { };
387     NvU32 head;
388     NvU32 inputHead = dataU32;
389     NVDispHeadStateEvoRec *pInputHeadState = &pDispEvo->headState[inputHead];
390     NvU32 displayRate = pInputHeadState->displayRate;
391     struct NvKmsVrrFramePacingInfo *pInputVrrFramePacingInfo =
392                             &(pInputHeadState->vrrFramePacingInfo);
393     const NvU32 headsMask = pInputHeadState->mergeModeVrrSecondaryHeadMask |
394         NVBIT(inputHead);
395     volatile NV0073_CTRL_RM_VRR_SHARED_DATA *pData = pInputVrrFramePacingInfo->pData;
396 
397     /*
398      * XXX[2Heads1OR] Implement per api-head frame pacing and remove this
399      * mergeMode check and NVDispEvoRec::mergeModeVrrSecondaryHeadMask.
400      */
401     if ((pInputHeadState->mergeMode == NV_EVO_MERGE_MODE_SECONDARY) ||
402             !pInputVrrFramePacingInfo->framePacingActive ||
403             (displayRate == pData->timeout)) {
404         return;
405     }
406 
407     nvPushEvoSubDevMaskDisp(pDispEvo);
408     FOR_EACH_EVO_HW_HEAD_IN_MASK(headsMask, head) {
409         pDispEvo->headState[head].displayRate = pData->timeout;
410 
411         pDevEvo->hal->SetDisplayRate(pDispEvo, head,
412                                      TRUE /* enable */,
413                                      &updateState,
414                                      pDispEvo->headState[head].displayRate / 1000);
415     }
416 
417     /*
418      * In order to change the one shot self refresh timeout mid-frame without
419      * immediately triggering a new frame, skip setting RELEASE_ELV for this
420      * update.
421      */
422     nvEvoUpdateAndKickOff(pDispEvo, FALSE, &updateState,
423                           FALSE /* releaseElv */);
424     nvPopEvoSubDevMask(pDevEvo);
425 }
426 
427 static void SetTimeoutEvent(void *arg, void *pEventDataVoid, NvU32 hEvent,
428                             NvU32 Data, NV_STATUS Status)
429 {
430     Nv2080VrrSetTimeoutNotification  *pParams = pEventDataVoid;
431 
432     (void) nvkms_alloc_timer_with_ref_ptr(
433         SetTimeoutPerFrame, /* callback */
434         arg, /* argument (this is a ref_ptr to a pDispEvo) */
435         pParams->head,   /* dataU32 */
436         0);
437 }
438 
439 static void DisableVrrSetTimeoutEvent(NVDispEvoRec *pDispEvo)
440 {
441     NVDevEvoPtr pDevEvo = pDispEvo->pDevEvo;
442     NvU32 sd = pDispEvo->displayOwner;
443     NvU32 subdeviceHandle = pDevEvo->pSubDevices[sd]->handle;
444     NV2080_CTRL_EVENT_SET_NOTIFICATION_PARAMS setEventParams = {0};
445     NvU32 ret;
446 
447     nvAssert(pDispEvo->vrrSetTimeoutEventUsageCount != 0);
448 
449     pDispEvo->vrrSetTimeoutEventUsageCount--;
450     if (pDispEvo->vrrSetTimeoutEventUsageCount != 0) {
451         return;
452     }
453 
454     nvAssert(pDispEvo->vrrSetTimeoutEventHandle != 0);
455 
456     setEventParams.event = NV2080_NOTIFIERS_VRR_SET_TIMEOUT;
457     setEventParams.action = NV2080_CTRL_EVENT_SET_NOTIFICATION_ACTION_DISABLE;
458     ret = nvRmApiControl(nvEvoGlobal.clientHandle,
459                          subdeviceHandle,
460                          NV2080_CTRL_CMD_EVENT_SET_NOTIFICATION,
461                          &setEventParams,
462                          sizeof(setEventParams));
463     if (ret != NVOS_STATUS_SUCCESS) {
464         nvEvoLogDev(pDevEvo, EVO_LOG_WARN,
465                 "NV2080_CTRL_EVENT_SET_NOTIFICATION_ACTION_DISABLE failed for vrr %d", ret);
466     }
467 
468     ret = nvRmApiFree(nvEvoGlobal.clientHandle,
469                       subdeviceHandle,
470                       pDispEvo->vrrSetTimeoutEventHandle);
471     if (ret != NVOS_STATUS_SUCCESS) {
472         nvEvoLogDev(pDevEvo, EVO_LOG_WARN,
473                     "nvRmApiFree(notify) failed for vrr %d", ret);
474     }
475 
476     nvFreeUnixRmHandle(&pDevEvo->handleAllocator,
477                        pDispEvo->vrrSetTimeoutEventHandle);
478     pDispEvo->vrrSetTimeoutEventHandle = 0;
479 }
480 
481 static NvBool EnableVrrSetTimeoutEvent(NVDispEvoRec *pDispEvo)
482 {
483     NVDevEvoPtr pDevEvo = pDispEvo->pDevEvo;
484     NvU32 sd = pDispEvo->displayOwner;
485     NvU32 subdeviceHandle = pDevEvo->pSubDevices[sd]->handle;
486     NV2080_CTRL_EVENT_SET_NOTIFICATION_PARAMS setEventParams = { };
487     NvU32 ret;
488 
489     if (pDispEvo->vrrSetTimeoutEventUsageCount != 0) {
490         nvAssert(pDispEvo->vrrSetTimeoutEventHandle != 0);
491         goto done;
492     }
493 
494     nvAssert(pDispEvo->vrrSetTimeoutEventHandle == 0);
495 
496     pDispEvo->vrrSetTimeoutEventHandle =
497         nvGenerateUnixRmHandle(&pDevEvo->handleAllocator);
498 
499     if (!nvRmRegisterCallback(pDevEvo,
500                               &pDispEvo->vrrSetTimeoutCallback,
501                               pDispEvo->ref_ptr,
502                               subdeviceHandle,
503                               pDispEvo->vrrSetTimeoutEventHandle,
504                               SetTimeoutEvent,
505                               NV2080_NOTIFIERS_VRR_SET_TIMEOUT)) {
506         nvFreeUnixRmHandle(&pDevEvo->handleAllocator,
507                            pDispEvo->vrrSetTimeoutEventHandle);
508         nvEvoLogDev(pDevEvo, EVO_LOG_ERROR,
509                     "nvRmRegisterCallback failed for vrr");
510         return FALSE;
511     }
512 
513     // Enable VRR notifications from this subdevice.
514     setEventParams.event = NV2080_NOTIFIERS_VRR_SET_TIMEOUT;
515     setEventParams.action = NV2080_CTRL_EVENT_SET_NOTIFICATION_ACTION_REPEAT;
516     ret = nvRmApiControl(nvEvoGlobal.clientHandle,
517                               subdeviceHandle,
518                               NV2080_CTRL_CMD_EVENT_SET_NOTIFICATION,
519                               &setEventParams,
520                               sizeof(setEventParams));
521     if (ret != NVOS_STATUS_SUCCESS) {
522         nvEvoLogDev(pDevEvo, EVO_LOG_ERROR,
523                     "NV2080_CTRL_EVENT_SET_NOTIFICATION_ACTION_REPEAT failed for vrr 0x%x", ret);
524         nvRmApiFree(nvEvoGlobal.clientHandle,
525                     subdeviceHandle, pDispEvo->vrrSetTimeoutEventHandle);
526         nvFreeUnixRmHandle(&pDevEvo->handleAllocator,
527                            pDispEvo->vrrSetTimeoutEventHandle);
528         pDispEvo->vrrSetTimeoutEventHandle = 0;
529         return FALSE;
530     }
531 
532 done:
533     pDispEvo->vrrSetTimeoutEventUsageCount++;
534     return TRUE;
535 }
536 
537 static NvBool VrrRgLineActiveSessionOpen(NVDispEvoPtr pDispEvo,
538                                         struct NvKmsVrrFramePacingInfo *pVrrFramePacingInfo)
539 {
540     NvU32 ret = 0;
541     NVDevEvoPtr pDevEvo = pDispEvo->pDevEvo;
542     NvU32 sd = pDispEvo->displayOwner;
543     NvU32 subdeviceHandle = pDevEvo->pSubDevices[sd]->handle;
544     NV_MEMORY_ALLOCATION_PARAMS memAllocParams = { };
545     NvHandle memoryHandle;
546     void *address = NULL;
547 
548     if (!EnableVrrSetTimeoutEvent(pDispEvo)) {
549         return FALSE;
550     }
551 
552     /* allocate memory from vidmem */
553     memoryHandle = nvGenerateUnixRmHandle(&pDevEvo->handleAllocator);
554     memAllocParams.owner = NVKMS_RM_HEAP_ID;
555     memAllocParams.type = NVOS32_TYPE_DMA;
556     memAllocParams.size = sizeof(NV0073_CTRL_RM_VRR_SHARED_DATA);
557     memAllocParams.attr = DRF_DEF(OS32, _ATTR, _PAGE_SIZE, _4KB) |
558                           DRF_DEF(OS32, _ATTR, _PHYSICALITY, _CONTIGUOUS) |
559                           DRF_DEF(OS32, _ATTR, _COHERENCY, _UNCACHED) |
560                           DRF_DEF(OS32, _ATTR, _LOCATION, _VIDMEM);
561 
562     memAllocParams.flags |= (NVOS32_ALLOC_FLAGS_ALLOCATE_KERNEL_PRIVILEGED |
563                             NVOS32_ALLOC_FLAGS_PERSISTENT_VIDMEM);
564 
565     ret = nvRmApiAlloc(nvEvoGlobal.clientHandle,
566                        pDevEvo->deviceHandle,
567                        memoryHandle,
568                        NV01_MEMORY_LOCAL_USER,
569                        &memAllocParams);
570 
571     if (ret != NVOS_STATUS_SUCCESS) {
572         nvEvoLogDev(pDevEvo, EVO_LOG_ERROR, "nvRmApiAlloc(memory) failed for vrr 0x%x", ret);
573         goto free_memory_handle;
574     }
575 
576     ret = nvRmApiMapMemory(nvEvoGlobal.clientHandle,
577                            subdeviceHandle,
578                            memoryHandle,
579                            0,
580                            sizeof(NV0073_CTRL_RM_VRR_SHARED_DATA),
581                            &address,
582                            0);
583     if ((ret != NVOS_STATUS_SUCCESS) || (address == NULL)) {
584         nvEvoLogDev(pDevEvo, EVO_LOG_ERROR, " nvRmApiMapMemory failed for vrr 0x%x addr: %p",
585                 ret, address);
586         nvRmApiFree(nvEvoGlobal.clientHandle,
587               subdeviceHandle, memoryHandle);
588         goto free_memory_handle;
589     }
590 
591     pVrrFramePacingInfo->pData = (NV0073_CTRL_RM_VRR_SHARED_DATA *)address;
592     pVrrFramePacingInfo->memoryHandle = memoryHandle;
593 
594     return TRUE;
595 
596 free_memory_handle:
597     nvFreeUnixRmHandle(&pDevEvo->handleAllocator, memoryHandle);
598     DisableVrrSetTimeoutEvent(pDispEvo);
599     return FALSE;
600 }
601 
602 static void VrrRgLineActiveSessionClose(NVDispEvoPtr pDispEvo,
603                                         struct NvKmsVrrFramePacingInfo *pVrrFramePacingInfo)
604 {
605     NVDevEvoPtr pDevEvo = pDispEvo->pDevEvo;
606     NvU32 sd = pDispEvo->displayOwner;
607     NvU32 subdeviceHandle = pDevEvo->pSubDevices[sd]->handle;
608     NvU32 ret = 0;
609 
610     // clean up allocated memory
611     ret = nvRmApiUnmapMemory(nvEvoGlobal.clientHandle,
612                             subdeviceHandle,
613                             pVrrFramePacingInfo->memoryHandle,
614                             (void *)pVrrFramePacingInfo->pData,
615                             0);
616     if (ret != NVOS_STATUS_SUCCESS) {
617         nvEvoLogDev(pDevEvo, EVO_LOG_WARN, "nvRmApiUnmapMemory failed for vrr %d", ret);
618     }
619 
620     ret = nvRmApiFree(nvEvoGlobal.clientHandle,
621                         subdeviceHandle,
622                         pVrrFramePacingInfo->memoryHandle);
623     if (ret != NVOS_STATUS_SUCCESS) {
624         nvEvoLogDev(pDevEvo, EVO_LOG_WARN, "nvRmApiFree(memory) failed for vrr %d", ret);
625     }
626 
627     nvFreeUnixRmHandle(&pDevEvo->handleAllocator, pVrrFramePacingInfo->memoryHandle);
628 
629     DisableVrrSetTimeoutEvent(pDispEvo);
630 }
631 
632 /*!
633  * Enable or disable SW Frame Pacing for one head.
634  *
635  * This will reset the NVDispHeadStateEvoRec::NvKmsVrrFramePacingInfo state used
636  * to track Frame pacing per head and call RM to set an interrupt to be called
637  * at every first RG scanline of every frame (whether initiated by a flip or
638  * a self-refresh).
639  */
640 static NvBool SetSwFramePacing(NVDispEvoPtr pDispEvo, NvU32 head, NvBool enable)
641 {
642     NVDevEvoPtr pDevEvo = pDispEvo->pDevEvo;
643     NVDispHeadStateEvoRec *pHeadState = &pDispEvo->headState[head];
644     struct NvKmsVrrFramePacingInfo *pVrrFramePacingInfo =
645         &pHeadState->vrrFramePacingInfo;
646     const NVHwModeTimingsEvo *pTimings = &pHeadState->timings;
647     const NvU32 timeout = pTimings->vrr.timeoutMicroseconds;
648     struct NV0073_CTRL_CMD_SYSTEM_VRR_SET_RGLINE_ACTIVE_PARAMS params = { };
649     NvU32 maxFrameTime = 0;
650     NvU32 minFrameTime = 0;
651 
652     if (pVrrFramePacingInfo->framePacingActive == enable) {
653         return TRUE;
654     }
655 
656     if (enable) {
657         maxFrameTime = timeout * 1000;
658         minFrameTime = 1000 *
659             axb_div_c(pTimings->rasterSize.y * 1000,
660                       pTimings->rasterSize.x,
661                       pTimings->pixelClock);
662 
663         /*
664          * SW Frame pacing won't work with infinite self-refresh adaptive sync
665          * or direct drive panels (none of which currently exist) or when
666          * driving a mode below the panel's minimum refresh rate.
667          */
668         if ((maxFrameTime == 0) ||
669             (minFrameTime == 0) ||
670             (minFrameTime >= maxFrameTime)) {
671             nvEvoLogDev(pDevEvo, EVO_LOG_ERROR,
672                         "Failed to set variable refresh rate with invalid "
673                         "minimum frame time (%u ns) or maximum frame time "
674                         "(%u ns)", minFrameTime, maxFrameTime);
675             return FALSE;
676         }
677 
678         if (!VrrRgLineActiveSessionOpen(pDispEvo, pVrrFramePacingInfo)) {
679             nvEvoLogDev(pDevEvo, EVO_LOG_ERROR,
680                         "Failed to setup Rgline active session for vrr");
681             return FALSE;
682         }
683     }
684 
685     params.head = head;
686     params.height = 1;
687     params.bEnable = enable;
688     params.subDeviceInstance = pDispEvo->displayOwner;
689     params.maxFrameTime = maxFrameTime;
690     params.minFrameTime = minFrameTime;
691     params.hMemory = pVrrFramePacingInfo->memoryHandle;
692     if (nvRmApiControl(nvEvoGlobal.clientHandle,
693                    pDispEvo->pDevEvo->displayCommonHandle,
694                    NV0073_CTRL_CMD_SYSTEM_VRR_SET_RGLINE_ACTIVE,
695                    &params, sizeof(params))
696         != NVOS_STATUS_SUCCESS) {
697         nvAssert(!"NV0073_CTRL_CMD_SYSTEM_VRR_SET_RGLINE_ACTIVE failed");
698         VrrRgLineActiveSessionClose(pDispEvo, pVrrFramePacingInfo);
699         return FALSE;
700     }
701 
702     if (!enable) {
703         VrrRgLineActiveSessionClose(pDispEvo, pVrrFramePacingInfo);
704 
705         // Reset the state used to track SW Frame pacing.
706         nvkms_memset(pVrrFramePacingInfo, 0, sizeof(*pVrrFramePacingInfo));
707     }
708 
709     pVrrFramePacingInfo->framePacingActive = enable;
710     return TRUE;
711 }
712 
713 void nvDisableVrr(NVDevEvoPtr pDevEvo)
714 {
715     NVDispEvoPtr pDispEvo;
716     NvU32 head, dispIndex;
717 
718     FOR_ALL_EVO_DISPLAYS(pDispEvo, dispIndex, pDevEvo) {
719         for (head = 0; head < pDevEvo->numHeads; head++) {
720             NVDispHeadStateEvoRec *pHeadState = &pDispEvo->headState[head];
721 
722             TellRMAboutVrrHead(pDispEvo, pHeadState, FALSE);
723 
724             SetSwFramePacing(pDispEvo, head, FALSE);
725         }
726     }
727 
728     if (!pDevEvo->vrr.enabled) {
729         return;
730     }
731 
732     SetVrrActivePriv(pDevEvo, FALSE);
733     RmDisableVrr(pDevEvo);
734 
735     FOR_ALL_EVO_DISPLAYS(pDispEvo, dispIndex, pDevEvo) {
736         for (head = 0; head < pDevEvo->numHeads; head++) {
737             NVDispHeadStateEvoRec *pHeadState = &pDispEvo->headState[head];
738 
739             if ((pHeadState->pConnectorEvo != NULL) &&
740                     IsAdaptiveSyncDpyVrrType(pHeadState->timings.vrr.type)) {
741                 if (nvConnectorUsesDPLib(pHeadState->pConnectorEvo)) {
742                     nvDPLibSetAdaptiveSync(pDispEvo, head, FALSE);
743                 } else {
744                     nvHdmiSetVRR(pDispEvo, head, FALSE);
745                 }
746             }
747         }
748     }
749 
750     pDevEvo->vrr.enabled = FALSE;
751     nvAssert(!pDevEvo->vrr.active);
752 }
753 
754 static NvBool AnyEnabledGsyncDpys(const NVDevEvoRec *pDevEvo)
755 {
756     NVDispEvoPtr pDispEvo;
757     NvU32 dispIndex;
758 
759     FOR_ALL_EVO_DISPLAYS(pDispEvo, dispIndex, pDevEvo) {
760         NvU32 head;
761 
762         for (head = 0; head < pDevEvo->numHeads; head++) {
763             const NVDispHeadStateEvoRec *pHeadState = &pDispEvo->headState[head];
764 
765             if (pHeadState->timings.vrr.type == NVKMS_DPY_VRR_TYPE_GSYNC) {
766                 return TRUE;
767             }
768         }
769     }
770 
771     return FALSE;
772 }
773 
774 static NvBool RmEnableVrr(NVDevEvoPtr pDevEvo)
775 {
776     NVDispEvoPtr pDispEvo;
777     NvU32 dispIndex, head;
778 
779     FOR_ALL_EVO_DISPLAYS(pDispEvo, dispIndex, pDevEvo) {
780         for (head = 0; head < pDevEvo->numHeads; head++) {
781             ConfigVrrPstateSwitch(pDispEvo, TRUE /* vrrEnabled */,
782                                   FALSE /* vrrState */,
783                                   TRUE/* vrrDirty */,
784                                   head);
785         }
786     }
787     nvAssert(pDevEvo->hal->caps.supportsDisplayRate);
788     return TRUE;
789 
790     return FALSE;
791 }
792 
793 void nvGetDpyMinRefreshRateValidValues(
794     const NVHwModeTimingsEvo *pTimings,
795     const enum NvKmsDpyVRRType vrrType,
796     const NvU32 edidTimeoutMicroseconds,
797     NvU32 *minMinRefreshRate,
798     NvU32 *maxMinRefreshRate)
799 {
800     NvU32 edidMinRefreshRate;
801 
802     if (IsAdaptiveSyncDpyVrrType(vrrType)) {
803         /*
804          * Adaptive-Sync monitors must always define a nonzero minimum refresh
805          * rate in the EDID, and a modeset may override this within a range
806          * of NVKMS_VRR_MIN_REFRESH_RATE_MAX_VARIANCE, as long as the minimum
807          * is not below 1hz and the maximum does not exceed the current
808          * refresh rate.
809          */
810         NvU32 minTimeoutMicroseconds =
811             axb_div_c(pTimings->rasterSize.y * 1000,
812                       pTimings->rasterSize.x, pTimings->pixelClock);
813         NvU32 maxRefreshRate = 1000000 / minTimeoutMicroseconds;
814 
815         nvAssert(edidTimeoutMicroseconds != 0);
816 
817         edidMinRefreshRate =
818             1000000 / edidTimeoutMicroseconds;
819 
820         if (edidMinRefreshRate <= NVKMS_VRR_MIN_REFRESH_RATE_MAX_VARIANCE) {
821             *minMinRefreshRate = 1;
822         } else {
823             *minMinRefreshRate = edidMinRefreshRate -
824                 NVKMS_VRR_MIN_REFRESH_RATE_MAX_VARIANCE;
825         }
826 
827         *maxMinRefreshRate = NV_MIN(maxRefreshRate,
828             edidMinRefreshRate + NVKMS_VRR_MIN_REFRESH_RATE_MAX_VARIANCE);
829     } else {
830         /*
831          * Non-Adaptive-Sync panels may not override the EDID-provided minimum
832          * refresh rate, which will be 1hz for most G-SYNC panels or 0hz for
833          * true self-refresh panels.
834          */
835         edidMinRefreshRate = edidTimeoutMicroseconds ?
836             1000000 / edidTimeoutMicroseconds : 0;
837         *minMinRefreshRate = *maxMinRefreshRate = edidMinRefreshRate;
838     }
839 }
840 
841 /*!
842  * Modify the VRR state to enable (but not activate) VRR at modeset time.
843  *
844  * This prepares VRR displays for VRR (through a DP MSA override for
845  * Adaptive-Sync and a backporch extension for G-SYNC) and sets up the RM
846  * VRR state machine (for pre-nvdisplay) but does not actually start VRR
847  * flipping until nvSetVrrActive() is called at flip time.
848  *
849  * \param[in]  pDevEvo            The device that is enabling VRR.
850  */
851 void nvEnableVrr(NVDevEvoPtr pDevEvo)
852 {
853     NVDispEvoPtr pDispEvo;
854     NvU32 head, dispIndex;
855 
856     nvAssert(!pDevEvo->vrr.enabled);
857 
858     FOR_ALL_EVO_DISPLAYS(pDispEvo, dispIndex, pDevEvo) {
859         for (head = 0; head < pDevEvo->numHeads; head++) {
860             NVDispHeadStateEvoRec *pHeadState = &pDispEvo->headState[head];
861 
862             if ((pHeadState->pConnectorEvo != NULL) &&
863                     IsAdaptiveSyncDpyVrrType(pHeadState->timings.vrr.type)) {
864                 if (nvConnectorUsesDPLib(pHeadState->pConnectorEvo)) {
865                     nvDPLibSetAdaptiveSync(pDispEvo, head, TRUE);
866                 } else {
867                     nvHdmiSetVRR(pDispEvo, head, TRUE);
868                 }
869             }
870         }
871     }
872 
873     FOR_ALL_EVO_DISPLAYS(pDispEvo, dispIndex, pDevEvo) {
874         for (head = 0; head < pDevEvo->numHeads; head++) {
875             NVDispHeadStateEvoRec *pHeadState = &pDispEvo->headState[head];
876 
877             // To allow VRR-based mclk switching, RM needs to know which heads
878             // are driving VRR displays capable of extending vblank.  This
879             // includes all G-SYNC displays (regardless of whether the modeset
880             // indicates that G-SYNC is allowed) but only Adaptive-Sync
881             // displays which put the display into Adaptive-Sync mode by calling
882             // nvDPLibSetAdaptiveSync above.
883             TellRMAboutVrrHead(pDispEvo,
884                                pHeadState,
885                                (pHeadState->timings.vrr.type !=
886                                 NVKMS_DPY_VRR_TYPE_NONE));
887         }
888     }
889 
890     if (!(AnyEnabledGsyncDpys(pDevEvo) ||
891           AnyEnabledAdaptiveSyncDpys(pDevEvo))) {
892         return;
893     }
894 
895     if (!RmEnableVrr(pDevEvo)) {
896         return;
897     }
898 
899     pDevEvo->vrr.enabled = TRUE;
900 }
901 
902 static void ClearElvBlock(NVDispEvoPtr pDispEvo, NvU32 head)
903 {
904     const NVDispHeadStateEvoRec *pHeadState = &pDispEvo->headState[head];
905     NV0073_CTRL_SYSTEM_CLEAR_ELV_BLOCK_PARAMS params = { };
906 
907     params.subDeviceInstance = pDispEvo->displayOwner;
908     params.displayId = pHeadState->activeRmId;
909 
910     if (nvRmApiControl(nvEvoGlobal.clientHandle,
911                        pDispEvo->pDevEvo->displayCommonHandle,
912                        NV0073_CTRL_CMD_SYSTEM_CLEAR_ELV_BLOCK,
913                        &params, sizeof(params))
914             != NVOS_STATUS_SUCCESS) {
915         nvAssert(!"CLEAR_ELV_BLOCK failed");
916     }
917 }
918 
919 static void ConfigVrrPstateSwitch(NVDispEvoPtr pDispEvo, NvBool vrrEnabled,
920                                   NvBool vrrState, NvBool vrrDirty, NvU32 head)
921 {
922     NV0073_CTRL_SYSTEM_CONFIG_VRR_PSTATE_SWITCH_PARAMS params = { };
923     NvU32 ret;
924     const NVDispHeadStateEvoRec *pHeadState = &pDispEvo->headState[head];
925     params.displayId = pHeadState->activeRmId;
926     params.bVrrEnabled = vrrEnabled;
927     params.bVrrState = vrrState;
928     params.bVrrDirty = vrrDirty;
929 
930     params.subDeviceInstance = pDispEvo->displayOwner;
931 
932     if (pHeadState->timings.vrr.type != NVKMS_DPY_VRR_TYPE_NONE) {
933         ret = nvRmApiControl(nvEvoGlobal.clientHandle,
934                              pDispEvo->pDevEvo->displayCommonHandle,
935                              NV0073_CTRL_CMD_SYSTEM_CONFIG_VRR_PSTATE_SWITCH,
936                              &params, sizeof(params));
937         if (ret != NVOS_STATUS_SUCCESS) {
938             nvEvoLogDispDebug(pDispEvo, EVO_LOG_WARN,
939                 "NV0073_CTRL_CMD_SYSTEM_CONFIG_VRR_PSTATE_SWITCH failed");
940         }
941     }
942 }
943 
944 static void SetStallLockOneDisp(NVDispEvoPtr pDispEvo, NvBool enable)
945 {
946     NVDevEvoPtr pDevEvo = pDispEvo->pDevEvo;
947     NvBool enableVrrOnHead[NVKMS_MAX_HEADS_PER_DISP];
948     NVEvoUpdateState updateState = { };
949     NvU32 head;
950 
951     if (enable) {
952         for (head = 0; head < pDevEvo->numHeads; head++) {
953             ConfigVrrPstateSwitch(pDispEvo, TRUE /* vrrEnabled */,
954                                   TRUE /* vrrState */,
955                                   FALSE/* vrrDirty */,
956                                   head);
957         }
958     }
959 
960     nvPushEvoSubDevMaskDisp(pDispEvo);
961 
962     // Make sure any pending updates that we didn't wait for previously have
963     // completed.
964     nvRMSyncEvoChannel(pDevEvo, pDevEvo->core, __LINE__);
965 
966     for (head = 0; head < pDevEvo->numHeads; head++) {
967         const NVDispHeadStateEvoRec *pHeadState = &pDispEvo->headState[head];
968         const NvU32 timeout = pHeadState->timings.vrr.timeoutMicroseconds;
969 
970         enableVrrOnHead[head] = ((pHeadState->timings.vrr.type !=
971                                     NVKMS_DPY_VRR_TYPE_NONE) && enable);
972 
973         nvEvoArmLightweightSupervisor(pDispEvo, head,
974                                       enableVrrOnHead[head], TRUE);
975         if (!enableVrrOnHead[head]) {
976             ClearElvBlock(pDispEvo, head);
977         }
978         pDevEvo->hal->SetStallLock(pDispEvo, head,
979                                    enableVrrOnHead[head],
980                                    &updateState);
981 
982         if (pDevEvo->hal->caps.supportsDisplayRate) {
983             pDevEvo->hal->SetDisplayRate(pDispEvo, head,
984                                          enableVrrOnHead[head],
985                                          &updateState,
986                                          timeout);
987 
988             if ((pHeadState->timings.vrr.type !=
989                         NVKMS_DPY_VRR_TYPE_NONE) &&
990                     pHeadState->timings.vrr.needsSwFramePacing) {
991                 SetSwFramePacing(pDispEvo, head,
992                                  enableVrrOnHead[head]);
993             }
994         }
995     }
996 
997     nvEvoUpdateAndKickOff(pDispEvo, TRUE, &updateState,
998                           TRUE /* releaseElv */);
999 
1000     for (head = 0; head < pDevEvo->numHeads; head++) {
1001         nvEvoArmLightweightSupervisor(pDispEvo, head,
1002                                       enableVrrOnHead[head], FALSE);
1003     }
1004 
1005     nvPopEvoSubDevMask(pDevEvo);
1006 
1007     if (!enable) {
1008         for (head = 0; head < pDevEvo->numHeads; head++) {
1009             ConfigVrrPstateSwitch(pDispEvo, TRUE /* vrrEnabled */,
1010                                   FALSE /* vrrState */,
1011                                   FALSE /* vrrDirty */,
1012                                   head);
1013         }
1014     }
1015 }
1016 
1017 static void SetStallLockOneDev(NVDevEvoPtr pDevEvo, NvBool enable)
1018 {
1019     NVDispEvoPtr pDispEvo;
1020     NvU32 dispIndex;
1021 
1022     FOR_ALL_EVO_DISPLAYS(pDispEvo, dispIndex, pDevEvo) {
1023         SetStallLockOneDisp(pDispEvo, enable);
1024     }
1025 }
1026 
1027 /*!
1028  * Modify the VRR state to activate or deactivate VRR on the heads of a pDevEvo.
1029  */
1030 static NvBool SetVrrActivePriv(NVDevEvoPtr pDevEvo, NvBool active)
1031 {
1032     if (!pDevEvo->vrr.enabled ||
1033         pDevEvo->vrr.active == active) {
1034         return NV_TRUE;
1035     }
1036 
1037     // TODO: Drain the base channel first?
1038     SetStallLockOneDev(pDevEvo, active);
1039 
1040     pDevEvo->vrr.active = active;
1041     pDevEvo->vrr.flipCounter = 0;
1042     return NV_TRUE;
1043 }
1044 
1045 void nvSetVrrActive(NVDevEvoPtr pDevEvo, NvBool active)
1046 {
1047     if (!SetVrrActivePriv(pDevEvo, active)) {
1048         nvDisableVrr(pDevEvo);
1049     }
1050 }
1051 
1052 /*!
1053  * Track the minimum and average time between flips over the last 16 flips, and
1054  * add a timestamp to delay the next flip to adjust Frame pacing if necessary.
1055  */
1056 void nvTrackAndDelayFlipForVrrSwFramePacing(NVDispEvoPtr pDispEvo,
1057     const struct NvKmsVrrFramePacingInfo *pVrrFramePacingInfo,
1058     NVFlipChannelEvoHwState *pFlip)
1059 {
1060     volatile NV0073_CTRL_RM_VRR_SHARED_DATA *pData = pVrrFramePacingInfo->pData;
1061     NvU32 retryCount = MAX_VRR_FLIP_DELAY_TIME_RETRY_COUNT;
1062     NvU64 flipTimeStamp = 0;
1063     NvU64 dataTimeStamp1 = 0, dataTimeStamp2 = 0;
1064     NvU32 expectedFrameNum = 0;
1065     NvBool bFlipTimeAdjustment = NV_FALSE;
1066     NvBool bCheckFlipTime = NV_FALSE;
1067 
1068     // If the RG interrupt isn't active, then SW Frame pacing isn't in use.
1069     if (!pVrrFramePacingInfo->framePacingActive) {
1070         return;
1071     }
1072 
1073     do {
1074         // read the data timestamp first
1075         dataTimeStamp1 = pData->dataTimeStamp;
1076 
1077         // now read the actual data required
1078         expectedFrameNum = pData->expectedFrameNum;
1079         bFlipTimeAdjustment = pData->bFlipTimeAdjustment;
1080         bCheckFlipTime = pData->bCheckFlipTime;
1081         flipTimeStamp = pData->flipTimeStamp;
1082 
1083         // read the data timestamp again to check if values were updated
1084         // by RM in between while nvkms was reading them.
1085         dataTimeStamp2 = pData->dataTimeStamp;
1086     } while ((dataTimeStamp1 != dataTimeStamp2) && --retryCount);
1087 
1088     if (retryCount == 0) {
1089         nvEvoLogDisp(pDispEvo, EVO_LOG_ERROR,
1090                     "Failed to sync with RM to get flipTimeStamp related data");
1091         return;
1092     }
1093 
1094     if (expectedFrameNum > 1) {
1095         pFlip->tearing = FALSE;
1096     }
1097 
1098     if (bFlipTimeAdjustment && !(pFlip->tearing && bCheckFlipTime)) {
1099         pFlip->timeStamp = flipTimeStamp;
1100     }
1101 }
1102 
1103 /*!
1104  * Override flip parameters for a head based on VRR state.
1105  */
1106 void nvApplyVrrBaseFlipOverrides(const NVDispEvoRec *pDispEvo, NvU32 head,
1107                                  const NVFlipChannelEvoHwState *pOld,
1108                                  NVFlipChannelEvoHwState *pNew)
1109 {
1110     const NVDevEvoRec *pDevEvo = pDispEvo->pDevEvo;
1111     const NVDispHeadStateEvoRec *pHeadState = NULL;
1112 
1113     if (!pDevEvo->vrr.enabled) {
1114         return;
1115     }
1116 
1117     if (head != NV_INVALID_HEAD) {
1118         pHeadState = &pDispEvo->headState[head];
1119         nvAssert(pDevEvo->head[head].layer[NVKMS_MAIN_LAYER]->caps.vrrTearingFlips);
1120     }
1121 
1122     // Tell RM the real requested tearing mode so that it can honor
1123     // __GL_SYNC_TO_VBLANK.
1124     pNew->vrrTearing = pNew->tearing;
1125 
1126     // If this head is driving non-VRR displays, force swap interval to be 0.
1127     // RM will block the flips as necessary using the pre-update trap methods
1128     // based on the vrrTearing flag above.
1129     if (pHeadState != NULL &&
1130             (pHeadState->timings.vrr.type == NVKMS_DPY_VRR_TYPE_NONE)) {
1131         pNew->tearing = TRUE;
1132         pNew->minPresentInterval = 0;
1133     }
1134 
1135     // If oneshot mode is in use, and the previous flip was non-tearing with
1136     // nonzero MIN_PRESENT_INTERVAL, and the new flip will be tearing with
1137     // MIN_PRESENT_INTERVAL 0, then force this first new flip to be
1138     // non-tearing to WAR bug 2406398 which causes these transitional flips
1139     // to stall for up to the display's minimum refresh rate.
1140     if ((pHeadState != NULL) &&
1141         (pHeadState->timings.vrr.type != NVKMS_DPY_VRR_TYPE_NONE) &&
1142         !pOld->tearing &&
1143         (pOld->minPresentInterval != 0) &&
1144         pNew->tearing &&
1145         (pNew->minPresentInterval == 0)) {
1146         pNew->tearing = FALSE;
1147     }
1148 }
1149 
1150 void nvCancelVrrFrameReleaseTimers(NVDevEvoPtr pDevEvo)
1151 {
1152     NVDispEvoPtr pDispEvo;
1153     NvU32 dispIndex;
1154 
1155     FOR_ALL_EVO_DISPLAYS(pDispEvo, dispIndex, pDevEvo) {
1156         nvkms_free_timer(pDispEvo->vrr.unstallTimer);
1157         pDispEvo->vrr.unstallTimer = NULL;
1158     }
1159 }
1160 
1161 /* Get active vrr type used by the flips. */
1162 enum NvKmsVrrFlipType nvGetActiveVrrType(const NVDevEvoRec *pDevEvo)
1163 {
1164     /*
1165      * If VRR is active, and any connected display is G-SYNC, then report that
1166      * this flip was a G-SYNC flip, otherwise report it as an Adaptive-Sync
1167      * flip.
1168      *
1169      * XXX NVKMS TODO: We could be smarter about reporting whether this flip
1170      * exclusively changed surfaces on Adaptive-Sync or G-SYNC heads.
1171      */
1172     if (pDevEvo->vrr.active) {
1173         if (AnyEnabledGsyncDpys(pDevEvo)) {
1174             return NV_KMS_VRR_FLIP_GSYNC;
1175         } else {
1176             return NV_KMS_VRR_FLIP_ADAPTIVE_SYNC;
1177         }
1178     }
1179 
1180     return NV_KMS_VRR_FLIP_NON_VRR;
1181 }
1182 
1183 /*!
1184  * Get the next VRR semaphore index to be released
1185  * by the client, increments the counter and handles wrapping.
1186  */
1187 NvS32 nvIncVrrSemaphoreIndex(NVDevEvoPtr pDevEvo)
1188 {
1189     NvS32 vrrSemaphoreIndex = -1;
1190 
1191     // If there are pending unstall timers (e.g. triggered by cursor motion),
1192     // cancel them now. The flip that was just requested will trigger an
1193     // unstall.
1194     nvCancelVrrFrameReleaseTimers(pDevEvo);
1195 
1196     if (pDevEvo->vrr.active && !pDevEvo->hal->caps.supportsDisplayRate) {
1197         vrrSemaphoreIndex = pDevEvo->vrr.flipCounter++;
1198         if (pDevEvo->vrr.flipCounter >=
1199             NVKMS_VRR_SEMAPHORE_SURFACE_SIZE / sizeof(NvU32)) {
1200             pDevEvo->vrr.flipCounter = 0;
1201         }
1202     }
1203 
1204     return vrrSemaphoreIndex;
1205 }
1206 
1207 static void
1208 VrrUnstallNow(NVDispEvoPtr pDispEvo)
1209 {
1210     NVDevEvoPtr pDevEvo = pDispEvo->pDevEvo;
1211     NvU32 head;
1212 
1213     nvAssert(pDevEvo->hal->caps.supportsDisplayRate);
1214 
1215     for (head = 0; head < pDevEvo->numHeads; head++) {
1216         if (!nvHeadIsActive(pDispEvo, head)) {
1217             continue;
1218         }
1219 
1220         pDevEvo->cursorHal->ReleaseElv(pDevEvo, pDispEvo->displayOwner, head);
1221     }
1222 }
1223 
1224 static void
1225 VrrUnstallTimer(void *dataPtr, NvU32 dataU32)
1226 {
1227     NVDispEvoPtr pDispEvo = dataPtr;
1228 
1229     VrrUnstallNow(pDispEvo);
1230     pDispEvo->vrr.unstallTimer = NULL;
1231 }
1232 
1233 /*!
1234  * Schedule a timer to trigger a VRR unstall if no flip occurs soon.
1235  *
1236  * When VRR is active and something other than a flip (i.e. cursor motion)
1237  * changes the screen, RM needs to be notified so that it can trigger a VRR
1238  * unstall to present the new frame.  However, if it does that immediately, then
1239  * applications that flip in response to cursor motion will end up always
1240  * flipping during the unstall, causing stutter.  So instead, schedule a timeout
1241  * for some time in the future in order to give the application some time to
1242  * respond, but force a minimum refresh rate if it doesn't.
1243  *
1244  * On nvdisplay, this schedules an nvkms timer and uses a method to trigger an
1245  * unstall. On EVO, it calls into RM to do something equivalent.
1246  */
1247 void nvTriggerVrrUnstallMoveCursor(NVDispEvoPtr pDispEvo)
1248 {
1249     NVDevEvoPtr pDevEvo = pDispEvo->pDevEvo;
1250     const NvU32 timeoutMs = 33; // 30 fps
1251 
1252     if (!pDevEvo->vrr.active) {
1253         return;
1254     }
1255 
1256     {
1257         if (!pDispEvo->vrr.unstallTimer) {
1258             pDispEvo->vrr.unstallTimer =
1259                 nvkms_alloc_timer(VrrUnstallTimer, pDispEvo, 0, timeoutMs * 1000);
1260         }
1261     }
1262 }
1263 
1264 /*!
1265  * Trigger a VRR unstall in response to a cursor image change.
1266  */
1267 void nvTriggerVrrUnstallSetCursorImage(NVDispEvoPtr pDispEvo,
1268                                        NvBool elvReleased)
1269 {
1270     NVDevEvoPtr pDevEvo = pDispEvo->pDevEvo;
1271 
1272     if (pDevEvo->vrr.active) {
1273         if (!elvReleased) {
1274             // On nvdisplay, no unstall is necessary if the cursor image update
1275             // path did a releaseElv=true Update.
1276             //
1277             // But, if elv was not released, then force an immediate unstall
1278             // now.
1279             VrrUnstallNow(pDispEvo);
1280         }
1281     }
1282 }
1283 
1284