diff options
author | Aaron Plattner <aplattner@nvidia.com> | 2008-01-23 21:32:51 -0800 |
---|---|---|
committer | Aaron Plattner <aplattner@nvidia.com> | 2008-01-24 15:02:41 -0800 |
commit | 62ff129257161db99dc4056cf16aa196ccfbc921 (patch) | |
tree | 508b158d9308624b913ee66f275d9da7b6e9ac96 | |
parent | 28f34db87cefdc6b327a98db43da5b4fefe3bdd8 (diff) |
Fix more load detection false positives.
-rw-r--r-- | src/g80_dac.c | 9 | ||||
-rw-r--r-- | src/g80_output.c | 38 | ||||
-rw-r--r-- | src/g80_type.h | 1 |
3 files changed, 43 insertions, 5 deletions
diff --git a/src/g80_dac.c b/src/g80_dac.c index 282436b..0d72d9d 100644 --- a/src/g80_dac.c +++ b/src/g80_dac.c @@ -136,23 +136,22 @@ G80DacLoadDetect(xf86OutputPtr output) const int scrnIndex = pScrn->scrnIndex; const int dacOff = 2048 * pPriv->or; int sigstate; - CARD32 load, tmp, tmp2; + CARD32 load, tmp; xf86DrvMsg(scrnIndex, X_PROBED, "Trying load detection on VGA%i ... ", pPriv->or); pNv->reg[(0x0061A010+dacOff)/4] = 0x00000001; - tmp2 = pNv->reg[(0x0061A004+dacOff)/4]; + tmp = pNv->reg[(0x0061A004+dacOff)/4]; pNv->reg[(0x0061A004+dacOff)/4] = 0x80150000; while(pNv->reg[(0x0061A004+dacOff)/4] & 0x80000000); - tmp = pNv->architecture == 0x50 ? 420 : 340; - pNv->reg[(0x0061A00C+dacOff)/4] = tmp | 0x100000; + pNv->reg[(0x0061A00C+dacOff)/4] = pNv->loadVal | 0x100000; sigstate = xf86BlockSIGIO(); usleep(45000); xf86UnblockSIGIO(sigstate); load = pNv->reg[(0x0061A00C+dacOff)/4]; pNv->reg[(0x0061A00C+dacOff)/4] = 0; - pNv->reg[(0x0061A004+dacOff)/4] = 0x80000000 | tmp2; + pNv->reg[(0x0061A004+dacOff)/4] = 0x80000000 | tmp; // Use this DAC if all three channels show load. if((load & 0x38000000) == 0x38000000) { diff --git a/src/g80_output.c b/src/g80_output.c index 1ec6a89..53c0954 100644 --- a/src/g80_output.c +++ b/src/g80_output.c @@ -32,6 +32,41 @@ #include "g80_display.h" #include "g80_output.h" +static CARD32 G80FindLoadVal(const unsigned char *table1) +{ + const unsigned char *p = table1; + int count; + const CARD32 def = 340; + + for(p = table1; *(CARD16*)p != 0xb8ff && p < table1 + 64000; p += 2); + if(p == table1 + 64000) + return def; + p += 2; + if(*(CARD32*)p != 0x544942) + return def; + p += 4; + if(*(CARD16*)p != 0x100) + return def; + p += 2; + if(*p != 12) + return def; + p++; + if(*p != 6) + return def; + p++; + count = *p; + p += 2; + for(; *p != 'A' && count >= 0; count--, p += 6); + if(count == -1) + return def; + p += 4; + p = table1 + *(CARD16*)p; + p = table1 + *(CARD16*)p; + if(p[0] != 0x10 || p[1] != 4 || p[2] != 4 || p[3] != 2) + return def; + return *(CARD32*)(p + 4) & 0x3ff; +} + static Bool G80ReadPortMapping(int scrnIndex, G80Ptr pNv) { unsigned char *table2; @@ -110,6 +145,9 @@ static Bool G80ReadPortMapping(int scrnIndex, G80Ptr pNv) xf86DrvMsg(scrnIndex, X_PROBED, " Bus %i -> SOR%i\n", i, pNv->i2cMap[i].sor); } + pNv->loadVal = G80FindLoadVal(pNv->table1); + xf86DrvMsg(scrnIndex, X_PROBED, "Load detection: %d\n", pNv->loadVal); + return TRUE; fail: diff --git a/src/g80_type.h b/src/g80_type.h index 41f170b..fc31085 100644 --- a/src/g80_type.h +++ b/src/g80_type.h @@ -56,6 +56,7 @@ typedef struct G80Rec { Bool present; ORNum or; } lvds; + CARD32 loadVal; xf86Int10InfoPtr int10; int int10Mode; /* Console mode to restore */ |