diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nv_cursor.c | 41 | ||||
-rw-r--r-- | src/nv_dac.c | 68 | ||||
-rw-r--r-- | src/nv_dma.h | 8 | ||||
-rw-r--r-- | src/nv_driver.c | 241 | ||||
-rw-r--r-- | src/nv_hw.c | 451 | ||||
-rw-r--r-- | src/nv_proto.h | 3 | ||||
-rw-r--r-- | src/nv_setup.c | 36 | ||||
-rw-r--r-- | src/nv_type.h | 12 | ||||
-rw-r--r-- | src/nv_video.c | 86 | ||||
-rw-r--r-- | src/nv_xaa.c | 15 |
10 files changed, 748 insertions, 213 deletions
diff --git a/src/nv_cursor.c b/src/nv_cursor.c index 577b44d..f22e3d7 100644 --- a/src/nv_cursor.c +++ b/src/nv_cursor.c @@ -37,7 +37,7 @@ |* *| \***************************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_cursor.c,v 1.11 2002/11/26 23:41:58 mvojkovi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_cursor.c,v 1.13 2004/03/13 22:07:05 mvojkovi Exp $ */ #include "nv_include.h" @@ -239,28 +239,37 @@ NVLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs) NVPtr pNv = NVPTR(pScrn); CARD32 *image = pCurs->bits->argb; CARD32 *dst = (CARD32*)pNv->CURSOR; + CARD32 alpha, tmp; int x, y, w, h; w = pCurs->bits->width; h = pCurs->bits->height; -#if X_BYTE_ORDER == X_BIG_ENDIAN - if((pNv->Chipset & 0x0ff0) == 0x0110) { - CARD32 tmp; - + if((pNv->Chipset & 0x0ff0) == 0x0110) { /* premultiply */ for(y = 0; y < h; y++) { for(x = 0; x < w; x++) { - tmp = *image++; - *dst++ = BYTE_SWAP_32(tmp); - } - for(; x < 64; x++) - *dst++ = 0; - } - } else + alpha = *image >> 24; + if(alpha == 0xff) + tmp = *image; + else { + tmp = (alpha << 24) | + (((*image & 0xff) * alpha) / 255) | + ((((*image & 0xff00) * alpha) / 255) & 0xff00) | + ((((*image & 0xff0000) * alpha) / 255) & 0xff0000); + } + image++; +#if X_BYTE_ORDER == X_BIG_ENDIAN + *dst++ = BYTE_SWAP_32(tmp); +#else + *dst++ = tmp; #endif - { + } + for(; x < 64; x++) + *dst++ = 0; + } + } else { for(y = 0; y < h; y++) { - for(x = 0; x < w; x++) + for(x = 0; x < w; x++) *dst++ = *image++; for(; x < 64; x++) *dst++ = 0; @@ -299,9 +308,7 @@ NVCursorInit(ScreenPtr pScreen) infoPtr->UseHWCursor = NVUseHWCursor; #ifdef ARGB_CURSOR - if(pNv->alphaCursor && - (((pNv->Chipset & 0x0ff0) != 0x0110) || !pNv->FPDither)) - { + if(pNv->alphaCursor) { infoPtr->UseHWCursorARGB = NVUseHWCursorARGB; infoPtr->LoadCursorARGB = NVLoadCursorARGB; } 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); diff --git a/src/nv_dma.h b/src/nv_dma.h index 15b222f..ca0bf1b 100644 --- a/src/nv_dma.h +++ b/src/nv_dma.h @@ -38,7 +38,7 @@ |* *| \***************************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_dma.h,v 1.1 2003/07/31 20:24:29 mvojkovi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_dma.h,v 1.4 2004/03/20 01:52:16 mvojkovi Exp $ */ #define SURFACE_FORMAT 0x00000300 #define SURFACE_FORMAT_DEPTH8 0x00000001 @@ -145,9 +145,15 @@ #define STRETCH_BLIT_FORMAT_DEPTH8 0x00000004 #define STRETCH_BLIT_FORMAT_DEPTH16 0x00000007 #define STRETCH_BLIT_FORMAT_DEPTH24 0x00000004 +#define STRETCH_BLIT_FORMAT_A8R8G8B8 0x00000003 #define STRETCH_BLIT_FORMAT_X8R8G8B8 0x00000004 #define STRETCH_BLIT_FORMAT_YUYV 0x00000005 #define STRETCH_BLIT_FORMAT_UYVY 0x00000006 +/* STRETCH_BLIT_OPERATION is only supported on TNT2 and newer */ +#define STRETCH_BLIT_OPERATION 0x0000E304 +#define STRETCH_BLIT_OPERATION_ROP 0x00000001 +#define STRETCH_BLIT_OPERATION_COPY 0x00000003 +#define STRETCH_BLIT_OPERATION_BLEND 0x00000002 #define STRETCH_BLIT_CLIP_POINT 0x0000E308 #define STRETCH_BLIT_CLIP_POINT_X 15:0 #define STRETCH_BLIT_CLIP_POINT_Y 31:16 diff --git a/src/nv_driver.c b/src/nv_driver.c index 11e29b0..f155e41 100644 --- a/src/nv_driver.c +++ b/src/nv_driver.c @@ -1,4 +1,4 @@ -/* $XdotOrg: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c,v 1.5 2004/08/16 09:13:14 ajax Exp $ */ +/* $XdotOrg$ */ /* $XConsortium: nv_driver.c /main/3 1996/10/28 05:13:37 kaleb $ */ /* * Copyright 1996-1997 David J. McKay @@ -25,7 +25,7 @@ /* Hacked together from mga driver and 3.3.4 NVIDIA driver by Jarno Paananen <jpaana@s2.org> */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c,v 1.122 2004/01/10 22:31:53 mvojkovi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c,v 1.130 2004/12/09 00:21:04 mvojkovi Exp $ */ #include "nv_include.h" @@ -113,18 +113,19 @@ static SymTabRec NVKnownChipsets[] = { 0x10DE0175, "GeForce4 420 Go" }, { 0x10DE0176, "GeForce4 420 Go 32M" }, { 0x10DE0177, "GeForce4 460 Go" }, + { 0x10DE0178, "Quadro4 550 XGL" }, #if defined(__powerpc__) { 0x10DE0179, "GeForce4 MX (Mac)" }, #else { 0x10DE0179, "GeForce4 440 Go 64M" }, #endif - { 0x10DE017D, "GeForce4 410 Go 16M" }, - { 0x10DE017C, "Quadro4 500 GoGL" }, - { 0x10DE0178, "Quadro4 550 XGL" }, { 0x10DE017A, "Quadro4 NVS" }, + { 0x10DE017C, "Quadro4 500 GoGL" }, + { 0x10DE017D, "GeForce4 410 Go 16M" }, { 0x10DE0181, "GeForce4 MX 440 with AGP8X" }, { 0x10DE0182, "GeForce4 MX 440SE with AGP8X" }, { 0x10DE0183, "GeForce4 MX 420 with AGP8X" }, + { 0x10DE0185, "GeForce4 MX 4000" }, { 0x10DE0186, "GeForce4 448 Go" }, { 0x10DE0187, "GeForce4 488 Go" }, { 0x10DE0188, "Quadro4 580 XGL" }, @@ -133,6 +134,8 @@ static SymTabRec NVKnownChipsets[] = #endif { 0x10DE018A, "Quadro4 280 NVS" }, { 0x10DE018B, "Quadro4 380 XGL" }, + { 0x10DE018C, "Quadro NVS 50 PCI" }, + { 0x10DE018D, "GeForce4 448 Go" }, { 0x10DE01F0, "GeForce4 MX Integrated GPU" }, { 0x10DE0200, "GeForce3" }, { 0x10DE0201, "GeForce3 Ti 200" }, @@ -174,6 +177,8 @@ static SymTabRec NVKnownChipsets[] = { 0x10DE0323, "GeForce FX 5200SE" }, { 0x10DE0324, "GeForce FX Go5200" }, { 0x10DE0325, "GeForce FX Go5250" }, + { 0x10DE0326, "GeForce FX 5500" }, + { 0x10DE0327, "GeForce FX 5100" }, { 0x10DE0328, "GeForce FX Go5200 32M/64M" }, #if defined(__powerpc__) { 0x10DE0329, "GeForce FX 5200 (Mac)" }, @@ -181,15 +186,16 @@ static SymTabRec NVKnownChipsets[] = { 0x10DE0329, "0x0329" }, #endif { 0x10DE032A, "Quadro NVS 280 PCI" }, - { 0x10DE032B, "Quadro FX 500" }, - { 0x10DE032C, "GeForce FX Go5300" }, + { 0x10DE032B, "Quadro FX 500/600 PCI" }, + { 0x10DE032C, "GeForce FX Go53xx Series" }, { 0x10DE032D, "GeForce FX Go5100" }, { 0x10DE032F, "0x032F" }, { 0x10DE0330, "GeForce FX 5900 Ultra" }, { 0x10DE0331, "GeForce FX 5900" }, { 0x10DE0332, "GeForce FX 5900XT" }, { 0x10DE0333, "GeForce FX 5950 Ultra" }, - { 0x10DE0334, "0x0334" }, + { 0x10DE033F, "Quadro FX 700" }, + { 0x10DE0334, "GeForce FX 5900ZT" }, { 0x10DE0338, "Quadro FX 3000" }, { 0x10DE0341, "GeForce FX 5700 Ultra" }, { 0x10DE0342, "GeForce FX 5700" }, @@ -203,6 +209,42 @@ static SymTabRec NVKnownChipsets[] = { 0x10DE034C, "Quadro FX Go1000" }, { 0x10DE034E, "Quadro FX 1100" }, { 0x10DE034F, "0x034F" }, + { 0x10DE0040, "GeForce 6800 Ultra" }, + { 0x10DE0041, "GeForce 6800" }, + { 0x10DE0042, "GeForce 6800 LE" }, + { 0x10DE0043, "0x0043" }, + { 0x10DE0045, "GeForce 6800 GT" }, + { 0x10DE0049, "0x0049" }, + { 0x10DE004E, "Quadro FX 4000" }, + { 0x10DE004D, "Quadro FX 4400" }, + { 0x10DE00C0, "0x00C0" }, + { 0x10DE00C1, "0x00C1" }, + { 0x10DE00C2, "GeForce 6800 LE" }, + { 0x10DE00C8, "0x00C8" }, + { 0x10DE00C9, "0x00C9" }, + { 0x10DE00CC, "0x00CC" }, + { 0x10DE00CE, "0x00CE" }, + { 0x10DE0140, "GeForce 6600 GT" }, + { 0x10DE0141, "GeForce 6600" }, + { 0x10DE0142, "0x0142" }, + { 0x10DE0143, "0x0143" }, + { 0x10DE0144, "GeForce Go 6600" }, + { 0x10DE0145, "GeForce 6610 XL" }, + { 0x10DE0146, "GeForce Go 6600 TE/6200 TE" }, + { 0x10DE0147, "0x0147" }, + { 0x10DE0148, "GeForce Go 6600" }, + { 0x10DE0149, "0x0149" }, + { 0x10DE014B, "0x014B" }, + { 0x10DE014C, "0x014C" }, + { 0x10DE014D, "0x014D" }, + { 0x10DE014E, "Quadro FX 540" }, + { 0x10DE014F, "GeForce 6200" }, + { 0x10DE0160, "0x0160" }, + { 0x10DE0166, "0x0166" }, + { 0x10DE0210, "0x0210" }, + { 0x10DE0211, "0x0211" }, + { 0x10DE021D, "0x021D" }, + { 0x10DE021E, "0x021E" }, {-1, NULL} }; @@ -350,7 +392,9 @@ typedef enum { OPTION_VIDEO_KEY, OPTION_FLAT_PANEL, OPTION_FP_DITHER, - OPTION_CRTC_NUMBER + OPTION_CRTC_NUMBER, + OPTION_FP_SCALE, + OPTION_FP_TWEAK } NVOpts; @@ -365,6 +409,8 @@ static const OptionInfoRec NVOptions[] = { { OPTION_FLAT_PANEL, "FlatPanel", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_FP_DITHER, "FPDither", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_CRTC_NUMBER, "CrtcNumber", OPTV_INTEGER, {0}, FALSE }, + { OPTION_FP_SCALE, "FPScale", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_FP_TWEAK, "FPTweak", OPTV_INTEGER, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; @@ -494,6 +540,36 @@ NVGetScrnInfoRec(PciChipsets *chips, int chip) #define MAX_CHIPS MAXSCREENS + +static CARD32 +NVGetPCIXpressChip (pciVideoPtr pVideo) +{ + volatile CARD32 *regs; + CARD32 pciid, pcicmd; + PCITAG Tag = ((pciConfigPtr)(pVideo->thisCard))->tag; + + pcicmd = pciReadLong(Tag, PCI_CMD_STAT_REG); + pciWriteLong(Tag, PCI_CMD_STAT_REG, pcicmd | PCI_CMD_MEM_ENABLE); + + regs = xf86MapPciMem(-1, VIDMEM_MMIO, Tag, pVideo->memBase[0], 0x2000); + + pciid = regs[0x1800/4]; + + xf86UnMapVidMem(-1, (pointer)regs, 0x2000); + + pciWriteLong(Tag, PCI_CMD_STAT_REG, pcicmd); + + if((pciid & 0x0000ffff) == 0x000010DE) + pciid = 0x10DE0000 | (pciid >> 16); + else + if((pciid & 0xffff0000) == 0xDE100000) /* wrong endian */ + pciid = 0x10DE0000 | ((pciid << 8) & 0x0000ff00) | + ((pciid >> 8) & 0x000000ff); + + return pciid; +} + + /* Mandatory */ static Bool NVProbe(DriverPtr drv, int flags) @@ -523,7 +599,11 @@ NVProbe(DriverPtr drv, int flags) ((*ppPci)->vendor == PCI_VENDOR_NVIDIA)) { SymTabRec *nvchips = NVKnownChipsets; - int token = ((*ppPci)->vendor << 16) | (*ppPci)->chipType; + int pciid = ((*ppPci)->vendor << 16) | (*ppPci)->chipType; + int token = pciid; + + if((token & 0xfff0) == 0x00F0) + token = NVGetPCIXpressChip(*ppPci); while(nvchips->name) { if(token == nvchips->token) @@ -532,10 +612,10 @@ NVProbe(DriverPtr drv, int flags) } if(nvchips->name) { /* found one */ - NVChipsets[numUsed].token = nvchips->token; + NVChipsets[numUsed].token = pciid; NVChipsets[numUsed].name = nvchips->name; - NVPciChipsets[numUsed].numChipset = nvchips->token; - NVPciChipsets[numUsed].PCIid = nvchips->token; + NVPciChipsets[numUsed].numChipset = pciid; + NVPciChipsets[numUsed].PCIid = pciid; NVPciChipsets[numUsed].resList = RES_SHARED_VGA; numUsed++; } else if ((*ppPci)->vendor == PCI_VENDOR_NVIDIA) { @@ -551,10 +631,19 @@ NVProbe(DriverPtr drv, int flags) case 0x0320: case 0x0330: case 0x0340: - NVChipsets[numUsed].token = token; + case 0x0040: + case 0x00C0: + case 0x0120: + case 0x0140: + case 0x0160: + case 0x0130: + case 0x01D0: + case 0x0090: + case 0x0210: + NVChipsets[numUsed].token = pciid; NVChipsets[numUsed].name = "Unknown NVIDIA chip"; - NVPciChipsets[numUsed].numChipset = token; - NVPciChipsets[numUsed].PCIid = token; + NVPciChipsets[numUsed].numChipset = pciid; + NVPciChipsets[numUsed].PCIid = pciid; NVPciChipsets[numUsed].resList = RES_SHARED_VGA; numUsed++; break; @@ -768,6 +857,17 @@ NVFreeScreen(int scrnIndex, int flags) static ModeStatus NVValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) { + NVPtr pNv = NVPTR(xf86Screens[scrnIndex]); + + if(pNv->fpWidth && pNv->fpHeight) { + if((pNv->fpWidth < mode->HDisplay) || (pNv->fpHeight < mode->VDisplay)) { + xf86DrvMsg(scrnIndex, X_INFO, "Mode \"%s\" is larger than " + "BIOS programmed panel size of %d x %d. Removing.\n", + mode->name, pNv->fpWidth, pNv->fpHeight); + return (MODE_BAD); + } + } + return (MODE_OK); } @@ -887,11 +987,16 @@ NVPreInit(ScrnInfoPtr pScrn, int flags) } else { from = X_PROBED; pNv->Chipset = (pNv->PciInfo->vendor << 16) | pNv->PciInfo->chipType; + + if((pNv->Chipset & 0xfff0) == 0x00F0) + pNv->Chipset = NVGetPCIXpressChip(pNv->PciInfo); + pScrn->chipset = (char *)xf86TokenToString(NVKnownChipsets, pNv->Chipset); if(!pScrn->chipset) pScrn->chipset = "Unknown NVIDIA chipset"; } + if (pNv->pEnt->device->chipRev >= 0) { pNv->ChipRev = pNv->pEnt->device->chipRev; xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", @@ -1026,6 +1131,12 @@ NVPreInit(ScrnInfoPtr pScrn, int flags) } xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", pNv->HWCursor ? "HW" : "SW"); + + pNv->FpScale = TRUE; + if (xf86GetOptValBool(pNv->Options, OPTION_FP_SCALE, &pNv->FpScale)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Flat panel scaling %s\n", + pNv->FpScale ? "on" : "off"); + } if (xf86ReturnOptValBool(pNv->Options, OPTION_NOACCEL, FALSE)) { pNv->NoAccel = TRUE; xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); @@ -1115,6 +1226,14 @@ NVPreInit(ScrnInfoPtr pScrn, int flags) pNv->CRTCnumber = -1; /* autodetect later */ } + + if (xf86GetOptValInteger(pNv->Options, OPTION_FP_TWEAK, + &pNv->PanelTweak)) + { + pNv->usePanelTweak = TRUE; + } else { + pNv->usePanelTweak = FALSE; + } if (pNv->pEnt->device->MemBase != 0) { /* Require that the config file value matches one of the PCI values. */ @@ -1178,12 +1297,46 @@ NVPreInit(ScrnInfoPtr pScrn, int flags) return FALSE; } - pNv->alphaCursor = ((pNv->Chipset & 0x0ff0) >= 0x0110); - - pNv->Architecture = (pNv->Chipset & 0x0f00) >> 4; + switch (pNv->Chipset & 0x0ff0) { + case 0x0100: /* GeForce 256 */ + case 0x0110: /* GeForce2 MX */ + case 0x0150: /* GeForce2 */ + case 0x0170: /* GeForce4 MX */ + case 0x0180: /* GeForce4 MX (8x AGP) */ + case 0x01A0: /* nForce */ + case 0x01F0: /* nForce2 */ + pNv->Architecture = NV_ARCH_10; + break; + case 0x0200: /* GeForce3 */ + case 0x0250: /* GeForce4 Ti */ + case 0x0280: /* GeForce4 Ti (8x AGP) */ + pNv->Architecture = NV_ARCH_20; + break; + case 0x0300: /* GeForceFX 5800 */ + case 0x0310: /* GeForceFX 5600 */ + case 0x0320: /* GeForceFX 5200 */ + case 0x0330: /* GeForceFX 5900 */ + case 0x0340: /* GeForceFX 5700 */ + pNv->Architecture = NV_ARCH_30; + break; + case 0x0040: + case 0x00C0: + case 0x0120: + case 0x0130: + case 0x0140: + case 0x0160: + case 0x01D0: + case 0x0090: + case 0x0210: + pNv->Architecture = NV_ARCH_40; + break; + default: + pNv->Architecture = NV_ARCH_04; + break; + } - if(pNv->Architecture < NV_ARCH_10) - pNv->Architecture = NV_ARCH_04; + pNv->alphaCursor = (pNv->Architecture >= NV_ARCH_10) && + ((pNv->Chipset & 0x0ff0) != 0x0100); NVCommonSetup(pScrn); @@ -1225,17 +1378,17 @@ NVPreInit(ScrnInfoPtr pScrn, int flags) clockRanges->minClock = pNv->MinVClockFreqKHz; clockRanges->maxClock = pNv->MaxVClockFreqKHz; clockRanges->clockIndex = -1; /* programmable */ - if(((pNv->Chipset & 0x0ff0) <= 0x0100) || - ((pNv->Chipset & 0x0ff0) == 0x0150) || - ((pNv->Chipset & 0x0ff0) >= 0x0300)) + clockRanges->doubleScanAllowed = TRUE; + if((pNv->Architecture == NV_ARCH_20) || + ((pNv->Architecture == NV_ARCH_10) && + ((pNv->Chipset & 0x0ff0) != 0x0100) && + ((pNv->Chipset & 0x0ff0) != 0x0150))) { - clockRanges->interlaceAllowed = TRUE; - } else { - /* No NV2x chips support interlaced modes and the only - NV1x chips that do are NV10 and NV15 */ + /* HW is broken */ clockRanges->interlaceAllowed = FALSE; + } else { + clockRanges->interlaceAllowed = TRUE; } - clockRanges->doubleScanAllowed = TRUE; if(pNv->FlatPanel == 1) { clockRanges->interlaceAllowed = FALSE; @@ -1488,22 +1641,28 @@ NVRestore(ScrnInfoPtr pScrn) NVPtr pNv = NVPTR(pScrn); NVRegPtr nvReg = &pNv->SavedReg; + NVLockUnlock(pNv, 0); + if(pNv->twoHeads) { VGA_WR08(pNv->PCIO, 0x03D4, 0x44); - VGA_WR08(pNv->PCIO, 0x03D5, nvReg->crtcOwner); + VGA_WR08(pNv->PCIO, 0x03D5, pNv->CRTCnumber * 0x3); NVLockUnlock(pNv, 0); } - NVLockUnlock(pNv, 0); - /* Only restore text mode fonts/text for the primary card */ vgaHWProtect(pScrn, TRUE); NVDACRestore(pScrn, vgaReg, nvReg, pNv->Primary); + if(pNv->twoHeads) { + VGA_WR08(pNv->PCIO, 0x03D4, 0x44); + VGA_WR08(pNv->PCIO, 0x03D5, nvReg->crtcOwner); + } vgaHWProtect(pScrn, FALSE); } static void NVBacklightEnable(NVPtr pNv, Bool on) { + CARD32 fpcontrol = pNv->PRAMDAC[0x0848/4] & 0xCfffffCC; + /* This is done differently on each laptop. Here we define the ones we know for sure. */ @@ -1524,6 +1683,12 @@ static void NVBacklightEnable(NVPtr pNv, Bool on) pNv->PCRTC0[0x081C/4] = tmp_pcrt; } #endif + + /* cut the TMDS output */ + if(on) fpcontrol |= pNv->fpSyncs; + else fpcontrol |= 0x20000022; + + pNv->PRAMDAC[0x0848/4] = fpcontrol; } static void @@ -1533,6 +1698,8 @@ NVDPMSSetLCD(ScrnInfoPtr pScrn, int PowerManagementMode, int flags) if (!pScrn->vtSema) return; + vgaHWDPMSSet(pScrn, PowerManagementMode, flags); + switch (PowerManagementMode) { case DPMSModeStandby: /* HSync: Off, VSync: On */ case DPMSModeSuspend: /* HSync: On, VSync: Off */ @@ -1544,7 +1711,6 @@ NVDPMSSetLCD(ScrnInfoPtr pScrn, int PowerManagementMode, int flags) default: break; } - vgaHWDPMSSet(pScrn, PowerManagementMode, flags); } @@ -1646,7 +1812,7 @@ NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) * function. If not, the visuals will need to be setup before calling * a fb ScreenInit() function and fixed up after. * - * For most PC hardware at depths >= 8, the defaults that cfb uses + * For most PC hardware at depths >= 8, the defaults that fb uses * are not appropriate. In this driver, we fixup the visuals after. */ @@ -1830,6 +1996,13 @@ NVSave(ScrnInfoPtr pScrn) vgaHWPtr pVga = VGAHWPTR(pScrn); vgaRegPtr vgaReg = &pVga->SavedReg; + NVLockUnlock(pNv, 0); + if(pNv->twoHeads) { + VGA_WR08(pNv->PCIO, 0x03D4, 0x44); + VGA_WR08(pNv->PCIO, 0x03D5, pNv->CRTCnumber * 0x3); + NVLockUnlock(pNv, 0); + } + NVDACSave(pScrn, vgaReg, nvReg, pNv->Primary); } diff --git a/src/nv_hw.c b/src/nv_hw.c index 67e3b5b..7499d97 100644 --- a/src/nv_hw.c +++ b/src/nv_hw.c @@ -36,7 +36,7 @@ |* those rights set forth herein. *| |* *| \***************************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_hw.c,v 1.4 2003/11/03 05:11:25 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_hw.c,v 1.13 2004/12/09 00:21:04 mvojkovi Exp $ */ #include "nv_local.h" #include "compiler.h" @@ -71,6 +71,12 @@ int NVShowHideCursor ( (ShowHide & 0x01); VGA_WR08(pNv->PCIO, 0x3D4, 0x31); VGA_WR08(pNv->PCIO, 0x3D5, pNv->CurrentState->cursor1); + + if(pNv->Architecture == NV_ARCH_40) { /* HW bug */ + volatile CARD32 curpos = pNv->PRAMDAC[0x0300/4]; + pNv->PRAMDAC[0x0300/4] = curpos; + } + return (current & 0x01); } @@ -132,6 +138,26 @@ static void nvGetClocks(NVPtr pNv, unsigned int *MClk, unsigned int *NVClk) { unsigned int pll, N, M, MB, NB, P; + if(pNv->Architecture >= NV_ARCH_40) { + pll = pNv->PMC[0x4020/4]; + P = (pll >> 16) & 0x03; + pll = pNv->PMC[0x4024/4]; + M = pll & 0xFF; + N = (pll >> 8) & 0xFF; + MB = (pll >> 16) & 0xFF; + NB = (pll >> 24) & 0xFF; + *MClk = ((N * NB * pNv->CrystalFreqKHz) / (M * MB)) >> P; + + pll = pNv->PMC[0x4000/4]; + P = (pll >> 16) & 0x03; + pll = pNv->PMC[0x4004/4]; + M = pll & 0xFF; + N = (pll >> 8) & 0xFF; + MB = (pll >> 16) & 0xFF; + NB = (pll >> 24) & 0xFF; + + *NVClk = ((N * NB * pNv->CrystalFreqKHz) / (M * MB)) >> P; + } else if(pNv->twoStagePLL) { pll = pNv->PRAMDAC0[0x0504/4]; M = pll & 0xFF; @@ -202,6 +228,10 @@ static void nvGetClocks(NVPtr pNv, unsigned int *MClk, unsigned int *NVClk) P = (pll >> 16) & 0x0F; *NVClk = (N * pNv->CrystalFreqKHz / M) >> P; } + +#if 0 + ErrorF("NVClock = %i MHz, MEMClock = %i MHz\n", *NVClk/1000, *MClk/1000); +#endif } @@ -509,21 +539,6 @@ static void nv10CalcArbitration ( clwm = us_crt * crtc_drain_rate/(1000*1000); clwm++; /* fixed point <= float_point - 1. Fixes that */ - /* - // - // Another concern, only for high pclks so don't do this - // with video: - // What happens if the latency to fetch the cbs is so large that - // fifo empties. In that case we need to have an alternate clwm value - // based off the total burst fetch - // - us_crt = (cbs * 1000 * 1000)/ (8*width)/mclk_freq ; - us_crt = us_crt + us_m + us_n + us_p + (4 * 1000 * 1000)/mclk_freq; - clwm_mt = us_crt * crtc_drain_rate/(1000*1000); - clwm_mt ++; - if(clwm_mt > clwm) - clwm = clwm_mt; - */ /* Finally, a heuristic check when width == 64 bits */ if(width == 1){ nvclk_fill = nvclk_freq * 8; @@ -622,6 +637,28 @@ static void nv10UpdateArbitrationSettings ( } } + +static void nv30UpdateArbitrationSettings ( + NVPtr pNv, + unsigned *burst, + unsigned *lwm +) +{ + unsigned int MClk, NVClk; + unsigned int fifo_size, burst_size, graphics_lwm; + + fifo_size = 2048; + burst_size = 512; + graphics_lwm = fifo_size - burst_size; + + nvGetClocks(pNv, &MClk, &NVClk); + + *burst = 0; + burst_size >>= 5; + while(burst_size >>= 1) (*burst)++; + *lwm = graphics_lwm >> 3; +} + static void nForceUpdateArbitrationSettings ( unsigned VClk, unsigned pixelDepth, @@ -632,12 +669,17 @@ static void nForceUpdateArbitrationSettings ( { nv10_fifo_info fifo_data; nv10_sim_state sim_data; - unsigned int M, N, P, pll, MClk, NVClk; - unsigned int uMClkPostDiv, memctrl; + unsigned int M, N, P, pll, MClk, NVClk, memctrl; + + if((pNv->Chipset & 0x0FF0) == 0x01A0) { + unsigned int uMClkPostDiv; - uMClkPostDiv = (pciReadLong(pciTag(0, 0, 3), 0x6C) >> 8) & 0xf; - if(!uMClkPostDiv) uMClkPostDiv = 4; - MClk = 400000 / uMClkPostDiv; + uMClkPostDiv = (pciReadLong(pciTag(0, 0, 3), 0x6C) >> 8) & 0xf; + if(!uMClkPostDiv) uMClkPostDiv = 4; + MClk = 400000 / uMClkPostDiv; + } else { + MClk = pciReadLong(pciTag(0, 0, 5), 0x4C) / 1000; + } pll = pNv->PRAMDAC0[0x0500/4]; M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F; @@ -837,12 +879,16 @@ void NVCalcStateExt ( &(state->arbitration0), &(state->arbitration1), pNv); - } else { + } else if(pNv->Architecture < NV_ARCH_30) { nv10UpdateArbitrationSettings(VClk, pixelDepth * 8, &(state->arbitration0), &(state->arbitration1), pNv); + } else { + nv30UpdateArbitrationSettings(pNv, + &(state->arbitration0), + &(state->arbitration1)); } state->cursor0 = 0x80 | (pNv->CursorStart >> 17); state->cursor1 = (pNv->CursorStart >> 11) << 2; @@ -901,79 +947,167 @@ void NVLoadStateExt ( pNv->PFB[0x02B4/4] = pNv->FbMapSize - 1; } - pNv->PRAMIN[0x0000] = 0x80000010; - pNv->PRAMIN[0x0001] = 0x80011201; - pNv->PRAMIN[0x0002] = 0x80000011; - pNv->PRAMIN[0x0003] = 0x80011202; - pNv->PRAMIN[0x0004] = 0x80000012; - pNv->PRAMIN[0x0005] = 0x80011203; - pNv->PRAMIN[0x0006] = 0x80000013; - pNv->PRAMIN[0x0007] = 0x80011204; - pNv->PRAMIN[0x0008] = 0x80000014; - pNv->PRAMIN[0x0009] = 0x80011205; - pNv->PRAMIN[0x000A] = 0x80000015; - pNv->PRAMIN[0x000B] = 0x80011206; - pNv->PRAMIN[0x000C] = 0x80000016; - pNv->PRAMIN[0x000D] = 0x80011207; - pNv->PRAMIN[0x000E] = 0x80000017; - pNv->PRAMIN[0x000F] = 0x80011208; - pNv->PRAMIN[0x0800] = 0x00003000; - pNv->PRAMIN[0x0801] = pNv->FbMapSize - 1; - pNv->PRAMIN[0x0802] = 0x00000002; - pNv->PRAMIN[0x0803] = 0x00000002; - if(pNv->Architecture >= NV_ARCH_10) - pNv->PRAMIN[0x0804] = 0x01008062; - else - pNv->PRAMIN[0x0804] = 0x01008042; - pNv->PRAMIN[0x0805] = 0x00000000; - pNv->PRAMIN[0x0806] = 0x12001200; - pNv->PRAMIN[0x0807] = 0x00000000; - pNv->PRAMIN[0x0808] = 0x01008043; - pNv->PRAMIN[0x0809] = 0x00000000; - pNv->PRAMIN[0x080A] = 0x00000000; - pNv->PRAMIN[0x080B] = 0x00000000; - pNv->PRAMIN[0x080C] = 0x01008044; - pNv->PRAMIN[0x080D] = 0x00000002; - pNv->PRAMIN[0x080E] = 0x00000000; - pNv->PRAMIN[0x080F] = 0x00000000; - pNv->PRAMIN[0x0810] = 0x01008019; - pNv->PRAMIN[0x0811] = 0x00000000; - pNv->PRAMIN[0x0812] = 0x00000000; - pNv->PRAMIN[0x0813] = 0x00000000; - pNv->PRAMIN[0x0814] = 0x0100A05C; - pNv->PRAMIN[0x0815] = 0x00000000; - pNv->PRAMIN[0x0816] = 0x00000000; - pNv->PRAMIN[0x0817] = 0x00000000; - pNv->PRAMIN[0x0818] = 0x0100805F; - pNv->PRAMIN[0x0819] = 0x00000000; - pNv->PRAMIN[0x081A] = 0x12001200; - pNv->PRAMIN[0x081B] = 0x00000000; - pNv->PRAMIN[0x081C] = 0x0100804A; - pNv->PRAMIN[0x081D] = 0x00000002; - pNv->PRAMIN[0x081E] = 0x00000000; - pNv->PRAMIN[0x081F] = 0x00000000; - pNv->PRAMIN[0x0820] = 0x01018077; - pNv->PRAMIN[0x0821] = 0x00000000; - pNv->PRAMIN[0x0822] = 0x01201200; - pNv->PRAMIN[0x0823] = 0x00000000; - pNv->PRAMIN[0x0824] = 0x00003002; - pNv->PRAMIN[0x0825] = 0x00007FFF; - pNv->PRAMIN[0x0826] = pNv->FbUsableSize | 0x00000002; - pNv->PRAMIN[0x0827] = 0x00000002; + if(pNv->Architecture >= NV_ARCH_40) { + pNv->PRAMIN[0x0000] = 0x80000010; + pNv->PRAMIN[0x0001] = 0x00101202; + pNv->PRAMIN[0x0002] = 0x80000011; + pNv->PRAMIN[0x0003] = 0x00101204; + pNv->PRAMIN[0x0004] = 0x80000012; + pNv->PRAMIN[0x0005] = 0x00101206; + pNv->PRAMIN[0x0006] = 0x80000013; + pNv->PRAMIN[0x0007] = 0x00101208; + pNv->PRAMIN[0x0008] = 0x80000014; + pNv->PRAMIN[0x0009] = 0x0010120A; + pNv->PRAMIN[0x000A] = 0x80000015; + pNv->PRAMIN[0x000B] = 0x0010120C; + pNv->PRAMIN[0x000C] = 0x80000016; + pNv->PRAMIN[0x000D] = 0x0010120E; + pNv->PRAMIN[0x000E] = 0x80000017; + pNv->PRAMIN[0x000F] = 0x00101210; + pNv->PRAMIN[0x0800] = 0x00003000; + pNv->PRAMIN[0x0801] = pNv->FbMapSize - 1; + pNv->PRAMIN[0x0802] = 0x00000002; + pNv->PRAMIN[0x0808] = 0x02080062; + pNv->PRAMIN[0x0809] = 0x00000000; + pNv->PRAMIN[0x080A] = 0x00001200; + pNv->PRAMIN[0x080B] = 0x00001200; + pNv->PRAMIN[0x080C] = 0x00000000; + pNv->PRAMIN[0x080D] = 0x00000000; + pNv->PRAMIN[0x0810] = 0x02080043; + pNv->PRAMIN[0x0811] = 0x00000000; + pNv->PRAMIN[0x0812] = 0x00000000; + pNv->PRAMIN[0x0813] = 0x00000000; + pNv->PRAMIN[0x0814] = 0x00000000; + pNv->PRAMIN[0x0815] = 0x00000000; + pNv->PRAMIN[0x0818] = 0x02080044; + pNv->PRAMIN[0x0819] = 0x02000000; + pNv->PRAMIN[0x081A] = 0x00000000; + pNv->PRAMIN[0x081B] = 0x00000000; + pNv->PRAMIN[0x081C] = 0x00000000; + pNv->PRAMIN[0x081D] = 0x00000000; + pNv->PRAMIN[0x0820] = 0x02080019; + pNv->PRAMIN[0x0821] = 0x00000000; + pNv->PRAMIN[0x0822] = 0x00000000; + pNv->PRAMIN[0x0823] = 0x00000000; + pNv->PRAMIN[0x0824] = 0x00000000; + pNv->PRAMIN[0x0825] = 0x00000000; + pNv->PRAMIN[0x0828] = 0x020A005C; + pNv->PRAMIN[0x0829] = 0x00000000; + pNv->PRAMIN[0x082A] = 0x00000000; + pNv->PRAMIN[0x082B] = 0x00000000; + pNv->PRAMIN[0x082C] = 0x00000000; + pNv->PRAMIN[0x082D] = 0x00000000; + pNv->PRAMIN[0x0830] = 0x0208009F; + pNv->PRAMIN[0x0831] = 0x00000000; + pNv->PRAMIN[0x0832] = 0x00001200; + pNv->PRAMIN[0x0833] = 0x00001200; + pNv->PRAMIN[0x0834] = 0x00000000; + pNv->PRAMIN[0x0835] = 0x00000000; + pNv->PRAMIN[0x0838] = 0x0208004A; + pNv->PRAMIN[0x0839] = 0x02000000; + pNv->PRAMIN[0x083A] = 0x00000000; + pNv->PRAMIN[0x083B] = 0x00000000; + pNv->PRAMIN[0x083C] = 0x00000000; + pNv->PRAMIN[0x083D] = 0x00000000; + pNv->PRAMIN[0x0840] = 0x02080077; + pNv->PRAMIN[0x0841] = 0x00000000; + pNv->PRAMIN[0x0842] = 0x00001200; + pNv->PRAMIN[0x0843] = 0x00001200; + pNv->PRAMIN[0x0844] = 0x00000000; + pNv->PRAMIN[0x0845] = 0x00000000; + pNv->PRAMIN[0x084C] = 0x00003002; + pNv->PRAMIN[0x084D] = 0x00007FFF; + pNv->PRAMIN[0x084E] = pNv->FbUsableSize | 0x00000002; + +#if X_BYTE_ORDER == X_BIG_ENDIAN + pNv->PRAMIN[0x080A] |= 0x01000000; + pNv->PRAMIN[0x0812] |= 0x01000000; + pNv->PRAMIN[0x081A] |= 0x01000000; + pNv->PRAMIN[0x0822] |= 0x01000000; + pNv->PRAMIN[0x082A] |= 0x01000000; + pNv->PRAMIN[0x0832] |= 0x01000000; + pNv->PRAMIN[0x083A] |= 0x01000000; + pNv->PRAMIN[0x0842] |= 0x01000000; + pNv->PRAMIN[0x0819] = 0x01000000; + pNv->PRAMIN[0x0839] = 0x01000000; +#endif + } else { + pNv->PRAMIN[0x0000] = 0x80000010; + pNv->PRAMIN[0x0001] = 0x80011201; + pNv->PRAMIN[0x0002] = 0x80000011; + pNv->PRAMIN[0x0003] = 0x80011202; + pNv->PRAMIN[0x0004] = 0x80000012; + pNv->PRAMIN[0x0005] = 0x80011203; + pNv->PRAMIN[0x0006] = 0x80000013; + pNv->PRAMIN[0x0007] = 0x80011204; + pNv->PRAMIN[0x0008] = 0x80000014; + pNv->PRAMIN[0x0009] = 0x80011205; + pNv->PRAMIN[0x000A] = 0x80000015; + pNv->PRAMIN[0x000B] = 0x80011206; + pNv->PRAMIN[0x000C] = 0x80000016; + pNv->PRAMIN[0x000D] = 0x80011207; + pNv->PRAMIN[0x000E] = 0x80000017; + pNv->PRAMIN[0x000F] = 0x80011208; + pNv->PRAMIN[0x0800] = 0x00003000; + pNv->PRAMIN[0x0801] = pNv->FbMapSize - 1; + pNv->PRAMIN[0x0802] = 0x00000002; + pNv->PRAMIN[0x0803] = 0x00000002; + if(pNv->Architecture >= NV_ARCH_10) + pNv->PRAMIN[0x0804] = 0x01008062; + else + pNv->PRAMIN[0x0804] = 0x01008042; + pNv->PRAMIN[0x0805] = 0x00000000; + pNv->PRAMIN[0x0806] = 0x12001200; + pNv->PRAMIN[0x0807] = 0x00000000; + pNv->PRAMIN[0x0808] = 0x01008043; + pNv->PRAMIN[0x0809] = 0x00000000; + pNv->PRAMIN[0x080A] = 0x00000000; + pNv->PRAMIN[0x080B] = 0x00000000; + pNv->PRAMIN[0x080C] = 0x01008044; + pNv->PRAMIN[0x080D] = 0x00000002; + pNv->PRAMIN[0x080E] = 0x00000000; + pNv->PRAMIN[0x080F] = 0x00000000; + pNv->PRAMIN[0x0810] = 0x01008019; + pNv->PRAMIN[0x0811] = 0x00000000; + pNv->PRAMIN[0x0812] = 0x00000000; + pNv->PRAMIN[0x0813] = 0x00000000; + pNv->PRAMIN[0x0814] = 0x0100A05C; + pNv->PRAMIN[0x0815] = 0x00000000; + pNv->PRAMIN[0x0816] = 0x00000000; + pNv->PRAMIN[0x0817] = 0x00000000; + if(pNv->WaitVSyncPossible) + pNv->PRAMIN[0x0818] = 0x0100809F; + else + pNv->PRAMIN[0x0818] = 0x0100805F; + pNv->PRAMIN[0x0819] = 0x00000000; + pNv->PRAMIN[0x081A] = 0x12001200; + pNv->PRAMIN[0x081B] = 0x00000000; + pNv->PRAMIN[0x081C] = 0x0100804A; + pNv->PRAMIN[0x081D] = 0x00000002; + pNv->PRAMIN[0x081E] = 0x00000000; + pNv->PRAMIN[0x081F] = 0x00000000; + pNv->PRAMIN[0x0820] = 0x01018077; + pNv->PRAMIN[0x0821] = 0x00000000; + pNv->PRAMIN[0x0822] = 0x12001200; + pNv->PRAMIN[0x0823] = 0x00000000; + pNv->PRAMIN[0x0824] = 0x00003002; + pNv->PRAMIN[0x0825] = 0x00007FFF; + pNv->PRAMIN[0x0826] = pNv->FbUsableSize | 0x00000002; + pNv->PRAMIN[0x0827] = 0x00000002; #if X_BYTE_ORDER == X_BIG_ENDIAN - pNv->PRAMIN[0x0804] |= 0x00080000; - pNv->PRAMIN[0x0808] |= 0x00080000; - pNv->PRAMIN[0x080C] |= 0x00080000; - pNv->PRAMIN[0x0810] |= 0x00080000; - pNv->PRAMIN[0x0814] |= 0x00080000; - pNv->PRAMIN[0x0818] |= 0x00080000; - pNv->PRAMIN[0x081C] |= 0x00080000; - pNv->PRAMIN[0x0820] |= 0x00080000; - - pNv->PRAMIN[0x080D] = 0x00000001; - pNv->PRAMIN[0x081D] = 0x00000001; + pNv->PRAMIN[0x0804] |= 0x00080000; + pNv->PRAMIN[0x0808] |= 0x00080000; + pNv->PRAMIN[0x080C] |= 0x00080000; + pNv->PRAMIN[0x0810] |= 0x00080000; + pNv->PRAMIN[0x0814] |= 0x00080000; + pNv->PRAMIN[0x0818] |= 0x00080000; + pNv->PRAMIN[0x081C] |= 0x00080000; + pNv->PRAMIN[0x0820] |= 0x00080000; + pNv->PRAMIN[0x080D] = 0x00000001; + pNv->PRAMIN[0x081D] = 0x00000001; #endif + } if(pNv->Architecture < NV_ARCH_10) { if((pNv->Chipset & 0x0fff) == 0x0020) { @@ -985,6 +1119,7 @@ void NVLoadStateExt ( pNv->PGRAPH[0x0084/4] = 0x72111101; pNv->PGRAPH[0x0088/4] = 0x11D5F071; pNv->PGRAPH[0x008C/4] = 0x0004FF31; + pNv->PGRAPH[0x008C/4] = 0x4004FF31; pNv->PGRAPH[0x0140/4] = 0x00000000; pNv->PGRAPH[0x0100/4] = 0xFFFFFFFF; @@ -993,6 +1128,7 @@ void NVLoadStateExt ( pNv->PGRAPH[0x0720/4] = 0x00000001; pNv->PGRAPH[0x0810/4] = 0x00000000; + pNv->PGRAPH[0x0608/4] = 0xFFFFFFFF; } else { pNv->PGRAPH[0x0080/4] = 0xFFFFFFFF; pNv->PGRAPH[0x0080/4] = 0x00000000; @@ -1002,6 +1138,8 @@ void NVLoadStateExt ( pNv->PGRAPH[0x0144/4] = 0x10010100; pNv->PGRAPH[0x0714/4] = 0xFFFFFFFF; pNv->PGRAPH[0x0720/4] = 0x00000001; + pNv->PGRAPH[0x0710/4] &= 0x0007ff00; + pNv->PGRAPH[0x0710/4] |= 0x00020100; if(pNv->Architecture == NV_ARCH_10) { pNv->PGRAPH[0x0084/4] = 0x00118700; @@ -1017,8 +1155,55 @@ void NVLoadStateExt ( pNv->PGRAPH[0x688/4] = pNv->FbMapSize - 1; pNv->PGRAPH[0x0810/4] = 0x00000000; + pNv->PGRAPH[0x0608/4] = 0xFFFFFFFF; } else { - if(pNv->Architecture >= NV_ARCH_30) { + if(pNv->Architecture >= NV_ARCH_40) { + pNv->PGRAPH[0x0084/4] = 0x401287c0; + pNv->PGRAPH[0x008C/4] = 0x60de8051; + pNv->PGRAPH[0x0090/4] = 0x00008000; + pNv->PGRAPH[0x0610/4] = 0x00be3c5f; + + if((pNv->Chipset & 0xfff0) == 0x0040) { + pNv->PGRAPH[0x09b0/4] = 0x83280fff; + pNv->PGRAPH[0x09b4/4] = 0x000000a0; + } else { + pNv->PGRAPH[0x0820/4] = 0x83280eff; + pNv->PGRAPH[0x0824/4] = 0x000000a0; + } + + switch(pNv->Chipset & 0xfff0) { + case 0x0040: + pNv->PGRAPH[0x09b8/4] = 0x0078e366; + pNv->PGRAPH[0x09bc/4] = 0x0000014c; + pNv->PFB[0x033C/4] &= 0xffff7fff; + break; + case 0x00C0: + pNv->PGRAPH[0x0828/4] = 0x007596ff; + pNv->PGRAPH[0x082C/4] = 0x00000108; + break; + case 0x0160: + pNv->PMC[0x1700/4] = pNv->PFB[0x020C/4]; + pNv->PMC[0x1704/4] = 0; + pNv->PMC[0x1708/4] = 0; + pNv->PMC[0x170C/4] = pNv->PFB[0x020C/4]; + pNv->PGRAPH[0x0860/4] = 0; + pNv->PGRAPH[0x0864/4] = 0; + pNv->PRAMDAC[0x0608/4] |= 0x00100000; + break; + case 0x0140: + pNv->PGRAPH[0x0828/4] = 0x0072cb77; + pNv->PGRAPH[0x082C/4] = 0x00000108; + break; + default: + break; + }; + + pNv->PGRAPH[0x0b38/4] = 0x2ffff800; + pNv->PGRAPH[0x0b3c/4] = 0x00006000; + pNv->PGRAPH[0x032C/4] = 0x01000000; + pNv->PGRAPH[0x0220/4] = 0x00001200; + } else + if(pNv->Architecture == NV_ARCH_30) { pNv->PGRAPH[0x0084/4] = 0x40108700; pNv->PGRAPH[0x0890/4] = 0x00140000; pNv->PGRAPH[0x008C/4] = 0xf00e0431; @@ -1055,19 +1240,44 @@ void NVLoadStateExt ( for(i = 0; i < 32; i++) pNv->PGRAPH[(0x0900/4) + i] = pNv->PFB[(0x0240/4) + i]; - pNv->PGRAPH[0x09A4/4] = pNv->PFB[0x0200/4]; - pNv->PGRAPH[0x09A8/4] = pNv->PFB[0x0204/4]; - pNv->PGRAPH[0x0750/4] = 0x00EA0000; - pNv->PGRAPH[0x0754/4] = pNv->PFB[0x0200/4]; - pNv->PGRAPH[0x0750/4] = 0x00EA0004; - pNv->PGRAPH[0x0754/4] = pNv->PFB[0x0204/4]; - - pNv->PGRAPH[0x0820/4] = 0; - pNv->PGRAPH[0x0824/4] = 0; - pNv->PGRAPH[0x0864/4] = pNv->FbMapSize - 1; - pNv->PGRAPH[0x0868/4] = pNv->FbMapSize - 1; + if(pNv->Architecture >= NV_ARCH_40) { + if((pNv->Chipset & 0xfff0) == 0x0040) { + pNv->PGRAPH[0x09A4/4] = pNv->PFB[0x0200/4]; + pNv->PGRAPH[0x09A8/4] = pNv->PFB[0x0204/4]; + pNv->PGRAPH[0x69A4/4] = pNv->PFB[0x0200/4]; + pNv->PGRAPH[0x69A8/4] = pNv->PFB[0x0204/4]; + + pNv->PGRAPH[0x0820/4] = 0; + pNv->PGRAPH[0x0824/4] = 0; + pNv->PGRAPH[0x0864/4] = pNv->FbMapSize - 1; + pNv->PGRAPH[0x0868/4] = pNv->FbMapSize - 1; + } else { + pNv->PGRAPH[0x09F0/4] = pNv->PFB[0x0200/4]; + pNv->PGRAPH[0x09F4/4] = pNv->PFB[0x0204/4]; + pNv->PGRAPH[0x69F0/4] = pNv->PFB[0x0200/4]; + pNv->PGRAPH[0x69F4/4] = pNv->PFB[0x0204/4]; + + pNv->PGRAPH[0x0840/4] = 0; + pNv->PGRAPH[0x0844/4] = 0; + pNv->PGRAPH[0x08a0/4] = pNv->FbMapSize - 1; + pNv->PGRAPH[0x08a4/4] = pNv->FbMapSize - 1; + } + } else { + pNv->PGRAPH[0x09A4/4] = pNv->PFB[0x0200/4]; + pNv->PGRAPH[0x09A8/4] = pNv->PFB[0x0204/4]; + pNv->PGRAPH[0x0750/4] = 0x00EA0000; + pNv->PGRAPH[0x0754/4] = pNv->PFB[0x0200/4]; + pNv->PGRAPH[0x0750/4] = 0x00EA0004; + pNv->PGRAPH[0x0754/4] = pNv->PFB[0x0204/4]; + + pNv->PGRAPH[0x0820/4] = 0; + pNv->PGRAPH[0x0824/4] = 0; + pNv->PGRAPH[0x0864/4] = pNv->FbMapSize - 1; + pNv->PGRAPH[0x0868/4] = pNv->FbMapSize - 1; + } pNv->PGRAPH[0x0B20/4] = 0x00000000; + pNv->PGRAPH[0x0B04/4] = 0xFFFFFFFF; } } pNv->PGRAPH[0x053C/4] = 0; @@ -1079,10 +1289,16 @@ void NVLoadStateExt ( pNv->PFIFO[0x0141] = 0x00000001; pNv->PFIFO[0x0480] = 0x00000000; pNv->PFIFO[0x0494] = 0x00000000; - pNv->PFIFO[0x0481] = 0x00000100; + if(pNv->Architecture >= NV_ARCH_40) + pNv->PFIFO[0x0481] = 0x00010000; + else + pNv->PFIFO[0x0481] = 0x00000100; pNv->PFIFO[0x0490] = 0x00000000; pNv->PFIFO[0x0491] = 0x00000000; - pNv->PFIFO[0x048B] = 0x00001209; + if(pNv->Architecture >= NV_ARCH_40) + pNv->PFIFO[0x048B] = 0x00001213; + else + pNv->PFIFO[0x048B] = 0x00001209; pNv->PFIFO[0x0400] = 0x00000000; pNv->PFIFO[0x0414] = 0x00000000; pNv->PFIFO[0x0084] = 0x03000100; @@ -1122,12 +1338,14 @@ void NVLoadStateExt ( pNv->PMC[0x1588/4] = 0; pNv->PCRTC[0x0810/4] = state->cursorConfig; + pNv->PCRTC[0x0830/4] = state->displayV - 3; + pNv->PCRTC[0x0834/4] = state->displayV - 1; if(pNv->FlatPanel) { if((pNv->Chipset & 0x0ff0) == 0x0110) { pNv->PRAMDAC[0x0528/4] = state->dither; } else - if((pNv->Chipset & 0x0ff0) >= 0x0170) { + if(pNv->twoHeads) { pNv->PRAMDAC[0x083C/4] = state->dither; } @@ -1153,10 +1371,16 @@ void NVLoadStateExt ( VGA_WR08(pNv->PCIO, 0x03D5, state->pixel); VGA_WR08(pNv->PCIO, 0x03D4, 0x2D); VGA_WR08(pNv->PCIO, 0x03D5, state->horiz); + VGA_WR08(pNv->PCIO, 0x03D4, 0x1C); + VGA_WR08(pNv->PCIO, 0x03D5, state->fifo); VGA_WR08(pNv->PCIO, 0x03D4, 0x1B); VGA_WR08(pNv->PCIO, 0x03D5, state->arbitration0); VGA_WR08(pNv->PCIO, 0x03D4, 0x20); VGA_WR08(pNv->PCIO, 0x03D5, state->arbitration1); + if(pNv->Architecture >= NV_ARCH_30) { + VGA_WR08(pNv->PCIO, 0x03D4, 0x47); + VGA_WR08(pNv->PCIO, 0x03D5, state->arbitration1 >> 8); + } VGA_WR08(pNv->PCIO, 0x03D4, 0x30); VGA_WR08(pNv->PCIO, 0x03D5, state->cursor0); VGA_WR08(pNv->PCIO, 0x03D4, 0x31); @@ -1177,6 +1401,7 @@ void NVLoadStateExt ( } } else { pNv->PRAMDAC[0x0848/4] = state->scale; + pNv->PRAMDAC[0x0828/4] = state->crtcSync; } pNv->PRAMDAC[0x0600/4] = state->general; @@ -1202,10 +1427,16 @@ void NVUnloadStateExt state->pixel = VGA_RD08(pNv->PCIO, 0x03D5); VGA_WR08(pNv->PCIO, 0x03D4, 0x2D); state->horiz = VGA_RD08(pNv->PCIO, 0x03D5); + VGA_WR08(pNv->PCIO, 0x03D4, 0x1C); + state->fifo = VGA_RD08(pNv->PCIO, 0x03D5); VGA_WR08(pNv->PCIO, 0x03D4, 0x1B); state->arbitration0 = VGA_RD08(pNv->PCIO, 0x03D5); VGA_WR08(pNv->PCIO, 0x03D4, 0x20); state->arbitration1 = VGA_RD08(pNv->PCIO, 0x03D5); + if(pNv->Architecture >= NV_ARCH_30) { + VGA_WR08(pNv->PCIO, 0x03D4, 0x47); + state->arbitration1 |= (VGA_RD08(pNv->PCIO, 0x03D5) & 1) << 8; + } VGA_WR08(pNv->PCIO, 0x03D4, 0x30); state->cursor0 = VGA_RD08(pNv->PCIO, 0x03D5); VGA_WR08(pNv->PCIO, 0x03D4, 0x31); @@ -1240,7 +1471,7 @@ void NVUnloadStateExt if((pNv->Chipset & 0x0ff0) == 0x0110) { state->dither = pNv->PRAMDAC[0x0528/4]; } else - if((pNv->Chipset & 0x0ff0) >= 0x0170) { + if(pNv->twoHeads) { state->dither = pNv->PRAMDAC[0x083C/4]; } @@ -1251,6 +1482,10 @@ void NVUnloadStateExt state->timingV = VGA_RD08(pNv->PCIO, 0x03D5); } } + + if(pNv->FlatPanel) { + state->crtcSync = pNv->PRAMDAC[0x0828/4]; + } } void NVSetStartAddress ( diff --git a/src/nv_proto.h b/src/nv_proto.h index a074346..5905309 100644 --- a/src/nv_proto.h +++ b/src/nv_proto.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_proto.h,v 1.9 2003/05/04 01:20:52 mvojkovi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_proto.h,v 1.11 2004/03/20 01:52:16 mvojkovi Exp $ */ #ifndef __NV_PROTO_H__ #define __NV_PROTO_H__ @@ -37,6 +37,7 @@ void NVSync(ScrnInfoPtr pScrn); void NVResetGraphics(ScrnInfoPtr pScrn); void NVDmaKickoff(NVPtr pNv); void NVDmaWait(NVPtr pNv, int size); +void NVWaitVSync(NVPtr pNv); /* in nv_dga.c */ Bool NVDGAInit(ScreenPtr pScreen); diff --git a/src/nv_setup.c b/src/nv_setup.c index e399904..95bb42f 100644 --- a/src/nv_setup.c +++ b/src/nv_setup.c @@ -37,7 +37,7 @@ |* *| \***************************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_setup.c,v 1.39 2003/11/07 23:56:28 mvojkovi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_setup.c,v 1.44 2004/12/09 00:21:05 mvojkovi Exp $ */ #include "nv_include.h" @@ -292,10 +292,10 @@ static void nv10GetConfig (NVPtr pNv) } #endif - if((pNv->Chipset & 0xffff) == 0x01a0) { + if(implementation == 0x01a0) { int amt = pciReadLong(pciTag(0, 0, 1), 0x7C); pNv->RamAmountKBytes = (((amt >> 6) & 31) + 1) * 1024; - } else if((pNv->Chipset & 0xffff) == 0x01f0) { + } else if(implementation == 0x01f0) { int amt = pciReadLong(pciTag(0, 0, 1), 0x84); pNv->RamAmountKBytes = (((amt >> 4) & 127) + 1) * 1024; } else { @@ -304,10 +304,7 @@ static void nv10GetConfig (NVPtr pNv) pNv->CrystalFreqKHz = (pNv->PEXTDEV[0x0000/4] & (1 << 6)) ? 14318 : 13500; - if((implementation == 0x0170) || - (implementation == 0x0180) || - (implementation == 0x01F0) || - (implementation >= 0x0250)) + if(pNv->twoHeads && (implementation != 0x0110)) { if(pNv->PEXTDEV[0x0000/4] & (1 << 22)) pNv->CrystalFreqKHz = 27000; @@ -381,15 +378,22 @@ NVCommonSetup(ScrnInfoPtr pScrn) pNv->PDIO0 = (U008*)pNv->REGS + 0x00681000; pNv->PVIO = (U008*)pNv->REGS + 0x000C0000; - pNv->twoHeads = (implementation >= 0x0110) && + pNv->twoHeads = (pNv->Architecture >= NV_ARCH_10) && + (implementation != 0x0100) && (implementation != 0x0150) && (implementation != 0x01A0) && (implementation != 0x0200); - pNv->fpScaler = (pNv->twoHeads && (implementation != 0x0110)); + pNv->fpScaler = (pNv->FpScale && pNv->twoHeads && (implementation!=0x0110)); pNv->twoStagePLL = (implementation == 0x0310) || - (implementation == 0x0340); + (implementation == 0x0340) || + (pNv->Architecture >= NV_ARCH_40); + + pNv->WaitVSyncPossible = (pNv->Architecture >= NV_ARCH_10) && + (implementation != 0x0100); + + pNv->BlendingPossible = ((pNv->Chipset & 0xffff) != 0x0020); /* look for known laptop chips */ switch(pNv->Chipset & 0xffff) { @@ -403,7 +407,7 @@ NVCommonSetup(ScrnInfoPtr pScrn) case 0x017D: case 0x0186: case 0x0187: - case 0x0189: + case 0x018D: case 0x0286: case 0x028C: case 0x0316: @@ -425,6 +429,13 @@ NVCommonSetup(ScrnInfoPtr pScrn) case 0x0349: case 0x034B: case 0x034C: + case 0x0160: + case 0x0166: + case 0x00C8: + case 0x00CC: + case 0x0144: + case 0x0146: + case 0x0148: mobile = TRUE; break; default: @@ -659,6 +670,7 @@ NVCommonSetup(ScrnInfoPtr pScrn) if(pNv->FlatPanel && !pNv->Television) { pNv->fpWidth = pNv->PRAMDAC[0x0820/4] + 1; pNv->fpHeight = pNv->PRAMDAC[0x0800/4] + 1; + pNv->fpSyncs = pNv->PRAMDAC[0x0848/4] & 0x30000033; xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Panel size is %i x %i\n", pNv->fpWidth, pNv->fpHeight); } @@ -666,7 +678,7 @@ NVCommonSetup(ScrnInfoPtr pScrn) if(monitorA) xf86SetDDCproperties(pScrn, monitorA); - if(!pNv->FlatPanel || (pScrn->depth != 24)) + if(!pNv->FlatPanel || (pScrn->depth != 24) || !pNv->twoHeads) pNv->FPDither = FALSE; } diff --git a/src/nv_type.h b/src/nv_type.h index 5cae38d..690366e 100644 --- a/src/nv_type.h +++ b/src/nv_type.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_type.h,v 1.44 2003/09/08 20:00:27 mvojkovi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_type.h,v 1.50 2004/12/09 00:21:05 mvojkovi Exp $ */ #ifndef __NV_STRUCT_H__ #define __NV_STRUCT_H__ @@ -13,6 +13,7 @@ #define NV_ARCH_10 0x10 #define NV_ARCH_20 0x20 #define NV_ARCH_30 0x30 +#define NV_ARCH_40 0x40 #define BITMASK(t,b) (((unsigned)(1U << (((t)-(b)+1)))-1) << (b)) @@ -43,6 +44,7 @@ typedef struct _riva_hw_state U032 scale; U032 dither; U032 extra; + U032 fifo; U032 pixel; U032 horiz; U032 arbitration0; @@ -65,6 +67,8 @@ typedef struct _riva_hw_state U032 cursor2; U032 timingH; U032 timingV; + U032 displayV; + U032 crtcSync; } RIVA_HW_STATE, *NVRegPtr; @@ -90,6 +94,7 @@ typedef struct { CARD32 ScratchBufferStart; Bool NoAccel; Bool HWCursor; + Bool FpScale; Bool ShadowFB; unsigned char * ShadowPtr; int ShadowPitch; @@ -153,6 +158,9 @@ typedef struct { Bool fpScaler; int fpWidth; int fpHeight; + CARD32 fpSyncs; + Bool usePanelTweak; + int PanelTweak; CARD32 dmaPut; CARD32 dmaCurrent; @@ -161,6 +169,8 @@ typedef struct { CARD32 *dmaBase; CARD32 currentRop; + Bool WaitVSyncPossible; + Bool BlendingPossible; } NVRec, *NVPtr; #define NVPTR(p) ((NVPtr)((p)->driverPrivate)) diff --git a/src/nv_video.c b/src/nv_video.c index 66f49c0..7bfa94b 100644 --- a/src/nv_video.c +++ b/src/nv_video.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_video.c,v 1.20tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_video.c,v 1.23 2004/03/20 22:07:06 mvojkovi Exp $ */ #include "xf86.h" #include "xf86_OSproc.h" @@ -46,6 +46,7 @@ typedef struct _NVPortPrivRec { Bool grabbedByV4L; Bool iturbt_709; Bool blitter; + Bool SyncToVBlank; FBLinearPtr linear; int pitch; int offset; @@ -95,7 +96,7 @@ static void NVInitOffscreenImages (ScreenPtr pScreen); static Atom xvBrightness, xvContrast, xvColorKey, xvSaturation, xvHue, xvAutopaintColorKey, xvSetDefaults, xvDoubleBuffer, - xvITURBT709; + xvITURBT709, xvSyncToVBlank; /* client libraries expect an encoding */ static XF86VideoEncodingRec DummyEncoding = @@ -114,9 +115,8 @@ XF86VideoFormatRec NVFormats[NUM_FORMATS_ALL] = {15, DirectColor}, {16, DirectColor}, {24, DirectColor} }; -#define NUM_ATTRIBUTES 9 - -XF86AttributeRec NVAttributes[NUM_ATTRIBUTES] = +#define NUM_OVERLAY_ATTRIBUTES 9 +XF86AttributeRec NVOverlayAttributes[NUM_OVERLAY_ATTRIBUTES] = { {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"}, {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, @@ -129,6 +129,14 @@ XF86AttributeRec NVAttributes[NUM_ATTRIBUTES] = {XvSettable | XvGettable, 0, 1, "XV_ITURBT_709"} }; +#define NUM_BLIT_ATTRIBUTES 2 +XF86AttributeRec NVBlitAttributes[NUM_BLIT_ATTRIBUTES] = +{ + {XvSettable , 0, 0, "XV_SET_DEFAULTS"}, + {XvSettable | XvGettable, 0, 1, "XV_SYNC_TO_VBLANK"} +}; + + #define NUM_IMAGES_YUV 4 #define NUM_IMAGES_ALL 5 @@ -285,7 +293,10 @@ void NVInitVideo (ScreenPtr pScreen) NVPtr pNv = NVPTR(pScrn); int num_adaptors; - if((pScrn->bitsPerPixel != 8) && (pNv->Architecture >= NV_ARCH_10)) { + if((pScrn->bitsPerPixel != 8) && (pNv->Architecture >= NV_ARCH_10) && + ((pNv->Architecture <= NV_ARCH_30) || + ((pNv->Chipset & 0xfff0) == 0x0040))) + { overlayAdaptor = NVSetupOverlayVideo(pScreen); if(overlayAdaptor) @@ -358,8 +369,13 @@ NVSetupBlitVideo (ScreenPtr pScreen) for(i = 0; i < NUM_BLIT_PORTS; i++) adapt->pPortPrivates[i].ptr = (pointer)(pPriv); - adapt->pAttributes = NULL; - adapt->nAttributes = 0; + if(pNv->WaitVSyncPossible) { + adapt->pAttributes = NVBlitAttributes; + adapt->nAttributes = NUM_BLIT_ATTRIBUTES; + } else { + adapt->pAttributes = NULL; + adapt->nAttributes = 0; + } adapt->pImages = NVImages; adapt->nImages = NUM_IMAGES_ALL; adapt->PutVideo = NULL; @@ -377,9 +393,12 @@ NVSetupBlitVideo (ScreenPtr pScreen) pPriv->grabbedByV4L = FALSE; pPriv->blitter = TRUE; pPriv->doubleBuffer = FALSE; + pPriv->SyncToVBlank = pNv->WaitVSyncPossible; pNv->blitAdaptor = adapt; + xvSyncToVBlank = MAKE_ATOM("XV_SYNC_TO_VBLANK"); + return adapt; } @@ -409,8 +428,8 @@ NVSetupOverlayVideo (ScreenPtr pScreen) adapt->pPortPrivates = (DevUnion*)(&adapt[1]); pPriv = (NVPortPrivPtr)(&adapt->pPortPrivates[1]); adapt->pPortPrivates[0].ptr = (pointer)(pPriv); - adapt->pAttributes = NVAttributes; - adapt->nAttributes = NUM_ATTRIBUTES; + adapt->pAttributes = NVOverlayAttributes; + adapt->nAttributes = NUM_OVERLAY_ATTRIBUTES; adapt->pImages = NVImages; adapt->nImages = NUM_IMAGES_YUV; adapt->PutVideo = NULL; @@ -571,8 +590,19 @@ NVPutBlitImage ( NVDmaNext (pNv, SURFACE_FORMAT_DEPTH15); } - NVDmaStart(pNv, STRETCH_BLIT_FORMAT, 1); - NVDmaNext (pNv, format); + if(pPriv->SyncToVBlank) { + NVDmaKickoff(pNv); + NVWaitVSync(pNv); + } + + if(pNv->BlendingPossible) { + NVDmaStart(pNv, STRETCH_BLIT_FORMAT, 2); + NVDmaNext (pNv, format); + NVDmaNext (pNv, STRETCH_BLIT_OPERATION_COPY); + } else { + NVDmaStart(pNv, STRETCH_BLIT_FORMAT, 1); + NVDmaNext (pNv, format); + } while(nbox--) { NVDmaStart(pNv, RECT_SOLID_COLOR, 1); @@ -757,7 +787,20 @@ static int NVSetBlitPortAttribute pointer data ) { - return BadMatch; + NVPortPrivPtr pPriv = (NVPortPrivPtr)data; + NVPtr pNv = NVPTR(pScrnInfo); + + if ((attribute == xvSyncToVBlank) && pNv->WaitVSyncPossible) { + if ((value < 0) || (value > 1)) + return BadValue; + pPriv->SyncToVBlank = value; + } else + if (attribute == xvSetDefaults) { + pPriv->SyncToVBlank = pNv->WaitVSyncPossible; + } else + return BadMatch; + + return Success; } static int NVGetBlitPortAttribute @@ -768,7 +811,14 @@ static int NVGetBlitPortAttribute pointer data ) { - return BadMatch; + NVPortPrivPtr pPriv = (NVPortPrivPtr)data; + + if(attribute == xvSyncToVBlank) + *value = (pPriv->SyncToVBlank) ? 1 : 0; + else + return BadMatch; + + return Success; } @@ -1434,8 +1484,8 @@ XF86OffscreenImageRec NVOffscreenImages[2] = NVGetSurfaceAttribute, NVSetSurfaceAttribute, 2046, 2046, - NUM_ATTRIBUTES - 1, - &NVAttributes[1] + NUM_OVERLAY_ATTRIBUTES - 1, + &NVOverlayAttributes[1] }, { &NVImages[2], @@ -1447,8 +1497,8 @@ XF86OffscreenImageRec NVOffscreenImages[2] = NVGetSurfaceAttribute, NVSetSurfaceAttribute, 2046, 2046, - NUM_ATTRIBUTES - 1, - &NVAttributes[1] + NUM_OVERLAY_ATTRIBUTES - 1, + &NVOverlayAttributes[1] }, }; diff --git a/src/nv_xaa.c b/src/nv_xaa.c index 3bf6b16..0723788 100644 --- a/src/nv_xaa.c +++ b/src/nv_xaa.c @@ -37,7 +37,7 @@ |* *| \***************************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_xaa.c,v 1.33 2003/09/21 00:17:34 mvojkovi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_xaa.c,v 1.35 2004/03/20 16:25:18 mvojkovi Exp $ */ #include "nv_include.h" #include "xaalocal.h" @@ -151,6 +151,19 @@ NVDmaWait ( } } +void +NVWaitVSync(NVPtr pNv) +{ + NVDmaStart(pNv, 0x0000A12C, 1); + NVDmaNext (pNv, 0); + NVDmaStart(pNv, 0x0000A134, 1); + NVDmaNext (pNv, pNv->CRTCnumber); + NVDmaStart(pNv, 0x0000A100, 1); + NVDmaNext (pNv, 0); + NVDmaStart(pNv, 0x0000A130, 1); + NVDmaNext (pNv, 0); +} + /* currentRop = 0-15 solid fill 16-31 8x8 pattern fill |