• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <assert.h>
2 #include <errno.h>
3 #include <stdbool.h>
4 #include <stdlib.h>
5 #include <string.h>
6 
7 #include "bits.h"
8 #include "dmt.h"
9 #include "edid.h"
10 #include "log.h"
11 
12 /**
13  * The size of an EDID block, defined in section 2.2.
14  */
15 #define EDID_BLOCK_SIZE 128
16 /**
17  * The size of an EDID standard timing, defined in section 3.9.
18  */
19 #define EDID_STANDARD_TIMING_SIZE 2
20 /**
21  * The size of an EDID CVT timing code, defined in section 3.10.3.8.
22  */
23 #define EDID_CVT_TIMING_CODE_SIZE 3
24 
25 /**
26  * Fixed EDID header, defined in section 3.1.
27  */
28 static const uint8_t header[] = { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 };
29 
30 static void
add_failure(struct di_edid * edid,const char fmt[],...)31 add_failure(struct di_edid *edid, const char fmt[], ...)
32 {
33 	va_list args;
34 
35 	va_start(args, fmt);
36 	_di_logger_va_add_failure(edid->logger, fmt, args);
37 	va_end(args);
38 }
39 
40 static void
add_failure_until(struct di_edid * edid,int revision,const char fmt[],...)41 add_failure_until(struct di_edid *edid, int revision, const char fmt[], ...)
42 {
43 	va_list args;
44 
45 	if (edid->revision > revision) {
46 		return;
47 	}
48 
49 	va_start(args, fmt);
50 	_di_logger_va_add_failure(edid->logger, fmt, args);
51 	va_end(args);
52 }
53 
54 static void
parse_version_revision(const uint8_t data[static EDID_BLOCK_SIZE],int * version,int * revision)55 parse_version_revision(const uint8_t data[static EDID_BLOCK_SIZE],
56 		       int *version, int *revision)
57 {
58 	*version = (int) data[0x12];
59 	*revision = (int) data[0x13];
60 }
61 
62 static size_t
parse_ext_count(const uint8_t data[static EDID_BLOCK_SIZE])63 parse_ext_count(const uint8_t data[static EDID_BLOCK_SIZE])
64 {
65 	return data[0x7E];
66 }
67 
68 static bool
validate_block_checksum(const uint8_t data[static EDID_BLOCK_SIZE])69 validate_block_checksum(const uint8_t data[static EDID_BLOCK_SIZE])
70 {
71 	uint8_t sum = 0;
72 	size_t i;
73 
74 	for (i = 0; i < EDID_BLOCK_SIZE; i++) {
75 		sum += data[i];
76 	}
77 
78 	return sum == 0;
79 }
80 
81 static void
parse_vendor_product(struct di_edid * edid,const uint8_t data[static EDID_BLOCK_SIZE])82 parse_vendor_product(struct di_edid *edid,
83 		     const uint8_t data[static EDID_BLOCK_SIZE])
84 {
85 	struct di_edid_vendor_product *out = &edid->vendor_product;
86 	uint16_t man, raw_week, raw_year;
87 	int year = 0;
88 
89 	/* The ASCII 3-letter manufacturer code is encoded in 5-bit codes. */
90 	man = (uint16_t) ((data[0x08] << 8) | data[0x09]);
91 	out->manufacturer[0] = ((man >> 10) & 0x1F) + '@';
92 	out->manufacturer[1] = ((man >> 5) & 0x1F) + '@';
93 	out->manufacturer[2] = ((man >> 0) & 0x1F) + '@';
94 
95 	out->product = (uint16_t) (data[0x0A] | (data[0x0B] << 8));
96 	out->serial = (uint32_t) (data[0x0C] |
97 				  (data[0x0D] << 8) |
98 				  (data[0x0E] << 16) |
99 				  (data[0x0F] << 24));
100 
101 	raw_week = data[0x10];
102 	raw_year = data[0x11];
103 
104 	if (raw_year >= 0x10 || edid->revision < 4) {
105 		year = data[0x11] + 1990;
106 	} else if (edid->revision == 4) {
107 		add_failure(edid, "Year set to reserved value.");
108 	}
109 
110 	if (raw_week == 0xFF) {
111 		/* Special flag for model year */
112 		out->model_year = year;
113 	} else {
114 		out->manufacture_year = year;
115 		if (raw_week > 54) {
116 			add_failure_until(edid, 4,
117 					  "Invalid week %u of manufacture.",
118 					  raw_week);
119 		} else if (raw_week > 0) {
120 			out->manufacture_week = raw_week;
121 		}
122 	}
123 }
124 
125 static void
parse_video_input_digital(struct di_edid * edid,uint8_t video_input)126 parse_video_input_digital(struct di_edid *edid, uint8_t video_input)
127 {
128 	uint8_t color_bit_depth, interface;
129 	struct di_edid_video_input_digital *digital = &edid->video_input_digital;
130 
131 	if (edid->revision < 2) {
132 		if (get_bit_range(video_input, 6, 0) != 0)
133 			add_failure(edid, "Digital Video Interface Standard set to reserved value 0x%02x.",
134 				    video_input);
135 		return;
136 	}
137 	if (edid->revision < 4) {
138 		if (get_bit_range(video_input, 6, 1) != 0)
139 			add_failure(edid, "Digital Video Interface Standard set to reserved value 0x%02x.",
140 				    video_input);
141 		digital->dfp1 = has_bit(video_input, 0);
142 		return;
143 	}
144 
145 	color_bit_depth = get_bit_range(video_input, 6, 4);
146 	if (color_bit_depth == 0x07) {
147 		/* Reserved */
148 		add_failure_until(edid, 4, "Color Bit Depth set to reserved value.");
149 	} else if (color_bit_depth != 0) {
150 		digital->color_bit_depth = 2 * color_bit_depth + 4;
151 	}
152 
153 	interface = get_bit_range(video_input, 3, 0);
154 	switch (interface) {
155 	case DI_EDID_VIDEO_INPUT_DIGITAL_UNDEFINED:
156 	case DI_EDID_VIDEO_INPUT_DIGITAL_DVI:
157 	case DI_EDID_VIDEO_INPUT_DIGITAL_HDMI_A:
158 	case DI_EDID_VIDEO_INPUT_DIGITAL_HDMI_B:
159 	case DI_EDID_VIDEO_INPUT_DIGITAL_MDDI:
160 	case DI_EDID_VIDEO_INPUT_DIGITAL_DISPLAYPORT:
161 		digital->interface = interface;
162 		break;
163 	default:
164 		add_failure_until(edid, 4,
165 				  "Digital Video Interface Standard set to reserved value 0x%02x.",
166 				  interface);
167 		digital->interface = DI_EDID_VIDEO_INPUT_DIGITAL_UNDEFINED;
168 		break;
169 	}
170 }
171 
172 static void
parse_video_input_analog(struct di_edid * edid,uint8_t video_input)173 parse_video_input_analog(struct di_edid *edid, uint8_t video_input)
174 {
175 	struct di_edid_video_input_analog *analog = &edid->video_input_analog;
176 
177 	analog->signal_level_std = get_bit_range(video_input, 6, 5);
178 	analog->video_setup = has_bit(video_input, 4);
179 	analog->sync_separate = has_bit(video_input, 3);
180 	analog->sync_composite = has_bit(video_input, 2);
181 	analog->sync_on_green = has_bit(video_input, 1);
182 	analog->sync_serrations = has_bit(video_input, 0);
183 }
184 
185 static void
parse_basic_params_features(struct di_edid * edid,const uint8_t data[static EDID_BLOCK_SIZE])186 parse_basic_params_features(struct di_edid *edid,
187 			    const uint8_t data[static EDID_BLOCK_SIZE])
188 {
189 	uint8_t video_input, width, height, features;
190 	struct di_edid_screen_size *screen_size = &edid->screen_size;
191 
192 	video_input = data[0x14];
193 	edid->is_digital = has_bit(video_input, 7);
194 
195 	if (edid->is_digital) {
196 		parse_video_input_digital(edid, video_input);
197 	} else {
198 		parse_video_input_analog(edid, video_input);
199 	}
200 
201 	/* v1.3 says screen size is undefined if either byte is zero, v1.4 says
202 	 * screen size and aspect ratio are undefined if both bytes are zero and
203 	 * encodes the aspect ratio if either byte is zero. */
204 	width = data[0x15];
205 	height = data[0x16];
206 	if (width > 0 && height > 0) {
207 		screen_size->width_cm = width;
208 		screen_size->height_cm = height;
209 	} else if (edid->revision >= 4) {
210 		if (width > 0) {
211 			screen_size->landscape_aspect_ratio = ((float) width + 99) / 100;
212 		} else if (height > 0) {
213 			screen_size->portait_aspect_ratio = ((float) height + 99) / 100;
214 		}
215 	}
216 
217 	if (data[0x17] != 0xFF) {
218 		edid->gamma = ((float) data[0x17] + 100) / 100;
219 	} else {
220 		edid->gamma = 0;
221 	}
222 
223 	features = data[0x18];
224 
225 	edid->dpms.standby = has_bit(features, 7);
226 	edid->dpms.suspend = has_bit(features, 6);
227 	edid->dpms.off = has_bit(features, 5);
228 
229 	if (edid->is_digital && edid->revision >= 4) {
230 		edid->color_encoding_formats.rgb444 = true;
231 		edid->color_encoding_formats.ycrcb444 = has_bit(features, 3);
232 		edid->color_encoding_formats.ycrcb422 = has_bit(features, 4);
233 		edid->display_color_type = DI_EDID_DISPLAY_COLOR_UNDEFINED;
234 	} else {
235 		edid->display_color_type = get_bit_range(features, 4, 3);
236 	}
237 
238 	if (edid->revision >= 4) {
239 		edid->misc_features.has_preferred_timing = true;
240 		edid->misc_features.continuous_freq = has_bit(features, 0);
241 		edid->misc_features.preferred_timing_is_native = has_bit(features, 1);
242 	} else {
243 		edid->misc_features.default_gtf = has_bit(features, 0);
244 		edid->misc_features.has_preferred_timing = has_bit(features, 1);
245 	}
246 	edid->misc_features.srgb_is_primary = has_bit(features, 2);
247 }
248 
249 static float
decode_chromaticity_coord(uint8_t hi,uint8_t lo)250 decode_chromaticity_coord(uint8_t hi, uint8_t lo)
251 {
252 	uint16_t raw; /* only 10 bits are used */
253 
254 	raw = (uint16_t) ((hi << 2) | lo);
255 	return (float) raw / 1024;
256 }
257 
258 static void
parse_chromaticity_coords(struct di_edid * edid,const uint8_t data[static EDID_BLOCK_SIZE])259 parse_chromaticity_coords(struct di_edid *edid,
260 			  const uint8_t data[static EDID_BLOCK_SIZE])
261 {
262 	uint8_t lo;
263 	bool all_set, any_set;
264 	struct di_edid_chromaticity_coords *coords;
265 
266 	coords = &edid->chromaticity_coords;
267 
268 	lo = data[0x19];
269 	coords->red_x = decode_chromaticity_coord(data[0x1B], get_bit_range(lo, 7, 6));
270 	coords->red_y = decode_chromaticity_coord(data[0x1C], get_bit_range(lo, 5, 4));
271 	coords->green_x = decode_chromaticity_coord(data[0x1D], get_bit_range(lo, 3, 2));
272 	coords->green_y = decode_chromaticity_coord(data[0x1E], get_bit_range(lo, 1, 0));
273 
274 	lo = data[0x1A];
275 	coords->blue_x = decode_chromaticity_coord(data[0x1F], get_bit_range(lo, 7, 6));
276 	coords->blue_y = decode_chromaticity_coord(data[0x20], get_bit_range(lo, 5, 4));
277 	coords->white_x = decode_chromaticity_coord(data[0x21], get_bit_range(lo, 3, 2));
278 	coords->white_y = decode_chromaticity_coord(data[0x22], get_bit_range(lo, 1, 0));
279 
280 	/* Either all primaries coords must be set, either none must be set */
281 	any_set = coords->red_x != 0 || coords->red_y != 0
282 		  || coords->green_x != 0 || coords->green_y != 0
283 		  || coords->blue_x != 0 || coords->blue_y != 0;
284 	all_set = coords->red_x != 0 && coords->red_y != 0
285 		  && coords->green_x != 0 && coords->green_y != 0
286 		  && coords->blue_x != 0 && coords->blue_y != 0;
287 	if (any_set && !all_set) {
288 		add_failure(edid, "Some but not all primaries coordinates are unset.");
289 	}
290 
291 	/* Both white-point coords must be set */
292 	if (coords->white_x == 0 || coords->white_y == 0) {
293 		add_failure(edid, "White-point coordinates are unset.");
294 	}
295 }
296 
297 static void
parse_established_timings_i_ii(struct di_edid * edid,const uint8_t data[static EDID_BLOCK_SIZE])298 parse_established_timings_i_ii(struct di_edid *edid,
299 			       const uint8_t data[static EDID_BLOCK_SIZE])
300 {
301 	struct di_edid_established_timings_i_ii *timings = &edid->established_timings_i_ii;
302 
303 	timings->has_720x400_70hz = has_bit(data[0x23], 7);
304 	timings->has_720x400_88hz = has_bit(data[0x23], 6);
305 	timings->has_640x480_60hz = has_bit(data[0x23], 5);
306 	timings->has_640x480_67hz = has_bit(data[0x23], 4);
307 	timings->has_640x480_72hz = has_bit(data[0x23], 3);
308 	timings->has_640x480_75hz = has_bit(data[0x23], 2);
309 	timings->has_800x600_56hz = has_bit(data[0x23], 1);
310 	timings->has_800x600_60hz = has_bit(data[0x23], 0);
311 
312 	/* Established timings II */
313 	timings->has_800x600_72hz = has_bit(data[0x24], 7);
314 	timings->has_800x600_75hz = has_bit(data[0x24], 6);
315 	timings->has_832x624_75hz = has_bit(data[0x24], 5);
316 	timings->has_1024x768_87hz_interlaced = has_bit(data[0x24], 4);
317 	timings->has_1024x768_60hz = has_bit(data[0x24], 3);
318 	timings->has_1024x768_70hz = has_bit(data[0x24], 2);
319 	timings->has_1024x768_75hz = has_bit(data[0x24], 1);
320 	timings->has_1280x1024_75hz = has_bit(data[0x24], 0);
321 
322 	timings->has_1152x870_75hz = has_bit(data[0x25], 7);
323 	/* TODO: manufacturer specified timings in bits 6:0 */
324 }
325 
326 static bool
parse_standard_timing(struct di_edid * edid,const uint8_t data[static EDID_STANDARD_TIMING_SIZE],struct di_edid_standard_timing ** out)327 parse_standard_timing(struct di_edid *edid,
328 		      const uint8_t data[static EDID_STANDARD_TIMING_SIZE],
329 		      struct di_edid_standard_timing **out)
330 {
331 	struct di_edid_standard_timing *t;
332 
333 	*out = NULL;
334 
335 	if (data[0] == 0x01 && data[1] == 0x01) {
336 		/* Unused */
337 		return true;
338 	}
339 	if (data[0] == 0x00) {
340 		add_failure_until(edid, 4,
341 				  "Use 0x0101 as the invalid Standard Timings code, not 0x%02x%02x.",
342 				  data[0], data[1]);
343 		return true;
344 	}
345 
346 	t = calloc(1, sizeof(*t));
347 	if (!t) {
348 		return false;
349 	}
350 
351 	t->horiz_video = ((int32_t) data[0] + 31) * 8;
352 	t->aspect_ratio = get_bit_range(data[1], 7, 6);
353 	t->refresh_rate_hz = (int32_t) get_bit_range(data[1], 5, 0) + 60;
354 
355 	*out = t;
356 	return true;
357 }
358 
359 struct di_edid_detailed_timing_def_priv *
_di_edid_parse_detailed_timing_def(const uint8_t data[static EDID_BYTE_DESCRIPTOR_SIZE])360 _di_edid_parse_detailed_timing_def(const uint8_t data[static EDID_BYTE_DESCRIPTOR_SIZE])
361 {
362 	struct di_edid_detailed_timing_def_priv *priv;
363 	struct di_edid_detailed_timing_def *def;
364 	struct di_edid_detailed_timing_analog_composite *analog_composite;
365 	struct di_edid_detailed_timing_bipolar_analog_composite *bipolar_analog_composite;
366 	struct di_edid_detailed_timing_digital_composite *digital_composite;
367 	struct di_edid_detailed_timing_digital_separate *digital_separate;
368 	int raw;
369 	uint8_t flags, stereo_hi, stereo_lo;
370 
371 	priv = calloc(1, sizeof(*priv));
372 	if (!priv) {
373 		return NULL;
374 	}
375 
376 	def = &priv->base;
377 
378 	raw = (data[1] << 8) | data[0];
379 	def->pixel_clock_hz = raw * 10 * 1000;
380 
381 	def->horiz_video = (get_bit_range(data[4], 7, 4) << 8) | data[2];
382 	def->horiz_blank = (get_bit_range(data[4], 3, 0) << 8) | data[3];
383 
384 	def->vert_video = (get_bit_range(data[7], 7, 4) << 8) | data[5];
385 	def->vert_blank = (get_bit_range(data[7], 3, 0) << 8) | data[6];
386 
387 	def->horiz_front_porch = (get_bit_range(data[11], 7, 6) << 8) | data[8];
388 	def->horiz_sync_pulse = (get_bit_range(data[11], 5, 4) << 8) | data[9];
389 	def->vert_front_porch = (get_bit_range(data[11], 3, 2) << 4)
390 				| get_bit_range(data[10], 7, 4);
391 	def->vert_sync_pulse = (get_bit_range(data[11], 1, 0) << 4)
392 			       | get_bit_range(data[10], 3, 0);
393 
394 	def->horiz_image_mm = (get_bit_range(data[14], 7, 4) << 8) | data[12];
395 	def->vert_image_mm = (get_bit_range(data[14], 3, 0) << 8) | data[13];
396 	if ((def->horiz_image_mm == 16 && def->vert_image_mm == 9)
397 	    || (def->horiz_image_mm == 4 && def->vert_image_mm == 3)) {
398 		/* Table 3.21 note 18.2: these are special cases and define the
399 		 * aspect ratio rather than the size in mm.
400 		 * TODO: expose these values */
401 		def->horiz_image_mm = def->vert_image_mm = 0;
402 	}
403 
404 	def->horiz_border = data[15];
405 	def->vert_border = data[16];
406 
407 	flags = data[17];
408 
409 	def->interlaced = has_bit(flags, 7);
410 
411 	stereo_hi = get_bit_range(flags, 6, 5);
412 	stereo_lo = get_bit_range(flags, 0, 0);
413 	if (stereo_hi == 0) {
414 		def->stereo = DI_EDID_DETAILED_TIMING_DEF_STEREO_NONE;
415 	} else {
416 		switch ((stereo_hi << 1) | stereo_lo) {
417 		case (1 << 1) | 0:
418 			def->stereo = DI_EDID_DETAILED_TIMING_DEF_STEREO_FIELD_SEQ_RIGHT;
419 			break;
420 		case (2 << 1) | 0:
421 			def->stereo = DI_EDID_DETAILED_TIMING_DEF_STEREO_FIELD_SEQ_LEFT;
422 			break;
423 		case (1 << 1) | 1:
424 			def->stereo = DI_EDID_DETAILED_TIMING_DEF_STEREO_2_WAY_INTERLEAVED_RIGHT;
425 			break;
426 		case (2 << 1) | 1:
427 			def->stereo = DI_EDID_DETAILED_TIMING_DEF_STEREO_2_WAY_INTERLEAVED_LEFT;
428 			break;
429 		case (3 << 1) | 0:
430 			def->stereo = DI_EDID_DETAILED_TIMING_DEF_STEREO_4_WAY_INTERLEAVED;
431 			break;
432 		case (3 << 1) | 1:
433 			def->stereo = DI_EDID_DETAILED_TIMING_DEF_STEREO_SIDE_BY_SIDE_INTERLEAVED;
434 			break;
435 		default:
436 			abort(); /* unreachable */
437 		}
438 	}
439 
440 	def->signal_type = get_bit_range(flags, 4, 3);
441 
442 	switch (def->signal_type) {
443 	case DI_EDID_DETAILED_TIMING_DEF_SIGNAL_ANALOG_COMPOSITE:
444 		analog_composite = &priv->analog_composite;
445 		analog_composite->sync_serrations = has_bit(flags, 2);
446 		analog_composite->sync_on_green = !has_bit(flags, 1);
447 		def->analog_composite = analog_composite;
448 		break;
449 	case DI_EDID_DETAILED_TIMING_DEF_SIGNAL_BIPOLAR_ANALOG_COMPOSITE:
450 		bipolar_analog_composite = &priv->bipolar_analog_composite;
451 		bipolar_analog_composite->sync_serrations = has_bit(flags, 2);
452 		bipolar_analog_composite->sync_on_green = !has_bit(flags, 1);
453 		def->bipolar_analog_composite = bipolar_analog_composite;
454 		break;
455 	case DI_EDID_DETAILED_TIMING_DEF_SIGNAL_DIGITAL_COMPOSITE:
456 		digital_composite = &priv->digital_composite;
457 		digital_composite->sync_serrations = has_bit(flags, 2);
458 		digital_composite->sync_horiz_polarity = has_bit(flags, 1);
459 		def->digital_composite = digital_composite;
460 		break;
461 	case DI_EDID_DETAILED_TIMING_DEF_SIGNAL_DIGITAL_SEPARATE:
462 		digital_separate = &priv->digital_separate;
463 		digital_separate->sync_vert_polarity = has_bit(flags, 2);
464 		digital_separate->sync_horiz_polarity = has_bit(flags, 1);
465 		def->digital_separate = digital_separate;
466 		break;
467 	}
468 
469 	return priv;
470 }
471 
472 static bool
decode_display_range_limits_offset(struct di_edid * edid,uint8_t flags,int * max_offset,int * min_offset)473 decode_display_range_limits_offset(struct di_edid *edid, uint8_t flags,
474 				  int *max_offset, int *min_offset)
475 {
476 	switch (flags) {
477 	case 0x00:
478 		/* No offset */
479 		break;
480 	case 0x02:
481 		*max_offset = 255;
482 		break;
483 	case 0x03:
484 		*max_offset = 255;
485 		*min_offset = 255;
486 		break;
487 	default:
488 		add_failure_until(edid, 4,
489 				  "Range offset flags set to reserved value 0x%02x.",
490 				  flags);
491 		return false;
492 	}
493 
494 	return true;
495 }
496 
497 static bool
parse_display_range_limits(struct di_edid * edid,const uint8_t data[static EDID_BYTE_DESCRIPTOR_SIZE],struct di_edid_display_range_limits_priv * priv)498 parse_display_range_limits(struct di_edid *edid,
499 			   const uint8_t data[static EDID_BYTE_DESCRIPTOR_SIZE],
500 			   struct di_edid_display_range_limits_priv *priv)
501 {
502 	uint8_t offset_flags, vert_offset_flags, horiz_offset_flags;
503 	uint8_t support_flags, preferred_aspect_ratio;
504 	int max_vert_offset = 0, min_vert_offset = 0;
505 	int max_horiz_offset = 0, min_horiz_offset = 0;
506 	size_t i;
507 	struct di_edid_display_range_limits *base;
508 	struct di_edid_display_range_limits_secondary_gtf *secondary_gtf;
509 	struct di_edid_display_range_limits_cvt *cvt;
510 
511 	base = &priv->base;
512 
513 	offset_flags = data[4];
514 	if (edid->revision >= 4) {
515 		vert_offset_flags = get_bit_range(offset_flags, 1, 0);
516 		horiz_offset_flags = get_bit_range(offset_flags, 3, 2);
517 
518 		if (!decode_display_range_limits_offset(edid,
519 							vert_offset_flags,
520 							&max_vert_offset,
521 							&min_vert_offset)) {
522 			return false;
523 		}
524 		if (!decode_display_range_limits_offset(edid,
525 							horiz_offset_flags,
526 							&max_horiz_offset,
527 							&min_horiz_offset)) {
528 			return false;
529 		}
530 
531 		if (edid->revision <= 4 &&
532 		    get_bit_range(offset_flags, 7, 4) != 0) {
533 			add_failure(edid, "Display Range Limits: Bits 7:4 of the range offset flags are reserved.");
534 		}
535 	} else if (offset_flags != 0) {
536 		add_failure(edid, "Display Range Limits: Range offset flags are unsupported in EDID 1.3.");
537 	}
538 
539 	if (edid->revision <= 4 && (data[5] == 0 || data[6] == 0 ||
540 				    data[7] == 0 || data[8] == 0)) {
541 		add_failure(edid, "Display Range Limits: Range limits set to reserved values.");
542 		return false;
543 	}
544 
545 	base->min_vert_rate_hz = data[5] + min_vert_offset;
546 	base->max_vert_rate_hz = data[6] + max_vert_offset;
547 	base->min_horiz_rate_hz = (data[7] + min_horiz_offset) * 1000;
548 	base->max_horiz_rate_hz = (data[8] + max_horiz_offset) * 1000;
549 
550 	if (base->min_vert_rate_hz > base->max_vert_rate_hz) {
551 		add_failure(edid, "Display Range Limits: Min vertical rate > max vertical rate.");
552 		return false;
553 	}
554 	if (base->min_horiz_rate_hz > base->max_horiz_rate_hz) {
555 		add_failure(edid, "Display Range Limits: Min horizontal freq > max horizontal freq.");
556 		return false;
557 	}
558 
559 	base->max_pixel_clock_hz = (int64_t) data[9] * 10 * 1000 * 1000;
560 	if (edid->revision == 4 && base->max_pixel_clock_hz == 0) {
561 		add_failure(edid, "Display Range Limits: EDID 1.4 block does not set max dotclock.");
562 	}
563 
564 	support_flags = data[10];
565 	switch (support_flags) {
566 	case 0x00:
567 		/* For EDID 1.4 and later, always indicates support for default
568 		 * GTF. For EDID 1.3 and earlier, a misc features bit indicates
569 		 * support for default GTF. */
570 		if (edid->revision >= 4 || edid->misc_features.default_gtf) {
571 			base->type = DI_EDID_DISPLAY_RANGE_LIMITS_DEFAULT_GTF;
572 		} else {
573 			base->type = DI_EDID_DISPLAY_RANGE_LIMITS_BARE;
574 		}
575 		break;
576 	case 0x01:
577 		if (edid->revision < 4) {
578 			/* Reserved */
579 			add_failure(edid, "Display Range Limits: 'Bare Limits' is not allowed for EDID < 1.4.");
580 			return false;
581 		}
582 		base->type = DI_EDID_DISPLAY_RANGE_LIMITS_BARE;
583 		break;
584 	case 0x02:
585 		base->type = DI_EDID_DISPLAY_RANGE_LIMITS_SECONDARY_GTF;
586 		break;
587 	case 0x04:
588 		if (edid->revision < 4) {
589 			/* Reserved */
590 			add_failure(edid, "Display Range Limits: 'CVT' is not allowed for EDID < 1.4.");
591 			return false;
592 		}
593 		base->type = DI_EDID_DISPLAY_RANGE_LIMITS_CVT;
594 		break;
595 	default:
596 		/* Reserved */
597 		if (edid->revision <= 4) {
598 			add_failure(edid,
599 				    "Display Range Limits: Unknown range class (0x%02x).",
600 				    support_flags);
601 			return false;
602 		}
603 		base->type = DI_EDID_DISPLAY_RANGE_LIMITS_BARE;
604 		break;
605 	}
606 
607 	/* Some types require the display to support continuous frequencies, but
608 	 * this flag is only set for EDID 1.4 and later */
609 	if (edid->revision >= 4 && !edid->misc_features.continuous_freq) {
610 		switch (base->type) {
611 		case DI_EDID_DISPLAY_RANGE_LIMITS_DEFAULT_GTF:
612 			add_failure(edid, "Display Range Limits: GTF is supported, but the display does not support continuous frequencies.");
613 			return false;
614 		case DI_EDID_DISPLAY_RANGE_LIMITS_SECONDARY_GTF:
615 			add_failure(edid, "Display Range Limits: Secondary GTF is supported, but the display does not support continuous frequencies.");
616 			return false;
617 		case DI_EDID_DISPLAY_RANGE_LIMITS_CVT:
618 			add_failure(edid, "Display Range Limits: CVT is supported, but the display does not support continuous frequencies.");
619 			return false;
620 		default:
621 			break;
622 		}
623 	}
624 
625 	switch (base->type) {
626 	case DI_EDID_DISPLAY_RANGE_LIMITS_SECONDARY_GTF:
627 		secondary_gtf = &priv->secondary_gtf;
628 
629 		if (data[11] != 0)
630 			add_failure(edid,
631 				    "Display Range Limits: Byte 11 is 0x%02x instead of 0x00.",
632 				    data[11]);
633 
634 		secondary_gtf->start_freq_hz = data[12] * 2 * 1000;
635 		secondary_gtf->c = (float) data[13] / 2;
636 		secondary_gtf->m = (float) ((data[15] << 8) | data[14]);
637 		secondary_gtf->k = (float) data[16];
638 		secondary_gtf->j = (float) data[17] / 2;
639 
640 		base->secondary_gtf = secondary_gtf;
641 		break;
642 	case DI_EDID_DISPLAY_RANGE_LIMITS_CVT:
643 		cvt = &priv->cvt;
644 
645 		cvt->version = get_bit_range(data[11], 7, 4);
646 		cvt->revision = get_bit_range(data[11], 3, 0);
647 
648 		base->max_pixel_clock_hz -= get_bit_range(data[12], 7, 2) * 250 * 1000;
649 		cvt->max_horiz_px = 8 * ((get_bit_range(data[12], 1, 0) << 8) | data[13]);
650 
651 		cvt->supported_aspect_ratio = data[14];
652 		if (get_bit_range(data[14], 2, 0) != 0)
653 			add_failure_until(edid, 4,
654 					  "Display Range Limits: Reserved bits of byte 14 are non-zero.");
655 
656 		preferred_aspect_ratio = get_bit_range(data[15], 7, 5);
657 		switch (preferred_aspect_ratio) {
658 		case 0:
659 			cvt->preferred_aspect_ratio = DI_EDID_CVT_ASPECT_RATIO_4_3;
660 			break;
661 		case 1:
662 			cvt->preferred_aspect_ratio = DI_EDID_CVT_ASPECT_RATIO_16_9;
663 			break;
664 		case 2:
665 			cvt->preferred_aspect_ratio = DI_EDID_CVT_ASPECT_RATIO_16_10;
666 			break;
667 		case 3:
668 			cvt->preferred_aspect_ratio = DI_EDID_CVT_ASPECT_RATIO_5_4;
669 			break;
670 		case 4:
671 			cvt->preferred_aspect_ratio = DI_EDID_CVT_ASPECT_RATIO_15_9;
672 			break;
673 		default:
674 			/* Reserved */
675 			add_failure_until(edid, 4,
676 					  "Display Range Limits: Invalid preferred aspect ratio 0x%02x.",
677 					  preferred_aspect_ratio);
678 			return false;
679 		}
680 
681 		cvt->standard_blanking = has_bit(data[15], 3);
682 		cvt->reduced_blanking = has_bit(data[15], 4);
683 
684 		if (get_bit_range(data[15], 2, 0) != 0)
685 			add_failure_until(edid, 4,
686 					  "Display Range Limits: Reserved bits of byte 15 are non-zero.");
687 
688 		cvt->supported_scaling = data[16];
689 		if (get_bit_range(data[16], 3, 0) != 0)
690 			add_failure_until(edid, 4,
691 					  "Display Range Limits: Reserved bits of byte 16 are non-zero.");
692 
693 		cvt->preferred_vert_refresh_hz = data[17];
694 		if (cvt->preferred_vert_refresh_hz == 0) {
695 			add_failure_until(edid, 4,
696 					  "Display Range Limits: Preferred vertical refresh rate must be specified.");
697 			return false;
698 		}
699 
700 		base->cvt = cvt;
701 		break;
702 	case DI_EDID_DISPLAY_RANGE_LIMITS_BARE:
703 	case DI_EDID_DISPLAY_RANGE_LIMITS_DEFAULT_GTF:
704 		if (data[11] != 0x0A)
705 			add_failure(edid,
706 				    "Display Range Limits: Byte 11 is 0x%02x instead of 0x0a.",
707 				    data[11]);
708 		for (i = 12; i < EDID_BYTE_DESCRIPTOR_SIZE; i++) {
709 			if (data[i] != 0x20) {
710 				add_failure(edid,
711 					    "Display Range Limits: Bytes 12-17 must be 0x20.");
712 				break;
713 			}
714 		}
715 		break;
716 	}
717 
718 	return true;
719 }
720 
721 static bool
parse_standard_timings_descriptor(struct di_edid * edid,const uint8_t data[static EDID_BYTE_DESCRIPTOR_SIZE],struct di_edid_display_descriptor * desc)722 parse_standard_timings_descriptor(struct di_edid *edid,
723 				  const uint8_t data[static EDID_BYTE_DESCRIPTOR_SIZE],
724 				  struct di_edid_display_descriptor *desc)
725 {
726 	struct di_edid_standard_timing *t;
727 	size_t i;
728 	const uint8_t *timing_data;
729 
730 	for (i = 0; i < EDID_MAX_DESCRIPTOR_STANDARD_TIMING_COUNT; i++) {
731 		timing_data = &data[5 + i * EDID_STANDARD_TIMING_SIZE];
732 		if (!parse_standard_timing(edid, timing_data, &t))
733 			return false;
734 		if (t) {
735 			assert(desc->standard_timings_len < EDID_MAX_DESCRIPTOR_STANDARD_TIMING_COUNT);
736 			desc->standard_timings[desc->standard_timings_len++] = t;
737 		}
738 	}
739 
740 	if (data[17] != 0x0A)
741 		add_failure_until(edid, 4,
742 				  "Standard Timing Identifications: Last byte must be a line feed.");
743 
744 	return true;
745 }
746 
747 /**
748  * Mapping table for established timings III.
749  *
750  * Contains one entry per bit, with the value set to the DMT ID.
751  */
752 static const uint8_t established_timings_iii[] = {
753 	/* 0x06 */
754 	0x01, /* 640 x 350 @ 85 Hz */
755 	0x02, /* 640 x 400 @ 85 Hz */
756 	0x03, /* 720 x 400 @ 85 Hz */
757 	0x07, /* 640 x 480 @ 85 Hz */
758 	0x0e, /* 848 x 480 @ 60 Hz */
759 	0x0c, /* 800 x 600 @ 85 Hz */
760 	0x13, /* 1024 x 768 @ 85 Hz */
761 	0x15, /* 1152 x 864 @ 75 Hz */
762 	/* 0x07 */
763 	0x16, /* 1280 x 768 @ 60 Hz (RB) */
764 	0x17, /* 1280 x 768 @ 60 Hz */
765 	0x18, /* 1280 x 768 @ 75 Hz */
766 	0x19, /* 1280 x 768 @ 85 Hz */
767 	0x20, /* 1280 x 960 @ 60 Hz */
768 	0x21, /* 1280 x 960 @ 85 Hz */
769 	0x23, /* 1280 x 1024 @ 60 Hz */
770 	0x25, /* 1280 x 1024 @ 85 Hz */
771 	/* 0x08 */
772 	0x27, /* 1360 x 768 @ 60 Hz */
773 	0x2e, /* 1440 x 900 @ 60 Hz (RB) */
774 	0x2f, /* 1440 x 900 @ 60 Hz */
775 	0x30, /* 1440 x 900 @ 75 Hz */
776 	0x31, /* 1440 x 900 @ 85 Hz */
777 	0x29, /* 1400 x 1050 @ 60 Hz (RB) */
778 	0x2a, /* 1400 x 1050 @ 60 Hz */
779 	0x2b, /* 1400 x 1050 @ 75 Hz */
780 	/* 0x09 */
781 	0x2c, /* 1400 x 1050 @ 85 Hz */
782 	0x39, /* 1680 x 1050 @ 60 Hz (RB) */
783 	0x3a, /* 1680 x 1050 @ 60 Hz */
784 	0x3b, /* 1680 x 1050 @ 75 Hz */
785 	0x3c, /* 1680 x 1050 @ 85 Hz */
786 	0x33, /* 1600 x 1200 @ 60 Hz */
787 	0x34, /* 1600 x 1200 @ 65 Hz */
788 	0x35, /* 1600 x 1200 @ 70 Hz */
789 	/* 0x0a */
790 	0x36, /* 1600 x 1200 @ 75 Hz */
791 	0x37, /* 1600 x 1200 @ 85 Hz */
792 	0x3e, /* 1792 x 1344 @ 60 Hz */
793 	0x3f, /* 1792 x 1344 @ 75 Hz */
794 	0x41, /* 1856 x 1392 @ 60 Hz */
795 	0x42, /* 1856 x 1392 @ 75 Hz */
796 	0x44, /* 1920 x 1200 @ 60 Hz (RB) */
797 	0x45, /* 1920 x 1200 @ 60 Hz */
798 	/* 0x0b */
799 	0x46, /* 1920 x 1200 @ 75 Hz */
800 	0x47, /* 1920 x 1200 @ 85 Hz */
801 	0x49, /* 1920 x 1440 @ 60 Hz */
802 	0x4a, /* 1920 x 1440 @ 75 Hz */
803 };
804 static_assert(EDID_MAX_DESCRIPTOR_ESTABLISHED_TIMING_III_COUNT
805 	      == sizeof(established_timings_iii) / sizeof(established_timings_iii[0]),
806 	      "Invalid number of established timings III in table");
807 
808 static const struct di_dmt_timing *
get_dmt_timing(uint8_t dmt_id)809 get_dmt_timing(uint8_t dmt_id)
810 {
811 	size_t i;
812 	const struct di_dmt_timing *t;
813 
814 	for (i = 0; i < _di_dmt_timings_len; i++) {
815 		t = &_di_dmt_timings[i];
816 		if (t->dmt_id == dmt_id)
817 			return t;
818 	}
819 
820 	return NULL;
821 }
822 
823 static void
parse_established_timings_iii_descriptor(struct di_edid * edid,const uint8_t data[static EDID_BYTE_DESCRIPTOR_SIZE],struct di_edid_display_descriptor * desc)824 parse_established_timings_iii_descriptor(struct di_edid *edid,
825 					 const uint8_t data[static EDID_BYTE_DESCRIPTOR_SIZE],
826 					 struct di_edid_display_descriptor *desc)
827 {
828 	size_t i, offset, bit;
829 	uint8_t dmt_id;
830 	const struct di_dmt_timing *t;
831 	bool has_zeroes;
832 
833 	if (edid->revision < 4)
834 		add_failure(edid, "Established timings III: Not allowed for EDID < 1.4.");
835 
836 	for (i = 0; i < EDID_MAX_DESCRIPTOR_ESTABLISHED_TIMING_III_COUNT; i++) {
837 		dmt_id = established_timings_iii[i];
838 		offset = 0x06 + i / 8;
839 		bit = 7 - i % 8;
840 		assert(offset < EDID_BYTE_DESCRIPTOR_SIZE);
841 		if (has_bit(data[offset], bit)) {
842 			t = get_dmt_timing(dmt_id);
843 			assert(t != NULL);
844 			desc->established_timings_iii[desc->established_timings_iii_len++] = t;
845 		}
846 	}
847 
848 	has_zeroes = get_bit_range(data[11], 3, 0) == 0;
849 	for (i = 12; i < EDID_BYTE_DESCRIPTOR_SIZE; i++) {
850 		has_zeroes = has_zeroes && data[i] == 0;
851 	}
852 	if (!has_zeroes) {
853 		add_failure_until(edid, 4,
854 				  "Established timings III: Reserved bits must be set to zero.");
855 	}
856 }
857 
858 static bool
parse_color_point_descriptor(struct di_edid * edid,const uint8_t data[static EDID_BYTE_DESCRIPTOR_SIZE],struct di_edid_display_descriptor * desc)859 parse_color_point_descriptor(struct di_edid *edid,
860 			     const uint8_t data[static EDID_BYTE_DESCRIPTOR_SIZE],
861 			     struct di_edid_display_descriptor *desc)
862 {
863 	struct di_edid_color_point *c;
864 
865 	if (data[5] == 0) {
866 		add_failure(edid, "White Point Index Number set to reserved value 0");
867 	}
868 
869 	c = calloc(1, sizeof(*c));
870 	if (!c) {
871 		return false;
872 	}
873 
874 	c->index = data[5];
875 	c->white_x = decode_chromaticity_coord(data[7], get_bit_range(data[6], 3, 2));
876 	c->white_y = decode_chromaticity_coord(data[8], get_bit_range(data[6], 1, 0));
877 
878 	if (data[9] != 0xFF) {
879 		c->gamma = ((float) data[9] + 100) / 100;
880 	}
881 
882 	desc->color_points[desc->color_points_len++] = c;
883 	if (data[10] == 0)  {
884 		return true;
885 	}
886 
887 	c = calloc(1, sizeof(*c));
888 	if (!c) {
889 		return false;
890 	}
891 
892 	c->index = data[10];
893 	c->white_x = decode_chromaticity_coord(data[12], get_bit_range(data[11], 3, 2));
894 	c->white_y = decode_chromaticity_coord(data[13], get_bit_range(data[11], 1, 0));
895 
896 	if (data[14] != 0xFF) {
897 		c->gamma = ((float) data[14] + 100) / 100;
898 	}
899 
900 	desc->color_points[desc->color_points_len++] = c;
901 	return true;
902 }
903 
904 static void
parse_color_management_data_descriptor(struct di_edid * edid,const uint8_t data[static EDID_BYTE_DESCRIPTOR_SIZE],struct di_edid_display_descriptor * desc)905 parse_color_management_data_descriptor(struct di_edid *edid,
906 				       const uint8_t data[static EDID_BYTE_DESCRIPTOR_SIZE],
907 				       struct di_edid_display_descriptor *desc)
908 {
909 	desc->dcm_data.version = data[5];
910 
911 	desc->dcm_data.red_a3 = (uint16_t)(data[6] | (data[7] << 8)) / 100.0f;
912 	desc->dcm_data.red_a2 = (uint16_t)(data[8] | (data[9] << 8)) / 100.0f;
913 	desc->dcm_data.green_a3 = (uint16_t)(data[10] | (data[11] << 8)) / 100.0f;
914 	desc->dcm_data.green_a2 = (uint16_t)(data[12] | (data[13] << 8)) / 100.0f;
915 	desc->dcm_data.blue_a3 = (uint16_t)(data[14] | (data[15] << 8)) / 100.0f;
916 	desc->dcm_data.blue_a2 = (uint16_t)(data[16] | (data[17] << 8)) / 100.0f;
917 
918 	if (desc->dcm_data.version != 3) {
919 		add_failure_until(edid, 4,
920 				  "Color Management Data version must be 3");
921 	}
922 }
923 
924 static bool
is_cvt_timing_code_preferred_vrate_supported(const struct di_edid_cvt_timing_code * t)925 is_cvt_timing_code_preferred_vrate_supported(const struct di_edid_cvt_timing_code *t)
926 {
927 	switch (t->preferred_vertical_rate) {
928 	case DI_EDID_CVT_TIMING_CODE_PREFERRED_VRATE_50HZ:
929 		return t->supports_50hz_sb;
930 	case DI_EDID_CVT_TIMING_CODE_PREFERRED_VRATE_60HZ:
931 		return t->supports_60hz_sb || t->supports_60hz_rb;
932 	case DI_EDID_CVT_TIMING_CODE_PREFERRED_VRATE_75HZ:
933 		return t->supports_75hz_sb;
934 	case DI_EDID_CVT_TIMING_CODE_PREFERRED_VRATE_85HZ:
935 		return t->supports_85hz_sb;
936 	}
937 	abort(); /* unreachable */
938 }
939 
940 static bool
parse_cvt_timing_code(struct di_edid * edid,const uint8_t data[static EDID_CVT_TIMING_CODE_SIZE],struct di_edid_cvt_timing_code ** out,bool first)941 parse_cvt_timing_code(struct di_edid *edid,
942 		      const uint8_t data[static EDID_CVT_TIMING_CODE_SIZE],
943 		      struct di_edid_cvt_timing_code **out,
944 		      bool first)
945 {
946 	struct di_edid_cvt_timing_code *t;
947 	int32_t raw;
948 
949 	*out = NULL;
950 
951 	if (!first && data[0] == 0 && data[1] == 0 && data[2] == 0) {
952 		/* Unused */
953 		return true;
954 	}
955 	if (data[0] == 0) {
956 		add_failure(edid,
957 			    "CVT byte 0 is 0, which is a reserved value.");
958 	}
959 
960 	t = calloc(1, sizeof(*t));
961 	if (!t) {
962 		return false;
963 	}
964 
965 	raw = (int32_t)(data[0] | (get_bit_range(data[1], 7, 4) << 8));
966 	t->addressable_lines_per_field = (raw + 1) * 2;
967 	t->aspect_ratio = get_bit_range(data[1], 3, 2);
968 
969 	if (get_bit_range(data[1], 1, 0) != 0) {
970 		add_failure(edid,
971 			    "Reserved bits of CVT byte 1 are non-zero.");
972 	}
973 
974 	t->supports_50hz_sb = has_bit(data[2], 4);
975 	t->supports_60hz_sb = has_bit(data[2], 3);
976 	t->supports_75hz_sb = has_bit(data[2], 2);
977 	t->supports_85hz_sb = has_bit(data[2], 1);
978 	t->supports_60hz_rb = has_bit(data[2], 0);
979 
980 	if (get_bit_range(data[2], 4, 0) == 0) {
981 		add_failure(edid,
982 			    "CVT byte 2 does not support any vertical rates.");
983 	}
984 
985 	t->preferred_vertical_rate = get_bit_range(data[2], 6, 5);
986 
987 	if (has_bit(data[2], 7) != 0) {
988 		add_failure(edid,
989 			    "Reserved bit of CVT byte 2 is non-zero.");
990 	}
991 
992 	if (!is_cvt_timing_code_preferred_vrate_supported(t))
993 		add_failure(edid, "The preferred CVT Vertical Rate is not supported.");
994 
995 	*out = t;
996 	return true;
997 }
998 
999 static bool
parse_cvt_timing_codes_descriptor(struct di_edid * edid,const uint8_t data[static EDID_BYTE_DESCRIPTOR_SIZE],struct di_edid_display_descriptor * desc)1000 parse_cvt_timing_codes_descriptor(struct di_edid *edid,
1001 				  const uint8_t data[static EDID_BYTE_DESCRIPTOR_SIZE],
1002 				  struct di_edid_display_descriptor *desc)
1003 {
1004 	struct di_edid_cvt_timing_code *t;
1005 	size_t i;
1006 	const uint8_t *timing_data;
1007 
1008 	if (data[5] != 1) {
1009 		add_failure_until(edid, 4, "Invalid version number %u.",
1010 				  data[5]);
1011 	}
1012 
1013 	for (i = 0; i < EDID_MAX_DESCRIPTOR_CVT_TIMING_CODES_COUNT; i++) {
1014 		timing_data = &data[6 + i * EDID_CVT_TIMING_CODE_SIZE];
1015 		if (!parse_cvt_timing_code(edid, timing_data, &t, !i))
1016 			return false;
1017 		if (t) {
1018 			assert(desc->cvt_timing_codes_len < EDID_MAX_DESCRIPTOR_CVT_TIMING_CODES_COUNT);
1019 			desc->cvt_timing_codes[desc->cvt_timing_codes_len++] = t;
1020 		}
1021 	}
1022 
1023 	return true;
1024 }
1025 
1026 static bool
parse_byte_descriptor(struct di_edid * edid,const uint8_t data[static EDID_BYTE_DESCRIPTOR_SIZE])1027 parse_byte_descriptor(struct di_edid *edid,
1028 		      const uint8_t data[static EDID_BYTE_DESCRIPTOR_SIZE])
1029 {
1030 	struct di_edid_display_descriptor *desc;
1031 	struct di_edid_detailed_timing_def_priv *detailed_timing_def;
1032 	uint8_t tag;
1033 	char *newline;
1034 
1035 	if (data[0] || data[1]) {
1036 		if (edid->display_descriptors_len > 0) {
1037 			/* A detailed timing descriptor is not allowed after a
1038 			 * display descriptor per note 3 of table 3.20. */
1039 			add_failure(edid, "Invalid detailed timing descriptor ordering.");
1040 		}
1041 
1042 		detailed_timing_def = _di_edid_parse_detailed_timing_def(data);
1043 		if (!detailed_timing_def) {
1044 			return false;
1045 		}
1046 
1047 		assert(edid->detailed_timing_defs_len < EDID_BYTE_DESCRIPTOR_COUNT);
1048 		edid->detailed_timing_defs[edid->detailed_timing_defs_len++] = detailed_timing_def;
1049 		return true;
1050 	}
1051 
1052 	if (edid->revision >= 3 && edid->revision <= 4 &&
1053 	    edid->detailed_timing_defs_len == 0) {
1054 		/* Per section 3.10.1 */
1055 		add_failure(edid,
1056 			    "The first byte descriptor must contain the preferred timing.");
1057 	}
1058 
1059 	desc = calloc(1, sizeof(*desc));
1060 	if (!desc) {
1061 		return false;
1062 	}
1063 
1064 	tag = data[3];
1065 	switch (tag) {
1066 	case DI_EDID_DISPLAY_DESCRIPTOR_PRODUCT_SERIAL:
1067 	case DI_EDID_DISPLAY_DESCRIPTOR_DATA_STRING:
1068 	case DI_EDID_DISPLAY_DESCRIPTOR_PRODUCT_NAME:
1069 		memcpy(desc->str, &data[5], 13);
1070 
1071 		/* A newline (if any) indicates the end of the string. */
1072 		newline = strchr(desc->str, '\n');
1073 		if (newline) {
1074 			newline[0] = '\0';
1075 		}
1076 		break;
1077 	case DI_EDID_DISPLAY_DESCRIPTOR_RANGE_LIMITS:
1078 		if (!parse_display_range_limits(edid, data, &desc->range_limits)) {
1079 			free(desc);
1080 			return true;
1081 		}
1082 		break;
1083 	case DI_EDID_DISPLAY_DESCRIPTOR_STD_TIMING_IDS:
1084 		if (!parse_standard_timings_descriptor(edid, data, desc)) {
1085 			free(desc);
1086 			return false;
1087 		}
1088 		break;
1089 	case DI_EDID_DISPLAY_DESCRIPTOR_ESTABLISHED_TIMINGS_III:
1090 		parse_established_timings_iii_descriptor(edid, data, desc);
1091 		break;
1092 	case DI_EDID_DISPLAY_DESCRIPTOR_COLOR_POINT:
1093 		if (!parse_color_point_descriptor(edid, data, desc)) {
1094 			free(desc);
1095 			return false;
1096 		}
1097 		break;
1098 	case DI_EDID_DISPLAY_DESCRIPTOR_DCM_DATA:
1099 		parse_color_management_data_descriptor(edid, data, desc);
1100 		break;
1101 	case DI_EDID_DISPLAY_DESCRIPTOR_CVT_TIMING_CODES:
1102 		if (!parse_cvt_timing_codes_descriptor(edid, data, desc)) {
1103 			free(desc);
1104 			return false;
1105 		}
1106 		break;
1107 	case DI_EDID_DISPLAY_DESCRIPTOR_DUMMY:
1108 		break; /* Ignore */
1109 	default:
1110 		free(desc);
1111 		if (tag <= 0x0F) {
1112 			/* Manufacturer-specific */
1113 		} else {
1114 			add_failure_until(edid, 4, "Unknown Type 0x%02hhx.", tag);
1115 		}
1116 		return true;
1117 	}
1118 
1119 	desc->tag = tag;
1120 	assert(edid->display_descriptors_len < EDID_BYTE_DESCRIPTOR_COUNT);
1121 	edid->display_descriptors[edid->display_descriptors_len++] = desc;
1122 	return true;
1123 }
1124 
1125 static bool
parse_ext(struct di_edid * edid,const uint8_t data[static EDID_BLOCK_SIZE])1126 parse_ext(struct di_edid *edid, const uint8_t data[static EDID_BLOCK_SIZE])
1127 {
1128 	struct di_edid_ext *ext;
1129 	uint8_t tag;
1130 	struct di_logger logger;
1131 	char section_name[64];
1132 
1133 	if (!validate_block_checksum(data)) {
1134 		errno = EINVAL;
1135 		return false;
1136 	}
1137 
1138 	ext = calloc(1, sizeof(*ext));
1139 	if (!ext) {
1140 		return false;
1141 	}
1142 
1143 	tag = data[0x00];
1144 	switch (tag) {
1145 	case DI_EDID_EXT_CEA:
1146 		snprintf(section_name, sizeof(section_name),
1147 			 "Block %zu, CTA-861 Extension Block",
1148 			 edid->exts_len + 1);
1149 		logger = (struct di_logger) {
1150 			.f = edid->logger->f,
1151 			.section = section_name,
1152 		};
1153 
1154 		if (!_di_edid_cta_parse(&ext->cta, data, EDID_BLOCK_SIZE, &logger)) {
1155 			free(ext);
1156 			return errno == EINVAL;
1157 		}
1158 		break;
1159 	case DI_EDID_EXT_VTB:
1160 	case DI_EDID_EXT_DI:
1161 	case DI_EDID_EXT_LS:
1162 	case DI_EDID_EXT_DPVL:
1163 	case DI_EDID_EXT_BLOCK_MAP:
1164 	case DI_EDID_EXT_VENDOR:
1165 		/* Supported */
1166 		break;
1167 	case DI_EDID_EXT_DISPLAYID:
1168 		snprintf(section_name, sizeof(section_name),
1169 			 "Block %zu, DisplayID Extension Block",
1170 			 edid->exts_len + 1);
1171 		logger = (struct di_logger) {
1172 			.f = edid->logger->f,
1173 			.section = section_name,
1174 		};
1175 
1176 		if (!_di_displayid_parse(&ext->displayid, &data[1],
1177 					 EDID_BLOCK_SIZE - 2, &logger)) {
1178 			free(ext);
1179 			return errno == ENOTSUP || errno == EINVAL;
1180 		}
1181 		break;
1182 	default:
1183 		/* Unsupported */
1184 		free(ext);
1185 		add_failure_until(edid, 4, "Unknown Extension Block.");
1186 		return true;
1187 	}
1188 
1189 	ext->tag = tag;
1190 	assert(edid->exts_len < EDID_MAX_BLOCK_COUNT - 1);
1191 	edid->exts[edid->exts_len++] = ext;
1192 	return true;
1193 }
1194 
1195 struct di_edid *
_di_edid_parse(const void * data,size_t size,FILE * failure_msg_file)1196 _di_edid_parse(const void *data, size_t size, FILE *failure_msg_file)
1197 {
1198 	struct di_edid *edid;
1199 	struct di_logger logger;
1200 	int version, revision;
1201 	size_t exts_len, parsed_ext_len, i;
1202 	const uint8_t *standard_timing_data, *byte_desc_data, *ext_data;
1203 	struct di_edid_standard_timing *standard_timing;
1204 
1205 	if (size < EDID_BLOCK_SIZE) {
1206 		errno = EINVAL;
1207 		return NULL;
1208 	}
1209 
1210 	if (memcmp(data, header, sizeof(header)) != 0) {
1211 		errno = EINVAL;
1212 		return NULL;
1213 	}
1214 
1215 	parse_version_revision(data, &version, &revision);
1216 	if (version != 1) {
1217 		/* Only EDID version 1 is supported -- as per section 2.1.7
1218 		 * subsequent versions break the structure */
1219 		errno = ENOTSUP;
1220 		return NULL;
1221 	}
1222 
1223 	if (!validate_block_checksum(data)) {
1224 		errno = EINVAL;
1225 		return NULL;
1226 	}
1227 
1228 	edid = calloc(1, sizeof(*edid));
1229 	if (!edid) {
1230 		return NULL;
1231 	}
1232 
1233 	logger = (struct di_logger) {
1234 		.f = failure_msg_file,
1235 		.section = "Block 0, Base EDID",
1236 	};
1237 	edid->logger = &logger;
1238 
1239 	edid->version = version;
1240 	edid->revision = revision;
1241 
1242 	if (size % EDID_BLOCK_SIZE != 0)
1243 		add_failure(edid, "The data is not a multiple of the block size.");
1244 	if (size > EDID_MAX_BLOCK_COUNT * EDID_BLOCK_SIZE)
1245 		add_failure(edid, "The data is exceeding the maximum block count.");
1246 
1247 	exts_len = (size / EDID_BLOCK_SIZE) - 1;
1248 	parsed_ext_len = parse_ext_count(data);
1249 
1250 	if (exts_len != parsed_ext_len)
1251 		add_failure(edid, "The data size does not match the encoded block count.");
1252 
1253 	if (parsed_ext_len < exts_len)
1254 		exts_len = parsed_ext_len;
1255 
1256 	assert(exts_len < EDID_MAX_BLOCK_COUNT);
1257 
1258 	parse_vendor_product(edid, data);
1259 	parse_basic_params_features(edid, data);
1260 	parse_chromaticity_coords(edid, data);
1261 
1262 	parse_established_timings_i_ii(edid, data);
1263 
1264 	for (i = 0; i < EDID_MAX_STANDARD_TIMING_COUNT; i++) {
1265 		standard_timing_data = (const uint8_t *) data
1266 				       + 0x26 + i * EDID_STANDARD_TIMING_SIZE;
1267 		if (!parse_standard_timing(edid, standard_timing_data,
1268 					   &standard_timing)) {
1269 			_di_edid_destroy(edid);
1270 			return NULL;
1271 		}
1272 		if (standard_timing) {
1273 			assert(edid->standard_timings_len < EDID_MAX_STANDARD_TIMING_COUNT);
1274 			edid->standard_timings[edid->standard_timings_len++] = standard_timing;
1275 		}
1276 	}
1277 
1278 	for (i = 0; i < EDID_BYTE_DESCRIPTOR_COUNT; i++) {
1279 		byte_desc_data = (const uint8_t *) data
1280 			       + 0x36 + i * EDID_BYTE_DESCRIPTOR_SIZE;
1281 		if (!parse_byte_descriptor(edid, byte_desc_data)) {
1282 			_di_edid_destroy(edid);
1283 			return NULL;
1284 		}
1285 	}
1286 
1287 	for (i = 0; i < exts_len; i++) {
1288 		ext_data = (const uint8_t *) data + (i + 1) * EDID_BLOCK_SIZE;
1289 		if (!parse_ext(edid, ext_data)) {
1290 			_di_edid_destroy(edid);
1291 			return NULL;
1292 		}
1293 	}
1294 
1295 	edid->logger = NULL;
1296 	return edid;
1297 }
1298 
1299 static void
destroy_display_descriptor(struct di_edid_display_descriptor * desc)1300 destroy_display_descriptor(struct di_edid_display_descriptor *desc)
1301 {
1302 	size_t i;
1303 
1304 	switch (desc->tag) {
1305 	case DI_EDID_DISPLAY_DESCRIPTOR_STD_TIMING_IDS:
1306 		for (i = 0; i < desc->standard_timings_len; i++) {
1307 			free(desc->standard_timings[i]);
1308 		}
1309 		break;
1310 	case DI_EDID_DISPLAY_DESCRIPTOR_COLOR_POINT:
1311 		for (i = 0; i < desc->color_points_len; i++) {
1312 			free(desc->color_points[i]);
1313 		}
1314 		break;
1315 	case DI_EDID_DISPLAY_DESCRIPTOR_CVT_TIMING_CODES:
1316 		for (i = 0; i < desc->cvt_timing_codes_len; i++) {
1317 			free(desc->cvt_timing_codes[i]);
1318 		}
1319 		break;
1320 	default:
1321 		break; /* Nothing to do */
1322 	}
1323 	free(desc);
1324 }
1325 
1326 void
_di_edid_destroy(struct di_edid * edid)1327 _di_edid_destroy(struct di_edid *edid)
1328 {
1329 	size_t i;
1330 	struct di_edid_ext *ext;
1331 
1332 	for (i = 0; i < edid->standard_timings_len; i++) {
1333 		free(edid->standard_timings[i]);
1334 	}
1335 
1336 	for (i = 0; i < edid->detailed_timing_defs_len; i++) {
1337 		free(edid->detailed_timing_defs[i]);
1338 	}
1339 
1340 	for (i = 0; i < edid->display_descriptors_len; i++) {
1341 		destroy_display_descriptor(edid->display_descriptors[i]);
1342 	}
1343 
1344 	for (i = 0; edid->exts[i] != NULL; i++) {
1345 		ext = edid->exts[i];
1346 		switch (ext->tag) {
1347 		case DI_EDID_EXT_CEA:
1348 			_di_edid_cta_finish(&ext->cta);
1349 			break;
1350 		case DI_EDID_EXT_DISPLAYID:
1351 			_di_displayid_finish(&ext->displayid);
1352 			break;
1353 		default:
1354 			break; /* Nothing to do */
1355 		}
1356 		free(ext);
1357 	}
1358 
1359 	free(edid);
1360 }
1361 
1362 int
di_edid_get_version(const struct di_edid * edid)1363 di_edid_get_version(const struct di_edid *edid)
1364 {
1365 	return edid->version;
1366 }
1367 
1368 int
di_edid_get_revision(const struct di_edid * edid)1369 di_edid_get_revision(const struct di_edid *edid)
1370 {
1371 	return edid->revision;
1372 }
1373 
1374 const struct di_edid_vendor_product *
di_edid_get_vendor_product(const struct di_edid * edid)1375 di_edid_get_vendor_product(const struct di_edid *edid)
1376 {
1377 	return &edid->vendor_product;
1378 }
1379 
1380 const struct di_edid_video_input_analog *
di_edid_get_video_input_analog(const struct di_edid * edid)1381 di_edid_get_video_input_analog(const struct di_edid *edid)
1382 {
1383 	return edid->is_digital ? NULL : &edid->video_input_analog;
1384 }
1385 
1386 const struct di_edid_video_input_digital *
di_edid_get_video_input_digital(const struct di_edid * edid)1387 di_edid_get_video_input_digital(const struct di_edid *edid)
1388 {
1389 	return edid->is_digital ? &edid->video_input_digital : NULL;
1390 }
1391 
1392 const struct di_edid_screen_size *
di_edid_get_screen_size(const struct di_edid * edid)1393 di_edid_get_screen_size(const struct di_edid *edid)
1394 {
1395 	return &edid->screen_size;
1396 }
1397 
1398 float
di_edid_get_basic_gamma(const struct di_edid * edid)1399 di_edid_get_basic_gamma(const struct di_edid *edid)
1400 {
1401 	return edid->gamma;
1402 }
1403 
1404 const struct di_edid_dpms *
di_edid_get_dpms(const struct di_edid * edid)1405 di_edid_get_dpms(const struct di_edid *edid)
1406 {
1407 	return &edid->dpms;
1408 }
1409 
1410 enum di_edid_display_color_type
di_edid_get_display_color_type(const struct di_edid * edid)1411 di_edid_get_display_color_type(const struct di_edid *edid)
1412 {
1413 	return edid->display_color_type;
1414 }
1415 
1416 const struct di_edid_color_encoding_formats *
di_edid_get_color_encoding_formats(const struct di_edid * edid)1417 di_edid_get_color_encoding_formats(const struct di_edid *edid)
1418 {
1419 	/* If color encoding formats are specified, RGB 4:4:4 is always
1420 	 * supported. */
1421 	return edid->color_encoding_formats.rgb444 ? &edid->color_encoding_formats : NULL;
1422 }
1423 
1424 const struct di_edid_misc_features *
di_edid_get_misc_features(const struct di_edid * edid)1425 di_edid_get_misc_features(const struct di_edid *edid)
1426 {
1427 	return &edid->misc_features;
1428 }
1429 
1430 const struct di_edid_chromaticity_coords *
di_edid_get_chromaticity_coords(const struct di_edid * edid)1431 di_edid_get_chromaticity_coords(const struct di_edid *edid)
1432 {
1433 	return &edid->chromaticity_coords;
1434 }
1435 
1436 const struct di_edid_established_timings_i_ii *
di_edid_get_established_timings_i_ii(const struct di_edid * edid)1437 di_edid_get_established_timings_i_ii(const struct di_edid *edid)
1438 {
1439 	return &edid->established_timings_i_ii;
1440 }
1441 
1442 int32_t
di_edid_standard_timing_get_vert_video(const struct di_edid_standard_timing * t)1443 di_edid_standard_timing_get_vert_video(const struct di_edid_standard_timing *t)
1444 {
1445 	switch (t->aspect_ratio) {
1446 	case DI_EDID_STANDARD_TIMING_16_10:
1447 		return t->horiz_video * 10 / 16;
1448 	case DI_EDID_STANDARD_TIMING_4_3:
1449 		return t->horiz_video * 3 / 4;
1450 	case DI_EDID_STANDARD_TIMING_5_4:
1451 		return t->horiz_video * 4 / 5;
1452 	case DI_EDID_STANDARD_TIMING_16_9:
1453 		return t->horiz_video * 9 / 16;
1454 	}
1455 	abort(); /* unreachable */
1456 }
1457 
1458 const struct di_dmt_timing *
di_edid_standard_timing_get_dmt(const struct di_edid_standard_timing * t)1459 di_edid_standard_timing_get_dmt(const struct di_edid_standard_timing *t)
1460 {
1461 	int32_t vert_video;
1462 	size_t i;
1463 	const struct di_dmt_timing *dmt;
1464 
1465 	vert_video = di_edid_standard_timing_get_vert_video(t);
1466 
1467 	for (i = 0; i < _di_dmt_timings_len; i++) {
1468 		dmt = &_di_dmt_timings[i];
1469 
1470 		if (dmt->horiz_video == t->horiz_video
1471 		    && dmt->vert_video == vert_video
1472 		    && dmt->refresh_rate_hz == (float)t->refresh_rate_hz
1473 		    && dmt->edid_std_id != 0) {
1474 			return dmt;
1475 		}
1476 	}
1477 
1478 	return 0;
1479 }
1480 
1481 const struct di_edid_standard_timing *const *
di_edid_get_standard_timings(const struct di_edid * edid)1482 di_edid_get_standard_timings(const struct di_edid *edid)
1483 {
1484 	return (const struct di_edid_standard_timing *const *) &edid->standard_timings;
1485 }
1486 
1487 const struct di_edid_detailed_timing_def *const *
di_edid_get_detailed_timing_defs(const struct di_edid * edid)1488 di_edid_get_detailed_timing_defs(const struct di_edid *edid)
1489 {
1490 	return (const struct di_edid_detailed_timing_def *const *) &edid->detailed_timing_defs;
1491 }
1492 
1493 const struct di_edid_display_descriptor *const *
di_edid_get_display_descriptors(const struct di_edid * edid)1494 di_edid_get_display_descriptors(const struct di_edid *edid)
1495 {
1496 	return (const struct di_edid_display_descriptor *const *) &edid->display_descriptors;
1497 }
1498 
1499 enum di_edid_display_descriptor_tag
di_edid_display_descriptor_get_tag(const struct di_edid_display_descriptor * desc)1500 di_edid_display_descriptor_get_tag(const struct di_edid_display_descriptor *desc)
1501 {
1502 	return desc->tag;
1503 }
1504 
1505 const char *
di_edid_display_descriptor_get_string(const struct di_edid_display_descriptor * desc)1506 di_edid_display_descriptor_get_string(const struct di_edid_display_descriptor *desc)
1507 {
1508 	switch (desc->tag) {
1509 	case DI_EDID_DISPLAY_DESCRIPTOR_PRODUCT_SERIAL:
1510 	case DI_EDID_DISPLAY_DESCRIPTOR_DATA_STRING:
1511 	case DI_EDID_DISPLAY_DESCRIPTOR_PRODUCT_NAME:
1512 		return desc->str;
1513 	default:
1514 		return NULL;
1515 	}
1516 }
1517 
1518 const struct di_edid_display_range_limits *
di_edid_display_descriptor_get_range_limits(const struct di_edid_display_descriptor * desc)1519 di_edid_display_descriptor_get_range_limits(const struct di_edid_display_descriptor *desc)
1520 {
1521 	if (desc->tag != DI_EDID_DISPLAY_DESCRIPTOR_RANGE_LIMITS) {
1522 		return NULL;
1523 	}
1524 	return &desc->range_limits.base;
1525 }
1526 
1527 const struct di_edid_standard_timing *const *
di_edid_display_descriptor_get_standard_timings(const struct di_edid_display_descriptor * desc)1528 di_edid_display_descriptor_get_standard_timings(const struct di_edid_display_descriptor *desc)
1529 {
1530 	if (desc->tag != DI_EDID_DISPLAY_DESCRIPTOR_STD_TIMING_IDS) {
1531 		return NULL;
1532 	}
1533 	return (const struct di_edid_standard_timing *const *) desc->standard_timings;
1534 }
1535 
1536 const struct di_edid_color_point *const *
di_edid_display_descriptor_get_color_points(const struct di_edid_display_descriptor * desc)1537 di_edid_display_descriptor_get_color_points(const struct di_edid_display_descriptor *desc)
1538 {
1539 	if (desc->tag != DI_EDID_DISPLAY_DESCRIPTOR_COLOR_POINT) {
1540 		return NULL;
1541 	}
1542 	return (const struct di_edid_color_point *const *) desc->color_points;
1543 }
1544 
1545 const struct di_dmt_timing *const *
di_edid_display_descriptor_get_established_timings_iii(const struct di_edid_display_descriptor * desc)1546 di_edid_display_descriptor_get_established_timings_iii(const struct di_edid_display_descriptor *desc)
1547 {
1548 	if (desc->tag != DI_EDID_DISPLAY_DESCRIPTOR_ESTABLISHED_TIMINGS_III) {
1549 		return NULL;
1550 	}
1551 	return desc->established_timings_iii;
1552 }
1553 
1554 const struct di_edid_color_management_data *
di_edid_display_descriptor_get_color_management_data(const struct di_edid_display_descriptor * desc)1555 di_edid_display_descriptor_get_color_management_data(const struct di_edid_display_descriptor *desc)
1556 {
1557 	if (desc->tag != DI_EDID_DISPLAY_DESCRIPTOR_DCM_DATA) {
1558 		return NULL;
1559 	}
1560 	return &desc->dcm_data;
1561 }
1562 
1563 const struct di_edid_cvt_timing_code *const *
di_edid_display_descriptor_get_cvt_timing_codes(const struct di_edid_display_descriptor * desc)1564 di_edid_display_descriptor_get_cvt_timing_codes(const struct di_edid_display_descriptor *desc)
1565 {
1566 	if (desc->tag != DI_EDID_DISPLAY_DESCRIPTOR_CVT_TIMING_CODES) {
1567 		return NULL;
1568 	}
1569 	return (const struct di_edid_cvt_timing_code *const *) desc->cvt_timing_codes;
1570 }
1571 
1572 const struct di_edid_ext *const *
di_edid_get_extensions(const struct di_edid * edid)1573 di_edid_get_extensions(const struct di_edid *edid)
1574 {
1575 	return (const struct di_edid_ext *const *) edid->exts;
1576 }
1577 
1578 enum di_edid_ext_tag
di_edid_ext_get_tag(const struct di_edid_ext * ext)1579 di_edid_ext_get_tag(const struct di_edid_ext *ext)
1580 {
1581 	return ext->tag;
1582 }
1583 
1584 const struct di_edid_cta *
di_edid_ext_get_cta(const struct di_edid_ext * ext)1585 di_edid_ext_get_cta(const struct di_edid_ext *ext)
1586 {
1587 	if (ext->tag != DI_EDID_EXT_CEA) {
1588 		return NULL;
1589 	}
1590 	return &ext->cta;
1591 }
1592 
1593 const struct di_displayid *
di_edid_ext_get_displayid(const struct di_edid_ext * ext)1594 di_edid_ext_get_displayid(const struct di_edid_ext *ext)
1595 {
1596 	if (ext->tag != DI_EDID_EXT_DISPLAYID) {
1597 		return NULL;
1598 	}
1599 	return &ext->displayid;
1600 }
1601