xref: /aosp_15_r20/external/edid-decode/edid-decode.h (revision 193032a37cc83cffc1526215991f3c21671f4245)
1*193032a3SAndroid Build Coastguard Worker // SPDX-License-Identifier: MIT
2*193032a3SAndroid Build Coastguard Worker /*
3*193032a3SAndroid Build Coastguard Worker  * Copyright 2006-2012 Red Hat, Inc.
4*193032a3SAndroid Build Coastguard Worker  * Copyright 2018-2020 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
5*193032a3SAndroid Build Coastguard Worker  *
6*193032a3SAndroid Build Coastguard Worker  * Author: Adam Jackson <[email protected]>
7*193032a3SAndroid Build Coastguard Worker  * Maintainer: Hans Verkuil <[email protected]>
8*193032a3SAndroid Build Coastguard Worker  */
9*193032a3SAndroid Build Coastguard Worker 
10*193032a3SAndroid Build Coastguard Worker #ifndef __EDID_DECODE_H_
11*193032a3SAndroid Build Coastguard Worker #define __EDID_DECODE_H_
12*193032a3SAndroid Build Coastguard Worker 
13*193032a3SAndroid Build Coastguard Worker #include <string>
14*193032a3SAndroid Build Coastguard Worker #include <vector>
15*193032a3SAndroid Build Coastguard Worker #include <set>
16*193032a3SAndroid Build Coastguard Worker #include <string.h>
17*193032a3SAndroid Build Coastguard Worker 
18*193032a3SAndroid Build Coastguard Worker #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
19*193032a3SAndroid Build Coastguard Worker #define min(a, b) ((a) < (b) ? (a) : (b))
20*193032a3SAndroid Build Coastguard Worker #define max(a, b) ((a) > (b) ? (a) : (b))
21*193032a3SAndroid Build Coastguard Worker 
22*193032a3SAndroid Build Coastguard Worker #define EDID_PAGE_SIZE 128U
23*193032a3SAndroid Build Coastguard Worker #define EDID_MAX_BLOCKS 256U
24*193032a3SAndroid Build Coastguard Worker 
25*193032a3SAndroid Build Coastguard Worker #define RB_ALT		(1U << 7)
26*193032a3SAndroid Build Coastguard Worker 
27*193032a3SAndroid Build Coastguard Worker #define RB_NONE		(0U)
28*193032a3SAndroid Build Coastguard Worker #define RB_CVT_V1	(1U)
29*193032a3SAndroid Build Coastguard Worker #define RB_CVT_V2	(2U)
30*193032a3SAndroid Build Coastguard Worker #define RB_CVT_V3	(3U)
31*193032a3SAndroid Build Coastguard Worker #define RB_GTF		(4U)
32*193032a3SAndroid Build Coastguard Worker 
33*193032a3SAndroid Build Coastguard Worker // Video Timings
34*193032a3SAndroid Build Coastguard Worker // If interlaced is true, then the vertical blanking
35*193032a3SAndroid Build Coastguard Worker // for each field is (vfp + vsync + vbp + 0.5), except for
36*193032a3SAndroid Build Coastguard Worker // the VIC 39 timings that doesn't have the 0.5 constant.
37*193032a3SAndroid Build Coastguard Worker //
38*193032a3SAndroid Build Coastguard Worker // The sequence of the various video parameters is as follows:
39*193032a3SAndroid Build Coastguard Worker //
40*193032a3SAndroid Build Coastguard Worker // border - front porch - sync - back porch - border - active video
41*193032a3SAndroid Build Coastguard Worker //
42*193032a3SAndroid Build Coastguard Worker // Note: this is slightly different from EDID 1.4 which calls
43*193032a3SAndroid Build Coastguard Worker // 'active video' as 'addressable video' and the EDID 1.4 term
44*193032a3SAndroid Build Coastguard Worker // 'active video' includes the borders.
45*193032a3SAndroid Build Coastguard Worker //
46*193032a3SAndroid Build Coastguard Worker // But since borders are rarely used, the term 'active video' will
47*193032a3SAndroid Build Coastguard Worker // typically be the same as 'addressable video', and that's how I
48*193032a3SAndroid Build Coastguard Worker // use it.
49*193032a3SAndroid Build Coastguard Worker struct timings {
50*193032a3SAndroid Build Coastguard Worker 	// Active horizontal and vertical frame height, excluding any
51*193032a3SAndroid Build Coastguard Worker 	// borders, if present.
52*193032a3SAndroid Build Coastguard Worker 	// Note: for interlaced formats the active field height is vact / 2
53*193032a3SAndroid Build Coastguard Worker 	unsigned hact, vact;
54*193032a3SAndroid Build Coastguard Worker 	unsigned hratio, vratio;
55*193032a3SAndroid Build Coastguard Worker 	unsigned pixclk_khz;
56*193032a3SAndroid Build Coastguard Worker 	// 0: no reduced blanking
57*193032a3SAndroid Build Coastguard Worker 	// 1: CVT reduced blanking version 1
58*193032a3SAndroid Build Coastguard Worker 	// 2: CVT reduced blanking version 2
59*193032a3SAndroid Build Coastguard Worker 	// 2 | RB_ALT: CVT reduced blanking version 2 video-optimized (1000/1001 fps)
60*193032a3SAndroid Build Coastguard Worker 	// 3: CVT reduced blanking version 3
61*193032a3SAndroid Build Coastguard Worker 	// 3 | RB_ALT: v3 with a horizontal blank of 160
62*193032a3SAndroid Build Coastguard Worker 	// 4: GTF Secondary Curve
63*193032a3SAndroid Build Coastguard Worker 	unsigned rb;
64*193032a3SAndroid Build Coastguard Worker 	bool interlaced;
65*193032a3SAndroid Build Coastguard Worker 	// The horizontal frontporch may be negative in GTF calculations,
66*193032a3SAndroid Build Coastguard Worker 	// so use int instead of unsigned for hfp. Example: 292x176@76.
67*193032a3SAndroid Build Coastguard Worker 	int hfp;
68*193032a3SAndroid Build Coastguard Worker 	unsigned hsync;
69*193032a3SAndroid Build Coastguard Worker 	// The backporch may be negative in buggy detailed timings.
70*193032a3SAndroid Build Coastguard Worker 	// So use int instead of unsigned for hbp and vbp.
71*193032a3SAndroid Build Coastguard Worker 	int hbp;
72*193032a3SAndroid Build Coastguard Worker 	bool pos_pol_hsync;
73*193032a3SAndroid Build Coastguard Worker 	// For interlaced formats the vertical front porch of the Even Field
74*193032a3SAndroid Build Coastguard Worker 	// is actually a half-line longer.
75*193032a3SAndroid Build Coastguard Worker 	unsigned vfp, vsync;
76*193032a3SAndroid Build Coastguard Worker 	// For interlaced formats the vertical back porch of the Odd Field
77*193032a3SAndroid Build Coastguard Worker 	// is actually a half-line longer.
78*193032a3SAndroid Build Coastguard Worker 	int vbp;
79*193032a3SAndroid Build Coastguard Worker 	bool pos_pol_vsync;
80*193032a3SAndroid Build Coastguard Worker 	unsigned hborder, vborder;
81*193032a3SAndroid Build Coastguard Worker 	bool even_vtotal; // special for VIC 39
82*193032a3SAndroid Build Coastguard Worker 	bool no_pol_vsync; // digital composite signals have no vsync polarity
83*193032a3SAndroid Build Coastguard Worker 	unsigned hsize_mm, vsize_mm;
84*193032a3SAndroid Build Coastguard Worker 	bool ycbcr420; // YCbCr 4:2:0 encoding
85*193032a3SAndroid Build Coastguard Worker };
86*193032a3SAndroid Build Coastguard Worker 
87*193032a3SAndroid Build Coastguard Worker struct timings_ext {
timings_exttimings_ext88*193032a3SAndroid Build Coastguard Worker 	timings_ext()
89*193032a3SAndroid Build Coastguard Worker 	{
90*193032a3SAndroid Build Coastguard Worker 		memset(&t, 0, sizeof(t));
91*193032a3SAndroid Build Coastguard Worker 	}
timings_exttimings_ext92*193032a3SAndroid Build Coastguard Worker 	timings_ext(unsigned svr, const std::string &_type)
93*193032a3SAndroid Build Coastguard Worker 	{
94*193032a3SAndroid Build Coastguard Worker 		memset(&t, 0, sizeof(t));
95*193032a3SAndroid Build Coastguard Worker 		t.hact = svr;
96*193032a3SAndroid Build Coastguard Worker 		type = _type;
97*193032a3SAndroid Build Coastguard Worker 	}
timings_exttimings_ext98*193032a3SAndroid Build Coastguard Worker 	timings_ext(const timings &_t, const std::string &_type, const std::string &_flags)
99*193032a3SAndroid Build Coastguard Worker 	{
100*193032a3SAndroid Build Coastguard Worker 		t = _t;
101*193032a3SAndroid Build Coastguard Worker 		type = _type;
102*193032a3SAndroid Build Coastguard Worker 		flags = _flags;
103*193032a3SAndroid Build Coastguard Worker 	}
104*193032a3SAndroid Build Coastguard Worker 
is_validtimings_ext105*193032a3SAndroid Build Coastguard Worker 	bool is_valid() const { return t.hact; }
has_svrtimings_ext106*193032a3SAndroid Build Coastguard Worker 	bool has_svr() const { return t.hact && !t.vact; }
svrtimings_ext107*193032a3SAndroid Build Coastguard Worker 	unsigned svr() const { return t.hact; }
108*193032a3SAndroid Build Coastguard Worker 	timings t;
109*193032a3SAndroid Build Coastguard Worker 	std::string type;
110*193032a3SAndroid Build Coastguard Worker 	std::string flags;
111*193032a3SAndroid Build Coastguard Worker };
112*193032a3SAndroid Build Coastguard Worker 
113*193032a3SAndroid Build Coastguard Worker enum gtf_ip_parm {
114*193032a3SAndroid Build Coastguard Worker 	gtf_ip_vert_freq = 1,
115*193032a3SAndroid Build Coastguard Worker 	gtf_ip_hor_freq,
116*193032a3SAndroid Build Coastguard Worker 	gtf_ip_clk_freq,
117*193032a3SAndroid Build Coastguard Worker };
118*193032a3SAndroid Build Coastguard Worker 
119*193032a3SAndroid Build Coastguard Worker typedef std::vector<timings_ext> vec_timings_ext;
120*193032a3SAndroid Build Coastguard Worker 
121*193032a3SAndroid Build Coastguard Worker struct edid_state {
edid_stateedid_state122*193032a3SAndroid Build Coastguard Worker 	edid_state()
123*193032a3SAndroid Build Coastguard Worker 	{
124*193032a3SAndroid Build Coastguard Worker 		// Global state
125*193032a3SAndroid Build Coastguard Worker 		edid_size = num_blocks = block_nr = 0;
126*193032a3SAndroid Build Coastguard Worker 		max_hor_freq_hz = max_vert_freq_hz = max_pixclk_khz = 0;
127*193032a3SAndroid Build Coastguard Worker 		min_hor_freq_hz = 0xffffff;
128*193032a3SAndroid Build Coastguard Worker 		min_vert_freq_hz = 0xffffffff;
129*193032a3SAndroid Build Coastguard Worker 		dtd_max_vsize_mm = dtd_max_hsize_mm = 0;
130*193032a3SAndroid Build Coastguard Worker 		warnings = failures = 0;
131*193032a3SAndroid Build Coastguard Worker 		has_cta = has_dispid = false;
132*193032a3SAndroid Build Coastguard Worker 		hide_serial_numbers = false;
133*193032a3SAndroid Build Coastguard Worker 
134*193032a3SAndroid Build Coastguard Worker 		// Base block state
135*193032a3SAndroid Build Coastguard Worker 		base.edid_minor = 0;
136*193032a3SAndroid Build Coastguard Worker 		base.has_name_descriptor = base.has_display_range_descriptor =
137*193032a3SAndroid Build Coastguard Worker 			base.has_serial_number = base.has_serial_string =
138*193032a3SAndroid Build Coastguard Worker 			base.supports_continuous_freq = base.supports_gtf =
139*193032a3SAndroid Build Coastguard Worker 			base.supports_cvt = base.seen_non_detailed_descriptor =
140*193032a3SAndroid Build Coastguard Worker 			base.has_640x480p60_est_timing = base.has_spwg =
141*193032a3SAndroid Build Coastguard Worker 			base.preferred_is_also_native = false;
142*193032a3SAndroid Build Coastguard Worker 		base.supports_sec_gtf = false;
143*193032a3SAndroid Build Coastguard Worker 		base.sec_gtf_start_freq = 0;
144*193032a3SAndroid Build Coastguard Worker 		base.C = base.M = base.K = base.J = 0;
145*193032a3SAndroid Build Coastguard Worker 		base.max_pos_neg_hor_freq_khz = 0;
146*193032a3SAndroid Build Coastguard Worker 		base.detailed_block_cnt = base.dtd_cnt = 0;
147*193032a3SAndroid Build Coastguard Worker 
148*193032a3SAndroid Build Coastguard Worker 		base.min_display_hor_freq_hz = base.max_display_hor_freq_hz =
149*193032a3SAndroid Build Coastguard Worker 			base.min_display_vert_freq_hz = base.max_display_vert_freq_hz =
150*193032a3SAndroid Build Coastguard Worker 			base.max_display_pixclk_khz = base.max_display_width_mm =
151*193032a3SAndroid Build Coastguard Worker 			base.max_display_height_mm = 0;
152*193032a3SAndroid Build Coastguard Worker 
153*193032a3SAndroid Build Coastguard Worker 		// CTA-861 block state
154*193032a3SAndroid Build Coastguard Worker 		cta.has_vic_1 = cta.first_svd_might_be_preferred = cta.has_sldb =
155*193032a3SAndroid Build Coastguard Worker 			cta.has_hdmi = cta.has_vcdb = cta.has_vfpdb = false;
156*193032a3SAndroid Build Coastguard Worker 		cta.last_block_was_hdmi_vsdb = cta.have_hf_vsdb = cta.have_hf_scdb = false;
157*193032a3SAndroid Build Coastguard Worker 		cta.first_block = cta.first_svd = true;
158*193032a3SAndroid Build Coastguard Worker 		cta.supported_hdmi_vic_codes = cta.supported_hdmi_vic_vsb_codes = 0;
159*193032a3SAndroid Build Coastguard Worker 		memset(cta.vics, 0, sizeof(cta.vics));
160*193032a3SAndroid Build Coastguard Worker 		memset(cta.preparsed_has_vic, 0, sizeof(cta.preparsed_has_vic));
161*193032a3SAndroid Build Coastguard Worker 		cta.preparsed_phys_addr = 0xffff;
162*193032a3SAndroid Build Coastguard Worker 		cta.preparsed_speaker_count = 0;
163*193032a3SAndroid Build Coastguard Worker 		cta.preparsed_sld = false;
164*193032a3SAndroid Build Coastguard Worker 		cta.preparsed_sld_has_coord = false;
165*193032a3SAndroid Build Coastguard Worker 		cta.preparsed_total_dtds = 0;
166*193032a3SAndroid Build Coastguard Worker 		cta.preparsed_total_vtdbs = 0;
167*193032a3SAndroid Build Coastguard Worker 		cta.preparsed_has_t8vtdb = false;
168*193032a3SAndroid Build Coastguard Worker 
169*193032a3SAndroid Build Coastguard Worker 		// DisplayID block state
170*193032a3SAndroid Build Coastguard Worker 		dispid.version = 0;
171*193032a3SAndroid Build Coastguard Worker 		dispid.native_width = dispid.native_height = 0;
172*193032a3SAndroid Build Coastguard Worker 		dispid.preparsed_color_ids = dispid.preparsed_xfer_ids = 0;
173*193032a3SAndroid Build Coastguard Worker 		dispid.preparsed_displayid_blocks = 0;
174*193032a3SAndroid Build Coastguard Worker 		dispid.is_base_block = true;
175*193032a3SAndroid Build Coastguard Worker 		dispid.is_display = dispid.has_product_identification =
176*193032a3SAndroid Build Coastguard Worker 			dispid.has_display_parameters = dispid.has_type_1_7 =
177*193032a3SAndroid Build Coastguard Worker 			dispid.has_display_interface_features = false;
178*193032a3SAndroid Build Coastguard Worker 
179*193032a3SAndroid Build Coastguard Worker 		// Block Map block state
180*193032a3SAndroid Build Coastguard Worker 		block_map.saw_block_1 = false;
181*193032a3SAndroid Build Coastguard Worker 		block_map.saw_block_128 = false;
182*193032a3SAndroid Build Coastguard Worker 	}
183*193032a3SAndroid Build Coastguard Worker 
184*193032a3SAndroid Build Coastguard Worker 	// Global state
185*193032a3SAndroid Build Coastguard Worker 	unsigned edid_size;
186*193032a3SAndroid Build Coastguard Worker 	unsigned num_blocks;
187*193032a3SAndroid Build Coastguard Worker 	unsigned block_nr;
188*193032a3SAndroid Build Coastguard Worker 	std::string block;
189*193032a3SAndroid Build Coastguard Worker 	std::string data_block;
190*193032a3SAndroid Build Coastguard Worker 	bool has_cta;
191*193032a3SAndroid Build Coastguard Worker 	bool has_dispid;
192*193032a3SAndroid Build Coastguard Worker 	bool hide_serial_numbers;
193*193032a3SAndroid Build Coastguard Worker 
194*193032a3SAndroid Build Coastguard Worker 	unsigned min_hor_freq_hz;
195*193032a3SAndroid Build Coastguard Worker 	unsigned max_hor_freq_hz;
196*193032a3SAndroid Build Coastguard Worker 	double min_vert_freq_hz;
197*193032a3SAndroid Build Coastguard Worker 	double max_vert_freq_hz;
198*193032a3SAndroid Build Coastguard Worker 	unsigned max_pixclk_khz;
199*193032a3SAndroid Build Coastguard Worker 	unsigned dtd_max_hsize_mm;
200*193032a3SAndroid Build Coastguard Worker 	unsigned dtd_max_vsize_mm;
201*193032a3SAndroid Build Coastguard Worker 
202*193032a3SAndroid Build Coastguard Worker 	unsigned warnings;
203*193032a3SAndroid Build Coastguard Worker 	unsigned failures;
204*193032a3SAndroid Build Coastguard Worker 
205*193032a3SAndroid Build Coastguard Worker 	// Base block state
206*193032a3SAndroid Build Coastguard Worker 	struct {
207*193032a3SAndroid Build Coastguard Worker 		unsigned edid_minor;
208*193032a3SAndroid Build Coastguard Worker 		bool has_name_descriptor;
209*193032a3SAndroid Build Coastguard Worker 		bool has_display_range_descriptor;
210*193032a3SAndroid Build Coastguard Worker 		bool has_serial_number;
211*193032a3SAndroid Build Coastguard Worker 		bool has_serial_string;
212*193032a3SAndroid Build Coastguard Worker 		bool supports_continuous_freq;
213*193032a3SAndroid Build Coastguard Worker 		bool supports_gtf;
214*193032a3SAndroid Build Coastguard Worker 		bool supports_sec_gtf;
215*193032a3SAndroid Build Coastguard Worker 		unsigned sec_gtf_start_freq;
216*193032a3SAndroid Build Coastguard Worker 		double C, M, K, J;
217*193032a3SAndroid Build Coastguard Worker 		bool supports_cvt;
218*193032a3SAndroid Build Coastguard Worker 		bool has_spwg;
219*193032a3SAndroid Build Coastguard Worker 		unsigned detailed_block_cnt;
220*193032a3SAndroid Build Coastguard Worker 		unsigned dtd_cnt;
221*193032a3SAndroid Build Coastguard Worker 		bool seen_non_detailed_descriptor;
222*193032a3SAndroid Build Coastguard Worker 		bool has_640x480p60_est_timing;
223*193032a3SAndroid Build Coastguard Worker 		bool preferred_is_also_native;
224*193032a3SAndroid Build Coastguard Worker 		timings_ext preferred_timing;
225*193032a3SAndroid Build Coastguard Worker 
226*193032a3SAndroid Build Coastguard Worker 		unsigned min_display_hor_freq_hz;
227*193032a3SAndroid Build Coastguard Worker 		unsigned max_display_hor_freq_hz;
228*193032a3SAndroid Build Coastguard Worker 		unsigned min_display_vert_freq_hz;
229*193032a3SAndroid Build Coastguard Worker 		unsigned max_display_vert_freq_hz;
230*193032a3SAndroid Build Coastguard Worker 		unsigned max_display_pixclk_khz;
231*193032a3SAndroid Build Coastguard Worker 		unsigned max_display_width_mm;
232*193032a3SAndroid Build Coastguard Worker 		unsigned max_display_height_mm;
233*193032a3SAndroid Build Coastguard Worker 		unsigned max_pos_neg_hor_freq_khz;
234*193032a3SAndroid Build Coastguard Worker 	} base;
235*193032a3SAndroid Build Coastguard Worker 
236*193032a3SAndroid Build Coastguard Worker 	// CTA-861 block state
237*193032a3SAndroid Build Coastguard Worker 	struct {
238*193032a3SAndroid Build Coastguard Worker 		unsigned preparsed_total_dtds;
239*193032a3SAndroid Build Coastguard Worker 		vec_timings_ext vec_dtds;
240*193032a3SAndroid Build Coastguard Worker 		unsigned preparsed_total_vtdbs;
241*193032a3SAndroid Build Coastguard Worker 		vec_timings_ext vec_vtdbs;
242*193032a3SAndroid Build Coastguard Worker 		vec_timings_ext preferred_timings;
243*193032a3SAndroid Build Coastguard Worker 		bool preparsed_has_t8vtdb;
244*193032a3SAndroid Build Coastguard Worker 		// Keep track of the found Tag/Extended Tag pairs.
245*193032a3SAndroid Build Coastguard Worker 		// The unsigned value is equal to: (tag << 8) | ext_tag
246*193032a3SAndroid Build Coastguard Worker 		std::set<unsigned> found_tags;
247*193032a3SAndroid Build Coastguard Worker 		timings_ext t8vtdb;
248*193032a3SAndroid Build Coastguard Worker 		vec_timings_ext native_timings;
249*193032a3SAndroid Build Coastguard Worker 		bool has_vic_1;
250*193032a3SAndroid Build Coastguard Worker 		bool first_svd_might_be_preferred;
251*193032a3SAndroid Build Coastguard Worker 		unsigned char byte3;
252*193032a3SAndroid Build Coastguard Worker 		bool has_hdmi;
253*193032a3SAndroid Build Coastguard Worker 		bool has_vcdb;
254*193032a3SAndroid Build Coastguard Worker 		bool has_vfpdb;
255*193032a3SAndroid Build Coastguard Worker 		unsigned preparsed_speaker_count;
256*193032a3SAndroid Build Coastguard Worker 		bool preparsed_sld_has_coord;
257*193032a3SAndroid Build Coastguard Worker 		bool preparsed_sld;
258*193032a3SAndroid Build Coastguard Worker 		bool has_sldb;
259*193032a3SAndroid Build Coastguard Worker 		unsigned short preparsed_phys_addr;
260*193032a3SAndroid Build Coastguard Worker 		bool last_block_was_hdmi_vsdb;
261*193032a3SAndroid Build Coastguard Worker 		bool have_hf_vsdb, have_hf_scdb;
262*193032a3SAndroid Build Coastguard Worker 		bool first_block;
263*193032a3SAndroid Build Coastguard Worker 		bool first_svd;
264*193032a3SAndroid Build Coastguard Worker 		unsigned supported_hdmi_vic_codes;
265*193032a3SAndroid Build Coastguard Worker 		unsigned supported_hdmi_vic_vsb_codes;
266*193032a3SAndroid Build Coastguard Worker 		unsigned short vics[256][2];
267*193032a3SAndroid Build Coastguard Worker 		bool preparsed_has_vic[2][256];
268*193032a3SAndroid Build Coastguard Worker 		std::vector<unsigned char> preparsed_svds[2];
269*193032a3SAndroid Build Coastguard Worker 	} cta;
270*193032a3SAndroid Build Coastguard Worker 
271*193032a3SAndroid Build Coastguard Worker 	// DisplayID block state
272*193032a3SAndroid Build Coastguard Worker 	struct {
273*193032a3SAndroid Build Coastguard Worker 		unsigned char version;
274*193032a3SAndroid Build Coastguard Worker 		unsigned short preparsed_color_ids;
275*193032a3SAndroid Build Coastguard Worker 		unsigned short preparsed_xfer_ids;
276*193032a3SAndroid Build Coastguard Worker 		unsigned preparsed_displayid_blocks;
277*193032a3SAndroid Build Coastguard Worker 		bool is_base_block;
278*193032a3SAndroid Build Coastguard Worker 		bool is_display;
279*193032a3SAndroid Build Coastguard Worker 		bool has_product_identification;
280*193032a3SAndroid Build Coastguard Worker 		bool has_display_parameters;
281*193032a3SAndroid Build Coastguard Worker 		bool has_type_1_7;
282*193032a3SAndroid Build Coastguard Worker 		bool has_display_interface_features;
283*193032a3SAndroid Build Coastguard Worker 		vec_timings_ext preferred_timings;
284*193032a3SAndroid Build Coastguard Worker 		unsigned native_width, native_height;
285*193032a3SAndroid Build Coastguard Worker 		// Keep track of the found CTA-861 Tag/Extended Tag pairs.
286*193032a3SAndroid Build Coastguard Worker 		// The unsigned value is equal to: (tag << 8) | ext_tag
287*193032a3SAndroid Build Coastguard Worker 		std::set<unsigned> found_tags;
288*193032a3SAndroid Build Coastguard Worker 	} dispid;
289*193032a3SAndroid Build Coastguard Worker 
290*193032a3SAndroid Build Coastguard Worker 	// Block Map block state
291*193032a3SAndroid Build Coastguard Worker 	struct {
292*193032a3SAndroid Build Coastguard Worker 		bool saw_block_1;
293*193032a3SAndroid Build Coastguard Worker 		bool saw_block_128;
294*193032a3SAndroid Build Coastguard Worker 	} block_map;
295*193032a3SAndroid Build Coastguard Worker 
296*193032a3SAndroid Build Coastguard Worker 	std::string dtd_type(unsigned dtd);
dtd_typeedid_state297*193032a3SAndroid Build Coastguard Worker 	std::string dtd_type() { return dtd_type(base.dtd_cnt); }
298*193032a3SAndroid Build Coastguard Worker 	bool print_timings(const char *prefix, const struct timings *t,
299*193032a3SAndroid Build Coastguard Worker 			   const char *type, const char *flags = "",
300*193032a3SAndroid Build Coastguard Worker 			   bool detailed = false, bool do_checks = true);
301*193032a3SAndroid Build Coastguard Worker 	bool print_timings(const char *prefix, const struct timings_ext &t,
302*193032a3SAndroid Build Coastguard Worker 			   bool detailed = false, bool do_checks = true)
303*193032a3SAndroid Build Coastguard Worker 	{
304*193032a3SAndroid Build Coastguard Worker 		return print_timings(prefix, &t.t, t.type.c_str(), t.flags.c_str(),
305*193032a3SAndroid Build Coastguard Worker 				     detailed, do_checks);
306*193032a3SAndroid Build Coastguard Worker 	};
307*193032a3SAndroid Build Coastguard Worker 	bool match_timings(const timings &t1, const timings &t2);
308*193032a3SAndroid Build Coastguard Worker 	timings calc_gtf_mode(unsigned h_pixels, unsigned v_lines,
309*193032a3SAndroid Build Coastguard Worker 			      double ip_freq_rqd, bool int_rqd = false,
310*193032a3SAndroid Build Coastguard Worker 			      enum gtf_ip_parm ip_parm = gtf_ip_vert_freq,
311*193032a3SAndroid Build Coastguard Worker 			      bool margins_rqd = false, bool secondary = false,
312*193032a3SAndroid Build Coastguard Worker 			      double C = 40, double M = 600, double K = 128, double J = 20);
313*193032a3SAndroid Build Coastguard Worker 	void edid_gtf_mode(unsigned refresh, struct timings &t);
314*193032a3SAndroid Build Coastguard Worker 	timings calc_cvt_mode(unsigned h_pixels, unsigned v_lines,
315*193032a3SAndroid Build Coastguard Worker 			      double ip_freq_rqd, unsigned rb, bool int_rqd = false,
316*193032a3SAndroid Build Coastguard Worker 			      bool margins_rqd = false, bool alt = false,
317*193032a3SAndroid Build Coastguard Worker 			      unsigned rb_h_blank = 0);
318*193032a3SAndroid Build Coastguard Worker 	void edid_cvt_mode(unsigned refresh, struct timings &t);
319*193032a3SAndroid Build Coastguard Worker 	void detailed_cvt_descriptor(const char *prefix, const unsigned char *x, bool first);
320*193032a3SAndroid Build Coastguard Worker 	void print_standard_timing(const char *prefix, unsigned char b1, unsigned char b2,
321*193032a3SAndroid Build Coastguard Worker 				   bool gtf_only = false, bool show_both = false);
322*193032a3SAndroid Build Coastguard Worker 	void detailed_display_range_limits(const unsigned char *x);
323*193032a3SAndroid Build Coastguard Worker 	void detailed_epi(const unsigned char *x);
324*193032a3SAndroid Build Coastguard Worker 	void detailed_timings(const char *prefix, const unsigned char *x,
325*193032a3SAndroid Build Coastguard Worker 			      bool base_or_cta = true);
326*193032a3SAndroid Build Coastguard Worker 	void preparse_detailed_block(const unsigned char *x);
327*193032a3SAndroid Build Coastguard Worker 	void detailed_block(const unsigned char *x);
328*193032a3SAndroid Build Coastguard Worker 	void parse_base_block(const unsigned char *x);
329*193032a3SAndroid Build Coastguard Worker 	void check_base_block();
330*193032a3SAndroid Build Coastguard Worker 	void list_dmts();
331*193032a3SAndroid Build Coastguard Worker 	void list_established_timings();
332*193032a3SAndroid Build Coastguard Worker 
333*193032a3SAndroid Build Coastguard Worker 	void print_vic_index(const char *prefix, unsigned idx, const char *suffix, bool ycbcr420 = false);
334*193032a3SAndroid Build Coastguard Worker 	void hdmi_latency(unsigned char vid_lat, unsigned char aud_lat, bool is_ilaced);
335*193032a3SAndroid Build Coastguard Worker 	void cta_vcdb(const unsigned char *x, unsigned length);
336*193032a3SAndroid Build Coastguard Worker 	void cta_svd(const unsigned char *x, unsigned n, bool for_ycbcr420);
337*193032a3SAndroid Build Coastguard Worker 	void cta_y420cmdb(const unsigned char *x, unsigned length);
338*193032a3SAndroid Build Coastguard Worker 	void cta_vfpdb(const unsigned char *x, unsigned length);
339*193032a3SAndroid Build Coastguard Worker 	void cta_rcdb(const unsigned char *x, unsigned length);
340*193032a3SAndroid Build Coastguard Worker 	void cta_sldb(const unsigned char *x, unsigned length);
341*193032a3SAndroid Build Coastguard Worker 	void cta_preparse_sldb(const unsigned char *x, unsigned length);
342*193032a3SAndroid Build Coastguard Worker 	void cta_hdmi_block(const unsigned char *x, unsigned length);
343*193032a3SAndroid Build Coastguard Worker 	void cta_displayid_type_7(const unsigned char *x, unsigned length);
344*193032a3SAndroid Build Coastguard Worker 	void cta_displayid_type_8(const unsigned char *x, unsigned length);
345*193032a3SAndroid Build Coastguard Worker 	void cta_displayid_type_10(const unsigned char *x, unsigned length);
346*193032a3SAndroid Build Coastguard Worker 	void cta_ext_block(const unsigned char *x, unsigned length, bool duplicate);
347*193032a3SAndroid Build Coastguard Worker 	void cta_block(const unsigned char *x, bool duplicate);
348*193032a3SAndroid Build Coastguard Worker 	void preparse_cta_block(const unsigned char *x);
349*193032a3SAndroid Build Coastguard Worker 	void parse_cta_block(const unsigned char *x);
350*193032a3SAndroid Build Coastguard Worker 	void cta_resolve_svr(vec_timings_ext::iterator iter);
351*193032a3SAndroid Build Coastguard Worker 	void cta_resolve_svrs();
352*193032a3SAndroid Build Coastguard Worker 	void check_cta_blocks();
353*193032a3SAndroid Build Coastguard Worker 	void cta_list_vics();
354*193032a3SAndroid Build Coastguard Worker 	void cta_list_hdmi_vics();
355*193032a3SAndroid Build Coastguard Worker 
356*193032a3SAndroid Build Coastguard Worker 	void parse_digital_interface(const unsigned char *x);
357*193032a3SAndroid Build Coastguard Worker 	void parse_display_device(const unsigned char *x);
358*193032a3SAndroid Build Coastguard Worker 	void parse_display_caps(const unsigned char *x);
359*193032a3SAndroid Build Coastguard Worker 	void parse_display_xfer(const unsigned char *x);
360*193032a3SAndroid Build Coastguard Worker 	void parse_di_ext_block(const unsigned char *x);
361*193032a3SAndroid Build Coastguard Worker 
362*193032a3SAndroid Build Coastguard Worker 	void check_displayid_datablock_revision(unsigned char hdr,
363*193032a3SAndroid Build Coastguard Worker 						unsigned char valid_flags = 0,
364*193032a3SAndroid Build Coastguard Worker 						unsigned char rev = 0);
365*193032a3SAndroid Build Coastguard Worker 	void parse_displayid_product_id(const unsigned char *x);
366*193032a3SAndroid Build Coastguard Worker 	std::string product_type(unsigned char x, bool heading);
367*193032a3SAndroid Build Coastguard Worker 	void parse_displayid_interface_features(const unsigned char *x);
368*193032a3SAndroid Build Coastguard Worker 	void parse_displayid_parameters(const unsigned char *x);
369*193032a3SAndroid Build Coastguard Worker 	void parse_displayid_parameters_v2(const unsigned char *x, unsigned block_rev);
370*193032a3SAndroid Build Coastguard Worker 	void parse_displayid_display_intf(const unsigned char *x);
371*193032a3SAndroid Build Coastguard Worker 	void parse_displayid_color_characteristics(const unsigned char *x);
372*193032a3SAndroid Build Coastguard Worker 	void parse_displayid_transfer_characteristics(const unsigned char *x);
373*193032a3SAndroid Build Coastguard Worker 	void parse_displayid_stereo_display_intf(const unsigned char *x);
374*193032a3SAndroid Build Coastguard Worker 	void parse_displayid_type_1_7_timing(const unsigned char *x,
375*193032a3SAndroid Build Coastguard Worker 					     bool type7, unsigned block_rev, bool is_cta = false);
376*193032a3SAndroid Build Coastguard Worker 	void parse_displayid_type_2_timing(const unsigned char *x);
377*193032a3SAndroid Build Coastguard Worker 	void parse_displayid_type_3_timing(const unsigned char *x);
378*193032a3SAndroid Build Coastguard Worker 	void parse_displayid_type_4_8_timing(unsigned char type, unsigned short id, bool is_cta = false);
379*193032a3SAndroid Build Coastguard Worker 	void parse_displayid_video_timing_range_limits(const unsigned char *x);
380*193032a3SAndroid Build Coastguard Worker 	void parse_displayid_string(const unsigned char *x);
381*193032a3SAndroid Build Coastguard Worker 	void parse_displayid_display_device(const unsigned char *x);
382*193032a3SAndroid Build Coastguard Worker 	void parse_displayid_intf_power_sequencing(const unsigned char *x);
383*193032a3SAndroid Build Coastguard Worker 	void parse_displayid_type_5_timing(const unsigned char *x);
384*193032a3SAndroid Build Coastguard Worker 	void parse_displayid_tiled_display_topology(const unsigned char *x, bool is_v2);
385*193032a3SAndroid Build Coastguard Worker 	void parse_displayid_type_6_timing(const unsigned char *x);
386*193032a3SAndroid Build Coastguard Worker 	void parse_displayid_type_9_timing(const unsigned char *x);
387*193032a3SAndroid Build Coastguard Worker 	void parse_displayid_dynamic_video_timings_range_limits(const unsigned char *x);
388*193032a3SAndroid Build Coastguard Worker 	void parse_displayid_ContainerID(const unsigned char *x);
389*193032a3SAndroid Build Coastguard Worker 	void parse_displayid_type_10_timing(const unsigned char *x, bool is_cta = false);
390*193032a3SAndroid Build Coastguard Worker 	void preparse_displayid_block(const unsigned char *x);
391*193032a3SAndroid Build Coastguard Worker 	void parse_displayid_block(const unsigned char *x);
392*193032a3SAndroid Build Coastguard Worker 	void parse_displayid_vesa(const unsigned char *x);
393*193032a3SAndroid Build Coastguard Worker 	void parse_displayid_cta_data_block(const unsigned char *x);
394*193032a3SAndroid Build Coastguard Worker 	void check_displayid_blocks();
395*193032a3SAndroid Build Coastguard Worker 
396*193032a3SAndroid Build Coastguard Worker 	void parse_vtb_ext_block(const unsigned char *x);
397*193032a3SAndroid Build Coastguard Worker 
398*193032a3SAndroid Build Coastguard Worker 	void parse_string_table(const unsigned char *x);
399*193032a3SAndroid Build Coastguard Worker 	void parse_ls_ext_block(const unsigned char *x);
400*193032a3SAndroid Build Coastguard Worker 
401*193032a3SAndroid Build Coastguard Worker 	void parse_block_map(const unsigned char *x);
402*193032a3SAndroid Build Coastguard Worker 
403*193032a3SAndroid Build Coastguard Worker 	void preparse_extension(const unsigned char *x);
404*193032a3SAndroid Build Coastguard Worker 	void parse_extension(const unsigned char *x);
405*193032a3SAndroid Build Coastguard Worker 	int parse_edid();
406*193032a3SAndroid Build Coastguard Worker };
407*193032a3SAndroid Build Coastguard Worker 
add_str(std::string & s,const std::string & add)408*193032a3SAndroid Build Coastguard Worker static inline void add_str(std::string &s, const std::string &add)
409*193032a3SAndroid Build Coastguard Worker {
410*193032a3SAndroid Build Coastguard Worker 	if (s.empty())
411*193032a3SAndroid Build Coastguard Worker 		s = add;
412*193032a3SAndroid Build Coastguard Worker 	else if (!add.empty())
413*193032a3SAndroid Build Coastguard Worker 		s = s + ", " + add;
414*193032a3SAndroid Build Coastguard Worker }
415*193032a3SAndroid Build Coastguard Worker 
416*193032a3SAndroid Build Coastguard Worker void msg(bool is_warn, const char *fmt, ...);
417*193032a3SAndroid Build Coastguard Worker 
418*193032a3SAndroid Build Coastguard Worker #ifdef _WIN32
419*193032a3SAndroid Build Coastguard Worker 
420*193032a3SAndroid Build Coastguard Worker #define warn(fmt, ...) msg(true, fmt, __VA_ARGS__)
421*193032a3SAndroid Build Coastguard Worker #define warn_once(fmt, ...)				\
422*193032a3SAndroid Build Coastguard Worker 	do {						\
423*193032a3SAndroid Build Coastguard Worker 		static bool shown_warn;			\
424*193032a3SAndroid Build Coastguard Worker 		if (!shown_warn) {			\
425*193032a3SAndroid Build Coastguard Worker 			shown_warn = true;		\
426*193032a3SAndroid Build Coastguard Worker 			msg(true, fmt, __VA_ARGS__);	\
427*193032a3SAndroid Build Coastguard Worker 		}					\
428*193032a3SAndroid Build Coastguard Worker 	} while (0)
429*193032a3SAndroid Build Coastguard Worker #define fail(fmt, ...) msg(false, fmt, __VA_ARGS__)
430*193032a3SAndroid Build Coastguard Worker 
431*193032a3SAndroid Build Coastguard Worker #else
432*193032a3SAndroid Build Coastguard Worker 
433*193032a3SAndroid Build Coastguard Worker #define warn(fmt, args...) msg(true, fmt, ##args)
434*193032a3SAndroid Build Coastguard Worker #define warn_once(fmt, args...)				\
435*193032a3SAndroid Build Coastguard Worker 	do {						\
436*193032a3SAndroid Build Coastguard Worker 		static bool shown_warn;			\
437*193032a3SAndroid Build Coastguard Worker 		if (!shown_warn) {			\
438*193032a3SAndroid Build Coastguard Worker 			shown_warn = true;		\
439*193032a3SAndroid Build Coastguard Worker 			msg(true, fmt, ##args);		\
440*193032a3SAndroid Build Coastguard Worker 		}					\
441*193032a3SAndroid Build Coastguard Worker 	} while (0)
442*193032a3SAndroid Build Coastguard Worker #define fail(fmt, args...) msg(false, fmt, ##args)
443*193032a3SAndroid Build Coastguard Worker 
444*193032a3SAndroid Build Coastguard Worker #endif
445*193032a3SAndroid Build Coastguard Worker 
446*193032a3SAndroid Build Coastguard Worker void do_checksum(const char *prefix, const unsigned char *x, size_t len);
447*193032a3SAndroid Build Coastguard Worker std::string utohex(unsigned char x);
448*193032a3SAndroid Build Coastguard Worker std::string ouitohex(unsigned oui);
449*193032a3SAndroid Build Coastguard Worker std::string containerid2s(const unsigned char *x);
450*193032a3SAndroid Build Coastguard Worker bool memchk(const unsigned char *x, unsigned len, unsigned char v = 0);
451*193032a3SAndroid Build Coastguard Worker void hex_block(const char *prefix, const unsigned char *x, unsigned length,
452*193032a3SAndroid Build Coastguard Worker 	       bool show_ascii = true, unsigned step = 16);
453*193032a3SAndroid Build Coastguard Worker std::string block_name(unsigned char block);
454*193032a3SAndroid Build Coastguard Worker void calc_ratio(struct timings *t);
455*193032a3SAndroid Build Coastguard Worker const char *oui_name(unsigned oui, bool reverse = false);
456*193032a3SAndroid Build Coastguard Worker 
457*193032a3SAndroid Build Coastguard Worker bool timings_close_match(const timings &t1, const timings &t2);
458*193032a3SAndroid Build Coastguard Worker const struct timings *find_dmt_id(unsigned char dmt_id);
459*193032a3SAndroid Build Coastguard Worker const struct timings *close_match_to_dmt(const timings &t, unsigned &dmt);
460*193032a3SAndroid Build Coastguard Worker const struct timings *find_vic_id(unsigned char vic);
461*193032a3SAndroid Build Coastguard Worker const struct timings *find_hdmi_vic_id(unsigned char hdmi_vic);
462*193032a3SAndroid Build Coastguard Worker const struct timings *cta_close_match_to_vic(const timings &t, unsigned &vic);
463*193032a3SAndroid Build Coastguard Worker unsigned char hdmi_vic_to_vic(unsigned char hdmi_vic);
464*193032a3SAndroid Build Coastguard Worker char *extract_string(const unsigned char *x, unsigned len);
465*193032a3SAndroid Build Coastguard Worker 
466*193032a3SAndroid Build Coastguard Worker #endif
467