[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

xorg-server: Changes to 'debian-unstable'



 debian/changelog                        |    8 
 debian/patches/49_x86emu_int1a_fix.diff |   70 +++++++
 debian/patches/series                   |    1 
 hw/xfree86/modes/xf86Crtc.c             |   31 ++-
 hw/xfree86/modes/xf86EdidModes.c        |  283 ++++++++++++++++++++++++++------
 hw/xfree86/modes/xf86Modes.h            |    3 
 6 files changed, 342 insertions(+), 54 deletions(-)

New commits:
commit 0d4a052db5bb10f82387f502977aff96684a57d3
Author: Julien Cristau <jcristau@debian.org>
Date:   Tue Jun 24 20:39:52 2008 +0200

    Backport patch from upstream git to fix emulation of int1A PCI BIOS services

diff --git a/debian/changelog b/debian/changelog
index 826002d..cae33c7 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -14,6 +14,8 @@ xorg-server (2:1.4.2-1) UNRELEASED; urgency=low
     - inherit the preferred mode from the global configuration (so if you have
       Modes "800x600" in the Display subsection the server will honor it
       instead of ignoring it)
+  * Backport patch from upstream git to fix emulation of int1A PCI BIOS
+    services (closes: #404885).  Thanks, Robert de Bath!
 
   [ Brice Goglin ]
   * Update patches to not require -p0, closes: #485185.
diff --git a/debian/patches/49_x86emu_int1a_fix.diff b/debian/patches/49_x86emu_int1a_fix.diff
new file mode 100644
index 0000000..1628a46
--- /dev/null
+++ b/debian/patches/49_x86emu_int1a_fix.diff
@@ -0,0 +1,70 @@
+commit 9e5b3deafb97ec1f83e6bfe067bc68df7385bc6a
+Author: Adam Jackson <ajax@redhat.com>
+Date:   Tue Jun 24 14:08:04 2008 -0400
+
+    Bug #11842: Fix emulation of int1A PCI BIOS services.
+    
+    Use only %di to name the PCI register to read/write, rather than %edi.
+    DOS is only expecting the base PCI config space anyway, and the BIOS
+    might be using the high bits of %edi.
+
+backported to pre-pciaccess, fixes #404885.
+
+Index: xorg-server/hw/xfree86/int10/xf86int10.c
+===================================================================
+--- xorg-server.orig/hw/xfree86/int10/xf86int10.c	2008-06-24 20:31:06.000000000 +0200
++++ xorg-server/hw/xfree86/int10/xf86int10.c	2008-06-24 20:34:46.000000000 +0200
+@@ -667,7 +667,7 @@
+ 	return 1;
+     case 0xb108:
+ 	if ((tag = findPci(pInt, X86_EBX)) != PCI_NOT_FOUND) {
+-	    X86_CL = pciReadByte(tag, X86_EDI);
++	    X86_CL = pciReadByte(tag, X86_DI);
+ 	    X86_EAX = X86_AL | (SUCCESSFUL << 8);
+ 	    X86_EFLAGS &= ~((unsigned long)0x01); /* clear carry flag */
+ 	} else {
+@@ -680,7 +680,7 @@
+ 	return 1;
+     case 0xb109:
+ 	if ((tag = findPci(pInt, X86_EBX)) != PCI_NOT_FOUND) {
+-	    X86_CX = pciReadWord(tag, X86_EDI);
++	    X86_CX = pciReadWord(tag, X86_DI);
+ 	    X86_EAX = X86_AL | (SUCCESSFUL << 8);
+ 	    X86_EFLAGS &= ~((unsigned long)0x01); /* clear carry flag */
+ 	} else {
+@@ -693,7 +693,7 @@
+ 	return 1;
+     case 0xb10a:
+ 	if ((tag = findPci(pInt, X86_EBX)) != PCI_NOT_FOUND) {
+-	    X86_ECX = pciReadLong(tag, X86_EDI);
++	    X86_ECX = pciReadLong(tag, X86_DI);
+ 	    X86_EAX = X86_AL | (SUCCESSFUL << 8);
+ 	    X86_EFLAGS &= ~((unsigned long)0x01); /* clear carry flag */
+ 	} else {
+@@ -706,7 +706,7 @@
+ 	return 1;
+     case 0xb10b:
+ 	if ((tag = findPci(pInt, X86_EBX)) != PCI_NOT_FOUND) {
+-	    pciWriteByte(tag, X86_EDI, X86_CL);
++	    pciWriteByte(tag, X86_DI, X86_CL);
+ 	    X86_EAX = X86_AL | (SUCCESSFUL << 8);
+ 	    X86_EFLAGS &= ~((unsigned long)0x01); /* clear carry flag */
+ 	} else {
+@@ -719,7 +719,7 @@
+ 	return 1;
+     case 0xb10c:
+ 	if ((tag = findPci(pInt, X86_EBX)) != PCI_NOT_FOUND) {
+-	    pciWriteWord(tag, X86_EDI, X86_CX);
++	    pciWriteWord(tag, X86_DI, X86_CX);
+ 	    X86_EAX = X86_AL | (SUCCESSFUL << 8);
+ 	    X86_EFLAGS &= ~((unsigned long)0x01); /* clear carry flag */
+ 	} else {
+@@ -732,7 +732,7 @@
+ 	return 1;
+     case 0xb10d:
+ 	if ((tag = findPci(pInt, X86_EBX)) != PCI_NOT_FOUND) {
+-	    pciWriteLong(tag, X86_EDI, X86_ECX);
++	    pciWriteLong(tag, X86_DI, X86_ECX);
+ 	    X86_EAX = X86_AL | (SUCCESSFUL << 8);
+ 	    X86_EFLAGS &= ~((unsigned long)0x01); /* clear carry flag */
+ 	} else {
diff --git a/debian/patches/series b/debian/patches/series
index 2b0c641..6132c6c 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -21,6 +21,7 @@
 46_reduce_wakeups_from_smart_scheduler.patch
 #47_fbdevhw_magic_numbers.diff
 48_xaa_nooffscreenpixmaps.diff
+49_x86emu_int1a_fix.diff
 91_ttf2pt1
 91_ttf2pt1_updates
 92_xprint-security-holes-fix.patch

commit 9af54c19ab186dc927e19bf4c56a9ac9f949fc0e
Author: Julien Cristau <jcristau@debian.org>
Date:   Mon Jun 23 20:59:49 2008 +0200

    update changelog for cherry-picked patches
    
    various fixes in hw/xfree86/modes/, mostly quirks

diff --git a/debian/changelog b/debian/changelog
index 7eb12a3..826002d 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -8,6 +8,12 @@ xorg-server (2:1.4.2-1) UNRELEASED; urgency=low
   * 48_xaa_nooffscreenpixmaps.diff: disable XAA offscreen pixmaps by default;
     they can be enabled with Option "XaaOffscreenPixmaps" (closes: #478277,
     #433331).
+  * Cherry-pick various patches from upstream for Xorg's modes code:
+    - add quirks for monitors with broken EDID (closes: #473260)
+    - fix max clock computation
+    - inherit the preferred mode from the global configuration (so if you have
+      Modes "800x600" in the Display subsection the server will honor it
+      instead of ignoring it)
 
   [ Brice Goglin ]
   * Update patches to not require -p0, closes: #485185.

commit 02419dfc239c4035ef9ab6b1cdcb20582928e073
Author: Dave Airlie <airlied@linux.ie>
Date:   Wed Apr 9 14:27:58 2008 +1000

    quirk: add quirk for ACR 640x350 default mode is wrong
    
    RH #440186
    (cherry picked from commit b19027fbaea4c3a146926e862983e0e3411fff3d)

diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c
index b562c4b..a038db3 100644
--- a/hw/xfree86/modes/xf86EdidModes.c
+++ b/hw/xfree86/modes/xf86EdidModes.c
@@ -93,6 +93,12 @@ static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC)
 	DDC->vendor.prod_id == 638)
 	return TRUE;
 
+    /* Acer F51 */
+    if (memcmp (DDC->vendor.name, "API", 4) == 0 &&
+	DDC->vendor.prod_id == 0x7602)
+	return TRUE;
+
+
     return FALSE;
 }
 

commit d248fcd410637300016f70f27438512af25d8670
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Apr 4 09:29:51 2008 +1000

    quirk: add quirk for ACER EDID
    (cherry picked from commit f0915fb3c4a9712200882440a64d11dc595a02bb)

diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c
index 3e9240d..b562c4b 100644
--- a/hw/xfree86/modes/xf86EdidModes.c
+++ b/hw/xfree86/modes/xf86EdidModes.c
@@ -158,6 +158,11 @@ static Bool quirk_first_detailed_preferred (int scrnIndex, xf86MonPtr DDC)
 	DDC->vendor.prod_id == 765)
 	return TRUE;
 
+    /* ACR of some sort RH #284231 */
+    if (memcmp (DDC->vendor.name, "ACR", 4) == 0 &&
+	DDC->vendor.prod_id == 2423)
+	return TRUE;
+
     return FALSE;
 }
 

commit 31591cad031ab6da4d6a6ec7257450d645f62a2d
Author: Hong Liu <hong.liu@intel.com>
Date:   Wed Apr 2 10:43:19 2008 +0800

    Bug #15160: quirk Proview AY765C
    
    prefer first detailed timing
    (cherry picked from commit ebc56aca8bdfec1918cac3c8380895dfddea48ce)

diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c
index b5eb4c8..3e9240d 100644
--- a/hw/xfree86/modes/xf86EdidModes.c
+++ b/hw/xfree86/modes/xf86EdidModes.c
@@ -153,6 +153,11 @@ static Bool quirk_first_detailed_preferred (int scrnIndex, xf86MonPtr DDC)
 	DDC->vendor.prod_id == 57364)
 	return TRUE;
 
+    /* Proview AY765C 17" LCD. See bug #15160*/
+    if (memcmp (DDC->vendor.name, "PTS", 4) == 0 &&
+	DDC->vendor.prod_id == 765)
+	return TRUE;
+
     return FALSE;
 }
 

commit 8f0b4b52dd561b107038cefb8454846139da9478
Author: Dave Airlie <airlied@redhat.com>
Date:   Thu Mar 27 15:18:39 2008 +1000

    quirk: fix LPL monitors properly.
    
    no point having a h cm fix when we really want to copy the sizes from the
    other place.
    
    RH BZ 435216
    (cherry picked from commit c747030a49dd289e873e2b686cd129d840e55468)

diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c
index 425845a..b5eb4c8 100644
--- a/hw/xfree86/modes/xf86EdidModes.c
+++ b/hw/xfree86/modes/xf86EdidModes.c
@@ -108,13 +108,6 @@ static Bool quirk_prefer_large_75 (int scrnIndex, xf86MonPtr DDC)
 
 static Bool quirk_detailed_h_in_cm (int scrnIndex, xf86MonPtr DDC)
 {
-    /* Bug #10304: "LGPhilipsLCD LP154W01-A5" */
-    /* Bug #12784: "LGPhilipsLCD LP154W01-TLA2" */
-    /* Red Hat #435216 "LGPhilipsLCD LP154W01-TLAE" */
-    if (memcmp (DDC->vendor.name, "LPL", 4) == 0 &&
-	(DDC->vendor.prod_id == 0 || DDC->vendor.prod_id == 0x2a00))
-	return TRUE;
-
     /* Bug #11603: Funai Electronics PM36B */
     if (memcmp (DDC->vendor.name, "FCM", 4) == 0 &&
 	DDC->vendor.prod_id == 13600)
@@ -137,7 +130,7 @@ 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)
+	(DDC->vendor.prod_id == 0 || DDC->vendor.prod_id == 0x2a00))
 	return TRUE;
 
     return FALSE;

commit da42566131d0dcbdf5a5b766e5fe7aa47290e6e6
Author: Adam Jackson <ajax@redhat.com>
Date:   Mon Mar 3 15:49:48 2008 -0500

    RANDR 1.2: Inherit PreferredMode from the global configuration, if any.
    
    If you don't do this, then Modes "800x600" in the Display subsection will
    be dutifully ignored and the driver will start at whatever resolution it
    feels like.
    (cherry picked from commit 708f07753ff22ade54e9ee8885e4198fff363b87)

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 19f3e29..7b2dddb 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -1214,6 +1214,23 @@ xf86SortModes (DisplayModePtr input)
     return output;
 }
 
+static char *
+preferredMode(ScrnInfoPtr pScrn, xf86OutputPtr output)
+{
+    char *preferred_mode = NULL;
+
+    /* Check for a configured preference for a particular mode */
+    preferred_mode = xf86GetOptValString (output->options,
+					  OPTION_PREFERRED_MODE);
+    if (preferred_mode)
+	return preferred_mode;
+
+    if (pScrn->display->modes && *pScrn->display->modes)
+	preferred_mode = *pScrn->display->modes;
+
+    return preferred_mode;
+}
+
 _X_EXPORT void
 xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
 {
@@ -1395,8 +1412,7 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
 	output->probed_modes = xf86SortModes (output->probed_modes);
 	
 	/* Check for a configured preference for a particular mode */
-	preferred_mode = xf86GetOptValString (output->options,
-					      OPTION_PREFERRED_MODE);
+	preferred_mode = preferredMode(scrn, output);
 
 	if (preferred_mode)
 	{

commit c21c34e6681b88db02f3e3a1d590a7904774eb23
Author: Tiago Vignatti <vignatti@c3sl.ufpr.br>
Date:   Thu Feb 28 01:22:31 2008 -0300

    Oops, there's one more parenthesis.
    (cherry picked from commit aebd9dc252449747416b23c740a550d914275399)

diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c
index 2f544cc..425845a 100644
--- a/hw/xfree86/modes/xf86EdidModes.c
+++ b/hw/xfree86/modes/xf86EdidModes.c
@@ -112,7 +112,7 @@ static Bool quirk_detailed_h_in_cm (int scrnIndex, xf86MonPtr DDC)
     /* Bug #12784: "LGPhilipsLCD LP154W01-TLA2" */
     /* Red Hat #435216 "LGPhilipsLCD LP154W01-TLAE" */
     if (memcmp (DDC->vendor.name, "LPL", 4) == 0 &&
-	(DDC->vendor.prod_id == 0 || DDC->vendor.prod_id == 0x2a00)
+	(DDC->vendor.prod_id == 0 || DDC->vendor.prod_id == 0x2a00))
 	return TRUE;
 
     /* Bug #11603: Funai Electronics PM36B */

commit 7fc11ec767068c3b6557e8df46c59e3afb58d03f
Author: Dave Airlie <airlied@redhat.com>
Date:   Thu Feb 28 10:45:41 2008 +1000

    quirks: another LPL panel with the cm/mm wrong
    (cherry picked from commit 08afc70513e5496cc5cd8b76c8658c4292119e4b)

diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c
index e6da47c..2f544cc 100644
--- a/hw/xfree86/modes/xf86EdidModes.c
+++ b/hw/xfree86/modes/xf86EdidModes.c
@@ -110,8 +110,9 @@ static Bool quirk_detailed_h_in_cm (int scrnIndex, xf86MonPtr DDC)
 {
     /* Bug #10304: "LGPhilipsLCD LP154W01-A5" */
     /* Bug #12784: "LGPhilipsLCD LP154W01-TLA2" */
+    /* Red Hat #435216 "LGPhilipsLCD LP154W01-TLAE" */
     if (memcmp (DDC->vendor.name, "LPL", 4) == 0 &&
-	DDC->vendor.prod_id == 0)
+	(DDC->vendor.prod_id == 0 || DDC->vendor.prod_id == 0x2a00)
 	return TRUE;
 
     /* Bug #11603: Funai Electronics PM36B */

commit eaa2182f37bc956fd6d8292dbe0c14ac0f72af9f
Author: liuhong <liuhong@devlinux-hong.sh.intel.com>
Date:   Tue Feb 5 10:54:10 2008 +0800

    fix max clock unit
    
    max clock from EDID data is in MHz, while we need KHz to validate modes.
    (cherry picked from commit 4b5b6e7baab58072a983d2ec136965f404c3a74a)

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index bfe1a5a..19f3e29 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -1318,8 +1318,8 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
 			if (sync_source == sync_default)
 			    sync_source = sync_edid;
 		    }
-		    if (ranges->max_clock > max_clock)
-			max_clock = ranges->max_clock;
+		    if (ranges->max_clock * 1000 > max_clock)
+			max_clock = ranges->max_clock * 1000;
 		}
 	    }
 	}

commit 79bd0bef735bf719fb5eef03ec08372269ed4b82
Author: Hong Liu <hong.liu@intel.com>
Date:   Wed Jan 23 21:04:32 2008 +0800

    Bug #12439: add a quirk to use +hsync +vsync for the probed detailed mode.
    
    Samsung 205BW quirk is somehow reworked.
    (cherry picked from commit 734e115871ce98badb8800383c423493802ae3d3)

diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c
index a125d8c..e6da47c 100644
--- a/hw/xfree86/modes/xf86EdidModes.c
+++ b/hw/xfree86/modes/xf86EdidModes.c
@@ -66,6 +66,8 @@ 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,
 } ddc_quirk_t;
 
 static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC)
@@ -160,6 +162,15 @@ static Bool quirk_first_detailed_preferred (int scrnIndex, xf86MonPtr DDC)
     return FALSE;
 }
 
+static Bool quirk_detailed_sync_pp(int scrnIndex, xf86MonPtr DDC)
+{
+    /* Bug #12439: Samsung SyncMaster 205BW */
+    if (memcmp (DDC->vendor.name, "SAM", 4) == 0 &&
+	DDC->vendor.prod_id == 541)
+	return TRUE;
+    return FALSE;
+}
+
 typedef struct {
     Bool	(*detect) (int scrnIndex, xf86MonPtr DDC);
     ddc_quirk_t	quirk;
@@ -195,6 +206,10 @@ static const ddc_quirk_map_t ddc_quirks[] = {
 	quirk_first_detailed_preferred, DDC_QUIRK_FIRST_DETAILED_PREFERRED,
 	"First detailed timing was not marked as preferred."
     },
+    {
+	quirk_detailed_sync_pp, DDC_QUIRK_DETAILED_SYNC_PP,
+	"Use +hsync +vsync for detailed timing."
+    },
     { 
 	NULL,		DDC_QUIRK_NONE,
 	"No known quirks"
@@ -341,15 +356,19 @@ DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing,
     if (timing->interlaced)
         Mode->Flags |= V_INTERLACE;
 
-    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_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;
+    }
 
     return Mode;
 }

commit d94f70e1f567f6b7eb935b216e5b1d352c36e3e7
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Dec 4 12:24:47 2007 +1100

    xf86crtc: oh mon could be NULL, so check before quirks
    (cherry picked from commit 678f786715d76e972f8a77807c9caf3e90c24418)

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 42ab1b1..bfe1a5a 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -2137,7 +2137,8 @@ xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus)
     xf86MonPtr mon;
 
     mon = xf86DoEDID_DDC2 (scrn->scrnIndex, pDDCBus);
-    xf86DDCApplyQuirks (scrn->scrnIndex, mon);
+    if (mon)
+        xf86DDCApplyQuirks (scrn->scrnIndex, mon);
 
     return mon;
 }

commit 8d75a23f28f4e8dd1d5f3db47cd99cbc4674862c
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Dec 4 12:17:29 2007 +1100

    xf86Crtc: pass correct parameter.
    
    quite how this has worked I've no idea.
    (cherry picked from commit a9df4bb555fd91707a68794c2dce24fb06e6cf64)

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index f849b91..42ab1b1 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -2137,7 +2137,7 @@ xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus)
     xf86MonPtr mon;
 
     mon = xf86DoEDID_DDC2 (scrn->scrnIndex, pDDCBus);
-    xf86DDCApplyQuirks (scrn->scrnIndex, pDDCBus);
+    xf86DDCApplyQuirks (scrn->scrnIndex, mon);
 
     return mon;
 }

commit ca8e8f003d8d884a18003134502406598af3ccbc
Author: Eric Anholt <eric@anholt.net>
Date:   Thu Oct 18 15:22:42 2007 -0700

    Add a quirk for Philips 107P5 which lacks the preferred bit on detailed timing.
    
    Also fix the prefer-large-75 quirk if the prefer-first-detailed bit was set,
    though it's not the case for the existing prefer-large-75 consumer.
    (cherry picked from commit ab4bce02a9457dd9c86b774fc74caf3dd6b287ca)

diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c
index 70a6241..a125d8c 100644
--- a/hw/xfree86/modes/xf86EdidModes.c
+++ b/hw/xfree86/modes/xf86EdidModes.c
@@ -64,6 +64,8 @@ typedef enum {
      * maximum size and use that.
      */
     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,
 } ddc_quirk_t;
 
 static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC)
@@ -148,6 +150,16 @@ static Bool quirk_135_clock_too_high (int scrnIndex, xf86MonPtr DDC)
     return FALSE;
 }
 
+static Bool quirk_first_detailed_preferred (int scrnIndex, xf86MonPtr DDC)
+{
+    /* Philips 107p5 CRT. Reported on xorg@ with pastebin. */
+    if (memcmp (DDC->vendor.name, "PHL", 4) == 0 &&
+	DDC->vendor.prod_id == 57364)
+	return TRUE;
+
+    return FALSE;
+}
+
 typedef struct {
     Bool	(*detect) (int scrnIndex, xf86MonPtr DDC);
     ddc_quirk_t	quirk;
@@ -179,6 +191,10 @@ static const ddc_quirk_map_t ddc_quirks[] = {
 	quirk_detailed_use_maximum_size,   DDC_QUIRK_DETAILED_USE_MAXIMUM_SIZE,
 	"Detailed timings give sizes in cm."
     },
+    {
+	quirk_first_detailed_preferred, DDC_QUIRK_FIRST_DETAILED_PREFERRED,
+	"First detailed timing was not marked as preferred."
+    },
     { 
 	NULL,		DDC_QUIRK_NONE,
 	"No known quirks"
@@ -258,7 +274,7 @@ DDCModesFromStandardTiming(int scrnIndex, struct std_timings *timing,
  */
 static DisplayModePtr
 DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing,
-			  int preferred, ddc_quirk_t quirks)
+			  Bool preferred, ddc_quirk_t quirks)
 {
     DisplayModePtr Mode;
 
@@ -477,9 +493,10 @@ xf86DDCSetPreferredRefresh(int scrnIndex, DisplayModePtr modes,
 _X_EXPORT DisplayModePtr
 xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
 {
-    int preferred, i;
+    int		    i;
     DisplayModePtr  Modes = NULL, Mode;
     ddc_quirk_t	    quirks;
+    Bool	    preferred;
 
     xf86DrvMsg (scrnIndex, X_INFO, "EDID vendor \"%s\", prod id %d\n",
 		DDC->vendor.name, DDC->vendor.prod_id);
@@ -487,8 +504,10 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
     quirks = xf86DDCDetectQuirks(scrnIndex, DDC, TRUE);
 
     preferred = PREFERRED_TIMING_MODE(DDC->features.msc);
-    if (quirks & DDC_QUIRK_PREFER_LARGE_60)
-	preferred = 0;
+    if (quirks & DDC_QUIRK_FIRST_DETAILED_PREFERRED)
+	preferred = TRUE;
+    if (quirks & (DDC_QUIRK_PREFER_LARGE_60 | DDC_QUIRK_PREFER_LARGE_75))
+	preferred = FALSE;
 
     for (i = 0; i < DET_TIMINGS; i++) {
 	struct detailed_monitor_section *det_mon = &DDC->det_mon[i];
@@ -499,7 +518,7 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
                                              &det_mon->section.d_timings,
 					     preferred,
 					     quirks);
-	    preferred = 0;
+	    preferred = FALSE;
             Modes = xf86ModesAdd(Modes, Mode);
             break;
         case DS_STD_TIMINGS:

commit 5acc5c0bc452e1622e628668d1190464cba13577
Author: Eric Anholt <eric@anholt.net>
Date:   Thu Oct 11 16:48:56 2007 -0700

    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.
    (cherry picked from commit fc092334ac0a323b80a9602cb8bf60ca9dee3bfa)

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 9d93993..f849b91 100644
--- 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",
diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c
index 27e28b8..70a6241 100644
--- 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)
@@ -82,6 +92,52 @@ static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC)
     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. */
@@ -107,6 +163,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"
@@ -310,6 +382,98 @@ DDCGuessRangesFromModes(int scrnIndex, MonPtr Monitor, DisplayModePtr Modes)
     }
 }
 
+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)
 {
@@ -319,15 +483,9 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
 
     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;
@@ -364,32 +522,11 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
     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;
 }
 
diff --git a/hw/xfree86/modes/xf86Modes.h b/hw/xfree86/modes/xf86Modes.h
index 2bd4ede..3722d25 100644
--- a/hw/xfree86/modes/xf86Modes.h
+++ b/hw/xfree86/modes/xf86Modes.h
@@ -95,4 +95,7 @@ xf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor);
 DisplayModePtr
 xf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed);
 
+void
+xf86DDCApplyQuirks(int scrnIndex, xf86MonPtr DDC);
+
 #endif /* _XF86MODES_H_ */


Reply to: