EDID: Fix interlaced detailed timings to be frame size, not field size

Signed-off-by: Adam Jackson <ajax@redhat.com>
This commit is contained in:
Adam Jackson 2009-10-26 14:49:57 -04:00
parent fb86433d89
commit 25236d19e6
1 changed files with 40 additions and 1 deletions

View File

@ -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;