debian/changelog | 9 debian/patches/149_add_quirks_for_physical_screen_size_issues.patch | 291 ++++++++++ debian/patches/series | 1 3 files changed, 301 insertions(+)
New commits: commit b0db7cbe9d91e89f91165370c7d9a0f6a6415e96 Author: Bryce Harrington <[EMAIL PROTECTED]@bryceharrington.org> Date: Thu Feb 14 16:42:06 2008 -0800 Adding a patch with quirks for various monitors with bad EDID info diff --git a/debian/changelog b/debian/changelog index a8bba1a..7f1ece7 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,12 @@ +xorg-server (2:1.4.1~git20080131-1ubuntu3) UNRELEASED; urgency=low + + [Bryce Harrington] + * Add 149_add_quirks_for_physical_screen_size_issues.patch to help + address various common EDID issues (like monitors that report in + centimeters instead of millimeters, etc.) (LP: #151311) + + -- Bryce Harrington <[EMAIL PROTECTED]> Thu, 14 Feb 2008 16:23:47 -0800 + xorg-server (2:1.4.1~git20080131-1ubuntu2) hardy; urgency=low * Add patch 148_dix_touchscreen_fixes.diff from Matthew Garrett to fix diff --git a/debian/patches/149_add_quirks_for_physical_screen_size_issues.patch b/debian/patches/149_add_quirks_for_physical_screen_size_issues.patch new file mode 100644 index 0000000..091e280 --- /dev/null +++ b/debian/patches/149_add_quirks_for_physical_screen_size_issues.patch @@ -0,0 +1,291 @@ +From: Eric Anholt <[EMAIL PROTECTED]> +Date: Thu, 11 Oct 2007 23:48:56 +0000 (-0700) +Subject: Bug #10304,12784,11603: Add quirks for several physical size issues. +X-Git-Url: http://gitweb.freedesktop.org/?p=xorg/xserver.git;a=commitdiff;h=fc092334ac0a323b80a9602cb8bf60ca9dee3bfa + +Bug #10304,12784,11603: Add quirks for several physical size issues. + +A lot of EDID writers apparently end up stuffing centimeters (like the +maximum image size field) into the detailed timings, instead of millimeters. +Some of them only get it wrong in one direction. Also, add a quirk to let +us mark the largest 75hz mode as preferred, which will often be used for +EDID 1.0 CRTs. +--- + +--- a/hw/xfree86/modes/xf86Crtc.c ++++ b/hw/xfree86/modes/xf86Crtc.c +@@ -2134,8 +2134,12 @@ _X_EXPORT xf86MonPtr + xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus) + { + ScrnInfoPtr scrn = output->scrn; ++ xf86MonPtr mon; + +- return xf86DoEDID_DDC2 (scrn->scrnIndex, pDDCBus); ++ mon = xf86DoEDID_DDC2 (scrn->scrnIndex, pDDCBus); ++ xf86DDCApplyQuirks (scrn->scrnIndex, pDDCBus); ++ ++ return mon; + } + + static char *_xf86ConnectorNames[] = { "None", "VGA", "DVI-I", "DVI-D", +--- a/hw/xfree86/modes/xf86EdidModes.c ++++ b/hw/xfree86/modes/xf86EdidModes.c +@@ -54,6 +54,16 @@ typedef enum { + DDC_QUIRK_PREFER_LARGE_60 = 1 << 0, + /* 135MHz clock is too high, drop a bit */ + DDC_QUIRK_135_CLOCK_TOO_HIGH = 1 << 1, ++ /* Prefer the largest mode at 75 Hz */ ++ DDC_QUIRK_PREFER_LARGE_75 = 1 << 2, ++ /* Convert detailed timing's horizontal from units of cm to mm */ ++ DDC_QUIRK_DETAILED_H_IN_CM = 1 << 3, ++ /* Convert detailed timing's vertical from units of cm to mm */ ++ DDC_QUIRK_DETAILED_V_IN_CM = 1 << 4, ++ /* Detailed timing descriptors have bogus size values, so just take the ++ * maximum size and use that. ++ */ ++ DDC_QUIRK_DETAILED_USE_MAXIMUM_SIZE = 1 << 5, + } ddc_quirk_t; + + static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC) +@@ -81,6 +91,52 @@ static Bool quirk_prefer_large_60 (int s + return FALSE; + } + ++static Bool quirk_prefer_large_75 (int scrnIndex, xf86MonPtr DDC) ++{ ++ /* Bug #11603: Funai Electronics PM36B */ ++ if (memcmp (DDC->vendor.name, "FCM", 4) == 0 && ++ DDC->vendor.prod_id == 13600) ++ return TRUE; ++ ++ return FALSE; ++} ++ ++static Bool quirk_detailed_h_in_cm (int scrnIndex, xf86MonPtr DDC) ++{ ++ /* Bug #10304: "LGPhilipsLCD LP154W01-A5" */ ++ /* Bug #12784: "LGPhilipsLCD LP154W01-TLA2" */ ++ if (memcmp (DDC->vendor.name, "LPL", 4) == 0 && ++ DDC->vendor.prod_id == 0) ++ return TRUE; ++ ++ /* Bug #11603: Funai Electronics PM36B */ ++ if (memcmp (DDC->vendor.name, "FCM", 4) == 0 && ++ DDC->vendor.prod_id == 13600) ++ return TRUE; ++ ++ return FALSE; ++} ++ ++static Bool quirk_detailed_v_in_cm (int scrnIndex, xf86MonPtr DDC) ++{ ++ /* Bug #11603: Funai Electronics PM36B */ ++ if (memcmp (DDC->vendor.name, "FCM", 4) == 0 && ++ DDC->vendor.prod_id == 13600) ++ return TRUE; ++ ++ return FALSE; ++} ++ ++static Bool quirk_detailed_use_maximum_size (int scrnIndex, xf86MonPtr DDC) ++{ ++ /* Bug #10304: LGPhilipsLCD LP154W01-A5 */ ++ if (memcmp (DDC->vendor.name, "LPL", 4) == 0 && ++ DDC->vendor.prod_id == 0) ++ return TRUE; ++ ++ return FALSE; ++} ++ + static Bool quirk_135_clock_too_high (int scrnIndex, xf86MonPtr DDC) + { + /* Envision Peripherals, Inc. EN-7100e. See bug #9550. */ +@@ -106,6 +162,22 @@ 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_large_75, DDC_QUIRK_PREFER_LARGE_75, ++ "Detailed timing is not preferred, use largest mode at 75Hz" ++ }, ++ { ++ quirk_detailed_h_in_cm, DDC_QUIRK_DETAILED_H_IN_CM, ++ "Detailed timings give horizontal size in cm." ++ }, ++ { ++ quirk_detailed_v_in_cm, DDC_QUIRK_DETAILED_V_IN_CM, ++ "Detailed timings give vertical size in cm." ++ }, ++ { ++ quirk_detailed_use_maximum_size, DDC_QUIRK_DETAILED_USE_MAXIMUM_SIZE, ++ "Detailed timings give sizes in cm." ++ }, + { + NULL, DDC_QUIRK_NONE, + "No known quirks" +@@ -303,6 +375,98 @@ DDCGuessRangesFromModes(int scrnIndex, M + } + } + ++static ddc_quirk_t ++xf86DDCDetectQuirks(int scrnIndex, xf86MonPtr DDC, Bool verbose) ++{ ++ ddc_quirk_t quirks; ++ int i; ++ ++ quirks = DDC_QUIRK_NONE; ++ for (i = 0; ddc_quirks[i].detect; i++) { ++ if (ddc_quirks[i].detect (scrnIndex, DDC)) { ++ if (verbose) { ++ xf86DrvMsg (scrnIndex, X_INFO, " EDID quirk: %s\n", ++ ddc_quirks[i].description); ++ } ++ quirks |= ddc_quirks[i].quirk; ++ } ++ } ++ ++ return quirks; ++} ++ ++/** ++ * Applies monitor-specific quirks to the decoded EDID information. ++ * ++ * Note that some quirks applying to the mode list are still implemented in ++ * xf86DDCGetModes. ++ */ ++void ++xf86DDCApplyQuirks(int scrnIndex, xf86MonPtr DDC) ++{ ++ ddc_quirk_t quirks = xf86DDCDetectQuirks (scrnIndex, DDC, FALSE); ++ int i; ++ ++ for (i = 0; i < DET_TIMINGS; i++) { ++ struct detailed_monitor_section *det_mon = &DDC->det_mon[i]; ++ ++ if (det_mon->type != DT) ++ continue; ++ ++ if (quirks & DDC_QUIRK_DETAILED_H_IN_CM) ++ det_mon->section.d_timings.h_size *= 10; ++ ++ if (quirks & DDC_QUIRK_DETAILED_V_IN_CM) ++ det_mon->section.d_timings.v_size *= 10; ++ ++ if (quirks & DDC_QUIRK_DETAILED_USE_MAXIMUM_SIZE) { ++ det_mon->section.d_timings.h_size = 10 * DDC->features.hsize; ++ det_mon->section.d_timings.v_size = 10 * DDC->features.vsize; ++ } ++ } ++} ++ ++/** ++ * Walks the modes list, finding the mode with the largest area which is ++ * closest to the target refresh rate, and marks it as the only preferred mode. ++*/ ++static void ++xf86DDCSetPreferredRefresh(int scrnIndex, DisplayModePtr modes, ++ float target_refresh) ++{ ++ DisplayModePtr mode, best = modes; ++ ++ for (mode = modes; mode; mode = mode->next) ++ { ++ mode->type &= ~M_T_PREFERRED; ++ ++ if (mode == best) continue; ++ ++ if (mode->HDisplay * mode->VDisplay > ++ best->HDisplay * best->VDisplay) ++ { ++ best = mode; ++ continue; ++ } ++ if (mode->HDisplay * mode->VDisplay == ++ best->HDisplay * best->VDisplay) ++ { ++ double mode_refresh = xf86ModeVRefresh (mode); ++ double best_refresh = xf86ModeVRefresh (best); ++ double mode_dist = fabs(mode_refresh - target_refresh); ++ double best_dist = fabs(best_refresh - target_refresh); ++ ++ if (mode_dist < best_dist) ++ { ++ best = mode; ++ continue; ++ } ++ } ++ } ++ if (best) ++ best->type |= M_T_PREFERRED; ++} ++ + _X_EXPORT DisplayModePtr + xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC) + { +@@ -312,15 +476,9 @@ xf86DDCGetModes(int scrnIndex, xf86MonPt + + xf86DrvMsg (scrnIndex, X_INFO, "EDID vendor \"%s\", prod id %d\n", + DDC->vendor.name, DDC->vendor.prod_id); +- quirks = DDC_QUIRK_NONE; +- for (i = 0; ddc_quirks[i].detect; i++) +- if (ddc_quirks[i].detect (scrnIndex, DDC)) +- { +- xf86DrvMsg (scrnIndex, X_INFO, " EDID quirk: %s\n", +- ddc_quirks[i].description); +- quirks |= ddc_quirks[i].quirk; +- } +- ++ ++ quirks = xf86DDCDetectQuirks(scrnIndex, DDC, TRUE); ++ + preferred = PREFERRED_TIMING_MODE(DDC->features.msc); + if (quirks & DDC_QUIRK_PREFER_LARGE_60) + preferred = 0; +@@ -357,32 +515,11 @@ xf86DDCGetModes(int scrnIndex, xf86MonPt + Modes = xf86ModesAdd(Modes, Mode); + + if (quirks & DDC_QUIRK_PREFER_LARGE_60) +- { +- DisplayModePtr best = Modes; +- for (Mode = Modes; Mode; Mode = Mode->next) +- { +- if (Mode == best) continue; +- if (Mode->HDisplay * Mode->VDisplay > best->HDisplay * best->VDisplay) +- { +- best = Mode; +- continue; +- } +- if (Mode->HDisplay * Mode->VDisplay == best->HDisplay * best->VDisplay) +- { +- 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) +- { +- best = Mode; +- continue; +- } +- } +- } +- if (best) +- best->type |= M_T_PREFERRED; +- } ++ xf86DDCSetPreferredRefresh(scrnIndex, Modes, 60); ++ ++ if (quirks & DDC_QUIRK_PREFER_LARGE_75) ++ xf86DDCSetPreferredRefresh(scrnIndex, Modes, 75); ++ + return Modes; + } + +--- a/hw/xfree86/modes/xf86Modes.h ++++ b/hw/xfree86/modes/xf86Modes.h +@@ -95,4 +95,7 @@ xf86GetMonitorModes (ScrnInfoPtr pScrn, + DisplayModePtr + xf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed); + ++void ++xf86DDCApplyQuirks(int scrnIndex, xf86MonPtr DDC); ++ + #endif /* _XF86MODES_H_ */ diff --git a/debian/patches/series b/debian/patches/series index 93e3aea..8e6819e 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -42,3 +42,4 @@ 146_X86EMU-added-blacklist-for-I-O-port-in-0-0xFF-range.patch 147_X86EMU-pass-the-correct-bus-dev-fn-tag-to-pci-emula.patch 148_dix_touchscreen_fixes.diff +149_add_quirks_for_physical_screen_size_issues.patch -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]