xf86-video-intel: 2 commits - src/i830_lvds.c

Zhenyu Wang zhen at kemper.freedesktop.org
Mon Jan 12 21:28:54 PST 2009


 src/i830_lvds.c |   86 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 79 insertions(+), 7 deletions(-)

New commits:
commit 3d206f9e46b5237bda7ca3c0f92d64c45ee8bdf5
Author: Ma Ling <ling.ma at intel.com>
Date:   Tue Jan 13 10:26:40 2009 +0800

    set continuous-frequency flag in get modes function
    
    http://bugs.freedesktop.org/show_bug.cgi?id=19247
    Because latest xorg will check whether the display is continuous frequency through one flag in monitor info structure,
    if not it doesn't touch default modes. When laptop failed to fetch edid, We don't set the flag. In i830_lvds.c,
    so currently we can not get default modes except only one mode line from bios.
    In order to achieve default modes from xserver successfully,I set the flag and other EDID features.

diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index 3796727..7056504 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -894,6 +894,28 @@ i830_lvds_detect(xf86OutputPtr output)
     return XF86OutputStatusConnected;
 }
 
+static void fill_detailed_block(struct detailed_monitor_section *det_mon,
+                                DisplayModePtr mode)
+{
+    struct detailed_timings *timing = &det_mon->section.d_timings;
+    det_mon->type = DT;
+    timing->clock = mode->Clock * 1000;
+    timing->h_active = mode->HDisplay;
+    timing->h_blanking = mode->HTotal - mode->HDisplay;
+    timing->v_active = mode->VDisplay;
+    timing->v_blanking = mode->VTotal - mode->VDisplay;
+    timing->h_sync_off = mode->HSyncStart - mode->HDisplay;
+    timing->h_sync_width = mode->HSyncEnd - mode->HSyncStart;
+    timing->v_sync_off = mode->VSyncStart - mode->VDisplay;
+    timing->v_sync_width = mode->VSyncEnd - mode->VSyncStart;
+
+    if (mode->Flags & V_PVSYNC)
+        timing->misc |= 0x02;
+
+    if (mode->Flags & V_PHSYNC)
+        timing->misc |= 0x01;
+}
+
 /**
  * Return the list of DDC modes if available, or the BIOS fixed mode otherwise.
  */
@@ -938,7 +960,7 @@ i830_lvds_get_modes(xf86OutputPtr output)
 	}
     }
     xf86OutputSetEDID (output, edid_mon);
-    
+
     modes = xf86OutputGetEDIDModes (output);
     if (modes != NULL)
 	return modes;
@@ -948,15 +970,35 @@ i830_lvds_get_modes(xf86OutputPtr output)
 	edid_mon = xcalloc (1, sizeof (xf86Monitor));
 	if (edid_mon)
 	{
+	    struct detailed_monitor_section *det_mon = edid_mon->det_mon;
+	    /*support DPM, instead of DPMS*/
+	    edid_mon->features.dpms |= 0x1;
+	    /*defaultly support RGB color display*/
+	    edid_mon->features.display_type |= 0x1;
+	    /*defaultly display support continuous-freqencey*/
+	    edid_mon->features.msc |= 0x1;
+	    /*defaultly  the EDID version is 1.4 */
+	    edid_mon->ver.version = 1;
+	    edid_mon->ver.revision = 4;
+
+	    if (pI830->lvds_fixed_mode != NULL) {
+		/* now we construct new EDID monitor,
+		 *  so filled one detailed timing block
+		 */
+		fill_detailed_block(det_mon, pI830->lvds_fixed_mode);
+		/* the filed timing block should be set preferred*/
+		edid_mon->features.msc |= 0x2;
+		det_mon = det_mon + 1;
+	    }
+
 	    /* Set wide sync ranges so we get all modes
 	     * handed to valid_mode for checking
 	     */
-	    edid_mon->det_mon[0].type = DS_RANGES;
-	    edid_mon->det_mon[0].section.ranges.min_v = 0;
-	    edid_mon->det_mon[0].section.ranges.max_v = 200;
-	    edid_mon->det_mon[0].section.ranges.min_h = 0;
-	    edid_mon->det_mon[0].section.ranges.max_h = 200;
-	    
+	    det_mon->type = DS_RANGES;
+	    det_mon->section.ranges.min_v = 0;
+	    det_mon->section.ranges.max_v = 200;
+	    det_mon->section.ranges.min_h = 0;
+	    det_mon->section.ranges.max_h = 200;
 	    output->MonInfo = edid_mon;
 	}
     }
commit 3354e660b0744976871683ce226f17e873f26b50
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 26 16:32:12 2008 +0800

    Fix LVDS EDID to match all possible default modes
    
    If the EDID data from the LVDS doesn't indicate support for a wide range of
    continuous frequencies, it will not match any of the default modes although
    our LVDS scaler logic ignores refresh rates when programming LVDS modes. Fix
    this by smashing the compute EDID data to open up the sync rates.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index df92dea..3796727 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -907,6 +907,36 @@ i830_lvds_get_modes(xf86OutputPtr output)
     DisplayModePtr	    modes;
 
     edid_mon = xf86OutputGetEDID (output, intel_output->pDDCBus);
+
+    /* Our LVDS scaler can hit any size, so mark the EDID data as
+     * supporting continuous timings
+     */
+    if (edid_mon) {
+	int i, j = -1;
+	edid_mon->features.msc |= 0x1;
+
+	/* Either find a DS_RANGES block, or replace a DS_VENDOR block,
+	 * smashing it into a DS_RANGES block with wide open refresh to
+	 * match all default modes
+	 */
+	for (i = 0; i < sizeof (edid_mon->det_mon) / sizeof (edid_mon->det_mon[0]); i++)
+	{
+	    if (edid_mon->det_mon[i].type >= DS_VENDOR && j == -1)
+		j = i;
+	    if (edid_mon->det_mon[i].type == DS_RANGES) {
+		j = i;
+		break;
+	    }
+	}
+	if (j != -1) {
+	    struct monitor_ranges   *ranges = &edid_mon->det_mon[j].section.ranges;
+	    edid_mon->det_mon[j].type = DS_RANGES;
+	    ranges->min_v = 0;
+	    ranges->max_v = 200;
+	    ranges->min_h = 0;
+	    ranges->max_h = 200;
+	}
+    }
     xf86OutputSetEDID (output, edid_mon);
     
     modes = xf86OutputGetEDIDModes (output);


More information about the xorg-commit mailing list