diff options
-rw-r--r-- | src/g80_output.c | 86 | ||||
-rw-r--r-- | src/g80_sor.c | 2 |
2 files changed, 59 insertions, 29 deletions
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 |