summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Jackson <ajax@redhat.com>2009-10-26 14:49:57 -0400
committerAdam Jackson <ajax@redhat.com>2009-10-29 14:06:00 -0400
commit25236d19e6ef07fcb2c71569f1b7b0c12810834a (patch)
treefc39523df2c5647165980e3d260b12139335ef55
parentfb86433d897c116315cc7994390d11ac2f577511 (diff)
downloadxserver-25236d19e6ef07fcb2c71569f1b7b0c12810834a.tar.gz
EDID: Fix interlaced detailed timings to be frame size, not field size
Signed-off-by: Adam Jackson <ajax@redhat.com>
-rw-r--r--hw/xfree86/modes/xf86EdidModes.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c
index 6fef1e0f9..23d641689 100644
--- a/hw/xfree86/modes/xf86EdidModes.c
+++ b/hw/xfree86/modes/xf86EdidModes.c
@@ -502,6 +502,45 @@ DDCModesFromStandardTiming(struct std_timings *timing, ddc_quirk_t quirks,
return Modes;
}
+static void
+DDCModeDoInterlaceQuirks(DisplayModePtr mode)
+{
+ /*
+ * EDID is delightfully ambiguous about how interlaced modes are to be
+ * encoded. X's internal representation is of frame height, but some
+ * HDTV detailed timings are encoded as field height.
+ *
+ * The format list here is from CEA, in frame size. Technically we
+ * should be checking refresh rate too. Whatever.
+ */
+ static const struct {
+ int w, h;
+ } cea_interlaced[] = {
+ { 1920, 1080 },
+ { 720, 480 },
+ { 1440, 480 },
+ { 2880, 480 },
+ { 720, 576 },
+ { 1440, 576 },
+ { 2880, 576 },
+ };
+ static const int n_modes = sizeof(cea_interlaced)/sizeof(cea_interlaced[0]);
+ int i;
+
+ for (i = 0; i < n_modes; i++) {
+ if ((mode->HDisplay == cea_interlaced[i].w) &&
+ (mode->VDisplay == cea_interlaced[i].h / 2)) {
+ mode->VDisplay *= 2;
+ mode->VSyncStart *= 2;
+ mode->VSyncEnd *= 2;
+ mode->VTotal *= 2;
+ mode->VTotal |= 1;
+ }
+ }
+
+ mode->Flags |= V_INTERLACE;
+}
+
/*
*
*/
@@ -569,7 +608,7 @@ DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing,
/* We ignore h/v_size and h/v_border for now. */
if (timing->interlaced)
- Mode->Flags |= V_INTERLACE;
+ DDCModeDoInterlaceQuirks(Mode);
if (quirks & DDC_QUIRK_DETAILED_SYNC_PP)
Mode->Flags |= V_PVSYNC | V_PHSYNC;