1f453ba04SDave Airlie /*
2f453ba04SDave Airlie * Copyright © 2007-2008 Intel Corporation
3f453ba04SDave Airlie * Jesse Barnes <jesse.barnes@intel.com>
4f453ba04SDave Airlie *
5f453ba04SDave Airlie * Permission is hereby granted, free of charge, to any person obtaining a
6f453ba04SDave Airlie * copy of this software and associated documentation files (the "Software"),
7f453ba04SDave Airlie * to deal in the Software without restriction, including without limitation
8f453ba04SDave Airlie * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9f453ba04SDave Airlie * and/or sell copies of the Software, and to permit persons to whom the
10f453ba04SDave Airlie * Software is furnished to do so, subject to the following conditions:
11f453ba04SDave Airlie *
12f453ba04SDave Airlie * The above copyright notice and this permission notice shall be included in
13f453ba04SDave Airlie * all copies or substantial portions of the Software.
14f453ba04SDave Airlie *
15f453ba04SDave Airlie * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16f453ba04SDave Airlie * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17f453ba04SDave Airlie * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18f453ba04SDave Airlie * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19f453ba04SDave Airlie * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20f453ba04SDave Airlie * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21f453ba04SDave Airlie * OTHER DEALINGS IN THE SOFTWARE.
22f453ba04SDave Airlie */
23f453ba04SDave Airlie #ifndef __DRM_EDID_H__
24f453ba04SDave Airlie #define __DRM_EDID_H__
25f453ba04SDave Airlie
26f453ba04SDave Airlie #include <linux/types.h>
2700147934SVille Syrjälä #include <linux/hdmi.h>
282cdbfd66SUma Shankar #include <drm/drm_mode.h>
29f453ba04SDave Airlie
30cdc3d09fSDaniel Vetter struct drm_device;
31d9ba1b4cSJani Nikula struct drm_edid;
32cdc3d09fSDaniel Vetter struct i2c_adapter;
33cdc3d09fSDaniel Vetter
34f453ba04SDave Airlie #define EDID_LENGTH 128
35f453ba04SDave Airlie #define DDC_ADDR 0x50
36b49b55bdSDave Airlie #define DDC_ADDR2 0x52 /* E-DDC 1.2 - where DisplayID can hide */
37f453ba04SDave Airlie
384d76a221SAdam Jackson #define CEA_EXT 0x02
394d76a221SAdam Jackson #define VTB_EXT 0x10
404d76a221SAdam Jackson #define DI_EXT 0x40
414d76a221SAdam Jackson #define LS_EXT 0x50
424d76a221SAdam Jackson #define MI_EXT 0x60
43b49b55bdSDave Airlie #define DISPLAYID_EXT 0x70
444d76a221SAdam Jackson
45f453ba04SDave Airlie struct est_timings {
46f453ba04SDave Airlie u8 t1;
47f453ba04SDave Airlie u8 t2;
48f453ba04SDave Airlie u8 mfg_rsvd;
49f453ba04SDave Airlie } __attribute__((packed));
50f453ba04SDave Airlie
510454beabSMichel Dänzer /* 00=16:10, 01=4:3, 10=5:4, 11=16:9 */
52e14cbee4SMichel Dänzer #define EDID_TIMING_ASPECT_SHIFT 6
530454beabSMichel Dänzer #define EDID_TIMING_ASPECT_MASK (0x3 << EDID_TIMING_ASPECT_SHIFT)
540454beabSMichel Dänzer
550454beabSMichel Dänzer /* need to add 60 */
56e14cbee4SMichel Dänzer #define EDID_TIMING_VFREQ_SHIFT 0
570454beabSMichel Dänzer #define EDID_TIMING_VFREQ_MASK (0x3f << EDID_TIMING_VFREQ_SHIFT)
580454beabSMichel Dänzer
59f453ba04SDave Airlie struct std_timing {
60f453ba04SDave Airlie u8 hsize; /* need to multiply by 8 then add 248 */
610454beabSMichel Dänzer u8 vfreq_aspect;
62f453ba04SDave Airlie } __attribute__((packed));
63f453ba04SDave Airlie
64*ca62297bSVille Syrjälä #define DRM_EDID_PT_HSYNC_POSITIVE (1 << 1)
65*ca62297bSVille Syrjälä #define DRM_EDID_PT_VSYNC_POSITIVE (1 << 2)
66*ca62297bSVille Syrjälä #define DRM_EDID_PT_SEPARATE_SYNC (3 << 3)
67*ca62297bSVille Syrjälä #define DRM_EDID_PT_STEREO (1 << 5)
68*ca62297bSVille Syrjälä #define DRM_EDID_PT_INTERLACED (1 << 7)
69*ca62297bSVille Syrjälä
70*ca62297bSVille Syrjälä /* If detailed data is pixel timing */
71*ca62297bSVille Syrjälä struct detailed_pixel_timing {
72e14cbee4SMichel Dänzer u8 hactive_lo;
73e14cbee4SMichel Dänzer u8 hblank_lo;
74e14cbee4SMichel Dänzer u8 hactive_hblank_hi;
750454beabSMichel Dänzer u8 vactive_lo;
76f453ba04SDave Airlie u8 vblank_lo;
77f453ba04SDave Airlie u8 vactive_vblank_hi;
78f453ba04SDave Airlie u8 hsync_offset_lo;
79f453ba04SDave Airlie u8 hsync_pulse_width_lo;
800454beabSMichel Dänzer u8 vsync_offset_pulse_width_lo;
81f453ba04SDave Airlie u8 hsync_vsync_offset_pulse_width_hi;
82f453ba04SDave Airlie u8 width_mm_lo;
830454beabSMichel Dänzer u8 height_mm_lo;
84f453ba04SDave Airlie u8 width_height_mm_hi;
85f453ba04SDave Airlie u8 hborder;
860454beabSMichel Dänzer u8 vborder;
870454beabSMichel Dänzer u8 misc;
88f453ba04SDave Airlie } __attribute__((packed));
89f453ba04SDave Airlie
900454beabSMichel Dänzer /* If it's not pixel timing, it'll be one of the below */
91f453ba04SDave Airlie struct detailed_data_string {
92f453ba04SDave Airlie u8 str[13];
930454beabSMichel Dänzer } __attribute__((packed));
94f453ba04SDave Airlie
95f453ba04SDave Airlie #define DRM_EDID_RANGE_OFFSET_MIN_VFREQ (1 << 0) /* 1.4 */
96f453ba04SDave Airlie #define DRM_EDID_RANGE_OFFSET_MAX_VFREQ (1 << 1) /* 1.4 */
97f453ba04SDave Airlie #define DRM_EDID_RANGE_OFFSET_MIN_HFREQ (1 << 2) /* 1.4 */
98f453ba04SDave Airlie #define DRM_EDID_RANGE_OFFSET_MAX_HFREQ (1 << 3) /* 1.4 */
99f453ba04SDave Airlie
100f453ba04SDave Airlie #define DRM_EDID_DEFAULT_GTF_SUPPORT_FLAG 0x00 /* 1.3 */
101c7943bb3SVille Syrjälä #define DRM_EDID_RANGE_LIMITS_ONLY_FLAG 0x01 /* 1.4 */
102c7943bb3SVille Syrjälä #define DRM_EDID_SECONDARY_GTF_SUPPORT_FLAG 0x02 /* 1.3 */
103c7943bb3SVille Syrjälä #define DRM_EDID_CVT_SUPPORT_FLAG 0x04 /* 1.4 */
104c7943bb3SVille Syrjälä
105c7943bb3SVille Syrjälä #define DRM_EDID_CVT_FLAGS_STANDARD_BLANKING (1 << 3)
106afd4429eSVille Syrjälä #define DRM_EDID_CVT_FLAGS_REDUCED_BLANKING (1 << 4)
107afd4429eSVille Syrjälä
108afd4429eSVille Syrjälä struct detailed_data_monitor_range {
109afd4429eSVille Syrjälä u8 min_vfreq;
110afd4429eSVille Syrjälä u8 max_vfreq;
111afd4429eSVille Syrjälä u8 min_hfreq_khz;
112afd4429eSVille Syrjälä u8 max_hfreq_khz;
113f1ce9876SManasi Navare u8 pixel_clock_mhz; /* need to multiply by 10 */
114f453ba04SDave Airlie u8 flags;
115f453ba04SDave Airlie union {
116f453ba04SDave Airlie struct {
117f453ba04SDave Airlie u8 reserved;
118f453ba04SDave Airlie u8 hfreq_start_khz; /* need to multiply by 2 */
119f453ba04SDave Airlie u8 c; /* need to divide by 2 */
120eeefa4beSAdam Jackson __le16 m;
121eeefa4beSAdam Jackson u8 k;
122eeefa4beSAdam Jackson u8 j; /* need to divide by 2 */
123eeefa4beSAdam Jackson } __attribute__((packed)) gtf2;
124f453ba04SDave Airlie struct {
125f453ba04SDave Airlie u8 version;
1260454beabSMichel Dänzer u8 data1; /* high 6 bits: extra clock resolution */
127f453ba04SDave Airlie u8 data2; /* plus low 2 of above: max hactive */
128f453ba04SDave Airlie u8 supported_aspects;
1298353e6c6STakashi Iwai u8 flags; /* preferred aspect and blanking support */
130eeefa4beSAdam Jackson u8 supported_scalings;
131eeefa4beSAdam Jackson u8 preferred_refresh;
132eeefa4beSAdam Jackson } __attribute__((packed)) cvt;
133eeefa4beSAdam Jackson } __attribute__((packed)) formula;
134eeefa4beSAdam Jackson } __attribute__((packed));
135eeefa4beSAdam Jackson
136eeefa4beSAdam Jackson struct detailed_data_wpindex {
137eeefa4beSAdam Jackson u8 white_yx_lo; /* Lower 2 bits each */
1388353e6c6STakashi Iwai u8 white_x_hi;
13947f15561SLinus Torvalds u8 white_y_hi;
140f453ba04SDave Airlie u8 gamma; /* need to divide by 100 then add 1 */
141f453ba04SDave Airlie } __attribute__((packed));
142f453ba04SDave Airlie
143e14cbee4SMichel Dänzer struct detailed_data_color_point {
144f453ba04SDave Airlie u8 windex1;
145f453ba04SDave Airlie u8 wpindex1[3];
146f453ba04SDave Airlie u8 windex2;
147f453ba04SDave Airlie u8 wpindex2[3];
148f453ba04SDave Airlie } __attribute__((packed));
149f453ba04SDave Airlie
150f453ba04SDave Airlie struct cvt_timing {
151f453ba04SDave Airlie u8 code[3];
152f453ba04SDave Airlie } __attribute__((packed));
153f453ba04SDave Airlie
154f453ba04SDave Airlie struct detailed_non_pixel {
155f453ba04SDave Airlie u8 pad1;
1569340d8cfSAdam Jackson u8 type; /* ff=serial, fe=string, fd=monitor range, fc=monitor name
1579340d8cfSAdam Jackson fb=color point data, fa=standard timing data,
1589340d8cfSAdam Jackson f9=undefined, f8=mfg. reserved */
1599340d8cfSAdam Jackson u8 pad2;
160f453ba04SDave Airlie union {
161f453ba04SDave Airlie struct detailed_data_string str;
162f453ba04SDave Airlie struct detailed_data_monitor_range range;
163f453ba04SDave Airlie struct detailed_data_wpindex color;
164f453ba04SDave Airlie struct std_timing timings[6];
165f453ba04SDave Airlie struct cvt_timing cvt[4];
166f453ba04SDave Airlie } __attribute__((packed)) data;
167f453ba04SDave Airlie } __attribute__((packed));
168f453ba04SDave Airlie
169f453ba04SDave Airlie #define EDID_DETAIL_EST_TIMINGS 0xf7
17096525a2fSDan Carpenter #define EDID_DETAIL_CVT_3BYTE 0xf8
1719340d8cfSAdam Jackson #define EDID_DETAIL_COLOR_MGMT_DATA 0xf9
17247f15561SLinus Torvalds #define EDID_DETAIL_STD_MODES 0xfa
173f453ba04SDave Airlie #define EDID_DETAIL_MONITOR_CPDATA 0xfb
174f453ba04SDave Airlie #define EDID_DETAIL_MONITOR_NAME 0xfc
1752dbdc52cSAdam Jackson #define EDID_DETAIL_MONITOR_RANGE 0xfd
1762dbdc52cSAdam Jackson #define EDID_DETAIL_MONITOR_STRING 0xfe
1772dbdc52cSAdam Jackson #define EDID_DETAIL_MONITOR_SERIAL 0xff
178f453ba04SDave Airlie
179f453ba04SDave Airlie struct detailed_timing {
180f453ba04SDave Airlie __le16 pixel_clock; /* need to multiply by 10 KHz */
181f453ba04SDave Airlie union {
182f453ba04SDave Airlie struct detailed_pixel_timing pixel_data;
183f453ba04SDave Airlie struct detailed_non_pixel other_data;
184f453ba04SDave Airlie } __attribute__((packed)) data;
185f453ba04SDave Airlie } __attribute__((packed));
1860454beabSMichel Dänzer
187f453ba04SDave Airlie #define DRM_EDID_INPUT_SERRATION_VSYNC (1 << 0)
188f453ba04SDave Airlie #define DRM_EDID_INPUT_SYNC_ON_GREEN (1 << 1)
189f453ba04SDave Airlie #define DRM_EDID_INPUT_COMPOSITE_SYNC (1 << 2)
19047f15561SLinus Torvalds #define DRM_EDID_INPUT_SEPARATE_SYNCS (1 << 3)
191f453ba04SDave Airlie #define DRM_EDID_INPUT_BLANK_TO_BLACK (1 << 4)
192f453ba04SDave Airlie #define DRM_EDID_INPUT_VIDEO_LEVEL (3 << 5)
193e14cbee4SMichel Dänzer #define DRM_EDID_INPUT_DIGITAL (1 << 7)
194e14cbee4SMichel Dänzer #define DRM_EDID_DIGITAL_DEPTH_MASK (7 << 4) /* 1.4 */
195e14cbee4SMichel Dänzer #define DRM_EDID_DIGITAL_DEPTH_UNDEF (0 << 4) /* 1.4 */
1960454beabSMichel Dänzer #define DRM_EDID_DIGITAL_DEPTH_6 (1 << 4) /* 1.4 */
197e14cbee4SMichel Dänzer #define DRM_EDID_DIGITAL_DEPTH_8 (2 << 4) /* 1.4 */
198e14cbee4SMichel Dänzer #define DRM_EDID_DIGITAL_DEPTH_10 (3 << 4) /* 1.4 */
1993b11228bSJesse Barnes #define DRM_EDID_DIGITAL_DEPTH_12 (4 << 4) /* 1.4 */
200382d2af6SVille Syrjälä #define DRM_EDID_DIGITAL_DEPTH_14 (5 << 4) /* 1.4 */
201382d2af6SVille Syrjälä #define DRM_EDID_DIGITAL_DEPTH_16 (6 << 4) /* 1.4 */
202382d2af6SVille Syrjälä #define DRM_EDID_DIGITAL_DEPTH_RSVD (7 << 4) /* 1.4 */
203382d2af6SVille Syrjälä #define DRM_EDID_DIGITAL_TYPE_MASK (7 << 0) /* 1.4 */
204382d2af6SVille Syrjälä #define DRM_EDID_DIGITAL_TYPE_UNDEF (0 << 0) /* 1.4 */
205382d2af6SVille Syrjälä #define DRM_EDID_DIGITAL_TYPE_DVI (1 << 0) /* 1.4 */
206382d2af6SVille Syrjälä #define DRM_EDID_DIGITAL_TYPE_HDMI_A (2 << 0) /* 1.4 */
207382d2af6SVille Syrjälä #define DRM_EDID_DIGITAL_TYPE_HDMI_B (3 << 0) /* 1.4 */
208382d2af6SVille Syrjälä #define DRM_EDID_DIGITAL_TYPE_MDDI (4 << 0) /* 1.4 */
209382d2af6SVille Syrjälä #define DRM_EDID_DIGITAL_TYPE_DP (5 << 0) /* 1.4 */
210382d2af6SVille Syrjälä #define DRM_EDID_DIGITAL_DFP_1_X (1 << 0) /* 1.3 */
211382d2af6SVille Syrjälä
212382d2af6SVille Syrjälä #define DRM_EDID_FEATURE_DEFAULT_GTF (1 << 0) /* 1.2 */
213382d2af6SVille Syrjälä #define DRM_EDID_FEATURE_CONTINUOUS_FREQ (1 << 0) /* 1.4 */
214382d2af6SVille Syrjälä #define DRM_EDID_FEATURE_PREFERRED_TIMING (1 << 1)
215382d2af6SVille Syrjälä #define DRM_EDID_FEATURE_STANDARD_COLOR (1 << 2)
216382d2af6SVille Syrjälä /* If analog */
2170454beabSMichel Dänzer #define DRM_EDID_FEATURE_DISPLAY_TYPE (3 << 3) /* 00=mono, 01=rgb, 10=non-rgb, 11=unknown */
218afd4429eSVille Syrjälä /* If digital */
219afd4429eSVille Syrjälä #define DRM_EDID_FEATURE_COLOR_MASK (3 << 3)
220e14cbee4SMichel Dänzer #define DRM_EDID_FEATURE_RGB (0 << 3)
221e14cbee4SMichel Dänzer #define DRM_EDID_FEATURE_RGB_YCRCB444 (1 << 3)
222da05a5a7SJesse Barnes #define DRM_EDID_FEATURE_RGB_YCRCB422 (2 << 3)
2230454beabSMichel Dänzer #define DRM_EDID_FEATURE_RGB_YCRCB (3 << 3) /* both 4:4:4 and 4:2:2 */
224da05a5a7SJesse Barnes
225da05a5a7SJesse Barnes #define DRM_EDID_FEATURE_PM_ACTIVE_OFF (1 << 5)
226da05a5a7SJesse Barnes #define DRM_EDID_FEATURE_PM_SUSPEND (1 << 6)
227da05a5a7SJesse Barnes #define DRM_EDID_FEATURE_PM_STANDBY (1 << 7)
228da05a5a7SJesse Barnes
229da05a5a7SJesse Barnes #define DRM_EDID_HDMI_DC_48 (1 << 6)
230da05a5a7SJesse Barnes #define DRM_EDID_HDMI_DC_36 (1 << 5)
231e14cbee4SMichel Dänzer #define DRM_EDID_HDMI_DC_30 (1 << 4)
232e14cbee4SMichel Dänzer #define DRM_EDID_HDMI_DC_Y444 (1 << 3)
233e14cbee4SMichel Dänzer
2340454beabSMichel Dänzer /* YCBCR 420 deep color modes */
235d0c94692SMario Kleiner #define DRM_EDID_YCBCR420_DC_48 (1 << 2)
236d0c94692SMario Kleiner #define DRM_EDID_YCBCR420_DC_36 (1 << 1)
237d0c94692SMario Kleiner #define DRM_EDID_YCBCR420_DC_30 (1 << 0)
238d0c94692SMario Kleiner #define DRM_EDID_YCBCR420_DC_MASK (DRM_EDID_YCBCR420_DC_48 | \
239d0c94692SMario Kleiner DRM_EDID_YCBCR420_DC_36 | \
240e6a9a2c3SShashank Sharma DRM_EDID_YCBCR420_DC_30)
2419068e02fSClint Taylor
2429068e02fSClint Taylor /* HDMI 2.1 additional fields */
2439068e02fSClint Taylor #define DRM_EDID_MAX_FRL_RATE_MASK 0xf0
244e6a9a2c3SShashank Sharma #define DRM_EDID_FAPA_START_LOCATION (1 << 0)
245e6a9a2c3SShashank Sharma #define DRM_EDID_ALLM (1 << 1)
246e6a9a2c3SShashank Sharma #define DRM_EDID_FVA (1 << 2)
247e6a9a2c3SShashank Sharma
2489bb85a6eSSwati Sharma /* Deep Color specific */
2499bb85a6eSSwati Sharma #define DRM_EDID_DC_30BIT_420 (1 << 0)
2509bb85a6eSSwati Sharma #define DRM_EDID_DC_36BIT_420 (1 << 1)
2519bb85a6eSSwati Sharma #define DRM_EDID_DC_48BIT_420 (1 << 2)
2529bb85a6eSSwati Sharma
2539bb85a6eSSwati Sharma /* VRR specific */
2549bb85a6eSSwati Sharma #define DRM_EDID_CNMVRR (1 << 3)
2559bb85a6eSSwati Sharma #define DRM_EDID_CINEMA_VRR (1 << 4)
2569bb85a6eSSwati Sharma #define DRM_EDID_MDELTA (1 << 5)
2579bb85a6eSSwati Sharma #define DRM_EDID_VRR_MAX_UPPER_MASK 0xc0
2589bb85a6eSSwati Sharma #define DRM_EDID_VRR_MAX_LOWER_MASK 0xff
2599bb85a6eSSwati Sharma #define DRM_EDID_VRR_MIN_MASK 0x3f
2609bb85a6eSSwati Sharma
2619bb85a6eSSwati Sharma /* DSC specific */
2629bb85a6eSSwati Sharma #define DRM_EDID_DSC_10BPC (1 << 0)
2639bb85a6eSSwati Sharma #define DRM_EDID_DSC_12BPC (1 << 1)
2649bb85a6eSSwati Sharma #define DRM_EDID_DSC_16BPC (1 << 2)
2659bb85a6eSSwati Sharma #define DRM_EDID_DSC_ALL_BPP (1 << 3)
2669bb85a6eSSwati Sharma #define DRM_EDID_DSC_NATIVE_420 (1 << 6)
2679bb85a6eSSwati Sharma #define DRM_EDID_DSC_1P2 (1 << 7)
2689bb85a6eSSwati Sharma #define DRM_EDID_DSC_MAX_FRL_RATE_MASK 0xf0
2699bb85a6eSSwati Sharma #define DRM_EDID_DSC_MAX_SLICES 0xf
2709bb85a6eSSwati Sharma #define DRM_EDID_DSC_TOTAL_CHUNK_KBYTES 0x3f
2719bb85a6eSSwati Sharma
2729bb85a6eSSwati Sharma /* ELD Header Block */
2739bb85a6eSSwati Sharma #define DRM_ELD_HEADER_BLOCK_SIZE 4
2749bb85a6eSSwati Sharma
2759bb85a6eSSwati Sharma #define DRM_ELD_VER 0
2769bb85a6eSSwati Sharma # define DRM_ELD_VER_SHIFT 3
2779bb85a6eSSwati Sharma # define DRM_ELD_VER_MASK (0x1f << 3)
278babc9493SJani Nikula # define DRM_ELD_VER_CEA861D (2 << 3) /* supports 861D or below */
279babc9493SJani Nikula # define DRM_ELD_VER_CANNED (0x1f << 3)
280babc9493SJani Nikula
281babc9493SJani Nikula #define DRM_ELD_BASELINE_ELD_LEN 2 /* in dwords! */
282babc9493SJani Nikula
283babc9493SJani Nikula /* ELD Baseline Block for ELD_Ver == 2 */
2841b54bdb8SJani Nikula #define DRM_ELD_CEA_EDID_VER_MNL 4
2851b54bdb8SJani Nikula # define DRM_ELD_CEA_EDID_VER_SHIFT 5
286babc9493SJani Nikula # define DRM_ELD_CEA_EDID_VER_MASK (7 << 5)
287babc9493SJani Nikula # define DRM_ELD_CEA_EDID_VER_NONE (0 << 5)
288babc9493SJani Nikula # define DRM_ELD_CEA_EDID_VER_CEA861 (1 << 5)
289babc9493SJani Nikula # define DRM_ELD_CEA_EDID_VER_CEA861A (2 << 5)
290babc9493SJani Nikula # define DRM_ELD_CEA_EDID_VER_CEA861BCD (3 << 5)
291babc9493SJani Nikula # define DRM_ELD_MNL_SHIFT 0
292babc9493SJani Nikula # define DRM_ELD_MNL_MASK (0x1f << 0)
293babc9493SJani Nikula
294babc9493SJani Nikula #define DRM_ELD_SAD_COUNT_CONN_TYPE 5
295babc9493SJani Nikula # define DRM_ELD_SAD_COUNT_SHIFT 4
296babc9493SJani Nikula # define DRM_ELD_SAD_COUNT_MASK (0xf << 4)
297babc9493SJani Nikula # define DRM_ELD_CONN_TYPE_SHIFT 2
298babc9493SJani Nikula # define DRM_ELD_CONN_TYPE_MASK (3 << 2)
299babc9493SJani Nikula # define DRM_ELD_CONN_TYPE_HDMI (0 << 2)
300babc9493SJani Nikula # define DRM_ELD_CONN_TYPE_DP (1 << 2)
301babc9493SJani Nikula # define DRM_ELD_SUPPORTS_AI (1 << 1)
302babc9493SJani Nikula # define DRM_ELD_SUPPORTS_HDCP (1 << 0)
303babc9493SJani Nikula
304babc9493SJani Nikula #define DRM_ELD_AUD_SYNCH_DELAY 6 /* in units of 2 ms */
305babc9493SJani Nikula # define DRM_ELD_AUD_SYNCH_DELAY_MAX 0xfa /* 500 ms */
306babc9493SJani Nikula
307babc9493SJani Nikula #define DRM_ELD_SPEAKER 7
308babc9493SJani Nikula # define DRM_ELD_SPEAKER_MASK 0x7f
309babc9493SJani Nikula # define DRM_ELD_SPEAKER_RLRC (1 << 6)
310babc9493SJani Nikula # define DRM_ELD_SPEAKER_FLRC (1 << 5)
311babc9493SJani Nikula # define DRM_ELD_SPEAKER_RC (1 << 4)
312babc9493SJani Nikula # define DRM_ELD_SPEAKER_RLR (1 << 3)
313babc9493SJani Nikula # define DRM_ELD_SPEAKER_FC (1 << 2)
314c82dbe5cSArnaud Pouliquen # define DRM_ELD_SPEAKER_LFE (1 << 1)
315babc9493SJani Nikula # define DRM_ELD_SPEAKER_FLR (1 << 0)
316babc9493SJani Nikula
317babc9493SJani Nikula #define DRM_ELD_PORT_ID 8 /* offsets 8..15 inclusive */
318babc9493SJani Nikula # define DRM_ELD_PORT_ID_LEN 8
319babc9493SJani Nikula
320babc9493SJani Nikula #define DRM_ELD_MANUFACTURER_NAME0 16
321babc9493SJani Nikula #define DRM_ELD_MANUFACTURER_NAME1 17
322babc9493SJani Nikula
323babc9493SJani Nikula #define DRM_ELD_PRODUCT_CODE0 18
324babc9493SJani Nikula #define DRM_ELD_PRODUCT_CODE1 19
325babc9493SJani Nikula
326babc9493SJani Nikula #define DRM_ELD_MONITOR_NAME_STRING 20 /* offsets 20..(20+mnl-1) inclusive */
327babc9493SJani Nikula
328babc9493SJani Nikula #define DRM_ELD_CEA_SAD(mnl, sad) (20 + (mnl) + 3 * (sad))
329babc9493SJani Nikula
330babc9493SJani Nikula struct edid {
331babc9493SJani Nikula u8 header[8];
332babc9493SJani Nikula /* Vendor & product info */
333babc9493SJani Nikula u8 mfg_id[2];
334babc9493SJani Nikula u8 prod_code[2];
335babc9493SJani Nikula u32 serial; /* FIXME: byte order */
336f453ba04SDave Airlie u8 mfg_week;
337f453ba04SDave Airlie u8 mfg_year;
338f453ba04SDave Airlie /* EDID version */
339f453ba04SDave Airlie u8 version;
340f453ba04SDave Airlie u8 revision;
341f453ba04SDave Airlie /* Display info: */
342f453ba04SDave Airlie u8 input;
343f453ba04SDave Airlie u8 width_cm;
344f453ba04SDave Airlie u8 height_cm;
345f453ba04SDave Airlie u8 gamma;
346f453ba04SDave Airlie u8 features;
347f453ba04SDave Airlie /* Color characteristics */
3480454beabSMichel Dänzer u8 red_green_lo;
349f453ba04SDave Airlie u8 blue_white_lo;
350f453ba04SDave Airlie u8 red_x;
351f453ba04SDave Airlie u8 red_y;
3520454beabSMichel Dänzer u8 green_x;
353f453ba04SDave Airlie u8 green_y;
354f453ba04SDave Airlie u8 blue_x;
35596275df8SLucas De Marchi u8 blue_y;
356f453ba04SDave Airlie u8 white_x;
357f453ba04SDave Airlie u8 white_y;
358f453ba04SDave Airlie /* Est. timings and mfg rsvd timings*/
359f453ba04SDave Airlie struct est_timings established_timings;
360f453ba04SDave Airlie /* Standard timings 1-8*/
361f453ba04SDave Airlie struct std_timing standard_timings[8];
362f453ba04SDave Airlie /* Detailing timings 1-4 */
363f453ba04SDave Airlie struct detailed_timing detailed_timings[4];
364f453ba04SDave Airlie /* Number of 128 byte ext. blocks */
365f453ba04SDave Airlie u8 extensions;
366f453ba04SDave Airlie /* Checksum */
367f453ba04SDave Airlie u8 checksum;
368f453ba04SDave Airlie } __attribute__((packed));
369f453ba04SDave Airlie
370f453ba04SDave Airlie #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1] << 8))
371f453ba04SDave Airlie
372f453ba04SDave Airlie /* Short Audio Descriptor */
373f453ba04SDave Airlie struct cea_sad {
374f453ba04SDave Airlie u8 format;
375f453ba04SDave Airlie u8 channels; /* max number of channels - 1 */
376f453ba04SDave Airlie u8 freq;
377f453ba04SDave Airlie u8 byte2; /* meaning depends on format */
378fe214163SRafał Miłecki };
379fe214163SRafał Miłecki
380fe214163SRafał Miłecki struct drm_encoder;
381fe214163SRafał Miłecki struct drm_connector;
382fe214163SRafał Miłecki struct drm_connector_state;
383fe214163SRafał Miłecki struct drm_display_mode;
384fe214163SRafał Miłecki
385fe214163SRafał Miłecki int drm_edid_to_sad(const struct edid *edid, struct cea_sad **sads);
38676adaa34SWu Fengguang int drm_edid_to_speaker_allocation(const struct edid *edid, u8 **sadb);
38776adaa34SWu Fengguang int drm_av_sync_delay(struct drm_connector *connector,
3880d68b887SUma Shankar const struct drm_display_mode *mode);
38976adaa34SWu Fengguang
39010a85120SThierry Reding #ifdef CONFIG_DRM_LOAD_EDID_FIRMWARE
391f4e558ecSJani Nikula int __drm_set_edid_firmware_path(const char *path);
392f4e558ecSJani Nikula int __drm_get_edid_firmware_path(char *buf, size_t bufsize);
39376adaa34SWu Fengguang #endif
3943a818d35SVille Syrjälä
395ba34d58cSEzequiel Garcia bool drm_edid_are_equal(const struct edid *edid1, const struct edid *edid2);
396ba34d58cSEzequiel Garcia
397ac6c35a4SJani Nikula int
398ac6c35a4SJani Nikula drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
399ba34d58cSEzequiel Garcia const struct drm_connector *connector,
40076adaa34SWu Fengguang const struct drm_display_mode *mode);
401536faa45SStanislav Lisovskiy int
402536faa45SStanislav Lisovskiy drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame,
40310a85120SThierry Reding const struct drm_connector *connector,
40410a85120SThierry Reding const struct drm_display_mode *mode);
405192a3aa0SLaurent Pinchart
40613d0add3SVille Syrjälä void
40783dd0008SLespiau, Damien drm_hdmi_avi_infoframe_quant_range(struct hdmi_avi_infoframe *frame,
40883dd0008SLespiau, Damien const struct drm_connector *connector,
409192a3aa0SLaurent Pinchart const struct drm_display_mode *mode,
41083dd0008SLespiau, Damien enum hdmi_quantization_range rgb_quant_range);
4110d68b887SUma Shankar
4120d68b887SUma Shankar /**
413a2ce26f8SVille Syrjälä * drm_eld_mnl - Get ELD monitor name length in bytes.
414192a3aa0SLaurent Pinchart * @eld: pointer to an eld memory structure with mnl set
415779c4c28SVille Syrjälä */
drm_eld_mnl(const uint8_t * eld)4161581b2dfSVille Syrjälä static inline int drm_eld_mnl(const uint8_t *eld)
41710a85120SThierry Reding {
418babc9493SJani Nikula return (eld[DRM_ELD_CEA_EDID_VER_MNL] & DRM_ELD_MNL_MASK) >> DRM_ELD_MNL_SHIFT;
419babc9493SJani Nikula }
420babc9493SJani Nikula
421babc9493SJani Nikula /**
422babc9493SJani Nikula * drm_eld_sad - Get ELD SAD structures.
423babc9493SJani Nikula * @eld: pointer to an eld memory structure with sad_count set
424babc9493SJani Nikula */
drm_eld_sad(const uint8_t * eld)425babc9493SJani Nikula static inline const uint8_t *drm_eld_sad(const uint8_t *eld)
426babc9493SJani Nikula {
427babc9493SJani Nikula unsigned int ver, mnl;
4281c73d3b1SRussell King
4291c73d3b1SRussell King ver = (eld[DRM_ELD_VER] & DRM_ELD_VER_MASK) >> DRM_ELD_VER_SHIFT;
4301c73d3b1SRussell King if (ver != 2 && ver != 31)
4311c73d3b1SRussell King return NULL;
4321c73d3b1SRussell King
4331c73d3b1SRussell King mnl = drm_eld_mnl(eld);
4341c73d3b1SRussell King if (mnl > 16)
4351c73d3b1SRussell King return NULL;
4361c73d3b1SRussell King
4371c73d3b1SRussell King return eld + DRM_ELD_CEA_SAD(mnl, 0);
4381c73d3b1SRussell King }
4391c73d3b1SRussell King
4401c73d3b1SRussell King /**
4411c73d3b1SRussell King * drm_eld_sad_count - Get ELD SAD count.
4421c73d3b1SRussell King * @eld: pointer to an eld memory structure with sad_count set
4431c73d3b1SRussell King */
drm_eld_sad_count(const uint8_t * eld)4441c73d3b1SRussell King static inline int drm_eld_sad_count(const uint8_t *eld)
4451c73d3b1SRussell King {
4461c73d3b1SRussell King return (eld[DRM_ELD_SAD_COUNT_CONN_TYPE] & DRM_ELD_SAD_COUNT_MASK) >>
447babc9493SJani Nikula DRM_ELD_SAD_COUNT_SHIFT;
448babc9493SJani Nikula }
449babc9493SJani Nikula
450babc9493SJani Nikula /**
451babc9493SJani Nikula * drm_eld_calc_baseline_block_size - Calculate baseline block size in bytes
452babc9493SJani Nikula * @eld: pointer to an eld memory structure with mnl and sad_count set
453babc9493SJani Nikula *
454babc9493SJani Nikula * This is a helper for determining the payload size of the baseline block, in
455babc9493SJani Nikula * bytes, for e.g. setting the Baseline_ELD_Len field in the ELD header block.
456babc9493SJani Nikula */
drm_eld_calc_baseline_block_size(const uint8_t * eld)457babc9493SJani Nikula static inline int drm_eld_calc_baseline_block_size(const uint8_t *eld)
458babc9493SJani Nikula {
459babc9493SJani Nikula return DRM_ELD_MONITOR_NAME_STRING - DRM_ELD_HEADER_BLOCK_SIZE +
460babc9493SJani Nikula drm_eld_mnl(eld) + drm_eld_sad_count(eld) * 3;
461babc9493SJani Nikula }
462babc9493SJani Nikula
463babc9493SJani Nikula /**
464babc9493SJani Nikula * drm_eld_size - Get ELD size in bytes
465babc9493SJani Nikula * @eld: pointer to a complete eld memory structure
466babc9493SJani Nikula *
467babc9493SJani Nikula * The returned value does not include the vendor block. It's vendor specific,
468babc9493SJani Nikula * and comprises of the remaining bytes in the ELD memory buffer after
469babc9493SJani Nikula * drm_eld_size() bytes of header and baseline block.
470babc9493SJani Nikula *
471babc9493SJani Nikula * The returned value is guaranteed to be a multiple of 4.
472babc9493SJani Nikula */
drm_eld_size(const uint8_t * eld)473babc9493SJani Nikula static inline int drm_eld_size(const uint8_t *eld)
474babc9493SJani Nikula {
475babc9493SJani Nikula return DRM_ELD_HEADER_BLOCK_SIZE + eld[DRM_ELD_BASELINE_ELD_LEN] * 4;
476babc9493SJani Nikula }
477babc9493SJani Nikula
478babc9493SJani Nikula /**
479babc9493SJani Nikula * drm_eld_get_spk_alloc - Get speaker allocation
480babc9493SJani Nikula * @eld: pointer to an ELD memory structure
481babc9493SJani Nikula *
482babc9493SJani Nikula * The returned value is the speakers mask. User has to use %DRM_ELD_SPEAKER
483babc9493SJani Nikula * field definitions to identify speakers.
4841aa8ec25SSubhransu S. Prusty */
drm_eld_get_spk_alloc(const uint8_t * eld)485c82dbe5cSArnaud Pouliquen static inline u8 drm_eld_get_spk_alloc(const uint8_t *eld)
486c82dbe5cSArnaud Pouliquen {
487c82dbe5cSArnaud Pouliquen return eld[DRM_ELD_SPEAKER] & DRM_ELD_SPEAKER_MASK;
488c82dbe5cSArnaud Pouliquen }
489c82dbe5cSArnaud Pouliquen
490c82dbe5cSArnaud Pouliquen /**
491c82dbe5cSArnaud Pouliquen * drm_eld_get_conn_type - Get device type hdmi/dp connected
492c82dbe5cSArnaud Pouliquen * @eld: pointer to an ELD memory structure
493c82dbe5cSArnaud Pouliquen *
494c82dbe5cSArnaud Pouliquen * The caller need to use %DRM_ELD_CONN_TYPE_HDMI or %DRM_ELD_CONN_TYPE_DP to
495c82dbe5cSArnaud Pouliquen * identify the display type connected.
496c82dbe5cSArnaud Pouliquen */
drm_eld_get_conn_type(const uint8_t * eld)4971aa8ec25SSubhransu S. Prusty static inline u8 drm_eld_get_conn_type(const uint8_t *eld)
4981aa8ec25SSubhransu S. Prusty {
4991aa8ec25SSubhransu S. Prusty return eld[DRM_ELD_SAD_COUNT_CONN_TYPE] & DRM_ELD_CONN_TYPE_MASK;
5001aa8ec25SSubhransu S. Prusty }
5011aa8ec25SSubhransu S. Prusty
5021aa8ec25SSubhransu S. Prusty /**
5031aa8ec25SSubhransu S. Prusty * drm_edid_decode_mfg_id - Decode the manufacturer ID
5041aa8ec25SSubhransu S. Prusty * @mfg_id: The manufacturer ID
5051aa8ec25SSubhransu S. Prusty * @vend: A 4-byte buffer to store the 3-letter vendor string plus a '\0'
5061aa8ec25SSubhransu S. Prusty * termination
5071aa8ec25SSubhransu S. Prusty */
drm_edid_decode_mfg_id(u16 mfg_id,char vend[4])508d9f91a10SDouglas Anderson static inline const char *drm_edid_decode_mfg_id(u16 mfg_id, char vend[4])
509ade1fc91SVille Syrjälä {
510ade1fc91SVille Syrjälä vend[0] = '@' + ((mfg_id >> 10) & 0x1f);
511ade1fc91SVille Syrjälä vend[1] = '@' + ((mfg_id >> 5) & 0x1f);
512ade1fc91SVille Syrjälä vend[2] = '@' + ((mfg_id >> 0) & 0x1f);
513ade1fc91SVille Syrjälä vend[3] = '\0';
514ade1fc91SVille Syrjälä
515ade1fc91SVille Syrjälä return vend;
516ade1fc91SVille Syrjälä }
517ade1fc91SVille Syrjälä
518ade1fc91SVille Syrjälä /**
519ade1fc91SVille Syrjälä * drm_edid_encode_panel_id - Encode an ID for matching against drm_edid_get_panel_id()
520ade1fc91SVille Syrjälä * @vend_chr_0: First character of the vendor string.
521ade1fc91SVille Syrjälä * @vend_chr_1: Second character of the vendor string.
522ade1fc91SVille Syrjälä * @vend_chr_2: Third character of the vendor string.
523ade1fc91SVille Syrjälä * @product_id: The 16-bit product ID.
524ade1fc91SVille Syrjälä *
525d9f91a10SDouglas Anderson * This is a macro so that it can be calculated at compile time and used
5267d1be0a0SDouglas Anderson * as an initializer.
527116e5947SDouglas Anderson *
528116e5947SDouglas Anderson * For instance:
529d9f91a10SDouglas Anderson * drm_edid_encode_panel_id('B', 'O', 'E', 0x2d08) => 0x09e52d08
530d9f91a10SDouglas Anderson *
531d9f91a10SDouglas Anderson * Return: a 32-bit ID per panel.
532d9f91a10SDouglas Anderson */
533d9f91a10SDouglas Anderson #define drm_edid_encode_panel_id(vend_chr_0, vend_chr_1, vend_chr_2, product_id) \
534d9f91a10SDouglas Anderson ((((u32)(vend_chr_0) - '@') & 0x1f) << 26 | \
5357d1be0a0SDouglas Anderson (((u32)(vend_chr_1) - '@') & 0x1f) << 21 | \
536d9f91a10SDouglas Anderson (((u32)(vend_chr_2) - '@') & 0x1f) << 16 | \
537d9f91a10SDouglas Anderson ((product_id) & 0xffff))
538d9f91a10SDouglas Anderson
5397d1be0a0SDouglas Anderson /**
5407d1be0a0SDouglas Anderson * drm_edid_decode_panel_id - Decode a panel ID from drm_edid_encode_panel_id()
5417d1be0a0SDouglas Anderson * @panel_id: The panel ID to decode.
5427d1be0a0SDouglas Anderson * @vend: A 4-byte buffer to store the 3-letter vendor string plus a '\0'
543d9f91a10SDouglas Anderson * termination
544d9f91a10SDouglas Anderson * @product_id: The product ID will be returned here.
545d9f91a10SDouglas Anderson *
546d9f91a10SDouglas Anderson * For instance, after:
547d9f91a10SDouglas Anderson * drm_edid_decode_panel_id(0x09e52d08, vend, &product_id)
548d9f91a10SDouglas Anderson * These will be true:
549d9f91a10SDouglas Anderson * vend[0] = 'B'
550d9f91a10SDouglas Anderson * vend[1] = 'O'
551d9f91a10SDouglas Anderson * vend[2] = 'E'
552d9f91a10SDouglas Anderson * vend[3] = '\0'
553d9f91a10SDouglas Anderson * product_id = 0x2d08
554d9f91a10SDouglas Anderson */
drm_edid_decode_panel_id(u32 panel_id,char vend[4],u16 * product_id)555d9f91a10SDouglas Anderson static inline void drm_edid_decode_panel_id(u32 panel_id, char vend[4], u16 *product_id)
556d9f91a10SDouglas Anderson {
557d9f91a10SDouglas Anderson *product_id = (u16)(panel_id & 0xffff);
558d9f91a10SDouglas Anderson drm_edid_decode_mfg_id(panel_id >> 16, vend);
559d9f91a10SDouglas Anderson }
560d9f91a10SDouglas Anderson
561d9f91a10SDouglas Anderson bool drm_probe_ddc(struct i2c_adapter *adapter);
562d9f91a10SDouglas Anderson struct edid *drm_do_get_edid(struct drm_connector *connector,
563d9f91a10SDouglas Anderson int (*get_edid_block)(void *data, u8 *buf, unsigned int block,
564ade1fc91SVille Syrjälä size_t len),
565d9f91a10SDouglas Anderson void *data);
566d9f91a10SDouglas Anderson struct edid *drm_get_edid(struct drm_connector *connector,
567cdc3d09fSDaniel Vetter struct i2c_adapter *adapter);
56818df89feSLars-Peter Clausen u32 drm_edid_get_panel_id(struct i2c_adapter *adapter);
56918df89feSLars-Peter Clausen struct edid *drm_get_edid_switcheroo(struct drm_connector *connector,
57018df89feSLars-Peter Clausen struct i2c_adapter *adapter);
57118df89feSLars-Peter Clausen struct edid *drm_edid_duplicate(const struct edid *edid);
572cdc3d09fSDaniel Vetter int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid);
573cdc3d09fSDaniel Vetter int drm_edid_override_connector_update(struct drm_connector *connector);
574d9f91a10SDouglas Anderson
575cdc3d09fSDaniel Vetter u8 drm_match_cea_mode(const struct drm_display_mode *to_match);
576cdc3d09fSDaniel Vetter bool drm_detect_hdmi_monitor(const struct edid *edid);
577cdc3d09fSDaniel Vetter bool drm_detect_monitor_audio(const struct edid *edid);
578cdc3d09fSDaniel Vetter enum hdmi_quantization_range
579019b9387SJani Nikula drm_default_rgb_quant_range(const struct drm_display_mode *mode);
580cdc3d09fSDaniel Vetter int drm_add_modes_noedid(struct drm_connector *connector,
581cdc3d09fSDaniel Vetter int hdisplay, int vdisplay);
582f4e558ecSJani Nikula void drm_set_preferred_mode(struct drm_connector *connector,
583f4e558ecSJani Nikula int hpref, int vpref);
584c8127cf0SVille Syrjälä
585c8127cf0SVille Syrjälä int drm_edid_header_is_valid(const void *edid);
586cdc3d09fSDaniel Vetter bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid,
587cdc3d09fSDaniel Vetter bool *edid_corrupt);
588cdc3d09fSDaniel Vetter bool drm_edid_is_valid(struct edid *edid);
589cdc3d09fSDaniel Vetter void drm_edid_get_monitor_name(const struct edid *edid, char *name,
590cdc3d09fSDaniel Vetter int buflen);
5916d987dddSJani Nikula struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev,
592cdc3d09fSDaniel Vetter int hsize, int vsize, int fresh,
593cdc3d09fSDaniel Vetter bool rb);
594cdc3d09fSDaniel Vetter struct drm_display_mode *
595f4e558ecSJani Nikula drm_display_mode_from_cea_vic(struct drm_device *dev,
596cdc3d09fSDaniel Vetter u8 video_code);
597cdc3d09fSDaniel Vetter
598cdc3d09fSDaniel Vetter /* Interface based on struct drm_edid */
599cdc3d09fSDaniel Vetter const struct drm_edid *drm_edid_alloc(const void *edid, size_t size);
6007af655bcSVille Syrjälä const struct drm_edid *drm_edid_dup(const struct drm_edid *drm_edid);
6017af655bcSVille Syrjälä void drm_edid_free(const struct drm_edid *drm_edid);
6027af655bcSVille Syrjälä bool drm_edid_valid(const struct drm_edid *drm_edid);
6034cc4f09eSJani Nikula const struct edid *drm_edid_raw(const struct drm_edid *drm_edid);
604d9ba1b4cSJani Nikula const struct drm_edid *drm_edid_read(struct drm_connector *connector);
6056537f79aSJani Nikula const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector,
6066537f79aSJani Nikula struct i2c_adapter *adapter);
6076537f79aSJani Nikula const struct drm_edid *drm_edid_read_custom(struct drm_connector *connector,
6086c9b3db7SJani Nikula int (*read_block)(void *context, u8 *buf, unsigned int block, size_t len),
6093d1ab66eSJani Nikula void *context);
6106537f79aSJani Nikula const struct drm_edid *drm_edid_read_switcheroo(struct drm_connector *connector,
6116537f79aSJani Nikula struct i2c_adapter *adapter);
6126537f79aSJani Nikula int drm_edid_connector_update(struct drm_connector *connector,
6136537f79aSJani Nikula const struct drm_edid *edid);
6146537f79aSJani Nikula int drm_edid_connector_add_modes(struct drm_connector *connector);
6156537f79aSJani Nikula
616b71c0aaaSJani Nikula const u8 *drm_find_edid_extension(const struct drm_edid *drm_edid,
617b71c0aaaSJani Nikula int ext_id, int *ext_index);
618c533b516SJani Nikula
619c533b516SJani Nikula #endif /* __DRM_EDID_H__ */
620d9ba1b4cSJani Nikula