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