From 7c34d051168eba499beb20c40fd95703375f4c7b Mon Sep 17 00:00:00 2001 From: Alan Coopersmith Date: Wed, 10 Nov 2004 02:53:44 +0000 Subject: (Bugzilla #1777) Import Mark Vojkovich's changes to NV driver since last sync with XFree86, including: Support for new NVIDIA chips. Egbert has a laptop that needs some DPMS ordering reversed. New chip support and workaround for Toshiba M30 laptop issue. PCI-Xpress chip support. DPMS support for DVI. Cursor changes for NV11 so that alpha blended cursors will work in conjunction with dithering (laptop panels). It previously did not. HW support for alpha blended stretch blits on NV5 and higher, though nothing is using them at this point. Add support for VBlank syncing the Xv Blit adaptor on hardware that supports it (NV11 and higher). Make console restoration a little more robust. We were making an assumption that failed on a newer laptop. Workaround for some NV31 DVI artifacts. Also add nVidia license statement to nv man page to comply with requirement that it appear in "user documentation" --- man/nv.man | 53 +++++++- src/nv_cursor.c | 41 +++--- src/nv_dac.c | 33 +++-- src/nv_dma.h | 8 +- src/nv_driver.c | 219 +++++++++++++++++++++++++----- src/nv_hw.c | 407 +++++++++++++++++++++++++++++++++++++++++++------------- src/nv_proto.h | 3 +- src/nv_setup.c | 37 ++++-- src/nv_type.h | 10 +- src/nv_video.c | 91 ++++++++++--- src/nv_xaa.c | 77 +++++++---- 11 files changed, 747 insertions(+), 232 deletions(-) diff --git a/man/nv.man b/man/nv.man index 04a89d6..95f5804 100644 --- a/man/nv.man +++ b/man/nv.man @@ -1,4 +1,4 @@ -.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv.man,v 1.21 2003/06/23 21:38:40 mvojkovi Exp $ +.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv.man,v 1.26 2004/10/15 20:32:21 mvojkovi Exp $ .\" shorthand for double quote that works everywhere. .ds q \N'34' .TH NV __drivermansuffix__ __vendorversion__ @@ -14,7 +14,7 @@ nv \- NVIDIA video driver .fi .SH DESCRIPTION .B nv -is an XFree86 driver for NVIDIA video cards. The driver supports 2D +is an __xservername__ driver for NVIDIA video cards. The driver supports 2D acceleration and provides support for the following framebuffer depths: 8, 15, 16 (except Riva128) and 24. All visual types are supported for depth 8, TrueColor and DirectColor @@ -51,9 +51,9 @@ NV1A, NV1F NV17, NV18, NV25, NV28 .TP 22 .B GeForce FX, QUADRO FX -NV30, NV31, NV34, NV35 +NV30, NV31, NV34, NV35, NV36, NV37, NV38, NV40, NV41, NV43, NV44, NV45 .SH CONFIGURATION DETAILS -Please refer to XF86Config(__filemansuffix__) for general configuration +Please refer to __xconfigfile__(__filemansuffix__) for general configuration details. This section only covers configuration details specific to this driver. .PP @@ -102,19 +102,58 @@ the flat panel truncates it. This is only supported in depth 24 on GeForce2 MX, nForce2, GeForce4, Quadro4, Geforce FX and Quadro FX. Default: off. .TP +.BI "Option \*qFPScale\*q \*q" boolean \*q +Supported only on GeForce4, Quadro4, Geforce FX and Quadro FX. This option +tells to the driver to scale lower resolutions up to the flat panel's native +resolution. Default: on. +.TP .BI "Option \*qRotate\*q \*qCW\*q" .TP .BI "Option \*qRotate\*q \*qCCW\*q" Rotate the display clockwise or counterclockwise. This mode is unaccelerated. Default: no rotation. -Note: Option Rotate does not work unless the Resize and Rotate extension has -been turned off. +Note: The Resize and Rotate extension will be disabled if the Rotate option +is used. .TP .BI "Option \*qShadowFB\*q \*q" boolean \*q Enable or disable use of the shadow framebuffer layer. Default: off. .SH "SEE ALSO" -XFree86(1), XF86Config(__filemansuffix__), xf86config(1), Xserver(1), X(__miscmansuffix__) +__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__) .SH AUTHORS Authors include: David McKay, Jarno Paananen, Chas Inman, Dave Schmenk, Mark Vojkovich +.SH COPYRIGHT +.LP +NOTICE TO USER: The source code is copyrighted under U.S. and +international laws. Users and possessors of this source code are +hereby granted a nonexclusive, royalty-free copyright license to +use this code in individual and commercial software. +.LP +Any use of this source code must include, in the user documentation and +internal comments to the code, notices to the end user as follows: +.LP +Copyright 1993-2003 NVIDIA, Corporation. All rights reserved. +.LP +NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY +OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" +WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPORATION +DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT, +AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL +NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL, +OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. +.LP +U.S. Government End Users. This source code is a "commercial +item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), +consisting of "commercial computer software" and "commercial +computer software documentation," as such terms are used in +48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Government +only as a commercial end item. Consistent with 48 C.F.R. +12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), +all U.S. Government End Users acquire the source code with only +those rights set forth herein. + diff --git a/src/nv_cursor.c b/src/nv_cursor.c index 85ac42a..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.12 2003/07/31 20:24:29 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 9b9b9e8..769179b 100644 --- a/src/nv_dac.c +++ b/src/nv_dac.c @@ -37,7 +37,7 @@ |* *| \***************************************************************************/ -/* $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.41 2004/10/05 21:23:03 mvojkovi Exp $ */ #include "nv_include.h" @@ -58,7 +58,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; @@ -215,29 +214,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 +249,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; 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 3ca1786..601d7ef 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.6 2004/09/17 03:04:52 ajax Exp $ */ +/* $XdotOrg: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c,v 1.5 2004/08/16 09:13:14 ajax Exp $ */ /* $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 */ -/* $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.128 2004/10/09 22:53:25 mvojkovi Exp $ */ #include "nv_include.h" @@ -174,6 +174,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 +183,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 +206,41 @@ 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" }, + { 0x10DE00C0, "0x00C0" }, + { 0x10DE00C1, "0x00C1" }, + { 0x10DE00C2, "0x00C2" }, + { 0x10DE00C8, "0x00C8" }, + { 0x10DE00C9, "0x00C9" }, + { 0x10DE00CC, "0x00CC" }, + { 0x10DE00CE, "0x00CE" }, + { 0x10DE0140, "GeForce 6600 GT" }, + { 0x10DE0141, "GeForce 6600" }, + { 0x10DE0142, "0x0142" }, + { 0x10DE0143, "0x0143" }, + { 0x10DE0144, "0x0144" }, + { 0x10DE0145, "GeForce 6610 XL" }, + { 0x10DE0146, "0x0146" }, + { 0x10DE0147, "0x0147" }, + { 0x10DE0148, "0x0148" }, + { 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 +388,8 @@ typedef enum { OPTION_VIDEO_KEY, OPTION_FLAT_PANEL, OPTION_FP_DITHER, - OPTION_CRTC_NUMBER + OPTION_CRTC_NUMBER, + OPTION_FP_SCALE } NVOpts; @@ -365,6 +404,7 @@ 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 }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; @@ -494,6 +534,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 +593,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 +606,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 +625,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 +851,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 +981,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 +1125,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"); @@ -1178,12 +1283,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 +1364,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; @@ -1489,25 +1628,27 @@ NVRestore(ScrnInfoPtr pScrn) NVRegPtr nvReg = &pNv->SavedReg; NVLockUnlock(pNv, 0); + if(pNv->twoHeads) { - VGA_WR08(pNv->PCIO, 0x03D4, 0x44); - VGA_WR08(pNv->PCIO, 0x03D5, pNv->CRTCnumber * 0x3); - NVLockUnlock(pNv, 0); + VGA_WR08(pNv->PCIO, 0x03D4, 0x44); + VGA_WR08(pNv->PCIO, 0x03D5, pNv->CRTCnumber * 0x3); + 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); - } - + 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. */ @@ -1528,6 +1669,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 @@ -1837,9 +1984,9 @@ NVSave(ScrnInfoPtr pScrn) NVLockUnlock(pNv, 0); if(pNv->twoHeads) { - VGA_WR08(pNv->PCIO, 0x03D4, 0x44); - VGA_WR08(pNv->PCIO, 0x03D5, pNv->CRTCnumber * 0x3); - NVLockUnlock(pNv, 0); + 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..25b10d2 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.11 2004/10/15 20:32:21 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 } @@ -632,12 +662,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; - uMClkPostDiv = (pciReadLong(pciTag(0, 0, 3), 0x6C) >> 8) & 0xf; - if(!uMClkPostDiv) uMClkPostDiv = 4; - MClk = 400000 / uMClkPostDiv; + if((pNv->Chipset & 0x0FF0) == 0x01A0) { + unsigned int 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; @@ -901,79 +936,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[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[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; +#endif + } if(pNv->Architecture < NV_ARCH_10) { if((pNv->Chipset & 0x0fff) == 0x0020) { @@ -985,6 +1108,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 +1117,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 +1127,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 +1144,54 @@ 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; + 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 +1228,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 +1277,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 +1326,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; } @@ -1177,6 +1383,23 @@ void NVLoadStateExt ( } } else { pNv->PRAMDAC[0x0848/4] = state->scale; + + /* 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. */ + pNv->PRAMDAC[0x0828/4] &= ~1; + } + + if((pNv->Chipset & 0xfff0) == 0x0310) { + pNv->PRAMDAC[0x0828/4] |= 1; + } + + /* end flat panel hacks */ } pNv->PRAMDAC[0x0600/4] = state->general; @@ -1240,7 +1463,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]; } diff --git a/src/nv_proto.h b/src/nv_proto.h index f526a71..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.10 2003/07/31 20:24:29 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 3d58efa..cc157f6 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.38 2003/09/08 20:00:27 mvojkovi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_setup.c,v 1.43 2004/08/26 22:38:47 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,6 +407,7 @@ NVCommonSetup(ScrnInfoPtr pScrn) case 0x017D: case 0x0186: case 0x0187: + case 0x0189: case 0x0286: case 0x028C: case 0x0316: @@ -424,6 +429,15 @@ NVCommonSetup(ScrnInfoPtr pScrn) case 0x0349: case 0x034B: case 0x034C: + case 0x0160: + case 0x0166: + case 0x00C8: + case 0x00C9: + case 0x00CC: + case 0x0147: + case 0x0148: + case 0x0149: + case 0x014C: mobile = TRUE; break; default: @@ -658,6 +672,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); } @@ -665,7 +680,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 5730cb5..96ca4e4 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.48 2004/08/26 22:38:47 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)) @@ -63,6 +64,9 @@ typedef struct _riva_hw_state U032 cursor0; U032 cursor1; U032 cursor2; + U032 timingH; + U032 timingV; + U032 displayV; } RIVA_HW_STATE, *NVRegPtr; @@ -88,6 +92,7 @@ typedef struct { CARD32 ScratchBufferStart; Bool NoAccel; Bool HWCursor; + Bool FpScale; Bool ShadowFB; unsigned char * ShadowPtr; int ShadowPitch; @@ -151,6 +156,7 @@ typedef struct { Bool fpScaler; int fpWidth; int fpHeight; + CARD32 fpSyncs; CARD32 dmaPut; CARD32 dmaCurrent; @@ -159,6 +165,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 f985461..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.19 2003/09/01 20:54:26 mvojkovi 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; @@ -432,7 +451,7 @@ NVSetupOverlayVideo (ScreenPtr pScreen) NVSetPortDefaults (pScrnInfo, pPriv); /* gotta uninit this someplace */ - REGION_INIT(pScreen, &pPriv->clip, NullBox, 0); + REGION_NULL(pScreen, &pPriv->clip); pNv->overlayAdaptor = adapt; @@ -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; } @@ -958,7 +1008,7 @@ static int NVPutImage NVPtr pNv = NVPTR(pScrnInfo); INT32 xa, xb, ya, yb; unsigned char *dst_start; - int pitch, newSize, offset, s2offset, s3offset; + int newSize, offset, s2offset, s3offset; int srcPitch, srcPitch2, dstPitch; int top, left, right, bottom, npixels, nlines, bpp; Bool skip = FALSE; @@ -1011,7 +1061,6 @@ static int NVPutImage } bpp = pScrnInfo->bitsPerPixel >> 3; - pitch = bpp * pScrnInfo->displayWidth; switch(id) { case FOURCC_YV12: @@ -1435,8 +1484,8 @@ XF86OffscreenImageRec NVOffscreenImages[2] = NVGetSurfaceAttribute, NVSetSurfaceAttribute, 2046, 2046, - NUM_ATTRIBUTES - 1, - &NVAttributes[1] + NUM_OVERLAY_ATTRIBUTES - 1, + &NVOverlayAttributes[1] }, { &NVImages[2], @@ -1448,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 2dd2bc1..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.32 2003/08/18 21:40:04 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" @@ -113,6 +113,13 @@ NVDmaKickoff(NVPtr pNv) } } + +/* There is a HW race condition with videoram command buffers. + You can't jump to the location of your put offset. We write put + at the jump offset + SKIPS dwords with noop padding in between + to solve this problem */ +#define SKIPS 8 + void NVDmaWait ( NVPtr pNv, @@ -129,21 +136,34 @@ NVDmaWait ( pNv->dmaFree = pNv->dmaMax - pNv->dmaCurrent; if(pNv->dmaFree < size) { NVDmaNext(pNv, 0x20000000); - if(!dmaGet) { - if(!pNv->dmaPut) /* corner case - idle */ - NVDmaKickoff(pNv); + if(dmaGet <= SKIPS) { + if(pNv->dmaPut <= SKIPS) /* corner case - will be idle */ + WRITE_PUT(pNv, SKIPS + 1); do { dmaGet = READ_GET(pNv); } - while(!dmaGet); + while(dmaGet <= SKIPS); } - WRITE_PUT(pNv, 0); - pNv->dmaCurrent = pNv->dmaPut = 0; - pNv->dmaFree = dmaGet - 1; + WRITE_PUT(pNv, SKIPS); + pNv->dmaCurrent = pNv->dmaPut = SKIPS; + pNv->dmaFree = dmaGet - (SKIPS + 1); } } else pNv->dmaFree = dmaGet - pNv->dmaCurrent - 1; } } +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 @@ -194,7 +214,7 @@ void NVResetGraphics(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); CARD32 surfaceFormat, patternFormat, rectFormat, lineFormat; - int pitch; + int pitch, i; if(pNv->NoAccel) return; @@ -203,27 +223,30 @@ void NVResetGraphics(ScrnInfoPtr pScrn) pNv->dmaBase = (CARD32*)(&pNv->FbStart[pNv->FbUsableSize]); - pNv->dmaBase[0x0] = 0x00040000; - pNv->dmaBase[0x1] = 0x80000010; - pNv->dmaBase[0x2] = 0x00042000; - pNv->dmaBase[0x3] = 0x80000011; - pNv->dmaBase[0x4] = 0x00044000; - pNv->dmaBase[0x5] = 0x80000012; - pNv->dmaBase[0x6] = 0x00046000; - pNv->dmaBase[0x7] = 0x80000013; - pNv->dmaBase[0x8] = 0x00048000; - pNv->dmaBase[0x9] = 0x80000014; - pNv->dmaBase[0xA] = 0x0004A000; - pNv->dmaBase[0xB] = 0x80000015; - pNv->dmaBase[0xC] = 0x0004C000; - pNv->dmaBase[0xD] = 0x80000016; - pNv->dmaBase[0xE] = 0x0004E000; - pNv->dmaBase[0xF] = 0x80000017; + for(i = 0; i < SKIPS; i++) + pNv->dmaBase[i] = 0x00000000; + + pNv->dmaBase[0x0 + SKIPS] = 0x00040000; + pNv->dmaBase[0x1 + SKIPS] = 0x80000010; + pNv->dmaBase[0x2 + SKIPS] = 0x00042000; + pNv->dmaBase[0x3 + SKIPS] = 0x80000011; + pNv->dmaBase[0x4 + SKIPS] = 0x00044000; + pNv->dmaBase[0x5 + SKIPS] = 0x80000012; + pNv->dmaBase[0x6 + SKIPS] = 0x00046000; + pNv->dmaBase[0x7 + SKIPS] = 0x80000013; + pNv->dmaBase[0x8 + SKIPS] = 0x00048000; + pNv->dmaBase[0x9 + SKIPS] = 0x80000014; + pNv->dmaBase[0xA + SKIPS] = 0x0004A000; + pNv->dmaBase[0xB + SKIPS] = 0x80000015; + pNv->dmaBase[0xC + SKIPS] = 0x0004C000; + pNv->dmaBase[0xD + SKIPS] = 0x80000016; + pNv->dmaBase[0xE + SKIPS] = 0x0004E000; + pNv->dmaBase[0xF + SKIPS] = 0x80000017; pNv->dmaPut = 0; - pNv->dmaCurrent = 16; + pNv->dmaCurrent = 16 + SKIPS; pNv->dmaMax = 8191; - pNv->dmaFree = 8175; + pNv->dmaFree = pNv->dmaMax - pNv->dmaCurrent; switch(pNv->CurrentLayout.depth) { case 24: -- cgit v1.2.3