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