summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/nv.man53
-rw-r--r--src/nv_cursor.c41
-rw-r--r--src/nv_dac.c33
-rw-r--r--src/nv_dma.h8
-rw-r--r--src/nv_driver.c219
-rw-r--r--src/nv_hw.c407
-rw-r--r--src/nv_proto.h3
-rw-r--r--src/nv_setup.c37
-rw-r--r--src/nv_type.h10
-rw-r--r--src/nv_video.c91
-rw-r--r--src/nv_xaa.c77
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
<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.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: