[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