[PATCH] edid-decode: parse displayid blocks

Dave Airlie airlied at gmail.com
Sun May 1 22:29:19 UTC 2016


From: Dave Airlie <airlied at redhat.com>

---
 edid-decode.c | 174 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 174 insertions(+)

diff --git a/edid-decode.c b/edid-decode.c
index 62c732d..631b223 100644
--- a/edid-decode.c
+++ b/edid-decode.c
@@ -1072,6 +1072,176 @@ parse_cea(unsigned char *x)
     return ret;
 }
 
+static int
+parse_displayid_detailed_timing(unsigned char *x)
+{
+    int ha, hbl, hso, hspw;
+    int va, vbl, vso, vspw;
+    char phsync, pvsync, *stereo;
+    int pix_clock;
+    char *aspect;
+
+    switch (x[3] & 0xf) {
+    case 0:
+	aspect = "1:1";
+	break;
+    case 1:
+	aspect = "5:4";
+	break;
+    case 2:
+	aspect = "4:3";
+	break;
+    case 3:
+	aspect = "15:9";
+	break;
+    case 4:
+	aspect = "16:9";
+	break;
+    case 5:
+	aspect = "16:10";
+	break;
+    case 6:
+	aspect = "64:27";
+	break;
+    case 7:
+	aspect = "256:135";
+	break;
+    default:
+	aspect = "undefined";
+	break;
+    }
+    switch ((x[3] >> 5) & 0x3) {
+    case 0:
+	stereo = "";
+	break;
+    case 1:
+	stereo = "stereo";
+	break;
+    case 2:
+	stereo = "user action";
+	break;
+    case 3:
+	stereo = "reserved";
+	break;
+    }
+    printf("Type 1 detailed timing: aspect: %s, %s %s\n", aspect, x[3] & 0x80 ? "Preferred " : "", stereo);
+    pix_clock = x[0] + (x[1] << 8) + (x[2] << 16);
+    ha = x[4] | (x[5] << 8);
+    hbl = x[6] | (x[7] << 8);
+    hso = x[8] | ((x[9] & 0x7f) << 8);
+    phsync = ((x[9] >> 7) & 0x1) ? '+' : '-';
+    hspw = x[10] | (x[11] << 8);
+    va = x[12] | (x[13] << 8);
+    vbl = x[14] | (x[15] << 8);
+    vso = x[16] | ((x[17] & 0x7f) << 8);
+    vspw = x[18] | (x[19] << 8);
+    pvsync = ((x[17] >> 7) & 0x1 ) ? '+' : '-';
+
+    printf("Detailed mode: Clock %.3f MHz, %d mm x %d mm\n"
+	   "               %4d %4d %4d %4d\n"
+	   "               %4d %4d %4d %4d\n"
+	   "               %chsync %cvsync\n",
+	   (float)pix_clock/100.0, 0, 0,
+	   ha, ha + hso, ha + hso + hspw, ha + hbl,
+	   va, va + vso, va + vso + vspw, va + vbl,
+	   phsync, pvsync
+	   );
+    return 1;
+}
+
+static int
+parse_displayid(unsigned char *x)
+{
+    int version = x[1];
+    int length = x[2];
+    int ext_count = x[4];
+    int i;
+    printf("Length %d, version %d, extension count %d\n", length, version, ext_count);
+    int offset = 5;
+    while (length > 0) {
+       int tag = x[offset];
+       int len = x[offset + 2];
+
+       if (len == 0)
+	   break;
+       switch (tag) {
+       case 0:
+	   printf("Product ID block\n");
+	   break;
+       case 1:
+	   printf("Display Parameters block\n");
+	   break;
+       case 2:
+	   printf("Color characteristics block\n");
+	   break;
+       case 3: {
+	   for (i = 0; i < len / 20; i++) {
+	       parse_displayid_detailed_timing(&x[offset + 3 + (i * 20)]);
+	   }
+	   break;
+       }
+       case 4:
+	   printf("Type 2 detailed timing\n");
+	   break;
+       case 5:
+	   printf("Type 3 short timing\n");
+	   break;
+       case 6:
+	   printf("Type 4 DMT timing\n");
+	   break;
+       case 7:
+	   printf("VESA DMT timing block\n");
+	   break;
+       case 8:
+	   printf("CEA timing block\n");
+	   break;
+       case 9:
+	   printf("Video timing range\n");
+	   break;
+       case 0xa:
+	   printf("Product serial number\n");
+	   break;
+       case 0xb:
+	   printf("GP ASCII string\n");
+	   break;
+       case 0xc:
+	   printf("Display device data\n");
+	   break;
+       case 0xd:
+	   printf("Interface power sequencing\n");
+	   break;
+       case 0xe:
+	   printf("Transfer characterisitics\n");
+	   break;
+       case 0xf:
+	   printf("Display interface\n");
+	   break;
+       case 0x10:
+	   printf("Stereo display interface\n");
+	   break;
+       case 0x12: {
+	   int capabilities = x[offset + 3];
+	   int num_v_tile = (x[offset + 4] & 0xf) | (x[offset + 6] & 0x30);
+	   int num_h_tile = (x[offset + 4] >> 4) | ((x[offset + 6] >> 2) & 0x30);
+	   int tile_v_location = (x[offset + 5] & 0xf) | ((x[offset + 6] & 0x3) << 4);
+	   int tile_h_location = (x[offset + 5] >> 4) | (((x[offset + 6] >> 2) & 0x3) << 4);
+	   int tile_width = x[offset + 7] | (x[offset + 8] << 8);
+	   int tile_height = x[offset + 9] | (x[offset + 10] << 8);
+	   printf("tiled display block: capabilities 0x%08x\n", capabilities);
+	   printf("num horizontal tiles %d, num vertical tiles %d\n", num_h_tile + 1, num_v_tile + 1);
+	   printf("tile location (%d, %d)\n", tile_h_location, tile_v_location);
+	   printf("tile dimensions (%d, %d)\n", tile_width + 1, tile_height + 1);
+	   break;
+       }
+       default:
+	   printf("Unknown displayid data block 0x%x\n", tag);
+	   break;
+       }
+       length -= len + 3;
+       offset += len + 3;
+    }
+    return 1;
+}
 /* generic extension code */
 
 static void
@@ -1096,6 +1266,10 @@ parse_extension(unsigned char *x)
     case 0x40: printf("DI extension block\n"); break;
     case 0x50: printf("LS extension block\n"); break;
     case 0x60: printf("DPVL extension block\n"); break;
+    case 0x70: printf("DisplayID extension block\n");
+	extension_version(x);
+        parse_displayid(x);
+        break;
     case 0xF0: printf("Block map\n"); break;
     case 0xFF: printf("Manufacturer-specific extension block\n");
     default:
-- 
2.5.5



More information about the xorg-devel mailing list