1 /* vim: set et fde fdm=syntax ft=c.doxygen ts=4 sts=4 sw=4 : */
3 * Copyright © 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.
34 #include "xil_types.h"
36 #include "xil_exception.h"
38 #include "xvidc_edid_ext.h"
40 #if XVIDC_EDID_VERBOSITY > 1
43 #define CM_2_MM(cm) ((cm) * 10)
44 #define CM_2_IN(cm) ((cm) * 0.3937)
46 #if XVIDC_EDID_VERBOSITY > 0
47 #define HZ_2_MHZ(hz) ((hz) / 1000000)
49 #if XVIDC_EDID_VERBOSITY > 1
51 xvidc_disp_cea861_audio_data(
52 const struct xvidc_cea861_audio_data_block * const adb,
53 XV_VidC_EdidCntrlParam *EdidCtrlParam,
54 XV_VidC_Verbose VerboseEn);
57 xvidc_disp_cea861_speaker_allocation_data(
58 const struct xvidc_cea861_speaker_allocation_data_block * const sadb,
59 XV_VidC_EdidCntrlParam *EdidCtrlParam,
60 XV_VidC_Verbose VerboseEn);
63 xvidc_disp_cea861_video_data(
64 const struct xvidc_cea861_video_data_block * const vdb,
65 XV_VidC_EdidCntrlParam *EdidCtrlParam,
66 XV_VidC_Verbose VerboseEn);
70 xvidc_disp_cea861_extended_data(
71 const struct xvidc_cea861_extended_data_block * const edb,
72 XV_VidC_EdidCntrlParam *EdidCtrlParam,
73 XV_VidC_Verbose VerboseEn);
76 xvidc_disp_cea861_vendor_data(
77 const struct xvidc_cea861_vendor_specific_data_block * vsdb,
78 XV_VidC_EdidCntrlParam *EdidCtrlParam,
79 XV_VidC_Verbose VerboseEn);
82 xvidc_disp_cea861(const struct xvidc_edid_extension * const ext,
83 XV_VidC_EdidCntrlParam *EdidCtrlParam,
84 XV_VidC_Verbose VerboseEn);
87 xvidc_disp_edid1(const struct edid * const edid,
88 XV_VidC_EdidCntrlParam *EdidCtrlParam,
89 XV_VidC_Verbose VerboseEn);
91 /*****************************************************************************/
94 * This function parse EDID on General Data & VESA Data
96 * @param data is a pointer to the EDID array.
97 * @param EdidCtrlParam is a pointer the EDID Control parameter
98 * @param VerboseEn is a pointer to the XV_HdmiTxSs core instance.
102 * @note API Define below here are CEA861 routines
104 ******************************************************************************/
106 xvidc_disp_edid1(const struct edid * const edid,
107 XV_VidC_EdidCntrlParam *EdidCtrlParam,
108 XV_VidC_Verbose VerboseEn)
110 const struct xvidc_edid_monitor_range_limits *monitor_range_limits = NULL;
111 xvidc_edid_monitor_descriptor_string monitor_serial_number = {0};
112 xvidc_edid_monitor_descriptor_string monitor_model_name = {0};
113 bool has_ascii_string = false;
114 char manufacturer[4] = {0};
115 #if XVIDC_EDID_VERBOSITY > 1
116 XV_VidC_DoubleRep min_doubleval;
117 XV_VidC_DoubleRep max_doubleval;
121 #if XVIDC_EDID_VERBOSITY > 0
123 XV_VidC_TimingParam timing_params;
126 #if XVIDC_EDID_VERBOSITY > 1
127 struct xvidc_edid_color_characteristics_data characteristics;
128 const u8 vlen = edid->maximum_vertical_image_size;
129 const u8 hlen = edid->maximum_horizontal_image_size;
132 static const char * const display_type[] = {
133 [XVIDC_EDID_DISPLAY_TYPE_MONOCHROME] = "Monochrome or greyscale",
134 [XVIDC_EDID_DISPLAY_TYPE_RGB] = "sRGB colour",
135 [XVIDC_EDID_DISPLAY_TYPE_NON_RGB] = "Non-sRGB colour",
136 [XVIDC_EDID_DISPLAY_TYPE_UNDEFINED] = "Undefined",
139 xvidc_edid_manufacturer(edid, manufacturer);
141 for (i = 0; i < ARRAY_SIZE(edid->detailed_timings); i++) {
142 const struct xvidc_edid_monitor_descriptor * const mon =
143 &edid->detailed_timings[i].monitor;
145 if (!xvidc_edid_detailed_timing_is_monitor_descriptor(edid, i))
149 case XVIDC_EDID_MONTIOR_DESCRIPTOR_MANUFACTURER_DEFINED:
150 /* This is arbitrary data, just silently ignore it. */
152 case XVIDC_EDID_MONITOR_DESCRIPTOR_ASCII_STRING:
153 has_ascii_string = true;
155 case XVIDC_EDID_MONITOR_DESCRIPTOR_MONITOR_NAME:
156 strncpy(monitor_model_name, (char *) mon->data,
157 sizeof(monitor_model_name) - 1);
159 case XVIDC_EDID_MONITOR_DESCRIPTOR_MONITOR_RANGE_LIMITS:
160 monitor_range_limits =
161 (struct xvidc_edid_monitor_range_limits *) &mon->data;
163 case XVIDC_EDID_MONITOR_DESCRIPTOR_MONITOR_SERIAL_NUMBER:
164 strncpy(monitor_serial_number, (char *) mon->data,
165 sizeof(monitor_serial_number) - 1);
169 xil_printf("unknown monitor descriptor type 0x%02x\n",
176 #if XVIDC_EDID_VERBOSITY > 0
178 xil_printf("Sink Information\r\n");
180 xil_printf(" Model name............... %s\r\n",
181 *monitor_model_name ? monitor_model_name : "n/a");
182 #if XVIDC_EDID_VERBOSITY > 1
183 xil_printf(" Manufacturer............. %s\r\n",
186 xil_printf(" Product code............. %u\r\n",
187 (u16) edid->product_u16);
189 if (*(u32 *) edid->serial_number_u32)
190 xil_printf(" Module serial number..... %u\r\n",
191 (u32) edid->serial_number_u32);
193 #if defined(DISPLAY_UNKNOWN)
194 xil_printf(" Plug and Play ID......... %s\r\n", NULL);
196 #if XVIDC_EDID_VERBOSITY > 1
197 xil_printf(" Serial number............ %s\r\n",
198 *monitor_serial_number ? monitor_serial_number : "n/a");
200 xil_printf(" Manufacture date......... %u",
201 edid->manufacture_year + 1990);
202 if (edid->manufacture_week <= 52)
203 xil_printf(", ISO week %u", edid->manufacture_week);
206 xil_printf(" EDID revision............ %u.%u\r\n",
207 edid->version, edid->revision);
208 #if XVIDC_EDID_VERBOSITY > 1
209 xil_printf(" Input signal type........ %s\r\n",
210 edid->video_input_definition.digital.digital ? "Digital" : "Analog");
212 if (edid->video_input_definition.digital.digital) {
213 xil_printf(" VESA DFP 1.x supported... %s\r\n",
214 edid->video_input_definition.digital.dfp_1x ? "Yes" : "No");
216 /* Missing Piece: To print analog flags */
219 #if defined(DISPLAY_UNKNOWN)
220 xil_printf(" Color bit depth.......... %s\r\n", NULL);
222 #if XVIDC_EDID_VERBOSITY > 1
223 xil_printf(" Display type............. %s\r\n",
224 display_type[edid->feature_support.display_type]);
226 xil_printf(" Screen size.............. %u mm x %u mm (%.1f in)\r\n",
227 CM_2_MM(hlen), CM_2_MM(vlen),
228 CM_2_IN(sqrt(hlen * hlen + vlen * vlen)));
230 xil_printf(" Power management......... %s%s%s%s\r\n",
231 edid->feature_support.active_off ? "Active off, " : "",
232 edid->feature_support.suspend ? "Suspend, " : "",
233 edid->feature_support.standby ? "Standby, " : "",
235 (edid->feature_support.active_off ||
236 edid->feature_support.suspend ||
237 edid->feature_support.standby) ? "\b\b " : "n/a");
239 xil_printf(" Extension blocks......... %u\r\n",
242 #if defined(DISPLAY_UNKNOWN)
243 xil_printf(" DDC/CI................... %s\r\n", NULL);
249 if (has_ascii_string) {
251 #if XVIDC_EDID_VERBOSITY > 1
252 xil_printf("General purpose ASCII string\r\n");
256 for (i = 0; i < ARRAY_SIZE(edid->detailed_timings); i++) {
257 if (!xvidc_edid_detailed_timing_is_monitor_descriptor(edid, i))
262 #if XVIDC_EDID_VERBOSITY > 1
267 #if XVIDC_EDID_VERBOSITY > 0
269 xil_printf("Color characteristics\r\n");
271 xil_printf(" Default color space...... %ssRGB\r\n",
272 edid->feature_support.standard_default_color_space ? "":"Non-");
273 #if XVIDC_EDID_VERBOSITY > 1
275 Double2Int(xvidc_edid_gamma(edid));
276 xil_printf(" Display gamma............ %d.%03d\r\n",
277 min_doubleval.Integer, min_doubleval.Decimal);
279 characteristics = xvidc_edid_color_characteristics(edid);
282 Double2Int(xvidc_edid_decode_fixed_point(characteristics.red.x));
284 Double2Int(xvidc_edid_decode_fixed_point(characteristics.red.y));
286 xil_printf(" Red chromaticity......... Rx %d.%03d - Ry %d.%03d\r\n",
287 min_doubleval.Integer, min_doubleval.Decimal,
288 max_doubleval.Integer, max_doubleval.Decimal);
291 Double2Int(xvidc_edid_decode_fixed_point(characteristics.green.x));
293 Double2Int(xvidc_edid_decode_fixed_point(characteristics.green.y));
295 xil_printf(" Green chromaticity....... Gx %d.%03d - Gy %d.%03d\r\n",
296 min_doubleval.Integer, min_doubleval.Decimal,
297 max_doubleval.Integer, max_doubleval.Decimal);
300 Double2Int(xvidc_edid_decode_fixed_point(characteristics.blue.x));
302 Double2Int(xvidc_edid_decode_fixed_point(characteristics.blue.y));
304 xil_printf(" Blue chromaticity........ Bx %d.%03d - By %d.%03d\r\n",
305 min_doubleval.Integer, min_doubleval.Decimal,
306 max_doubleval.Integer, max_doubleval.Decimal);
309 Double2Int(xvidc_edid_decode_fixed_point(characteristics.white.x));
311 Double2Int(xvidc_edid_decode_fixed_point(characteristics.white.y));
313 xil_printf(" White point (default).... Wx %d.%03d - Wy %d.%03d\r\n",
314 min_doubleval.Integer, min_doubleval.Decimal,
315 max_doubleval.Integer, max_doubleval.Decimal);
317 #if defined(DISPLAY_UNKNOWN)
318 xil_printf(" Additional descriptors... %s\r\n", NULL);
322 xil_printf("VESA Timing characteristics\r\n");
325 if (monitor_range_limits) {
326 #if XVIDC_EDID_VERBOSITY > 0
328 xil_printf(" Horizontal scan range.... %u - %u kHz\r\n",
329 monitor_range_limits->minimum_horizontal_rate,
330 monitor_range_limits->maximum_horizontal_rate);
332 xil_printf(" Vertical scan range...... %u - %u Hz\r\n",
333 monitor_range_limits->minimum_vertical_rate,
334 monitor_range_limits->maximum_vertical_rate);
336 xil_printf(" Video bandwidth.......... %u MHz\r\n",
337 monitor_range_limits->maximum_supported_pixel_clock * 10);
340 EdidCtrlParam->MaxFrameRateSupp =
341 monitor_range_limits->maximum_vertical_rate;
342 EdidCtrlParam->MaxTmdsMhz =
343 (monitor_range_limits->maximum_supported_pixel_clock * 10);
346 #if XVIDC_EDID_VERBOSITY > 0
348 #if defined(DISPLAY_UNKNOWN)
349 xil_printf(" CVT standard............. %s\r\n", NULL);
351 #if XVIDC_EDID_VERBOSITY > 1
352 xil_printf(" GTF standard............. %sSupported\r\n",
353 edid->feature_support.default_gtf ? "" : "Not ");
355 #if defined(DISPLAY_UNKNOWN)
356 xil_printf(" Additional descriptors... %s\r\n", NULL);
358 #if XVIDC_EDID_VERBOSITY > 0
359 xil_printf(" Preferred timing......... %s\r\n",
360 edid->feature_support.preferred_timing_mode ? "Yes" : "No");
362 for (i = 0; i < ARRAY_SIZE(edid->detailed_timings); i++) {
363 if (xvidc_edid_detailed_timing_is_monitor_descriptor(edid, i))
366 timing_params = XV_VidC_timing(&edid->detailed_timings[i].timing);
367 EdidCtrlParam->PreferedTiming[i] =
368 XV_VidC_timing(&edid->detailed_timings[i].timing);
369 #if XVIDC_EDID_VERBOSITY > 0
370 if (edid->feature_support.preferred_timing_mode) {
371 xil_printf(" Native/preferred timing.. %ux%u%c at %uHz"
375 timing_params.vidfrmt ? 'i' : 'p',
377 timing_params.aspect_ratio.width,
378 timing_params.aspect_ratio.height);
379 xil_printf(" Modeline............... \"%ux%u\" %u %u %u %u"
380 " %u %u %u %u %u %chsync %cvsync\r\n",
383 HZ_2_MHZ (timing_params.pixclk),
384 (timing_params.hres),
385 (timing_params.hres + timing_params.hfp),
386 (timing_params.hres + timing_params.hfp +
387 timing_params.hsync_width),
388 (timing_params.htotal),
389 (timing_params.vres),
390 (timing_params.vres + timing_params.vfp),
391 (timing_params.vres + timing_params.vfp +
392 timing_params.vsync_width),
393 (timing_params.vtotal),
394 timing_params.hsync_polarity ? '+' : '-',
395 timing_params.vsync_polarity ? '+' : '-');
397 xil_printf(" Native/preferred timing.. n/a\r\n");
401 #if XVIDC_EDID_VERBOSITY > 0
404 #if XVIDC_EDID_VERBOSITY > 1
405 xil_printf("Established Timings supported\r\n");
406 if (edid->established_timings.timing_720x400_70)
407 xil_printf(" 720 x 400p @ 70Hz - IBM VGA\r\n");
408 if (edid->established_timings.timing_720x400_88)
409 xil_printf(" 720 x 400p @ 88Hz - IBM XGA2\r\n");
410 if (edid->established_timings.timing_640x480_60)
411 xil_printf(" 640 x 480p @ 60Hz - IBM VGA\r\n");
412 if (edid->established_timings.timing_640x480_67)
413 xil_printf(" 640 x 480p @ 67Hz - Apple Mac II\r\n");
414 if (edid->established_timings.timing_640x480_72)
415 xil_printf(" 640 x 480p @ 72Hz - VESA\r\n");
416 if (edid->established_timings.timing_640x480_75)
417 xil_printf(" 640 x 480p @ 75Hz - VESA\r\n");
418 if (edid->established_timings.timing_800x600_56)
419 xil_printf(" 800 x 600p @ 56Hz - VESA\r\n");
420 if (edid->established_timings.timing_800x600_60)
421 xil_printf(" 800 x 600p @ 60Hz - VESA\r\n");
423 if (edid->established_timings.timing_800x600_72)
424 xil_printf(" 800 x 600p @ 72Hz - VESA\r\n");
425 if (edid->established_timings.timing_800x600_75)
426 xil_printf(" 800 x 600p @ 75Hz - VESA\r\n");
427 if (edid->established_timings.timing_832x624_75)
428 xil_printf(" 832 x 624p @ 75Hz - Apple Mac II\r\n");
429 if (edid->established_timings.timing_1024x768_87)
430 xil_printf(" 1024 x 768i @ 87Hz - VESA\r\n");
431 if (edid->established_timings.timing_1024x768_60)
432 xil_printf(" 1024 x 768p @ 60Hz - VESA\r\n");
433 if (edid->established_timings.timing_1024x768_70)
434 xil_printf(" 1024 x 768p @ 70Hz - VESA\r\n");
435 if (edid->established_timings.timing_1024x768_75)
436 xil_printf(" 1024 x 768p @ 75Hz - VESA\r\n");
437 if (edid->established_timings.timing_1280x1024_75)
438 xil_printf(" 1280 x 1024p @ 75Hz - VESA\r\n");
443 #if XVIDC_EDID_VERBOSITY > 1
445 xil_printf("Standard Timings supported\r\n");
446 for (i = 0; i < ARRAY_SIZE(edid->standard_timing_id); i++) {
447 const struct xvidc_edid_standard_timing_descriptor * const desc =
448 &edid->standard_timing_id[i];
450 if (!memcmp(desc, XVIDC_EDID_STANDARD_TIMING_DESCRIPTOR_INVALID,
455 if (((desc->horizontal_active_pixels + 31)* 8) >= 1000) {
456 xil_printf(" %u x",(desc->horizontal_active_pixels + 31)* 8);
458 xil_printf(" %u x",(desc->horizontal_active_pixels + 31)* 8);
460 switch (desc->image_aspect_ratio) {
461 case 0: //Aspect Ratio = 16:10
463 (((desc->horizontal_active_pixels + 31)* 8) * 10) / 16);
465 case 1: //Aspect Ratio = 4:3
467 (((desc->horizontal_active_pixels + 31)* 8) * 3) / 4);
469 case 2: //Aspect Ratio = 5:4
471 (((desc->horizontal_active_pixels + 31)* 8) * 4) / 5);
473 case 3: //Aspect Ratio = 16:9
475 (((desc->horizontal_active_pixels + 31)* 8) * 9) / 16);
477 default: //Aspect Ratio = 16:10
479 (((desc->horizontal_active_pixels + 31)* 8) * 10) / 16);
482 xil_printf("@ %uHz\r\n",(desc->refresh_rate + 60));
487 #if XVIDC_EDID_VERBOSITY > 0
496 /*****************************************************************************/
499 * This function parse EDID on CEA 861 Audio Data
501 * @param data is a pointer to the EDID array.
502 * @param EdidCtrlParam is a pointer the EDID Control parameter
503 * @param VerboseEn is a pointer to the XV_HdmiTxSs core instance.
507 * @note API Define below here are CEA861 routines
509 ******************************************************************************/
510 #if XVIDC_EDID_VERBOSITY > 1
512 xvidc_disp_cea861_audio_data(
513 const struct xvidc_cea861_audio_data_block * const adb,
514 XV_VidC_EdidCntrlParam *EdidCtrlParam,
515 XV_VidC_Verbose VerboseEn) {
516 /* For Future Usage */
517 EdidCtrlParam = EdidCtrlParam;
519 const u8 descriptors = adb->header.length / sizeof(*adb->sad);
520 #if XVIDC_EDID_VERBOSITY > 0
522 xil_printf("CE audio data (formats supported)\r\n");
525 for (u8 i = 0; i < descriptors; i++) {
526 const struct xvidc_cea861_short_audio_descriptor * const sad =
527 (struct xvidc_cea861_short_audio_descriptor *) &adb->sad[i];
529 switch (sad->audio_format) {
530 case XVIDC_CEA861_AUDIO_FORMAT_LPCM:
531 #if XVIDC_EDID_VERBOSITY > 0
533 xil_printf(" LPCM %u-channel, %s%s%s\b%s",
535 sad->flags.lpcm.bitrate_16_bit ? "16/" : "",
536 sad->flags.lpcm.bitrate_20_bit ? "20/" : "",
537 sad->flags.lpcm.bitrate_24_bit ? "24/" : "",
539 ((sad->flags.lpcm.bitrate_16_bit +
540 sad->flags.lpcm.bitrate_20_bit +
541 sad->flags.lpcm.bitrate_24_bit) > 1) ?
542 " bit depths" : "-bit");
546 case XVIDC_CEA861_AUDIO_FORMAT_AC_3:
547 #if XVIDC_EDID_VERBOSITY > 0
549 xil_printf(" AC-3 %u-channel, %4uk max. bit rate",
551 (sad->flags.maximum_bit_rate << 3));
556 #if XVIDC_EDID_VERBOSITY > 0
558 xil_printf("Unknown audio format 0x%02x\r\n",
564 #if XVIDC_EDID_VERBOSITY > 0
566 xil_printf(" at %s%s%s%s%s%s%s\b kHz\r\n",
567 sad->sample_rate_32_kHz ? "32/" : "",
568 sad->sample_rate_44_1_kHz ? "44.1/" : "",
569 sad->sample_rate_48_kHz ? "48/" : "",
570 sad->sample_rate_88_2_kHz ? "88.2/" : "",
571 sad->sample_rate_96_kHz ? "96/" : "",
572 sad->sample_rate_176_4_kHz ? "176.4/" : "",
573 sad->sample_rate_192_kHz ? "192/" : "");
577 #if XVIDC_EDID_VERBOSITY > 0
585 /*****************************************************************************/
588 * This function parse EDID on CEA 861 Extended Data
590 * @param data is a pointer to the EDID array.
591 * @param EdidCtrlParam is a pointer the EDID Control parameter
592 * @param VerboseEn is a pointer to the XV_HdmiTxSs core instance.
598 ******************************************************************************/
600 xvidc_disp_cea861_extended_data(
601 const struct xvidc_cea861_extended_data_block * const edb,
602 XV_VidC_EdidCntrlParam *EdidCtrlParam,
603 XV_VidC_Verbose VerboseEn) {
605 /* During Verbosity 0, VerboseEn won't be used */
606 /* To avoid compilation warnings */
607 VerboseEn = VerboseEn;
609 #if XVIDC_EDID_VERBOSITY > 0
611 xil_printf("CEA Extended Tags\r\n");
614 switch(edb->xvidc_cea861_extended_tag_codes) {
615 #if XVIDC_EDID_VERBOSITY > 1
616 case XVIDC_CEA861_EXT_TAG_TYPE_VIDEO_CAPABILITY:
618 xil_printf(" Video capability data block\r\n");
622 case XVIDC_CEA861_EXT_TAG_TYPE_VENDOR_SPECIFIC:
624 xil_printf(" Vendor-specific video data block\r\n");
628 case XVIDC_CEA861_EXT_TAG_TYPE_VESA_DISPLAY_DEVICE:
630 xil_printf(" VESA video display device data block\r\n");
634 case XVIDC_CEA861_EXT_TAG_TYPE_VESA_VIDEO_TIMING_BLOCK_EXT:
636 xil_printf("VESA video timing block extension\r\n");
640 case XVIDC_CEA861_EXT_TAG_TYPE_RESERVED_FOR_HDMI_VIDEO_DATA_BLOCK:
642 xil_printf("Reserved for HDMI video data block\r\n");
646 case XVIDC_CEA861_EXT_TAG_TYPE_COLORIMETRY:
648 xil_printf(" Colorimetry data block\r\n");
652 case XVIDC_CEA861_EXT_TAG_TYPE_HDR_STATIC_METADATA:
654 xil_printf("HDR static metadata data block\r\n");
658 case XVIDC_CEA861_EXT_TAG_TYPE_HDR_DYNAMIC_METADATA:
660 xil_printf(" HDR dynamic metadata data block\r\n");
664 case XVIDC_CEA861_EXT_TAG_TYPE_VIDEO_FRMT_PREFERENCE:
666 xil_printf(" Video format preference data block\r\n");
670 case XVIDC_CEA861_EXT_TAG_TYPE_CEA_MISC_AUDIO_FIELDS:
672 xil_printf("Reserved for CEA miscellaneous audio fields\r\n");
676 case XVIDC_CEA861_EXT_TAG_TYPE_VENDOR_SPECIFC_AUDIO:
678 xil_printf(" Vendor-specific audio data block\r\n\r\n");
682 case XVIDC_CEA861_EXT_TAG_TYPE_HDMI_AUDIO:
684 xil_printf(" HDMI audio data block\r\n");
688 case XVIDC_CEA861_EXT_TAG_TYPE_ROOM_CONFIGURATION:
690 xil_printf(" Room configuration data block\r\n");
694 case XVIDC_CEA861_EXT_TAG_TYPE_SPEAKER_LOCATION:
696 xil_printf(" Speaker location data block\r\n");
700 case XVIDC_CEA861_EXT_TAG_TYPE_INFOFRAME:
702 xil_printf(" Video capability data block\r\n");
706 case XVIDC_CEA861_EXT_TAG_TYPE_YCBCR420_VIDEO:
707 #if XVIDC_EDID_VERBOSITY > 1
709 xil_printf(" YCbCr 4:2:0 video data block\r\n");
710 xil_printf(" YCbCr 4:2:0.............. Supported\r\n");
713 EdidCtrlParam->IsYCbCr420Supp = XVIDC_SUPPORTED;
715 #if XVIDC_EDID_VERBOSITY > 1
717 xil_printf(" CE video identifiers (VICs) - "
718 " timing/formats supported\r\n");
720 for (u8 i = 0; i < edb->header.length - 1; i++) {
723 if ((edb->data[i] & 0x7F) == 0) {
725 } else if (((edb->data[i]) >= 1) && ((edb->data[i]) <= 64)){
726 vic = (edb->data[i]) & 0x7F;
727 } else if (((edb->data[i]) >= 65) && ((edb->data[i]) <= 127)){
728 vic = (edb->data[i]);
729 } else if (((edb->data[i]) >= 129) && ((edb->data[i]) <= 192)){
730 vic = (edb->data[i]) & 0x7F;
732 } else if (((edb->data[i]) >= 193) && ((edb->data[i]) <= 253)){
733 vic = (edb->data[i]);
738 const struct xvidc_cea861_timing * const timing =
739 &xvidc_cea861_timings[vic];
742 xil_printf(" %s CEA Mode %02u: %4u x %4u%c @ %dHz\r\n",
745 timing->hactive, timing->vactive,
746 (timing->mode == INTERLACED) ? 'i' : 'p',
747 (u32)(timing->vfreq));
756 case XVIDC_CEA861_EXT_TAG_TYPE_YCBCR420_CAPABILITY_MAP:
757 #if XVIDC_EDID_VERBOSITY > 1
759 xil_printf(" YCbCr 4:2:0 capability map data block\r\n");
760 xil_printf(" YCbCr 4:2:0.............. Supported\r\n");
763 EdidCtrlParam->IsYCbCr420Supp = XVIDC_SUPPORTED;
764 #if XVIDC_EDID_VERBOSITY > 1
765 for (u8 i = 0; i < edb->header.length - 1; i++) {
768 for (u8 j = 0; j < 8; j++) {
771 const struct xvidc_cea861_timing * const timing =
772 &xvidc_cea861_timings[EdidCtrlParam->SuppCeaVIC[(i * 8) + j]];
773 xil_printf(" CEA Mode %02u: %4u x %4u%c"
775 EdidCtrlParam->SuppCeaVIC[(i * 8) + j],
776 timing->hactive, timing->vactive,
777 (timing->mode == INTERLACED) ? 'i' : 'p',
778 (u32)(timing->vfreq));
784 #if XVIDC_EDID_VERBOSITY > 0
792 #if XVIDC_EDID_VERBOSITY > 0
794 #if XVIDC_EDID_VERBOSITY > 1
795 xil_printf(" Not Supported: Ext Tag: %03x\r\n",
796 edb->xvidc_cea861_extended_tag_codes);
804 #if XVIDC_EDID_VERBOSITY > 1
806 xvidc_disp_cea861_video_data(
807 const struct xvidc_cea861_video_data_block * const vdb,
808 XV_VidC_EdidCntrlParam *EdidCtrlParam,
809 XV_VidC_Verbose VerboseEn) {
810 /* For Future Usage */
811 EdidCtrlParam = EdidCtrlParam;
814 xil_printf("CE video identifiers (VICs) - timing/formats"
818 for (u8 i = 0; i < vdb->header.length; i++) {
820 const struct xvidc_cea861_timing * const timing =
821 &xvidc_cea861_timings[vdb->svd[i].video_identification_code];
823 EdidCtrlParam->SuppCeaVIC[i] = vdb->svd[i].video_identification_code;
825 xil_printf(" %s CEA Mode %02u: %4u x %4u%c @ %dHz\r\n",
826 vdb->svd[i].native ? "*" : " ",
827 vdb->svd[i].video_identification_code,
828 timing->hactive, timing->vactive,
829 (timing->mode == INTERLACED) ? 'i' : 'p',
830 (u32)(timing->vfreq));
839 /*****************************************************************************/
842 * This function parse EDID on CEA 861 Vendor Specific Data
844 * @param data is a pointer to the EDID array.
845 * @param EdidCtrlParam is a pointer the EDID Control parameter
846 * @param VerboseEn is a pointer to the XV_HdmiTxSs core instance.
852 ******************************************************************************/
854 xvidc_disp_cea861_vendor_data(
855 const struct xvidc_cea861_vendor_specific_data_block * vsdb,
856 XV_VidC_EdidCntrlParam *EdidCtrlParam,
857 XV_VidC_Verbose VerboseEn) {
859 /* During Verbosity 0, VerboseEn won't be used */
860 /* To avoid compilation warnings */
861 VerboseEn = VerboseEn;
863 const u8 oui[] = { vsdb->ieee_registration[2],
864 vsdb->ieee_registration[1],
865 vsdb->ieee_registration[0] };
866 #if XVIDC_EDID_VERBOSITY > 0
868 xil_printf("CEA vendor specific data (VSDB)\r\n");
869 xil_printf(" IEEE registration number. 0x");
870 for (u8 i = 0; i < ARRAY_SIZE(oui); i++)
871 xil_printf("%02X", oui[i]);
875 if (!memcmp(oui, HDMI_OUI, sizeof(oui))) {
876 const struct xvidc_cea861_hdmi_vendor_specific_data_block * const hdmi =
877 (struct xvidc_cea861_hdmi_vendor_specific_data_block *) vsdb;
878 #if XVIDC_EDID_VERBOSITY > 0
880 xil_printf(" CEC physical address..... %u.%u.%u.%u\r\n",
881 hdmi->port_configuration_a,
882 hdmi->port_configuration_b,
883 hdmi->port_configuration_c,
884 hdmi->port_configuration_d);
888 if (hdmi->header.length >= HDMI_VSDB_EXTENSION_FLAGS_OFFSET) {
889 #if XVIDC_EDID_VERBOSITY > 0
891 #if XVIDC_EDID_VERBOSITY > 1
892 xil_printf(" Supports AI (ACP, ISRC).. %s\r\n",
893 hdmi->audio_info_frame ? "Yes" : "No");
895 xil_printf(" Supports 48bpp........... %s\r\n",
896 hdmi->colour_depth_48_bit ? "Yes" : "No");
897 xil_printf(" Supports 36bpp........... %s\r\n",
898 hdmi->colour_depth_36_bit ? "Yes" : "No");
899 xil_printf(" Supports 30bpp........... %s\r\n",
900 hdmi->colour_depth_30_bit ? "Yes" : "No");
901 xil_printf(" Supp. YUV444 Deep Color.. %s\r\n",
902 hdmi->yuv_444_supported ? "Yes" : "No");
903 #if XVIDC_EDID_VERBOSITY > 1
904 xil_printf(" Supports dual-link DVI... %s\r\n",
905 hdmi->dvi_dual_link ? "Yes" : "No");
909 EdidCtrlParam->Is30bppSupp = hdmi->colour_depth_30_bit;
910 EdidCtrlParam->Is36bppSupp = hdmi->colour_depth_36_bit;
911 EdidCtrlParam->Is48bppSupp = hdmi->colour_depth_48_bit;
912 EdidCtrlParam->IsYCbCr444DeepColSupp = hdmi->yuv_444_supported;
915 if (hdmi->header.length >= HDMI_VSDB_MAX_TMDS_OFFSET) {
916 if (hdmi->max_tmds_clock) {
917 #if XVIDC_EDID_VERBOSITY > 0
919 xil_printf(" Maximum TMDS clock....... %uMHz\r\n",
920 hdmi->max_tmds_clock * 5);
923 EdidCtrlParam->MaxTmdsMhz = (hdmi->max_tmds_clock * 5);
925 #if XVIDC_EDID_VERBOSITY > 0
927 xil_printf(" Maximum TMDS clock....... n/a\r\n");
933 if (hdmi->header.length >= HDMI_VSDB_LATENCY_FIELDS_OFFSET) {
934 if (hdmi->latency_fields) {
935 #if XVIDC_EDID_VERBOSITY > 0
937 xil_printf(" Video latency %s........ %ums\r\n",
938 hdmi->interlaced_latency_fields ? "(p)" : "...",
939 (hdmi->video_latency - 1) << 1);
940 xil_printf(" Audio latency %s........ %ums\r\n",
941 hdmi->interlaced_latency_fields ? "(p)" : "...",
942 (hdmi->audio_latency - 1) << 1);
947 if (hdmi->interlaced_latency_fields) {
948 #if XVIDC_EDID_VERBOSITY > 0
950 xil_printf(" Video latency (i)........ %ums\r\n",
951 hdmi->interlaced_video_latency);
952 xil_printf(" Audio latency (i)........ %ums\r\n",
953 hdmi->interlaced_audio_latency);
958 } else if (!memcmp(oui, HDMI_OUI_HF, sizeof(oui))) {
959 const struct xvidc_cea861_hdmi_hf_vendor_specific_data_block * const hdmi =
960 (struct xvidc_cea861_hdmi_hf_vendor_specific_data_block *) vsdb;
962 #if XVIDC_EDID_VERBOSITY > 0
964 xil_printf(" Version.................. %d\r\n",hdmi->version);
968 if (hdmi->max_tmds_char_rate) {
969 #if XVIDC_EDID_VERBOSITY > 0
971 xil_printf(" Maximum TMDS clock....... %uMHz\r\n",
972 hdmi->max_tmds_char_rate * 5);
975 EdidCtrlParam->MaxTmdsMhz = (hdmi->max_tmds_char_rate * 5);
977 #if XVIDC_EDID_VERBOSITY > 0
979 xil_printf(" Max. Supp. TMDS clock (<=340MHz)\r\n");
984 if (hdmi->header.length >= HDMI_VSDB_EXTENSION_FLAGS_OFFSET) {
985 #if XVIDC_EDID_VERBOSITY > 0
987 #if XVIDC_EDID_VERBOSITY > 1
988 xil_printf(" RRC Capable Support...... %s\r\n",
989 hdmi->rr_capable ? "Yes" : "No");
990 xil_printf(" SCDC Present............. %s\r\n",
991 hdmi->scdc_present ? "Yes" : "No");
992 xil_printf(" HDMI1.4 Scramble Support. %s\r\n",
993 hdmi->lte_340mcsc_scramble ? "Yes" : "No");
995 xil_printf(" YUV 420 Deep.C. Support..\r\n");
996 xil_printf(" Supports 48bpp......... %s\r\n",
997 hdmi->dc_48bit_yuv420 ? "Yes" : "No");
998 xil_printf(" Supports 36bpp......... %s\r\n",
999 hdmi->dc_36bit_yuv420 ? "Yes" : "No");
1000 xil_printf(" Supports 30bpp......... %s\r\n",
1001 hdmi->dc_30bit_yuv420 ? "Yes" : "No");
1004 EdidCtrlParam->IsYCbCr420dc30bppSupp = hdmi->dc_30bit_yuv420;
1005 EdidCtrlParam->IsYCbCr420dc36bppSupp = hdmi->dc_36bit_yuv420;
1006 EdidCtrlParam->IsYCbCr420dc48bppSupp = hdmi->dc_48bit_yuv420;
1007 EdidCtrlParam->IsSCDCReadRequestReady = hdmi->rr_capable;
1008 EdidCtrlParam->IsSCDCPresent = hdmi->scdc_present;
1011 #if XVIDC_EDID_VERBOSITY > 0
1018 #if XVIDC_EDID_VERBOSITY > 1
1019 /*****************************************************************************/
1022 * This function parse EDID on CEA 861 Speaker Allocation
1024 * @param data is a pointer to the EDID array.
1025 * @param EdidCtrlParam is a pointer the EDID Control parameter
1026 * @param VerboseEn is a pointer to the XV_HdmiTxSs core instance.
1032 ******************************************************************************/
1034 xvidc_disp_cea861_speaker_allocation_data(
1035 const struct xvidc_cea861_speaker_allocation_data_block * const sadb,
1036 XV_VidC_EdidCntrlParam *EdidCtrlParam,
1037 XV_VidC_Verbose VerboseEn) {
1038 /* For Future Usage */
1039 EdidCtrlParam = EdidCtrlParam;
1041 const struct xvidc_cea861_speaker_allocation * const sa = &sadb->payload;
1042 const u8 * const channel_configuration = (u8 *) sa;
1045 xil_printf("CEA speaker allocation data\r\n");
1046 xil_printf(" Channel configuration.... %u.%u\r\n",
1047 (__builtin_popcountll(channel_configuration[0] & 0xe9) << 1) +
1048 (__builtin_popcountll(channel_configuration[0] & 0x14) << 0) +
1049 (__builtin_popcountll(channel_configuration[1] & 0x01) << 1) +
1050 (__builtin_popcountll(channel_configuration[1] & 0x06) << 0),
1051 (channel_configuration[0] & 0x02));
1052 xil_printf(" Front left/right......... %s\r\n",
1053 sa->front_left_right ? "Yes" : "No");
1054 xil_printf(" Front LFE................ %s\r\n",
1055 sa->front_lfe ? "Yes" : "No");
1056 xil_printf(" Front center............. %s\r\n",
1057 sa->front_center ? "Yes" : "No");
1058 xil_printf(" Rear left/right.......... %s\r\n",
1059 sa->rear_left_right ? "Yes" : "No");
1060 xil_printf(" Rear center.............. %s\r\n",
1061 sa->rear_center ? "Yes" : "No");
1062 xil_printf(" Front left/right center.. %s\r\n",
1063 sa->front_left_right_center ? "Yes" : "No");
1064 xil_printf(" Rear left/right center... %s\r\n",
1065 sa->rear_left_right_center ? "Yes" : "No");
1066 xil_printf(" Front left/right wide.... %s\r\n",
1067 sa->front_left_right_wide ? "Yes" : "No");
1068 xil_printf(" Front left/right high.... %s\r\n",
1069 sa->front_left_right_high ? "Yes" : "No");
1070 xil_printf(" Top center............... %s\r\n",
1071 sa->top_center ? "Yes" : "No");
1072 xil_printf(" Front center high........ %s\r\n",
1073 sa->front_center_high ? "Yes" : "No");
1081 /*****************************************************************************/
1084 * This function Parse and Display the CEA-861
1086 * @param data is a pointer to the EDID array.
1087 * @param EdidCtrlParam is a pointer the EDID Control parameter
1088 * @param VerboseEn is a pointer to the XV_HdmiTxSs core instance.
1094 ******************************************************************************/
1096 xvidc_disp_cea861(const struct xvidc_edid_extension * const ext,
1097 XV_VidC_EdidCntrlParam *EdidCtrlParam,
1098 XV_VidC_Verbose VerboseEn) {
1100 const struct xvidc_cea861_timing_block * const ctb =
1101 (struct xvidc_cea861_timing_block *) ext;
1102 const u8 offset = offsetof(struct xvidc_cea861_timing_block, data);
1105 #if XVIDC_EDID_VERBOSITY > 1
1106 const struct xvidc_edid_detailed_timing_descriptor *dtd = NULL;
1109 XV_VidC_TimingParam timing_params;
1112 #if XVIDC_EDID_VERBOSITY > 0
1115 xil_printf("CEA-861 Information\r\n");
1116 xil_printf(" Revision number.......... %u\r\n",
1121 if (ctb->revision >= 2) {
1122 #if XVIDC_EDID_VERBOSITY > 0
1124 #if XVIDC_EDID_VERBOSITY > 1
1125 xil_printf(" IT underscan............. %supported\r\n",
1126 ctb->underscan_supported ? "S" : "Not s");
1128 xil_printf(" Basic audio.............. %supported\r\n",
1129 ctb->basic_audio_supported ? "S" : "Not s");
1130 xil_printf(" YCbCr 4:4:4.............. %supported\r\n",
1131 ctb->yuv_444_supported ? "S" : "Not s");
1132 xil_printf(" YCbCr 4:2:2.............. %supported\r\n",
1133 ctb->yuv_422_supported ? "S" : "Not s");
1134 #if XVIDC_EDID_VERBOSITY > 1
1135 xil_printf(" Native formats........... %u\r\n",
1140 EdidCtrlParam->IsYCbCr444Supp = ctb->yuv_444_supported;
1141 EdidCtrlParam->IsYCbCr422Supp = ctb->yuv_422_supported;
1144 #if XVIDC_EDID_VERBOSITY > 1
1145 dtd = (struct xvidc_edid_detailed_timing_descriptor *)
1146 ((u8 *) ctb + ctb->dtd_offset);
1147 for (i = 0; dtd->pixel_clock; i++, dtd++) {
1149 timing_params = XV_VidC_timing(dtd);
1151 xil_printf(" Detailed timing #%u....... %ux%u%c at %uHz "
1156 timing_params.vidfrmt ? 'i' : 'p',
1157 timing_params.vfreq,
1158 timing_params.aspect_ratio.width,
1159 timing_params.aspect_ratio.height);
1162 " Modeline............... \"%ux%u\" %u %u %u %u %u %u %u %u %u"
1163 " %chsync %cvsync\r\n",
1166 HZ_2_MHZ (timing_params.pixclk),
1167 (timing_params.hres),
1168 (timing_params.hres + timing_params.hfp),
1169 (timing_params.hres + timing_params.hfp +
1170 timing_params.hsync_width),
1171 (timing_params.htotal),
1172 (timing_params.vres),
1173 (timing_params.vres + timing_params.vfp),
1174 (timing_params.vres + timing_params.vfp +
1175 timing_params.vsync_width),
1176 (timing_params.vtotal),
1177 timing_params.hsync_polarity ? '+' : '-',
1178 timing_params.vsync_polarity ? '+' : '-');
1182 #if XVIDC_EDID_VERBOSITY > 0
1188 if (ctb->revision >= 3) {
1190 const struct xvidc_cea861_data_block_header * const header =
1191 (struct xvidc_cea861_data_block_header *) &ctb->data[index];
1193 switch (header->tag) {
1195 case XVIDC_CEA861_DATA_BLOCK_TYPE_AUDIO:
1197 #if XVIDC_EDID_VERBOSITY > 1
1198 const struct xvidc_cea861_audio_data_block * const db =
1199 (struct xvidc_cea861_audio_data_block *) header;
1201 xvidc_disp_cea861_audio_data(db,EdidCtrlParam,VerboseEn);
1206 case XVIDC_CEA861_DATA_BLOCK_TYPE_VIDEO:
1208 #if XVIDC_EDID_VERBOSITY > 1
1209 const struct xvidc_cea861_video_data_block * const db =
1210 (struct xvidc_cea861_video_data_block *) header;
1212 xvidc_disp_cea861_video_data(db,EdidCtrlParam,VerboseEn);
1217 case XVIDC_CEA861_DATA_BLOCK_TYPE_VENDOR_SPECIFIC:
1220 xvidc_cea861_vendor_specific_data_block * const db =
1221 (struct xvidc_cea861_vendor_specific_data_block *) header;
1223 xvidc_disp_cea861_vendor_data(db,EdidCtrlParam,VerboseEn);
1227 case XVIDC_CEA861_DATA_BLOCK_TYPE_SPEAKER_ALLOCATION:
1229 #if XVIDC_EDID_VERBOSITY > 1
1231 xvidc_cea861_speaker_allocation_data_block * const db =
1232 (struct xvidc_cea861_speaker_allocation_data_block *) header;
1234 xvidc_disp_cea861_speaker_allocation_data(db,
1235 EdidCtrlParam,VerboseEn);
1240 case XVIDC_CEA861_DATA_BLOCK_TYPE_EXTENDED:
1242 const struct xvidc_cea861_extended_data_block * const db =
1243 (struct xvidc_cea861_extended_data_block *) header;
1245 xvidc_disp_cea861_extended_data(db,EdidCtrlParam,VerboseEn);
1250 #if XVIDC_EDID_VERBOSITY > 1
1252 xil_printf("Unknown CEA-861 data block type 0x%02x\r\n",
1259 index = index + header->length + sizeof(*header);
1260 } while (index < ctb->dtd_offset - offset);
1262 #if XVIDC_EDID_VERBOSITY > 0
1270 /*****************************************************************************/
1273 * This structure parse parse EDID routines
1278 ******************************************************************************/
1279 static const struct xvidc_edid_extension_handler {
1280 void (* const inf_disp)(const struct xvidc_edid_extension * const,
1281 XV_VidC_EdidCntrlParam *EdidCtrlParam, XV_VidC_Verbose VerboseEn);
1282 } xvidc_edid_extension_handlers[] = {
1283 [XVIDC_EDID_EXTENSION_CEA] = { xvidc_disp_cea861 },
1287 /*****************************************************************************/
1290 * This function parse and print the EDID of the Sink
1292 * @param data is a pointer to the EDID array.
1293 * @param EdidCtrlParam is a pointer the EDID Control parameter
1294 * @param VerboseEn is a pointer to the XV_HdmiTxSs core instance.
1300 ******************************************************************************/
1302 XV_VidC_parse_edid(const u8 * const data,
1303 XV_VidC_EdidCntrlParam *EdidCtrlParam,
1304 XV_VidC_Verbose VerboseEn) {
1305 const struct edid * const edid = (struct edid *) data;
1306 const struct xvidc_edid_extension * const extensions =
1307 (struct xvidc_edid_extension *) (data + sizeof(*edid));
1309 XV_VidC_EdidCtrlParamInit(EdidCtrlParam);
1311 xvidc_disp_edid1(edid,EdidCtrlParam,VerboseEn);
1313 for (u8 i = 0; i < edid->extensions; i++) {
1314 const struct xvidc_edid_extension * const extension = &extensions[i];
1315 const struct xvidc_edid_extension_handler * const handler =
1316 &xvidc_edid_extension_handlers[extension->tag];
1319 #if XVIDC_EDID_VERBOSITY > 0
1321 xil_printf("WARNING: block %u contains unknown extension "
1322 " (%#04x)\r\n", i, extensions[i].tag);
1328 if (handler->inf_disp) {
1329 (*handler->inf_disp)(extension,EdidCtrlParam,VerboseEn);