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 ¶ms, 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 ¶ms, 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 ¶ms, 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 const NVHwModeTimingsEvo *pTimings = &pHeadState->timings; 926 927 if (nvkms_disable_vrr_memclk_switch() || 928 (pTimings->vrr.type == NVKMS_DPY_VRR_TYPE_NONE)) { 929 return; 930 } 931 932 /* 933 * An inactive head should always have pTimings->vrr.type == 934 * NVKMS_DPY_VRR_TYPE_NONE and therefore return early above. 935 */ 936 nvAssert(nvHeadIsActive(pDispEvo, head)); 937 938 params.displayId = pHeadState->activeRmId; 939 params.bVrrEnabled = vrrEnabled; 940 params.bVrrState = vrrState; 941 params.bVrrDirty = vrrDirty; 942 943 if (params.bVrrDirty) { 944 NvU64 frameTimeUs = axb_div_c(pTimings->rasterSize.y * 1000ULL, 945 pTimings->rasterSize.x, pTimings->pixelClock); 946 NvU64 timePerLineNs = (frameTimeUs * 1000ULL) / pTimings->rasterSize.y; 947 948 NvU64 maxFrameTimeUs = pTimings->vrr.timeoutMicroseconds; 949 NvU64 maxVblankExtTimeNs = (maxFrameTimeUs - frameTimeUs) * 1000ULL; 950 951 params.maxVblankExtension = maxVblankExtTimeNs / timePerLineNs; 952 } 953 954 ret = nvRmApiControl(nvEvoGlobal.clientHandle, 955 pDispEvo->pDevEvo->displayCommonHandle, 956 NV0073_CTRL_CMD_SYSTEM_CONFIG_VRR_PSTATE_SWITCH, 957 ¶ms, sizeof(params)); 958 if (ret != NVOS_STATUS_SUCCESS) { 959 nvEvoLogDispDebug(pDispEvo, EVO_LOG_WARN, 960 "NV0073_CTRL_CMD_SYSTEM_CONFIG_VRR_PSTATE_SWITCH failed"); 961 } 962 } 963 964 static void SetStallLockOneDisp(NVDispEvoPtr pDispEvo, NvBool enable) 965 { 966 NVDevEvoPtr pDevEvo = pDispEvo->pDevEvo; 967 NvBool enableVrrOnHead[NVKMS_MAX_HEADS_PER_DISP]; 968 NVEvoUpdateState updateState = { }; 969 NvU32 head; 970 971 if (enable) { 972 for (head = 0; head < pDevEvo->numHeads; head++) { 973 ConfigVrrPstateSwitch(pDispEvo, TRUE /* vrrEnabled */, 974 TRUE /* vrrState */, 975 FALSE/* vrrDirty */, 976 head); 977 } 978 } 979 980 nvPushEvoSubDevMaskDisp(pDispEvo); 981 982 // Make sure any pending updates that we didn't wait for previously have 983 // completed. 984 nvRMSyncEvoChannel(pDevEvo, pDevEvo->core, __LINE__); 985 986 for (head = 0; head < pDevEvo->numHeads; head++) { 987 const NVDispHeadStateEvoRec *pHeadState = &pDispEvo->headState[head]; 988 const NvU32 timeout = pHeadState->timings.vrr.timeoutMicroseconds; 989 990 enableVrrOnHead[head] = ((pHeadState->timings.vrr.type != 991 NVKMS_DPY_VRR_TYPE_NONE) && enable); 992 993 nvEvoArmLightweightSupervisor(pDispEvo, head, 994 enableVrrOnHead[head], TRUE); 995 if (!enableVrrOnHead[head]) { 996 ClearElvBlock(pDispEvo, head); 997 } 998 pDevEvo->hal->SetStallLock(pDispEvo, head, 999 enableVrrOnHead[head], 1000 &updateState); 1001 1002 if (pDevEvo->hal->caps.supportsDisplayRate) { 1003 pDevEvo->hal->SetDisplayRate(pDispEvo, head, 1004 enableVrrOnHead[head], 1005 &updateState, 1006 timeout); 1007 1008 if ((pHeadState->timings.vrr.type != 1009 NVKMS_DPY_VRR_TYPE_NONE) && 1010 pHeadState->timings.vrr.needsSwFramePacing) { 1011 SetSwFramePacing(pDispEvo, head, 1012 enableVrrOnHead[head]); 1013 } 1014 } 1015 } 1016 1017 nvEvoUpdateAndKickOff(pDispEvo, TRUE, &updateState, 1018 TRUE /* releaseElv */); 1019 1020 for (head = 0; head < pDevEvo->numHeads; head++) { 1021 nvEvoArmLightweightSupervisor(pDispEvo, head, 1022 enableVrrOnHead[head], FALSE); 1023 } 1024 1025 nvPopEvoSubDevMask(pDevEvo); 1026 1027 if (!enable) { 1028 for (head = 0; head < pDevEvo->numHeads; head++) { 1029 ConfigVrrPstateSwitch(pDispEvo, TRUE /* vrrEnabled */, 1030 FALSE /* vrrState */, 1031 FALSE /* vrrDirty */, 1032 head); 1033 } 1034 } 1035 } 1036 1037 static void SetStallLockOneDev(NVDevEvoPtr pDevEvo, NvBool enable) 1038 { 1039 NVDispEvoPtr pDispEvo; 1040 NvU32 dispIndex; 1041 1042 FOR_ALL_EVO_DISPLAYS(pDispEvo, dispIndex, pDevEvo) { 1043 SetStallLockOneDisp(pDispEvo, enable); 1044 } 1045 } 1046 1047 /*! 1048 * Modify the VRR state to activate or deactivate VRR on the heads of a pDevEvo. 1049 */ 1050 static NvBool SetVrrActivePriv(NVDevEvoPtr pDevEvo, NvBool active) 1051 { 1052 if (!pDevEvo->vrr.enabled || 1053 pDevEvo->vrr.active == active) { 1054 return NV_TRUE; 1055 } 1056 1057 // TODO: Drain the base channel first? 1058 SetStallLockOneDev(pDevEvo, active); 1059 1060 pDevEvo->vrr.active = active; 1061 pDevEvo->vrr.flipCounter = 0; 1062 return NV_TRUE; 1063 } 1064 1065 void nvSetVrrActive(NVDevEvoPtr pDevEvo, NvBool active) 1066 { 1067 if (!SetVrrActivePriv(pDevEvo, active)) { 1068 nvDisableVrr(pDevEvo); 1069 } 1070 } 1071 1072 /*! 1073 * Track the minimum and average time between flips over the last 16 flips, and 1074 * add a timestamp to delay the next flip to adjust Frame pacing if necessary. 1075 */ 1076 void nvTrackAndDelayFlipForVrrSwFramePacing(NVDispEvoPtr pDispEvo, 1077 const struct NvKmsVrrFramePacingInfo *pVrrFramePacingInfo, 1078 NVFlipChannelEvoHwState *pFlip) 1079 { 1080 volatile NV0073_CTRL_RM_VRR_SHARED_DATA *pData = pVrrFramePacingInfo->pData; 1081 NvU32 retryCount = MAX_VRR_FLIP_DELAY_TIME_RETRY_COUNT; 1082 NvU64 flipTimeStamp = 0; 1083 NvU64 dataTimeStamp1 = 0, dataTimeStamp2 = 0; 1084 NvU32 expectedFrameNum = 0; 1085 NvBool bFlipTimeAdjustment = NV_FALSE; 1086 NvBool bCheckFlipTime = NV_FALSE; 1087 1088 // If the RG interrupt isn't active, then SW Frame pacing isn't in use. 1089 if (!pVrrFramePacingInfo->framePacingActive) { 1090 return; 1091 } 1092 1093 do { 1094 // read the data timestamp first 1095 dataTimeStamp1 = pData->dataTimeStamp; 1096 1097 // now read the actual data required 1098 expectedFrameNum = pData->expectedFrameNum; 1099 bFlipTimeAdjustment = pData->bFlipTimeAdjustment; 1100 bCheckFlipTime = pData->bCheckFlipTime; 1101 flipTimeStamp = pData->flipTimeStamp; 1102 1103 // read the data timestamp again to check if values were updated 1104 // by RM in between while nvkms was reading them. 1105 dataTimeStamp2 = pData->dataTimeStamp; 1106 } while ((dataTimeStamp1 != dataTimeStamp2) && --retryCount); 1107 1108 if (retryCount == 0) { 1109 nvEvoLogDisp(pDispEvo, EVO_LOG_ERROR, 1110 "Failed to sync with RM to get flipTimeStamp related data"); 1111 return; 1112 } 1113 1114 if (expectedFrameNum > 1) { 1115 pFlip->tearing = FALSE; 1116 } 1117 1118 if (bFlipTimeAdjustment && !(pFlip->tearing && bCheckFlipTime)) { 1119 pFlip->timeStamp = flipTimeStamp; 1120 } 1121 } 1122 1123 /*! 1124 * Override flip parameters for a head based on VRR state. 1125 */ 1126 void nvApplyVrrBaseFlipOverrides(const NVDispEvoRec *pDispEvo, NvU32 head, 1127 const NVFlipChannelEvoHwState *pOld, 1128 NVFlipChannelEvoHwState *pNew) 1129 { 1130 const NVDevEvoRec *pDevEvo = pDispEvo->pDevEvo; 1131 const NVDispHeadStateEvoRec *pHeadState = NULL; 1132 1133 if (!pDevEvo->vrr.enabled) { 1134 return; 1135 } 1136 1137 if (head != NV_INVALID_HEAD) { 1138 pHeadState = &pDispEvo->headState[head]; 1139 nvAssert(pDevEvo->head[head].layer[NVKMS_MAIN_LAYER]->caps.vrrTearingFlips); 1140 } 1141 1142 // Tell RM the real requested tearing mode so that it can honor 1143 // __GL_SYNC_TO_VBLANK. 1144 pNew->vrrTearing = pNew->tearing; 1145 1146 // If this head is driving non-VRR displays, force swap interval to be 0. 1147 // RM will block the flips as necessary using the pre-update trap methods 1148 // based on the vrrTearing flag above. 1149 if (pHeadState != NULL && 1150 (pHeadState->timings.vrr.type == NVKMS_DPY_VRR_TYPE_NONE)) { 1151 pNew->tearing = TRUE; 1152 pNew->minPresentInterval = 0; 1153 } 1154 1155 // If oneshot mode is in use, and the previous flip was non-tearing with 1156 // nonzero MIN_PRESENT_INTERVAL, and the new flip will be tearing with 1157 // MIN_PRESENT_INTERVAL 0, then force this first new flip to be 1158 // non-tearing to WAR bug 2406398 which causes these transitional flips 1159 // to stall for up to the display's minimum refresh rate. 1160 if ((pHeadState != NULL) && 1161 (pHeadState->timings.vrr.type != NVKMS_DPY_VRR_TYPE_NONE) && 1162 !pOld->tearing && 1163 (pOld->minPresentInterval != 0) && 1164 pNew->tearing && 1165 (pNew->minPresentInterval == 0)) { 1166 pNew->tearing = FALSE; 1167 } 1168 } 1169 1170 void nvCancelVrrFrameReleaseTimers(NVDevEvoPtr pDevEvo) 1171 { 1172 NVDispEvoPtr pDispEvo; 1173 NvU32 dispIndex; 1174 1175 FOR_ALL_EVO_DISPLAYS(pDispEvo, dispIndex, pDevEvo) { 1176 nvkms_free_timer(pDispEvo->vrr.unstallTimer); 1177 pDispEvo->vrr.unstallTimer = NULL; 1178 } 1179 } 1180 1181 /* Get active vrr type used by the flips. */ 1182 enum NvKmsVrrFlipType nvGetActiveVrrType(const NVDevEvoRec *pDevEvo) 1183 { 1184 /* 1185 * If VRR is active, and any connected display is G-SYNC, then report that 1186 * this flip was a G-SYNC flip, otherwise report it as an Adaptive-Sync 1187 * flip. 1188 * 1189 * XXX NVKMS TODO: We could be smarter about reporting whether this flip 1190 * exclusively changed surfaces on Adaptive-Sync or G-SYNC heads. 1191 */ 1192 if (pDevEvo->vrr.active) { 1193 if (AnyEnabledGsyncDpys(pDevEvo)) { 1194 return NV_KMS_VRR_FLIP_GSYNC; 1195 } else { 1196 return NV_KMS_VRR_FLIP_ADAPTIVE_SYNC; 1197 } 1198 } 1199 1200 return NV_KMS_VRR_FLIP_NON_VRR; 1201 } 1202 1203 /*! 1204 * Get the next VRR semaphore index to be released 1205 * by the client, increments the counter and handles wrapping. 1206 */ 1207 NvS32 nvIncVrrSemaphoreIndex(NVDevEvoPtr pDevEvo) 1208 { 1209 NvS32 vrrSemaphoreIndex = -1; 1210 1211 // If there are pending unstall timers (e.g. triggered by cursor motion), 1212 // cancel them now. The flip that was just requested will trigger an 1213 // unstall. 1214 nvCancelVrrFrameReleaseTimers(pDevEvo); 1215 1216 if (pDevEvo->vrr.active && !pDevEvo->hal->caps.supportsDisplayRate) { 1217 vrrSemaphoreIndex = pDevEvo->vrr.flipCounter++; 1218 if (pDevEvo->vrr.flipCounter >= 1219 NVKMS_VRR_SEMAPHORE_SURFACE_SIZE / sizeof(NvU32)) { 1220 pDevEvo->vrr.flipCounter = 0; 1221 } 1222 } 1223 1224 return vrrSemaphoreIndex; 1225 } 1226 1227 static void 1228 VrrUnstallNow(NVDispEvoPtr pDispEvo) 1229 { 1230 NVDevEvoPtr pDevEvo = pDispEvo->pDevEvo; 1231 NvU32 head; 1232 1233 nvAssert(pDevEvo->hal->caps.supportsDisplayRate); 1234 1235 for (head = 0; head < pDevEvo->numHeads; head++) { 1236 if (!nvHeadIsActive(pDispEvo, head)) { 1237 continue; 1238 } 1239 1240 pDevEvo->cursorHal->ReleaseElv(pDevEvo, pDispEvo->displayOwner, head); 1241 } 1242 } 1243 1244 static void 1245 VrrUnstallTimer(void *dataPtr, NvU32 dataU32) 1246 { 1247 NVDispEvoPtr pDispEvo = dataPtr; 1248 1249 VrrUnstallNow(pDispEvo); 1250 pDispEvo->vrr.unstallTimer = NULL; 1251 } 1252 1253 /*! 1254 * Schedule a timer to trigger a VRR unstall if no flip occurs soon. 1255 * 1256 * When VRR is active and something other than a flip (i.e. cursor motion) 1257 * changes the screen, RM needs to be notified so that it can trigger a VRR 1258 * unstall to present the new frame. However, if it does that immediately, then 1259 * applications that flip in response to cursor motion will end up always 1260 * flipping during the unstall, causing stutter. So instead, schedule a timeout 1261 * for some time in the future in order to give the application some time to 1262 * respond, but force a minimum refresh rate if it doesn't. 1263 * 1264 * On nvdisplay, this schedules an nvkms timer and uses a method to trigger an 1265 * unstall. On EVO, it calls into RM to do something equivalent. 1266 */ 1267 void nvTriggerVrrUnstallMoveCursor(NVDispEvoPtr pDispEvo) 1268 { 1269 NVDevEvoPtr pDevEvo = pDispEvo->pDevEvo; 1270 const NvU32 timeoutMs = 33; // 30 fps 1271 1272 if (!pDevEvo->vrr.active) { 1273 return; 1274 } 1275 1276 { 1277 if (!pDispEvo->vrr.unstallTimer) { 1278 pDispEvo->vrr.unstallTimer = 1279 nvkms_alloc_timer(VrrUnstallTimer, pDispEvo, 0, timeoutMs * 1000); 1280 } 1281 } 1282 } 1283 1284 /*! 1285 * Trigger a VRR unstall in response to a cursor image change. 1286 */ 1287 void nvTriggerVrrUnstallSetCursorImage(NVDispEvoPtr pDispEvo, 1288 NvBool elvReleased) 1289 { 1290 NVDevEvoPtr pDevEvo = pDispEvo->pDevEvo; 1291 1292 if (pDevEvo->vrr.active) { 1293 if (!elvReleased) { 1294 // On nvdisplay, no unstall is necessary if the cursor image update 1295 // path did a releaseElv=true Update. 1296 // 1297 // But, if elv was not released, then force an immediate unstall 1298 // now. 1299 VrrUnstallNow(pDispEvo); 1300 } 1301 } 1302 } 1303 1304