xf86-video-intel: Branch 'modesetting' - 3 commits - src/i830_display.c src/i830_edid_modes.c src/i830_xf86Crtc.c

Keith Packard keithp at kemper.freedesktop.org
Fri Dec 22 07:20:58 EET 2006


 src/i830_display.c    |    2 -
 src/i830_edid_modes.c |   92 +++++++++++++++++++++++++++++++++++++++++---------
 src/i830_xf86Crtc.c   |    4 ++
 3 files changed, 81 insertions(+), 17 deletions(-)

New commits:
diff-tree d8c5dba4d797fc50d7b2b5855f34e2d2e2ad3e4f (from fab9a6b6210daea423b609208ef57fa26571f5d3)
Author: Keith Packard <keithp at guitar.keithp.com>
Date:   Thu Dec 21 21:20:43 2006 -0800

    When cleaning duplicate modes, make sure ->Last is reset correctly.
    
    When removing the very last mode for a monitor, move the ->Last pointer to
    the previous list element.

diff --git a/src/i830_xf86Crtc.c b/src/i830_xf86Crtc.c
index bb6c869..0c482a2 100644
--- a/src/i830_xf86Crtc.c
+++ b/src/i830_xf86Crtc.c
@@ -437,7 +437,11 @@ xf86PruneDuplicateMonitorModes (MonPtr M
 	{
 	    next = clone->next;
 	    if (xf86ModesEqual (master, clone))
+	    {
+		if (Monitor->Last == clone)
+		    Monitor->Last = clone->prev;
 		xf86DeleteMode (&Monitor->Modes, clone);
+	    }
 	}
     }
 }
diff-tree fab9a6b6210daea423b609208ef57fa26571f5d3 (from d9b27667e6cc6c7e171b0f513d40be7658cf4574)
Author: Keith Packard <keithp at guitar.keithp.com>
Date:   Thu Dec 21 21:19:32 2006 -0800

    Add EDID quirk support for broken EDID data.
    
    For EDID with known errors, add a quirk mechanism to automatically
    compensate. The first quirk is for a Belinea 1440x900 monitor which
    incorrectly specifies sync polarities in the detailed mode.

diff --git a/src/i830_edid_modes.c b/src/i830_edid_modes.c
index 3becbb5..5357023 100644
--- a/src/i830_edid_modes.c
+++ b/src/i830_edid_modes.c
@@ -41,6 +41,44 @@
 #if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0)
 
 /*
+ * Quirks to work around broken EDID data from various monitors.
+ */
+
+typedef enum {
+    DDC_QUIRK_NONE = 0,
+    /*
+     * Detailed timing sync polarity values are inverted
+     */
+    DDC_QUIRK_DT_SYNC_INVERT = 1 << 0,
+} ddc_quirk_t;
+
+static Bool dt_sync_invert (int scrnIndex, xf86MonPtr DDC)
+{
+    /* Belinea 1924S1W */
+    if (memcmp (DDC->vendor.name, "MAX", 4) == 0 &&
+	DDC->vendor.prod_id == 1932)
+	return TRUE;
+    return FALSE;
+}
+
+typedef struct {
+    Bool	(*detect) (int scrnIndex, xf86MonPtr DDC);
+    ddc_quirk_t	quirk;
+    char	*description;
+} ddc_quirk_map_t;
+
+static const ddc_quirk_map_t ddc_quirks[] = {
+    { 
+	dt_sync_invert,	DDC_QUIRK_DT_SYNC_INVERT,
+	"Detailed timing data contains inverted sync polarity"
+    },
+    { 
+	NULL,		DDC_QUIRK_NONE,
+	"No known quirks"
+    },
+};
+
+/*
  * TODO:
  *  - for those with access to the VESA DMT standard; review please.
  */
@@ -68,7 +106,8 @@ DisplayModeRec DDCEstablishedModes[17] =
 };
 
 static DisplayModePtr
-DDCModesFromEstablished(int scrnIndex, struct established_timings *timing)
+DDCModesFromEstablished(int scrnIndex, struct established_timings *timing,
+			ddc_quirk_t quirks)
 {
     DisplayModePtr Modes = NULL, Mode = NULL;
     CARD32 bits = (timing->t1) | (timing->t2 << 8) |
@@ -89,7 +128,8 @@ DDCModesFromEstablished(int scrnIndex, s
  *
  */
 static DisplayModePtr
-DDCModesFromStandardTiming(int scrnIndex, struct std_timings *timing)
+DDCModesFromStandardTiming(int scrnIndex, struct std_timings *timing,
+			   ddc_quirk_t quirks)
 {
     DisplayModePtr Modes = NULL, Mode = NULL;
     int i;
@@ -111,9 +151,10 @@ DDCModesFromStandardTiming(int scrnIndex
  */
 static DisplayModePtr
 DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing,
-			  int preferred)
+			  int preferred, ddc_quirk_t quirks)
 {
     DisplayModePtr Mode;
+    unsigned int misc;
 
     /* We don't do stereo */
     if (timing->stereo) {
@@ -155,12 +196,16 @@ DDCModeFromDetailedTiming(int scrnIndex,
     if (timing->interlaced)
         Mode->Flags |= V_INTERLACE;
 
-    if (timing->misc & 0x02)
+    misc = timing->misc;
+    if (quirks & DDC_QUIRK_DT_SYNC_INVERT)
+	misc ^= 0x3;
+    
+    if (misc & 0x02)
         Mode->Flags |= V_PHSYNC;
     else
         Mode->Flags |= V_NHSYNC;
 
-    if (timing->misc & 0x01)
+    if (misc & 0x01)
         Mode->Flags |= V_PVSYNC;
     else
         Mode->Flags |= V_NVSYNC;
@@ -172,17 +217,22 @@ DisplayModePtr
 xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
 {
     int preferred, i;
-    DisplayModePtr Modes = NULL, Mode;
-
-    preferred = PREFERRED_TIMING_MODE(DDC->features.msc);
+    DisplayModePtr  Modes = NULL, Mode;
+    ddc_quirk_t	    quirks;
 
-    /* Add established timings */
-    Mode = DDCModesFromEstablished(scrnIndex, &DDC->timings1);
-    Modes = xf86ModesAdd(Modes, Mode);
+    xf86DrvMsg (scrnIndex, X_INFO, "EDID vendor \"%s\", prod id %d\n",
+		DDC->vendor.name, DDC->vendor.prod_id);
+    quirks = DDC_QUIRK_NONE;
+    for (i = 0; ddc_quirks[i].detect; i++)
+	if (ddc_quirks[i].detect (scrnIndex, DDC))
+	{
+	    xf86DrvMsg (scrnIndex, X_INFO, "    EDID quirk: %s\n",
+			ddc_quirks[i].description);
+	    quirks |= ddc_quirks[i].quirk;
+	}
+    
 
-    /* Add standard timings */
-    Mode = DDCModesFromStandardTiming(scrnIndex, DDC->timings2);
-    Modes = xf86ModesAdd(Modes, Mode);
+    preferred = PREFERRED_TIMING_MODE(DDC->features.msc);
 
     for (i = 0; i < DET_TIMINGS; i++) {
 	struct detailed_monitor_section *det_mon = &DDC->det_mon[i];
@@ -191,13 +241,15 @@ xf86DDCGetModes(int scrnIndex, xf86MonPt
         case DT:
             Mode = DDCModeFromDetailedTiming(scrnIndex,
                                              &det_mon->section.d_timings,
-					     preferred);
+					     preferred,
+					     quirks);
 	    preferred = 0;
             Modes = xf86ModesAdd(Modes, Mode);
             break;
         case DS_STD_TIMINGS:
             Mode = DDCModesFromStandardTiming(scrnIndex,
-					      det_mon->section.std_t);
+					      det_mon->section.std_t,
+					      quirks);
             Modes = xf86ModesAdd(Modes, Mode);
             break;
         default:
@@ -205,6 +257,14 @@ xf86DDCGetModes(int scrnIndex, xf86MonPt
         }
     }
 
+    /* Add established timings */
+    Mode = DDCModesFromEstablished(scrnIndex, &DDC->timings1, quirks);
+    Modes = xf86ModesAdd(Modes, Mode);
+
+    /* Add standard timings */
+    Mode = DDCModesFromStandardTiming(scrnIndex, DDC->timings2, quirks);
+    Modes = xf86ModesAdd(Modes, Mode);
+
     return Modes;
 }
 
diff-tree d9b27667e6cc6c7e171b0f513d40be7658cf4574 (from 4c0c1aa882cfec77b2183baec93cbc4cfaf4abe0)
Author: Keith Packard <keithp at guitar.keithp.com>
Date:   Thu Dec 21 21:17:03 2006 -0800

    PLL computations missed one possible 'm2' value.
    
    m2 was ranging from min <= m2 < max instead of <= max resulting in
    inaccurate PLL frequencies for some modes.

diff --git a/src/i830_display.c b/src/i830_display.c
index e3fdf6d..c5880d6 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -299,7 +299,7 @@ i830FindBestPLL(xf86CrtcPtr crtc, int ta
 
     for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) 
     {
-	for (clock.m2 = limit->m2.min; clock.m2 < clock.m1 && clock.m2 < limit->m2.max; clock.m2++) 
+	for (clock.m2 = limit->m2.min; clock.m2 < clock.m1 && clock.m2 <= limit->m2.max; clock.m2++) 
 	{
 	    for (clock.n = limit->n.min; clock.n <= limit->n.max; clock.n++) 
 	    {



More information about the xorg-commit mailing list