1 /* 2 * SPDX-FileCopyrightText: Copyright (c) 2014 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-hw-flip.h" 27 #include "nvkms-utils-flip.h" 28 #include "nvkms-flip-workarea.h" 29 #include "nvkms-surface.h" 30 #include "nvkms-prealloc.h" 31 #include "nvkms-private.h" 32 #include "nvkms-rm.h" 33 #include "nvkms-vrr.h" 34 #include "nvkms-cursor.h" 35 #include "nvkms-types.h" 36 #include "nvkms-dpy.h" 37 #include "nvkms-lut.h" 38 #include "nvkms-softfloat.h" 39 40 #include "nvkms-sync.h" 41 42 #include "nvkms-difr.h" 43 44 static void SchedulePostFlipIMPTimer(NVDevEvoPtr pDevEvo); 45 46 // The EVO .mfs file defines the maximum minPresentInterval to be 8. 47 #define NV_MAX_SWAP_INTERVAL 8 48 49 static NvBool AssignPreSyncptEvoHwState( 50 const NVDevEvoRec *pDevEvo, 51 const struct NvKmsChannelSyncObjects *pChannelSyncObjects, 52 NVFlipSyncObjectEvoHwState *pFlipSyncObject) 53 { 54 NvBool ret; 55 NvU32 id = 0; 56 NvU32 value; 57 enum NvKmsSyncptType preType; 58 59 nvAssert(pChannelSyncObjects->useSyncpt); 60 61 preType = pChannelSyncObjects->u.syncpts.pre.type; 62 63 if (preType == NVKMS_SYNCPT_TYPE_NONE) { 64 return TRUE; 65 } 66 67 if (preType == NVKMS_SYNCPT_TYPE_FD) { 68 /*! Get id from fd using nvhost API */ 69 NvKmsSyncPtOpParams params = { }; 70 params.fd_to_id_and_thresh.fd = 71 pChannelSyncObjects->u.syncpts.pre.u.fd; 72 ret = nvkms_syncpt_op(NVKMS_SYNCPT_OP_FD_TO_ID_AND_THRESH, 73 ¶ms); 74 if (!ret) { 75 return FALSE; 76 } 77 id = params.fd_to_id_and_thresh.id; 78 value = params.fd_to_id_and_thresh.thresh; 79 } else { 80 id = pChannelSyncObjects->u.syncpts.pre.u.raw.id; 81 value = pChannelSyncObjects->u.syncpts.pre.u.raw.value; 82 } 83 if (id >= NV_SYNCPT_GLOBAL_TABLE_LENGTH) { 84 return FALSE; 85 } 86 /*! Fill pre-syncpt related information in hardware state */ 87 pFlipSyncObject->u.syncpts.preSyncpt = id; 88 pFlipSyncObject->u.syncpts.preValue = value; 89 pFlipSyncObject->u.syncpts.isPreSyncptSpecified = TRUE; 90 pFlipSyncObject->usingSyncpt = TRUE; 91 92 return TRUE; 93 } 94 95 static NvBool AssignPostSyncptEvoHwState( 96 const NVDevEvoRec *pDevEvo, 97 NVEvoChannel *pChannel, 98 const struct NvKmsChannelSyncObjects *pChannelSyncObjects, 99 NVFlipSyncObjectEvoHwState *pFlipSyncObject) 100 { 101 enum NvKmsSyncptType postType; 102 NvU32 threshold; 103 104 nvAssert(pChannelSyncObjects->useSyncpt); 105 106 postType = pChannelSyncObjects->u.syncpts.requestedPostType; 107 108 /*! 109 * It is possible that syncpt is mentioned but post-syncpt 110 * is not specified (case where only pre-syncpt used) 111 */ 112 if (postType == NVKMS_SYNCPT_TYPE_NONE) { 113 return TRUE; 114 } 115 116 /*! return threshold to caller but increase only when programming hw */ 117 threshold = pChannel->postSyncpt.syncptMaxVal + 1; 118 119 /*! each channel associated with one post-syncpt */ 120 pFlipSyncObject->u.syncpts.postCtxDma = pChannel->postSyncpt.hCtxDma; 121 pFlipSyncObject->u.syncpts.postValue = threshold; 122 123 pFlipSyncObject->usingSyncpt = TRUE; 124 125 return TRUE; 126 } 127 128 void nvFillPostSyncptReplyOneChannel( 129 NVEvoChannel *pChannel, 130 enum NvKmsSyncptType postType, 131 struct NvKmsSyncpt *postSyncpt, 132 const NVFlipSyncObjectEvoHwState *pHwSyncObject) 133 { 134 if (postType == NVKMS_SYNCPT_TYPE_RAW) { 135 postSyncpt->u.raw.id = pChannel->postSyncpt.id; 136 postSyncpt->u.raw.value = pHwSyncObject->u.syncpts.postValue; 137 postSyncpt->type = NVKMS_SYNCPT_TYPE_RAW; 138 } else if (postType == NVKMS_SYNCPT_TYPE_FD) { 139 NvBool ret = TRUE; 140 NvKmsSyncPtOpParams params = { }; 141 params.id_and_thresh_to_fd.id = pChannel->postSyncpt.id; 142 params.id_and_thresh_to_fd.thresh = 143 pHwSyncObject->u.syncpts.postValue; 144 145 ret = nvkms_syncpt_op(NVKMS_SYNCPT_OP_ID_AND_THRESH_TO_FD, ¶ms); 146 if (!ret) { 147 nvAssert(!"Failed syncpt op ID_AND_THRESH_TO_FD"); 148 return; 149 } 150 postSyncpt->u.fd = params.id_and_thresh_to_fd.fd; 151 postSyncpt->type = NVKMS_SYNCPT_TYPE_FD; 152 } 153 } 154 155 static NvBool GetPreSyncptCtxDma(NVDevEvoRec *pDevEvo, 156 NVEvoChannel *pChannel, const NvU32 id) 157 { 158 NvU32 hSyncptCtxDma, hSyncpt; 159 160 /*! use id value to check the global table */ 161 if (pDevEvo->preSyncptTable[id].hCtxDma == 0) { 162 /*! Register - allocate and bind ctxdma to syncpt*/ 163 if (!nvRmEvoAllocAndBindSyncpt(pDevEvo, 164 pChannel, 165 id, 166 &hSyncpt, 167 &hSyncptCtxDma)) { 168 nvAssert(!"Failed to register pre-syncpt"); 169 return FALSE; 170 } 171 172 /*! Fill the Entry in Global Table */ 173 pDevEvo->preSyncptTable[id].hCtxDma = hSyncptCtxDma; 174 pDevEvo->preSyncptTable[id].hSyncpt = hSyncpt; 175 pDevEvo->preSyncptTable[id].channelMask |= pChannel->channelMask; 176 pDevEvo->preSyncptTable[id].id = id; 177 } else { 178 /*! 179 * syncpt found, just bind the context dma of this syncpt 180 * to the window if it is not already. 181 */ 182 if ((pDevEvo->preSyncptTable[id].channelMask & 183 pChannel->channelMask) == 0) { 184 185 NvU32 ret = 186 nvRmEvoBindDispContextDMA(pDevEvo, 187 pChannel, 188 pDevEvo->preSyncptTable[id].hCtxDma); 189 if (ret != NVOS_STATUS_SUCCESS) { 190 nvAssert(!"Failed to bind pre-syncpt with ctxdma"); 191 } 192 pDevEvo->preSyncptTable[id].channelMask |= pChannel->channelMask; 193 /*! hSyncpt already allocated for id*/ 194 } 195 } 196 197 return TRUE; 198 } 199 200 static NvBool RegisterPreSyncpt(NVDevEvoRec *pDevEvo, 201 struct NvKmsFlipWorkArea *pWorkArea) 202 { 203 NvU32 sd; 204 NvU32 ret = TRUE; 205 const NVDispEvoRec *pDispEvo; 206 207 pDevEvo->pAllSyncptUsedInCurrentFlip = 208 nvCalloc(1, sizeof(NvBool) * NV_SYNCPT_GLOBAL_TABLE_LENGTH); 209 if (pDevEvo->pAllSyncptUsedInCurrentFlip == NULL) { 210 ret = FALSE; 211 goto done; 212 } 213 214 FOR_ALL_EVO_DISPLAYS(pDispEvo, sd, pDevEvo) { 215 NvU32 head; 216 for (head = 0; head < ARRAY_LEN(pWorkArea->sd[sd].head); head++) { 217 NVFlipEvoHwState *pFlipState = 218 &pWorkArea->sd[sd].head[head].newState; 219 NvU32 layer; 220 221 for (layer = 0; layer < ARRAY_LEN(pFlipState->layer); layer++) { 222 NVFlipSyncObjectEvoHwState *pFlipSyncObject = 223 &pFlipState->layer[layer].syncObject; 224 NvU32 preSyncpt = pFlipSyncObject->u.syncpts.preSyncpt; 225 226 if (!pFlipState->dirty.layerSyncObjects[layer] || 227 !pFlipSyncObject->usingSyncpt || 228 !pFlipSyncObject->u.syncpts.isPreSyncptSpecified) { 229 continue; 230 } 231 232 if (!GetPreSyncptCtxDma(pDevEvo, 233 pDevEvo->head[head].layer[layer], 234 preSyncpt)) { 235 ret = FALSE; 236 goto done; 237 } 238 239 pDevEvo->pAllSyncptUsedInCurrentFlip[preSyncpt] = NV_TRUE; 240 } 241 } 242 } 243 244 done: 245 nvFree(pDevEvo->pAllSyncptUsedInCurrentFlip); 246 pDevEvo->pAllSyncptUsedInCurrentFlip = NULL; 247 248 return ret; 249 } 250 251 void nvClearFlipEvoHwState( 252 NVFlipEvoHwState *pFlipState) 253 { 254 NvU32 i; 255 256 nvkms_memset(pFlipState, 0, sizeof(*pFlipState)); 257 258 for (i = 0; i < ARRAY_LEN(pFlipState->layer); i++) { 259 pFlipState->layer[i].cscMatrix = NVKMS_IDENTITY_CSC_MATRIX; 260 } 261 } 262 263 /*! 264 * Initialize NVFlipEvoHwState with a current snapshot from headState. 265 */ 266 void nvInitFlipEvoHwState( 267 const NVDevEvoRec *pDevEvo, 268 const NvU32 sd, 269 const NvU32 head, 270 NVFlipEvoHwState *pFlipState) 271 { 272 NVDispEvoRec *pDispEvo = pDevEvo->gpus[sd].pDispEvo; 273 const NVEvoSubDevHeadStateRec *pSdHeadState; 274 NvU32 i; 275 276 nvClearFlipEvoHwState(pFlipState); 277 278 if (!nvHeadIsActive(pDispEvo, head)) { 279 return; 280 } 281 282 pSdHeadState = &pDevEvo->gpus[sd].headState[head]; 283 284 pFlipState->viewPortPointIn = pSdHeadState->viewPortPointIn; 285 pFlipState->cursor = pSdHeadState->cursor; 286 287 ct_assert(ARRAY_LEN(pFlipState->layer) == ARRAY_LEN(pSdHeadState->layer)); 288 289 for (i = 0; i < ARRAY_LEN(pFlipState->layer); i++) { 290 pFlipState->layer[i] = pSdHeadState->layer[i]; 291 } 292 293 // pFlipState->usage describes the usage bounds that will be necessary after 294 // this flip is complete. Initialize it using pSdHeadState->targetUsage, 295 // which describes the usage bounds that will be required just before this 296 // flip occurs, rather than pSdHeadState->usage, which describes the usage 297 // bounds currently programmed into the hardware. 298 // 299 // pSdHeadState->usage may have higher bounds than pSdHeadState->targetUsage 300 // if TryLoweringUsageBounds has not yet noticed that a satellite channel is 301 // no longer in use, or a flip to NULL in a satellite channel is pending but 302 // has not yet occurred. 303 pFlipState->usage = pSdHeadState->targetUsage; 304 305 pFlipState->disableMidFrameAndDWCFWatermark = 306 pSdHeadState->targetDisableMidFrameAndDWCFWatermark; 307 } 308 309 310 NvBool nvIsLayerDirty(const struct NvKmsFlipCommonParams *pParams, 311 const NvU32 layer) 312 { 313 return pParams->layer[layer].surface.specified || 314 pParams->layer[layer].sizeIn.specified || 315 pParams->layer[layer].sizeOut.specified || 316 pParams->layer[layer].outputPosition.specified || 317 pParams->layer[layer].completionNotifier.specified || 318 pParams->layer[layer].syncObjects.specified || 319 pParams->layer[layer].compositionParams.specified || 320 pParams->layer[layer].csc.specified || 321 pParams->layer[layer].hdr.specified || 322 pParams->layer[layer].colorspace.specified; 323 } 324 325 /*! 326 * Determine whether a base channel flip requires a non-tearing present mode. 327 * 328 * EVO requires a non-tearing flip when certain parameters are changing. See 329 * NV_DISP_BASE_STATE_ERROR_052 in dispClass024XBaseUpdateErrorChecks.mfs. 330 */ 331 static NvBool FlipRequiresNonTearingMode( 332 const NVDevEvoRec *pDevEvo, 333 const NvU32 head, 334 const NVFlipChannelEvoHwState *pOld, 335 const NVFlipChannelEvoHwState *pNew) 336 { 337 // TODO: Do we need to care about the right eye here? The error check 338 // doesn't. 339 const NVSurfaceEvoRec *pOldSurf = pOld->pSurfaceEvo[NVKMS_LEFT]; 340 const NVSurfaceEvoRec *pNewSurf = pNew->pSurfaceEvo[NVKMS_LEFT]; 341 NvU32 oldHwFormat = 0, newHwFormat = 0; 342 343 if (pOldSurf == NULL || pNewSurf == NULL) { 344 return TRUE; 345 } 346 347 // If these functions actually return FALSE at this point, then something is 348 // really wrong... 349 if (!pDevEvo->hal->ValidateWindowFormat( 350 pOldSurf->format, NULL, &oldHwFormat)) { 351 nvAssert(FALSE); 352 } 353 354 if (!pDevEvo->hal->ValidateWindowFormat( 355 pNewSurf->format, NULL, &newHwFormat)) { 356 nvAssert(FALSE); 357 } 358 359 // Commented entries are things checked in the .mfs that are not yet 360 // supported in NVKMS. 361 return // SuperSample 362 oldHwFormat != newHwFormat || 363 // Gamma 364 // Layout (i.e. frame, field1, or field2) 365 pOldSurf->widthInPixels != pNewSurf->widthInPixels || 366 pOldSurf->heightInPixels != pNewSurf->heightInPixels || 367 pOldSurf->layout != pNewSurf->layout; 368 // UseGainOfs 369 // NewBaseLut -- USE_CORE_LUT is programmed in InitChannel* 370 // NewOutputLut 371 } 372 373 374 /*! 375 * Apply flip overrides if necessary. 376 * 377 * 1. Override swap intervals for VRR. 378 * 2. If the flip is changing certain parameters, override the tearing mode. 379 */ 380 static NvBool ApplyBaseFlipOverrides( 381 const NVDevEvoRec *pDevEvo, 382 const NvU32 sd, 383 const NvU32 head, 384 NVFlipChannelEvoHwState *pNew, 385 NvBool allowVrr) 386 { 387 const NVDispEvoRec *pDispEvo = pDevEvo->gpus[sd].pDispEvo; 388 const NVFlipChannelEvoHwState *pOld = 389 &pDevEvo->gpus[sd].headState[head].layer[NVKMS_MAIN_LAYER]; 390 391 // Apply VRR swap interval overrides. 392 // 393 // Note that this applies the overrides whenever the client requests VRR and 394 // VRR is enabled, regardless of whether actually activating it later 395 // succeeds. 396 if (allowVrr) { 397 if (!nvHeadIsActive(pDispEvo, head)) { 398 // 399 // XXX If VRR is allowed then modeset should have happened before 400 // base channel flip, currently we don't know how to do modeset 401 // and program base channel for VRR at same time. This should be 402 // revisited as part of bug 1731279. 403 // 404 return FALSE; 405 } 406 nvApplyVrrBaseFlipOverrides(pDevEvo->gpus[sd].pDispEvo, head, 407 pOld, pNew); 408 } 409 410 if (!nvHeadIsActive(pDispEvo, head)) { 411 // 412 // This is possible when modeset and base flip happening at same time, 413 // tearing parameter does not make sense in that case, 414 // it should is disabled. 415 // 416 pNew->tearing = FALSE; 417 } else { 418 // Force non-tearing mode if EVO requires it. 419 if (FlipRequiresNonTearingMode(pDevEvo, head, pOld, pNew)) { 420 pNew->tearing = FALSE; 421 } 422 } 423 424 return TRUE; 425 } 426 427 static NvBool ValidateScalingUsageBounds( 428 const struct NvKmsScalingUsageBounds *pS, 429 const struct NvKmsScalingUsageBounds *pMaxS) 430 { 431 return (pS->maxVDownscaleFactor <= pMaxS->maxVDownscaleFactor) && 432 (pS->maxHDownscaleFactor <= pMaxS->maxHDownscaleFactor) && 433 (pS->vTaps <= pMaxS->vTaps) && 434 (!pS->vUpscalingAllowed || pMaxS->vUpscalingAllowed); 435 } 436 437 /*! 438 * Validate the requested usage bounds against the specified maximums. 439 */ 440 static NvBool ValidateUsageBounds( 441 const NVDevEvoRec *pDevEvo, 442 const NvU32 head, 443 const struct NvKmsUsageBounds *pUsage, 444 const struct NvKmsUsageBounds *pGuaranteedUsage) 445 { 446 NvU32 i; 447 448 for (i = 0; i < pDevEvo->head[head].numLayers; i++) { 449 const NvU64 supportedSurfaceFormatsUnion = 450 pUsage->layer[i].supportedSurfaceMemoryFormats | 451 pGuaranteedUsage->layer[i].supportedSurfaceMemoryFormats; 452 453 if ((pUsage->layer[i].usable && !pGuaranteedUsage->layer[i].usable) || 454 (supportedSurfaceFormatsUnion != 455 pGuaranteedUsage->layer[i].supportedSurfaceMemoryFormats) || 456 !ValidateScalingUsageBounds(&pUsage->layer[i].scaling, 457 &pGuaranteedUsage->layer[i].scaling)) { 458 return FALSE; 459 } 460 } 461 462 return TRUE; 463 } 464 465 /*! 466 * Assign pFlipState->usage. 467 */ 468 static NvBool AssignUsageBounds( 469 const NVDevEvoRec *pDevEvo, 470 const NvU32 head, 471 NVFlipEvoHwState *pFlipState) 472 { 473 struct NvKmsUsageBounds *pUsage = &pFlipState->usage; 474 int i; 475 476 for (i = 0; i < pDevEvo->head[head].numLayers; i++) { 477 const NVFlipChannelEvoHwState *pLayerFlipState = &pFlipState->layer[i]; 478 479 nvInitScalingUsageBounds(pDevEvo, &pUsage->layer[i].scaling); 480 481 if (pLayerFlipState->pSurfaceEvo[NVKMS_LEFT]) { 482 pUsage->layer[i].usable = TRUE; 483 pUsage->layer[i].supportedSurfaceMemoryFormats = 484 nvEvoGetFormatsWithEqualOrLowerUsageBound( 485 pLayerFlipState->pSurfaceEvo[NVKMS_LEFT]->format, 486 pDevEvo->caps.layerCaps[i].supportedSurfaceMemoryFormats); 487 488 if (pDevEvo->hal->GetWindowScalingCaps) { 489 const NVEvoScalerCaps *pScalerCaps = 490 pDevEvo->hal->GetWindowScalingCaps(pDevEvo); 491 492 if (!nvComputeScalingUsageBounds(pScalerCaps, 493 pLayerFlipState->sizeIn.width, 494 pLayerFlipState->sizeIn.height, 495 pLayerFlipState->sizeOut.width, 496 pLayerFlipState->sizeOut.height, 497 pLayerFlipState->hTaps, 498 pLayerFlipState->vTaps, 499 &pUsage->layer[i].scaling)) { 500 return FALSE; 501 } 502 } 503 504 if (pLayerFlipState->maxDownscaleFactors.specified) { 505 struct NvKmsScalingUsageBounds *pTargetScaling = 506 &pFlipState->usage.layer[i].scaling; 507 508 if ((pLayerFlipState->maxDownscaleFactors.vertical < 509 pTargetScaling->maxVDownscaleFactor) || 510 (pLayerFlipState->maxDownscaleFactors.horizontal < 511 pTargetScaling->maxHDownscaleFactor)) { 512 return FALSE; 513 } 514 515 pTargetScaling->maxVDownscaleFactor = 516 pLayerFlipState->maxDownscaleFactors.vertical; 517 pTargetScaling->maxHDownscaleFactor = 518 pLayerFlipState->maxDownscaleFactors.horizontal; 519 } 520 521 } else { 522 pUsage->layer[i].usable = FALSE; 523 pUsage->layer[i].supportedSurfaceMemoryFormats = 0; 524 } 525 } 526 527 return TRUE; 528 } 529 530 void 531 nvOverrideScalingUsageBounds(const NVDevEvoRec *pDevEvo, 532 NvU32 head, 533 NVFlipEvoHwState *pFlipState, 534 const struct NvKmsUsageBounds *pPossibleUsage) 535 { 536 NvU32 i; 537 538 for (i = 0; i < pDevEvo->head[head].numLayers; i++) { 539 const NVFlipChannelEvoHwState *pLayerFlipState = &pFlipState->layer[i]; 540 const struct NvKmsScalingUsageBounds *pPossibleScaling = 541 &pPossibleUsage->layer[i].scaling; 542 struct NvKmsScalingUsageBounds *pTargetScaling = 543 &pFlipState->usage.layer[i].scaling; 544 545 if (!pFlipState->usage.layer[i].usable) { 546 continue; 547 } 548 549 if (!pLayerFlipState->maxDownscaleFactors.specified) { 550 const NvU16 possibleV = pPossibleScaling->maxVDownscaleFactor; 551 const NvU16 possibleH = pPossibleScaling->maxHDownscaleFactor; 552 NvU16 targetV = pTargetScaling->maxVDownscaleFactor; 553 NvU16 targetH = pTargetScaling->maxHDownscaleFactor; 554 555 /* 556 * Calculate max H/V downscale factor by quantizing the range. 557 * 558 * E.g., 559 * max H/V downscale factor supported by HW is 4x for 5-tap and 2x 560 * for 2-tap mode. If 5-tap mode is required, the target usage bound 561 * that nvkms will attempt to program will either allow up to 2x 562 * downscaling, or up to 4x downscaling. If 2-tap mode is required, 563 * the target usage bound that NVKMS will attempt to program will 564 * allow up to 2x downscaling. Example: to downscale from 4096x2160 565 * -> 2731x864 in 5-tap mode, NVKMS would specify up to 2x for the 566 * H downscale bound (required is 1.5x), and up to 4x for the V 567 * downscale bound (required is 2.5x). 568 */ 569 if (targetV > NV_EVO_SCALE_FACTOR_1X) { 570 const NvU16 possibleMid = 571 NV_EVO_SCALE_FACTOR_1X + ((possibleV - NV_EVO_SCALE_FACTOR_1X) / 2); 572 573 if (targetV <= possibleMid) { 574 pTargetScaling->maxVDownscaleFactor = possibleMid; 575 } else { 576 pTargetScaling->maxVDownscaleFactor = possibleV; 577 } 578 } 579 580 if (targetH > NV_EVO_SCALE_FACTOR_1X) { 581 const NvU16 possibleMid = 582 NV_EVO_SCALE_FACTOR_1X + ((possibleH - NV_EVO_SCALE_FACTOR_1X) / 2); 583 584 if (targetH <= possibleMid) { 585 pTargetScaling->maxHDownscaleFactor = possibleMid; 586 } else { 587 pTargetScaling->maxHDownscaleFactor = possibleH; 588 } 589 } 590 } 591 592 pTargetScaling->vTaps = pPossibleScaling->vTaps; 593 pTargetScaling->vUpscalingAllowed = pPossibleScaling->vUpscalingAllowed; 594 } 595 } 596 597 static NvBool FlipTimeStampValidForChannel( 598 const NVEvoChannel *pChannel, 599 NvU64 timeStamp) 600 { 601 if (pChannel->caps.validTimeStampBits < 64) { 602 const NvU64 validTimeStampMask = 603 NVBIT64(pChannel->caps.validTimeStampBits) - 1; 604 if ((timeStamp & ~validTimeStampMask) != 0) { 605 return FALSE; 606 } 607 } 608 return TRUE; 609 } 610 611 static NvBool UpdateFlipEvoHwStateHDRStaticMetadata( 612 const NVDevEvoRec *pDevEvo, 613 const struct NvKmsFlipCommonParams *pParams, 614 NVFlipEvoHwState *pFlipState, 615 NVFlipChannelEvoHwState *pHwState, 616 const NvU32 head, 617 const NvU32 layer) 618 { 619 if (pParams->layer[layer].hdr.specified) { 620 if (pParams->layer[layer].hdr.enabled) { 621 // Don't allow enabling HDR on a layer that doesn't support it. 622 if (!pDevEvo->caps.layerCaps[layer].supportsHDR) { 623 return FALSE; 624 } 625 626 pHwState->hdrStaticMetadata.val = 627 pParams->layer[layer].hdr.staticMetadata; 628 } 629 pHwState->hdrStaticMetadata.enabled = pParams->layer[layer].hdr.enabled; 630 631 // Only mark dirty if layer supports HDR, otherwise this is a no-op. 632 if (pDevEvo->caps.layerCaps[layer].supportsHDR) { 633 pFlipState->dirty.hdrStaticMetadata = TRUE; 634 } 635 } 636 637 return TRUE; 638 } 639 640 static NvBool UpdateLayerFlipEvoHwStateCommon( 641 const struct NvKmsPerOpenDev *pOpenDev, 642 const NVDevEvoRec *pDevEvo, 643 const NvU32 sd, 644 const NvU32 head, 645 const NvU32 layer, 646 const struct NvKmsFlipCommonParams *pParams, 647 NVFlipEvoHwState *pFlipState) 648 { 649 const NVEvoChannel *pChannel = pDevEvo->head[head].layer[layer]; 650 NVFlipChannelEvoHwState *pHwState = &pFlipState->layer[layer]; 651 const NVEvoApiHandlesRec *pOpenDevSurfaceHandles = 652 nvGetSurfaceHandlesFromOpenDevConst(pOpenDev); 653 NvBool ret; 654 655 if (pParams->layer[layer].surface.specified) { 656 ret = nvAssignSurfaceArray(pDevEvo, 657 pOpenDevSurfaceHandles, 658 pParams->layer[layer].surface.handle, 659 FALSE /* isUsedByCursorChannel */, 660 TRUE /* isUsedByLayerChannel */, 661 pHwState->pSurfaceEvo); 662 if (!ret) { 663 return FALSE; 664 } 665 666 /* 667 * Verify the (rotation, reflectionX, reflectionY) is a 668 * combination currently supported. 669 */ 670 if ((NVBIT(NvKmsRRParamsToCapBit(&pParams->layer[layer].surface.rrParams)) & 671 pDevEvo->caps.validLayerRRTransforms) == 0) { 672 return FALSE; 673 } 674 pHwState->rrParams = pParams->layer[layer].surface.rrParams; 675 676 } 677 678 /* Verify the timestamp is in the valid range for this channel. */ 679 if (!FlipTimeStampValidForChannel(pChannel, 680 pParams->layer[layer].timeStamp)) { 681 return FALSE; 682 } 683 pHwState->timeStamp = pParams->layer[layer].timeStamp; 684 685 if (pParams->layer[layer].syncObjects.specified) { 686 if (!pDevEvo->supportsSyncpts && 687 pParams->layer[layer].syncObjects.val.useSyncpt) { 688 return FALSE; 689 } 690 691 nvkms_memset(&pFlipState->layer[layer].syncObject, 692 0, 693 sizeof(pFlipState->layer[layer].syncObject)); 694 695 if (pParams->layer[layer].syncObjects.val.useSyncpt) { 696 ret = AssignPreSyncptEvoHwState(pDevEvo, 697 &pParams->layer[layer].syncObjects.val, 698 &pHwState->syncObject); 699 if (!ret) { 700 return FALSE; 701 } 702 pFlipState->dirty.layerSyncObjects[layer] = TRUE; 703 704 ret = AssignPostSyncptEvoHwState(pDevEvo, 705 pDevEvo->head[head].layer[layer], 706 &pParams->layer[layer].syncObjects.val, 707 &pHwState->syncObject); 708 if (!ret) { 709 return FALSE; 710 } 711 } else { 712 if (pParams->layer[layer].syncObjects.val.u.semaphores.acquire.surface.surfaceHandle != 0 || 713 pParams->layer[layer].syncObjects.val.u.semaphores.release.surface.surfaceHandle != 0) { 714 if (pParams->layer[layer].skipPendingFlips) { 715 return FALSE; 716 } 717 } 718 719 ret = nvAssignSemaphoreEvoHwState(pDevEvo, 720 pOpenDevSurfaceHandles, 721 layer, 722 sd, 723 &pParams->layer[layer].syncObjects.val, 724 &pHwState->syncObject); 725 if (!ret) { 726 return FALSE; 727 } 728 } 729 } 730 731 if (pHwState->pSurfaceEvo[NVKMS_LEFT]) { 732 pHwState->minPresentInterval = 733 pParams->layer[layer].minPresentInterval; 734 } else { 735 /* The hardware requires that MPI be 0 when disabled. */ 736 pHwState->minPresentInterval = 0; 737 } 738 739 if (pParams->layer[layer].sizeIn.specified) { 740 pHwState->sizeIn = pParams->layer[layer].sizeIn.val; 741 } 742 743 if (pParams->layer[layer].sizeOut.specified) { 744 pHwState->sizeOut = pParams->layer[layer].sizeOut.val; 745 } 746 747 /* 748 * If supportsWindowMode = TRUE, the sizeIn/sizeOut dimensions can be 749 * any arbitrary (valid) values. 750 * 751 * If supportsWindowMode = FALSE (legacy EVO main layer), the sizeIn 752 * /sizeOut dimensions must match the size of the surface for that layer. 753 * 754 * Note that if sizeIn/Out dimensions are invalid i.e. with a width or 755 * height of zero, this will be rejected by a call to 756 * ValidateFlipChannelEvoHwState() later in the code path. 757 * 758 * Note that if scaling is unsupported, i.e. that sizeIn cannot differ 759 * from sizeOut, then any unsupported configurations will be caught by the 760 * ComputeWindowScalingTaps() call later on in this function. 761 */ 762 if (!pDevEvo->caps.layerCaps[layer].supportsWindowMode && 763 (pHwState->pSurfaceEvo[NVKMS_LEFT] != NULL)) { 764 const NVSurfaceEvoRec *pSurfaceEvo = 765 pHwState->pSurfaceEvo[NVKMS_LEFT]; 766 767 if ((pHwState->sizeIn.width != pSurfaceEvo->widthInPixels) || 768 (pHwState->sizeIn.height != pSurfaceEvo->heightInPixels)) { 769 return FALSE; 770 } 771 772 if ((pHwState->sizeOut.width != pSurfaceEvo->widthInPixels) || 773 (pHwState->sizeOut.height != pSurfaceEvo->heightInPixels)) { 774 return FALSE; 775 } 776 } 777 778 /* 779 * Allow the client to specify non-origin outputPosition only if the 780 * layer supports window mode. 781 * 782 * If window mode is unsupported but the client specifies non-origin 783 * outputPosition, return FALSE. 784 */ 785 if (pDevEvo->caps.layerCaps[layer].supportsWindowMode) { 786 if (pParams->layer[layer].outputPosition.specified) { 787 const NvS16 x = pParams->layer[layer].outputPosition.val.x; 788 const NvS16 y = pParams->layer[layer].outputPosition.val.y; 789 if ((pHwState->outputPosition.x != x) || 790 (pHwState->outputPosition.y != y)) { 791 pHwState->outputPosition.x = x; 792 pHwState->outputPosition.y = y; 793 pFlipState->dirty.layerPosition[layer] = TRUE; 794 } 795 } 796 } else if (pParams->layer[layer].outputPosition.specified && 797 ((pParams->layer[layer].outputPosition.val.x != 0) || 798 (pParams->layer[layer].outputPosition.val.y != 0))) { 799 return FALSE; 800 } 801 802 if (pParams->layer[layer].compositionParams.specified) { 803 pHwState->composition = 804 pParams->layer[layer].compositionParams.val; 805 } 806 807 if (!UpdateFlipEvoHwStateHDRStaticMetadata( 808 pDevEvo, pParams, pFlipState, 809 pHwState, head, layer)) { 810 return FALSE; 811 } 812 813 if (pParams->layer[layer].colorspace.specified) { 814 pHwState->colorspace = 815 pParams->layer[layer].colorspace.val; 816 } 817 818 if (pHwState->composition.depth == 0) { 819 pHwState->composition.depth = 820 NVKMS_MAX_LAYERS_PER_HEAD - layer; 821 } 822 823 /* XXX Move ValidatePerLayerCompParams() call to nvValidateFlipEvoHwState() */ 824 if (!nvValidatePerLayerCompParams( 825 &pHwState->composition, 826 &pDevEvo->caps.layerCaps[layer].composition, 827 pHwState->pSurfaceEvo[NVKMS_LEFT])) { 828 return FALSE; 829 } 830 831 if (!pDevEvo->hal->ComputeWindowScalingTaps(pDevEvo, 832 pChannel, 833 pHwState)) { 834 return FALSE; 835 } 836 837 if (pParams->layer[layer].completionNotifier.specified) { 838 ret = nvAssignCompletionNotifierEvoHwState( 839 pDevEvo, 840 pOpenDevSurfaceHandles, 841 &pParams->layer[layer].completionNotifier.val, 842 layer, 843 &pFlipState->layer[layer].completionNotifier); 844 if (!ret) { 845 return FALSE; 846 } 847 } 848 849 if (pParams->layer[layer].maxDownscaleFactors.specified) { 850 pFlipState->layer[layer].maxDownscaleFactors.vertical = 851 pParams->layer[layer].maxDownscaleFactors.vertical; 852 pFlipState->layer[layer].maxDownscaleFactors.horizontal = 853 pParams->layer[layer].maxDownscaleFactors.horizontal; 854 pFlipState->layer[layer].maxDownscaleFactors.specified = TRUE; 855 } else { 856 pFlipState->layer[layer].maxDownscaleFactors.vertical = 0; 857 pFlipState->layer[layer].maxDownscaleFactors.horizontal = 0; 858 pFlipState->layer[layer].maxDownscaleFactors.specified = FALSE; 859 } 860 861 pFlipState->dirty.layer[layer] = TRUE; 862 863 return TRUE; 864 } 865 866 static NvBool UpdateMainLayerFlipEvoHwState( 867 const struct NvKmsPerOpenDev *pOpenDev, 868 const NVDevEvoRec *pDevEvo, 869 const NvU32 sd, 870 const NvU32 head, 871 const struct NvKmsFlipCommonParams *pParams, 872 NVFlipEvoHwState *pFlipState, 873 NvBool allowVrr) 874 { 875 const NVEvoChannel *pChannel = 876 pDevEvo->head[head].layer[NVKMS_MAIN_LAYER]; 877 NVFlipChannelEvoHwState *pHwState = &pFlipState->layer[NVKMS_MAIN_LAYER]; 878 879 if (!nvIsLayerDirty(pParams, NVKMS_MAIN_LAYER)) { 880 return TRUE; 881 } 882 883 if (!UpdateLayerFlipEvoHwStateCommon(pOpenDev, pDevEvo, sd, head, 884 NVKMS_MAIN_LAYER, 885 pParams, pFlipState)) { 886 return FALSE; 887 } 888 889 if (pParams->layer[NVKMS_MAIN_LAYER].csc.specified) { 890 if (pParams->layer[NVKMS_MAIN_LAYER].csc.useMain) { 891 return FALSE; 892 } else { 893 pHwState->cscMatrix = pParams->layer[NVKMS_MAIN_LAYER].csc.matrix; 894 } 895 } 896 897 if (pParams->layer[NVKMS_MAIN_LAYER].surface.specified) { 898 if (pParams->layer[NVKMS_MAIN_LAYER].perEyeStereoFlip && 899 !pChannel->caps.perEyeStereoFlips) { 900 return FALSE; 901 } 902 903 pHwState->perEyeStereoFlip = 904 pParams->layer[NVKMS_MAIN_LAYER].perEyeStereoFlip; 905 } 906 907 if (pParams->layer[NVKMS_MAIN_LAYER].tearing && !pChannel->caps.tearingFlips) { 908 return FALSE; 909 } 910 911 // EVO will throw an invalid argument exception if 912 // minPresentInterval is too large, or if tearing is enabled and 913 // it's not zero. 914 if (pParams->layer[NVKMS_MAIN_LAYER].minPresentInterval > NV_MAX_SWAP_INTERVAL || 915 (pParams->layer[NVKMS_MAIN_LAYER].tearing && 916 pParams->layer[NVKMS_MAIN_LAYER].minPresentInterval != 0)) { 917 return FALSE; 918 } 919 920 pHwState->tearing = pParams->layer[NVKMS_MAIN_LAYER].tearing; 921 922 if (!ApplyBaseFlipOverrides(pDevEvo, 923 sd, head, &pFlipState->layer[NVKMS_MAIN_LAYER], 924 allowVrr)) { 925 return FALSE; 926 } 927 928 pFlipState->skipLayerPendingFlips[NVKMS_MAIN_LAYER] = 929 pParams->layer[NVKMS_MAIN_LAYER].skipPendingFlips; 930 931 return TRUE; 932 } 933 934 static NvBool UpdateCursorLayerFlipEvoHwState( 935 const struct NvKmsPerOpenDev *pOpenDev, 936 const NVDevEvoRec *pDevEvo, 937 const struct NvKmsFlipCommonParams *pParams, 938 const NVHwModeTimingsEvo *pTimings, 939 const NvU8 tilePosition, 940 NVFlipEvoHwState *pFlipState) 941 { 942 if (pParams->cursor.imageSpecified) { 943 if (!nvAssignCursorSurface(pOpenDev, pDevEvo, &pParams->cursor.image, 944 &pFlipState->cursor.pSurfaceEvo)) { 945 return FALSE; 946 } 947 948 if (pFlipState->cursor.pSurfaceEvo != NULL) { 949 pFlipState->cursor.cursorCompParams = 950 pParams->cursor.image.cursorCompParams; 951 } 952 953 pFlipState->dirty.cursorSurface = TRUE; 954 } 955 956 if (pParams->cursor.positionSpecified) { 957 pFlipState->cursor.x = (pParams->cursor.position.x - 958 (pTimings->viewPort.in.width * tilePosition)); 959 pFlipState->cursor.y = pParams->cursor.position.y; 960 961 pFlipState->dirty.cursorPosition = TRUE; 962 } 963 964 return TRUE; 965 } 966 967 static NvBool UpdateOverlayLayerFlipEvoHwState( 968 const struct NvKmsPerOpenDev *pOpenDev, 969 const NVDevEvoRec *pDevEvo, 970 const NvU32 sd, 971 const NvU32 head, 972 const NvU32 layer, 973 const struct NvKmsFlipCommonParams *pParams, 974 NVFlipEvoHwState *pFlipState) 975 { 976 NVFlipChannelEvoHwState *pHwState = &pFlipState->layer[layer]; 977 978 nvAssert(layer != NVKMS_MAIN_LAYER); 979 980 if (!nvIsLayerDirty(pParams, layer)) { 981 return TRUE; 982 } 983 984 if (pParams->layer[layer].skipPendingFlips || 985 pParams->layer[layer].perEyeStereoFlip) { 986 return FALSE; 987 } 988 989 if (!UpdateLayerFlipEvoHwStateCommon(pOpenDev, pDevEvo, sd, head, layer, 990 pParams, pFlipState)) { 991 return FALSE; 992 } 993 994 if (pParams->layer[layer].csc.specified) { 995 if (pParams->layer[layer].csc.useMain) { 996 if (pFlipState->layer[NVKMS_MAIN_LAYER].pSurfaceEvo[NVKMS_LEFT]) { 997 pHwState->cscMatrix = 998 pFlipState->layer[NVKMS_MAIN_LAYER].cscMatrix; 999 } 1000 } else { 1001 pHwState->cscMatrix = pParams->layer[layer].csc.matrix; 1002 } 1003 } 1004 1005 return TRUE; 1006 } 1007 1008 /*! 1009 * Update the NVFlipEvoHwState, using NvKmsFlipCommonParams. 1010 * 1011 * Propagate the requested configuration from NvKmsFlipCommonParams to 1012 * NVFlipEvoHwState, performing steps such as translating from 1013 * NvKmsSurfaceHandle to NVSurfaceEvoRecs. Validate the NvKmsFlipCommonParams 1014 * parameters, but defer more general validation of the resulting 1015 * NVFlipEvoHwState until nvValidateFlipEvoHwState(), which callers must call 1016 * separately. 1017 * 1018 * The NVFlipEvoHwState should first be initialized by calling 1019 * nvInitFlipEvoHwState(). 1020 * 1021 * No NVKMS hardware or software state should be altered here, because 1022 * this function is used before we have decided to commit the proposed 1023 * NVFlipEvoHwState to hardware. 1024 * 1025 * \param[in] pOpenDev The pOpenDev of the client doing the flip. 1026 * \param[in] pDevEvo The device on which the surface image will be set. 1027 * \param[in] sd The subdevice for the flip, as specified by the 1028 * client. 1029 * \param[in] head The head for the flip, as specified by the client. 1030 * \param[in] pParams The requested flip, NvKmsFlipCommonParams. 1031 * \param[in] pTimings The mode timings for the flip. 1032 * \param[in,out] pFlipState The resulting NVFlipEvoHwState. 1033 * \param[in] allowVrr Whether VRR flipping should be allowed. 1034 * \param[in] pPossibleUsage Possible usage. 1035 * 1036 * \return If pFlipState could be updated, return TRUE. 1037 * Otherwise, return FALSE. 1038 */ 1039 NvBool nvUpdateFlipEvoHwState( 1040 const struct NvKmsPerOpenDev *pOpenDev, 1041 const NVDevEvoRec *pDevEvo, 1042 const NvU32 sd, 1043 const NvU32 head, 1044 const struct NvKmsFlipCommonParams *pParams, 1045 const NVHwModeTimingsEvo *pTimings, 1046 const NvU8 tilePosition, 1047 NVFlipEvoHwState *pFlipState, 1048 NvBool allowVrr) 1049 { 1050 NvU32 layer; 1051 1052 if (pParams->viewPortIn.specified) { 1053 pFlipState->dirty.viewPortPointIn = TRUE; 1054 pFlipState->viewPortPointIn.x = pParams->viewPortIn.point.x + 1055 (pTimings->viewPort.in.width * tilePosition); 1056 pFlipState->viewPortPointIn.y = pParams->viewPortIn.point.y; 1057 } 1058 1059 if (!UpdateCursorLayerFlipEvoHwState(pOpenDev, pDevEvo, pParams, pTimings, 1060 tilePosition, pFlipState)) { 1061 return FALSE; 1062 } 1063 1064 if (pParams->tf.specified) { 1065 pFlipState->dirty.tf = TRUE; 1066 pFlipState->tf = pParams->tf.val; 1067 } 1068 1069 for (layer = 0; layer < pDevEvo->head[head].numLayers; layer++) { 1070 if (layer == NVKMS_MAIN_LAYER) { 1071 if (!UpdateMainLayerFlipEvoHwState(pOpenDev, pDevEvo, sd, head, 1072 pParams, pFlipState, allowVrr)) { 1073 return FALSE; 1074 } 1075 continue; 1076 } 1077 1078 if (!UpdateOverlayLayerFlipEvoHwState(pOpenDev, pDevEvo, sd, head, 1079 layer, pParams, pFlipState)) { 1080 return FALSE; 1081 } 1082 } 1083 1084 if (!AssignUsageBounds(pDevEvo, head, pFlipState)) { 1085 return FALSE; 1086 } 1087 1088 /* 1089 * If there is active cursor/cropped-window(overlay) without full screen 1090 * window(base/core) then NVKMS is supposed to disable MidFrame/DWCF 1091 * watermark. 1092 */ 1093 1094 pFlipState->disableMidFrameAndDWCFWatermark = FALSE; 1095 1096 if (NV5070_CTRL_SYSTEM_GET_CAP( 1097 pDevEvo->capsBits, 1098 NV5070_CTRL_SYSTEM_CAPS_BUG_2052012_GLITCHY_MCLK_SWITCH) && 1099 !pFlipState->layer[NVKMS_MAIN_LAYER].pSurfaceEvo[NVKMS_LEFT]) { 1100 1101 if (pFlipState->cursor.pSurfaceEvo != NULL) { 1102 pFlipState->disableMidFrameAndDWCFWatermark = TRUE; 1103 } else { 1104 NvU32 layer; 1105 1106 /* 1107 * XXX TODO: Check the output size of the overlay in order 1108 * to determine if it will be fullscreen or not. 1109 */ 1110 for (layer = 0; layer < pDevEvo->head[head].numLayers; layer++) { 1111 if (layer != NVKMS_MAIN_LAYER && 1112 pFlipState->layer[layer].pSurfaceEvo[NVKMS_LEFT] != NULL) { 1113 pFlipState->disableMidFrameAndDWCFWatermark = TRUE; 1114 break; 1115 } 1116 } 1117 } 1118 } 1119 1120 return TRUE; 1121 } 1122 1123 /* 1124 * Checks that if the surface is NULL (i.e. no image will be shown), various 1125 * other elements must be NULL as well. If the surface is not NULL, verifies 1126 * that the sizeIn/Out have nonzero values. 1127 */ 1128 inline static NvBool ValidateFlipChannelEvoHwState( 1129 const NVFlipChannelEvoHwState *pState) 1130 { 1131 if (pState->pSurfaceEvo[NVKMS_LEFT] != NULL) { 1132 /* Verify sizes are valid. */ 1133 if ((pState->sizeIn.width == 0) || (pState->sizeIn.height == 0) || 1134 (pState->sizeOut.width == 0) || (pState->sizeOut.height == 0)) { 1135 return FALSE; 1136 } 1137 1138 return TRUE; 1139 } 1140 1141 if (pState->completionNotifier.surface.pSurfaceEvo != NULL) { 1142 return FALSE; 1143 } 1144 1145 if (!pState->syncObject.usingSyncpt) { 1146 if (pState->syncObject.u.semaphores.acquireSurface.pSurfaceEvo != NULL) { 1147 return FALSE; 1148 } 1149 1150 if (pState->syncObject.u.semaphores.releaseSurface.pSurfaceEvo != NULL) { 1151 return FALSE; 1152 } 1153 } 1154 1155 return TRUE; 1156 } 1157 1158 static NvBool ValidateSurfaceSize( 1159 const NVDevEvoRec *pDevEvo, 1160 const NVSurfaceEvoRec *pSurfaceEvo, 1161 const struct NvKmsRect *sourceFetchRect) 1162 { 1163 NvU8 planeIndex; 1164 1165 if ((pSurfaceEvo->widthInPixels > pDevEvo->caps.maxWidthInPixels) || 1166 (pSurfaceEvo->heightInPixels > pDevEvo->caps.maxHeight)) { 1167 return FALSE; 1168 } 1169 1170 FOR_ALL_VALID_PLANES(planeIndex, pSurfaceEvo) { 1171 1172 NvU64 planePitch = pSurfaceEvo->planes[planeIndex].pitch; 1173 1174 /* 1175 * Convert planePitch to units of bytes if it's currently specified in 1176 * units of blocks. Each block is 64-bytes wide. 1177 */ 1178 if (pSurfaceEvo->layout == NvKmsSurfaceMemoryLayoutBlockLinear) { 1179 planePitch <<= NVKMS_BLOCK_LINEAR_LOG_GOB_WIDTH; 1180 } 1181 1182 if (planePitch > pDevEvo->caps.maxWidthInBytes) { 1183 return FALSE; 1184 } 1185 } 1186 1187 if (!pDevEvo->hal->ValidateWindowFormat(pSurfaceEvo->format, 1188 sourceFetchRect, 1189 NULL)) { 1190 return FALSE; 1191 } 1192 1193 return TRUE; 1194 } 1195 1196 static NvBool 1197 ValidateMainFlipChannelEvoHwState(const NVDevEvoRec *pDevEvo, 1198 const NVFlipChannelEvoHwState *pHwState, 1199 const NVHwModeTimingsEvo *pTimings, 1200 struct NvKmsPoint viewPortPointIn) 1201 { 1202 NvU32 eye; 1203 const NVSurfaceEvoRec *pFirstSurfaceEvo = NULL; 1204 1205 /* 1206 * This struct represents the source fetch rectangle for a given surface, 1207 * and will be populated later as such. This function doesn't explicitly set 1208 * sourceFetchRect.{x,y} because NVKMS currently doesn't support programming 1209 * source fetch offsets, so the init value of 0 should be fine for both of 1210 * these fields. 1211 */ 1212 struct NvKmsRect sourceFetchRect = {0}; 1213 1214 if (!ValidateFlipChannelEvoHwState(pHwState)) { 1215 return FALSE; 1216 } 1217 1218 for (eye = 0; eye < NVKMS_MAX_EYES; eye++) { 1219 const NVSurfaceEvoRec *pSurfaceEvo = pHwState->pSurfaceEvo[eye]; 1220 1221 if (pSurfaceEvo == NULL) { 1222 continue; 1223 } 1224 1225 if (pFirstSurfaceEvo == NULL) { 1226 pFirstSurfaceEvo = pSurfaceEvo; 1227 } else if (pSurfaceEvo->widthInPixels != 1228 pFirstSurfaceEvo->widthInPixels || 1229 pSurfaceEvo->heightInPixels != 1230 pFirstSurfaceEvo->heightInPixels) { 1231 return FALSE; 1232 } 1233 1234 sourceFetchRect.width = pHwState->sizeIn.width; 1235 sourceFetchRect.height = pHwState->sizeIn.height; 1236 1237 if (!ValidateSurfaceSize(pDevEvo, pSurfaceEvo, &sourceFetchRect)) { 1238 return FALSE; 1239 } 1240 1241 /* The use of A_plus_B_greater_than_C_U16 is only valid if these 1242 * fit in a U16 */ 1243 nvAssert(pSurfaceEvo->widthInPixels <= NV_U16_MAX); 1244 nvAssert(pSurfaceEvo->heightInPixels <= NV_U16_MAX); 1245 /* And the checks above in ValidateSurfaceSize should have 1246 * guaranteed that. */ 1247 nvAssert(pDevEvo->caps.maxWidthInPixels <= NV_U16_MAX); 1248 nvAssert(pDevEvo->caps.maxHeight <= NV_U16_MAX); 1249 1250 /* 1251 * Validate that the requested viewport parameters fit within the 1252 * specified surface, unless the main layer is allowed to be smaller 1253 * than the viewport. 1254 */ 1255 if (!pDevEvo->caps.layerCaps[NVKMS_MAIN_LAYER].supportsWindowMode) { 1256 if (A_plus_B_greater_than_C_U16(viewPortPointIn.x, 1257 pTimings->viewPort.in.width, 1258 pSurfaceEvo->widthInPixels)) { 1259 return FALSE; 1260 } 1261 1262 if (A_plus_B_greater_than_C_U16(viewPortPointIn.y, 1263 pTimings->viewPort.in.height, 1264 pSurfaceEvo->heightInPixels)) { 1265 return FALSE; 1266 } 1267 } 1268 } 1269 1270 return TRUE; 1271 } 1272 1273 static NvBool 1274 ValidateOverlayFlipChannelEvoHwState(const NVDevEvoRec *pDevEvo, 1275 const NVFlipChannelEvoHwState *pHwState) 1276 { 1277 const NVSurfaceEvoRec *pSurfaceEvo = pHwState->pSurfaceEvo[NVKMS_LEFT]; 1278 1279 /* 1280 * This struct represents the source fetch rectangle for a given surface, 1281 * and will be populated later as such. This function doesn't explicitly set 1282 * sourceFetchRect.{x,y} because NVKMS currently doesn't support programming 1283 * source fetch offsets, so the init value of 0 should be fine for both of 1284 * these fields. 1285 */ 1286 struct NvKmsRect sourceFetchRect = {0}; 1287 1288 if (!ValidateFlipChannelEvoHwState(pHwState)) { 1289 return FALSE; 1290 } 1291 1292 if (pSurfaceEvo == NULL) { 1293 return TRUE; 1294 } 1295 1296 sourceFetchRect.width = pHwState->sizeIn.width; 1297 sourceFetchRect.height = pHwState->sizeIn.height; 1298 1299 if (!ValidateSurfaceSize(pDevEvo, pSurfaceEvo, &sourceFetchRect)) { 1300 return FALSE; 1301 } 1302 1303 /* Validate input size against surface size. */ 1304 if (pHwState->sizeIn.width > pSurfaceEvo->widthInPixels || 1305 pHwState->sizeIn.height > pSurfaceEvo->heightInPixels) { 1306 return FALSE; 1307 } 1308 1309 return TRUE; 1310 } 1311 1312 static NvBool 1313 ValidateHDR(const NVDevEvoRec *pDevEvo, 1314 const NvU32 head, 1315 const NVFlipEvoHwState *pFlipState) 1316 { 1317 NvU32 staticMetadataCount = 0; 1318 NvU32 layerSupportedCount = 0; 1319 1320 NvU32 layer; 1321 1322 for (layer = 0; layer < pDevEvo->head[head].numLayers; layer++) { 1323 if (pDevEvo->caps.layerCaps[layer].supportsHDR) { 1324 layerSupportedCount++; 1325 } 1326 1327 if (pFlipState->layer[layer].hdrStaticMetadata.enabled) { 1328 staticMetadataCount++; 1329 1330 /* 1331 * If HDR static metadata is enabled, we may need TMO. CSC11 will be 1332 * used by NVKMS to convert from linear FP16 LMS to linear FP16 RGB. 1333 * As such, the user-supplied precomp CSC can't be programmed into 1334 * CSC11 in this case. 1335 */ 1336 if (!nvIsCscMatrixIdentity(&pFlipState->layer[layer].cscMatrix)) { 1337 return FALSE; 1338 } 1339 1340 // Already checked in UpdateFlipEvoHwStateHDRStaticMetadata() 1341 nvAssert(pDevEvo->caps.layerCaps[layer].supportsHDR); 1342 } 1343 } 1344 1345 // If enabling HDR... 1346 // XXX HDR TODO: Handle other transfer functions 1347 if (pFlipState->tf == NVKMS_OUTPUT_TF_PQ) { 1348 // At least one layer must have static metadata. 1349 if (staticMetadataCount == 0) { 1350 return FALSE; 1351 } 1352 1353 // At least one layer must support HDR, implied above. 1354 nvAssert(layerSupportedCount != 0); 1355 } 1356 1357 // Only one layer can specify HDR static metadata. 1358 // XXX HDR TODO: Support multiple layers with HDR static metadata 1359 if (staticMetadataCount > 1) { 1360 return FALSE; 1361 } 1362 1363 return TRUE; 1364 } 1365 1366 static NvBool 1367 ValidateColorspace(const NVDevEvoRec *pDevEvo, 1368 const NvU32 head, 1369 const NVFlipEvoHwState *pFlipState) 1370 { 1371 NvU32 layer; 1372 1373 for (layer = 0; layer < pDevEvo->head[head].numLayers; layer++) { 1374 if ((pFlipState->layer[layer].colorspace != 1375 NVKMS_INPUT_COLORSPACE_NONE)) { 1376 1377 NVSurfaceEvoPtr pSurfaceEvo = 1378 pFlipState->layer[layer].pSurfaceEvo[NVKMS_LEFT]; 1379 const NvKmsSurfaceMemoryFormatInfo *pFormatInfo = 1380 (pSurfaceEvo != NULL) ? 1381 nvKmsGetSurfaceMemoryFormatInfo(pSurfaceEvo->format) : NULL; 1382 1383 // XXX HDR TODO: Support YUV. 1384 if ((pFormatInfo == NULL) || pFormatInfo->isYUV) { 1385 return FALSE; 1386 } 1387 1388 // FP16 is only for use with scRGB. 1389 if ((pFlipState->layer[layer].colorspace != 1390 NVKMS_INPUT_COLORSPACE_SCRGB_LINEAR) && 1391 ((pSurfaceEvo->format == 1392 NvKmsSurfaceMemoryFormatRF16GF16BF16AF16) || 1393 (pSurfaceEvo->format == 1394 NvKmsSurfaceMemoryFormatRF16GF16BF16XF16))) { 1395 return FALSE; 1396 } 1397 1398 // scRGB is only compatible with FP16. 1399 if ((pFlipState->layer[layer].colorspace == 1400 NVKMS_INPUT_COLORSPACE_SCRGB_LINEAR) && 1401 !((pSurfaceEvo->format == 1402 NvKmsSurfaceMemoryFormatRF16GF16BF16AF16) || 1403 (pSurfaceEvo->format == 1404 NvKmsSurfaceMemoryFormatRF16GF16BF16XF16))) { 1405 return FALSE; 1406 } 1407 } 1408 } 1409 1410 return TRUE; 1411 } 1412 1413 static NvU32 ValidateCompositionDepth(const NVFlipEvoHwState *pFlipState, 1414 const NvU32 layer) 1415 { 1416 NvU32 tmpLayer; 1417 1418 if (pFlipState->layer[layer].pSurfaceEvo[NVKMS_LEFT] == NULL) { 1419 return TRUE; 1420 } 1421 1422 /* Depth should be different for each of the layers owned by the head */ 1423 for (tmpLayer = 0; tmpLayer < ARRAY_LEN(pFlipState->layer); tmpLayer++) { 1424 if (pFlipState->layer[tmpLayer].pSurfaceEvo[NVKMS_LEFT] == NULL) { 1425 continue; 1426 } 1427 1428 if ((tmpLayer != layer) && 1429 (pFlipState->layer[tmpLayer].composition.depth == 1430 pFlipState->layer[layer].composition.depth)) { 1431 return FALSE; 1432 } 1433 } 1434 1435 /* Depth of the main layer should be the greatest one */ 1436 if (pFlipState->layer[NVKMS_MAIN_LAYER].pSurfaceEvo[NVKMS_LEFT] != NULL) { 1437 if (pFlipState->layer[NVKMS_MAIN_LAYER].composition.depth < 1438 pFlipState->layer[layer].composition.depth) { 1439 return FALSE; 1440 } 1441 } 1442 1443 return TRUE; 1444 } 1445 1446 /*! 1447 * Perform validation of the the given NVFlipEvoHwState. 1448 */ 1449 NvBool nvValidateFlipEvoHwState( 1450 const NVDevEvoRec *pDevEvo, 1451 const NvU32 head, 1452 const NVHwModeTimingsEvo *pTimings, 1453 const NVFlipEvoHwState *pFlipState) 1454 { 1455 NvU32 layer; 1456 1457 for (layer = 0; layer < pDevEvo->head[head].numLayers; layer++) { 1458 if (!ValidateCompositionDepth(pFlipState, layer)) { 1459 return FALSE; 1460 } 1461 1462 if (layer == NVKMS_MAIN_LAYER) { 1463 if (!ValidateMainFlipChannelEvoHwState(pDevEvo, 1464 &pFlipState->layer[layer], 1465 pTimings, 1466 pFlipState->viewPortPointIn)) { 1467 return FALSE; 1468 } 1469 } else { 1470 const NVFlipChannelEvoHwState *pMainLayerState = 1471 &pFlipState->layer[NVKMS_MAIN_LAYER]; 1472 1473 /* 1474 * No overlay layer should be enabled if the main 1475 * layer is disabled. 1476 */ 1477 if ((pMainLayerState->pSurfaceEvo[NVKMS_LEFT] == NULL) && 1478 (pFlipState->layer[layer].pSurfaceEvo[NVKMS_LEFT] != NULL)) { 1479 return FALSE; 1480 } 1481 1482 if (!pFlipState->dirty.layer[layer]) { 1483 continue; 1484 } 1485 1486 if (!ValidateOverlayFlipChannelEvoHwState(pDevEvo, 1487 &pFlipState->layer[layer])) { 1488 return FALSE; 1489 } 1490 } 1491 } 1492 1493 if (!ValidateHDR(pDevEvo, head, pFlipState)) { 1494 return FALSE; 1495 } 1496 1497 if (!ValidateColorspace(pDevEvo, head, pFlipState)) { 1498 return FALSE; 1499 } 1500 1501 /* XXX NVKMS TODO: validate cursor x,y against current viewport in? */ 1502 1503 return ValidateUsageBounds(pDevEvo, 1504 head, 1505 &pFlipState->usage, 1506 &pTimings->viewPort.possibleUsage); 1507 } 1508 1509 /* 1510 * Record in the updateState that the given channel needs interlocked 1511 * window immediate updates. 1512 */ 1513 static void UpdateWinImmInterlockState(NVDevEvoPtr pDevEvo, 1514 NVEvoUpdateState *updateState, 1515 const NVEvoChannel *pChannel) 1516 { 1517 const NvU32 subDevMask = nvPeekEvoSubDevMask(pDevEvo); 1518 NvU32 sd; 1519 1520 for (sd = 0; sd < pDevEvo->numSubDevices; sd++) { 1521 if (subDevMask & (1 << sd)) { 1522 updateState->subdev[sd].winImmInterlockMask |= 1523 pChannel->channelMask; 1524 } 1525 } 1526 } 1527 1528 /*! 1529 * Record in the updateState that the given channel's method are eligible for 1530 * flip locking. 1531 */ 1532 static void UpdateUpdateFlipLockState(NVDevEvoPtr pDevEvo, 1533 NVEvoUpdateState *updateState, 1534 const NVEvoChannel *pChannel) 1535 { 1536 const NvU32 subDevMask = nvPeekEvoSubDevMask(pDevEvo); 1537 NvU32 sd; 1538 1539 for (sd = 0; sd < pDevEvo->numSubDevices; sd++) { 1540 if (subDevMask & (1 << sd)) { 1541 updateState->subdev[sd].flipLockQualifyingMask |= 1542 pChannel->channelMask; 1543 } 1544 } 1545 } 1546 1547 // Adjust from EDID-encoded maxCLL/maxFALL to actual values in units of 1 cd/m2 1548 static inline NvU32 MaxCvToVal(NvU32 cv) 1549 { 1550 // 50*2^(cv/32) 1551 return f64_to_ui32( 1552 f64_mul(ui32_to_f64(50), 1553 nvKmsPow(ui32_to_f64(2), 1554 f64_div(ui32_to_f64(cv), 1555 ui32_to_f64(32)))), softfloat_round_near_even, FALSE); 1556 } 1557 1558 // Adjust from EDID-encoded minCLL to actual value in units of 0.0001 cd/m2 1559 static inline NvU32 MinCvToVal(NvU32 cv, NvU32 maxCLL) 1560 { 1561 // 10,000 * (minCLL = (maxCLL * ((cv/255)^2 / 100))) 1562 return f64_to_ui32( 1563 f64_mul(ui32_to_f64(10000), 1564 f64_mul(ui32_to_f64(maxCLL), 1565 f64_div(nvKmsPow(f64_div(ui32_to_f64(cv), 1566 ui32_to_f64(255)), 1567 ui32_to_f64(2)), 1568 ui32_to_f64(100)))), 1569 softfloat_round_near_even, FALSE); 1570 } 1571 1572 static void UpdateHDR(NVDevEvoPtr pDevEvo, 1573 const NVFlipEvoHwState *pFlipState, 1574 const NvU32 sd, 1575 const NvU32 head, 1576 const NVT_HDR_STATIC_METADATA *pHdrInfo, 1577 NVEvoUpdateState *updateState) 1578 { 1579 NVDispEvoPtr pDispEvo = pDevEvo->gpus[sd].pDispEvo; 1580 NVDispHeadStateEvoRec *pHeadState = &pDispEvo->headState[head]; 1581 NvBool dirty = FALSE; 1582 1583 if (pFlipState->dirty.tf) { 1584 // XXX HDR TODO: Handle other transfer functions 1585 if (pFlipState->tf == NVKMS_OUTPUT_TF_PQ) { 1586 pHeadState->hdr.outputState = NVKMS_HDR_OUTPUT_STATE_HDR; 1587 } else if (pHeadState->hdr.outputState == NVKMS_HDR_OUTPUT_STATE_HDR) { 1588 pHeadState->hdr.outputState = 1589 NVKMS_HDR_OUTPUT_STATE_TRANSITIONING_TO_SDR; 1590 } 1591 pHeadState->tf = pFlipState->tf; 1592 1593 dirty = TRUE; 1594 } 1595 1596 if (pFlipState->dirty.hdrStaticMetadata) { 1597 NvU32 layer; 1598 NvBool found = FALSE; 1599 for (layer = 0; layer < pDevEvo->head[head].numLayers; layer++) { 1600 // Populate head with updated static metadata. 1601 if (pFlipState->layer[layer].hdrStaticMetadata.enabled) { 1602 NvU32 targetMaxCLL = MaxCvToVal(pHdrInfo->max_cll); 1603 1604 // Send this layer's metadata to the display. 1605 pHeadState->hdr.staticMetadata = 1606 pFlipState->layer[layer].hdrStaticMetadata.val; 1607 1608 /* 1609 * Prepare for tone mapping. If we expect to tone map and the 1610 * EDID has valid lum values, mirror EDID lum values to prevent 1611 * redundant tone mapping by the display. We will tone map to 1612 * the specified maxCLL. 1613 */ 1614 if (nvNeedsTmoLut(pDevEvo, pDevEvo->head[head].layer[layer], 1615 &pFlipState->layer[layer], 1616 nvGetHDRSrcMaxLum( 1617 &pFlipState->layer[layer]), 1618 targetMaxCLL)) { 1619 NvU32 targetMaxFALL = MaxCvToVal(pHdrInfo->max_fall); 1620 if ((targetMaxCLL > 0) && 1621 (targetMaxCLL <= 10000) && 1622 (targetMaxCLL >= targetMaxFALL)) { 1623 1624 NvU32 targetMinCLL = MinCvToVal(pHdrInfo->min_cll, 1625 targetMaxCLL); 1626 1627 pHeadState->hdr.staticMetadata. 1628 maxDisplayMasteringLuminance = targetMaxCLL; 1629 pHeadState->hdr.staticMetadata. 1630 minDisplayMasteringLuminance = targetMinCLL; 1631 pHeadState->hdr.staticMetadata.maxCLL = targetMaxCLL; 1632 pHeadState->hdr.staticMetadata.maxFALL = targetMaxFALL; 1633 } 1634 } 1635 1636 /* 1637 * Only one layer can currently specify static metadata, 1638 * verified by ValidateHDR(). 1639 * 1640 * XXX HDR TODO: Combine metadata from multiple layers. 1641 */ 1642 nvAssert(!found); 1643 found = TRUE; 1644 } 1645 } 1646 if (!found) { 1647 nvkms_memset(&pHeadState->hdr.staticMetadata, 0, 1648 sizeof(struct NvKmsHDRStaticMetadata)); 1649 } 1650 1651 dirty = TRUE; 1652 } 1653 1654 if (dirty) { 1655 // Update OCSC / OLUT 1656 nvEvoSetLUTContextDma(pDispEvo, head, updateState); 1657 } 1658 } 1659 1660 /*! 1661 * Program a flip on all requested layers on the specified head. 1662 * 1663 * This also updates pDispEvo->headState[head], caching what was programmed. 1664 1665 * \param[in,out] pDispEvo The disp on which the flip should be performed. 1666 * \param[in] head The head on which the flip should be performed. 1667 * \param[in] pFlipState The description of how to update each layer. 1668 * \param[in,out] updateState Indicates which channels require UPDATEs 1669 */ 1670 void nvFlipEvoOneHead( 1671 NVDevEvoPtr pDevEvo, 1672 const NvU32 sd, 1673 const NvU32 head, 1674 const NVT_HDR_STATIC_METADATA *pHdrInfo, 1675 const NVFlipEvoHwState *pFlipState, 1676 NvBool allowFlipLock, 1677 NVEvoUpdateState *updateState) 1678 { 1679 const NvU32 subDeviceMask = NVBIT(sd); 1680 const NVDispHeadStateEvoRec *pHeadState = 1681 &pDevEvo->gpus[sd].pDispEvo->headState[head]; 1682 NvBool bypassComposition = pHeadState->bypassComposition; 1683 NVEvoSubDevHeadStateRec *pSdHeadState = 1684 &pDevEvo->gpus[sd].headState[head]; 1685 NvU32 layer; 1686 1687 /* 1688 * Provide the pre-update hardware state (in pSdHeadState) and the new 1689 * target state (pFlipState) to the HAL implementation so that it has the 1690 * information it needs to implement the workaround for hardware bug 1691 * 2193096, which requires special logic on transitions between NULL and 1692 * non-NULL ctxdmas (and vice versa). 1693 */ 1694 pDevEvo->hal->FlipTransitionWAR(pDevEvo, sd, head, 1695 pSdHeadState, pFlipState, 1696 updateState); 1697 1698 /* 1699 * Promote the software state first, such that the hardware programming 1700 * paths below see the new state atomically. 1701 */ 1702 if (pFlipState->dirty.viewPortPointIn) { 1703 pSdHeadState->viewPortPointIn = pFlipState->viewPortPointIn; 1704 } 1705 1706 if (pFlipState->dirty.cursorSurface || pFlipState->dirty.cursorPosition) { 1707 pSdHeadState->cursor = pFlipState->cursor; 1708 } 1709 1710 for (layer = 0; layer < pDevEvo->head[head].numLayers; layer++) { 1711 if (pFlipState->dirty.layer[layer]) { 1712 pSdHeadState->layer[layer] = pFlipState->layer[layer]; 1713 } 1714 } 1715 1716 if (pFlipState->dirty.viewPortPointIn) { 1717 nvSetViewPortPointInEvo(pDevEvo->gpus[sd].pDispEvo, 1718 head, 1719 pFlipState->viewPortPointIn.x, 1720 pFlipState->viewPortPointIn.y, 1721 updateState); 1722 } 1723 1724 if (pFlipState->dirty.cursorSurface) { 1725 nvPushEvoSubDevMask(pDevEvo, NVBIT(sd)); 1726 pDevEvo->hal->SetCursorImage(pDevEvo, 1727 head, 1728 pSdHeadState->cursor.pSurfaceEvo, 1729 updateState, 1730 &pSdHeadState->cursor.cursorCompParams); 1731 nvPopEvoSubDevMask(pDevEvo); 1732 } 1733 1734 if (pFlipState->dirty.cursorPosition) { 1735 nvEvoMoveCursorInternal(pDevEvo->gpus[sd].pDispEvo, 1736 head, 1737 pFlipState->cursor.x, 1738 pFlipState->cursor.y); 1739 } 1740 1741 UpdateHDR(pDevEvo, pFlipState, sd, head, pHdrInfo, updateState); 1742 1743 for (layer = 0; layer < pDevEvo->head[head].numLayers; layer++) { 1744 if (!pFlipState->dirty.layer[layer]) { 1745 continue; 1746 } 1747 1748 if (pFlipState->dirty.layerPosition[layer]) { 1749 /* Ensure position updates are supported on this layer. */ 1750 nvAssert(pDevEvo->caps.layerCaps[layer].supportsWindowMode); 1751 1752 pDevEvo->hal->SetImmPointOut(pDevEvo, 1753 pDevEvo->head[head].layer[layer], 1754 sd, 1755 updateState, 1756 pFlipState->layer[layer].outputPosition.x, 1757 pFlipState->layer[layer].outputPosition.y); 1758 1759 if (pDevEvo->hal->caps.supportsSynchronizedOverlayPositionUpdate) { 1760 UpdateWinImmInterlockState(pDevEvo, updateState, 1761 pDevEvo->head[head].layer[layer]); 1762 } 1763 } 1764 1765 nvPushEvoSubDevMask(pDevEvo, subDeviceMask); 1766 1767 /* Inform DIFR about the upcoming flip. */ 1768 if (pDevEvo->pDifrState) { 1769 nvDIFRNotifyFlip(pDevEvo->pDifrState); 1770 } 1771 1772 pDevEvo->hal->Flip(pDevEvo, 1773 pDevEvo->head[head].layer[layer], 1774 &pFlipState->layer[layer], 1775 updateState, 1776 bypassComposition); 1777 if (layer == NVKMS_MAIN_LAYER && allowFlipLock) { 1778 UpdateUpdateFlipLockState(pDevEvo, updateState, 1779 pDevEvo->head[head].layer[layer]); 1780 } 1781 nvPopEvoSubDevMask(pDevEvo); 1782 } 1783 1784 pSdHeadState->targetUsage = pFlipState->usage; 1785 1786 pSdHeadState->targetDisableMidFrameAndDWCFWatermark = 1787 pFlipState->disableMidFrameAndDWCFWatermark; 1788 } 1789 1790 static void ChangeSurfaceFlipRefCount( 1791 NVDevEvoPtr pDevEvo, 1792 NVSurfaceEvoPtr pSurfaceEvo, 1793 NvBool increase) 1794 { 1795 if (pSurfaceEvo != NULL) { 1796 if (increase) { 1797 nvEvoIncrementSurfaceRefCnts(pSurfaceEvo); 1798 } else { 1799 nvEvoDecrementSurfaceRefCnts(pSurfaceEvo); 1800 } 1801 } 1802 } 1803 1804 void nvUpdateSurfacesFlipRefCount( 1805 NVDevEvoPtr pDevEvo, 1806 const NvU32 head, 1807 NVFlipEvoHwState *pFlipState, 1808 NvBool increase) 1809 { 1810 NvU32 i; 1811 1812 ChangeSurfaceFlipRefCount( 1813 pDevEvo, 1814 pFlipState->cursor.pSurfaceEvo, 1815 increase); 1816 1817 for (i = 0; i < pDevEvo->head[head].numLayers; i++) { 1818 NVFlipChannelEvoHwState *pLayerFlipState = &pFlipState->layer[i]; 1819 1820 ChangeSurfaceFlipRefCount( 1821 pDevEvo, 1822 pLayerFlipState->pSurfaceEvo[NVKMS_LEFT], 1823 increase); 1824 ChangeSurfaceFlipRefCount( 1825 pDevEvo, 1826 pLayerFlipState->pSurfaceEvo[NVKMS_RIGHT], 1827 increase); 1828 ChangeSurfaceFlipRefCount( 1829 pDevEvo, 1830 pLayerFlipState->completionNotifier.surface.pSurfaceEvo, 1831 increase); 1832 1833 if (!pLayerFlipState->syncObject.usingSyncpt) { 1834 ChangeSurfaceFlipRefCount( 1835 pDevEvo, 1836 pLayerFlipState->syncObject.u.semaphores.acquireSurface.pSurfaceEvo, 1837 increase); 1838 ChangeSurfaceFlipRefCount( 1839 pDevEvo, 1840 pLayerFlipState->syncObject.u.semaphores.releaseSurface.pSurfaceEvo, 1841 increase); 1842 } 1843 } 1844 } 1845 1846 static void UnionScalingUsageBounds( 1847 const struct NvKmsScalingUsageBounds *a, 1848 const struct NvKmsScalingUsageBounds *b, 1849 struct NvKmsScalingUsageBounds *ret) 1850 { 1851 ret->maxVDownscaleFactor = NV_MAX(a->maxVDownscaleFactor, 1852 b->maxVDownscaleFactor); 1853 ret->maxHDownscaleFactor = NV_MAX(a->maxHDownscaleFactor, 1854 b->maxHDownscaleFactor); 1855 ret->vTaps = NV_MAX(a->vTaps, b->vTaps); 1856 ret->vUpscalingAllowed = a->vUpscalingAllowed || b->vUpscalingAllowed; 1857 } 1858 1859 void nvUnionUsageBounds(const struct NvKmsUsageBounds *a, 1860 const struct NvKmsUsageBounds *b, 1861 struct NvKmsUsageBounds *ret) 1862 { 1863 NvU32 i; 1864 1865 nvkms_memset(ret, 0, sizeof(*ret)); 1866 1867 for (i = 0; i < ARRAY_LEN(a->layer); i++) { 1868 nvAssert(a->layer[i].usable == 1869 !!a->layer[i].supportedSurfaceMemoryFormats); 1870 nvAssert(b->layer[i].usable == 1871 !!b->layer[i].supportedSurfaceMemoryFormats); 1872 1873 ret->layer[i].usable = a->layer[i].usable || b->layer[i].usable; 1874 1875 ret->layer[i].supportedSurfaceMemoryFormats = 1876 a->layer[i].supportedSurfaceMemoryFormats | 1877 b->layer[i].supportedSurfaceMemoryFormats; 1878 1879 UnionScalingUsageBounds(&a->layer[i].scaling, 1880 &b->layer[i].scaling, 1881 &ret->layer[i].scaling); 1882 } 1883 } 1884 1885 static void IntersectScalingUsageBounds( 1886 const struct NvKmsScalingUsageBounds *a, 1887 const struct NvKmsScalingUsageBounds *b, 1888 struct NvKmsScalingUsageBounds *ret) 1889 { 1890 ret->maxVDownscaleFactor = NV_MIN(a->maxVDownscaleFactor, 1891 b->maxVDownscaleFactor); 1892 ret->maxHDownscaleFactor = NV_MIN(a->maxHDownscaleFactor, 1893 b->maxHDownscaleFactor); 1894 ret->vTaps = NV_MIN(a->vTaps, b->vTaps); 1895 ret->vUpscalingAllowed = a->vUpscalingAllowed && b->vUpscalingAllowed; 1896 } 1897 1898 void nvIntersectUsageBounds(const struct NvKmsUsageBounds *a, 1899 const struct NvKmsUsageBounds *b, 1900 struct NvKmsUsageBounds *ret) 1901 { 1902 NvU32 i; 1903 1904 nvkms_memset(ret, 0, sizeof(*ret)); 1905 1906 for (i = 0; i < ARRAY_LEN(a->layer); i++) { 1907 nvAssert(a->layer[i].usable == 1908 !!a->layer[i].supportedSurfaceMemoryFormats); 1909 nvAssert(b->layer[i].usable == 1910 !!b->layer[i].supportedSurfaceMemoryFormats); 1911 1912 ret->layer[i].usable = a->layer[i].usable && b->layer[i].usable; 1913 1914 ret->layer[i].supportedSurfaceMemoryFormats = 1915 a->layer[i].supportedSurfaceMemoryFormats & 1916 b->layer[i].supportedSurfaceMemoryFormats; 1917 1918 IntersectScalingUsageBounds(&a->layer[i].scaling, 1919 &b->layer[i].scaling, 1920 &ret->layer[i].scaling); 1921 } 1922 } 1923 NvBool UsageBoundsEqual( 1924 const struct NvKmsUsageBounds *a, 1925 const struct NvKmsUsageBounds *b) 1926 { 1927 NvU32 layer; 1928 1929 for (layer = 0; layer < ARRAY_LEN(a->layer); layer++) { 1930 if (!nvEvoLayerUsageBoundsEqual(a, b, layer)) { 1931 return FALSE; 1932 } 1933 } 1934 1935 return TRUE; 1936 } 1937 1938 NvBool nvAllocatePreFlipBandwidth(NVDevEvoPtr pDevEvo, 1939 struct NvKmsFlipWorkArea *pWorkArea) 1940 { 1941 NVValidateImpOneDispHeadParamsRec *timingsParams = NULL; 1942 struct NvKmsUsageBounds *currentAndNew = NULL; 1943 struct NvKmsUsageBounds *guaranteedAndCurrent = NULL; 1944 NVDispEvoPtr pDispEvo; 1945 NvU32 head; 1946 NvBool recheckIMP = FALSE; 1947 NvBool ret = TRUE; 1948 1949 if (!pDevEvo->isSOCDisplay) { 1950 return TRUE; 1951 } 1952 1953 timingsParams = 1954 nvCalloc(NVKMS_MAX_HEADS_PER_DISP, sizeof(*timingsParams)); 1955 if (timingsParams == NULL) { 1956 return FALSE; 1957 } 1958 1959 currentAndNew = 1960 nvCalloc(NVKMS_MAX_HEADS_PER_DISP, sizeof(*currentAndNew)); 1961 if (currentAndNew == NULL) { 1962 nvFree(timingsParams); 1963 return FALSE; 1964 } 1965 1966 guaranteedAndCurrent = 1967 nvCalloc(NVKMS_MAX_HEADS_PER_DISP, sizeof(*guaranteedAndCurrent)); 1968 if (guaranteedAndCurrent == NULL) { 1969 nvFree(timingsParams); 1970 nvFree(currentAndNew); 1971 return FALSE; 1972 } 1973 1974 pDispEvo = pDevEvo->pDispEvo[0]; 1975 1976 // SOC Display never has more than one disp 1977 nvAssert(pDevEvo->nDispEvo == 1); 1978 1979 for (head = 0; head < pDevEvo->numHeads; head++) { 1980 NVDispHeadStateEvoRec *pHeadState = 1981 &pDispEvo->headState[head]; 1982 const struct NvKmsUsageBounds *pCurrent = 1983 &pDevEvo->gpus[0].headState[head].preallocatedUsage; 1984 const struct NvKmsUsageBounds *pNew = 1985 &pWorkArea->sd[0].head[head].newState.usage; 1986 1987 if (pHeadState->activeRmId == 0) { 1988 continue; 1989 } 1990 1991 timingsParams[head].pConnectorEvo = pHeadState->pConnectorEvo; 1992 timingsParams[head].activeRmId = pHeadState->activeRmId; 1993 timingsParams[head].pixelDepth = pHeadState->pixelDepth; 1994 timingsParams[head].pTimings = &pHeadState->timings; 1995 timingsParams[head].enableDsc = (pHeadState->dscInfo.type != 1996 NV_DSC_INFO_EVO_TYPE_DISABLED); 1997 timingsParams[head].b2Heads1Or = 1998 (pHeadState->mergeMode != NV_EVO_MERGE_MODE_DISABLED); 1999 2000 nvUnionUsageBounds(pCurrent, pNew, ¤tAndNew[head]); 2001 nvUnionUsageBounds(&pHeadState->timings.viewPort.guaranteedUsage, 2002 pCurrent, &guaranteedAndCurrent[head]); 2003 2004 if (!ValidateUsageBounds(pDevEvo, 2005 head, 2006 pNew, 2007 &guaranteedAndCurrent[head])) { 2008 recheckIMP = TRUE; 2009 } 2010 2011 nvUnionUsageBounds(&guaranteedAndCurrent[head], pNew, 2012 &guaranteedAndCurrent[head]); 2013 timingsParams[head].pUsage = &guaranteedAndCurrent[head]; 2014 } 2015 2016 if (recheckIMP) { 2017 ret = nvValidateImpOneDisp(pDispEvo, timingsParams, 2018 FALSE /* requireBootClocks */, 2019 NV_EVO_REALLOCATE_BANDWIDTH_MODE_PRE, 2020 NULL /* pMinIsoBandwidthKBPS */, 2021 NULL /* pMinDramFloorKBPS */); 2022 if (ret) { 2023 for (head = 0; head < pDevEvo->numHeads; head++) { 2024 pDevEvo->gpus[0].headState[head].preallocatedUsage = 2025 currentAndNew[head]; 2026 } 2027 } 2028 } 2029 2030 nvFree(timingsParams); 2031 nvFree(currentAndNew); 2032 nvFree(guaranteedAndCurrent); 2033 2034 if (ret) { 2035 nvScheduleLowerDispBandwidthTimer(pDevEvo); 2036 } 2037 2038 return ret; 2039 } 2040 2041 /*! 2042 * If the satellite channel is active then pre-NVDisplay hardware does not allow 2043 * to change its usage bounds in non-interlock update. The nvSetUsageBoundsEvo() 2044 * code path for pre-NVDisplay hardware, interlocks the satellite channels with 2045 * the usage bounds update. This makes it essential to poll for 2046 * NO_METHOD_PENDING state of the satellite channels, otherwise blocking 2047 * pre-flip IMP update will also get stuck. 2048 * 2049 * It is not possible to interlock flip-locked satellite channels with the core 2050 * channel usage bounds update; in that case, reject the flip. Do not allow 2051 * client to make any change in surface usage bounds parameters without 2052 * deactivating channel first, if channel is flip-locked. 2053 */ 2054 static NvBool PrepareToDoPreFlipIMP(NVDevEvoPtr pDevEvo, 2055 struct NvKmsFlipWorkArea *pWorkArea) 2056 { 2057 NvU64 startTime = 0; 2058 NvU32 timeout = 2000000; /* 2 seconds */ 2059 NvU32 sd; 2060 2061 for (sd = 0; sd < pDevEvo->numSubDevices; sd++) { 2062 NVEvoSubDevPtr pEvoSubDev = &pDevEvo->gpus[sd]; 2063 NvU32 head; 2064 2065 for (head = 0; head < pDevEvo->numHeads; head++) { 2066 NVEvoHeadControlPtr pHC = 2067 &pEvoSubDev->headControl[head]; 2068 const NVEvoSubDevHeadStateRec *pCurrentFlipState = 2069 &pDevEvo->gpus[sd].headState[head]; 2070 const NVSurfaceEvoRec *pCurrentBaseSurf = 2071 pCurrentFlipState->layer[NVKMS_MAIN_LAYER].pSurfaceEvo[NVKMS_LEFT]; 2072 const struct NvKmsUsageBounds *pCurrentUsage = 2073 &pCurrentFlipState->usage; 2074 2075 NVFlipEvoHwState *pNewFlipState = 2076 &pWorkArea->sd[sd].head[head].newState; 2077 const NVSurfaceEvoRec *pNewBaseSurf = 2078 pNewFlipState->layer[NVKMS_MAIN_LAYER].pSurfaceEvo[NVKMS_LEFT]; 2079 struct NvKmsUsageBounds *pNewUsage = 2080 &pNewFlipState->usage; 2081 2082 struct NvKmsUsageBounds *pPreFlipUsage = 2083 &pWorkArea->sd[sd].head[head].preFlipUsage; 2084 2085 NvU32 layer; 2086 2087 nvUnionUsageBounds(pNewUsage, pCurrentUsage, pPreFlipUsage); 2088 2089 if (pDevEvo->hal->caps.supportsNonInterlockedUsageBoundsUpdate) { 2090 /* 2091 * NVDisplay does not interlock the satellite channel 2092 * with its usage bounds update. 2093 */ 2094 continue; 2095 } 2096 2097 /* 2098 * If head is flip-locked then do not change usage 2099 * bounds while base channel is active. 2100 */ 2101 if (pHC->flipLock && 2102 /* If the base channel is active before and after flip then 2103 * current and new base usage bounds should be same. */ 2104 ((pNewBaseSurf != NULL && 2105 pCurrentBaseSurf != NULL && 2106 !nvEvoLayerUsageBoundsEqual(pCurrentUsage, 2107 pNewUsage, NVKMS_MAIN_LAYER)) || 2108 /* If the base channel is active before flip then current and 2109 * preflip base usage bounds should be same. */ 2110 (pCurrentBaseSurf != NULL && 2111 !nvEvoLayerUsageBoundsEqual(pCurrentUsage, 2112 pPreFlipUsage, NVKMS_MAIN_LAYER)))) { 2113 return FALSE; 2114 } 2115 2116 /* 2117 * Poll for NO_METHOD_PENDING state if usage 2118 * bounds of the channel are changed. 2119 */ 2120 for (layer = 0; layer < pDevEvo->head[head].numLayers; layer++) { 2121 if (!nvEvoLayerUsageBoundsEqual(pCurrentUsage, 2122 pPreFlipUsage, layer) && 2123 !nvEvoPollForNoMethodPending(pDevEvo, 2124 sd, 2125 pDevEvo->head[head].layer[layer], 2126 &startTime, 2127 timeout)) { 2128 return FALSE; 2129 } 2130 } 2131 } 2132 } 2133 2134 return TRUE; 2135 } 2136 2137 /*! 2138 * Tasks need to perform before triggering flip, they all should be done here. 2139 * 2140 * If necessary, raise usage bounds and/or disable MidFrameAndDWCFWatermark 2141 * (bug 200508242) in the core channel and do an IMP update. 2142 * 2143 * Note that this function only raises usage bounds and/or disables 2144 * MidFrameAndDWCFWatermark, never lowers usage bounds and/or enables 2145 * MidFrameAndDWCFWatermark. This allows it to run before queuing a flip even 2146 * if there are still pending flips in a base channel. 2147 */ 2148 static void PreFlipIMP(NVDevEvoPtr pDevEvo, 2149 const struct NvKmsFlipWorkArea *pWorkArea) 2150 { 2151 NvU32 head, sd; 2152 NVDispEvoPtr pDispEvo; 2153 2154 FOR_ALL_EVO_DISPLAYS(pDispEvo, sd, pDevEvo) { 2155 NVEvoUpdateState updateState = { }; 2156 NvBool update = FALSE; 2157 2158 for (head = 0; head < pDispEvo->pDevEvo->numHeads; head++) { 2159 const NVFlipEvoHwState *pNewState = 2160 &pWorkArea->sd[sd].head[head].newState; 2161 const struct NvKmsUsageBounds *pPreFlipUsage = 2162 &pWorkArea->sd[sd].head[head].preFlipUsage; 2163 struct NvKmsUsageBounds *pCurrentUsage = 2164 &pDevEvo->gpus[sd].headState[head].usage; 2165 2166 if (!UsageBoundsEqual(pCurrentUsage, pPreFlipUsage)) { 2167 update |= nvSetUsageBoundsEvo(pDevEvo, sd, head, 2168 pPreFlipUsage, &updateState); 2169 } 2170 2171 if (!pDevEvo->gpus[sd]. 2172 headState[head].disableMidFrameAndDWCFWatermark && 2173 pNewState->disableMidFrameAndDWCFWatermark) { 2174 2175 nvEnableMidFrameAndDWCFWatermark(pDevEvo, 2176 sd, 2177 head, 2178 FALSE /* enable */, 2179 &updateState); 2180 update = TRUE; 2181 } 2182 } 2183 2184 if (update) { 2185 nvDoIMPUpdateEvo(pDispEvo, &updateState); 2186 } 2187 } 2188 } 2189 2190 static void LowerDispBandwidth(void *dataPtr, NvU32 dataU32) 2191 { 2192 NVValidateImpOneDispHeadParamsRec timingsParams[NVKMS_MAX_HEADS_PER_DISP]; 2193 struct NvKmsUsageBounds *guaranteedAndCurrent; 2194 NVDevEvoPtr pDevEvo = dataPtr; 2195 NVDispEvoPtr pDispEvo; 2196 NvU32 head; 2197 NvBool ret; 2198 2199 guaranteedAndCurrent = 2200 nvCalloc(1, sizeof(*guaranteedAndCurrent) * NVKMS_MAX_HEADS_PER_DISP); 2201 if (guaranteedAndCurrent == NULL) { 2202 nvAssert(guaranteedAndCurrent != NULL); 2203 return; 2204 } 2205 2206 nvkms_memset(&timingsParams, 0, sizeof(timingsParams)); 2207 2208 pDispEvo = pDevEvo->pDispEvo[0]; 2209 2210 // SOC Display never has more than one disp 2211 nvAssert(pDevEvo->nDispEvo == 1); 2212 2213 for (head = 0; head < pDevEvo->numHeads; head++) { 2214 NVDispHeadStateEvoRec *pHeadState = 2215 &pDispEvo->headState[head]; 2216 const struct NvKmsUsageBounds *pGuaranteed = 2217 &pHeadState->timings.viewPort.guaranteedUsage; 2218 const struct NvKmsUsageBounds *pCurrent = 2219 &pDevEvo->gpus[0].headState[head].usage; 2220 2221 if (pHeadState->activeRmId == 0) { 2222 continue; 2223 } 2224 2225 timingsParams[head].pConnectorEvo = pHeadState->pConnectorEvo; 2226 timingsParams[head].activeRmId = pHeadState->activeRmId; 2227 timingsParams[head].pixelDepth = pHeadState->pixelDepth; 2228 timingsParams[head].pTimings = &pHeadState->timings; 2229 timingsParams[head].enableDsc = (pHeadState->dscInfo.type != 2230 NV_DSC_INFO_EVO_TYPE_DISABLED); 2231 timingsParams[head].b2Heads1Or = 2232 (pHeadState->mergeMode != NV_EVO_MERGE_MODE_DISABLED); 2233 2234 nvUnionUsageBounds(pGuaranteed, pCurrent, &guaranteedAndCurrent[head]); 2235 timingsParams[head].pUsage = &guaranteedAndCurrent[head]; 2236 } 2237 2238 ret = nvValidateImpOneDisp(pDispEvo, timingsParams, 2239 FALSE /* requireBootClocks */, 2240 NV_EVO_REALLOCATE_BANDWIDTH_MODE_POST, 2241 NULL /* pMinIsoBandwidthKBPS */, 2242 NULL /* pMinDramFloorKBPS */); 2243 if (ret) { 2244 for (head = 0; head < pDevEvo->numHeads; head++) { 2245 pDevEvo->gpus[0].headState[head].preallocatedUsage = 2246 pDevEvo->gpus[0].headState[head].usage; 2247 } 2248 } 2249 2250 nvAssert(ret); 2251 2252 nvFree(guaranteedAndCurrent); 2253 } 2254 2255 void nvCancelLowerDispBandwidthTimer(NVDevEvoPtr pDevEvo) 2256 { 2257 nvkms_free_timer(pDevEvo->lowerDispBandwidthTimer); 2258 pDevEvo->lowerDispBandwidthTimer = NULL; 2259 } 2260 2261 void nvScheduleLowerDispBandwidthTimer(NVDevEvoPtr pDevEvo) 2262 { 2263 nvAssert(pDevEvo->isSOCDisplay); 2264 2265 nvCancelLowerDispBandwidthTimer(pDevEvo); 2266 2267 pDevEvo->lowerDispBandwidthTimer = 2268 nvkms_alloc_timer(LowerDispBandwidth, 2269 pDevEvo, 2270 0, /* dataU32 */ 2271 30000000 /* 30 seconds */); 2272 } 2273 2274 /*! 2275 * Check whether the core, base, and overlay channels are idle (i.e. no methods 2276 * pending in the corresponding pushbuffer) and lower the usage bounds if 2277 * possible. 2278 */ 2279 static NvBool TryLoweringUsageBoundsOneHead(NVDevEvoPtr pDevEvo, NvU32 sd, 2280 NvU32 head, 2281 NVEvoUpdateState *updateState) 2282 { 2283 const NVEvoSubDevHeadStateRec *pHeadState = 2284 &pDevEvo->gpus[sd].headState[head]; 2285 const struct NvKmsUsageBounds *pCurrent = &pHeadState->usage; 2286 const struct NvKmsUsageBounds *pTarget = &pHeadState->targetUsage; 2287 struct NvKmsUsageBounds newUsage = *pCurrent; 2288 NvBool changed = FALSE; 2289 NvBool scheduleLater = FALSE; 2290 int i; 2291 2292 for (i = 0; i < pDevEvo->head[head].numLayers; i++) { 2293 if (pCurrent->layer[i].usable && !pTarget->layer[i].usable) { 2294 NvBool isMethodPending; 2295 2296 if (pDevEvo->hal->IsChannelMethodPending( 2297 pDevEvo, 2298 pDevEvo->head[head].layer[i], 2299 sd, 2300 &isMethodPending) && !isMethodPending) { 2301 newUsage.layer[i] = pTarget->layer[i]; 2302 changed = TRUE; 2303 } else { 2304 scheduleLater = TRUE; 2305 } 2306 } else if ((pCurrent->layer[i].usable && pTarget->layer[i].usable) && 2307 ((pCurrent->layer[i].supportedSurfaceMemoryFormats != 2308 pTarget->layer[i].supportedSurfaceMemoryFormats) || 2309 (!nvEvoScalingUsageBoundsEqual(&pCurrent->layer[i].scaling, 2310 &pTarget->layer[i].scaling)))) { 2311 NvBool isMethodPending; 2312 2313 if (pDevEvo->hal->IsChannelMethodPending( 2314 pDevEvo, 2315 pDevEvo->head[head].layer[i], 2316 sd, 2317 &isMethodPending) && !isMethodPending) { 2318 newUsage.layer[i] = pTarget->layer[i]; 2319 changed = TRUE; 2320 } else { 2321 scheduleLater = TRUE; 2322 } 2323 } 2324 } 2325 2326 if (scheduleLater) { 2327 SchedulePostFlipIMPTimer(pDevEvo); 2328 } 2329 2330 if (changed) { 2331 changed = nvSetUsageBoundsEvo(pDevEvo, sd, head, &newUsage, 2332 updateState); 2333 } 2334 2335 return changed; 2336 } 2337 2338 static NvBool 2339 TryEnablingMidFrameAndDWCFWatermarkOneHead(NVDevEvoPtr pDevEvo, 2340 NvU32 sd, 2341 NvU32 head, 2342 NVEvoUpdateState *updateState) 2343 { 2344 const NVEvoSubDevHeadStateRec *pHeadState = 2345 &pDevEvo->gpus[sd].headState[head]; 2346 NvBool changed = FALSE; 2347 2348 if (pHeadState->disableMidFrameAndDWCFWatermark && 2349 !pHeadState->targetDisableMidFrameAndDWCFWatermark) { 2350 2351 NvBool isIdle; 2352 2353 if (pDevEvo->hal->IsChannelIdle(pDevEvo, 2354 pDevEvo->head[head].layer[NVKMS_MAIN_LAYER], 2355 sd, 2356 &isIdle) && isIdle) { 2357 nvEnableMidFrameAndDWCFWatermark(pDevEvo, 2358 sd, 2359 head, 2360 TRUE /* enable */, 2361 updateState); 2362 changed = TRUE; 2363 } else { 2364 // Schedule another timer to try again later. 2365 SchedulePostFlipIMPTimer(pDevEvo); 2366 } 2367 } 2368 2369 return changed; 2370 } 2371 2372 static void 2373 TryToDoPostFlipIMP(void *dataPtr, NvU32 dataU32) 2374 { 2375 NVDevEvoPtr pDevEvo = dataPtr; 2376 NvU32 head, sd; 2377 NVDispEvoPtr pDispEvo; 2378 2379 pDevEvo->postFlipIMPTimer = NULL; 2380 2381 FOR_ALL_EVO_DISPLAYS(pDispEvo, sd, pDevEvo) { 2382 NVEvoUpdateState updateState = { }; 2383 NvBool update = FALSE; 2384 2385 for (head = 0; head < pDispEvo->pDevEvo->numHeads; head++) { 2386 if (TryLoweringUsageBoundsOneHead(pDevEvo, sd, head, 2387 &updateState)) { 2388 update = TRUE; 2389 } 2390 2391 if (TryEnablingMidFrameAndDWCFWatermarkOneHead( 2392 pDevEvo, 2393 sd, 2394 head, 2395 &updateState)) { 2396 update = TRUE; 2397 } 2398 } 2399 2400 if (update) { 2401 nvDoIMPUpdateEvo(pDispEvo, &updateState); 2402 } 2403 } 2404 } 2405 2406 static void SchedulePostFlipIMPTimer(NVDevEvoPtr pDevEvo) 2407 { 2408 if (!pDevEvo->postFlipIMPTimer) { 2409 pDevEvo->postFlipIMPTimer = 2410 nvkms_alloc_timer( 2411 TryToDoPostFlipIMP, 2412 pDevEvo, 2413 0, /* dataU32 */ 2414 10000000 /* 10 seconds */); 2415 } 2416 } 2417 2418 void nvEvoCancelPostFlipIMPTimer(NVDevEvoPtr pDevEvo) 2419 { 2420 nvkms_free_timer(pDevEvo->postFlipIMPTimer); 2421 pDevEvo->postFlipIMPTimer = NULL; 2422 } 2423 2424 /*! 2425 * If necessary, schedule a timer to see if usage bounds can be lowered. 2426 */ 2427 static void SchedulePostFlipIMP(NVDevEvoPtr pDevEvo) 2428 { 2429 NvU32 head, sd; 2430 NVDispEvoPtr pDispEvo; 2431 2432 // If a timer is already scheduled, do nothing. 2433 if (pDevEvo->postFlipIMPTimer) { 2434 return; 2435 } 2436 2437 FOR_ALL_EVO_DISPLAYS(pDispEvo, sd, pDevEvo) { 2438 for (head = 0; head < pDispEvo->pDevEvo->numHeads; head++) { 2439 const NVEvoSubDevHeadStateRec *pHeadState = 2440 &pDevEvo->gpus[sd].headState[head]; 2441 2442 if (!UsageBoundsEqual(&pHeadState->usage, 2443 &pHeadState->targetUsage) || 2444 (pHeadState->disableMidFrameAndDWCFWatermark != 2445 pHeadState->targetDisableMidFrameAndDWCFWatermark)) { 2446 2447 SchedulePostFlipIMPTimer(pDevEvo); 2448 return; 2449 } 2450 } 2451 } 2452 } 2453 2454 static void SkipLayerPendingFlips(NVDevEvoRec *pDevEvo, 2455 const NvBool trashPendingMethods, 2456 const NvBool unblockMethodsInExecutation, 2457 struct NvKmsFlipWorkArea *pWorkArea) 2458 { 2459 NvU64 startTime = 0; 2460 const NvU32 timeout = 2000000; /* 2 seconds */ 2461 struct { 2462 struct { 2463 struct { 2464 NvU32 oldAccelMask; 2465 } head[NVKMS_MAX_HEADS_PER_DISP]; 2466 } sd[NVKMS_MAX_SUBDEVICES]; 2467 } accelState = { }; 2468 NvU32 sd, head; 2469 2470 for (sd = 0; sd < pDevEvo->numSubDevices; sd++) { 2471 if (!pWorkArea->sd[sd].changed) { 2472 continue; 2473 } 2474 2475 for (head = 0; head < NVKMS_MAX_HEADS_PER_DISP; head++) { 2476 const NVFlipEvoHwState *pFlipState = 2477 &pWorkArea->sd[sd].head[head].newState; 2478 2479 if (!pFlipState->skipLayerPendingFlips[NVKMS_MAIN_LAYER]|| 2480 !pFlipState->dirty.layer[NVKMS_MAIN_LAYER]) { 2481 continue; 2482 } 2483 2484 pDevEvo->hal->AccelerateChannel( 2485 pDevEvo, 2486 pDevEvo->head[head].layer[NVKMS_MAIN_LAYER], 2487 sd, 2488 trashPendingMethods, 2489 unblockMethodsInExecutation, 2490 &accelState.sd[sd].head[head].oldAccelMask); 2491 } 2492 } 2493 2494 for (sd = 0; sd < pDevEvo->numSubDevices; sd++) { 2495 if (!pWorkArea->sd[sd].changed) { 2496 continue; 2497 } 2498 2499 for (head = 0; head < NVKMS_MAX_HEADS_PER_DISP; head++) { 2500 const NVFlipEvoHwState *pFlipState = 2501 &pWorkArea->sd[sd].head[head].newState; 2502 2503 if (!pFlipState->skipLayerPendingFlips[NVKMS_MAIN_LAYER] || 2504 !pFlipState->dirty.layer[NVKMS_MAIN_LAYER]) { 2505 continue; 2506 } 2507 2508 if (unblockMethodsInExecutation) { 2509 if (!nvEvoPollForNoMethodPending(pDevEvo, 2510 sd, 2511 pDevEvo->head[head].layer[NVKMS_MAIN_LAYER], 2512 &startTime, 2513 timeout)) { 2514 nvAssert(!"Failed to idle the main layer channel"); 2515 } 2516 } else { 2517 if (!nvEvoPollForEmptyChannel(pDevEvo->head[head].layer[NVKMS_MAIN_LAYER], 2518 sd, 2519 &startTime, 2520 timeout)) { 2521 nvAssert(!"Failed to empty the main layer channel"); 2522 } 2523 } 2524 2525 pDevEvo->hal->ResetChannelAccelerators( 2526 pDevEvo, 2527 pDevEvo->head[head].layer[NVKMS_MAIN_LAYER], 2528 sd, 2529 trashPendingMethods, 2530 unblockMethodsInExecutation, 2531 accelState.sd[sd].head[head].oldAccelMask); 2532 } 2533 } 2534 } 2535 2536 void nvPreFlip(NVDevEvoRec *pDevEvo, 2537 struct NvKmsFlipWorkArea *pWorkArea, 2538 const NvBool applyAllowVrr, 2539 const NvBool allowVrr, 2540 const NvBool skipUpdate) 2541 { 2542 NvU32 sd, head; 2543 NVDispEvoRec *pDispEvo; 2544 2545 for (sd = 0; sd < pDevEvo->numSubDevices; sd++) { 2546 2547 if (!pWorkArea->sd[sd].changed) { 2548 continue; 2549 } 2550 2551 for (head = 0; head < NVKMS_MAX_HEADS_PER_DISP; head++) { 2552 // Increase refCnt of surfaces used AFTER flip 2553 nvUpdateSurfacesFlipRefCount( 2554 pDevEvo, 2555 head, 2556 &pWorkArea->sd[sd].head[head].newState, 2557 NV_TRUE); 2558 2559 nvRefTmoLutSurfacesEvo( 2560 pDevEvo, 2561 &pWorkArea->sd[sd].head[head].newState, 2562 head); 2563 } 2564 } 2565 2566 PreFlipIMP(pDevEvo, pWorkArea); 2567 2568 if (!skipUpdate) { 2569 /* Trash flips pending in channel which are not yet in execution */ 2570 SkipLayerPendingFlips(pDevEvo, TRUE /* trashPendingMethods */, 2571 FALSE /* unblockMethodsInExecutation */, 2572 pWorkArea); 2573 } 2574 2575 if (applyAllowVrr) { 2576 nvSetVrrActive(pDevEvo, allowVrr); 2577 } 2578 2579 /* 2580 * Update flip metering for Frame pacing smoothing/frame splitting for direct 2581 * drive and adaptive sync VRR, and override the flip timestamp if 2582 * necessary. 2583 */ 2584 FOR_ALL_EVO_DISPLAYS(pDispEvo, sd, pDevEvo) { 2585 for (NvU32 inputHead = 0; inputHead < pDevEvo->numHeads; inputHead++) { 2586 const NVDispHeadStateEvoRec *pInputHeadState = 2587 &pDispEvo->headState[inputHead]; 2588 const struct NvKmsVrrFramePacingInfo *pInputVrrFramePacingInfo = 2589 &pInputHeadState->vrrFramePacingInfo; 2590 const NvU32 headsMask = pInputHeadState->mergeModeVrrSecondaryHeadMask | 2591 NVBIT(inputHead); 2592 2593 /* 2594 * XXX[2Heads1OR] Implement per api-head frame pacing and remove this 2595 * mergeMode check and NVDispEvoRec::mergeModeVrrSecondaryHeadMask. 2596 */ 2597 if (pInputHeadState->mergeMode == NV_EVO_MERGE_MODE_SECONDARY) { 2598 continue; 2599 } 2600 2601 #if defined(DEBUG) 2602 FOR_EACH_EVO_HW_HEAD_IN_MASK(headsMask, head) { 2603 const NVFlipEvoHwState *pInputHeadNewState = 2604 &pWorkArea->sd[sd].head[inputHead].newState; 2605 const NVFlipEvoHwState *pNewState = 2606 &pWorkArea->sd[sd].head[head].newState; 2607 2608 nvAssert(pNewState->dirty.layer[NVKMS_MAIN_LAYER] == 2609 pInputHeadNewState->dirty.layer[NVKMS_MAIN_LAYER]); 2610 } 2611 #endif 2612 2613 FOR_EACH_EVO_HW_HEAD_IN_MASK(headsMask, head) { 2614 NVFlipEvoHwState *pNewState = 2615 &pWorkArea->sd[sd].head[head].newState; 2616 if (pNewState->dirty.layer[NVKMS_MAIN_LAYER]) { 2617 nvTrackAndDelayFlipForVrrSwFramePacing(pDispEvo, 2618 pInputVrrFramePacingInfo, 2619 &pNewState->layer[NVKMS_MAIN_LAYER]); 2620 } 2621 } 2622 } 2623 } 2624 } 2625 2626 void nvPostFlip(NVDevEvoRec *pDevEvo, 2627 struct NvKmsFlipWorkArea *pWorkArea, 2628 const NvBool skipUpdate, 2629 const NvBool applyAllowVrr, 2630 NvS32 *pVrrSemaphoreIndex) 2631 { 2632 NvU32 sd, head; 2633 2634 if (!skipUpdate) { 2635 /* Unblock flips which are stuck in execution */ 2636 SkipLayerPendingFlips(pDevEvo, FALSE /* trashPendingMethods */, 2637 TRUE /* unblockMethodsInExecutation */, 2638 pWorkArea); 2639 } 2640 2641 if (applyAllowVrr) { 2642 *pVrrSemaphoreIndex = nvIncVrrSemaphoreIndex(pDevEvo); 2643 } else { 2644 // TODO Schedule vrr unstall; per-disp/per-device? 2645 } 2646 2647 for (sd = 0; sd < pDevEvo->numSubDevices; sd++) { 2648 if (!pWorkArea->sd[sd].changed) { 2649 continue; 2650 } 2651 2652 for (head = 0; head < NVKMS_MAX_HEADS_PER_DISP; head++) { 2653 // Decrease refCnt of surfaces used BEFORE the flip 2654 nvUpdateSurfacesFlipRefCount( 2655 pDevEvo, 2656 head, 2657 &pWorkArea->sd[sd].head[head].oldState, 2658 NV_FALSE); 2659 2660 nvUnrefTmoLutSurfacesEvo( 2661 pDevEvo, 2662 &pWorkArea->sd[sd].head[head].oldState, 2663 head); 2664 } 2665 } 2666 2667 if (!skipUpdate) { 2668 // Note that usage bounds are not lowered here, because the flip 2669 // queued by this function may not occur until later. Instead, schedule 2670 // a timer for later to check if the usage bounds can be lowered. 2671 SchedulePostFlipIMP(pDevEvo); 2672 2673 pDevEvo->skipConsoleRestore = FALSE; 2674 } 2675 } 2676 2677 NvBool nvPrepareToDoPreFlip(NVDevEvoRec *pDevEvo, 2678 struct NvKmsFlipWorkArea *pWorkArea) 2679 { 2680 if (!RegisterPreSyncpt(pDevEvo, pWorkArea)) { 2681 return FALSE; 2682 } 2683 2684 if (!PrepareToDoPreFlipIMP(pDevEvo, pWorkArea)) { 2685 return FALSE; 2686 } 2687 2688 return TRUE; 2689 } 2690 2691 NvBool nvAssignNVFlipEvoHwState(NVDevEvoRec *pDevEvo, 2692 const struct NvKmsPerOpenDev *pOpenDev, 2693 const NvU32 sd, 2694 const NvU32 head, 2695 const struct NvKmsFlipCommonParams *pParams, 2696 const NvBool allowVrr, 2697 NVFlipEvoHwState *pFlipHwState) 2698 { 2699 const NVDispEvoRec *pDispEvo = pDevEvo->gpus[sd].pDispEvo; 2700 const NVDispHeadStateEvoRec *pHeadState = &pDispEvo->headState[head]; 2701 const struct NvKmsUsageBounds *pPossibleUsage = 2702 &pHeadState->timings.viewPort.possibleUsage; 2703 2704 if (!nvUpdateFlipEvoHwState(pOpenDev, pDevEvo, sd, head, pParams, 2705 &pHeadState->timings, pHeadState->tilePosition, 2706 pFlipHwState, allowVrr)) { 2707 return FALSE; 2708 } 2709 2710 nvOverrideScalingUsageBounds(pDevEvo, head, pFlipHwState, pPossibleUsage); 2711 2712 if (!nvValidateFlipEvoHwState(pDevEvo, head, &pHeadState->timings, 2713 pFlipHwState)) { 2714 return FALSE; 2715 } 2716 2717 if (!nvSetTmoLutSurfacesEvo(pDevEvo, pFlipHwState, head)) { 2718 return FALSE; 2719 } 2720 2721 return TRUE; 2722 } 2723 2724 /*! 2725 * Wait for idle on a set of the main layer channels. 2726 * 2727 * \param[in,out] pDevEvo The device. 2728 * \param[in] idleChannelMaskPerSd The channel masks per subdevice that 2729 * we should wait to be idle. 2730 * \param[in] allowForceIdle Whether we should force idle a channel 2731 * or just assert if the idle times out. 2732 */ 2733 void nvIdleMainLayerChannels( 2734 NVDevEvoPtr pDevEvo, 2735 const NVEvoChannelMask *idleChannelMaskPerSd, 2736 NvBool allowStopBase) 2737 { 2738 NvU64 startTime = 0; 2739 NvBool allChannelsIdle = FALSE; 2740 NVDispEvoPtr pDispEvo; 2741 NvU32 dispIndex, head; 2742 NVEvoChannelMask busyChannelMaskPerSd[NVKMS_MAX_SUBDEVICES] = { }; 2743 2744 /* 2745 * Wait up to 2 seconds for all channels to be idle, and gather a list of 2746 * all busy channels. 2747 */ 2748 while (!allChannelsIdle) { 2749 2750 const NvU32 timeout = 2000000; /* 2 seconds */ 2751 NvBool anyChannelBusy = FALSE; 2752 2753 FOR_ALL_EVO_DISPLAYS(pDispEvo, dispIndex, pDevEvo) { 2754 for (head = 0; head < pDevEvo->numHeads; head++) { 2755 NVEvoChannelPtr pMainLayerChannel = 2756 pDevEvo->head[head].layer[NVKMS_MAIN_LAYER]; 2757 if (idleChannelMaskPerSd[pDispEvo->displayOwner] & 2758 pMainLayerChannel->channelMask) { 2759 2760 NvBool isMethodPending = FALSE; 2761 if (!pDevEvo->hal->IsChannelMethodPending( 2762 pDevEvo, 2763 pMainLayerChannel, 2764 pDispEvo->displayOwner, 2765 &isMethodPending) 2766 || isMethodPending) { 2767 2768 /* Mark this channel as busy. */ 2769 busyChannelMaskPerSd[pDispEvo->displayOwner] |= 2770 pMainLayerChannel->channelMask; 2771 anyChannelBusy = TRUE; 2772 } else { 2773 /* 2774 * Mark this channel as no longer busy, in case its 2775 * flip completed while we were waiting on another 2776 * channel. 2777 */ 2778 busyChannelMaskPerSd[pDispEvo->displayOwner] &= 2779 ~pMainLayerChannel->channelMask; 2780 } 2781 } 2782 } 2783 } 2784 2785 if (!anyChannelBusy) { 2786 allChannelsIdle = TRUE; 2787 break; 2788 } 2789 2790 /* Break out of the loop if we exceed the timeout. */ 2791 if (nvExceedsTimeoutUSec(&startTime, timeout)) { 2792 break; 2793 } 2794 2795 nvkms_yield(); 2796 } 2797 2798 if (!allChannelsIdle) { 2799 /* 2800 * At least one channel was still idle after the 2 second timeout 2801 * above. 2802 */ 2803 if (!allowStopBase) { 2804 /* 2805 * The caller of this function expected this wait for idle not to 2806 * time out. 2807 */ 2808 nvEvoLogDev(pDevEvo, EVO_LOG_WARN, 2809 "Timeout while waiting for idle."); 2810 } else { 2811 /* 2812 * Idle all base channels that were still busy when the wait above 2813 * timed out. 2814 */ 2815 NVEvoIdleChannelState idleChannelState = { }; 2816 2817 FOR_ALL_EVO_DISPLAYS(pDispEvo, dispIndex, pDevEvo) { 2818 idleChannelState.subdev[pDispEvo->displayOwner].channelMask = 2819 busyChannelMaskPerSd[pDispEvo->displayOwner]; 2820 } 2821 2822 pDevEvo->hal->ForceIdleSatelliteChannelIgnoreLock( 2823 pDevEvo, &idleChannelState); 2824 } 2825 } 2826 } 2827 2828 NvBool nvNeedToToggleFlipLock(const NVDispEvoRec *pDispEvo, 2829 const NvU32 head, const NvBool enable) 2830 { 2831 const NVDevEvoRec *pDevEvo = pDispEvo->pDevEvo; 2832 const NVEvoSubDevPtr pEvoSubDev = &pDevEvo->gpus[pDispEvo->displayOwner]; 2833 const NVEvoHeadControlPtr pHC = &pEvoSubDev->headControl[head]; 2834 NvBool needToToggle = FALSE; 2835 2836 if (!enable && pHC->flipLock) { 2837 /* 2838 * This channel is currently using fliplock in the config that 2839 * is being torn down; idle its base channel and disable 2840 * fliplock. 2841 */ 2842 needToToggle = TRUE; 2843 } 2844 2845 if (enable && ((pHC->serverLock != NV_EVO_NO_LOCK) || 2846 (pHC->clientLock != NV_EVO_NO_LOCK))) { 2847 /* 2848 * This channel will be using fliplock for swap groups in the 2849 * new config; idle its base channel and enable fliplock. 2850 */ 2851 nvAssert(!HEAD_MASK_QUERY(pEvoSubDev->flipLockProhibitedHeadMask, 2852 head)); 2853 needToToggle = TRUE; 2854 } 2855 2856 return needToToggle; 2857 } 2858 2859 void nvToggleFlipLockPerDisp(NVDispEvoRec *pDispEvo, const NvU32 headMask, 2860 const NvBool enable) 2861 { 2862 NvU32 head; 2863 NVEvoUpdateState updateState = { }; 2864 const NVDevEvoRec *pDevEvo = pDispEvo->pDevEvo; 2865 2866 for (head = 0; head < pDevEvo->numHeads; head++) { 2867 if ((headMask & NVBIT(head)) != 0x0) { 2868 NvU32 setEnable = enable; 2869 2870 if (!nvUpdateFlipLockEvoOneHead(pDispEvo, head, &setEnable, 2871 TRUE /* set */, 2872 NULL /* needsEarlyUpdate */, 2873 &updateState)) { 2874 nvEvoLogDev(pDevEvo, EVO_LOG_WARN, 2875 "Failed to toggle fliplock for swapgroups."); 2876 } 2877 } 2878 } 2879 2880 if (!nvIsUpdateStateEmpty(pDevEvo, &updateState)) { 2881 nvEvoUpdateAndKickOff(pDispEvo, TRUE, &updateState, 2882 TRUE /* releaseElv */); 2883 } 2884 } 2885