xserver: Branch 'master' - 10 commits

Adam Jackson ajax at kemper.freedesktop.org
Fri Dec 28 13:53:53 PST 2007


 hw/xfree86/ddc/edid.h            |   65 +++++-
 hw/xfree86/ddc/interpret_edid.c  |   80 +++++++-
 hw/xfree86/ddc/print_edid.c      |  367 ++++++++++++++++++++++++---------------
 hw/xfree86/modes/xf86EdidModes.c |   34 +++
 4 files changed, 391 insertions(+), 155 deletions(-)

New commits:
commit bae459cfc4f17a5ec5f2810e9f913e3ad2d8b8d4
Author: Adam Jackson <ajax at redhat.com>
Date:   Fri Dec 28 16:50:18 2007 -0500

    Don't carp on EDID 1.4 blocks anymore.
    
    Also whine more loudly when we get something other than 1.x.

diff --git a/hw/xfree86/ddc/interpret_edid.c b/hw/xfree86/ddc/interpret_edid.c
index 045c12d..14b0fd7 100644
--- a/hw/xfree86/ddc/interpret_edid.c
+++ b/hw/xfree86/ddc/interpret_edid.c
@@ -369,13 +369,16 @@ get_detailed_timing_section(Uchar *c, struct detailed_timings *r)
   r->misc = MISC;
 }
 
-#define MAX_EDID_MINOR 3
+#define MAX_EDID_MINOR 4
 
 static Bool
 validate_version(int scrnIndex, struct edid_version *r)
 {
-    if (r->version != 1)
+    if (r->version != 1) {
+	xf86DrvMsg(scrnIndex, X_ERROR, "Unknown EDID version %d\n",
+		   r->version);
 	return FALSE;
+    }
 
     if (r->revision > MAX_EDID_MINOR)
 	xf86DrvMsg(scrnIndex, X_WARNING,
commit 70b2d6cfeb3bcb7b862a2ae29f6ef7cb84d69486
Author: Adam Jackson <ajax at redhat.com>
Date:   Fri Dec 28 16:39:00 2007 -0500

    Check the gamma value, not its address.

diff --git a/hw/xfree86/ddc/print_edid.c b/hw/xfree86/ddc/print_edid.c
index a55c465..d9f18fa 100644
--- a/hw/xfree86/ddc/print_edid.c
+++ b/hw/xfree86/ddc/print_edid.c
@@ -211,7 +211,7 @@ print_display(int scrnIndex, struct disp_features *disp,
 	xf86DrvMsg(scrnIndex, X_INFO, "Indeterminate output size\n");
     }
 
-    if (!gamma && v->revision >= 1.4)
+    if (!disp->gamma && v->revision >= 1.4)
 	xf86DrvMsg(scrnIndex, X_INFO, "Gamma defined in extension block\n");
     else
 	xf86DrvMsg(scrnIndex, X_INFO, "Gamma: %.2f\n", disp->gamma);
commit 592d814ee09e86e283116a7a1052762c8398e8e5
Author: Adam Jackson <ajax at redhat.com>
Date:   Fri Dec 28 16:37:23 2007 -0500

    EDID 1.4: Additional semantics for display feature bits.
    
    First mode is _always_ preferred in 1.4; the bit that used to mean this
    now means that the preferred mode is also the native pixel format.  The
    old "is GTF" bit now means "is continuous-frequency" instead.
    
    Section 3.6.4, Table 3.14: Feature Support, Notes 4 and 5.

diff --git a/hw/xfree86/ddc/print_edid.c b/hw/xfree86/ddc/print_edid.c
index 30cd175..a55c465 100644
--- a/hw/xfree86/ddc/print_edid.c
+++ b/hw/xfree86/ddc/print_edid.c
@@ -154,16 +154,27 @@ print_dpms_features(int scrnIndex, struct disp_features *c,
     if (STD_COLOR_SPACE(c->msc))
 	xf86DrvMsg(scrnIndex,X_INFO,
 		   "Default color space is primary color space\n"); 
-    if (PREFERRED_TIMING_MODE(c->msc))
-	xf86DrvMsg(scrnIndex,X_INFO,
+
+    if (PREFERRED_TIMING_MODE(c->msc) || v->revision >= 4) {
+	xf86DrvMsg(scrnIndex, X_INFO,
 		   "First detailed timing is preferred mode\n"); 
-    else if (v->version == 1 && v->revision >= 3)
+	if (v->revision >= 4)
+	    xf86DrvMsg(scrnIndex, X_INFO,
+		"Preferred mode is native pixel format and refresh rate\n");
+    } else if (v->revision == 3) {
 	xf86DrvMsg(scrnIndex,X_INFO,
 		   "First detailed timing not preferred "
 		   "mode in violation of standard!");
-    if (GFT_SUPPORTED(c->msc))
-	xf86DrvMsg(scrnIndex,X_INFO,
-		   "GTF timings supported\n"); 
+    }
+
+    if (v->revision >= 4) {
+	if (GFT_SUPPORTED(c->msc)) {
+	    xf86DrvMsg(scrnIndex, X_INFO, "Display is continuous-frequency\n");
+	}
+    } else {
+	if (GFT_SUPPORTED(c->msc))
+	    xf86DrvMsg(scrnIndex, X_INFO, "GTF timings supported\n"); 
+    }
 }
   
 static void 
commit 322d0103aee317500057c80d542d7270d69a5731
Author: Adam Jackson <ajax at redhat.com>
Date:   Fri Dec 28 16:28:44 2007 -0500

    EDID 1.4: Alternate color encodings for digital inputs.
    
    Section 3.6.4, Table 3.14: Feature support.

diff --git a/hw/xfree86/ddc/edid.h b/hw/xfree86/ddc/edid.h
index 198794e..2496e19 100644
--- a/hw/xfree86/ddc/edid.h
+++ b/hw/xfree86/ddc/edid.h
@@ -326,11 +326,15 @@
 #define DPMS_SUSPEND(x) (x & 0x02)
 #define DPMS_OFF(x) (x & 0x01)
 
-/* display type */
+/* display type, analog */
 #define DISP_MONO 0
 #define DISP_RGB 1
 #define DISP_MULTCOLOR 2
 
+/* display color encodings, digital */
+#define DISP_YCRCB444 0x01
+#define DISP_YCRCB422 0x02
+
 /* Msc stuff EDID Ver > 1.1 */
 #define STD_COLOR_SPACE(x) (x & 0x4)
 #define PREFERRED_TIMING_MODE(x) (x & 0x2)
diff --git a/hw/xfree86/ddc/print_edid.c b/hw/xfree86/ddc/print_edid.c
index 880ca07..30cd175 100644
--- a/hw/xfree86/ddc/print_edid.c
+++ b/hw/xfree86/ddc/print_edid.c
@@ -128,20 +128,29 @@ print_dpms_features(int scrnIndex, struct disp_features *c,
 	 if (DPMS_OFF(c->dpms)) xf86ErrorF(" Off");
      } else 
 	 xf86DrvMsg(scrnIndex,X_INFO,"No DPMS capabilities specified");
-    switch (c->display_type){
-    case DISP_MONO:
-	xf86ErrorF("; Monochorome/GrayScale Display\n");
-	break;
-    case DISP_RGB:
-	xf86ErrorF("; RGB/Color Display\n");
-	break;
-    case DISP_MULTCOLOR:
-	xf86ErrorF("; Non RGB Multicolor Display\n");
-	break;
-    default:
-	xf86ErrorF("\n");
-	break;
+    if (!c->input_type) { /* analog */
+	switch (c->display_type){
+	    case DISP_MONO:
+		xf86ErrorF("; Monochorome/GrayScale Display\n");
+		break;
+	    case DISP_RGB:
+		xf86ErrorF("; RGB/Color Display\n");
+		break;
+	    case DISP_MULTCOLOR:
+		xf86ErrorF("; Non RGB Multicolor Display\n");
+		break;
+	    default:
+		xf86ErrorF("\n");
+		break;
+	}
+    } else {
+	int enc = c->display_type;
+	xf86DrvMsg(scrnIndex, X_INFO, "\nSupported color encodings: "
+		   "RGB 4:4:4 %s%s\n",
+		   enc & DISP_YCRCB444 ? "YCrCb 4:4:4 " : "",
+		   enc & DISP_YCRCB422 ? "YCrCb 4:2:2" : "");
     }
+
     if (STD_COLOR_SPACE(c->msc))
 	xf86DrvMsg(scrnIndex,X_INFO,
 		   "Default color space is primary color space\n"); 
commit f1f43caf7e26a84dbacd4e5d7d47c8b4e4982836
Author: Adam Jackson <ajax at redhat.com>
Date:   Fri Dec 28 16:12:11 2007 -0500

    EDID 1.4: Allow for gamma definition in extension blocks.
    
    Section 3.6.3, Table 3.13: Display Transfer Characteristics (Gamma)

diff --git a/hw/xfree86/ddc/edid.h b/hw/xfree86/ddc/edid.h
index 25163a6..198794e 100644
--- a/hw/xfree86/ddc/edid.h
+++ b/hw/xfree86/ddc/edid.h
@@ -129,7 +129,7 @@
 #define BPC _BPC(GET(D_INPUT))
 #define _DIGITAL_INTERFACE(x) (x & 0x0F)
 #define DIGITAL_INTERFACE _DIGITAL_INTERFACE(GET(D_INPUT))
-#define _GAMMA(x) (x == 0xff ? 1.0 : ((x + 100.0)/100.0))
+#define _GAMMA(x) (x == 0xff ? 0.0 : ((x + 100.0)/100.0))
 #define GAMMA _GAMMA(GET(D_GAMMA))
 #define HSIZE_MAX GET(D_HSIZE)
 #define VSIZE_MAX GET(D_VSIZE)
diff --git a/hw/xfree86/ddc/print_edid.c b/hw/xfree86/ddc/print_edid.c
index 59d414f..880ca07 100644
--- a/hw/xfree86/ddc/print_edid.c
+++ b/hw/xfree86/ddc/print_edid.c
@@ -191,7 +191,11 @@ print_display(int scrnIndex, struct disp_features *disp,
 	xf86DrvMsg(scrnIndex, X_INFO, "Indeterminate output size\n");
     }
 
-    xf86DrvMsg(scrnIndex, X_INFO, "Gamma: %.2f\n", disp->gamma);
+    if (!gamma && v->revision >= 1.4)
+	xf86DrvMsg(scrnIndex, X_INFO, "Gamma defined in extension block\n");
+    else
+	xf86DrvMsg(scrnIndex, X_INFO, "Gamma: %.2f\n", disp->gamma);
+
     print_dpms_features(scrnIndex, disp, v);
     print_whitepoint(scrnIndex, disp);
 }
commit 861ee38817523a647e6be10d7e8fe26f66054217
Author: Adam Jackson <ajax at redhat.com>
Date:   Fri Dec 28 16:06:45 2007 -0500

    EDID 1.4: Additional aspect ratio semantics for screen size fields.
    
    Section 3.6.2, Table 3.12: Horizontal and Vertical Screen Size or
    Aspect Ratio.

diff --git a/hw/xfree86/ddc/print_edid.c b/hw/xfree86/ddc/print_edid.c
index 9bd7ebc..59d414f 100644
--- a/hw/xfree86/ddc/print_edid.c
+++ b/hw/xfree86/ddc/print_edid.c
@@ -172,21 +172,28 @@ print_whitepoint(int scrnIndex, struct disp_features *disp)
 
 static void
 print_display(int scrnIndex, struct disp_features *disp,
-	      struct edid_version *version)
+	      struct edid_version *v)
 {
-    print_input_features(scrnIndex, disp, version);
-    xf86DrvMsg(scrnIndex,X_INFO,"Max H-Image Size [cm]: ");
-    if (disp->hsize)
-	xf86ErrorF("horiz.: %i  ",disp->hsize);
-    else
-	xf86ErrorF("H-Size may change,  ");
-    if (disp->vsize)
-	xf86ErrorF("vert.: %i\n",disp->vsize);
-      else
-	xf86ErrorF("V-Size may change\n");
-    xf86DrvMsg(scrnIndex,X_INFO,"Gamma: %.2f\n", disp->gamma);
-    print_dpms_features(scrnIndex,disp,version);
-    print_whitepoint(scrnIndex,disp);
+    print_input_features(scrnIndex, disp, v);
+    if (disp->hsize && disp->vsize) {
+	xf86DrvMsg(scrnIndex, X_INFO, "Max Image Size [cm]: ");
+	xf86ErrorF("horiz.: %i  ", disp->hsize);
+	xf86ErrorF("vert.: %i\n", disp->vsize);
+    } else if (v->revision >= 4 && (disp->hsize || disp->vsize)) {
+	if (disp->hsize)
+	    xf86DrvMsg(scrnIndex, X_INFO, "Aspect ratio: %.2f (landscape)\n",
+		       (disp->hsize + 99) / 100.0);
+	if (disp->vsize)
+	    xf86DrvMsg(scrnIndex, X_INFO, "Aspect ratio: %.2f (portrait)\n",
+		       100.0 / (float)(disp->vsize + 99));
+
+    } else {
+	xf86DrvMsg(scrnIndex, X_INFO, "Indeterminate output size\n");
+    }
+
+    xf86DrvMsg(scrnIndex, X_INFO, "Gamma: %.2f\n", disp->gamma);
+    print_dpms_features(scrnIndex, disp, v);
+    print_whitepoint(scrnIndex, disp);
 }
 
 static void 
commit 14b5c8a447db0395fb14b2d404eafb1d8e4fb817
Author: Adam Jackson <ajax at redhat.com>
Date:   Fri Dec 28 15:52:42 2007 -0500

    EDID 1.4: Extended support for digital interfaces.
    
    Section 3.6.1, Table 3.11: Video Input Definition.

diff --git a/hw/xfree86/ddc/edid.h b/hw/xfree86/ddc/edid.h
index 6708eaa..25163a6 100644
--- a/hw/xfree86/ddc/edid.h
+++ b/hw/xfree86/ddc/edid.h
@@ -125,6 +125,10 @@
 #define SYNC _SYNC(GET(D_INPUT))
 #define _DFP(x) (x & 0x01)
 #define DFP _DFP(GET(D_INPUT))
+#define _BPC(x) ((x & 0x70) >> 4)
+#define BPC _BPC(GET(D_INPUT))
+#define _DIGITAL_INTERFACE(x) (x & 0x0F)
+#define DIGITAL_INTERFACE _DIGITAL_INTERFACE(GET(D_INPUT))
 #define _GAMMA(x) (x == 0xff ? 1.0 : ((x + 100.0)/100.0))
 #define GAMMA _GAMMA(GET(D_GAMMA))
 #define HSIZE_MAX GET(D_HSIZE)
@@ -364,6 +368,9 @@ struct disp_features {
   unsigned int input_setup:1;
   unsigned int input_sync:5;
   unsigned int input_dfp:1;
+  unsigned int input_bpc:3;
+  unsigned int input_interface:4;
+  /* 15 bit hole */
   int hsize;
   int vsize;
   float gamma;
diff --git a/hw/xfree86/ddc/interpret_edid.c b/hw/xfree86/ddc/interpret_edid.c
index 982a502..045c12d 100644
--- a/hw/xfree86/ddc/interpret_edid.c
+++ b/hw/xfree86/ddc/interpret_edid.c
@@ -148,8 +148,12 @@ get_display_section(Uchar *c, struct disp_features *r,
 	r->input_voltage = INPUT_VOLTAGE;
 	r->input_setup = SETUP;
 	r->input_sync = SYNC;
-    } else if (v->version > 1 || v->revision > 2)
+    } else if (v->revision == 2 || v->revision == 3) {
 	r->input_dfp = DFP;
+    } else if (v->revision >= 4) {
+	r->input_bpc = BPC;
+	r->input_interface = DIGITAL_INTERFACE;
+    }
     r->hsize = HSIZE_MAX;
     r->vsize = VSIZE_MAX;
     r->gamma = GAMMA;
diff --git a/hw/xfree86/ddc/print_edid.c b/hw/xfree86/ddc/print_edid.c
index 5aebc6e..9bd7ebc 100644
--- a/hw/xfree86/ddc/print_edid.c
+++ b/hw/xfree86/ddc/print_edid.c
@@ -1,8 +1,28 @@
-
-/* print_edid.c: print out all information retrieved from display device 
- * 
+/*
  * Copyright 1998 by Egbert Eich <Egbert.Eich at Physik.TU-Darmstadt.DE>
+ * Copyright 2007 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software")
+ * to deal in the software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * them Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTIBILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * print_edid.c: print out all information retrieved from display device  
  */
+
 #ifdef HAVE_XORG_CONFIG_H
 #include <xorg-config.h>
 #endif
@@ -11,53 +31,9 @@
 #include "xf86.h"
 #include "xf86_OSproc.h"
 #include "xf86DDC.h"
+#include "edid.h"
   
-static void print_vendor(int scrnIndex, struct vendor *);
-static void print_version(int scrnIndex, struct edid_version *);
-static void print_display(int scrnIndex, struct disp_features *,
-			  struct edid_version *);
-static void print_established_timings(int scrnIndex,
-				      struct established_timings *);
-static void print_std_timings(int scrnIndex, struct std_timings *);
-static void print_detailed_monitor_section(int scrnIndex,
-					   struct detailed_monitor_section *);
-static void print_detailed_timings(int scrnIndex, struct detailed_timings *);
-
-static void print_input_features(int scrnIndex, struct disp_features *);
-static void print_dpms_features(int scrnIndex, struct disp_features *,
-				struct edid_version *v);
-static void print_whitepoint(int scrnIndex, struct disp_features *);
-static void print_number_sections(int scrnIndex, int);
-
 #define EDID_WIDTH	16
-
-xf86MonPtr
-xf86PrintEDID(xf86MonPtr m)
-{
-    CARD16 i, j;
-    char buf[EDID_WIDTH * 2 + 1];
-
-    if (!(m)) return NULL;
-
-    print_vendor(m->scrnIndex,&m->vendor);
-    print_version(m->scrnIndex,&m->ver);
-    print_display(m->scrnIndex,&m->features, &m->ver);
-    print_established_timings(m->scrnIndex,&m->timings1);
-    print_std_timings(m->scrnIndex,m->timings2);
-    print_detailed_monitor_section(m->scrnIndex,m->det_mon);
-    print_number_sections(m->scrnIndex,m->no_sections);
-
-    xf86DrvMsg(m->scrnIndex, X_INFO, "EDID (in hex):\n");
- 
-    for (i = 0; i < 128; i += j) {
-	for (j = 0; j < EDID_WIDTH; ++j) {
-	    sprintf(&buf[j * 2], "%02x", m->rawData[i + j]);
-	}
-	xf86DrvMsg(m->scrnIndex, X_INFO, "\t%s\n", buf);
-    }
-    
-    return m;
-}
   
 static void
 print_vendor(int scrnIndex, struct vendor *c)
@@ -66,7 +42,7 @@ print_vendor(int scrnIndex, struct vendor *c)
 	(char *)&c->name, c->prod_id, c->serial);
     xf86DrvMsg(scrnIndex, X_INFO, "Year: %u  Week: %u\n", c->year, c->week);
 }
-  
+
 static void
 print_version(int scrnIndex, struct edid_version *c)
 {
@@ -74,32 +50,38 @@ print_version(int scrnIndex, struct edid_version *c)
 	       c->revision);  
 }
   
-static void
-print_display(int scrnIndex, struct disp_features *disp,
-	      struct edid_version *version)
-{
-    print_input_features(scrnIndex,disp);
-    xf86DrvMsg(scrnIndex,X_INFO,"Max H-Image Size [cm]: ");
-    if (disp->hsize)
-	xf86ErrorF("horiz.: %i  ",disp->hsize);
-    else
-	xf86ErrorF("H-Size may change,  ");
-    if (disp->vsize)
-	xf86ErrorF("vert.: %i\n",disp->vsize);
-      else
-	xf86ErrorF("V-Size may change\n");
-    xf86DrvMsg(scrnIndex,X_INFO,"Gamma: %.2f\n", disp->gamma);
-    print_dpms_features(scrnIndex,disp,version);
-    print_whitepoint(scrnIndex,disp);
-}
-  
+static const char *digital_interfaces[] = {
+    "undefined",
+    "DVI",
+    "HDMI-a",
+    "HDMI-b",
+    "MDDI",
+    "DisplayPort",
+    "unknown"
+};
+
 static void 
-print_input_features(int scrnIndex, struct disp_features *c)
+print_input_features(int scrnIndex, struct disp_features *c,
+		     struct edid_version *v)
 {
     if (DIGITAL(c->input_type)) {
-	xf86DrvMsg(scrnIndex,X_INFO,"Digital Display Input\n");
-	if (DFP1(c->input_dfp))
-	    xf86DrvMsg(scrnIndex,X_INFO,"DFP 1.x compatible TMDS\n");
+	xf86DrvMsg(scrnIndex, X_INFO, "Digital Display Input\n");
+	if (v->revision == 2 || v->revision == 3) {
+	    if (DFP1(c->input_dfp))
+		xf86DrvMsg(scrnIndex, X_INFO, "DFP 1.x compatible TMDS\n");
+	} else if (v->revision >= 4) {
+	    int interface = c->input_interface;
+	    int bpc = c->input_bpc;
+	    if (interface > 6)
+		interface = 6; /* unknown */
+	    if (bpc == 0 || bpc == 7)
+		xf86DrvMsg(scrnIndex, X_INFO, "Undefined color depth\n");
+	    else
+		xf86DrvMsg(scrnIndex, X_INFO, "%d bits per channel\n",
+			   bpc * 2 + 4);
+	    xf86DrvMsg(scrnIndex, X_INFO, "Digital interface is %s\n",
+		       digital_interfaces[interface]);
+	}
     } else {
 	xf86DrvMsg(scrnIndex,X_INFO,"Analog Display Input,  ");
 	xf86ErrorF("Input Voltage Level: ");
@@ -187,7 +169,26 @@ print_whitepoint(int scrnIndex, struct disp_features *disp)
     xf86ErrorF("whiteX: %.3f whiteY: %.3f\n",
 	       disp->whitex,disp->whitey);
 }
-  
+
+static void
+print_display(int scrnIndex, struct disp_features *disp,
+	      struct edid_version *version)
+{
+    print_input_features(scrnIndex, disp, version);
+    xf86DrvMsg(scrnIndex,X_INFO,"Max H-Image Size [cm]: ");
+    if (disp->hsize)
+	xf86ErrorF("horiz.: %i  ",disp->hsize);
+    else
+	xf86ErrorF("H-Size may change,  ");
+    if (disp->vsize)
+	xf86ErrorF("vert.: %i\n",disp->vsize);
+      else
+	xf86ErrorF("V-Size may change\n");
+    xf86DrvMsg(scrnIndex,X_INFO,"Gamma: %.2f\n", disp->gamma);
+    print_dpms_features(scrnIndex,disp,version);
+    print_whitepoint(scrnIndex,disp);
+}
+
 static void 
 print_established_timings(int scrnIndex, struct established_timings *t)
 {
@@ -253,7 +254,50 @@ print_cvt_timings(int si, struct cvt_timings *t)
 	} else break;
     }
 }
-  
+
+static void
+print_detailed_timings(int scrnIndex, struct detailed_timings *t)
+{
+
+    if (t->clock > 15000000) {  /* sanity check */
+	xf86DrvMsg(scrnIndex,X_INFO,"Supported additional Video Mode:\n");
+	xf86DrvMsg(scrnIndex,X_INFO,"clock: %.1f MHz   ",t->clock/1000000.0);
+	xf86ErrorF("Image Size:  %i x %i mm\n",t->h_size,t->v_size); 
+	xf86DrvMsg(scrnIndex,X_INFO,
+		   "h_active: %i  h_sync: %i  h_sync_end %i h_blank_end %i ",
+		   t->h_active, t->h_sync_off + t->h_active,
+		   t->h_sync_off + t->h_sync_width + t->h_active,
+		   t->h_active + t->h_blanking);
+	xf86ErrorF("h_border: %i\n",t->h_border);
+	xf86DrvMsg(scrnIndex,X_INFO,
+		   "v_active: %i  v_sync: %i  v_sync_end %i v_blanking: %i ",
+		   t->v_active, t->v_sync_off + t->v_active,
+		   t->v_sync_off + t->v_sync_width + t->v_active,
+		   t->v_active + t->v_blanking);
+	xf86ErrorF("v_border: %i\n",t->v_border);
+	if (IS_STEREO(t->stereo)) {
+	    xf86DrvMsg(scrnIndex,X_INFO,"Stereo: ");
+	    if (IS_RIGHT_STEREO(t->stereo)) {
+		if (!t->stereo_1)
+		    xf86ErrorF("right channel on sync\n");
+		else
+		    xf86ErrorF("left channel on sync\n");
+	    } else if (IS_LEFT_STEREO(t->stereo)) {
+		if (!t->stereo_1)
+		    xf86ErrorF("right channel on even line\n");
+		else 
+		    xf86ErrorF("left channel on evel line\n");
+	    }
+	    if (IS_4WAY_STEREO(t->stereo)) {
+		if (!t->stereo_1)
+		    xf86ErrorF("4-way interleaved\n");
+		else
+		    xf86ErrorF("side-by-side interleaved");
+	    }
+	}
+    }
+}
+
 static void
 print_detailed_monitor_section(int scrnIndex,
 			       struct detailed_monitor_section *m)
@@ -334,49 +378,6 @@ print_detailed_monitor_section(int scrnIndex,
 }
   
 static void
-print_detailed_timings(int scrnIndex, struct detailed_timings *t)
-{
-
-    if (t->clock > 15000000) {  /* sanity check */
-	xf86DrvMsg(scrnIndex,X_INFO,"Supported additional Video Mode:\n");
-	xf86DrvMsg(scrnIndex,X_INFO,"clock: %.1f MHz   ",t->clock/1000000.0);
-	xf86ErrorF("Image Size:  %i x %i mm\n",t->h_size,t->v_size); 
-	xf86DrvMsg(scrnIndex,X_INFO,
-		   "h_active: %i  h_sync: %i  h_sync_end %i h_blank_end %i ",
-		   t->h_active, t->h_sync_off + t->h_active,
-		   t->h_sync_off + t->h_sync_width + t->h_active,
-		   t->h_active + t->h_blanking);
-	xf86ErrorF("h_border: %i\n",t->h_border);
-	xf86DrvMsg(scrnIndex,X_INFO,
-		   "v_active: %i  v_sync: %i  v_sync_end %i v_blanking: %i ",
-		   t->v_active, t->v_sync_off + t->v_active,
-		   t->v_sync_off + t->v_sync_width + t->v_active,
-		   t->v_active + t->v_blanking);
-	xf86ErrorF("v_border: %i\n",t->v_border);
-	if (IS_STEREO(t->stereo)) {
-	    xf86DrvMsg(scrnIndex,X_INFO,"Stereo: ");
-	    if (IS_RIGHT_STEREO(t->stereo)) {
-		if (!t->stereo_1)
-		    xf86ErrorF("right channel on sync\n");
-		else
-		    xf86ErrorF("left channel on sync\n");
-	    } else if (IS_LEFT_STEREO(t->stereo)) {
-		if (!t->stereo_1)
-		    xf86ErrorF("right channel on even line\n");
-		else 
-		    xf86ErrorF("left channel on evel line\n");
-	    }
-	    if (IS_4WAY_STEREO(t->stereo)) {
-		if (!t->stereo_1)
-		    xf86ErrorF("4-way interleaved\n");
-		else
-		    xf86ErrorF("side-by-side interleaved");
-	    }
-	}
-    }
-}
-
-static void
 print_number_sections(int scrnIndex, int num)
 {
     if (num)
@@ -384,3 +385,30 @@ print_number_sections(int scrnIndex, int num)
 		   num);
 }
 
+xf86MonPtr
+xf86PrintEDID(xf86MonPtr m)
+{
+    CARD16 i, j;
+    char buf[EDID_WIDTH * 2 + 1];
+
+    if (!(m)) return NULL;
+
+    print_vendor(m->scrnIndex,&m->vendor);
+    print_version(m->scrnIndex,&m->ver);
+    print_display(m->scrnIndex,&m->features, &m->ver);
+    print_established_timings(m->scrnIndex,&m->timings1);
+    print_std_timings(m->scrnIndex,m->timings2);
+    print_detailed_monitor_section(m->scrnIndex,m->det_mon);
+    print_number_sections(m->scrnIndex,m->no_sections);
+
+    xf86DrvMsg(m->scrnIndex, X_INFO, "EDID (in hex):\n");
+ 
+    for (i = 0; i < 128; i += j) {
+	for (j = 0; j < EDID_WIDTH; ++j) {
+	    sprintf(&buf[j * 2], "%02x", m->rawData[i + j]);
+	}
+	xf86DrvMsg(m->scrnIndex, X_INFO, "\t%s\n", buf);
+    }
+    
+    return m;
+}
commit a948216dccb5ee577a50a42035dc9bc49d0a00c6
Author: Adam Jackson <ajax at redhat.com>
Date:   Fri Dec 28 15:00:41 2007 -0500

    EDID 1.4: Decode CVT 3-byte codes and add them to the mode pool.
    
    Section 3.10.3.8: CVT 3 Byte Code Descriptor Definition.

diff --git a/hw/xfree86/ddc/edid.h b/hw/xfree86/ddc/edid.h
index 2e3e7df..6708eaa 100644
--- a/hw/xfree86/ddc/edid.h
+++ b/hw/xfree86/ddc/edid.h
@@ -449,17 +449,33 @@ struct whitePoints{
   float white_gamma;
 };
 
+struct cvt_timings {
+    int width;
+    int height;
+    int rate;
+    int rates;
+};
+
+/*
+ * Be careful when adding new sections; this structure can't grow, it's
+ * embedded in the middle of xf86Monitor which is ABI.  Sizes below are
+ * in bytes, for ILP32 systems.  If all else fails just copy the section
+ * literally like serial and friends.
+ */
 struct detailed_monitor_section {
   int type;
   union {
-    struct detailed_timings d_timings;
+    struct detailed_timings d_timings;	/* 56 */
     Uchar serial[13];
     Uchar ascii_data[13];
     Uchar name[13];
-    struct monitor_ranges ranges;
-    struct std_timings std_t[5];
-    struct whitePoints wp[2];
-  } section;
+    struct monitor_ranges ranges;	/* 40 */
+    struct std_timings std_t[5];	/* 80 */
+    struct whitePoints wp[2];		/* 32 */
+    /* color management data */
+    struct cvt_timings cvt[4];		/* 64 */
+    /* established timings III */
+  } section;				/* max: 80 */
 };
 
 typedef struct {
diff --git a/hw/xfree86/ddc/interpret_edid.c b/hw/xfree86/ddc/interpret_edid.c
index ecec2b0..982a502 100644
--- a/hw/xfree86/ddc/interpret_edid.c
+++ b/hw/xfree86/ddc/interpret_edid.c
@@ -175,6 +175,34 @@ get_established_timing_section(Uchar *c, struct established_timings *r)
 }
 
 static void
+get_cvt_timing_section(Uchar *c, struct cvt_timings *r)
+{
+    int i;
+
+    for (i = 0; i < 4; i++) {
+	if (c[0] && c[1] && c[2]) {
+	    r[i].height = (c[0] + ((c[1] & 0xF0) << 8) + 1) * 2;
+	    switch (c[1] & 0xc0) {
+		case 0x00: r[i].width = r[i].height * 4 / 3; break;
+		case 0x40: r[i].width = r[i].height * 16 / 9; break;
+		case 0x80: r[i].width = r[i].height * 16 / 10; break;
+		case 0xc0: r[i].width = r[i].height * 15 / 9; break;
+	    }
+	    switch (c[2] & 0x60) {
+		case 0x00: r[i].rate = 50; break;
+		case 0x20: r[i].rate = 60; break;
+		case 0x40: r[i].rate = 75; break;
+		case 0x60: r[i].rate = 85; break;
+	    }
+	    r[i].rates = c[2] & 0x1f;
+	} else {
+	    return;
+	}
+	c += 3;
+    }
+}
+
+static void
 get_std_timing_section(Uchar *c, struct std_timings *r,
 		       struct edid_version *v)
 {
@@ -232,6 +260,7 @@ get_dt_md_section(Uchar *c, struct edid_version *ver,
 	break;
       case CVT_3BYTE_DATA:
 	det_mon[i].type = DS_CVT;
+	get_cvt_timing_section(c, det_mon[i].section.cvt);
 	break;
       case ADD_EST_TIMINGS:
 	det_mon[i].type = DS_EST_III;
diff --git a/hw/xfree86/ddc/print_edid.c b/hw/xfree86/ddc/print_edid.c
index 17e21ac..5aebc6e 100644
--- a/hw/xfree86/ddc/print_edid.c
+++ b/hw/xfree86/ddc/print_edid.c
@@ -235,6 +235,24 @@ print_std_timings(int scrnIndex, struct std_timings *t)
 	}
     }
 }
+
+static void
+print_cvt_timings(int si, struct cvt_timings *t)
+{
+    int i;
+
+    for (i = 0; i < 4; i++) {
+	if (t[i].height) {
+	    xf86DrvMsg(si, X_INFO, "%dx%d @ %s%s%s%s%s Hz\n",
+		    t[i].width, t[i].height,
+		    t[i].rates & 0x10 ? "50," : "",
+		    t[i].rates & 0x08 ? "60," : "",
+		    t[i].rates & 0x04 ? "75," : "",
+		    t[i].rates & 0x02 ? "85," : "",
+		    t[i].rates & 0x01 ? "60RB" : "");
+	} else break;
+    }
+}
   
 static void
 print_detailed_monitor_section(int scrnIndex,
@@ -296,7 +314,8 @@ print_detailed_monitor_section(int scrnIndex,
 	    break;
 	case DS_CVT:
 	    xf86DrvMsg(scrnIndex, X_INFO,
-		       "CVT 3-byte-code modes: (not decoded)\n");
+		       "CVT 3-byte-code modes:\n");
+	    print_cvt_timings(scrnIndex, m[i].section.cvt);
 	    break;
 	case DS_EST_III:
 	    xf86DrvMsg(scrnIndex, X_INFO,
diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c
index a125d8c..d8c6161 100644
--- a/hw/xfree86/modes/xf86EdidModes.c
+++ b/hw/xfree86/modes/xf86EdidModes.c
@@ -354,6 +354,36 @@ DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing,
     return Mode;
 }
 
+static DisplayModePtr
+DDCModesFromCVT(int scrnIndex, struct cvt_timings *t)
+{
+    DisplayModePtr modes = NULL;
+    int i;
+
+    for (i = 0; i < 4; i++) {
+	if (t[i].height) {
+	    if (t[i].rates & 0x10)
+		modes = xf86ModesAdd(modes,
+			xf86CVTMode(t[i].width, t[i].height, 50, 0, 0));
+	    if (t[i].rates & 0x08)
+		modes = xf86ModesAdd(modes,
+			xf86CVTMode(t[i].width, t[i].height, 60, 0, 0));
+	    if (t[i].rates & 0x04)
+		modes = xf86ModesAdd(modes,
+			xf86CVTMode(t[i].width, t[i].height, 75, 0, 0));
+	    if (t[i].rates & 0x02)
+		modes = xf86ModesAdd(modes,
+			xf86CVTMode(t[i].width, t[i].height, 85, 0, 0));
+	    if (t[i].rates & 0x01)
+		modes = xf86ModesAdd(modes,
+			xf86CVTMode(t[i].width, t[i].height, 60, 1, 0));
+	} else break;
+    }
+
+    return modes;
+}
+
+
 /*
  *
  */
@@ -527,6 +557,10 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
 					      quirks);
             Modes = xf86ModesAdd(Modes, Mode);
             break;
+	case DS_CVT:
+	    Mode = DDCModesFromCVT(scrnIndex, det_mon->section.cvt);
+	    Modes = xf86ModesAdd(Modes, Mode);
+	    break;
         default:
             break;
         }
commit f6df66cc89bcd0a0be2e7bca05839fdd428c1d4c
Author: Adam Jackson <ajax at redhat.com>
Date:   Fri Dec 28 13:55:39 2007 -0500

    EDID 1.4: Trivial support for new detailed sections.
    
    Nothing actually decoded yet, but at least we print what they are.
    
    New in EDID 1.4:
    - Color Management Data (0xF9), Section 3.10.3.7
    - CVT 3 Byte Code Descriptor (0xF8), Section 3.10.3.8
    - Established Timings III Descriptor (0xF7), section 3.10.3.9
    - Manufacturer-specified data tag (0x00 - 0x0F), section 3.10.3.12

diff --git a/hw/xfree86/ddc/edid.h b/hw/xfree86/ddc/edid.h
index 02f5d09..2e3e7df 100644
--- a/hw/xfree86/ddc/edid.h
+++ b/hw/xfree86/ddc/edid.h
@@ -286,6 +286,9 @@
 #define _WHITE_GAMMA2(x) _GAMMA(x[14])
 #define WHITE_GAMMA2 _WHITE_GAMMA2(c)
 #define ADD_STD_TIMINGS 0xFA
+#define COLOR_MANAGEMENT_DATA 0xF9
+#define CVT_3BYTE_DATA 0xF8
+#define ADD_EST_TIMINGS 0xF7
 #define ADD_DUMMY 0x10
 
 #define _NEXT_DT_MD_SECTION(x) (x = (x + DET_TIMING_INFO_LEN))
@@ -418,8 +421,13 @@ struct detailed_timings {
 #define DS_RANGES 0xFD
 #define DS_WHITE_P 0xFB
 #define DS_STD_TIMINGS 0xFA
+#define DS_CMD 0xF9
+#define DS_CVT 0xF8
+#define DS_EST_III 0xF7
 #define DS_DUMMY 0x10
 #define DS_UNKOWN 0x100 /* type is an int */
+#define DS_VENDOR 0x101
+#define DS_VENDOR_MAX 0x110
 
 struct monitor_ranges {
   int min_v;
diff --git a/hw/xfree86/ddc/interpret_edid.c b/hw/xfree86/ddc/interpret_edid.c
index 7b4b2b9..ecec2b0 100644
--- a/hw/xfree86/ddc/interpret_edid.c
+++ b/hw/xfree86/ddc/interpret_edid.c
@@ -1,8 +1,28 @@
-
-/* interpret_edid.c: interpret a primary EDID block
- * 
+/*
  * Copyright 1998 by Egbert Eich <Egbert.Eich at Physik.TU-Darmstadt.DE>
+ * Copyright 2007 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software")
+ * to deal in the software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * them Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTIBILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * interpret_edid.c: interpret a primary EDID block
  */
+
 #ifdef HAVE_XORG_CONFIG_H
 #include <xorg-config.h>
 #endif
@@ -207,6 +227,15 @@ get_dt_md_section(Uchar *c, struct edid_version *ver,
 	det_mon[i].type = DS_STD_TIMINGS;
 	get_dst_timing_section(c,det_mon[i].section.std_t, ver);
 	break;
+      case COLOR_MANAGEMENT_DATA:
+	det_mon[i].type = DS_CMD;
+	break;
+      case CVT_3BYTE_DATA:
+	det_mon[i].type = DS_CVT;
+	break;
+      case ADD_EST_TIMINGS:
+	det_mon[i].type = DS_EST_III;
+	break;
       case ADD_DUMMY:
 	det_mon[i].type = DS_DUMMY;
         break;
@@ -214,6 +243,9 @@ get_dt_md_section(Uchar *c, struct edid_version *ver,
         det_mon[i].type = DS_UNKOWN;
         break;
       }
+      if (c[3] <= 0x0F) {
+	det_mon[i].type = DS_VENDOR + c[3];
+      }
     } else { 
       det_mon[i].type = DT;
       get_detailed_timing_section(c,&det_mon[i].section.d_timings);
diff --git a/hw/xfree86/ddc/print_edid.c b/hw/xfree86/ddc/print_edid.c
index 30b607d..17e21ac 100644
--- a/hw/xfree86/ddc/print_edid.c
+++ b/hw/xfree86/ddc/print_edid.c
@@ -290,10 +290,27 @@ print_detailed_monitor_section(int scrnIndex,
 			       m[i].section.wp[j].white_y,
 			       m[i].section.wp[j].white_gamma);
 	    break;
+	case DS_CMD:
+	    xf86DrvMsg(scrnIndex, X_INFO,
+		       "Color management data: (not decoded)\n");
+	    break;
+	case DS_CVT:
+	    xf86DrvMsg(scrnIndex, X_INFO,
+		       "CVT 3-byte-code modes: (not decoded)\n");
+	    break;
+	case DS_EST_III:
+	    xf86DrvMsg(scrnIndex, X_INFO,
+		       "Established timings III: (not decoded)\n");
+	    break;
 	case DS_DUMMY:
 	default:
 	    break;
 	}
+	if (m[i].type >= DS_VENDOR && m[i].type <= DS_VENDOR_MAX) {
+	    xf86DrvMsg(scrnIndex, X_WARNING,
+		       "Unknown vendor-specific block %hx\n",
+		       m[i].type - DS_VENDOR);
+	}
     }
 }
   
commit bac3ecde39cc914ab515991234b7dc2138005b84
Author: Adam Jackson <ajax at redhat.com>
Date:   Fri Dec 28 13:33:39 2007 -0500

    EDID 1.4: Allow for sync range offsets.
    
    Table 3.26: Display Range Limits & Timing Descriptor Block Definition

diff --git a/hw/xfree86/ddc/edid.h b/hw/xfree86/ddc/edid.h
index 4487273..02f5d09 100644
--- a/hw/xfree86/ddc/edid.h
+++ b/hw/xfree86/ddc/edid.h
@@ -1,5 +1,5 @@
-
-/* edid.h: defines to parse an EDID block 
+/*
+ * edid.h: defines to parse an EDID block 
  *
  * This file contains all information to interpret a standard EDIC block 
  * transmitted by a display device via DDC (Display Data Channel). So far 
@@ -241,14 +241,18 @@
 #define SERIAL_NUMBER 0xFF
 #define ASCII_STR 0xFE
 #define MONITOR_RANGES 0xFD
+#define _MIN_V_OFFSET(x) ((!!(x[4] & 0x01)) * 255)
+#define _MAX_V_OFFSET(x) ((!!(x[4] & 0x02)) * 255)
+#define _MIN_H_OFFSET(x) ((!!(x[4] & 0x04)) * 255)
+#define _MAX_H_OFFSET(x) ((!!(x[4] & 0x08)) * 255)
 #define _MIN_V(x) x[5]
-#define MIN_V _MIN_V(c) 
+#define MIN_V (_MIN_V(c) + _MIN_V_OFFSET(c))
 #define _MAX_V(x) x[6]
-#define MAX_V _MAX_V(c) 
+#define MAX_V (_MAX_V(c) + _MAX_V_OFFSET(c))
 #define _MIN_H(x) x[7]
-#define MIN_H _MIN_H(c) 
+#define MIN_H (_MIN_H(c) + _MIN_H_OFFSET(c))
 #define _MAX_H(x) x[8]
-#define MAX_H _MAX_H(c) 
+#define MAX_H (_MAX_H(c) + _MAX_H_OFFSET(c))
 #define _MAX_CLOCK(x) x[9]
 #define MAX_CLOCK _MAX_CLOCK(c) 
 #define _HAVE_2ND_GTF(x) (x[10] == 0x02)


More information about the xorg-commit mailing list