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