xf86-video-ati: Branch 'master'

Alex Deucher agd5f at kemper.freedesktop.org
Sun Oct 4 21:09:45 PDT 2009


 man/radeon.man      |   28 +++++++++++++++++++++++
 src/radeon.h        |    1 
 src/radeon_driver.c |    1 
 src/radeon_output.c |   61 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/radeon_probe.h  |    3 ++
 5 files changed, 93 insertions(+), 1 deletion(-)

New commits:
commit f8471512ea9f1d38140dfe98a0f832e9f935f51b
Author: Csillag Kristof <csillag.kristof at united-consult.hu>
Date:   Sun Oct 4 18:18:56 2009 -0400

    radeon: add support for Custom EDID
    
    Allows you to specify an edid per output from a file
    to override what is detected by DDC.  Useful for
    problematic monitors or KVM switches that block
    DDC.  Specifying an EDID that is not compatible with
    your monitor could damage your monitor so use with
    caution.
    
    agd5f: cache the custom edid at startup so we don't
    have to read it from file every time the output is
    queried.

diff --git a/man/radeon.man b/man/radeon.man
index 703fe1d..62270fb 100644
--- a/man/radeon.man
+++ b/man/radeon.man
@@ -302,6 +302,34 @@ for monitor detection. This is different from NoDDC option.
 The default value is
 .B off.
 .TP 
+.BI "Option \*qCustomEDID\*q \*q" string \*q
+Forces the X driver to use the EDID data specified in a file rather
+than the display's EDID. Also overrides DDC monitor detection.
+.br
+You may specify a semicolon separated list of output name and filename pairs.
+The output name is something like "VGA-0" or "DVI-0";
+consult the Xorg log for the supported output names of any given system.
+.br
+The file must contain a raw 128-byte EDID block, as captured by
+.B
+get-edid.
+.br
+For example:
+.B
+Option \*qCustomEDID\*q \*qVGA-0:/tmp/edid1.bin; DVI-0:/tmp/edid2.bin\*q
+will assign the EDID from the file /tmp/edid1.bin to the output device
+VGA-0, and the EDID from the file /tmp/edid2.bin to the output device
+DVI-0.
+.br
+Note that a output name must always be specified,
+even if only one EDID is specified.
+.br
+.B
+Caution:
+Specifying an EDID that doesn't exactly match your display may
+damage your hardware, as it allows the driver to specify timings beyond
+the capabilities of your display. Use with care.
+.TP 
 .BI "Option \*qPanelSize\*q \*q" "string" \*q
 Should only be used when driver cannot detect the correct panel size.
 Apply to both desktop (TMDS) and laptop (LVDS) digital panels.
diff --git a/src/radeon.h b/src/radeon.h
index 9d283bb..7fd297e 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -176,6 +176,7 @@ typedef enum {
 #endif
 #endif
     OPTION_IGNORE_EDID,
+    OPTION_CUSTOM_EDID,
     OPTION_DISP_PRIORITY,
     OPTION_PANEL_SIZE,
     OPTION_MIN_DOTCLOCK,
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index e0ba9ba..d039920 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -161,6 +161,7 @@ static const OptionInfoRec RADEONOptions[] = {
 #endif
 #endif
     { OPTION_IGNORE_EDID,    "IgnoreEDID",       OPTV_BOOLEAN, {0}, FALSE },
+    { OPTION_CUSTOM_EDID,    "CustomEDID",       OPTV_ANYSTR,  {0}, FALSE },
     { OPTION_DISP_PRIORITY,  "DisplayPriority",  OPTV_ANYSTR,  {0}, FALSE },
     { OPTION_PANEL_SIZE,     "PanelSize",        OPTV_ANYSTR,  {0}, FALSE },
     { OPTION_MIN_DOTCLOCK,   "ForceMinDotClock", OPTV_FREQ,    {0}, FALSE },
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 30f6f3b..36ef1aa 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -32,6 +32,7 @@
 
 #include <string.h>
 #include <stdio.h>
+#include <fcntl.h>
 
 /* X and server generic header files */
 #include "xf86.h"
@@ -215,6 +216,60 @@ monitor_is_digital(xf86MonPtr MonInfo)
     return (MonInfo->rawData[0x14] & 0x80) != 0;
 }
 
+static void
+RADEONGetHardCodedEDIDFromFile(xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    char *EDIDlist = (char *)xf86GetOptValString(info->Options, OPTION_CUSTOM_EDID);
+
+    radeon_output->custom_edid = FALSE;
+    radeon_output->custom_mon = NULL;
+
+    if (EDIDlist != NULL) {
+	unsigned char edid[128];
+	char *name = output->name;
+	char *outputEDID = strstr(EDIDlist, name);
+
+	if (outputEDID != NULL) {
+	    char *end;
+	    int fd;
+
+	    outputEDID += strlen(name) + 1;
+	    end = strstr(outputEDID, ";");
+	    if (end != NULL)
+		*end = 0;
+
+	    fd = open (outputEDID, O_RDONLY);
+	    if (fd >= 0) {
+		read(fd, edid, 128);
+		close(fd);
+		if (edid[1] == 0xff) {
+		    radeon_output->custom_mon = xf86InterpretEDID(output->scrn->scrnIndex, edid);
+		    radeon_output->custom_edid = TRUE;
+		    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+			       "Successfully read Custom EDID data for output %s from %s.\n",
+			       name, outputEDID);
+		} else {
+		    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+			       "Custom EDID data for %s read from %s was invalid.\n",
+			       name, outputEDID);
+		}
+	    } else {
+		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+			   "Could not read custom EDID for output %s from file %s.\n",
+			   name, outputEDID);
+	    }
+	} else {
+	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		       "Could not find EDID file name for output %s; using auto detection.\n",
+		       name);
+	}
+    }
+}
+
+
 static RADEONMonitorType
 radeon_ddc_connected(xf86OutputPtr output)
 {
@@ -224,7 +279,10 @@ radeon_ddc_connected(xf86OutputPtr output)
     xf86MonPtr MonInfo = NULL;
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
-    if (radeon_output->pI2CBus) {
+    if (radeon_output->custom_edid) {
+	MonInfo = xnfcalloc(sizeof(xf86Monitor), 1);
+	*MonInfo = *radeon_output->custom_mon;
+    } else if (radeon_output->pI2CBus) {
 	if (info->get_hardcoded_edid_from_bios)
 	    MonInfo = RADEONGetHardCodedEDIDFromBIOS(output);
 	if (MonInfo == NULL) {
@@ -2802,6 +2860,7 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
 	xf86OutputPtr output = xf86_config->output[i];
 
 	output->possible_clones = radeon_output_clones(pScrn, output);
+	RADEONGetHardCodedEDIDFromFile(output);
     }
 
     return TRUE;
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 9b2cd70..0ae3a87 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -261,6 +261,9 @@ typedef struct _RADEONOutputPrivateRec {
     I2CBusPtr         pI2CBus;
     RADEONI2CBusRec   ddc_i2c;
     Bool shared_ddc;
+
+    Bool custom_edid;
+    xf86MonPtr custom_mon;
     // router info
     // HDP info
 


More information about the xorg-commit mailing list