xf86-video-intel: Branch 'modesetting' - src/i830_display.h src/i830_edid_modes.c src/i830_gtf.c src/i830.h src/i830_modes.c src/i830_xf86cvt.c src/i830_xf86Modes.c src/i830_xf86Modes.h src/Makefile.am

Eric Anholt anholt at kemper.freedesktop.org
Tue Nov 28 21:19:36 EET 2006


 src/Makefile.am       |    1 
 src/i830.h            |    4 
 src/i830_display.h    |    8 +
 src/i830_edid_modes.c |  249 +++++++++++++++++++++++++++++++++++
 src/i830_gtf.c        |  353 --------------------------------------------------
 src/i830_modes.c      |  230 --------------------------------
 src/i830_xf86Modes.c  |  117 ----------------
 src/i830_xf86Modes.h  |    2 
 src/i830_xf86cvt.c    |  297 ++++++++++++++++++++++++++++++++++++++++++
 9 files changed, 557 insertions(+), 704 deletions(-)

New commits:
diff-tree e8fb40ab1063b18372be2b5996257eb69d3f15c4 (from 72692ba2e0254460c4f5a8cd476f5748383390ae)
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Nov 28 11:17:21 2006 -0800

    Replace custom DDC mode list code with a copy of the X Server's.
    
    The X Server now has most of the mode helper functions we want, and we can
    start removing compilation of our copies when the server is new enough.

diff --git a/src/Makefile.am b/src/Makefile.am
index 0fce5e4..52def8b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -63,7 +63,6 @@ i810_drv_la_SOURCES = \
          i830_driver.c \
 	 i830_dvo.c \
          i830.h \
-         i830_gtf.c \
          i830_i2c.c \
          i830_io.c \
 	 i830_lvds.c \
diff --git a/src/i830.h b/src/i830.h
index 32a540e..96ac7a4 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -676,10 +676,6 @@ void i830_lvds_init(ScrnInfoPtr pScrn);
 Bool I830BindAGPMemory(ScrnInfoPtr pScrn);
 Bool I830UnbindAGPMemory(ScrnInfoPtr pScrn);
 
-/* i830_gtf.c */
-DisplayModePtr i830GetGTF(int h_pixels, int v_lines, float freq,
-			  int interlaced, int margins);
-
 /* i830_modes.c */
 int I830ValidateXF86ModeList(ScrnInfoPtr pScrn, Bool first_time);
 void i830_reprobe_output_modes(ScrnInfoPtr pScrn);
diff --git a/src/i830_display.h b/src/i830_display.h
index 361a3c6..322f635 100644
--- a/src/i830_display.h
+++ b/src/i830_display.h
@@ -38,3 +38,11 @@ void i830DescribeOutputConfiguration(Scr
 int i830GetLoadDetectPipe(ScrnInfoPtr pScrn, I830OutputPtr output);
 void i830ReleaseLoadDetectPipe(ScrnInfoPtr pScrn, I830OutputPtr output);
 Bool i830PipeInUse(ScrnInfoPtr pScrn, int pipe);
+
+/** @{
+ */
+DisplayModePtr i830xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC);
+DisplayModePtr i830xf86CVTMode(int HDisplay, int VDisplay, float VRefresh,
+			       Bool Reduced, Bool Interlaced);
+/** @} */
+
diff --git a/src/i830_edid_modes.c b/src/i830_edid_modes.c
new file mode 100644
index 0000000..05df60c
--- /dev/null
+++ b/src/i830_edid_modes.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright 2006 Luc Verhaegen.
+ *
+ * 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
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * 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 MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ */
+
+/**
+ * @file This is a copy of edid_modes.c from the X Server, for compatibility
+ * with old X Servers.
+ */
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "xf86.h"
+#include "xf86DDC.h"
+#include <X11/Xatom.h>
+#include "property.h"
+#include "propertyst.h"
+#include "xf86DDC.h"
+
+/*
+ * TODO:
+ *  - for those with access to the VESA DMT standard; review please.
+ */
+#define MODEPREFIX(name) NULL, NULL, name, 0,M_T_DRIVER
+#define MODESUFFIX   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FALSE,FALSE,0,NULL,0,0.0,0.0
+
+DisplayModeRec DDCEstablishedModes[17] = {
+    { MODEPREFIX("800x600"),    40000,  800,  840,  968, 1056, 0,  600,  601,  605,  628, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600 at 60Hz */
+    { MODEPREFIX("800x600"),    36000,  800,  824,  896, 1024, 0,  600,  601,  603,  625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600 at 56Hz */
+    { MODEPREFIX("640x480"),    31500,  640,  656,  720,  840, 0,  480,  481,  484,  500, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480 at 75Hz */
+    { MODEPREFIX("640x480"),    31500,  640,  664,  704,  832, 0,  480,  489,  491,  520, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480 at 72Hz */
+    { MODEPREFIX("640x480"),    30240,  640,  704,  768,  864, 0,  480,  483,  486,  525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480 at 67Hz */
+    { MODEPREFIX("640x480"),    25200,  640,  656,  752,  800, 0,  480,  490,  492,  525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480 at 60Hz */
+    { MODEPREFIX("720x400"),    35500,  720,  738,  846,  900, 0,  400,  421,  423,  449, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 720x400 at 88Hz */
+    { MODEPREFIX("720x400"),    28320,  720,  738,  846,  900, 0,  400,  412,  414,  449, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 720x400 at 70Hz */
+    { MODEPREFIX("1280x1024"), 135000, 1280, 1296, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x1024 at 75Hz */
+    { MODEPREFIX("1024x768"),   78800, 1024, 1040, 1136, 1312, 0,  768,  769,  772,  800, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1024x768 at 75Hz */
+    { MODEPREFIX("1024x768"),   75000, 1024, 1048, 1184, 1328, 0,  768,  771,  777,  806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768 at 70Hz */
+    { MODEPREFIX("1024x768"),   65000, 1024, 1048, 1184, 1344, 0,  768,  771,  777,  806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768 at 60Hz */
+    { MODEPREFIX("1024x768"),   44900, 1024, 1032, 1208, 1264, 0,  768,  768,  776,  817, 0, V_PHSYNC | V_PVSYNC | V_INTERLACE, MODESUFFIX }, /* 1024x768 at 43Hz */
+    { MODEPREFIX("832x624"),    57284,  832,  864,  928, 1152, 0,  624,  625,  628,  667, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 832x624 at 75Hz */
+    { MODEPREFIX("800x600"),    49500,  800,  816,  896, 1056, 0,  600,  601,  604,  625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600 at 75Hz */
+    { MODEPREFIX("800x600"),    50000,  800,  856,  976, 1040, 0,  600,  637,  643,  666, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600 at 72Hz */
+    { MODEPREFIX("1152x864"),  108000, 1152, 1216, 1344, 1600, 0,  864,  865,  868,  900, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1152x864 at 75Hz */
+};
+
+static DisplayModePtr
+DDCModesFromEstablished(int scrnIndex, struct established_timings *timing)
+{
+    DisplayModePtr Modes = NULL, Mode = NULL;
+    CARD32 bits = (timing->t1) | (timing->t2 << 8) |
+        ((timing->t_manu & 0x80) << 9);
+    int i;
+
+    for (i = 0; i < 17; i++) {
+        if (bits & (0x01 << i)) {
+            Mode = xf86DuplicateMode(&DDCEstablishedModes[i]);
+            Modes = xf86ModesAdd(Modes, Mode);
+        }
+    }
+
+    return Modes;
+}
+
+/*
+ *
+ */
+static DisplayModePtr
+DDCModesFromStandardTiming(int scrnIndex, struct std_timings *timing)
+{
+    DisplayModePtr Modes = NULL, Mode = NULL;
+    int i;
+
+    for (i = 0; i < STD_TIMINGS; i++) {
+        if (timing[i].hsize && timing[i].vsize && timing[i].refresh) {
+            Mode =  i830xf86CVTMode(timing[i].hsize, timing[i].vsize,
+                                timing[i].refresh, FALSE, FALSE);
+	    Mode->type = M_T_DRIVER;
+            Modes = xf86ModesAdd(Modes, Mode);
+        }
+    }
+
+    return Modes;
+}
+
+/*
+ *
+ */
+static DisplayModePtr
+DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing,
+			  int preferred)
+{
+    DisplayModePtr Mode;
+
+    /* We don't do stereo */
+    if (timing->stereo) {
+        xf86DrvMsg(scrnIndex, X_INFO,
+		   "%s: Ignoring: We don't handle stereo.\n", __func__);
+        return NULL;
+    }
+
+    /* We only do seperate sync currently */
+    if (timing->sync != 0x03) {
+         xf86DrvMsg(scrnIndex, X_INFO,
+		    "%s: %dx%d Warning: We only handle seperate"
+                    " sync.\n", __func__, timing->h_active, timing->v_active);
+    }
+
+    Mode = xnfalloc(sizeof(DisplayModeRec));
+    memset(Mode, 0, sizeof(DisplayModeRec));
+
+    Mode->type = M_T_DRIVER;
+    if (preferred)
+	Mode->type |= M_T_PREFERRED;
+
+    Mode->Clock = timing->clock / 1000.0;
+
+    Mode->HDisplay = timing->h_active;
+    Mode->HSyncStart = timing->h_active + timing->h_sync_off;
+    Mode->HSyncEnd = Mode->HSyncStart + timing->h_sync_width;
+    Mode->HTotal = timing->h_active + timing->h_blanking;
+
+    Mode->VDisplay = timing->v_active;
+    Mode->VSyncStart = timing->v_active + timing->v_sync_off;
+    Mode->VSyncEnd = Mode->VSyncStart + timing->v_sync_width;
+    Mode->VTotal = timing->v_active + timing->v_blanking;
+
+    xf86SetModeDefaultName(Mode);
+
+    /* We ignore h/v_size and h/v_border for now. */
+
+    if (timing->interlaced)
+        Mode->Flags |= V_INTERLACE;
+
+    if (timing->misc & 0x02)
+        Mode->Flags |= V_PHSYNC;
+    else
+        Mode->Flags |= V_NHSYNC;
+
+    if (timing->misc & 0x01)
+        Mode->Flags |= V_PVSYNC;
+    else
+        Mode->Flags |= V_NVSYNC;
+
+    return Mode;
+}
+
+/*
+ *
+ */
+static void
+DDCGuessRangesFromModes(int scrnIndex, MonPtr Monitor, DisplayModePtr Modes)
+{
+    DisplayModePtr Mode = Modes;
+
+    if (!Monitor || !Modes)
+        return;
+
+    /* set up the ranges for scanning through the modes */
+    Monitor->nHsync = 1;
+    Monitor->hsync[0].lo = 1024.0;
+    Monitor->hsync[0].hi = 0.0;
+
+    Monitor->nVrefresh = 1;
+    Monitor->vrefresh[0].lo = 1024.0;
+    Monitor->vrefresh[0].hi = 0.0;
+
+    while (Mode) {
+        if (!Mode->HSync)
+            Mode->HSync = ((float) Mode->Clock ) / ((float) Mode->HTotal);
+
+        if (!Mode->VRefresh)
+            Mode->VRefresh = (1000.0 * ((float) Mode->Clock)) / 
+                ((float) (Mode->HTotal * Mode->VTotal));
+
+        if (Mode->HSync < Monitor->hsync[0].lo)
+            Monitor->hsync[0].lo = Mode->HSync;
+
+        if (Mode->HSync > Monitor->hsync[0].hi)
+            Monitor->hsync[0].hi = Mode->HSync;
+
+        if (Mode->VRefresh < Monitor->vrefresh[0].lo)
+            Monitor->vrefresh[0].lo = Mode->VRefresh;
+
+        if (Mode->VRefresh > Monitor->vrefresh[0].hi)
+            Monitor->vrefresh[0].hi = Mode->VRefresh;
+
+        Mode = Mode->next;
+    }
+}
+
+DisplayModePtr
+i830xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
+{
+    int preferred, i;
+    DisplayModePtr Modes = NULL, Mode;
+
+    preferred = PREFERRED_TIMING_MODE(DDC->features.msc);
+
+    /* Add established timings */
+    Mode = DDCModesFromEstablished(scrnIndex, &DDC->timings1);
+    Modes = xf86ModesAdd(Modes, Mode);
+
+    /* Add standard timings */
+    Mode = DDCModesFromStandardTiming(scrnIndex, DDC->timings2);
+    Modes = xf86ModesAdd(Modes, Mode);
+
+    for (i = 0; i < DET_TIMINGS; i++) {
+	struct detailed_monitor_section *det_mon = &DDC->det_mon[i];
+
+        switch (det_mon->type) {
+        case DT:
+            Mode = DDCModeFromDetailedTiming(scrnIndex,
+                                             &det_mon->section.d_timings,
+					     preferred);
+	    preferred = 0;
+            Modes = xf86ModesAdd(Modes, Mode);
+            break;
+        case DS_STD_TIMINGS:
+            Mode = DDCModesFromStandardTiming(scrnIndex,
+					      det_mon->section.std_t);
+            Modes = xf86ModesAdd(Modes, Mode);
+            break;
+        default:
+            break;
+        }
+    }
+
+    return Modes;
+}
diff --git a/src/i830_gtf.c b/src/i830_gtf.c
deleted file mode 100644
index 523e167..0000000
--- a/src/i830_gtf.c
+++ /dev/null
@@ -1,353 +0,0 @@
-#define DEBUG_VERB 2
-/*
- * Copyright © 2002 David Dawes
- *
- * 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
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice 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 MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHOR(S) 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.
- *
- * Except as contained in this notice, the name of the author(s) shall
- * not be used in advertising or otherwise to promote the sale, use or other
- * dealings in this Software without prior written authorization from
- * the author(s).
- *
- * Authors: David Dawes <dawes at xfree86.org>
- *
- * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/vbe/vbeModes.c,v 1.6 2002/11/02 01:38:25 dawes Exp $
- */
-/*
- * Modified by Alan Hourihane <alanh at tungstengraphics.com>
- * to support extended BIOS modes for the Intel chipsets
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdio.h>
-#include <string.h>
-
-#include "xf86.h"
-#include "vbe.h"
-#include "vbeModes.h"
-#include "i830.h"
-#include "i830_xf86Modes.h"
-
-#include <math.h>
-
-#define rint(x) floor(x)
-
-#define MARGIN_PERCENT    1.8   /* % of active vertical image                */
-#define CELL_GRAN         8.0   /* assumed character cell granularity        */
-#define MIN_PORCH         1     /* minimum front porch                       */
-#define V_SYNC_RQD        3     /* width of vsync in lines                   */
-#define H_SYNC_PERCENT    8.0   /* width of hsync as % of total line         */
-#define MIN_VSYNC_PLUS_BP 550.0 /* min time of vsync + back porch (microsec) */
-#define M                 600.0 /* blanking formula gradient                 */
-#define C                 40.0  /* blanking formula offset                   */
-#define K                 128.0 /* blanking formula scaling factor           */
-#define J                 20.0  /* blanking formula scaling factor           */
-
-/* C' and M' are part of the Blanking Duty Cycle computation */
-
-#define C_PRIME           (((C - J) * K/256.0) + J)
-#define M_PRIME           (K/256.0 * M)
-
-DisplayModePtr
-i830GetGTF(int h_pixels, int v_lines, float freq, int interlaced, int margins)
-{
-    float h_pixels_rnd;
-    float v_lines_rnd;
-    float v_field_rate_rqd;
-    float top_margin;
-    float bottom_margin;
-    float interlace;
-    float h_period_est;
-    float vsync_plus_bp;
-    float v_back_porch;
-    float total_v_lines;
-    float v_field_rate_est;
-    float h_period;
-    float v_field_rate;
-    float v_frame_rate;
-    float left_margin;
-    float right_margin;
-    float total_active_pixels;
-    float ideal_duty_cycle;
-    float h_blank;
-    float total_pixels;
-    float pixel_freq;
-    float h_freq;
-
-    float h_sync;
-    float h_front_porch;
-    float v_odd_front_porch_lines;
-    DisplayModePtr m;
-
-    m = xnfcalloc(sizeof(DisplayModeRec), 1);
-    
-    
-    /*  1. In order to give correct results, the number of horizontal
-     *  pixels requested is first processed to ensure that it is divisible
-     *  by the character size, by rounding it to the nearest character
-     *  cell boundary:
-     *
-     *  [H PIXELS RND] = ((ROUND([H PIXELS]/[CELL GRAN RND],0))*[CELLGRAN RND])
-     */
-    
-    h_pixels_rnd = rint((float) h_pixels / CELL_GRAN) * CELL_GRAN;
-    
-    
-    /*  2. If interlace is requested, the number of vertical lines assumed
-     *  by the calculation must be halved, as the computation calculates
-     *  the number of vertical lines per field. In either case, the
-     *  number of lines is rounded to the nearest integer.
-     *   
-     *  [V LINES RND] = IF([INT RQD?]="y", ROUND([V LINES]/2,0),
-     *                                     ROUND([V LINES],0))
-     */
-
-    v_lines_rnd = interlaced ?
-            rint((float) v_lines) / 2.0 :
-            rint((float) v_lines);
-    
-    /*  3. Find the frame rate required:
-     *
-     *  [V FIELD RATE RQD] = IF([INT RQD?]="y", [I/P FREQ RQD]*2,
-     *                                          [I/P FREQ RQD])
-     */
-
-    v_field_rate_rqd = interlaced ? (freq * 2.0) : (freq);
-
-    /*  4. Find number of lines in Top margin:
-     *
-     *  [TOP MARGIN (LINES)] = IF([MARGINS RQD?]="Y",
-     *          ROUND(([MARGIN%]/100*[V LINES RND]),0),
-     *          0)
-     */
-
-    top_margin = margins ? rint(MARGIN_PERCENT / 100.0 * v_lines_rnd) : (0.0);
-
-    /*  5. Find number of lines in Bottom margin:
-     *
-     *  [BOT MARGIN (LINES)] = IF([MARGINS RQD?]="Y",
-     *          ROUND(([MARGIN%]/100*[V LINES RND]),0),
-     *          0)
-     */
-
-    bottom_margin = margins ? rint(MARGIN_PERCENT/100.0 * v_lines_rnd) : (0.0);
-
-    /*  6. If interlace is required, then set variable [INTERLACE]=0.5:
-     *   
-     *  [INTERLACE]=(IF([INT RQD?]="y",0.5,0))
-     */
-
-    interlace = interlaced ? 0.5 : 0.0;
-
-    /*  7. Estimate the Horizontal period
-     *
-     *  [H PERIOD EST] = ((1/[V FIELD RATE RQD]) - [MIN VSYNC+BP]/1000000) /
-     *                    ([V LINES RND] + (2*[TOP MARGIN (LINES)]) +
-     *                     [MIN PORCH RND]+[INTERLACE]) * 1000000
-     */
-
-    h_period_est = (((1.0/v_field_rate_rqd) - (MIN_VSYNC_PLUS_BP/1000000.0))
-                    / (v_lines_rnd + (2*top_margin) + MIN_PORCH + interlace)
-                    * 1000000.0);
-
-    /*  8. Find the number of lines in V sync + back porch:
-     *
-     *  [V SYNC+BP] = ROUND(([MIN VSYNC+BP]/[H PERIOD EST]),0)
-     */
-
-    vsync_plus_bp = rint(MIN_VSYNC_PLUS_BP/h_period_est);
-
-    /*  9. Find the number of lines in V back porch alone:
-     *
-     *  [V BACK PORCH] = [V SYNC+BP] - [V SYNC RND]
-     *
-     *  XXX is "[V SYNC RND]" a typo? should be [V SYNC RQD]?
-     */
-    
-    v_back_porch = vsync_plus_bp - V_SYNC_RQD;
-    
-    /*  10. Find the total number of lines in Vertical field period:
-     *
-     *  [TOTAL V LINES] = [V LINES RND] + [TOP MARGIN (LINES)] +
-     *                    [BOT MARGIN (LINES)] + [V SYNC+BP] + [INTERLACE] +
-     *                    [MIN PORCH RND]
-     */
-
-    total_v_lines = v_lines_rnd + top_margin + bottom_margin + vsync_plus_bp +
-        interlace + MIN_PORCH;
-    
-    /*  11. Estimate the Vertical field frequency:
-     *
-     *  [V FIELD RATE EST] = 1 / [H PERIOD EST] / [TOTAL V LINES] * 1000000
-     */
-
-    v_field_rate_est = 1.0 / h_period_est / total_v_lines * 1000000.0;
-    
-    /*  12. Find the actual horizontal period:
-     *
-     *  [H PERIOD] = [H PERIOD EST] / ([V FIELD RATE RQD] / [V FIELD RATE EST])
-     */
-
-    h_period = h_period_est / (v_field_rate_rqd / v_field_rate_est);
-    
-    /*  13. Find the actual Vertical field frequency:
-     *
-     *  [V FIELD RATE] = 1 / [H PERIOD] / [TOTAL V LINES] * 1000000
-     */
-
-    v_field_rate = 1.0 / h_period / total_v_lines * 1000000.0;
-
-    /*  14. Find the Vertical frame frequency:
-     *
-     *  [V FRAME RATE] = (IF([INT RQD?]="y", [V FIELD RATE]/2, [V FIELD RATE]))
-     */
-
-    v_frame_rate = interlaced ? v_field_rate / 2.0 : v_field_rate;
-
-    /*  15. Find number of pixels in left margin:
-     *
-     *  [LEFT MARGIN (PIXELS)] = (IF( [MARGINS RQD?]="Y",
-     *          (ROUND( ([H PIXELS RND] * [MARGIN%] / 100 /
-     *                   [CELL GRAN RND]),0)) * [CELL GRAN RND],
-     *          0))
-     */
-
-    left_margin = margins ?
-        rint(h_pixels_rnd * MARGIN_PERCENT / 100.0 / CELL_GRAN) * CELL_GRAN :
-        0.0;
-    
-    /*  16. Find number of pixels in right margin:
-     *
-     *  [RIGHT MARGIN (PIXELS)] = (IF( [MARGINS RQD?]="Y",
-     *          (ROUND( ([H PIXELS RND] * [MARGIN%] / 100 /
-     *                   [CELL GRAN RND]),0)) * [CELL GRAN RND],
-     *          0))
-     */
-    
-    right_margin = margins ?
-        rint(h_pixels_rnd * MARGIN_PERCENT / 100.0 / CELL_GRAN) * CELL_GRAN :
-        0.0;
-    
-    /*  17. Find total number of active pixels in image and left and right
-     *  margins:
-     *
-     *  [TOTAL ACTIVE PIXELS] = [H PIXELS RND] + [LEFT MARGIN (PIXELS)] +
-     *                          [RIGHT MARGIN (PIXELS)]
-     */
-
-    total_active_pixels = h_pixels_rnd + left_margin + right_margin;
-    
-    /*  18. Find the ideal blanking duty cycle from the blanking duty cycle
-     *  equation:
-     *
-     *  [IDEAL DUTY CYCLE] = [C'] - ([M']*[H PERIOD]/1000)
-     */
-
-    ideal_duty_cycle = C_PRIME - (M_PRIME * h_period / 1000.0);
-    
-    /*  19. Find the number of pixels in the blanking time to the nearest
-     *  double character cell:
-     *
-     *  [H BLANK (PIXELS)] = (ROUND(([TOTAL ACTIVE PIXELS] *
-     *                               [IDEAL DUTY CYCLE] /
-     *                               (100-[IDEAL DUTY CYCLE]) /
-     *                               (2*[CELL GRAN RND])), 0))
-     *                       * (2*[CELL GRAN RND])
-     */
-
-    h_blank = rint(total_active_pixels *
-                   ideal_duty_cycle /
-                   (100.0 - ideal_duty_cycle) /
-                   (2.0 * CELL_GRAN)) * (2.0 * CELL_GRAN);
-    
-    /*  20. Find total number of pixels:
-     *
-     *  [TOTAL PIXELS] = [TOTAL ACTIVE PIXELS] + [H BLANK (PIXELS)]
-     */
-
-    total_pixels = total_active_pixels + h_blank;
-    
-    /*  21. Find pixel clock frequency:
-     *
-     *  [PIXEL FREQ] = [TOTAL PIXELS] / [H PERIOD]
-     */
-    
-    pixel_freq = total_pixels / h_period;
-    
-    /*  22. Find horizontal frequency:
-     *
-     *  [H FREQ] = 1000 / [H PERIOD]
-     */
-
-    h_freq = 1000.0 / h_period;
-    
-
-    /* Stage 1 computations are now complete; I should really pass
-       the results to another function and do the Stage 2
-       computations, but I only need a few more values so I'll just
-       append the computations here for now */
-
-    
-
-    /*  17. Find the number of pixels in the horizontal sync period:
-     *
-     *  [H SYNC (PIXELS)] =(ROUND(([H SYNC%] / 100 * [TOTAL PIXELS] /
-     *                             [CELL GRAN RND]),0))*[CELL GRAN RND]
-     */
-
-    h_sync = rint(H_SYNC_PERCENT/100.0 * total_pixels / CELL_GRAN) * CELL_GRAN;
-
-    /*  18. Find the number of pixels in the horizontal front porch period:
-     *
-     *  [H FRONT PORCH (PIXELS)] = ([H BLANK (PIXELS)]/2)-[H SYNC (PIXELS)]
-     */
-
-    h_front_porch = (h_blank / 2.0) - h_sync;
-
-    /*  36. Find the number of lines in the odd front porch period:
-     *
-     *  [V ODD FRONT PORCH(LINES)]=([MIN PORCH RND]+[INTERLACE])
-     */
-    
-    v_odd_front_porch_lines = MIN_PORCH + interlace;
-    
-    /* finally, pack the results in the DisplayMode struct */
-    
-    m->HDisplay  = (int) (h_pixels_rnd);
-    m->HSyncStart = (int) (h_pixels_rnd + h_front_porch);
-    m->HSyncEnd = (int) (h_pixels_rnd + h_front_porch + h_sync);
-    m->HTotal = (int) (total_pixels);
-
-    m->VDisplay  = (int) (v_lines_rnd);
-    m->VSyncStart = (int) (v_lines_rnd + v_odd_front_porch_lines);
-    m->VSyncEnd = (int) (int) (v_lines_rnd + v_odd_front_porch_lines + V_SYNC_RQD);
-    m->VTotal = (int) (total_v_lines);
-
-    m->Clock   = (int)(pixel_freq * 1000);
-    m->SynthClock   = m->Clock;
-    m->HSync = h_freq;
-    m->VRefresh = v_frame_rate /* freq */;
-
-    i830xf86SetModeDefaultName(m);
-
-    return (m);
-}
diff --git a/src/i830_modes.c b/src/i830_modes.c
index 7fdd40e..a0428a0 100644
--- a/src/i830_modes.c
+++ b/src/i830_modes.c
@@ -48,31 +48,13 @@
 #include <math.h>
 
 #include "xf86.h"
+#include "xf86DDC.h"
 #include "X11/Xatom.h"
 #include "i830.h"
 #include "i830_display.h"
 #include "i830_xf86Modes.h"
 #include <randrstr.h>
 
-#define rint(x) floor(x)
-
-#define MAX(a,b) ((a) > (b) ? (a) : (b))
-
-#define MARGIN_PERCENT    1.8   /* % of active vertical image                */
-#define CELL_GRAN         8.0   /* assumed character cell granularity        */
-#define MIN_PORCH         1     /* minimum front porch                       */
-#define V_SYNC_RQD        3     /* width of vsync in lines                   */
-#define H_SYNC_PERCENT    8.0   /* width of hsync as % of total line         */
-#define MIN_VSYNC_PLUS_BP 550.0 /* min time of vsync + back porch (microsec) */
-#define M                 600.0 /* blanking formula gradient                 */
-#define C                 40.0  /* blanking formula offset                   */
-#define K                 128.0 /* blanking formula scaling factor           */
-#define J                 20.0  /* blanking formula scaling factor           */
-
-/* C' and M' are part of the Blanking Duty Cycle computation */
-
-#define C_PRIME           (((C - J) * K/256.0) + J)
-#define M_PRIME           (K/256.0 * M)
 /* Established timings from EDID standard */
 static struct
 {
@@ -163,214 +145,6 @@ I830PrintModes(ScrnInfoPtr scrp)
     } while (p != NULL && p != scrp->modes);
 }
 
-/* This function will sort all modes according to their resolution.
- * Highest resolution first.
- */
-static void
-I830xf86SortModes(DisplayModePtr new, DisplayModePtr *first,
-	      DisplayModePtr *last)
-{
-    DisplayModePtr  p;
-
-    p = *last;
-    while (p) {
-	if (((new->HDisplay < p->HDisplay) &&
-	     (new->VDisplay < p->VDisplay)) ||
-	    ((new->HDisplay * new->VDisplay) < (p->HDisplay * p->VDisplay)) ||
-	    ((new->HDisplay == p->HDisplay) &&
-	     (new->VDisplay == p->VDisplay) &&
-	     (new->Clock < p->Clock))) {
-
-	    if (p->next) 
-		p->next->prev = new;
-	    new->prev = p;
-	    new->next = p->next;
-	    p->next = new;
-	    if (!(new->next))
-		*last = new;
-	    break;
-	}
-	if (!p->prev) {
-	    new->prev = NULL;
-	    new->next = p;
-	    p->prev = new;
-	    *first = new;
-	    break;
-	}
-	p = p->prev;
-    }
-
-    if (!*first) {
-	*first = new;
-	new->prev = NULL;
-	new->next = NULL;
-	*last = new;
-    }
-}
-
-/**
- * Gets a new pointer to a VESA established mode.
- *
- * \param i index into the VESA established modes table.
- */
-static DisplayModePtr
-I830GetVESAEstablishedMode(ScrnInfoPtr pScrn, int i)
-{
-    DisplayModePtr pMode;
-
-    for (pMode = I830xf86DefaultModes; pMode->name != NULL; pMode++)
-    {
-	if (pMode->HDisplay == est_timings[i].hsize &&
-	    pMode->VDisplay == est_timings[i].vsize &&
-	    fabs(i830xf86ModeVRefresh(pMode) - est_timings[i].refresh) < 1.0)
-	{
-	    DisplayModePtr pNew = i830xf86DuplicateMode(pMode);
-	    i830xf86SetModeDefaultName(pNew);
-	    pNew->VRefresh = i830xf86ModeVRefresh(pMode);
-	    return pNew;
-	}
-    }
-    return NULL;
-}
-
-static DisplayModePtr
-i830GetDDCModes(ScrnInfoPtr pScrn, xf86MonPtr ddc)
-{
-    DisplayModePtr  last  = NULL;
-    DisplayModePtr  new   = NULL;
-    DisplayModePtr  first = NULL;
-    int             count = 0;
-    int             j, tmp;
-
-    if (ddc == NULL)
-	return NULL;
-
-    /* Go thru detailed timing table first */
-    for (j = 0; j < 4; j++) {
-	if (ddc->det_mon[j].type == 0) {
-	    struct detailed_timings *d_timings =
-		&ddc->det_mon[j].section.d_timings;
-
-	    if (d_timings->h_active == 0 || d_timings->v_active == 0) break;
-
-	    new = xnfcalloc(1, sizeof (DisplayModeRec));
-	    memset(new, 0, sizeof (DisplayModeRec));
-
-	    new->HDisplay   = d_timings->h_active;
-	    new->VDisplay   = d_timings->v_active;
-
-	    new->HTotal     = new->HDisplay + d_timings->h_blanking;
-	    new->HSyncStart = new->HDisplay + d_timings->h_sync_off;
-	    new->HSyncEnd   = new->HSyncStart + d_timings->h_sync_width;
-	    new->VTotal     = new->VDisplay + d_timings->v_blanking;
-	    new->VSyncStart = new->VDisplay + d_timings->v_sync_off;
-	    new->VSyncEnd   = new->VSyncStart + d_timings->v_sync_width;
-	    new->Clock      = d_timings->clock / 1000;
-	    new->Flags      = (d_timings->interlaced ? V_INTERLACE : 0);
-	    new->status     = MODE_OK;
-	    if (PREFERRED_TIMING_MODE(ddc->features.msc))
-		new->type   = M_T_PREFERRED;
-	    else
-		new->type   = M_T_DRIVER;
-
-	    i830xf86SetModeDefaultName(new);
-
-	    if (d_timings->sync == 3) {
-		switch (d_timings->misc) {
-		case 0: new->Flags |= V_NHSYNC | V_NVSYNC; break;
-		case 1: new->Flags |= V_PHSYNC | V_NVSYNC; break;
-		case 2: new->Flags |= V_NHSYNC | V_PVSYNC; break;
-		case 3: new->Flags |= V_PHSYNC | V_PVSYNC; break;
-		}
-	    }
-	    count++;
-
-	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		       "Valid Mode from Detailed timing table: %s (ht %d hss %d hse %d vt %d vss %d vse %d)\n",
-		       new->name,
-		       new->HTotal, new->HSyncStart, new->HSyncEnd,
-		       new->VTotal, new->VSyncStart, new->VSyncEnd);
-
-	    I830xf86SortModes(new, &first, &last);
-	}
-    }
-
-    /* Search thru standard VESA modes from EDID */
-    for (j = 0; j < 8; j++) {
-        if (ddc->timings2[j].hsize == 0 || ddc->timings2[j].vsize == 0)
-               continue;
-#if 1
-	new = i830GetGTF(ddc->timings2[j].hsize, ddc->timings2[j].vsize,
-			 ddc->timings2[j].refresh, FALSE, FALSE);
-	new->status = MODE_OK;
-	new->type |= M_T_DEFAULT;
-
-	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		   "Valid Mode from standard timing table: %s\n",
-		   new->name);
-
-	I830xf86SortModes(new, &first, &last);
-#else
-	for (p = pScrn->monitor->Modes; p && p->next; p = p->next->next) {
-
-	    /* Ignore all double scan modes */
-	    if ((ddc->timings2[j].hsize == p->HDisplay) &&
-		(ddc->timings2[j].vsize == p->VDisplay)) {
-		float  refresh =
-		    (float)p->Clock * 1000.0 / p->HTotal / p->VTotal;
-		float err = (float)ddc->timings2[j].refresh - refresh;
-
-		if (err < 0) err = -err;
-		if (err < 1.0) {
-		    /* Is this good enough? */
-		    new = xnfcalloc(1, sizeof (DisplayModeRec));
-		    memcpy(new, p, sizeof(DisplayModeRec));
-		    new->name = xnfalloc(strlen(p->name) + 1);
-		    strcpy(new->name, p->name);
-		    new->status = MODE_OK;
-		    new->type   = M_T_DEFAULT;
-
-		    count++;
-
-		    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-			       "Valid Mode from standard timing table: %s\n",
-			       new->name);
-
-		    I830xf86SortModes(new, &first, &last);
-		    break;
-		}
-	    }
-	}
-#endif
-    }
-
-    /* Search thru established modes from EDID */
-    tmp = (ddc->timings1.t1 << 8) | ddc->timings1.t2;
-    for (j = 0; j < 16; j++) {
-	if (tmp & (1 << j)) {
-	    new = I830GetVESAEstablishedMode(pScrn, j);
-	    if (new == NULL) {
-		ErrorF("Couldn't get established mode %d\n", j);
-		continue;
-	    }
-	    new->status = MODE_OK;
-	    new->type = M_T_DEFAULT;
-
-	    count++;
-
-	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Valid Mode from established "
-		       "timing table: %s\n", new->name);
-
-	    I830xf86SortModes(new, &first, &last);
-	}
-    }
-
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	       "Total of %d DDC mode(s) found.\n", count);
-
-    return first;
-}
-
 static DisplayModePtr
 i830GetModeListTail(DisplayModePtr pModeList)
 {
@@ -673,7 +447,7 @@ i830_ddc_get_modes(ScrnInfoPtr pScrn, I8
 	       i830_output_type_names[output->type]);
     xf86PrintEDID(output->MonInfo);
 
-    ddc_modes = i830GetDDCModes(pScrn, ddc_mon);
+    ddc_modes = xf86DDCGetModes(pScrn->scrnIndex, ddc_mon);
 
     /* Strip out any modes that can't be supported on this output. */
     for (mode = ddc_modes; mode != NULL; mode = mode->next) {
diff --git a/src/i830_xf86Modes.c b/src/i830_xf86Modes.c
index ca92e4d..24cc23b 100644
--- a/src/i830_xf86Modes.c
+++ b/src/i830_xf86Modes.c
@@ -45,7 +45,6 @@
  * there but we still want to use.  We need to come up with better API here.
  */
 
-
 /**
  * Calculates the horizontal sync rate of a mode.
  *
@@ -88,12 +87,7 @@ i830xf86ModeVRefresh(DisplayModePtr mode
     return refresh;
 }
 
-/**
- * Sets a default mode name of <width>x<height>x<refresh> on a mode.
- *
- * The refresh rate doesn't contain decimals, as that's expected to be
- * unimportant from the user's perspective for non-custom modelines.
- */
+/** Sets a default mode name of <width>x<height> on a mode. */
 void
 i830xf86SetModeDefaultName(DisplayModePtr mode)
 {
@@ -530,112 +524,3 @@ i830xf86PruneInvalidModes(ScrnInfoPtr pS
 	mode = next;
     }
 }
-
-#define MODEPREFIX(name) NULL, NULL, name, MODE_OK, M_T_DEFAULT
-#define MODESUFFIX       0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0,FALSE,FALSE,0,NULL,0,0.0,0.0
-
-/**
- * List of VESA established modes, taken from xf86DefaultModes but trimmed down.
- * (not trimming should be harmless).
- */
-DisplayModeRec I830xf86DefaultModes[] = {
-/* 640x350 @ 85Hz (VESA) hsync: 37.9kHz */
-	{MODEPREFIX("640x350"),31500, 640,672,736,832,0, 350,382,385,445,0, V_PHSYNC | V_NVSYNC, MODESUFFIX},
-	{MODEPREFIX("320x175"),15750, 320,336,368,416,0, 175,191,192,222,0, V_PHSYNC | V_NVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 640x400 @ 85Hz (VESA) hsync: 37.9kHz */
-	{MODEPREFIX("640x400"),31500, 640,672,736,832,0, 400,401,404,445,0, V_NHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("320x200"),15750, 320,336,368,416,0, 200,200,202,222,0, V_NHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 720x400 @ 85Hz (VESA) hsync: 37.9kHz */
-	{MODEPREFIX("720x400"),35500, 720,756,828,936,0, 400,401,404,446,0, V_NHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("360x200"),17750, 360,378,414,468,0, 200,200,202,223,0, V_NHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 640x480 @ 72Hz (VESA) hsync: 37.9kHz */
-	{MODEPREFIX("640x480"),31500, 640,664,704,832,0, 480,489,491,520,0, V_NHSYNC | V_NVSYNC, MODESUFFIX},
-	{MODEPREFIX("320x240"),15750, 320,332,352,416,0, 240,244,245,260,0, V_NHSYNC | V_NVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 640x480 @ 75Hz (VESA) hsync: 37.5kHz */
-	{MODEPREFIX("640x480"),31500, 640,656,720,840,0, 480,481,484,500,0, V_NHSYNC | V_NVSYNC, MODESUFFIX},
-	{MODEPREFIX("320x240"),15750, 320,328,360,420,0, 240,240,242,250,0, V_NHSYNC | V_NVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 640x480 @ 85Hz (VESA) hsync: 43.3kHz */
-	{MODEPREFIX("640x480"),36000, 640,696,752,832,0, 480,481,484,509,0, V_NHSYNC | V_NVSYNC, MODESUFFIX},
-	{MODEPREFIX("320x240"),18000, 320,348,376,416,0, 240,240,242,254,0, V_NHSYNC | V_NVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 800x600 @ 56Hz (VESA) hsync: 35.2kHz */
-	{MODEPREFIX("800x600"),36000, 800,824,896,1024,0, 600,601,603,625,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("400x300"),18000, 400,412,448,512,0, 300,300,301,312,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 800x600 @ 60Hz (VESA) hsync: 37.9kHz */
-	{MODEPREFIX("800x600"),40000, 800,840,968,1056,0, 600,601,605,628,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("400x300"),20000, 400,420,484,528,0, 300,300,302,314,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 800x600 @ 72Hz (VESA) hsync: 48.1kHz */
-	{MODEPREFIX("800x600"),50000, 800,856,976,1040,0, 600,637,643,666,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("400x300"),25000, 400,428,488,520,0, 300,318,321,333,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 800x600 @ 75Hz (VESA) hsync: 46.9kHz */
-	{MODEPREFIX("800x600"),49500, 800,816,896,1056,0, 600,601,604,625,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("400x300"),24750, 400,408,448,528,0, 300,300,302,312,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 800x600 @ 85Hz (VESA) hsync: 53.7kHz */
-	{MODEPREFIX("800x600"),56300, 800,832,896,1048,0, 600,601,604,631,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("400x300"),28150, 400,416,448,524,0, 300,300,302,315,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1024x768 @ 60Hz (VESA) hsync: 48.4kHz */
-	{MODEPREFIX("1024x768"),65000, 1024,1048,1184,1344,0, 768,771,777,806,0, V_NHSYNC | V_NVSYNC, MODESUFFIX},
-	{MODEPREFIX("512x384"),32500, 512,524,592,672,0, 384,385,388,403,0, V_NHSYNC | V_NVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1024x768 @ 70Hz (VESA) hsync: 56.5kHz */
-	{MODEPREFIX("1024x768"),75000, 1024,1048,1184,1328,0, 768,771,777,806,0, V_NHSYNC | V_NVSYNC, MODESUFFIX},
-	{MODEPREFIX("512x384"),37500, 512,524,592,664,0, 384,385,388,403,0, V_NHSYNC | V_NVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1024x768 @ 75Hz (VESA) hsync: 60.0kHz */
-	{MODEPREFIX("1024x768"),78800, 1024,1040,1136,1312,0, 768,769,772,800,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("512x384"),39400, 512,520,568,656,0, 384,384,386,400,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1024x768 @ 85Hz (VESA) hsync: 68.7kHz */
-	{MODEPREFIX("1024x768"),94500, 1024,1072,1168,1376,0, 768,769,772,808,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("512x384"),47250, 512,536,584,688,0, 384,384,386,404,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1152x864 @ 75Hz (VESA) hsync: 67.5kHz */
-	{MODEPREFIX("1152x864"),108000, 1152,1216,1344,1600,0, 864,865,868,900,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("576x432"),54000, 576,608,672,800,0, 432,432,434,450,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1280x960 @ 60Hz (VESA) hsync: 60.0kHz */
-	{MODEPREFIX("1280x960"),108000, 1280,1376,1488,1800,0, 960,961,964,1000,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("640x480"),54000, 640,688,744,900,0, 480,480,482,500,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1280x960 @ 85Hz (VESA) hsync: 85.9kHz */
-	{MODEPREFIX("1280x960"),148500, 1280,1344,1504,1728,0, 960,961,964,1011,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("640x480"),74250, 640,672,752,864,0, 480,480,482,505,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1280x1024 @ 60Hz (VESA) hsync: 64.0kHz */
-	{MODEPREFIX("1280x1024"),108000, 1280,1328,1440,1688,0, 1024,1025,1028,1066,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("640x512"),54000, 640,664,720,844,0, 512,512,514,533,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1280x1024 @ 75Hz (VESA) hsync: 80.0kHz */
-	{MODEPREFIX("1280x1024"),135000, 1280,1296,1440,1688,0, 1024,1025,1028,1066,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("640x512"),67500, 640,648,720,844,0, 512,512,514,533,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1280x1024 @ 85Hz (VESA) hsync: 91.1kHz */
-	{MODEPREFIX("1280x1024"),157500, 1280,1344,1504,1728,0, 1024,1025,1028,1072,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("640x512"),78750, 640,672,752,864,0, 512,512,514,536,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1600x1200 @ 60Hz (VESA) hsync: 75.0kHz */
-	{MODEPREFIX("1600x1200"),162000, 1600,1664,1856,2160,0, 1200,1201,1204,1250,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("800x600"),81000, 800,832,928,1080,0, 600,600,602,625,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1600x1200 @ 65Hz (VESA) hsync: 81.3kHz */
-	{MODEPREFIX("1600x1200"),175500, 1600,1664,1856,2160,0, 1200,1201,1204,1250,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("800x600"),87750, 800,832,928,1080,0, 600,600,602,625,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1600x1200 @ 70Hz (VESA) hsync: 87.5kHz */
-	{MODEPREFIX("1600x1200"),189000, 1600,1664,1856,2160,0, 1200,1201,1204,1250,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("800x600"),94500, 800,832,928,1080,0, 600,600,602,625,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1600x1200 @ 75Hz (VESA) hsync: 93.8kHz */
-	{MODEPREFIX("1600x1200"),202500, 1600,1664,1856,2160,0, 1200,1201,1204,1250,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("800x600"),101250, 800,832,928,1080,0, 600,600,602,625,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1600x1200 @ 85Hz (VESA) hsync: 106.3kHz */
-	{MODEPREFIX("1600x1200"),229500, 1600,1664,1856,2160,0, 1200,1201,1204,1250,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("800x600"),114750, 800,832,928,1080,0, 600,600,602,625,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1792x1344 @ 60Hz (VESA) hsync: 83.6kHz */
-	{MODEPREFIX("1792x1344"),204800, 1792,1920,2120,2448,0, 1344,1345,1348,1394,0, V_NHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("896x672"),102400, 896,960,1060,1224,0, 672,672,674,697,0, V_NHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1792x1344 @ 75Hz (VESA) hsync: 106.3kHz */
-	{MODEPREFIX("1792x1344"),261000, 1792,1888,2104,2456,0, 1344,1345,1348,1417,0, V_NHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("896x672"),130500, 896,944,1052,1228,0, 672,672,674,708,0, V_NHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1856x1392 @ 60Hz (VESA) hsync: 86.3kHz */
-	{MODEPREFIX("1856x1392"),218300, 1856,1952,2176,2528,0, 1392,1393,1396,1439,0, V_NHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("928x696"),109150, 928,976,1088,1264,0, 696,696,698,719,0, V_NHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1856x1392 @ 75Hz (VESA) hsync: 112.5kHz */
-	{MODEPREFIX("1856x1392"),288000, 1856,1984,2208,2560,0, 1392,1393,1396,1500,0, V_NHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("928x696"),144000, 928,992,1104,1280,0, 696,696,698,750,0, V_NHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1920x1440 @ 60Hz (VESA) hsync: 90.0kHz */
-	{MODEPREFIX("1920x1440"),234000, 1920,2048,2256,2600,0, 1440,1441,1444,1500,0, V_NHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("960x720"),117000, 960,1024,1128,1300,0, 720,720,722,750,0, V_NHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1920x1440 @ 75Hz (VESA) hsync: 112.5kHz */
-	{MODEPREFIX("1920x1440"),297000, 1920,2064,2288,2640,0, 1440,1441,1444,1500,0, V_NHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("960x720"),148500, 960,1032,1144,1320,0, 720,720,722,750,0, V_NHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-
-	/* Terminator */
-	{MODEPREFIX(NULL), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MODESUFFIX}
-};
diff --git a/src/i830_xf86Modes.h b/src/i830_xf86Modes.h
index 5a26c0e..262a45c 100644
--- a/src/i830_xf86Modes.h
+++ b/src/i830_xf86Modes.h
@@ -75,5 +75,3 @@ i830xf86ValidateModesUserConfig(ScrnInfo
 
 void
 PrintModeline(int scrnIndex,DisplayModePtr mode);
-
-extern DisplayModeRec I830xf86DefaultModes[];
diff --git a/src/i830_xf86cvt.c b/src/i830_xf86cvt.c
new file mode 100644
index 0000000..b0f9727
--- /dev/null
+++ b/src/i830_xf86cvt.c
@@ -0,0 +1,297 @@
+/*
+ * Copyright 2005-2006 Luc Verhaegen.
+ *
+ * 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
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice 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 MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ */
+
+/**
+ * @file This is a copy of xf86cvt.c from the X Server, for compatibility with
+ * old servers (pre-1.2).
+ */
+
+/*
+ * The reason for having this function in a file of its own is
+ * so that ../utils/cvt/cvt can link to it, and that xf86CVTMode
+ * code is shared directly.
+ */
+
+#include "xf86.h"
+
+/*
+ * Generate a CVT standard mode from HDisplay, VDisplay and VRefresh.
+ *
+ * These calculations are stolen from the CVT calculation spreadsheet written
+ * by Graham Loveridge. He seems to be claiming no copyright and there seems to
+ * be no license attached to this. He apparently just wants to see his name
+ * mentioned.
+ *
+ * This file can be found at http://www.vesa.org/Public/CVT/CVTd6r1.xls
+ *
+ * Comments and structure corresponds to the comments and structure of the xls.
+ * This should ease importing of future changes to the standard (not very
+ * likely though).
+ *
+ * About margins; i'm sure that they are to be the bit between HDisplay and
+ * HBlankStart, HBlankEnd and HTotal, VDisplay and VBlankStart, VBlankEnd and 
+ * VTotal, where the overscan colour is shown. FB seems to call _all_ blanking
+ * outside sync "margin" for some reason. Since we prefer seeing proper
+ * blanking instead of the overscan colour, and since the Crtc* values will
+ * probably get altered after us, we will disable margins altogether. With
+ * these calculations, Margins will plainly expand H/VDisplay, and we don't
+ * want that. -- libv
+ *
+ */
+_X_EXPORT DisplayModePtr
+i830xf86CVTMode(int HDisplay, int VDisplay, float VRefresh, Bool Reduced,
+		Bool Interlaced)
+{
+    DisplayModeRec  *Mode = xnfalloc(sizeof(DisplayModeRec));
+
+    /* 1) top/bottom margin size (% of height) - default: 1.8 */
+#define CVT_MARGIN_PERCENTAGE 1.8    
+
+    /* 2) character cell horizontal granularity (pixels) - default 8 */
+#define CVT_H_GRANULARITY 8
+
+    /* 4) Minimum vertical porch (lines) - default 3 */
+#define CVT_MIN_V_PORCH 3
+
+    /* 4) Minimum number of vertical back porch lines - default 6 */
+#define CVT_MIN_V_BPORCH 6
+
+    /* Pixel Clock step (kHz) */
+#define CVT_CLOCK_STEP 250
+
+    Bool Margins = FALSE;
+    float  VFieldRate, HPeriod;
+    int  HDisplayRnd, HMargin;
+    int  VDisplayRnd, VMargin, VSync;
+    float  Interlace; /* Please rename this */
+
+    memset(Mode, 0, sizeof(DisplayModeRec));
+
+    /* CVT default is 60.0Hz */
+    if (!VRefresh)
+        VRefresh = 60.0;
+
+    /* 1. Required field rate */
+    if (Interlaced)
+        VFieldRate = VRefresh * 2;
+    else
+        VFieldRate = VRefresh;
+
+    /* 2. Horizontal pixels */
+    HDisplayRnd = HDisplay - (HDisplay % CVT_H_GRANULARITY);
+
+    /* 3. Determine left and right borders */
+    if (Margins) {
+        /* right margin is actually exactly the same as left */
+        HMargin = (((float) HDisplayRnd) * CVT_MARGIN_PERCENTAGE / 100.0);
+        HMargin -= HMargin % CVT_H_GRANULARITY;
+    } else
+        HMargin = 0;
+
+    /* 4. Find total active pixels */
+    Mode->HDisplay = HDisplayRnd + 2*HMargin;
+
+    /* 5. Find number of lines per field */
+    if (Interlaced)
+        VDisplayRnd = VDisplay / 2;
+    else
+        VDisplayRnd = VDisplay;
+
+    /* 6. Find top and bottom margins */
+    /* nope. */
+    if (Margins)
+        /* top and bottom margins are equal again. */
+        VMargin = (((float) VDisplayRnd) * CVT_MARGIN_PERCENTAGE / 100.0);
+    else
+        VMargin = 0;
+
+    Mode->VDisplay = VDisplay + 2*VMargin;
+
+    /* 7. Interlace */
+    if (Interlaced)
+        Interlace = 0.5;
+    else
+        Interlace = 0.0;
+
+    /* Determine VSync Width from aspect ratio */
+    if (!(VDisplay % 3) && ((VDisplay * 4 / 3) == HDisplay))
+        VSync = 4;
+    else if (!(VDisplay % 9) && ((VDisplay * 16 / 9) == HDisplay))
+        VSync = 5;
+    else if (!(VDisplay % 10) && ((VDisplay * 16 / 10) == HDisplay))
+        VSync = 6;
+    else if (!(VDisplay % 4) && ((VDisplay * 5 / 4) == HDisplay))
+        VSync = 7;
+    else if (!(VDisplay % 9) && ((VDisplay * 15 / 9) == HDisplay))
+        VSync = 7;
+    else /* Custom */
+        VSync = 10;
+
+    if (!Reduced) { /* simplified GTF calculation */
+
+        /* 4) Minimum time of vertical sync + back porch interval (µs) 
+         * default 550.0 */
+#define CVT_MIN_VSYNC_BP 550.0
+
+        /* 3) Nominal HSync width (% of line period) - default 8 */
+#define CVT_HSYNC_PERCENTAGE 8
+
+        float  HBlankPercentage;
+        int  VSyncAndBackPorch, VBackPorch;
+        int  HBlank;
+
+        /* 8. Estimated Horizontal period */
+        HPeriod = ((float) (1000000.0 / VFieldRate - CVT_MIN_VSYNC_BP)) / 
+            (VDisplayRnd + 2 * VMargin + CVT_MIN_V_PORCH + Interlace);
+
+        /* 9. Find number of lines in sync + backporch */
+        if (((int)(CVT_MIN_VSYNC_BP / HPeriod) + 1) < (VSync + CVT_MIN_V_PORCH))
+            VSyncAndBackPorch = VSync + CVT_MIN_V_PORCH;
+        else
+            VSyncAndBackPorch = (int)(CVT_MIN_VSYNC_BP / HPeriod) + 1;
+
+        /* 10. Find number of lines in back porch */
+        VBackPorch = VSyncAndBackPorch - VSync;
+
+        /* 11. Find total number of lines in vertical field */
+        Mode->VTotal = VDisplayRnd + 2 * VMargin + VSyncAndBackPorch + Interlace
+            + CVT_MIN_V_PORCH;
+
+        /* 5) Definition of Horizontal blanking time limitation */
+        /* Gradient (%/kHz) - default 600 */
+#define CVT_M_FACTOR 600
+
+        /* Offset (%) - default 40 */
+#define CVT_C_FACTOR 40
+
+        /* Blanking time scaling factor - default 128 */
+#define CVT_K_FACTOR 128
+
+        /* Scaling factor weighting - default 20 */
+#define CVT_J_FACTOR 20
+
+#define CVT_M_PRIME CVT_M_FACTOR * CVT_K_FACTOR / 256
+#define CVT_C_PRIME (CVT_C_FACTOR - CVT_J_FACTOR) * CVT_K_FACTOR / 256 + \
+        CVT_J_FACTOR
+
+        /* 12. Find ideal blanking duty cycle from formula */
+        HBlankPercentage = CVT_C_PRIME - CVT_M_PRIME * HPeriod/1000.0;
+
+        /* 13. Blanking time */
+        if (HBlankPercentage < 20)
+            HBlankPercentage = 20;
+
+        HBlank = Mode->HDisplay * HBlankPercentage/(100.0 - HBlankPercentage);
+        HBlank -= HBlank % (2*CVT_H_GRANULARITY);
+        
+        /* 14. Find total number of pixels in a line. */
+        Mode->HTotal = Mode->HDisplay + HBlank;
+
+        /* Fill in HSync values */
+        Mode->HSyncEnd = Mode->HDisplay + HBlank / 2;
+
+        Mode->HSyncStart = Mode->HSyncEnd - 
+            (Mode->HTotal * CVT_HSYNC_PERCENTAGE) / 100;
+        Mode->HSyncStart += CVT_H_GRANULARITY - 
+            Mode->HSyncStart % CVT_H_GRANULARITY;
+
+        /* Fill in VSync values */
+        Mode->VSyncStart = Mode->VDisplay + CVT_MIN_V_PORCH;
+        Mode->VSyncEnd = Mode->VSyncStart + VSync;
+
+    } else { /* Reduced blanking */
+        /* Minimum vertical blanking interval time (µs) - default 460 */
+#define CVT_RB_MIN_VBLANK 460.0
+
+        /* Fixed number of clocks for horizontal sync */
+#define CVT_RB_H_SYNC 32.0
+
+        /* Fixed number of clocks for horizontal blanking */
+#define CVT_RB_H_BLANK 160.0
+
+        /* Fixed number of lines for vertical front porch - default 3 */
+#define CVT_RB_VFPORCH 3
+
+        int  VBILines;
+
+        /* 8. Estimate Horizontal period. */
+        HPeriod = ((float) (1000000.0 / VFieldRate - CVT_RB_MIN_VBLANK)) / 
+            (VDisplayRnd + 2*VMargin);
+
+        /* 9. Find number of lines in vertical blanking */
+        VBILines = ((float) CVT_RB_MIN_VBLANK) / HPeriod + 1;
+
+        /* 10. Check if vertical blanking is sufficient */
+        if (VBILines < (CVT_RB_VFPORCH + VSync + CVT_MIN_V_BPORCH))
+            VBILines = CVT_RB_VFPORCH + VSync + CVT_MIN_V_BPORCH;
+        
+        /* 11. Find total number of lines in vertical field */
+        Mode->VTotal = VDisplayRnd + 2 * VMargin + Interlace + VBILines;
+
+        /* 12. Find total number of pixels in a line */
+        Mode->HTotal = Mode->HDisplay + CVT_RB_H_BLANK;
+
+        /* Fill in HSync values */
+        Mode->HSyncEnd = Mode->HDisplay + CVT_RB_H_BLANK / 2;
+        Mode->HSyncStart = Mode->HSyncEnd - CVT_RB_H_SYNC;
+
+        /* Fill in VSync values */
+        Mode->VSyncStart = Mode->VDisplay + CVT_RB_VFPORCH;
+        Mode->VSyncEnd = Mode->VSyncStart + VSync;
+    }
+
+    /* 15/13. Find pixel clock frequency (kHz for xf86) */
+    Mode->Clock = Mode->HTotal * 1000.0 / HPeriod;
+    Mode->Clock -= Mode->Clock % CVT_CLOCK_STEP;
+
+    /* 16/14. Find actual Horizontal Frequency (kHz) */
+    Mode->HSync = ((float) Mode->Clock) / ((float) Mode->HTotal);
+
+    /* 17/15. Find actual Field rate */
+    Mode->VRefresh = (1000.0 * ((float) Mode->Clock)) / 
+        ((float) (Mode->HTotal * Mode->VTotal));
+
+    /* 18/16. Find actual vertical frame frequency */
+    /* ignore - just set the mode flag for interlaced */
+    if (Interlaced)
+        Mode->VTotal *= 2;
+
+    {
+        char  Name[256];
+        Name[0] = 0;
+
+        snprintf(Name, 256, "%dx%d", HDisplay, VDisplay);
+
+        Mode->name = xnfalloc(strlen(Name) + 1);
+        memcpy(Mode->name, Name, strlen(Name) + 1);
+    }
+
+    if (Reduced)
+        Mode->Flags |= V_PHSYNC | V_NVSYNC;
+    else
+        Mode->Flags |= V_NHSYNC | V_PVSYNC;
+
+    if (Interlaced)
+        Mode->Flags |= V_INTERLACE;
+
+    return Mode;
+}



More information about the xorg-commit mailing list