1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2014-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 #if !defined(NVKMS_API_H)
25 #define NVKMS_API_H
26 
27 /*
28  * NVKMS API
29  *
30  *
31  * All file operations described in this header file go through a
32  * single device file that has system-wide scope.  The individual
33  * ioctl request data structures specify the objects to which the
34  * request is targeted.
35  *
36  *
37  * OBJECTS
38  *
39  * The NVKMS API is organized into several objects:
40  *
41  * - A device, which corresponds to an RM device.  This can either be
42  *   a single GPU, or multiple GPUs linked into SLI.  Each GPU is
43  *   called a "subdevice".  The subdevices used by an NVKMS device are
44  *   reported in NvKmsAllocDeviceReply::subDeviceMask.
45  *
46  *   A device is specified by a deviceHandle, returned by
47  *   NVKMS_IOCTL_ALLOC_DEVICE.
48  *
49  * - A disp, which represents an individually programmable display
50  *   engine of a GPU.  In SLI Mosaic, there is one disp per physical
51  *   GPU.  In all other configurations there is one disp for the
52  *   entire device.  A disp is specified by a (deviceHandle,
53  *   dispHandle) duple.  A dispHandle is only unique within a single
54  *   device: multiple devices may have disps with the same dispHandle
55  *   value.
56  *
57  *   A disp represents one subdevice; disp index N corresponds to subdevice
58  *   index N.
59  *
60  * - A connector, which represents an electrical connection to the
61  *   GPU.  E.g., a physical DVI-I connector has two NVKMS connector
62  *   objects (a VGA NVKMS connector and a TMDS NVKMS connector).
63  *   However, a physical DisplayPort connector has one NVKMS connector
64  *   object, even if there is a tree of DisplayPort1.2 Multistream
65  *   monitors connected to it.
66  *
67  *   Connectors are associated with a specific disp.  A connector is
68  *   specified by a (deviceHandle, dispHandle, connectorHandle)
69  *   triplet.  A connectorHandle is only unique within a single disp:
70  *   multiple disps may have connectors with the same connectorHandle
71  *   value.
72  *
73  * - A dpy, which represents a connection of a display device to the
74  *   system.  Multiple dpys can map to the same connector in the case
75  *   of DisplayPort1.2 MultiStream.  A dpy is specified by a
76  *   (deviceHandle, dispHandle, dpyId) triplet.  A dpyId is only
77  *   unique within a single disp: multiple disps may have dpys with
78  *   the same dpyId value.
79  *
80  * - A surface, which represents memory to be scanned out.  Surfaces
81  *   should be allocated by resman, and then registered and
82  *   unregistered with NVKMS.  The NvKmsSurfaceHandle value of 0 is
83  *   reserved to mean no surface.
84  *
85  * NVKMS clients should treat the device, disp, connector, and surface
86  * handles as opaque values.  They are specific to the file descriptor
87  * through which a client allocated and queried them.  Dpys should
88  * also be treated as opaque, though they can be passed between
89  * clients.
90  *
91  * NVKMS clients initialize NVKMS by allocating an NVKMS device.  The
92  * device can either be a single GPU, or an SLI group.  It is expected
93  * that the client has already attached/linked the GPUs through
94  * resman and created a resman device.
95  *
96  * NVKMS device allocation returns a device handle, the disp handles,
97  * and capabilities of the device.
98  *
99  *
100  * MODE VALIDATION
101  *
102  * When a client requests to set a mode via NVKMS_IOCTL_SET_MODE,
103  * NVKMS will validate the mode at that point in time, honoring the
104  * NvKmsModeValidationParams specified as part of the request.
105  *
106  * Clients can use NVKMS_IOCTL_VALIDATE_MODE to test if a mode is valid.
107  *
108  * Clients can use NVKMS_IOCTL_VALIDATE_MODE_INDEX to get the list of
109  * modes that NVKMS currently considers valid for the dpy (modes from
110  * the EDID, etc).
111  *
112  * IMPLEMENTATION NOTE: the same mode validation common code will be
113  * used in each of NVKMS_IOCTL_SET_MODE, NVKMS_IOCTL_VALIDATE_MODE,
114  * and NVKMS_IOCTL_VALIDATE_MODE_INDEX, but NVKMS won't generally maintain
115  * a "mode pool" with an exhaustive list of the allowable modes for a
116  * dpy.
117  *
118  *
119  * DYNAMIC DPY HANDLING
120  *
121  * Dynamic dpys (namely, DisplayPort multistream dpys) share the NVDpyId
122  * namespace with non-dynamic dpys on the same disp.  However, dynamic dpys will
123  * not be listed in NvKmsQueryDispReply::validDpys.  Instead, dynamic dpys are
124  * added and removed from the system dynamically.
125  *
126  * When a dynamic dpy is first connected, NVKMS will allocate a new NVDpyId for
127  * it and generate an NVKMS_EVENT_TYPE_DYNAMIC_DPY_CONNECTED event.  When the
128  * dynamic dpy is disconnected, NVKMS will generate an
129  * NVKMS_EVENT_TYPE_DYNAMIC_DPY_DISCONNECTED event.  Whether the corresponding
130  * NVDpyId is immediately freed and made available for subsequent dynamic dpys
131  * depends on client behavior.
132  *
133  * Clients may require that a dynamic NVDpyId persist even after the dynamic dpy
134  * is disconnected.  Clients who require this can use
135  * NVKMS_IOCTL_DECLARE_DYNAMIC_DPY_INTEREST.  NVKMS will retain the NVDpyId
136  * until the dynamic dpy is disconnected and there are no clients who have
137  * declared "interest" on the particular dynamic dpy.  While the NVDpyId
138  * persists, it will be used for any monitor that is connected at the same
139  * dynamic dpy address (i.e., port address, in the case of DP MST).
140  *
141  *
142  * FILE DESCRIPTOR HANDLING
143  *
144  * With the exception of NVDpyIds, all handles should be assumed to be
145  * specific to the current file descriptor on which the ioctls are
146  * performed.
147  *
148  * Multiple devices can be allocated on the same file descriptor.
149  * E.g., to drive the display of multiple GPUs.
150  *
151  * If a file descriptor is closed prematurely, either explicitly by
152  * the client or implicitly by the operating system because the client
153  * process was terminated, NVKMS will perform an
154  * NVKMS_IOCTL_FREE_DEVICE for any devices currently allocated by the
155  * client on the closed file descriptor.
156  *
157  * NVKMS file descriptors are normally used as the first argument of
158  * ioctl(2).  However, NVKMS file descriptors are also used for
159  * granting surfaces (see NVKMS_IOCTL_GRANT_SURFACE) or permissions
160  * (see NVKMS_IOCTL_GRANT_PERMISSIONS).  Any given NVKMS file
161  * descriptor can only be used for one of these uses.
162  *
163  * QUESTIONS:
164  *
165  * - Is there any reason for errors to be returned through a status field
166  *   in the Param structures, rather than the ioctl(2) return value?
167  *
168  * - Is it too asymmetric that NVKMS_IOCTL_SET_MODE can set a
169  *   mode across heads/disps, but other requests (e.g.,
170  *   NVKMS_IOCTL_SET_CURSOR_IMAGE) operate on a single head?
171  *
172  *
173  * IOCTL PARAMETER ORGANIZATION
174  *
175  * For table-driven processing of ioctls, it is useful for all ioctl
176  * parameters to follow the same convention:
177  *
178  *   struct NvKmsFooRequest {
179  *       (...)
180  *   };
181  *
182  *   struct NvKmsFooReply {
183  *       (...)
184  *   };
185  *
186  *   struct NvKmsFooParams {
187  *       struct NvKmsFooRequest request; //! in
188  *       struct NvKmsFooReply reply;     //! out
189  *   };
190  *
191  * I.e., all ioctl parameter structures NvKmsFooParams should have
192  * "request" and "reply" fields, with types "struct NvKmsFooRequest"
193  * and "struct NvKmsFooReply".  C doesn't technically support empty
194  * structures, so the convention is to place a "padding" NvU32 in
195  * request or reply structures that would otherwise be empty.
196  */
197 
198 #include "nvtypes.h"
199 #include "nvlimits.h"
200 #include "nv_dpy_id.h"
201 #include "nv_mode_timings.h"
202 #include "nvkms-api-types.h"
203 #include "nvgputypes.h" /* NvGpuSemaphore */
204 #include "nvkms-format.h"
205 
206 /*
207  * The NVKMS ioctl commands.  See the ioctl parameter declarations
208  * later in this header file for an explanation of each ioctl command.
209  */
210 enum NvKmsIoctlCommand {
211     NVKMS_IOCTL_ALLOC_DEVICE,
212     NVKMS_IOCTL_FREE_DEVICE,
213     NVKMS_IOCTL_QUERY_DISP,
214     NVKMS_IOCTL_QUERY_CONNECTOR_STATIC_DATA,
215     NVKMS_IOCTL_QUERY_CONNECTOR_DYNAMIC_DATA,
216     NVKMS_IOCTL_QUERY_DPY_STATIC_DATA,
217     NVKMS_IOCTL_QUERY_DPY_DYNAMIC_DATA,
218     NVKMS_IOCTL_VALIDATE_MODE_INDEX,
219     NVKMS_IOCTL_VALIDATE_MODE,
220     NVKMS_IOCTL_SET_MODE,
221     NVKMS_IOCTL_SET_CURSOR_IMAGE,
222     NVKMS_IOCTL_MOVE_CURSOR,
223     NVKMS_IOCTL_SET_LUT,
224     NVKMS_IOCTL_IDLE_BASE_CHANNEL,
225     NVKMS_IOCTL_FLIP,
226     NVKMS_IOCTL_DECLARE_DYNAMIC_DPY_INTEREST,
227     NVKMS_IOCTL_REGISTER_SURFACE,
228     NVKMS_IOCTL_UNREGISTER_SURFACE,
229     NVKMS_IOCTL_GRANT_SURFACE,
230     NVKMS_IOCTL_ACQUIRE_SURFACE,
231     NVKMS_IOCTL_RELEASE_SURFACE,
232     NVKMS_IOCTL_SET_DPY_ATTRIBUTE,
233     NVKMS_IOCTL_GET_DPY_ATTRIBUTE,
234     NVKMS_IOCTL_GET_DPY_ATTRIBUTE_VALID_VALUES,
235     NVKMS_IOCTL_SET_DISP_ATTRIBUTE,
236     NVKMS_IOCTL_GET_DISP_ATTRIBUTE,
237     NVKMS_IOCTL_GET_DISP_ATTRIBUTE_VALID_VALUES,
238     NVKMS_IOCTL_QUERY_FRAMELOCK,
239     NVKMS_IOCTL_SET_FRAMELOCK_ATTRIBUTE,
240     NVKMS_IOCTL_GET_FRAMELOCK_ATTRIBUTE,
241     NVKMS_IOCTL_GET_FRAMELOCK_ATTRIBUTE_VALID_VALUES,
242     NVKMS_IOCTL_GET_NEXT_EVENT,
243     NVKMS_IOCTL_DECLARE_EVENT_INTEREST,
244     NVKMS_IOCTL_CLEAR_UNICAST_EVENT,
245     NVKMS_IOCTL_GET_3DVISION_DONGLE_PARAM_BYTES,
246     NVKMS_IOCTL_SET_3DVISION_AEGIS_PARAMS,
247     NVKMS_IOCTL_SET_LAYER_POSITION,
248     NVKMS_IOCTL_GRAB_OWNERSHIP,
249     NVKMS_IOCTL_RELEASE_OWNERSHIP,
250     NVKMS_IOCTL_GRANT_PERMISSIONS,
251     NVKMS_IOCTL_ACQUIRE_PERMISSIONS,
252     NVKMS_IOCTL_REVOKE_PERMISSIONS,
253     NVKMS_IOCTL_QUERY_DPY_CRC32,
254     NVKMS_IOCTL_REGISTER_DEFERRED_REQUEST_FIFO,
255     NVKMS_IOCTL_UNREGISTER_DEFERRED_REQUEST_FIFO,
256     NVKMS_IOCTL_ALLOC_SWAP_GROUP,
257     NVKMS_IOCTL_FREE_SWAP_GROUP,
258     NVKMS_IOCTL_JOIN_SWAP_GROUP,
259     NVKMS_IOCTL_LEAVE_SWAP_GROUP,
260     NVKMS_IOCTL_SET_SWAP_GROUP_CLIP_LIST,
261     NVKMS_IOCTL_GRANT_SWAP_GROUP,
262     NVKMS_IOCTL_ACQUIRE_SWAP_GROUP,
263     NVKMS_IOCTL_RELEASE_SWAP_GROUP,
264     NVKMS_IOCTL_SWITCH_MUX,
265     NVKMS_IOCTL_GET_MUX_STATE,
266     NVKMS_IOCTL_EXPORT_VRR_SEMAPHORE_SURFACE,
267     NVKMS_IOCTL_ENABLE_VBLANK_SYNC_OBJECT,
268     NVKMS_IOCTL_DISABLE_VBLANK_SYNC_OBJECT,
269     NVKMS_IOCTL_NOTIFY_VBLANK,
270     NVKMS_IOCTL_SET_FLIPLOCK_GROUP,
271 };
272 
273 
274 #define NVKMS_NVIDIA_DRIVER_VERSION_STRING_LENGTH                     32
275 #define NVKMS_MAX_CONNECTORS_PER_DISP                                 16
276 #define NVKMS_MAX_GPUS_PER_FRAMELOCK                                  4
277 #define NVKMS_MAX_DEVICE_REGISTRY_KEYS                                16
278 #define NVKMS_MAX_DEVICE_REGISTRY_KEYNAME_LEN                         32
279 #define NVKMS_MAX_VBLANK_SYNC_OBJECTS_PER_HEAD                        6
280 
281 
282 /*
283  * There can be at most one SwapGroup per-head, per-disp (and,
284  * in the extreme, there is one disp per-GPU).
285  */
286 #define NVKMS_MAX_SWAPGROUPS (NVKMS_MAX_HEADS_PER_DISP * NV_MAX_DEVICES)
287 
288 #define NVKMS_MAX_VALID_SYNC_RANGES                                   8
289 
290 #define NVKMS_DPY_NAME_SIZE                                           128
291 #define NVKMS_GUID_SIZE                                               16
292 #define NVKMS_3DVISION_DONGLE_PARAM_BYTES                             20
293 #define NVKMS_GPU_STRING_SIZE                                         80
294 
295 #define NVKMS_VRR_SEMAPHORE_SURFACE_SIZE                              1024
296 
297 /*
298  * The GUID string has the form:
299  * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
300  * Two Xs per byte, plus four dashes and a NUL byte.
301  */
302 #define NVKMS_GUID_STRING_SIZE                  ((NVKMS_GUID_SIZE * 2) + 5)
303 
304 #define NVKMS_MODE_VALIDATION_MAX_INFO_STRING_LENGTH                  2048
305 #define NVKMS_EDID_INFO_STRING_LENGTH                                 (32 * 1024)
306 
307 /*!
308  * A base EDID is 128 bytes, with 128 bytes per extension block.  2048
309  * should be large enough for any EDID we see.
310  */
311 #define NVKMS_EDID_BUFFER_SIZE                                        2048
312 
313 /*!
314  * Description of modetimings.
315  *
316  * YUV420 modes require special care since some GPUs do not support YUV420
317  * scanout in hardware.  When timings::yuv420Mode is NV_YUV420_SW, NVKMS will
318  * set a mode with horizontal values that are half of what are described in
319  * NvKmsMode, and not enable any color space conversion.  When clients allocate
320  * a surface and populate it with content, the region of interest within the
321  * surface should be half the width of the NvKmsMode, and the surface content
322  * should be RGB->YUV color space converted, and decimated from 4:4:4 to 4:2:0.
323  *
324  * The NvKmsMode and viewPortOut, specified by the NVKMS client,
325  * should be in "full" horizontal space, but the surface and
326  * viewPortIn should be in "half" horizontal space.
327  */
328 struct NvKmsMode {
329     NvModeTimings timings;
330     char name[32];
331 };
332 
333 /*!
334  * Mode validation override bit flags, for use in
335  * NvKmsModeValidationParams::overrides.
336  */
337 enum NvKmsModeValidationOverrides {
338     NVKMS_MODE_VALIDATION_NO_MAX_PCLK_CHECK                  = (1 << 0),
339     NVKMS_MODE_VALIDATION_NO_EDID_MAX_PCLK_CHECK             = (1 << 1),
340     NVKMS_MODE_VALIDATION_NO_HORIZ_SYNC_CHECK                = (1 << 2),
341     NVKMS_MODE_VALIDATION_NO_VERT_REFRESH_CHECK              = (1 << 3),
342     NVKMS_MODE_VALIDATION_NO_EDID_DFP_MAX_SIZE_CHECK         = (1 << 4),
343     NVKMS_MODE_VALIDATION_NO_EXTENDED_GPU_CAPABILITIES_CHECK = (1 << 5),
344     NVKMS_MODE_VALIDATION_OBEY_EDID_CONTRADICTIONS           = (1 << 6),
345     NVKMS_MODE_VALIDATION_NO_TOTAL_SIZE_CHECK                = (1 << 7),
346     NVKMS_MODE_VALIDATION_NO_DUAL_LINK_DVI_CHECK             = (1 << 8),
347     NVKMS_MODE_VALIDATION_NO_DISPLAYPORT_BANDWIDTH_CHECK     = (1 << 9),
348     NVKMS_MODE_VALIDATION_ALLOW_NON_3DVISION_MODES           = (1 << 10),
349     NVKMS_MODE_VALIDATION_ALLOW_NON_EDID_MODES               = (1 << 11),
350     NVKMS_MODE_VALIDATION_ALLOW_NON_HDMI3D_MODES             = (1 << 12),
351     NVKMS_MODE_VALIDATION_NO_MAX_SIZE_CHECK                  = (1 << 13),
352     NVKMS_MODE_VALIDATION_NO_HDMI2_CHECK                     = (1 << 14),
353     NVKMS_MODE_VALIDATION_NO_RRX1K_CHECK                     = (1 << 15),
354     NVKMS_MODE_VALIDATION_REQUIRE_BOOT_CLOCKS                = (1 << 16),
355     NVKMS_MODE_VALIDATION_ALLOW_DP_INTERLACED                = (1 << 17),
356     NVKMS_MODE_VALIDATION_NO_INTERLACED_MODES                = (1 << 18),
357     NVKMS_MODE_VALIDATION_MAX_ONE_HARDWARE_HEAD              = (1 << 19),
358 };
359 
360 /*!
361  * Frequency information used during mode validation (for HorizSync
362  * and VertRefresh) can come from several possible sources.  NVKMS
363  * selects the frequency information by prioritizing the input sources
364  * and then reports the selected source.
365  *
366  * Without client input, NVKMS will use frequency ranges from the
367  * EDID, if available.  If there is no EDID, NVKMS will fall back to
368  * builtin conservative defaults.
369  *
370  * The client can specify frequency ranges that are used instead of
371  * anything in the EDID (_CLIENT_BEFORE_EDID), or frequency ranges
372  * that are used only if no EDID-reported ranges are available
373  * (_CLIENT_AFTER_EDID).
374  */
375 enum NvKmsModeValidationFrequencyRangesSource {
376     NVKMS_MODE_VALIDATION_FREQUENCY_RANGE_SOURCE_NONE                  = 0,
377     NVKMS_MODE_VALIDATION_FREQUENCY_RANGE_SOURCE_CLIENT_BEFORE_EDID    = 1,
378     NVKMS_MODE_VALIDATION_FREQUENCY_RANGE_SOURCE_EDID                  = 2,
379     NVKMS_MODE_VALIDATION_FREQUENCY_RANGE_SOURCE_CLIENT_AFTER_EDID     = 3,
380     NVKMS_MODE_VALIDATION_FREQUENCY_RANGE_SOURCE_CONSERVATIVE_DEFAULTS = 4,
381 };
382 
383 
384 /*!
385  * Mode validation parameters.
386  */
387 struct NvKmsModeValidationFrequencyRanges {
388     enum NvKmsModeValidationFrequencyRangesSource source;
389     NvU32 numRanges;
390     struct {
391         NvU32 high;
392         NvU32 low;
393     } range[NVKMS_MAX_VALID_SYNC_RANGES];
394 };
395 
396 struct NvKmsModeValidationValidSyncs {
397 
398     /*! If TRUE, ignore frequency information from the EDID. */
399     NvBool ignoreEdidSource;
400 
401     /*! values are in Hz */
402     struct NvKmsModeValidationFrequencyRanges horizSyncHz;
403 
404     /*! values are in 1/1000 Hz */
405     struct NvKmsModeValidationFrequencyRanges vertRefreshHz1k;
406 };
407 
408 enum NvKmsStereoMode {
409     NVKMS_STEREO_DISABLED = 0,
410     NVKMS_STEREO_NVIDIA_3D_VISION,
411     NVKMS_STEREO_NVIDIA_3D_VISION_PRO,
412     NVKMS_STEREO_HDMI_3D,
413     NVKMS_STEREO_OTHER,
414 };
415 
416 struct NvKmsModeValidationParams {
417     NvBool verboseModeValidation;
418     NvBool moreVerboseModeValidation;
419 
420     /*!
421      * Normally, if a mode supports both YUV 4:2:0 and RGB 4:4:4,
422      * NVKMS will prefer RGB 4:4:4 if both the monitor and the GPU
423      * support it.  Use preferYUV420 to override that preference.
424      */
425     NvBool preferYUV420;
426 
427     enum NvKmsStereoMode stereoMode;
428     NvU32 overrides;
429 
430     struct NvKmsModeValidationValidSyncs validSyncs;
431 
432     /*!
433      * Normally, NVKMS will determine on its own whether to use Display
434      * Stream Compression (DSC).  Use forceDsc to force NVKMS to use DSC,
435      * when the GPU supports it.
436      */
437     NvBool forceDsc;
438 
439     /*!
440      * When enabled, Display Stream Compression (DSC) has an
441      * associated bits/pixel rate, which NVKMS normally computes.
442      * Use dscOverrideBitsPerPixelX16 to override the DSC bits/pixel rate.
443      * This is in units of 1/16 of a bit per pixel.
444      *
445      * This target bits/pixel rate should be >= 8.0 and <= 32.0, i.e. the valid
446      * bits/pixel values are members of the sequence 8.0, 8.0625, 8.125, ...,
447      * 31.9375, 32.0.  You can convert bits/pixel value to
448      * the dscOverrideBitsPerPixelX16 as follow:
449      *
450      *   +------------------+--------------------------------------------+
451      *   |  bits_per_pixel  |  dscBitsPerPixelX16 = bits_per_pixel * 16  |
452      *   +------------------+--------------------------------------------+
453      *   |  8.0             |  128                                       |
454      *   |  8.0625          |  129                                       |
455      *   |  .               |  .                                         |
456      *   |  .               |  .                                         |
457      *   |  .               |  .                                         |
458      *   |  31.9375         |  511                                       |
459      *   |  32.0            |  512                                       |
460      *   +------------------+--------------------------------------------+
461      *
462      * If the specified dscOverrideBitsPerPixelX16 is out of range,
463      * then mode validation may fail.
464      *
465      * When dscOverrideBitsPerPixelX16 is 0, NVKMS compute the rate itself.
466      */
467     NvU32 dscOverrideBitsPerPixelX16;
468 };
469 
470 /*!
471  * The list of pixelShift modes.
472  */
473 enum NvKmsPixelShiftMode {
474     NVKMS_PIXEL_SHIFT_NONE = 0,
475     NVKMS_PIXEL_SHIFT_4K_TOP_LEFT,
476     NVKMS_PIXEL_SHIFT_4K_BOTTOM_RIGHT,
477     NVKMS_PIXEL_SHIFT_8K,
478 };
479 
480 /*!
481  * The available resampling methods used when viewport scaling is requested.
482  */
483 enum NvKmsResamplingMethod {
484     NVKMS_RESAMPLING_METHOD_BILINEAR = 0,
485     NVKMS_RESAMPLING_METHOD_BICUBIC_TRIANGULAR,
486     NVKMS_RESAMPLING_METHOD_BICUBIC_BELL_SHAPED,
487     NVKMS_RESAMPLING_METHOD_BICUBIC_BSPLINE,
488     NVKMS_RESAMPLING_METHOD_BICUBIC_ADAPTIVE_TRIANGULAR,
489     NVKMS_RESAMPLING_METHOD_BICUBIC_ADAPTIVE_BELL_SHAPED,
490     NVKMS_RESAMPLING_METHOD_BICUBIC_ADAPTIVE_BSPLINE,
491     NVKMS_RESAMPLING_METHOD_NEAREST,
492     NVKMS_RESAMPLING_METHOD_DEFAULT = NVKMS_RESAMPLING_METHOD_BILINEAR,
493 };
494 
495 enum NvKmsWarpMeshDataType {
496     NVKMS_WARP_MESH_DATA_TYPE_TRIANGLES_XYUVRQ,
497     NVKMS_WARP_MESH_DATA_TYPE_TRIANGLE_STRIP_XYUVRQ,
498 };
499 
500 /*!
501  * Description of a cursor image on a single head; this is used by any
502  * NVKMS request that needs to specify the cursor image.
503  */
504 struct NvKmsSetCursorImageCommonParams {
505     /*! The surface to display in the cursor. */
506     NvKmsSurfaceHandle surfaceHandle[NVKMS_MAX_EYES];
507     /*!
508      * The cursor composition parameters gets read and applied only if the
509      * specified cursor surface is not null.
510      */
511     struct NvKmsCompositionParams cursorCompParams;
512 };
513 
514 
515 /*!
516  * Description of the cursor position on a single head; this is used
517  * by any NVKMS request that needs to specify the cursor position.
518  *
519  * x,y are relative to the current viewPortIn configured on the head.
520  */
521 struct NvKmsMoveCursorCommonParams {
522     NvS16 x; /*! in */
523     NvS16 y; /*! in */
524 };
525 
526 /*!
527  * Description of the main layer LUT on a single head; this is used by any NVKMS
528  * request that needs to specify the LUT.
529  */
530 struct NvKmsSetInputLutParams {
531     NvBool specified;
532     NvU32 depth;        /*! used bits per pixel (8, 15, 16, 24, 30) */
533 
534     /*!
535      * The first and last elements (inclusive) in the color arrays to
536      * use.  Valid values are in the range [0,N], where N is a
537      * function of depth:
538      *
539      * Depth   N
540      *  8      256
541      *  15     32
542      *  16     64
543      *  24     256
544      *  30     1024
545      *
546      * 'start' is the first element in the color arrays to use.
547      */
548     NvU32 start;
549 
550     /*!
551      * 'end' is the last element (inclusive) in the color arrays to
552      * use.  If end == 0, this command will disable the HW LUT for
553      * this head.
554      *
555      * The other fields in this structure, besides 'specified', are ignored if
556      * end == 0.
557      */
558     NvU32 end;
559 
560     /*!
561      * Pointer to struct NvKmsLutRamps describing the LUT.
562      * Elements [start,end] will be used.
563      *
564      * Each entry in the input LUT has valid values in the range [0, 65535].
565      * However, on pre-Turing GPUs only 11 bits are significant; NVKMS will
566      * convert values in this range into the appropriate internal format.
567      *
568      * Use nvKmsPointerToNvU64() to assign pRamps.
569      */
570     NvU64 pRamps NV_ALIGN_BYTES(8);
571 };
572 
573 
574 /*!
575  * Description of the output LUT on a single head; this is used by any NVKMS
576  * request that needs to specify the LUT.
577  *
578  * Unlike the input LUT:
579  *  - specifying the output LUT updates all values at once.
580  *
581  * Each entry in the output LUT has valid values in the range [0, 65535].
582  * However, only 11 bits are significant; NVKMS will convert values in this
583  * range into the appropriate internal format.
584  */
585 struct NvKmsSetOutputLutParams {
586     NvBool specified;
587     NvBool enabled;
588 
589     /*!
590      * Pointer to struct NvKmsLutRamps containing the actual LUT data, if
591      * required.
592      * Use nvKmsPointerToNvU64() to assign pRamps.
593      */
594     NvU64 pRamps NV_ALIGN_BYTES(8);
595 };
596 
597 /*!
598  * Description of the LUT on a single head; this is used by any NVKMS
599  * request that needs to specify the LUT.
600  */
601 struct NvKmsSetLutCommonParams {
602     struct NvKmsSetInputLutParams  input;
603     struct NvKmsSetOutputLutParams output;
604 
605     NvBool synchronous; /*! block until the LUT update is complete */
606 };
607 
608 struct NvKmsNIsoSurface {
609     NvKmsSurfaceHandle surfaceHandle;
610     enum NvKmsNIsoFormat format;
611     NvU16 offsetInWords;
612 };
613 
614 struct NvKmsCompletionNotifierDescription {
615     struct NvKmsNIsoSurface surface;
616     NvBool awaken;
617 };
618 
619 struct NvKmsSemaphore {
620     struct NvKmsNIsoSurface surface;
621     NvU32 value;
622 };
623 
624 enum NvKmsSyncptType {
625     NVKMS_SYNCPT_TYPE_NONE,
626     NVKMS_SYNCPT_TYPE_RAW,
627     NVKMS_SYNCPT_TYPE_FD,
628 };
629 
630 struct NvKmsSyncpt {
631     enum NvKmsSyncptType type;
632     union {
633         int fd;
634         struct {
635             NvU32 id;
636             NvU32 value;
637         } raw;
638     } u;
639 };
640 
641 struct NvKmsChannelSyncObjects {
642     /*
643      * If useSyncpt is set to FALSE, clients can provide an acquisition and/or
644      * release semaphore via the 'syncObjects.semaphores' struct.
645      *
646      *    If NvKmsAllocDeviceReply::supportsIndependentAcqRelSemaphore is
647      *    FALSE, then 'syncObjects.semaphores.acquire.surface' must be the same
648      *    as 'syncObjects.semaphores.release.surface'. In other words, the same
649      *    exact semaphore surface must be used for both acquire and release.
650      *
651      *    If NvKmsAllocDeviceReply::supportsIndependentAcqRelSemaphore is
652      *    TRUE, then the client is allowed to provide different semaphore
653      *    surfaces for acquire and release.
654      *
655      * If useSyncpt is set to TRUE, clients can provide a pre-syncpt that they
656      * want the display engine to wait on before scanning out from the given
657      * buffer, and can specify that they want NVKMS to return a post-syncpt
658      * that they can wait on, via the 'syncObjects.syncpts' struct.
659      *
660      *    The post-syncpt that NVKMS returns will be signaled once the
661      *    buffer that was activated by this flip is displaced. As a typical
662      *    example:
663      *    - Client flips buffer A, and requests a post-syncpt PS.
664      *    - Buffer A becomes active at the next frame boundary, and display
665      *      starts scanning out buffer A.
666      *    - Client flips buffer B.
667      *    - Once the UPDATE for the buffer B flip is processed and display
668      *      has finished sending the last pixel of buffer A to precomp for
669      *      the current frame, post-syncpt PS will get signaled.
670      *
671      *    Clients can use this option iff
672      *    NvKmsAllocDeviceReply::supportsSyncpts is TRUE.
673      */
674     NvBool useSyncpt;
675 
676     union {
677         struct {
678             struct NvKmsSemaphore acquire;
679             struct NvKmsSemaphore release;
680         } semaphores;
681 
682         struct {
683             struct NvKmsSyncpt pre;
684             enum NvKmsSyncptType requestedPostType;
685         } syncpts;
686     } u;
687 };
688 
689 /*!
690  * Description of how to flip on a single head.
691  *
692  * viewPortIn::point describes the position of the viewPortIn that
693  * should be scaled to the viewPortOut of the head.  The
694  * viewPortSizeIn is specified by NvKmsSetModeOneHeadRequest.  Note
695  * that viewPortIn::point is in desktop coordinate space, and
696  * therefore applies across all layers.
697  *
698  * For YUV420 modes, the surfaces and position should be in "half"
699  * horizontal space.  See the explanation in NvKmsMode.
700  *
701  * If 'specified' is FALSE for any of the layers, then the current
702  * hardware value is used.
703  */
704 struct NvKmsFlipCommonParams {
705 
706     struct {
707         NvBool specified;
708         struct NvKmsPoint point;
709     } viewPortIn;
710 
711     struct {
712         struct NvKmsSetCursorImageCommonParams image;
713         NvBool imageSpecified;
714 
715         struct NvKmsMoveCursorCommonParams position;
716         NvBool positionSpecified;
717     } cursor;
718 
719     /*
720      * Set the output transfer function.
721      *
722      * If output transfer function is HDR and no staticMetadata is specified
723      * for the head or layers, flip request will be rejected.
724      *
725      * If output transfer is set, output lut values specified during modeset
726      * will be ignored and output lut will be set with the specified HDR
727      * transfer function.
728      *
729      * If output transfer function is SDR and staticMetadata is enabled,
730      * HDR content for that layer will be tonemapped to the SDR output
731      * range.
732      */
733     struct {
734         enum NvKmsOutputTf val;
735         NvBool specified;
736     } tf;
737 
738     /*!
739      * Describe the LUT to be used with the modeset or flip.
740      */
741     struct NvKmsSetLutCommonParams lut;
742 
743     struct {
744         NvBool specified;
745         /*!
746          * If TRUE, override HDR static metadata for the head, instead of
747          * calculating it from HDR layer(s). If FALSE, do not override.
748          *
749          * Note that “specified” serves to mark the field as being changed in
750          * this flip request, rather than as specified for this frame.  So to
751          * disable HDR static metadata, set hdrStaticMetadata.specified = TRUE
752          * and hdrStaticMetadata.enabled = FALSE.
753          */
754         NvBool enabled;
755         enum NvKmsInfoFrameEOTF eotf;
756         struct NvKmsHDRStaticMetadata staticMetadata;
757     } hdrInfoFrame;
758 
759     struct {
760         NvBool specified;
761         enum NvKmsOutputColorimetry val;
762     } colorimetry;
763 
764     struct {
765         struct {
766             NvKmsSurfaceHandle handle[NVKMS_MAX_EYES];
767             struct NvKmsRRParams rrParams;
768             NvBool specified;
769         } surface;
770 
771         /*
772          * sizeIn/sizeOut can be used when
773          * NvKmsAllocDeviceReply::layerCaps[layer].supportsWindowMode is TRUE.
774          */
775         struct {
776             struct NvKmsSize val;
777             NvBool specified;
778         } sizeIn;
779 
780         struct {
781             struct NvKmsSize val;
782             NvBool specified;
783         } sizeOut;
784 
785         /*
786          * Set the position of the layer, relative to the upper left
787          * corner of the surface. This controls the same state as
788          * NVKMS_IOCTL_SET_LAYER_POSITION.
789          *
790          * This field can be used when
791          * NvKmsAllocDeviceReply::layerCaps[layer].supportsWindowMode is TRUE.
792          */
793         struct {
794             struct NvKmsSignedPoint val;
795             NvBool specified;
796         } outputPosition;
797 
798         struct {
799             struct NvKmsCompletionNotifierDescription val;
800             NvBool specified;
801         } completionNotifier;
802 
803         struct {
804             struct NvKmsChannelSyncObjects val;
805 
806             /* If 'specified' is FALSE, then the current hardware value is used. */
807             NvBool specified;
808         } syncObjects;
809 
810         /*
811          * If 'maxDownscaleFactors::specified' is true, nvkms will set the
812          * max H/V downscale usage bounds to the values specified in
813          * 'maxDownscaleFactors::horizontal' and 'maxDownscaleFactors::vertical'.
814          *
815          * If the 'maxDownscaleFactors::specified' values are within the bounds
816          * of 'NvKmsSetModeOneHeadReply::guaranteedUsage', then clients can expect
817          * the flip to succeed. If the 'maxDownscaleFactors::specified' values are
818          * beyond the bounds of 'NvKmsSetModeOneHeadReply::guaranteedUsage' but
819          * within 'NvKmsSetModeOneHeadReply::possibleUsage', then the request may
820          * legitimately fail due to insufficient display bandwidth and clients
821          * need to be prepared to handle that flip request failure.
822          *
823          * If 'maxDownscaleFactors::specified' is false, nvkms will calculate max
824          * H/V downscale factor by quantizing the range. E.g., max H/V downscale
825          * factor supported by HW is 4x for 5-tap and 2x for 2-tap mode. If
826          * 5-tap mode is required, the target usage bound that nvkms will
827          * attempt to program will either allow up to 2x downscaling, or up to
828          * 4x downscaling. If 2-tap mode is required, the target usage bound
829          * that NVKMS will attempt to program will allow up to 2x downscaling.
830          * Example: to downscale from 4096x2160 -> 2731x864 in 5-tap mode,
831          * NVKMS would specify up to 2x for the H downscale bound (required is
832          * 1.5x), and up to 4x for the V downscale bound (required is 2.5x).
833          */
834         struct {
835             /*
836              * Maximum vertical downscale factor (scaled by 1024)
837              *
838              * For example, if the downscale factor is 1.5, then maxVDownscaleFactor
839              * would be 1.5 x 1024 = 1536.
840              */
841             NvU16 vertical;
842 
843             /*
844              * Maximum horizontal downscale factor (scaled by 1024)
845              *
846              * See the example above for vertical.
847              */
848             NvU16 horizontal;
849 
850             NvBool specified;
851         } maxDownscaleFactors;
852 
853         NvBool tearing;
854 
855         /*
856          * When true, we will flip to this buffer whenever the current eye is
857          * finished scanning out.  Otherwise, this flip will only execute after
858          * both eyes have finished scanout.
859          *
860          * Note that if this is FALSE and a vsynced stereo flip is requested,
861          * the buffers in this flip will be displayed for minPresentInterval*2
862          * vblanks, one for each eye.
863          *
864          * This flag cannot be used for the overlay layer.
865          */
866         NvBool perEyeStereoFlip;
867 
868         /* When non-zero, block the flip until PTIMER >= timeStamp. */
869         NvU64 timeStamp NV_ALIGN_BYTES(8);
870         NvU8 minPresentInterval;
871 
872         /* This field cannot be used for the main layer right now. */
873         struct {
874             struct NvKmsCompositionParams val;
875             NvBool specified;
876         } compositionParams;
877 
878         /*
879          * Color-space conversion matrix applied to the layer before
880          * compositing.
881          *
882          * If csc::specified is TRUE and csc::useMain is TRUE, then the CSC
883          * matrix specified in the main layer is used instead of the one here.
884          * If csc::specified is FALSE, then the CSC matrix used from the previous
885          * flip is used. csc::useMain must be set to FALSE for the main layer.
886          */
887         struct {
888             NvBool specified;
889             NvBool useMain;
890             struct NvKmsCscMatrix matrix;
891         } csc;
892 
893         /*
894          * When true, all pending flips and synchronization operations get
895          * ignored, and channel flips to given buffer. Notifier and semaphore
896          * should not be specified if this flag is true.  This flag does
897          * nothing if set true for NVKMS_IOCTL_SET_MODE ioctl.
898          *
899          * This flag allows client to remove stalled flips and unblock
900          * the channel.
901          *
902          * This flag cannot be used for the overlay layer.
903          */
904         NvBool skipPendingFlips;
905 
906         /*
907          * This field can be used when
908          * NvKmsAllocDeviceReply::layerCaps[layer].supportsHDR = TRUE.
909          *
910          * If staticMetadata is enabled for multiple layers, flip request
911          * will be rejected.
912          */
913         struct {
914             NvBool specified;
915             /*!
916              * If TRUE, enable HDR static metadata. If FALSE, disable it.
917              *
918              * Note that “specified” serves to mark the field as being changed
919              * in this flip request, rather than as specified for this frame.
920              * So to disable HDR static metadata, set hdr.specified = TRUE and
921              * hdr.staticMetadata.enabled = FALSE.
922              */
923             NvBool enabled;
924             struct NvKmsHDRStaticMetadata staticMetadata;
925         } hdr;
926 
927         /* Specifies whether the input color range is FULL or LIMITED. */
928         struct {
929             enum NvKmsInputColorRange val;
930             NvBool specified;
931         } colorRange;
932 
933         /* This field has no effect right now. */
934         struct {
935             enum NvKmsInputColorSpace val;
936             NvBool specified;
937         } colorSpace;
938     } layer[NVKMS_MAX_LAYERS_PER_HEAD];
939 };
940 
941 struct NvKmsFlipCommonReplyOneHead {
942     struct {
943         struct NvKmsSyncpt postSyncpt;
944     } layer[NVKMS_MAX_LAYERS_PER_HEAD];
945 };
946 
947 /*!
948  * NVKMS_IOCTL_ALLOC_DEVICE: Allocate an NVKMS device object.
949  *
950  * This has the scope of a resman SLI device.
951  *
952  * Multiple clients can allocate devices (DRM-KMS, multiple X
953  * servers).  Clients should configure SLI before initializing NVKMS.
954  * NVKMS will query resman for the current SLI topology.
955  *
956  * The SLI configuration (both the linked SLI device, and the sliMosaic
957  * boolean below) will be latched when the specified GPU transitions
958  * from zero NVKMS devices allocated to one NVKMS device allocated.
959  *
960  * The returned information will remain static until the NVKMS device
961  * object is freed.
962  */
963 
964 struct NvKmsAllocDeviceRequest {
965     /*!
966      * Clients should populate versionString with the value of
967      * NV_VERSION_STRING from nvUnixVersion.h.  This is used for a
968      * version handshake.
969      */
970     char versionString[NVKMS_NVIDIA_DRIVER_VERSION_STRING_LENGTH];
971 
972     /*!
973      * The (primary) GPU for this device; this is used as the value
974      * for NV0080_ALLOC_PARAMETERS::deviceId.
975      */
976     NvU32 deviceId;
977 
978     /*!
979      * Whether SLI Mosaic is requested: i.e., multiple disps, one
980      * per physical GPU, for the SLI device.
981      */
982     NvBool sliMosaic;
983 
984     /*!
985      * When tryInferSliMosaicFromExistingDevice=TRUE, then the above
986      * 'sliMosaic' field is ignored and the ALLOC_DEVICE request will
987      * inherit the current sliMosaic state of the existing device
988      * identified by deviceId.  If there is not an existing device for
989      * deviceId, then the ALLOC_DEVICE request will proceed normally, honoring
990      * the requested sliMosaic state.
991      */
992     NvBool tryInferSliMosaicFromExistingDevice;
993 
994     /*!
995      * NVKMS will use the 3D engine for headSurface.  If clients want to avoid
996      * the use of the 3D engine, set no3d = TRUE.  Note this will cause modesets
997      * that require headSurface to fail.
998      *
999      * This flag is only honored when there is not already an existing device
1000      * for the deviceId.
1001      */
1002     NvBool no3d;
1003 
1004     /*!
1005      * When enableConsoleHotplugHandling is TRUE, NVKMS will start handling
1006      * hotplug events at the console when no modeset owner is present.
1007      *
1008      * If FALSE, console hotplug handling behavior is not changed.
1009      *
1010      * This should be set to TRUE for clients that intend to allocate the device
1011      * but don't intend to become the modeset owner right away. It should be set
1012      * to FALSE for clients that may take modeset ownership immediately, in
1013      * order to suppress hotplug handling between the NVKMS_IOCTL_ALLOC_DEVICE
1014      * and NVKMS_IOCTL_GRAB_OWNERSHIP calls when the calling client is the first
1015      * to allocate the device.
1016      *
1017      * Note that NVKMS_IOCTL_RELEASE_OWNERSHIP also enables console hotplug
1018      * handling. Once enabled, console hotplug handling remains enabled until
1019      * the last client frees the device.
1020      */
1021     NvBool enableConsoleHotplugHandling;
1022 
1023     struct {
1024         /* name[0] == '\0' for unused registryKeys[] array elements. */
1025         char name[NVKMS_MAX_DEVICE_REGISTRY_KEYNAME_LEN];
1026         NvU32 value;
1027     } registryKeys[NVKMS_MAX_DEVICE_REGISTRY_KEYS];
1028 };
1029 
1030 enum NvKmsAllocDeviceStatus {
1031     NVKMS_ALLOC_DEVICE_STATUS_SUCCESS,
1032     NVKMS_ALLOC_DEVICE_STATUS_VERSION_MISMATCH,
1033     NVKMS_ALLOC_DEVICE_STATUS_BAD_REQUEST,
1034     NVKMS_ALLOC_DEVICE_STATUS_FATAL_ERROR,
1035     NVKMS_ALLOC_DEVICE_STATUS_NO_HARDWARE_AVAILABLE,
1036     NVKMS_ALLOC_DEVICE_STATUS_CORE_CHANNEL_ALLOC_FAILED,
1037 };
1038 
1039 
1040 struct NvKmsAllocDeviceReply {
1041 
1042     enum NvKmsAllocDeviceStatus status;
1043 
1044     /*!
1045      * The handle to use when identifying this NVKMS device in
1046      * subsequent calls.
1047      */
1048     NvKmsDeviceHandle deviceHandle;
1049 
1050     /*!
1051      * A bitmask, indicating the GPUs, one per bit, contained by this
1052      * device.
1053      */
1054     NvU32 subDeviceMask;
1055 
1056     /*! The number of heads on each disp. */
1057     NvU32 numHeads;
1058 
1059     /*! The number of disps. */
1060     NvU32 numDisps;
1061 
1062     /*! The handle to identify each disp, in dispHandles[0..numDisps). */
1063     NvKmsDispHandle dispHandles[NVKMS_MAX_SUBDEVICES];
1064 
1065     /*!
1066      * Device-wide Capabilities: of the display engine.
1067      *
1068      * IMPLEMENTATION NOTE: this is the portion of DispHalRec::caps
1069      * that can vary between EVO classes.
1070      */
1071     NvBool requiresVrrSemaphores;
1072     NvBool inputLutAppliesToBase;
1073 
1074     /*!
1075      * Whether the client can allocate and manipulate SwapGroup objects via
1076      * NVKMS_IOCTL_ALLOC_SWAP_GROUP and friends.
1077      */
1078     NvBool supportsSwapGroups;
1079 
1080     /*!
1081      * Whether NVKMS supports Warp and Blend on this device.
1082      */
1083     NvBool supportsWarpAndBlend;
1084 
1085     /*!
1086      * When nIsoSurfacesInVidmemOnly=TRUE, then only video memory
1087      * surfaces can be used for the surface in
1088      * NvKmsCompletionNotifierDescription or NvKmsSemaphore.
1089      */
1090     NvBool nIsoSurfacesInVidmemOnly;
1091 
1092     /*
1093      * When requiresAllAllocationsInSysmem=TRUE, then all memory allocations
1094      * that will be accessed by display must come from sysmem.
1095      */
1096     NvBool requiresAllAllocationsInSysmem;
1097 
1098     /*
1099      * Whether the device that NVKMS is driving supports headSurface GPU
1100      * composition.
1101      */
1102     NvBool supportsHeadSurface;
1103 
1104     /*!
1105      * The display engine supports a "legacy" format for notifiers and
1106      * semaphores (one word for semaphores and base channel notifiers;
1107      * two words for overlay notifiers).  On newer GPUs, the display
1108      * engine also supports a similar four word semaphore and notifier
1109      * format used by graphics.
1110      *
1111      * This describes which values are valid for NvKmsNIsoFormat.
1112      *
1113      * Iff a particular enum NvKmsNIsoFormat 'value' is supported,
1114      * then (1 << value) will be set in validNIsoFormatMask.
1115      */
1116     NvU8 validNIsoFormatMask;
1117 
1118     NvU32 surfaceAlignment;
1119     NvU32 maxWidthInBytes;
1120     NvU32 maxWidthInPixels;
1121     NvU32 maxHeightInPixels;
1122     NvU32 maxCursorSize;
1123 
1124     /*!
1125      * The page kind used by the GPU's MMU for uncompressed block-linear color
1126      * formats.
1127      */
1128     NvU8 genericPageKind;
1129 
1130     /*!
1131      * Describes the supported Color Key selects and blending modes for match
1132      * and nomatch cursor pixels.
1133      */
1134     struct NvKmsCompositionCapabilities cursorCompositionCaps;
1135 
1136     /*! The number of layers attached to each head. */
1137     NvU32 numLayers[NVKMS_MAX_HEADS_PER_DISP];
1138 
1139     /*!
1140      * Describes supported functionalities for each layer.
1141      */
1142     struct NvKmsLayerCapabilities layerCaps[NVKMS_MAX_LAYERS_PER_HEAD];
1143 
1144     /*!
1145      * This bitmask specifies all of the (rotation, reflectionX, reflectionY)
1146      * combinations that are supported for the main and overlay layers.
1147      * Each bit in this bitmask is mapped to one combination per the scheme
1148      * in NvKmsRRParamsToCapBit().
1149      */
1150     NvU16 validLayerRRTransforms;
1151 
1152     /*!
1153      * IO coherency modes that display supports for ISO and NISO memory
1154      * allocations, respectively.
1155      */
1156     NvKmsDispIOCoherencyModes isoIOCoherencyModes;
1157     NvKmsDispIOCoherencyModes nisoIOCoherencyModes;
1158 
1159     /*!
1160      * 'displayIsGpuL2Coherent' indicates whether display is coherent with
1161      * GPU's L2 cache.
1162      */
1163     NvBool displayIsGpuL2Coherent;
1164 
1165     /*!
1166      * 'supportsSyncpts' indicates whether NVKMS supports the use of syncpts
1167      * for synchronization.
1168      */
1169     NvBool supportsSyncpts;
1170 
1171     /*!
1172      * 'supportsIndependentAcqRelSemaphore' indicates whether HW supports
1173      * configuring different semaphores for acquire and release for a buffer
1174      * flip on a given layer.
1175      */
1176     NvBool supportsIndependentAcqRelSemaphore;
1177 
1178     /*!
1179      * 'supportsVblankSyncObjects' indicates whether HW supports raster
1180      * generator sync objects that signal at vblank.
1181      */
1182     NvBool supportsVblankSyncObjects;
1183 };
1184 
1185 struct NvKmsAllocDeviceParams {
1186     struct NvKmsAllocDeviceRequest request; /*! in */
1187     struct NvKmsAllocDeviceReply reply;     /*! out */
1188 };
1189 
1190 
1191 /*!
1192  * NVKMS_IOCTL_FREE_DEVICE: Free the NVKMS device object specified by
1193  * deviceHandle.
1194  *
1195  * The underlying device is not actually freed until all callers of
1196  * NVKMS_IOCTL_ALLOC_DEVICE have freed their reference to the device.
1197  *
1198  * When a client calls FREE_DEVICE, any configuration specified by
1199  * that client will be removed:
1200  * - Any EDID overrides.
1201  * - Any interest declared on dynamic dpys.
1202  * - Any cursor image on any head.
1203  * - Any custom LUT contents.
1204  * - Any interest declared on any events.
1205  *
1206  * XXX define how FREE_DEVICE interacts with:
1207  * - concurrent X servers on different VTs
1208  * - console restore
1209  */
1210 
1211 struct NvKmsFreeDeviceRequest {
1212     NvKmsDeviceHandle deviceHandle;
1213 };
1214 
1215 struct NvKmsFreeDeviceReply {
1216     NvU32 padding;
1217 };
1218 
1219 struct NvKmsFreeDeviceParams {
1220     struct NvKmsFreeDeviceRequest request; /*! in */
1221     struct NvKmsFreeDeviceReply reply;     /*!out */
1222 };
1223 
1224 
1225 /*!
1226  * NVKMS_IOCTL_QUERY_DISP: Query information about the NVKMS disp
1227  * object specified by the tuple (deviceHandle, dispHandle).
1228  *
1229  * The returned information will remain static until the NVKMS device
1230  * object is freed.
1231  */
1232 
1233 struct NvKmsQueryDispRequest {
1234     NvKmsDeviceHandle deviceHandle;
1235     NvKmsDispHandle dispHandle;
1236 };
1237 
1238 struct NvKmsQueryDispReply {
1239     /*! The possible dpys for this disp, excluding any dynamic dpys. */
1240     NVDpyIdList validDpys;
1241 
1242     /*! The dpys that were driven at boot-time, if any. */
1243     NVDpyIdList bootDpys;
1244 
1245     /*! The dpys that are capable of dynamic mux switching, if any. */
1246     NVDpyIdList muxDpys;
1247 
1248     /*! The framelock device, if any, connected to this disp. */
1249     NvKmsFrameLockHandle frameLockHandle;
1250 
1251     /*! The number of connectors on this disp. */
1252     NvU32 numConnectors;
1253 
1254     /*!
1255      * The handle to identify each connector, in
1256      * connectorHandles[0..numConnectors)
1257      */
1258     NvKmsConnectorHandle connectorHandles[NVKMS_MAX_CONNECTORS_PER_DISP];
1259 
1260     /*!
1261      * A string describing one of the the GPUs used by this disp.  The
1262      * NVKMS log will also print this string to the kernel log.  Users
1263      * should be able to correlate GPUs between NVKMS and NVKMS
1264      * clients using this string.
1265      */
1266     char gpuString[NVKMS_GPU_STRING_SIZE];
1267 };
1268 
1269 struct NvKmsQueryDispParams {
1270     struct NvKmsQueryDispRequest request; /*! in */
1271     struct NvKmsQueryDispReply reply;     /*! out */
1272 };
1273 
1274 
1275 /*!
1276  * NVKMS_IOCTL_QUERY_CONNECTOR_STATIC_DATA: Query information about the NVKMS
1277  * connector object specified by the triplet (deviceHandle, dispHandle,
1278  * connectorHandle).
1279  *
1280  * The returned information will remain static until the NVKMS device
1281  * object is freed.
1282  */
1283 
1284 struct NvKmsQueryConnectorStaticDataRequest {
1285     NvKmsDeviceHandle deviceHandle;
1286     NvKmsDispHandle dispHandle;
1287     NvKmsConnectorHandle connectorHandle;
1288 };
1289 
1290 struct NvKmsQueryConnectorStaticDataReply {
1291     NVDpyId dpyId;
1292     NvBool isDP;
1293     NvBool isLvds;
1294     NvBool locationOnChip;
1295     NvU32 legacyTypeIndex;
1296     NvKmsConnectorType type;
1297     NvU32 typeIndex;
1298     NvKmsConnectorSignalFormat signalFormat;
1299     NvU32 physicalIndex;
1300     NvU32 physicalLocation;
1301 };
1302 
1303 struct NvKmsQueryConnectorStaticDataParams {
1304     struct NvKmsQueryConnectorStaticDataRequest request; /*! in */
1305     struct NvKmsQueryConnectorStaticDataReply reply;     /*! out */
1306 };
1307 
1308 
1309 /*!
1310  * NVKMS_IOCTL_QUERY_CONNECTOR_DYNAMIC_DATA: Query dynamic information about the
1311  * NVKMS connector object specified by the triplet (deviceHandle, dispHandle,
1312  * connectorHandle).
1313  */
1314 
1315 struct NvKmsQueryConnectorDynamicDataRequest {
1316     NvKmsDeviceHandle deviceHandle;
1317     NvKmsDispHandle dispHandle;
1318     NvKmsConnectorHandle connectorHandle;
1319 };
1320 
1321 struct NvKmsQueryConnectorDynamicDataReply {
1322 #define NVKMS_DP_DETECT_COMPLETE_POLL_INTERVAL_USEC    100000 /* in microseconds */
1323 #define NVKMS_DP_DETECT_COMPLETE_TIMEOUT_USEC        10000000 /* in microseconds */
1324 
1325     /*
1326      * For DisplayPort devices, indicates whether the DisplayPort library is
1327      * finished detecting devices on this connector.  This is set to TRUE for
1328      * other devices because NVKMS knows as soon as ALLOC_DEVICE is complete
1329      * whether the device is connected or not.
1330      */
1331     NvBool detectComplete;
1332     /*
1333      * Contains the list of display IDs for dynamic dpys detected on this
1334      * connector.
1335      */
1336     NVDpyIdList dynamicDpyIdList;
1337 };
1338 
1339 struct NvKmsQueryConnectorDynamicDataParams {
1340     struct NvKmsQueryConnectorDynamicDataRequest request; /*! in */
1341     struct NvKmsQueryConnectorDynamicDataReply reply;     /*! out */
1342 };
1343 
1344 
1345 /*!
1346  * NVKMS_IOCTL_QUERY_DPY_STATIC_DATA: Query static information about
1347  * the NVKMS dpy object specified by the triplet (deviceHandle,
1348  * dispHandle, dpyId).  This information should remain static for the
1349  * lifetime of the dpy.
1350  */
1351 
1352 struct NvKmsQueryDpyStaticDataRequest {
1353     NvKmsDeviceHandle deviceHandle;
1354     NvKmsDispHandle dispHandle;
1355     NVDpyId dpyId;
1356 };
1357 
1358 struct NvKmsQueryDpyStaticDataReply {
1359     NvKmsConnectorHandle connectorHandle; /*! The connector driving this dpy. */
1360     NvU32 type;                        /*! NV0073_CTRL_SPECIFIC_DISPLAY_TYPE_ */
1361     char dpAddress[NVKMS_DP_ADDRESS_STRING_LENGTH];
1362     NvBool mobileInternal;
1363     NvBool isDpMST;
1364     /* Bitmask of valid heads to drive this dpy. */
1365     NvU32 headMask;
1366 };
1367 
1368 struct NvKmsQueryDpyStaticDataParams {
1369     struct NvKmsQueryDpyStaticDataRequest request; /*! in */
1370     struct NvKmsQueryDpyStaticDataReply reply;     /*! out */
1371 };
1372 
1373 
1374 /*!
1375  * NVKMS_IOCTL_QUERY_DPY_DYNAMIC_DATA: Query dynamic information about
1376  * the NVKMS dpy object specified by the triplet (deviceHandle,
1377  * dispHandle, dpyId).
1378  *
1379  * This information should be re-queried after an
1380  * NVKMS_EVENT_TYPE_DPY_CHANGED event.
1381  */
1382 
1383 struct NvKmsQueryDpyDynamicDataRequest {
1384     NvKmsDeviceHandle deviceHandle;
1385     NvKmsDispHandle dispHandle;
1386     NVDpyId dpyId;
1387 
1388     NvBool forceConnected;
1389     NvBool forceDisconnected;
1390     NvBool overrideEdid;
1391     NvBool ignoreEdid;
1392     NvBool ignoreEdidChecksum;
1393     NvBool allowDVISpecPClkOverride;
1394     NvBool dpInbandStereoSignaling;
1395     NvBool disableACPIBrightnessHotkeys;
1396 
1397     /*
1398      * If overrideEdid is TRUE, then edid::buffer[] contains an EDID
1399      * to override anything detected.
1400      */
1401     struct {
1402         NvU16 bufferSize;
1403         NvU8 buffer[NVKMS_EDID_BUFFER_SIZE];
1404     } edid;
1405 };
1406 
1407 enum NvKmsDpyVRRType {
1408     NVKMS_DPY_VRR_TYPE_NONE,
1409     NVKMS_DPY_VRR_TYPE_GSYNC,
1410     NVKMS_DPY_VRR_TYPE_ADAPTIVE_SYNC_DEFAULTLISTED,
1411     NVKMS_DPY_VRR_TYPE_ADAPTIVE_SYNC_NON_DEFAULTLISTED,
1412 };
1413 
1414 struct NvKmsQueryDpyDynamicDataReply {
1415     char name[NVKMS_DPY_NAME_SIZE];
1416 
1417     NvU32 maxPixelClockKHz;
1418     NvBool connected;
1419     NvBool isVirtualRealityHeadMountedDisplay;
1420 
1421     struct {
1422         NvU8 heightInCM; /* vertical screen size */
1423         NvU8 widthInCM; /* horizontal screen size */
1424     } physicalDimensions;
1425 
1426     /*!
1427      * Which VRR type has been selected for this display, either true
1428      * G-SYNC, Adaptive-Sync defaultlisted, or Adaptive-Sync non-defaultlisted.
1429      */
1430     enum NvKmsDpyVRRType vrrType;
1431 
1432     struct {
1433         NvBool supported;
1434         NvBool isDLP;
1435         NvBool isAegis;
1436         NvU32  subType; /*! STEREO_PLUG_AND_PLAY_ from nvStereoDisplayDef.h */
1437     } stereo3DVision;
1438 
1439     struct {
1440         struct {
1441             NvBool valid;
1442             NvU8 buffer[NVKMS_GUID_SIZE];
1443             char str[NVKMS_GUID_STRING_SIZE];
1444         } guid;
1445     } dp;
1446 
1447     struct {
1448         /*!
1449          * The size of the EDID in buffer[], or 0 if there is no EDID
1450          * available in buffer[].
1451          */
1452         NvU16 bufferSize;
1453 
1454         /*!
1455          * Whether NVKMS determined that the EDID is valid.  If the
1456          * EDID is not valid, there may still be information available
1457          * in infoString: the infoString will describe why the EDID
1458          * was deemed invalid.
1459          */
1460         NvBool valid;
1461 
1462         /*!
1463          * The raw EDID bytes.
1464          */
1465         NvU8 buffer[NVKMS_EDID_BUFFER_SIZE];
1466 
1467         /*!
1468          * Parsed information from the EDID.  For the raw EDID bytes,
1469          * see NvKmsQueryDpyDynamicDataParams::edid::buffer[].
1470          */
1471         char infoString[NVKMS_EDID_INFO_STRING_LENGTH];
1472     } edid;
1473 
1474     struct NvKmsSuperframeInfo superframeInfo;
1475 };
1476 
1477 struct NvKmsQueryDpyDynamicDataParams {
1478     struct NvKmsQueryDpyDynamicDataRequest request; /*! in */
1479     struct NvKmsQueryDpyDynamicDataReply reply;     /*! out */
1480 };
1481 
1482 
1483 /*!
1484  * NVKMS_IOCTL_VALIDATE_MODE_INDEX: Validate a particular mode from a
1485  * dpy's candidate modes.
1486  *
1487  * NVKMS can consider modes from a dpy's EDID, as well as a
1488  * variety of builtin modes.
1489  *
1490  * This ioctl identifies one of those candidate modes by index.  NVKMS
1491  * will attempt to validate that candidate mode for the dpy, using the
1492  * specified mode validation parameters.
1493  *
1494  * If the mode index is larger than the list of candidate modes,
1495  * reply::end will be TRUE.  Otherwise, reply::end will be FALSE, and
1496  * reply::mode will contain the candidate mode.
1497  *
1498  * If the mode is valid, then reply::valid will be TRUE.  Otherwise,
1499  * reply::valid will be FALSE.  In either case, request::pInfoString[]
1500  * will contain a description of what happened during mode validation.
1501  *
1502  * To query the full modepool, clients should repeatedly call
1503  * NVKMS_IOCTL_VALIDATE_MODE_INDEX with increasing mode index values,
1504  * until NVKMS reports end==TRUE.
1505  *
1506  * Note that the candidate mode list can change when the dpy changes
1507  * (reported by the NVKMS_EVENT_TYPE_DPY_CHANGED event).  The client
1508  * should restart its modepool querying if it receives a DPY_CHANGED
1509  * event.  The candidate mode list can also change based on the
1510  * parameters in request::modeValidation.  Clients should not change
1511  * request::modeValidation while looping over candidate mode indices.
1512  *
1513  * Pseudocode example usage pattern:
1514  *
1515  *   struct NvKmsModeValidationParams modeValidation = Initialize();
1516  *
1517  * retry:
1518  *   NvU32 modeIndex = 0;
1519  *
1520  *   while (1) {
1521  *       char infoString[INFO_STRING_LENGTH];
1522  *       memset(&params);
1523  *       params.request.dpyId = dpyId;
1524  *       params.request.modeIndex = modeIndex++;
1525  *       params.request.modeValidation = modeValidation;
1526  *       params.request.pInfoString = nvKmsPointerToNvU64(infoString);
1527  *       params.request.infoStringLength = sizeof(infoString);
1528  *
1529  *       ioctl(&params);
1530  *
1531  *       if (params.reply.end) break;
1532  *
1533  *       print(infoString);
1534  *
1535  *       if (params.reply.valid) {
1536  *           AddToModePool(params.reply.mode);
1537  *       }
1538  *   }
1539  *
1540  *   if (dpyChanged) goto retry;
1541  *
1542  */
1543 
1544 struct NvKmsValidateModeIndexRequest {
1545     NvKmsDeviceHandle deviceHandle;
1546     NvKmsDispHandle dispHandle;
1547     NVDpyId dpyId;
1548     struct NvKmsModeValidationParams modeValidation;
1549     NvU32 modeIndex;
1550 
1551     /*
1552      * Pointer to a string of size 'infoStringSize'.
1553      * Use nvKmsPointerToNvU64() to assign pInfoString.
1554      * The maximum size allowed is
1555      * NVKMS_MODE_VALIDATION_MAX_INFO_STRING_LENGTH.
1556      */
1557     NvU32 infoStringSize;
1558     NvU64 pInfoString NV_ALIGN_BYTES(8);
1559 };
1560 
1561 struct NvKmsValidateModeIndexReply {
1562     NvBool end;
1563     NvBool valid;
1564 
1565     struct NvKmsMode mode;
1566 
1567     /*! The validSyncs used by NVKMS when validating the mode. */
1568     struct NvKmsModeValidationValidSyncs validSyncs;
1569 
1570     /*! Whether this mode is marked as "preferred" by the EDID. */
1571     NvBool preferredMode;
1572 
1573     /*! A text description of the mode. */
1574     char description[64];
1575 
1576     /*! Where the mode came from. */
1577     enum NvKmsModeSource {
1578         NvKmsModeSourceUnknown = 0,
1579         NvKmsModeSourceEdid    = 1,
1580         NvKmsModeSourceVesa    = 2,
1581     } source;
1582 
1583     /* The number of bytes written to 'pInfoString' (from the request) */
1584     NvU32 infoStringLenWritten;
1585 
1586     /*!
1587      * These are the usage bounds that may be possible with this mode,
1588      * assuming that only one head is active. For actual usage bounds,
1589      * see guaranteedUsage and possibleUsage returned in
1590      * NvKmsSetModeOneHeadReply.
1591      */
1592     struct NvKmsUsageBounds modeUsage;
1593 };
1594 
1595 struct NvKmsValidateModeIndexParams {
1596     struct NvKmsValidateModeIndexRequest request; /*! in */
1597     struct NvKmsValidateModeIndexReply reply;     /*! out */
1598 };
1599 
1600 
1601 /*!
1602  * NVKMS_IOCTL_VALIDATE_MODE: Validate an individual mode for the
1603  * specified dpy.
1604  *
1605  * Given the validation parameters, NVKMS will test whether the given
1606  * mode is currently valid for the specified dpy.
1607  *
1608  * If the mode is valid, then reply::valid will be TRUE.  Otherwise,
1609  * reply::valid will be FALSE.  In either case, reply::infoString[]
1610  * will contain a description of what happened during mode validation.
1611  */
1612 
1613 struct NvKmsValidateModeRequest {
1614     NvKmsDeviceHandle deviceHandle;
1615     NvKmsDispHandle dispHandle;
1616     NVDpyId dpyId;
1617     struct NvKmsModeValidationParams modeValidation;
1618     struct NvKmsMode mode;
1619 
1620     /*
1621      * Pointer to a string of size 'infoStringSize'.
1622      * Use nvKmsPointerToNvU64() to assign pInfoString.
1623      * The maximum size allowed is
1624      * NVKMS_MODE_VALIDATION_MAX_INFO_STRING_LENGTH.
1625      */
1626     NvU32 infoStringSize;
1627     NvU64 pInfoString NV_ALIGN_BYTES(8);
1628 };
1629 
1630 struct NvKmsValidateModeReply {
1631     NvBool valid;
1632 
1633     /*! The validSyncs used by NVKMS when validating the mode. */
1634     struct NvKmsModeValidationValidSyncs validSyncs;
1635 
1636     /* The number of bytes written to 'pInfoString' (from the request) */
1637     NvU32 infoStringLenWritten;
1638 
1639     /*!
1640      * These are the usage bounds that may be possible with this mode,
1641      * assuming that only one head is active. For actual usage bounds,
1642      * see guaranteedUsage and possibleUsage returned in
1643      * NvKmsSetModeOneHeadReply.
1644      */
1645     struct NvKmsUsageBounds modeUsage;
1646 };
1647 
1648 struct NvKmsValidateModeParams {
1649     struct NvKmsValidateModeRequest request; /*! in */
1650     struct NvKmsValidateModeReply reply;     /*! out */
1651 };
1652 
1653 
1654 /*!
1655  * NVKMS_IOCTL_SET_MODE: Perform a modeset.
1656  *
1657  * NvKmsSetModeRequest can describe the modetiming configuration
1658  * across all heads of all disps within the SLI device.
1659  *
1660  * The elements in NvKmsSetModeRequest::disp[] correspond to the disps
1661  * returned in NvKmsAllocDeviceReply::dispHandles[].
1662  *
1663  * To only touch certain heads and disps, use the
1664  * requestedHeadsBitMask and requestedDispsBitMask fields to limit
1665  * which array elements are honored.
1666  *
1667  * If the request is invalid, one or more of the
1668  * NvKmsSetMode{,OneDisp,OneHead}Reply::status fields will have a
1669  * non-SUCCESS value.  If the mode set completed successfully, then
1670  * all {NvKmsSetMode{,OneDisp,OneHead}Reply::status fields should be
1671  * SUCCESS.
1672  */
1673 
1674 struct NvKmsSetModeHeadSurfaceParams {
1675     NvBool forceCompositionPipeline;
1676     NvBool forceFullCompositionPipeline;
1677     NvBool fakeOverlay;
1678     NvBool blendAfterWarp;
1679     NvBool transformSpecified;
1680 
1681     /* Reflect the image along the X axis. */
1682     NvBool reflectionX;
1683 
1684     /* Reflect the image along the Y axis. */
1685     NvBool reflectionY;
1686 
1687     /*
1688      * Rotate the image counter-clockwise in 90 degree increments.
1689      *
1690      * Reflection (specified above by ::reflection[XY]) is applied
1691      * before rotation.  This matches the semantics of RandR.  From:
1692      *
1693      *  https://cgit.freedesktop.org/xorg/proto/randrproto/tree/randrproto.txt
1694      *
1695      * "Rotation and reflection and how they interact can be confusing. In
1696      * Randr, the coordinate system is rotated in a counter-clockwise direction
1697      * relative to the normal orientation. Reflection is along the window system
1698      * coordinate system, not the physical screen X and Y axis, so that rotation
1699      * and reflection do not interact. The other way to consider reflection is
1700      * to is specified in the 'normal' orientation, before rotation, if you find
1701      * the other way confusing."
1702      */
1703     enum NvKmsRotation rotation;
1704     enum NvKmsPixelShiftMode pixelShift;
1705     enum NvKmsResamplingMethod resamplingMethod;
1706     struct NvKmsMatrix transform; /* Only honored if transformSpecified. */
1707 
1708     NvKmsSurfaceHandle blendTexSurfaceHandle;
1709     NvKmsSurfaceHandle offsetTexSurfaceHandle;
1710 
1711     /*
1712      * When warpMesh::surfaceHandle is non-zero, it indicates a surface
1713      * containing warp mesh vertex data.  The surface should:
1714      *
1715      * - Have a width multiple of 1024 pixels.
1716      * - Have a depth of 32.
1717      * - Contain a binary representation of a list of six-component
1718      *   vertices. Each of these components is a 32-bit floating point value.
1719      *
1720      * The X, Y components should contain normalized vertex coordinates, to be
1721      * rendered as a triangle list or strip.  The X and Y components' [0,1]
1722      * range map to the head's ViewportOut X and Y, respectively.
1723      *
1724      * The U, V, R, and Q components should contain normalized, projective
1725      * texture coordinates:
1726      *
1727      * U, V: 2D texture coordinate.  U and V components' [0,1] range maps to the
1728      * display's MetaMode ViewportIn X and Y, respectively.
1729      *
1730      * R: unused
1731      *
1732      * Q: Used for interpolation purposes.  This is typically the third
1733      * component of the result of a multiplication by a 3x3 projective transform
1734      * matrix.
1735      *
1736      * warpMesh::vertexCount should contain the amount of vertices stored in the
1737      * surface.
1738      *
1739      * warpMesh::dataType indicates if the vertices describe a triangle list or
1740      * a triangle strip.  A triangle list must have a vertexCount that is a
1741      * multiple of 3.
1742      */
1743     struct {
1744         NvKmsSurfaceHandle surfaceHandle;
1745         NvU32 vertexCount;
1746         enum NvKmsWarpMeshDataType dataType;
1747     } warpMesh;
1748 };
1749 
1750 #define NVKMS_VRR_MIN_REFRESH_RATE_MAX_VARIANCE 10 // 10hz
1751 
1752 enum NvKmsAllowAdaptiveSync {
1753     NVKMS_ALLOW_ADAPTIVE_SYNC_DISABLED = 0,
1754     NVKMS_ALLOW_ADAPTIVE_SYNC_DEFAULTLISTED_ONLY,
1755     NVKMS_ALLOW_ADAPTIVE_SYNC_ALL,
1756 };
1757 
1758 /*! Values for the NV_KMS_DPY_ATTRIBUTE_REQUESTED_COLOR_SPACE attribute. */
1759 enum NvKmsDpyAttributeRequestedColorSpaceValue {
1760     NV_KMS_DPY_ATTRIBUTE_REQUESTED_COLOR_SPACE_RGB = 0,
1761     NV_KMS_DPY_ATTRIBUTE_REQUESTED_COLOR_SPACE_YCbCr422 = 1,
1762     NV_KMS_DPY_ATTRIBUTE_REQUESTED_COLOR_SPACE_YCbCr444 = 2,
1763 };
1764 
1765 /*!
1766  * Values for the NV_KMS_DPY_ATTRIBUTE_REQUESTED_COLOR_RANGE and
1767  * NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_RANGE attributes.
1768  */
1769 enum NvKmsDpyAttributeColorRangeValue {
1770     NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_FULL = 0,
1771     NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_LIMITED = 1,
1772 };
1773 
1774 struct NvKmsSetModeOneHeadRequest {
1775     /*!
1776      * The list of dpys to drive with this head; or, empty to disable
1777      * the head.
1778      */
1779     NVDpyIdList dpyIdList;
1780 
1781     /*! The modetimings to set on the head. */
1782     struct NvKmsMode mode;
1783 
1784     /*! The above mode will be validated, using these validation parameters. */
1785     struct NvKmsModeValidationParams modeValidationParams;
1786 
1787     /*!
1788      * The region within the raster timings that should contain an image.
1789      * This is only used when viewPortOutSpecified is TRUE.  Otherwise, the
1790      * viewPortOut is inferred from the raster timings.
1791      *
1792      * For YUV420 modes, the viewPortOut should be in "full"
1793      * horizontal space.  See the explanation in NvKmsMode.
1794      */
1795     struct NvKmsRect viewPortOut;
1796 
1797     /*!
1798      * The size, in pixels, that the head will fetch from any surface
1799      * it scans from.  The viewPortPointIn is specified in
1800      * NvKmsFlipCommonParams.
1801      *
1802      * For YUV420 modes, the viewPortSizeIn should be in "half"
1803      * horizontal space.  See the explanation in NvKmsMode.
1804      */
1805     struct NvKmsSize viewPortSizeIn;
1806 
1807     /*!
1808      * Describe the surfaces to present on this head.
1809      */
1810     struct NvKmsFlipCommonParams flip;
1811 
1812     /*!
1813      * The headSurface configuration requested, if any.
1814      */
1815     struct NvKmsSetModeHeadSurfaceParams headSurface;
1816 
1817     NvBool viewPortOutSpecified; /*! Whether to use viewPortOut. */
1818 
1819     /*!
1820      * Allow G-SYNC to be enabled on this head if it is supported by the GPU
1821      * and monitor.
1822      */
1823     NvBool allowGsync;
1824 
1825     /*!
1826      * Whether to allow Adaptive-Sync to be enabled on this head if it is
1827      * supported by the GPU:
1828      *
1829      * NVKMS_ALLOW_ADAPTIVE_SYNC_ALL:
1830      *     VRR is enabled as long as this monitor supports Adaptive-Sync.
1831      *
1832      * NVKMS_ALLOW_ADAPTIVE_SYNC_DEFAULTLISTED_ONLY:
1833      *     VRR is only enabled on this head if the monitor is on the
1834      *     Adaptive-Sync defaultlist.
1835      *
1836      * NVKMS_ALLOW_ADAPTIVE_SYNC_DISABLED:
1837      *     VRR is forced to be disabled if this is an Adaptive-Sync monitor.
1838      */
1839     enum NvKmsAllowAdaptiveSync allowAdaptiveSync;
1840 
1841     /*!
1842      * Override the minimum refresh rate for VRR monitors specified by the
1843      * EDID (0 to not override the EDID-provided value).  Clamped at modeset
1844      * time to within NVKMS_VRR_MIN_REFRESH_RATE_MAX_VARIANCE of the
1845      * EDID-specified minimum refresh rate, as long as the minimum is no
1846      * lower than 1hz and the maximum does not exceed the maximum refresh rate
1847      * defined by the mode timings.  The current minimum refresh rate and this
1848      * valid range are exposed through
1849      * NV_KMS_DPY_ATTRIBUTE_VRR_MIN_REFRESH_RATE.
1850      *
1851      * Does not affect G-SYNC monitors, which do not have a minimum refresh
1852      * rate.
1853      */
1854     NvU32 vrrOverrideMinRefreshRate;
1855 
1856     /*!
1857      * Output colorspace. Valid only when colorSpaceSpecified is true.
1858      */
1859     enum NvKmsDpyAttributeRequestedColorSpaceValue colorSpace;
1860     NvBool colorSpaceSpecified;
1861 
1862     /*!
1863      * Output color range. Valid only when colorRangeSpecified is true.
1864      */
1865     enum NvKmsDpyAttributeColorRangeValue colorRange;
1866     NvBool colorRangeSpecified;
1867 };
1868 
1869 struct NvKmsSetModeOneDispRequest {
1870     /*!
1871      * The bit mask of which head[] elements to look at on this disp;
1872      * any other head will use its existing configuration.
1873      */
1874     NvU32 requestedHeadsBitMask;
1875     struct NvKmsSetModeOneHeadRequest head[NVKMS_MAX_HEADS_PER_DISP];
1876 };
1877 
1878 struct NvKmsSetModeRequest {
1879     NvKmsDeviceHandle deviceHandle;
1880 
1881     /*!
1882      * When a modeset request is made, NVKMS will first perform
1883      * validation to confirm whether the request can be satisfied.  If
1884      * the requested configuration cannot be fulfilled, the request
1885      * returns FALSE.
1886      *
1887      * Only the modeset owner can issue a modeset with commit set to TRUE.
1888      *
1889      * If 'commit' is FALSE, then the status of validation will be returned.
1890      *
1891      * If 'commit' is TRUE, and validation passes, then NVKMS will
1892      * apply the requested configuration.
1893      */
1894     NvBool commit;
1895 
1896     /*!
1897      * The bitmask of which indices within disp[] describe requested
1898      * configuration changes.  Any other disps will use their existing
1899      * configuration.
1900      */
1901     NvU32 requestedDispsBitMask;
1902 
1903     /*
1904      * disp[n] corresponds to the disp named by
1905      * NvKmsAllocDeviceReply::dispHandles[n].
1906      */
1907     struct NvKmsSetModeOneDispRequest disp[NVKMS_MAX_SUBDEVICES];
1908 
1909     /*!
1910      * Whether to use NVKMS's builtin headSurface support when necessary.
1911      *
1912      * XXX NVKMS HEADSURFACE TODO: Make this the default and remove this field.
1913      */
1914     NvBool allowHeadSurfaceInNvKms;
1915 };
1916 
1917 enum NvKmsSetModeOneHeadStatus {
1918     NVKMS_SET_MODE_ONE_HEAD_STATUS_SUCCESS = 0,
1919     NVKMS_SET_MODE_ONE_HEAD_STATUS_INVALID_MODE = 1,
1920     NVKMS_SET_MODE_ONE_HEAD_STATUS_INVALID_DPY = 2,
1921     NVKMS_SET_MODE_ONE_HEAD_STATUS_INVALID_CURSOR_IMAGE = 3,
1922     NVKMS_SET_MODE_ONE_HEAD_STATUS_INVALID_CURSOR_POSITION = 4,
1923     NVKMS_SET_MODE_ONE_HEAD_STATUS_INVALID_LUT = 5,
1924     NVKMS_SET_MODE_ONE_HEAD_STATUS_INVALID_FLIP = 6,
1925     NVKMS_SET_MODE_ONE_HEAD_STATUS_INVALID_PERMISSIONS = 7,
1926     NVKMS_SET_MODE_ONE_HEAD_STATUS_INVALID_HEAD_SURFACE = 8,
1927     NVKMS_SET_MODE_ONE_HEAD_STATUS_UNSUPPORTED_HEAD_SURFACE_COMBO = 9,
1928 };
1929 
1930 struct NvKmsSetModeOneHeadReply {
1931     /*!
1932      * When the NVKMS_IOCTL_SET_MODE succeeds, then this will be SUCCESS.
1933      * Otherwise, 'status' will be a non-SUCCESS value for one or more
1934      * heads and/or one or more disps.
1935      *
1936      * Note that a failure could occur for a preexisting head
1937      * configuration, so this status could be != SUCCESS for a head
1938      * not listed in NvKmsSetModeOneDispRequest::requestedHeadsBitMask.
1939      */
1940     enum NvKmsSetModeOneHeadStatus status;
1941 
1942     NvU32 hwHead;
1943 
1944     /*!
1945      * The usage bounds that may be possible on this head based on the ISO
1946      * BW at that point.
1947      *
1948      * If a flip request is within the bounds of NvKmsSetModeOneHeadReply::
1949      * guaranteedUsage, then clients can expect the flip to succeed.
1950      * If a flip request is beyond the bounds of NvKmsSetModeOneHeadReply::
1951      * guaranteedUsage but within NvKmsSetModeOneHeadReply::possibleUsage,
1952      * then the request may legitimately fail due to insufficient display
1953      * bandwidth and clients need to be prepared to handle that flip
1954      * request failure.
1955      */
1956     struct NvKmsUsageBounds possibleUsage;
1957 
1958     /*!
1959      * The guaranteed usage bounds usable on this head.
1960      */
1961     struct NvKmsUsageBounds guaranteedUsage;
1962 
1963     /*!
1964      * Whether NVKMS chose to use headSurface on this head.
1965      */
1966     NvBool usingHeadSurface;
1967 
1968     /*!
1969      * Whether NVKMS enabled VRR on this head.
1970      */
1971     NvBool vrrEnabled;
1972 
1973     /*!
1974      * Contains the 'postSyncObject' that the client requested via
1975      * NvKmsSetModeOneHeadRequest::flip.
1976      */
1977     struct NvKmsFlipCommonReplyOneHead flipReply;
1978 };
1979 
1980 enum NvKmsSetModeOneDispStatus {
1981     NVKMS_SET_MODE_ONE_DISP_STATUS_SUCCESS = 0,
1982     NVKMS_SET_MODE_ONE_DISP_STATUS_INVALID_REQUESTED_HEADS_BITMASK = 1,
1983     NVKMS_SET_MODE_ONE_DISP_STATUS_FAILED_EXTENDED_GPU_CAPABILITIES_CHECK = 2,
1984     NVKMS_SET_MODE_ONE_DISP_STATUS_FAILED_DISPLAY_PORT_BANDWIDTH_CHECK = 3,
1985     NVKMS_SET_MODE_ONE_DISP_STATUS_INCOMPATIBLE_DPYS = 4,
1986     NVKMS_SET_MODE_ONE_DISP_STATUS_DUPLICATE_DPYS = 5,
1987     NVKMS_SET_MODE_ONE_DISP_STATUS_FAILED_TO_ASSIGN_HARDWARE_HEADS = 6,
1988 };
1989 
1990 struct NvKmsSetModeOneDispReply {
1991     /*!
1992      * When the NVKMS_IOCTL_SET_MODE succeeds, then this will be SUCCESS.
1993      * Otherwise, 'status' will be a non-SUCCESS value for one or more
1994      * heads and/or one or more disps.
1995      *
1996      * Note that a failure could occur for a preexisting disp
1997      * configuration, so this status could be != SUCCESS for a disp
1998      * not listed in NvKmsSetModeRequest::requestedDispsBitMask.
1999      */
2000     enum NvKmsSetModeOneDispStatus status;
2001     struct NvKmsSetModeOneHeadReply head[NVKMS_MAX_HEADS_PER_DISP];
2002 };
2003 
2004 enum NvKmsSetModeStatus {
2005     NVKMS_SET_MODE_STATUS_SUCCESS = 0,
2006     NVKMS_SET_MODE_STATUS_INVALID_REQUESTED_DISPS_BITMASK = 1,
2007     NVKMS_SET_MODE_STATUS_NOT_MODESET_OWNER = 2,
2008 };
2009 
2010 struct NvKmsSetModeReply {
2011     enum NvKmsSetModeStatus status;
2012     struct NvKmsSetModeOneDispReply disp[NVKMS_MAX_SUBDEVICES];
2013 };
2014 
2015 struct NvKmsSetModeParams {
2016     struct NvKmsSetModeRequest request; /*! in */
2017     struct NvKmsSetModeReply reply;     /*! out */
2018 };
2019 
2020 
2021 /*!
2022  * NVKMS_IOCTL_SET_CURSOR_IMAGE: Set the cursor image for the
2023  * specified head.
2024  */
2025 
2026 struct NvKmsSetCursorImageRequest {
2027     NvKmsDeviceHandle deviceHandle;
2028     NvKmsDispHandle dispHandle;
2029     NvU32 head;
2030 
2031     struct NvKmsSetCursorImageCommonParams common;
2032 };
2033 
2034 struct NvKmsSetCursorImageReply {
2035     NvU32 padding;
2036 };
2037 
2038 struct NvKmsSetCursorImageParams {
2039     struct NvKmsSetCursorImageRequest request; /*! in */
2040     struct NvKmsSetCursorImageReply reply;     /*! out */
2041 };
2042 
2043 
2044 /*!
2045  * NVKMS_IOCTL_MOVE_CURSOR: Set the cursor position for the specified
2046  * head.
2047  *
2048  * x,y are relative to the current viewPortIn configured on the head.
2049  */
2050 
2051 struct NvKmsMoveCursorRequest {
2052     NvKmsDeviceHandle deviceHandle;
2053     NvKmsDispHandle dispHandle;
2054     NvU32 head;
2055 
2056     struct NvKmsMoveCursorCommonParams common;
2057 };
2058 
2059 struct NvKmsMoveCursorReply {
2060     NvU32 padding;
2061 };
2062 
2063 struct NvKmsMoveCursorParams {
2064     struct NvKmsMoveCursorRequest request; /*! in */
2065     struct NvKmsMoveCursorReply reply;     /*! out */
2066 };
2067 
2068 
2069 /*!
2070  * NVKMS_IOCTL_SET_LUT: Set the LUT contents for the specified head.
2071  */
2072 
2073 struct NvKmsSetLutRequest {
2074     NvKmsDeviceHandle deviceHandle;
2075     NvKmsDispHandle dispHandle;
2076     NvU32 head;
2077 
2078     struct NvKmsSetLutCommonParams common;
2079 };
2080 
2081 struct NvKmsSetLutReply {
2082     NvU32 padding;
2083 };
2084 
2085 struct NvKmsSetLutParams {
2086     struct NvKmsSetLutRequest request; /*! in */
2087     struct NvKmsSetLutReply reply;     /*! out */
2088 };
2089 
2090 
2091 /*!
2092  * NVKMS_IOCTL_IDLE_BASE_CHANNEL: Wait for the base channel to be idle on
2093  * the requested heads on the requested subdevices of a device.
2094  *
2095  * Each (head,sd) pair to be idled is described by:
2096  *
2097  *   subDevicesPerHead[head] |= NVBIT(sd)
2098  */
2099 
2100 struct NvKmsIdleBaseChannelRequest {
2101     NvKmsDeviceHandle deviceHandle;
2102     NvU32 subDevicesPerHead[NVKMS_MAX_HEADS_PER_DISP];
2103 };
2104 
2105 struct NvKmsIdleBaseChannelReply {
2106     /*!
2107      * If stopping the base channel is necessary due to a timeout, (head,sd)
2108      * pairs will be described with:
2109      *
2110      *   stopSubDevicesPerHead[head] |= NVBIT(sd)
2111      *
2112      * indicating that semaphore releases from the stalled channels may not have
2113      * occurred.
2114      */
2115     NvU32 stopSubDevicesPerHead[NVKMS_MAX_HEADS_PER_DISP];
2116 };
2117 
2118 struct NvKmsIdleBaseChannelParams {
2119     struct NvKmsIdleBaseChannelRequest request; /*! in */
2120     struct NvKmsIdleBaseChannelReply reply;     /*! out */
2121 };
2122 
2123 
2124 /*!
2125  * NVKMS_IOCTL_FLIP: Flip one or more heads on the subdevices of a device.
2126  *
2127  * At least one head must be specified in a flip request, and at most
2128  * NV_MAX_FLIP_REQUEST_HEADS may be specified.
2129  */
2130 
2131 struct NvKmsFlipRequestOneHead {
2132     NvU32 sd;
2133     NvU32 head;
2134     struct NvKmsFlipCommonParams flip;
2135 };
2136 
2137 #define NV_MAX_FLIP_REQUEST_HEADS (NV_MAX_SUBDEVICES * NV_MAX_HEADS)
2138 
2139 struct NvKmsFlipRequest {
2140     NvKmsDeviceHandle deviceHandle;
2141 
2142     /* Pointer to an array of length 'numFlipHeads'; each entry in the array is
2143      * of type 'struct NvKmsFlipRequestOneHead'. */
2144     NvU64 pFlipHead NV_ALIGN_BYTES(8);
2145     NvU32 numFlipHeads;
2146 
2147     /*!
2148      * When a flip request is made, NVKMS will first perform
2149      * validation to confirm whether the request can be satisfied.  If
2150      * the requested configuration cannot be fulfilled, the request
2151      * returns FALSE.
2152      *
2153      * If 'commit' is FALSE, then the status of validation will be returned.
2154      *
2155      * If 'commit' is TRUE, and validation passes, then NVKMS will
2156      * apply the requested configuration.
2157      */
2158     NvBool commit;
2159 
2160     /*!
2161      * When set, indicates that the client is capable of releasing the VRR
2162      * semaphore to indicate when the flip is ready.  Setting this to FALSE
2163      * disables VRR.
2164      */
2165     NvBool allowVrr;
2166 };
2167 
2168 enum NvKmsVrrFlipType {
2169     NV_KMS_VRR_FLIP_NON_VRR = 0,
2170     NV_KMS_VRR_FLIP_GSYNC,
2171     NV_KMS_VRR_FLIP_ADAPTIVE_SYNC,
2172 };
2173 
2174 struct NvKmsFlipReply {
2175     /*!
2176      * If vrrFlipType != NV_KMS_VRR_FLIP_NON_VRR, then VRR was used for the
2177      * requested flip. In this case, vrrSemaphoreIndex indicates the index
2178      * into the VRR semaphore surface that the client should release to
2179      * trigger the flip.
2180      *
2181      * A value of -1 indicates that no VRR semaphore release is needed.
2182      */
2183     NvS32 vrrSemaphoreIndex;
2184 
2185     /*!
2186      * Indicates whether the flip was non-VRR, was a VRR flip on one or more
2187      * G-SYNC displays, or was a VRR flip exclusively on Adaptive-Sync
2188      * displays.
2189      */
2190     enum NvKmsVrrFlipType vrrFlipType;
2191 
2192     /*!
2193      * Indicates either success or the reason the flip request failed.
2194      */
2195     enum NvKmsFlipResult flipResult;
2196 
2197     /*!
2198      * Entries correspond to the heads specified in
2199      * NvKmsFlipRequest::pFlipHead, in the same order.
2200      */
2201     struct NvKmsFlipCommonReplyOneHead flipHead[NV_MAX_FLIP_REQUEST_HEADS];
2202 };
2203 
2204 struct NvKmsFlipParams {
2205     struct NvKmsFlipRequest request; /*! in */
2206     struct NvKmsFlipReply reply;     /*! out */
2207 };
2208 
2209 
2210 /*!
2211  * NVKMS_IOCTL_DECLARE_DYNAMIC_DPY_INTEREST: "Dynamic dpy" reference
2212  * counting.
2213  *
2214  * Most dpys have a lifetime equal to the NVKMS device.  However, some
2215  * dpys are dynamic and are created and destroyed in response to
2216  * getting connected or disconnected.  DisplayPort MST dpys are dynamic dpys.
2217  *
2218  * When a dynamic dpy is disconnected, its NVDpyId will be freed and
2219  * made available for use by dynamic dpys connected later, unless any
2220  * client has declared "interest" in the NVDpyId.  The dynamic NVDpyId
2221  * will persist as long as a client has declared interest on it, and
2222  * will be reused for newly connected monitors at the same dynamic dpy
2223  * address (port address, in the case of DP MST dynamic dpys).
2224  *
2225  * The 'interest' field selects interest in the dynamic dpy.
2226  *
2227  * If the dynamic dpy has already been disconnected (and therefore
2228  * removed) before the client has declared interest in it, this ioctl
2229  * will fail.
2230  *
2231  * The recommended usage pattern is:
2232  *
2233  * - Declare interest in the event types:
2234  *     NVKMS_EVENT_TYPE_DYNAMIC_DPY_CONNECTED
2235  *     NVKMS_EVENT_TYPE_DYNAMIC_DPY_DISCONNECTED
2236  *
2237  * - When a DYNAMIC_DPY_CONNECTED event is received, call
2238  *     NVKMS_IOCTL_DECLARE_DYNAMIC_DPY_INTEREST
2239  *   to declare interest on the dpy.  Be sure to check the return
2240  *   value, in case the dynamic dpy was already removed.  Update any
2241  *   client bookkeeping, to start tracking the dpy.
2242  *
2243  * - When a DYNAMIC_DPY_DISCONNECTED event is received, update any
2244  *   client bookkeeping, to stop tracking this dynamic dpy.  Call
2245  *     NVKMS_IOCTL_DECLARE_DYNAMIC_DPY_INTEREST
2246  *   to remove interest on the dpy.
2247  */
2248 
2249 struct NvKmsDeclareDynamicDpyInterestRequest {
2250     NvKmsDeviceHandle deviceHandle;
2251     NvKmsDispHandle dispHandle;
2252     NVDpyId dpyId;
2253     NvBool interest;
2254 };
2255 
2256 struct NvKmsDeclareDynamicDpyInterestReply {
2257     NvU32 padding;
2258 };
2259 
2260 struct NvKmsDeclareDynamicDpyInterestParams {
2261     struct NvKmsDeclareDynamicDpyInterestRequest request; /*! in */
2262     struct NvKmsDeclareDynamicDpyInterestReply reply;     /*! out */
2263 };
2264 
2265 
2266 /*!
2267  * NVKMS_IOCTL_{,UN}REGISTER_SURFACE: Register and unregister an
2268  * RM-allocated surface with NVKMS.
2269  *
2270  * A surface must be registered with NVKMS before NVKMS can display
2271  * it.  Note that NVKMS will create its own RM object for the registered
2272  * surface.  The surface will not be freed by resman until the surface
2273  * is unregistered by the client.
2274  */
2275 
2276 struct NvKmsRegisterSurfaceRequest {
2277     NvKmsDeviceHandle deviceHandle;
2278 
2279     /*!
2280      * Surfaces can be specified either by file descriptor or by
2281      * (rmClient, rmObject) tuple.  useFd indicates which is specified
2282      * in this request.  Userspace clients are required to specify surface by
2283      * file descriptor.
2284      */
2285     NvBool useFd;
2286 
2287     /*!
2288      * The RM client handle that was used to allocate the surface.
2289      * NVKMS will use this as the hClientSrc argument to
2290      * NvRmDupObject().  Only used when useFd is FALSE.
2291      */
2292     NvU32 rmClient;
2293 
2294     /*
2295      * For multi-plane formats, clients are free to use one memory allocation
2296      * for all planes, or a separate memory allocation per plane:
2297      * - For the first usecase, 'rmObject'/'fd' and 'rmObjectSizeInBytes'
2298      *   should be the same for all planes, and each plane should have a
2299      *   different 'offset'.
2300      * - For the second usecase, 'rmObject'/'fd' should be different for each
2301      *   plane.
2302      *
2303      * The 'planes' array is indexed as follows:
2304      * - For RGB and YUV packed formats, 'planes[0]' refers to the single plane
2305      *   that's used for these formats.
2306      * - For YUV semi-planar formats, 'planes[0]' refers to the Y-plane and
2307      *   'planes[1]' refers to the UV-plane.
2308      * - For YUV planar formats, 'planes[0]' refers to the Y-plane, 'planes[1]'
2309      *   refers to the U plane, and 'planes[2]' refers to the V plane.
2310      */
2311     struct {
2312 
2313         union {
2314             NvU32 rmObject; /* RM memory handle */
2315             NvS32 fd;       /* file descriptor describing memory */
2316         } u;
2317 
2318         /*
2319          * This byte offset will be added to the base address of the RM memory
2320          * allocation, and determines the starting address of this plane within
2321          * that allocation. This offset must be 1KB-aligned.
2322          */
2323         NvU64 offset NV_ALIGN_BYTES(8);
2324 
2325         /*
2326          * If the surface layout is NvKmsSurfaceMemoryLayoutPitch, then
2327          * 'pitch' should be the pitch of this plane in bytes, and must
2328          * have an alignment of 256 bytes.  If the surface layout is
2329          * NvKmsSurfaceMemoryLayoutBlockLinear, then 'pitch' should be the
2330          * pitch of this plane in _blocks_.  Blocks are always 64 bytes
2331          * wide.
2332          */
2333         NvU32 pitch;
2334 
2335         /*
2336          * This is the size of the entire RM memory allocation pointed to by
2337          * rmObject or fd prior to taking the offset into account. This is
2338          * _not_ always the size of this plane since a single RM memory
2339          * allocation can contain multiple planes, and we're also not taking
2340          * the offset into account.
2341          */
2342         NvU64 rmObjectSizeInBytes NV_ALIGN_BYTES(8);
2343     } planes[NVKMS_MAX_PLANES_PER_SURFACE];
2344 
2345     NvU32 widthInPixels;
2346     NvU32 heightInPixels;
2347 
2348     enum NvKmsSurfaceMemoryLayout layout;
2349     enum NvKmsSurfaceMemoryFormat format;
2350 
2351     NvBool noDisplayHardwareAccess;
2352 
2353     /*
2354      * This flag should be set if the surface can potentially be updated
2355      * directly on the screen after the flip. For example, this is the case
2356      * if the surface is CPU mapped, accessible by more than one GPU, or in
2357      * a similar situation. If this flag is set NVKMS knows not to consider
2358      * the surface content cacheable between flips.
2359      */
2360     NvBool noDisplayCaching;
2361 
2362     /*
2363      * If isoType == NVKMS_MEMORY_NISO, NVKMS will create CPU and GPU mappings
2364      * for the surface memory.
2365      */
2366     NvKmsMemoryIsoType isoType;
2367 
2368     NvU32 log2GobsPerBlockY;
2369 };
2370 
2371 struct NvKmsRegisterSurfaceReply {
2372     NvKmsSurfaceHandle surfaceHandle;
2373 };
2374 
2375 struct NvKmsRegisterSurfaceParams {
2376     struct NvKmsRegisterSurfaceRequest request; /*! in */
2377     struct NvKmsRegisterSurfaceReply reply;     /*! out */
2378 };
2379 
2380 struct NvKmsUnregisterSurfaceRequest {
2381     NvKmsDeviceHandle deviceHandle;
2382     NvKmsSurfaceHandle surfaceHandle;
2383 };
2384 
2385 struct NvKmsUnregisterSurfaceReply {
2386     NvU32 padding;
2387 };
2388 
2389 struct NvKmsUnregisterSurfaceParams {
2390     struct NvKmsUnregisterSurfaceRequest request; /*! in */
2391     struct NvKmsUnregisterSurfaceReply reply;     /*! out */
2392 };
2393 
2394 
2395 /*!
2396  * NVKMS_IOCTL_GRANT_SURFACE:
2397  * NVKMS_IOCTL_ACQUIRE_SURFACE:
2398  * NVKMS_IOCTL_RELEASE_SURFACE:
2399  *
2400  * An NVKMS client can "grant" a registered surface to another NVKMS
2401  * client through the following steps:
2402  *
2403  * - The granting NVKMS client should open /dev/nvidia-modeset, and
2404  *   call NVKMS_IOCTL_GRANT_SURFACE to associate an NvKmsSurfaceHandle
2405  *   with the file descriptor.
2406  *
2407  * - The granting NVKMS client should pass the file descriptor over a
2408  *   UNIX domain socket to one or more clients who should acquire the
2409  *   surface.
2410  *
2411  * - The granting NVKMS client can optionally close the file
2412  *   descriptor now or later.
2413  *
2414  * - Each acquiring client should call NVKMS_IOCTL_ACQUIRE_SURFACE,
2415  *   and pass in the file descriptor it received.  This returns an
2416  *   NvKmsSurfaceHandle that the acquiring client can use to refer to
2417  *   the surface in any other NVKMS API call that takes an
2418  *   NvKmsSurfaceHandle.
2419  *
2420  * - The acquiring clients can optionally close the file descriptor
2421  *   now or later.
2422  *
2423  * - Each acquiring client should call NVKMS_IOCTL_RELEASE_SURFACE to
2424  *   release it when they are done with the surface.
2425  *
2426  * - When the granting client unregisters the surface, it is
2427  *   "orphaned": NVKMS will flip away from the surface if necessary,
2428  *   the RM surface allocation is unduped, and the surface is
2429  *   unregistered from EVO.  But, the acquiring clients will continue
2430  *   to hold a reference to this orphaned surface until they release
2431  *   it.
2432  *
2433  * Notes:
2434  *
2435  * - It is an error to call NVKMS_IOCTL_GRANT_SURFACE more than once
2436  *   on a /dev/nvidia-modeset file descriptor, or to use a file
2437  *   descriptor other than one created by opening /dev/nvidia-modeset,
2438  *   or to use a file descriptor that was previously used as the first
2439  *   argument to ioctl(2).
2440  *
2441  * - The special handling of surfaces when the granting client
2442  *   unregisters the surface might be a little asymmetric.  However,
2443  *   this strikes a balance between:
2444  *
2445  *   (a) Making sure modesetting NVKMS clients can free memory when
2446  *   they intend to.
2447  *
2448  *   (b) Making sure acquiring clients don't get a stale view of their
2449  *   surface handle namespace: if the surface were completely
2450  *   unregistered out from under them, the surface handle could be
2451  *   recycled without them knowing.  If they later attempted to
2452  *   release the original surface, they could inadvertently release a
2453  *   different surface that happened to have the recycled handle.
2454  *
2455  * - Do we need an NVKMS_IOCTL_REVOKE_SURFACE?  Or is the
2456  *   automatic-unregistration-in-acquiring-clients behavior
2457  *   sufficient?
2458  */
2459 
2460 struct NvKmsGrantSurfaceRequest {
2461     NvKmsDeviceHandle deviceHandle;
2462     NvKmsSurfaceHandle surfaceHandle;
2463     int fd;
2464 };
2465 
2466 struct NvKmsGrantSurfaceReply {
2467     NvU32 padding;
2468 };
2469 
2470 struct NvKmsGrantSurfaceParams {
2471     struct NvKmsGrantSurfaceRequest request; /*! in */
2472     struct NvKmsGrantSurfaceReply reply;     /*! out */
2473 };
2474 
2475 struct NvKmsAcquireSurfaceRequest {
2476     int fd;
2477 };
2478 
2479 struct NvKmsAcquireSurfaceReply {
2480     NvKmsDeviceHandle deviceHandle;
2481     NvKmsSurfaceHandle surfaceHandle;
2482 };
2483 
2484 struct NvKmsAcquireSurfaceParams {
2485     struct NvKmsAcquireSurfaceRequest request; /*! in */
2486     struct NvKmsAcquireSurfaceReply reply;     /*! out */
2487 };
2488 
2489 struct NvKmsReleaseSurfaceRequest {
2490     NvKmsDeviceHandle deviceHandle;
2491     NvKmsSurfaceHandle surfaceHandle;
2492 };
2493 
2494 struct NvKmsReleaseSurfaceReply {
2495     NvU32 padding;
2496 };
2497 
2498 struct NvKmsReleaseSurfaceParams {
2499     struct NvKmsReleaseSurfaceRequest request; /*! in */
2500     struct NvKmsReleaseSurfaceReply reply;     /*! out */
2501 };
2502 
2503 
2504 /*!
2505  * NVKMS_IOCTL_SET_DPY_ATTRIBUTE:
2506  * NVKMS_IOCTL_GET_DPY_ATTRIBUTE:
2507  * NVKMS_IOCTL_GET_DPY_ATTRIBUTE_VALID_VALUES:
2508  *
2509  * Dpys have several attributes that can be queried and set.
2510  *
2511  * An attribute has a type (defined by NvKmsAttributeType), read/write
2512  * permissions, and potentially other descriptions of its valid
2513  * values.  Use NVKMS_IOCTL_GET_DPY_ATTRIBUTE_VALID_VALUES to get the
2514  * valid values of an attribute.
2515  */
2516 
2517 enum NvKmsAttributeType {
2518     NV_KMS_ATTRIBUTE_TYPE_INTEGER = 0,
2519     NV_KMS_ATTRIBUTE_TYPE_BOOLEAN,
2520     NV_KMS_ATTRIBUTE_TYPE_INTBITS,
2521     NV_KMS_ATTRIBUTE_TYPE_RANGE,
2522     NV_KMS_ATTRIBUTE_TYPE_BITMASK,
2523     NV_KMS_ATTRIBUTE_TYPE_DPY_ID,
2524     NV_KMS_ATTRIBUTE_TYPE_DPY_ID_LIST,
2525 };
2526 
2527 enum NvKmsDpyAttribute {
2528     NV_KMS_DPY_ATTRIBUTE_BACKLIGHT_BRIGHTNESS = 0,
2529     NV_KMS_DPY_ATTRIBUTE_SCANLINE,
2530     NV_KMS_DPY_ATTRIBUTE_HW_HEAD,
2531     NV_KMS_DPY_ATTRIBUTE_HEAD,
2532     NV_KMS_DPY_ATTRIBUTE_REQUESTED_DITHERING,
2533     NV_KMS_DPY_ATTRIBUTE_REQUESTED_DITHERING_MODE,
2534     NV_KMS_DPY_ATTRIBUTE_REQUESTED_DITHERING_DEPTH,
2535     NV_KMS_DPY_ATTRIBUTE_CURRENT_DITHERING,
2536     NV_KMS_DPY_ATTRIBUTE_CURRENT_DITHERING_MODE,
2537     NV_KMS_DPY_ATTRIBUTE_CURRENT_DITHERING_DEPTH,
2538     NV_KMS_DPY_ATTRIBUTE_DIGITAL_VIBRANCE,
2539     NV_KMS_DPY_ATTRIBUTE_IMAGE_SHARPENING,
2540     NV_KMS_DPY_ATTRIBUTE_IMAGE_SHARPENING_AVAILABLE,
2541     NV_KMS_DPY_ATTRIBUTE_IMAGE_SHARPENING_DEFAULT,
2542     NV_KMS_DPY_ATTRIBUTE_REQUESTED_COLOR_SPACE,
2543     NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE,
2544     NV_KMS_DPY_ATTRIBUTE_REQUESTED_COLOR_RANGE,
2545     NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_RANGE,
2546     NV_KMS_DPY_ATTRIBUTE_DIGITAL_SIGNAL,
2547     NV_KMS_DPY_ATTRIBUTE_DIGITAL_LINK_TYPE,
2548     NV_KMS_DPY_ATTRIBUTE_DISPLAYPORT_LINK_RATE,
2549     NV_KMS_DPY_ATTRIBUTE_FRAMELOCK_DISPLAY_CONFIG,
2550     /*
2551      * XXX NVKMS TODO: Delete UPDATE_GLS_FRAMELOCK; this event-only
2552      * attribute is a kludge to tell GLS about a change in framelock
2553      * configuration made by NVKMS.  Eventually, NVKMS should manage
2554      * framelock itself and GLS shouldn't need to be notified.
2555      *
2556      * Note that the event data reports two boolean values: enable
2557      * (bit 0) and server (bit 1).
2558      */
2559     NV_KMS_DPY_ATTRIBUTE_UPDATE_GLS_FRAMELOCK,
2560     NV_KMS_DPY_ATTRIBUTE_RASTER_LOCK,
2561     NV_KMS_DPY_ATTRIBUTE_UPDATE_FLIPLOCK,
2562     NV_KMS_DPY_ATTRIBUTE_UPDATE_STEREO,
2563     NV_KMS_DPY_ATTRIBUTE_DPMS,
2564     NV_KMS_DPY_ATTRIBUTE_VRR_MIN_REFRESH_RATE,
2565 
2566     NV_KMS_DPY_ATTRIBUTE_DISPLAYPORT_CONNECTOR_TYPE,
2567     NV_KMS_DPY_ATTRIBUTE_DISPLAYPORT_IS_MULTISTREAM,
2568     NV_KMS_DPY_ATTRIBUTE_DISPLAYPORT_SINK_IS_AUDIO_CAPABLE,
2569 
2570     NV_KMS_DPY_ATTRIBUTE_NUMBER_OF_HARDWARE_HEADS_USED,
2571 };
2572 
2573 /*! Values for the NV_KMS_DPY_ATTRIBUTE_REQUESTED_DITHERING attribute. */
2574 enum NvKmsDpyAttributeRequestedDitheringValue {
2575     NV_KMS_DPY_ATTRIBUTE_REQUESTED_DITHERING_AUTO = 0,
2576     NV_KMS_DPY_ATTRIBUTE_REQUESTED_DITHERING_ENABLED = 1,
2577     NV_KMS_DPY_ATTRIBUTE_REQUESTED_DITHERING_DISABLED = 2,
2578 };
2579 
2580 /*! Values for the NV_KMS_DPY_ATTRIBUTE_REQUESTED_DITHERING_MODE attribute. */
2581 enum NvKmsDpyAttributeRequestedDitheringModeValue {
2582     NV_KMS_DPY_ATTRIBUTE_REQUESTED_DITHERING_MODE_AUTO = 0,
2583     NV_KMS_DPY_ATTRIBUTE_REQUESTED_DITHERING_MODE_DYNAMIC_2X2 = 1,
2584     NV_KMS_DPY_ATTRIBUTE_REQUESTED_DITHERING_MODE_STATIC_2X2 = 2,
2585     NV_KMS_DPY_ATTRIBUTE_REQUESTED_DITHERING_MODE_TEMPORAL = 3,
2586 };
2587 
2588 /*! Values for the NV_KMS_DPY_ATTRIBUTE_CURRENT_DITHERING_MODE attribute. */
2589 enum NvKmsDpyAttributeCurrentDitheringModeValue {
2590     NV_KMS_DPY_ATTRIBUTE_CURRENT_DITHERING_MODE_NONE = 0,
2591     NV_KMS_DPY_ATTRIBUTE_CURRENT_DITHERING_MODE_DYNAMIC_2X2 = 1,
2592     NV_KMS_DPY_ATTRIBUTE_CURRENT_DITHERING_MODE_STATIC_2X2 = 2,
2593     NV_KMS_DPY_ATTRIBUTE_CURRENT_DITHERING_MODE_TEMPORAL = 3,
2594 };
2595 
2596 /*! Values for the NV_KMS_DPY_ATTRIBUTE_REQUESTED_DITHERING_DEPTH attribute. */
2597 enum NvKmsDpyAttributeRequestedDitheringDepthValue {
2598     NV_KMS_DPY_ATTRIBUTE_REQUESTED_DITHERING_DEPTH_AUTO = 0,
2599     NV_KMS_DPY_ATTRIBUTE_REQUESTED_DITHERING_DEPTH_6_BITS = 1,
2600     NV_KMS_DPY_ATTRIBUTE_REQUESTED_DITHERING_DEPTH_8_BITS = 2,
2601 };
2602 
2603 /*! Values for the NV_KMS_DPY_ATTRIBUTE_CURRENT_DITHERING_DEPTH attribute. */
2604 enum NvKmsDpyAttributeCurrentDitheringDepthValue {
2605     NV_KMS_DPY_ATTRIBUTE_CURRENT_DITHERING_DEPTH_NONE = 0,
2606     NV_KMS_DPY_ATTRIBUTE_CURRENT_DITHERING_DEPTH_6_BITS = 1,
2607     NV_KMS_DPY_ATTRIBUTE_CURRENT_DITHERING_DEPTH_8_BITS = 2,
2608 };
2609 
2610 /*! Values for the NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE attribute. */
2611 enum NvKmsDpyAttributeCurrentColorSpaceValue {
2612     NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB = 0,
2613     NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr422 = 1,
2614     NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr444 = 2,
2615     NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr420 = 3,
2616 };
2617 
2618 /*! Values for the NV_KMS_DPY_ATTRIBUTE_DIGITAL_SIGNAL attribute. */
2619 enum NvKmsDpyAttributeDigitalSignalValue {
2620     NV_KMS_DPY_ATTRIBUTE_DIGITAL_SIGNAL_LVDS = 0,
2621     NV_KMS_DPY_ATTRIBUTE_DIGITAL_SIGNAL_TMDS = 1,
2622     NV_KMS_DPY_ATTRIBUTE_DIGITAL_SIGNAL_DISPLAYPORT = 2,
2623     NV_KMS_DPY_ATTRIBUTE_DIGITAL_SIGNAL_HDMI_FRL = 3,
2624     NV_KMS_DPY_ATTRIBUTE_DIGITAL_SIGNAL_DSI = 4,
2625 };
2626 
2627 /*! Values for the NV_KMS_DPY_ATTRIBUTE_DIGITAL_LINK_TYPE attribute. */
2628 enum NvKmsDpyAttributeDigitalLinkTypeValue {
2629     NV_KMS_DPY_ATTRIBUTE_DIGITAL_LINK_TYPE_SINGLE = 0,
2630     NV_KMS_DPY_ATTRIBUTE_DIGITAL_LINK_TYPE_DUAL = 1,
2631     NV_KMS_DPY_ATTRIBUTE_DIGITAL_LINK_TYPE_QUAD = 3,
2632 };
2633 
2634 /*! Values for the NV_KMS_DPY_ATTRIBUTE_FRAMELOCK_DISPLAY_CONFIG attribute. */
2635 enum NvKmsDpyAttributeFrameLockDisplayConfigValue {
2636     NV_KMS_DPY_ATTRIBUTE_FRAMELOCK_DISPLAY_CONFIG_DISABLED = 0,
2637     NV_KMS_DPY_ATTRIBUTE_FRAMELOCK_DISPLAY_CONFIG_CLIENT = 1,
2638     NV_KMS_DPY_ATTRIBUTE_FRAMELOCK_DISPLAY_CONFIG_SERVER = 2,
2639 };
2640 
2641 /*! Values for the NV_KMS_DPY_ATTRIBUTE_DPMS attribute. */
2642 enum NvKmsDpyAttributeDpmsValue {
2643     NV_KMS_DPY_ATTRIBUTE_DPMS_ON,
2644     NV_KMS_DPY_ATTRIBUTE_DPMS_STANDBY,
2645     NV_KMS_DPY_ATTRIBUTE_DPMS_SUSPEND,
2646     NV_KMS_DPY_ATTRIBUTE_DPMS_OFF,
2647 };
2648 
2649 /*! Values for the NV_KMS_DPY_ATTRIBUTE_DISPLAYPORT_CONNECTOR_TYPE attribute */
2650 enum NvKmsDpyAttributeDisplayportConnectorTypeValue {
2651     NV_KMS_DPY_ATTRIBUTE_DISPLAYPORT_CONNECTOR_TYPE_UNKNOWN = 0,
2652     NV_KMS_DPY_ATTRIBUTE_DISPLAYPORT_CONNECTOR_TYPE_DISPLAYPORT,
2653     NV_KMS_DPY_ATTRIBUTE_DISPLAYPORT_CONNECTOR_TYPE_HDMI,
2654     NV_KMS_DPY_ATTRIBUTE_DISPLAYPORT_CONNECTOR_TYPE_DVI,
2655     NV_KMS_DPY_ATTRIBUTE_DISPLAYPORT_CONNECTOR_TYPE_VGA,
2656 };
2657 
2658 struct NvKmsSetDpyAttributeRequest {
2659     NvKmsDeviceHandle deviceHandle;
2660     NvKmsDispHandle dispHandle;
2661     NVDpyId dpyId;
2662     enum NvKmsDpyAttribute attribute;
2663     NvS64 value NV_ALIGN_BYTES(8);
2664 };
2665 
2666 struct NvKmsSetDpyAttributeReply {
2667     NvU32 padding;
2668 };
2669 
2670 struct NvKmsSetDpyAttributeParams {
2671     struct NvKmsSetDpyAttributeRequest request; /*! in */
2672     struct NvKmsSetDpyAttributeReply reply;     /*! out */
2673 };
2674 
2675 
2676 struct NvKmsGetDpyAttributeRequest {
2677     NvKmsDeviceHandle deviceHandle;
2678     NvKmsDispHandle dispHandle;
2679     NVDpyId dpyId;
2680     enum NvKmsDpyAttribute attribute;
2681 };
2682 
2683 struct NvKmsGetDpyAttributeReply {
2684     NvS64 value NV_ALIGN_BYTES(8);
2685 };
2686 
2687 struct NvKmsGetDpyAttributeParams {
2688     struct NvKmsGetDpyAttributeRequest request; /*! in */
2689     struct NvKmsGetDpyAttributeReply reply;     /*! out */
2690 };
2691 
2692 
2693 struct NvKmsAttributeValidValuesCommonReply {
2694     NvBool readable;
2695     NvBool writable;
2696     enum NvKmsAttributeType type;
2697     union {
2698         struct {
2699             NvS64 min NV_ALIGN_BYTES(8);
2700             NvS64 max NV_ALIGN_BYTES(8);
2701         } range; /*! Used when type == NV_KMS_ATTRIBUTE_TYPE_RANGE. */
2702         struct {
2703             NvU32 ints;
2704         } bits;  /*! Used when type == NV_KMS_ATTRIBUTE_TYPE_INTBITS. */
2705     } u;
2706 };
2707 
2708 struct NvKmsGetDpyAttributeValidValuesRequest {
2709     NvKmsDeviceHandle deviceHandle;
2710     NvKmsDispHandle dispHandle;
2711     NVDpyId dpyId;
2712     enum NvKmsDpyAttribute attribute;
2713 };
2714 
2715 struct NvKmsGetDpyAttributeValidValuesReply {
2716     struct NvKmsAttributeValidValuesCommonReply common;
2717 };
2718 
2719 
2720 struct NvKmsGetDpyAttributeValidValuesParams {
2721     struct NvKmsGetDpyAttributeValidValuesRequest request; /*! in */
2722     struct NvKmsGetDpyAttributeValidValuesReply reply;     /*! out */
2723 };
2724 
2725 
2726 /*!
2727  * NVKMS_IOCTL_SET_DISP_ATTRIBUTE:
2728  * NVKMS_IOCTL_GET_DISP_ATTRIBUTE:
2729  * NVKMS_IOCTL_GET_DISP_ATTRIBUTE_VALID_VALUES:
2730  */
2731 
2732 
2733 enum NvKmsDispAttribute {
2734     NV_KMS_DISP_ATTRIBUTE_FRAMELOCK = 0,
2735     NV_KMS_DISP_ATTRIBUTE_FRAMELOCK_SYNC,
2736     NV_KMS_DISP_ATTRIBUTE_GPU_FRAMELOCK_FPGA_REVISION_UNSUPPORTED,
2737     NV_KMS_DISP_ATTRIBUTE_FRAMELOCK_STEREO_SYNC,
2738     NV_KMS_DISP_ATTRIBUTE_FRAMELOCK_TIMING,
2739     NV_KMS_DISP_ATTRIBUTE_FRAMELOCK_TEST_SIGNAL,
2740     NV_KMS_DISP_ATTRIBUTE_FRAMELOCK_RESET,
2741     NV_KMS_DISP_ATTRIBUTE_FRAMELOCK_SET_SWAP_BARRIER,
2742     NV_KMS_DISP_ATTRIBUTE_ALLOW_FLIPLOCK,
2743     NV_KMS_DISP_ATTRIBUTE_QUERY_DP_AUX_LOG,
2744 };
2745 
2746 
2747 struct NvKmsSetDispAttributeRequest {
2748     NvKmsDeviceHandle deviceHandle;
2749     NvKmsDispHandle dispHandle;
2750     enum NvKmsDispAttribute attribute;
2751     NvS64 value NV_ALIGN_BYTES(8);
2752 };
2753 
2754 struct NvKmsSetDispAttributeReply {
2755     NvU32 padding;
2756 };
2757 
2758 struct NvKmsSetDispAttributeParams {
2759     struct NvKmsSetDispAttributeRequest request; /*! in */
2760     struct NvKmsSetDispAttributeReply reply;     /*! out */
2761 };
2762 
2763 
2764 struct NvKmsGetDispAttributeRequest {
2765     NvKmsDeviceHandle deviceHandle;
2766     NvKmsDispHandle dispHandle;
2767     enum NvKmsDispAttribute attribute;
2768 };
2769 
2770 struct NvKmsGetDispAttributeReply {
2771     NvS64 value NV_ALIGN_BYTES(8);
2772 };
2773 
2774 struct NvKmsGetDispAttributeParams {
2775     struct NvKmsGetDispAttributeRequest request; /*! in */
2776     struct NvKmsGetDispAttributeReply reply;     /*! out */
2777 };
2778 
2779 
2780 struct NvKmsGetDispAttributeValidValuesRequest {
2781     NvKmsDeviceHandle deviceHandle;
2782     NvKmsDispHandle dispHandle;
2783     enum NvKmsDispAttribute attribute;
2784 };
2785 
2786 struct NvKmsGetDispAttributeValidValuesReply {
2787     struct NvKmsAttributeValidValuesCommonReply common;
2788 };
2789 
2790 struct NvKmsGetDispAttributeValidValuesParams {
2791     struct NvKmsGetDispAttributeValidValuesRequest request; /*! in */
2792     struct NvKmsGetDispAttributeValidValuesReply reply;     /*! out */
2793 };
2794 
2795 
2796 /*!
2797  * NVKMS_IOCTL_QUERY_FRAMELOCK: Query information about a framelock
2798  * device.
2799  */
2800 
2801 struct NvKmsQueryFrameLockRequest {
2802     NvKmsFrameLockHandle frameLockHandle;
2803 };
2804 
2805 struct NvKmsQueryFrameLockReply {
2806     NvU32 gpuIds[NVKMS_MAX_GPUS_PER_FRAMELOCK];
2807 };
2808 
2809 struct NvKmsQueryFrameLockParams {
2810     struct NvKmsQueryFrameLockRequest request; /*! in */
2811     struct NvKmsQueryFrameLockReply reply;     /*! out */
2812 };
2813 
2814 
2815 /*!
2816  * NVKMS_IOCTL_SET_FRAMELOCK_ATTRIBUTE:
2817  * NVKMS_IOCTL_GET_FRAMELOCK_ATTRIBUTE:
2818  * NVKMS_IOCTL_GET_FRAMELOCK_ATTRIBUTE_VALID_VALUES:
2819  */
2820 
2821 enum NvKmsFrameLockAttribute {
2822     NV_KMS_FRAMELOCK_ATTRIBUTE_POLARITY = 0,
2823     NV_KMS_FRAMELOCK_ATTRIBUTE_SYNC_DELAY,
2824     NV_KMS_FRAMELOCK_ATTRIBUTE_HOUSE_SYNC_MODE,
2825     NV_KMS_FRAMELOCK_ATTRIBUTE_SYNC_INTERVAL,
2826     NV_KMS_FRAMELOCK_ATTRIBUTE_SYNC_READY,
2827     NV_KMS_FRAMELOCK_ATTRIBUTE_VIDEO_MODE,
2828     NV_KMS_FRAMELOCK_ATTRIBUTE_FPGA_REVISION,
2829     NV_KMS_FRAMELOCK_ATTRIBUTE_FIRMWARE_MAJOR_VERSION,
2830     NV_KMS_FRAMELOCK_ATTRIBUTE_FIRMWARE_MINOR_VERSION,
2831     NV_KMS_FRAMELOCK_ATTRIBUTE_BOARD_ID,
2832     NV_KMS_FRAMELOCK_ATTRIBUTE_SYNC_DELAY_RESOLUTION,
2833     NV_KMS_FRAMELOCK_ATTRIBUTE_PORT0_STATUS,
2834     NV_KMS_FRAMELOCK_ATTRIBUTE_PORT1_STATUS,
2835     NV_KMS_FRAMELOCK_ATTRIBUTE_HOUSE_STATUS,
2836     NV_KMS_FRAMELOCK_ATTRIBUTE_ETHERNET_DETECTED,
2837     NV_KMS_FRAMELOCK_ATTRIBUTE_SYNC_RATE,
2838     NV_KMS_FRAMELOCK_ATTRIBUTE_SYNC_RATE_4,
2839     NV_KMS_FRAMELOCK_ATTRIBUTE_INCOMING_HOUSE_SYNC_RATE,
2840     NV_KMS_FRAMELOCK_ATTRIBUTE_MULTIPLY_DIVIDE_VALUE,
2841     NV_KMS_FRAMELOCK_ATTRIBUTE_MULTIPLY_DIVIDE_MODE,
2842 };
2843 
2844 /*! Values for the NV_KMS_FRAMELOCK_ATTRIBUTE_POLARITY attribute. */
2845 enum NvKmsFrameLockAttributePolarityValue {
2846     NV_KMS_FRAMELOCK_ATTRIBUTE_POLARITY_RISING_EDGE  = 0x1,
2847     NV_KMS_FRAMELOCK_ATTRIBUTE_POLARITY_FALLING_EDGE = 0x2,
2848     NV_KMS_FRAMELOCK_ATTRIBUTE_POLARITY_BOTH_EDGES   = 0x3,
2849 };
2850 
2851 /*! Values for the NV_KMS_FRAMELOCK_ATTRIBUTE_HOUSE_SYNC_MODE attribute. */
2852 enum NvKmsFrameLockAttributeHouseSyncModeValue {
2853     NV_KMS_FRAMELOCK_ATTRIBUTE_HOUSE_SYNC_MODE_DISABLED = 0,
2854     NV_KMS_FRAMELOCK_ATTRIBUTE_HOUSE_SYNC_MODE_INPUT    = 0x1,
2855     NV_KMS_FRAMELOCK_ATTRIBUTE_HOUSE_SYNC_MODE_OUTPUT   = 0x2,
2856 };
2857 
2858 /*! Values for the NV_KMS_FRAMELOCK_ATTRIBUTE_ETHERNET_DETECTED attribute. */
2859 enum NvKmsFrameLockAttributeEthernetDetectedValue {
2860     NV_KMS_FRAMELOCK_ATTRIBUTE_ETHERNET_DETECTED_NONE  = 0,
2861     NV_KMS_FRAMELOCK_ATTRIBUTE_ETHERNET_DETECTED_PORT0 = 0x1,
2862     NV_KMS_FRAMELOCK_ATTRIBUTE_ETHERNET_DETECTED_PORT1 = 0x2,
2863 };
2864 
2865 /*! Values for the NV_KMS_FRAMELOCK_ATTRIBUTE_VIDEO_MODE attribute. */
2866 enum NvKmsFrameLockAttributeVideoModeValue {
2867     NV_KMS_FRAMELOCK_ATTRIBUTE_VIDEO_MODE_COMPOSITE_AUTO      = 0,
2868     NV_KMS_FRAMELOCK_ATTRIBUTE_VIDEO_MODE_TTL                 = 1,
2869     NV_KMS_FRAMELOCK_ATTRIBUTE_VIDEO_MODE_COMPOSITE_BI_LEVEL  = 2,
2870     NV_KMS_FRAMELOCK_ATTRIBUTE_VIDEO_MODE_COMPOSITE_TRI_LEVEL = 3,
2871 };
2872 
2873 /*! Values for the NV_KMS_FRAMELOCK_ATTRIBUTE_PORT[01]_STATUS attributes. */
2874 enum NvKmsFrameLockAttributePortStatusValue {
2875     NV_KMS_FRAMELOCK_ATTRIBUTE_PORT_STATUS_INPUT = 0,
2876     NV_KMS_FRAMELOCK_ATTRIBUTE_PORT_STATUS_OUTPUT = 1,
2877 };
2878 
2879 /*! Values for the NV_KMS_FRAMELOCK_ATTRIBUTE_MULTIPLY_DIVIDE_MODE attribute. */
2880 enum NvKmsFrameLockAttributeMulDivModeValue {
2881     NV_KMS_FRAMELOCK_ATTRIBUTE_MULTIPLY_DIVIDE_MODE_MULTIPLY = 0,
2882     NV_KMS_FRAMELOCK_ATTRIBUTE_MULTIPLY_DIVIDE_MODE_DIVIDE = 1,
2883 };
2884 
2885 struct NvKmsSetFrameLockAttributeRequest {
2886     NvKmsFrameLockHandle frameLockHandle;
2887     enum NvKmsFrameLockAttribute attribute;
2888     NvS64 value NV_ALIGN_BYTES(8);
2889 };
2890 
2891 struct NvKmsSetFrameLockAttributeReply {
2892     NvU32 padding;
2893 };
2894 
2895 struct NvKmsSetFrameLockAttributeParams {
2896     struct NvKmsSetFrameLockAttributeRequest request; /*! in */
2897     struct NvKmsSetFrameLockAttributeReply reply;     /*! out */
2898 };
2899 
2900 
2901 struct NvKmsGetFrameLockAttributeRequest {
2902     NvKmsFrameLockHandle frameLockHandle;
2903     enum NvKmsFrameLockAttribute attribute;
2904 };
2905 
2906 struct NvKmsGetFrameLockAttributeReply {
2907     NvS64 value NV_ALIGN_BYTES(8);
2908 };
2909 
2910 struct NvKmsGetFrameLockAttributeParams {
2911     struct NvKmsGetFrameLockAttributeRequest request; /*! in */
2912     struct NvKmsGetFrameLockAttributeReply reply;     /*! out */
2913 };
2914 
2915 
2916 struct NvKmsGetFrameLockAttributeValidValuesRequest {
2917     NvKmsFrameLockHandle frameLockHandle;
2918     enum NvKmsFrameLockAttribute attribute;
2919 };
2920 
2921 struct NvKmsGetFrameLockAttributeValidValuesReply {
2922     struct NvKmsAttributeValidValuesCommonReply common;
2923 };
2924 
2925 struct NvKmsGetFrameLockAttributeValidValuesParams {
2926     struct NvKmsGetFrameLockAttributeValidValuesRequest request; /*! in */
2927     struct NvKmsGetFrameLockAttributeValidValuesReply reply;     /*! out */
2928 };
2929 
2930 
2931 
2932 /*!
2933  * NVKMS_IOCTL_GET_NEXT_EVENT, NVKMS_IOCTL_DECLARE_EVENT_INTEREST:
2934  * Event handling.
2935  *
2936  * Clients should call NVKMS_IOCTL_DECLARE_EVENT_INTEREST to indicate
2937  * the events in which they are interested.  Then, block on poll(2) or
2938  * select(2) until there are events available to read on the file
2939  * descriptor.
2940  *
2941  * When events are available, the client should call
2942  * NVKMS_IOCTL_GET_NEXT_EVENT to get an NvKmsEvent structure, and
2943  * interpret the union based on eventType.
2944  *
2945  * Clients can remove interest for events by calling
2946  * NVKMS_IOCTL_DECLARE_EVENT_INTEREST again, specifying a new
2947  * interestMask.
2948  *
2949  * Note that there may still be events queued for the client when the
2950  * client calls NVKMS_IOCTL_DECLARE_EVENT_INTEREST to change its
2951  * interestMask.  So, clients should be prepared to ignore unexpected
2952  * events after calling NVKMS_IOCTL_DECLARE_EVENT_INTEREST.
2953  */
2954 
2955 
2956 
2957 /*!
2958  * NVKMS_EVENT_TYPE_DPY_CHANGED
2959  *
2960  * When a dpy changes, this event will be generated.  The client
2961  * should call NVKMS_IOCTL_QUERY_DPY_DYNAMIC_DATA to get an updated
2962  * NvKmsQueryDpyDynamicDataReply.
2963  */
2964 
2965 struct NvKmsEventDpyChanged {
2966     NvKmsDeviceHandle deviceHandle;
2967     NvKmsDispHandle dispHandle;
2968     NVDpyId dpyId;
2969 };
2970 
2971 
2972 /*!
2973  * NVKMS_EVENT_TYPE_DYNAMIC_DPY_CONNECTED
2974  *
2975  * When a dynamic dpy is connected, this event will be generated.
2976  */
2977 
2978 struct NvKmsEventDynamicDpyConnected {
2979     NvKmsDeviceHandle deviceHandle;
2980     NvKmsDispHandle dispHandle;
2981     NVDpyId dpyId;
2982 };
2983 
2984 
2985 /*!
2986  * NVKMS_EVENT_TYPE_DYNAMIC_DPY_DISCONNECTED
2987  *
2988  * When a dynamic dpy is disconnected, this event will be generated.
2989  */
2990 
2991 struct NvKmsEventDynamicDpyDisconnected {
2992     NvKmsDeviceHandle deviceHandle;
2993     NvKmsDispHandle dispHandle;
2994     NVDpyId dpyId;
2995 };
2996 
2997 
2998 /*!
2999  * NVKMS_EVENT_TYPE_DPY_ATTRIBUTE_CHANGED
3000  *
3001  * When a dpy attribute changes, this event will be generated.
3002  */
3003 
3004 struct NvKmsEventDpyAttributeChanged {
3005     NvKmsDeviceHandle deviceHandle;
3006     NvKmsDispHandle dispHandle;
3007     NVDpyId dpyId;
3008     enum NvKmsDpyAttribute attribute;
3009     NvS64 value NV_ALIGN_BYTES(8);
3010 };
3011 
3012 
3013 /*!
3014  * NVKMS_EVENT_TYPE_FRAMELOCK_ATTRIBUTE_CHANGED
3015  *
3016  * When a framelock attribute changes, this event will be generated.
3017  */
3018 
3019 struct NvKmsEventFrameLockAttributeChanged {
3020     NvKmsFrameLockHandle frameLockHandle;
3021     enum NvKmsFrameLockAttribute attribute;
3022     NvS64 value NV_ALIGN_BYTES(8);
3023 };
3024 
3025 
3026 /*!
3027  * NVKMS_EVENT_TYPE_FLIP_OCCURRED
3028  *
3029  * When a client requests a flip and specifies a completion notifier
3030  * with NvKmsCompletionNotifierDescription::awaken == TRUE, this event
3031  * will be generated. This event is only delivered to clients with
3032  * flipping permission.
3033  */
3034 
3035 struct NvKmsEventFlipOccurred {
3036     NvKmsDeviceHandle deviceHandle;
3037     /* XXX NVKMS TODO: the dispHandle is currently hard-coded to 0. */
3038     NvKmsDispHandle dispHandle;
3039     NvU32 head;
3040     NvU32 layer;
3041 };
3042 
3043 
3044 struct NvKmsEvent {
3045     enum NvKmsEventType eventType;
3046     union {
3047         struct NvKmsEventDpyChanged dpyChanged;
3048         struct NvKmsEventDynamicDpyConnected dynamicDpyConnected;
3049         struct NvKmsEventDynamicDpyDisconnected dynamicDpyDisconnected;
3050         struct NvKmsEventDpyAttributeChanged dpyAttributeChanged;
3051         struct NvKmsEventFrameLockAttributeChanged frameLockAttributeChanged;
3052         struct NvKmsEventFlipOccurred flipOccurred;
3053     } u;
3054 };
3055 
3056 
3057 struct NvKmsGetNextEventRequest {
3058     NvU32 padding;
3059 };
3060 
3061 struct NvKmsGetNextEventReply {
3062     /*!
3063      * If an event is available, valid = TRUE and the NvKmsEvent
3064      * contains the event.  If no event is available, valid = FALSE.
3065      */
3066     NvBool valid;
3067     struct NvKmsEvent event;
3068 };
3069 
3070 struct NvKmsGetNextEventParams {
3071     struct NvKmsGetNextEventRequest request; /*! in */
3072     struct NvKmsGetNextEventReply reply;     /*! out */
3073 };
3074 
3075 
3076 struct NvKmsDeclareEventInterestRequest {
3077     /*!
3078      * Mask of event types, where each event type is indicated by (1
3079      * << NVKMS_EVENT_TYPE_).
3080      */
3081     NvU32 interestMask;
3082 };
3083 
3084 struct NvKmsDeclareEventInterestReply {
3085     NvU32 padding;
3086 };
3087 
3088 struct NvKmsDeclareEventInterestParams {
3089     struct NvKmsDeclareEventInterestRequest request; /*! in */
3090     struct NvKmsDeclareEventInterestReply reply;     /*! out */
3091 };
3092 
3093 /*!
3094  * NVKMS_IOCTL_CLEAR_UNICAST_EVENT
3095  *
3096  * The events generated through NVKMS_IOCTL_DECLARE_EVENT_INTEREST and
3097  * NVKMS_IOCTL_GET_NEXT_EVENT are most useful for system-wide events which
3098  * multiple clients may be interested in.  Clients declare their interest in a
3099  * collection of event types, and when they are notified that some number of
3100  * events arrived, they have to query the events from the event queue.
3101  *
3102  * In contrast, "Unicast Events" are for use in cases where a client is only
3103  * interested in a particular type of event on a particular object.
3104  *
3105  * To use a Unicast Event:
3106  *
3107  * - Create an fd through nvKmsOpen().
3108  *
3109  * - Do _not_ use the fd for anything else (the first argument to ioctl(2), the
3110  *   fd in any of the granting APIs such as NvKmsGrantSurfaceParams::request:fd,
3111  *   etc).
3112  *
3113  * - Pass the fd into an API that allows a unicast event.  E.g.,
3114  *   NvKmsJoinSwapGroupParams::request::member::unicastEvent::fd
3115  *
3116  * - Clear the unicast event with NVKMS_IOCTL_CLEAR_UNICAST_EVENT.
3117  *
3118  * - Check if the event arrived; if it hasn't, then wait for the event through
3119  *   poll(2) or select(2).
3120  */
3121 
3122 struct NvKmsClearUnicastEventRequest {
3123     int unicastEventFd;
3124 };
3125 
3126 struct NvKmsClearUnicastEventReply {
3127     NvU32 padding;
3128 };
3129 
3130 struct NvKmsClearUnicastEventParams {
3131     struct NvKmsClearUnicastEventRequest request; /*! in */
3132     struct NvKmsClearUnicastEventReply reply;     /*! out */
3133 };
3134 
3135 
3136 /*!
3137  * NVKMS_IOCTL_SET_LAYER_POSITION: Set the position of the layer
3138  * for the specified heads on the specified disps.  The layer
3139  * position is in "desktop coordinate space", i.e., relative to the
3140  * upper left corner of the input viewport.
3141  *
3142  * Note that this is only valid if
3143  * NvKmsAllocDeviceReply::layerCaps[layer].supportsWindowMode is TRUE.
3144  */
3145 struct NvKmsSetLayerPositionRequest {
3146     NvKmsDeviceHandle deviceHandle;
3147 
3148     /*!
3149      * The bitmask of which indices within disp[] describe requested
3150      * configuration changes.  Any other disps will use their existing
3151      * configuration.
3152      */
3153     NvU32 requestedDispsBitMask;
3154 
3155     struct {
3156         /*!
3157          * The bitmask of which head[] elements to look at on this
3158          * disp; any other head will use its existing configuration.
3159          */
3160         NvU32 requestedHeadsBitMask;
3161 
3162         struct {
3163             struct NvKmsSignedPoint layerPosition[NVKMS_MAX_LAYERS_PER_HEAD];
3164             /*!
3165              * The bitmask of which layerPosition[] elements to look at on this
3166              * head; any other layer will use its existing configuration.
3167              */
3168             NvU32 requestedLayerBitMask;
3169         } head[NVKMS_MAX_HEADS_PER_DISP];
3170 
3171     } disp[NVKMS_MAX_SUBDEVICES];
3172 };
3173 
3174 struct NvKmsSetLayerPositionReply {
3175     NvU32 padding;
3176 };
3177 
3178 struct NvKmsSetLayerPositionParams {
3179     struct NvKmsSetLayerPositionRequest request; /*! in */
3180     struct NvKmsSetLayerPositionReply reply;     /*! out */
3181 };
3182 
3183 
3184 /*!
3185  * NVKMS_IOCTL_GRAB_OWNERSHIP:
3186  * NVKMS_IOCTL_RELEASE_OWNERSHIP:
3187  *
3188  * NVKMS_IOCTL_GRAB_OWNERSHIP notifies NVKMS that the calling client wants to
3189  * control modesets on the device, and NVKMS_IOCTL_RELEASE_OWNERSHIP indicates
3190  * that the modeset ownership should be released and the VT console mode
3191  * restored.
3192  *
3193  * It is not necessary to call NVKMS_IOCTL_RELEASE_OWNERSHIP during shutdown;
3194  * NVKMS will implicitly clear modeset ownership in nvKmsClose().
3195  *
3196  * Releasing modeset ownership enables console hotplug handling. See the
3197  * explanation in the comment for enableConsoleHotplugHandling above.
3198  *
3199  * If modeset ownership is held by nvidia-drm, then NVKMS_IOCTL_GRAB_OWNERSHIP
3200  * will fail. Clients should open the corresponding DRM device node, acquire
3201  * 'master' on it, and then use DRM_NVIDIA_GRANT_PERMISSIONS with permission
3202  * type NV_DRM_PERMISSIONS_TYPE_SUB_OWNER to acquire sub-owner permission.
3203  */
3204 
3205 struct NvKmsGrabOwnershipRequest {
3206     NvKmsDeviceHandle deviceHandle;
3207 };
3208 
3209 struct NvKmsGrabOwnershipReply {
3210     NvU32 padding;
3211 };
3212 
3213 struct NvKmsGrabOwnershipParams {
3214     struct NvKmsGrabOwnershipRequest request; /*! in */
3215     struct NvKmsGrabOwnershipReply reply;     /*! out */
3216 };
3217 
3218 struct NvKmsReleaseOwnershipRequest {
3219     NvKmsDeviceHandle deviceHandle;
3220 };
3221 
3222 struct NvKmsReleaseOwnershipReply {
3223     NvU32 padding;
3224 };
3225 
3226 struct NvKmsReleaseOwnershipParams {
3227     struct NvKmsReleaseOwnershipRequest request; /*! in */
3228     struct NvKmsReleaseOwnershipReply reply;     /*! out */
3229 };
3230 
3231 
3232 /*!
3233  * NVKMS_IOCTL_GRANT_PERMISSIONS:
3234  * NVKMS_IOCTL_ACQUIRE_PERMISSIONS:
3235  * NVKMS_IOCTL_REVOKE_PERMISSIONS:
3236  *
3237  * By default, only the modeset owning NVKMS client (the one who
3238  * successfully called NVKMS_IOCTL_GRAB_OWNERSHIP) is allowed to flip
3239  * or set modes.
3240  *
3241  * However, the modeset owner or another NVKMS client with
3242  * NV_KMS_PERMISSIONS_TYPE_SUB_OWNER permission can grant various
3243  * permissions to other clients through the following steps:
3244  *
3245  * - The modeset owner should open /dev/nvidia-modeset, and call
3246  *   NVKMS_IOCTL_GRANT_PERMISSIONS to define a set of permissions
3247  *   associated with the file descriptor.
3248  *
3249  * - The modeset owner should pass the file descriptor over a UNIX
3250  *   domain socket to one or more clients who should acquire these
3251  *   permissions.
3252  *
3253  * - The modeset owner can optionally close the file descriptor now or
3254  *   later.
3255  *
3256  * - The acquiring clients should call NVKMS_IOCTL_ACQUIRE_PERMISSIONS
3257  *   and pass in the file descriptor they received, to update their
3258  *   client connection to include the permissions specified by the modeset
3259  *   owner in the first bullet.
3260  *
3261  * - The acquiring clients can optionally close the file descriptor
3262  *   now or later.
3263  *
3264  * - From this point forward, both the modeset owner and the clients
3265  *   are allowed to perform the actions allowed by the granted
3266  *   permissions.
3267  *
3268  * - The modeset owner can optionally revoke any previously granted
3269  *   permissions with NVKMS_IOCTL_REVOKE_PERMISSIONS. This can be
3270  *   device-scope for all of a type, or just a set of permissions.
3271  *   Note that _REVOKE_PERMISSIONS to revoke a set of modeset permissions
3272  *   will cause the revoked heads to be shut down.
3273  *
3274  * Notes:
3275  *
3276  * - NvKmsPermissions::disp[n] corresponds to the disp named by
3277  *   NvKmsAllocDeviceReply::dispHandles[n].
3278  *
3279  * - It is an error to call NVKMS_IOCTL_GRANT_PERMISSIONS more than
3280  *   once on a /dev/nvidia-modeset file descriptor, or to use a file
3281  *   descriptor other than one created by opening /dev/nvidia-modeset,
3282  *   or to use a file descriptor that was previously used as the first
3283  *   argument to ioctl(2).
3284  *
3285  * - Calling NVKMS_IOCTL_ACQUIRE_PERMISSIONS more than once on the
3286  *   same NVKMS client will cause the new permissions for that client
3287  *   to be the union of the previous permissions and the latest
3288  *   permissions being acquired.
3289  */
3290 
3291 enum NvKmsPermissionsType {
3292     NV_KMS_PERMISSIONS_TYPE_FLIPPING = 1,
3293     NV_KMS_PERMISSIONS_TYPE_MODESET = 2,
3294     NV_KMS_PERMISSIONS_TYPE_SUB_OWNER = 3,
3295 };
3296 
3297 struct NvKmsFlipPermissions {
3298     struct {
3299         struct {
3300             /*
3301              * Bitmask of flippable layers, where each layer is
3302              * indicated by '1 << layer'.  It is an error for bits
3303              * above NVKMS_MAX_LAYERS_PER_HEAD to be set.
3304              *
3305              * Only applicable when type==FLIPPING.
3306              */
3307             NvU8 layerMask;
3308         } head[NVKMS_MAX_HEADS_PER_DISP];
3309     } disp[NVKMS_MAX_SUBDEVICES];
3310 };
3311 
3312 struct NvKmsModesetPermissions {
3313     struct {
3314         struct {
3315             /*
3316              * A list of dpys which a particular NVKMS client is
3317              * allowed to use when performing a modeset on this head.
3318              *
3319              * If the NVKMS client is not allowed to set a mode on
3320              * this head, this list will be empty.
3321              *
3322              * If an NVKMS client can drive the head without
3323              * restrictions, this will be nvAllDpyIdList().
3324              *
3325              * Only applicable when type==MODESET.
3326              */
3327             NVDpyIdList dpyIdList;
3328         } head[NVKMS_MAX_HEADS_PER_DISP];
3329     } disp[NVKMS_MAX_SUBDEVICES];
3330 };
3331 
3332 struct NvKmsPermissions {
3333     enum NvKmsPermissionsType type;
3334     union {
3335         struct NvKmsFlipPermissions flip;
3336         struct NvKmsModesetPermissions modeset;
3337     };
3338 };
3339 
3340 struct NvKmsGrantPermissionsRequest {
3341     int fd;
3342     NvKmsDeviceHandle deviceHandle;
3343     struct NvKmsPermissions permissions;
3344 };
3345 
3346 struct NvKmsGrantPermissionsReply {
3347     NvU32 padding;
3348 };
3349 
3350 struct NvKmsGrantPermissionsParams {
3351     struct NvKmsGrantPermissionsRequest request; /*! in */
3352     struct NvKmsGrantPermissionsReply reply;     /*! out */
3353 };
3354 
3355 struct NvKmsAcquirePermissionsRequest {
3356     int fd;
3357 };
3358 
3359 struct NvKmsAcquirePermissionsReply {
3360     /*! This client's handle for the device which acquired new permissions */
3361     NvKmsDeviceHandle deviceHandle;
3362 
3363     /*!
3364      * The acquired permissions.
3365      *
3366      * If permissions::type == FLIPPING, the new combined flipping
3367      * permissions of the calling client on this device, including
3368      * prior permissions and permissions added by this operation.
3369      */
3370     struct NvKmsPermissions permissions;
3371 };
3372 
3373 struct NvKmsAcquirePermissionsParams {
3374     struct NvKmsAcquirePermissionsRequest request; /*! in */
3375     struct NvKmsAcquirePermissionsReply reply;     /*! out */
3376 };
3377 
3378 struct NvKmsRevokePermissionsRequest {
3379     NvKmsDeviceHandle deviceHandle;
3380 
3381     /*
3382      * A bitmask of permission types to be revoked for this device.
3383      * It should be the bitwise 'or' of any number of
3384      * NVBIT(NV_KMS_PERMISSIONS_TYPE_*) values.
3385      */
3386     NvU32 permissionsTypeBitmask;
3387 
3388     /*
3389      * If permissionsTypeBitmask is 0, instead revoke only these permissions.
3390      */
3391     struct NvKmsPermissions permissions;
3392 };
3393 
3394 struct NvKmsRevokePermissionsReply {
3395     NvU32 padding;
3396 };
3397 
3398 struct NvKmsRevokePermissionsParams {
3399     struct NvKmsRevokePermissionsRequest request; /*! in */
3400     struct NvKmsRevokePermissionsReply reply;     /*! out */
3401 };
3402 
3403 
3404 /*!
3405  * NVKMS_IOCTL_QUERY_DPY_CRC32
3406  *
3407  * Query last CRC32 value from the NVKMS disp head specified by the triplet
3408  * (deviceHandle, dispHandle, head).
3409  */
3410 
3411 struct NvKmsQueryDpyCRC32Request {
3412     NvKmsDeviceHandle deviceHandle;
3413     NvKmsDispHandle dispHandle;
3414     NvU32 head;
3415 };
3416 
3417 /*!
3418  * Generic CRC-structure type to represent CRC value obtained and if
3419  * hardware architecture supports collection of the CRC type. If
3420  * the CRC is not supported by hardware, its value is undefined.
3421  */
3422 struct NvKmsDpyCRC32 {
3423    /*!
3424     * Value of the CRC. If it is not supported, value is undefined.
3425     */
3426    NvU32 value;
3427 
3428    /*!
3429     * Boolean which represents if hardware supports CRC collection
3430     * If this boolean is FALSE, CRC hardware collection is not supported.
3431     */
3432    NvBool supported;
3433 };
3434 
3435 /*!
3436  * Reply structure that contains CRC32 values returned from hardware.
3437  * Supported CRCs obtained are represented by supported boolean in crc struct
3438  * Note- Crcs that are not supported will not be updated and will remain at 0
3439  */
3440 struct NvKmsQueryDpyCRC32Reply {
3441    /*!
3442     * CRC generated from the Compositor hardware
3443     */
3444     struct NvKmsDpyCRC32 compositorCrc32;
3445 
3446     /*!
3447      * CRC generated from the RG hardware, if head is driving RG/SF.
3448      * Note that if Dithering is enabled, this CRC will vary across reads
3449      * from the same frame.
3450      */
3451     struct NvKmsDpyCRC32 rasterGeneratorCrc32;
3452 
3453     /*!
3454      * Crc value generated from the target SF/OR depending on connector's OR type
3455      * Note that if Dithering is enabled, this CRC will vary across reads
3456      * from the same frame.
3457      */
3458     struct NvKmsDpyCRC32 outputCrc32;
3459 
3460 };
3461 
3462 struct NvKmsQueryDpyCRC32Params {
3463     struct NvKmsQueryDpyCRC32Request request; /*! in */
3464     struct NvKmsQueryDpyCRC32Reply reply;     /*! out */
3465 };
3466 
3467 /*!
3468  * User-space pointers are always passed to NVKMS in an NvU64.
3469  * This user-space address is eventually passed into the platform's
3470  * copyin/copyout functions, in a void* argument.
3471  *
3472  * This utility function converts from a pointer to an NvU64.
3473  */
3474 
3475 static inline NvU64 nvKmsPointerToNvU64(const void *ptr)
3476 {
3477     return (NvU64)(NvUPtr)ptr;
3478 }
3479 
3480 
3481 /*!
3482  * NVKMS_IOCTL_REGISTER_DEFERRED_REQUEST_FIFO:
3483  * NVKMS_IOCTL_UNREGISTER_DEFERRED_REQUEST_FIFO:
3484  *
3485  * To make a request that is deferred until after a specific point in a client's
3486  * graphics channel, a client should register a surface with NVKMS as a
3487  * "deferred request fifo".  The surface is interpreted as having the layout of
3488  * struct NvKmsDeferredRequestFifo.
3489  *
3490  * To make deferred requests, the client should:
3491  *
3492  * - Write the NVKMS_DEFERRED_REQUEST_OPCODE for the desired operation to
3493  *   NvKmsDeferredRequestFifo::request[i], where 'i' is the next available
3494  *   element in the request[] array.  Repeat as necessary.
3495  *
3496  * - Push NV906F_SEMAPHORE[ABCD] methods in its graphics channel to write
3497  *   '(i + 1) % NVKMS_MAX_DEFERRED_REQUESTS' to
3498  *   NvKmsDeferredRequestFifo::put.
3499  *
3500  * - Push an NV906F_NON_STALL_INTERRUPT method in its graphics channel.
3501  *
3502  * NVKMS will be notified of the non-stall interrupt, and scan all clients'
3503  * deferred request fifos for put != get.  NVKMS will then perform the requests
3504  * specified in request[get] through request[put-1].  Finally, NVKMS will update
3505  * get to indicate how much of the fifo it consumed.
3506  *
3507  * Wrapping behaves as expected.  In pseudo code:
3508  *
3509  *  while (get != put) {
3510  *      do(request[get]);
3511  *      get = (get + 1) % NVKMS_MAX_DEFERRED_REQUESTS;
3512  *  }
3513  *
3514  * The only time it is safe for clients to write to get is when get == put and
3515  * there are no outstanding semaphore releases to gpuPut.
3516  *
3517  * The surface used for the deferred request fifo must be:
3518  *
3519  * - In system memory (NVKMS will create one device-scoped mapping, not one per
3520  *   subdevice, as would be needed if the surface were in video memory).
3521  *
3522  * - At least as large as sizeof(NvKmsDeferredRequestFifo).
3523  *
3524  * Some NVKMS_DEFERRED_REQUESTs may need to write to a semaphore after some
3525  * operation is performed (e.g., to indicate that a SwapGroup is ready, or that
3526  * we've reached vblank).  The NVKMS_DEFERRED_REQUEST_SEMAPHORE_INDEX field
3527  * within the request specifies a semaphore within the
3528  * NvKmsDeferredRequestFifo::semaphore[] array.  The semantics of that semaphore
3529  * index are opcode-specific.
3530  *
3531  * The opcode and semaphore index are in the low 16-bits of the request.  The
3532  * upper 16-bits are opcode-specific.
3533  */
3534 
3535 #define NVKMS_MAX_DEFERRED_REQUESTS 128
3536 
3537 #define NVKMS_DEFERRED_REQUEST_OPCODE                                      7:0
3538 
3539 #define NVKMS_DEFERRED_REQUEST_SEMAPHORE_INDEX                            15:8
3540 
3541 #define NVKMS_DEFERRED_REQUEST_OPCODE_NOP                                    0
3542 
3543 /*
3544  * The SWAP_GROUP_READY request means that this NvKmsDeferredRequestFifo is
3545  * ready for the next swap of the SwapGroup (see NVKMS_IOCTL_JOIN_SWAP_GROUP,
3546  * below).  NVKMS_DEFERRED_REQUEST_SEMAPHORE_INDEX should specify an element in
3547  * the semaphore[] array which will be released to
3548  *
3549  *   NVKMS_DEFERRED_REQUEST_SEMAPHORE_VALUE_SWAP_GROUP_READY
3550  *
3551  * when the SwapGroup actually swaps.
3552  */
3553 #define NVKMS_DEFERRED_REQUEST_OPCODE_SWAP_GROUP_READY                       1
3554 #define NVKMS_DEFERRED_REQUEST_SEMAPHORE_VALUE_SWAP_GROUP_NOT_READY 0x00000000
3555 #define NVKMS_DEFERRED_REQUEST_SEMAPHORE_VALUE_SWAP_GROUP_READY     0xFFFFFFFF
3556 
3557 
3558 /*
3559  * The SWAP_GROUP_READY_PER_EYE_STEREO field indicates whether this deferred
3560  * request fifo wants the SwapGroup to present new content at every eye boundary
3561  * (PER_EYE), or present new content only when transitioning from the right eye
3562  * to the left eye (PER_PAIR).
3563  */
3564 #define NVKMS_DEFERRED_REQUEST_SWAP_GROUP_READY_PER_EYE_STEREO           16:16
3565 #define NVKMS_DEFERRED_REQUEST_SWAP_GROUP_READY_PER_EYE_STEREO_PER_PAIR      0
3566 #define NVKMS_DEFERRED_REQUEST_SWAP_GROUP_READY_PER_EYE_STEREO_PER_EYE       1
3567 
3568 
3569 struct NvKmsDeferredRequestFifo {
3570     NvU32 put;
3571     NvU32 get;
3572     NvU32 request[NVKMS_MAX_DEFERRED_REQUESTS];
3573     NvGpuSemaphore semaphore[NVKMS_MAX_DEFERRED_REQUESTS];
3574 };
3575 
3576 struct NvKmsRegisterDeferredRequestFifoRequest {
3577     NvKmsDeviceHandle deviceHandle;
3578     NvKmsSurfaceHandle surfaceHandle;
3579 };
3580 
3581 struct NvKmsRegisterDeferredRequestFifoReply {
3582     NvKmsDeferredRequestFifoHandle deferredRequestFifoHandle;
3583 };
3584 
3585 struct NvKmsRegisterDeferredRequestFifoParams {
3586     struct NvKmsRegisterDeferredRequestFifoRequest request; /*! in */
3587     struct NvKmsRegisterDeferredRequestFifoReply reply;     /*! out */
3588 };
3589 
3590 struct NvKmsUnregisterDeferredRequestFifoRequest {
3591     NvKmsDeviceHandle deviceHandle;
3592     NvKmsDeferredRequestFifoHandle deferredRequestFifoHandle;
3593 };
3594 
3595 struct NvKmsUnregisterDeferredRequestFifoReply {
3596     NvU32 padding;
3597 };
3598 
3599 struct NvKmsUnregisterDeferredRequestFifoParams {
3600     struct NvKmsUnregisterDeferredRequestFifoRequest request; /*! in */
3601     struct NvKmsUnregisterDeferredRequestFifoReply reply;     /*! out */
3602 };
3603 
3604 
3605 /*!
3606  * NVKMS_IOCTL_ALLOC_SWAP_GROUP
3607  * NVKMS_IOCTL_FREE_SWAP_GROUP
3608  *
3609  * An NVKMS client creates a SwapGroup by calling NVKMS_IOCTL_ALLOC_SWAP_GROUP
3610  * and specifying the heads in the SwapGroup with
3611  * NvKmsAllocSwapGroupRequest::disp[]::headMask.
3612  *
3613  * The SwapGroup can be shared with clients through
3614  * NVKMS_IOCTL_GRANT_SWAP_GROUP, and it is destroyed once all clients that have
3615  * acquired the swap group through NVKMS_IOCTL_ACQUIRE_SWAP_GROUP have released
3616  * it through NVKMS_IOCTL_RELEASE_SWAP_GROUP and when the client that created
3617  * the swap group has called NVKMS_IOCTL_FREE_SWAP_GROUP or freed the device.
3618  *
3619  * The SwapGroup allocation is expected to have a long lifetime (e.g., the X
3620  * driver might call ALLOC_SWAP_GROUP from ScreenInit and FREE_SWAP_GROUP from
3621  * CloseScreen).  The point of these requests is to define the head topology of
3622  * the SwapGroup (for X driver purposes, presumably all the heads that are
3623  * assigned to the X screen).
3624  *
3625  * As such:
3626  *
3627  * - Not all heads described in the ALLOC_SWAP_GROUP request need to be active
3628  *   (they can come and go with different modesets).
3629  *
3630  * - The SwapGroup persists across modesets.
3631  *
3632  * - SwapGroup allocation is expected to be lightweight: the heavyweight
3633  *   operations like allocating and freeing headSurface resources are done when
3634  *   the number of SwapGroup members (see {JOIN,LEAVE}_SWAP_GROUP below)
3635  *   transitions between 0 and 1.
3636  *
3637  * Only an NVKMS modeset owner can alloc or free a SwapGroup.
3638  */
3639 
3640 struct NvKmsSwapGroupConfig {
3641     struct {
3642         NvU32 headMask;
3643     } disp[NVKMS_MAX_SUBDEVICES];
3644 };
3645 
3646 struct NvKmsAllocSwapGroupRequest {
3647     NvKmsDeviceHandle deviceHandle;
3648     struct NvKmsSwapGroupConfig config;
3649 };
3650 
3651 struct NvKmsAllocSwapGroupReply {
3652     NvKmsSwapGroupHandle swapGroupHandle;
3653 };
3654 
3655 struct NvKmsAllocSwapGroupParams {
3656     struct NvKmsAllocSwapGroupRequest request; /*! in */
3657     struct NvKmsAllocSwapGroupReply reply;     /*! out */
3658 };
3659 
3660 struct NvKmsFreeSwapGroupRequest {
3661     NvKmsDeviceHandle deviceHandle;
3662     NvKmsSwapGroupHandle swapGroupHandle;
3663 };
3664 
3665 struct NvKmsFreeSwapGroupReply {
3666     NvU32 padding;
3667 };
3668 
3669 struct NvKmsFreeSwapGroupParams {
3670     struct NvKmsFreeSwapGroupRequest request; /*! in */
3671     struct NvKmsFreeSwapGroupReply reply;     /*! out */
3672 };
3673 
3674 
3675 /*!
3676  * NVKMS_IOCTL_JOIN_SWAP_GROUP
3677  * NVKMS_IOCTL_LEAVE_SWAP_GROUP
3678  *
3679  * Clients can join NvKmsDeferredRequestFifos to SwapGroups using
3680  * NVKMS_IOCTL_JOIN_SWAP_GROUP, and remove NvKmsDeferredRequestFifos from
3681  * SwapGroups using NVKMS_IOCTL_LEAVE_SWAP_GROUP (or freeing the
3682  * NvKmsDeferredRequestFifo, or freeing the device).
3683  *
3684  * Once an NvKmsDeferredRequestFifo is joined to a SwapGroup, the SwapGroup will
3685  * not become ready again until the SwapGroup member sends the
3686  * NVKMS_DEFERRED_REQUEST_OPCODE_SWAP_GROUP_READY request through their
3687  * NvKmsDeferredRequestFifo.  The NVKMS_DEFERRED_REQUEST_SEMAPHORE_INDEX
3688  * specified as part of the request indicates an index into
3689  * NvKmsDeferredRequestFifo::semaphore[] where NVKMS will write
3690  *
3691  *    NVKMS_DEFERRED_REQUEST_SEMAPHORE_VALUE_SWAP_GROUP_READY
3692  *
3693  * when the SwapGroup becomes ready.
3694  *
3695  * If unicastEvent::specified is TRUE, then unicastEvent::fd will be interpreted
3696  * as a unicast event file descriptor.  See NVKMS_IOCTL_CLEAR_UNICAST_EVENT for
3697  * details.  Whenever SWAP_GROUP_READY is written to a semaphore within
3698  * NvKmsDeferredRequestFifo, the unicastEvent fd will be notified.
3699  *
3700  * An NvKmsDeferredRequestFifo can be joined to at most one SwapGroup at a time.
3701  *
3702  * If one client uses multiple NvKmsDeferredRequestFifos joined to multiple
3703  * SwapGroups and wants to synchronize swaps between these fifos, it should
3704  * bundle all of the (deviceHandle, swapGroupHandle, deferredRequestFifoHandle)
3705  * tuples into a single join/leave request.
3706  *
3707  * If any client joins multiple NvKmsDeferredRequestFifos to multiple
3708  * SwapGroups, all NVKMS_IOCTL_JOIN_SWAP_GROUP requests must specify the same
3709  * set of SwapGroups.
3710  */
3711 
3712 struct NvKmsJoinSwapGroupRequestOneMember {
3713     NvKmsDeviceHandle deviceHandle;
3714     NvKmsSwapGroupHandle swapGroupHandle;
3715     NvKmsDeferredRequestFifoHandle deferredRequestFifoHandle;
3716 
3717     struct {
3718         int fd;
3719         NvBool specified;
3720     } unicastEvent;
3721 };
3722 
3723 struct NvKmsJoinSwapGroupRequest {
3724     NvU32 numMembers;
3725     struct NvKmsJoinSwapGroupRequestOneMember member[NVKMS_MAX_SWAPGROUPS];
3726 };
3727 
3728 struct NvKmsJoinSwapGroupReply {
3729     NvU32 padding;
3730 };
3731 
3732 struct NvKmsJoinSwapGroupParams {
3733     struct NvKmsJoinSwapGroupRequest request; /*! in */
3734     struct NvKmsJoinSwapGroupReply reply;     /*! out */
3735 };
3736 
3737 struct NvKmsLeaveSwapGroupRequestOneMember {
3738     NvKmsDeviceHandle deviceHandle;
3739     NvKmsDeferredRequestFifoHandle deferredRequestFifoHandle;
3740 };
3741 
3742 struct NvKmsLeaveSwapGroupRequest {
3743     NvU32 numMembers;
3744     struct NvKmsLeaveSwapGroupRequestOneMember member[NVKMS_MAX_SWAPGROUPS];
3745 };
3746 
3747 struct NvKmsLeaveSwapGroupReply {
3748     NvU32 padding;
3749 };
3750 
3751 struct NvKmsLeaveSwapGroupParams {
3752     struct NvKmsLeaveSwapGroupRequest request; /*! in */
3753     struct NvKmsLeaveSwapGroupReply reply;     /*! out */
3754 };
3755 
3756 
3757 /*!
3758  * NVKMS_IOCTL_SET_SWAP_GROUP_CLIP_LIST
3759  *
3760  * The X driver needs to define which pixels on-screen are owned by the
3761  * SwapGroup.  NVKMS will use this to prevent those pixels from updating until
3762  * all SwapGroup members indicate that they are ready.
3763  *
3764  * The clip list is interpreted by NVKMS as relative to the surface specified
3765  * during a flip or modeset.  The clip list is intersected with the ViewPortIn
3766  * of the head, described by
3767  *
3768  *   NvKmsFlipCommonParams::viewPortIn::point
3769  *
3770  * and
3771  *
3772  *   NvKmsSetModeOneHeadRequest::viewPortSizeIn
3773  *
3774  * The clip list is exclusive.  I.e., each NvKmsRect is a region outside of the
3775  * SwapGroup.  One surface-sized NvKmsRect would mean that there are no
3776  * SwapGroup-owned pixels.
3777  *
3778  * When no clip list is specified, NVKMS behaves as if there were no
3779  * SwapGroup-owned pixels.
3780  *
3781  * Only an NVKMS modeset owner can set the clip list of a SwapGroup.
3782  */
3783 
3784 struct NvKmsSetSwapGroupClipListRequest {
3785     NvKmsDeviceHandle deviceHandle;
3786     NvKmsSwapGroupHandle swapGroupHandle;
3787 
3788     /*! The number of struct NvKmsRects pointed to by pClipList. */
3789     NvU16 nClips;
3790 
3791     /*!
3792      * Pointer to an array of struct NvKmsRects describing the inclusive clip
3793      * list for the SwapGroup.  The NvKmsRects are in desktop coordinate space.
3794      *
3795      * Use nvKmsPointerToNvU64() to assign pClipList.
3796      */
3797     NvU64 pClipList NV_ALIGN_BYTES(8);
3798 };
3799 
3800 struct NvKmsSetSwapGroupClipListReply {
3801     NvU32 padding;
3802 };
3803 
3804 struct NvKmsSetSwapGroupClipListParams {
3805     struct NvKmsSetSwapGroupClipListRequest request; /*! in */
3806     struct NvKmsSetSwapGroupClipListReply reply;     /*! out */
3807 };
3808 
3809 
3810 /*!
3811  * NVKMS_IOCTL_GRANT_SWAP_GROUP:
3812  * NVKMS_IOCTL_ACQUIRE_SWAP_GROUP:
3813  * NVKMS_IOCTL_RELEASE_SWAP_GROUP:
3814  *
3815  * An NVKMS client can "grant" a swap group that it has allocated through
3816  * NVKMS_IOCTL_ALLOC_SWAP_GROUP to another NVKMS client through the following
3817  * steps:
3818  *
3819  * - The granting NVKMS client should open /dev/nvidia-modeset, and call
3820  *   NVKMS_IOCTL_GRANT_SWAP_GROUP to associate an NvKmsSwapGroupHandle
3821  *   with the file descriptor.
3822  *
3823  * - The granting NVKMS client should pass the file descriptor over a
3824  *   UNIX domain socket to one or more clients who should acquire the
3825  *   swap group.
3826  *
3827  * - The granting NVKMS client can optionally close the file
3828  *   descriptor now or later.
3829  *
3830  * - Each acquiring client should call NVKMS_IOCTL_ACQUIRE_SWAP_GROUP,
3831  *   and pass in the file descriptor it received.  This returns an
3832  *   NvKmsSwapGroupHandle that the acquiring client can use to refer to
3833  *   the swap group in any other NVKMS API call that takes an
3834  *   NvKmsSwapGroupHandle.
3835  *
3836  * - The acquiring clients can optionally close the file descriptor
3837  *   now or later.
3838  *
3839  * - Each acquiring client should call NVKMS_IOCTL_RELEASE_SWAP_GROUP to
3840  *   release it when they are done with the swap group.
3841  */
3842 
3843 struct NvKmsGrantSwapGroupRequest {
3844     NvKmsDeviceHandle deviceHandle;
3845     NvKmsSwapGroupHandle swapGroupHandle;
3846     int fd;
3847 };
3848 
3849 struct NvKmsGrantSwapGroupReply {
3850     NvU32 padding;
3851 };
3852 
3853 struct NvKmsGrantSwapGroupParams {
3854     struct NvKmsGrantSwapGroupRequest request; /*! in */
3855     struct NvKmsGrantSwapGroupReply reply;     /*! out */
3856 };
3857 
3858 struct NvKmsAcquireSwapGroupRequest {
3859     int fd;
3860 };
3861 
3862 struct NvKmsAcquireSwapGroupReply {
3863     NvKmsDeviceHandle deviceHandle;
3864     NvKmsSwapGroupHandle swapGroupHandle;
3865 };
3866 
3867 struct NvKmsAcquireSwapGroupParams {
3868     struct NvKmsAcquireSwapGroupRequest request; /*! in */
3869     struct NvKmsAcquireSwapGroupReply reply;     /*! out */
3870 };
3871 
3872 struct NvKmsReleaseSwapGroupRequest {
3873     NvKmsDeviceHandle deviceHandle;
3874     NvKmsSwapGroupHandle swapGroupHandle;
3875 };
3876 
3877 struct NvKmsReleaseSwapGroupReply {
3878     NvU32 padding;
3879 };
3880 
3881 struct NvKmsReleaseSwapGroupParams {
3882     struct NvKmsReleaseSwapGroupRequest request; /*! in */
3883     struct NvKmsReleaseSwapGroupReply reply;     /*! out */
3884 };
3885 
3886 /*!
3887  * NVKMS_IOCTL_SWITCH_MUX:
3888  *
3889  * Switch the mux for the given Dpy in the given direction. The mux switch is
3890  * performed in three stages.
3891  */
3892 
3893 enum NvKmsMuxOperation {
3894     NVKMS_SWITCH_MUX_PRE,
3895     NVKMS_SWITCH_MUX,
3896     NVKMS_SWITCH_MUX_POST,
3897 };
3898 
3899 struct NvKmsSwitchMuxRequest {
3900     NvKmsDeviceHandle deviceHandle;
3901     NvKmsDispHandle dispHandle;
3902     NVDpyId dpyId;
3903     enum NvKmsMuxOperation operation;
3904     NvMuxState state;
3905 };
3906 
3907 struct NvKmsSwitchMuxReply {
3908     NvU32 padding;
3909 };
3910 
3911 struct NvKmsSwitchMuxParams {
3912     struct NvKmsSwitchMuxRequest request;
3913     struct NvKmsSwitchMuxReply reply;
3914 };
3915 
3916 struct NvKmsGetMuxStateRequest {
3917     NvKmsDeviceHandle deviceHandle;
3918     NvKmsDispHandle dispHandle;
3919     NVDpyId dpyId;
3920 };
3921 
3922 struct NvKmsGetMuxStateReply {
3923     NvMuxState state;
3924 };
3925 
3926 struct NvKmsGetMuxStateParams {
3927     struct NvKmsGetMuxStateRequest request;
3928     struct NvKmsGetMuxStateReply reply;
3929 };
3930 
3931 /*!
3932  * NVKMS_IOCTL_EXPORT_VRR_SEMAPHORE_SURFACE:
3933  *
3934  * Export the VRR semaphore surface onto the provided RM 'memFd'.
3935  * The RM memory FD should be "empty".  An empty FD can be allocated by calling
3936  * NV0000_CTRL_OS_UNIX_EXPORT_OBJECT_TO_FD with 'EMPTY_FD' set.
3937  */
3938 
3939 struct NvKmsExportVrrSemaphoreSurfaceRequest {
3940     NvKmsDeviceHandle deviceHandle;
3941     int memFd;
3942 };
3943 
3944 struct NvKmsExportVrrSemaphoreSurfaceReply {
3945     NvU32 padding;
3946 };
3947 
3948 struct NvKmsExportVrrSemaphoreSurfaceParams {
3949     struct NvKmsExportVrrSemaphoreSurfaceRequest request;
3950     struct NvKmsExportVrrSemaphoreSurfaceReply reply;
3951 };
3952 
3953 /*!
3954  * NVKMS_IOCTL_ENABLE_VBLANK_SYNC_OBJECT:
3955  * NVKMS_IOCTL_DISABLE_VBLANK_SYNC_OBJECT:
3956  *
3957  * The NVKMS client can use NVKMS_IOCTL_ENABLE_VBLANK_SYNC_OBJECT to request a
3958  * vblank syncpt that continuously triggers each time the raster generator
3959  * reaches the start of vblank. NVKMS will return the syncpt id in
3960  * 'NvKmsEnableVblankSyncObjectReply::syncptId'.
3961  *
3962  * The NVKMS client can use NVKMS_IOCTL_DISABLE_VBLANK_SYNC_OBJECT to disable
3963  * the vblank syncpt.
3964  *
3965  * If a vblank syncpt is currently enabled on a head, and a modeset request is
3966  * issued to reconfigure that head with a new set of mode timings, NVKMS will
3967  * automatically reenable the vblank syncpt so it continues to trigger with the
3968  * new mode timings.
3969  *
3970  * Clients can use these IOCTLs only if both NvKmsAllocDeviceReply::
3971  * supportsVblankSyncObjects and NvKmsAllocDeviceReply::supportsSyncpts are
3972  * TRUE.
3973  */
3974 
3975 struct NvKmsEnableVblankSyncObjectRequest {
3976     NvKmsDeviceHandle deviceHandle;
3977     NvKmsDispHandle dispHandle;
3978     NvU32 head;
3979 };
3980 
3981 struct NvKmsEnableVblankSyncObjectReply {
3982     /*
3983      * Clients should explicitly disable the vblank sync object to consume the
3984      * handle.
3985      */
3986     NvKmsVblankSyncObjectHandle vblankHandle;
3987 
3988     NvU32 syncptId;
3989 };
3990 
3991 struct NvKmsEnableVblankSyncObjectParams {
3992     struct NvKmsEnableVblankSyncObjectRequest request; /*! in */
3993     struct NvKmsEnableVblankSyncObjectReply reply;     /*! out */
3994 };
3995 
3996 struct NvKmsDisableVblankSyncObjectRequest {
3997     NvKmsDeviceHandle deviceHandle;
3998     NvKmsDispHandle dispHandle;
3999     NvU32 head;
4000 
4001     /* This handle is received in NVKMS_IOCTL_ENABLE_VBLANK_SYNC_OBJECT. */
4002     NvKmsVblankSyncObjectHandle vblankHandle;
4003 };
4004 
4005 struct NvKmsDisableVblankSyncObjectReply {
4006     NvU32 padding;
4007 };
4008 
4009 struct NvKmsDisableVblankSyncObjectParams {
4010     struct NvKmsDisableVblankSyncObjectRequest request; /*! in */
4011     struct NvKmsDisableVblankSyncObjectReply reply;     /*! out */
4012 };
4013 
4014 /*!
4015  * NVKMS_IOCTL_NOTIFY_VBLANK:
4016  *
4017  * Register a unicast event fd to be notified when the next vblank event occurs
4018  * on the specified head. This is a one-shot notification, and in order to be
4019  * notified of subsequent vblank events the caller must clear and re-register
4020  * the unicast event fd.
4021  */
4022 
4023 struct NvKmsNotifyVblankRequest {
4024     NvKmsDeviceHandle deviceHandle;
4025     NvKmsDispHandle dispHandle;
4026     NvU32 head;
4027 
4028     struct {
4029         int fd;
4030     } unicastEvent;
4031 };
4032 
4033 struct NvKmsNotifyVblankReply {
4034     NvU32 padding;
4035 };
4036 
4037 struct NvKmsNotifyVblankParams {
4038     struct NvKmsNotifyVblankRequest request; /*! in */
4039     struct NvKmsNotifyVblankReply reply;     /*! out */
4040 };
4041 
4042 /*!
4043  * NVKMS_IOCTL_SET_FLIPLOCK_GROUP:
4044  *
4045  * This ioctl specifies a set of active heads on which fliplock is allowed.
4046  * The heads can span devices.
4047  * The requested state for this group will be maintained until:
4048  * a) A subsequent SetFlipLockGroup ioctl that specifies any of the heads
4049  * b) A subsequent ModeSet ioctl that specifies any of the heads
4050  * If either of those occurs, the requested state will be destroyed for *all*
4051  * of the heads.
4052  *
4053  * Note that a successful call with 'enable = TRUE' only indicates that the
4054  * request to enable fliplock is registered, not that fliplock was actually
4055  * enabled.  Fliplock may not be enabled due to incompatible modetimings, for
4056  * example.
4057  */
4058 
4059 struct NvKmsSetFlipLockGroupOneDev {
4060     NvKmsDeviceHandle deviceHandle;
4061 
4062     NvU32 requestedDispsBitMask;
4063     struct {
4064         NvU32 requestedHeadsBitMask;
4065     } disp[NVKMS_MAX_SUBDEVICES];
4066 };
4067 
4068 struct NvKmsSetFlipLockGroupRequest {
4069     NvBool enable;
4070     struct NvKmsSetFlipLockGroupOneDev dev[NV_MAX_SUBDEVICES];
4071 };
4072 
4073 struct NvKmsSetFlipLockGroupReply {
4074     NvU32 padding;
4075 };
4076 
4077 struct NvKmsSetFlipLockGroupParams {
4078     struct NvKmsSetFlipLockGroupRequest request; /*! in */
4079     struct NvKmsSetFlipLockGroupReply reply;     /*! out */
4080 };
4081 
4082 #endif /* NVKMS_API_H */
4083