diff options
author | Adam Jackson <ajax@redhat.com> | 2009-10-26 14:49:57 -0400 |
---|---|---|
committer | Adam Jackson <ajax@redhat.com> | 2009-10-29 14:06:00 -0400 |
commit | 25236d19e6ef07fcb2c71569f1b7b0c12810834a (patch) | |
tree | fc39523df2c5647165980e3d260b12139335ef55 | |
parent | fb86433d897c116315cc7994390d11ac2f577511 (diff) | |
download | xserver-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.c | 41 |
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; |