diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c index 057b93d..54db6cb 100644 --- a/hw/xfree86/modes/xf86EdidModes.c +++ b/hw/xfree86/modes/xf86EdidModes.c @@ -66,8 +66,10 @@ typedef enum { DDC_QUIRK_DETAILED_USE_MAXIMUM_SIZE = 1 << 5, /* Monitor forgot to set the first detailed is preferred bit. */ DDC_QUIRK_FIRST_DETAILED_PREFERRED = 1 << 6, - /* use +hsync +vsync for detailed mode */ - DDC_QUIRK_DETAILED_SYNC_PP = 1 << 7, + /* flip the hsync polarity for detailed timing */ + DDC_QUIRK_DETAILED_FLIP_HSYNC = 1 << 7, + /* flip the vsync polarity for detailed timing */ + DDC_QUIRK_DETAILED_FLIP_VSYNC = 1 << 8, } ddc_quirk_t; static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC) @@ -172,12 +174,26 @@ static Bool quirk_first_detailed_preferred (int scrnIndex, xf86MonPtr DDC) return FALSE; } -static Bool quirk_detailed_sync_pp(int scrnIndex, xf86MonPtr DDC) +static Bool quirk_detailed_flip_vsync(int scrnIndex, xf86MonPtr DDC) +{ + /* Bug #16109: Eizo S2431W */ + if (memcmp (DDC->vendor.name, "ENC", 4) == 0 && + DDC->vendor.prod_id == 6279) + return TRUE; + return FALSE; +} + +static Bool quirk_detailed_flip_hsync(int scrnIndex, xf86MonPtr DDC) { /* Bug #12439: Samsung SyncMaster 205BW */ if (memcmp (DDC->vendor.name, "SAM", 4) == 0 && DDC->vendor.prod_id == 541) return TRUE; + + /* Bug #16109: Eizo S2431W */ + if (memcmp (DDC->vendor.name, "ENC", 4) == 0 && + DDC->vendor.prod_id == 6279) + return TRUE; return FALSE; } @@ -217,8 +233,12 @@ static const ddc_quirk_map_t ddc_quirks[] = { "First detailed timing was not marked as preferred." }, { - quirk_detailed_sync_pp, DDC_QUIRK_DETAILED_SYNC_PP, - "Use +hsync +vsync for detailed timing." + quirk_detailed_flip_hsync, DDC_QUIRK_DETAILED_FLIP_HSYNC, + "flip hsync polarity for detailed timing." + }, + { + quirk_detailed_flip_vsync, DDC_QUIRK_DETAILED_FLIP_VSYNC, + "flip vsync polarity for detailed timing." }, { NULL, DDC_QUIRK_NONE, @@ -339,6 +359,7 @@ DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing, Bool preferred, ddc_quirk_t quirks) { DisplayModePtr Mode; + unsigned int temp; /* * Refuse to create modes that are insufficiently large. 64 is a random @@ -402,19 +423,26 @@ DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing, if (timing->interlaced) Mode->Flags |= V_INTERLACE; - if (quirks & DDC_QUIRK_DETAILED_SYNC_PP) - Mode->Flags |= V_PVSYNC | V_PHSYNC; - else { - if (timing->misc & 0x02) - Mode->Flags |= V_PVSYNC; - else - Mode->Flags |= V_NVSYNC; - - if (timing->misc & 0x01) - Mode->Flags |= V_PHSYNC; - else - Mode->Flags |= V_NHSYNC; + if (quirks & DDC_QUIRK_DETAILED_FLIP_VSYNC) { + temp = timing->misc & 0x1; + temp |= (timing->misc & 0x2 + 0x2) & 0x2; + timing->misc = temp; } + if (quirks & DDC_QUIRK_DETAILED_FLIP_HSYNC) { + temp = timing->misc & 0x2; + temp |= ((timing->misc & 0x1) + 0x1) & 0x1; + timing->misc = temp; + } + + if (timing->misc & 0x02) + Mode->Flags |= V_PVSYNC; + else + Mode->Flags |= V_NVSYNC; + + if (timing->misc & 0x01) + Mode->Flags |= V_PHSYNC; + else + Mode->Flags |= V_NHSYNC; return Mode; }