1*193032a3SAndroid Build Coastguard Worker // SPDX-License-Identifier: MIT
2*193032a3SAndroid Build Coastguard Worker /*
3*193032a3SAndroid Build Coastguard Worker * Copyright 2020 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
4*193032a3SAndroid Build Coastguard Worker *
5*193032a3SAndroid Build Coastguard Worker * Author: Hans Verkuil <[email protected]>
6*193032a3SAndroid Build Coastguard Worker */
7*193032a3SAndroid Build Coastguard Worker
8*193032a3SAndroid Build Coastguard Worker #include "edid-decode.h"
9*193032a3SAndroid Build Coastguard Worker
parse_digital_interface(const unsigned char * x)10*193032a3SAndroid Build Coastguard Worker void edid_state::parse_digital_interface(const unsigned char *x)
11*193032a3SAndroid Build Coastguard Worker {
12*193032a3SAndroid Build Coastguard Worker data_block = "Digital Interface";
13*193032a3SAndroid Build Coastguard Worker printf(" %s:\n", data_block.c_str());
14*193032a3SAndroid Build Coastguard Worker
15*193032a3SAndroid Build Coastguard Worker printf(" Supported Digital Interface: ");
16*193032a3SAndroid Build Coastguard Worker unsigned short v = x[2];
17*193032a3SAndroid Build Coastguard Worker switch (v) {
18*193032a3SAndroid Build Coastguard Worker case 0x00:
19*193032a3SAndroid Build Coastguard Worker printf("Analog Video Input\n");
20*193032a3SAndroid Build Coastguard Worker if (!memchk(x + 2, 12))
21*193032a3SAndroid Build Coastguard Worker fail("Bytes 0x02-0x0d should be 0.\n");
22*193032a3SAndroid Build Coastguard Worker return;
23*193032a3SAndroid Build Coastguard Worker case 0x01: printf("DVI\n"); break;
24*193032a3SAndroid Build Coastguard Worker case 0x02: printf("DVI Single Link\n"); break;
25*193032a3SAndroid Build Coastguard Worker case 0x03: printf("DVI Dual Link - High Resolution\n"); break;
26*193032a3SAndroid Build Coastguard Worker case 0x04: printf("DVI Dual Link - High Color\n"); break;
27*193032a3SAndroid Build Coastguard Worker case 0x05: printf("DVI - Consumer Electronics\n"); break;
28*193032a3SAndroid Build Coastguard Worker case 0x06: printf("Plug & Display\n"); break;
29*193032a3SAndroid Build Coastguard Worker case 0x07: printf("DFP\n"); break;
30*193032a3SAndroid Build Coastguard Worker case 0x08: printf("Open LDI - Single Link\n"); break;
31*193032a3SAndroid Build Coastguard Worker case 0x09: printf("Open LDI - Dual Link\n"); break;
32*193032a3SAndroid Build Coastguard Worker case 0x0a: printf("Open LDI - Consumer Electronics\n"); break;
33*193032a3SAndroid Build Coastguard Worker default:
34*193032a3SAndroid Build Coastguard Worker printf("Unknown (0x%02x)\n", v);
35*193032a3SAndroid Build Coastguard Worker fail("Unknown Digital Interface 0x%02x.\n", v);
36*193032a3SAndroid Build Coastguard Worker break;
37*193032a3SAndroid Build Coastguard Worker }
38*193032a3SAndroid Build Coastguard Worker
39*193032a3SAndroid Build Coastguard Worker switch ((x[3]) >> 6) {
40*193032a3SAndroid Build Coastguard Worker case 0x00:
41*193032a3SAndroid Build Coastguard Worker if (!memchk(x + 3, 4))
42*193032a3SAndroid Build Coastguard Worker fail("Bytes 0x03-0x06 should be 0.\n");
43*193032a3SAndroid Build Coastguard Worker break;
44*193032a3SAndroid Build Coastguard Worker case 0x01:
45*193032a3SAndroid Build Coastguard Worker printf(" Version: %u.%u\n Release: %u.%u\n", x[3] & 0x3f, x[4], x[5], x[6]);
46*193032a3SAndroid Build Coastguard Worker if (x[4] > 99)
47*193032a3SAndroid Build Coastguard Worker fail("Version number > 99.\n");
48*193032a3SAndroid Build Coastguard Worker if (x[6] > 99)
49*193032a3SAndroid Build Coastguard Worker fail("Release number > 99.\n");
50*193032a3SAndroid Build Coastguard Worker break;
51*193032a3SAndroid Build Coastguard Worker case 0x02:
52*193032a3SAndroid Build Coastguard Worker if (x[3] & 0x3f)
53*193032a3SAndroid Build Coastguard Worker fail("Bits 5-0 of byte 0x03 should be 0.\n");
54*193032a3SAndroid Build Coastguard Worker if (x[5] || x[6])
55*193032a3SAndroid Build Coastguard Worker fail("Bytes 0x05-0x06 should be 0.\n");
56*193032a3SAndroid Build Coastguard Worker printf(" Letter Designation: %c\n", x[4]);
57*193032a3SAndroid Build Coastguard Worker break;
58*193032a3SAndroid Build Coastguard Worker case 0x03:
59*193032a3SAndroid Build Coastguard Worker if (x[3] & 0x3f)
60*193032a3SAndroid Build Coastguard Worker fail("Bits 5-0 of byte 0x03 should be 0.\n");
61*193032a3SAndroid Build Coastguard Worker printf(" Date Code: Year %u Week %u Day %u\n", 1990 + x[4], x[5], x[6]);
62*193032a3SAndroid Build Coastguard Worker if (!x[5] || x[5] > 12)
63*193032a3SAndroid Build Coastguard Worker fail("Bad month number.\n");
64*193032a3SAndroid Build Coastguard Worker if (!x[6] || x[6] > 31)
65*193032a3SAndroid Build Coastguard Worker fail("Bad day number.\n");
66*193032a3SAndroid Build Coastguard Worker break;
67*193032a3SAndroid Build Coastguard Worker }
68*193032a3SAndroid Build Coastguard Worker
69*193032a3SAndroid Build Coastguard Worker v = x[7];
70*193032a3SAndroid Build Coastguard Worker printf(" Data Enable Signal Usage %sAvailable\n",
71*193032a3SAndroid Build Coastguard Worker (v & 0x80) ? "" : "Not ");
72*193032a3SAndroid Build Coastguard Worker if (v & 0x80)
73*193032a3SAndroid Build Coastguard Worker printf(" Data Enable Signal %s\n",
74*193032a3SAndroid Build Coastguard Worker (v & 0x40) ? "High" : "Low");
75*193032a3SAndroid Build Coastguard Worker else if (v & 0x40)
76*193032a3SAndroid Build Coastguard Worker fail("Bit 6 of byte 0x07 should be 0.\n");
77*193032a3SAndroid Build Coastguard Worker printf(" Edge of Shift Clock: ");
78*193032a3SAndroid Build Coastguard Worker switch ((v >> 4) & 0x03) {
79*193032a3SAndroid Build Coastguard Worker case 0: printf("Not specified\n"); break;
80*193032a3SAndroid Build Coastguard Worker case 1: printf("Use rising edge of shift clock\n"); break;
81*193032a3SAndroid Build Coastguard Worker case 2: printf("Use falling edge of shift clock\n"); break;
82*193032a3SAndroid Build Coastguard Worker case 3: printf("Use both edges of shift clock\n"); break;
83*193032a3SAndroid Build Coastguard Worker }
84*193032a3SAndroid Build Coastguard Worker printf(" HDCP is %ssupported\n", (v & 0x08) ? "" : "not ");
85*193032a3SAndroid Build Coastguard Worker printf(" Digital Receivers %ssupport Double Clocking of Input Data\n",
86*193032a3SAndroid Build Coastguard Worker (v & 0x04) ? "" : "do not ");
87*193032a3SAndroid Build Coastguard Worker printf(" Packetized Digital Video is %ssupported\n", (v & 0x02) ? "" : "not ");
88*193032a3SAndroid Build Coastguard Worker if (v & 0x01)
89*193032a3SAndroid Build Coastguard Worker fail("Bit 0 of byte 0x07 should be 0.\n");
90*193032a3SAndroid Build Coastguard Worker
91*193032a3SAndroid Build Coastguard Worker v = x[8];
92*193032a3SAndroid Build Coastguard Worker printf(" Data Formats: ");
93*193032a3SAndroid Build Coastguard Worker switch (v) {
94*193032a3SAndroid Build Coastguard Worker case 0x15: printf("8-Bit Over 8-Bit RGB\n"); break;
95*193032a3SAndroid Build Coastguard Worker case 0x19: printf("12-Bit Over 12-Bit RGB\n"); break;
96*193032a3SAndroid Build Coastguard Worker case 0x24: printf("24-Bit MSB-Aligned RGB (Single Link)\n"); break;
97*193032a3SAndroid Build Coastguard Worker case 0x48: printf("48-Bit MSB-Aligned RGB (Dual Link - High Resolution)\n"); break;
98*193032a3SAndroid Build Coastguard Worker case 0x49: printf("48-Bit MSB-Aligned RGB (Dual Link - High Color)\n"); break;
99*193032a3SAndroid Build Coastguard Worker default:
100*193032a3SAndroid Build Coastguard Worker printf("Unknown (0x%02x)\n", v);
101*193032a3SAndroid Build Coastguard Worker fail("Unknown Data Format 0x%02x.\n", v);
102*193032a3SAndroid Build Coastguard Worker break;
103*193032a3SAndroid Build Coastguard Worker }
104*193032a3SAndroid Build Coastguard Worker if (x[2] == 0x03 && v != 0x48)
105*193032a3SAndroid Build Coastguard Worker fail("Data Format should be 0x48, not 0x%02x.\n", v);
106*193032a3SAndroid Build Coastguard Worker if (x[2] == 0x04 && v != 0x49)
107*193032a3SAndroid Build Coastguard Worker fail("Data Format should be 0x49, not 0x%02x.\n", v);
108*193032a3SAndroid Build Coastguard Worker
109*193032a3SAndroid Build Coastguard Worker v = x[9];
110*193032a3SAndroid Build Coastguard Worker if (v) {
111*193032a3SAndroid Build Coastguard Worker printf(" Minimum Pixel Clock Frequency Per Link: %u MHz\n", v);
112*193032a3SAndroid Build Coastguard Worker if (v == 0xff)
113*193032a3SAndroid Build Coastguard Worker fail("Invalid Min-PCF 0x%02x.\n", v);
114*193032a3SAndroid Build Coastguard Worker }
115*193032a3SAndroid Build Coastguard Worker
116*193032a3SAndroid Build Coastguard Worker v = x[10] | (x[11] << 8);
117*193032a3SAndroid Build Coastguard Worker if (v) {
118*193032a3SAndroid Build Coastguard Worker printf(" Maximum Pixel Clock Frequency Per Link: %u MHz\n", v);
119*193032a3SAndroid Build Coastguard Worker if (v == 0xffff)
120*193032a3SAndroid Build Coastguard Worker fail("Invalid Max-PCF 0x%04x.\n", v);
121*193032a3SAndroid Build Coastguard Worker }
122*193032a3SAndroid Build Coastguard Worker
123*193032a3SAndroid Build Coastguard Worker v = x[12] | (x[13] << 8);
124*193032a3SAndroid Build Coastguard Worker if (v == 0xffff)
125*193032a3SAndroid Build Coastguard Worker printf(" Crossover Frequency: None - Single Link\n");
126*193032a3SAndroid Build Coastguard Worker else if (v)
127*193032a3SAndroid Build Coastguard Worker printf(" Crossover Frequency: %u MHz\n", v);
128*193032a3SAndroid Build Coastguard Worker }
129*193032a3SAndroid Build Coastguard Worker
parse_display_device(const unsigned char * x)130*193032a3SAndroid Build Coastguard Worker void edid_state::parse_display_device(const unsigned char *x)
131*193032a3SAndroid Build Coastguard Worker {
132*193032a3SAndroid Build Coastguard Worker data_block = "Display Device";
133*193032a3SAndroid Build Coastguard Worker printf(" %s:\n", data_block.c_str());
134*193032a3SAndroid Build Coastguard Worker
135*193032a3SAndroid Build Coastguard Worker printf(" Sub-Pixel Layout: ");
136*193032a3SAndroid Build Coastguard Worker unsigned char v = x[0x0e];
137*193032a3SAndroid Build Coastguard Worker switch (v) {
138*193032a3SAndroid Build Coastguard Worker case 0x00: printf("Not defined\n"); break;
139*193032a3SAndroid Build Coastguard Worker case 0x01: printf("RGB\n"); break;
140*193032a3SAndroid Build Coastguard Worker case 0x02: printf("BGR\n"); break;
141*193032a3SAndroid Build Coastguard Worker case 0x03: printf("Quad Pixel - G at bottom left & top right\n"); break;
142*193032a3SAndroid Build Coastguard Worker case 0x04: printf("Quad Pixel - G at bottom right & top left\n"); break;
143*193032a3SAndroid Build Coastguard Worker default:
144*193032a3SAndroid Build Coastguard Worker printf("Unknown (0x%02x)\n", v);
145*193032a3SAndroid Build Coastguard Worker fail("Unknown Sub-Pixel Layout 0x%02x.\n", v);
146*193032a3SAndroid Build Coastguard Worker break;
147*193032a3SAndroid Build Coastguard Worker }
148*193032a3SAndroid Build Coastguard Worker printf(" Sub-Pixel Configuration: ");
149*193032a3SAndroid Build Coastguard Worker v = x[0x0f];
150*193032a3SAndroid Build Coastguard Worker switch (v) {
151*193032a3SAndroid Build Coastguard Worker case 0x00: printf("Not defined\n"); break;
152*193032a3SAndroid Build Coastguard Worker case 0x01: printf("Delta (Tri-ad)\n"); break;
153*193032a3SAndroid Build Coastguard Worker case 0x02: printf("Stripe\n"); break;
154*193032a3SAndroid Build Coastguard Worker case 0x03: printf("Stripe Offset\n"); break;
155*193032a3SAndroid Build Coastguard Worker case 0x04: printf("Quad Pixel\n"); break;
156*193032a3SAndroid Build Coastguard Worker default:
157*193032a3SAndroid Build Coastguard Worker printf("Unknown (0x%02x)\n", v);
158*193032a3SAndroid Build Coastguard Worker fail("Unknown Sub-Pixel Configuration 0x%02x.\n", v);
159*193032a3SAndroid Build Coastguard Worker break;
160*193032a3SAndroid Build Coastguard Worker }
161*193032a3SAndroid Build Coastguard Worker printf(" Sub-Pixel Shape: ");
162*193032a3SAndroid Build Coastguard Worker v = x[0x10];
163*193032a3SAndroid Build Coastguard Worker switch (v) {
164*193032a3SAndroid Build Coastguard Worker case 0x00: printf("Not defined\n"); break;
165*193032a3SAndroid Build Coastguard Worker case 0x01: printf("Round\n"); break;
166*193032a3SAndroid Build Coastguard Worker case 0x02: printf("Square\n"); break;
167*193032a3SAndroid Build Coastguard Worker case 0x03: printf("Rectangular\n"); break;
168*193032a3SAndroid Build Coastguard Worker case 0x04: printf("Oval\n"); break;
169*193032a3SAndroid Build Coastguard Worker case 0x05: printf("Elliptical\n"); break;
170*193032a3SAndroid Build Coastguard Worker default:
171*193032a3SAndroid Build Coastguard Worker printf("Unknown (0x%02x)\n", v);
172*193032a3SAndroid Build Coastguard Worker fail("Unknown Sub-Pixel Shape 0x%02x.\n", v);
173*193032a3SAndroid Build Coastguard Worker break;
174*193032a3SAndroid Build Coastguard Worker }
175*193032a3SAndroid Build Coastguard Worker if (x[0x11])
176*193032a3SAndroid Build Coastguard Worker printf(" Horizontal Dot/Pixel Pitch: %.2f mm\n",
177*193032a3SAndroid Build Coastguard Worker x[0x11] / 100.0);
178*193032a3SAndroid Build Coastguard Worker if (x[0x12])
179*193032a3SAndroid Build Coastguard Worker printf(" Vertical Dot/Pixel Pitch: %.2f mm\n",
180*193032a3SAndroid Build Coastguard Worker x[0x12] / 100.0);
181*193032a3SAndroid Build Coastguard Worker v = x[0x13];
182*193032a3SAndroid Build Coastguard Worker printf(" Display Device %s a Fixed Pixel Format\n",
183*193032a3SAndroid Build Coastguard Worker (v & 0x80) ? "has" : "does not have");
184*193032a3SAndroid Build Coastguard Worker printf(" View Direction: ");
185*193032a3SAndroid Build Coastguard Worker switch ((v & 0x60) >> 5) {
186*193032a3SAndroid Build Coastguard Worker case 0x00: printf("Not specified\n"); break;
187*193032a3SAndroid Build Coastguard Worker case 0x01: printf("Direct\n"); break;
188*193032a3SAndroid Build Coastguard Worker case 0x02: printf("Reflected\n"); break;
189*193032a3SAndroid Build Coastguard Worker case 0x03: printf("Direct & Reflected\n"); break;
190*193032a3SAndroid Build Coastguard Worker }
191*193032a3SAndroid Build Coastguard Worker printf(" Display Device uses %stransparent background\n",
192*193032a3SAndroid Build Coastguard Worker (v & 0x10) ? "" : "non-");
193*193032a3SAndroid Build Coastguard Worker printf(" Physical Implementation: ");
194*193032a3SAndroid Build Coastguard Worker switch ((v & 0x0c) >> 2) {
195*193032a3SAndroid Build Coastguard Worker case 0x00: printf("Not specified\n"); break;
196*193032a3SAndroid Build Coastguard Worker case 0x01: printf("Large Image device for group viewing\n"); break;
197*193032a3SAndroid Build Coastguard Worker case 0x02: printf("Desktop or personal display\n"); break;
198*193032a3SAndroid Build Coastguard Worker case 0x03: printf("Eyepiece type personal display\n"); break;
199*193032a3SAndroid Build Coastguard Worker }
200*193032a3SAndroid Build Coastguard Worker printf(" Monitor/display does %ssupport DDC/CI\n",
201*193032a3SAndroid Build Coastguard Worker (v & 0x02) ? "" : "not ");
202*193032a3SAndroid Build Coastguard Worker if (v & 0x01)
203*193032a3SAndroid Build Coastguard Worker fail("Bit 0 of byte 0x13 should be 0.\n");
204*193032a3SAndroid Build Coastguard Worker }
205*193032a3SAndroid Build Coastguard Worker
parse_display_caps(const unsigned char * x)206*193032a3SAndroid Build Coastguard Worker void edid_state::parse_display_caps(const unsigned char *x)
207*193032a3SAndroid Build Coastguard Worker {
208*193032a3SAndroid Build Coastguard Worker data_block = "Display Capabities & Feature Support Set";
209*193032a3SAndroid Build Coastguard Worker printf(" %s:\n", data_block.c_str());
210*193032a3SAndroid Build Coastguard Worker
211*193032a3SAndroid Build Coastguard Worker unsigned short v = x[0x14];
212*193032a3SAndroid Build Coastguard Worker
213*193032a3SAndroid Build Coastguard Worker printf(" Legacy Modes: %s VGA/DOS Legacy Timing Modes are supported\n",
214*193032a3SAndroid Build Coastguard Worker (v & 0x80) ? "All" : "Not all");
215*193032a3SAndroid Build Coastguard Worker printf(" Stereo Video: ");
216*193032a3SAndroid Build Coastguard Worker switch ((v & 0x70) >> 4) {
217*193032a3SAndroid Build Coastguard Worker case 0x00: printf("No direct stereo\n"); break;
218*193032a3SAndroid Build Coastguard Worker case 0x01: printf("Field seq. stereo via stereo sync signal\n"); break;
219*193032a3SAndroid Build Coastguard Worker case 0x02: printf("auto-stereoscopic, column interleave\n"); break;
220*193032a3SAndroid Build Coastguard Worker case 0x03: printf("auto-stereoscopic, line interleave\n"); break;
221*193032a3SAndroid Build Coastguard Worker default:
222*193032a3SAndroid Build Coastguard Worker printf("Unknown (0x%02x)\n", (v & 0x70) >> 4);
223*193032a3SAndroid Build Coastguard Worker fail("Unknown Stereo Video 0x%02x.\n", (v & 0x70) >> 4);
224*193032a3SAndroid Build Coastguard Worker break;
225*193032a3SAndroid Build Coastguard Worker }
226*193032a3SAndroid Build Coastguard Worker printf(" Scaler On Board: %s\n", (v & 0x08) ? "Yes" : "No");
227*193032a3SAndroid Build Coastguard Worker printf(" Image Centering: %s\n", (v & 0x04) ? "Yes" : "No");
228*193032a3SAndroid Build Coastguard Worker printf(" Conditional Update: %s\n", (v & 0x02) ? "Yes" : "No");
229*193032a3SAndroid Build Coastguard Worker printf(" Interlaced Video: %s\n", (v & 0x01) ? "Yes" : "No");
230*193032a3SAndroid Build Coastguard Worker
231*193032a3SAndroid Build Coastguard Worker v = x[0x15];
232*193032a3SAndroid Build Coastguard Worker printf(" Frame Lock: %s\n", (v & 0x80) ? "Yes" : "No");
233*193032a3SAndroid Build Coastguard Worker printf(" Frame Rate Conversion: ");
234*193032a3SAndroid Build Coastguard Worker switch ((v & 0x60) >> 5) {
235*193032a3SAndroid Build Coastguard Worker case 0x00: printf("Not supported\n"); break;
236*193032a3SAndroid Build Coastguard Worker case 0x01: printf("Vertical is converted to a single frequency\n"); break;
237*193032a3SAndroid Build Coastguard Worker case 0x02: printf("Horizontal is convertred to a single frequency\n"); break;
238*193032a3SAndroid Build Coastguard Worker case 0x03: printf("Both Vertical & Horizontal are converted to single frequencies\n"); break;
239*193032a3SAndroid Build Coastguard Worker }
240*193032a3SAndroid Build Coastguard Worker if (v & 0x1f)
241*193032a3SAndroid Build Coastguard Worker fail("Bits 4-0 of byte 0x15 should be 0.\n");
242*193032a3SAndroid Build Coastguard Worker v = x[0x16] | (x[0x17] << 8);
243*193032a3SAndroid Build Coastguard Worker printf(" Vertical Frequency: ");
244*193032a3SAndroid Build Coastguard Worker if (!v) {
245*193032a3SAndroid Build Coastguard Worker printf("Not available\n");
246*193032a3SAndroid Build Coastguard Worker } else if (v == 0xffff) {
247*193032a3SAndroid Build Coastguard Worker printf("Reserved\n");
248*193032a3SAndroid Build Coastguard Worker fail("Vertical Frequency uses 0xffff (reserved value).\n");
249*193032a3SAndroid Build Coastguard Worker } else {
250*193032a3SAndroid Build Coastguard Worker printf("%.2f kHz\n", v / 100.0);
251*193032a3SAndroid Build Coastguard Worker }
252*193032a3SAndroid Build Coastguard Worker v = x[0x18] | (x[0x19] << 8);
253*193032a3SAndroid Build Coastguard Worker printf(" Horizontal Frequency: ");
254*193032a3SAndroid Build Coastguard Worker if (!v) {
255*193032a3SAndroid Build Coastguard Worker printf("Not available\n");
256*193032a3SAndroid Build Coastguard Worker } else if (v == 0xffff) {
257*193032a3SAndroid Build Coastguard Worker printf("Reserved\n");
258*193032a3SAndroid Build Coastguard Worker fail("Horizontal Frequency uses 0xffff (reserved value).\n");
259*193032a3SAndroid Build Coastguard Worker } else {
260*193032a3SAndroid Build Coastguard Worker printf("%.2f kHz\n", v / 100.0);
261*193032a3SAndroid Build Coastguard Worker }
262*193032a3SAndroid Build Coastguard Worker
263*193032a3SAndroid Build Coastguard Worker v = x[0x1a];
264*193032a3SAndroid Build Coastguard Worker printf(" Display/Scan Orientation Definition Type: ");
265*193032a3SAndroid Build Coastguard Worker switch ((v & 0xc0) >> 6) {
266*193032a3SAndroid Build Coastguard Worker case 0x00: printf("Not defined\n"); break;
267*193032a3SAndroid Build Coastguard Worker case 0x01: printf("Fixed Orientation\n"); break;
268*193032a3SAndroid Build Coastguard Worker case 0x02: printf("Pivots: Default Orientation\n"); break;
269*193032a3SAndroid Build Coastguard Worker case 0x03: printf("Pivots: Current Orientation (requires multiple EDID Extension Tables)\n"); break;
270*193032a3SAndroid Build Coastguard Worker }
271*193032a3SAndroid Build Coastguard Worker printf(" Screen Orientation: %s\n",
272*193032a3SAndroid Build Coastguard Worker (v & 0x20) ? "Portrait" : "Landscape");
273*193032a3SAndroid Build Coastguard Worker printf(" Zero Pixel Location: ");
274*193032a3SAndroid Build Coastguard Worker switch ((v & 0x18) >> 3) {
275*193032a3SAndroid Build Coastguard Worker case 0x00: printf("Upper Left\n"); break;
276*193032a3SAndroid Build Coastguard Worker case 0x01: printf("Upper Right\n"); break;
277*193032a3SAndroid Build Coastguard Worker case 0x02: printf("Lower Left\n"); break;
278*193032a3SAndroid Build Coastguard Worker case 0x03: printf("Lower Right\n"); break;
279*193032a3SAndroid Build Coastguard Worker }
280*193032a3SAndroid Build Coastguard Worker printf(" Scan Direction: ");
281*193032a3SAndroid Build Coastguard Worker switch ((v & 0x06) >> 1) {
282*193032a3SAndroid Build Coastguard Worker case 0x00: printf("Not defined\n"); break;
283*193032a3SAndroid Build Coastguard Worker case 0x01: printf("Fast Scan is on the Major (Long) Axis and Slow Scan is on the Minor Axis\n"); break;
284*193032a3SAndroid Build Coastguard Worker case 0x02: printf("Fast Scan is on the Minor (Short) Axis and Slow Scan is on the Major Axis\n"); break;
285*193032a3SAndroid Build Coastguard Worker case 0x03:
286*193032a3SAndroid Build Coastguard Worker printf("Reserved\n");
287*193032a3SAndroid Build Coastguard Worker fail("Scan Direction used the reserved value 0x03.\n");
288*193032a3SAndroid Build Coastguard Worker break;
289*193032a3SAndroid Build Coastguard Worker }
290*193032a3SAndroid Build Coastguard Worker printf(" Standalone Projector: %s\n",
291*193032a3SAndroid Build Coastguard Worker (v & 0x01) ? "Yes" : "No");
292*193032a3SAndroid Build Coastguard Worker
293*193032a3SAndroid Build Coastguard Worker v = x[0x1b];
294*193032a3SAndroid Build Coastguard Worker printf(" Default Color/Luminance Decoding: ");
295*193032a3SAndroid Build Coastguard Worker switch (v) {
296*193032a3SAndroid Build Coastguard Worker case 0x00: printf("Not defined\n"); break;
297*193032a3SAndroid Build Coastguard Worker case 0x01: printf("BGR\n"); break;
298*193032a3SAndroid Build Coastguard Worker case 0x02: printf("Y/C (S-Video) NTSC\n"); break;
299*193032a3SAndroid Build Coastguard Worker case 0x03: printf("Y/C (S-Video) PAL\n"); break;
300*193032a3SAndroid Build Coastguard Worker case 0x04: printf("Y/C (S-Video) SECAM\n"); break;
301*193032a3SAndroid Build Coastguard Worker case 0x05: printf("YCrCb 4:4:4 per SMPTE 293M & 294M\n"); break;
302*193032a3SAndroid Build Coastguard Worker case 0x06: printf("YCrCb 4:2:2 per SMPTE 293M & 294M\n"); break;
303*193032a3SAndroid Build Coastguard Worker case 0x07: printf("YCrCb 4:2:0 per SMPTE 293M & 294M\n"); break;
304*193032a3SAndroid Build Coastguard Worker case 0x08: printf("YCrCb per SMPTE 260M (Legacy HDTV)\n"); break;
305*193032a3SAndroid Build Coastguard Worker case 0x09: printf("YPbPr per SMPTE 240M (Legacy HDTV)\n"); break;
306*193032a3SAndroid Build Coastguard Worker case 0x0a: printf("YCrCb per SMPTE 274M (Modern HDTV)\n"); break;
307*193032a3SAndroid Build Coastguard Worker case 0x0b: printf("YPbPr per SMPTE 274M (Modern HDTV)\n"); break;
308*193032a3SAndroid Build Coastguard Worker case 0x0c: printf("Y B-Y R-Y BetaCam (Sony)\n"); break;
309*193032a3SAndroid Build Coastguard Worker case 0x0d: printf("Y B-Y R-Y M-2 (Matsushita)\n"); break;
310*193032a3SAndroid Build Coastguard Worker case 0x0e: printf("Monochrome\n"); break;
311*193032a3SAndroid Build Coastguard Worker default:
312*193032a3SAndroid Build Coastguard Worker printf("Unknown (0x%02x)\n", v);
313*193032a3SAndroid Build Coastguard Worker fail("Unknown Default Color/Luminance Decoding 0x%02x.\n", v);
314*193032a3SAndroid Build Coastguard Worker break;
315*193032a3SAndroid Build Coastguard Worker }
316*193032a3SAndroid Build Coastguard Worker v = x[0x1c];
317*193032a3SAndroid Build Coastguard Worker printf(" Preferred Color/Luminance Decoder: ");
318*193032a3SAndroid Build Coastguard Worker switch (v) {
319*193032a3SAndroid Build Coastguard Worker case 0x00: printf("Uses Default Decoding\n"); break;
320*193032a3SAndroid Build Coastguard Worker case 0x01: printf("BGR\n"); break;
321*193032a3SAndroid Build Coastguard Worker case 0x02: printf("Y/C (S-Video)\n"); break;
322*193032a3SAndroid Build Coastguard Worker case 0x03: printf("Yxx (SMPTE 2xxM)\n"); break;
323*193032a3SAndroid Build Coastguard Worker case 0x04: printf("Monochrome\n"); break;
324*193032a3SAndroid Build Coastguard Worker default:
325*193032a3SAndroid Build Coastguard Worker printf("Unknown (0x%02x)\n", v);
326*193032a3SAndroid Build Coastguard Worker fail("Unknown Preferred Color/Luminance Decoding 0x%02x.\n", v);
327*193032a3SAndroid Build Coastguard Worker break;
328*193032a3SAndroid Build Coastguard Worker }
329*193032a3SAndroid Build Coastguard Worker v = x[0x1d];
330*193032a3SAndroid Build Coastguard Worker if (v && (x[0x1e] & 0xfc)) {
331*193032a3SAndroid Build Coastguard Worker printf(" Color/Luminance Decoding Capabilities:\n");
332*193032a3SAndroid Build Coastguard Worker printf(" BGR: %s\n", (v & 0x80) ? "Yes" : "No");
333*193032a3SAndroid Build Coastguard Worker printf(" Y/C (S-Video) NTSC: %s\n", (v & 0x40) ? "Yes" : "No");
334*193032a3SAndroid Build Coastguard Worker printf(" Y/C (S-Video) PAL: %s\n", (v & 0x20) ? "Yes" : "No");
335*193032a3SAndroid Build Coastguard Worker printf(" Y/C (S-Video) SECAM: %s\n", (v & 0x10) ? "Yes" : "No");
336*193032a3SAndroid Build Coastguard Worker printf(" YCrCb 4:4:4 per SMPTE 293M & 294M: %s\n", (v & 0x08) ? "Yes" : "No");
337*193032a3SAndroid Build Coastguard Worker printf(" YCrCb 4:2:2 per SMPTE 293M & 294M: %s\n", (v & 0x04) ? "Yes" : "No");
338*193032a3SAndroid Build Coastguard Worker printf(" YCrCb 4:2:0 per SMPTE 293M & 294M: %s\n", (v & 0x02) ? "Yes" : "No");
339*193032a3SAndroid Build Coastguard Worker printf(" YCrCb per SMPTE 260M (Legacy HDTV): %s\n", (v & 0x01) ? "Yes" : "No");
340*193032a3SAndroid Build Coastguard Worker v = x[0x1e];
341*193032a3SAndroid Build Coastguard Worker printf(" YPbPr per SMPTE 240M (Legacy HDTV): %s\n", (v & 0x80) ? "Yes" : "No");
342*193032a3SAndroid Build Coastguard Worker printf(" YCrCb per SMPTE 274M (Modern HDTV): %s\n", (v & 0x40) ? "Yes" : "No");
343*193032a3SAndroid Build Coastguard Worker printf(" YPbPr per SMPTE 274M (Modern HDTV): %s\n", (v & 0x20) ? "Yes" : "No");
344*193032a3SAndroid Build Coastguard Worker printf(" Y B-Y R-Y BetaCam (Sony): %s\n", (v & 0x10) ? "Yes" : "No");
345*193032a3SAndroid Build Coastguard Worker printf(" Y B-Y R-Y M-2 (Matsushita): %s\n", (v & 0x08) ? "Yes" : "No");
346*193032a3SAndroid Build Coastguard Worker printf(" Monochrome: %s\n", (v & 0x04) ? "Yes" : "No");
347*193032a3SAndroid Build Coastguard Worker } else {
348*193032a3SAndroid Build Coastguard Worker printf(" Color/Luminance Decoding Capabilities: None\n");
349*193032a3SAndroid Build Coastguard Worker }
350*193032a3SAndroid Build Coastguard Worker if (v & 0x03)
351*193032a3SAndroid Build Coastguard Worker fail("Bits 1-0 of byte 0x1e should be 0.\n");
352*193032a3SAndroid Build Coastguard Worker
353*193032a3SAndroid Build Coastguard Worker v = x[0x1f];
354*193032a3SAndroid Build Coastguard Worker printf(" Dithering: %s\n", (v & 0x80) ? "Yes" : "No");
355*193032a3SAndroid Build Coastguard Worker if (v & 0x7f)
356*193032a3SAndroid Build Coastguard Worker fail("Bits 6-0 of byte 0x1f should be 0.\n");
357*193032a3SAndroid Build Coastguard Worker v = x[0x20];
358*193032a3SAndroid Build Coastguard Worker printf(" Supported Color Bit-Depth of Sub-Channel 0 (Blue): ");
359*193032a3SAndroid Build Coastguard Worker if (!v) {
360*193032a3SAndroid Build Coastguard Worker printf("No Information\n");
361*193032a3SAndroid Build Coastguard Worker } else if (v <= 16) {
362*193032a3SAndroid Build Coastguard Worker printf("%u\n", v);
363*193032a3SAndroid Build Coastguard Worker } else {
364*193032a3SAndroid Build Coastguard Worker printf("Reserved (0x%02x)\n", v);
365*193032a3SAndroid Build Coastguard Worker fail("Supported Color Bit-Depth of Sub-Channel Blue value is 0x%02x.\n", v);
366*193032a3SAndroid Build Coastguard Worker }
367*193032a3SAndroid Build Coastguard Worker v = x[0x21];
368*193032a3SAndroid Build Coastguard Worker printf(" Supported Color Bit-Depth of Sub-Channel 1 (Green): ");
369*193032a3SAndroid Build Coastguard Worker if (!v) {
370*193032a3SAndroid Build Coastguard Worker printf("No Information\n");
371*193032a3SAndroid Build Coastguard Worker } else if (v <= 16) {
372*193032a3SAndroid Build Coastguard Worker printf("%u\n", v);
373*193032a3SAndroid Build Coastguard Worker } else {
374*193032a3SAndroid Build Coastguard Worker printf("Reserved (0x%02x)\n", v);
375*193032a3SAndroid Build Coastguard Worker fail("Supported Color Bit-Depth of Sub-Channel Green value is 0x%02x.\n", v);
376*193032a3SAndroid Build Coastguard Worker }
377*193032a3SAndroid Build Coastguard Worker v = x[0x22];
378*193032a3SAndroid Build Coastguard Worker printf(" Supported Color Bit-Depth of Sub-Channel 2 (Red): ");
379*193032a3SAndroid Build Coastguard Worker if (!v) {
380*193032a3SAndroid Build Coastguard Worker printf("No Information\n");
381*193032a3SAndroid Build Coastguard Worker } else if (v <= 16) {
382*193032a3SAndroid Build Coastguard Worker printf("%u\n", v);
383*193032a3SAndroid Build Coastguard Worker } else {
384*193032a3SAndroid Build Coastguard Worker printf("Reserved (0x%02x)\n", v);
385*193032a3SAndroid Build Coastguard Worker fail("Supported Color Bit-Depth of Sub-Channel Red value is 0x%02x.\n", v);
386*193032a3SAndroid Build Coastguard Worker }
387*193032a3SAndroid Build Coastguard Worker v = x[0x23];
388*193032a3SAndroid Build Coastguard Worker printf(" Supported Color Bit-Depth of Sub-Channel 0 (Cb/Pb): ");
389*193032a3SAndroid Build Coastguard Worker if (!v) {
390*193032a3SAndroid Build Coastguard Worker printf("No Information\n");
391*193032a3SAndroid Build Coastguard Worker } else if (v <= 16) {
392*193032a3SAndroid Build Coastguard Worker printf("%u\n", v);
393*193032a3SAndroid Build Coastguard Worker } else {
394*193032a3SAndroid Build Coastguard Worker printf("Reserved (0x%02x)\n", v);
395*193032a3SAndroid Build Coastguard Worker fail("Supported Color Bit-Depth of Sub-Channel Cb/Pb value is 0x%02x.\n", v);
396*193032a3SAndroid Build Coastguard Worker }
397*193032a3SAndroid Build Coastguard Worker v = x[0x24];
398*193032a3SAndroid Build Coastguard Worker printf(" Supported Color Bit-Depth of Sub-Channel 1 (Y): ");
399*193032a3SAndroid Build Coastguard Worker if (!v) {
400*193032a3SAndroid Build Coastguard Worker printf("No Information\n");
401*193032a3SAndroid Build Coastguard Worker } else if (v <= 16) {
402*193032a3SAndroid Build Coastguard Worker printf("%u\n", v);
403*193032a3SAndroid Build Coastguard Worker } else {
404*193032a3SAndroid Build Coastguard Worker printf("Reserved (0x%02x)\n", v);
405*193032a3SAndroid Build Coastguard Worker fail("Supported Color Bit-Depth of Sub-Channel Y value is 0x%02x.\n", v);
406*193032a3SAndroid Build Coastguard Worker }
407*193032a3SAndroid Build Coastguard Worker v = x[0x25];
408*193032a3SAndroid Build Coastguard Worker printf(" Supported Color Bit-Depth of Sub-Channel 2 (Cr/Pr): ");
409*193032a3SAndroid Build Coastguard Worker if (!v) {
410*193032a3SAndroid Build Coastguard Worker printf("No Information\n");
411*193032a3SAndroid Build Coastguard Worker } else if (v <= 16) {
412*193032a3SAndroid Build Coastguard Worker printf("%u\n", v);
413*193032a3SAndroid Build Coastguard Worker } else {
414*193032a3SAndroid Build Coastguard Worker printf("Reserved (0x%02x)\n", v);
415*193032a3SAndroid Build Coastguard Worker fail("Supported Color Bit-Depth of Sub-Channel Cr/Pr value is 0x%02x.\n", v);
416*193032a3SAndroid Build Coastguard Worker }
417*193032a3SAndroid Build Coastguard Worker
418*193032a3SAndroid Build Coastguard Worker v = x[0x26];
419*193032a3SAndroid Build Coastguard Worker printf(" Aspect Ratio Conversion Modes:");
420*193032a3SAndroid Build Coastguard Worker if (!v) {
421*193032a3SAndroid Build Coastguard Worker printf(" None\n");
422*193032a3SAndroid Build Coastguard Worker } else {
423*193032a3SAndroid Build Coastguard Worker printf("\n");
424*193032a3SAndroid Build Coastguard Worker printf(" Full Mode: %s\n", (v & 0x80) ? "Yes" : "No");
425*193032a3SAndroid Build Coastguard Worker printf(" Zoom Mode: %s\n", (v & 0x40) ? "Yes" : "No");
426*193032a3SAndroid Build Coastguard Worker printf(" Squeeze (Side Bars/Letterbox) Mode: %s\n", (v & 0x20) ? "Yes" : "No");
427*193032a3SAndroid Build Coastguard Worker printf(" Variable (Expand/Shrink) Mode: %s\n", (v & 0x10) ? "Yes" : "No");
428*193032a3SAndroid Build Coastguard Worker }
429*193032a3SAndroid Build Coastguard Worker if (v & 0x0f)
430*193032a3SAndroid Build Coastguard Worker fail("Bits 3-0 of byte 0x26 should be 0.\n");
431*193032a3SAndroid Build Coastguard Worker }
432*193032a3SAndroid Build Coastguard Worker
parse_display_xfer(const unsigned char * x)433*193032a3SAndroid Build Coastguard Worker void edid_state::parse_display_xfer(const unsigned char *x)
434*193032a3SAndroid Build Coastguard Worker {
435*193032a3SAndroid Build Coastguard Worker data_block = "Display Transfer Characteristics - Gamma";
436*193032a3SAndroid Build Coastguard Worker printf(" %s:\n", data_block.c_str());
437*193032a3SAndroid Build Coastguard Worker
438*193032a3SAndroid Build Coastguard Worker unsigned char v = x[0x51];
439*193032a3SAndroid Build Coastguard Worker unsigned num_entries = v & 0x3f;
440*193032a3SAndroid Build Coastguard Worker
441*193032a3SAndroid Build Coastguard Worker switch ((v & 0xc0) >> 6) {
442*193032a3SAndroid Build Coastguard Worker case 0x00:
443*193032a3SAndroid Build Coastguard Worker printf(" No Display Transfer Characteristics\n");
444*193032a3SAndroid Build Coastguard Worker if (!memchk(x + 0x51, 46))
445*193032a3SAndroid Build Coastguard Worker fail("Bytes 0x51-0x7e should be 0.\n");
446*193032a3SAndroid Build Coastguard Worker return;
447*193032a3SAndroid Build Coastguard Worker case 0x03:
448*193032a3SAndroid Build Coastguard Worker fail("Bits 7-6 of byte 0x51 cannot be 0x03.\n");
449*193032a3SAndroid Build Coastguard Worker return;
450*193032a3SAndroid Build Coastguard Worker default:
451*193032a3SAndroid Build Coastguard Worker break;
452*193032a3SAndroid Build Coastguard Worker }
453*193032a3SAndroid Build Coastguard Worker
454*193032a3SAndroid Build Coastguard Worker if (((v & 0xc0) >> 6) == 0x01) {
455*193032a3SAndroid Build Coastguard Worker if (!num_entries || num_entries > 45)
456*193032a3SAndroid Build Coastguard Worker fail("White Curve with %u entries.\n", num_entries);
457*193032a3SAndroid Build Coastguard Worker if (num_entries > 45)
458*193032a3SAndroid Build Coastguard Worker num_entries = 45;
459*193032a3SAndroid Build Coastguard Worker if (!memchk(x + 0x52 + num_entries, 45 - num_entries))
460*193032a3SAndroid Build Coastguard Worker fail("Bytes 0x%02x-0x7e should be 0.\n", 0x52 + num_entries);
461*193032a3SAndroid Build Coastguard Worker printf(" White Curve (%u entries):\n", num_entries);
462*193032a3SAndroid Build Coastguard Worker hex_block(" ", x + 0x52, num_entries, false, 15);
463*193032a3SAndroid Build Coastguard Worker } else {
464*193032a3SAndroid Build Coastguard Worker if (!num_entries || num_entries > 15)
465*193032a3SAndroid Build Coastguard Worker fail("Sub-Channel Curve with %u entries.\n", num_entries);
466*193032a3SAndroid Build Coastguard Worker if (num_entries > 15)
467*193032a3SAndroid Build Coastguard Worker num_entries = 15;
468*193032a3SAndroid Build Coastguard Worker printf(" Sub-Channel 0 (Blue) Curve with %u entries:\n", num_entries);
469*193032a3SAndroid Build Coastguard Worker hex_block(" ", x + 0x52, num_entries, false);
470*193032a3SAndroid Build Coastguard Worker if (!memchk(x + 0x52 + num_entries, 15 - num_entries))
471*193032a3SAndroid Build Coastguard Worker fail("Bytes 0x%02x-0x7e should be 0.\n", 0x52 + num_entries);
472*193032a3SAndroid Build Coastguard Worker printf(" Sub-Channel 1 (Green) Curve with %u entries:\n", num_entries);
473*193032a3SAndroid Build Coastguard Worker hex_block(" ", x + 0x52 + 15, num_entries, false);
474*193032a3SAndroid Build Coastguard Worker if (!memchk(x + 0x52 + 15 + num_entries, 15 - num_entries))
475*193032a3SAndroid Build Coastguard Worker fail("Bytes 0x%02x-0x7e should be 0.\n", 0x52 + 15 + num_entries);
476*193032a3SAndroid Build Coastguard Worker printf(" Sub-Channel 2 (Red) Curve with %u entries:\n", num_entries);
477*193032a3SAndroid Build Coastguard Worker hex_block(" ", x + 0x52 + 30, num_entries, false);
478*193032a3SAndroid Build Coastguard Worker if (!memchk(x + 0x52 + 30 + num_entries, 15 - num_entries))
479*193032a3SAndroid Build Coastguard Worker fail("Bytes 0x%02x-0x7e should be 0.\n", 0x52 + 30 + num_entries);
480*193032a3SAndroid Build Coastguard Worker }
481*193032a3SAndroid Build Coastguard Worker }
482*193032a3SAndroid Build Coastguard Worker
parse_di_ext_block(const unsigned char * x)483*193032a3SAndroid Build Coastguard Worker void edid_state::parse_di_ext_block(const unsigned char *x)
484*193032a3SAndroid Build Coastguard Worker {
485*193032a3SAndroid Build Coastguard Worker printf(" Version: %u\n", x[1]);
486*193032a3SAndroid Build Coastguard Worker if (!x[1])
487*193032a3SAndroid Build Coastguard Worker fail("Invalid version 0.\n");
488*193032a3SAndroid Build Coastguard Worker
489*193032a3SAndroid Build Coastguard Worker parse_digital_interface(x);
490*193032a3SAndroid Build Coastguard Worker parse_display_device(x);
491*193032a3SAndroid Build Coastguard Worker parse_display_caps(x);
492*193032a3SAndroid Build Coastguard Worker if (!memchk(x + 0x27, 16))
493*193032a3SAndroid Build Coastguard Worker fail("Bytes 0x27-0x36 should be 0.\n");
494*193032a3SAndroid Build Coastguard Worker if (!memchk(x + 0x37, 17))
495*193032a3SAndroid Build Coastguard Worker fail("Bytes 0x37-0x47 should be 0.\n");
496*193032a3SAndroid Build Coastguard Worker if (!memchk(x + 0x48, 9))
497*193032a3SAndroid Build Coastguard Worker fail("Bytes 0x48-0x50 should be 0.\n");
498*193032a3SAndroid Build Coastguard Worker parse_display_xfer(x);
499*193032a3SAndroid Build Coastguard Worker }
500