diff options
author | Aaron Plattner <aplattner@nvidia.com> | 2007-10-14 14:15:07 -0700 |
---|---|---|
committer | Aaron Plattner <aplattner@nvidia.com> | 2007-10-14 14:18:20 -0700 |
commit | 0887084730af8428e902dabc6e00c505f383f57f (patch) | |
tree | 4fd53efe1cad60cf0b8ec5b419b2746cb2f18c30 /src | |
parent | 1003bcbe4381201f1d7b34dc1af72f57b2943b67 (diff) |
G80 bug #12397: Fix LVDS detection on certain laptops.
Diffstat (limited to 'src')
-rw-r--r-- | src/g80_sor.c | 48 |
1 files changed, 33 insertions, 15 deletions
diff --git a/src/g80_sor.c b/src/g80_sor.c index c98b66d..e1128ef 100644 --- a/src/g80_sor.c +++ b/src/g80_sor.c @@ -427,20 +427,20 @@ static const xf86OutputFuncsRec G80SorLVDSOutputFuncs = { }; static DisplayModePtr -GetLVDSNativeMode(G80Ptr pNv) +ReadLVDSNativeMode(G80Ptr pNv, const int off) { DisplayModePtr mode = xnfcalloc(1, sizeof(DisplayModeRec)); - const CARD32 size = pNv->reg[0x00610B4C/4]; + const CARD32 size = pNv->reg[(0x00610B4C+off)/4]; const int width = size & 0x3fff; const int height = (size >> 16) & 0x3fff; mode->HDisplay = mode->CrtcHDisplay = width; mode->VDisplay = mode->CrtcVDisplay = height; - mode->Clock = pNv->reg[0x610AD4/4] & 0x3fffff; - mode->CrtcHBlankStart = pNv->reg[0x610AFC/4]; - mode->CrtcHSyncEnd = pNv->reg[0x610B04/4]; - mode->CrtcHBlankEnd = pNv->reg[0x610AE8/4]; - mode->CrtcHTotal = pNv->reg[0x610AF4/4]; + mode->Clock = pNv->reg[(0x610AD4+off)/4] & 0x3fffff; + mode->CrtcHBlankStart = pNv->reg[(0x610AFC+off)/4]; + mode->CrtcHSyncEnd = pNv->reg[(0x610B04+off)/4]; + mode->CrtcHBlankEnd = pNv->reg[(0x610AE8+off)/4]; + mode->CrtcHTotal = pNv->reg[(0x610AF4+off)/4]; mode->next = mode->prev = NULL; mode->status = MODE_OK; @@ -451,6 +451,19 @@ GetLVDSNativeMode(G80Ptr pNv) return mode; } +static DisplayModePtr +GetLVDSNativeMode(G80Ptr pNv) +{ + CARD32 val = pNv->reg[0x00610050/4]; + + if((val & 3) == 2) + return ReadLVDSNativeMode(pNv, 0); + else if((val & 0x300) == 0x200) + return ReadLVDSNativeMode(pNv, 0x540); + + return NULL; +} + xf86OutputPtr G80CreateSor(ScrnInfoPtr pScrn, ORNum or, PanelType panelType) { @@ -467,6 +480,19 @@ G80CreateSor(ScrnInfoPtr pScrn, ORNum or, PanelType panelType) if(panelType == LVDS) { strcpy(orName, "LVDS"); funcs = &G80SorLVDSOutputFuncs; + + pPriv->nativeMode = GetLVDSNativeMode(pNv); + + if(!pPriv->nativeMode) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Failed to find LVDS native mode\n"); + xfree(pPriv); + return FALSE; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s native size %dx%d\n", + orName, pPriv->nativeMode->HDisplay, + pPriv->nativeMode->VDisplay); } else { snprintf(orName, 5, "DVI%d", or); pNv->reg[(0x61C00C+off)/4] = 0x03010700; @@ -488,13 +514,5 @@ G80CreateSor(ScrnInfoPtr pScrn, ORNum or, PanelType panelType) output->interlaceAllowed = TRUE; output->doubleScanAllowed = TRUE; - if(panelType == LVDS) { - pPriv->nativeMode = GetLVDSNativeMode(pNv); - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s native size %dx%d\n", - orName, pPriv->nativeMode->HDisplay, - pPriv->nativeMode->VDisplay); - } - return output; } |