1 //*****************************************************************************
2 //
3 //  SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
4 //  SPDX-License-Identifier: MIT
5 //
6 //  Permission is hereby granted, free of charge, to any person obtaining a
7 //  copy of this software and associated documentation files (the "Software"),
8 //  to deal in the Software without restriction, including without limitation
9 //  the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 //  and/or sell copies of the Software, and to permit persons to whom the
11 //  Software is furnished to do so, subject to the following conditions:
12 //
13 //  The above copyright notice and this permission notice shall be included in
14 //  all copies or substantial portions of the Software.
15 //
16 //  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 //  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 //  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 //  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 //  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 //  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 //  DEALINGS IN THE SOFTWARE.
23 //
24 //  File:       displayid20.h
25 //
26 //  Purpose:    the template for DisplayID 2.0 parsing (future replacement for EDID)
27 //
28 //*****************************************************************************
29 
30 
31 #ifndef __DISPLAYID20_H_
32 #define __DISPLAYID20_H_
33 
34 #include "nvtiming.h"
35 
36 // The structures below must be tightly packed, in order to correctly
37 // overlay on the DisplayID 2.0  block bytes.  Both MSVC and
38 // gcc support the pack() pragma for this.
39 
40 #if defined(__GNUC__) || defined(_MSC_VER)
41 #  define __SUPPORTS_PACK_PRAGMA 1
42 #else
43 #  error "unrecognized compiler: displayid structures must be tightly packed"
44 #endif
45 
46 #ifdef __SUPPORTS_PACK_PRAGMA
47 #pragma pack(1)
48 #endif
49 
50 #define DISPLAYID_2_0_SECTION_SIZE_TOTAL(_pSectionHeader_)  ((_pSectionHeader_).section_bytes +      \
51                                                              sizeof(DISPLAYID_2_0_SECTION_HEADER) +  \
52                                                              sizeof(NvU8))
53 #define DISPLAYID_2_0_DATA_BLOCK_SIZE_TOTAL(_pBlockHeader_) ((_pBlockHeader_)->data_bytes +          \
54                                                              sizeof(DISPLAYID_2_0_DATA_BLOCK_HEADER))
55 #define DISPLAYID_2_0_SECTION_SIZE_MAX                      256
56 #define DISPLAYID_2_0_SECTION_DATA_SIZE_MAX                 (DISPLAYID_2_0_SECTION_SIZE_MAX -        \
57                                                             sizeof(DISPLAYID_2_0_SECTION_HEADER)
58 
59 typedef struct _tagDISPLAYID_2_0_SECTION_HEADER
60 {
61     NvU8 revision:4;       // displayID revision
62     NvU8 version:4;        // displayID version
63     NvU8 section_bytes;    // length of this displayID section excluding mandatory bytes [0, 251]
64 
65     NvU8 product_type:4;   // Display Product Primary Use Case
66     NvU8 reserved:4;       // RESERVED
67     NvU8 extension_count;  // Total extension count.
68 } DISPLAYID_2_0_SECTION_HEADER;
69 
70 typedef struct _tagDISPLAYID_2_0_SECTION
71 {
72     DISPLAYID_2_0_SECTION_HEADER header;
73 
74     NvU8 data[DISPLAYID_2_0_SECTION_SIZE_MAX]; // data blocks. Note, DisplayID has variable length
75 } DISPLAYID_2_0_SECTION;
76 
77 #define DISPLAYID_2_0_VERSION                           2
78 #define DISPLAYID_2_0_REVISION                          0
79 
80 #define DISPLAYID_2_0_PROD_EXTENSION                    0 // Extension (same primary use case as base section)
81 #define DISPLAYID_2_0_PROD_TEST                         1 // Test Structure/Test Equipment
82 #define DISPLAYID_2_0_PROD_GENERIC_DISPLAY              2 // None of the listed primary use cases; generic display
83 #define DISPLAYID_2_0_PROD_TELEVISION                   3 // Television (TV) display
84 #define DISPLAYID_2_0_PROD_DESKTOP_PRODUCTIVITY_DISPLAY 4 // Desktop productivity display
85 #define DISPLAYID_2_0_PROD_DESKTOP_GAMING_DISPLAY       5 // Desktop gaming display
86 #define DISPLAYID_2_0_PROD_PRESENTATION_DISPLAY         6 // Presentation display
87 #define DISPLAYID_2_0_PROD_HMD_VR                       7 // Head mounted Virtual Reality display
88 #define DISPLAYID_2_0_PROD_HMD_AR                       8 // Head mounted Augmented Reality display
89 
90 typedef struct _tagDISPLAYID_2_0_DATA_BLOCK_HEADER
91 {
92     NvU8  type;        // Data block tag
93     NvU8  revision:3;  // block revision
94     NvU8  reserved:5;
95     NvU8  data_bytes;  // number of payload bytes in Block [ 0, 248]
96 } DISPLAYID_2_0_DATA_BLOCK_HEADER;
97 
98 #define DISPLAYID_2_0_BLOCK_TYPE_PRODUCT_IDENTITY               0x20
99 #define DISPLAYID_2_0_BLOCK_TYPE_DISPLAY_PARAM                  0x21
100 #define DISPLAYID_2_0_BLOCK_TYPE_TIMING_7                       0x22
101 #define DISPLAYID_2_0_BLOCK_TYPE_TIMING_8                       0x23
102 #define DISPLAYID_2_0_BLOCK_TYPE_TIMING_9                       0x24
103 #define DISPLAYID_2_0_BLOCK_TYPE_RANGE_LIMITS                   0x25
104 #define DISPLAYID_2_0_BLOCK_TYPE_INTERFACE_FEATURES             0x26
105 #define DISPLAYID_2_0_BLOCK_TYPE_STEREO                         0x27
106 #define DISPLAYID_2_0_BLOCK_TYPE_TILED_DISPLAY                  0x28
107 #define DISPLAYID_2_0_BLOCK_TYPE_CONTAINER_ID                   0x29
108 #define DISPLAYID_2_0_BLOCK_TYPE_TIMING_10                      0x2A
109 #define DISPLAYID_2_0_BLOCK_TYPE_ADAPTIVE_SYNC                  0x2B
110 #define DISPLAYID_2_0_BLOCK_TYPE_ARVR_HMD                       0x2C
111 #define DISPLAYID_2_0_BLOCK_TYPE_ARVR_LAYER                     0x2D
112 #define DISPLAYID_2_0_BLOCK_TYPE_BRIGHTNESS_LUMINANCE_RANGE     0x2E
113 // 0x7D - 0x2F RESERVED for Additional VESA-defined Data Blocks
114 #define DISPLAYID_2_0_BLOCK_TYPE_VENDOR_SPEC          0x7E
115 // 0x80 - 0x7F RESERVED
116 #define DISPLAYID_2_0_BLOCK_TYPE_CTA_DATA             0x81
117 // 0xFF - 0x82 RESERVED for additional data blocks related to external standards organization(s).
118 
119 #define DISPLAYID_2_0_PRODUCT_NAME_STRING_MAX_LEN     ((0xFB - 0xF) + 1)
120 
121 typedef struct _tagDISPLAYID_2_0_PROD_IDENTIFICATION_BLOCK
122 {
123     // Product Identification Data Block (0x20)
124     // Number of payload bytes 12(0xC) - 248(0xF8)
125     DISPLAYID_2_0_DATA_BLOCK_HEADER header;
126 
127     NvU8  vendor[3];
128     NvU8  product_code[2];
129     NvU8  serial_number[4];
130     NvU8  model_tag;
131     NvU8  model_year;
132     NvU8  product_name_string_size;
133     NvU8  product_name_string[DISPLAYID_2_0_PRODUCT_NAME_STRING_MAX_LEN];
134 } DISPLAYID_2_0_PROD_IDENTIFICATION_BLOCK;
135 
136 typedef struct _tagDISPLAY_2_0_DISPLAY_PARAM_BLOCK_HEADER
137 {
138     NvU8  type;        // Display Parameters Data Block (0x21)
139     NvU8  revision:3;
140     NvU8  reserved:4;
141     NvU8  image_size_multiplier:1;
142     NvU8  data_bytes;  // number of payload bytes 29(0x1D)
143 } DISPLAY_2_0_DISPLAY_PARAM_BLOCK_HEADER;
144 
145 typedef struct _tagDISPLAYID_2_0_COLOR_CHROMATICITY
146 {
147     NvU8 color_x_bits_low;
148     struct {
149         NvU8 color_x_bits_high:4;
150         NvU8 color_y_bits_low:4;
151     } color_bits_mid;
152     NvU8 color_y_bits_high;
153 } DISPLAYID_2_0_COLOR_CHROMATICITY;
154 
155 typedef enum _tagDISPLAYID_2_0_NATIVE_COLOR_DEPTH
156 {
157     NATIVE_COLOR_NOT_DEFINED = 0,
158     NATIVE_COLOR_BPC_6       = 1,
159     NATIVE_COLOR_BPC_8       = 2,
160     NATIVE_COLOR_BPC_10      = 3,
161     NATIVE_COLOR_BPC_12      = 4,
162     NATIVE_COLOR_BPC_16      = 5,
163 } DISPLAYID_2_0_NATIVE_COLOR_DEPTH;
164 
165 #define DISPLAYID_2_0_DISPLAY_PARAM_BLOCK_PAYLOAD_LENGTH   29
166 typedef struct _tagDISPLAYID_2_0_DISPLAY_PARAM_BLOCK
167 {
168     DISPLAY_2_0_DISPLAY_PARAM_BLOCK_HEADER header;
169 
170     NvU8  horizontal_image_size[2];
171     NvU8  vertical_image_size[2];
172     NvU8  horizontal_pixel_count[2];
173     NvU8  vertical_pixel_count[2];
174 
175     struct {
176         NvU8  scan_orientation          :3;
177         NvU8  luminance_information     :2;
178         NvU8  reserved                  :1;
179         NvU8  color_information         :1;
180         NvU8  audio_speaker_information :1;
181     } feature;
182 
183     DISPLAYID_2_0_COLOR_CHROMATICITY primary_color_1_chromaticity;
184     DISPLAYID_2_0_COLOR_CHROMATICITY primary_color_2_chromaticity;
185     DISPLAYID_2_0_COLOR_CHROMATICITY primary_color_3_chromaticity;
186     DISPLAYID_2_0_COLOR_CHROMATICITY white_point_chromaticity;
187     NvU8 max_luminance_full_coverage[2];
188     NvU8 max_luminance_10_percent_rectangular_coverage[2];
189     NvU8 min_luminance[2];
190 
191     struct {
192         NvU8  color_depth             :3;
193         NvU8  reserved0               :1;
194         NvU8  device_technology       :3;
195         NvU8  device_theme_preference :1;
196     } color_depth_and_device_technology;
197 
198     NvU8  gamma_EOTF;
199 } DISPLAYID_2_0_DISPLAY_PARAM_BLOCK;
200 
201 #define DISPLAYID_2_0_SCAN_ORIENTATION_LRTB         0  // Left to right, top to bottom
202 #define DISPLAYID_2_0_SCAN_ORIENTATION_RLTB         1  // Right to left, top to bottom
203 #define DISPLAYID_2_0_SCAN_ORIENTATION_TBRL         2  // Top to bottom, right to left
204 #define DISPLAYID_2_0_SCAN_ORIENTATION_BTRL         3  // Bottom to top, right to left
205 #define DISPLAYID_2_0_SCAN_ORIENTATION_RLBT         4  // Right to left, bottom to top
206 #define DISPLAYID_2_0_SCAN_ORIENTATION_LRBT         5  // Left to right, bottom to top
207 #define DISPLAYID_2_0_SCAN_ORIENTATION_BTLR         6  // Bottom to top, left to right
208 #define DISPLAYID_2_0_SCAN_ORIENTATION_TBLR         7  // Top to bottom, left to right
209 
210 #define DISPLAYID_2_0_COLOR_INFORMATION_1931_CIE    0
211 #define DISPLAYID_2_0_color_INFORMATION_1976_CIE    1
212 
213 #define DISPLAYID_2_0_AUDIO_SPEAKER_INTEGRATED      0
214 #define DISPLAYID_2_0_AUDIO_SPEAKER_NOT_INTEGRATED  1
215 
216 #define DISPLAYID_2_0_DEVICE_TECHNOLOGY_UNSPECIFIED 0
217 #define DISPLAYID_2_0_DEVICE_TECHNOLOGY_LCD         1
218 #define DISPLAYID_2_0_DEVICE_TECHNOLOGY_OLED        2
219 
220 #define DISPLAYID_2_0_TYPE7_DSC_PASSTHRU_REVISION   1
221 #define DISPLAYID_2_0_TYPE7_YCC420_SUPPORT_REVISION 2
222 
223 // DisplayID_v2.0 E5 - DSC Pass-Through timing
224 // DisplayID_v2.0 E7 - YCC420 and > 20 bytes per descriptor supported
225 typedef struct _tagDISPLAYID_2_0_TIMING_7_BLOCK_HEADER
226 {
227     NvU8  type;                // Type VII Timing (0x22)
228     NvU8  revision          :3;
229     NvU8  dsc_passthrough   :1;
230     NvU8  payload_bytes_len :3;
231     NvU8  reserved          :1;
232     NvU8  data_bytes;          // Values range from 1(0x01) to 248(0xF8)
233 } DISPLAYID_2_0_TIMING_7_BLOCK_HEADER;
234 
235 typedef struct _tag_DISPLAYID_2_0_TIMING_7_DESCRIPTOR
236 {
237     // Range is defined as 0.001 through 16,777.216 MP/s
238     NvU8 pixel_clock[3];
239 
240     struct
241     {
242         NvU8 aspect_ratio                   : 4;
243         NvU8 interface_frame_scanning_type  : 1;
244         NvU8 stereo_support                 : 2;
245         NvU8 is_preferred_or_ycc420         : 1;
246     } options;
247 
248     struct
249     {
250         NvU8 active_image_pixels[2];
251         NvU8 blank_pixels[2];
252         NvU8 front_porch_pixels_low;
253         NvU8 front_porch_pixels_high        : 7;
254         NvU8 sync_polarity                  : 1;
255         NvU8 sync_width_pixels[2];
256     } horizontal;
257 
258     struct
259     {
260         NvU8 active_image_lines[2];
261         NvU8 blank_lines[2];
262         NvU8 front_porch_lines_low;
263         NvU8 front_porch_lines_high         : 7;
264         NvU8 sync_polarity                  : 1;
265         NvU8 sync_width_lines[2];
266     } vertical;
267 } DISPLAYID_2_0_TIMING_7_DESCRIPTOR;
268 
269 #define DISPLAYID_2_0_TIMING_7_MAX_DESCRIPTORS 12
270 
271 typedef struct _tagDISPLAYID_2_0_TIMING_7_BLOCK
272 {
273     DISPLAYID_2_0_TIMING_7_BLOCK_HEADER   header;
274     DISPLAYID_2_0_TIMING_7_DESCRIPTOR     descriptors[DISPLAYID_2_0_TIMING_7_MAX_DESCRIPTORS];
275 } DISPLAYID_2_0_TIMING_7_BLOCK;
276 
277 #define DISPLAYID_2_0_TIMING_DSC_PASSTHRU_TIMING    1
278 
279 // the following fields apply to Timing 7 Descriptors (Not all of them are
280 // used per descriptor, but the format is the same
281 #define DISPLAYID_2_0_TIMING_ASPECT_RATIO_1_1       0
282 #define DISPLAYID_2_0_TIMING_ASPECT_RATIO_5_4       1
283 #define DISPLAYID_2_0_TIMING_ASPECT_RATIO_4_3       2
284 #define DISPLAYID_2_0_TIMING_ASPECT_RATIO_15_9      3
285 #define DISPLAYID_2_0_TIMING_ASPECT_RATIO_16_9      4
286 #define DISPLAYID_2_0_TIMING_ASPECT_RATIO_16_10     5
287 #define DISPLAYID_2_0_TIMING_ASPECT_RATIO_64_27     6
288 #define DISPLAYID_2_0_TIMING_ASPECT_RATIO_256_135   7
289 #define DISPLAYID_2_0_TIMING_ASPECT_RATIO_CALCULATE 8  // calculate using Horizontal and Vertical Active Image Pixels
290 
291 #define DISPLAYID_2_0_TIMING_PROGRESSIVE_SCAN       0
292 #define DISPLAYID_2_0_TIMING_INTERLACED_SCAN        1
293 
294 #define DISPLAYID_2_0_TIMING_3D_STEREO_MONO         0
295 #define DISPLAYID_2_0_TIMING_3D_STEREO_STEREO       1
296 #define DISPLAYID_2_0_TIMING_3D_STEREO_EITHER       2
297 
298 #define DISPLAYID_2_0_TIMING_SYNC_POLARITY_NEGATIVE 0
299 #define DISPLAYID_2_0_TIMING_SYNC_POLARITY_POSITIVE 1
300 
301 typedef struct _tagDISPLAYID_2_0_TIMING_8_BLOCK_HEADER
302 {
303     NvU8  type;                // Type VIII Timing (0x23)
304     NvU8  revision          :3;
305     NvU8  timing_code_size  :1;
306     NvU8  reserved          :1;
307     NvU8  is_support_yuv420 :1;
308     NvU8  timing_code_type  :2;
309     NvU8  data_bytes;          // Values range from 1(0x01) to 248(0xF8)
310 } DISPLAYID_2_0_TIMING_8_BLOCK_HEADER;
311 
312 #define DISPLAYID_2_0_TIMING_8_MAX_CODES    248
313 
314 typedef struct _tagDISPLAYID_2_0_TIMING_8_BLOCK
315 {
316     DISPLAYID_2_0_TIMING_8_BLOCK_HEADER header;
317     NvU8 timingCode[DISPLAYID_2_0_TIMING_8_MAX_CODES];
318 } DISPLAYID_2_0_TIMING_8_BLOCK;
319 
320 // the following fields apply to Timing 8 Descriptors
321 #define DISPLAYID_2_0_TIMING_CODE_DMT       0
322 #define DISPLAYID_2_0_TIMING_CODE_CTA_VIC   1
323 #define DISPLAYID_2_0_TIMING_CODE_HDMI_VIC  2
324 #define DISPLAYID_2_0_TIMING_CODE_RSERVED   3
325 #define DISPLAYID_2_0_TIMING_CODE_SIZE_1_BYTE 0
326 #define DISPLAYID_2_0_TIMING_CODE_SIZE_2_BYTE 1
327 
328 typedef struct _TAG_DISPLAYID_2_0_TIMING_9_DESCRIPTOR
329 {
330     struct {
331         NvU8 timing_formula          :3;
332         NvU8 reserved0               :1;
333         NvU8 rr_1000div1001_support  :1;
334         NvU8 stereo_support          :2;
335         NvU8 reserved1               :1;
336     } options;
337 
338     NvU8  horizontal_active_pixels[2];
339     NvU8  vertical_active_lines[2];
340     NvU8  refresh_rate;              // 1 Hz to 256 Hz
341 } DISPLAYID_2_0_TIMING_9_DESCRIPTOR;
342 
343 // the following fields apply to Timing 9/10 Descriptors
344 #define DISPLAYID_2_0_TIMING_FORMULA_CVT_1_2_STANDARD            0
345 #define DISPLAYID_2_0_TIMING_FORMULA_CVT_1_2_REDUCED_BLANKING_1  1
346 #define DISPLAYID_2_0_TIMING_FORMULA_CVT_2_0_REDUCED_BLANKING_2  2
347 #define DISPLAYID_2_0_TIMING_FORMULA_CVT_2_0_REDUCED_BLANKING_3  3
348 
349 #define DISPLAYID_2_0_TIMING_9_MAX_DESCRIPTORS 18
350 
351 typedef struct _tagDISPLAYID_2_0_TIMING_9_BLOCK
352 {
353     // Type IX Timing (0x24)
354     DISPLAYID_2_0_DATA_BLOCK_HEADER   header;
355     DISPLAYID_2_0_TIMING_9_DESCRIPTOR descriptors[DISPLAYID_2_0_TIMING_9_MAX_DESCRIPTORS];
356 } DISPLAYID_2_0_TIMING_9_BLOCK;
357 
358 #define DISPLAYID_2_0_TIMING_10_PAYLOAD_BYTES_6    0
359 #define DISPLAYID_2_0_TIMING_10_PAYLOAD_BYTES_7    1
360 
361 typedef struct _tagDISPLAYID_2_0_TIMING_10_BLOCK_HEADER
362 {
363     NvU8  type;                    // Type X Timing (0x2A)
364     NvU8  revision          :3;
365     NvU8  reserved0         :1;
366     NvU8  payload_bytes_len :3;
367     NvU8  reserved1         :1;
368     NvU8  payload_bytes;
369 } DISPLAYID_2_0_TIMING_10_BLOCK_HEADER;
370 
371 typedef struct _DISPLAYID_2_0_TIMING_10_6BYTES_DESCRIPTOR
372 {
373     struct {
374         NvU8 timing_formula :3;
375         NvU8 early_vsync    :1;
376         NvU8 rr1000div1001_or_hblank :1;
377         NvU8 stereo_support :2;
378         NvU8 ycc420_support :1;
379     } options;
380 
381     NvU8  horizontal_active_pixels[2];
382     NvU8  vertical_active_lines[2];
383     NvU8  refresh_rate;                 // 1 Hz to 256 Hz
384 } DISPLAYID_2_0_TIMING_10_6BYTES_DESCRIPTOR;
385 
386 typedef struct _DISPLAYID_2_0_TIMING_10_7BYTES_DESCRIPTOR
387 {
388     DISPLAYID_2_0_TIMING_10_6BYTES_DESCRIPTOR descriptor_6_bytes;
389     NvU8                                      refresh_rate_high        :2;
390     NvU8                                      delta_hblank             :3;
391     NvU8                                      additional_vblank_timing :3;
392 } DISPLAYID_2_0_TIMING_10_7BYTES_DESCRIPTOR;
393 
394 #define DISPLAYID_2_0_TIMING_10_MAX_6BYTES_DESCRIPTORS 18
395 #define DISPLAYID_2_0_TIMING_10_MAX_7BYTES_DESCRIPTORS 16
396 
397 typedef struct _DISPLAYID_2_0_TIMING_10_BLOCK
398 {
399     DISPLAYID_2_0_TIMING_10_BLOCK_HEADER    header;
400     NvU8                                    descriptors[120];
401 } DISPLAYID_2_0_TIMING_10_BLOCK;
402 
403 #define DISPLAYID_2_0_RANGE_LIMITS_BLOCK_PAYLOAD_LENGTH   9
404 typedef struct _tagDISPLAYID_2_0_RANGE_LIMITS_BLOCK
405 {
406     DISPLAYID_2_0_DATA_BLOCK_HEADER   header;
407 
408     NvU8  pixel_clock_min[3];
409     NvU8  pixel_clock_max[3];
410     NvU8  vertical_frequency_min;
411     NvU8  vertical_frequency_max_7_0;
412 
413     struct {
414        NvU8  vertical_frequency_max_9_8           :2;
415        NvU8  reserved                             :5;
416        NvU8  seamless_dynamic_video_timing_change :1;
417     } dynamic_video_timing_range_support;
418 } DISPLAYID_2_0_RANGE_LIMITS_BLOCK;
419 
420 #define DISPLAYID_2_0_SEAMLESS_DYNAMIC_VIDEO_TIMING_CHANGE_NOT_SUPPORTED 0
421 #define DISPLAYID_2_0_SEAMLESS_DYNAMIC_VIDEO_TIMING_CHANGE_SUPPORTED     1
422 
423 #define DISPLAYID_2_0_INTERFACE_FEATURES_BLOCK_PAYLOAD_LENGTH_MIN 9
424 #define DISPLAYID_2_0_MAX_COLOR_SPACE_AND_EOTF     7
425 typedef struct _tagDISPLAYID_2_0_INTERFACE_FEATURES_BLOCK
426 {
427     // Display Interface Features Data Block (0x26)
428     DISPLAYID_2_0_DATA_BLOCK_HEADER   header;
429 
430     struct {
431         NvU8  bit_per_primary_6:1;
432         NvU8  bit_per_primary_8:1;
433         NvU8  bit_per_primary_10:1;
434         NvU8  bit_per_primary_12:1;
435         NvU8  bit_per_primary_14:1;
436         NvU8  bit_per_primary_16:1;
437         NvU8  reserved:2;
438     } interface_color_depth_rgb;
439 
440     struct {
441         NvU8  bit_per_primary_6:1;
442         NvU8  bit_per_primary_8:1;
443         NvU8  bit_per_primary_10:1;
444         NvU8  bit_per_primary_12:1;
445         NvU8  bit_per_primary_14:1;
446         NvU8  bit_per_primary_16:1;
447         NvU8  reserved:2;
448     } interface_color_depth_ycbcr444;
449 
450     struct {
451         NvU8  bit_per_primary_8:1;
452         NvU8  bit_per_primary_10:1;
453         NvU8  bit_per_primary_12:1;
454         NvU8  bit_per_primary_14:1;
455         NvU8  bit_per_primary_16:1;
456         NvU8  reserved:3;
457     } interface_color_depth_ycbcr422;
458 
459     struct {
460         NvU8  bit_per_primary_8:1;
461         NvU8  bit_per_primary_10:1;
462         NvU8  bit_per_primary_12:1;
463         NvU8  bit_per_primary_14:1;
464         NvU8  bit_per_primary_16:1;
465         NvU8  reserved:3;
466     } interface_color_depth_ycbcr420;
467 
468     NvU8  min_pixel_rate_ycbcr420; // x 74.25MP/s
469 
470     struct {
471         NvU8  reserved:5;
472         NvU8  sample_rate_48_khz:1;
473         NvU8  sample_rate_44_1_khz:1;
474         NvU8  sample_rate_32_khz:1;
475     } audio_capability;
476 
477     struct {
478         NvU8  color_space_srgb_eotf_srgb:1;
479         NvU8  color_space_bt601_eotf_bt601:1;
480         NvU8  color_space_bt709_eotf_bt1886:1;
481         NvU8  color_space_adobe_rgb_eotf_adobe_rgb:1;
482         NvU8  color_space_dci_p3_eotf_dci_p3:1;
483         NvU8  color_space_bt2020_eotf_bt2020:1;
484         NvU8  color_space_bt2020_eotf_smpte_st2084:1;
485         NvU8  reserved:1;
486     } color_space_and_eotf_1;
487 
488     struct {
489         NvU8  reserved;
490     } color_space_and_eotf_2;
491 
492     struct {
493         NvU8  count:3;
494         NvU8  reserved:5;
495     } additional_color_space_and_eotf_count;
496 
497     struct {
498         NvU8  eotf:4;
499         NvU8  color_space:4;
500     } additional_color_space_and_eotf[DISPLAYID_2_0_MAX_COLOR_SPACE_AND_EOTF];
501 } DISPLAYID_2_0_INTERFACE_FEATURES_BLOCK;
502 
503 #define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_COLORSPACE_NOT_DEFINED  0
504 #define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_COLORSPACE_SRGB         1
505 #define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_COLORSPACE_BT601        2
506 #define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_COLORSPACE_BT709        3
507 #define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_COLORSPACE_ADOBE_RGB    4
508 #define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_COLORSPACE_DCI_P3       5
509 #define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_COLORSPACE_BT2020       6
510 #define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_COLORSPACE_CUSTOM       7
511 
512 #define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_EOTF_NOT_DEFINED  0
513 #define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_EOTF_SRGB         1
514 #define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_EOTF_BT601        2
515 #define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_EOTF_BT709        3
516 #define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_EOTF_ADOBE_RGB    4
517 #define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_EOTF_DCI_P3       5
518 #define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_EOTF_BT2020       6
519 #define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_EOTF_GAMMA        7
520 #define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_EOTF_SMPTE_ST2084 8
521 #define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_EOTF_HYBRID_LOG   9
522 #define DISPLAYID_2_0_INTERFACE_FEATURES_SUPPORTED_EOTF_CUSTOM       10
523 
524 typedef struct _tagDISPLAYID_2_0_STEREO_INTERFACE_BLOCK_HEADER
525 {
526     NvU8  type;
527     NvU8  revision:3;
528     NvU8  reserved:3;
529     NvU8  stereo_timing_support:2;
530 } DISPLAYID_2_0_STEREO_INTERFACE_BLOCK_HEADER;
531 
532 typedef struct _tagDISPLAYID_2_0_STEREO_TIMING_DESCRIPTOR
533 {
534     NvU8  supported_timing_code_count:5;
535     NvU8  reserved:1;
536     NvU8  timing_code_type:2;
537     NvU8  timing_code[0x1F];
538 } DISPLAYID_2_0_STEREO_TIMING_DESCRIPTOR;
539 
540 typedef struct _tagDISPLAYID_2_0_STEREO_FIELD_SEQUENTIAL_INTERFACE_DESCRIPTOR
541 {
542     NvU8  polarity_descriptor:1;
543     NvU8  reserved:7;
544     DISPLAYID_2_0_STEREO_TIMING_DESCRIPTOR timing_descriptor;
545 } DISPLAYID_2_0_STEREO_FIELD_SEQUENTIAL_INTERFACE_DESCRIPTOR;
546 
547 typedef struct _tagDISPLAYID_2_0_STEREO_SIDE_BY_SIDE_INTERFACE_DESCRIPTOR
548 {
549     NvU8  view_identity_descriptor:1;
550     NvU8  reserved:7;
551     DISPLAYID_2_0_STEREO_TIMING_DESCRIPTOR timing_descriptor;
552 } DISPLAYID_2_0_STEREO_SIDE_BY_SIDE_INTERFACE_DESCRIPTOR;
553 
554 typedef struct _tagDISPLAYID_2_0_STEREO_PIXEL_INTERLEAVED_DESCRIPTOR
555 {
556     NvU8  interleaved_pattern_descriptor[8];
557     DISPLAYID_2_0_STEREO_TIMING_DESCRIPTOR timing_descriptor;
558 } DISPLAYID_2_0_STEREO_PIXEL_INTERLEAVED_DESCRIPTOR;
559 
560 typedef struct _tagDISPLAYID_2_0_STEREO_DUAL_INTERFACE_LEFT_AND_RIGHT_SEPARATE_DESCRIPTOR
561 {
562     NvU8  left_and_right_polarity_descriptor:1;
563     NvU8  mirroring_descriptor:2;
564     NvU8  reserved:5;
565     DISPLAYID_2_0_STEREO_TIMING_DESCRIPTOR timing_descriptor;
566 } DISPLAYID_2_0_STEREO_DUAL_INTERFACE_LEFT_AND_RIGHT_SEPARATE_DESCRIPTOR;
567 
568 typedef struct _tagDISPLAYID_2_0_STEREO_MULTI_VIEW_DESCRIPTOR
569 {
570     NvU8  views_descriptors_count;
571     NvU8  view_interleaving_method_code_descriptor;
572     DISPLAYID_2_0_STEREO_TIMING_DESCRIPTOR timing_descriptor;
573 } DISPLAYID_2_0_STEREO_MULTI_VIEW_DESCRIPTOR;
574 
575 typedef struct _tagDISPLAYID_2_0_STEREO_STACKED_FRAME_DESCRIPTOR
576 {
577     NvU8  view_identity_descriptor:1;
578     NvU8  reserved:7;
579     DISPLAYID_2_0_STEREO_TIMING_DESCRIPTOR timing_descriptor;
580 } DISPLAYID_2_0_STEREO_STACKED_FRAME_DESCRIPTOR;
581 
582 typedef struct _tagDISPLAYID_2_0_STEREO_PROPRIETARY_DESCRIPTOR
583 {
584     DISPLAYID_2_0_STEREO_TIMING_DESCRIPTOR timing_descriptor;
585 } DISPLAYID_2_0_STEREO_PROPRIETARY_DESCRIPTOR;
586 
587 typedef struct _tagDISPLAYID_2_0_STEREO_INTERFACE_METHOD_BLOCK
588 {
589     DISPLAYID_2_0_STEREO_INTERFACE_BLOCK_HEADER header;
590 
591     NvU8 stereo_bytes;
592     NvU8 stereo_code;
593     union {
594         DISPLAYID_2_0_STEREO_FIELD_SEQUENTIAL_INTERFACE_DESCRIPTOR             field_sequential;
595         DISPLAYID_2_0_STEREO_SIDE_BY_SIDE_INTERFACE_DESCRIPTOR                 side_by_side;
596         DISPLAYID_2_0_STEREO_PIXEL_INTERLEAVED_DESCRIPTOR                      pixel_interleaved;
597         DISPLAYID_2_0_STEREO_DUAL_INTERFACE_LEFT_AND_RIGHT_SEPARATE_DESCRIPTOR dual_interface;
598         DISPLAYID_2_0_STEREO_MULTI_VIEW_DESCRIPTOR                             multi_view;
599         DISPLAYID_2_0_STEREO_STACKED_FRAME_DESCRIPTOR                          stacked_frame;
600         DISPLAYID_2_0_STEREO_PROPRIETARY_DESCRIPTOR                            proprietary;
601     };
602 } DISPLAYID_2_0_STEREO_INTERFACE_METHOD_BLOCK;
603 
604 #define DISPLAYID_2_0_STEREO_CODE_FIELD_SEQUENTIAL  0x0
605 #define DISPLAYID_2_0_STEREO_CODE_SIDE_BY_SIDE      0x1
606 #define DISPLAYID_2_0_STEREO_CODE_PIXEL_INTERLEAVED 0x2
607 #define DISPLAYID_2_0_STEREO_CODE_DUAL_INTERFACE    0x3
608 #define DISPLAYID_2_0_STEREO_CODE_MULTIVIEW         0x4
609 #define DISPLAYID_2_0_STEREO_CODE_STACKED_FRAME     0x5
610 #define DISPLAYID_2_0_STEREO_CODE_PROPRIETARY       0xFF
611 
612 #define DISPLAYID_STEREO_MIRRORING 2:1
613 #define DISPLAYID_STEREO_POLARITY  0:0
614 
615 #define DISPLAYID_2_0_TILED_DISPLAY_BLOCK_PAYLOAD_LENGTH   22
616 typedef struct _tagDISPLAYID_2_0_TILED_DISPLAY_BLOCK
617 {
618     DISPLAYID_2_0_DATA_BLOCK_HEADER   header;
619     struct
620     {
621         NvU8 single_tile_behavior:3;       // 0x03
622         NvU8 multi_tile_behavior:2;        // 0x03
623         NvU8 rsvd             :1;          // 0x03
624         NvU8 has_bezel_info   :1;          // 0x03
625         NvU8 single_enclosure :1;          // 0x03
626     } capability;
627     struct
628     {
629         NvU8 row              :4;          // 0x04
630         NvU8 col              :4;          // 0x04
631     } topo_low;
632     struct
633     {
634         NvU8 y                :4;          // 0x05
635         NvU8 x                :4;          // 0x05
636     } loc_low;
637     struct
638     {
639         NvU8 y                :2;          // 0x06
640         NvU8 x                :2;          // 0x06
641         NvU8 row              :2;          // 0x06
642         NvU8 col              :2;          // 0x06
643     } topo_loc_high;
644     struct
645     {
646         NvU8 width_low;                   // 0x07
647         NvU8 width_high;                  // 0x08
648         NvU8 height_low;                  // 0x09
649         NvU8 height_high;                 // 0X0A
650     } native_resolution;
651     struct
652     {
653         NvU8 pixel_density;                // 0x0B
654         NvU8 top;                          // 0x0C
655         NvU8 bottom;                       // 0x0D
656         NvU8 right;                        // 0x0E
657         NvU8 left;                         // 0x0F
658     } bezel_info;
659     struct
660     {
661         NvU8 vendor_id[3];                 // 0x10 ~ 0x12
662         NvU8 product_id[2];                // 0x13 ~ 0x14
663         NvU8 serial_number[4];             // 0x15 ~ 0x18
664     } topo_id;
665 } DISPLAYID_2_0_TILED_DISPLAY_BLOCK;
666 
667 #define DISPLAYID_2_0_CONTAINERID_BLOCK_PAYLOAD_LENGTH   16
668 typedef struct _tagDISPLAYID_2_0_CONTAINERID_BLOCK
669 {
670     DISPLAYID_2_0_DATA_BLOCK_HEADER header;
671     NvU8  container_id[DISPLAYID_2_0_CONTAINERID_BLOCK_PAYLOAD_LENGTH];
672 } DISPLAYID_2_0_CONTAINERID_BLOCK;
673 
674 #define DISPLAYID_2_0_ADAPTIVE_SYNC_DETAILED_TIMING_COUNT 4
675 typedef struct _tagDISPLAYID_2_0_ADAPTIVE_SYNC_BLOCK_HEADER
676 {
677     NvU8  type;                                // Adaptive-Sync (0x2B)
678     NvU8  revision                        :3;
679     NvU8  reserved0                       :1;
680     NvU8  payload_bytes_adaptive_sync_len :3;
681     NvU8  reserved1                       :1;
682     NvU8  payload_bytes;
683 } DISPLAYID_2_0_ADAPTIVE_SYNC_BLOCK_HEADER;
684 
685 typedef struct _tagDISPLAYID_2_0_ADAPTIVE_SYNC_DESCRIPTOR
686 {
687     struct
688     {
689         NvU8 range                          : 1;
690         NvU8 successive_frame_inc_tolerance : 1;
691         NvU8 modes                          : 2;
692         NvU8 seamless_transition_not_support: 1;
693         NvU8 successive_frame_dec_tolerance : 1;
694         NvU8 reserved                       : 2;
695     } operation_range_info;
696 
697     // 6.2 format (six integer bits and two fractional bits)
698     // six integer bits    == 0 - 63ms
699     // two fractional bits == 0.00(00), 0.25(01b),0.50(10), 0.75(11b)
700     NvU8 max_single_frame_inc;
701     NvU8 min_refresh_rate;
702     struct
703     {
704         NvU8 max_rr_7_0;
705         NvU8 max_rr_9_8 : 2;
706         NvU8 reserved   : 6;
707     } max_refresh_rate;
708 
709     // same as max_single_frame_inc expression
710     NvU8 max_single_frame_dec;
711 } DISPLAYID_2_0_ADAPTIVE_SYNC_DESCRIPTOR;
712 
713 typedef struct _tagDISPLAYID_2_0_ADAPTIVE_SYNC_BLOCK
714 {
715     DISPLAYID_2_0_ADAPTIVE_SYNC_BLOCK_HEADER header;
716     DISPLAYID_2_0_ADAPTIVE_SYNC_DESCRIPTOR   descriptors[DISPLAYID_2_0_ADAPTIVE_SYNC_DETAILED_TIMING_COUNT];
717 } DISPLAYID_2_0_ADAPTIVE_SYNC_BLOCK;
718 
719 // Payload value as defined in DID2.1 spec
720 #define DISPLAYID_2_0_BRIGHTNESS_LUMINANCE_RANGE_BLOCK_PAYLOAD_LENGTH   6
721 typedef struct _tagDISPLAYID_2_0_BRIGHTNESS_LUMINANCE_RANGE_BLOCK
722 {
723     DISPLAYID_2_0_DATA_BLOCK_HEADER header;
724     NvU16 min_sdr_luminance;                  // 0x03 ~ 0x04
725     NvU16 max_sdr_luminance;                  // 0x05 ~ 0x06
726     NvU16 max_boost_sdr_luminance;            // 0x07 ~ 0x08
727 } DISPLAYID_2_0_BRIGHTNESS_LUMINANCE_RANGE_BLOCK;
728 
729 typedef struct _tagDISPLAYID_2_0_VENDOR_SPECIFIC_BLOCK
730 {
731     DISPLAYID_2_0_DATA_BLOCK_HEADER header;
732     NvU8  vendor_id[3];
733     NvU8  vendor_specific_data[245];
734 } DISPLAYID_2_0_VENDOR_SPECIFIC_BLOCK;
735 
736 typedef struct _tagDISPLAYID_2_0_CTA_BLOCK
737 {
738     DISPLAYID_2_0_DATA_BLOCK_HEADER header;
739     NvU8  cta_data[248];
740 } DISPLAYID_2_0_CTA_BLOCK;
741 
742 #ifdef __SUPPORTS_PACK_PRAGMA
743 #pragma pack()
744 #endif
745 
746 #ifdef __cplusplus
747 extern "C" {
748 #endif
749 
750 // Entry point functions both used in DID20 and DID20ext
751 NVT_STATUS parseDisplayId20DataBlock(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo);
752 NvU8       computeDisplayId20SectionCheckSum(const NvU8 *pSectionBytes, NvU32 length);
753 
754 // DisplayID20 as EDID extension entry point function
755 NVT_STATUS parseDisplayId20EDIDExtSection(DISPLAYID_2_0_SECTION *section, NVT_EDID_INFO *pEdidInfo);
756 
757 // DisplayID20 Entry point functions
758 NVT_STATUS parseDisplayId20BaseSection(const DISPLAYID_2_0_SECTION *pSection, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo);
759 NVT_STATUS parseDisplayId20SectionDataBlocks(const DISPLAYID_2_0_SECTION *pSection, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo);
760 NVT_STATUS parseDisplayId20ExtensionSection(const DISPLAYID_2_0_SECTION *pSection, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo);
761 
762 // DisplayID20 Data Block Tag Allocation
763 NVT_STATUS parseDisplayId20ProductIdentity(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo);                // 0x20 Product Identificaton
764 NVT_STATUS parseDisplayId20DisplayParam(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo);                   // 0x21 Display Parameters
765 NVT_STATUS parseDisplayId20Timing7(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo);                        // 0x22 Type VII Timing - Detailed Timing
766 NVT_STATUS parseDisplayId20Timing8(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo);                        // 0x23 Type VIII Timing - Enumerated Timing
767 NVT_STATUS parseDisplayId20Timing9(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo);                        // 0x24 Type IX Timing - Formula-based
768 NVT_STATUS parseDisplayId20RangeLimit(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo);                     // 0x25 Dynamic Video Timing Range Limits
769 NVT_STATUS parseDisplayId20DisplayInterfaceFeatures(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo);       // 0x26 Display Interface Features
770 NVT_STATUS parseDisplayId20Stereo(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo);                         // 0x27 Stereo Display Interface
771 NVT_STATUS parseDisplayId20TiledDisplay(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo);                   // 0x28 Tiled Display Topology
772 NVT_STATUS parseDisplayId20ContainerId(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo);                    // 0x29 ContainerID
773 NVT_STATUS parseDisplayId20Timing10(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo);                       // 0x2A Type X Timing - Formula-based Timing
774 NVT_STATUS parseDisplayId20AdaptiveSync(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo);                   // 0x2B Adaptive-Sync
775 NVT_STATUS parseDisplayId20ARVRHMD(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo);                        // 0x2C ARVR HMD
776 NVT_STATUS parseDisplayId20ARVRLayer(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo);                      // 0x2D ARVR Layer
777 NVT_STATUS parseDisplayId20BrightnessLuminanceRange(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo);       // 0x2E Brightness Luminance Range
778 NVT_STATUS parseDisplayId20VendorSpecific(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo);                 // 0x7E Vendor-specific
779 NVT_STATUS parseDisplayId20CtaData(const DISPLAYID_2_0_DATA_BLOCK_HEADER *pDataBlock, NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo);                        // 0x81 CTA DisplayID
780 
781 #ifdef __cplusplus
782 }
783 #endif
784 #endif // __DISPLAYID20_H_1
785 
786