1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2008-2023 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 /***************************** HW State Routines ***************************\
25 *                                                                           *
26 *         Gsync module                                                      *
27 *                                                                           *
28 \***************************************************************************/
29 
30 #include "core/core.h"
31 
32 // The "ONLY_IF => 'EXTDEV_GSYNC'," condition in sources.def is ignored!
33 
34 #include "nvRmReg.h"
35 #include "core/system.h"
36 #include "core/locks.h"
37 #include "gpu_mgr/gpu_mgr.h"
38 #include "platform/sli/sli.h"
39 #include "gpu/external_device/gsync.h"
40 #include "os/os.h"
41 #include "rmapi/control.h"
42 #include "gpu/external_device/gsync_api.h"
43 
44 #include "gpu/external_device/dac_p2060.h"
45 #include "gpu/external_device/dac_p2061.h"
46 
47 #include "ctrl/ctrl0000/ctrl0000gsync.h"
48 #include "ctrl/ctrl30f1.h"
49 
50 #include "class/cl30f1.h"
51 
52 // local static funcs
53 static NV_STATUS gsyncSetupNullProvider   (OBJGSYNCMGR *pGsyncMgr, NvU32);
54 
55 static OBJGPU   *gsyncGetMasterableGpu(OBJGSYNC *);
56 static NvBool    gsyncIsAnyHeadFramelocked(OBJGSYNC *);
57 
58 static NV_STATUS gsyncGetGpuTopology(OBJGSYNC *,
59             NV30F1_CTRL_GET_GSYNC_GPU_TOPOLOGY_PARAMS*);
60 static NV_STATUS gsyncGetStatusSignals(OBJGSYNC *,
61             NV30F1_CTRL_GSYNC_GET_STATUS_SIGNALS_PARAMS*);
62 static NV_STATUS gsyncGetStatusParams(OBJGSYNC *,
63             NV30F1_CTRL_GSYNC_GET_CONTROL_PARAMS_PARAMS*);
64 static NV_STATUS gsyncSetControlParams(OBJGSYNC *,
65             NV30F1_CTRL_GSYNC_SET_CONTROL_PARAMS_PARAMS*);
66 static NV_STATUS gsyncGetStatusCaps(OBJGSYNC *,
67             NV30F1_CTRL_GSYNC_GET_CAPS_PARAMS*);
68 static NV_STATUS gsyncGetControlSync(OBJGSYNC *,
69             NV30F1_CTRL_GSYNC_GET_CONTROL_SYNC_PARAMS*);
70 static NV_STATUS gsyncSetControlSync(OBJGSYNC *,
71             NV30F1_CTRL_GSYNC_SET_CONTROL_SYNC_PARAMS*);
72 static NV_STATUS gsyncSetControlUnsync(OBJGSYNC *,
73             NV30F1_CTRL_GSYNC_SET_CONTROL_UNSYNC_PARAMS*);
74 static NV_STATUS gsyncGetStatusSync(OBJGSYNC *pGsync,
75             NV30F1_CTRL_GSYNC_GET_STATUS_SYNC_PARAMS* pParams);
76 static NV_STATUS gsyncGetStatus(OBJGSYNC *,
77             NV30F1_CTRL_GSYNC_GET_STATUS_PARAMS*);
78 static NV_STATUS gsyncGetControlTesting(OBJGSYNC *,
79             NV30F1_CTRL_GSYNC_SET_CONTROL_TESTING_PARAMS*);
80 static NV_STATUS gsyncSetControlTesting(OBJGSYNC *,
81             NV30F1_CTRL_GSYNC_SET_CONTROL_TESTING_PARAMS*);
82 static NV_STATUS gsyncSetControlWatchdog(OBJGSYNC *,
83             NV30F1_CTRL_GSYNC_SET_CONTROL_WATCHDOG_PARAMS*);
84 static NV_STATUS gsyncGetControlInterlaceMode(OBJGSYNC *,
85             NV30F1_CTRL_GSYNC_SET_CONTROL_INTERLACE_MODE_PARAMS*);
86 static NV_STATUS gsyncSetControlInterlaceMode(OBJGSYNC *,
87             NV30F1_CTRL_GSYNC_SET_CONTROL_INTERLACE_MODE_PARAMS*);
88 static NV_STATUS gsyncGetControlSwapBarrier(OBJGSYNC *, OBJGPU *,
89             NV30F1_CTRL_GSYNC_GET_CONTROL_SWAP_BARRIER_PARAMS*);
90 static NV_STATUS gsyncSetControlSwapBarrier(OBJGSYNC *, OBJGPU *,
91             NV30F1_CTRL_GSYNC_SET_CONTROL_SWAP_BARRIER_PARAMS*);
92 static NV_STATUS gsyncGetControlSwapLockWindow(OBJGSYNC *,
93             NV30F1_CTRL_GSYNC_GET_CONTROL_SWAP_LOCK_WINDOW_PARAMS*);
94 static NV_STATUS gsyncGetOptimizedTiming(OBJGSYNC *pGsync,
95             NV30F1_CTRL_GSYNC_GET_OPTIMIZED_TIMING_PARAMS* pParams);
96 static NV_STATUS gsyncGetControlStereoLockMode(OBJGSYNC *,
97             NV30F1_CTRL_CMD_GSYNC_GET_CONTROL_STEREO_LOCK_MODE_PARAMS*);
98 static NV_STATUS gsyncSetControlStereoLockMode(OBJGSYNC *,
99             NV30F1_CTRL_CMD_GSYNC_SET_CONTROL_STEREO_LOCK_MODE_PARAMS*);
100 static NV_STATUS gsyncReadRegister(OBJGSYNC *,
101             NV30F1_CTRL_GSYNC_READ_REGISTER_PARAMS *);
102 static NV_STATUS gsyncWriteRegister(OBJGSYNC *,
103             NV30F1_CTRL_GSYNC_WRITE_REGISTER_PARAMS *);
104 static NV_STATUS gsyncSetLocalSync(OBJGSYNC *,
105             NV30F1_CTRL_GSYNC_SET_LOCAL_SYNC_PARAMS*);
106 static NV_STATUS gsyncConfigFlash(OBJGSYNC *,
107             NV30F1_CTRL_CMD_GSYNC_CONFIG_FLASH_PARAMS*);
108 static NV_STATUS gsyncGetHouseSyncMode(OBJGSYNC *pGsync,
109                       NV30F1_CTRL_GSYNC_HOUSE_SYNC_MODE_PARAMS*);
110 static NV_STATUS gsyncSetHouseSyncMode(OBJGSYNC *pGsync,
111                       NV30F1_CTRL_GSYNC_HOUSE_SYNC_MODE_PARAMS*);
112 
113 NV_STATUS
gsyncmgrConstruct_IMPL(OBJGSYNCMGR * pGsyncMgr)114 gsyncmgrConstruct_IMPL(OBJGSYNCMGR *pGsyncMgr)
115 {
116     NvU32 i;
117 
118     NV_PRINTF(LEVEL_INFO, "\n");
119 
120     pGsyncMgr->gsyncCount = 0;
121 
122     for (i = 0; i < NV30F1_MAX_GSYNCS; i++)
123     {
124         portMemSet(&pGsyncMgr->gsyncTable[i], 0, sizeof (OBJGSYNC));
125         gsyncSetupNullProvider(pGsyncMgr, i);
126         pGsyncMgr->gsyncTable[i].gsyncId = NV0000_CTRL_GSYNC_INVALID_ID;
127         // Automatic watchdog scheduling is enabled until 1st manual call.
128         pGsyncMgr->gsyncTable[i].bAutomaticWatchdogScheduling = NV_TRUE;
129         pGsyncMgr->gsyncTable[i].bDoEventFiltering = NV_FALSE;
130     }
131 
132     return NV_OK;
133 }
134 
135 // Destructor
136 void
gsyncmgrDestruct_IMPL(OBJGSYNCMGR * pGsyncMgr)137 gsyncmgrDestruct_IMPL(OBJGSYNCMGR *pGsyncMgr)
138 {
139     OBJGSYNC *pGsync;
140     NvU32 i;
141 
142     NV_PRINTF(LEVEL_INFO, "\n");
143 
144     for (i = 0; i < NV30F1_MAX_GSYNCS; i++)
145     {
146         pGsync = &pGsyncMgr->gsyncTable[i];
147 
148         // NULL everything
149         portMemSet(pGsync, 0, sizeof (OBJGSYNC));
150     }
151 }
152 
153 //
154 // gsyncGetMasterableGpuByInstance
155 // Return a gpu that can be timing master for the specified gsync instance.
156 //
157 POBJGPU
gsyncGetMasterableGpuByInstance(NvU32 gsyncInst)158 gsyncGetMasterableGpuByInstance(NvU32 gsyncInst)
159 {
160     OBJSYS *pSys = SYS_GET_INSTANCE();
161     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
162 
163     if (gsyncInst >= NV30F1_MAX_GSYNCS)
164         return NULL;
165 
166     NV_ASSERT(pGsyncMgr->gsyncTable[gsyncInst].gpuCount > 0);
167 
168     return gsyncGetMasterableGpu(&pGsyncMgr->gsyncTable[gsyncInst]);
169 
170 }
171 
gsyncGetMasterableGpu(OBJGSYNC * pGsync)172 static OBJGPU *gsyncGetMasterableGpu(OBJGSYNC *pGsync)
173 {
174     NvU32 i;
175 
176     for (i = 0; i < pGsync->gpuCount; i++)
177     {
178         if ((pGsync->masterableGpuConnectors & (1 << i)) &&
179             (pGsync->gpus[i].connector != gsync_Connector_None))
180         {
181             return gpumgrGetGpuFromId(pGsync->gpus[i].gpuId);
182         }
183     }
184 
185     NV_PRINTF(LEVEL_ERROR, "Invalid gsync state\n");
186 
187     return NULL;
188 }
189 
190 /*
191  * Set up the function pointers for p2060 gsync object.
192  */
193 static NV_STATUS
gsyncP2060StartupProvider(OBJGSYNC * pGsync)194 gsyncP2060StartupProvider(OBJGSYNC *pGsync)
195 {
196     DACEXTERNALDEVICE      *pExtDev = pGsync->pExtDev;
197     DACP2060EXTERNALDEVICE *p2060   = (DACP2060EXTERNALDEVICE *)pGsync->pExtDev;
198 
199     // All four GPU connectors are masterable on P2060
200     pGsync->masterableGpuConnectors          = ((1 << NV30F1_GSYNC_CONNECTOR_ONE)   |
201                                                 (1 << NV30F1_GSYNC_CONNECTOR_TWO)   |
202                                                 (1 << NV30F1_GSYNC_CONNECTOR_THREE) |
203                                                 (1 << NV30F1_GSYNC_CONNECTOR_FOUR));
204 
205     pGsync->connectorCount                   = NV_P2060_MAX_IFACES_PER_GSYNC;
206 
207     pGsync->gsyncHal.gsyncGpuCanBeMaster     = gsyncGpuCanBeMaster_P2060;
208     pGsync->gsyncHal.gsyncOptimizeTiming     = gsyncOptimizeTimingParameters_P2060;
209 
210     pGsync->gsyncHal.gsyncRefSignal          = gsyncRefSignal_P2060;
211     pGsync->gsyncHal.gsyncRefMaster          = gsyncRefMaster_P2060;
212     pGsync->gsyncHal.gsyncRefSlaves          = gsyncRefSlaves_P2060;
213     pGsync->gsyncHal.gsyncGetCplStatus       = gsyncGetCplStatus_P2060;
214     pGsync->gsyncHal.gsyncSetWatchdog        = gsyncSetWatchdog_P2060;
215     pGsync->gsyncHal.gsyncGetRevision        = gsyncGetRevision_P2060;
216 
217     // Get and Set
218     pGsync->gsyncHal.gsyncGetUseHouse        = gsyncGetUseHouse_P2060;
219     pGsync->gsyncHal.gsyncSetUseHouse        = gsyncSetUseHouse_P2060;
220     pGsync->gsyncHal.gsyncGetSyncPolarity    = gsyncGetSyncPolarity_P2060;
221     pGsync->gsyncHal.gsyncSetSyncPolarity    = gsyncSetSyncPolarity_P2060;
222     pGsync->gsyncHal.gsyncGetVideoMode       = gsyncGetVideoMode_P2060;
223     pGsync->gsyncHal.gsyncSetVideoMode       = gsyncSetVideoMode_P2060;
224     pGsync->gsyncHal.gsyncGetNSync           = gsyncGetNSync_P2060;
225     pGsync->gsyncHal.gsyncSetNSync           = gsyncSetNSync_P2060;
226     pGsync->gsyncHal.gsyncGetSyncSkew        = gsyncGetSyncSkew_P2060;
227     pGsync->gsyncHal.gsyncSetSyncSkew        = gsyncSetSyncSkew_P2060;
228     pGsync->gsyncHal.gsyncGetSyncStartDelay  = gsyncGetSyncStartDelay_P2060;
229     pGsync->gsyncHal.gsyncSetSyncStartDelay  = gsyncSetSyncStartDelay_P2060;
230     pGsync->gsyncHal.gsyncGetEmitTestSignal  = gsyncGetEmitTestSignal_P2060;
231     pGsync->gsyncHal.gsyncSetEmitTestSignal  = gsyncSetEmitTestSignal_P2060;
232     pGsync->gsyncHal.gsyncGetInterlaceMode   = gsyncGetInterlaceMode_P2060;
233     pGsync->gsyncHal.gsyncSetInterlaceMode   = gsyncSetInterlaceMode_P2060;
234     pGsync->gsyncHal.gsyncGetStereoLockMode  = gsyncGetStereoLockMode_P2060;
235     pGsync->gsyncHal.gsyncSetStereoLockMode  = gsyncSetStereoLockMode_P2060;
236     pGsync->gsyncHal.gsyncGetMulDiv          = gsyncGetMulDiv_P2060;
237     pGsync->gsyncHal.gsyncSetMulDiv          = gsyncSetMulDiv_P2060;
238 
239     pGsync->gsyncHal.gsyncRefSwapBarrier     = gsyncRefSwapBarrier_P2060;
240     pGsync->gsyncHal.gsyncSetMosaic          = gsyncSetMosaic_P2060;
241     pGsync->gsyncHal.gsyncConfigFlashGsync   = gsyncConfigFlashGsync_P2060;
242 
243     // Constants to be returned in NV30F1_CTRL_GSYNC_GET_CAPS
244     p2060->syncSkewResolutionInNs = NV_P2060_SYNC_SKEW_RESOLUTION;
245     p2060->syncSkewMax            = gsyncSupportsLargeSyncSkew_P2060(pExtDev) ?
246                                     NV_P2060_SYNC_SKEW_MAX_UNITS_FULL_SUPPORT :
247                                     NV_P2060_SYNC_SKEW_MAX_UNITS_LIMITED_SUPPORT;
248 
249     return NV_OK;
250 }
251 
252 /*
253  * Set up the function pointers for p2061 gsync object.
254  */
255 static NV_STATUS
gsyncP2061StartupProvider(OBJGSYNC * pGsync)256 gsyncP2061StartupProvider(OBJGSYNC *pGsync)
257 {
258     NV_STATUS status;
259     DACP2060EXTERNALDEVICE *p2060 = (DACP2060EXTERNALDEVICE *)pGsync->pExtDev;
260 
261     // Call P2060 startup provider for setting up those HALs that
262     // are identical to P2060.
263     status = gsyncP2060StartupProvider(pGsync);
264 
265     // Hals differ between p2060 and p2061, apply override
266     pGsync->gsyncHal.gsyncGetCplStatus      = gsyncGetCplStatus_P2061;
267 
268     // HALs for P2061 specifically
269     pGsync->gsyncHal.gsyncGetHouseSyncMode  = gsyncGetHouseSyncMode_P2061;
270     pGsync->gsyncHal.gsyncSetHouseSyncMode  = gsyncSetHouseSyncMode_P2061;
271 
272     // SyncSkew is different for FW V2.04+
273     if (P2061_FW_REV(pGsync->pExtDev) >= 0x204)
274     {
275         pGsync->gsyncHal.gsyncGetSyncSkew  = gsyncGetSyncSkew_P2061_V204;
276         pGsync->gsyncHal.gsyncSetSyncSkew  = gsyncSetSyncSkew_P2061_V204;
277 
278         // Constants to be returned in NV30F1_CTRL_GSYNC_GET_CAPS
279         p2060->syncSkewResolutionInNs      = NV_P2061_V204_SYNC_SKEW_RESOLUTION;
280         p2060->syncSkewMax                 = NV_P2061_V204_SYNC_SKEW_MAX_UNITS;
281         p2060->lastUserSkewSent            = NV_P2061_V204_SYNC_SKEW_INVALID;
282     }
283 
284     return status;
285 }
286 
287 /*
288  * This is the general entrance for setting up interfaces for different objects.
289  * We will direct it to a specific start-up provider based on board ID.
290  */
291 static NV_STATUS
gsyncStartupProvider(OBJGSYNC * pGsync,DAC_EXTERNAL_DEVICES externalDevice)292 gsyncStartupProvider
293 (
294     OBJGSYNC *pGsync,
295     DAC_EXTERNAL_DEVICES externalDevice
296 )
297 {
298     switch (externalDevice)
299     {
300         default:
301         case DAC_EXTERNAL_DEVICE_NONE:
302             return NV_OK;
303         case DAC_EXTERNAL_DEVICE_P2060:
304             return gsyncP2060StartupProvider(pGsync);
305         case DAC_EXTERNAL_DEVICE_P2061:
306             return gsyncP2061StartupProvider(pGsync);
307     }
308 }
309 
310 //
311 // gsyncAttachGpu
312 //
313 // Associate this gpu with this gsync. Some gsyncs have primary
314 // and secondary connectors, and it's important to keep track of
315 // that because the primary can talk to the device, whereas the
316 // secondary can only listen. Also, only a display on the primary
317 // connector can be a frame lock master.
318 //
319 NV_STATUS
gsyncAttachGpu(PDACEXTERNALDEVICE pExtDev,OBJGPU * pGpu,GSYNCCONNECTOR connector,OBJGPU * pProxyGpu,DAC_EXTERNAL_DEVICES externalDevice)320 gsyncAttachGpu(PDACEXTERNALDEVICE pExtDev, OBJGPU *pGpu,
321     GSYNCCONNECTOR connector, OBJGPU *pProxyGpu,
322     DAC_EXTERNAL_DEVICES externalDevice)
323 {
324     OBJSYS *pSys = SYS_GET_INSTANCE();
325     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
326     OBJGSYNC    *pGsync = NULL;
327     NvU32 i, j;
328 
329     NV_ASSERT(rmGpuLockIsOwner());
330 
331     // Check to see if we've already attached this gpu
332     for (i = 0; i < NV30F1_MAX_GSYNCS; i++)
333     {
334         for (j = 0; j < pGsyncMgr->gsyncTable[i].gpuCount; j++)
335         {
336             if (pGsyncMgr->gsyncTable[i].gpus[j].gpuId == pGpu->gpuId)
337             {
338                 NV_PRINTF(LEVEL_ERROR, "gpu is %d already attached!\n",
339                           pGpu->gpuId);
340 
341                 return NV_ERR_INVALID_ARGUMENT;
342             }
343         }
344     }
345 
346     // try to match this external device
347     for (i = 0; i < NV30F1_MAX_GSYNCS; i++)
348     {
349         if (pGsyncMgr->gsyncTable[i].pExtDev == pExtDev)
350             break;
351     }
352 
353     // allocate new entry in gsync table if extdev not found
354     if (i == NV30F1_MAX_GSYNCS)
355     {
356         for (i = 0; i < NV30F1_MAX_GSYNCS; i++)
357         {
358             if (pGsyncMgr->gsyncTable[i].gpuCount == 0)
359             {
360                 pGsyncMgr->gsyncCount++;
361                 break;
362             }
363         }
364     }
365 
366     if ((i == NV30F1_MAX_GSYNCS) ||
367         (pGsyncMgr->gsyncTable[i].gpuCount == NV30F1_CTRL_MAX_GPUS_PER_GSYNC))
368     {
369         NV_PRINTF(LEVEL_ERROR, "gsync table full!\n");
370         return NV_ERR_INSUFFICIENT_RESOURCES;
371     }
372 
373     pGsync = &pGsyncMgr->gsyncTable[i];
374 
375     pGsync->pExtDev = pExtDev;
376     pGsync->gpus[pGsync->gpuCount].gpuId = pGpu->gpuId;
377     pGsync->gpus[pGsync->gpuCount].connector = connector;
378     pGsync->gpus[pGsync->gpuCount].proxyGpuId =
379         (pProxyGpu != NULL) ? pProxyGpu->gpuId : NV30F1_CTRL_GPU_INVALID_ID;
380 
381     if (pGsync->gsyncId == NV30F1_CTRL_GPU_INVALID_ID)
382     {
383         // If invalid, GSYNC gsyncId will be any of attached GPU gpuId.
384         pGsync->gsyncId = pGpu->gpuId;
385     }
386 
387     pGsync->gpuCount++;
388 
389     pSys->setProperty(pSys, PDB_PROP_SYS_IS_GSYNC_ENABLED, NV_TRUE);
390 
391     return gsyncStartupProvider(pGsync, externalDevice);
392 }
393 
394 //
395 // gsyncRemoveGpu
396 //
397 // Remove a gpu from this gsync
398 //
399 NV_STATUS
gsyncRemoveGpu(OBJGPU * pGpu)400 gsyncRemoveGpu(OBJGPU *pGpu)
401 {
402     OBJSYS *pSys = SYS_GET_INSTANCE();
403     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
404     OBJGSYNC    *pGsync;
405     NvU32 i, j;
406 
407     NV_ASSERT(rmGpuLockIsOwner());
408 
409     for (i = 0; i < NV30F1_MAX_GSYNCS; i++)
410     {
411         pGsync = &pGsyncMgr->gsyncTable[i];
412 
413         for (j = 0; j < pGsync->gpuCount; j++)
414         {
415             if (pGpu->gpuId == pGsync->gpus[j].gpuId)
416             {
417                 // Careful here: we are modifying one of the test conditions
418                 // for this for loop.
419                 pGsync->gpuCount--;
420 
421                 if (j != pGsync->gpuCount)
422                 {
423                     // copy the last gpu in the array over this one (if this
424                     // isn't already the last element)
425                     portMemCopy(&pGsync->gpus[j],
426                                 sizeof(pGsync->gpus[j]),
427                                 &pGsync->gpus[pGsync->gpuCount],
428                                 sizeof(pGsync->gpus[j]));
429                 }
430 
431                 // zero out the element (which we may have just copied)
432                 portMemSet(&pGsync->gpus[pGsync->gpuCount], 0,
433                          sizeof(pGsync->gpus[pGsync->gpuCount]));
434 
435                 if (pGsync->gpuCount == 0)
436                 {
437                     pGsyncMgr->gsyncCount--;
438                     pGsync->gsyncId = NV0000_CTRL_GSYNC_INVALID_ID;
439                     gsyncSetupNullProvider(pGsyncMgr, i);
440                 }
441 
442                 if (pGsyncMgr->gsyncCount == 0)
443                 {
444                     pSys->setProperty(pSys, PDB_PROP_SYS_IS_GSYNC_ENABLED, NV_FALSE);
445                 }
446                 // If we ever support multiple gsyncs per
447                 // gpu, need to make sure we handle this correctly since we
448                 // are modifying one of our test conditions inside the 'for'
449                 // loop. For now just return from here.
450                 return NV_OK;
451             }
452         }
453     }
454 
455     NV_PRINTF(LEVEL_INFO, "GPU was not found in gsync object\n");
456 
457     return NV_OK;
458 }
459 
460 //
461 // gsyncmgrGetGsync
462 //
463 // This routine returns a OBJGSYNC object associated with this GPU.
464 //
465 POBJGSYNC
gsyncmgrGetGsync(OBJGPU * pGpu)466 gsyncmgrGetGsync(OBJGPU *pGpu)
467 {
468     OBJSYS *pSys = SYS_GET_INSTANCE();
469     OBJGSYNCMGR *pGsyncMgr = NULL;
470     OBJGSYNC    *pGsync    = NULL;
471     NvU32 i, j;
472 
473     if (!RMCFG_FEATURE_EXTDEV_GSYNC)
474         return NULL;
475 
476     if (!pGpu)
477         return NULL;
478 
479     pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
480 
481     for (i = 0; i < NV30F1_MAX_GSYNCS; i++)
482     {
483         pGsync = &pGsyncMgr->gsyncTable[i];
484 
485         for (j = 0; j < pGsync->gpuCount; j++)
486         {
487             if (pGpu->gpuId == pGsync->gpus[j].gpuId)
488             {
489                 return pGsync;
490             }
491         }
492     }
493 
494     return NULL;
495 }
496 
497 //
498 // gsyncGetAttachedIds
499 //
500 // This routine services the NV0000_CTRL_GSYNC_GET_ATTACHED_IDS command.
501 // The passed in gsync table is filled in with the unique gsync value
502 // for each attached gsync.  Any remaining entries in the table
503 // are set to the invalid id value.
504 //
505 NV_STATUS
gsyncGetAttachedIds(NV0000_CTRL_GSYNC_GET_ATTACHED_IDS_PARAMS * pGsyncIdsParams)506 gsyncGetAttachedIds(NV0000_CTRL_GSYNC_GET_ATTACHED_IDS_PARAMS *pGsyncIdsParams)
507 {
508     OBJSYS *pSys = SYS_GET_INSTANCE();
509     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
510     NvU32 *pGsyncIds = &pGsyncIdsParams->gsyncIds[0];
511     NvU32 i, cnt;
512 
513     // fill the table w/valid entries
514     for (cnt = 0, i = 0; i < NV30F1_MAX_GSYNCS; i++)
515     {
516         if (pGsyncMgr->gsyncTable[i].gpuCount > 0)
517         {
518             pGsyncIds[cnt++] = pGsyncMgr->gsyncTable[i].gsyncId;
519         }
520     }
521 
522     // invalidate rest of the entries
523     while (cnt < NV30F1_MAX_GSYNCS)
524         pGsyncIds[cnt++] = NV0000_CTRL_GSYNC_INVALID_ID;
525 
526     return NV_OK;
527 }
528 
529 //
530 // gsyncGetIdInfo
531 //
532 // Special purpose routine that handles NV0000_CTRL_CMD_GSYNC_GET_ID_INFO
533 // requests from clients.
534 //
535 NV_STATUS
gsyncGetIdInfo(NV0000_CTRL_GSYNC_GET_ID_INFO_PARAMS * pGsyncInfo)536 gsyncGetIdInfo(NV0000_CTRL_GSYNC_GET_ID_INFO_PARAMS *pGsyncInfo)
537 {
538     OBJSYS *pSys = SYS_GET_INSTANCE();
539     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
540     NvU32 i;
541 
542     // fill the table w/valid entries
543     for (i = 0; i < NV30F1_MAX_GSYNCS; i++)
544     {
545         if (pGsyncMgr->gsyncTable[i].gpuCount > 0)
546             if (pGsyncInfo->gsyncId == pGsyncMgr->gsyncTable[i].gsyncId)
547                 break;
548     }
549 
550     if (i == NV30F1_MAX_GSYNCS)
551         return NV_ERR_INVALID_ARGUMENT;
552 
553     pGsyncInfo->gsyncInstance = i;
554     pGsyncInfo->gsyncFlags = 0;
555 
556     return NV_OK;
557 }
558 
559 //
560 // gsyncGetGsyncId
561 //
562 // Return the associated gsyncId for the specified gpu.
563 //
564 NvU32
gsyncGetGsyncInstance(OBJGPU * pGpu)565 gsyncGetGsyncInstance(OBJGPU *pGpu)
566 {
567 
568     OBJSYS *pSys = SYS_GET_INSTANCE();
569     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
570     OBJGSYNC *pGsync;
571     NvU32 i, j;
572 
573     for (i = 0; i < NV30F1_MAX_GSYNCS; i++)
574     {
575         pGsync = &pGsyncMgr->gsyncTable[i];
576 
577         for (j = 0; j < pGsync->gpuCount; j++)
578         {
579             if (pGpu->gpuId == pGsync->gpus[j].gpuId)
580                 return i;
581         }
582     }
583 
584     return NV30F1_MAX_GSYNCS;
585 }
586 
587 NvBool
gsyncAreAllGpusInConfigAttachedToSameGsyncBoard(OBJGPU ** pGpus,NvU32 gpuCount)588 gsyncAreAllGpusInConfigAttachedToSameGsyncBoard(OBJGPU **pGpus, NvU32 gpuCount)
589 {
590     OBJSYS *pSys = SYS_GET_INSTANCE();
591     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
592     OBJGSYNC    *pGsync    = NULL;
593     NvBool       bIsGpuFoundInGsync = NV_FALSE;
594     NvU32        gsyncCount = 0, i, j;
595 
596     while(gsyncCount < pGsyncMgr->gsyncCount)
597     {
598         pGsync = &pGsyncMgr->gsyncTable[gsyncCount++];
599         if (pGsync == NULL)
600         {
601             continue;
602         }
603 
604         for (i = 0; i < gpuCount; i++)
605         {
606             // Take any gpu form given pGpus
607             OBJGPU *pGpu = pGpus[i];
608             bIsGpuFoundInGsync = NV_FALSE;
609 
610             for (j = 0; j < pGsync->gpuCount; j++)
611             {
612                if (pGpu->gpuId == pGsync->gpus[j].gpuId)
613                {
614                    bIsGpuFoundInGsync = NV_TRUE;
615                }
616             }
617 
618             if (!bIsGpuFoundInGsync)
619             {
620                 // pGpu is not present under this gsync.
621                 break;
622             }
623         }
624 
625         if (bIsGpuFoundInGsync)
626         {
627            // All `gpu form given pGpus are attached to same gysnc
628            return NV_TRUE;
629         }
630     }
631     return NV_FALSE;
632 }
633 
634 NV_STATUS
gsyncapiCtrlCmdGsyncGetVersion_IMPL(GSyncApi * pGsyncApi,NV30F1_CTRL_GSYNC_GET_VERSION_PARAMS * pGsyncGetVersionParams)635 gsyncapiCtrlCmdGsyncGetVersion_IMPL
636 (
637     GSyncApi *pGsyncApi,
638     NV30F1_CTRL_GSYNC_GET_VERSION_PARAMS *pGsyncGetVersionParams
639 )
640 {
641     pGsyncGetVersionParams->version = NV30F1_CTRL_GSYNC_API_VER;
642     pGsyncGetVersionParams->revision = NV30F1_CTRL_GSYNC_API_REV;
643 
644     return NV_OK;
645 }
646 
647 NV_STATUS
gsyncapiCtrlCmdGetGsyncGpuTopology_IMPL(GSyncApi * pGsyncApi,NV30F1_CTRL_GET_GSYNC_GPU_TOPOLOGY_PARAMS * pParams)648 gsyncapiCtrlCmdGetGsyncGpuTopology_IMPL
649 (
650     GSyncApi *pGsyncApi,
651     NV30F1_CTRL_GET_GSYNC_GPU_TOPOLOGY_PARAMS *pParams
652 )
653 {
654     OBJSYS *pSys = SYS_GET_INSTANCE();
655     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
656     OBJGSYNC *pGsync = &pGsyncMgr->gsyncTable[pGsyncApi->instance];
657 
658     return gsyncGetGpuTopology(pGsync, pParams);
659 }
660 
661 NV_STATUS
gsyncapiCtrlCmdGsyncGetStatusSignals_IMPL(GSyncApi * pGsyncApi,NV30F1_CTRL_GSYNC_GET_STATUS_SIGNALS_PARAMS * pParams)662 gsyncapiCtrlCmdGsyncGetStatusSignals_IMPL
663 (
664     GSyncApi *pGsyncApi,
665     NV30F1_CTRL_GSYNC_GET_STATUS_SIGNALS_PARAMS *pParams
666 )
667 {
668     OBJSYS *pSys = SYS_GET_INSTANCE();
669     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
670     OBJGSYNC *pGsync = &pGsyncMgr->gsyncTable[pGsyncApi->instance];
671 
672     return gsyncGetStatusSignals(pGsync, pParams);
673 }
674 
675 NV_STATUS
gsyncapiCtrlCmdGsyncGetControlParams_IMPL(GSyncApi * pGsyncApi,NV30F1_CTRL_GSYNC_GET_CONTROL_PARAMS_PARAMS * pParams)676 gsyncapiCtrlCmdGsyncGetControlParams_IMPL
677 (
678     GSyncApi *pGsyncApi,
679     NV30F1_CTRL_GSYNC_GET_CONTROL_PARAMS_PARAMS *pParams
680 )
681 {
682     OBJSYS *pSys = SYS_GET_INSTANCE();
683     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
684     OBJGSYNC *pGsync = &pGsyncMgr->gsyncTable[pGsyncApi->instance];
685 
686     return gsyncGetStatusParams(pGsync, pParams);
687 }
688 
689 NV_STATUS
gsyncapiCtrlCmdGsyncSetControlParams_IMPL(GSyncApi * pGsyncApi,NV30F1_CTRL_GSYNC_SET_CONTROL_PARAMS_PARAMS * pParams)690 gsyncapiCtrlCmdGsyncSetControlParams_IMPL
691 (
692     GSyncApi *pGsyncApi,
693     NV30F1_CTRL_GSYNC_SET_CONTROL_PARAMS_PARAMS *pParams
694 )
695 {
696     OBJSYS *pSys = SYS_GET_INSTANCE();
697     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
698     OBJGSYNC *pGsync = &pGsyncMgr->gsyncTable[pGsyncApi->instance];
699 
700     return gsyncSetControlParams(pGsync, pParams);
701 }
702 
703 NV_STATUS
gsyncapiCtrlCmdGsyncGetControlSync_IMPL(GSyncApi * pGsyncApi,NV30F1_CTRL_GSYNC_GET_CONTROL_SYNC_PARAMS * pParams)704 gsyncapiCtrlCmdGsyncGetControlSync_IMPL
705 (
706     GSyncApi *pGsyncApi,
707     NV30F1_CTRL_GSYNC_GET_CONTROL_SYNC_PARAMS *pParams
708 )
709 {
710     OBJSYS *pSys = SYS_GET_INSTANCE();
711     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
712     OBJGSYNC *pGsync = &pGsyncMgr->gsyncTable[pGsyncApi->instance];
713 
714     return gsyncGetControlSync(pGsync, pParams);
715 }
716 
717 NV_STATUS
gsyncapiCtrlCmdGsyncSetControlSync_IMPL(GSyncApi * pGsyncApi,NV30F1_CTRL_GSYNC_SET_CONTROL_SYNC_PARAMS * pParams)718 gsyncapiCtrlCmdGsyncSetControlSync_IMPL
719 (
720     GSyncApi *pGsyncApi,
721     NV30F1_CTRL_GSYNC_SET_CONTROL_SYNC_PARAMS *pParams
722 )
723 {
724     OBJSYS *pSys = SYS_GET_INSTANCE();
725     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
726     OBJGSYNC *pGsync = &pGsyncMgr->gsyncTable[pGsyncApi->instance];
727 
728     return gsyncSetControlSync(pGsync, pParams);
729 }
730 
731 NV_STATUS
gsyncapiCtrlCmdGsyncSetControlUnsync_IMPL(GSyncApi * pGsyncApi,NV30F1_CTRL_GSYNC_SET_CONTROL_UNSYNC_PARAMS * pParams)732 gsyncapiCtrlCmdGsyncSetControlUnsync_IMPL
733 (
734     GSyncApi *pGsyncApi,
735     NV30F1_CTRL_GSYNC_SET_CONTROL_UNSYNC_PARAMS *pParams
736 )
737 {
738     OBJSYS *pSys = SYS_GET_INSTANCE();
739     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
740     OBJGSYNC *pGsync = &pGsyncMgr->gsyncTable[pGsyncApi->instance];
741 
742     return gsyncSetControlUnsync(pGsync, pParams);
743 }
744 
745 NV_STATUS
gsyncapiCtrlCmdGsyncGetStatusSync_IMPL(GSyncApi * pGsyncApi,NV30F1_CTRL_GSYNC_GET_STATUS_SYNC_PARAMS * pParams)746 gsyncapiCtrlCmdGsyncGetStatusSync_IMPL
747 (
748     GSyncApi *pGsyncApi,
749     NV30F1_CTRL_GSYNC_GET_STATUS_SYNC_PARAMS *pParams
750 )
751 {
752     OBJSYS *pSys = SYS_GET_INSTANCE();
753     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
754     OBJGSYNC *pGsync = &pGsyncMgr->gsyncTable[pGsyncApi->instance];
755 
756     return gsyncGetStatusSync(pGsync, pParams);
757 }
758 
759 NV_STATUS
gsyncapiCtrlCmdGsyncGetStatus_IMPL(GSyncApi * pGsyncApi,NV30F1_CTRL_GSYNC_GET_STATUS_PARAMS * pParams)760 gsyncapiCtrlCmdGsyncGetStatus_IMPL
761 (
762     GSyncApi *pGsyncApi,
763     NV30F1_CTRL_GSYNC_GET_STATUS_PARAMS *pParams
764 )
765 {
766     OBJSYS *pSys = SYS_GET_INSTANCE();
767     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
768     OBJGSYNC *pGsync = &pGsyncMgr->gsyncTable[pGsyncApi->instance];
769 
770     return gsyncGetStatus(pGsync, pParams);
771 }
772 
773 NV_STATUS
gsyncapiCtrlCmdGsyncGetControlTesting_IMPL(GSyncApi * pGsyncApi,NV30F1_CTRL_GSYNC_GET_CONTROL_TESTING_PARAMS * pParams)774 gsyncapiCtrlCmdGsyncGetControlTesting_IMPL
775 (
776     GSyncApi *pGsyncApi,
777     NV30F1_CTRL_GSYNC_GET_CONTROL_TESTING_PARAMS *pParams
778 )
779 {
780     OBJSYS *pSys = SYS_GET_INSTANCE();
781     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
782     OBJGSYNC *pGsync = &pGsyncMgr->gsyncTable[pGsyncApi->instance];
783 
784     return gsyncGetControlTesting(pGsync, pParams);
785 }
786 
787 NV_STATUS
gsyncapiCtrlCmdGsyncSetControlTesting_IMPL(GSyncApi * pGsyncApi,NV30F1_CTRL_GSYNC_SET_CONTROL_TESTING_PARAMS * pParams)788 gsyncapiCtrlCmdGsyncSetControlTesting_IMPL
789 (
790     GSyncApi *pGsyncApi,
791     NV30F1_CTRL_GSYNC_SET_CONTROL_TESTING_PARAMS *pParams
792 )
793 {
794     OBJSYS *pSys = SYS_GET_INSTANCE();
795     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
796     OBJGSYNC *pGsync = &pGsyncMgr->gsyncTable[pGsyncApi->instance];
797 
798     return gsyncSetControlTesting(pGsync, pParams);
799 }
800 
801 NV_STATUS
gsyncapiCtrlCmdGsyncSetControlWatchdog_IMPL(GSyncApi * pGsyncApi,NV30F1_CTRL_GSYNC_SET_CONTROL_WATCHDOG_PARAMS * pParams)802 gsyncapiCtrlCmdGsyncSetControlWatchdog_IMPL
803 (
804     GSyncApi *pGsyncApi,
805     NV30F1_CTRL_GSYNC_SET_CONTROL_WATCHDOG_PARAMS *pParams
806 )
807 {
808     OBJSYS *pSys = SYS_GET_INSTANCE();
809     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
810     OBJGSYNC *pGsync = &pGsyncMgr->gsyncTable[pGsyncApi->instance];
811 
812     return gsyncSetControlWatchdog(pGsync, pParams);
813 }
814 
815 NV_STATUS
gsyncapiCtrlCmdGsyncGetControlInterlaceMode_IMPL(GSyncApi * pGsyncApi,NV30F1_CTRL_GSYNC_GET_CONTROL_INTERLACE_MODE_PARAMS * pParams)816 gsyncapiCtrlCmdGsyncGetControlInterlaceMode_IMPL
817 (
818     GSyncApi *pGsyncApi,
819     NV30F1_CTRL_GSYNC_GET_CONTROL_INTERLACE_MODE_PARAMS *pParams
820 )
821 {
822     OBJSYS *pSys = SYS_GET_INSTANCE();
823     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
824     OBJGSYNC *pGsync = &pGsyncMgr->gsyncTable[pGsyncApi->instance];
825 
826     return gsyncGetControlInterlaceMode(pGsync, pParams);
827 }
828 
829 NV_STATUS
gsyncapiCtrlCmdGsyncSetControlInterlaceMode_IMPL(GSyncApi * pGsyncApi,NV30F1_CTRL_GSYNC_SET_CONTROL_INTERLACE_MODE_PARAMS * pParams)830 gsyncapiCtrlCmdGsyncSetControlInterlaceMode_IMPL
831 (
832     GSyncApi *pGsyncApi,
833     NV30F1_CTRL_GSYNC_SET_CONTROL_INTERLACE_MODE_PARAMS *pParams
834 )
835 {
836     OBJSYS *pSys = SYS_GET_INSTANCE();
837     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
838     OBJGSYNC *pGsync = &pGsyncMgr->gsyncTable[pGsyncApi->instance];
839 
840     return gsyncSetControlInterlaceMode(pGsync, pParams);
841 }
842 
843 NV_STATUS
gsyncapiCtrlCmdGsyncGetControlSwapBarrier_IMPL(GSyncApi * pGsyncApi,NV30F1_CTRL_GSYNC_GET_CONTROL_SWAP_BARRIER_PARAMS * pParams)844 gsyncapiCtrlCmdGsyncGetControlSwapBarrier_IMPL
845 (
846     GSyncApi *pGsyncApi,
847     NV30F1_CTRL_GSYNC_GET_CONTROL_SWAP_BARRIER_PARAMS *pParams
848 )
849 {
850     NV_STATUS status = NV_ERR_INVALID_STATE;
851     OBJSYS *pSys = SYS_GET_INSTANCE();
852     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
853     OBJGSYNC *pGsync = &pGsyncMgr->gsyncTable[pGsyncApi->instance];
854     OBJGPU *pGpu = gpumgrGetGpuFromId(pParams->gpuId);
855 
856     if (pGpu == NULL)
857     {
858         return NV_ERR_INVALID_ARGUMENT;
859     }
860 
861     SLI_LOOP_START(SLI_LOOP_FLAGS_NONE)
862     {
863         status = gsyncGetControlSwapBarrier(pGsync, pGpu, pParams);
864         if (status != NV_OK)
865         {
866             SLI_LOOP_BREAK;
867         }
868     }
869     SLI_LOOP_END
870 
871     return status;
872 }
873 
874 NV_STATUS
gsyncapiCtrlCmdGsyncSetControlSwapBarrier_IMPL(GSyncApi * pGsyncApi,NV30F1_CTRL_GSYNC_SET_CONTROL_SWAP_BARRIER_PARAMS * pParams)875 gsyncapiCtrlCmdGsyncSetControlSwapBarrier_IMPL
876 (
877     GSyncApi *pGsyncApi,
878     NV30F1_CTRL_GSYNC_SET_CONTROL_SWAP_BARRIER_PARAMS *pParams
879 )
880 {
881     NV_STATUS status = NV_ERR_INVALID_STATE;
882     OBJSYS *pSys = SYS_GET_INSTANCE();
883     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
884     OBJGSYNC *pGsync = &pGsyncMgr->gsyncTable[pGsyncApi->instance];
885     OBJGPU *pGpu = gpumgrGetGpuFromId(pParams->gpuId);
886 
887     if (pGpu == NULL)
888     {
889         return NV_ERR_INVALID_ARGUMENT;
890     }
891 
892     SLI_LOOP_START(SLI_LOOP_FLAGS_NONE)
893     {
894         status = gsyncSetControlSwapBarrier(pGsync, pGpu, pParams);
895         if (status != NV_OK)
896         {
897             SLI_LOOP_BREAK;
898         }
899     }
900     SLI_LOOP_END
901 
902     return status;
903 }
904 
905 NV_STATUS
gsyncapiCtrlCmdGsyncGetControlSwapLockWindow_IMPL(GSyncApi * pGsyncApi,NV30F1_CTRL_GSYNC_GET_CONTROL_SWAP_LOCK_WINDOW_PARAMS * pParams)906 gsyncapiCtrlCmdGsyncGetControlSwapLockWindow_IMPL
907 (
908     GSyncApi *pGsyncApi,
909     NV30F1_CTRL_GSYNC_GET_CONTROL_SWAP_LOCK_WINDOW_PARAMS *pParams
910 )
911 {
912     OBJSYS *pSys = SYS_GET_INSTANCE();
913     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
914     OBJGSYNC *pGsync = &pGsyncMgr->gsyncTable[pGsyncApi->instance];
915 
916     return gsyncGetControlSwapLockWindow(pGsync, pParams);
917 }
918 
919 NV_STATUS
gsyncapiCtrlCmdGsyncGetCaps_IMPL(GSyncApi * pGsyncApi,NV30F1_CTRL_GSYNC_GET_CAPS_PARAMS * pParams)920 gsyncapiCtrlCmdGsyncGetCaps_IMPL
921 (
922     GSyncApi *pGsyncApi,
923     NV30F1_CTRL_GSYNC_GET_CAPS_PARAMS *pParams
924 )
925 {
926     OBJSYS *pSys = SYS_GET_INSTANCE();
927     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
928     OBJGSYNC *pGsync = &pGsyncMgr->gsyncTable[pGsyncApi->instance];
929 
930     return gsyncGetStatusCaps(pGsync, pParams);
931 }
932 
933 NV_STATUS
gsyncapiCtrlCmdGsyncGetOptimizedTiming_IMPL(GSyncApi * pGsyncApi,NV30F1_CTRL_GSYNC_GET_OPTIMIZED_TIMING_PARAMS * pParams)934 gsyncapiCtrlCmdGsyncGetOptimizedTiming_IMPL
935 (
936     GSyncApi *pGsyncApi,
937     NV30F1_CTRL_GSYNC_GET_OPTIMIZED_TIMING_PARAMS *pParams
938 )
939 {
940     OBJSYS *pSys = SYS_GET_INSTANCE();
941     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
942     OBJGSYNC *pGsync = &pGsyncMgr->gsyncTable[pGsyncApi->instance];
943 
944     return gsyncGetOptimizedTiming(pGsync, pParams);
945 }
946 
947 NV_STATUS
gsyncapiCtrlCmdGsyncSetLocalSync_IMPL(GSyncApi * pGsyncApi,NV30F1_CTRL_GSYNC_SET_LOCAL_SYNC_PARAMS * pParams)948 gsyncapiCtrlCmdGsyncSetLocalSync_IMPL
949 (
950     GSyncApi *pGsyncApi,
951     NV30F1_CTRL_GSYNC_SET_LOCAL_SYNC_PARAMS *pParams
952 )
953 {
954     OBJSYS *pSys = SYS_GET_INSTANCE();
955     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
956     OBJGSYNC *pGsync = &pGsyncMgr->gsyncTable[pGsyncApi->instance];
957 
958     return gsyncSetLocalSync(pGsync, pParams);
959 }
960 
961 NV_STATUS
gsyncapiCtrlCmdGsyncConfigFlash_IMPL(GSyncApi * pGsyncApi,NV30F1_CTRL_CMD_GSYNC_CONFIG_FLASH_PARAMS * pParams)962 gsyncapiCtrlCmdGsyncConfigFlash_IMPL
963 (
964     GSyncApi *pGsyncApi,
965     NV30F1_CTRL_CMD_GSYNC_CONFIG_FLASH_PARAMS *pParams
966 )
967 {
968     OBJSYS *pSys = SYS_GET_INSTANCE();
969     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
970     OBJGSYNC *pGsync = &pGsyncMgr->gsyncTable[pGsyncApi->instance];
971 
972     return gsyncConfigFlash(pGsync, pParams);
973 }
974 
975 NV_STATUS
gsyncapiCtrlCmdGsyncSetEventNotification_IMPL(GSyncApi * pGsyncApi,NV30F1_CTRL_GSYNC_SET_EVENT_NOTIFICATION_PARAMS * pSetEventParams)976 gsyncapiCtrlCmdGsyncSetEventNotification_IMPL
977 (
978     GSyncApi *pGsyncApi,
979     NV30F1_CTRL_GSYNC_SET_EVENT_NOTIFICATION_PARAMS *pSetEventParams
980 )
981 {
982     OBJSYS *pSys = SYS_GET_INSTANCE();
983     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
984     OBJGSYNC *pGsync = &pGsyncMgr->gsyncTable[pGsyncApi->instance];
985     NV_STATUS status = NV_OK;
986 
987     if (NV30F1_CTRL_GSYNC_SET_EVENT_NOTIFICATION_ACTION_DISABLE == pSetEventParams->action)
988     {
989         pGsyncApi->notifyAction = pSetEventParams->action;
990     }
991     else
992     {
993         Notifier *pNotifier = staticCast(pGsyncApi, Notifier);
994         PEVENTNOTIFICATION *ppEventNotifications = NULL;
995 
996         // NV01_EVENT must have been plugged in
997         if (pNotifier->pNotifierShare == NULL)
998             return NV_ERR_INVALID_STATE;
999 
1000         ppEventNotifications = inotifyGetNotificationListPtr(staticCast(pNotifier, INotifier));
1001         if (*ppEventNotifications == NULL)
1002             return NV_ERR_INVALID_STATE;
1003 
1004         if (NV30F1_CTRL_GSYNC_SET_EVENT_NOTIFICATION_ACTION_SMART_ALL & pSetEventParams->action)
1005         {
1006             NvU32 eventNum = 0, tempMask = pSetEventParams->action;
1007 
1008             // If more than one bit is set, the highest on is choosen.
1009             // This is a fallback, we should only be called with one bit set.
1010             NV_ASSERT(ONEBITSET(tempMask));
1011 
1012             // convert mask to array index
1013             while (tempMask >>= 1)
1014             {
1015                 eventNum++;
1016             }
1017 
1018             if (eventNum < NV30F1_CTRL_GSYNC_EVENT_TYPES)
1019             {
1020                 NV_ASSERT_OR_RETURN(pGsyncApi->pEventByType[eventNum] == NULL, NV_ERR_INVALID_STATE);
1021 
1022                 // pull event off of queue, put in the slot we calculated
1023                 pGsyncApi->pEventByType[eventNum] = *ppEventNotifications;
1024                 *ppEventNotifications = (*ppEventNotifications)->Next;
1025                 pGsyncApi->pEventByType[eventNum]->Next = NULL;
1026 
1027                 // add to the master mask
1028                 pGsyncApi->notifyAction |= pSetEventParams->action;
1029             }
1030             pGsyncApi->oldEventNotification = NV_TRUE;
1031             pGsync->bDoEventFiltering = NV_TRUE;
1032         }
1033         else
1034         {
1035             status = NV_ERR_INVALID_ARGUMENT;
1036         }
1037     }
1038     return status;
1039 
1040 }
1041 
1042 NV_STATUS
gsyncapiCtrlCmdGsyncGetControlStereoLockMode_IMPL(GSyncApi * pGsyncApi,NV30F1_CTRL_CMD_GSYNC_GET_CONTROL_STEREO_LOCK_MODE_PARAMS * pParams)1043 gsyncapiCtrlCmdGsyncGetControlStereoLockMode_IMPL
1044 (
1045     GSyncApi *pGsyncApi,
1046     NV30F1_CTRL_CMD_GSYNC_GET_CONTROL_STEREO_LOCK_MODE_PARAMS *pParams
1047 )
1048 {
1049     OBJSYS *pSys = SYS_GET_INSTANCE();
1050     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
1051     OBJGSYNC *pGsync = &pGsyncMgr->gsyncTable[pGsyncApi->instance];
1052 
1053     return gsyncGetControlStereoLockMode(pGsync, pParams);
1054 }
1055 
1056 NV_STATUS
gsyncapiCtrlCmdGsyncSetControlStereoLockMode_IMPL(GSyncApi * pGsyncApi,NV30F1_CTRL_CMD_GSYNC_SET_CONTROL_STEREO_LOCK_MODE_PARAMS * pParams)1057 gsyncapiCtrlCmdGsyncSetControlStereoLockMode_IMPL
1058 (
1059     GSyncApi *pGsyncApi,
1060     NV30F1_CTRL_CMD_GSYNC_SET_CONTROL_STEREO_LOCK_MODE_PARAMS *pParams
1061 )
1062 {
1063     OBJSYS *pSys = SYS_GET_INSTANCE();
1064     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
1065     OBJGSYNC *pGsync = &pGsyncMgr->gsyncTable[pGsyncApi->instance];
1066 
1067     return gsyncSetControlStereoLockMode(pGsync, pParams);
1068 }
1069 
1070 NV_STATUS
gsyncapiCtrlCmdGsyncReadRegister_IMPL(GSyncApi * pGsyncApi,NV30F1_CTRL_GSYNC_READ_REGISTER_PARAMS * pParams)1071 gsyncapiCtrlCmdGsyncReadRegister_IMPL
1072 (
1073     GSyncApi *pGsyncApi,
1074     NV30F1_CTRL_GSYNC_READ_REGISTER_PARAMS *pParams
1075 )
1076 {
1077     OBJSYS *pSys = SYS_GET_INSTANCE();
1078     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
1079     OBJGSYNC *pGsync = &pGsyncMgr->gsyncTable[pGsyncApi->instance];
1080 
1081     return gsyncReadRegister(pGsync, pParams);
1082 }
1083 
1084 NV_STATUS
gsyncapiCtrlCmdGsyncWriteRegister_IMPL(GSyncApi * pGsyncApi,NV30F1_CTRL_GSYNC_WRITE_REGISTER_PARAMS * pParams)1085 gsyncapiCtrlCmdGsyncWriteRegister_IMPL
1086 (
1087     GSyncApi *pGsyncApi,
1088     NV30F1_CTRL_GSYNC_WRITE_REGISTER_PARAMS *pParams
1089 )
1090 {
1091     OBJSYS *pSys = SYS_GET_INSTANCE();
1092     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
1093     OBJGSYNC *pGsync = &pGsyncMgr->gsyncTable[pGsyncApi->instance];
1094 
1095     return gsyncWriteRegister(pGsync, pParams);
1096 }
1097 
1098 NV_STATUS
gsyncapiCtrlCmdGsyncGetHouseSyncMode_IMPL(GSyncApi * pGsyncApi,NV30F1_CTRL_GSYNC_HOUSE_SYNC_MODE_PARAMS * pParams)1099 gsyncapiCtrlCmdGsyncGetHouseSyncMode_IMPL
1100 (
1101     GSyncApi *pGsyncApi,
1102     NV30F1_CTRL_GSYNC_HOUSE_SYNC_MODE_PARAMS *pParams
1103 )
1104 {
1105     OBJSYS *pSys = SYS_GET_INSTANCE();
1106     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
1107     OBJGSYNC *pGsync = &pGsyncMgr->gsyncTable[pGsyncApi->instance];
1108 
1109     return gsyncGetHouseSyncMode(pGsync, pParams);
1110 }
1111 
1112 NV_STATUS
gsyncapiCtrlCmdGsyncSetHouseSyncMode_IMPL(GSyncApi * pGsyncApi,NV30F1_CTRL_GSYNC_HOUSE_SYNC_MODE_PARAMS * pParams)1113 gsyncapiCtrlCmdGsyncSetHouseSyncMode_IMPL
1114 (
1115     GSyncApi *pGsyncApi,
1116     NV30F1_CTRL_GSYNC_HOUSE_SYNC_MODE_PARAMS *pParams
1117 )
1118 {
1119     OBJSYS *pSys = SYS_GET_INSTANCE();
1120     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
1121     OBJGSYNC *pGsync = &pGsyncMgr->gsyncTable[pGsyncApi->instance];
1122 
1123     return gsyncSetHouseSyncMode(pGsync, pParams);
1124 }
1125 
1126 NV_STATUS
gsyncGetGpuTopology(OBJGSYNC * pGsync,NV30F1_CTRL_GET_GSYNC_GPU_TOPOLOGY_PARAMS * pParams)1127 gsyncGetGpuTopology(OBJGSYNC *pGsync,
1128             NV30F1_CTRL_GET_GSYNC_GPU_TOPOLOGY_PARAMS* pParams)
1129 {
1130     NvU32 i;
1131 
1132     for (i = 0; i < NV30F1_CTRL_MAX_GPUS_PER_GSYNC; i++)
1133     {
1134         if (i < pGsync->gpuCount &&
1135             pGsync->gpus[i].connector <= NV30F1_GSYNC_CONNECTOR_COUNT)
1136         {
1137             pParams->gpus[i].gpuId      = pGsync->gpus[i].gpuId;
1138             pParams->gpus[i].connector  = pGsync->gpus[i].connector;
1139             pParams->gpus[i].proxyGpuId = pGsync->gpus[i].proxyGpuId;
1140         }
1141         else
1142         {
1143             pParams->gpus[i].gpuId = NV30F1_CTRL_GPU_INVALID_ID;
1144         }
1145     }
1146     pParams->connectorCount = pGsync->connectorCount;
1147 
1148     return NV_OK;
1149 }
1150 
1151 //
1152 // gsyncIsAnyHeadFramelocked
1153 //
1154 // Returns NV_TRUE if any of the heads attached to any of the gpus
1155 // attached to the gsync object is framelocked. NV_FALSE otherwise.
1156 NvBool
gsyncIsAnyHeadFramelocked(OBJGSYNC * pGsync)1157 gsyncIsAnyHeadFramelocked(OBJGSYNC *pGsync)
1158 {
1159     if (pGsync && pGsync->pExtDev)
1160     {
1161         OBJGPU *pGpu = NULL;
1162         NvU32 i;
1163         NvU32 refresh, assigned;
1164 
1165         // Loop over all gpus of the gsync object.
1166         for (i = 0; i < pGsync->gpuCount; i++)
1167         {
1168             pGpu = gpumgrGetGpuFromId(pGsync->gpus[i].gpuId);
1169 
1170             if (pGpu)
1171             {
1172                 // Check if assigned slaves displays are there.
1173                 if ((NV_OK == pGsync->gsyncHal.gsyncRefSlaves(pGpu,
1174                      pGsync->pExtDev, refRead, &assigned, &refresh)) &&
1175                     (assigned != 0))
1176                 {
1177                     return NV_TRUE;
1178                 }
1179                 // Check if assigned master displays are there.
1180                 if ((NV_OK == pGsync->gsyncHal.gsyncRefMaster(pGpu,
1181                      pGsync->pExtDev, refRead, &assigned, &refresh, NV_FALSE, NV_FALSE)) &&
1182                     (assigned != 0))
1183                 {
1184                     return NV_TRUE;
1185                 }
1186             }
1187         }
1188     }
1189 
1190     return NV_FALSE;
1191 }
1192 
1193 NV_STATUS
gsyncGetStatusSignals(OBJGSYNC * pGsync,NV30F1_CTRL_GSYNC_GET_STATUS_SIGNALS_PARAMS * pParams)1194 gsyncGetStatusSignals(OBJGSYNC *pGsync,
1195             NV30F1_CTRL_GSYNC_GET_STATUS_SIGNALS_PARAMS* pParams)
1196 {
1197     NvBool bRate; // whether or not to test the rate.
1198     NV_STATUS status = NV_OK;
1199     OBJGPU *pGpu = NULL;
1200     REFTYPE rType = refFetchGet;
1201 
1202     NV_ASSERT_OR_RETURN(pGsync && pGsync->pExtDev, NV_ERR_INVALID_DEVICE);
1203 
1204     pGpu = gsyncGetMasterableGpu(pGsync);
1205 
1206     bRate = !! (pParams->rate & NV30F1_CTRL_GSYNC_GET_STATUS_SIGNALS_RJ45_0);
1207     status |= pGsync->gsyncHal.gsyncRefSignal(pGpu, pGsync->pExtDev, rType,
1208             gsync_Signal_RJ45_0, bRate, &pParams->RJ45[0]);
1209 
1210     bRate = !! (pParams->rate & NV30F1_CTRL_GSYNC_GET_STATUS_SIGNALS_RJ45_1);
1211     status |= pGsync->gsyncHal.gsyncRefSignal(pGpu, pGsync->pExtDev, rType,
1212             gsync_Signal_RJ45_1, bRate, &pParams->RJ45[1]);
1213 
1214     bRate = !! (pParams->rate & NV30F1_CTRL_GSYNC_GET_SIGNALS_HOUSE);
1215     status |= pGsync->gsyncHal.gsyncRefSignal(pGpu, pGsync->pExtDev, rType,
1216             gsync_Signal_House, bRate, &pParams->house);
1217 
1218     return status;
1219 }
1220 
1221 NV_STATUS
gsyncGetStatusParams(OBJGSYNC * pGsync,NV30F1_CTRL_GSYNC_GET_CONTROL_PARAMS_PARAMS * pParams)1222 gsyncGetStatusParams(OBJGSYNC *pGsync,
1223             NV30F1_CTRL_GSYNC_GET_CONTROL_PARAMS_PARAMS* pParams)
1224 {
1225     OBJGPU *pGpu = NULL;
1226     GSYNCSYNCPOLARITY SyncPolarity = pParams->syncPolarity;
1227     GSYNCVIDEOMODE VideoMode   = pParams->syncVideoMode;
1228     NV_STATUS status = NV_OK;
1229 
1230     NV_ASSERT_OR_RETURN(pGsync && pGsync->pExtDev, NV_ERR_INVALID_DEVICE);
1231 
1232     pGpu = gsyncGetMasterableGpu(pGsync);
1233 
1234     if ( pParams->which & NV30F1_CTRL_GSYNC_GET_CONTROL_SYNC_POLARITY )
1235     {
1236         NV_CHECK_OK_OR_CAPTURE_FIRST_ERROR(status, LEVEL_INFO, pGsync->gsyncHal.gsyncGetSyncPolarity(pGpu, pGsync->pExtDev, &SyncPolarity));
1237         pParams->syncPolarity = (NvU32)SyncPolarity;
1238     }
1239 
1240     if ( pParams->which & NV30F1_CTRL_GSYNC_GET_CONTROL_VIDEO_MODE )
1241     {
1242         NV_CHECK_OK_OR_CAPTURE_FIRST_ERROR(status, LEVEL_INFO, pGsync->gsyncHal.gsyncGetVideoMode(pGpu, pGsync->pExtDev, &VideoMode));
1243         pParams->syncVideoMode = (NvU32)VideoMode;
1244     }
1245 
1246     if ( pParams->which & NV30F1_CTRL_GSYNC_GET_CONTROL_NSYNC )
1247     {
1248         NV_CHECK_OK_OR_CAPTURE_FIRST_ERROR(status, LEVEL_INFO, pGsync->gsyncHal.gsyncGetNSync(pGpu, pGsync->pExtDev, &pParams->nSync));
1249     }
1250 
1251     if ( pParams->which & NV30F1_CTRL_GSYNC_GET_CONTROL_SYNC_SKEW )
1252     {
1253         NV_CHECK_OK_OR_CAPTURE_FIRST_ERROR(status, LEVEL_INFO, pGsync->gsyncHal.gsyncGetSyncSkew(pGpu, pGsync->pExtDev, &pParams->syncSkew));
1254     }
1255 
1256     if ( pParams->which & NV30F1_CTRL_GSYNC_GET_CONTROL_SYNC_START_DELAY )
1257     {
1258         NV_CHECK_OK_OR_CAPTURE_FIRST_ERROR(status, LEVEL_INFO, pGsync->gsyncHal.gsyncGetSyncStartDelay(pGpu, pGsync->pExtDev, &pParams->syncStartDelay));
1259     }
1260 
1261     if ( pParams->which & NV30F1_CTRL_GSYNC_GET_CONTROL_SYNC_USE_HOUSE )
1262     {
1263         NV_CHECK_OK_OR_CAPTURE_FIRST_ERROR(status, LEVEL_INFO, pGsync->gsyncHal.gsyncGetUseHouse(pGpu, pGsync->pExtDev, &pParams->useHouseSync));
1264     }
1265 
1266     if ( pParams->which & NV30F1_CTRL_GSYNC_GET_CONTROL_SYNC_MULTIPLY_DIVIDE )
1267     {
1268         NV_CHECK_OK_OR_CAPTURE_FIRST_ERROR(status, LEVEL_INFO, pGsync->gsyncHal.gsyncGetMulDiv(pGpu, pGsync->pExtDev, &pParams->syncMulDiv));
1269     }
1270 
1271     return status;
1272 }
1273 
1274 NV_STATUS
gsyncSetControlParams(OBJGSYNC * pGsync,NV30F1_CTRL_GSYNC_SET_CONTROL_PARAMS_PARAMS * pParams)1275 gsyncSetControlParams(OBJGSYNC *pGsync,
1276             NV30F1_CTRL_GSYNC_SET_CONTROL_PARAMS_PARAMS* pParams)
1277 {
1278     OBJGPU *pGpu = NULL;
1279     GSYNCSYNCPOLARITY SyncPolarity = pParams->syncPolarity;
1280     GSYNCVIDEOMODE VideoMode   = pParams->syncVideoMode;
1281     NV_STATUS status = NV_OK;
1282 
1283     NV_ASSERT_OR_RETURN(pGsync && pGsync->pExtDev, NV_ERR_INVALID_DEVICE);
1284 
1285     pGpu = gsyncGetMasterableGpu(pGsync);
1286 
1287     if ( pParams->which & NV30F1_CTRL_GSYNC_SET_CONTROL_SYNC_POLARITY )
1288     {
1289         status |= pGsync->gsyncHal.gsyncSetSyncPolarity(pGpu, pGsync->pExtDev, SyncPolarity);
1290         pParams->syncPolarity = (NvU32)SyncPolarity;
1291     }
1292 
1293     if ( pParams->which & NV30F1_CTRL_GSYNC_SET_CONTROL_VIDEO_MODE )
1294     {
1295         status |= pGsync->gsyncHal.gsyncSetVideoMode(pGpu, pGsync->pExtDev, VideoMode);
1296         pParams->syncVideoMode = (NvU32)VideoMode;
1297     }
1298 
1299     if ( pParams->which & NV30F1_CTRL_GSYNC_SET_CONTROL_NSYNC )
1300     {
1301         status |= pGsync->gsyncHal.gsyncSetNSync(pGpu, pGsync->pExtDev, pParams->nSync);
1302     }
1303 
1304     if ( pParams->which & NV30F1_CTRL_GSYNC_SET_CONTROL_SYNC_SKEW )
1305     {
1306         status |= pGsync->gsyncHal.gsyncSetSyncSkew(pGpu, pGsync->pExtDev, pParams->syncSkew);
1307     }
1308 
1309     if ( pParams->which & NV30F1_CTRL_GSYNC_SET_CONTROL_SYNC_START_DELAY )
1310     {
1311         status |= pGsync->gsyncHal.gsyncSetSyncStartDelay(pGpu, pGsync->pExtDev, pParams->syncStartDelay);
1312     }
1313 
1314     if ( pParams->which & NV30F1_CTRL_GSYNC_SET_CONTROL_SYNC_USE_HOUSE )
1315     {
1316         status |= pGsync->gsyncHal.gsyncSetUseHouse(pGpu, pGsync->pExtDev, pParams->useHouseSync);
1317     }
1318 
1319     if ( pParams->which & NV30F1_CTRL_GSYNC_SET_CONTROL_SYNC_MULTIPLY_DIVIDE )
1320     {
1321         status |= pGsync->gsyncHal.gsyncSetMulDiv(pGpu, pGsync->pExtDev, &pParams->syncMulDiv);
1322     }
1323 
1324     return status;
1325 }
1326 
gsyncGetStatusCaps(OBJGSYNC * pGsync,NV30F1_CTRL_GSYNC_GET_CAPS_PARAMS * pParams)1327 NV_STATUS gsyncGetStatusCaps(OBJGSYNC *pGsync,
1328             NV30F1_CTRL_GSYNC_GET_CAPS_PARAMS* pParams)
1329 {
1330     OBJGPU *pGpu = NULL;
1331     NV_STATUS status = NV_OK;
1332 
1333     NV_ASSERT_OR_RETURN(pGsync && pGsync->pExtDev, NV_ERR_INVALID_DEVICE);
1334 
1335     pGpu = gsyncGetMasterableGpu(pGsync);
1336 
1337     status |= pGsync->gsyncHal.gsyncGetRevision(pGpu, pGsync->pExtDev, pParams);
1338 
1339     return status;
1340 }
1341 
1342 static NvBool
gsyncIsGpuInGsync(OBJGPU * pGpu,OBJGSYNC * pGsync)1343 gsyncIsGpuInGsync(OBJGPU *pGpu, OBJGSYNC *pGsync)
1344 {
1345     NvU32 gpuCount;
1346 
1347     if (!pGpu || !pGsync)
1348     {
1349         return NV_FALSE;
1350     }
1351 
1352     for (gpuCount = 0; gpuCount < NV30F1_CTRL_MAX_GPUS_PER_GSYNC; gpuCount++)
1353     {
1354         if (pGpu->gpuId == pGsync->gpus[gpuCount].gpuId)
1355         {
1356             return NV_TRUE;
1357         }
1358     }
1359 
1360     return NV_FALSE;
1361 }
1362 
1363 NV_STATUS
gsyncSetLocalSync(OBJGSYNC * pGsync,NV30F1_CTRL_GSYNC_SET_LOCAL_SYNC_PARAMS * pParams)1364 gsyncSetLocalSync(OBJGSYNC *pGsync,
1365             NV30F1_CTRL_GSYNC_SET_LOCAL_SYNC_PARAMS* pParams)
1366 {
1367     OBJGPU *pSourceGpu = NULL;
1368     OBJGPU *pTempGpu = NULL;
1369     NvU32 i;
1370     NV_STATUS status = NV_OK;
1371 
1372     NV_ASSERT_OR_RETURN(pGsync && pGsync->pExtDev, NV_ERR_INVALID_DEVICE);
1373 
1374     pSourceGpu = gpumgrGetGpuFromId(pParams->gpuTimingSource);
1375     if (pSourceGpu == NULL)
1376     {
1377         return NV_ERR_INVALID_ARGUMENT;
1378     }
1379 
1380     if(!gsyncIsGpuInGsync(pSourceGpu, pGsync))
1381     {
1382         return NV_ERR_INVALID_ARGUMENT;
1383     }
1384 
1385     if (pParams->slaveGpuCount > NV30F1_CTRL_MAX_GPUS_PER_GSYNC)
1386     {
1387         return NV_ERR_INVALID_ARGUMENT;
1388     }
1389 
1390     for (i = 0; i < pParams->slaveGpuCount; i++)
1391     {
1392         pTempGpu = gpumgrGetGpuFromId(pParams->gpuTimingSlaves[i]);
1393         if (pTempGpu == NULL)
1394         {
1395             return NV_ERR_INVALID_ARGUMENT;
1396         }
1397 
1398         if(!gsyncIsGpuInGsync(pTempGpu, pGsync))
1399         {
1400             return NV_ERR_INVALID_ARGUMENT;
1401         }
1402     }
1403 
1404     status |= pGsync->gsyncHal.gsyncSetMosaic(pSourceGpu, pGsync->pExtDev, pParams);
1405 
1406     return status;
1407 }
1408 
1409 NV_STATUS
gsyncConfigFlash(OBJGSYNC * pGsync,NV30F1_CTRL_CMD_GSYNC_CONFIG_FLASH_PARAMS * pParams)1410 gsyncConfigFlash(OBJGSYNC *pGsync,
1411             NV30F1_CTRL_CMD_GSYNC_CONFIG_FLASH_PARAMS* pParams)
1412 {
1413     OBJGPU *pGpu = NULL;
1414     NV_STATUS status = NV_OK;
1415 
1416     NV_ASSERT_OR_RETURN(pGsync && pGsync->pExtDev, NV_ERR_INVALID_DEVICE);
1417 
1418     pGpu = gpumgrGetGpuFromId(pParams->gpuId);
1419     if (pGpu == NULL)
1420     {
1421         return NV_ERR_INVALID_ARGUMENT;
1422     }
1423 
1424     if(!gsyncIsGpuInGsync(pGpu, pGsync))
1425     {
1426         return NV_ERR_INVALID_ARGUMENT;
1427     }
1428 
1429     status |= pGsync->gsyncHal.gsyncConfigFlashGsync(pGpu, pGsync->pExtDev,
1430                   pParams->preFlash);
1431 
1432     return status;
1433 }
1434 
1435 NV_STATUS
gsyncGetControlSync(OBJGSYNC * pGsync,NV30F1_CTRL_GSYNC_GET_CONTROL_SYNC_PARAMS * pParams)1436 gsyncGetControlSync(OBJGSYNC *pGsync,
1437             NV30F1_CTRL_GSYNC_GET_CONTROL_SYNC_PARAMS* pParams)
1438 {
1439     OBJGPU *pGpu = NULL;
1440     NV_STATUS status = NV_OK;
1441 
1442     NV_ASSERT_OR_RETURN(pGsync && pGsync->pExtDev, NV_ERR_INVALID_DEVICE);
1443 
1444     pGpu = gpumgrGetGpuFromId(pParams->gpuId);
1445     if (pGpu == NULL)
1446     {
1447         return NV_ERR_INVALID_ARGUMENT;
1448     }
1449 
1450     if(!gsyncIsGpuInGsync(pGpu, pGsync))
1451     {
1452         return NV_ERR_INVALID_ARGUMENT;
1453     }
1454 
1455     if ( pParams->displays == 0 )
1456     {
1457         // This is the case where we want to query what is current.
1458         if ( pParams->master )
1459         {
1460             status |= pGsync->gsyncHal.gsyncRefMaster(pGpu, pGsync->pExtDev, refFetchGet,
1461                 &pParams->displays, &pParams->refresh, NV_FALSE, NV_FALSE);
1462         }
1463         else
1464         {
1465             status |= pGsync->gsyncHal.gsyncRefSlaves(pGpu, pGsync->pExtDev, refFetchGet,
1466                 &pParams->displays, &pParams->refresh);
1467         }
1468     }
1469     else
1470     {
1471         // This is where we want to see if the given Display is assignable
1472         // to this DisplaySync unit under the current conditions (mode, etc).
1473         // If there is no mode then this is definitely a failure.
1474         RM_API   *pRmApi      = GPU_GET_PHYSICAL_RMAPI(pGpu);
1475         NvU32     hClient     = pGpu->hInternalClient;
1476         NvU32     hSubdevice  = pGpu->hInternalSubdevice;
1477         NV2080_CTRL_INTERNAL_GSYNC_IS_DISPLAYID_VALID_PARAMS ctrlParams = {0};
1478 
1479         ctrlParams.displays = pParams->displays;
1480         status = pRmApi->Control(pRmApi, hClient, hSubdevice,
1481                                  NV2080_CTRL_CMD_INTERNAL_GSYNC_IS_DISPLAYID_VALID,
1482                                  &ctrlParams, sizeof(ctrlParams));
1483 
1484         if (status != NV_OK)
1485         {
1486             pParams->displays = 0; // Signals failure to start with.
1487                                    // If we find a head with this as its currenty bound
1488                                    // display then we'll signal success.
1489             NV_PRINTF(LEVEL_ERROR, "Extdev display IDs for the display doesn't exist!\n");
1490         }
1491         else
1492         {
1493             // Also check if this display is capable of being server
1494             pParams->master = pGsync->gsyncHal.gsyncGpuCanBeMaster(pGpu, pGsync->pExtDev);
1495             pParams->displays = ctrlParams.displayId;
1496         }
1497     }
1498 
1499     return status;
1500 }
1501 
1502 NV_STATUS
gsyncSetControlSync(OBJGSYNC * pGsync,NV30F1_CTRL_GSYNC_SET_CONTROL_SYNC_PARAMS * pParams)1503 gsyncSetControlSync(OBJGSYNC *pGsync,
1504             NV30F1_CTRL_GSYNC_SET_CONTROL_SYNC_PARAMS* pParams)
1505 {
1506     OBJGPU *pGpu = NULL;
1507     NV_STATUS status = NV_OK;
1508     NvU32 assigned, refresh;
1509 
1510     NV_ASSERT_OR_RETURN(pGsync && pGsync->pExtDev, NV_ERR_INVALID_DEVICE);
1511 
1512     pGpu = gpumgrGetGpuFromId(pParams->gpuId);
1513     if (pGpu == NULL)
1514     {
1515         return NV_ERR_INVALID_ARGUMENT;
1516     }
1517 
1518     if(!gsyncIsGpuInGsync(pGpu, pGsync))
1519     {
1520         return NV_ERR_INVALID_ARGUMENT;
1521     }
1522 
1523     if (pParams->refresh == 0)
1524     {
1525         return NV_ERR_INVALID_ARGUMENT;
1526     }
1527 
1528     if (pParams->master)
1529     {
1530         NvBool skipSwapBarrierWar = !!(pParams->configFlags &
1531             NV30F1_CTRL_GSYNC_GET_CONTROL_SYNC_CONFIG_FLAGS_KEEP_MASTER_SWAPBARRIER_DISABLED);
1532 
1533         status |= pGsync->gsyncHal.gsyncRefMaster(pGpu, pGsync->pExtDev,
1534             refRead, &assigned, &refresh, NV_FALSE, NV_FALSE);
1535         pParams->displays |= assigned;
1536         status |= pGsync->gsyncHal.gsyncRefMaster(pGpu, pGsync->pExtDev,
1537             refSetCommit, &pParams->displays, &pParams->refresh, NV_FALSE, skipSwapBarrierWar);
1538     }
1539     else
1540     {
1541         status |= pGsync->gsyncHal.gsyncRefSlaves(pGpu, pGsync->pExtDev,
1542             refRead, &assigned, &refresh);
1543         pParams->displays |= assigned;
1544         status |= pGsync->gsyncHal.gsyncRefSlaves(pGpu, pGsync->pExtDev,
1545             refSetCommit, &pParams->displays, &pParams->refresh);
1546     }
1547 
1548     // Update watchdog here.
1549     // Only do that is client doesn't take care.
1550     if ((pGsync->bAutomaticWatchdogScheduling) && (NV_OK == status) &&
1551         (0 != pParams->displays))
1552     {
1553         NvU32 enable = 1;
1554         if (NV_OK != pGsync->gsyncHal.gsyncSetWatchdog(pGpu, pGsync->pExtDev, enable))
1555         {
1556             // Only assert as the master/slave assignment has succeded.
1557             NV_ASSERT(0);
1558         }
1559     }
1560 
1561     return status;
1562 }
1563 
1564 NV_STATUS
gsyncSetControlUnsync(OBJGSYNC * pGsync,NV30F1_CTRL_GSYNC_SET_CONTROL_UNSYNC_PARAMS * pParams)1565 gsyncSetControlUnsync(OBJGSYNC *pGsync,
1566             NV30F1_CTRL_GSYNC_SET_CONTROL_UNSYNC_PARAMS* pParams)
1567 {
1568     OBJGPU *pGpu = NULL;
1569     NV_STATUS status = NV_OK;
1570     NvU32 assigned, refresh;
1571 
1572     NV_ASSERT_OR_RETURN(pGsync && pGsync->pExtDev, NV_ERR_INVALID_DEVICE);
1573 
1574     pGpu = gpumgrGetGpuFromId(pParams->gpuId);
1575     if (pGpu == NULL)
1576     {
1577         return NV_ERR_INVALID_ARGUMENT;
1578     }
1579 
1580     if(!gsyncIsGpuInGsync(pGpu, pGsync))
1581     {
1582         return NV_ERR_INVALID_ARGUMENT;
1583     }
1584 
1585     if (pParams->master)
1586     {
1587         status |= pGsync->gsyncHal.gsyncRefMaster(pGpu, pGsync->pExtDev,
1588             refRead, &assigned, &refresh, NV_FALSE, NV_FALSE);
1589         pParams->displays = assigned & ~pParams->displays;
1590         status |= pGsync->gsyncHal.gsyncRefMaster(pGpu, pGsync->pExtDev,
1591             refSetCommit, &pParams->displays, &refresh, !!pParams->retainMaster, NV_FALSE);
1592     }
1593     else
1594     {
1595         status |= pGsync->gsyncHal.gsyncRefSlaves(pGpu, pGsync->pExtDev,
1596             refRead, &assigned, &refresh);
1597         pParams->displays = assigned & ~pParams->displays;
1598         status |= pGsync->gsyncHal.gsyncRefSlaves(pGpu, pGsync->pExtDev,
1599             refSetCommit, &pParams->displays, &refresh);
1600     }
1601 
1602     // Update watchdog here: if no master or slave is
1603     // remaining on the gsync device, disable watchdog.
1604     // Only do that is client doesn't take care.
1605     if ((pGsync->bAutomaticWatchdogScheduling) &&
1606         (NV_OK == status) && (0 == pParams->displays) &&
1607         (!(gsyncIsAnyHeadFramelocked(pGsync))))
1608     {
1609         NvU32 enable = 0;
1610         // Only print erromessages as the
1611         if (NV_OK != pGsync->gsyncHal.gsyncSetWatchdog(pGpu, pGsync->pExtDev, enable))
1612         {
1613             // Only assert as the master/slave unassignment has succeded.
1614             NV_ASSERT(0);
1615         }
1616     }
1617 
1618     return status;
1619 }
1620 
1621 NV_STATUS
gsyncGetStatusSync(OBJGSYNC * pGsync,NV30F1_CTRL_GSYNC_GET_STATUS_SYNC_PARAMS * pParams)1622 gsyncGetStatusSync(OBJGSYNC *pGsync, NV30F1_CTRL_GSYNC_GET_STATUS_SYNC_PARAMS* pParams)
1623 {
1624     OBJGPU *pGpu = NULL;
1625     NV_STATUS status = NV_OK;
1626 
1627     NV_ASSERT_OR_RETURN(pGsync && pGsync->pExtDev, NV_ERR_INVALID_DEVICE);
1628 
1629     pGpu = gpumgrGetGpuFromId(pParams->gpuId);
1630     if (pGpu == NULL)
1631     {
1632         return NV_ERR_INVALID_ARGUMENT;
1633     }
1634 
1635     if(!gsyncIsGpuInGsync(pGpu, pGsync))
1636     {
1637         return NV_ERR_INVALID_ARGUMENT;
1638     }
1639 
1640     status |= pGsync->gsyncHal.gsyncGetCplStatus(pGpu, pGsync->pExtDev,
1641               gsync_Status_bTiming, &pParams->bTiming);
1642 
1643     status |= pGsync->gsyncHal.gsyncGetCplStatus(pGpu, pGsync->pExtDev,
1644               gsync_Status_bStereoSync, &pParams->bStereoSync);
1645 
1646     status |= pGsync->gsyncHal.gsyncGetCplStatus(pGpu, pGsync->pExtDev,
1647               gsync_Status_bSyncReady, &pParams->bSyncReady);
1648 
1649     return status;
1650 }
1651 
1652 
1653 NV_STATUS
gsyncGetStatus(OBJGSYNC * pGsync,NV30F1_CTRL_GSYNC_GET_STATUS_PARAMS * pParams)1654 gsyncGetStatus(OBJGSYNC *pGsync, NV30F1_CTRL_GSYNC_GET_STATUS_PARAMS* pParams)
1655 {
1656     OBJGPU *pGpu = NULL;
1657     NV_STATUS status = NV_OK;
1658 
1659     NV_ASSERT_OR_RETURN(pGsync && pGsync->pExtDev, NV_ERR_INVALID_DEVICE);
1660 
1661     pGpu = gsyncGetMasterableGpu(pGsync);
1662 
1663     if (pParams->which & NV30F1_CTRL_GSYNC_GET_STATUS_SYNC_POLARITY)
1664     {
1665         GSYNCSYNCPOLARITY SyncPolarity = gsync_SyncPolarity_RisingEdge;
1666 
1667         NV_CHECK_OK_OR_CAPTURE_FIRST_ERROR(status, LEVEL_INFO,
1668             pGsync->gsyncHal.gsyncGetSyncPolarity(pGpu, pGsync->pExtDev,
1669             &SyncPolarity));
1670 
1671         if (status == NV_OK)
1672         {
1673             pParams->bLeadingEdge = (SyncPolarity == gsync_SyncPolarity_BothEdges ||
1674                                     SyncPolarity == gsync_SyncPolarity_RisingEdge);
1675 
1676             pParams->bFallingEdge = (SyncPolarity == gsync_SyncPolarity_BothEdges ||
1677                                     SyncPolarity == gsync_SyncPolarity_FallingEdge);
1678         }
1679     }
1680 
1681     if (pParams->which & NV30F1_CTRL_GSYNC_GET_STATUS_SYNC_DELAY)
1682     {
1683         NV_CHECK_OK_OR_CAPTURE_FIRST_ERROR(status, LEVEL_INFO,
1684             pGsync->gsyncHal.gsyncGetSyncStartDelay(pGpu, pGsync->pExtDev,
1685             &pParams->syncDelay));
1686     }
1687 
1688     if (pParams->which & NV30F1_CTRL_GSYNC_GET_STATUS_REFRESH)
1689     {
1690         NV_CHECK_OK_OR_CAPTURE_FIRST_ERROR(status, LEVEL_INFO,
1691             pGsync->gsyncHal.gsyncGetCplStatus(pGpu, pGsync->pExtDev,
1692             gsync_Status_Refresh, &pParams->refresh));
1693     }
1694 
1695     if (pParams->which & NV30F1_CTRL_GSYNC_GET_STATUS_HOUSE_SYNC_INCOMING)
1696     {
1697          NV_CHECK_OK_OR_CAPTURE_FIRST_ERROR(status, LEVEL_INFO,
1698             pGsync->gsyncHal.gsyncGetCplStatus(pGpu, pGsync->pExtDev,
1699             gsync_Status_HouseSyncIncoming, &pParams->houseSyncIncoming));
1700     }
1701 
1702     if (pParams->which & NV30F1_CTRL_GSYNC_GET_STATUS_SYNC_INTERVAL)
1703     {
1704         NV_CHECK_OK_OR_CAPTURE_FIRST_ERROR(status, LEVEL_INFO,
1705             pGsync->gsyncHal.gsyncGetNSync(pGpu, pGsync->pExtDev,
1706             &pParams->syncInterval));
1707     }
1708 
1709     if (pParams->which & NV30F1_CTRL_GSYNC_GET_STATUS_SYNC_READY)
1710     {
1711         NV_CHECK_OK_OR_CAPTURE_FIRST_ERROR(status, LEVEL_INFO,
1712             pGsync->gsyncHal.gsyncGetCplStatus(pGpu, pGsync->pExtDev,
1713             gsync_Status_bSyncReady, &pParams->bSyncReady));
1714     }
1715 
1716     if (pParams->which & NV30F1_CTRL_GSYNC_GET_STATUS_SWAP_READY)
1717     {
1718         NV_CHECK_OK_OR_CAPTURE_FIRST_ERROR(status, LEVEL_INFO,
1719             pGsync->gsyncHal.gsyncGetCplStatus(pGpu, pGsync->pExtDev,
1720             gsync_Status_bSwapReady, &pParams->bSwapReady));
1721     }
1722 
1723     if (pParams->which & NV30F1_CTRL_GSYNC_GET_STATUS_HOUSE_SYNC)
1724     {
1725         NV_CHECK_OK_OR_CAPTURE_FIRST_ERROR(status, LEVEL_INFO,
1726             pGsync->gsyncHal.gsyncGetCplStatus(pGpu, pGsync->pExtDev,
1727             gsync_Status_bHouseSync, &pParams->bHouseSync));
1728     }
1729 
1730     if (pParams->which & NV30F1_CTRL_GSYNC_GET_STATUS_PORT_INPUT)
1731     {
1732         NV_CHECK_OK_OR_CAPTURE_FIRST_ERROR(status, LEVEL_INFO,
1733             pGsync->gsyncHal.gsyncGetCplStatus(pGpu, pGsync->pExtDev,
1734             gsync_Status_bPort0Input, &pParams->bPort0Input));
1735         NV_CHECK_OK_OR_CAPTURE_FIRST_ERROR(status, LEVEL_INFO,
1736             pGsync->gsyncHal.gsyncGetCplStatus(pGpu, pGsync->pExtDev,
1737             gsync_Status_bPort1Input, &pParams->bPort1Input));
1738     }
1739 
1740     if (pParams->which & NV30F1_CTRL_GSYNC_GET_STATUS_PORT_ETHERNET)
1741     {
1742         NV_CHECK_OK_OR_CAPTURE_FIRST_ERROR(status, LEVEL_INFO,
1743             pGsync->gsyncHal.gsyncGetCplStatus(pGpu, pGsync->pExtDev,
1744             gsync_Status_bPort0Ethernet, &pParams->bPort0Ethernet));
1745         NV_CHECK_OK_OR_CAPTURE_FIRST_ERROR(status, LEVEL_INFO,
1746             pGsync->gsyncHal.gsyncGetCplStatus(pGpu, pGsync->pExtDev,
1747             gsync_Status_bPort1Ethernet, &pParams->bPort1Ethernet));
1748     }
1749 
1750     if (pParams->which & NV30F1_CTRL_GSYNC_GET_STATUS_UNIVERSAL_FRAME_COUNT)
1751     {
1752         NV_CHECK_OK_OR_CAPTURE_FIRST_ERROR(status, LEVEL_INFO,
1753             pGsync->gsyncHal.gsyncGetCplStatus(pGpu, pGsync->pExtDev,
1754             gsync_Status_UniversalFrameCount, &pParams->universalFrameCount));
1755     }
1756 
1757     if (pParams->which & NV30F1_CTRL_GSYNC_GET_STATUS_INTERNAL_SLAVE)
1758     {
1759         NV_CHECK_OK_OR_CAPTURE_FIRST_ERROR(status, LEVEL_INFO,
1760             pGsync->gsyncHal.gsyncGetCplStatus(pGpu, pGsync->pExtDev,
1761             gsync_Status_bInternalSlave, &pParams->bInternalSlave));
1762     }
1763 
1764     return status;
1765 }
1766 
1767 NV_STATUS
gsyncGetControlTesting(OBJGSYNC * pGsync,NV30F1_CTRL_GSYNC_SET_CONTROL_TESTING_PARAMS * pParams)1768 gsyncGetControlTesting(OBJGSYNC *pGsync,
1769             NV30F1_CTRL_GSYNC_SET_CONTROL_TESTING_PARAMS* pParams)
1770 {
1771     OBJGPU *pGpu = NULL;
1772     NV_STATUS status = NV_OK;
1773 
1774     NV_ASSERT_OR_RETURN(pGsync && pGsync->pExtDev, NV_ERR_INVALID_DEVICE);
1775 
1776     pGpu = gsyncGetMasterableGpu(pGsync);
1777 
1778     status = pGsync->gsyncHal.gsyncGetEmitTestSignal(pGpu, pGsync->pExtDev,
1779              &pParams->bEmitTestSignal);
1780 
1781     return status;
1782 }
1783 
1784 NV_STATUS
gsyncSetControlTesting(OBJGSYNC * pGsync,NV30F1_CTRL_GSYNC_SET_CONTROL_TESTING_PARAMS * pParams)1785 gsyncSetControlTesting(OBJGSYNC *pGsync,
1786             NV30F1_CTRL_GSYNC_SET_CONTROL_TESTING_PARAMS* pParams)
1787 {
1788     OBJGPU *pGpu = NULL;
1789     NV_STATUS status = NV_OK;
1790 
1791     NV_ASSERT_OR_RETURN(pGsync && pGsync->pExtDev, NV_ERR_INVALID_DEVICE);
1792 
1793     pGpu = gsyncGetMasterableGpu(pGsync);
1794 
1795     status = pGsync->gsyncHal.gsyncSetEmitTestSignal(pGpu, pGsync->pExtDev,
1796              pParams->bEmitTestSignal);
1797 
1798     return status;
1799 }
1800 
1801 NV_STATUS
gsyncSetControlWatchdog(OBJGSYNC * pGsync,NV30F1_CTRL_GSYNC_SET_CONTROL_WATCHDOG_PARAMS * pParams)1802 gsyncSetControlWatchdog(OBJGSYNC *pGsync,
1803             NV30F1_CTRL_GSYNC_SET_CONTROL_WATCHDOG_PARAMS* pParams)
1804 {
1805     OBJGPU *pGpu = NULL;
1806     NV_STATUS status = NV_OK;
1807 
1808     NV_ASSERT_OR_RETURN(pGsync && pGsync->pExtDev, NV_ERR_INVALID_DEVICE);
1809 
1810     pGpu = gsyncGetMasterableGpu(pGsync);
1811 
1812     // Client indicates it's taking care
1813     // and doesn't want any automatic solution.
1814     pGsync->bAutomaticWatchdogScheduling = NV_FALSE;
1815 
1816     status = pGsync->gsyncHal.gsyncSetWatchdog(pGpu, pGsync->pExtDev,
1817              pParams->enable);
1818 
1819     return status;
1820 }
1821 
1822 NV_STATUS
gsyncGetControlInterlaceMode(OBJGSYNC * pGsync,NV30F1_CTRL_GSYNC_SET_CONTROL_INTERLACE_MODE_PARAMS * pParams)1823 gsyncGetControlInterlaceMode(OBJGSYNC *pGsync,
1824             NV30F1_CTRL_GSYNC_SET_CONTROL_INTERLACE_MODE_PARAMS* pParams)
1825 {
1826     OBJGPU *pGpu = NULL;
1827     NV_STATUS status = NV_OK;
1828 
1829     NV_ASSERT_OR_RETURN(pGsync && pGsync->pExtDev, NV_ERR_INVALID_DEVICE);
1830 
1831     pGpu = gsyncGetMasterableGpu(pGsync);
1832 
1833     status = pGsync->gsyncHal.gsyncGetInterlaceMode(pGpu, pGsync->pExtDev,
1834              &pParams->enable);
1835 
1836     return status;
1837 }
1838 
1839 NV_STATUS
gsyncSetControlInterlaceMode(OBJGSYNC * pGsync,NV30F1_CTRL_GSYNC_SET_CONTROL_INTERLACE_MODE_PARAMS * pParams)1840 gsyncSetControlInterlaceMode(OBJGSYNC *pGsync,
1841             NV30F1_CTRL_GSYNC_SET_CONTROL_INTERLACE_MODE_PARAMS* pParams)
1842 {
1843     OBJGPU *pGpu = NULL;
1844     NV_STATUS status = NV_OK;
1845 
1846     NV_ASSERT_OR_RETURN(pGsync && pGsync->pExtDev, NV_ERR_INVALID_DEVICE);
1847 
1848     pGpu = gsyncGetMasterableGpu(pGsync);
1849 
1850     status = pGsync->gsyncHal.gsyncSetInterlaceMode(pGpu, pGsync->pExtDev,
1851              pParams->enable);
1852 
1853     return status;
1854 }
1855 
1856 NV_STATUS
gsyncGetControlSwapBarrier(OBJGSYNC * pGsync,OBJGPU * pGpu,NV30F1_CTRL_GSYNC_GET_CONTROL_SWAP_BARRIER_PARAMS * pParams)1857 gsyncGetControlSwapBarrier(OBJGSYNC *pGsync, OBJGPU *pGpu,
1858             NV30F1_CTRL_GSYNC_GET_CONTROL_SWAP_BARRIER_PARAMS* pParams)
1859 {
1860     REFTYPE rType = refFetchGet;
1861     NV_STATUS status = NV_OK;
1862 
1863     NV_ASSERT_OR_RETURN(pGsync && pGsync->pExtDev, NV_ERR_INVALID_DEVICE);
1864 
1865     status = pGsync->gsyncHal.gsyncRefSwapBarrier(pGpu, pGsync->pExtDev,
1866         rType, &pParams->enable);
1867 
1868     return status;
1869 }
1870 
1871 NV_STATUS
gsyncSetControlSwapBarrier(OBJGSYNC * pGsync,OBJGPU * pGpu,NV30F1_CTRL_GSYNC_SET_CONTROL_SWAP_BARRIER_PARAMS * pParams)1872 gsyncSetControlSwapBarrier(OBJGSYNC *pGsync, OBJGPU *pGpu,
1873             NV30F1_CTRL_GSYNC_SET_CONTROL_SWAP_BARRIER_PARAMS* pParams)
1874 {
1875     REFTYPE rType = refSetCommit;
1876     NV_STATUS status = NV_OK;
1877 
1878     NV_ASSERT_OR_RETURN(pGsync && pGsync->pExtDev, NV_ERR_INVALID_DEVICE);
1879 
1880     status = pGsync->gsyncHal.gsyncRefSwapBarrier(pGpu, pGsync->pExtDev,
1881         rType, &pParams->enable);
1882 
1883     return status;
1884 }
1885 
1886 NV_STATUS
gsyncGetControlSwapLockWindow(OBJGSYNC * pGsync,NV30F1_CTRL_GSYNC_GET_CONTROL_SWAP_LOCK_WINDOW_PARAMS * pParams)1887 gsyncGetControlSwapLockWindow(OBJGSYNC *pGsync,
1888                NV30F1_CTRL_GSYNC_GET_CONTROL_SWAP_LOCK_WINDOW_PARAMS* pParams)
1889 {
1890     OBJGPU *pGpu = NULL;
1891     NvU32 data = 0;
1892     NV_STATUS status = NV_OK;
1893 
1894     NV_ASSERT_OR_RETURN(pGsync && pGsync->pExtDev, NV_ERR_INVALID_DEVICE);
1895 
1896     pGpu = gsyncGetMasterableGpu(pGsync);
1897     if (pGpu == NULL)
1898     {
1899         return NV_ERR_GENERIC;
1900     }
1901 
1902     if (osReadRegistryDword(pGpu,
1903         NV_REG_STR_TIME_SWAP_RDY_HI_MODIFY_SWAP_LOCKOUT_START, &data) != NV_OK)
1904     {
1905         // Bug 967618 - default value for tSwapRdyHi is 250 micro seconds.
1906         pParams->tSwapRdyHi =
1907           NV_REG_STR_TIME_SWAP_RDY_HI_MODIFY_SWAP_LOCKOUT_START_DEFAULT;
1908     }
1909     else
1910     {
1911         // regkey added value for tSwapRdyHi i.e. swap lock window.
1912         pParams->tSwapRdyHi = data;
1913     }
1914 
1915     return status;
1916 }
1917 
1918 NV_STATUS
gsyncGetOptimizedTiming(OBJGSYNC * pGsync,NV30F1_CTRL_GSYNC_GET_OPTIMIZED_TIMING_PARAMS * pParams)1919 gsyncGetOptimizedTiming(OBJGSYNC *pGsync,
1920             NV30F1_CTRL_GSYNC_GET_OPTIMIZED_TIMING_PARAMS* pParams)
1921 {
1922     OBJGPU *pGpu = NULL;
1923 
1924     NV_STATUS status = NV_OK;
1925 
1926     NV_ASSERT_OR_RETURN(pGsync && pGsync->pExtDev, NV_ERR_INVALID_DEVICE);
1927 
1928     pGpu = gpumgrGetGpuFromId(pParams->gpuId);
1929     if (pGpu == NULL)
1930     {
1931         return NV_ERR_INVALID_ARGUMENT;
1932     }
1933 
1934     status |= pGsync->gsyncHal.gsyncOptimizeTiming(pGpu, pParams);
1935 
1936     return status;
1937 }
1938 
1939 NV_STATUS
gsyncGetControlStereoLockMode(OBJGSYNC * pGsync,NV30F1_CTRL_CMD_GSYNC_GET_CONTROL_STEREO_LOCK_MODE_PARAMS * pParams)1940 gsyncGetControlStereoLockMode(OBJGSYNC *pGsync,
1941             NV30F1_CTRL_CMD_GSYNC_GET_CONTROL_STEREO_LOCK_MODE_PARAMS *pParams)
1942 {
1943     OBJGPU *pGpu = NULL;
1944     NV_ASSERT_OR_RETURN(pGsync && pGsync->pExtDev, NV_ERR_INVALID_DEVICE);
1945 
1946     pGpu = gpumgrGetGpuFromId(pParams->gpuId);
1947     if (pGpu == NULL)
1948     {
1949         return NV_ERR_INVALID_ARGUMENT;
1950     }
1951 
1952     return pGsync->gsyncHal.gsyncGetStereoLockMode(pGpu, pGsync->pExtDev,
1953            &pParams->enable);
1954 }
1955 
1956 NV_STATUS
gsyncSetControlStereoLockMode(OBJGSYNC * pGsync,NV30F1_CTRL_CMD_GSYNC_SET_CONTROL_STEREO_LOCK_MODE_PARAMS * pParams)1957 gsyncSetControlStereoLockMode(OBJGSYNC *pGsync,
1958             NV30F1_CTRL_CMD_GSYNC_SET_CONTROL_STEREO_LOCK_MODE_PARAMS *pParams)
1959 {
1960     OBJGPU *pGpu = NULL;
1961     NV_ASSERT_OR_RETURN(pGsync && pGsync->pExtDev, NV_ERR_INVALID_DEVICE);
1962 
1963     pGpu = gpumgrGetGpuFromId(pParams->gpuId);
1964     if (pGpu == NULL)
1965     {
1966         return NV_ERR_INVALID_ARGUMENT;
1967     }
1968 
1969     return pGsync->gsyncHal.gsyncSetStereoLockMode(pGpu, pGsync->pExtDev,
1970            pParams->enable);
1971 }
1972 
1973 static NV_STATUS
gsyncReadRegister(OBJGSYNC * pGsync,NV30F1_CTRL_GSYNC_READ_REGISTER_PARAMS * pParams)1974 gsyncReadRegister(OBJGSYNC *pGsync,
1975                   NV30F1_CTRL_GSYNC_READ_REGISTER_PARAMS *pParams)
1976 {
1977     OBJGPU *pGpu = NULL;
1978     NvU32 i;
1979 
1980     NV_ASSERT_OR_RETURN(pGsync && pGsync->pExtDev, NV_ERR_INVALID_DEVICE);
1981 
1982     for (i = 0; i < NV30F1_CTRL_MAX_GPUS_PER_GSYNC && i < pGsync->gpuCount; i++)
1983     {
1984         if (pParams->gpuId == pGsync->gpus[i].gpuId)
1985         {
1986             pGpu = gpumgrGetGpuFromId(pGsync->gpus[i].gpuId);
1987             break;
1988         }
1989     }
1990 
1991     if (!pGpu)
1992     {
1993         return NV_ERR_INVALID_ARGUMENT;
1994     }
1995 
1996     return readregu008_extdeviceTargeted(pGpu,
1997                                          pGsync->pExtDev,
1998                                          pParams->reg,
1999                                          &pParams->data);
2000 }
2001 
2002 static NV_STATUS
gsyncWriteRegister(OBJGSYNC * pGsync,NV30F1_CTRL_GSYNC_WRITE_REGISTER_PARAMS * pParams)2003 gsyncWriteRegister(OBJGSYNC *pGsync,
2004                    NV30F1_CTRL_GSYNC_WRITE_REGISTER_PARAMS *pParams)
2005 {
2006     OBJGPU *pGpu = NULL;
2007     NvU32 i;
2008 
2009     NV_ASSERT_OR_RETURN(pGsync && pGsync->pExtDev, NV_ERR_INVALID_DEVICE);
2010 
2011     for (i = 0; i < NV30F1_CTRL_MAX_GPUS_PER_GSYNC && i < pGsync->gpuCount; i++)
2012     {
2013         if (pParams->gpuId == pGsync->gpus[i].gpuId)
2014         {
2015             pGpu = gpumgrGetGpuFromId(pGsync->gpus[i].gpuId);
2016             break;
2017         }
2018     }
2019 
2020     if (!pGpu)
2021     {
2022         return NV_ERR_INVALID_ARGUMENT;
2023     }
2024 
2025     return writeregu008_extdeviceTargeted(pGpu,
2026                                           pGsync->pExtDev,
2027                                           pParams->reg,
2028                                           pParams->data);
2029 }
2030 
2031 NvBool
gsyncIsInstanceValid(NvU32 gsyncInstance)2032 gsyncIsInstanceValid(NvU32 gsyncInstance)
2033 {
2034     OBJSYS *pSys = SYS_GET_INSTANCE();
2035     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
2036     OBJGSYNC *pGsync;
2037     OBJGPU *pGpu;
2038     DACEXTERNALDEVICE *pExtDev;
2039 
2040     if (gsyncInstance >= NV30F1_MAX_GSYNCS)
2041         return NV_FALSE;
2042 
2043     pGsync = &pGsyncMgr->gsyncTable[gsyncInstance];
2044 
2045     if (pGsync->gpuCount == 0)
2046         return NV_FALSE;
2047 
2048     pGpu = gsyncGetMasterableGpu(pGsync);
2049     // make sure we don't dereference a NULL ptr if the primary gpu
2050     // was already freed.
2051     if (pGpu == NULL)
2052         return NV_FALSE;
2053 
2054     pExtDev = pGsync->pExtDev;
2055 
2056     return pExtDev->pI->Validate(pGpu,pExtDev);
2057 }
2058 
2059 
2060 //
2061 // gsyncSignalServiceRequested
2062 //
2063 // Something has happened on this Gsync.  Signal interested clients.
2064 //
2065 NV_STATUS
gsyncSignalServiceRequested(NvU32 gsyncInst,NvU32 eventFlags,NvU32 iface)2066 gsyncSignalServiceRequested(NvU32 gsyncInst, NvU32 eventFlags, NvU32 iface)
2067 {
2068     OBJSYS *pSys = SYS_GET_INSTANCE();
2069     OBJGSYNCMGR *pGsyncMgr = SYS_GET_GSYNCMGR(pSys);
2070     OBJGSYNC *pGsync;
2071 
2072     if (gsyncInst >= NV30F1_MAX_GSYNCS)
2073         return NV_ERR_GENERIC;
2074 
2075     pGsync = &pGsyncMgr->gsyncTable[gsyncInst];
2076 
2077     if (pGsync->gpuCount == 0)
2078         return NV_ERR_GENERIC;
2079 
2080     if (pGsync->bDoEventFiltering)
2081     {
2082         eventFlags = gsyncFilterEvents(eventFlags, iface);
2083     }
2084 
2085     CliNotifyGsyncEvent(gsyncInst, eventFlags);
2086 
2087     return NV_OK;
2088 }
2089 
2090 static NV_STATUS
gsyncGetHouseSyncMode(OBJGSYNC * pGsync,NV30F1_CTRL_GSYNC_HOUSE_SYNC_MODE_PARAMS * pParams)2091 gsyncGetHouseSyncMode(OBJGSYNC *pGsync,
2092                       NV30F1_CTRL_GSYNC_HOUSE_SYNC_MODE_PARAMS *pParams)
2093 {
2094     OBJGPU *pGpu = NULL;
2095 
2096     NV_ASSERT_OR_RETURN(pGsync && pGsync->pExtDev, NV_ERR_INVALID_DEVICE);
2097 
2098     pGpu = gsyncGetMasterableGpu(pGsync);
2099 
2100     return pGsync->gsyncHal.gsyncGetHouseSyncMode(pGpu, pGsync->pExtDev,
2101                                                   &pParams->houseSyncMode);
2102 }
2103 
2104 static NV_STATUS
gsyncSetHouseSyncMode(OBJGSYNC * pGsync,NV30F1_CTRL_GSYNC_HOUSE_SYNC_MODE_PARAMS * pParams)2105 gsyncSetHouseSyncMode(OBJGSYNC *pGsync,
2106                       NV30F1_CTRL_GSYNC_HOUSE_SYNC_MODE_PARAMS *pParams)
2107 {
2108     OBJGPU *pGpu = NULL;
2109 
2110     NV_ASSERT_OR_RETURN(pGsync && pGsync->pExtDev, NV_ERR_INVALID_DEVICE);
2111 
2112     pGpu = gsyncGetMasterableGpu(pGsync);
2113 
2114     return pGsync->gsyncHal.gsyncSetHouseSyncMode(pGpu, pGsync->pExtDev,
2115                                                   pParams->houseSyncMode);
2116 }
2117 
2118 static NvBool
gsyncNullGpuCanBeMaster(OBJGPU * pGpu,PDACEXTERNALDEVICE pExtDev)2119 gsyncNullGpuCanBeMaster
2120 (
2121     OBJGPU            *pGpu,
2122     PDACEXTERNALDEVICE pExtDev
2123 )
2124 {
2125     return NV_FALSE;
2126 }
2127 
2128 static NV_STATUS
gsyncNullOptimizeTimingParameters(OBJGPU * pGpu,GSYNCTIMINGPARAMS * pParams)2129 gsyncNullOptimizeTimingParameters
2130 (
2131     OBJGPU         *pGpu,
2132     GSYNCTIMINGPARAMS *pParams
2133 )
2134 {
2135     return NV_ERR_GENERIC;
2136 }
2137 
2138 static NV_STATUS
gsyncNullGetStereoLockMode(OBJGPU * pGpu,PDACEXTERNALDEVICE pExtDev,NvU32 * val)2139 gsyncNullGetStereoLockMode
2140 (
2141     OBJGPU              *pGpu,
2142     PDACEXTERNALDEVICE   pExtDev,
2143     NvU32                *val
2144 )
2145 {
2146     return NV_ERR_GENERIC;
2147 }
2148 
2149 static NV_STATUS
gsyncNullSetStereoLockMode(OBJGPU * pGpu,PDACEXTERNALDEVICE pExtDev,NvU32 val)2150 gsyncNullSetStereoLockMode
2151 (
2152     OBJGPU              *pGpu,
2153     PDACEXTERNALDEVICE   pExtDev,
2154     NvU32                val
2155 )
2156 {
2157     return NV_ERR_GENERIC;
2158 }
2159 
2160 static NV_STATUS
gsyncNullGetSyncPolarity(OBJGPU * pGpu,PDACEXTERNALDEVICE pExtDev,GSYNCSYNCPOLARITY * polarity)2161 gsyncNullGetSyncPolarity
2162 (
2163  OBJGPU       *pGpu,
2164  PDACEXTERNALDEVICE pExtDev,
2165  GSYNCSYNCPOLARITY *polarity
2166 )
2167 {
2168     return NV_ERR_GENERIC;
2169 }
2170 
2171 static NV_STATUS
gsyncNullSetSyncPolarity(OBJGPU * pGpu,PDACEXTERNALDEVICE pExtDev,GSYNCSYNCPOLARITY polarity)2172 gsyncNullSetSyncPolarity
2173 (
2174  OBJGPU       *pGpu,
2175  PDACEXTERNALDEVICE pExtDev,
2176  GSYNCSYNCPOLARITY polarity
2177 )
2178 {
2179     return NV_ERR_GENERIC;
2180 }
2181 
2182 static NV_STATUS
gsyncNullGetVideoMode(OBJGPU * pGpu,PDACEXTERNALDEVICE pExtDev,GSYNCVIDEOMODE * videoMode)2183 gsyncNullGetVideoMode
2184 (
2185  OBJGPU       *pGpu,
2186  PDACEXTERNALDEVICE pExtDev,
2187  GSYNCVIDEOMODE *videoMode
2188 )
2189 {
2190     return NV_ERR_GENERIC;
2191 }
2192 
2193 static NV_STATUS
gsyncNullSetVideoMode(OBJGPU * pGpu,PDACEXTERNALDEVICE pExtDev,GSYNCVIDEOMODE videoMode)2194 gsyncNullSetVideoMode
2195 (
2196  OBJGPU       *pGpu,
2197  PDACEXTERNALDEVICE pExtDev,
2198  GSYNCVIDEOMODE videoMode
2199 )
2200 {
2201     return NV_ERR_GENERIC;
2202 }
2203 
2204 static NV_STATUS
gsyncNullGetNSync(OBJGPU * pGpu,PDACEXTERNALDEVICE pExtDev,NvU32 * count)2205 gsyncNullGetNSync
2206 (
2207  OBJGPU       *pGpu,
2208  PDACEXTERNALDEVICE pExtDev,
2209  NvU32 *count
2210 )
2211 {
2212     return NV_ERR_GENERIC;
2213 }
2214 
2215 static NV_STATUS
gsyncNullSetNSync(OBJGPU * pGpu,PDACEXTERNALDEVICE pExtDev,NvU32 count)2216 gsyncNullSetNSync
2217 (
2218  OBJGPU       *pGpu,
2219  PDACEXTERNALDEVICE pExtDev,
2220  NvU32 count
2221 )
2222 {
2223     return NV_ERR_GENERIC;
2224 }
2225 
2226 static NV_STATUS
gsyncNullGetSyncSkew(OBJGPU * pGpu,PDACEXTERNALDEVICE pExtDev,NvU32 * skew)2227 gsyncNullGetSyncSkew
2228 (
2229  OBJGPU       *pGpu,
2230  PDACEXTERNALDEVICE pExtDev,
2231  NvU32 *skew
2232 )
2233 {
2234     return NV_ERR_GENERIC;
2235 }
2236 
2237 static NV_STATUS
gsyncNullSetSyncSkew(OBJGPU * pGpu,PDACEXTERNALDEVICE pExtDev,NvU32 skew)2238 gsyncNullSetSyncSkew
2239 (
2240  OBJGPU       *pGpu,
2241  PDACEXTERNALDEVICE pExtDev,
2242  NvU32 skew
2243 )
2244 {
2245     return NV_ERR_GENERIC;
2246 }
2247 
2248 static NV_STATUS
gsyncNullGetUseHouse(OBJGPU * pGpu,PDACEXTERNALDEVICE pExtDev,NvU32 * val)2249 gsyncNullGetUseHouse
2250 (
2251  OBJGPU       *pGpu,
2252  PDACEXTERNALDEVICE pExtDev,
2253  NvU32 *val
2254 )
2255 {
2256     return NV_ERR_GENERIC;
2257 }
2258 
2259 static NV_STATUS
gsyncNullSetUseHouse(OBJGPU * pGpu,PDACEXTERNALDEVICE pExtDev,NvU32 val)2260 gsyncNullSetUseHouse
2261 (
2262  OBJGPU       *pGpu,
2263  PDACEXTERNALDEVICE pExtDev,
2264  NvU32 val
2265 )
2266 {
2267     return NV_ERR_GENERIC;
2268 }
2269 
2270 static NV_STATUS
gsyncNullGetSyncStartDelay(OBJGPU * pGpu,PDACEXTERNALDEVICE pExtDev,NvU32 * delay)2271 gsyncNullGetSyncStartDelay
2272 (
2273  OBJGPU       *pGpu,
2274  PDACEXTERNALDEVICE pExtDev,
2275  NvU32 *delay
2276 )
2277 {
2278     return NV_ERR_GENERIC;
2279 }
2280 
2281 static NV_STATUS
gsyncNullSetSyncStartDelay(OBJGPU * pGpu,PDACEXTERNALDEVICE pExtDev,NvU32 delay)2282 gsyncNullSetSyncStartDelay
2283 (
2284  OBJGPU       *pGpu,
2285  PDACEXTERNALDEVICE pExtDev,
2286  NvU32 delay
2287 )
2288 {
2289     return NV_ERR_GENERIC;
2290 }
2291 
2292 static NV_STATUS
gsyncNullGetEmitTestSignal(OBJGPU * pGpu,PDACEXTERNALDEVICE pExtDev,NvU32 * val)2293 gsyncNullGetEmitTestSignal
2294 (
2295  OBJGPU       *pGpu,
2296  PDACEXTERNALDEVICE pExtDev,
2297  NvU32 *val
2298 )
2299 {
2300     return NV_ERR_GENERIC;
2301 }
2302 
2303 static NV_STATUS
gsyncNullSetEmitTestSignal(OBJGPU * pGpu,PDACEXTERNALDEVICE pExtDev,NvU32 val)2304 gsyncNullSetEmitTestSignal
2305 (
2306  OBJGPU       *pGpu,
2307  PDACEXTERNALDEVICE pExtDev,
2308  NvU32 val
2309 )
2310 {
2311     return NV_ERR_GENERIC;
2312 }
2313 
2314 static NV_STATUS
gsyncNullGetInterlaceMode(OBJGPU * pGpu,PDACEXTERNALDEVICE pExtDev,NvU32 * mode)2315 gsyncNullGetInterlaceMode
2316 (
2317  OBJGPU       *pGpu,
2318  PDACEXTERNALDEVICE pExtDev,
2319  NvU32 *mode
2320 )
2321 {
2322     return NV_ERR_GENERIC;
2323 }
2324 
2325 static NV_STATUS
gsyncNullSetInterlaceMode(OBJGPU * pGpu,PDACEXTERNALDEVICE pExtDev,NvU32 mode)2326 gsyncNullSetInterlaceMode
2327 (
2328  OBJGPU       *pGpu,
2329  PDACEXTERNALDEVICE pExtDev,
2330  NvU32 mode
2331 )
2332 {
2333     return NV_ERR_GENERIC;
2334 }
2335 
2336 static NV_STATUS
gsyncNullRefSwapBarrier(OBJGPU * pGpu,PDACEXTERNALDEVICE pExtDev,REFTYPE rType,NvBool * enable)2337 gsyncNullRefSwapBarrier
2338 (
2339  OBJGPU       *pGpu,
2340  PDACEXTERNALDEVICE pExtDev,
2341  REFTYPE rType,
2342  NvBool *enable
2343 )
2344 {
2345     return NV_ERR_GENERIC;
2346 }
2347 
2348 static NV_STATUS
gsyncNullRefSignal(OBJGPU * pGpu,PDACEXTERNALDEVICE pExtDev,REFTYPE rType,GSYNCSYNCSIGNAL Signal,NvBool bRate,NvU32 * pPresence)2349 gsyncNullRefSignal
2350 (
2351  OBJGPU       *pGpu,
2352  PDACEXTERNALDEVICE pExtDev,
2353  REFTYPE rType,
2354  GSYNCSYNCSIGNAL Signal,
2355  NvBool bRate,
2356  NvU32 *pPresence
2357 )
2358 {
2359     return NV_ERR_GENERIC;
2360 }
2361 
2362 static NV_STATUS
gsyncNullRefMaster(OBJGPU * pGpu,PDACEXTERNALDEVICE pExtDev,REFTYPE rType,NvU32 * pDisplayMask,NvU32 * pRefresh,NvBool retainMaster,NvBool skipSwapBarrierWar)2363 gsyncNullRefMaster
2364 (
2365  OBJGPU       *pGpu,
2366  PDACEXTERNALDEVICE pExtDev,
2367  REFTYPE rType,
2368  NvU32 *pDisplayMask,
2369  NvU32 *pRefresh,
2370  NvBool retainMaster,
2371  NvBool skipSwapBarrierWar
2372 )
2373 {
2374     return NV_ERR_GENERIC;
2375 }
2376 
2377 static NV_STATUS
gsyncNullRefSlaves(OBJGPU * pGpu,PDACEXTERNALDEVICE pExtDev,REFTYPE rType,NvU32 * pDisplayMasks,NvU32 * pRefresh)2378 gsyncNullRefSlaves
2379 (
2380  OBJGPU       *pGpu,
2381  PDACEXTERNALDEVICE pExtDev,
2382  REFTYPE rType,
2383  NvU32 *pDisplayMasks,
2384  NvU32 *pRefresh
2385 )
2386 {
2387     return NV_ERR_GENERIC;
2388 }
2389 
2390 static NV_STATUS
gsyncNullGetCplStatus(OBJGPU * pGpu,PDACEXTERNALDEVICE pExtDev,GSYNCSTATUS status,NvU32 * pVal)2391 gsyncNullGetCplStatus
2392 (
2393  OBJGPU       *pGpu,
2394  PDACEXTERNALDEVICE pExtDev,
2395  GSYNCSTATUS status,
2396  NvU32 *pVal
2397 )
2398 {
2399     return NV_ERR_GENERIC;
2400 }
2401 
2402 static NV_STATUS
gsyncNullSetWatchdog(OBJGPU * pGpu,PDACEXTERNALDEVICE pExtDev,NvU32 pVal)2403 gsyncNullSetWatchdog
2404 (
2405  OBJGPU       *pGpu,
2406  PDACEXTERNALDEVICE pExtDev,
2407  NvU32 pVal
2408 )
2409 {
2410     return NV_ERR_GENERIC;
2411 }
2412 
2413 static NV_STATUS
gsyncNullGetRevision(OBJGPU * pGpu,PDACEXTERNALDEVICE pExtDev,GSYNCCAPSPARAMS * pParams)2414 gsyncNullGetRevision
2415 (
2416  OBJGPU       *pGpu,
2417  PDACEXTERNALDEVICE pExtDev,
2418  GSYNCCAPSPARAMS *pParams
2419 )
2420 {
2421     return NV_ERR_GENERIC;
2422 }
2423 
2424 static NV_STATUS
gsyncNullSetMosaic(OBJGPU * pSourceGpu,PDACEXTERNALDEVICE pExtDev,NV30F1_CTRL_GSYNC_SET_LOCAL_SYNC_PARAMS * pParams)2425 gsyncNullSetMosaic
2426 (
2427  OBJGPU *pSourceGpu,
2428  PDACEXTERNALDEVICE pExtDev,
2429  NV30F1_CTRL_GSYNC_SET_LOCAL_SYNC_PARAMS *pParams
2430 )
2431 {
2432     return NV_ERR_GENERIC;
2433 }
2434 
2435 static NV_STATUS
gsyncNullConfigFlashGsync(OBJGPU * pGpu,PDACEXTERNALDEVICE pExtDev,NvU32 preFlash)2436 gsyncNullConfigFlashGsync
2437 (
2438  OBJGPU *pGpu,
2439  PDACEXTERNALDEVICE pExtDev,
2440  NvU32 preFlash
2441 )
2442 {
2443     return NV_ERR_GENERIC;
2444 }
2445 
2446 static NV_STATUS
gsyncNullGetHouseSyncMode(OBJGPU * pGpu,PDACEXTERNALDEVICE pExtDev,NvU8 * mode)2447 gsyncNullGetHouseSyncMode
2448 (
2449     OBJGPU *pGpu,
2450     PDACEXTERNALDEVICE pExtDev,
2451     NvU8* mode
2452 )
2453 {
2454     return NV_ERR_GENERIC;
2455 }
2456 
2457 static NV_STATUS
gsyncNullSetHouseSyncMode(OBJGPU * pGpu,PDACEXTERNALDEVICE pExtDev,NvU8 mode)2458 gsyncNullSetHouseSyncMode
2459 (
2460     OBJGPU *pGpu,
2461     PDACEXTERNALDEVICE pExtDev,
2462     NvU8 mode
2463 )
2464 {
2465     return NV_ERR_GENERIC;
2466 }
2467 
2468 static NV_STATUS
gsyncNullGetMulDiv(OBJGPU * pGpu,DACEXTERNALDEVICE * pExtDev,NV30F1_CTRL_GSYNC_MULTIPLY_DIVIDE_SETTINGS * pMulDivSettings)2469 gsyncNullGetMulDiv
2470 (
2471     OBJGPU       *pGpu,
2472     DACEXTERNALDEVICE *pExtDev,
2473     NV30F1_CTRL_GSYNC_MULTIPLY_DIVIDE_SETTINGS *pMulDivSettings
2474 )
2475 {
2476     return NV_ERR_NOT_SUPPORTED;
2477 }
2478 
2479 static NV_STATUS
gsyncNullSetMulDiv(OBJGPU * pGpu,DACEXTERNALDEVICE * pExtDev,NV30F1_CTRL_GSYNC_MULTIPLY_DIVIDE_SETTINGS * pMulDivSettings)2480 gsyncNullSetMulDiv
2481 (
2482     OBJGPU       *pGpu,
2483     DACEXTERNALDEVICE *pExtDev,
2484     NV30F1_CTRL_GSYNC_MULTIPLY_DIVIDE_SETTINGS *pMulDivSettings
2485 )
2486 {
2487     return NV_ERR_NOT_SUPPORTED;
2488 }
2489 
2490 static NV_STATUS
gsyncSetupNullProvider(OBJGSYNCMGR * pGsyncMgr,NvU32 gsyncInst)2491 gsyncSetupNullProvider(OBJGSYNCMGR *pGsyncMgr, NvU32 gsyncInst)
2492 {
2493     OBJGSYNC *pGsync;
2494     NV_STATUS status = NV_OK;
2495 
2496     NV_ASSERT(gsyncInst < NV30F1_MAX_GSYNCS);
2497 
2498     pGsync = &pGsyncMgr->gsyncTable[gsyncInst];
2499 
2500     pGsync->connectorCount                     = 0;
2501 
2502     pGsync->gsyncHal.gsyncGpuCanBeMaster       = gsyncNullGpuCanBeMaster;
2503     pGsync->gsyncHal.gsyncOptimizeTiming       = gsyncNullOptimizeTimingParameters;
2504     pGsync->gsyncHal.gsyncGetStereoLockMode    = gsyncNullGetStereoLockMode;
2505     pGsync->gsyncHal.gsyncSetStereoLockMode    = gsyncNullSetStereoLockMode;
2506 
2507     pGsync->gsyncHal.gsyncGetSyncPolarity      = gsyncNullGetSyncPolarity;
2508     pGsync->gsyncHal.gsyncSetSyncPolarity      = gsyncNullSetSyncPolarity;
2509     pGsync->gsyncHal.gsyncGetVideoMode         = gsyncNullGetVideoMode;
2510     pGsync->gsyncHal.gsyncSetVideoMode         = gsyncNullSetVideoMode;
2511     pGsync->gsyncHal.gsyncGetNSync             = gsyncNullGetNSync;
2512     pGsync->gsyncHal.gsyncSetNSync             = gsyncNullSetNSync;
2513     pGsync->gsyncHal.gsyncGetSyncSkew          = gsyncNullGetSyncSkew;
2514     pGsync->gsyncHal.gsyncSetSyncSkew          = gsyncNullSetSyncSkew;
2515     pGsync->gsyncHal.gsyncGetUseHouse          = gsyncNullGetUseHouse;
2516     pGsync->gsyncHal.gsyncSetUseHouse          = gsyncNullSetUseHouse;
2517     pGsync->gsyncHal.gsyncGetSyncStartDelay    = gsyncNullGetSyncStartDelay;
2518     pGsync->gsyncHal.gsyncSetSyncStartDelay    = gsyncNullSetSyncStartDelay;
2519     pGsync->gsyncHal.gsyncGetEmitTestSignal    = gsyncNullGetEmitTestSignal;
2520     pGsync->gsyncHal.gsyncSetEmitTestSignal    = gsyncNullSetEmitTestSignal;
2521     pGsync->gsyncHal.gsyncGetInterlaceMode     = gsyncNullGetInterlaceMode;
2522     pGsync->gsyncHal.gsyncSetInterlaceMode     = gsyncNullSetInterlaceMode;
2523     pGsync->gsyncHal.gsyncRefSwapBarrier       = gsyncNullRefSwapBarrier;
2524     pGsync->gsyncHal.gsyncRefSignal            = gsyncNullRefSignal;
2525     pGsync->gsyncHal.gsyncRefMaster            = gsyncNullRefMaster;
2526     pGsync->gsyncHal.gsyncRefSlaves            = gsyncNullRefSlaves;
2527     pGsync->gsyncHal.gsyncGetCplStatus         = gsyncNullGetCplStatus;
2528     pGsync->gsyncHal.gsyncSetWatchdog          = gsyncNullSetWatchdog;
2529     pGsync->gsyncHal.gsyncGetRevision          = gsyncNullGetRevision;
2530     pGsync->gsyncHal.gsyncSetMosaic            = gsyncNullSetMosaic;
2531     pGsync->gsyncHal.gsyncConfigFlashGsync     = gsyncNullConfigFlashGsync;
2532     pGsync->gsyncHal.gsyncGetHouseSyncMode     = gsyncNullGetHouseSyncMode;
2533     pGsync->gsyncHal.gsyncSetHouseSyncMode     = gsyncNullSetHouseSyncMode;
2534     pGsync->gsyncHal.gsyncGetMulDiv            = gsyncNullGetMulDiv;
2535     pGsync->gsyncHal.gsyncSetMulDiv            = gsyncNullSetMulDiv;
2536 
2537     return status;
2538 }
2539 
2540 //
2541 // gsyncFilterEvents
2542 //
2543 // Perform event filtering.
2544 // 1. Report stereo sync loss if both stereo sync loss and sync gain
2545 //    happen at the same time.
2546 // 2. Report sync loss if both stereo sync loss and sync loss
2547 //    happen at the same time.
2548 // 3. Report sync gain if both stero sync gain and sync gain
2549 //    happen at the same time. (Bug 580086)
2550 //
2551 NvU32
gsyncFilterEvents(NvU32 eventFlags,NvU32 iface)2552 gsyncFilterEvents
2553 (
2554     NvU32 eventFlags,
2555     NvU32 iface
2556 )
2557 {
2558     if ((eventFlags & NVBIT(NV30F1_GSYNC_NOTIFIERS_SYNC_GAIN(iface))) &&
2559         (eventFlags & NVBIT(NV30F1_GSYNC_NOTIFIERS_STEREO_LOSS(iface))))
2560     {
2561         // report only stereo sync loss
2562         eventFlags &= ~NVBIT(NV30F1_GSYNC_NOTIFIERS_SYNC_GAIN(iface));
2563     }
2564 
2565     if ((eventFlags & NVBIT(NV30F1_GSYNC_NOTIFIERS_SYNC_LOSS(iface))) &&
2566         (eventFlags & NVBIT(NV30F1_GSYNC_NOTIFIERS_STEREO_LOSS(iface))))
2567     {
2568         // report only sync loss
2569         eventFlags &= ~NVBIT(NV30F1_GSYNC_NOTIFIERS_STEREO_LOSS(iface));
2570     }
2571 
2572     if ((eventFlags & NVBIT(NV30F1_GSYNC_NOTIFIERS_SYNC_GAIN(iface))) &&
2573         (eventFlags & NVBIT(NV30F1_GSYNC_NOTIFIERS_STEREO_GAIN(iface))))
2574     {
2575         // report sync gain (bug 580086)
2576         eventFlags &= ~NVBIT(NV30F1_GSYNC_NOTIFIERS_STEREO_GAIN(iface));
2577     }
2578 
2579     return eventFlags;
2580 }
2581 
2582 //
2583 // gsyncConvertNewEventToOldEventNum
2584 //
2585 // contevert new event numbers to old event numbers.
2586 //
2587 NvU32
gsyncConvertNewEventToOldEventNum(NvU32 eventFlags)2588 gsyncConvertNewEventToOldEventNum
2589 (
2590     NvU32 eventFlags
2591 )
2592 {
2593     NvU32 eventNum = 0;
2594     NvU32 isEventOccured = 0;
2595     NvU32 connectorCount;
2596 
2597     // SYNC_LOSS events
2598     for (connectorCount = 0; connectorCount < NV30F1_GSYNC_CONNECTOR_COUNT; connectorCount++)
2599     {
2600       isEventOccured |= (eventFlags & NVBIT(NV30F1_GSYNC_NOTIFIERS_SYNC_LOSS(connectorCount)));
2601     }
2602     if (isEventOccured)
2603     {
2604         eventNum = eventNum | NV30F1_CTRL_GSYNC_SET_EVENT_NOTIFICATION_ACTION_SMART_SYNC_LOSS;
2605     }
2606 
2607     // SYNC_GAIN events
2608     isEventOccured = 0;
2609     for (connectorCount = 0; connectorCount < NV30F1_GSYNC_CONNECTOR_COUNT; connectorCount++)
2610     {
2611       isEventOccured |= (eventFlags & NVBIT(NV30F1_GSYNC_NOTIFIERS_SYNC_GAIN(connectorCount)));
2612     }
2613     if (isEventOccured)
2614     {
2615         eventNum = eventNum | NV30F1_CTRL_GSYNC_SET_EVENT_NOTIFICATION_ACTION_SMART_SYNC_GAIN;
2616     }
2617 
2618     // STEREO_GAIN events
2619     isEventOccured = 0;
2620     for (connectorCount = 0; connectorCount < NV30F1_GSYNC_CONNECTOR_COUNT; connectorCount++)
2621     {
2622       isEventOccured |= (eventFlags & NVBIT(NV30F1_GSYNC_NOTIFIERS_STEREO_GAIN(connectorCount)));
2623     }
2624     if (isEventOccured)
2625     {
2626         eventNum = eventNum | NV30F1_CTRL_GSYNC_SET_EVENT_NOTIFICATION_ACTION_SMART_STEREO_GAIN;
2627     }
2628 
2629     // STEREO_LOSS events
2630     isEventOccured = 0;
2631     for (connectorCount = 0; connectorCount < NV30F1_GSYNC_CONNECTOR_COUNT; connectorCount++)
2632     {
2633       isEventOccured |= (eventFlags & NVBIT(NV30F1_GSYNC_NOTIFIERS_STEREO_LOSS(connectorCount)));
2634     }
2635     if (isEventOccured)
2636     {
2637         eventNum = eventNum | NV30F1_CTRL_GSYNC_SET_EVENT_NOTIFICATION_ACTION_SMART_STEREO_LOSS;
2638     }
2639 
2640     // HOUSE_GAIN events
2641     if (eventFlags & NVBIT(NV30F1_GSYNC_NOTIFIERS_HOUSE_GAIN))
2642     {
2643         eventNum = eventNum | NV30F1_CTRL_GSYNC_SET_EVENT_NOTIFICATION_ACTION_SMART_HOUSE_GAIN;
2644     }
2645 
2646     // HOUSE_LOSS events
2647     if (eventFlags & NVBIT(NV30F1_GSYNC_NOTIFIERS_HOUSE_LOSS))
2648     {
2649         eventNum = eventNum | NV30F1_CTRL_GSYNC_SET_EVENT_NOTIFICATION_ACTION_SMART_HOUSE_LOSS;
2650     }
2651 
2652     // RJ45_GAIN events
2653     if (eventFlags & NVBIT(NV30F1_GSYNC_NOTIFIERS_RJ45_GAIN))
2654     {
2655         eventNum = eventNum | NV30F1_CTRL_GSYNC_SET_EVENT_NOTIFICATION_ACTION_SMART_RJ45_GAIN;
2656     }
2657 
2658     // RJ45_LOSS events
2659     if (eventFlags & NVBIT(NV30F1_GSYNC_NOTIFIERS_RJ45_LOSS))
2660     {
2661         eventNum = eventNum | NV30F1_CTRL_GSYNC_SET_EVENT_NOTIFICATION_ACTION_SMART_RJ45_LOSS;
2662     }
2663 
2664     return eventNum;
2665 }
2666 
2667 #ifdef DEBUG
2668 void
gsyncDbgPrintGsyncEvents(NvU32 events,NvU32 iface)2669 gsyncDbgPrintGsyncEvents(NvU32 events, NvU32 iface)
2670 {
2671     if (events & NVBIT(NV30F1_GSYNC_NOTIFIERS_SYNC_LOSS(iface)))
2672         NV_PRINTF_EX(NV_PRINTF_MODULE, LEVEL_INFO, "SYNC_LOSS ");
2673     if (events & NVBIT(NV30F1_GSYNC_NOTIFIERS_SYNC_GAIN(iface)))
2674         NV_PRINTF_EX(NV_PRINTF_MODULE, LEVEL_INFO, "SYNC_GAIN ");
2675     if (events & NVBIT(NV30F1_GSYNC_NOTIFIERS_STEREO_LOSS(iface)))
2676         NV_PRINTF_EX(NV_PRINTF_MODULE, LEVEL_INFO, "STEREO_LOSS ");
2677     if (events & NVBIT(NV30F1_GSYNC_NOTIFIERS_STEREO_GAIN(iface)))
2678         NV_PRINTF_EX(NV_PRINTF_MODULE, LEVEL_INFO, "STEREO_GAIN ");
2679     if (events & NVBIT(NV30F1_GSYNC_NOTIFIERS_HOUSE_GAIN))
2680         NV_PRINTF_EX(NV_PRINTF_MODULE, LEVEL_INFO, "HOUSE_GAIN ");
2681     if (events & NVBIT(NV30F1_GSYNC_NOTIFIERS_HOUSE_LOSS))
2682         NV_PRINTF_EX(NV_PRINTF_MODULE, LEVEL_INFO, "HOUSE LOSS ");
2683     if (events & NVBIT(NV30F1_GSYNC_NOTIFIERS_RJ45_GAIN))
2684         NV_PRINTF_EX(NV_PRINTF_MODULE, LEVEL_INFO, "RJ45 GAIN ");
2685     if (events & NVBIT(NV30F1_GSYNC_NOTIFIERS_RJ45_LOSS))
2686         NV_PRINTF_EX(NV_PRINTF_MODULE, LEVEL_INFO, "RJ45 LOSS ");
2687 }
2688 #endif // DEBUG
2689 
2690