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                               &params);
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, &params);
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, &currentAndNew[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