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

Keith Packard keithp at kemper.freedesktop.org
Fri Dec 29 08:23:19 EET 2006


 src/i830_edid_modes.c |   46 +++++++++++++++++++++++++++++++++++++++++++++-
 src/i830_xf86Crtc.c   |   45 +++++++++++++++++++++++++++++++++++----------
 src/i830_xf86Modes.c  |    3 +++
 3 files changed, 83 insertions(+), 11 deletions(-)

New commits:
diff-tree b8692e646227e56c9ae4f72b9aaa75457b4c0f5f (from 973da654219ea43916b0b44acfa09a415bed3d7a)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Thu Dec 28 22:23:16 2006 -0800

    Lack of configured monitor implies no configured modes.
    
    Missing check for missing monitor configuration would result in segfault.

diff --git a/src/i830_xf86Modes.c b/src/i830_xf86Modes.c
index 58a6e6f..3a272cb 100644
--- a/src/i830_xf86Modes.c
+++ b/src/i830_xf86Modes.c
@@ -609,6 +609,9 @@ i830xf86GetMonitorModes (ScrnInfoPtr pSc
     DisplayModePtr	    modes = NULL;
     XF86ConfModesLinkPtr    modes_link;
     
+    if (!conf_monitor)
+	return NULL;
+
     /*
      * first we collect the mode lines from the UseModes directive
      */
diff-tree 973da654219ea43916b0b44acfa09a415bed3d7a (from f7b1d4c1f7d17a811e17c6a17861ff70be9fbdd7)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Thu Dec 28 22:22:22 2006 -0800

    Sync ranges from EDID/default should not limit configured modelines.
    
    Limit the effect of sync ranges so that sync ranges found via EDID will not
    eliminate modes explicitly added by the user. Limit default sync range to
    eliminating only default modes, not configured or EDID modes.

diff --git a/src/i830_xf86Crtc.c b/src/i830_xf86Crtc.c
index 763df43..f2d6026 100644
--- a/src/i830_xf86Crtc.c
+++ b/src/i830_xf86Crtc.c
@@ -542,9 +542,11 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn)
     {
 	xf86OutputPtr	    output = config->output[o];
 	DisplayModePtr	    mode;
+	DisplayModePtr	    config_modes, output_modes, default_modes;
 	XF86ConfMonitorPtr  conf_monitor = output->conf_monitor;
 	xf86MonPtr	    edid_monitor = output->MonInfo;
 	MonRec		    mon_rec;
+	enum { sync_config, sync_edid, sync_default } sync_source = sync_default;
 	
 	while (output->probed_modes != NULL)
 	    xf86DeleteMode(&output->probed_modes, output->probed_modes);
@@ -562,12 +564,14 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn)
 		mon_rec.hsync[mon_rec.nHsync].lo = conf_monitor->mon_hsync[i].lo;
 		mon_rec.hsync[mon_rec.nHsync].hi = conf_monitor->mon_hsync[i].hi;
 		mon_rec.nHsync++;
+		sync_source = sync_config;
 	    }
 	    for (i = 0; i < conf_monitor->mon_n_vrefresh; i++)
 	    {
 		mon_rec.vrefresh[mon_rec.nVrefresh].lo = conf_monitor->mon_vrefresh[i].lo;
 		mon_rec.vrefresh[mon_rec.nVrefresh].hi = conf_monitor->mon_vrefresh[i].hi;
 		mon_rec.nVrefresh++;
+		sync_source = sync_config;
 	    }
 	}
 	if (edid_monitor)
@@ -586,12 +590,16 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn)
 			mon_rec.hsync[mon_rec.nHsync].lo = ranges->min_h;
 			mon_rec.hsync[mon_rec.nHsync].hi = ranges->max_h;
 			mon_rec.nHsync++;
+			if (sync_source == sync_default)
+			    sync_source = sync_edid;
 		    }
 		    if (set_vrefresh && ranges->max_v)
 		    {
 			mon_rec.vrefresh[mon_rec.nVrefresh].lo = ranges->min_v;
 			mon_rec.vrefresh[mon_rec.nVrefresh].hi = ranges->max_v;
 			mon_rec.nVrefresh++;
+			if (sync_source == sync_default)
+			    sync_source = sync_edid;
 		    }
 		}
 	    }
@@ -614,19 +622,36 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn)
 	    mon_rec.nVrefresh = 1;
 	}
 	
+	config_modes = i830xf86GetMonitorModes (pScrn, conf_monitor);
+	output_modes = (*output->funcs->get_modes) (output);
+	default_modes = i830xf86GetDefaultModes ();
+	
+	if (sync_source == sync_config)
+	{
+	    /* 
+	     * Check output and config modes against sync range from config file
+	     */
+	    i830xf86ValidateModesSync (pScrn, output_modes, &mon_rec);
+	    i830xf86ValidateModesSync (pScrn, config_modes, &mon_rec);
+	}
+	/*
+	 * Check default modes against sync range
+	 */
+        i830xf86ValidateModesSync (pScrn, default_modes, &mon_rec);
+	
 	output->probed_modes = NULL;
-	if (conf_monitor)
-	    output->probed_modes = xf86ModesAdd (output->probed_modes,
-						 i830xf86GetMonitorModes (pScrn, conf_monitor));
-	output->probed_modes = xf86ModesAdd (output->probed_modes,
-					     (*output->funcs->get_modes) (output));
-	output->probed_modes = xf86ModesAdd (output->probed_modes,
-					     i830xf86GetDefaultModes ());
-
+	output->probed_modes = xf86ModesAdd (output->probed_modes, config_modes);
+	output->probed_modes = xf86ModesAdd (output->probed_modes, output_modes);
+	output->probed_modes = xf86ModesAdd (output->probed_modes, default_modes);
+	
+	/*
+	 * Check all modes against virtual size
+	 */
 	i830xf86ValidateModesSize (pScrn, output->probed_modes, virtualX, virtualY, 0);
-	i830xf86ValidateModesSync (pScrn, output->probed_modes, &mon_rec);
 	 
-	/* Strip out any modes that can't be supported on this output. */
+	/*
+	 * Check all modes against output
+	 */
 	for (mode = output->probed_modes; mode != NULL; mode = mode->next) 
 	    if (mode->status == MODE_OK)
 		mode->status = (*output->funcs->mode_valid)(output, mode);
diff-tree f7b1d4c1f7d17a811e17c6a17861ff70be9fbdd7 (from bedab1654e2dfcf7800bd0101e6991800a544019)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Thu Dec 28 22:18:57 2006 -0800

    Belinea 10 15 55 monitor quirk - override preferred mode with largest @60Hz
    
    Belinea 10 15 55 model monitor reports a preferred mode of 640x350, when in
    fact it wants a 1024x768 mode @ 60Hz. Add an edid quirk that selects the
    largest size mode, preferring those closer to 60hz among equal sized modes.

diff --git a/src/i830_edid_modes.c b/src/i830_edid_modes.c
index 5cef46d..c121610 100644
--- a/src/i830_edid_modes.c
+++ b/src/i830_edid_modes.c
@@ -48,6 +48,8 @@ typedef enum {
     DDC_QUIRK_NONE = 0,
     /* Force detailed sync polarity to -h +v */
     DDC_QUIRK_DT_SYNC_HM_VP = 1 << 0,
+    /* First detailed mode is bogus, prefer largest mode at 60hz */
+    DDC_QUIRK_PREFER_LARGE_60 = 1 << 1,
 } ddc_quirk_t;
 
 static Bool quirk_dt_sync_hm_vp (int scrnIndex, xf86MonPtr DDC)
@@ -64,6 +66,16 @@ static Bool quirk_dt_sync_hm_vp (int scr
     return FALSE;
 }
 
+static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC)
+{
+    /* Belinea 10 15 55 */
+    if (memcmp (DDC->vendor.name, "MAX", 4) == 0 &&
+	DDC->vendor.prod_id == 1516)
+	return TRUE;
+    
+    return FALSE;
+}
+
 typedef struct {
     Bool	(*detect) (int scrnIndex, xf86MonPtr DDC);
     ddc_quirk_t	quirk;
@@ -75,6 +87,10 @@ static const ddc_quirk_map_t ddc_quirks[
 	quirk_dt_sync_hm_vp,	DDC_QUIRK_DT_SYNC_HM_VP,
 	"Set detailed timing sync polarity to -h +v"
     },
+    {
+	quirk_prefer_large_60,   DDC_QUIRK_PREFER_LARGE_60,
+	"Detailed timing is not preferred, use largest mode at 60Hz"
+    },
     { 
 	NULL,		DDC_QUIRK_NONE,
 	"No known quirks"
@@ -234,8 +250,9 @@ xf86DDCGetModes(int scrnIndex, xf86MonPt
 	    quirks |= ddc_quirks[i].quirk;
 	}
     
-
     preferred = PREFERRED_TIMING_MODE(DDC->features.msc);
+    if (quirks & DDC_QUIRK_PREFER_LARGE_60)
+	preferred = 0;
 
     for (i = 0; i < DET_TIMINGS; i++) {
 	struct detailed_monitor_section *det_mon = &DDC->det_mon[i];
@@ -268,6 +285,33 @@ xf86DDCGetModes(int scrnIndex, xf86MonPt
     Mode = DDCModesFromStandardTiming(scrnIndex, DDC->timings2, quirks);
     Modes = xf86ModesAdd(Modes, Mode);
 
+    if (quirks & DDC_QUIRK_PREFER_LARGE_60)
+    {
+	DisplayModePtr	best = Modes;
+	for (Mode = Modes; Mode; Mode = Mode->next)
+	{
+	    if (Mode == best) continue;
+	    if (Mode->HDisplay * Mode->VDisplay > best->HDisplay * best->VDisplay)
+	    {
+		best = Mode;
+		continue;
+	    }
+	    if (Mode->HDisplay * Mode->VDisplay == best->HDisplay * best->VDisplay)
+	    {
+		double	mode_refresh = xf86ModeVRefresh (Mode);
+		double	best_refresh = xf86ModeVRefresh (best);
+		double	mode_dist = fabs(mode_refresh - 60.0);
+		double	best_dist = fabs(best_refresh - 60.0);
+		if (mode_dist < best_dist)
+		{
+		    best = Mode;
+		    continue;
+		}
+	    }
+	}
+	if (best)
+	    best->type |= M_T_PREFERRED;
+    }
     return Modes;
 }
 



More information about the xorg-commit mailing list