diff options
Diffstat (limited to 'src/nv_dac.c')
-rw-r--r-- | src/nv_dac.c | 68 |
1 files changed, 48 insertions, 20 deletions
diff --git a/src/nv_dac.c b/src/nv_dac.c index 4b3f528..f62db58 100644 --- a/src/nv_dac.c +++ b/src/nv_dac.c @@ -37,10 +37,38 @@ |* *| \***************************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_dac.c,v 1.37 2003/09/08 20:00:27 mvojkovi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_dac.c,v 1.44 2004/12/09 00:21:04 mvojkovi Exp $ */ #include "nv_include.h" +static int +NVDACPanelTweaks(NVPtr pNv, NVRegPtr state) +{ + int tweak = 0; + + if(pNv->usePanelTweak) { + tweak = pNv->PanelTweak; + } else { + /* begin flat panel hacks */ + /* This is unfortunate, but some chips need this register + tweaked or else you get artifacts where adjacent pixels are + swapped. There are no hard rules for what to set here so all + we can do is experiment and apply hacks. */ + + if(((pNv->Chipset & 0xffff) == 0x0328) && (state->bpp == 32)) { + /* At least one NV34 laptop needs this workaround. */ + tweak = -1; + } + + if((pNv->Chipset & 0xfff0) == 0x0310) { + tweak = 1; + } + /* end flat panel hacks */ + } + + return tweak; +} + Bool NVDACInit(ScrnInfoPtr pScrn, DisplayModePtr mode) { @@ -58,7 +86,6 @@ NVDACInit(ScrnInfoPtr pScrn, DisplayModePtr mode) int vertBlankStart = mode->CrtcVDisplay - 1; int vertBlankEnd = mode->CrtcVTotal - 1; - NVPtr pNv = NVPTR(pScrn); NVRegPtr nvReg = &pNv->ModeReg; NVFBLayout *pLayout = &pNv->CurrentLayout; @@ -186,6 +213,8 @@ NVDACInit(ScrnInfoPtr pScrn, DisplayModePtr mode) { nvReg->scale |= (1 << 8) ; } + nvReg->crtcSync = pNv->PRAMDAC[0x0828/4]; + nvReg->crtcSync += NVDACPanelTweaks(pNv, nvReg); } nvReg->vpll = nvReg->pll; @@ -193,6 +222,9 @@ NVDACInit(ScrnInfoPtr pScrn, DisplayModePtr mode) nvReg->vpllB = nvReg->pllB; nvReg->vpll2B = nvReg->pllB; + VGA_WR08(pNv->PCIO, 0x03D4, 0x1C); + nvReg->fifo = VGA_RD08(pNv->PCIO, 0x03D5) & ~(1<<5); + if(pNv->CRTCnumber) { nvReg->head = pNv->PCRTC0[0x00000860/4] & ~0x00001000; nvReg->head2 = pNv->PCRTC0[0x00002860/4] | 0x00001000; @@ -215,29 +247,29 @@ NVDACInit(ScrnInfoPtr pScrn, DisplayModePtr mode) if(mode->Flags & V_DBLSCAN) nvReg->cursorConfig |= (1 << 4); if(pNv->alphaCursor) { - nvReg->cursorConfig |= 0x04011000; + if((pNv->Chipset & 0x0ff0) != 0x0110) + nvReg->cursorConfig |= 0x04011000; + else + nvReg->cursorConfig |= 0x14011000; nvReg->general |= (1 << 29); + } else + nvReg->cursorConfig |= 0x02000000; + if(pNv->twoHeads) { if((pNv->Chipset & 0x0ff0) == 0x0110) { - nvReg->dither = pNv->PRAMDAC[0x0528/4] & ~0x00010000; - if(pNv->FPDither) - nvReg->dither |= 0x00010000; - else - nvReg->cursorConfig |= (1 << 28); - } else - if((pNv->Chipset & 0x0ff0) >= 0x0170) { + nvReg->dither = pNv->PRAMDAC[0x0528/4] & ~0x00010000; + if(pNv->FPDither) + nvReg->dither |= 0x00010000; + } else { nvReg->dither = pNv->PRAMDAC[0x083C/4] & ~1; - nvReg->cursorConfig |= (1 << 28); if(pNv->FPDither) nvReg->dither |= 1; - } else { - nvReg->cursorConfig |= (1 << 28); - } - } else - nvReg->cursorConfig |= 0x02000000; + } + } nvReg->timingH = 0; nvReg->timingV = 0; + nvReg->displayV = mode->CrtcVDisplay; return (TRUE); } @@ -250,8 +282,6 @@ NVDACRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, NVRegPtr nvReg, int restore = VGA_SR_MODE; if(primary) restore |= VGA_SR_CMAP | VGA_SR_FONTS; - else if((pNv->Chipset & 0xffff) == 0x0018) - restore |= VGA_SR_CMAP; NVLoadStateExt(pNv, nvReg); #if defined(__powerpc__) restore &= ~VGA_SR_FONTS; @@ -274,8 +304,6 @@ NVDACSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, NVRegPtr nvReg, saveFonts = FALSE; #endif - NVLockUnlock(pNv, 0); - vgaHWSave(pScrn, vgaReg, VGA_SR_CMAP | VGA_SR_MODE | (saveFonts? VGA_SR_FONTS : 0)); NVUnloadStateExt(pNv, nvReg); |