[PATCH] Bug #10239: Add quirk for Samsung SyncMaster 171N.

Christian Schlotter schlotter at users.sourceforge.net
Sat Apr 14 11:15:37 PDT 2007


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 <schlotter at users.sourceforge.net>
---

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




More information about the xorg mailing list