summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/nv.man115
-rw-r--r--src/nv_const.h20
-rw-r--r--src/nv_cursor.c301
-rw-r--r--src/nv_dac.c415
-rw-r--r--src/nv_dga.c312
-rw-r--r--src/nv_driver.c1934
-rw-r--r--src/nv_include.h59
-rw-r--r--src/nv_local.h74
-rw-r--r--src/nv_proto.h46
-rw-r--r--src/nv_setup.c551
-rw-r--r--src/nv_shadow.c194
-rw-r--r--src/nv_type.h135
-rw-r--r--src/nv_video.c1160
-rw-r--r--src/nv_xaa.c573
-rw-r--r--src/riva_hw.c2100
-rw-r--r--src/riva_hw.h428
-rw-r--r--src/riva_tbl.h826
17 files changed, 9243 insertions, 0 deletions
diff --git a/man/nv.man b/man/nv.man
new file mode 100644
index 0000000..7856227
--- /dev/null
+++ b/man/nv.man
@@ -0,0 +1,115 @@
+.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv.man,v 1.17 2003/02/11 00:00:18 mvojkovi Exp $
+.\" shorthand for double quote that works everywhere.
+.ds q \N'34'
+.TH NV __drivermansuffix__ __vendorversion__
+.SH NAME
+nv \- NVIDIA video driver
+.SH SYNOPSIS
+.nf
+.B "Section \*qDevice\*q"
+.BI " Identifier \*q" devname \*q
+.B " Driver \*qnv\*q"
+\ \ ...
+.B EndSection
+.fi
+.SH DESCRIPTION
+.B nv
+is an XFree86 driver for NVIDIA video cards. The driver supports full 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
+visuals are supported for the other depths with the exception of
+the Riva128 which only supports TrueColor in the higher depths.
+
+.SH SUPPORTED HARDWARE
+The
+.B nv
+driver supports PCI and AGP video cards based on the following NVIDIA chips:
+.TP 22
+.B RIVA 128
+NV3
+.TP 22
+.B RIVA TNT
+NV4
+.TP 22
+.B RIVA TNT2
+NV5
+.TP 22
+.B GeForce 256, QUADRO
+NV10
+.TP 22
+.B GeForce2, QUADRO2
+NV11 & NV15
+.TP 22
+.B GeForce3, QUADRO DCC
+NV20
+.TP 22
+.B nForce, nForce2
+NV1A, NV1F
+.TP 22
+.B GeForce4, QUADRO4
+NV17, NV18, NV25, NV28
+.TP 22
+.B GeForce FX, QUADRO FX
+NV30
+.SH CONFIGURATION DETAILS
+Please refer to XF86Config(__filemansuffix__) for general configuration
+details. This section only covers configuration details specific to this
+driver.
+.PP
+The driver auto-detects the chipset type and the amount of video memory
+present for all chips.
+.PP
+The following driver
+.B Options
+are supported:
+.TP
+.BI "Option \*qHWCursor\*q \*q" boolean \*q
+Enable or disable the HW cursor. Default: on.
+.TP
+.BI "Option \*qNoAccel\*q \*q" boolean \*q
+Disable or enable acceleration. Default: acceleration is enabled.
+.TP
+.BI "Option \*qUseFBDev\*q \*q" boolean \*q
+Enable or disable use of on OS-specific fb interface (and is not supported
+on all OSs). See fbdevhw(__drivermansuffix__) for further information.
+Default: off.
+.TP
+.BI "Option \*qCrtcNumber\*q \*q" integer \*q
+nForce2, Quadro4, GeForce4 and NV30 may have two video outputs.
+The driver attempts to autodetect
+which one the monitor is connected to. In the case that autodetection picks
+the wrong one, this option may be used to force usage of a particular output.
+The options are "0" or "1".
+Default: autodetected.
+.TP
+.BI "Option \*qFlatPanel\*q \*q" boolean \*q
+The driver usually cannot autodetect the presence of a flat panel so
+this option should be set when used with a flat panel. With this driver
+a flat panel will only work if it was POSTed by the BIOS, that is, the
+machine must have booted to the panel.
+Default: off.
+.TP
+.BI "Option \*qFPDither\*q \*q" boolean \*q
+Most digital flat panels have only 6 bits per component color resolution.
+This option tells the driver to dither from 8 bits per component to 6 before
+the flat panel truncates it. This is only suported in depth 24 on NV11,
+nForce2, GeForce4, Quadro4 and NV30.
+Default: off.
+.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.
+.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__)
+.SH AUTHORS
+Authors include: David McKay, Jarno Paananen, Chas Inman, Dave Schmenk,
+Mark Vojkovich
diff --git a/src/nv_const.h b/src/nv_const.h
new file mode 100644
index 0000000..14ba134
--- /dev/null
+++ b/src/nv_const.h
@@ -0,0 +1,20 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_const.h,v 1.6 2001/12/07 00:09:55 mvojkovi Exp $ */
+
+#ifndef __NV_CONST_H__
+#define __NV_CONST_H__
+
+#define VERSION 4000
+#define NV_NAME "NV"
+#define NV_DRIVER_NAME "nv"
+#define NV_MAJOR_VERSION 1
+#define NV_MINOR_VERSION 0
+#define NV_PATCHLEVEL 1
+
+#ifdef DEBUG_PRINT
+#define DEBUG(x) x
+#else
+#define DEBUG(x)
+#endif
+
+#endif /* __NV_CONST_H__ */
+
diff --git a/src/nv_cursor.c b/src/nv_cursor.c
new file mode 100644
index 0000000..04107ee
--- /dev/null
+++ b/src/nv_cursor.c
@@ -0,0 +1,301 @@
+/* $XConsortium: nv_driver.c /main/3 1996/10/28 05:13:37 kaleb $ */
+/*
+ * Copyright 1996-1997 David J. McKay
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * DAVID J. MCKAY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* Rewritten with reference from mga driver and 3.3.4 NVIDIA driver by
+ Jarno Paananen <jpaana@s2.org> */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_cursor.c,v 1.11 2002/11/26 23:41:58 mvojkovi Exp $ */
+
+#include "nv_include.h"
+
+#include "cursorstr.h"
+
+/****************************************************************************\
+* *
+* HW Cursor Entrypoints *
+* *
+\****************************************************************************/
+
+#define TRANSPARENT_PIXEL 0
+
+#define ConvertToRGB555(c) \
+(((c & 0xf80000) >> 9 ) | ((c & 0xf800) >> 6 ) | ((c & 0xf8) >> 3 ) | 0x8000)
+
+#define ConvertToRGB888(c) (c | 0xff000000)
+
+#define BYTE_SWAP_32(c) ((c & 0xff000000) >> 24) | \
+ ((c & 0xff0000) >> 8) | \
+ ((c & 0xff00) << 8) | \
+ ((c & 0xff) << 24)
+
+
+static void
+ConvertCursor1555(NVPtr pNv, CARD32 *src, CARD16 *dst)
+{
+ CARD32 b, m;
+ int i, j;
+
+ for ( i = 0; i < 32; i++ ) {
+ b = *src++;
+ m = *src++;
+ for ( j = 0; j < 32; j++ ) {
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ if ( m & 0x80000000)
+ *dst = ( b & 0x80000000) ? pNv->curFg : pNv->curBg;
+ else
+ *dst = TRANSPARENT_PIXEL;
+ b <<= 1;
+ m <<= 1;
+#else
+ if ( m & 1 )
+ *dst = ( b & 1) ? pNv->curFg : pNv->curBg;
+ else
+ *dst = TRANSPARENT_PIXEL;
+ b >>= 1;
+ m >>= 1;
+#endif
+ dst++;
+ }
+ }
+}
+
+
+static void
+ConvertCursor8888(NVPtr pNv, CARD32 *src, CARD32 *dst)
+{
+ CARD32 b, m;
+ int i, j;
+
+ for ( i = 0; i < 128; i++ ) {
+ b = *src++;
+ m = *src++;
+ for ( j = 0; j < 32; j++ ) {
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ if ( m & 0x80000000)
+ *dst = ( b & 0x80000000) ? pNv->curFg : pNv->curBg;
+ else
+ *dst = TRANSPARENT_PIXEL;
+ b <<= 1;
+ m <<= 1;
+#else
+ if ( m & 1 )
+ *dst = ( b & 1) ? pNv->curFg : pNv->curBg;
+ else
+ *dst = TRANSPARENT_PIXEL;
+ b >>= 1;
+ m >>= 1;
+#endif
+ dst++;
+ }
+ }
+}
+
+
+static void
+TransformCursor (NVPtr pNv)
+{
+ CARD32 *tmp;
+ int i, dwords;
+
+ /* convert to color cursor */
+ if(pNv->alphaCursor) {
+ dwords = 64 * 64;
+ if(!(tmp = ALLOCATE_LOCAL(dwords * 4))) return;
+ ConvertCursor8888(pNv, pNv->curImage, tmp);
+ } else {
+ dwords = (32 * 32) >> 1;
+ if(!(tmp = ALLOCATE_LOCAL(dwords * 4))) return;
+ ConvertCursor1555(pNv, pNv->curImage, (CARD16*)tmp);
+ }
+
+ for(i = 0; i < dwords; i++)
+ pNv->riva.CURSOR[i] = tmp[i];
+
+ DEALLOCATE_LOCAL(tmp);
+}
+
+static void
+NVLoadCursorImage( ScrnInfoPtr pScrn, unsigned char *src )
+{
+ NVPtr pNv = NVPTR(pScrn);
+
+ /* save copy of image for color changes */
+ memcpy(pNv->curImage, src, (pNv->alphaCursor) ? 1024 : 256);
+
+ TransformCursor(pNv);
+}
+
+static void
+NVSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+ NVPtr pNv = NVPTR(pScrn);
+
+ pNv->riva.PRAMDAC[0x0000300/4] = (x & 0xFFFF) | (y << 16);
+}
+
+static void
+NVSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ CARD32 fore, back;
+
+ if(pNv->alphaCursor) {
+ fore = ConvertToRGB888(fg);
+ back = ConvertToRGB888(bg);
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ if((pNv->Chipset & 0x0ff0) == 0x0110) {
+ fore = BYTE_SWAP_32(fore);
+ back = BYTE_SWAP_32(back);
+ }
+#endif
+ } else {
+ fore = ConvertToRGB555(fg);
+ back = ConvertToRGB555(bg);
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ if((pNv->Chipset & 0x0ff0) == 0x0110) {
+ fore = ((fore & 0xff) << 8) | (fore >> 8);
+ back = ((back & 0xff) << 8) | (back >> 8);
+ }
+#endif
+ }
+
+ if ((pNv->curFg != fore) || (pNv->curBg != back)) {
+ pNv->curFg = fore;
+ pNv->curBg = back;
+
+ TransformCursor(pNv);
+ }
+}
+
+
+static void
+NVShowCursor(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ /* Enable cursor - X-Windows mode */
+ pNv->riva.ShowHideCursor(&pNv->riva, 1);
+}
+
+static void
+NVHideCursor(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ /* Disable cursor */
+ pNv->riva.ShowHideCursor(&pNv->riva, 0);
+}
+
+static Bool
+NVUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
+{
+ return TRUE;
+}
+
+#ifdef ARGB_CURSOR
+static Bool
+NVUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs)
+{
+ if((pCurs->bits->width <= 64) && (pCurs->bits->height <= 64))
+ return TRUE;
+
+ return FALSE;
+}
+
+static void
+NVLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ CARD32 *image = pCurs->bits->argb;
+ CARD32 *dst = (CARD32*)pNv->riva.CURSOR;
+ 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;
+
+ 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
+#endif
+ {
+ for(y = 0; y < h; y++) {
+ for(x = 0; x < w; x++)
+ *dst++ = *image++;
+ for(; x < 64; x++)
+ *dst++ = 0;
+ }
+ }
+
+ if(y < 64)
+ memset(dst, 0, 64 * (64 - y) * 4);
+}
+#endif
+
+Bool
+NVCursorInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ NVPtr pNv = NVPTR(pScrn);
+ xf86CursorInfoPtr infoPtr;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVCursorInit\n"));
+
+ infoPtr = xf86CreateCursorInfoRec();
+ if(!infoPtr) return FALSE;
+
+ pNv->CursorInfoRec = infoPtr;
+
+ if(pNv->alphaCursor)
+ infoPtr->MaxWidth = infoPtr->MaxHeight = 64;
+ else
+ infoPtr->MaxWidth = infoPtr->MaxHeight = 32;
+
+ infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32;
+ infoPtr->SetCursorColors = NVSetCursorColors;
+ infoPtr->SetCursorPosition = NVSetCursorPosition;
+ infoPtr->LoadCursorImage = NVLoadCursorImage;
+ infoPtr->HideCursor = NVHideCursor;
+ infoPtr->ShowCursor = NVShowCursor;
+ infoPtr->UseHWCursor = NVUseHWCursor;
+
+#ifdef ARGB_CURSOR
+ if(pNv->alphaCursor &&
+ (((pNv->Chipset & 0x0ff0) != 0x0110) ||
+ !(pNv->riva.flatPanel & FP_DITHER)))
+ {
+ infoPtr->UseHWCursorARGB = NVUseHWCursorARGB;
+ infoPtr->LoadCursorARGB = NVLoadCursorARGB;
+ }
+#endif
+
+ return(xf86InitCursor(pScreen, infoPtr));
+}
diff --git a/src/nv_dac.c b/src/nv_dac.c
new file mode 100644
index 0000000..90d75da
--- /dev/null
+++ b/src/nv_dac.c
@@ -0,0 +1,415 @@
+/* $XConsortium: nv_driver.c /main/3 1996/10/28 05:13:37 kaleb $ */
+/*
+ * Copyright 1996-1997 David J. McKay
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * DAVID J. MCKAY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* 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_dac.c,v 1.31 2003/01/02 20:44:56 mvojkovi Exp $ */
+
+#include "nv_include.h"
+
+Bool
+NVDACInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ int i;
+ int horizDisplay = (mode->CrtcHDisplay/8) - 1;
+ int horizStart = (mode->CrtcHSyncStart/8) - 1;
+ int horizEnd = (mode->CrtcHSyncEnd/8) - 1;
+ int horizTotal = (mode->CrtcHTotal/8) - 5;
+ int horizBlankStart = (mode->CrtcHDisplay/8) - 1;
+ int horizBlankEnd = (mode->CrtcHTotal/8) - 1;
+ int vertDisplay = mode->CrtcVDisplay - 1;
+ int vertStart = mode->CrtcVSyncStart - 1;
+ int vertEnd = mode->CrtcVSyncEnd - 1;
+ int vertTotal = mode->CrtcVTotal - 2;
+ int vertBlankStart = mode->CrtcVDisplay - 1;
+ int vertBlankEnd = mode->CrtcVTotal - 1;
+
+
+ NVPtr pNv = NVPTR(pScrn);
+ NVRegPtr nvReg = &pNv->ModeReg;
+ NVFBLayout *pLayout = &pNv->CurrentLayout;
+ vgaRegPtr pVga;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVDACInit\n"));
+
+ /*
+ * This will initialize all of the generic VGA registers.
+ */
+ if (!vgaHWInit(pScrn, mode))
+ return(FALSE);
+
+ pVga = &VGAHWPTR(pScrn)->ModeReg;
+
+ /*
+ * Set all CRTC values.
+ */
+
+ if(mode->Flags & V_INTERLACE)
+ vertTotal |= 1;
+
+ if(pNv->FlatPanel == 1) {
+ vertStart = vertTotal - 3;
+ vertEnd = vertTotal - 2;
+ vertBlankStart = vertStart;
+ horizStart = horizTotal - 3;
+ horizEnd = horizTotal - 2;
+ horizBlankEnd = horizTotal + 4;
+ }
+
+ pVga->CRTC[0x0] = Set8Bits(horizTotal);
+ pVga->CRTC[0x1] = Set8Bits(horizDisplay);
+ pVga->CRTC[0x2] = Set8Bits(horizBlankStart);
+ pVga->CRTC[0x3] = SetBitField(horizBlankEnd,4:0,4:0)
+ | SetBit(7);
+ pVga->CRTC[0x4] = Set8Bits(horizStart);
+ pVga->CRTC[0x5] = SetBitField(horizBlankEnd,5:5,7:7)
+ | SetBitField(horizEnd,4:0,4:0);
+ pVga->CRTC[0x6] = SetBitField(vertTotal,7:0,7:0);
+ pVga->CRTC[0x7] = SetBitField(vertTotal,8:8,0:0)
+ | SetBitField(vertDisplay,8:8,1:1)
+ | SetBitField(vertStart,8:8,2:2)
+ | SetBitField(vertBlankStart,8:8,3:3)
+ | SetBit(4)
+ | SetBitField(vertTotal,9:9,5:5)
+ | SetBitField(vertDisplay,9:9,6:6)
+ | SetBitField(vertStart,9:9,7:7);
+ pVga->CRTC[0x9] = SetBitField(vertBlankStart,9:9,5:5)
+ | SetBit(6)
+ | ((mode->Flags & V_DBLSCAN) ? 0x80 : 0x00);
+ pVga->CRTC[0x10] = Set8Bits(vertStart);
+ pVga->CRTC[0x11] = SetBitField(vertEnd,3:0,3:0) | SetBit(5);
+ pVga->CRTC[0x12] = Set8Bits(vertDisplay);
+ pVga->CRTC[0x13] = ((pLayout->displayWidth/8)*(pLayout->bitsPerPixel/8));
+ pVga->CRTC[0x15] = Set8Bits(vertBlankStart);
+ pVga->CRTC[0x16] = Set8Bits(vertBlankEnd);
+
+ pVga->Attribute[0x10] = 0x01;
+
+ nvReg->screen = SetBitField(horizBlankEnd,6:6,4:4)
+ | SetBitField(vertBlankStart,10:10,3:3)
+ | SetBitField(vertStart,10:10,2:2)
+ | SetBitField(vertDisplay,10:10,1:1)
+ | SetBitField(vertTotal,10:10,0:0);
+
+ nvReg->horiz = SetBitField(horizTotal,8:8,0:0)
+ | SetBitField(horizDisplay,8:8,1:1)
+ | SetBitField(horizBlankStart,8:8,2:2)
+ | SetBitField(horizStart,8:8,3:3);
+
+ nvReg->extra = SetBitField(vertTotal,11:11,0:0)
+ | SetBitField(vertDisplay,11:11,2:2)
+ | SetBitField(vertStart,11:11,4:4)
+ | SetBitField(vertBlankStart,11:11,6:6);
+
+ if(mode->Flags & V_INTERLACE) {
+ horizTotal = (horizTotal >> 1) & ~1;
+ nvReg->interlace = Set8Bits(horizTotal);
+ nvReg->horiz |= SetBitField(horizTotal,8:8,4:4);
+ } else {
+ nvReg->interlace = 0xff; /* interlace off */
+ }
+
+
+ /*
+ * Initialize DAC palette.
+ */
+ if(pLayout->bitsPerPixel != 8 )
+ {
+ for (i = 0; i < 256; i++)
+ {
+ pVga->DAC[i*3] = i;
+ pVga->DAC[(i*3)+1] = i;
+ pVga->DAC[(i*3)+2] = i;
+ }
+ }
+
+ /*
+ * Calculate the extended registers.
+ */
+
+ if(pLayout->depth < 24)
+ i = pLayout->depth;
+ else i = 32;
+
+ if(pNv->riva.Architecture >= NV_ARCH_10)
+ pNv->riva.CURSOR = (U032 *)(pNv->FbStart + pNv->riva.CursorStart);
+
+ pNv->riva.LockUnlock(&pNv->riva, 0);
+
+ pNv->riva.CalcStateExt(&pNv->riva,
+ nvReg,
+ i,
+ pLayout->displayWidth,
+ mode->CrtcHDisplay,
+ pScrn->virtualY,
+ mode->Clock,
+ mode->Flags);
+
+ nvReg->scale = pNv->riva.PRAMDAC[0x00000848/4] & 0xfff000ff;
+ if(pNv->FlatPanel == 1) {
+ nvReg->pixel |= (1 << 7);
+ nvReg->scale |= (1 << 8) ;
+ }
+ if(pNv->SecondCRTC) {
+ nvReg->head = pNv->riva.PCRTC0[0x00000860/4] & ~0x00001000;
+ nvReg->head2 = pNv->riva.PCRTC0[0x00002860/4] | 0x00001000;
+ nvReg->crtcOwner = 3;
+ nvReg->pllsel |= 0x20000800;
+ nvReg->vpll2 = nvReg->vpll;
+ } else
+ if(pNv->riva.twoHeads) {
+ nvReg->head = pNv->riva.PCRTC0[0x00000860/4] | 0x00001000;
+ nvReg->head2 = pNv->riva.PCRTC0[0x00002860/4] & ~0x00001000;
+ nvReg->crtcOwner = 0;
+ nvReg->vpll2 = pNv->riva.PRAMDAC0[0x00000520/4];
+ }
+
+ nvReg->cursorConfig = 0x00000100;
+ if(mode->Flags & V_DBLSCAN)
+ nvReg->cursorConfig |= (1 << 4);
+ if(pNv->alphaCursor) {
+ nvReg->cursorConfig |= 0x04011000;
+ nvReg->general |= (1 << 29);
+
+ if((pNv->Chipset & 0x0ff0) == 0x0110) {
+ nvReg->dither = pNv->riva.PRAMDAC[0x0528/4] & ~0x00010000;
+ if(pNv->riva.flatPanel & FP_DITHER)
+ nvReg->dither |= 0x00010000;
+ else
+ nvReg->cursorConfig |= (1 << 28);
+ } else
+ if((pNv->riva.Chipset & 0x0ff0) >= 0x0170) {
+ nvReg->dither = pNv->riva.PRAMDAC[0x083C/4] & ~1;
+ nvReg->cursorConfig |= (1 << 28);
+ if(pNv->riva.flatPanel & FP_DITHER)
+ nvReg->dither |= 1;
+ } else {
+ nvReg->cursorConfig |= (1 << 28);
+ }
+ } else
+ nvReg->cursorConfig |= 0x02000000;
+
+ nvReg->vpllB = 0;
+ nvReg->vpll2B = 0;
+
+ return (TRUE);
+}
+
+void
+NVDACRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, NVRegPtr nvReg,
+ Bool primary)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ int restore = VGA_SR_MODE;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVDACRestore\n"));
+
+ if(primary) restore |= VGA_SR_CMAP | VGA_SR_FONTS;
+ else if((pNv->Chipset & 0xffff) == 0x0018)
+ restore |= VGA_SR_CMAP;
+ pNv->riva.LoadStateExt(&pNv->riva, nvReg);
+#if defined(__powerpc__)
+ restore &= ~VGA_SR_FONTS;
+#endif
+ vgaHWRestore(pScrn, vgaReg, restore);
+}
+
+/*
+ * NVDACSave
+ *
+ * This function saves the video state.
+ */
+void
+NVDACSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, NVRegPtr nvReg,
+ Bool saveFonts)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVDACSave\n"));
+
+#if defined(__powerpc__)
+ saveFonts = FALSE;
+#endif
+
+ vgaHWSave(pScrn, vgaReg, VGA_SR_CMAP | VGA_SR_MODE |
+ (saveFonts? VGA_SR_FONTS : 0));
+ pNv->riva.UnloadStateExt(&pNv->riva, nvReg);
+
+ if((pNv->Chipset & 0x0ff0) == 0x0110)
+ nvReg->crtcOwner = ((pNv->Chipset & 0x0fff) == 0x0112) ? 3 : 0;
+}
+
+#define DEPTH_SHIFT(val, w) ((val << (8 - w)) | (val >> ((w << 1) - 8)))
+#define MAKE_INDEX(in, w) (DEPTH_SHIFT(in, w) * 3)
+
+void
+NVDACLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
+ VisualPtr pVisual )
+{
+ int i, index;
+ NVPtr pNv = NVPTR(pScrn);
+ vgaRegPtr pVga;
+
+ pVga = &VGAHWPTR(pScrn)->ModeReg;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVDACLoadPalette\n"));
+
+ if((pNv->riva.Architecture == NV_ARCH_03) &&
+ (pNv->CurrentLayout.depth != 8))
+ return;
+
+ switch(pNv->CurrentLayout.depth) {
+ case 15:
+ for(i = 0; i < numColors; i++) {
+ index = indices[i];
+ pVga->DAC[MAKE_INDEX(index, 5) + 0] = colors[index].red;
+ pVga->DAC[MAKE_INDEX(index, 5) + 1] = colors[index].green;
+ pVga->DAC[MAKE_INDEX(index, 5) + 2] = colors[index].blue;
+ }
+ break;
+ case 16:
+ for(i = 0; i < numColors; i++) {
+ index = indices[i];
+ pVga->DAC[MAKE_INDEX(index, 6) + 1] = colors[index].green;
+ if(index < 32) {
+ pVga->DAC[MAKE_INDEX(index, 5) + 0] = colors[index].red;
+ pVga->DAC[MAKE_INDEX(index, 5) + 2] = colors[index].blue;
+ }
+ }
+ break;
+ default:
+ for(i = 0; i < numColors; i++) {
+ index = indices[i];
+ pVga->DAC[index*3] = colors[index].red;
+ pVga->DAC[(index*3)+1] = colors[index].green;
+ pVga->DAC[(index*3)+2] = colors[index].blue;
+ }
+ break;
+ }
+ vgaHWRestore(pScrn, pVga, VGA_SR_CMAP);
+}
+
+/*
+ * DDC1 support only requires DDC_SDA_MASK,
+ * DDC2 support requires DDC_SDA_MASK and DDC_SCL_MASK
+ */
+#define DDC_SDA_READ_MASK (1 << 3)
+#define DDC_SCL_READ_MASK (1 << 2)
+#define DDC_SDA_WRITE_MASK (1 << 4)
+#define DDC_SCL_WRITE_MASK (1 << 5)
+
+static unsigned int
+NV_ddc1Read(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ unsigned char val;
+
+ /* wait for Vsync */
+ while(VGA_RD08(pNv->riva.PCIO, 0x3da) & 0x08);
+ while(!(VGA_RD08(pNv->riva.PCIO, 0x3da) & 0x08));
+
+ /* Get the result */
+ VGA_WR08(pNv->riva.PCIO, 0x3d4, pNv->DDCBase);
+ val = VGA_RD08(pNv->riva.PCIO, 0x3d5);
+ DEBUG(ErrorF("NV_ddc1Read(%p,...) returns %d\n",
+ pScrn, val));
+ return (val & DDC_SDA_READ_MASK) != 0;
+}
+
+static void
+NV_I2CGetBits(I2CBusPtr b, int *clock, int *data)
+{
+ NVPtr pNv = NVPTR(xf86Screens[b->scrnIndex]);
+ unsigned char val;
+
+ /* Get the result. */
+ VGA_WR08(pNv->riva.PCIO, 0x3d4, pNv->DDCBase);
+ val = VGA_RD08(pNv->riva.PCIO, 0x3d5);
+
+ *clock = (val & DDC_SCL_READ_MASK) != 0;
+ *data = (val & DDC_SDA_READ_MASK) != 0;
+ DEBUG(ErrorF("NV_I2CGetBits(%p,...) val=0x%x, returns clock %d, data %d\n",
+ b, val, *clock, *data));
+}
+
+static void
+NV_I2CPutBits(I2CBusPtr b, int clock, int data)
+{
+ NVPtr pNv = NVPTR(xf86Screens[b->scrnIndex]);
+ unsigned char val;
+
+ VGA_WR08(pNv->riva.PCIO, 0x3d4, pNv->DDCBase + 1);
+ val = VGA_RD08(pNv->riva.PCIO, 0x3d5) & 0xf0;
+ if (clock)
+ val |= DDC_SCL_WRITE_MASK;
+ else
+ val &= ~DDC_SCL_WRITE_MASK;
+
+ if (data)
+ val |= DDC_SDA_WRITE_MASK;
+ else
+ val &= ~DDC_SDA_WRITE_MASK;
+
+ VGA_WR08(pNv->riva.PCIO, 0x3d4, pNv->DDCBase + 1);
+ VGA_WR08(pNv->riva.PCIO, 0x3d5, val | 0x1);
+
+ DEBUG(ErrorF("NV_I2CPutBits(%p, %d, %d) val=0x%x\n", b, clock, data, val));
+}
+
+static Bool
+NV_i2cInit(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ I2CBusPtr I2CPtr;
+
+ I2CPtr = xf86CreateI2CBusRec();
+ if(!I2CPtr) return FALSE;
+
+ pNv->I2C = I2CPtr;
+
+ I2CPtr->BusName = "DDC";
+ I2CPtr->scrnIndex = pScrn->scrnIndex;
+ I2CPtr->I2CPutBits = NV_I2CPutBits;
+ I2CPtr->I2CGetBits = NV_I2CGetBits;
+ I2CPtr->AcknTimeout = 5;
+
+ if (!xf86I2CBusInit(I2CPtr)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+ * NVRamdacInit
+ */
+void
+NVRamdacInit(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVRamdacInit\n"));
+ pNv->ddc1Read = NV_ddc1Read;
+ /* vgaHWddc1SetSpeed will only work if the card is in VGA mode */
+ pNv->DDC1SetSpeed = vgaHWddc1SetSpeed;
+ pNv->i2cInit = NV_i2cInit;
+}
+
diff --git a/src/nv_dga.c b/src/nv_dga.c
new file mode 100644
index 0000000..714467a
--- /dev/null
+++ b/src/nv_dga.c
@@ -0,0 +1,312 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_dga.c,v 1.11 2002/01/25 21:56:06 tsi Exp $ */
+
+#include "nv_local.h"
+#include "nv_include.h"
+#include "nv_type.h"
+#include "nv_proto.h"
+#include "xaalocal.h"
+#include "dgaproc.h"
+
+
+static Bool NV_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
+ int *, int *, int *);
+static Bool NV_SetMode(ScrnInfoPtr, DGAModePtr);
+static int NV_GetViewport(ScrnInfoPtr);
+static void NV_SetViewport(ScrnInfoPtr, int, int, int);
+static void NV_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
+static void NV_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
+static void NV_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int,
+ unsigned long);
+
+static
+DGAFunctionRec NV_DGAFuncs = {
+ NV_OpenFramebuffer,
+ NULL,
+ NV_SetMode,
+ NV_SetViewport,
+ NV_GetViewport,
+ NVSync,
+ NV_FillRect,
+ NV_BlitRect,
+ NV_BlitTransRect
+};
+
+
+
+static DGAModePtr
+NVSetupDGAMode(
+ ScrnInfoPtr pScrn,
+ DGAModePtr modes,
+ int *num,
+ int bitsPerPixel,
+ int depth,
+ Bool pixmap,
+ int secondPitch,
+ unsigned long red,
+ unsigned long green,
+ unsigned long blue,
+ short visualClass
+){
+ DisplayModePtr firstMode, pMode;
+ NVPtr pNv = NVPTR(pScrn);
+ DGAModePtr mode, newmodes;
+ int size, pitch, Bpp = bitsPerPixel >> 3;
+
+SECOND_PASS:
+
+ pMode = firstMode = pScrn->modes;
+
+ while(1) {
+
+ pitch = (pMode->HDisplay + 31) & ~31;
+ size = pitch * Bpp * pMode->VDisplay;
+
+ if((!secondPitch || (pitch != secondPitch)) &&
+ (size <= pNv->FbUsableSize)) {
+
+ if(secondPitch)
+ pitch = secondPitch;
+
+ if(!(newmodes = xrealloc(modes, (*num + 1) * sizeof(DGAModeRec))))
+ break;
+
+ modes = newmodes;
+ mode = modes + *num;
+
+ mode->mode = pMode;
+ mode->flags = DGA_CONCURRENT_ACCESS;
+
+ if(pixmap)
+ mode->flags |= DGA_PIXMAP_AVAILABLE;
+ if(!pNv->NoAccel)
+ mode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT;
+ if(pMode->Flags & V_DBLSCAN)
+ mode->flags |= DGA_DOUBLESCAN;
+ if(pMode->Flags & V_INTERLACE)
+ mode->flags |= DGA_INTERLACED;
+ mode->byteOrder = pScrn->imageByteOrder;
+ mode->depth = depth;
+ mode->bitsPerPixel = bitsPerPixel;
+ mode->red_mask = red;
+ mode->green_mask = green;
+ mode->blue_mask = blue;
+ mode->visualClass = visualClass;
+ mode->viewportWidth = pMode->HDisplay;
+ mode->viewportHeight = pMode->VDisplay;
+ mode->xViewportStep = 4 / Bpp;
+ mode->yViewportStep = 1;
+ mode->viewportFlags = DGA_FLIP_RETRACE;
+ mode->offset = 0;
+ mode->address = pNv->FbStart;
+ mode->bytesPerScanline = pitch * Bpp;
+ mode->imageWidth = pitch;
+ mode->imageHeight = pNv->FbUsableSize / mode->bytesPerScanline;
+ mode->pixmapWidth = mode->imageWidth;
+ mode->pixmapHeight = mode->imageHeight;
+ mode->maxViewportX = mode->imageWidth - mode->viewportWidth;
+ mode->maxViewportY = mode->imageHeight - mode->viewportHeight;
+ (*num)++;
+ }
+
+ pMode = pMode->next;
+ if(pMode == firstMode)
+ break;
+ }
+
+ if(secondPitch) {
+ secondPitch = 0;
+ goto SECOND_PASS;
+ }
+
+ return modes;
+}
+
+
+Bool
+NVDGAInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ NVPtr pNv = NVPTR(pScrn);
+ DGAModePtr modes = NULL;
+ int num = 0;
+
+ /* 8 */
+ modes = NVSetupDGAMode (pScrn, modes, &num, 8, 8,
+ (pScrn->bitsPerPixel == 8),
+ (pScrn->bitsPerPixel != 8) ? 0 : pScrn->displayWidth,
+ 0, 0, 0, PseudoColor);
+
+ /* 15 */
+ modes = NVSetupDGAMode (pScrn, modes, &num, 16, 15,
+ (pScrn->bitsPerPixel == 16),
+ (pScrn->depth != 15) ? 0 : pScrn->displayWidth,
+ 0x7c00, 0x03e0, 0x001f, TrueColor);
+
+ /* 16 */
+ if(pNv->riva.Architecture != 3)
+ modes = NVSetupDGAMode (pScrn, modes, &num, 16, 16,
+ (pScrn->bitsPerPixel == 16),
+ (pScrn->depth != 16) ? 0 : pScrn->displayWidth,
+ 0xf800, 0x07e0, 0x001f, TrueColor);
+
+ /* 32 */
+ modes = NVSetupDGAMode (pScrn, modes, &num, 32, 24,
+ (pScrn->bitsPerPixel == 32),
+ (pScrn->bitsPerPixel != 32) ? 0 : pScrn->displayWidth,
+ 0xff0000, 0x00ff00, 0x0000ff, TrueColor);
+
+ pNv->numDGAModes = num;
+ pNv->DGAModes = modes;
+
+ return DGAInit(pScreen, &NV_DGAFuncs, modes, num);
+}
+
+
+static int
+BitsSet(unsigned long data)
+{
+ unsigned long mask;
+ int set = 0;
+
+ for(mask = 1; mask; mask <<= 1)
+ if(mask & data) set++;
+
+ return set;
+}
+
+static Bool
+NV_SetMode(
+ ScrnInfoPtr pScrn,
+ DGAModePtr pMode
+){
+ static NVFBLayout SavedLayouts[MAXSCREENS];
+ int index = pScrn->pScreen->myNum;
+
+ NVPtr pNv = NVPTR(pScrn);
+
+ if(!pMode) { /* restore the original mode */
+ if(pNv->DGAactive)
+ memcpy(&pNv->CurrentLayout, &SavedLayouts[index], sizeof(NVFBLayout));
+
+ pScrn->currentMode = pNv->CurrentLayout.mode;
+ NVSwitchMode(index, pScrn->currentMode, 0);
+ NVAdjustFrame(index, pScrn->frameX0, pScrn->frameY0, 0);
+ pNv->DGAactive = FALSE;
+ } else {
+ if(!pNv->DGAactive) { /* save the old parameters */
+ memcpy(&SavedLayouts[index], &pNv->CurrentLayout, sizeof(NVFBLayout));
+ pNv->DGAactive = TRUE;
+ }
+
+ /* update CurrentLayout */
+ pNv->CurrentLayout.bitsPerPixel = pMode->bitsPerPixel;
+ pNv->CurrentLayout.depth = pMode->depth;
+ pNv->CurrentLayout.displayWidth = pMode->bytesPerScanline /
+ (pMode->bitsPerPixel >> 3);
+ pNv->CurrentLayout.weight.red = BitsSet(pMode->red_mask);
+ pNv->CurrentLayout.weight.green = BitsSet(pMode->green_mask);
+ pNv->CurrentLayout.weight.blue = BitsSet(pMode->blue_mask);
+ /* NVModeInit() will set the mode field */
+ NVSwitchMode(index, pMode->mode, 0);
+ }
+
+ return TRUE;
+}
+
+
+
+static int
+NV_GetViewport(
+ ScrnInfoPtr pScrn
+){
+ NVPtr pNv = NVPTR(pScrn);
+
+ return pNv->DGAViewportStatus;
+}
+
+static void
+NV_SetViewport(
+ ScrnInfoPtr pScrn,
+ int x, int y,
+ int flags
+){
+ NVPtr pNv = NVPTR(pScrn);
+
+ NVAdjustFrame(pScrn->pScreen->myNum, x, y, flags);
+
+ while(VGA_RD08(pNv->riva.PCIO, 0x3da) & 0x08);
+ while(!(VGA_RD08(pNv->riva.PCIO, 0x3da) & 0x08));
+
+ pNv->DGAViewportStatus = 0;
+}
+
+static void
+NV_FillRect (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned long color
+){
+ NVPtr pNv = NVPTR(pScrn);
+
+ if(!pNv->AccelInfoRec) return;
+
+ (*pNv->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0);
+ (*pNv->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
+
+ SET_SYNC_FLAG(pNv->AccelInfoRec);
+}
+
+static void
+NV_BlitRect(
+ ScrnInfoPtr pScrn,
+ int srcx, int srcy,
+ int w, int h,
+ int dstx, int dsty
+){
+ NVPtr pNv = NVPTR(pScrn);
+ int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
+ int ydir = (srcy < dsty) ? -1 : 1;
+
+ if(!pNv->AccelInfoRec) return;
+
+ (*pNv->AccelInfoRec->SetupForScreenToScreenCopy)(
+ pScrn, xdir, ydir, GXcopy, ~0, -1);
+
+ (*pNv->AccelInfoRec->SubsequentScreenToScreenCopy)(
+ pScrn, srcx, srcy, dstx, dsty, w, h);
+
+ SET_SYNC_FLAG(pNv->AccelInfoRec);
+}
+
+
+static void
+NV_BlitTransRect(
+ ScrnInfoPtr pScrn,
+ int srcx, int srcy,
+ int w, int h,
+ int dstx, int dsty,
+ unsigned long color
+){
+ /* not implemented... yet */
+}
+
+
+static Bool
+NV_OpenFramebuffer(
+ ScrnInfoPtr pScrn,
+ char **name,
+ unsigned char **mem,
+ int *size,
+ int *offset,
+ int *flags
+){
+ NVPtr pNv = NVPTR(pScrn);
+
+ *name = NULL; /* no special device */
+ *mem = (unsigned char*)pNv->FbAddress;
+ *size = pNv->FbMapSize;
+ *offset = 0;
+ *flags = DGA_NEED_ROOT;
+
+ return TRUE;
+}
diff --git a/src/nv_driver.c b/src/nv_driver.c
new file mode 100644
index 0000000..92d4599
--- /dev/null
+++ b/src/nv_driver.c
@@ -0,0 +1,1934 @@
+/* $XConsortium: nv_driver.c /main/3 1996/10/28 05:13:37 kaleb $ */
+/*
+ * Copyright 1996-1997 David J. McKay
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * DAVID J. MCKAY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* 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.101 2003/02/10 23:42:51 mvojkovi Exp $ */
+
+#include "nv_include.h"
+
+#include "xf86int10.h"
+
+/*
+ * Forward definitions for the functions that make up the driver.
+ */
+/* Mandatory functions */
+static const OptionInfoRec * NVAvailableOptions(int chipid, int busid);
+static void NVIdentify(int flags);
+static Bool NVProbe(DriverPtr drv, int flags);
+static Bool NVPreInit(ScrnInfoPtr pScrn, int flags);
+static Bool NVScreenInit(int Index, ScreenPtr pScreen, int argc,
+ char **argv);
+static Bool NVEnterVT(int scrnIndex, int flags);
+static Bool NVEnterVTFBDev(int scrnIndex, int flags);
+static void NVLeaveVT(int scrnIndex, int flags);
+static Bool NVCloseScreen(int scrnIndex, ScreenPtr pScreen);
+static Bool NVSaveScreen(ScreenPtr pScreen, int mode);
+
+/* Optional functions */
+static void NVFreeScreen(int scrnIndex, int flags);
+static int NVValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose,
+ int flags);
+
+/* Internally used functions */
+
+static Bool NVMapMem(ScrnInfoPtr pScrn);
+static Bool NVMapMemFBDev(ScrnInfoPtr pScrn);
+static Bool NVUnmapMem(ScrnInfoPtr pScrn);
+static void NVSave(ScrnInfoPtr pScrn);
+static void NVRestore(ScrnInfoPtr pScrn);
+static Bool NVModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+
+
+/*
+ * This contains the functions needed by the server after loading the
+ * driver module. It must be supplied, and gets added the driver list by
+ * the Module Setup funtion in the dynamic case. In the static case a
+ * reference to this is compiled in, and this requires that the name of
+ * this DriverRec be an upper-case version of the driver name.
+ */
+
+DriverRec NV = {
+ VERSION,
+ NV_DRIVER_NAME,
+ NVIdentify,
+ NVProbe,
+ NVAvailableOptions,
+ NULL,
+ 0
+};
+
+static SymTabRec NVKnownChipsets[] =
+{
+ { 0x12D20018, "RIVA 128" },
+ { 0x10DE0020, "RIVA TNT" },
+ { 0x10DE0028, "RIVA TNT2" },
+ { 0x10DE002C, "Vanta" },
+ { 0x10DE0029, "RIVA TNT2 Ultra" },
+ { 0x10DE002D, "RIVA TNT2 Model 64" },
+ { 0x10DE00A0, "Aladdin TNT2" },
+ { 0x10DE0100, "GeForce 256" },
+ { 0x10DE0101, "GeForce DDR" },
+ { 0x10DE0103, "Quadro" },
+ { 0x10DE0110, "GeForce2 MX/MX 400" },
+ { 0x10DE0111, "GeForce2 MX 100/200" },
+ { 0x10DE0112, "GeForce2 Go" },
+ { 0x10DE0113, "Quadro2 MXR/EX/Go" },
+ { 0x10DE01A0, "GeForce2 Integrated GPU" },
+ { 0x10DE0150, "GeForce2 GTS" },
+ { 0x10DE0151, "GeForce2 Ti" },
+ { 0x10DE0152, "GeForce2 Ultra" },
+ { 0x10DE0153, "Quadro2 Pro" },
+ { 0x10DE0170, "GeForce4 MX 460" },
+ { 0x10DE0171, "GeForce4 MX 440" },
+ { 0x10DE0172, "GeForce4 MX 420" },
+ { 0x10DE0173, "GeForce4 MX 440-SE" },
+ { 0x10DE0174, "GeForce4 440 Go" },
+ { 0x10DE0175, "GeForce4 420 Go" },
+ { 0x10DE0176, "GeForce4 420 Go 32M" },
+ { 0x10DE0177, "GeForce4 460 Go" },
+ { 0x10DE0179, "GeForce4 440 Go 64M" },
+ { 0x10DE017D, "GeForce4 410 Go 16M" },
+ { 0x10DE017C, "Quadro4 500 GoGL" },
+ { 0x10DE0178, "Quadro4 550 XGL" },
+ { 0x10DE017A, "Quadro4 NVS" },
+ { 0x10DE0181, "GeForce4 MX 440 with AGP8X" },
+ { 0x10DE0182, "GeForce4 MX 440SE with AGP8X" },
+ { 0x10DE0183, "GeForce4 MX 420 with AGP8X" },
+ { 0x10DE0186, "GeForce4 448 Go" },
+ { 0x10DE0187, "GeForce4 488 Go" },
+ { 0x10DE0188, "Quadro4 580 XGL" },
+ { 0x10DE018A, "Quadro4 280 NVS" },
+ { 0x10DE018B, "Quadro4 380 XGL" },
+ { 0x10DE01F0, "GeForce4 MX Integrated GPU" },
+ { 0x10DE0200, "GeForce3" },
+ { 0x10DE0201, "GeForce3 Ti 200" },
+ { 0x10DE0202, "GeForce3 Ti 500" },
+ { 0x10DE0203, "Quadro DCC" },
+ { 0x10DE0250, "GeForce4 Ti 4600" },
+ { 0x10DE0251, "GeForce4 Ti 4400" },
+ { 0x10DE0252, "0x0252" },
+ { 0x10DE0253, "GeForce4 Ti 4200" },
+ { 0x10DE0258, "Quadro4 900 XGL" },
+ { 0x10DE0259, "Quadro4 750 XGL" },
+ { 0x10DE025B, "Quadro4 700 XGL" },
+ { 0x10DE0280, "GeForce4 Ti 4800" },
+ { 0x10DE0281, "GeForce4 Ti 4200 with AGP8X" },
+ { 0x10DE0282, "GeForce4 Ti 4800 SE" },
+ { 0x10DE0286, "GeForce4 4200 Go" },
+ { 0x10DE028C, "Quadro4 700 GoGL" },
+ { 0x10DE0288, "Quadro4 980 XGL" },
+ { 0x10DE0289, "Quadro4 780 XGL" },
+ { 0x10DE0300, "0x0300" },
+ { 0x10DE0301, "GeForce FX 5800 Ultra" },
+ { 0x10DE0302, "GeForce FX 5800" },
+ { 0x10DE0308, "Quadro FX 2000" },
+ { 0x10DE0309, "Quadro FX 1000" },
+ { 0x10DE0311, "0x0311" },
+ { 0x10DE0312, "0x0312" },
+ { 0x10DE0316, "0x0316" },
+ { 0x10DE0317, "0x0317" },
+ { 0x10DE0318, "0x0318" },
+ { 0x10DE0319, "0x0319" },
+ { 0x10DE031A, "0x031A" },
+ { 0x10DE031B, "0x031B" },
+ { 0x10DE031C, "0x031C" },
+ { 0x10DE031D, "0x031D" },
+ { 0x10DE031E, "0x031E" },
+ { 0x10DE031F, "0x031F" },
+ { 0x10DE0321, "0x0321" },
+ { 0x10DE0322, "0x0322" },
+ { 0x10DE0323, "0x0323" },
+ { 0x10DE0326, "0x0326" },
+ { 0x10DE032A, "0x032A" },
+ { 0x10DE032B, "0x032B" },
+ { 0x10DE032E, "0x032E" },
+ {-1, NULL}
+};
+
+
+/*
+ * List of symbols from other modules that this module references. This
+ * list is used to tell the loader that it is OK for symbols here to be
+ * unresolved providing that it hasn't been told that they haven't been
+ * told that they are essential via a call to xf86LoaderReqSymbols() or
+ * xf86LoaderReqSymLists(). The purpose is this is to avoid warnings about
+ * unresolved symbols that are not required.
+ */
+
+static const char *vgahwSymbols[] = {
+ "vgaHWDPMSSet",
+ "vgaHWFreeHWRec",
+ "vgaHWGetHWRec",
+ "vgaHWGetIndex",
+ "vgaHWInit",
+ "vgaHWMapMem",
+ "vgaHWProtect",
+ "vgaHWRestore",
+ "vgaHWSave",
+ "vgaHWSaveScreen",
+ "vgaHWddc1SetSpeed",
+ NULL
+};
+
+static const char *fbSymbols[] = {
+ "fbPictureInit",
+ "fbScreenInit",
+ NULL
+};
+
+static const char *xaaSymbols[] = {
+ "XAACopyROP",
+ "XAACreateInfoRec",
+ "XAADestroyInfoRec",
+ "XAAFallbackOps",
+ "XAAInit",
+ "XAAPatternROP",
+ NULL
+};
+
+static const char *ramdacSymbols[] = {
+ "xf86CreateCursorInfoRec",
+ "xf86DestroyCursorInfoRec",
+ "xf86InitCursor",
+ NULL
+};
+
+#define NVuseI2C 1
+
+static const char *ddcSymbols[] = {
+ "xf86PrintEDID",
+ "xf86DoEDID_DDC1",
+#if NVuseI2C
+ "xf86DoEDID_DDC2",
+#endif
+ "xf86SetDDCproperties",
+ NULL
+};
+
+static const char *vbeSymbols[] = {
+ "VBEInit",
+ "vbeDoEDID",
+ "vbeFree",
+ NULL
+};
+
+static const char *i2cSymbols[] = {
+ "xf86CreateI2CBusRec",
+ "xf86I2CBusInit",
+ NULL
+};
+
+static const char *shadowSymbols[] = {
+ "ShadowFBInit",
+ NULL
+};
+
+static const char *fbdevHWSymbols[] = {
+ "fbdevHWInit",
+ "fbdevHWUseBuildinMode",
+
+ "fbdevHWGetVidmem",
+
+ /* colormap */
+ "fbdevHWLoadPalette",
+
+ /* ScrnInfo hooks */
+ "fbdevHWAdjustFrame",
+ "fbdevHWEnterVT",
+ "fbdevHWLeaveVT",
+ "fbdevHWModeInit",
+ "fbdevHWSave",
+ "fbdevHWSwitchMode",
+ "fbdevHWValidMode",
+
+ "fbdevHWMapMMIO",
+ "fbdevHWMapVidmem",
+
+ NULL
+};
+
+static const char *int10Symbols[] = {
+ "xf86FreeInt10",
+ "xf86InitInt10",
+ NULL
+};
+
+
+#ifdef XFree86LOADER
+
+static MODULESETUPPROTO(nvSetup);
+
+static XF86ModuleVersionInfo nvVersRec =
+{
+ "nv",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ NV_MAJOR_VERSION, NV_MINOR_VERSION, NV_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV, /* This is a video driver */
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0,0,0,0}
+};
+
+XF86ModuleData nvModuleData = { &nvVersRec, nvSetup, NULL };
+#endif
+
+
+typedef enum {
+ OPTION_SW_CURSOR,
+ OPTION_HW_CURSOR,
+ OPTION_NOACCEL,
+ OPTION_SHOWCACHE,
+ OPTION_SHADOW_FB,
+ OPTION_FBDEV,
+ OPTION_ROTATE,
+ OPTION_VIDEO_KEY,
+ OPTION_FLAT_PANEL,
+ OPTION_FP_DITHER,
+ OPTION_CRTC_NUMBER
+} NVOpts;
+
+
+static const OptionInfoRec NVOptions[] = {
+ { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SHOWCACHE, "ShowCache", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_FBDEV, "UseFBDev", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE },
+ { OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_FLAT_PANEL, "FlatPanel", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_FP_DITHER, "FPDither", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_CRTC_NUMBER, "CrtcNumber", OPTV_INTEGER, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+/*
+ * This is intentionally screen-independent. It indicates the binding
+ * choice made in the first PreInit.
+ */
+static int pix24bpp = 0;
+
+/*
+ * ramdac info structure initialization
+ */
+static NVRamdacRec DacInit = {
+ FALSE, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL,
+ 0, NULL, NULL, NULL, NULL
+};
+
+
+
+static Bool
+NVGetRec(ScrnInfoPtr pScrn)
+{
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVGetRec\n"));
+ /*
+ * Allocate an NVRec, and hook it into pScrn->driverPrivate.
+ * pScrn->driverPrivate is initialised to NULL, so we can check if
+ * the allocation has already been done.
+ */
+ if (pScrn->driverPrivate != NULL)
+ return TRUE;
+
+ pScrn->driverPrivate = xnfcalloc(sizeof(NVRec), 1);
+ /* Initialise it */
+
+ NVPTR(pScrn)->Dac = DacInit;
+ return TRUE;
+}
+
+static void
+NVFreeRec(ScrnInfoPtr pScrn)
+{
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVFreeRec\n"));
+
+ if (pScrn->driverPrivate == NULL)
+ return;
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+}
+
+
+#ifdef XFree86LOADER
+
+static pointer
+nvSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ /* This module should be loaded only once, but check to be sure. */
+
+ if (!setupDone) {
+ setupDone = TRUE;
+ xf86AddDriver(&NV, module, 0);
+
+ /*
+ * Modules that this driver always requires may be loaded here
+ * by calling LoadSubModule().
+ */
+
+ /*
+ * Tell the loader about symbols from other modules that this module
+ * might refer to.
+ */
+ LoaderRefSymLists(vgahwSymbols, xaaSymbols, fbSymbols,
+ ramdacSymbols, shadowSymbols,
+ i2cSymbols, ddcSymbols, vbeSymbols,
+ fbdevHWSymbols, int10Symbols, NULL);
+
+ /*
+ * The return value must be non-NULL on success even though there
+ * is no TearDownProc.
+ */
+ return (pointer)1;
+ } else {
+ if (errmaj) *errmaj = LDR_ONCEONLY;
+ return NULL;
+ }
+}
+
+
+#endif /* XFree86LOADER */
+
+static const OptionInfoRec *
+NVAvailableOptions(int chipid, int busid)
+{
+ return NVOptions;
+}
+
+/* Mandatory */
+static void
+NVIdentify(int flags)
+{
+ xf86PrintChipsets(NV_NAME, "driver for NVIDIA chipsets", NVKnownChipsets);
+}
+
+
+#define MAX_CHIPS MAXSCREENS
+
+/* Mandatory */
+static Bool
+NVProbe(DriverPtr drv, int flags)
+{
+ int i;
+ GDevPtr *devSections;
+ int *usedChips;
+ SymTabRec NVChipsets[MAX_CHIPS + 1];
+ PciChipsets NVPciChipsets[MAX_CHIPS + 1];
+ pciVideoPtr *ppPci;
+ int numDevSections;
+ int numUsed;
+ Bool foundScreen = FALSE;
+
+
+ if ((numDevSections = xf86MatchDevice(NV_DRIVER_NAME, &devSections)) <= 0)
+ return FALSE; /* no matching device section */
+
+ if (!(ppPci = xf86GetPciVideoInfo()))
+ return FALSE; /* no PCI cards found */
+
+ numUsed = 0;
+
+ /* Create the NVChipsets and NVPciChipsets from found devices */
+ while (*ppPci && (numUsed < MAX_CHIPS)) {
+ if(((*ppPci)->vendor == PCI_VENDOR_NVIDIA_SGS) ||
+ ((*ppPci)->vendor == PCI_VENDOR_NVIDIA))
+ {
+ SymTabRec *nvchips = NVKnownChipsets;
+ int token = ((*ppPci)->vendor << 16) | (*ppPci)->chipType;
+
+ while(nvchips->name) {
+ if(token == nvchips->token)
+ break;
+ nvchips++;
+ }
+
+ if(nvchips->name) { /* found one */
+ NVChipsets[numUsed].token = nvchips->token;
+ NVChipsets[numUsed].name = nvchips->name;
+ NVPciChipsets[numUsed].numChipset = nvchips->token;
+ NVPciChipsets[numUsed].PCIid = nvchips->token;
+ NVPciChipsets[numUsed].resList = RES_SHARED_VGA;
+ numUsed++;
+ } else if ((*ppPci)->vendor == PCI_VENDOR_NVIDIA) {
+ /* look for a compatible devices which may be newer than
+ the NVKnownChipsets list above. */
+ switch(token & 0xfff0) {
+ case 0x0170:
+ case 0x0180:
+ case 0x0250:
+ case 0x0280:
+ case 0x0300:
+ case 0x0310:
+ case 0x0320:
+ case 0x0330:
+ case 0x0340:
+ NVChipsets[numUsed].token = token;
+ NVChipsets[numUsed].name = "Unknown NVIDIA chip";
+ NVPciChipsets[numUsed].numChipset = token;
+ NVPciChipsets[numUsed].PCIid = token;
+ NVPciChipsets[numUsed].resList = RES_SHARED_VGA;
+ numUsed++;
+ break;
+ default: break; /* we don't recognize it */
+ }
+ }
+ }
+ ppPci++;
+ }
+
+ /* terminate the list */
+ NVChipsets[numUsed].token = -1;
+ NVChipsets[numUsed].name = NULL;
+ NVPciChipsets[numUsed].numChipset = -1;
+ NVPciChipsets[numUsed].PCIid = -1;
+ NVPciChipsets[numUsed].resList = RES_UNDEFINED;
+
+ numUsed = xf86MatchPciInstances(NV_NAME, 0, NVChipsets, NVPciChipsets,
+ devSections, numDevSections, drv,
+ &usedChips);
+
+ if (numUsed <= 0)
+ return FALSE;
+
+ if (flags & PROBE_DETECT)
+ foundScreen = TRUE;
+ else for (i = 0; i < numUsed; i++) {
+ ScrnInfoPtr pScrn = NULL;
+
+ /* Allocate a ScrnInfoRec and claim the slot */
+ if ((pScrn = xf86ConfigPciEntity(pScrn, 0,usedChips[i],
+ NVPciChipsets, NULL, NULL, NULL,
+ NULL, NULL))) {
+
+ /* Fill in what we can of the ScrnInfoRec */
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = NV_DRIVER_NAME;
+ pScrn->name = NV_NAME;
+ pScrn->Probe = NVProbe;
+ pScrn->PreInit = NVPreInit;
+ pScrn->ScreenInit = NVScreenInit;
+ pScrn->SwitchMode = NVSwitchMode;
+ pScrn->AdjustFrame = NVAdjustFrame;
+ pScrn->EnterVT = NVEnterVT;
+ pScrn->LeaveVT = NVLeaveVT;
+ pScrn->FreeScreen = NVFreeScreen;
+ pScrn->ValidMode = NVValidMode;
+ foundScreen = TRUE;
+ }
+ }
+
+ xfree(devSections);
+ xfree(usedChips);
+
+ return foundScreen;
+}
+
+/* Usually mandatory */
+Bool
+NVSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "NVSwitchMode\n"));
+ return NVModeInit(xf86Screens[scrnIndex], mode);
+}
+
+/*
+ * This function is used to initialize the Start Address - the first
+ * displayed location in the video memory.
+ */
+/* Usually mandatory */
+void
+NVAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ int startAddr;
+ NVPtr pNv = NVPTR(pScrn);
+ NVFBLayout *pLayout = &pNv->CurrentLayout;
+
+ DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "NVAdjustFrame\n"));
+
+ if(pNv->ShowCache && y && pScrn->vtSema)
+ y += pScrn->virtualY - 1;
+
+ startAddr = (((y*pLayout->displayWidth)+x)*(pLayout->bitsPerPixel/8));
+ pNv->riva.SetStartAddress(&pNv->riva, startAddr);
+}
+
+
+/*
+ * This is called when VT switching back to the X server. Its job is
+ * to reinitialise the video mode.
+ *
+ * We may wish to unmap video/MMIO memory too.
+ */
+
+/* Mandatory */
+static Bool
+NVEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ NVPtr pNv = NVPTR(pScrn);
+
+ DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "NVEnterVT\n"));
+
+ if (!NVModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+ NVAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ if(pNv->overlayAdaptor)
+ NVResetVideo(pScrn);
+ return TRUE;
+}
+
+static Bool
+NVEnterVTFBDev(int scrnIndex, int flags)
+{
+ DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "NVEnterVTFBDev\n"));
+
+ fbdevHWEnterVT(scrnIndex,flags);
+ return TRUE;
+}
+
+/*
+ * This is called when VT switching away from the X server. Its job is
+ * to restore the previous (text) mode.
+ *
+ * We may wish to remap video/MMIO memory too.
+ */
+
+/* Mandatory */
+static void
+NVLeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ NVPtr pNv = NVPTR(pScrn);
+
+ DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "NVLeaveVT\n"));
+
+ NVRestore(pScrn);
+ pNv->riva.LockUnlock(&pNv->riva, 1);
+}
+
+
+
+static void
+NVBlockHandler (
+ int i,
+ pointer blockData,
+ pointer pTimeout,
+ pointer pReadmask
+)
+{
+ ScreenPtr pScreen = screenInfo.screens[i];
+ ScrnInfoPtr pScrnInfo = xf86Screens[i];
+ NVPtr pNv = NVPTR(pScrnInfo);
+
+ pScreen->BlockHandler = pNv->BlockHandler;
+ (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
+ pScreen->BlockHandler = NVBlockHandler;
+
+ if (pNv->VideoTimerCallback)
+ (*pNv->VideoTimerCallback)(pScrnInfo, currentTime.milliseconds);
+
+}
+
+
+/*
+ * This is called at the end of each server generation. It restores the
+ * original (text) mode. It should also unmap the video memory, and free
+ * any per-generation data allocated by the driver. It should finish
+ * by unwrapping and calling the saved CloseScreen function.
+ */
+
+/* Mandatory */
+static Bool
+NVCloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ NVPtr pNv = NVPTR(pScrn);
+
+ DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "NVCloseScreen\n"));
+
+ if (pScrn->vtSema) {
+ NVRestore(pScrn);
+ pNv->riva.LockUnlock(&pNv->riva, 1);
+ }
+
+ NVUnmapMem(pScrn);
+ vgaHWUnmapMem(pScrn);
+ if (pNv->AccelInfoRec)
+ XAADestroyInfoRec(pNv->AccelInfoRec);
+ if (pNv->CursorInfoRec)
+ xf86DestroyCursorInfoRec(pNv->CursorInfoRec);
+ if (pNv->ShadowPtr)
+ xfree(pNv->ShadowPtr);
+ if (pNv->DGAModes)
+ xfree(pNv->DGAModes);
+ if ( pNv->expandBuffer )
+ xfree(pNv->expandBuffer);
+ if (pNv->overlayAdaptor)
+ xfree(pNv->overlayAdaptor);
+
+ pScrn->vtSema = FALSE;
+ pScreen->CloseScreen = pNv->CloseScreen;
+ pScreen->BlockHandler = pNv->BlockHandler;
+ return (*pScreen->CloseScreen)(scrnIndex, pScreen);
+}
+
+/* Free up any persistent data structures */
+
+/* Optional */
+static void
+NVFreeScreen(int scrnIndex, int flags)
+{
+ DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "NVFreeScreen\n"));
+ /*
+ * This only gets called when a screen is being deleted. It does not
+ * get called routinely at the end of a server generation.
+ */
+ if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
+ vgaHWFreeHWRec(xf86Screens[scrnIndex]);
+ NVFreeRec(xf86Screens[scrnIndex]);
+}
+
+
+/* Checks if a mode is suitable for the selected chipset. */
+
+/* Optional */
+static int
+NVValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+{
+ DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "NVValidMode\n"));
+ /* HACK HACK HACK */
+ return (MODE_OK);
+}
+
+static xf86MonPtr
+nvDoDDC2(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ xf86MonPtr MonInfo = NULL;
+
+ if (!pNv->i2cInit) return NULL;
+
+ /* - DDC can use I2C bus */
+ /* Load I2C if we have the code to use it */
+ if ( xf86LoadSubModule(pScrn, "i2c") ) {
+ xf86LoaderReqSymLists(i2cSymbols,NULL);
+ if (pNv->i2cInit(pScrn)) {
+ DEBUG(ErrorF("I2C initialized on %p\n",pNv->I2C));
+ if ((MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex,pNv->I2C))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "DDC Monitor info: %p\n",
+ MonInfo);
+ xf86PrintEDID( MonInfo );
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "end of DDC Monitor "
+ "info\n\n");
+ xf86SetDDCproperties(pScrn,MonInfo);
+ }
+ }
+ }
+ return MonInfo;
+}
+
+#if 0
+static xf86MonPtr
+nvDoDDC1(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ xf86MonPtr MonInfo = NULL;
+
+ if (!pNv->ddc1Read || !pNv->DDC1SetSpeed) return NULL;
+ if (!pNv->Primary
+ && (pNv->DDC1SetSpeed == vgaHWddc1SetSpeed)) return NULL;
+
+ if ((MonInfo = xf86DoEDID_DDC1(pScrn->scrnIndex, pNv->DDC1SetSpeed,
+ pNv->ddc1Read ))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "DDC Monitor info: %p\n",
+ MonInfo);
+ xf86PrintEDID( MonInfo );
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "end of DDC Monitor info\n\n");
+ xf86SetDDCproperties(pScrn,MonInfo);
+ }
+ return MonInfo;
+}
+#endif
+
+/*
+static xf86MonPtr
+nvDoDDCVBE(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ xf86MonPtr MonInfo = NULL;
+ vbeInfoPtr pVbe;
+
+ if (xf86LoadSubModule(pScrn, "vbe")) {
+ xf86LoaderReqSymLists(vbeSymbols,NULL);
+ pVbe = VBEInit(pNv->pInt,pNv->pEnt->index);
+ if (pVbe) {
+ if ((MonInfo = vbeDoEDID(pVbe,NULL))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "DDC Monitor info: %p\n",
+ MonInfo);
+ xf86PrintEDID( MonInfo );
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "end of DDC Monitor info\n\n");
+ xf86SetDDCproperties(pScrn,MonInfo);
+ }
+ vbeFree(pVbe);
+ }
+ }
+ return MonInfo;
+}
+*/
+
+/* Internally used */
+xf86MonPtr
+NVdoDDC(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv;
+ NVRamdacPtr NVdac;
+ xf86MonPtr MonInfo = NULL;
+
+ pNv = NVPTR(pScrn);
+ NVdac = &pNv->Dac;
+
+ /* Load DDC if we have the code to use it */
+
+ if (!xf86LoadSubModule(pScrn, "ddc")) return NULL;
+
+ xf86LoaderReqSymLists(ddcSymbols, NULL);
+
+ /* if ((MonInfo = nvDoDDCVBE(pScrn))) return MonInfo; */
+
+ /* Enable access to extended registers */
+ pNv->riva.LockUnlock(&pNv->riva, 0);
+ /* Save the current state */
+ NVSave(pScrn);
+
+ if ((MonInfo = nvDoDDC2(pScrn))) goto done;
+#if 0 /* disable for now - causes problems on AXP */
+ if ((MonInfo = nvDoDDC1(pScrn))) goto done;
+#endif
+
+ done:
+ /* Restore previous state */
+ NVRestore(pScrn);
+ pNv->riva.LockUnlock(&pNv->riva, 1);
+
+ return MonInfo;
+}
+
+static void
+nvProbeDDC(ScrnInfoPtr pScrn, int index)
+{
+ vbeInfoPtr pVbe;
+
+ if (xf86LoadSubModule(pScrn, "vbe")) {
+ pVbe = VBEInit(NULL,index);
+ ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
+ vbeFree(pVbe);
+ }
+}
+
+/* Mandatory */
+Bool
+NVPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ NVPtr pNv;
+ MessageType from;
+ int i;
+ int bytesPerPixel;
+ ClockRangePtr clockRanges;
+ const char *s;
+
+ if (flags & PROBE_DETECT) {
+ nvProbeDDC( pScrn, xf86GetEntityInfo(pScrn->entityList[0])->index );
+ return TRUE;
+ }
+
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVPreInit\n"));
+ /*
+ * Note: This function is only called once at server startup, and
+ * not at the start of each server generation. This means that
+ * only things that are persistent across server generations can
+ * be initialised here. xf86Screens[] is (pScrn is a pointer to one
+ * of these). Privates allocated using xf86AllocateScrnInfoPrivateIndex()
+ * are too, and should be used for data that must persist across
+ * server generations.
+ *
+ * Per-generation data should be allocated with
+ * AllocateScreenPrivateIndex() from the ScreenInit() function.
+ */
+
+ /* Check the number of entities, and fail if it isn't one. */
+ if (pScrn->numEntities != 1)
+ return FALSE;
+
+ /* Allocate the NVRec driverPrivate */
+ if (!NVGetRec(pScrn)) {
+ return FALSE;
+ }
+ pNv = NVPTR(pScrn);
+
+ /* Get the entity, and make sure it is PCI. */
+ pNv->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+ if (pNv->pEnt->location.type != BUS_PCI)
+ return FALSE;
+
+ /* Find the PCI info for this screen */
+ pNv->PciInfo = xf86GetPciInfoForEntity(pNv->pEnt->index);
+ pNv->PciTag = pciTag(pNv->PciInfo->bus, pNv->PciInfo->device,
+ pNv->PciInfo->func);
+
+ pNv->Primary = xf86IsPrimaryPci(pNv->PciInfo);
+
+ /* Initialize the card through int10 interface if needed */
+ if (xf86LoadSubModule(pScrn, "int10")) {
+ xf86LoaderReqSymLists(int10Symbols, NULL);
+#if !defined(__alpha__) && !defined(__powerpc__)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initializing int10\n");
+ pNv->pInt = xf86InitInt10(pNv->pEnt->index);
+#endif
+ }
+
+ xf86SetOperatingState(resVgaIo, pNv->pEnt->index, ResUnusedOpr);
+ xf86SetOperatingState(resVgaMem, pNv->pEnt->index, ResDisableOpr);
+
+ /* Set pScrn->monitor */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ /*
+ * Set the Chipset and ChipRev, allowing config file entries to
+ * override.
+ */
+ if (pNv->pEnt->device->chipset && *pNv->pEnt->device->chipset) {
+ pScrn->chipset = pNv->pEnt->device->chipset;
+ pNv->Chipset = xf86StringToToken(NVKnownChipsets, pScrn->chipset);
+ from = X_CONFIG;
+ } else if (pNv->pEnt->device->chipID >= 0) {
+ pNv->Chipset = pNv->pEnt->device->chipID;
+ pScrn->chipset = (char *)xf86TokenToString(NVKnownChipsets,
+ pNv->Chipset);
+ from = X_CONFIG;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
+ pNv->Chipset);
+ } else {
+ from = X_PROBED;
+ pNv->Chipset = (pNv->PciInfo->vendor << 16) | pNv->PciInfo->chipType;
+ 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",
+ pNv->ChipRev);
+ } else {
+ pNv->ChipRev = pNv->PciInfo->chipRev;
+ }
+
+ /*
+ * This shouldn't happen because such problems should be caught in
+ * NVProbe(), but check it just in case.
+ */
+ if (pScrn->chipset == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "ChipID 0x%04X is not recognised\n", pNv->Chipset);
+ xf86FreeInt10(pNv->pInt);
+ return FALSE;
+ }
+ if (pNv->Chipset < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Chipset \"%s\" is not recognised\n", pScrn->chipset);
+ xf86FreeInt10(pNv->pInt);
+ return FALSE;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset);
+
+
+ /*
+ * The first thing we should figure out is the depth, bpp, etc.
+ * Our default depth is 8, so pass it to the helper function.
+ */
+
+ if (!xf86SetDepthBpp(pScrn, 8, 8, 8, Support32bppFb)) {
+ xf86FreeInt10(pNv->pInt);
+ return FALSE;
+ } else {
+ /* Check that the returned depth is one we support */
+ switch (pScrn->depth) {
+ case 8:
+ case 15:
+ case 24:
+ /* OK */
+ break;
+ case 16:
+ if((pNv->Chipset & 0xffff) == 0x0018) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "The Riva 128 chipset does not support depth 16. "
+ "Using depth 15 instead\n");
+ pScrn->depth = 15;
+ }
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by this driver\n",
+ pScrn->depth);
+ xf86FreeInt10(pNv->pInt);
+ return FALSE;
+ }
+ }
+ xf86PrintDepthBpp(pScrn);
+
+ /* Get the depth24 pixmap format */
+ if (pScrn->depth == 24 && pix24bpp == 0)
+ pix24bpp = xf86GetBppFromDepth(pScrn, 24);
+
+ /*
+ * This must happen after pScrn->display has been set because
+ * xf86SetWeight references it.
+ */
+ if (pScrn->depth > 8) {
+ /* The defaults are OK for us */
+ rgb zeros = {0, 0, 0};
+
+ if (!xf86SetWeight(pScrn, zeros, zeros)) {
+ xf86FreeInt10(pNv->pInt);
+ return FALSE;
+ }
+ }
+
+ if (!xf86SetDefaultVisual(pScrn, -1)) {
+ xf86FreeInt10(pNv->pInt);
+ return FALSE;
+ } else {
+ /* We don't currently support DirectColor at > 8bpp */
+ if (pScrn->depth > 8 && (pScrn->defaultVisual != TrueColor)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
+ " (%s) is not supported at depth %d\n",
+ xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
+ xf86FreeInt10(pNv->pInt);
+ return FALSE;
+ }
+ }
+
+ bytesPerPixel = pScrn->bitsPerPixel / 8;
+
+ /* The vgahw module should be loaded here when needed */
+ if (!xf86LoadSubModule(pScrn, "vgahw")) {
+ xf86FreeInt10(pNv->pInt);
+ return FALSE;
+ }
+
+ xf86LoaderReqSymLists(vgahwSymbols, NULL);
+
+ /*
+ * Allocate a vgaHWRec
+ */
+ if (!vgaHWGetHWRec(pScrn)) {
+ xf86FreeInt10(pNv->pInt);
+ return FALSE;
+ }
+
+ /* We use a programmable clock */
+ pScrn->progClock = TRUE;
+
+ /* Collect all of the relevant option flags (fill in pScrn->options) */
+ xf86CollectOptions(pScrn, NULL);
+
+ /* Process the options */
+ if (!(pNv->Options = xalloc(sizeof(NVOptions))))
+ return FALSE;
+ memcpy(pNv->Options, NVOptions, sizeof(NVOptions));
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pNv->Options);
+
+ /* Set the bits per RGB for 8bpp mode */
+ if (pScrn->depth == 8)
+ pScrn->rgbBits = 8;
+
+ from = X_DEFAULT;
+ pNv->HWCursor = TRUE;
+ /*
+ * The preferred method is to use the "hw cursor" option as a tri-state
+ * option, with the default set above.
+ */
+ if (xf86GetOptValBool(pNv->Options, OPTION_HW_CURSOR, &pNv->HWCursor)) {
+ from = X_CONFIG;
+ }
+ /* For compatibility, accept this too (as an override) */
+ if (xf86ReturnOptValBool(pNv->Options, OPTION_SW_CURSOR, FALSE)) {
+ from = X_CONFIG;
+ pNv->HWCursor = FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
+ pNv->HWCursor ? "HW" : "SW");
+ if (xf86ReturnOptValBool(pNv->Options, OPTION_NOACCEL, FALSE)) {
+ pNv->NoAccel = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
+ }
+ if (xf86ReturnOptValBool(pNv->Options, OPTION_SHOWCACHE, FALSE)) {
+ pNv->ShowCache = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShowCache enabled\n");
+ }
+ if (xf86ReturnOptValBool(pNv->Options, OPTION_SHADOW_FB, FALSE)) {
+ pNv->ShadowFB = TRUE;
+ pNv->NoAccel = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using \"Shadow Framebuffer\" - acceleration disabled\n");
+ }
+ if (xf86ReturnOptValBool(pNv->Options, OPTION_FBDEV, FALSE)) {
+ pNv->FBDev = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using framebuffer device\n");
+ }
+ if (pNv->FBDev) {
+ /* check for linux framebuffer device */
+ if (!xf86LoadSubModule(pScrn, "fbdevhw")) {
+ xf86FreeInt10(pNv->pInt);
+ return FALSE;
+ }
+
+ xf86LoaderReqSymLists(fbdevHWSymbols, NULL);
+ if (!fbdevHWInit(pScrn, pNv->PciInfo, NULL)) {
+ xf86FreeInt10(pNv->pInt);
+ return FALSE;
+ }
+ pScrn->SwitchMode = fbdevHWSwitchMode;
+ pScrn->AdjustFrame = fbdevHWAdjustFrame;
+ pScrn->EnterVT = NVEnterVTFBDev;
+ pScrn->LeaveVT = fbdevHWLeaveVT;
+ pScrn->ValidMode = fbdevHWValidMode;
+ }
+ pNv->Rotate = 0;
+ if ((s = xf86GetOptValString(pNv->Options, OPTION_ROTATE))) {
+ if(!xf86NameCmp(s, "CW")) {
+ pNv->ShadowFB = TRUE;
+ pNv->NoAccel = TRUE;
+ pNv->HWCursor = FALSE;
+ pNv->Rotate = 1;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Rotating screen clockwise - acceleration disabled\n");
+ } else
+ if(!xf86NameCmp(s, "CCW")) {
+ pNv->ShadowFB = TRUE;
+ pNv->NoAccel = TRUE;
+ pNv->HWCursor = FALSE;
+ pNv->Rotate = -1;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Rotating screen counter clockwise - acceleration disabled\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "\"%s\" is not a valid value for Option \"Rotate\"\n", s);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Valid options are \"CW\" or \"CCW\"\n");
+ }
+ }
+ if(xf86GetOptValInteger(pNv->Options, OPTION_VIDEO_KEY, &(pNv->videoKey))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n",
+ pNv->videoKey);
+ } else {
+ pNv->videoKey = (1 << pScrn->offset.red) |
+ (1 << pScrn->offset.green) |
+ (((pScrn->mask.blue >> pScrn->offset.blue) - 1) << pScrn->offset.blue);
+ }
+
+ if (xf86GetOptValBool(pNv->Options, OPTION_FLAT_PANEL, &(pNv->FlatPanel))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "forcing %s usage\n",
+ pNv->FlatPanel ? "DFP" : "CRTC");
+ } else {
+ pNv->FlatPanel = -1; /* autodetect later */
+ }
+
+ pNv->FPDither = FALSE;
+ if (xf86GetOptValBool(pNv->Options, OPTION_FP_DITHER, &(pNv->FPDither)))
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "enabling flat panel dither\n");
+
+ if (xf86GetOptValInteger(pNv->Options, OPTION_CRTC_NUMBER,
+ &pNv->forceCRTC))
+ {
+ if((pNv->forceCRTC < 0) || (pNv->forceCRTC > 1)) {
+ pNv->forceCRTC = -1;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Invalid CRTC number. Must be 0 or 1\n");
+ }
+ } else pNv->forceCRTC = -1;
+
+
+ if (pNv->pEnt->device->MemBase != 0) {
+ /* Require that the config file value matches one of the PCI values. */
+ if (!xf86CheckPciMemBase(pNv->PciInfo, pNv->pEnt->device->MemBase)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "MemBase 0x%08lX doesn't match any PCI base register.\n",
+ pNv->pEnt->device->MemBase);
+ xf86FreeInt10(pNv->pInt);
+ NVFreeRec(pScrn);
+ return FALSE;
+ }
+ pNv->FbAddress = pNv->pEnt->device->MemBase;
+ from = X_CONFIG;
+ } else {
+ int i = 1;
+ pNv->FbBaseReg = i;
+ if (pNv->PciInfo->memBase[i] != 0) {
+ pNv->FbAddress = pNv->PciInfo->memBase[i] & 0xff800000;
+ from = X_PROBED;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No valid FB address in PCI config space\n");
+ xf86FreeInt10(pNv->pInt);
+ NVFreeRec(pScrn);
+ return FALSE;
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
+ (unsigned long)pNv->FbAddress);
+
+ if (pNv->pEnt->device->IOBase != 0) {
+ /* Require that the config file value matches one of the PCI values. */
+ if (!xf86CheckPciMemBase(pNv->PciInfo, pNv->pEnt->device->IOBase)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "IOBase 0x%08lX doesn't match any PCI base register.\n",
+ pNv->pEnt->device->IOBase);
+ xf86FreeInt10(pNv->pInt);
+ NVFreeRec(pScrn);
+ return FALSE;
+ }
+ pNv->IOAddress = pNv->pEnt->device->IOBase;
+ from = X_CONFIG;
+ } else {
+ int i = 0;
+ if (pNv->PciInfo->memBase[i] != 0) {
+ pNv->IOAddress = pNv->PciInfo->memBase[i] & 0xffffc000;
+ from = X_PROBED;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No valid MMIO address in PCI config space\n");
+ xf86FreeInt10(pNv->pInt);
+ NVFreeRec(pScrn);
+ return FALSE;
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n",
+ (unsigned long)pNv->IOAddress);
+
+ if (xf86RegisterResources(pNv->pEnt->index, NULL, ResExclusive)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "xf86RegisterResources() found resource conflicts\n");
+ xf86FreeInt10(pNv->pInt);
+ NVFreeRec(pScrn);
+ return FALSE;
+ }
+
+ pNv->alphaCursor = ((pNv->Chipset & 0x0ff0) >= 0x0110);
+
+ switch (pNv->Chipset & 0x0ff0) {
+ case 0x0010:
+ NV3Setup(pScrn);
+ break;
+ case 0x0020:
+ case 0x00A0:
+ NV4Setup(pScrn);
+ break;
+ case 0x0100:
+ case 0x0110:
+ case 0x0150:
+ case 0x0170:
+ case 0x0180:
+ case 0x01A0:
+ case 0x01F0:
+ NV10Setup(pScrn);
+ break;
+ case 0x0200:
+ case 0x0250:
+ case 0x0280:
+ case 0x0300:
+ case 0x0310:
+ case 0x0320:
+ case 0x0330:
+ case 0x0340:
+ NV20Setup(pScrn);
+ break;
+ }
+
+ /*
+ * If the user has specified the amount of memory in the XF86Config
+ * file, we respect that setting.
+ */
+ if (pNv->pEnt->device->videoRam != 0) {
+ pScrn->videoRam = pNv->pEnt->device->videoRam;
+ from = X_CONFIG;
+ } else {
+ if (pNv->FBDev) {
+ pScrn->videoRam = fbdevHWGetVidmem(pScrn)/1024;
+ } else {
+ pScrn->videoRam = pNv->riva.RamAmountKBytes;
+ }
+ from = X_PROBED;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kBytes\n",
+ pScrn->videoRam);
+
+ pNv->FbMapSize = pScrn->videoRam * 1024;
+
+ /*
+ * If the driver can do gamma correction, it should call xf86SetGamma()
+ * here.
+ */
+
+ {
+ Gamma zeros = {0.0, 0.0, 0.0};
+
+ if (!xf86SetGamma(pScrn, zeros)) {
+ xf86FreeInt10(pNv->pInt);
+ return FALSE;
+ }
+ }
+
+ pNv->FbUsableSize = pNv->FbMapSize;
+
+ /* Remove reserved memory from end of buffer */
+ switch( pNv->riva.Architecture ) {
+ case NV_ARCH_03:
+ pNv->FbUsableSize -= 32 * 1024;
+ break;
+ case NV_ARCH_04:
+ case NV_ARCH_10:
+ case NV_ARCH_20:
+ default:
+ pNv->FbUsableSize -= 128 * 1024;
+ break;
+ }
+
+
+ /*
+ * Setup the ClockRanges, which describe what clock ranges are available,
+ * and what sort of modes they can be used for.
+ */
+
+ pNv->MinClock = 12000;
+ pNv->MaxClock = pNv->riva.MaxVClockFreqKHz;
+
+ clockRanges = xnfcalloc(sizeof(ClockRange), 1);
+ clockRanges->next = NULL;
+ clockRanges->minClock = pNv->MinClock;
+ clockRanges->maxClock = pNv->MaxClock;
+ clockRanges->clockIndex = -1; /* programmable */
+ if(((pNv->Chipset & 0x0ff0) <= 0x0100) ||
+ ((pNv->Chipset & 0x0ff0) == 0x0150))
+ {
+ clockRanges->interlaceAllowed = TRUE;
+ } else /* Chips after NV15 (including NV11) do not support interlaced */
+ clockRanges->interlaceAllowed = FALSE;
+ clockRanges->doubleScanAllowed = TRUE;
+
+ if(pNv->FlatPanel == 1) {
+ clockRanges->interlaceAllowed = FALSE;
+ clockRanges->doubleScanAllowed = FALSE;
+ }
+
+ /*
+ * xf86ValidateModes will check that the mode HTotal and VTotal values
+ * don't exceed the chipset's limit if pScrn->maxHValue and
+ * pScrn->maxVValue are set. Since our NVValidMode() already takes
+ * care of this, we don't worry about setting them here.
+ */
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges,
+ NULL, 256, 2048,
+ 32 * pScrn->bitsPerPixel, 128, 2048,
+ pScrn->display->virtualX,
+ pScrn->display->virtualY,
+ pNv->FbUsableSize,
+ LOOKUP_BEST_REFRESH);
+
+ if (i < 1 && pNv->FBDev) {
+ fbdevHWUseBuildinMode(pScrn);
+ pScrn->displayWidth = pScrn->virtualX; /* FIXME: might be wrong */
+ i = 1;
+ }
+ if (i == -1) {
+ xf86FreeInt10(pNv->pInt);
+ NVFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Prune the modes marked as invalid */
+ xf86PruneDriverModes(pScrn);
+
+ if (i == 0 || pScrn->modes == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
+ xf86FreeInt10(pNv->pInt);
+ NVFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /*
+ * Set the CRTC parameters for all of the modes based on the type
+ * of mode, and the chipset's interlace requirements.
+ *
+ * Calling this is required if the mode->Crtc* values are used by the
+ * driver and if the driver doesn't provide code to set them. They
+ * are not pre-initialised at all.
+ */
+ xf86SetCrtcForModes(pScrn, 0);
+
+ /* Set the current mode to the first in the list */
+ pScrn->currentMode = pScrn->modes;
+
+ /* Print the list of modes being used */
+ xf86PrintModes(pScrn);
+
+ /* Set display resolution */
+ xf86SetDpi(pScrn, 0, 0);
+
+
+ /*
+ * XXX This should be taken into account in some way in the mode valdation
+ * section.
+ */
+
+ if (xf86LoadSubModule(pScrn, "fb") == NULL) {
+ xf86FreeInt10(pNv->pInt);
+ NVFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86LoaderReqSymLists(fbSymbols, NULL);
+
+ /* Load XAA if needed */
+ if (!pNv->NoAccel) {
+ if (!xf86LoadSubModule(pScrn, "xaa")) {
+ xf86FreeInt10(pNv->pInt);
+ NVFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(xaaSymbols, NULL);
+ }
+
+ /* Load ramdac if needed */
+ if (pNv->HWCursor) {
+ if (!xf86LoadSubModule(pScrn, "ramdac")) {
+ xf86FreeInt10(pNv->pInt);
+ NVFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(ramdacSymbols, NULL);
+ }
+
+ /* Load shadowfb if needed */
+ if (pNv->ShadowFB) {
+ if (!xf86LoadSubModule(pScrn, "shadowfb")) {
+ xf86FreeInt10(pNv->pInt);
+ NVFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(shadowSymbols, NULL);
+ }
+
+ pNv->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel;
+ pNv->CurrentLayout.depth = pScrn->depth;
+ pNv->CurrentLayout.displayWidth = pScrn->displayWidth;
+ pNv->CurrentLayout.weight.red = pScrn->weight.red;
+ pNv->CurrentLayout.weight.green = pScrn->weight.green;
+ pNv->CurrentLayout.weight.blue = pScrn->weight.blue;
+ pNv->CurrentLayout.mode = pScrn->currentMode;
+
+ xf86FreeInt10(pNv->pInt);
+
+ pNv->pInt = NULL;
+ return TRUE;
+}
+
+
+/*
+ * Map the framebuffer and MMIO memory.
+ */
+
+static Bool
+NVMapMem(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVMapMem\n"));
+ pNv = NVPTR(pScrn);
+
+ /*
+ * Map IO registers to virtual address space
+ */
+ pNv->IOBase = xf86MapPciMem(pScrn->scrnIndex,
+ VIDMEM_MMIO | VIDMEM_READSIDEEFFECT,
+ pNv->PciTag, pNv->IOAddress, 0x1000000);
+ if (pNv->IOBase == NULL)
+ return FALSE;
+
+ pNv->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
+ pNv->PciTag, pNv->FbAddress,
+ pNv->FbMapSize);
+ if (pNv->FbBase == NULL)
+ return FALSE;
+
+ pNv->FbStart = pNv->FbBase;
+
+ return TRUE;
+}
+
+Bool
+NVMapMemFBDev(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVMamMemFBDev\n"));
+ pNv = NVPTR(pScrn);
+
+ pNv->FbBase = fbdevHWMapVidmem(pScrn);
+ if (pNv->FbBase == NULL)
+ return FALSE;
+
+ pNv->IOBase = fbdevHWMapMMIO(pScrn);
+ if (pNv->IOBase == NULL)
+ return FALSE;
+
+ pNv->FbStart = pNv->FbBase;
+
+ return TRUE;
+}
+
+/*
+ * Unmap the framebuffer and MMIO memory.
+ */
+
+static Bool
+NVUnmapMem(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVUnmapMem\n"));
+ pNv = NVPTR(pScrn);
+
+ /*
+ * Unmap IO registers to virtual address space
+ */
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pNv->IOBase, 0x1000000);
+ pNv->IOBase = NULL;
+
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pNv->FbBase, pNv->FbMapSize);
+ pNv->FbBase = NULL;
+ pNv->FbStart = NULL;
+
+ return TRUE;
+}
+
+
+/*
+ * Initialise a new mode.
+ */
+
+static Bool
+NVModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ vgaRegPtr vgaReg;
+ NVPtr pNv = NVPTR(pScrn);
+ NVRegPtr nvReg;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVModeInit\n"));
+
+ /* Initialise the ModeReg values */
+ if (!vgaHWInit(pScrn, mode))
+ return FALSE;
+ pScrn->vtSema = TRUE;
+
+ if(!(*pNv->ModeInit)(pScrn, mode))
+ return FALSE;
+
+ /* Program the registers */
+ vgaHWProtect(pScrn, TRUE);
+ vgaReg = &hwp->ModeReg;
+ nvReg = &pNv->ModeReg;
+
+ (*pNv->Restore)(pScrn, vgaReg, nvReg, FALSE);
+
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ /* turn on LFB swapping */
+ {
+ unsigned char tmp;
+
+ VGA_WR08(pNv->riva.PCIO, 0x3d4, 0x46);
+ tmp = VGA_RD08(pNv->riva.PCIO, 0x3d5);
+ tmp |= (1 << 7);
+ VGA_WR08(pNv->riva.PCIO, 0x3d5, tmp);
+ }
+#endif
+
+ NVResetGraphics(pScrn);
+
+ vgaHWProtect(pScrn, FALSE);
+
+ pNv->CurrentLayout.mode = mode;
+
+ return TRUE;
+}
+
+/*
+ * Restore the initial (text) mode.
+ */
+static void
+NVRestore(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ vgaRegPtr vgaReg = &hwp->SavedReg;
+ NVPtr pNv = NVPTR(pScrn);
+ NVRegPtr nvReg = &pNv->SavedReg;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVRestore\n"));
+ /* Only restore text mode fonts/text for the primary card */
+ vgaHWProtect(pScrn, TRUE);
+ (*pNv->Restore)(pScrn, vgaReg, nvReg, pNv->Primary);
+ vgaHWProtect(pScrn, FALSE);
+}
+
+static void
+NVDPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
+{
+ unsigned char crtc1A;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+ if (!pScrn->vtSema) return;
+
+ crtc1A = hwp->readCrtc(hwp, 0x1A) & ~0xC0;
+
+ switch (PowerManagementMode) {
+ case DPMSModeStandby: /* HSync: Off, VSync: On */
+ crtc1A |= 0x80;
+ break;
+ case DPMSModeSuspend: /* HSync: On, VSync: Off */
+ crtc1A |= 0x40;
+ break;
+ case DPMSModeOff: /* HSync: Off, VSync: Off */
+ crtc1A |= 0xC0;
+ break;
+ case DPMSModeOn: /* HSync: On, VSync: On */
+ default:
+ break;
+ }
+
+ hwp->writeCrtc(hwp, 0x1A, crtc1A);
+}
+
+
+/* Mandatory */
+
+/* This gets called at the start of each server generation */
+
+static Bool
+NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ ScrnInfoPtr pScrn;
+ vgaHWPtr hwp;
+ NVPtr pNv;
+ NVRamdacPtr NVdac;
+ int ret;
+ VisualPtr visual;
+ unsigned char *FBStart;
+ int width, height, displayWidth;
+ BoxRec AvailFBArea;
+
+ /*
+ * First get the ScrnInfoRec
+ */
+ pScrn = xf86Screens[pScreen->myNum];
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVScreenInit\n"));
+
+ hwp = VGAHWPTR(pScrn);
+ pNv = NVPTR(pScrn);
+ NVdac = &pNv->Dac;
+
+ /* Map the NV memory and MMIO areas */
+ if (pNv->FBDev) {
+ if (!NVMapMemFBDev(pScrn))
+ return FALSE;
+ } else {
+ if (!NVMapMem(pScrn))
+ return FALSE;
+ }
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Mem Mapped\n"));
+
+ /* Map the VGA memory when the primary video */
+ if (pNv->Primary && !pNv->FBDev) {
+ hwp->MapSize = 0x10000;
+ if (!vgaHWMapMem(pScrn))
+ return FALSE;
+ }
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- VGA Mapped\n"));
+
+ if (pNv->FBDev) {
+ fbdevHWSave(pScrn);
+ if (!fbdevHWModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+ } else {
+ /* Save the current state */
+ pNv->riva.LockUnlock(&pNv->riva, 0);
+ NVSave(pScrn);
+ /* Initialise the first mode */
+ if (!NVModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+ }
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- State saved\n"));
+
+ /* Darken the screen for aesthetic reasons and set the viewport */
+ NVSaveScreen(pScreen, SCREEN_SAVER_ON);
+ pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Blanked\n"));
+
+ /*
+ * The next step is to setup the screen's visuals, and initialise the
+ * framebuffer code. In cases where the framebuffer's default
+ * choices for things like visual layouts and bits per RGB are OK,
+ * this may be as simple as calling the framebuffer's ScreenInit()
+ * function. If not, the visuals will need to be setup before calling
+ * a fb ScreenInit() function and fixed up after.
+ *
+ * For most PC hardware at depths >= 8, the defaults that cfb uses
+ * are not appropriate. In this driver, we fixup the visuals after.
+ */
+
+ /*
+ * Reset the visual list.
+ */
+ miClearVisualTypes();
+
+ /* Setup the visuals we support. */
+
+ if ((pScrn->bitsPerPixel > 8) && (pNv->riva.Architecture == NV_ARCH_03)) {
+ if (!miSetVisualTypes(pScrn->depth, TrueColorMask, 8,
+ pScrn->defaultVisual))
+ return FALSE;
+ } else {
+ if (!miSetVisualTypes(pScrn->depth,
+ miGetDefaultVisualMask(pScrn->depth), 8,
+ pScrn->defaultVisual))
+ return FALSE;
+ }
+ if (!miSetPixmapDepths ()) return FALSE;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Visuals set up\n"));
+
+ /*
+ * Call the framebuffer layer's ScreenInit function, and fill in other
+ * pScreen fields.
+ */
+
+ width = pScrn->virtualX;
+ height = pScrn->virtualY;
+ displayWidth = pScrn->displayWidth;
+
+
+ if(pNv->Rotate) {
+ height = pScrn->virtualX;
+ width = pScrn->virtualY;
+ }
+
+ if(pNv->ShadowFB) {
+ pNv->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
+ pNv->ShadowPtr = xalloc(pNv->ShadowPitch * height);
+ displayWidth = pNv->ShadowPitch / (pScrn->bitsPerPixel >> 3);
+ FBStart = pNv->ShadowPtr;
+ } else {
+ pNv->ShadowPtr = NULL;
+ FBStart = pNv->FbStart;
+ }
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ case 16:
+ case 32:
+ ret = fbScreenInit(pScreen, FBStart, width, height,
+ pScrn->xDpi, pScrn->yDpi,
+ displayWidth, pScrn->bitsPerPixel);
+ break;
+ default:
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Internal error: invalid bpp (%d) in NVScreenInit\n",
+ pScrn->bitsPerPixel);
+ ret = FALSE;
+ break;
+ }
+ if (!ret)
+ return FALSE;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- cfb set up\n"));
+
+ if (pScrn->bitsPerPixel > 8) {
+ /* Fixup RGB ordering */
+ visual = pScreen->visuals + pScreen->numVisuals;
+ while (--visual >= pScreen->visuals) {
+ if ((visual->class | DynamicClass) == DirectColor) {
+ visual->offsetRed = pScrn->offset.red;
+ visual->offsetGreen = pScrn->offset.green;
+ visual->offsetBlue = pScrn->offset.blue;
+ visual->redMask = pScrn->mask.red;
+ visual->greenMask = pScrn->mask.green;
+ visual->blueMask = pScrn->mask.blue;
+ }
+ }
+ }
+
+ fbPictureInit (pScreen, 0, 0);
+
+ xf86SetBlackWhitePixels(pScreen);
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- B & W\n"));
+
+ if(!pNv->ShadowFB) /* hardware cursor needs to wrap this layer */
+ NVDGAInit(pScreen);
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pScrn->displayWidth;
+ AvailFBArea.y2 = (min(pNv->FbUsableSize, 32*1024*1024)) /
+ (pScrn->displayWidth * pScrn->bitsPerPixel / 8);
+ xf86InitFBManager(pScreen, &AvailFBArea);
+
+ if (!pNv->NoAccel)
+ NVAccelInit(pScreen);
+
+ miInitializeBackingStore(pScreen);
+ xf86SetBackingStore(pScreen);
+ xf86SetSilkenMouse(pScreen);
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Backing store set up\n"));
+
+ /* Initialize software cursor.
+ Must precede creation of the default colormap */
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- SW cursor set up\n"));
+
+ /* Initialize HW cursor layer.
+ Must follow software cursor initialization*/
+ if (pNv->HWCursor) {
+ if(!NVCursorInit(pScreen))
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Hardware cursor initialization failed\n");
+ }
+
+ /* Initialise default colourmap */
+ if (!miCreateDefColormap(pScreen))
+ return FALSE;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Def Color map set up\n"));
+
+ /* Initialize colormap layer.
+ Must follow initialization of the default colormap */
+ if(!xf86HandleColormaps(pScreen, 256, 8,
+ (pNv->FBDev ? fbdevHWLoadPalette : NVdac->LoadPalette),
+ NULL, CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR))
+ return FALSE;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Palette loaded\n"));
+
+ if(pNv->ShadowFB) {
+ RefreshAreaFuncPtr refreshArea = NVRefreshArea;
+
+ if(pNv->Rotate) {
+ pNv->PointerMoved = pScrn->PointerMoved;
+ pScrn->PointerMoved = NVPointerMoved;
+
+ switch(pScrn->bitsPerPixel) {
+ case 8: refreshArea = NVRefreshArea8; break;
+ case 16: refreshArea = NVRefreshArea16; break;
+ case 32: refreshArea = NVRefreshArea32; break;
+ }
+ }
+
+ ShadowFBInit(pScreen, refreshArea);
+ }
+
+ /* Call the vgaHW DPMS function directly.
+ XXX There must be a way to get all the DPMS modes. */
+#if 0
+ xf86DPMSInit(pScreen, vgaHWDPMSSet, 0);
+#else
+ xf86DPMSInit(pScreen, NVDPMSSet, 0);
+#endif
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- DPMS set up\n"));
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Color maps etc. set up\n"));
+
+ pScrn->memPhysBase = pNv->FbAddress;
+ pScrn->fbOffset = 0;
+
+ NVInitVideo(pScreen);
+
+ pScreen->SaveScreen = NVSaveScreen;
+
+ /* Wrap the current CloseScreen function */
+ pNv->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = NVCloseScreen;
+
+ pNv->BlockHandler = pScreen->BlockHandler;
+ pScreen->BlockHandler = NVBlockHandler;
+
+ /* Report any unused options (only for the first generation) */
+ if (serverGeneration == 1) {
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+ }
+ /* Done */
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Done\n"));
+ return TRUE;
+}
+
+/* Free up any persistent data structures */
+
+
+/* Do screen blanking */
+
+/* Mandatory */
+static Bool
+NVSaveScreen(ScreenPtr pScreen, int mode)
+{
+ return vgaHWSaveScreen(pScreen, mode);
+}
+
+static void
+NVSave(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ NVRegPtr nvReg = &pNv->SavedReg;
+ vgaHWPtr pVga = VGAHWPTR(pScrn);
+ vgaRegPtr vgaReg = &pVga->SavedReg;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVSave\n"));
+ (*pNv->Save)(pScrn, vgaReg, nvReg, pNv->Primary);
+}
+
diff --git a/src/nv_include.h b/src/nv_include.h
new file mode 100644
index 0000000..2d4465b
--- /dev/null
+++ b/src/nv_include.h
@@ -0,0 +1,59 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_include.h,v 1.11 2001/12/07 00:09:56 mvojkovi Exp $ */
+
+#ifndef __NV_INCLUDE_H__
+#define __NV_INCLUDE_H__
+
+/* All drivers should typically include these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "xf86_ansic.h"
+#include "compiler.h"
+
+/* Drivers for PCI hardware need this */
+#include "xf86PciInfo.h"
+
+/* Drivers that need to access the PCI config space directly need this */
+#include "xf86Pci.h"
+
+/* All drivers initialising the SW cursor need this */
+#include "mipointer.h"
+
+/* All drivers implementing backing store need this */
+#include "mibstore.h"
+
+#include "micmap.h"
+
+#include "xf86DDC.h"
+
+#include "vbe.h"
+
+#include "xf86RAC.h"
+
+#include "nv_const.h"
+
+#include "dixstruct.h"
+#include "scrnintstr.h"
+
+#include "fb.h"
+
+#include "xaa.h"
+#include "xf86cmap.h"
+#include "shadowfb.h"
+#include "fbdevhw.h"
+
+#include "xf86xv.h"
+#include "Xv.h"
+
+#include "vgaHW.h"
+
+#include "xf86Cursor.h"
+#include "xf86DDC.h"
+
+#include "region.h"
+
+#include "nv_local.h"
+#include "nv_type.h"
+#include "nv_proto.h"
+
+#endif /* __NV_INCLUDE_H__ */
diff --git a/src/nv_local.h b/src/nv_local.h
new file mode 100644
index 0000000..50ec06a
--- /dev/null
+++ b/src/nv_local.h
@@ -0,0 +1,74 @@
+ /***************************************************************************\
+|* *|
+|* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
+|* *|
+|* 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. *|
+|* *|
+|* Any use of this source code must include, in the user documenta- *|
+|* tion and internal comments to the code, notices to the end user *|
+|* as follows: *|
+|* *|
+|* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
+|* *|
+|* 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, CORPOR- *|
+|* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
+|* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
+|* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
+|* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
+|* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
+|* SULTING 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. *|
+|* *|
+|* 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. Govern- *|
+|* ment 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. *|
+|* *|
+ \***************************************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_local.h,v 1.7 2002/01/25 21:56:06 tsi Exp $ */
+
+#ifndef __NV_LOCAL_H__
+#define __NV_LOCAL_H__
+
+/*
+ * This file includes any environment or machine specific values to access the
+ * HW. Put all affected includes, typdefs, etc. here so the riva_hw.* files
+ * can stay generic in nature.
+ */
+#include "xf86_ansic.h"
+#include "compiler.h"
+#include "xf86_OSproc.h"
+
+/*
+ * Typedefs to force certain sized values.
+ */
+typedef unsigned char U008;
+typedef unsigned short U016;
+typedef unsigned int U032;
+
+/*
+ * HW access macros. These assume memory-mapped I/O, and not normal I/O space.
+ */
+#define NV_WR08(p,i,d) MMIO_OUT8((volatile pointer)(p), (i), (d))
+#define NV_RD08(p,i) MMIO_IN8((volatile pointer)(p), (i))
+#define NV_WR16(p,i,d) MMIO_OUT16((volatile pointer)(p), (i), (d))
+#define NV_RD16(p,i) MMIO_IN16((volatile pointer)(p), (i))
+#define NV_WR32(p,i,d) MMIO_OUT32((volatile pointer)(p), (i), (d))
+#define NV_RD32(p,i) MMIO_IN32((volatile pointer)(p), (i))
+
+/* VGA I/O is now always done through MMIO */
+#define VGA_WR08(p,i,d) NV_WR08(p,i,d)
+#define VGA_RD08(p,i) NV_RD08(p,i)
+
+#endif /* __NV_LOCAL_H__ */
diff --git a/src/nv_proto.h b/src/nv_proto.h
new file mode 100644
index 0000000..013f57a
--- /dev/null
+++ b/src/nv_proto.h
@@ -0,0 +1,46 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_proto.h,v 1.8 2002/11/26 23:41:59 mvojkovi Exp $ */
+
+#ifndef __NV_PROTO_H__
+#define __NV_PROTO_H__
+
+/* in nv_driver.c */
+Bool NVSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
+void NVAdjustFrame(int scrnIndex, int x, int y, int flags);
+xf86MonPtr NVdoDDC(ScrnInfoPtr pScrn);
+
+
+/* in nv_dac.c */
+void NVRamdacInit(ScrnInfoPtr pScrn);
+Bool NVDACInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+void NVDACSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg,
+ NVRegPtr nvReg, Bool saveFonts);
+void NVDACRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg,
+ NVRegPtr nvReg, Bool restoreFonts);
+void NVDACLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
+ LOCO *colors, VisualPtr pVisual );
+
+/* in nv_video.c */
+void NVInitVideo(ScreenPtr);
+void NVResetVideo (ScrnInfoPtr pScrnInfo);
+
+/* in nv_setup.c */
+void RivaEnterLeave(ScrnInfoPtr pScrn, Bool enter);
+void NV1Setup(ScrnInfoPtr pScrn);
+void NV3Setup(ScrnInfoPtr pScrn);
+void NV4Setup(ScrnInfoPtr pScrn);
+void NV10Setup(ScrnInfoPtr pScrn);
+void NV20Setup(ScrnInfoPtr pScrn);
+
+/* in nv_cursor.c */
+Bool NVCursorInit(ScreenPtr pScreen);
+
+/* in nv_xaa.c */
+Bool NVAccelInit(ScreenPtr pScreen);
+void NVSync(ScrnInfoPtr pScrn);
+void NVResetGraphics(ScrnInfoPtr pScrn);
+
+/* in nv_dga.c */
+Bool NVDGAInit(ScreenPtr pScreen);
+
+#endif /* __NV_PROTO_H__ */
+
diff --git a/src/nv_setup.c b/src/nv_setup.c
new file mode 100644
index 0000000..cdb0ade
--- /dev/null
+++ b/src/nv_setup.c
@@ -0,0 +1,551 @@
+/* $XConsortium: nv_driver.c /main/3 1996/10/28 05:13:37 kaleb $ */
+/*
+ * Copyright 1996-1997 David J. McKay
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * DAVID J. MCKAY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* 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_setup.c,v 1.27.2.1 2003/05/09 02:17:49 dawes Exp $ */
+
+#include "nv_include.h"
+
+/*
+ * Override VGA I/O routines.
+ */
+static void NVWriteCrtc(vgaHWPtr pVga, CARD8 index, CARD8 value)
+{
+ NVPtr pNv = (NVPtr)pVga->MMIOBase;
+ VGA_WR08(pNv->riva.PCIO, pVga->IOBase + VGA_CRTC_INDEX_OFFSET, index);
+ VGA_WR08(pNv->riva.PCIO, pVga->IOBase + VGA_CRTC_DATA_OFFSET, value);
+}
+static CARD8 NVReadCrtc(vgaHWPtr pVga, CARD8 index)
+{
+ NVPtr pNv = (NVPtr)pVga->MMIOBase;
+ VGA_WR08(pNv->riva.PCIO, pVga->IOBase + VGA_CRTC_INDEX_OFFSET, index);
+ return (VGA_RD08(pNv->riva.PCIO, pVga->IOBase + VGA_CRTC_DATA_OFFSET));
+}
+static void NVWriteGr(vgaHWPtr pVga, CARD8 index, CARD8 value)
+{
+ NVPtr pNv = (NVPtr)pVga->MMIOBase;
+ VGA_WR08(pNv->riva.PVIO, VGA_GRAPH_INDEX, index);
+ VGA_WR08(pNv->riva.PVIO, VGA_GRAPH_DATA, value);
+}
+static CARD8 NVReadGr(vgaHWPtr pVga, CARD8 index)
+{
+ NVPtr pNv = (NVPtr)pVga->MMIOBase;
+ VGA_WR08(pNv->riva.PVIO, VGA_GRAPH_INDEX, index);
+ return (VGA_RD08(pNv->riva.PVIO, VGA_GRAPH_DATA));
+}
+static void NVWriteSeq(vgaHWPtr pVga, CARD8 index, CARD8 value)
+{
+ NVPtr pNv = (NVPtr)pVga->MMIOBase;
+ VGA_WR08(pNv->riva.PVIO, VGA_SEQ_INDEX, index);
+ VGA_WR08(pNv->riva.PVIO, VGA_SEQ_DATA, value);
+}
+static CARD8 NVReadSeq(vgaHWPtr pVga, CARD8 index)
+{
+ NVPtr pNv = (NVPtr)pVga->MMIOBase;
+ VGA_WR08(pNv->riva.PVIO, VGA_SEQ_INDEX, index);
+ return (VGA_RD08(pNv->riva.PVIO, VGA_SEQ_DATA));
+}
+static void NVWriteAttr(vgaHWPtr pVga, CARD8 index, CARD8 value)
+{
+ NVPtr pNv = (NVPtr)pVga->MMIOBase;
+ volatile CARD8 tmp;
+
+ tmp = VGA_RD08(pNv->riva.PCIO, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
+ if (pVga->paletteEnabled)
+ index &= ~0x20;
+ else
+ index |= 0x20;
+ VGA_WR08(pNv->riva.PCIO, VGA_ATTR_INDEX, index);
+ VGA_WR08(pNv->riva.PCIO, VGA_ATTR_DATA_W, value);
+}
+static CARD8 NVReadAttr(vgaHWPtr pVga, CARD8 index)
+{
+ NVPtr pNv = (NVPtr)pVga->MMIOBase;
+ volatile CARD8 tmp;
+
+ tmp = VGA_RD08(pNv->riva.PCIO, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
+ if (pVga->paletteEnabled)
+ index &= ~0x20;
+ else
+ index |= 0x20;
+ VGA_WR08(pNv->riva.PCIO, VGA_ATTR_INDEX, index);
+ return (VGA_RD08(pNv->riva.PCIO, VGA_ATTR_DATA_R));
+}
+static void NVWriteMiscOut(vgaHWPtr pVga, CARD8 value)
+{
+ NVPtr pNv = (NVPtr)pVga->MMIOBase;
+ VGA_WR08(pNv->riva.PVIO, VGA_MISC_OUT_W, value);
+}
+static CARD8 NVReadMiscOut(vgaHWPtr pVga)
+{
+ NVPtr pNv = (NVPtr)pVga->MMIOBase;
+ return (VGA_RD08(pNv->riva.PVIO, VGA_MISC_OUT_R));
+}
+static void NVEnablePalette(vgaHWPtr pVga)
+{
+ NVPtr pNv = (NVPtr)pVga->MMIOBase;
+ volatile CARD8 tmp;
+
+ tmp = VGA_RD08(pNv->riva.PCIO, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
+ VGA_WR08(pNv->riva.PCIO, VGA_ATTR_INDEX, 0x00);
+ pVga->paletteEnabled = TRUE;
+}
+static void NVDisablePalette(vgaHWPtr pVga)
+{
+ NVPtr pNv = (NVPtr)pVga->MMIOBase;
+ volatile CARD8 tmp;
+
+ tmp = VGA_RD08(pNv->riva.PCIO, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
+ VGA_WR08(pNv->riva.PCIO, VGA_ATTR_INDEX, 0x20);
+ pVga->paletteEnabled = FALSE;
+}
+static void NVWriteDacMask(vgaHWPtr pVga, CARD8 value)
+{
+ NVPtr pNv = (NVPtr)pVga->MMIOBase;
+ VGA_WR08(pNv->riva.PDIO, VGA_DAC_MASK, value);
+}
+static CARD8 NVReadDacMask(vgaHWPtr pVga)
+{
+ NVPtr pNv = (NVPtr)pVga->MMIOBase;
+ return (VGA_RD08(pNv->riva.PDIO, VGA_DAC_MASK));
+}
+static void NVWriteDacReadAddr(vgaHWPtr pVga, CARD8 value)
+{
+ NVPtr pNv = (NVPtr)pVga->MMIOBase;
+ VGA_WR08(pNv->riva.PDIO, VGA_DAC_READ_ADDR, value);
+}
+static void NVWriteDacWriteAddr(vgaHWPtr pVga, CARD8 value)
+{
+ NVPtr pNv = (NVPtr)pVga->MMIOBase;
+ VGA_WR08(pNv->riva.PDIO, VGA_DAC_WRITE_ADDR, value);
+}
+static void NVWriteDacData(vgaHWPtr pVga, CARD8 value)
+{
+ NVPtr pNv = (NVPtr)pVga->MMIOBase;
+ VGA_WR08(pNv->riva.PDIO, VGA_DAC_DATA, value);
+}
+static CARD8 NVReadDacData(vgaHWPtr pVga)
+{
+ NVPtr pNv = (NVPtr)pVga->MMIOBase;
+ return (VGA_RD08(pNv->riva.PDIO, VGA_DAC_DATA));
+}
+
+static Bool
+NVIsConnected (ScrnInfoPtr pScrn, Bool second)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ volatile U032 *PRAMDAC = pNv->riva.PRAMDAC0;
+ CARD32 reg52C, reg608;
+ Bool present;
+
+ if(second) PRAMDAC += 0x800;
+
+ reg52C = PRAMDAC[0x052C/4];
+ reg608 = PRAMDAC[0x0608/4];
+
+ PRAMDAC[0x0608/4] = reg608 & ~0x00010000;
+
+ PRAMDAC[0x052C/4] = reg52C & 0x0000FEEE;
+ usleep(1000);
+ PRAMDAC[0x052C/4] |= 1;
+
+ pNv->riva.PRAMDAC0[0x0610/4] = 0x94050140;
+ pNv->riva.PRAMDAC0[0x0608/4] |= 0x00001000;
+
+ usleep(1000);
+
+ present = (PRAMDAC[0x0608/4] & (1 << 28)) ? TRUE : FALSE;
+
+ pNv->riva.PRAMDAC0[0x0608/4] &= 0x0000EFFF;
+
+ PRAMDAC[0x052C/4] = reg52C;
+ PRAMDAC[0x0608/4] = reg608;
+
+ return present;
+}
+
+static void
+NVOverrideCRTC(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv = NVPTR(pScrn);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Detected CRTC controller %i being used\n",
+ pNv->SecondCRTC ? 1 : 0);
+
+ if(pNv->forceCRTC != -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Forcing usage of CRTC %i\n", pNv->forceCRTC);
+ pNv->SecondCRTC = pNv->forceCRTC;
+ }
+}
+
+static void
+NVIsSecond (ScrnInfoPtr pScrn)
+{
+ NVPtr pNv = NVPTR(pScrn);
+
+ if(pNv->FlatPanel == 1) {
+ switch(pNv->Chipset & 0xffff) {
+ case 0x0174:
+ case 0x0175:
+ case 0x0176:
+ case 0x0177:
+ case 0x0179:
+ case 0x017C:
+ case 0x017D:
+ case 0x0186:
+ case 0x0187:
+ /* this might not be a good default for the chips below */
+ case 0x0286:
+ case 0x028C:
+ case 0x0316:
+ case 0x0317:
+ case 0x031A:
+ case 0x031B:
+ case 0x031C:
+ case 0x031D:
+ case 0x031E:
+ case 0x031F:
+ case 0x0326:
+ case 0x032E:
+ pNv->SecondCRTC = TRUE;
+ break;
+ default:
+ pNv->SecondCRTC = FALSE;
+ break;
+ }
+ } else {
+ if(NVIsConnected(pScrn, 0)) {
+ if(pNv->riva.PRAMDAC0[0x0000052C/4] & 0x100)
+ pNv->SecondCRTC = TRUE;
+ else
+ pNv->SecondCRTC = FALSE;
+ } else
+ if (NVIsConnected(pScrn, 1)) {
+ pNv->DDCBase = 0x36;
+ if(pNv->riva.PRAMDAC0[0x0000252C/4] & 0x100)
+ pNv->SecondCRTC = TRUE;
+ else
+ pNv->SecondCRTC = FALSE;
+ } else /* default */
+ pNv->SecondCRTC = FALSE;
+ }
+
+ NVOverrideCRTC(pScrn);
+}
+
+static void
+NVCommonSetup(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ vgaHWPtr pVga = VGAHWPTR(pScrn);
+ CARD32 regBase = pNv->IOAddress;
+ int mmioFlags;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVCommonSetup\n"));
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Regbase %x\n", regBase));
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- riva %x\n", &pNv->riva));
+
+ pNv->Save = NVDACSave;
+ pNv->Restore = NVDACRestore;
+ pNv->ModeInit = NVDACInit;
+
+ pNv->Dac.LoadPalette = NVDACLoadPalette;
+
+ /*
+ * Override VGA I/O routines.
+ */
+ pVga->writeCrtc = NVWriteCrtc;
+ pVga->readCrtc = NVReadCrtc;
+ pVga->writeGr = NVWriteGr;
+ pVga->readGr = NVReadGr;
+ pVga->writeAttr = NVWriteAttr;
+ pVga->readAttr = NVReadAttr;
+ pVga->writeSeq = NVWriteSeq;
+ pVga->readSeq = NVReadSeq;
+ pVga->writeMiscOut = NVWriteMiscOut;
+ pVga->readMiscOut = NVReadMiscOut;
+ pVga->enablePalette = NVEnablePalette;
+ pVga->disablePalette = NVDisablePalette;
+ pVga->writeDacMask = NVWriteDacMask;
+ pVga->readDacMask = NVReadDacMask;
+ pVga->writeDacWriteAddr = NVWriteDacWriteAddr;
+ pVga->writeDacReadAddr = NVWriteDacReadAddr;
+ pVga->writeDacData = NVWriteDacData;
+ pVga->readDacData = NVReadDacData;
+ /*
+ * Note: There are different pointers to the CRTC/AR and GR/SEQ registers.
+ * Bastardize the intended uses of these to make it work.
+ */
+ pVga->MMIOBase = (CARD8 *)pNv;
+ pVga->MMIOOffset = 0;
+
+ /*
+ * No IRQ in use.
+ */
+ pNv->riva.EnableIRQ = 0;
+ /*
+ * Map remaining registers. This MUST be done in the OS specific driver code.
+ */
+ pNv->riva.IO = VGA_IOBASE_COLOR;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- IO %x\n", pNv->riva.IO));
+
+ mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT;
+
+ pNv->riva.PRAMDAC0 = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
+ regBase+0x00680000, 0x00003000);
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- PRAMDAC %x\n", pNv->riva.PRAMDAC0));
+ pNv->riva.PFB = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
+ regBase+0x00100000, 0x00001000);
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- PFB %x\n", pNv->riva.PFB));
+ pNv->riva.PFIFO = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
+ regBase+0x00002000, 0x00002000);
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- PFIFO %x\n", pNv->riva.PFIFO));
+ pNv->riva.PGRAPH = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
+ regBase+0x00400000, 0x00002000);
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- PGRAPH %x\n", pNv->riva.PGRAPH));
+ pNv->riva.PEXTDEV = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
+ regBase+0x00101000, 0x00001000);
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- PEXTDEV %x\n", pNv->riva.PEXTDEV));
+ pNv->riva.PTIMER = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
+ regBase+0x00009000, 0x00001000);
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- PTIMER %x\n", pNv->riva.PTIMER));
+ pNv->riva.PMC = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
+ regBase+0x00000000, 0x00009000);
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- PMC %x\n", pNv->riva.PMC));
+ pNv->riva.FIFO = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
+ regBase+0x00800000, 0x00010000);
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- FIFO %x\n", pNv->riva.FIFO));
+
+ /*
+ * These registers are read/write as 8 bit values. Probably have to map
+ * sparse on alpha.
+ */
+ pNv->riva.PCIO0 = (U008 *)xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
+ pNv->PciTag, regBase+0x00601000,
+ 0x00003000);
+ pNv->riva.PDIO0 = (U008 *)xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
+ pNv->PciTag, regBase+0x00681000,
+ 0x00003000);
+ pNv->riva.PVIO = (U008 *)xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
+ pNv->PciTag, regBase+0x000C0000,
+ 0x00001000);
+
+ if(pNv->FlatPanel == -1) {
+ switch(pNv->Chipset & 0xffff) {
+ case 0x0112: /* known laptop chips */
+ case 0x0174:
+ case 0x0175:
+ case 0x0176:
+ case 0x0177:
+ case 0x0179:
+ case 0x017C:
+ case 0x017D:
+ case 0x0186:
+ case 0x0187:
+ case 0x0286:
+ case 0x028C:
+ case 0x0316:
+ case 0x0317:
+ case 0x031A:
+ case 0x031B:
+ case 0x031C:
+ case 0x031D:
+ case 0x031E:
+ case 0x031F:
+ case 0x0326:
+ case 0x032E:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "On a laptop. Assuming Digital Flat Panel\n");
+ pNv->FlatPanel = 1;
+ break;
+ default:
+ break;
+ }
+ }
+
+ pNv->DDCBase = 0x3e;
+
+ switch(pNv->Chipset & 0x0ff0) {
+ case 0x0110:
+ if((pNv->Chipset & 0xffff) == 0x0112)
+ pNv->SecondCRTC = TRUE;
+#if defined(__powerpc__)
+ else if(pNv->FlatPanel == 1)
+ pNv->SecondCRTC = TRUE;
+#endif
+ NVOverrideCRTC(pScrn);
+ break;
+ case 0x0170:
+ case 0x0180:
+ case 0x01F0:
+ case 0x0250:
+ case 0x0280:
+ case 0x0300:
+ case 0x0310:
+ case 0x0320:
+ case 0x0330:
+ case 0x0340:
+ NVIsSecond(pScrn);
+ break;
+ default:
+ break;
+ }
+
+ if(pNv->riva.Architecture == 3)
+ pNv->riva.PCRTC0 = pNv->riva.PGRAPH;
+
+ if(pNv->SecondCRTC) {
+ pNv->riva.PCIO = pNv->riva.PCIO0 + 0x2000;
+ pNv->riva.PCRTC = pNv->riva.PCRTC0 + 0x800;
+ pNv->riva.PRAMDAC = pNv->riva.PRAMDAC0 + 0x800;
+ pNv->riva.PDIO = pNv->riva.PDIO0 + 0x2000;
+ } else {
+ pNv->riva.PCIO = pNv->riva.PCIO0;
+ pNv->riva.PCRTC = pNv->riva.PCRTC0;
+ pNv->riva.PRAMDAC = pNv->riva.PRAMDAC0;
+ pNv->riva.PDIO = pNv->riva.PDIO0;
+ }
+
+ RivaGetConfig(pNv);
+
+ pNv->Dac.maxPixelClock = pNv->riva.MaxVClockFreqKHz;
+
+ pNv->riva.LockUnlock(&pNv->riva, 0);
+
+ NVRamdacInit(pScrn);
+
+#if !defined(__powerpc__)
+ /* Read and print the Monitor DDC info */
+ pScrn->monitor->DDC = NVdoDDC(pScrn);
+#endif
+ if(pNv->FlatPanel == -1) {
+ pNv->FlatPanel = 0;
+ if(pScrn->monitor->DDC) {
+ xf86MonPtr ddc = (xf86MonPtr)pScrn->monitor->DDC;
+
+ if(ddc->features.input_type) {
+ pNv->FlatPanel = 1;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "autodetected Digital Flat Panel\n");
+ }
+ }
+ }
+ pNv->riva.flatPanel = (pNv->FlatPanel > 0) ? FP_ENABLE : 0;
+ if(pNv->riva.flatPanel && pNv->FPDither && (pScrn->depth == 24))
+ pNv->riva.flatPanel |= FP_DITHER;
+
+}
+
+void
+NV1Setup(ScrnInfoPtr pScrn)
+{
+}
+
+void
+NV3Setup(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ CARD32 frameBase = pNv->FbAddress;
+ int mmioFlags;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV3Setup\n"));
+
+ /*
+ * Record chip architecture based in PCI probe.
+ */
+ pNv->riva.Architecture = 3;
+ /*
+ * Map chip-specific memory-mapped registers. This MUST be done in the OS specific driver code.
+ */
+ mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT;
+ pNv->riva.PRAMIN = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
+ frameBase+0x00C00000, 0x00008000);
+
+ NVCommonSetup(pScrn);
+}
+
+void
+NV4Setup(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ CARD32 regBase = pNv->IOAddress;
+ int mmioFlags;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV4Setup\n"));
+
+ pNv->riva.Architecture = 4;
+ /*
+ * Map chip-specific memory-mapped registers. This MUST be done in the OS specific driver code.
+ */
+ mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT;
+ pNv->riva.PRAMIN = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
+ regBase+0x00710000, 0x00010000);
+ pNv->riva.PCRTC0 = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
+ regBase+0x00600000, 0x00001000);
+
+ NVCommonSetup(pScrn);
+}
+
+void
+NV10Setup(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ CARD32 regBase = pNv->IOAddress;
+ int mmioFlags;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV10Setup\n"));
+
+ pNv->riva.Architecture = 0x10;
+ mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT;
+ pNv->riva.PRAMIN = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
+ regBase+0x00710000, 0x00010000);
+ pNv->riva.PCRTC0 = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
+ regBase+0x00600000, 0x00003000);
+
+ NVCommonSetup(pScrn);
+}
+
+void
+NV20Setup(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ CARD32 regBase = pNv->IOAddress;
+ int mmioFlags;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV20Setup\n"));
+
+ pNv->riva.Architecture = 0x20;
+ mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT;
+ pNv->riva.PRAMIN = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
+ regBase+0x00710000, 0x00010000);
+ pNv->riva.PCRTC0 = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
+ regBase+0x00600000, 0x00003000);
+
+ NVCommonSetup(pScrn);
+}
+
diff --git a/src/nv_shadow.c b/src/nv_shadow.c
new file mode 100644
index 0000000..5effc79
--- /dev/null
+++ b/src/nv_shadow.c
@@ -0,0 +1,194 @@
+/*
+ Copyright (c) 1999, The XFree86 Project Inc.
+ Written by Mark Vojkovich <markv@valinux.com>
+*/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_shadow.c,v 1.6 2001/01/22 21:32:36 dawes Exp $ */
+
+#include "nv_local.h"
+#include "nv_include.h"
+#include "nv_type.h"
+#include "shadowfb.h"
+#include "servermd.h"
+
+
+void
+NVRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ int width, height, Bpp, FBPitch;
+ unsigned char *src, *dst;
+
+ Bpp = pScrn->bitsPerPixel >> 3;
+ FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel);
+
+ while(num--) {
+ width = (pbox->x2 - pbox->x1) * Bpp;
+ height = pbox->y2 - pbox->y1;
+ src = pNv->ShadowPtr + (pbox->y1 * pNv->ShadowPitch) +
+ (pbox->x1 * Bpp);
+ dst = pNv->FbStart + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp);
+
+ while(height--) {
+ memcpy(dst, src, width);
+ dst += FBPitch;
+ src += pNv->ShadowPitch;
+ }
+
+ pbox++;
+ }
+}
+
+void
+NVPointerMoved(int index, int x, int y)
+{
+ ScrnInfoPtr pScrn = xf86Screens[index];
+ NVPtr pNv = NVPTR(pScrn);
+ int newX, newY;
+
+ if(pNv->Rotate == 1) {
+ newX = pScrn->pScreen->height - y - 1;
+ newY = x;
+ } else {
+ newX = y;
+ newY = pScrn->pScreen->width - x - 1;
+ }
+
+ (*pNv->PointerMoved)(index, newX, newY);
+}
+
+void
+NVRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ int count, width, height, y1, y2, dstPitch, srcPitch;
+ CARD8 *dstPtr, *srcPtr, *src;
+ CARD32 *dst;
+
+ dstPitch = pScrn->displayWidth;
+ srcPitch = -pNv->Rotate * pNv->ShadowPitch;
+
+ while(num--) {
+ width = pbox->x2 - pbox->x1;
+ y1 = pbox->y1 & ~3;
+ y2 = (pbox->y2 + 3) & ~3;
+ height = (y2 - y1) >> 2; /* in dwords */
+
+ if(pNv->Rotate == 1) {
+ dstPtr = pNv->FbStart +
+ (pbox->x1 * dstPitch) + pScrn->virtualX - y2;
+ srcPtr = pNv->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1;
+ } else {
+ dstPtr = pNv->FbStart +
+ ((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
+ srcPtr = pNv->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1;
+ }
+
+ while(width--) {
+ src = srcPtr;
+ dst = (CARD32*)dstPtr;
+ count = height;
+ while(count--) {
+ *(dst++) = src[0] | (src[srcPitch] << 8) |
+ (src[srcPitch * 2] << 16) |
+ (src[srcPitch * 3] << 24);
+ src += srcPitch * 4;
+ }
+ srcPtr += pNv->Rotate;
+ dstPtr += dstPitch;
+ }
+
+ pbox++;
+ }
+}
+
+
+void
+NVRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ int count, width, height, y1, y2, dstPitch, srcPitch;
+ CARD16 *dstPtr, *srcPtr, *src;
+ CARD32 *dst;
+
+ dstPitch = pScrn->displayWidth;
+ srcPitch = -pNv->Rotate * pNv->ShadowPitch >> 1;
+
+ while(num--) {
+ width = pbox->x2 - pbox->x1;
+ y1 = pbox->y1 & ~1;
+ y2 = (pbox->y2 + 1) & ~1;
+ height = (y2 - y1) >> 1; /* in dwords */
+
+ if(pNv->Rotate == 1) {
+ dstPtr = (CARD16*)pNv->FbStart +
+ (pbox->x1 * dstPitch) + pScrn->virtualX - y2;
+ srcPtr = (CARD16*)pNv->ShadowPtr +
+ ((1 - y2) * srcPitch) + pbox->x1;
+ } else {
+ dstPtr = (CARD16*)pNv->FbStart +
+ ((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
+ srcPtr = (CARD16*)pNv->ShadowPtr +
+ (y1 * srcPitch) + pbox->x2 - 1;
+ }
+
+ while(width--) {
+ src = srcPtr;
+ dst = (CARD32*)dstPtr;
+ count = height;
+ while(count--) {
+ *(dst++) = src[0] | (src[srcPitch] << 16);
+ src += srcPitch * 2;
+ }
+ srcPtr += pNv->Rotate;
+ dstPtr += dstPitch;
+ }
+
+ pbox++;
+ }
+}
+
+
+void
+NVRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ int count, width, height, dstPitch, srcPitch;
+ CARD32 *dstPtr, *srcPtr, *src, *dst;
+
+ dstPitch = pScrn->displayWidth;
+ srcPitch = -pNv->Rotate * pNv->ShadowPitch >> 2;
+
+ while(num--) {
+ width = pbox->x2 - pbox->x1;
+ height = pbox->y2 - pbox->y1;
+
+ if(pNv->Rotate == 1) {
+ dstPtr = (CARD32*)pNv->FbStart +
+ (pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2;
+ srcPtr = (CARD32*)pNv->ShadowPtr +
+ ((1 - pbox->y2) * srcPitch) + pbox->x1;
+ } else {
+ dstPtr = (CARD32*)pNv->FbStart +
+ ((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1;
+ srcPtr = (CARD32*)pNv->ShadowPtr +
+ (pbox->y1 * srcPitch) + pbox->x2 - 1;
+ }
+
+ while(width--) {
+ src = srcPtr;
+ dst = dstPtr;
+ count = height;
+ while(count--) {
+ *(dst++) = *src;
+ src += srcPitch;
+ }
+ srcPtr += pNv->Rotate;
+ dstPtr += dstPitch;
+ }
+
+ pbox++;
+ }
+}
+
+
+
diff --git a/src/nv_type.h b/src/nv_type.h
new file mode 100644
index 0000000..9e9e2bd
--- /dev/null
+++ b/src/nv_type.h
@@ -0,0 +1,135 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_type.h,v 1.39 2002/11/28 23:02:13 mvojkovi Exp $ */
+
+#ifndef __NV_STRUCT_H__
+#define __NV_STRUCT_H__
+
+#include "riva_hw.h"
+#include "colormapst.h"
+#include "vgaHW.h"
+#include "xaa.h"
+#include "xf86Cursor.h"
+#include "xf86int10.h"
+
+
+#define BITMASK(t,b) (((unsigned)(1U << (((t)-(b)+1)))-1) << (b))
+#define MASKEXPAND(mask) BITMASK(1?mask,0?mask)
+#define SetBF(mask,value) ((value) << (0?mask))
+#define GetBF(var,mask) (((unsigned)((var) & MASKEXPAND(mask))) >> (0?mask) )
+#define SetBitField(value,from,to) SetBF(to, GetBF(value,from))
+#define SetBit(n) (1<<(n))
+#define Set8Bits(value) ((value)&0xff)
+
+typedef RIVA_HW_STATE* NVRegPtr;
+
+typedef struct {
+ Bool isHwCursor;
+ int CursorMaxWidth;
+ int CursorMaxHeight;
+ int CursorFlags;
+ int CursorOffscreenMemSize;
+ Bool (*UseHWCursor)(ScreenPtr, CursorPtr);
+ void (*LoadCursorImage)(ScrnInfoPtr, unsigned char*);
+ void (*ShowCursor)(ScrnInfoPtr);
+ void (*HideCursor)(ScrnInfoPtr);
+ void (*SetCursorPosition)(ScrnInfoPtr, int, int);
+ void (*SetCursorColors)(ScrnInfoPtr, int, int);
+ long maxPixelClock;
+ void (*LoadPalette)(ScrnInfoPtr, int, int*, LOCO*, VisualPtr);
+ void (*Save)(ScrnInfoPtr, vgaRegPtr, NVRegPtr, Bool);
+ void (*Restore)(ScrnInfoPtr, vgaRegPtr, NVRegPtr, Bool);
+ Bool (*ModeInit)(ScrnInfoPtr, DisplayModePtr);
+} NVRamdacRec, *NVRamdacPtr;
+
+typedef struct {
+ int bitsPerPixel;
+ int depth;
+ int displayWidth;
+ rgb weight;
+ DisplayModePtr mode;
+} NVFBLayout;
+
+typedef struct {
+ RIVA_HW_INST riva;
+ RIVA_HW_STATE SavedReg;
+ RIVA_HW_STATE ModeReg;
+ EntityInfoPtr pEnt;
+ pciVideoPtr PciInfo;
+ PCITAG PciTag;
+ xf86AccessRec Access;
+ int Chipset;
+ int ChipRev;
+ Bool Primary;
+ CARD32 IOAddress;
+ unsigned long FbAddress;
+ int FbBaseReg;
+ unsigned char * IOBase;
+ unsigned char * FbBase;
+ unsigned char * FbStart;
+ long FbMapSize;
+ long FbUsableSize;
+ NVRamdacRec Dac;
+ Bool NoAccel;
+ Bool HWCursor;
+ Bool ShowCache;
+ Bool ShadowFB;
+ unsigned char * ShadowPtr;
+ int ShadowPitch;
+ int MinClock;
+ int MaxClock;
+ XAAInfoRecPtr AccelInfoRec;
+ xf86CursorInfoPtr CursorInfoRec;
+ DGAModePtr DGAModes;
+ int numDGAModes;
+ Bool DGAactive;
+ int DGAViewportStatus;
+ void (*Save)(ScrnInfoPtr, vgaRegPtr, NVRegPtr, Bool);
+ void (*Restore)(ScrnInfoPtr, vgaRegPtr, NVRegPtr, Bool);
+ Bool (*ModeInit)(ScrnInfoPtr, DisplayModePtr);
+ void (*PointerMoved)(int index, int x, int y);
+ ScreenBlockHandlerProcPtr BlockHandler;
+ CloseScreenProcPtr CloseScreen;
+ Bool FBDev;
+ /* Color expansion */
+ unsigned char *expandBuffer;
+ unsigned char *expandFifo;
+ int expandWidth;
+ int expandRows;
+ CARD32 FgColor;
+ CARD32 BgColor;
+ int Rotate;
+ NVFBLayout CurrentLayout;
+ /* Cursor */
+ CARD32 curFg, curBg;
+ CARD32 curImage[256];
+ /* Misc flags */
+ unsigned int opaqueMonochrome;
+ int currentRop;
+ /* I2C / DDC */
+ unsigned int (*ddc1Read)(ScrnInfoPtr);
+ void (*DDC1SetSpeed)(ScrnInfoPtr, xf86ddcSpeed);
+ Bool (*i2cInit)(ScrnInfoPtr);
+ I2CBusPtr I2C;
+ xf86Int10InfoPtr pInt;
+ void (*VideoTimerCallback)(ScrnInfoPtr, Time);
+ XF86VideoAdaptorPtr overlayAdaptor;
+ int videoKey;
+ int FlatPanel;
+ Bool FPDither;
+ Bool SecondCRTC;
+ int forceCRTC;
+ OptionInfoPtr Options;
+ Bool alphaCursor;
+ unsigned char DDCBase;
+} NVRec, *NVPtr;
+
+#define NVPTR(p) ((NVPtr)((p)->driverPrivate))
+
+void NVRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+void NVRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+void NVRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+void NVRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+void NVPointerMoved(int index, int x, int y);
+
+int RivaGetConfig(NVPtr);
+
+#endif /* __NV_STRUCT_H__ */
diff --git a/src/nv_video.c b/src/nv_video.c
new file mode 100644
index 0000000..e2010a9
--- /dev/null
+++ b/src/nv_video.c
@@ -0,0 +1,1160 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_video.c,v 1.11 2002/11/26 23:41:59 mvojkovi Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "xf86_ansic.h"
+#include "compiler.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "xf86fbman.h"
+#include "regionstr.h"
+
+#include "xf86xv.h"
+#include "Xv.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "dixstruct.h"
+#include "fourcc.h"
+
+#include "nv_include.h"
+
+
+#define OFF_DELAY 450 /* milliseconds */
+#define FREE_DELAY 10000
+
+#define OFF_TIMER 0x01
+#define FREE_TIMER 0x02
+#define CLIENT_VIDEO_ON 0x04
+
+#define TIMER_MASK (OFF_TIMER | FREE_TIMER)
+
+
+
+#ifndef XvExtension
+void NVInitVideo(ScreenPtr pScreen) {}
+#else
+
+typedef struct _NVPortPrivRec {
+ short brightness;
+ short contrast;
+ short saturation;
+ short hue;
+ RegionRec clip;
+ CARD32 colorKey;
+ Bool autopaintColorKey;
+ Bool doubleBuffer;
+ CARD32 videoStatus;
+ int currentBuffer;
+ Time videoTime;
+ Bool grabbedByV4L;
+ Bool iturbt_709;
+ FBLinearPtr linear;
+ int pitch;
+ int offset;
+} NVPortPrivRec, *NVPortPrivPtr;
+
+
+static XF86VideoAdaptorPtr NVSetupImageVideo(ScreenPtr);
+
+static void NVStopOverlay (ScrnInfoPtr);
+static void NVPutOverlayImage(ScrnInfoPtr pScrnInfo,
+ int offset,
+ int id,
+ int dstPitch,
+ BoxPtr dstBox,
+ int x1, int y1, int x2, int y2,
+ short width, short height,
+ short src_w, short src_h,
+ short dst_w, short dst_h,
+ RegionPtr cliplist);
+
+static int NVSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer);
+static int NVGetPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer);
+
+static void NVStopOverlayVideo(ScrnInfoPtr, pointer, Bool);
+
+static int NVPutImage( ScrnInfoPtr, short, short, short, short, short, short, short, short, int, unsigned char*, short, short, Bool, RegionPtr, pointer);
+static void NVQueryBestSize(ScrnInfoPtr, Bool, short, short, short, short, unsigned int *, unsigned int *, pointer);
+static int NVQueryImageAttributes(ScrnInfoPtr, int, unsigned short *, unsigned short *, int *, int *);
+
+static void NVVideoTimerCallback(ScrnInfoPtr, Time);
+
+static void NVInitOffscreenImages (ScreenPtr pScreen);
+
+
+#define GET_OVERLAY_PRIVATE(pNv) \
+ (NVPortPrivPtr)((pNv)->overlayAdaptor->pPortPrivates[0].ptr)
+
+#define GET_BLIT_PRIVATE(pNv) \
+ (NVPortPrivPtr)((pNv)->blitAdaptor->pPortPrivates[0].ptr)
+
+#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
+
+static Atom xvBrightness, xvContrast, xvColorKey, xvSaturation,
+ xvHue, xvAutopaintColorKey, xvSetDefaults, xvDoubleBuffer,
+ xvITURBT709;
+
+/* client libraries expect an encoding */
+static XF86VideoEncodingRec DummyEncoding =
+{
+ 0,
+ "XV_IMAGE",
+ 2046, 2046,
+ {1, 1}
+};
+
+#define NUM_FORMATS_ALL 6
+
+XF86VideoFormatRec NVFormats[NUM_FORMATS_ALL] =
+{
+ {15, TrueColor}, {16, TrueColor}, {24, TrueColor},
+ {15, DirectColor}, {16, DirectColor}, {24, DirectColor}
+};
+
+#define NUM_ATTRIBUTES 9
+
+XF86AttributeRec NVAttributes[NUM_ATTRIBUTES] =
+{
+ {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"},
+ {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"},
+ {XvSettable | XvGettable, 0, 1, "XV_AUTOPAINT_COLORKEY"},
+ {XvSettable , 0, 0, "XV_SET_DEFAULTS"},
+ {XvSettable | XvGettable, -512, 511, "XV_BRIGHTNESS"},
+ {XvSettable | XvGettable, 0, 8191, "XV_CONTRAST"},
+ {XvSettable | XvGettable, 0, 8191, "XV_SATURATION"},
+ {XvSettable | XvGettable, 0, 360, "XV_HUE"},
+ {XvSettable | XvGettable, 0, 1, "XV_ITURBT_709"}
+};
+
+#define NUM_IMAGES_ALL 4
+
+static XF86ImageRec NVImages[NUM_IMAGES_ALL] =
+{
+ XVIMAGE_YUY2,
+ XVIMAGE_YV12,
+ XVIMAGE_UYVY,
+ XVIMAGE_I420
+};
+
+static void
+NVSetPortDefaults (ScrnInfoPtr pScrnInfo, NVPortPrivPtr pPriv)
+{
+ NVPtr pNv = NVPTR(pScrnInfo);
+
+ pPriv->brightness = 0;
+ pPriv->contrast = 4096;
+ pPriv->saturation = 4096;
+ pPriv->hue = 0;
+ pPriv->colorKey = pNv->videoKey;
+ pPriv->autopaintColorKey = TRUE;
+ pPriv->doubleBuffer = TRUE;
+ pPriv->iturbt_709 = FALSE;
+}
+
+
+void
+NVResetVideo (ScrnInfoPtr pScrnInfo)
+{
+ NVPtr pNv = NVPTR(pScrnInfo);
+ NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv);
+ RIVA_HW_INST *pRiva = &(pNv->riva);
+ int satSine, satCosine;
+ double angle;
+
+ angle = (double)pPriv->hue * 3.1415927 / 180.0;
+
+ satSine = pPriv->saturation * sin(angle);
+ if (satSine < -1024)
+ satSine = -1024;
+ satCosine = pPriv->saturation * cos(angle);
+ if (satCosine < -1024)
+ satCosine = -1024;
+
+ pRiva->PMC[0x00008910/4] = (pPriv->brightness << 16) | pPriv->contrast;
+ pRiva->PMC[0x00008914/4] = (pPriv->brightness << 16) | pPriv->contrast;
+ pRiva->PMC[0x00008918/4] = (satSine << 16) | (satCosine & 0xffff);
+ pRiva->PMC[0x0000891C/4] = (satSine << 16) | (satCosine & 0xffff);
+ pRiva->PMC[0x00008b00/4] = pPriv->colorKey;
+}
+
+
+
+static void
+NVStopOverlay (ScrnInfoPtr pScrnInfo)
+{
+ NVPtr pNv = NVPTR(pScrnInfo);
+ RIVA_HW_INST *pRiva = &(pNv->riva);
+
+ pRiva->PMC[0x00008704/4] = 1;
+}
+
+static FBLinearPtr
+NVAllocateOverlayMemory(
+ ScrnInfoPtr pScrn,
+ FBLinearPtr linear,
+ int size
+){
+ ScreenPtr pScreen;
+ FBLinearPtr new_linear;
+
+ if(linear) {
+ if(linear->size >= size)
+ return linear;
+
+ if(xf86ResizeOffscreenLinear(linear, size))
+ return linear;
+
+ xf86FreeOffscreenLinear(linear);
+ }
+
+ pScreen = screenInfo.screens[pScrn->scrnIndex];
+
+ new_linear = xf86AllocateOffscreenLinear(pScreen, size, 32,
+ NULL, NULL, NULL);
+
+ if(!new_linear) {
+ int max_size;
+
+ xf86QueryLargestOffscreenLinear(pScreen, &max_size, 32,
+ PRIORITY_EXTREME);
+
+ if(max_size < size)
+ return NULL;
+
+ xf86PurgeUnlockedOffscreenAreas(pScreen);
+ new_linear = xf86AllocateOffscreenLinear(pScreen, size, 32,
+ NULL, NULL, NULL);
+ }
+
+ return new_linear;
+}
+
+static void NVFreeOverlayMemory(ScrnInfoPtr pScrnInfo)
+{
+ NVPtr pNv = NVPTR(pScrnInfo);
+ NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv);
+
+ if(pPriv->linear) {
+ xf86FreeOffscreenLinear(pPriv->linear);
+ pPriv->linear = NULL;
+ }
+}
+
+
+void NVInitVideo (ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL;
+ XF86VideoAdaptorPtr overlayAdaptor = NULL;
+ NVPtr pNv = NVPTR(pScrn);
+ int num_adaptors;
+
+ if((pScrn->bitsPerPixel != 8) && (pNv->riva.Architecture >= NV_ARCH_10))
+ {
+ overlayAdaptor = NVSetupImageVideo(pScreen);
+
+ if(overlayAdaptor)
+ NVInitOffscreenImages(pScreen);
+ }
+
+ num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
+
+ if(overlayAdaptor) {
+ int size = num_adaptors + 1;
+
+ if((newAdaptors = xalloc(size * sizeof(XF86VideoAdaptorPtr*)))) {
+ if(num_adaptors)
+ memcpy(newAdaptors, adaptors,
+ num_adaptors * sizeof(XF86VideoAdaptorPtr));
+
+ if(overlayAdaptor) {
+ newAdaptors[num_adaptors] = overlayAdaptor;
+ num_adaptors++;
+ }
+ adaptors = newAdaptors;
+ }
+ }
+
+ if (num_adaptors)
+ xf86XVScreenInit(pScreen, adaptors, num_adaptors);
+
+ if (newAdaptors)
+ xfree(newAdaptors);
+}
+
+
+static XF86VideoAdaptorPtr
+NVSetupImageVideo (ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrnInfo = xf86Screens[pScreen->myNum];
+ NVPtr pNv = NVPTR(pScrnInfo);
+ XF86VideoAdaptorPtr adapt;
+ NVPortPrivPtr pPriv;
+
+ if (!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) +
+ sizeof(NVPortPrivRec) +
+ sizeof(DevUnion))))
+ {
+ return NULL;
+ }
+
+ adapt->type = XvWindowMask | XvInputMask | XvImageMask;
+ adapt->flags = VIDEO_OVERLAID_IMAGES|VIDEO_CLIP_TO_VIEWPORT;
+ adapt->name = "NV Video Overlay";
+ adapt->nEncodings = 1;
+ adapt->pEncodings = &DummyEncoding;
+ adapt->nFormats = NUM_FORMATS_ALL;
+ adapt->pFormats = NVFormats;
+ adapt->nPorts = 1;
+ adapt->pPortPrivates = (DevUnion*)(&adapt[1]);
+ pPriv = (NVPortPrivPtr)(&adapt->pPortPrivates[1]);
+ adapt->pPortPrivates[0].ptr = (pointer)(pPriv);
+ adapt->pAttributes = NVAttributes;
+ adapt->nAttributes = NUM_ATTRIBUTES;
+ adapt->pImages = NVImages;
+ adapt->nImages = NUM_IMAGES_ALL;
+ adapt->PutVideo = NULL;
+ adapt->PutStill = NULL;
+ adapt->GetVideo = NULL;
+ adapt->GetStill = NULL;
+ adapt->StopVideo = NVStopOverlayVideo;
+ adapt->SetPortAttribute = NVSetPortAttribute;
+ adapt->GetPortAttribute = NVGetPortAttribute;
+ adapt->QueryBestSize = NVQueryBestSize;
+ adapt->PutImage = NVPutImage;
+ adapt->QueryImageAttributes = NVQueryImageAttributes;
+
+ pPriv->videoStatus = 0;
+ pPriv->currentBuffer = 0;
+ pPriv->grabbedByV4L = FALSE;
+
+ NVSetPortDefaults (pScrnInfo, pPriv);
+
+ /* gotta uninit this someplace */
+ REGION_INIT(pScreen, &pPriv->clip, NullBox, 0);
+
+ pNv->overlayAdaptor = adapt;
+
+ xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
+ xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER");
+ xvContrast = MAKE_ATOM("XV_CONTRAST");
+ xvColorKey = MAKE_ATOM("XV_COLORKEY");
+ xvSaturation = MAKE_ATOM("XV_SATURATION");
+ xvHue = MAKE_ATOM("XV_HUE");
+ xvAutopaintColorKey = MAKE_ATOM("XV_AUTOPAINT_COLORKEY");
+ xvSetDefaults = MAKE_ATOM("XV_SET_DEFAULTS");
+ xvITURBT709 = MAKE_ATOM("XV_ITURBT_709");
+
+ NVResetVideo(pScrnInfo);
+
+ return adapt;
+}
+
+/*
+ * RegionsEqual
+ */
+static Bool RegionsEqual
+(
+ RegionPtr A,
+ RegionPtr B
+)
+{
+ int *dataA, *dataB;
+ int num;
+
+ num = REGION_NUM_RECTS(A);
+ if (num != REGION_NUM_RECTS(B))
+ return FALSE;
+
+ if ((A->extents.x1 != B->extents.x1) ||
+ (A->extents.x2 != B->extents.x2) ||
+ (A->extents.y1 != B->extents.y1) ||
+ (A->extents.y2 != B->extents.y2))
+ return FALSE;
+
+ dataA = (int*)REGION_RECTS(A);
+ dataB = (int*)REGION_RECTS(B);
+
+ while(num--)
+ {
+ if((dataA[0] != dataB[0]) || (dataA[1] != dataB[1]))
+ return FALSE;
+ dataA += 2;
+ dataB += 2;
+ }
+ return TRUE;
+}
+
+static void
+NVPutOverlayImage (
+ ScrnInfoPtr pScrnInfo,
+ int offset,
+ int id,
+ int dstPitch,
+ BoxPtr dstBox,
+ int x1,
+ int y1,
+ int x2,
+ int y2,
+ short width,
+ short height,
+ short src_w,
+ short src_h,
+ short drw_w,
+ short drw_h,
+ RegionPtr clipBoxes
+)
+{
+ NVPtr pNv = NVPTR(pScrnInfo);
+ NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv);
+ RIVA_HW_INST *pRiva = &(pNv->riva);
+ int buffer = pPriv->currentBuffer;
+
+ /* paint the color key */
+ if(pPriv->autopaintColorKey &&
+ (pPriv->grabbedByV4L || !RegionsEqual(&pPriv->clip, clipBoxes)))
+ {
+ /* we always paint V4L's color key */
+ if(!pPriv->grabbedByV4L)
+ REGION_COPY(pScrnInfo->pScreen, &pPriv->clip, clipBoxes);
+ xf86XVFillKeyHelper(pScrnInfo->pScreen, pPriv->colorKey, clipBoxes);
+ }
+
+ pRiva->PMC[(0x8900/4) + buffer] = offset;
+ pRiva->PMC[(0x8928/4) + buffer] = (height << 16) | width;
+ pRiva->PMC[(0x8930/4) + buffer] = ((y1 << 4) & 0xffff0000) | (x1 >> 12);
+ pRiva->PMC[(0x8938/4) + buffer] = (src_w << 20) / drw_w;
+ pRiva->PMC[(0x8940/4) + buffer] = (src_h << 20) / drw_h;
+ pRiva->PMC[(0x8948/4) + buffer] = (dstBox->y1 << 16) | dstBox->x1;
+ pRiva->PMC[(0x8950/4) + buffer] = ((dstBox->y2 - dstBox->y1) << 16) |
+ (dstBox->x2 - dstBox->x1);
+
+ dstPitch |= 1 << 20; /* use color key */
+
+ if(id != FOURCC_UYVY)
+ dstPitch |= 1 << 16;
+ if(pPriv->iturbt_709)
+ dstPitch |= 1 << 24;
+
+ pRiva->PMC[(0x8958/4) + buffer] = dstPitch;
+ pRiva->PMC[0x00008704/4] = 0;
+ pRiva->PMC[0x8700/4] = 1 << (buffer << 2);
+
+ pPriv->videoStatus = CLIENT_VIDEO_ON;
+}
+
+
+
+/*
+ * StopVideo
+ */
+static void NVStopOverlayVideo
+(
+ ScrnInfoPtr pScrnInfo,
+ pointer data,
+ Bool Exit
+)
+{
+ NVPtr pNv = NVPTR(pScrnInfo);
+ NVPortPrivPtr pPriv = (NVPortPrivPtr)data;
+
+ if(pPriv->grabbedByV4L) return;
+
+ REGION_EMPTY(pScrnInfo->pScreen, &pPriv->clip);
+
+ if(Exit)
+ {
+ if(pPriv->videoStatus & CLIENT_VIDEO_ON)
+ NVStopOverlay(pScrnInfo);
+ NVFreeOverlayMemory(pScrnInfo);
+ pPriv->videoStatus = 0;
+ pNv->VideoTimerCallback = NULL;
+ }
+ else
+ {
+ if(pPriv->videoStatus & CLIENT_VIDEO_ON)
+ {
+ pPriv->videoStatus = OFF_TIMER | CLIENT_VIDEO_ON;
+ pPriv->videoTime = currentTime.milliseconds + OFF_DELAY;
+ pNv->VideoTimerCallback = NVVideoTimerCallback;
+ }
+ }
+}
+
+
+
+static int NVSetPortAttribute
+(
+ ScrnInfoPtr pScrnInfo,
+ Atom attribute,
+ INT32 value,
+ pointer data
+)
+{
+ NVPortPrivPtr pPriv = (NVPortPrivPtr)data;
+
+ if (attribute == xvBrightness)
+ {
+ if ((value < -512) || (value > 512))
+ return BadValue;
+ pPriv->brightness = value;
+ }
+ else if (attribute == xvDoubleBuffer)
+ {
+ if ((value < 0) || (value > 1))
+ return BadValue;
+ pPriv->doubleBuffer = value;
+ }
+ else if (attribute == xvContrast)
+ {
+ if ((value < 0) || (value > 8191))
+ return BadValue;
+ pPriv->contrast = value;
+ }
+ else if (attribute == xvHue)
+ {
+ value %= 360;
+ if (value < 0)
+ value += 360;
+ pPriv->hue = value;
+ }
+ else if (attribute == xvSaturation)
+ {
+ if ((value < 0) || (value > 8191))
+ return BadValue;
+ pPriv->saturation = value;
+ }
+ else if (attribute == xvColorKey)
+ {
+ pPriv->colorKey = value;
+ REGION_EMPTY(pScrnInfo->pScreen, &pPriv->clip);
+ }
+ else if (attribute == xvAutopaintColorKey)
+ {
+ if ((value < 0) || (value > 1))
+ return BadValue;
+ pPriv->autopaintColorKey = value;
+ }
+ else if (attribute == xvITURBT709)
+ {
+ if ((value < 0) || (value > 1))
+ return BadValue;
+ pPriv->iturbt_709 = value;
+ }
+ else if (attribute == xvSetDefaults)
+ {
+ NVSetPortDefaults(pScrnInfo, pPriv);
+ }
+ else
+ return BadMatch;
+
+ NVResetVideo(pScrnInfo);
+ return Success;
+}
+
+
+
+
+static int NVGetPortAttribute
+(
+ ScrnInfoPtr pScrnInfo,
+ Atom attribute,
+ INT32 *value,
+ pointer data
+)
+{
+ NVPortPrivPtr pPriv = (NVPortPrivPtr)data;
+
+ if (attribute == xvBrightness)
+ *value = pPriv->brightness;
+ else if (attribute == xvDoubleBuffer)
+ *value = (pPriv->doubleBuffer) ? 1 : 0;
+ else if (attribute == xvContrast)
+ *value = pPriv->contrast;
+ else if (attribute == xvSaturation)
+ *value = pPriv->saturation;
+ else if (attribute == xvHue)
+ *value = pPriv->hue;
+ else if (attribute == xvColorKey)
+ *value = pPriv->colorKey;
+ else if (attribute == xvAutopaintColorKey)
+ *value = (pPriv->autopaintColorKey) ? 1 : 0;
+ else if (attribute == xvITURBT709)
+ *value = (pPriv->iturbt_709) ? 1 : 0;
+ else
+ return BadMatch;
+
+ return Success;
+}
+
+
+/*
+ * QueryBestSize
+ */
+static void NVQueryBestSize
+(
+ ScrnInfoPtr pScrnInfo,
+ Bool motion,
+ short vid_w,
+ short vid_h,
+ short drw_w,
+ short drw_h,
+ unsigned int *p_w,
+ unsigned int *p_h,
+ pointer data
+)
+{
+ if(vid_w > (drw_w << 3))
+ drw_w = vid_w >> 3;
+ if(vid_h > (drw_h << 3))
+ drw_h = vid_h >> 3;
+
+ *p_w = drw_w;
+ *p_h = drw_h;
+}
+/*
+ * CopyData
+ */
+static void NVCopyData422
+(
+ unsigned char *src,
+ unsigned char *dst,
+ int srcPitch,
+ int dstPitch,
+ int h,
+ int w
+)
+{
+ w <<= 1;
+ while(h--)
+ {
+ memcpy(dst, src, w);
+ src += srcPitch;
+ dst += dstPitch;
+ }
+}
+/*
+ * CopyMungedData
+ */
+static void NVCopyData420
+(
+ unsigned char *src1,
+ unsigned char *src2,
+ unsigned char *src3,
+ unsigned char *dst1,
+ int srcPitch,
+ int srcPitch2,
+ int dstPitch,
+ int h,
+ int w
+)
+{
+ CARD32 *dst;
+ CARD8 *s1, *s2, *s3;
+ int i, j;
+
+ w >>= 1;
+
+ for(j = 0; j < h; j++) {
+ dst = (CARD32*)dst1;
+ s1 = src1; s2 = src2; s3 = src3;
+ i = w;
+ while(i > 4) {
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ dst[0] = (s1[0] << 24) | (s1[1] << 8) | (s3[0] << 16) | s2[0];
+ dst[1] = (s1[2] << 24) | (s1[3] << 8) | (s3[1] << 16) | s2[1];
+ dst[2] = (s1[4] << 24) | (s1[5] << 8) | (s3[2] << 16) | s2[2];
+ dst[3] = (s1[6] << 24) | (s1[7] << 8) | (s3[3] << 16) | s2[3];
+#else
+ dst[0] = s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24);
+ dst[1] = s1[2] | (s1[3] << 16) | (s3[1] << 8) | (s2[1] << 24);
+ dst[2] = s1[4] | (s1[5] << 16) | (s3[2] << 8) | (s2[2] << 24);
+ dst[3] = s1[6] | (s1[7] << 16) | (s3[3] << 8) | (s2[3] << 24);
+#endif
+ dst += 4; s2 += 4; s3 += 4; s1 += 8;
+ i -= 4;
+ }
+
+ while(i--) {
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ dst[0] = (s1[0] << 24) | (s1[1] << 8) | (s3[0] << 16) | s2[0];
+#else
+ dst[0] = s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24);
+#endif
+ dst++; s2++; s3++;
+ s1 += 2;
+ }
+
+ dst1 += dstPitch;
+ src1 += srcPitch;
+ if(j & 1) {
+ src2 += srcPitch2;
+ src3 += srcPitch2;
+ }
+ }
+}
+/*
+ * PutImage
+ */
+static int NVPutImage
+(
+ ScrnInfoPtr pScrnInfo,
+ short src_x,
+ short src_y,
+ short drw_x,
+ short drw_y,
+ short src_w,
+ short src_h,
+ short drw_w,
+ short drw_h,
+ int id,
+ unsigned char *buf,
+ short width,
+ short height,
+ Bool Sync,
+ RegionPtr clipBoxes,
+ pointer data
+)
+{
+ NVPortPrivPtr pPriv = (NVPortPrivPtr)data;
+ NVPtr pNv = NVPTR(pScrnInfo);
+ INT32 xa, xb, ya, yb;
+ unsigned char *dst_start;
+ int pitch, newSize, offset, s2offset, s3offset;
+ int srcPitch, srcPitch2, dstPitch;
+ int top, left, npixels, nlines, bpp;
+ Bool skip = FALSE;
+ BoxRec dstBox;
+ CARD32 tmp;
+
+ /*
+ * s2offset, s3offset - byte offsets into U and V plane of the
+ * source where copying starts. Y plane is
+ * done by editing "buf".
+ *
+ * offset - byte offset to the first line of the destination.
+ *
+ * dst_start - byte address to the first displayed pel.
+ *
+ */
+
+ if(pPriv->grabbedByV4L) return Success;
+
+ /* make the compiler happy */
+ s2offset = s3offset = srcPitch2 = 0;
+
+ if(src_w > (drw_w << 3))
+ drw_w = src_w >> 3;
+ if(src_h > (drw_h << 3))
+ drw_h = src_h >> 3;
+
+ /* Clip */
+ xa = src_x;
+ xb = src_x + src_w;
+ ya = src_y;
+ yb = src_y + src_h;
+
+ dstBox.x1 = drw_x;
+ dstBox.x2 = drw_x + drw_w;
+ dstBox.y1 = drw_y;
+ dstBox.y2 = drw_y + drw_h;
+
+ if(!xf86XVClipVideoHelper(&dstBox, &xa, &xb, &ya, &yb, clipBoxes,
+ width, height))
+ return Success;
+
+ dstBox.x1 -= pScrnInfo->frameX0;
+ dstBox.x2 -= pScrnInfo->frameX0;
+ dstBox.y1 -= pScrnInfo->frameY0;
+ dstBox.y2 -= pScrnInfo->frameY0;
+
+ bpp = pScrnInfo->bitsPerPixel >> 3;
+ pitch = bpp * pScrnInfo->displayWidth;
+
+ dstPitch = ((width << 1) + 63) & ~63;
+
+ switch(id) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ srcPitch = (width + 3) & ~3; /* of luma */
+ s2offset = srcPitch * height;
+ srcPitch2 = ((width >> 1) + 3) & ~3;
+ s3offset = (srcPitch2 * (height >> 1)) + s2offset;
+ break;
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ default:
+ srcPitch = (width << 1);
+ break;
+ }
+
+ newSize = height * dstPitch / bpp;
+
+ if(pPriv->doubleBuffer)
+ newSize <<= 1;
+
+ pPriv->linear = NVAllocateOverlayMemory(pScrnInfo,
+ pPriv->linear,
+ newSize);
+
+ if(!pPriv->linear) return BadAlloc;
+
+ offset = pPriv->linear->offset * bpp;
+
+ if(pPriv->doubleBuffer) {
+ RIVA_HW_INST *pRiva = &(pNv->riva);
+ int mask = 1 << (pPriv->currentBuffer << 2);
+
+#if 0
+ /* burn the CPU until the next buffer is available */
+ while(pRiva->PMC[0x00008700/4] & mask);
+#else
+ /* overwrite the newest buffer if there's not one free */
+ if(pRiva->PMC[0x00008700/4] & mask) {
+ if(!pPriv->currentBuffer)
+ offset += (newSize * bpp) >> 1;
+ skip = TRUE;
+ } else
+#endif
+ if(pPriv->currentBuffer)
+ offset += (newSize * bpp) >> 1;
+ }
+
+ dst_start = pNv->FbStart + offset;
+
+ /* copy data */
+ top = ya >> 16;
+ left = (xa >> 16) & ~1;
+ npixels = ((((xb + 0xffff) >> 16) + 1) & ~1) - left;
+
+ switch(id) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ top &= ~1;
+ dst_start += (left << 1) + (top * dstPitch);
+ tmp = ((top >> 1) * srcPitch2) + (left >> 1);
+ s2offset += tmp;
+ s3offset += tmp;
+ if(id == FOURCC_I420) {
+ tmp = s2offset;
+ s2offset = s3offset;
+ s3offset = tmp;
+ }
+ nlines = ((((yb + 0xffff) >> 16) + 1) & ~1) - top;
+ NVCopyData420(buf + (top * srcPitch) + left, buf + s2offset,
+ buf + s3offset, dst_start, srcPitch, srcPitch2,
+ dstPitch, nlines, npixels);
+ break;
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ default:
+ left <<= 1;
+ buf += (top * srcPitch) + left;
+ nlines = ((yb + 0xffff) >> 16) - top;
+ dst_start += left + (top * dstPitch);
+ NVCopyData422(buf, dst_start, srcPitch, dstPitch, nlines, npixels);
+ break;
+ }
+
+ if(!skip) {
+ NVPutOverlayImage(pScrnInfo, offset, id, dstPitch, &dstBox,
+ xa, ya, xb, yb,
+ width, height, src_w, src_h, drw_w, drw_h, clipBoxes);
+ pPriv->currentBuffer ^= 1;
+ }
+
+ return Success;
+}
+/*
+ * QueryImageAttributes
+ */
+static int NVQueryImageAttributes
+(
+ ScrnInfoPtr pScrnInfo,
+ int id,
+ unsigned short *w,
+ unsigned short *h,
+ int *pitches,
+ int *offsets
+)
+{
+ int size, tmp;
+
+ if(*w > 2046)
+ *w = 2046;
+ if(*h > 2046)
+ *h = 2046;
+
+ *w = (*w + 1) & ~1;
+ if (offsets)
+ offsets[0] = 0;
+
+ switch (id)
+ {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ *h = (*h + 1) & ~1;
+ size = (*w + 3) & ~3;
+ if (pitches)
+ pitches[0] = size;
+ size *= *h;
+ if (offsets)
+ offsets[1] = size;
+ tmp = ((*w >> 1) + 3) & ~3;
+ if (pitches)
+ pitches[1] = pitches[2] = tmp;
+ tmp *= (*h >> 1);
+ size += tmp;
+ if (offsets)
+ offsets[2] = size;
+ size += tmp;
+ break;
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ default:
+ size = *w << 1;
+ if (pitches)
+ pitches[0] = size;
+ size *= *h;
+ break;
+ }
+ return size;
+}
+
+static void NVVideoTimerCallback
+(
+ ScrnInfoPtr pScrnInfo,
+ Time currentTime
+)
+{
+ NVPtr pNv = NVPTR(pScrnInfo);
+ NVPortPrivPtr pOverPriv = NULL;
+
+ pNv->VideoTimerCallback = NULL;
+
+ if(!pScrnInfo->vtSema) return;
+
+ if(pNv->overlayAdaptor) {
+ pOverPriv = GET_OVERLAY_PRIVATE(pNv);
+ if(!pOverPriv->videoStatus)
+ pOverPriv = NULL;
+ }
+
+ if(pOverPriv) {
+ if(pOverPriv->videoTime < currentTime) {
+ if(pOverPriv->videoStatus & OFF_TIMER) {
+ NVStopOverlay(pScrnInfo);
+ pOverPriv->videoStatus = FREE_TIMER;
+ pOverPriv->videoTime = currentTime + FREE_DELAY;
+ pNv->VideoTimerCallback = NVVideoTimerCallback;
+ } else
+ if(pOverPriv->videoStatus & FREE_TIMER) {
+ NVFreeOverlayMemory(pScrnInfo);
+ pOverPriv->videoStatus = 0;
+ }
+ } else
+ pNv->VideoTimerCallback = NVVideoTimerCallback;
+ }
+}
+
+
+/***** Exported offscreen surface stuff ****/
+
+
+static int
+NVAllocSurface (
+ ScrnInfoPtr pScrnInfo,
+ int id,
+ unsigned short w,
+ unsigned short h,
+ XF86SurfacePtr surface
+)
+{
+ NVPtr pNv = NVPTR(pScrnInfo);
+ NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv);
+ CARD8 *address;
+ int size, bpp;
+
+ bpp = pScrnInfo->bitsPerPixel >> 3;
+
+ if(pPriv->grabbedByV4L) return BadAlloc;
+
+ if((w > 2046) || (h > 2046)) return BadValue;
+
+ w = (w + 1) & ~1;
+ pPriv->pitch = ((w << 1) + 63) & ~63;
+ size = h * pPriv->pitch / bpp;
+
+ pPriv->linear = NVAllocateOverlayMemory(pScrnInfo, pPriv->linear,
+ size);
+
+ if(!pPriv->linear) return BadAlloc;
+
+ pPriv->offset = pPriv->linear->offset * bpp;
+ address = pPriv->offset + pNv->FbStart;
+
+ surface->width = w;
+ surface->height = h;
+ surface->pScrn = pScrnInfo;
+ surface->pitches = &pPriv->pitch;
+ surface->offsets = &pPriv->offset;
+ surface->devPrivate.ptr = (pointer)pPriv;
+ surface->id = id;
+
+ /* grab the video */
+ NVStopOverlay(pScrnInfo);
+ pPriv->videoStatus = 0;
+ REGION_EMPTY(pScrnInfo->pScreen, &pPriv->clip);
+ pNv->VideoTimerCallback = NULL;
+ pPriv->grabbedByV4L = TRUE;
+
+ return Success;
+}
+
+static int
+NVStopSurface (XF86SurfacePtr surface)
+{
+ NVPortPrivPtr pPriv = (NVPortPrivPtr)(surface->devPrivate.ptr);
+
+ if(pPriv->grabbedByV4L && pPriv->videoStatus) {
+ NVStopOverlay(surface->pScrn);
+ pPriv->videoStatus = 0;
+ }
+
+ return Success;
+}
+
+static int
+NVFreeSurface (XF86SurfacePtr surface)
+{
+ NVPortPrivPtr pPriv = (NVPortPrivPtr)(surface->devPrivate.ptr);
+
+ if(pPriv->grabbedByV4L) {
+ NVStopSurface(surface);
+ NVFreeOverlayMemory(surface->pScrn);
+ pPriv->grabbedByV4L = FALSE;
+ }
+
+ return Success;
+}
+
+static int
+NVGetSurfaceAttribute (
+ ScrnInfoPtr pScrnInfo,
+ Atom attribute,
+ INT32 *value
+)
+{
+ NVPtr pNv = NVPTR(pScrnInfo);
+ NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv);
+
+ return NVGetPortAttribute(pScrnInfo, attribute, value, (pointer)pPriv);
+}
+
+static int
+NVSetSurfaceAttribute(
+ ScrnInfoPtr pScrnInfo,
+ Atom attribute,
+ INT32 value
+)
+{
+ NVPtr pNv = NVPTR(pScrnInfo);
+ NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv);
+
+ return NVSetPortAttribute(pScrnInfo, attribute, value, (pointer)pPriv);
+}
+
+static int
+NVDisplaySurface (
+ XF86SurfacePtr surface,
+ short src_x, short src_y,
+ short drw_x, short drw_y,
+ short src_w, short src_h,
+ short drw_w, short drw_h,
+ RegionPtr clipBoxes
+)
+{
+ ScrnInfoPtr pScrnInfo = surface->pScrn;
+ NVPortPrivPtr pPriv = (NVPortPrivPtr)(surface->devPrivate.ptr);
+ INT32 xa, xb, ya, yb;
+ BoxRec dstBox;
+
+ if(!pPriv->grabbedByV4L) return Success;
+
+ if(src_w > (drw_w << 3))
+ drw_w = src_w >> 3;
+ if(src_h > (drw_h << 3))
+ drw_h = src_h >> 3;
+
+ /* Clip */
+ xa = src_x;
+ xb = src_x + src_w;
+ ya = src_y;
+ yb = src_y + src_h;
+
+ dstBox.x1 = drw_x;
+ dstBox.x2 = drw_x + drw_w;
+ dstBox.y1 = drw_y;
+ dstBox.y2 = drw_y + drw_h;
+
+ if(!xf86XVClipVideoHelper(&dstBox, &xa, &xb, &ya, &yb, clipBoxes,
+ surface->width, surface->height))
+ {
+ return Success;
+ }
+
+ dstBox.x1 -= pScrnInfo->frameX0;
+ dstBox.x2 -= pScrnInfo->frameX0;
+ dstBox.y1 -= pScrnInfo->frameY0;
+ dstBox.y2 -= pScrnInfo->frameY0;
+
+ pPriv->currentBuffer = 0;
+
+ NVPutOverlayImage (pScrnInfo, surface->offsets[0], surface->id,
+ surface->pitches[0], &dstBox, xa, ya, xb, yb,
+ surface->width, surface->height, src_w, src_h,
+ drw_w, drw_h, clipBoxes);
+
+ return Success;
+}
+
+XF86OffscreenImageRec NVOffscreenImages[2] =
+{
+ {
+ &NVImages[0],
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT,
+ NVAllocSurface,
+ NVFreeSurface,
+ NVDisplaySurface,
+ NVStopSurface,
+ NVGetSurfaceAttribute,
+ NVSetSurfaceAttribute,
+ 2046, 2046,
+ NUM_ATTRIBUTES - 1,
+ &NVAttributes[1]
+ },
+ {
+ &NVImages[2],
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT,
+ NVAllocSurface,
+ NVFreeSurface,
+ NVDisplaySurface,
+ NVStopSurface,
+ NVGetSurfaceAttribute,
+ NVSetSurfaceAttribute,
+ 2046, 2046,
+ NUM_ATTRIBUTES - 1,
+ &NVAttributes[1]
+ },
+};
+
+static void
+NVInitOffscreenImages (ScreenPtr pScreen)
+{
+ xf86XVRegisterOffscreenImages(pScreen, NVOffscreenImages, 2);
+}
+
+#endif
+
+
diff --git a/src/nv_xaa.c b/src/nv_xaa.c
new file mode 100644
index 0000000..e4400b6
--- /dev/null
+++ b/src/nv_xaa.c
@@ -0,0 +1,573 @@
+/* $XConsortium: nv_driver.c /main/3 1996/10/28 05:13:37 kaleb $ */
+ /***************************************************************************\
+|* *|
+|* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
+|* *|
+|* 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. *|
+|* *|
+|* Any use of this source code must include, in the user documenta- *|
+|* tion and internal comments to the code, notices to the end user *|
+|* as follows: *|
+|* *|
+|* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
+|* *|
+|* 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, CORPOR- *|
+|* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
+|* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
+|* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
+|* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
+|* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
+|* SULTING 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. *|
+|* *|
+|* 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. Govern- *|
+|* ment 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. *|
+|* *|
+ \***************************************************************************/
+
+/* 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_xaa.c,v 1.29 2003/02/12 21:26:27 mvojkovi Exp $ */
+
+#include "nv_include.h"
+#include "xaalocal.h"
+#include "xaarop.h"
+
+#include "miline.h"
+
+static void
+NVSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2)
+{
+ int height = y2-y1 + 1;
+ int width = x2-x1 + 1;
+ NVPtr pNv = NVPTR(pScrn);
+
+ RIVA_FIFO_FREE(pNv->riva, Clip, 2);
+ pNv->riva.Clip->TopLeft = (y1 << 16) | (x1 & 0xffff);
+ pNv->riva.Clip->WidthHeight = (height << 16) | width;
+}
+
+
+static void
+NVDisableClipping(ScrnInfoPtr pScrn)
+{
+ NVSetClippingRectangle(pScrn, 0, 0, 0x7fff, 0x7fff);
+}
+
+/*
+ * Set pattern. Internal routine. The upper bits of the colors
+ * are the ALPHA bits. 0 == transparency.
+ */
+static void
+NVSetPattern(NVPtr pNv, int clr0, int clr1, int pat0, int pat1)
+{
+ RIVA_FIFO_FREE(pNv->riva, Patt, 5);
+ pNv->riva.Patt->Shape = 0; /* 0 = 8X8, 1 = 64X1, 2 = 1X64 */
+ pNv->riva.Patt->Color0 = clr0;
+ pNv->riva.Patt->Color1 = clr1;
+ pNv->riva.Patt->Monochrome[0] = pat0;
+ pNv->riva.Patt->Monochrome[1] = pat1;
+}
+
+/*
+ * Set ROP. Translate X rop into ROP3. Internal routine.
+ */
+static void
+NVSetRopSolid(NVPtr pNv, int rop)
+{
+ if (pNv->currentRop != rop)
+ {
+ if (pNv->currentRop > 16)
+ NVSetPattern(pNv, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
+ pNv->currentRop = rop;
+ RIVA_FIFO_FREE(pNv->riva, Rop, 1);
+ pNv->riva.Rop->Rop3 = XAACopyROP[rop];
+ }
+}
+
+static void
+NVSetRopPattern(NVPtr pNv, int rop)
+{
+ if (pNv->currentRop != rop + 16)
+ {
+ pNv->currentRop = rop + 16; /* +16 is important */
+ RIVA_FIFO_FREE(pNv->riva, Rop, 1);
+ pNv->riva.Rop->Rop3 = XAAPatternROP[rop];
+ }
+}
+
+/*
+ * Fill solid rectangles.
+ */
+static
+void NVSetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned planemask)
+{
+ NVPtr pNv = NVPTR(pScrn);
+
+ NVSetRopSolid(pNv, rop);
+ RIVA_FIFO_FREE(pNv->riva, Bitmap, 1);
+ pNv->riva.Bitmap->Color1A = color;
+}
+
+static void
+NVSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
+{
+ NVPtr pNv = NVPTR(pScrn);
+
+ RIVA_FIFO_FREE(pNv->riva, Bitmap, 2);
+ pNv->riva.Bitmap->UnclippedRectangle[0].TopLeft = (x << 16) | y;
+ write_mem_barrier();
+ pNv->riva.Bitmap->UnclippedRectangle[0].WidthHeight = (w << 16) | h;
+ write_mem_barrier();
+}
+
+/*
+ * Screen to screen BLTs.
+ */
+static void
+NVSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop,
+ unsigned planemask, int transparency_color)
+{
+ NVSetRopSolid(NVPTR(pScrn), rop);
+}
+
+static void
+NVSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2, int w, int h)
+{
+ NVPtr pNv = NVPTR(pScrn);
+
+ RIVA_FIFO_FREE(pNv->riva, Blt, 3);
+ pNv->riva.Blt->TopLeftSrc = (y1 << 16) | x1;
+ pNv->riva.Blt->TopLeftDst = (y2 << 16) | x2;
+ write_mem_barrier();
+ pNv->riva.Blt->WidthHeight = (h << 16) | w;
+ write_mem_barrier();
+}
+
+
+/*
+ * Fill 8x8 monochrome pattern rectangles. patternx and patterny are
+ * the overloaded pattern bits themselves. The pattern colors don't
+ * support 565, only 555. Hack around it.
+ */
+static void
+NVSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny,
+ int fg, int bg, int rop, unsigned planemask)
+{
+ NVPtr pNv = NVPTR(pScrn);
+
+ NVSetRopPattern(pNv, rop);
+ if (pScrn->depth == 16)
+ {
+ fg = ((fg & 0x0000F800) << 8)
+ | ((fg & 0x000007E0) << 5)
+ | ((fg & 0x0000001F) << 3)
+ | 0xFF000000;
+ if (bg != -1)
+ bg = ((bg & 0x0000F800) << 8)
+ | ((bg & 0x000007E0) << 5)
+ | ((bg & 0x0000001F) << 3)
+ | 0xFF000000;
+ else
+ bg = 0;
+ }
+ else
+ {
+ fg |= pNv->opaqueMonochrome;
+ bg = (bg == -1) ? 0 : bg | pNv->opaqueMonochrome;
+ };
+ NVSetPattern(pNv, bg, fg, patternx, patterny);
+ RIVA_FIFO_FREE(pNv->riva, Bitmap, 1);
+ pNv->riva.Bitmap->Color1A = fg;
+}
+
+static void
+NVSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int x, int y, int w, int h)
+{
+ NVPtr pNv = NVPTR(pScrn);
+
+ RIVA_FIFO_FREE(pNv->riva, Bitmap, 2);
+ pNv->riva.Bitmap->UnclippedRectangle[0].TopLeft = (x << 16) | y;
+ write_mem_barrier();
+ pNv->riva.Bitmap->UnclippedRectangle[0].WidthHeight = (w << 16) | h;
+ write_mem_barrier();
+}
+
+
+void
+NVResetGraphics(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv = NVPTR(pScrn);
+
+ if(pNv->NoAccel) return;
+
+ pNv->currentRop = -1;
+ NVSetRopPattern(pNv, GXcopy);
+}
+
+
+
+/*
+ * Synchronise with graphics engine. Make sure it is idle before returning.
+ * Should attempt to yield CPU if busy for awhile.
+ */
+void NVSync(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ RIVA_BUSY(pNv->riva);
+}
+
+/* Color expansion */
+static void
+NVSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+ NVPtr pNv = NVPTR(pScrn);
+
+ NVSetRopSolid(pNv, rop);
+
+ if ( bg == -1 )
+ {
+ /* Transparent case */
+ bg = 0x80000000;
+ pNv->expandFifo = (unsigned char*)&pNv->riva.Bitmap->MonochromeData1C;
+ }
+ else
+ {
+ pNv->expandFifo = (unsigned char*)&pNv->riva.Bitmap->MonochromeData01E;
+ if (pScrn->depth == 16)
+ {
+ bg = ((bg & 0x0000F800) << 8)
+ | ((bg & 0x000007E0) << 5)
+ | ((bg & 0x0000001F) << 3)
+ | 0xFF000000;
+ }
+ else
+ {
+ bg |= pNv->opaqueMonochrome;
+ };
+ }
+ pNv->FgColor = fg;
+ pNv->BgColor = bg;
+}
+
+static void
+NVSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
+{
+ NVPtr pNv = NVPTR(pScrn);
+
+ int t = pNv->expandWidth;
+ CARD32 *pbits = (CARD32*)pNv->expandBuffer;
+ CARD32 *d = (CARD32*)pNv->expandFifo;
+
+ while(t >= 16)
+ {
+ RIVA_FIFO_FREE(pNv->riva, Bitmap, 16);
+ d[0] = pbits[0];
+ d[1] = pbits[1];
+ d[2] = pbits[2];
+ d[3] = pbits[3];
+ d[4] = pbits[4];
+ d[5] = pbits[5];
+ d[6] = pbits[6];
+ d[7] = pbits[7];
+ d[8] = pbits[8];
+ d[9] = pbits[9];
+ d[10] = pbits[10];
+ d[11] = pbits[11];
+ d[12] = pbits[12];
+ d[13] = pbits[13];
+ d[14] = pbits[14];
+ d[15] = pbits[15];
+ t -= 16; pbits += 16;
+ }
+ if(t) {
+ RIVA_FIFO_FREE(pNv->riva, Bitmap, t);
+ while(t >= 4)
+ {
+ d[0] = pbits[0];
+ d[1] = pbits[1];
+ d[2] = pbits[2];
+ d[3] = pbits[3];
+ t -= 4; pbits += 4;
+ }
+ while(t--)
+ *(d++) = *(pbits++);
+ }
+
+ if (!(--pNv->expandRows)) { /* hardware bug workaround */
+ RIVA_FIFO_FREE(pNv->riva, Blt, 1);
+ write_mem_barrier();
+ pNv->riva.Blt->TopLeftSrc = 0;
+ }
+ write_mem_barrier();
+}
+
+static void
+NVSubsequentColorExpandScanlineFifo(ScrnInfoPtr pScrn, int bufno)
+{
+ NVPtr pNv = NVPTR(pScrn);
+
+ if ( --pNv->expandRows ) {
+ RIVA_FIFO_FREE(pNv->riva, Bitmap, pNv->expandWidth);
+ } else { /* hardware bug workaround */
+ RIVA_FIFO_FREE(pNv->riva, Blt, 1);
+ write_mem_barrier();
+ pNv->riva.Blt->TopLeftSrc = 0;
+ }
+ write_mem_barrier();
+}
+
+static void
+NVSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x,
+ int y, int w, int h,
+ int skipleft)
+{
+ int bw;
+ NVPtr pNv = NVPTR(pScrn);
+
+ bw = (w + 31) & ~31;
+ pNv->expandWidth = bw >> 5;
+
+ if ( pNv->BgColor == 0x80000000 )
+ {
+ /* Use faster transparent method */
+ RIVA_FIFO_FREE(pNv->riva, Bitmap, 5);
+ pNv->riva.Bitmap->ClipC.TopLeft = (y << 16) | ((x+skipleft)
+ & 0xFFFF);
+ pNv->riva.Bitmap->ClipC.BottomRight = ((y+h) << 16) | ((x+w)&0xffff);
+ pNv->riva.Bitmap->Color1C = pNv->FgColor;
+ pNv->riva.Bitmap->WidthHeightC = (h << 16) | bw;
+ write_mem_barrier();
+ pNv->riva.Bitmap->PointC = (y << 16) | (x & 0xFFFF);
+ write_mem_barrier();
+ }
+ else
+ {
+ /* Opaque */
+ RIVA_FIFO_FREE(pNv->riva, Bitmap, 7);
+ pNv->riva.Bitmap->ClipE.TopLeft = (y << 16) | ((x+skipleft)
+ & 0xFFFF);
+ pNv->riva.Bitmap->ClipE.BottomRight = ((y+h) << 16) | ((x+w)&0xffff);
+ pNv->riva.Bitmap->Color0E = pNv->BgColor;
+ pNv->riva.Bitmap->Color1E = pNv->FgColor;
+ pNv->riva.Bitmap->WidthHeightInE = (h << 16) | bw;
+ pNv->riva.Bitmap->WidthHeightOutE = (h << 16) | bw;
+ write_mem_barrier();
+ pNv->riva.Bitmap->PointE = (y << 16) | (x & 0xFFFF);
+ write_mem_barrier();
+ }
+
+ pNv->expandRows = h;
+
+ if(pNv->expandWidth > (pNv->riva.FifoEmptyCount >> 2)) {
+ pNv->AccelInfoRec->ScanlineColorExpandBuffers = &pNv->expandBuffer;
+ pNv->AccelInfoRec->SubsequentColorExpandScanline =
+ NVSubsequentColorExpandScanline;
+ } else {
+ pNv->AccelInfoRec->ScanlineColorExpandBuffers = &pNv->expandFifo;
+ pNv->AccelInfoRec->SubsequentColorExpandScanline =
+ NVSubsequentColorExpandScanlineFifo;
+ RIVA_FIFO_FREE(pNv->riva, Bitmap, pNv->expandWidth);
+ }
+}
+
+static void
+NVSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, unsigned planemask)
+{
+ NVPtr pNv = NVPTR(pScrn);
+
+ NVSetRopSolid(pNv, rop);
+ pNv->FgColor = color;
+}
+
+static void
+NVSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len, int dir)
+{
+ NVPtr pNv = NVPTR(pScrn);
+
+ RIVA_FIFO_FREE(pNv->riva, Line, 3);
+ pNv->riva.Line->Color = pNv->FgColor;
+ pNv->riva.Line->Lin[0].point0 = ((y << 16) | ( x & 0xffff));
+ write_mem_barrier();
+ if ( dir ==DEGREES_0 )
+ pNv->riva.Line->Lin[0].point1 = ((y << 16) | (( x + len ) & 0xffff));
+ else
+ pNv->riva.Line->Lin[0].point1 = (((y + len) << 16) | ( x & 0xffff));
+ write_mem_barrier();
+}
+
+static void
+NVSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2, int flags)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ Bool lastPoint = !(flags & OMIT_LAST);
+
+ RIVA_FIFO_FREE(pNv->riva, Line, lastPoint ? 5 : 3);
+ pNv->riva.Line->Color = pNv->FgColor;
+ pNv->riva.Line->Lin[0].point0 = ((y1 << 16) | (x1 & 0xffff));
+ write_mem_barrier();
+ pNv->riva.Line->Lin[0].point1 = ((y2 << 16) | (x2 & 0xffff));
+ write_mem_barrier();
+ if (lastPoint)
+ {
+ pNv->riva.Line->Lin[1].point0 = ((y2 << 16) | (x2 & 0xffff));
+ write_mem_barrier();
+ pNv->riva.Line->Lin[1].point1 = (((y2 + 1) << 16) | (x2 & 0xffff));
+ write_mem_barrier();
+ }
+}
+
+static void
+NVValidatePolyArc(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+){
+ if(pGC->planemask != ~0) return;
+
+ if(!pGC->lineWidth &&
+ ((pGC->alu != GXcopy) || (pGC->lineStyle != LineSolid)))
+ {
+ pGC->ops->PolyArc = miZeroPolyArc;
+ }
+}
+
+static void
+NVValidatePolyPoint(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+){
+ pGC->ops->PolyPoint = XAAFallbackOps.PolyPoint;
+
+ if(pGC->planemask != ~0) return;
+
+ if(pGC->alu != GXcopy)
+ pGC->ops->PolyPoint = miPolyPoint;
+}
+
+/* Initialize XAA acceleration info */
+Bool
+NVAccelInit(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoPtr;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ NVPtr pNv = NVPTR(pScrn);
+ Bool lowClocks;
+
+ /* The hardware POSTs with clocks too low to support some acceleration
+ on NV20 and higher and we don't know enough about timing particulars
+ to raise them */
+
+ lowClocks = ((pNv->Chipset & 0x0ff0) >= 0x0200);
+
+ pNv->AccelInfoRec = infoPtr = XAACreateInfoRec();
+ if(!infoPtr) return FALSE;
+
+ /* fill out infoPtr here */
+ infoPtr->Flags = LINEAR_FRAMEBUFFER | PIXMAP_CACHE | OFFSCREEN_PIXMAPS;
+
+ /* sync */
+ infoPtr->Sync = NVSync;
+
+ /* solid fills */
+ infoPtr->SolidFillFlags = NO_PLANEMASK;
+ infoPtr->SetupForSolidFill = NVSetupForSolidFill;
+ infoPtr->SubsequentSolidFillRect = NVSubsequentSolidFillRect;
+
+ if(lowClocks)
+ infoPtr->SolidFillFlags |= GXCOPY_ONLY;
+
+ /* screen to screen copy */
+ infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY | NO_PLANEMASK;
+ infoPtr->SetupForScreenToScreenCopy = NVSetupForScreenToScreenCopy;
+ infoPtr->SubsequentScreenToScreenCopy = NVSubsequentScreenToScreenCopy;
+
+ /* 8x8 mono patterns */
+ /*
+ * Set pattern opaque bits based on pixel format.
+ */
+ pNv->opaqueMonochrome = ~((1 << pScrn->depth) - 1);
+
+ pNv->currentRop = -1;
+
+ infoPtr->Mono8x8PatternFillFlags = HARDWARE_PATTERN_SCREEN_ORIGIN |
+ HARDWARE_PATTERN_PROGRAMMED_BITS |
+ NO_PLANEMASK;
+ infoPtr->SetupForMono8x8PatternFill = NVSetupForMono8x8PatternFill;
+ infoPtr->SubsequentMono8x8PatternFillRect =
+ NVSubsequentMono8x8PatternFillRect;
+
+ /* Color expansion */
+ infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ BIT_ORDER_IN_BYTE_MSBFIRST |
+#else
+ BIT_ORDER_IN_BYTE_LSBFIRST |
+#endif
+ NO_PLANEMASK |
+ CPU_TRANSFER_PAD_DWORD |
+ LEFT_EDGE_CLIPPING |
+ LEFT_EDGE_CLIPPING_NEGATIVE_X;
+
+ infoPtr->NumScanlineColorExpandBuffers = 1;
+
+ if(!lowClocks) {
+ infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
+ NVSetupForScanlineCPUToScreenColorExpandFill;
+ infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
+ NVSubsequentScanlineCPUToScreenColorExpandFill;
+ }
+
+ pNv->expandFifo = (unsigned char*)&pNv->riva.Bitmap->MonochromeData01E;
+
+ /* Allocate buffer for color expansion and also image writes in the
+ future */
+ pNv->expandBuffer = xnfalloc(((pScrn->virtualX*pScrn->bitsPerPixel)/8) + 8);
+
+
+ infoPtr->ScanlineColorExpandBuffers = &pNv->expandBuffer;
+ infoPtr->SubsequentColorExpandScanline = NVSubsequentColorExpandScanline;
+
+ infoPtr->SolidLineFlags = infoPtr->SolidFillFlags;
+ infoPtr->SetupForSolidLine = NVSetupForSolidLine;
+ infoPtr->SubsequentSolidHorVertLine =
+ NVSubsequentSolidHorVertLine;
+ infoPtr->SubsequentSolidTwoPointLine =
+ NVSubsequentSolidTwoPointLine;
+ infoPtr->SetClippingRectangle = NVSetClippingRectangle;
+ infoPtr->DisableClipping = NVDisableClipping;
+ infoPtr->ClippingFlags = HARDWARE_CLIP_SOLID_LINE;
+ miSetZeroLineBias(pScreen, OCTANT1 | OCTANT3 | OCTANT4 | OCTANT6);
+
+ infoPtr->ValidatePolyArc = NVValidatePolyArc;
+ infoPtr->PolyArcMask = GCFunction | GCLineWidth | GCPlaneMask;
+ infoPtr->ValidatePolyPoint = NVValidatePolyPoint;
+ infoPtr->PolyPointMask = GCFunction | GCPlaneMask;
+
+ NVDisableClipping(pScrn);
+
+ return(XAAInit(pScreen, infoPtr));
+}
+
diff --git a/src/riva_hw.c b/src/riva_hw.c
new file mode 100644
index 0000000..bbb515f
--- /dev/null
+++ b/src/riva_hw.c
@@ -0,0 +1,2100 @@
+ /***************************************************************************\
+|* *|
+|* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
+|* *|
+|* 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. *|
+|* *|
+|* Any use of this source code must include, in the user documenta- *|
+|* tion and internal comments to the code, notices to the end user *|
+|* as follows: *|
+|* *|
+|* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
+|* *|
+|* 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, CORPOR- *|
+|* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
+|* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
+|* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
+|* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
+|* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
+|* SULTING 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. *|
+|* *|
+|* 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. Govern- *|
+|* ment 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. *|
+|* *|
+ \***************************************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_hw.c,v 1.47 2003/02/10 23:42:51 mvojkovi Exp $ */
+
+#include "nv_local.h"
+#include "compiler.h"
+#include "nv_include.h"
+#include "riva_hw.h"
+#include "riva_tbl.h"
+
+/*
+ * This file is an OS-agnostic file used to make RIVA 128 and RIVA TNT
+ * operate identically (except TNT has more memory and better 3D quality.
+ */
+static int nv3Busy
+(
+ RIVA_HW_INST *chip
+)
+{
+ return ((chip->Rop->FifoFree < chip->FifoEmptyCount) || (chip->PGRAPH[0x000006B0/4] & 0x01));
+}
+static int nv4Busy
+(
+ RIVA_HW_INST *chip
+)
+{
+ return ((chip->Rop->FifoFree < chip->FifoEmptyCount) || (chip->PGRAPH[0x00000700/4] & 0x01));
+}
+static int nv10Busy
+(
+ RIVA_HW_INST *chip
+)
+{
+ return ((chip->Rop->FifoFree < chip->FifoEmptyCount) || (chip->PGRAPH[0x00000700/4] & 0x01));
+}
+static void vgaLockUnlock
+(
+ RIVA_HW_INST *chip,
+ Bool Lock
+)
+{
+ CARD8 cr11;
+ VGA_WR08(chip->PCIO, 0x3D4, 0x11);
+ cr11 = VGA_RD08(chip->PCIO, 0x3D5);
+ if(Lock) cr11 |= 0x80;
+ else cr11 &= ~0x80;
+ VGA_WR08(chip->PCIO, 0x3D5, cr11);
+}
+
+static void nv3LockUnlock
+(
+ RIVA_HW_INST *chip,
+ Bool Lock
+)
+{
+ VGA_WR08(chip->PVIO, 0x3C4, 0x06);
+ VGA_WR08(chip->PVIO, 0x3C5, Lock ? 0x99 : 0x57);
+ vgaLockUnlock(chip, Lock);
+}
+static void nv4LockUnlock
+(
+ RIVA_HW_INST *chip,
+ Bool Lock
+)
+{
+ VGA_WR08(chip->PCIO, 0x3D4, 0x1F);
+ VGA_WR08(chip->PCIO, 0x3D5, Lock ? 0x99 : 0x57);
+ vgaLockUnlock(chip, Lock);
+}
+static int ShowHideCursor
+(
+ RIVA_HW_INST *chip,
+ int ShowHide
+)
+{
+ int current;
+ current = chip->CurrentState->cursor1;
+ chip->CurrentState->cursor1 = (chip->CurrentState->cursor1 & 0xFE) |
+ (ShowHide & 0x01);
+ VGA_WR08(chip->PCIO, 0x3D4, 0x31);
+ VGA_WR08(chip->PCIO, 0x3D5, chip->CurrentState->cursor1);
+ return (current & 0x01);
+}
+
+/****************************************************************************\
+* *
+* The video arbitration routines calculate some "magic" numbers. Fixes *
+* the snow seen when accessing the framebuffer without it. *
+* It just works (I hope). *
+* *
+\****************************************************************************/
+
+#define DEFAULT_GR_LWM 100
+#define DEFAULT_VID_LWM 100
+#define DEFAULT_GR_BURST_SIZE 256
+#define DEFAULT_VID_BURST_SIZE 128
+#define VIDEO 0
+#define GRAPHICS 1
+#define MPORT 2
+#define ENGINE 3
+#define GFIFO_SIZE 320
+#define GFIFO_SIZE_128 256
+#define MFIFO_SIZE 120
+#define VFIFO_SIZE 256
+#define ABS(a) (a>0?a:-a)
+typedef struct {
+ int gdrain_rate;
+ int vdrain_rate;
+ int mdrain_rate;
+ int gburst_size;
+ int vburst_size;
+ char vid_en;
+ char gr_en;
+ int wcmocc, wcgocc, wcvocc, wcvlwm, wcglwm;
+ int by_gfacc;
+ char vid_only_once;
+ char gr_only_once;
+ char first_vacc;
+ char first_gacc;
+ char first_macc;
+ int vocc;
+ int gocc;
+ int mocc;
+ char cur;
+ char engine_en;
+ char converged;
+ int priority;
+} nv3_arb_info;
+typedef struct {
+ int graphics_lwm;
+ int video_lwm;
+ int graphics_burst_size;
+ int video_burst_size;
+ int graphics_hi_priority;
+ int media_hi_priority;
+ int rtl_values;
+ int valid;
+} nv3_fifo_info;
+typedef struct {
+ char pix_bpp;
+ char enable_video;
+ char gr_during_vid;
+ char enable_mp;
+ int memory_width;
+ int video_scale;
+ int pclk_khz;
+ int mclk_khz;
+ int mem_page_miss;
+ int mem_latency;
+ char mem_aligned;
+} nv3_sim_state;
+typedef struct {
+ int graphics_lwm;
+ int video_lwm;
+ int graphics_burst_size;
+ int video_burst_size;
+ int valid;
+} nv4_fifo_info;
+typedef struct {
+ int pclk_khz;
+ int mclk_khz;
+ int nvclk_khz;
+ char mem_page_miss;
+ char mem_latency;
+ int memory_width;
+ char enable_video;
+ char gr_during_vid;
+ char pix_bpp;
+ char mem_aligned;
+ char enable_mp;
+} nv4_sim_state;
+typedef struct {
+ int graphics_lwm;
+ int video_lwm;
+ int graphics_burst_size;
+ int video_burst_size;
+ int valid;
+} nv10_fifo_info;
+typedef struct {
+ int pclk_khz;
+ int mclk_khz;
+ int nvclk_khz;
+ char mem_page_miss;
+ char mem_latency;
+ int memory_type;
+ int memory_width;
+ char enable_video;
+ char gr_during_vid;
+ char pix_bpp;
+ char mem_aligned;
+ char enable_mp;
+} nv10_sim_state;
+static int nv3_iterate(nv3_fifo_info *res_info, nv3_sim_state * state, nv3_arb_info *ainfo)
+{
+ int iter = 0;
+ int tmp;
+ int vfsize, mfsize, gfsize;
+ int mburst_size = 32;
+ int mmisses, gmisses, vmisses;
+ int misses;
+ int vlwm, glwm, mlwm;
+ int last, next, cur;
+ int max_gfsize ;
+ long ns;
+
+ vlwm = 0;
+ glwm = 0;
+ mlwm = 0;
+ vfsize = 0;
+ gfsize = 0;
+ cur = ainfo->cur;
+ mmisses = 2;
+ gmisses = 2;
+ vmisses = 2;
+ if (ainfo->gburst_size == 128) max_gfsize = GFIFO_SIZE_128;
+ else max_gfsize = GFIFO_SIZE;
+ max_gfsize = GFIFO_SIZE;
+ while (1)
+ {
+ if (ainfo->vid_en)
+ {
+ if (ainfo->wcvocc > ainfo->vocc) ainfo->wcvocc = ainfo->vocc;
+ if (ainfo->wcvlwm > vlwm) ainfo->wcvlwm = vlwm ;
+ ns = 1000000 * ainfo->vburst_size/(state->memory_width/8)/state->mclk_khz;
+ vfsize = ns * ainfo->vdrain_rate / 1000000;
+ vfsize = ainfo->wcvlwm - ainfo->vburst_size + vfsize;
+ }
+ if (state->enable_mp)
+ {
+ if (ainfo->wcmocc > ainfo->mocc) ainfo->wcmocc = ainfo->mocc;
+ }
+ if (ainfo->gr_en)
+ {
+ if (ainfo->wcglwm > glwm) ainfo->wcglwm = glwm ;
+ if (ainfo->wcgocc > ainfo->gocc) ainfo->wcgocc = ainfo->gocc;
+ ns = 1000000 * (ainfo->gburst_size/(state->memory_width/8))/state->mclk_khz;
+ gfsize = (ns * (long) ainfo->gdrain_rate)/1000000;
+ gfsize = ainfo->wcglwm - ainfo->gburst_size + gfsize;
+ }
+ mfsize = 0;
+ if (!state->gr_during_vid && ainfo->vid_en)
+ if (ainfo->vid_en && (ainfo->vocc < 0) && !ainfo->vid_only_once)
+ next = VIDEO;
+ else if (ainfo->mocc < 0)
+ next = MPORT;
+ else if (ainfo->gocc< ainfo->by_gfacc)
+ next = GRAPHICS;
+ else return (0);
+ else switch (ainfo->priority)
+ {
+ case VIDEO:
+ if (ainfo->vid_en && ainfo->vocc<0 && !ainfo->vid_only_once)
+ next = VIDEO;
+ else if (ainfo->gr_en && ainfo->gocc<0 && !ainfo->gr_only_once)
+ next = GRAPHICS;
+ else if (ainfo->mocc<0)
+ next = MPORT;
+ else return (0);
+ break;
+ case GRAPHICS:
+ if (ainfo->gr_en && ainfo->gocc<0 && !ainfo->gr_only_once)
+ next = GRAPHICS;
+ else if (ainfo->vid_en && ainfo->vocc<0 && !ainfo->vid_only_once)
+ next = VIDEO;
+ else if (ainfo->mocc<0)
+ next = MPORT;
+ else return (0);
+ break;
+ default:
+ if (ainfo->mocc<0)
+ next = MPORT;
+ else if (ainfo->gr_en && ainfo->gocc<0 && !ainfo->gr_only_once)
+ next = GRAPHICS;
+ else if (ainfo->vid_en && ainfo->vocc<0 && !ainfo->vid_only_once)
+ next = VIDEO;
+ else return (0);
+ break;
+ }
+ last = cur;
+ cur = next;
+ iter++;
+ switch (cur)
+ {
+ case VIDEO:
+ if (last==cur) misses = 0;
+ else if (ainfo->first_vacc) misses = vmisses;
+ else misses = 1;
+ ainfo->first_vacc = 0;
+ if (last!=cur)
+ {
+ ns = 1000000 * (vmisses*state->mem_page_miss + state->mem_latency)/state->mclk_khz;
+ vlwm = ns * ainfo->vdrain_rate/ 1000000;
+ vlwm = ainfo->vocc - vlwm;
+ }
+ ns = 1000000*(misses*state->mem_page_miss + ainfo->vburst_size)/(state->memory_width/8)/state->mclk_khz;
+ ainfo->vocc = ainfo->vocc + ainfo->vburst_size - ns*ainfo->vdrain_rate/1000000;
+ ainfo->gocc = ainfo->gocc - ns*ainfo->gdrain_rate/1000000;
+ ainfo->mocc = ainfo->mocc - ns*ainfo->mdrain_rate/1000000;
+ break;
+ case GRAPHICS:
+ if (last==cur) misses = 0;
+ else if (ainfo->first_gacc) misses = gmisses;
+ else misses = 1;
+ ainfo->first_gacc = 0;
+ if (last!=cur)
+ {
+ ns = 1000000*(gmisses*state->mem_page_miss + state->mem_latency)/state->mclk_khz ;
+ glwm = ns * ainfo->gdrain_rate/1000000;
+ glwm = ainfo->gocc - glwm;
+ }
+ ns = 1000000*(misses*state->mem_page_miss + ainfo->gburst_size/(state->memory_width/8))/state->mclk_khz;
+ ainfo->vocc = ainfo->vocc + 0 - ns*ainfo->vdrain_rate/1000000;
+ ainfo->gocc = ainfo->gocc + ainfo->gburst_size - ns*ainfo->gdrain_rate/1000000;
+ ainfo->mocc = ainfo->mocc + 0 - ns*ainfo->mdrain_rate/1000000;
+ break;
+ default:
+ if (last==cur) misses = 0;
+ else if (ainfo->first_macc) misses = mmisses;
+ else misses = 1;
+ ainfo->first_macc = 0;
+ ns = 1000000*(misses*state->mem_page_miss + mburst_size/(state->memory_width/8))/state->mclk_khz;
+ ainfo->vocc = ainfo->vocc + 0 - ns*ainfo->vdrain_rate/1000000;
+ ainfo->gocc = ainfo->gocc + 0 - ns*ainfo->gdrain_rate/1000000;
+ ainfo->mocc = ainfo->mocc + mburst_size - ns*ainfo->mdrain_rate/1000000;
+ break;
+ }
+ if (iter>100)
+ {
+ ainfo->converged = 0;
+ return (1);
+ }
+ ns = 1000000*ainfo->gburst_size/(state->memory_width/8)/state->mclk_khz;
+ tmp = ns * ainfo->gdrain_rate/1000000;
+ if (ABS(ainfo->gburst_size) + ((ABS(ainfo->wcglwm) + 16 ) & ~0x7) - tmp > max_gfsize)
+ {
+ ainfo->converged = 0;
+ return (1);
+ }
+ ns = 1000000*ainfo->vburst_size/(state->memory_width/8)/state->mclk_khz;
+ tmp = ns * ainfo->vdrain_rate/1000000;
+ if (ABS(ainfo->vburst_size) + (ABS(ainfo->wcvlwm + 32) & ~0xf) - tmp> VFIFO_SIZE)
+ {
+ ainfo->converged = 0;
+ return (1);
+ }
+ if (ABS(ainfo->gocc) > max_gfsize)
+ {
+ ainfo->converged = 0;
+ return (1);
+ }
+ if (ABS(ainfo->vocc) > VFIFO_SIZE)
+ {
+ ainfo->converged = 0;
+ return (1);
+ }
+ if (ABS(ainfo->mocc) > MFIFO_SIZE)
+ {
+ ainfo->converged = 0;
+ return (1);
+ }
+ if (ABS(vfsize) > VFIFO_SIZE)
+ {
+ ainfo->converged = 0;
+ return (1);
+ }
+ if (ABS(gfsize) > max_gfsize)
+ {
+ ainfo->converged = 0;
+ return (1);
+ }
+ if (ABS(mfsize) > MFIFO_SIZE)
+ {
+ ainfo->converged = 0;
+ return (1);
+ }
+ }
+}
+static char nv3_arb(nv3_fifo_info * res_info, nv3_sim_state * state, nv3_arb_info *ainfo)
+{
+ long ens, vns, mns, gns;
+ int mmisses, gmisses, vmisses, eburst_size, mburst_size;
+ int refresh_cycle;
+
+ refresh_cycle = 0;
+ refresh_cycle = 2*(state->mclk_khz/state->pclk_khz) + 5;
+ mmisses = 2;
+ if (state->mem_aligned) gmisses = 2;
+ else gmisses = 3;
+ vmisses = 2;
+ eburst_size = state->memory_width * 1;
+ mburst_size = 32;
+ gns = 1000000 * (gmisses*state->mem_page_miss + state->mem_latency)/state->mclk_khz;
+ ainfo->by_gfacc = gns*ainfo->gdrain_rate/1000000;
+ ainfo->wcmocc = 0;
+ ainfo->wcgocc = 0;
+ ainfo->wcvocc = 0;
+ ainfo->wcvlwm = 0;
+ ainfo->wcglwm = 0;
+ ainfo->engine_en = 1;
+ ainfo->converged = 1;
+ if (ainfo->engine_en)
+ {
+ ens = 1000000*(state->mem_page_miss + eburst_size/(state->memory_width/8) +refresh_cycle)/state->mclk_khz;
+ ainfo->mocc = state->enable_mp ? 0-ens*ainfo->mdrain_rate/1000000 : 0;
+ ainfo->vocc = ainfo->vid_en ? 0-ens*ainfo->vdrain_rate/1000000 : 0;
+ ainfo->gocc = ainfo->gr_en ? 0-ens*ainfo->gdrain_rate/1000000 : 0;
+ ainfo->cur = ENGINE;
+ ainfo->first_vacc = 1;
+ ainfo->first_gacc = 1;
+ ainfo->first_macc = 1;
+ nv3_iterate(res_info, state,ainfo);
+ }
+ if (state->enable_mp)
+ {
+ mns = 1000000 * (mmisses*state->mem_page_miss + mburst_size/(state->memory_width/8) + refresh_cycle)/state->mclk_khz;
+ ainfo->mocc = state->enable_mp ? 0 : mburst_size - mns*ainfo->mdrain_rate/1000000;
+ ainfo->vocc = ainfo->vid_en ? 0 : 0- mns*ainfo->vdrain_rate/1000000;
+ ainfo->gocc = ainfo->gr_en ? 0: 0- mns*ainfo->gdrain_rate/1000000;
+ ainfo->cur = MPORT;
+ ainfo->first_vacc = 1;
+ ainfo->first_gacc = 1;
+ ainfo->first_macc = 0;
+ nv3_iterate(res_info, state,ainfo);
+ }
+ if (ainfo->gr_en)
+ {
+ ainfo->first_vacc = 1;
+ ainfo->first_gacc = 0;
+ ainfo->first_macc = 1;
+ gns = 1000000*(gmisses*state->mem_page_miss + ainfo->gburst_size/(state->memory_width/8) + refresh_cycle)/state->mclk_khz;
+ ainfo->gocc = ainfo->gburst_size - gns*ainfo->gdrain_rate/1000000;
+ ainfo->vocc = ainfo->vid_en? 0-gns*ainfo->vdrain_rate/1000000 : 0;
+ ainfo->mocc = state->enable_mp ? 0-gns*ainfo->mdrain_rate/1000000: 0;
+ ainfo->cur = GRAPHICS;
+ nv3_iterate(res_info, state,ainfo);
+ }
+ if (ainfo->vid_en)
+ {
+ ainfo->first_vacc = 0;
+ ainfo->first_gacc = 1;
+ ainfo->first_macc = 1;
+ vns = 1000000*(vmisses*state->mem_page_miss + ainfo->vburst_size/(state->memory_width/8) + refresh_cycle)/state->mclk_khz;
+ ainfo->vocc = ainfo->vburst_size - vns*ainfo->vdrain_rate/1000000;
+ ainfo->gocc = ainfo->gr_en? (0-vns*ainfo->gdrain_rate/1000000) : 0;
+ ainfo->mocc = state->enable_mp? 0-vns*ainfo->mdrain_rate/1000000 :0 ;
+ ainfo->cur = VIDEO;
+ nv3_iterate(res_info, state, ainfo);
+ }
+ if (ainfo->converged)
+ {
+ res_info->graphics_lwm = (int)ABS(ainfo->wcglwm) + 16;
+ res_info->video_lwm = (int)ABS(ainfo->wcvlwm) + 32;
+ res_info->graphics_burst_size = ainfo->gburst_size;
+ res_info->video_burst_size = ainfo->vburst_size;
+ res_info->graphics_hi_priority = (ainfo->priority == GRAPHICS);
+ res_info->media_hi_priority = (ainfo->priority == MPORT);
+ if (res_info->video_lwm > 160)
+ {
+ res_info->graphics_lwm = 256;
+ res_info->video_lwm = 128;
+ res_info->graphics_burst_size = 64;
+ res_info->video_burst_size = 64;
+ res_info->graphics_hi_priority = 0;
+ res_info->media_hi_priority = 0;
+ ainfo->converged = 0;
+ return (0);
+ }
+ if (res_info->video_lwm > 128)
+ {
+ res_info->video_lwm = 128;
+ }
+ return (1);
+ }
+ else
+ {
+ res_info->graphics_lwm = 256;
+ res_info->video_lwm = 128;
+ res_info->graphics_burst_size = 64;
+ res_info->video_burst_size = 64;
+ res_info->graphics_hi_priority = 0;
+ res_info->media_hi_priority = 0;
+ return (0);
+ }
+}
+static char nv3_get_param(nv3_fifo_info *res_info, nv3_sim_state * state, nv3_arb_info *ainfo)
+{
+ int done, g,v, p;
+
+ done = 0;
+ for (p=0; p < 2; p++)
+ {
+ for (g=128 ; g > 32; g= g>> 1)
+ {
+ for (v=128; v >=32; v = v>> 1)
+ {
+ ainfo->priority = p;
+ ainfo->gburst_size = g;
+ ainfo->vburst_size = v;
+ done = nv3_arb(res_info, state,ainfo);
+ if (done && (g==128))
+ if ((res_info->graphics_lwm + g) > 256)
+ done = 0;
+ if (done)
+ goto Done;
+ }
+ }
+ }
+
+ Done:
+ return done;
+}
+static void nv3CalcArbitration
+(
+ nv3_fifo_info * res_info,
+ nv3_sim_state * state
+)
+{
+ nv3_fifo_info save_info;
+ nv3_arb_info ainfo;
+ char res_gr, res_vid;
+
+ ainfo.gr_en = 1;
+ ainfo.vid_en = state->enable_video;
+ ainfo.vid_only_once = 0;
+ ainfo.gr_only_once = 0;
+ ainfo.gdrain_rate = (int) state->pclk_khz * (state->pix_bpp/8);
+ ainfo.vdrain_rate = (int) state->pclk_khz * 2;
+ if (state->video_scale != 0)
+ ainfo.vdrain_rate = ainfo.vdrain_rate/state->video_scale;
+ ainfo.mdrain_rate = 33000;
+ res_info->rtl_values = 0;
+ if (!state->gr_during_vid && state->enable_video)
+ {
+ ainfo.gr_only_once = 1;
+ ainfo.gr_en = 1;
+ ainfo.gdrain_rate = 0;
+ res_vid = nv3_get_param(res_info, state, &ainfo);
+ res_vid = ainfo.converged;
+ save_info.video_lwm = res_info->video_lwm;
+ save_info.video_burst_size = res_info->video_burst_size;
+ ainfo.vid_en = 1;
+ ainfo.vid_only_once = 1;
+ ainfo.gr_en = 1;
+ ainfo.gdrain_rate = (int) state->pclk_khz * (state->pix_bpp/8);
+ ainfo.vdrain_rate = 0;
+ res_gr = nv3_get_param(res_info, state, &ainfo);
+ res_gr = ainfo.converged;
+ res_info->video_lwm = save_info.video_lwm;
+ res_info->video_burst_size = save_info.video_burst_size;
+ res_info->valid = res_gr & res_vid;
+ }
+ else
+ {
+ if (!ainfo.gr_en) ainfo.gdrain_rate = 0;
+ if (!ainfo.vid_en) ainfo.vdrain_rate = 0;
+ res_gr = nv3_get_param(res_info, state, &ainfo);
+ res_info->valid = ainfo.converged;
+ }
+}
+static void nv3UpdateArbitrationSettings
+(
+ unsigned VClk,
+ unsigned pixelDepth,
+ unsigned *burst,
+ unsigned *lwm,
+ RIVA_HW_INST *chip
+)
+{
+ nv3_fifo_info fifo_data;
+ nv3_sim_state sim_data;
+ unsigned int M, N, P, pll, MClk;
+
+ pll = chip->PRAMDAC0[0x00000504/4];
+ M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F;
+ MClk = (N * chip->CrystalFreqKHz / M) >> P;
+ sim_data.pix_bpp = (char)pixelDepth;
+ sim_data.enable_video = 0;
+ sim_data.enable_mp = 0;
+ sim_data.video_scale = 1;
+ sim_data.memory_width = (chip->PEXTDEV[0x00000000/4] & 0x10) ? 128 : 64;
+ sim_data.memory_width = 128;
+
+ sim_data.mem_latency = 9;
+ sim_data.mem_aligned = 1;
+ sim_data.mem_page_miss = 11;
+ sim_data.gr_during_vid = 0;
+ sim_data.pclk_khz = VClk;
+ sim_data.mclk_khz = MClk;
+ nv3CalcArbitration(&fifo_data, &sim_data);
+ if (fifo_data.valid)
+ {
+ int b = fifo_data.graphics_burst_size >> 4;
+ *burst = 0;
+ while (b >>= 1) (*burst)++;
+ *lwm = fifo_data.graphics_lwm >> 3;
+ }
+ else
+ {
+ *lwm = 0x24;
+ *burst = 0x2;
+ }
+}
+static void nv4CalcArbitration
+(
+ nv4_fifo_info *fifo,
+ nv4_sim_state *arb
+)
+{
+ int data, pagemiss, cas,width, video_enable, color_key_enable, bpp, align;
+ int nvclks, mclks, pclks, vpagemiss, crtpagemiss, vbs;
+ int found, mclk_extra, mclk_loop, cbs, m1, p1;
+ int mclk_freq, pclk_freq, nvclk_freq, mp_enable;
+ int us_m, us_n, us_p, video_drain_rate, crtc_drain_rate;
+ int vpm_us, us_video, vlwm, video_fill_us, cpm_us, us_crt,clwm;
+ int craw, vraw;
+
+ fifo->valid = 1;
+ pclk_freq = arb->pclk_khz;
+ mclk_freq = arb->mclk_khz;
+ nvclk_freq = arb->nvclk_khz;
+ pagemiss = arb->mem_page_miss;
+ cas = arb->mem_latency;
+ width = arb->memory_width >> 6;
+ video_enable = arb->enable_video;
+ color_key_enable = arb->gr_during_vid;
+ bpp = arb->pix_bpp;
+ align = arb->mem_aligned;
+ mp_enable = arb->enable_mp;
+ clwm = 0;
+ vlwm = 0;
+ cbs = 128;
+ pclks = 2;
+ nvclks = 2;
+ nvclks += 2;
+ nvclks += 1;
+ mclks = 5;
+ mclks += 3;
+ mclks += 1;
+ mclks += cas;
+ mclks += 1;
+ mclks += 1;
+ mclks += 1;
+ mclks += 1;
+ mclk_extra = 3;
+ nvclks += 2;
+ nvclks += 1;
+ nvclks += 1;
+ nvclks += 1;
+ if (mp_enable)
+ mclks+=4;
+ nvclks += 0;
+ pclks += 0;
+ found = 0;
+ vbs = 0;
+ while (found != 1)
+ {
+ fifo->valid = 1;
+ found = 1;
+ mclk_loop = mclks+mclk_extra;
+ us_m = mclk_loop *1000*1000 / mclk_freq;
+ us_n = nvclks*1000*1000 / nvclk_freq;
+ us_p = nvclks*1000*1000 / pclk_freq;
+ if (video_enable)
+ {
+ video_drain_rate = pclk_freq * 2;
+ crtc_drain_rate = pclk_freq * bpp/8;
+ vpagemiss = 2;
+ vpagemiss += 1;
+ crtpagemiss = 2;
+ vpm_us = (vpagemiss * pagemiss)*1000*1000/mclk_freq;
+ if (nvclk_freq * 2 > mclk_freq * width)
+ video_fill_us = cbs*1000*1000 / 16 / nvclk_freq ;
+ else
+ video_fill_us = cbs*1000*1000 / (8 * width) / mclk_freq;
+ us_video = vpm_us + us_m + us_n + us_p + video_fill_us;
+ vlwm = us_video * video_drain_rate/(1000*1000);
+ vlwm++;
+ vbs = 128;
+ if (vlwm > 128) vbs = 64;
+ if (vlwm > (256-64)) vbs = 32;
+ if (nvclk_freq * 2 > mclk_freq * width)
+ video_fill_us = vbs *1000*1000/ 16 / nvclk_freq ;
+ else
+ video_fill_us = vbs*1000*1000 / (8 * width) / mclk_freq;
+ cpm_us = crtpagemiss * pagemiss *1000*1000/ mclk_freq;
+ us_crt =
+ us_video
+ +video_fill_us
+ +cpm_us
+ +us_m + us_n +us_p
+ ;
+ clwm = us_crt * crtc_drain_rate/(1000*1000);
+ clwm++;
+ }
+ else
+ {
+ crtc_drain_rate = pclk_freq * bpp/8;
+ crtpagemiss = 2;
+ crtpagemiss += 1;
+ cpm_us = crtpagemiss * pagemiss *1000*1000/ mclk_freq;
+ us_crt = cpm_us + us_m + us_n + us_p ;
+ clwm = us_crt * crtc_drain_rate/(1000*1000);
+ clwm++;
+ }
+ m1 = clwm + cbs - 512;
+ p1 = m1 * pclk_freq / mclk_freq;
+ p1 = p1 * bpp / 8;
+ if ((p1 < m1) && (m1 > 0))
+ {
+ fifo->valid = 0;
+ found = 0;
+ if (mclk_extra ==0) found = 1;
+ mclk_extra--;
+ }
+ else if (video_enable)
+ {
+ if ((clwm > 511) || (vlwm > 255))
+ {
+ fifo->valid = 0;
+ found = 0;
+ if (mclk_extra ==0) found = 1;
+ mclk_extra--;
+ }
+ }
+ else
+ {
+ if (clwm > 519)
+ {
+ fifo->valid = 0;
+ found = 0;
+ if (mclk_extra ==0) found = 1;
+ mclk_extra--;
+ }
+ }
+ craw = clwm;
+ vraw = vlwm;
+ if (clwm < 384) clwm = 384;
+ if (vlwm < 128) vlwm = 128;
+ data = (int)(clwm);
+ fifo->graphics_lwm = data;
+ fifo->graphics_burst_size = 128;
+ data = (int)((vlwm+15));
+ fifo->video_lwm = data;
+ fifo->video_burst_size = vbs;
+ }
+}
+static void nv4UpdateArbitrationSettings
+(
+ unsigned VClk,
+ unsigned pixelDepth,
+ unsigned *burst,
+ unsigned *lwm,
+ RIVA_HW_INST *chip
+)
+{
+ nv4_fifo_info fifo_data;
+ nv4_sim_state sim_data;
+ unsigned int M, N, P, pll, MClk, NVClk, cfg1;
+
+ pll = chip->PRAMDAC0[0x00000504/4];
+ M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F;
+ MClk = (N * chip->CrystalFreqKHz / M) >> P;
+ pll = chip->PRAMDAC0[0x00000500/4];
+ M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F;
+ NVClk = (N * chip->CrystalFreqKHz / M) >> P;
+ cfg1 = chip->PFB[0x00000204/4];
+ sim_data.pix_bpp = (char)pixelDepth;
+ sim_data.enable_video = 0;
+ sim_data.enable_mp = 0;
+ sim_data.memory_width = (chip->PEXTDEV[0x00000000/4] & 0x10) ? 128 : 64;
+ sim_data.mem_latency = (char)cfg1 & 0x0F;
+ sim_data.mem_aligned = 1;
+ sim_data.mem_page_miss = (char)(((cfg1 >> 4) &0x0F) + ((cfg1 >> 31) & 0x01));
+ sim_data.gr_during_vid = 0;
+ sim_data.pclk_khz = VClk;
+ sim_data.mclk_khz = MClk;
+ sim_data.nvclk_khz = NVClk;
+ nv4CalcArbitration(&fifo_data, &sim_data);
+ if (fifo_data.valid)
+ {
+ int b = fifo_data.graphics_burst_size >> 4;
+ *burst = 0;
+ while (b >>= 1) (*burst)++;
+ *lwm = fifo_data.graphics_lwm >> 3;
+ }
+}
+static void nv10CalcArbitration
+(
+ nv10_fifo_info *fifo,
+ nv10_sim_state *arb
+)
+{
+ int data, pagemiss, cas,width, video_enable, color_key_enable, bpp, align;
+ int nvclks, mclks, pclks, vpagemiss, crtpagemiss, vbs;
+ int nvclk_fill, us_extra;
+ int found, mclk_extra, mclk_loop, cbs, m1;
+ int mclk_freq, pclk_freq, nvclk_freq, mp_enable;
+ int us_m, us_m_min, us_n, us_p, video_drain_rate, crtc_drain_rate;
+ int vus_m, vus_n, vus_p;
+ int vpm_us, us_video, vlwm, cpm_us, us_crt,clwm;
+ int clwm_rnd_down;
+ int craw, m2us, us_pipe, us_pipe_min, vus_pipe, p1clk, p2;
+ int pclks_2_top_fifo, min_mclk_extra;
+ int us_min_mclk_extra;
+
+ fifo->valid = 1;
+ pclk_freq = arb->pclk_khz; /* freq in KHz */
+ mclk_freq = arb->mclk_khz;
+ nvclk_freq = arb->nvclk_khz;
+ pagemiss = arb->mem_page_miss;
+ cas = arb->mem_latency;
+ width = arb->memory_width/64;
+ video_enable = arb->enable_video;
+ color_key_enable = arb->gr_during_vid;
+ bpp = arb->pix_bpp;
+ align = arb->mem_aligned;
+ mp_enable = arb->enable_mp;
+ clwm = 0;
+ vlwm = 1024;
+
+ cbs = 512;
+ vbs = 512;
+
+ pclks = 4; /* lwm detect. */
+
+ nvclks = 3; /* lwm -> sync. */
+ nvclks += 2; /* fbi bus cycles (1 req + 1 busy) */
+
+ mclks = 1; /* 2 edge sync. may be very close to edge so just put one. */
+
+ mclks += 1; /* arb_hp_req */
+ mclks += 5; /* ap_hp_req tiling pipeline */
+
+ mclks += 2; /* tc_req latency fifo */
+ mclks += 2; /* fb_cas_n_ memory request to fbio block */
+ mclks += 7; /* sm_d_rdv data returned from fbio block */
+
+ /* fb.rd.d.Put_gc need to accumulate 256 bits for read */
+ if (arb->memory_type == 0)
+ if (arb->memory_width == 64) /* 64 bit bus */
+ mclks += 4;
+ else
+ mclks += 2;
+ else
+ if (arb->memory_width == 64) /* 64 bit bus */
+ mclks += 2;
+ else
+ mclks += 1;
+
+ if ((!video_enable) && (arb->memory_width == 128))
+ {
+ mclk_extra = (bpp == 32) ? 31 : 42; /* Margin of error */
+ min_mclk_extra = 17;
+ }
+ else
+ {
+ mclk_extra = (bpp == 32) ? 8 : 4; /* Margin of error */
+ /* mclk_extra = 4; */ /* Margin of error */
+ min_mclk_extra = 18;
+ }
+
+ nvclks += 1; /* 2 edge sync. may be very close to edge so just put one. */
+ nvclks += 1; /* fbi_d_rdv_n */
+ nvclks += 1; /* Fbi_d_rdata */
+ nvclks += 1; /* crtfifo load */
+
+ if(mp_enable)
+ mclks+=4; /* Mp can get in with a burst of 8. */
+ /* Extra clocks determined by heuristics */
+
+ nvclks += 0;
+ pclks += 0;
+ found = 0;
+ while(found != 1) {
+ fifo->valid = 1;
+ found = 1;
+ mclk_loop = mclks+mclk_extra;
+ us_m = mclk_loop *1000*1000 / mclk_freq; /* Mclk latency in us */
+ us_m_min = mclks * 1000*1000 / mclk_freq; /* Minimum Mclk latency in us */
+ us_min_mclk_extra = min_mclk_extra *1000*1000 / mclk_freq;
+ us_n = nvclks*1000*1000 / nvclk_freq;/* nvclk latency in us */
+ us_p = pclks*1000*1000 / pclk_freq;/* nvclk latency in us */
+ us_pipe = us_m + us_n + us_p;
+ us_pipe_min = us_m_min + us_n + us_p;
+ us_extra = 0;
+
+ vus_m = mclk_loop *1000*1000 / mclk_freq; /* Mclk latency in us */
+ vus_n = (4)*1000*1000 / nvclk_freq;/* nvclk latency in us */
+ vus_p = 0*1000*1000 / pclk_freq;/* pclk latency in us */
+ vus_pipe = vus_m + vus_n + vus_p;
+
+ if(video_enable) {
+ video_drain_rate = pclk_freq * 4; /* MB/s */
+ crtc_drain_rate = pclk_freq * bpp/8; /* MB/s */
+
+ vpagemiss = 1; /* self generating page miss */
+ vpagemiss += 1; /* One higher priority before */
+
+ crtpagemiss = 2; /* self generating page miss */
+ if(mp_enable)
+ crtpagemiss += 1; /* if MA0 conflict */
+
+ vpm_us = (vpagemiss * pagemiss)*1000*1000/mclk_freq;
+
+ us_video = vpm_us + vus_m; /* Video has separate read return path */
+
+ cpm_us = crtpagemiss * pagemiss *1000*1000/ mclk_freq;
+ us_crt =
+ us_video /* Wait for video */
+ +cpm_us /* CRT Page miss */
+ +us_m + us_n +us_p /* other latency */
+ ;
+
+ clwm = us_crt * crtc_drain_rate/(1000*1000);
+ clwm++; /* fixed point <= float_point - 1. Fixes that */
+ } else {
+ crtc_drain_rate = pclk_freq * bpp/8; /* bpp * pclk/8 */
+
+ crtpagemiss = 1; /* self generating page miss */
+ crtpagemiss += 1; /* MA0 page miss */
+ if(mp_enable)
+ crtpagemiss += 1; /* if MA0 conflict */
+ cpm_us = crtpagemiss * pagemiss *1000*1000/ mclk_freq;
+ us_crt = cpm_us + us_m + us_n + us_p ;
+ clwm = us_crt * crtc_drain_rate/(1000*1000);
+ clwm++; /* fixed point <= float_point - 1. Fixes that */
+
+ /*
+ //
+ // Another concern, only for high pclks so don't do this
+ // with video:
+ // What happens if the latency to fetch the cbs is so large that
+ // fifo empties. In that case we need to have an alternate clwm value
+ // based off the total burst fetch
+ //
+ us_crt = (cbs * 1000 * 1000)/ (8*width)/mclk_freq ;
+ us_crt = us_crt + us_m + us_n + us_p + (4 * 1000 * 1000)/mclk_freq;
+ clwm_mt = us_crt * crtc_drain_rate/(1000*1000);
+ clwm_mt ++;
+ if(clwm_mt > clwm)
+ clwm = clwm_mt;
+ */
+ /* Finally, a heuristic check when width == 64 bits */
+ if(width == 1){
+ nvclk_fill = nvclk_freq * 8;
+ if(crtc_drain_rate * 100 >= nvclk_fill * 102)
+ clwm = 0xfff; /*Large number to fail */
+
+ else if(crtc_drain_rate * 100 >= nvclk_fill * 98) {
+ clwm = 1024;
+ cbs = 512;
+ us_extra = (cbs * 1000 * 1000)/ (8*width)/mclk_freq ;
+ }
+ }
+ }
+
+
+ /*
+ Overfill check:
+
+ */
+
+ clwm_rnd_down = ((int)clwm/8)*8;
+ if (clwm_rnd_down < clwm)
+ clwm += 8;
+
+ m1 = clwm + cbs - 1024; /* Amount of overfill */
+ m2us = us_pipe_min + us_min_mclk_extra;
+ pclks_2_top_fifo = (1024-clwm)/(8*width);
+
+ /* pclk cycles to drain */
+ p1clk = m2us * pclk_freq/(1000*1000);
+ p2 = p1clk * bpp / 8; /* bytes drained. */
+
+ if((p2 < m1) && (m1 > 0)) {
+ fifo->valid = 0;
+ found = 0;
+ if(min_mclk_extra == 0) {
+ if(cbs <= 32) {
+ found = 1; /* Can't adjust anymore! */
+ } else {
+ cbs = cbs/2; /* reduce the burst size */
+ }
+ } else {
+ min_mclk_extra--;
+ }
+ } else {
+ if (clwm > 1023){ /* Have some margin */
+ fifo->valid = 0;
+ found = 0;
+ if(min_mclk_extra == 0)
+ found = 1; /* Can't adjust anymore! */
+ else
+ min_mclk_extra--;
+ }
+ }
+ craw = clwm;
+
+ if(clwm < (1024-cbs+8)) clwm = 1024-cbs+8;
+ data = (int)(clwm);
+ /* printf("CRT LWM: %f bytes, prog: 0x%x, bs: 256\n", clwm, data ); */
+ fifo->graphics_lwm = data; fifo->graphics_burst_size = cbs;
+
+ /* printf("VID LWM: %f bytes, prog: 0x%x, bs: %d\n, ", vlwm, data, vbs ); */
+ fifo->video_lwm = 1024; fifo->video_burst_size = 512;
+ }
+}
+static void nv10UpdateArbitrationSettings
+(
+ unsigned VClk,
+ unsigned pixelDepth,
+ unsigned *burst,
+ unsigned *lwm,
+ RIVA_HW_INST *chip
+)
+{
+ nv10_fifo_info fifo_data;
+ nv10_sim_state sim_data;
+ unsigned int M, N, P, pll, MClk, NVClk, cfg1;
+
+ pll = chip->PRAMDAC0[0x00000504/4];
+ M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F;
+ MClk = (N * chip->CrystalFreqKHz / M) >> P;
+ pll = chip->PRAMDAC0[0x00000500/4];
+ M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F;
+ NVClk = (N * chip->CrystalFreqKHz / M) >> P;
+ cfg1 = chip->PFB[0x00000204/4];
+ sim_data.pix_bpp = (char)pixelDepth;
+ sim_data.enable_video = 0;
+ sim_data.enable_mp = 0;
+ sim_data.memory_type = (chip->PFB[0x00000200/4] & 0x01) ? 1 : 0;
+ sim_data.memory_width = (chip->PEXTDEV[0x00000000/4] & 0x10) ? 128 : 64;
+ sim_data.mem_latency = (char)cfg1 & 0x0F;
+ sim_data.mem_aligned = 1;
+ sim_data.mem_page_miss = (char)(((cfg1 >> 4) &0x0F) + ((cfg1 >> 31) & 0x01));
+ sim_data.gr_during_vid = 0;
+ sim_data.pclk_khz = VClk;
+ sim_data.mclk_khz = MClk;
+ sim_data.nvclk_khz = NVClk;
+ nv10CalcArbitration(&fifo_data, &sim_data);
+ if (fifo_data.valid)
+ {
+ int b = fifo_data.graphics_burst_size >> 4;
+ *burst = 0;
+ while (b >>= 1) (*burst)++;
+ *lwm = fifo_data.graphics_lwm >> 3;
+ }
+}
+
+static void nForceUpdateArbitrationSettings
+(
+ unsigned VClk,
+ unsigned pixelDepth,
+ unsigned *burst,
+ unsigned *lwm,
+ RIVA_HW_INST *chip
+)
+{
+ nv10_fifo_info fifo_data;
+ nv10_sim_state sim_data;
+ unsigned int M, N, P, pll, MClk, NVClk;
+ unsigned int uMClkPostDiv, memctrl;
+
+ uMClkPostDiv = (pciReadLong(pciTag(0, 0, 3), 0x6C) >> 8) & 0xf;
+ if(!uMClkPostDiv) uMClkPostDiv = 4;
+ MClk = 400000 / uMClkPostDiv;
+
+ pll = chip->PRAMDAC0[0x00000500/4];
+ M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F;
+ NVClk = (N * chip->CrystalFreqKHz / M) >> P;
+ sim_data.pix_bpp = (char)pixelDepth;
+ sim_data.enable_video = 0;
+ sim_data.enable_mp = 0;
+ sim_data.memory_type = (pciReadLong(pciTag(0, 0, 1), 0x7C) >> 12) & 1;
+ sim_data.memory_width = 64;
+
+ memctrl = pciReadLong(pciTag(0, 0, 3), 0x00) >> 16;
+
+ if((memctrl == 0x1A9) || (memctrl == 0x1AB) || (memctrl == 0x1ED)) {
+ int dimm[3];
+
+ dimm[0] = (pciReadLong(pciTag(0, 0, 2), 0x40) >> 8) & 0x4F;
+ dimm[1] = (pciReadLong(pciTag(0, 0, 2), 0x44) >> 8) & 0x4F;
+ dimm[2] = (pciReadLong(pciTag(0, 0, 2), 0x48) >> 8) & 0x4F;
+
+ if((dimm[0] + dimm[1]) != dimm[2]) {
+ ErrorF("WARNING: "
+ "your nForce DIMMs are not arranged in optimal banks!\n");
+ }
+ }
+
+ sim_data.mem_latency = 3;
+ sim_data.mem_aligned = 1;
+ sim_data.mem_page_miss = 10;
+ sim_data.gr_during_vid = 0;
+ sim_data.pclk_khz = VClk;
+ sim_data.mclk_khz = MClk;
+ sim_data.nvclk_khz = NVClk;
+ nv10CalcArbitration(&fifo_data, &sim_data);
+ if (fifo_data.valid)
+ {
+ int b = fifo_data.graphics_burst_size >> 4;
+ *burst = 0;
+ while (b >>= 1) (*burst)++;
+ *lwm = fifo_data.graphics_lwm >> 3;
+ }
+}
+
+
+/****************************************************************************\
+* *
+* RIVA Mode State Routines *
+* *
+\****************************************************************************/
+
+/*
+ * Calculate the Video Clock parameters for the PLL.
+ */
+static int CalcVClock
+(
+ int clockIn,
+ int *clockOut,
+ int *mOut,
+ int *nOut,
+ int *pOut,
+ RIVA_HW_INST *chip
+)
+{
+ unsigned lowM, highM, highP;
+ unsigned DeltaNew, DeltaOld;
+ unsigned VClk, Freq;
+ unsigned M, N, P;
+
+ DeltaOld = 0xFFFFFFFF;
+
+ VClk = (unsigned)clockIn;
+
+ if (chip->CrystalFreqKHz == 13500)
+ {
+ lowM = 7;
+ highM = 13 - (chip->Architecture == NV_ARCH_03);
+ }
+ else
+ {
+ lowM = 8;
+ highM = 14 - (chip->Architecture == NV_ARCH_03);
+ }
+
+ highP = 4 - (chip->Architecture == NV_ARCH_03);
+ for (P = 0; P <= highP; P ++)
+ {
+ Freq = VClk << P;
+ if ((Freq >= 128000) && (Freq <= chip->MaxVClockFreqKHz))
+ {
+ for (M = lowM; M <= highM; M++)
+ {
+ N = (VClk << P) * M / chip->CrystalFreqKHz;
+ if(N <= 255) {
+ Freq = (chip->CrystalFreqKHz * N / M) >> P;
+ if (Freq > VClk)
+ DeltaNew = Freq - VClk;
+ else
+ DeltaNew = VClk - Freq;
+ if (DeltaNew < DeltaOld)
+ {
+ *mOut = M;
+ *nOut = N;
+ *pOut = P;
+ *clockOut = Freq;
+ DeltaOld = DeltaNew;
+ }
+ }
+ }
+ }
+ }
+ return (DeltaOld != 0xFFFFFFFF);
+}
+/*
+ * Calculate extended mode parameters (SVGA) and save in a
+ * mode state structure.
+ */
+static void CalcStateExt
+(
+ RIVA_HW_INST *chip,
+ RIVA_HW_STATE *state,
+ int bpp,
+ int width,
+ int hDisplaySize,
+ int height,
+ int dotClock,
+ int flags
+)
+{
+ int pixelDepth, VClk, m, n, p;
+ /*
+ * Save mode parameters.
+ */
+ state->bpp = bpp; /* this is not bitsPerPixel, it's 8,15,16,32 */
+ state->width = width;
+ state->height = height;
+ /*
+ * Extended RIVA registers.
+ */
+ pixelDepth = (bpp + 1)/8;
+ CalcVClock(dotClock, &VClk, &m, &n, &p, chip);
+
+ switch (chip->Architecture)
+ {
+ case NV_ARCH_03:
+ nv3UpdateArbitrationSettings(VClk,
+ pixelDepth * 8,
+ &(state->arbitration0),
+ &(state->arbitration1),
+ chip);
+ state->cursor0 = 0x00;
+ state->cursor1 = 0x78;
+ if (flags & V_DBLSCAN)
+ state->cursor1 |= 2;
+ state->cursor2 = 0x00000000;
+ state->pllsel = 0x10010100;
+ state->config = ((width + 31)/32)
+ | (((pixelDepth > 2) ? 3 : pixelDepth) << 8)
+ | 0x1000;
+ state->general = 0x00100100;
+ state->repaint1 = hDisplaySize < 1280 ? 0x06 : 0x02;
+ break;
+ case NV_ARCH_04:
+ nv4UpdateArbitrationSettings(VClk,
+ pixelDepth * 8,
+ &(state->arbitration0),
+ &(state->arbitration1),
+ chip);
+ state->cursor0 = 0x00;
+ state->cursor1 = 0xFC;
+ if (flags & V_DBLSCAN)
+ state->cursor1 |= 2;
+ state->cursor2 = 0x00000000;
+ state->pllsel = 0x10000700;
+ state->config = 0x00001114;
+ state->general = bpp == 16 ? 0x00101100 : 0x00100100;
+ state->repaint1 = hDisplaySize < 1280 ? 0x04 : 0x00;
+ break;
+ case NV_ARCH_10:
+ case NV_ARCH_20:
+ if(((chip->Chipset & 0xffff) == 0x01A0) ||
+ ((chip->Chipset & 0xffff) == 0x01f0))
+ {
+ nForceUpdateArbitrationSettings(VClk,
+ pixelDepth * 8,
+ &(state->arbitration0),
+ &(state->arbitration1),
+ chip);
+ } else {
+ nv10UpdateArbitrationSettings(VClk,
+ pixelDepth * 8,
+ &(state->arbitration0),
+ &(state->arbitration1),
+ chip);
+ }
+ state->cursor0 = 0x80 | (chip->CursorStart >> 17);
+ state->cursor1 = (chip->CursorStart >> 11) << 2;
+ state->cursor2 = chip->CursorStart >> 24;
+ if (flags & V_DBLSCAN)
+ state->cursor1 |= 2;
+ state->pllsel = 0x10000700;
+ state->config = chip->PFB[0x00000200/4];
+ state->general = bpp == 16 ? 0x00101100 : 0x00100100;
+ state->repaint1 = hDisplaySize < 1280 ? 0x04 : 0x00;
+ break;
+ }
+
+ if((bpp != 8) && (chip->Architecture != NV_ARCH_03)) /* DirectColor */
+ state->general |= 0x00000030;
+
+ state->vpll = (p << 16) | (n << 8) | m;
+ state->repaint0 = (((width/8)*pixelDepth) & 0x700) >> 3;
+ state->pixel = pixelDepth > 2 ? 3 : pixelDepth;
+ state->offset = 0;
+ state->pitch = pixelDepth * width;
+}
+/*
+ * Load fixed function state and pre-calculated/stored state.
+ */
+#define LOAD_FIXED_STATE(tbl,dev) \
+ for (i = 0; i < sizeof(tbl##Table##dev)/8; i++) \
+ chip->dev[tbl##Table##dev[i][0]] = tbl##Table##dev[i][1]
+#define LOAD_FIXED_STATE_8BPP(tbl,dev) \
+ for (i = 0; i < sizeof(tbl##Table##dev##_8BPP)/8; i++) \
+ chip->dev[tbl##Table##dev##_8BPP[i][0]] = tbl##Table##dev##_8BPP[i][1]
+#define LOAD_FIXED_STATE_15BPP(tbl,dev) \
+ for (i = 0; i < sizeof(tbl##Table##dev##_15BPP)/8; i++) \
+ chip->dev[tbl##Table##dev##_15BPP[i][0]] = tbl##Table##dev##_15BPP[i][1]
+#define LOAD_FIXED_STATE_16BPP(tbl,dev) \
+ for (i = 0; i < sizeof(tbl##Table##dev##_16BPP)/8; i++) \
+ chip->dev[tbl##Table##dev##_16BPP[i][0]] = tbl##Table##dev##_16BPP[i][1]
+#define LOAD_FIXED_STATE_32BPP(tbl,dev) \
+ for (i = 0; i < sizeof(tbl##Table##dev##_32BPP)/8; i++) \
+ chip->dev[tbl##Table##dev##_32BPP[i][0]] = tbl##Table##dev##_32BPP[i][1]
+static void UpdateFifoState
+(
+ RIVA_HW_INST *chip
+)
+{
+ int i;
+
+ switch (chip->Architecture)
+ {
+ case NV_ARCH_04:
+ LOAD_FIXED_STATE(nv4,FIFO);
+ break;
+ case NV_ARCH_10:
+ case NV_ARCH_20:
+ LOAD_FIXED_STATE(nv10,FIFO);
+ break;
+ }
+}
+static void LoadStateExt
+(
+ RIVA_HW_INST *chip,
+ RIVA_HW_STATE *state
+)
+{
+ int i, format;
+
+ /*
+ * Load HW fixed function state.
+ */
+ LOAD_FIXED_STATE(Riva,PMC);
+ LOAD_FIXED_STATE(Riva,PTIMER);
+ switch (chip->Architecture)
+ {
+ case NV_ARCH_03:
+ /*
+ * Make sure frame buffer config gets set before loading PRAMIN.
+ */
+ chip->PFB[0x00000200/4] = state->config;
+ LOAD_FIXED_STATE(nv3,PFIFO);
+ LOAD_FIXED_STATE(nv3,PRAMIN);
+ LOAD_FIXED_STATE(nv3,PGRAPH);
+ switch (state->bpp)
+ {
+ case 15:
+ case 16:
+ LOAD_FIXED_STATE_15BPP(nv3,PRAMIN);
+ LOAD_FIXED_STATE_15BPP(nv3,PGRAPH);
+ break;
+ case 24:
+ case 32:
+ LOAD_FIXED_STATE_32BPP(nv3,PRAMIN);
+ LOAD_FIXED_STATE_32BPP(nv3,PGRAPH);
+ break;
+ case 8:
+ default:
+ LOAD_FIXED_STATE_8BPP(nv3,PRAMIN);
+ LOAD_FIXED_STATE_8BPP(nv3,PGRAPH);
+ break;
+ }
+ for (i = 0x00000; i < 0x00800; i++)
+ chip->PRAMIN[0x00000502 + i] = (i << 12) | 0x03;
+ chip->PGRAPH[0x00000630/4] = state->offset;
+ chip->PGRAPH[0x00000634/4] = state->offset;
+ chip->PGRAPH[0x00000638/4] = state->offset;
+ chip->PGRAPH[0x0000063C/4] = state->offset;
+ chip->PGRAPH[0x00000650/4] = state->pitch;
+ chip->PGRAPH[0x00000654/4] = state->pitch;
+ chip->PGRAPH[0x00000658/4] = state->pitch;
+ chip->PGRAPH[0x0000065C/4] = state->pitch;
+ break;
+ case NV_ARCH_04:
+ /*
+ * Make sure frame buffer config gets set before loading PRAMIN.
+ */
+ chip->PFB[0x00000200/4] = state->config;
+ LOAD_FIXED_STATE(nv4,PFIFO);
+ LOAD_FIXED_STATE(nv4,PRAMIN);
+ LOAD_FIXED_STATE(nv4,PGRAPH);
+ switch (state->bpp)
+ {
+ case 15:
+ LOAD_FIXED_STATE_15BPP(nv4,PRAMIN);
+ LOAD_FIXED_STATE_15BPP(nv4,PGRAPH);
+ break;
+ case 16:
+ LOAD_FIXED_STATE_16BPP(nv4,PRAMIN);
+ LOAD_FIXED_STATE_16BPP(nv4,PGRAPH);
+ break;
+ case 24:
+ case 32:
+ LOAD_FIXED_STATE_32BPP(nv4,PRAMIN);
+ LOAD_FIXED_STATE_32BPP(nv4,PGRAPH);
+ break;
+ case 8:
+ default:
+ LOAD_FIXED_STATE_8BPP(nv4,PRAMIN);
+ LOAD_FIXED_STATE_8BPP(nv4,PGRAPH);
+ break;
+ }
+ chip->PGRAPH[0x00000640/4] = state->offset;
+ chip->PGRAPH[0x00000644/4] = state->offset;
+ chip->PGRAPH[0x00000648/4] = state->offset;
+ chip->PGRAPH[0x0000064C/4] = state->offset;
+ chip->PGRAPH[0x00000670/4] = state->pitch;
+ chip->PGRAPH[0x00000674/4] = state->pitch;
+ chip->PGRAPH[0x00000678/4] = state->pitch;
+ chip->PGRAPH[0x0000067C/4] = state->pitch;
+ break;
+ case NV_ARCH_10:
+ case NV_ARCH_20:
+ if(chip->twoHeads) {
+ VGA_WR08(chip->PCIO, 0x03D4, 0x44);
+ VGA_WR08(chip->PCIO, 0x03D5, state->crtcOwner);
+ chip->LockUnlock(chip, 0);
+ }
+
+ LOAD_FIXED_STATE(nv10,PFIFO);
+ LOAD_FIXED_STATE(nv10,PRAMIN);
+ LOAD_FIXED_STATE(nv10,PGRAPH);
+ switch (state->bpp)
+ {
+ case 15:
+ format = 2;
+ LOAD_FIXED_STATE_15BPP(nv10,PRAMIN);
+ LOAD_FIXED_STATE_15BPP(nv10,PGRAPH);
+ break;
+ case 16:
+ format = 5;
+ LOAD_FIXED_STATE_16BPP(nv10,PRAMIN);
+ LOAD_FIXED_STATE_16BPP(nv10,PGRAPH);
+ break;
+ case 32:
+ format = 7;
+ LOAD_FIXED_STATE_32BPP(nv10,PRAMIN);
+ LOAD_FIXED_STATE_32BPP(nv10,PGRAPH);
+ break;
+ default:
+ format = 1;
+ LOAD_FIXED_STATE_8BPP(nv10,PRAMIN);
+ LOAD_FIXED_STATE_8BPP(nv10,PGRAPH);
+ break;
+ }
+
+ if(chip->Architecture == NV_ARCH_10) {
+ chip->PGRAPH[0x00000640/4] = state->offset;
+ chip->PGRAPH[0x00000644/4] = state->offset;
+ chip->PGRAPH[0x00000648/4] = state->offset;
+ chip->PGRAPH[0x0000064C/4] = state->offset;
+ chip->PGRAPH[0x00000670/4] = state->pitch;
+ chip->PGRAPH[0x00000674/4] = state->pitch;
+ chip->PGRAPH[0x00000678/4] = state->pitch;
+ chip->PGRAPH[0x0000067C/4] = state->pitch;
+ chip->PGRAPH[0x00000680/4] = state->pitch;
+ } else {
+ chip->PGRAPH[0x00000864/4] = 0x01ffffff;
+ chip->PGRAPH[0x00000868/4] = 0x01ffffff;
+ chip->PGRAPH[0x0000086c/4] = 0x01ffffff;
+ chip->PGRAPH[0x00000870/4] = 0x01ffffff;
+
+ chip->PGRAPH[0x00000820/4] = state->offset;
+ chip->PGRAPH[0x00000824/4] = state->offset;
+ chip->PGRAPH[0x00000828/4] = state->offset;
+ chip->PGRAPH[0x0000082C/4] = state->offset;
+ chip->PGRAPH[0x00000850/4] = state->pitch;
+ chip->PGRAPH[0x00000854/4] = state->pitch;
+ chip->PGRAPH[0x00000858/4] = state->pitch;
+ chip->PGRAPH[0x0000085C/4] = state->pitch;
+ chip->PGRAPH[0x000009A4/4] = chip->PFB[0x00000200/4];
+ chip->PGRAPH[0x000009A8/4] = chip->PFB[0x00000204/4];
+
+ if((chip->Chipset & 0x0ff0) >= 0x0300) {
+ if(!chip->flatPanel) {
+ chip->PRAMDAC0[0x0578/4] = state->vpllB;
+ chip->PRAMDAC0[0x057C/4] = state->vpll2B;
+ }
+ chip->PGRAPH[0x00000724/4] = format | (format << 5);
+ chip->PGRAPH[0x0000008C/4] |= 1;
+ chip->PGRAPH[0x00000890/4] |= 0x00040000;
+ }
+ }
+ if(chip->twoHeads) {
+ chip->PCRTC0[0x00000860/4] = state->head;
+ chip->PCRTC0[0x00002860/4] = state->head2;
+ }
+ chip->PRAMDAC[0x00000404/4] |= (1 << 25);
+
+ chip->PMC[0x00008704/4] = 1;
+ chip->PMC[0x00008140/4] = 0;
+ chip->PMC[0x00008920/4] = 0;
+ chip->PMC[0x00008924/4] = 0;
+ chip->PMC[0x00008908/4] = 0x01ffffff;
+ chip->PMC[0x0000890C/4] = 0x01ffffff;
+ chip->PMC[0x00001588/4] = 0;
+
+ chip->PFB[0x00000240/4] = 0;
+ chip->PFB[0x00000250/4] = 0;
+ chip->PFB[0x00000260/4] = 0;
+ chip->PFB[0x00000270/4] = 0;
+ chip->PFB[0x00000280/4] = 0;
+ chip->PFB[0x00000290/4] = 0;
+ chip->PFB[0x000002A0/4] = 0;
+ chip->PFB[0x000002B0/4] = 0;
+
+ chip->PGRAPH[0x00000B00/4] = chip->PFB[0x00000240/4];
+ chip->PGRAPH[0x00000B04/4] = chip->PFB[0x00000244/4];
+ chip->PGRAPH[0x00000B08/4] = chip->PFB[0x00000248/4];
+ chip->PGRAPH[0x00000B0C/4] = chip->PFB[0x0000024C/4];
+ chip->PGRAPH[0x00000B10/4] = chip->PFB[0x00000250/4];
+ chip->PGRAPH[0x00000B14/4] = chip->PFB[0x00000254/4];
+ chip->PGRAPH[0x00000B18/4] = chip->PFB[0x00000258/4];
+ chip->PGRAPH[0x00000B1C/4] = chip->PFB[0x0000025C/4];
+ chip->PGRAPH[0x00000B20/4] = chip->PFB[0x00000260/4];
+ chip->PGRAPH[0x00000B24/4] = chip->PFB[0x00000264/4];
+ chip->PGRAPH[0x00000B28/4] = chip->PFB[0x00000268/4];
+ chip->PGRAPH[0x00000B2C/4] = chip->PFB[0x0000026C/4];
+ chip->PGRAPH[0x00000B30/4] = chip->PFB[0x00000270/4];
+ chip->PGRAPH[0x00000B34/4] = chip->PFB[0x00000274/4];
+ chip->PGRAPH[0x00000B38/4] = chip->PFB[0x00000278/4];
+ chip->PGRAPH[0x00000B3C/4] = chip->PFB[0x0000027C/4];
+ chip->PGRAPH[0x00000B40/4] = chip->PFB[0x00000280/4];
+ chip->PGRAPH[0x00000B44/4] = chip->PFB[0x00000284/4];
+ chip->PGRAPH[0x00000B48/4] = chip->PFB[0x00000288/4];
+ chip->PGRAPH[0x00000B4C/4] = chip->PFB[0x0000028C/4];
+ chip->PGRAPH[0x00000B50/4] = chip->PFB[0x00000290/4];
+ chip->PGRAPH[0x00000B54/4] = chip->PFB[0x00000294/4];
+ chip->PGRAPH[0x00000B58/4] = chip->PFB[0x00000298/4];
+ chip->PGRAPH[0x00000B5C/4] = chip->PFB[0x0000029C/4];
+ chip->PGRAPH[0x00000B60/4] = chip->PFB[0x000002A0/4];
+ chip->PGRAPH[0x00000B64/4] = chip->PFB[0x000002A4/4];
+ chip->PGRAPH[0x00000B68/4] = chip->PFB[0x000002A8/4];
+ chip->PGRAPH[0x00000B6C/4] = chip->PFB[0x000002AC/4];
+ chip->PGRAPH[0x00000B70/4] = chip->PFB[0x000002B0/4];
+ chip->PGRAPH[0x00000B74/4] = chip->PFB[0x000002B4/4];
+ chip->PGRAPH[0x00000B78/4] = chip->PFB[0x000002B8/4];
+ chip->PGRAPH[0x00000B7C/4] = chip->PFB[0x000002BC/4];
+ chip->PGRAPH[0x00000F40/4] = 0x10000000;
+ chip->PGRAPH[0x00000F44/4] = 0x00000000;
+ chip->PGRAPH[0x00000F50/4] = 0x00000040;
+ chip->PGRAPH[0x00000F54/4] = 0x00000008;
+ chip->PGRAPH[0x00000F50/4] = 0x00000200;
+ for (i = 0; i < (3*16); i++)
+ chip->PGRAPH[0x00000F54/4] = 0x00000000;
+ chip->PGRAPH[0x00000F50/4] = 0x00000040;
+ chip->PGRAPH[0x00000F54/4] = 0x00000000;
+ chip->PGRAPH[0x00000F50/4] = 0x00000800;
+ for (i = 0; i < (16*16); i++)
+ chip->PGRAPH[0x00000F54/4] = 0x00000000;
+ chip->PGRAPH[0x00000F40/4] = 0x30000000;
+ chip->PGRAPH[0x00000F44/4] = 0x00000004;
+ chip->PGRAPH[0x00000F50/4] = 0x00006400;
+ for (i = 0; i < (59*4); i++)
+ chip->PGRAPH[0x00000F54/4] = 0x00000000;
+ chip->PGRAPH[0x00000F50/4] = 0x00006800;
+ for (i = 0; i < (47*4); i++)
+ chip->PGRAPH[0x00000F54/4] = 0x00000000;
+ chip->PGRAPH[0x00000F50/4] = 0x00006C00;
+ for (i = 0; i < (3*4); i++)
+ chip->PGRAPH[0x00000F54/4] = 0x00000000;
+ chip->PGRAPH[0x00000F50/4] = 0x00007000;
+ for (i = 0; i < (19*4); i++)
+ chip->PGRAPH[0x00000F54/4] = 0x00000000;
+ chip->PGRAPH[0x00000F50/4] = 0x00007400;
+ for (i = 0; i < (12*4); i++)
+ chip->PGRAPH[0x00000F54/4] = 0x00000000;
+ chip->PGRAPH[0x00000F50/4] = 0x00007800;
+ for (i = 0; i < (12*4); i++)
+ chip->PGRAPH[0x00000F54/4] = 0x00000000;
+ chip->PGRAPH[0x00000F50/4] = 0x00004400;
+ for (i = 0; i < (8*4); i++)
+ chip->PGRAPH[0x00000F54/4] = 0x00000000;
+ chip->PGRAPH[0x00000F50/4] = 0x00000000;
+ for (i = 0; i < 16; i++)
+ chip->PGRAPH[0x00000F54/4] = 0x00000000;
+ chip->PGRAPH[0x00000F50/4] = 0x00000040;
+ for (i = 0; i < 4; i++)
+ chip->PGRAPH[0x00000F54/4] = 0x00000000;
+
+ chip->PCRTC[0x00000810/4] = state->cursorConfig;
+
+ if(chip->flatPanel) {
+ if((chip->Chipset & 0x0ff0) == 0x0110) {
+ chip->PRAMDAC[0x0528/4] = state->dither;
+ } else
+ if((chip->Chipset & 0x0ff0) >= 0x0170) {
+ chip->PRAMDAC[0x083C/4] = state->dither;
+ }
+
+
+ VGA_WR08(chip->PCIO, 0x03D4, 0x53);
+ VGA_WR08(chip->PCIO, 0x03D5, 0);
+ VGA_WR08(chip->PCIO, 0x03D4, 0x54);
+ VGA_WR08(chip->PCIO, 0x03D5, 0);
+ VGA_WR08(chip->PCIO, 0x03D4, 0x21);
+ VGA_WR08(chip->PCIO, 0x03D5, 0xfa);
+ }
+
+ VGA_WR08(chip->PCIO, 0x03D4, 0x41);
+ VGA_WR08(chip->PCIO, 0x03D5, state->extra);
+ }
+
+ LOAD_FIXED_STATE(Riva,FIFO);
+ UpdateFifoState(chip);
+
+ /*
+ * Load HW mode state.
+ */
+ VGA_WR08(chip->PCIO, 0x03D4, 0x19);
+ VGA_WR08(chip->PCIO, 0x03D5, state->repaint0);
+ VGA_WR08(chip->PCIO, 0x03D4, 0x1A);
+ VGA_WR08(chip->PCIO, 0x03D5, state->repaint1);
+ VGA_WR08(chip->PCIO, 0x03D4, 0x25);
+ VGA_WR08(chip->PCIO, 0x03D5, state->screen);
+ VGA_WR08(chip->PCIO, 0x03D4, 0x28);
+ VGA_WR08(chip->PCIO, 0x03D5, state->pixel);
+ VGA_WR08(chip->PCIO, 0x03D4, 0x2D);
+ VGA_WR08(chip->PCIO, 0x03D5, state->horiz);
+ VGA_WR08(chip->PCIO, 0x03D4, 0x1B);
+ VGA_WR08(chip->PCIO, 0x03D5, state->arbitration0);
+ VGA_WR08(chip->PCIO, 0x03D4, 0x20);
+ VGA_WR08(chip->PCIO, 0x03D5, state->arbitration1);
+ VGA_WR08(chip->PCIO, 0x03D4, 0x30);
+ VGA_WR08(chip->PCIO, 0x03D5, state->cursor0);
+ VGA_WR08(chip->PCIO, 0x03D4, 0x31);
+ VGA_WR08(chip->PCIO, 0x03D5, state->cursor1);
+ VGA_WR08(chip->PCIO, 0x03D4, 0x2F);
+ VGA_WR08(chip->PCIO, 0x03D5, state->cursor2);
+ VGA_WR08(chip->PCIO, 0x03D4, 0x39);
+ VGA_WR08(chip->PCIO, 0x03D5, state->interlace);
+
+ if(!chip->flatPanel) {
+ chip->PRAMDAC0[0x00000508/4] = state->vpll;
+ chip->PRAMDAC0[0x0000050C/4] = state->pllsel;
+ if(chip->twoHeads)
+ chip->PRAMDAC0[0x00000520/4] = state->vpll2;
+ } else {
+ chip->PRAMDAC[0x00000848/4] = state->scale;
+ }
+ chip->PRAMDAC[0x00000600/4] = state->general;
+
+ /*
+ * Turn off VBlank enable and reset.
+ */
+ chip->PCRTC[0x00000140/4] = 0;
+ chip->PCRTC[0x00000100/4] = chip->VBlankBit;
+ /*
+ * Set interrupt enable.
+ */
+ chip->PMC[0x00000140/4] = chip->EnableIRQ & 0x01;
+ /*
+ * Set current state pointer.
+ */
+ chip->CurrentState = state;
+ /*
+ * Reset FIFO free and empty counts.
+ */
+ chip->FifoFreeCount = 0;
+ /* Free count from first subchannel */
+ chip->FifoEmptyCount = chip->Rop->FifoFree;
+}
+
+static void UnloadStateExt
+(
+ RIVA_HW_INST *chip,
+ RIVA_HW_STATE *state
+)
+{
+ /*
+ * Save current HW state.
+ */
+ VGA_WR08(chip->PCIO, 0x03D4, 0x19);
+ state->repaint0 = VGA_RD08(chip->PCIO, 0x03D5);
+ VGA_WR08(chip->PCIO, 0x03D4, 0x1A);
+ state->repaint1 = VGA_RD08(chip->PCIO, 0x03D5);
+ VGA_WR08(chip->PCIO, 0x03D4, 0x25);
+ state->screen = VGA_RD08(chip->PCIO, 0x03D5);
+ VGA_WR08(chip->PCIO, 0x03D4, 0x28);
+ state->pixel = VGA_RD08(chip->PCIO, 0x03D5);
+ VGA_WR08(chip->PCIO, 0x03D4, 0x2D);
+ state->horiz = VGA_RD08(chip->PCIO, 0x03D5);
+ VGA_WR08(chip->PCIO, 0x03D4, 0x1B);
+ state->arbitration0 = VGA_RD08(chip->PCIO, 0x03D5);
+ VGA_WR08(chip->PCIO, 0x03D4, 0x20);
+ state->arbitration1 = VGA_RD08(chip->PCIO, 0x03D5);
+ VGA_WR08(chip->PCIO, 0x03D4, 0x30);
+ state->cursor0 = VGA_RD08(chip->PCIO, 0x03D5);
+ VGA_WR08(chip->PCIO, 0x03D4, 0x31);
+ state->cursor1 = VGA_RD08(chip->PCIO, 0x03D5);
+ VGA_WR08(chip->PCIO, 0x03D4, 0x2F);
+ state->cursor2 = VGA_RD08(chip->PCIO, 0x03D5);
+ VGA_WR08(chip->PCIO, 0x03D4, 0x39);
+ state->interlace = VGA_RD08(chip->PCIO, 0x03D5);
+ state->vpll = chip->PRAMDAC0[0x00000508/4];
+ state->vpll2 = chip->PRAMDAC0[0x00000520/4];
+ state->vpllB = chip->PRAMDAC0[0x00000578/4];
+ state->vpll2B = chip->PRAMDAC0[0x0000057C/4];
+ state->pllsel = chip->PRAMDAC0[0x0000050C/4];
+ state->general = chip->PRAMDAC[0x00000600/4];
+ state->scale = chip->PRAMDAC[0x00000848/4];
+ state->config = chip->PFB[0x00000200/4];
+
+ switch (chip->Architecture)
+ {
+ case NV_ARCH_03:
+ state->offset = chip->PGRAPH[0x00000630/4];
+ state->pitch = chip->PGRAPH[0x00000650/4];
+ break;
+ case NV_ARCH_04:
+ state->offset = chip->PGRAPH[0x00000640/4];
+ state->pitch = chip->PGRAPH[0x00000670/4];
+ break;
+ case NV_ARCH_10:
+ case NV_ARCH_20:
+ state->offset = chip->PGRAPH[0x00000640/4];
+ state->pitch = chip->PGRAPH[0x00000670/4];
+ if(chip->twoHeads) {
+ state->head = chip->PCRTC0[0x00000860/4];
+ state->head2 = chip->PCRTC0[0x00002860/4];
+ VGA_WR08(chip->PCIO, 0x03D4, 0x44);
+ state->crtcOwner = VGA_RD08(chip->PCIO, 0x03D5);
+ }
+ VGA_WR08(chip->PCIO, 0x03D4, 0x41);
+ state->extra = VGA_RD08(chip->PCIO, 0x03D5);
+ state->cursorConfig = chip->PCRTC[0x00000810/4];
+
+ if((chip->Chipset & 0x0ff0) == 0x0110) {
+ state->dither = chip->PRAMDAC[0x0528/4];
+ } else
+ if((chip->Chipset & 0x0ff0) >= 0x0170) {
+ state->dither = chip->PRAMDAC[0x083C/4];
+ }
+
+ break;
+ }
+}
+static void SetStartAddress
+(
+ RIVA_HW_INST *chip,
+ unsigned start
+)
+{
+ chip->PCRTC[0x800/4] = start;
+}
+
+static void SetStartAddress3
+(
+ RIVA_HW_INST *chip,
+ unsigned start
+)
+{
+ int offset = start >> 2;
+ int pan = (start & 3) << 1;
+ unsigned char tmp;
+
+ /*
+ * Unlock extended registers.
+ */
+ chip->LockUnlock(chip, 0);
+ /*
+ * Set start address.
+ */
+ VGA_WR08(chip->PCIO, 0x3D4, 0x0D); VGA_WR08(chip->PCIO, 0x3D5, offset);
+ offset >>= 8;
+ VGA_WR08(chip->PCIO, 0x3D4, 0x0C); VGA_WR08(chip->PCIO, 0x3D5, offset);
+ offset >>= 8;
+ VGA_WR08(chip->PCIO, 0x3D4, 0x19); tmp = VGA_RD08(chip->PCIO, 0x3D5);
+ VGA_WR08(chip->PCIO, 0x3D5, (offset & 0x01F) | (tmp & ~0x1F));
+ VGA_WR08(chip->PCIO, 0x3D4, 0x2D); tmp = VGA_RD08(chip->PCIO, 0x3D5);
+ VGA_WR08(chip->PCIO, 0x3D5, (offset & 0x60) | (tmp & ~0x60));
+ /*
+ * 4 pixel pan register.
+ */
+ offset = VGA_RD08(chip->PCIO, chip->IO + 0x0A);
+ VGA_WR08(chip->PCIO, 0x3C0, 0x13);
+ VGA_WR08(chip->PCIO, 0x3C0, pan);
+}
+/****************************************************************************\
+* *
+* Probe RIVA Chip Configuration *
+* *
+\****************************************************************************/
+
+static void nv3GetConfig
+(
+ RIVA_HW_INST *chip
+)
+{
+ /*
+ * Fill in chip configuration.
+ */
+ if (chip->PFB[0x00000000/4] & 0x00000020)
+ {
+ if (((chip->PMC[0x00000000/4] & 0xF0) == 0x20)
+ && ((chip->PMC[0x00000000/4] & 0x0F) >= 0x02))
+ {
+ /*
+ * SDRAM 128 ZX.
+ */
+ chip->RamBandwidthKBytesPerSec = 800000;
+ switch (chip->PFB[0x00000000/4] & 0x03)
+ {
+ case 2:
+ chip->RamAmountKBytes = 1024 * 4;
+ break;
+ case 1:
+ chip->RamAmountKBytes = 1024 * 2;
+ break;
+ default:
+ chip->RamAmountKBytes = 1024 * 8;
+ break;
+ }
+ }
+ else
+ {
+ chip->RamBandwidthKBytesPerSec = 1000000;
+ chip->RamAmountKBytes = 1024 * 8;
+ }
+ }
+ else
+ {
+ /*
+ * SGRAM 128.
+ */
+ chip->RamBandwidthKBytesPerSec = 1000000;
+ switch (chip->PFB[0x00000000/4] & 0x00000003)
+ {
+ case 0:
+ chip->RamAmountKBytes = 1024 * 8;
+ break;
+ case 2:
+ chip->RamAmountKBytes = 1024 * 4;
+ break;
+ default:
+ chip->RamAmountKBytes = 1024 * 2;
+ break;
+ }
+ }
+ chip->CrystalFreqKHz = (chip->PEXTDEV[0x00000000/4] & 0x00000040) ? 14318 : 13500;
+ chip->CURSOR = &(chip->PRAMIN[0x00008000/4 - 0x0800/4]);
+ chip->VBlankBit = 0x00000100;
+ chip->MaxVClockFreqKHz = 256000;
+ /*
+ * Set chip functions.
+ */
+ chip->Busy = nv3Busy;
+ chip->ShowHideCursor = ShowHideCursor;
+ chip->CalcStateExt = CalcStateExt;
+ chip->LoadStateExt = LoadStateExt;
+ chip->UnloadStateExt = UnloadStateExt;
+ chip->SetStartAddress = SetStartAddress3;
+ chip->LockUnlock = nv3LockUnlock;
+}
+static void nv4GetConfig
+(
+ RIVA_HW_INST *chip
+)
+{
+ /*
+ * Fill in chip configuration.
+ */
+ if (chip->PFB[0x00000000/4] & 0x00000100)
+ {
+ chip->RamAmountKBytes = ((chip->PFB[0x00000000/4] >> 12) & 0x0F) * 1024 * 2
+ + 1024 * 2;
+ }
+ else
+ {
+ switch (chip->PFB[0x00000000/4] & 0x00000003)
+ {
+ case 0:
+ chip->RamAmountKBytes = 1024 * 32;
+ break;
+ case 1:
+ chip->RamAmountKBytes = 1024 * 4;
+ break;
+ case 2:
+ chip->RamAmountKBytes = 1024 * 8;
+ break;
+ case 3:
+ default:
+ chip->RamAmountKBytes = 1024 * 16;
+ break;
+ }
+ }
+ switch ((chip->PFB[0x00000000/4] >> 3) & 0x00000003)
+ {
+ case 3:
+ chip->RamBandwidthKBytesPerSec = 800000;
+ break;
+ default:
+ chip->RamBandwidthKBytesPerSec = 1000000;
+ break;
+ }
+ chip->CrystalFreqKHz = (chip->PEXTDEV[0x00000000/4] & 0x00000040) ? 14318 : 13500;
+ chip->CURSOR = &(chip->PRAMIN[0x00010000/4 - 0x0800/4]);
+ chip->VBlankBit = 0x00000001;
+ chip->MaxVClockFreqKHz = 350000;
+ /*
+ * Set chip functions.
+ */
+ chip->Busy = nv4Busy;
+ chip->ShowHideCursor = ShowHideCursor;
+ chip->CalcStateExt = CalcStateExt;
+ chip->LoadStateExt = LoadStateExt;
+ chip->UnloadStateExt = UnloadStateExt;
+ chip->SetStartAddress = SetStartAddress;
+ chip->LockUnlock = nv4LockUnlock;
+}
+static void nv10GetConfig
+(
+ NVPtr pNv
+)
+{
+ RIVA_HW_INST *chip = &pNv->riva;
+
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ /* turn on big endian register access */
+ if(!(chip->PMC[0x00000004/4] & 0x01000001))
+ chip->PMC[0x00000004/4] = 0x01000001;
+#endif
+
+ /*
+ * Fill in chip configuration.
+ */
+ if((pNv->Chipset && 0xffff) == 0x01a0) {
+ int amt = pciReadLong(pciTag(0, 0, 1), 0x7C);
+
+ chip->RamAmountKBytes = (((amt >> 6) & 31) + 1) * 1024;
+ } else if((pNv->Chipset & 0xffff) == 0x01f0) {
+ int amt = pciReadLong(pciTag(0, 0, 1), 0x84);
+
+ chip->RamAmountKBytes = (((amt >> 4) & 127) + 1) * 1024;
+ } else {
+ switch ((chip->PFB[0x0000020C/4] >> 20) & 0x000000FF)
+ {
+ case 0x02:
+ chip->RamAmountKBytes = 1024 * 2;
+ break;
+ case 0x04:
+ chip->RamAmountKBytes = 1024 * 4;
+ break;
+ case 0x08:
+ chip->RamAmountKBytes = 1024 * 8;
+ break;
+ case 0x10:
+ chip->RamAmountKBytes = 1024 * 16;
+ break;
+ case 0x20:
+ chip->RamAmountKBytes = 1024 * 32;
+ break;
+ case 0x40:
+ chip->RamAmountKBytes = 1024 * 64;
+ break;
+ case 0x80:
+ chip->RamAmountKBytes = 1024 * 128;
+ break;
+ default:
+ chip->RamAmountKBytes = 1024 * 16;
+ break;
+ }
+ }
+ switch ((chip->PFB[0x00000000/4] >> 3) & 0x00000003)
+ {
+ case 3:
+ chip->RamBandwidthKBytesPerSec = 800000;
+ break;
+ default:
+ chip->RamBandwidthKBytesPerSec = 1000000;
+ break;
+ }
+
+ chip->CrystalFreqKHz = (chip->PEXTDEV[0x0000/4] & (1 << 6)) ? 14318 :
+ 13500;
+ switch(pNv->Chipset & 0x0ff0) {
+ case 0x0170:
+ case 0x0180:
+ case 0x01F0:
+ case 0x0250:
+ case 0x0280:
+ case 0x0300:
+ case 0x0310:
+ case 0x0320:
+ case 0x0330:
+ case 0x0340:
+ if(chip->PEXTDEV[0x0000/4] & (1 << 22))
+ chip->CrystalFreqKHz = 27000;
+ break;
+ default:
+ break;
+ }
+
+ chip->CursorStart = (chip->RamAmountKBytes - 128) * 1024;
+ chip->CURSOR = NULL; /* can't set this here */
+ chip->VBlankBit = 0x00000001;
+ chip->MaxVClockFreqKHz = 350000;
+ /*
+ * Set chip functions.
+ */
+ chip->Busy = nv10Busy;
+ chip->ShowHideCursor = ShowHideCursor;
+ chip->CalcStateExt = CalcStateExt;
+ chip->LoadStateExt = LoadStateExt;
+ chip->UnloadStateExt = UnloadStateExt;
+ chip->SetStartAddress = SetStartAddress;
+ chip->LockUnlock = nv4LockUnlock;
+
+ switch(pNv->Chipset & 0x0ff0) {
+ case 0x0110:
+ case 0x0170:
+ case 0x0180:
+ case 0x01F0:
+ case 0x0250:
+ case 0x0280:
+ case 0x0300:
+ case 0x0310:
+ case 0x0320:
+ case 0x0330:
+ case 0x0340:
+ chip->twoHeads = TRUE;
+ break;
+ default:
+ chip->twoHeads = FALSE;
+ break;
+ }
+}
+int RivaGetConfig
+(
+ NVPtr pNv
+)
+{
+ RIVA_HW_INST *chip = &pNv->riva;
+ /*
+ * Save this so future SW know whats it's dealing with.
+ */
+ chip->Version = RIVA_SW_VERSION;
+ /*
+ * Chip specific configuration.
+ */
+ switch (chip->Architecture)
+ {
+ case NV_ARCH_03:
+ nv3GetConfig(chip);
+ break;
+ case NV_ARCH_04:
+ nv4GetConfig(chip);
+ break;
+ case NV_ARCH_10:
+ case NV_ARCH_20:
+ nv10GetConfig(pNv);
+ break;
+ default:
+ return (-1);
+ }
+ chip->Chipset = pNv->Chipset;
+ /*
+ * Fill in FIFO pointers.
+ */
+ chip->Rop = (RivaRop *)&(chip->FIFO[0x00000000/4]);
+ chip->Clip = (RivaClip *)&(chip->FIFO[0x00002000/4]);
+ chip->Patt = (RivaPattern *)&(chip->FIFO[0x00004000/4]);
+ chip->Pixmap = (RivaPixmap *)&(chip->FIFO[0x00006000/4]);
+ chip->Blt = (RivaScreenBlt *)&(chip->FIFO[0x00008000/4]);
+ chip->Bitmap = (RivaBitmap *)&(chip->FIFO[0x0000A000/4]);
+ chip->Line = (RivaLine *)&(chip->FIFO[0x0000C000/4]);
+ return (0);
+}
+
diff --git a/src/riva_hw.h b/src/riva_hw.h
new file mode 100644
index 0000000..8d53d4f
--- /dev/null
+++ b/src/riva_hw.h
@@ -0,0 +1,428 @@
+/***************************************************************************\
+|* *|
+|* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
+|* *|
+|* 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. *|
+|* *|
+|* Any use of this source code must include, in the user documenta- *|
+|* tion and internal comments to the code, notices to the end user *|
+|* as follows: *|
+|* *|
+|* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
+|* *|
+|* 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, CORPOR- *|
+|* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
+|* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
+|* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
+|* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
+|* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
+|* SULTING 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. *|
+|* *|
+|* 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. Govern- *|
+|* ment 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. *|
+|* *|
+\***************************************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_hw.h,v 1.24 2003/02/10 23:42:51 mvojkovi Exp $ */
+#ifndef __RIVA_HW_H__
+#define __RIVA_HW_H__
+#define RIVA_SW_VERSION 0x00010003
+
+/*
+ * Define supported architectures.
+ */
+#define NV_ARCH_03 0x03
+#define NV_ARCH_04 0x04
+#define NV_ARCH_10 0x10
+#define NV_ARCH_20 0x20
+/***************************************************************************\
+* *
+* FIFO registers. *
+* *
+\***************************************************************************/
+
+/*
+ * Raster OPeration. Windows style ROP3.
+ */
+typedef volatile struct
+{
+ U032 reserved00[4];
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ U032 FifoFree;
+#else
+ U016 FifoFree;
+ U016 Nop;
+#endif
+ U032 reserved01[0x0BB];
+ U032 Rop3;
+} RivaRop;
+/*
+ * 8X8 Monochrome pattern.
+ */
+typedef volatile struct
+{
+ U032 reserved00[4];
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ U032 FifoFree;
+#else
+ U016 FifoFree;
+ U016 Nop;
+#endif
+ U032 reserved01[0x0BD];
+ U032 Shape;
+ U032 reserved03[0x001];
+ U032 Color0;
+ U032 Color1;
+ U032 Monochrome[2];
+} RivaPattern;
+/*
+ * Scissor clip rectangle.
+ */
+typedef volatile struct
+{
+ U032 reserved00[4];
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ U032 FifoFree;
+#else
+ U016 FifoFree;
+ U016 Nop;
+#endif
+ U032 reserved01[0x0BB];
+ U032 TopLeft;
+ U032 WidthHeight;
+} RivaClip;
+/*
+ * 2D filled rectangle.
+ */
+typedef volatile struct
+{
+ U032 reserved00[4];
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ U032 FifoFree;
+#else
+ U016 FifoFree;
+ U016 Nop[1];
+#endif
+ U032 reserved01[0x0BC];
+ U032 Color;
+ U032 reserved03[0x03E];
+ U032 TopLeft;
+ U032 WidthHeight;
+} RivaRectangle;
+/*
+ * 2D screen-screen BLT.
+ */
+typedef volatile struct
+{
+ U032 reserved00[4];
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ U032 FifoFree;
+#else
+ U016 FifoFree;
+ U016 Nop;
+#endif
+ U032 reserved01[0x0BB];
+ U032 TopLeftSrc;
+ U032 TopLeftDst;
+ U032 WidthHeight;
+} RivaScreenBlt;
+/*
+ * 2D pixel BLT.
+ */
+typedef volatile struct
+{
+ U032 reserved00[4];
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ U032 FifoFree;
+#else
+ U016 FifoFree;
+ U016 Nop[1];
+#endif
+ U032 reserved01[0x0BC];
+ U032 TopLeft;
+ U032 WidthHeight;
+ U032 WidthHeightIn;
+ U032 reserved02[0x03C];
+ U032 Pixels;
+} RivaPixmap;
+/*
+ * Filled rectangle combined with monochrome expand. Useful for glyphs.
+ */
+typedef volatile struct
+{
+ U032 reserved00[4];
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ U032 FifoFree;
+#else
+ U016 FifoFree;
+ U016 Nop;
+#endif
+ U032 reserved01[0x0BB];
+ U032 reserved03[(0x040)-1];
+ U032 Color1A;
+ struct
+ {
+ U032 TopLeft;
+ U032 WidthHeight;
+ } UnclippedRectangle[64];
+ U032 reserved04[(0x080)-3];
+ struct
+ {
+ U032 TopLeft;
+ U032 BottomRight;
+ } ClipB;
+ U032 Color1B;
+ struct
+ {
+ U032 TopLeft;
+ U032 BottomRight;
+ } ClippedRectangle[64];
+ U032 reserved05[(0x080)-5];
+ struct
+ {
+ U032 TopLeft;
+ U032 BottomRight;
+ } ClipC;
+ U032 Color1C;
+ U032 WidthHeightC;
+ U032 PointC;
+ U032 MonochromeData1C;
+ U032 reserved06[(0x080)+121];
+ struct
+ {
+ U032 TopLeft;
+ U032 BottomRight;
+ } ClipD;
+ U032 Color1D;
+ U032 WidthHeightInD;
+ U032 WidthHeightOutD;
+ U032 PointD;
+ U032 MonochromeData1D;
+ U032 reserved07[(0x080)+120];
+ struct
+ {
+ U032 TopLeft;
+ U032 BottomRight;
+ } ClipE;
+ U032 Color0E;
+ U032 Color1E;
+ U032 WidthHeightInE;
+ U032 WidthHeightOutE;
+ U032 PointE;
+ U032 MonochromeData01E;
+} RivaBitmap;
+/*
+ * 2D line.
+ */
+typedef volatile struct
+{
+ U032 reserved00[4];
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ U032 FifoFree;
+#else
+ U016 FifoFree;
+ U016 Nop[1];
+#endif
+ U032 reserved01[0x0BC];
+ U032 Color; /* source color 0304-0307*/
+ U032 Reserved02[0x03e];
+ struct { /* start aliased methods in array 0400- */
+ U032 point0; /* y_x S16_S16 in pixels 0- 3*/
+ U032 point1; /* y_x S16_S16 in pixels 4- 7*/
+ } Lin[16]; /* end of aliased methods in array -047f*/
+ struct { /* start aliased methods in array 0480- */
+ U032 point0X; /* in pixels, 0 at left 0- 3*/
+ U032 point0Y; /* in pixels, 0 at top 4- 7*/
+ U032 point1X; /* in pixels, 0 at left 8- b*/
+ U032 point1Y; /* in pixels, 0 at top c- f*/
+ } Lin32[8]; /* end of aliased methods in array -04ff*/
+ U032 PolyLin[32]; /* y_x S16_S16 in pixels 0500-057f*/
+ struct { /* start aliased methods in array 0580- */
+ U032 x; /* in pixels, 0 at left 0- 3*/
+ U032 y; /* in pixels, 0 at top 4- 7*/
+ } PolyLin32[16]; /* end of aliased methods in array -05ff*/
+ struct { /* start aliased methods in array 0600- */
+ U032 color; /* source color 0- 3*/
+ U032 point; /* y_x S16_S16 in pixels 4- 7*/
+ } ColorPolyLin[16]; /* end of aliased methods in array -067f*/
+} RivaLine;
+/*
+ * 2D/3D surfaces
+ */
+typedef volatile struct
+{
+ U032 reserved00[4];
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ U032 FifoFree;
+#else
+ U016 FifoFree;
+ U016 Nop;
+#endif
+ U032 reserved01[0x0BE];
+ U032 Offset;
+} RivaSurface;
+typedef volatile struct
+{
+ U032 reserved00[4];
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ U032 FifoFree;
+#else
+ U016 FifoFree;
+ U016 Nop;
+#endif
+ U032 reserved01[0x0BD];
+ U032 Pitch;
+ U032 RenderBufferOffset;
+ U032 ZBufferOffset;
+} RivaSurface3D;
+
+/***************************************************************************\
+* *
+* Virtualized RIVA H/W interface. *
+* *
+\***************************************************************************/
+
+#define FP_ENABLE 1
+#define FP_DITHER 2
+
+struct _riva_hw_inst;
+struct _riva_hw_state;
+/*
+ * Virtialized chip interface. Makes RIVA 128 and TNT look alike.
+ */
+typedef struct _riva_hw_inst
+{
+ /*
+ * Chip specific settings.
+ */
+ U032 Architecture;
+ U032 Version;
+ U032 Chipset;
+ U032 CrystalFreqKHz;
+ U032 RamAmountKBytes;
+ U032 MaxVClockFreqKHz;
+ U032 RamBandwidthKBytesPerSec;
+ U032 EnableIRQ;
+ U032 IO;
+ U032 VBlankBit;
+ U032 FifoFreeCount;
+ U032 FifoEmptyCount;
+ U032 CursorStart;
+ U032 flatPanel;
+ Bool twoHeads;
+ /*
+ * Non-FIFO registers.
+ */
+ volatile U032 *PCRTC0;
+ volatile U032 *PCRTC;
+ volatile U032 *PRAMDAC0;
+ volatile U032 *PFB;
+ volatile U032 *PFIFO;
+ volatile U032 *PGRAPH;
+ volatile U032 *PEXTDEV;
+ volatile U032 *PTIMER;
+ volatile U032 *PMC;
+ volatile U032 *PRAMIN;
+ volatile U032 *FIFO;
+ volatile U032 *CURSOR;
+ volatile U008 *PCIO0;
+ volatile U008 *PCIO;
+ volatile U008 *PVIO;
+ volatile U008 *PDIO0;
+ volatile U008 *PDIO;
+ volatile U032 *PRAMDAC;
+ /*
+ * Common chip functions.
+ */
+ int (*Busy)(struct _riva_hw_inst *);
+ void (*CalcStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *,int,int,int,int,int,int);
+ void (*LoadStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *);
+ void (*UnloadStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *);
+ void (*SetStartAddress)(struct _riva_hw_inst *,U032);
+ int (*ShowHideCursor)(struct _riva_hw_inst *,int);
+ void (*LockUnlock)(struct _riva_hw_inst *, int);
+ /*
+ * Current extended mode settings.
+ */
+ struct _riva_hw_state *CurrentState;
+ /*
+ * FIFO registers.
+ */
+ RivaRop *Rop;
+ RivaPattern *Patt;
+ RivaClip *Clip;
+ RivaPixmap *Pixmap;
+ RivaScreenBlt *Blt;
+ RivaBitmap *Bitmap;
+ RivaLine *Line;
+} RIVA_HW_INST;
+/*
+ * Extended mode state information.
+ */
+typedef struct _riva_hw_state
+{
+ U032 bpp;
+ U032 width;
+ U032 height;
+ U032 interlace;
+ U032 repaint0;
+ U032 repaint1;
+ U032 screen;
+ U032 scale;
+ U032 dither;
+ U032 extra;
+ U032 pixel;
+ U032 horiz;
+ U032 arbitration0;
+ U032 arbitration1;
+ U032 vpll;
+ U032 vpll2;
+ U032 vpllB;
+ U032 vpll2B;
+ U032 pllsel;
+ U032 general;
+ U032 crtcOwner;
+ U032 head;
+ U032 head2;
+ U032 config;
+ U032 cursorConfig;
+ U032 cursor0;
+ U032 cursor1;
+ U032 cursor2;
+ U032 offset;
+ U032 pitch;
+} RIVA_HW_STATE;
+
+/*
+ * FIFO Free Count. Should attempt to yield processor if RIVA is busy.
+ */
+
+#define RIVA_FIFO_FREE(hwinst,hwptr,cnt) \
+{ \
+ while ((hwinst).FifoFreeCount < (cnt)) { \
+ mem_barrier(); \
+ mem_barrier(); \
+ (hwinst).FifoFreeCount = (hwinst).hwptr->FifoFree >> 2; \
+ } \
+ (hwinst).FifoFreeCount -= (cnt); \
+}
+#define RIVA_BUSY(hwinst) \
+{ \
+ mem_barrier(); \
+ while ((hwinst).Busy(&(hwinst))); \
+}
+#endif /* __RIVA_HW_H__ */
+
diff --git a/src/riva_tbl.h b/src/riva_tbl.h
new file mode 100644
index 0000000..bc86c75
--- /dev/null
+++ b/src/riva_tbl.h
@@ -0,0 +1,826 @@
+ /***************************************************************************\
+|* *|
+|* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
+|* *|
+|* 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. *|
+|* *|
+|* Any use of this source code must include, in the user documenta- *|
+|* tion and internal comments to the code, notices to the end user *|
+|* as follows: *|
+|* *|
+|* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
+|* *|
+|* 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, CORPOR- *|
+|* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
+|* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
+|* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
+|* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
+|* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
+|* SULTING 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. *|
+|* *|
+|* 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. Govern- *|
+|* ment 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. *|
+|* *|
+ \***************************************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_tbl.h,v 1.9 2002/01/30 01:35:03 mvojkovi Exp $ */
+
+
+/*
+ * RIVA Fixed Functionality Init Tables.
+ */
+static unsigned RivaTablePMC[][2] =
+{
+ {0x00000050, 0x00000000},
+ {0x00000080, 0xFFFF00FF},
+ {0x00000080, 0xFFFFFFFF}
+};
+static unsigned RivaTablePTIMER[][2] =
+{
+ {0x00000080, 0x00000008},
+ {0x00000084, 0x00000003},
+ {0x00000050, 0x00000000},
+ {0x00000040, 0xFFFFFFFF}
+};
+static unsigned RivaTableFIFO[][2] =
+{
+ {0x00000000, 0x80000000},
+ {0x00000800, 0x80000001},
+ {0x00001000, 0x80000002},
+ {0x00001800, 0x80000010},
+ {0x00002000, 0x80000011},
+ {0x00002800, 0x80000012},
+ {0x00003000, 0x80000016},
+ {0x00003800, 0x80000013}
+};
+static unsigned nv3TablePFIFO[][2] =
+{
+ {0x00000140, 0x00000000},
+ {0x00000480, 0x00000000},
+ {0x00000490, 0x00000000},
+ {0x00000494, 0x00000000},
+ {0x00000481, 0x00000000},
+ {0x00000084, 0x00000000},
+ {0x00000086, 0x00002000},
+ {0x00000085, 0x00002200},
+ {0x00000484, 0x00000000},
+ {0x0000049C, 0x00000000},
+ {0x00000104, 0x00000000},
+ {0x00000108, 0x00000000},
+ {0x00000100, 0x00000000},
+ {0x000004A0, 0x00000000},
+ {0x000004A4, 0x00000000},
+ {0x000004A8, 0x00000000},
+ {0x000004AC, 0x00000000},
+ {0x000004B0, 0x00000000},
+ {0x000004B4, 0x00000000},
+ {0x000004B8, 0x00000000},
+ {0x000004BC, 0x00000000},
+ {0x00000050, 0x00000000},
+ {0x00000040, 0xFFFFFFFF},
+ {0x00000480, 0x00000001},
+ {0x00000490, 0x00000001},
+ {0x00000140, 0x00000001}
+};
+static unsigned nv3TablePGRAPH[][2] =
+{
+ {0x00000020, 0x1230001F},
+ {0x00000021, 0x10113000},
+ {0x00000022, 0x1131F101},
+ {0x00000023, 0x0100F531},
+ {0x00000060, 0x00000000},
+ {0x00000065, 0x00000000},
+ {0x00000068, 0x00000000},
+ {0x00000069, 0x00000000},
+ {0x0000006A, 0x00000000},
+ {0x0000006B, 0x00000000},
+ {0x0000006C, 0x00000000},
+ {0x0000006D, 0x00000000},
+ {0x0000006E, 0x00000000},
+ {0x0000006F, 0x00000000},
+ {0x000001A8, 0x00000000},
+ {0x00000440, 0xFFFFFFFF},
+ {0x00000480, 0x00000001},
+ {0x000001A0, 0x00000000},
+ {0x000001A2, 0x00000000},
+ {0x0000018A, 0xFFFFFFFF},
+ {0x00000190, 0x00000000},
+ {0x00000142, 0x00000000},
+ {0x00000154, 0x00000000},
+ {0x00000155, 0xFFFFFFFF},
+ {0x00000156, 0x00000000},
+ {0x00000157, 0xFFFFFFFF},
+ {0x00000064, 0x10010002},
+ {0x00000050, 0x00000000},
+ {0x00000051, 0x00000000},
+ {0x00000040, 0xFFFFFFFF},
+ {0x00000041, 0xFFFFFFFF},
+ {0x00000440, 0xFFFFFFFF},
+ {0x000001A9, 0x00000001}
+};
+static unsigned nv3TablePGRAPH_8BPP[][2] =
+{
+ {0x000001AA, 0x00001111}
+};
+static unsigned nv3TablePGRAPH_15BPP[][2] =
+{
+ {0x000001AA, 0x00002222}
+};
+static unsigned nv3TablePGRAPH_32BPP[][2] =
+{
+ {0x000001AA, 0x00003333}
+};
+static unsigned nv3TablePRAMIN[][2] =
+{
+ {0x00000500, 0x00010000},
+ {0x00000501, 0x007FFFFF},
+ {0x00000200, 0x80000000},
+ {0x00000201, 0x00C20341},
+ {0x00000204, 0x80000001},
+ {0x00000205, 0x00C50342},
+ {0x00000208, 0x80000002},
+ {0x00000209, 0x00C60343},
+ {0x0000020C, 0x80000003},
+ {0x0000020D, 0x00DC0348},
+ {0x00000210, 0x80000004},
+ {0x00000211, 0x00DC0349},
+ {0x00000214, 0x80000005},
+ {0x00000215, 0x00DC034A},
+ {0x00000218, 0x80000006},
+ {0x00000219, 0x00DC034B},
+ {0x00000240, 0x80000010},
+ {0x00000241, 0x00D10344},
+ {0x00000244, 0x80000011},
+ {0x00000245, 0x00D00345},
+ {0x00000248, 0x80000012},
+ {0x00000249, 0x00CC0346},
+ {0x0000024C, 0x80000013},
+ {0x0000024D, 0x00D70347},
+ {0x00000258, 0x80000016},
+ {0x00000259, 0x00CA034C},
+ {0x00000D05, 0x00000000},
+ {0x00000D06, 0x00000000},
+ {0x00000D07, 0x00000000},
+ {0x00000D09, 0x00000000},
+ {0x00000D0A, 0x00000000},
+ {0x00000D0B, 0x00000000},
+ {0x00000D0D, 0x00000000},
+ {0x00000D0E, 0x00000000},
+ {0x00000D0F, 0x00000000},
+ {0x00000D11, 0x00000000},
+ {0x00000D12, 0x00000000},
+ {0x00000D13, 0x00000000},
+ {0x00000D15, 0x00000000},
+ {0x00000D16, 0x00000000},
+ {0x00000D17, 0x00000000},
+ {0x00000D19, 0x00000000},
+ {0x00000D1A, 0x00000000},
+ {0x00000D1B, 0x00000000},
+ {0x00000D1D, 0x00000140},
+ {0x00000D1E, 0x00000000},
+ {0x00000D1F, 0x00000000},
+ {0x00000D20, 0x10100200},
+ {0x00000D21, 0x00000000},
+ {0x00000D22, 0x00000000},
+ {0x00000D23, 0x00000000},
+ {0x00000D24, 0x10210200},
+ {0x00000D25, 0x00000000},
+ {0x00000D26, 0x00000000},
+ {0x00000D27, 0x00000000},
+ {0x00000D28, 0x10420200},
+ {0x00000D29, 0x00000000},
+ {0x00000D2A, 0x00000000},
+ {0x00000D2B, 0x00000000},
+ {0x00000D2C, 0x10830200},
+ {0x00000D2D, 0x00000000},
+ {0x00000D2E, 0x00000000},
+ {0x00000D2F, 0x00000000},
+ {0x00000D31, 0x00000000},
+ {0x00000D32, 0x00000000},
+ {0x00000D33, 0x00000000}
+};
+static unsigned nv3TablePRAMIN_8BPP[][2] =
+{
+ /* 0xXXXXX3XX For MSB mono format */
+ /* 0xXXXXX2XX For LSB mono format */
+ {0x00000D04, 0x10110203},
+ {0x00000D08, 0x10110203},
+ {0x00000D0C, 0x1011020B},
+ {0x00000D10, 0x10118203},
+ {0x00000D14, 0x10110203},
+ {0x00000D18, 0x10110203},
+ {0x00000D1C, 0x10419208},
+ {0x00000D30, 0x10118203}
+};
+static unsigned nv3TablePRAMIN_15BPP[][2] =
+{
+ /* 0xXXXXX2XX For MSB mono format */
+ /* 0xXXXXX3XX For LSB mono format */
+ {0x00000D04, 0x10110200},
+ {0x00000D08, 0x10110200},
+ {0x00000D0C, 0x10110208},
+ {0x00000D10, 0x10118200},
+ {0x00000D14, 0x10110200},
+ {0x00000D18, 0x10110200},
+ {0x00000D1C, 0x10419208},
+ {0x00000D30, 0x10118200}
+};
+static unsigned nv3TablePRAMIN_32BPP[][2] =
+{
+ /* 0xXXXXX3XX For MSB mono format */
+ /* 0xXXXXX2XX For LSB mono format */
+ {0x00000D04, 0x10110201},
+ {0x00000D08, 0x10110201},
+ {0x00000D0C, 0x10110209},
+ {0x00000D10, 0x10118201},
+ {0x00000D14, 0x10110201},
+ {0x00000D18, 0x10110201},
+ {0x00000D1C, 0x10419208},
+ {0x00000D30, 0x10118201}
+};
+static unsigned nv4TableFIFO[][2] =
+{
+ {0x00003800, 0x80000014}
+};
+static unsigned nv4TablePFIFO[][2] =
+{
+ {0x00000140, 0x00000000},
+ {0x00000480, 0x00000000},
+ {0x00000494, 0x00000000},
+ {0x00000481, 0x00000000},
+ {0x0000048B, 0x00000000},
+ {0x00000400, 0x00000000},
+ {0x00000414, 0x00000000},
+ {0x00000084, 0x03000100},
+ {0x00000085, 0x00000110},
+ {0x00000086, 0x00000112},
+ {0x00000143, 0x0000FFFF},
+ {0x00000496, 0x0000FFFF},
+ {0x00000050, 0x00000000},
+ {0x00000040, 0xFFFFFFFF},
+ {0x00000415, 0x00000001},
+ {0x00000480, 0x00000001},
+ {0x00000494, 0x00000001},
+ {0x00000495, 0x00000001},
+ {0x00000140, 0x00000001}
+};
+static unsigned nv4TablePGRAPH[][2] =
+{
+ {0x00000020, 0x1231C001},
+ {0x00000021, 0x72111101},
+ {0x00000022, 0x11D5F071},
+ {0x00000023, 0x10D4FF31},
+ {0x00000060, 0x00000000},
+ {0x00000068, 0x00000000},
+ {0x00000070, 0x00000000},
+ {0x00000078, 0x00000000},
+ {0x00000061, 0x00000000},
+ {0x00000069, 0x00000000},
+ {0x00000071, 0x00000000},
+ {0x00000079, 0x00000000},
+ {0x00000062, 0x00000000},
+ {0x0000006A, 0x00000000},
+ {0x00000072, 0x00000000},
+ {0x0000007A, 0x00000000},
+ {0x00000063, 0x00000000},
+ {0x0000006B, 0x00000000},
+ {0x00000073, 0x00000000},
+ {0x0000007B, 0x00000000},
+ {0x00000064, 0x00000000},
+ {0x0000006C, 0x00000000},
+ {0x00000074, 0x00000000},
+ {0x0000007C, 0x00000000},
+ {0x00000065, 0x00000000},
+ {0x0000006D, 0x00000000},
+ {0x00000075, 0x00000000},
+ {0x0000007D, 0x00000000},
+ {0x00000066, 0x00000000},
+ {0x0000006E, 0x00000000},
+ {0x00000076, 0x00000000},
+ {0x0000007E, 0x00000000},
+ {0x00000067, 0x00000000},
+ {0x0000006F, 0x00000000},
+ {0x00000077, 0x00000000},
+ {0x0000007F, 0x00000000},
+ {0x00000058, 0x00000000},
+ {0x00000059, 0x00000000},
+ {0x0000005A, 0x00000000},
+ {0x0000005B, 0x00000000},
+ {0x00000196, 0x00000000},
+ {0x000001A1, 0x01FFFFFF},
+ {0x00000197, 0x00000000},
+ {0x000001A2, 0x01FFFFFF},
+ {0x00000198, 0x00000000},
+ {0x000001A3, 0x01FFFFFF},
+ {0x00000199, 0x00000000},
+ {0x000001A4, 0x01FFFFFF},
+ {0x00000050, 0x00000000},
+ {0x00000040, 0xFFFFFFFF},
+ {0x0000005C, 0x10010100},
+ {0x000001C4, 0xFFFFFFFF},
+ {0x000001C8, 0x00000001},
+ {0x00000204, 0x00000000},
+ {0x000001C3, 0x00000001}
+};
+static unsigned nv4TablePGRAPH_8BPP[][2] =
+{
+ {0x000001C9, 0x00111111},
+ {0x00000186, 0x00001010},
+ {0x0000020C, 0x03020202}
+};
+static unsigned nv4TablePGRAPH_15BPP[][2] =
+{
+ {0x000001C9, 0x00226222},
+ {0x00000186, 0x00002071},
+ {0x0000020C, 0x09080808}
+};
+static unsigned nv4TablePGRAPH_16BPP[][2] =
+{
+ {0x000001C9, 0x00556555},
+ {0x00000186, 0x000050C2},
+ {0x0000020C, 0x0C0B0B0B}
+};
+static unsigned nv4TablePGRAPH_32BPP[][2] =
+{
+ {0x000001C9, 0x0077D777},
+ {0x00000186, 0x000070E5},
+ {0x0000020C, 0x0E0D0D0D}
+};
+static unsigned nv4TablePRAMIN[][2] =
+{
+ {0x00000000, 0x80000010},
+ {0x00000001, 0x80011145},
+ {0x00000002, 0x80000011},
+ {0x00000003, 0x80011146},
+ {0x00000004, 0x80000012},
+ {0x00000005, 0x80011147},
+ {0x00000006, 0x80000013},
+ {0x00000007, 0x80011148},
+ {0x00000008, 0x80000014},
+ {0x00000009, 0x80011149},
+ {0x0000000A, 0x80000015},
+ {0x0000000B, 0x8001114A},
+ {0x0000000C, 0x80000016},
+ {0x0000000D, 0x8001114F},
+ {0x00000020, 0x80000000},
+ {0x00000021, 0x80011142},
+ {0x00000022, 0x80000001},
+ {0x00000023, 0x80011143},
+ {0x00000024, 0x80000002},
+ {0x00000025, 0x80011144},
+ {0x00000026, 0x80000003},
+ {0x00000027, 0x8001114B},
+ {0x00000028, 0x80000004},
+ {0x00000029, 0x8001114C},
+ {0x0000002A, 0x80000005},
+ {0x0000002B, 0x8001114D},
+ {0x0000002C, 0x80000006},
+ {0x0000002D, 0x8001114E},
+ {0x00000500, 0x00003000},
+ {0x00000501, 0x01FFFFFF},
+ {0x00000502, 0x00000002},
+ {0x00000503, 0x00000002},
+ {0x00000508, 0x01008043},
+ {0x0000050A, 0x00000000},
+ {0x0000050B, 0x00000000},
+ {0x0000050C, 0x01008019},
+ {0x0000050E, 0x00000000},
+ {0x0000050F, 0x00000000},
+#if 1
+ {0x00000510, 0x01008018},
+#else
+ {0x00000510, 0x01008044},
+#endif
+ {0x00000512, 0x00000000},
+ {0x00000513, 0x00000000},
+ {0x00000514, 0x01008021},
+ {0x00000516, 0x00000000},
+ {0x00000517, 0x00000000},
+ {0x00000518, 0x0100805F},
+ {0x0000051A, 0x00000000},
+ {0x0000051B, 0x00000000},
+#if 1
+ {0x0000051C, 0x0100804B},
+#else
+ {0x0000051C, 0x0100804A},
+#endif
+ {0x0000051E, 0x00000000},
+ {0x0000051F, 0x00000000},
+ {0x00000520, 0x0100A048},
+ {0x00000521, 0x00000D01},
+ {0x00000522, 0x11401140},
+ {0x00000523, 0x00000000},
+ {0x00000524, 0x0300A054},
+ {0x00000525, 0x00000D01},
+ {0x00000526, 0x11401140},
+ {0x00000527, 0x00000000},
+ {0x00000528, 0x0300A055},
+ {0x00000529, 0x00000D01},
+ {0x0000052A, 0x11401140},
+ {0x0000052B, 0x00000000},
+ {0x0000052C, 0x00000058},
+ {0x0000052E, 0x11401140},
+ {0x0000052F, 0x00000000},
+ {0x00000530, 0x00000059},
+ {0x00000532, 0x11401140},
+ {0x00000533, 0x00000000},
+ {0x00000534, 0x0000005A},
+ {0x00000536, 0x11401140},
+ {0x00000537, 0x00000000},
+ {0x00000538, 0x0000005B},
+ {0x0000053A, 0x11401140},
+ {0x0000053B, 0x00000000},
+ {0x0000053C, 0x0300A01C},
+ {0x0000053E, 0x11401140},
+ {0x0000053F, 0x00000000}
+};
+static unsigned nv4TablePRAMIN_8BPP[][2] =
+{
+ /* 0xXXXXXX01 For MSB mono format */
+ /* 0xXXXXXX02 For LSB mono format */
+ {0x00000509, 0x00000302},
+ {0x0000050D, 0x00000302},
+ {0x00000511, 0x00000202},
+ {0x00000515, 0x00000302},
+ {0x00000519, 0x00000302},
+ {0x0000051D, 0x00000302},
+ {0x0000052D, 0x00000302},
+ {0x0000052E, 0x00000302},
+ {0x00000535, 0x00000000},
+ {0x00000539, 0x00000000},
+ {0x0000053D, 0x00000302}
+};
+static unsigned nv4TablePRAMIN_15BPP[][2] =
+{
+ /* 0xXXXXXX01 For MSB mono format */
+ /* 0xXXXXXX02 For LSB mono format */
+ {0x00000509, 0x00000902},
+ {0x0000050D, 0x00000902},
+ {0x00000511, 0x00000802},
+ {0x00000515, 0x00000902},
+ {0x00000519, 0x00000902},
+ {0x0000051D, 0x00000902},
+ {0x0000052D, 0x00000902},
+ {0x0000052E, 0x00000902},
+ {0x00000535, 0x00000702},
+ {0x00000539, 0x00000702},
+ {0x0000053D, 0x00000902}
+};
+static unsigned nv4TablePRAMIN_16BPP[][2] =
+{
+ /* 0xXXXXXX01 For MSB mono format */
+ /* 0xXXXXXX02 For LSB mono format */
+ {0x00000509, 0x00000C02},
+ {0x0000050D, 0x00000C02},
+ {0x00000511, 0x00000B02},
+ {0x00000515, 0x00000C02},
+ {0x00000519, 0x00000C02},
+ {0x0000051D, 0x00000C02},
+ {0x0000052D, 0x00000C02},
+ {0x0000052E, 0x00000C02},
+ {0x00000535, 0x00000702},
+ {0x00000539, 0x00000702},
+ {0x0000053D, 0x00000C02}
+};
+static unsigned nv4TablePRAMIN_32BPP[][2] =
+{
+ /* 0xXXXXXX01 For MSB mono format */
+ /* 0xXXXXXX02 For LSB mono format */
+ {0x00000509, 0x00000E02},
+ {0x0000050D, 0x00000E02},
+ {0x00000511, 0x00000D02},
+ {0x00000515, 0x00000E02},
+ {0x00000519, 0x00000E02},
+ {0x0000051D, 0x00000E02},
+ {0x0000052D, 0x00000E02},
+ {0x0000052E, 0x00000E02},
+ {0x00000535, 0x00000E02},
+ {0x00000539, 0x00000E02},
+ {0x0000053D, 0x00000E02}
+};
+static unsigned nv10TableFIFO[][2] =
+{
+ {0x00003800, 0x80000014}
+};
+static unsigned nv10TablePFIFO[][2] =
+{
+ {0x00000140, 0x00000000},
+ {0x00000480, 0x00000000},
+ {0x00000494, 0x00000000},
+ {0x00000481, 0x00000000},
+ {0x0000048B, 0x00000000},
+ {0x00000400, 0x00000000},
+ {0x00000414, 0x00000000},
+ {0x00000084, 0x03000100},
+ {0x00000085, 0x00000110},
+ {0x00000086, 0x00000112},
+ {0x00000143, 0x0000FFFF},
+ {0x00000496, 0x0000FFFF},
+ {0x00000050, 0x00000000},
+ {0x00000040, 0xFFFFFFFF},
+ {0x00000415, 0x00000001},
+ {0x00000480, 0x00000001},
+ {0x00000494, 0x00000001},
+ {0x00000495, 0x00000001},
+ {0x00000140, 0x00000001}
+};
+static unsigned nv10TablePGRAPH[][2] =
+{
+ {0x00000020, 0x0003FFFF},
+ {0x00000021, 0x00118701},
+ {0x00000022, 0x24F82AD9},
+ {0x00000023, 0x55DE0030},
+ {0x00000020, 0x00000000},
+ {0x00000024, 0x00000000},
+ {0x00000058, 0x00000000},
+ {0x00000060, 0x00000000},
+ {0x00000068, 0x00000000},
+ {0x00000070, 0x00000000},
+ {0x00000078, 0x00000000},
+ {0x00000059, 0x00000000},
+ {0x00000061, 0x00000000},
+ {0x00000069, 0x00000000},
+ {0x00000071, 0x00000000},
+ {0x00000079, 0x00000000},
+ {0x0000005A, 0x00000000},
+ {0x00000062, 0x00000000},
+ {0x0000006A, 0x00000000},
+ {0x00000072, 0x00000000},
+ {0x0000007A, 0x00000000},
+ {0x0000005B, 0x00000000},
+ {0x00000063, 0x00000000},
+ {0x0000006B, 0x00000000},
+ {0x00000073, 0x00000000},
+ {0x0000007B, 0x00000000},
+ {0x0000005C, 0x00000000},
+ {0x00000064, 0x00000000},
+ {0x0000006C, 0x00000000},
+ {0x00000074, 0x00000000},
+ {0x0000007C, 0x00000000},
+ {0x0000005D, 0x00000000},
+ {0x00000065, 0x00000000},
+ {0x0000006D, 0x00000000},
+ {0x00000075, 0x00000000},
+ {0x0000007D, 0x00000000},
+ {0x0000005E, 0x00000000},
+ {0x00000066, 0x00000000},
+ {0x0000006E, 0x00000000},
+ {0x00000076, 0x00000000},
+ {0x0000007E, 0x00000000},
+ {0x0000005F, 0x00000000},
+ {0x00000067, 0x00000000},
+ {0x0000006F, 0x00000000},
+ {0x00000077, 0x00000000},
+ {0x0000007F, 0x00000000},
+ {0x00000053, 0x00000000},
+ {0x00000054, 0x00000000},
+ {0x00000055, 0x00000000},
+ {0x00000056, 0x00000000},
+ {0x00000057, 0x00000000},
+ {0x00000196, 0x00000000},
+ {0x000001A1, 0x01FFFFFF},
+ {0x00000197, 0x00000000},
+ {0x000001A2, 0x01FFFFFF},
+ {0x00000198, 0x00000000},
+ {0x000001A3, 0x01FFFFFF},
+ {0x00000199, 0x00000000},
+ {0x000001A4, 0x01FFFFFF},
+ {0x0000019A, 0x00000000},
+ {0x000001A5, 0x01FFFFFF},
+ {0x0000019B, 0x00000000},
+ {0x000001A6, 0x01FFFFFF},
+ {0x00000050, 0x01111111},
+ {0x00000040, 0xFFFFFFFF},
+ {0x00000051, 0x10010100},
+ {0x000001C5, 0xFFFFFFFF},
+ {0x000001C8, 0x00000001},
+ {0x00000204, 0x00000000},
+ {0x000001C4, 0x00000001}
+};
+static unsigned nv10TablePGRAPH_8BPP[][2] =
+{
+ {0x000001C9, 0x00111111},
+ {0x00000186, 0x00001010},
+ {0x0000020C, 0x03020202}
+};
+static unsigned nv10TablePGRAPH_15BPP[][2] =
+{
+ {0x000001C9, 0x00226222},
+ {0x00000186, 0x00002071},
+ {0x0000020C, 0x09080808}
+};
+static unsigned nv10TablePGRAPH_16BPP[][2] =
+{
+ {0x000001C9, 0x00556555},
+ {0x00000186, 0x000050C2},
+ {0x0000020C, 0x000B0B0C}
+};
+static unsigned nv10TablePGRAPH_32BPP[][2] =
+{
+ {0x000001C9, 0x0077D777},
+ {0x00000186, 0x000070E5},
+ {0x0000020C, 0x0E0D0D0D}
+};
+static unsigned nv10TablePRAMIN[][2] =
+{
+ {0x00000000, 0x80000010},
+ {0x00000001, 0x80011145},
+ {0x00000002, 0x80000011},
+ {0x00000003, 0x80011146},
+ {0x00000004, 0x80000012},
+ {0x00000005, 0x80011147},
+ {0x00000006, 0x80000013},
+ {0x00000007, 0x80011148},
+ {0x00000008, 0x80000014},
+ {0x00000009, 0x80011149},
+ {0x0000000A, 0x80000015},
+ {0x0000000B, 0x8001114A},
+ {0x0000000C, 0x80000016},
+ {0x0000000D, 0x80011150},
+ {0x00000020, 0x80000000},
+ {0x00000021, 0x80011142},
+ {0x00000022, 0x80000001},
+ {0x00000023, 0x80011143},
+ {0x00000024, 0x80000002},
+ {0x00000025, 0x80011144},
+ {0x00000026, 0x80000003},
+ {0x00000027, 0x8001114B},
+ {0x00000028, 0x80000004},
+ {0x00000029, 0x8001114C},
+ {0x0000002A, 0x80000005},
+ {0x0000002B, 0x8001114D},
+ {0x0000002C, 0x80000006},
+ {0x0000002D, 0x8001114E},
+ {0x0000002E, 0x80000007},
+ {0x0000002F, 0x8001114F},
+ {0x00000500, 0x00003000},
+ {0x00000501, 0x01FFFFFF},
+ {0x00000502, 0x00000002},
+ {0x00000503, 0x00000002},
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ {0x00000508, 0x01088043},
+#else
+ {0x00000508, 0x01008043},
+#endif
+ {0x0000050A, 0x00000000},
+ {0x0000050B, 0x00000000},
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ {0x0000050C, 0x01088019},
+#else
+ {0x0000050C, 0x01008019},
+#endif
+ {0x0000050E, 0x00000000},
+ {0x0000050F, 0x00000000},
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ {0x00000510, 0x01088018},
+#else
+ {0x00000510, 0x01008018},
+#endif
+ {0x00000512, 0x00000000},
+ {0x00000513, 0x00000000},
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ {0x00000514, 0x01088021},
+#else
+ {0x00000514, 0x01008021},
+#endif
+ {0x00000516, 0x00000000},
+ {0x00000517, 0x00000000},
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ {0x00000518, 0x0108805F},
+#else
+ {0x00000518, 0x0100805F},
+#endif
+ {0x0000051A, 0x00000000},
+ {0x0000051B, 0x00000000},
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ {0x0000051C, 0x0108804B},
+#else
+ {0x0000051C, 0x0100804B},
+#endif
+ {0x0000051E, 0x00000000},
+ {0x0000051F, 0x00000000},
+ {0x00000520, 0x0100A048},
+ {0x00000521, 0x00000D01},
+ {0x00000522, 0x11401140},
+ {0x00000523, 0x00000000},
+ {0x00000524, 0x0300A094},
+ {0x00000525, 0x00000D01},
+ {0x00000526, 0x11401140},
+ {0x00000527, 0x00000000},
+ {0x00000528, 0x0300A095},
+ {0x00000529, 0x00000D01},
+ {0x0000052A, 0x11401140},
+ {0x0000052B, 0x00000000},
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ {0x0000052C, 0x00080058},
+#else
+ {0x0000052C, 0x00000058},
+#endif
+ {0x0000052E, 0x11401140},
+ {0x0000052F, 0x00000000},
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ {0x00000530, 0x00080059},
+#else
+ {0x00000530, 0x00000059},
+#endif
+ {0x00000532, 0x11401140},
+ {0x00000533, 0x00000000},
+ {0x00000534, 0x0000005A},
+ {0x00000536, 0x11401140},
+ {0x00000537, 0x00000000},
+ {0x00000538, 0x0000005B},
+ {0x0000053A, 0x11401140},
+ {0x0000053B, 0x00000000},
+ {0x0000053C, 0x00000093},
+ {0x0000053E, 0x11401140},
+ {0x0000053F, 0x00000000},
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ {0x00000540, 0x0308A01C},
+#else
+ {0x00000540, 0x0300A01C},
+#endif
+ {0x00000542, 0x11401140},
+ {0x00000543, 0x00000000}
+};
+static unsigned nv10TablePRAMIN_8BPP[][2] =
+{
+ /* 0xXXXXXX01 For MSB mono format */
+ /* 0xXXXXXX02 For LSB mono format */
+ {0x00000509, 0x00000302},
+ {0x0000050D, 0x00000302},
+ {0x00000511, 0x00000202},
+ {0x00000515, 0x00000302},
+ {0x00000519, 0x00000302},
+ {0x0000051D, 0x00000302},
+ {0x0000052D, 0x00000302},
+ {0x0000052E, 0x00000302},
+ {0x00000535, 0x00000000},
+ {0x00000539, 0x00000000},
+ {0x0000053D, 0x00000000},
+ {0x00000541, 0x00000302}
+};
+static unsigned nv10TablePRAMIN_15BPP[][2] =
+{
+ /* 0xXXXXXX01 For MSB mono format */
+ /* 0xXXXXXX02 For LSB mono format */
+ {0x00000509, 0x00000902},
+ {0x0000050D, 0x00000902},
+ {0x00000511, 0x00000802},
+ {0x00000515, 0x00000902},
+ {0x00000519, 0x00000902},
+ {0x0000051D, 0x00000902},
+ {0x0000052D, 0x00000902},
+ {0x0000052E, 0x00000902},
+ {0x00000535, 0x00000902},
+ {0x00000539, 0x00000902},
+ {0x0000053D, 0x00000902},
+ {0x00000541, 0x00000902}
+};
+static unsigned nv10TablePRAMIN_16BPP[][2] =
+{
+ /* 0xXXXXXX01 For MSB mono format */
+ /* 0xXXXXXX02 For LSB mono format */
+ {0x00000509, 0x00000C02},
+ {0x0000050D, 0x00000C02},
+ {0x00000511, 0x00000B02},
+ {0x00000515, 0x00000C02},
+ {0x00000519, 0x00000C02},
+ {0x0000051D, 0x00000C02},
+ {0x0000052D, 0x00000C02},
+ {0x0000052E, 0x00000C02},
+ {0x00000535, 0x00000C02},
+ {0x00000539, 0x00000C02},
+ {0x0000053D, 0x00000C02},
+ {0x00000541, 0x00000C02}
+};
+static unsigned nv10TablePRAMIN_32BPP[][2] =
+{
+ /* 0xXXXXXX01 For MSB mono format */
+ /* 0xXXXXXX02 For LSB mono format */
+ {0x00000509, 0x00000E02},
+ {0x0000050D, 0x00000E02},
+ {0x00000511, 0x00000D02},
+ {0x00000515, 0x00000E02},
+ {0x00000519, 0x00000E02},
+ {0x0000051D, 0x00000E02},
+ {0x0000052D, 0x00000E02},
+ {0x0000052E, 0x00000E02},
+ {0x00000535, 0x00000E02},
+ {0x00000539, 0x00000E02},
+ {0x0000053D, 0x00000E02},
+ {0x00000541, 0x00000E02}
+};
+