From e8b201cf288921c546c2c72d7f3f9648ea24eb37 Mon Sep 17 00:00:00 2001 From: Christian Schlotter Date: Sat, 14 Apr 2007 19:48:10 +0200 Subject: [PATCH] Bug #10239: Add quirk for Samsung SyncMaster 171N. This patch adds a quirk which chooses the detailed mode close to 60 Hz with the lowest vertical refresh rate. It fixes the issue of displaying a garbled line after startup of the X-server on this type of monitor (see bug #10239's description). This is the ouput of xrandr before the patch: $ xrandr --verbose Screen 0: minimum 320 x 200, current 1280 x 1024, maximum 1280 x 1280 VGA connected 1280x1024+0+0 normal (normal left inverted right) 338mm x 270mm Identifier: 0x5c Timestamp: -268625002 Subpixel: unknown Clones: CRTC: 0 CRTCs: 0 EDID_DATA: 00ffffffffffff004c2d6b0037314847 1a0d01030f221b8cea6f8ba25a4d9424 1a5156bfef8081806140454031400101 010101010101302a009851002a403070 1300520e1100001e000000fd00384c1e 510e000a202020202020000000fc0053 796e634d61737465720a2020000000ff 00484a45573630343939370a202000f4 1280x1024 (0x5f) 108.0MHz h: width 1280 start 1328 end 1440 total 1688 skew 0 clock 64.0KHz v: height 1024 start 1025 end 1028 total 1066 clock 60.0Hz 1280x1024 (0x60) 135.0MHz h: width 1280 start 1296 end 1440 total 1688 skew 0 clock 80.0KHz v: height 1024 start 1025 end 1028 total 1066 clock 75.0Hz 1280x1024 (0x61) 109.0MHz h: width 1280 start 1368 end 1496 total 1712 skew 0 clock 63.7KHz v: height 1024 start 1027 end 1034 total 1063 clock 59.9Hz [...] This is the output afterwards: $ xrandr --verbose Screen 0: minimum 320 x 200, current 1280 x 1024, maximum 1280 x 1280 VGA connected 1280x1024+0+0 normal (normal left inverted right) 338mm x 270mm Identifier: 0x5c Timestamp: -248945063 Subpixel: unknown Clones: CRTC: 0 CRTCs: 0 EDID_DATA: 00ffffffffffff004c2d6b0037314847 1a0d01030f221b8cea6f8ba25a4d9424 1a5156bfef8081806140454031400101 010101010101302a009851002a403070 1300520e1100001e000000fd00384c1e 510e000a202020202020000000fc0053 796e634d61737465720a2020000000ff 00484a45573630343939370a202000f4 1280x1024 (0x5f) 109.0MHz h: width 1280 start 1368 end 1496 total 1712 skew 0 clock 63.7KHz v: height 1024 start 1027 end 1034 total 1063 clock 59.9Hz 1280x1024 (0x60) 135.0MHz h: width 1280 start 1296 end 1440 total 1688 skew 0 clock 80.0KHz v: height 1024 start 1025 end 1028 total 1066 clock 75.0Hz 1280x1024 (0x61) 108.0MHz h: width 1280 start 1328 end 1440 total 1688 skew 0 clock 64.0KHz v: height 1024 start 1025 end 1028 total 1066 clock 60.0Hz [...] Signed-off-by: Christian Schlotter --- Hi! Please review this patch and tell me if I the naming "prefer_tiny_60" and the implementation is OK. I hope that the way the quirk is implemented, other monitors with a similar defect can use it, too. If you think, this is nonsense, I can submit another fix which simply chooses the mode which is closest to a vertical refresh rate of 59.9 Hz. Best regards Christian hw/xfree86/modes/xf86EdidModes.c | 43 +++++++++++++++++++++++++++++++------ 1 files changed, 36 insertions(+), 7 deletions(-) diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c index 7a8ec19..9edd861 100644 --- a/hw/xfree86/modes/xf86EdidModes.c +++ b/hw/xfree86/modes/xf86EdidModes.c @@ -54,7 +54,9 @@ typedef enum { /* First detailed mode is bogus, prefer largest mode at 60hz */ DDC_QUIRK_PREFER_LARGE_60 = 1 << 1, /* 135MHz clock is too high, drop a bit */ - DDC_QUIRK_135_CLOCK_TOO_HIGH = 1 << 2 + DDC_QUIRK_135_CLOCK_TOO_HIGH = 1 << 2, + /* First detailed mode is bogus, prefer tiniest mode at 60hz */ + DDC_QUIRK_PREFER_TINY_60 = 1 << 3, } ddc_quirk_t; static Bool quirk_dt_sync_hm_vp (int scrnIndex, xf86MonPtr DDC) @@ -95,6 +97,16 @@ static Bool quirk_135_clock_too_high (int scrnIndex, xf86MonPtr DDC) return FALSE; } +static Bool quirk_prefer_tiny_60 (int scrnIndex, xf86MonPtr DDC) +{ + /* Samsung SyncMaster 171N. See bug #10239. */ + if (memcmp (DDC->vendor.name, "SAM", 4) == 0 && + DDC->vendor.prod_id == 107) + return TRUE; + + return FALSE; +} + typedef struct { Bool (*detect) (int scrnIndex, xf86MonPtr DDC); ddc_quirk_t quirk; @@ -114,6 +126,10 @@ static const ddc_quirk_map_t ddc_quirks[] = { quirk_135_clock_too_high, DDC_QUIRK_135_CLOCK_TOO_HIGH, "Recommended 135MHz pixel clock is too high" }, + { + quirk_prefer_tiny_60, DDC_QUIRK_PREFER_TINY_60, + "Detailed timing is not preferred, use tiniest mode at 60Hz" + }, { NULL, DDC_QUIRK_NONE, "No known quirks" @@ -335,7 +351,7 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC) } preferred = PREFERRED_TIMING_MODE(DDC->features.msc); - if (quirks & DDC_QUIRK_PREFER_LARGE_60) + if (quirks & (DDC_QUIRK_PREFER_LARGE_60 | DDC_QUIRK_PREFER_TINY_60)) preferred = 0; for (i = 0; i < DET_TIMINGS; i++) { @@ -369,7 +385,7 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC) Mode = DDCModesFromStandardTiming(scrnIndex, DDC->timings2, quirks); Modes = xf86ModesAdd(Modes, Mode); - if (quirks & DDC_QUIRK_PREFER_LARGE_60) + if (quirks & (DDC_QUIRK_PREFER_LARGE_60 | DDC_QUIRK_PREFER_TINY_60)) { DisplayModePtr best = Modes; for (Mode = Modes; Mode; Mode = Mode->next) @@ -385,11 +401,24 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC) double mode_refresh = xf86ModeVRefresh (Mode); double best_refresh = xf86ModeVRefresh (best); double mode_dist = fabs(mode_refresh - 60.0); - double best_dist = fabs(best_refresh - 60.0); - if (mode_dist < best_dist) + if (quirks & DDC_QUIRK_PREFER_LARGE_60) + { + double best_dist = fabs(best_refresh - 60.0); + if (mode_dist < best_dist) + { + best = Mode; + continue; + } + } + else /* quirks & DDC_QUIRK_PREFER_TINY_60 */ { - best = Mode; - continue; + /* choose tiniest mode close to 60Hz */ + const double EPSILON_60HZ = 1.0; + if (mode_dist < EPSILON_60HZ && mode_refresh < best_refresh) + { + best = Mode; + continue; + } } } } -- 1.5.1.1