xf86-video-nv: src/g80_output.c src/g80_sor.c

Aaron Plattner aplattner at kemper.freedesktop.org
Tue Feb 19 14:25:33 PST 2008


 src/g80_output.c |   86 +++++++++++++++++++++++++++++++++++++------------------
 src/g80_sor.c    |    2 -
 2 files changed, 59 insertions(+), 29 deletions(-)

New commits:
commit a87b93d5c5b4d1a65a60dad271b06a2d560b71b8
Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Tue Feb 19 14:17:57 2008 -0800

    G80: Fix connector mapping and TMDS initialization on certain GPUs.

diff --git a/src/g80_output.c b/src/g80_output.c
index d2ea9ee..05b907b 100644
--- a/src/g80_output.c
+++ b/src/g80_output.c
@@ -69,8 +69,8 @@ static unsigned G80FindLoadVal(const unsigned char *table1)
 
 static Bool G80ReadPortMapping(int scrnIndex, G80Ptr pNv)
 {
-    unsigned char *table2;
-    unsigned char headerSize, entries;
+    unsigned char *table2, *table3;
+    unsigned char headerSize, entries, table3Entries, table3EntSize;
     int i;
     CARD16 a;
     CARD32 b;
@@ -89,11 +89,16 @@ static Bool G80ReadPortMapping(int scrnIndex, G80Ptr pNv)
     b = *(CARD32*)(table2 + 6);
     if(b != 0x4edcbdcb) goto fail;
 
+    table3 = (unsigned char*)pNv->table1 + *(CARD16*)(table2 + 4);
+    table3Entries = table3[2];
+    table3EntSize = table3[3];
+    table3 += table3[1];
+
     headerSize = table2[1];
     entries = table2[2];
 
     for(i = 0; i < entries; i++) {
-        int type, port;
+        int type, port, portType;
         ORNum or;
 
         b = *(CARD32*)&table2[headerSize + 8*i];
@@ -103,35 +108,60 @@ static Bool G80ReadPortMapping(int scrnIndex, G80Ptr pNv)
 
         if(type == 0xe) break;
 
-        if(type < 4) {
-            switch(type) {
-                case 0: /* CRT */
-                    if(pNv->i2cMap[port].dac != -1) {
-                        xf86DrvMsg(scrnIndex, X_WARNING,
-                                   "DDC routing table corrupt!  DAC %i -> %i "
-                                   "for port %i\n",
-                                   or, pNv->i2cMap[port].dac, port);
-                    }
-                    pNv->i2cMap[port].dac = or;
+        switch(type) {
+            case 0: /* CRT */
+                if(port >= table3Entries) {
+                    xf86DrvMsg(scrnIndex, X_WARNING,
+                               "VGA%d: invalid port %d\n", or, port);
                     break;
-                case 1: /* TV */
-                    /* Ignore TVs */
+                }
+                b = *(CARD32*)&table3[table3EntSize * port];
+                port = b & 0xff;
+                portType = b >> 24;
+                if(portType != 5) {
+                    xf86DrvMsg(scrnIndex, X_WARNING,
+                               "VGA%d: invalid port type %d\n", or, portType);
                     break;
-
-                case 2: /* TMDS */
-                    if(pNv->i2cMap[port].sor != -1)
-                        xf86DrvMsg(scrnIndex, X_WARNING,
-                                   "DDC routing table corrupt!  SOR %i -> %i "
-                                   "for port %i\n",
-                                   or, pNv->i2cMap[port].sor, port);
-                    pNv->i2cMap[port].sor = or;
+                }
+                if(pNv->i2cMap[port].dac != -1) {
+                    xf86DrvMsg(scrnIndex, X_WARNING,
+                               "DDC routing table corrupt!  DAC %i -> %i for "
+                               "port %i\n", or, pNv->i2cMap[port].dac, port);
+                }
+                pNv->i2cMap[port].dac = or;
+                break;
+            case 1: /* TV */
+                /* Ignore TVs */
+                break;
+
+            case 2: /* TMDS */
+                if(port >= table3Entries) {
+                    xf86DrvMsg(scrnIndex, X_WARNING,
+                               "DVI%d: invalid port %d\n", or, port);
                     break;
-
-                case 3: /* LVDS */
-                    pNv->lvds.present = TRUE;
-                    pNv->lvds.or = or;
+                }
+                b = *(CARD32*)&table3[table3EntSize * port];
+                port = b & 0xff;
+                portType = b >> 24;
+                if(portType != 5) {
+                    xf86DrvMsg(scrnIndex, X_WARNING,
+                               "DVI%d: invalid port type %d\n", or, portType);
                     break;
-            }
+                }
+                if(pNv->i2cMap[port].sor != -1)
+                    xf86DrvMsg(scrnIndex, X_WARNING,
+                               "DDC routing table corrupt!  SOR %i -> %i for "
+                               "port %i\n", or, pNv->i2cMap[port].sor, port);
+                pNv->i2cMap[port].sor = or;
+                break;
+
+            case 3: /* LVDS */
+                pNv->lvds.present = TRUE;
+                pNv->lvds.or = or;
+                break;
+
+            default:
+                break;
         }
     }
 
diff --git a/src/g80_sor.c b/src/g80_sor.c
index 0b39005..02a5f3b 100644
--- a/src/g80_sor.c
+++ b/src/g80_sor.c
@@ -41,7 +41,7 @@ G80SorSetPClk(xf86OutputPtr output, int pclk)
     const int orOff = 0x800 * pPriv->or;
     const int limit = 165000;
 
-    pNv->reg[(0x00614300+orOff)/4] = (pclk > limit) ? 0x101 : 0;
+    pNv->reg[(0x00614300+orOff)/4] = 0x70000 | (pclk > limit ? 0x101 : 0);
 }
 
 static void


More information about the xorg-commit mailing list