1 /* vim: set et fde fdm=syntax ft=c.doxygen ts=4 sts=4 sw=4 : */
3 * Copyright © 2010-2011 Saleem Abdulrasool <compnerd@compnerd.org>.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
20 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
22 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 #include "xil_assert.h"
37 #include "xvidc_cea861.h"
39 #define XVIDC_EDID_BLOCK_SIZE (0x80)
40 #define XVIDC_EDID_MAX_EXTENSIONS (0xFE)
43 static const u8 XVIDC_EDID_EXT_HEADER[] =
44 { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 };
45 static const u8 XVIDC_EDID_STANDARD_TIMING_DESCRIPTOR_INVALID[] =
48 enum xvidc_edid_extension_type {
49 XVIDC_EDID_EXTENSION_TIMING = 0x01, /* Timing Extension */
50 XVIDC_EDID_EXTENSION_CEA = 0x02, /* Additional Timing Block
51 Data (CEA EDID Timing Extension)*/
52 XVIDC_EDID_EXTENSION_VTB = 0x10, /* Video Timing Block
54 XVIDC_EDID_EXTENSION_XVIDC_EDID_2_0= 0x20, /* EDID 2.0 Extension */
55 XVIDC_EDID_EXTENSION_DI = 0x40, /* Display Information
57 XVIDC_EDID_EXTENSION_LS = 0x50, /* Localised String
59 XVIDC_EDID_EXTENSION_MI = 0x60, /* Microdisplay Interface
61 XVIDC_EDID_EXTENSION_DTCDB_1 = 0xA7, /* Display Transfer
62 Characteristics Data Block (DTCDB) */
63 XVIDC_EDID_EXTENSION_DTCDB_2 = 0xAF,
64 XVIDC_EDID_EXTENSION_DTCDB_3 = 0xBF,
65 XVIDC_EDID_EXTENSION_BLOCK_MAP = 0xF0, /* Block Map*/
66 XVIDC_EDID_EXTENSION_DDDB = 0xFF, /* Display Device Data
70 enum xvidc_edid_display_type {
71 XVIDC_EDID_DISPLAY_TYPE_MONOCHROME,
72 XVIDC_EDID_DISPLAY_TYPE_RGB,
73 XVIDC_EDID_DISPLAY_TYPE_NON_RGB,
74 XVIDC_EDID_DISPLAY_TYPE_UNDEFINED,
77 enum xvidc_edid_aspect_ratio {
78 XVIDC_EDID_ASPECT_RATIO_16_10,
79 XVIDC_EDID_ASPECT_RATIO_4_3,
80 XVIDC_EDID_ASPECT_RATIO_5_4,
81 XVIDC_EDID_ASPECT_RATIO_16_9,
84 enum xvidc_edid_signal_sync {
85 XVIDC_EDID_SIGNAL_SYNC_ANALOG_COMPOSITE,
86 XVIDC_EDID_SIGNAL_SYNC_BIPOLAR_ANALOG_COMPOSITE,
87 XVIDC_EDID_SIGNAL_SYNC_DIGITAL_COMPOSITE,
88 XVIDC_EDID_SIGNAL_SYNC_DIGITAL_SEPARATE,
91 enum xvidc_edid_stereo_mode {
92 XVIDC_EDID_STEREO_MODE_NONE,
93 XVIDC_EDID_STEREO_MODE_RESERVED,
94 XVIDC_EDID_STEREO_MODE_FIELD_SEQUENTIAL_RIGHT,
95 XVIDC_EDID_STEREO_MODE_2_WAY_INTERLEAVED_RIGHT,
96 XVIDC_EDID_STEREO_MODE_FIELD_SEQUENTIAL_LEFT,
97 XVIDC_EDID_STEREO_MODE_2_WAY_INTERLEAVED_LEFT,
98 XVIDC_EDID_STEREO_MODE_4_WAY_INTERLEAVED,
99 XVIDC_EDID_STEREO_MODE_SIDE_BY_SIDE_INTERLEAVED,
102 enum xvidc_edid_monitor_descriptor_type {
103 XVIDC_EDID_MONTIOR_DESCRIPTOR_MANUFACTURER_DEFINED = 0x0F,
104 XVIDC_EDID_MONITOR_DESCRIPTOR_STANDARD_TIMING_IDENTIFIERS = 0xFA,
105 XVIDC_EDID_MONITOR_DESCRIPTOR_COLOR_POINT = 0xFB,
106 XVIDC_EDID_MONITOR_DESCRIPTOR_MONITOR_NAME = 0xFC,
107 XVIDC_EDID_MONITOR_DESCRIPTOR_MONITOR_RANGE_LIMITS = 0xFD,
108 XVIDC_EDID_MONITOR_DESCRIPTOR_ASCII_STRING = 0xFE,
109 XVIDC_EDID_MONITOR_DESCRIPTOR_MONITOR_SERIAL_NUMBER = 0xFF,
112 enum xvidc_edid_secondary_timing_support {
113 XVIDC_EDID_SECONDARY_TIMING_NOT_SUPPORTED,
114 XVIDC_EDID_SECONDARY_TIMING_GFT = 0x02,
118 struct __attribute__ (( packed )) xvidc_edid_detailed_timing_descriptor {
119 u16 pixel_clock; /* = value * 10000 */
121 u8 horizontal_active_lo;
122 u8 horizontal_blanking_lo;
124 unsigned horizontal_blanking_hi : 4;
125 unsigned horizontal_active_hi : 4;
127 u8 vertical_active_lo;
128 u8 vertical_blanking_lo;
130 unsigned vertical_blanking_hi : 4;
131 unsigned vertical_active_hi : 4;
133 u8 horizontal_sync_offset_lo;
134 u8 horizontal_sync_pulse_width_lo;
136 unsigned vertical_sync_pulse_width_lo : 4;
137 unsigned vertical_sync_offset_lo : 4;
139 unsigned vertical_sync_pulse_width_hi : 2;
140 unsigned vertical_sync_offset_hi : 2;
141 unsigned horizontal_sync_pulse_width_hi : 2;
142 unsigned horizontal_sync_offset_hi : 2;
144 u8 horizontal_image_size_lo;
145 u8 vertical_image_size_lo;
147 unsigned vertical_image_size_hi : 4;
148 unsigned horizontal_image_size_hi : 4;
150 u8 horizontal_border;
153 unsigned stereo_mode_lo : 1;
154 unsigned signal_pulse_polarity : 1; /* pulse on sync,
155 composite/horizontal polarity */
156 unsigned signal_serration_polarity : 1; /* serrate on sync, vertical
158 unsigned signal_sync : 2;
159 unsigned stereo_mode_hi : 2;
160 unsigned interlaced : 1;
164 xvidc_edid_detailed_timing_pixel_clock
165 (const struct xvidc_edid_detailed_timing_descriptor * const dtb)
167 return dtb->pixel_clock * 10000;
171 xvidc_edid_detailed_timing_horizontal_blanking
172 (const struct xvidc_edid_detailed_timing_descriptor * const dtb)
174 return (dtb->horizontal_blanking_hi << 8) | dtb->horizontal_blanking_lo;
178 xvidc_edid_detailed_timing_horizontal_active
179 (const struct xvidc_edid_detailed_timing_descriptor * const dtb)
181 return (dtb->horizontal_active_hi << 8) | dtb->horizontal_active_lo;
185 xvidc_edid_detailed_timing_vertical_blanking
186 (const struct xvidc_edid_detailed_timing_descriptor * const dtb)
188 return (dtb->vertical_blanking_hi << 8) | dtb->vertical_blanking_lo;
192 xvidc_edid_detailed_timing_vertical_active
193 (const struct xvidc_edid_detailed_timing_descriptor * const dtb)
195 return (dtb->vertical_active_hi << 8) | dtb->vertical_active_lo;
199 xvidc_edid_detailed_timing_vertical_sync_offset
200 (const struct xvidc_edid_detailed_timing_descriptor * const dtb)
202 return (dtb->vertical_sync_offset_hi << 4) | dtb->vertical_sync_offset_lo;
206 xvidc_edid_detailed_timing_vertical_sync_pulse_width
207 (const struct xvidc_edid_detailed_timing_descriptor * const dtb)
209 return (dtb->vertical_sync_pulse_width_hi << 4) |
210 dtb->vertical_sync_pulse_width_lo;
214 xvidc_edid_detailed_timing_horizontal_sync_offset
215 (const struct xvidc_edid_detailed_timing_descriptor * const dtb)
217 return (dtb->horizontal_sync_offset_hi << 4) |
218 dtb->horizontal_sync_offset_lo;
222 xvidc_edid_detailed_timing_horizontal_sync_pulse_width
223 (const struct xvidc_edid_detailed_timing_descriptor * const dtb)
225 return (dtb->horizontal_sync_pulse_width_hi << 4) |
226 dtb->horizontal_sync_pulse_width_lo;
230 xvidc_edid_detailed_timing_horizontal_image_size
231 (const struct xvidc_edid_detailed_timing_descriptor * const dtb)
234 (dtb->horizontal_image_size_hi << 8) | dtb->horizontal_image_size_lo;
238 xvidc_edid_detailed_timing_vertical_image_size
239 (const struct xvidc_edid_detailed_timing_descriptor * const dtb)
241 return (dtb->vertical_image_size_hi << 8) | dtb->vertical_image_size_lo;
245 xvidc_edid_detailed_timing_stereo_mode
246 (const struct xvidc_edid_detailed_timing_descriptor * const dtb)
248 return (dtb->stereo_mode_hi << 2 | dtb->stereo_mode_lo);
252 struct __attribute__ (( packed )) xvidc_edid_monitor_descriptor {
260 typedef char xvidc_edid_monitor_descriptor_string
261 [sizeof(((struct xvidc_edid_monitor_descriptor *)0)->data) + 1];
264 struct __attribute__ (( packed )) xvidc_edid_monitor_range_limits {
265 u8 minimum_vertical_rate; /* Hz */
266 u8 maximum_vertical_rate; /* Hz */
267 u8 minimum_horizontal_rate; /* kHz */
268 u8 maximum_horizontal_rate; /* kHz */
269 u8 maximum_supported_pixel_clock; /* = (value * 10) Mhz
272 /* secondary timing formula */
273 u8 secondary_timing_support;
275 u8 secondary_curve_start_frequency; /* horizontal frequency / 2 kHz */
276 u8 c; /* = (value >> 1) */
279 u8 j; /* = (value >> 1) */
283 struct __attribute__ (( packed )) xvidc_edid_standard_timing_descriptor {
284 u8 horizontal_active_pixels; /* = (value + 31) * 8 */
286 unsigned refresh_rate : 6; /* = value + 60 */
287 unsigned image_aspect_ratio : 2;
291 xvidc_edid_standard_timing_horizontal_active
292 (const struct xvidc_edid_standard_timing_descriptor * const desc) {
293 return ((desc->horizontal_active_pixels + 31) << 3);
297 xvidc_edid_standard_timing_vertical_active
298 (const struct xvidc_edid_standard_timing_descriptor * const desc) {
299 const u32 hres = xvidc_edid_standard_timing_horizontal_active(desc);
301 switch (desc->image_aspect_ratio) {
302 case XVIDC_EDID_ASPECT_RATIO_16_10:
303 return ((hres * 10) >> 4);
304 case XVIDC_EDID_ASPECT_RATIO_4_3:
305 return ((hres * 3) >> 2);
306 case XVIDC_EDID_ASPECT_RATIO_5_4:
307 return ((hres << 2) / 5);
308 case XVIDC_EDID_ASPECT_RATIO_16_9:
309 return ((hres * 9) >> 4);
316 xvidc_edid_standard_timing_refresh_rate
317 (const struct xvidc_edid_standard_timing_descriptor * const desc) {
318 return (desc->refresh_rate + 60);
322 struct __attribute__ (( packed )) edid {
323 /* header information */
326 /* vendor/product identification */
333 u32 serial_number_u32;
337 u8 manufacture_year; /* = value + 1990 */
343 /* basic display parameters and features */
345 struct __attribute__ (( packed )) {
346 unsigned dfp_1x : 1; /* VESA DFP 1.x */
348 unsigned digital : 1;
350 struct __attribute__ (( packed )) {
351 unsigned vsync_serration : 1;
352 unsigned green_video_sync : 1;
353 unsigned composite_sync : 1;
354 unsigned separate_sync : 1;
355 unsigned blank_to_black_setup : 1;
356 unsigned signal_level_standard : 2;
357 unsigned digital : 1;
359 } video_input_definition;
361 u8 maximum_horizontal_image_size; /* cm */
362 u8 maximum_vertical_image_size; /* cm */
364 u8 display_transfer_characteristics; /* gamma = (value + 100) / 100 */
366 struct __attribute__ (( packed )) {
367 unsigned default_gtf : 1; /* generalised timing
369 unsigned preferred_timing_mode : 1;
370 unsigned standard_default_color_space : 1;
371 unsigned display_type : 2;
372 unsigned active_off : 1;
373 unsigned suspend : 1;
374 unsigned standby : 1;
377 /* color characteristics block */
378 unsigned green_y_low : 2;
379 unsigned green_x_low : 2;
380 unsigned red_y_low : 2;
381 unsigned red_x_low : 2;
383 unsigned white_y_low : 2;
384 unsigned white_x_low : 2;
385 unsigned blue_y_low : 2;
386 unsigned blue_x_low : 2;
397 /* established timings */
398 struct __attribute__ (( packed )) {
399 unsigned timing_800x600_60 : 1;
400 unsigned timing_800x600_56 : 1;
401 unsigned timing_640x480_75 : 1;
402 unsigned timing_640x480_72 : 1;
403 unsigned timing_640x480_67 : 1;
404 unsigned timing_640x480_60 : 1;
405 unsigned timing_720x400_88 : 1;
406 unsigned timing_720x400_70 : 1;
408 unsigned timing_1280x1024_75 : 1;
409 unsigned timing_1024x768_75 : 1;
410 unsigned timing_1024x768_70 : 1;
411 unsigned timing_1024x768_60 : 1;
412 unsigned timing_1024x768_87 : 1;
413 unsigned timing_832x624_75 : 1;
414 unsigned timing_800x600_75 : 1;
415 unsigned timing_800x600_72 : 1;
416 } established_timings;
418 struct __attribute__ (( packed )) {
419 unsigned reserved : 7;
420 unsigned timing_1152x870_75 : 1;
421 } manufacturer_timings;
423 /* standard timing id */
424 struct xvidc_edid_standard_timing_descriptor standard_timing_id[8];
426 /* detailed timing */
428 struct xvidc_edid_monitor_descriptor monitor;
429 struct xvidc_edid_detailed_timing_descriptor timing;
430 } detailed_timings[4];
437 xvidc_edid_manufacturer(const struct edid * const edid, char manufacturer[4])
439 manufacturer[0] = '@' + ((edid->manufacturer & 0x007c) >> 2);
440 manufacturer[1] = '@' + ((((edid->manufacturer & 0x0003) >> 00) << 3) | (((edid->manufacturer & 0xe000) >> 13) << 0));
441 manufacturer[2] = '@' + ((edid->manufacturer & 0x1f00) >> 8);
442 manufacturer[3] = '\0';
446 xvidc_edid_gamma(const struct edid * const edid)
448 return (edid->display_transfer_characteristics + 100) / 100.0;
452 xvidc_edid_detailed_timing_is_monitor_descriptor(const struct edid * const edid,
455 const struct xvidc_edid_monitor_descriptor * const mon =
456 &edid->detailed_timings[timing].monitor;
458 Xil_AssertNonvoid(timing < ARRAY_SIZE(edid->detailed_timings));
460 return mon->flag0 == 0x0000 && mon->flag1 == 0x00 && mon->flag2 == 0x00;
464 struct __attribute__ (( packed )) xvidc_edid_color_characteristics_data {
468 } red, green, blue, white;
471 static inline struct xvidc_edid_color_characteristics_data
472 xvidc_edid_color_characteristics(const struct edid * const edid)
474 const struct xvidc_edid_color_characteristics_data characteristics = {
476 .x = (edid->red_x << 2) | edid->red_x_low,
477 .y = (edid->red_y << 2) | edid->red_y_low,
480 .x = (edid->green_x << 2) | edid->green_x_low,
481 .y = (edid->green_y << 2) | edid->green_y_low,
484 .x = (edid->blue_x << 2) | edid->blue_x_low,
485 .y = (edid->blue_y << 2) | edid->blue_y_low,
488 .x = (edid->white_x << 2) | edid->white_x_low,
489 .y = (edid->white_y << 2) | edid->white_y_low,
493 return characteristics;
497 struct __attribute__ (( packed )) xvidc_edid_block_map {
499 u8 extension_tag[126];
504 struct __attribute__ (( packed )) xvidc_edid_extension {
507 u8 extension_data[125];
513 xvidc_edid_verify_checksum(const u8 * const block)
518 for (i = 0; i < XVIDC_EDID_BLOCK_SIZE; i++)
519 checksum += block[i];
521 return (checksum == 0);
525 xvidc_edid_decode_fixed_point(u16 value)
529 Xil_AssertNonvoid((~value & 0xfc00) == 0xfc00);
530 /* edid fraction is 10 bits */
532 for (u8 i = 0; value && (i < 10); i++, value >>= 1)
533 result = result + ((value & 0x1) * (1.0 / (1 << (10 - i))));
539 XVIDC_VERBOSE_DISABLE,
552 #if XVIDC_EDID_VERBOSITY > 1
562 } XV_VidC_PicAspectRatio;
569 XVidC_VideoFormat vidfrmt;
576 XV_VidC_PicAspectRatio aspect_ratio;
577 unsigned hsync_polarity : 1;
578 unsigned vsync_polarity : 1;
579 } XV_VidC_TimingParam;
582 /*Checks whether Sink able to support HDMI*/
583 XV_VidC_IsHdmi IsHdmi;
584 /*Color Space Support*/
585 XV_VidC_Supp IsYCbCr444Supp;
586 XV_VidC_Supp IsYCbCr420Supp;
587 XV_VidC_Supp IsYCbCr422Supp;
588 /*YCbCr444/YCbCr422/RGB444 Deep Color Support*/
589 XV_VidC_Supp IsYCbCr444DeepColSupp;
590 XV_VidC_Supp Is30bppSupp;
591 XV_VidC_Supp Is36bppSupp;
592 XV_VidC_Supp Is48bppSupp;
593 /*YCbCr420 Deep Color Support*/
594 XV_VidC_Supp IsYCbCr420dc30bppSupp;
595 XV_VidC_Supp IsYCbCr420dc36bppSupp;
596 XV_VidC_Supp IsYCbCr420dc48bppSupp;
597 /*SCDC and SCDC ReadRequest Support*/
598 XV_VidC_Supp IsSCDCReadRequestReady;
599 XV_VidC_Supp IsSCDCPresent;
600 /*Sink Capability Support*/
603 /*CEA 861 Supported VIC Support*/
605 /*VESA Sink Preffered Timing Support*/
606 XV_VidC_TimingParam PreferedTiming[4];
607 } XV_VidC_EdidCntrlParam;
612 (const struct xvidc_edid_detailed_timing_descriptor * const dtb);
613 #if XVIDC_EDID_VERBOSITY > 1
614 XV_VidC_DoubleRep Double2Int (double in_val);
616 void XV_VidC_EdidCtrlParamInit (XV_VidC_EdidCntrlParam *EdidCtrlParam);
619 XV_VidC_parse_edid(const u8 * const data,
620 XV_VidC_EdidCntrlParam *EdidCtrlParam,
621 XV_VidC_Verbose VerboseEn);