summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaleb Keithley <kaleb@freedesktop.org>2003-11-17 19:03:45 +0000
committerKaleb Keithley <kaleb@freedesktop.org>2003-11-17 19:03:45 +0000
commit6962e55a393c6b1cddf6b23f9c39842234b4ef7d (patch)
tree0801ca9d58e7c2950cad719ab400d852f10f4212
parent2f223903fba2bdee1623f3442d7580c809b428cc (diff)
merge XFree86 4.3.0.1 to -CURRENT
-rw-r--r--README.NV1206
-rw-r--r--src/nv_dma.h180
-rw-r--r--src/nv_hw.c1257
-rw-r--r--src/riva_const.h14
-rw-r--r--src/riva_cursor.c165
-rw-r--r--src/riva_dac.c280
-rw-r--r--src/riva_dga.c305
-rw-r--r--src/riva_driver.c1384
-rw-r--r--src/riva_include.h59
-rw-r--r--src/riva_local.h74
-rw-r--r--src/riva_proto.h41
-rw-r--r--src/riva_setup.c279
-rw-r--r--src/riva_shadow.c194
-rw-r--r--src/riva_type.h122
-rw-r--r--src/riva_xaa.c554
15 files changed, 4932 insertions, 182 deletions
diff --git a/README.NV1 b/README.NV1
index 28488f2..47bc437 100644
--- a/README.NV1
+++ b/README.NV1
@@ -1,200 +1,42 @@
+ Information for NVidia NV1 / SGS-Thomson STG2000 Users
+ David McKay
+ 20th March 1997
+1. XFree driver for NVidia NV1 / SGS-Thomson STG2000 v1.0
-
-
-
-
-
- Information for NVidia NV1 / SGS-Thomson STG2000 and Riva128 Users
-
- David McKay, Dirk Hohndel
-
- 26 February 1998
-
-
-
-1. XFree86 driver for NVidia NV1 / SGS-Thomson STG2000 and Riva128
-
-This driver supports good acceleration for both the NV1/STG2000 as well as the
-Riva128. It is known to work on PCI and AGP versions of the Riva128.
+This driver now accelerates bitblits and filled rectangles. It also support a
+hardware cursor. More graphic acceleration is planned. There is no plan to
+support the audio functionality of the chip.
1.1 Notes
- o On the NV1/STG2000, the driver does not support the virtual desktop fea-
- tures of xfree86. This is because the NV1 does not have the necessary
- hardware to support this feature. If you want to change resolutions, you
- will have to modify your config file. Comment out all but the mode you
- wish to use.
+ o THE DRIVER DOES NOT SUPPORT THE VIRTUAL DESKTOP FEATURES OF XFREE86 This
+ is because the NV1 does not have the necessary hardware to support this
+ feature. If you want to change resolutions, you will have to modify your
+ config file. Comment out all but the mode you wish to use.
o The generic VGA16 server will not work with the NV1. For this reason
- XF86Setup cannot be used to configure the server. Use xf86config instead.
- Select `Diamond Edge 3D' as your board, and select only ONE mode for each
- of 8bpp and 16bpp. Do not select a virtual desktop. Also, make sure you
- don't select a RAMDAC or clock chip. This does not apply if you own a
- Riva128 card, as the VGA16 server works just fine on that.
-
- o Both the NV1 and the Riva128 only support a 555 RGB Weight in 16 bpp, the
- hardware does not do 565. If you run into problems with some window man-
- agers in 16bpp, try putting a Weight 555 in the Display section.
-
- o 24 bpp is not supported.
-
- o In some modes the hardware cursor gets out of sync with the display. Use
- Option "sw_cursor" to work around this problem.
-
- o There are modelines that confuse the Riva128 chip. This results in a
- greenish display. Slightly modifying the modeline usually fixes the prob-
- lem. In most cases all that is needed is to reduce the HTotal. You can use
- xvidtune to do that.
-
- o The dotclock limits for this driver seem to be lower than the hardware
- specs (and drivers for other graphical user interfaces) seem to indicate.
- If you get a flickery screen with flashes, try to limit the modes you use
- to about 160MHz in 16bpp and about 100MHz in 32bpp.
-
- Generated from XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/NV1.sgml,v 3.2.2.3 1998/02/26 20:11:27 hohndel Exp $
-
-
-
-
-
-
-Information for NVidia NV1 / SGS-Thomson STG2000 and Riva128 Users
-
-
-
-
-
-Information for NVidia NV1 / SGS-Thomson STG2000 and Riva128 Users
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- CONTENTS
-
-
-
-1. XFree86 driver for NVidia NV1 / SGS-Thomson STG2000 and Riva128 .......... 1
- 1.1 Notes ................................................................ 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ XF86Setup cannot be used to configure the server. Use xf86config
+ instead. Select `Diamond Edge 3D' as your board, and select only ONE
+ mode for each of 8bpp and 16bpp. Do not select a virtual desktop.
+ Also, make sure you don't select a RAMDAC or clock chip.
+ o The NV1 only supports a 555 RGB Weight in 16 bpp, the hardware does not
+ do 565. You must put a Weight 555 in the Display section.
+ o 24/32 bpp mode is not yet supported.
+1.2 Known Bugs
+ o The driver should force Weight 555 in 16 bpp mode
+ o The hardware cursor doesn't work if an doublescan mode is selected.
- i
+ o Screen blanking doesn't work, nor does DPMS.
+ Generated from XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/NV1.sgml,v 3.3 1997/03/22 09:35:30 hohndel Exp $
-$XFree86: xc/programs/Xserver/hw/xfree86/doc/README.NV1,v 3.5.2.3 1998/02/27 02:54:59 dawes Exp $
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/README.NV1,v 3.7 1999/04/15 03:34:51 dawes Exp $
diff --git a/src/nv_dma.h b/src/nv_dma.h
new file mode 100644
index 0000000..6506068
--- /dev/null
+++ b/src/nv_dma.h
@@ -0,0 +1,180 @@
+
+ /***************************************************************************\
+|* *|
+|* Copyright 2003 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 2003 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_dma.h,v 1.2 2003/07/31 21:41:26 mvojkovi Exp $ */
+
+#define SURFACE_FORMAT 0x00000300
+#define SURFACE_FORMAT_DEPTH8 0x00000001
+#define SURFACE_FORMAT_DEPTH15 0x00000002
+#define SURFACE_FORMAT_DEPTH16 0x00000004
+#define SURFACE_FORMAT_DEPTH24 0x00000006
+#define SURFACE_PITCH 0x00000304
+#define SURFACE_PITCH_SRC 15:0
+#define SURFACE_PITCH_DST 31:16
+#define SURFACE_OFFSET_SRC 0x00000308
+#define SURFACE_OFFSET_DST 0x0000030C
+
+#define ROP_SET 0x00002300
+
+#define PATTERN_FORMAT 0x00004300
+#define PATTERN_FORMAT_DEPTH8 0x00000003
+#define PATTERN_FORMAT_DEPTH16 0x00000001
+#define PATTERN_FORMAT_DEPTH24 0x00000003
+#define PATTERN_COLOR_0 0x00004310
+#define PATTERN_COLOR_1 0x00004314
+#define PATTERN_PATTERN_0 0x00004318
+#define PATTERN_PATTERN_1 0x0000431C
+
+#define CLIP_POINT 0x00006300
+#define CLIP_POINT_X 15:0
+#define CLIP_POINT_Y 31:16
+#define CLIP_SIZE 0x00006304
+#define CLIP_SIZE_WIDTH 15:0
+#define CLIP_SIZE_HEIGHT 31:16
+
+#define LINE_FORMAT 0x00008300
+#define LINE_FORMAT_DEPTH8 0x00000003
+#define LINE_FORMAT_DEPTH16 0x00000001
+#define LINE_FORMAT_DEPTH24 0x00000003
+#define LINE_COLOR 0x00008304
+#define LINE_MAX_LINES 16
+#define LINE_LINES(i) 0x00008400\
+ +(i)*8
+#define LINE_LINES_POINT0_X 15:0
+#define LINE_LINES_POINT0_Y 31:16
+#define LINE_LINES_POINT1_X 47:32
+#define LINE_LINES_POINT1_Y 63:48
+
+#define BLIT_POINT_SRC 0x0000A300
+#define BLIT_POINT_SRC_X 15:0
+#define BLIT_POINT_SRC_Y 31:16
+#define BLIT_POINT_DST 0x0000A304
+#define BLIT_POINT_DST_X 15:0
+#define BLIT_POINT_DST_Y 31:16
+#define BLIT_SIZE 0x0000A308
+#define BLIT_SIZE_WIDTH 15:0
+#define BLIT_SIZE_HEIGHT 31:16
+
+#define RECT_FORMAT 0x0000C300
+#define RECT_FORMAT_DEPTH8 0x00000003
+#define RECT_FORMAT_DEPTH16 0x00000001
+#define RECT_FORMAT_DEPTH24 0x00000003
+#define RECT_SOLID_COLOR 0x0000C3FC
+#define RECT_SOLID_RECTS_MAX_RECTS 32
+#define RECT_SOLID_RECTS(i) 0x0000C400\
+ +(i)*8
+#define RECT_SOLID_RECTS_Y 15:0
+#define RECT_SOLID_RECTS_X 31:16
+#define RECT_SOLID_RECTS_HEIGHT 47:32
+#define RECT_SOLID_RECTS_WIDTH 63:48
+
+#define RECT_EXPAND_ONE_COLOR_CLIP 0x0000C7EC
+#define RECT_EXPAND_ONE_COLOR_CLIP_POINT0_X 15:0
+#define RECT_EXPAND_ONE_COLOR_CLIP_POINT0_Y 31:16
+#define RECT_EXPAND_ONE_COLOR_CLIP_POINT1_X 47:32
+#define RECT_EXPAND_ONE_COLOR_CLIP_POINT1_Y 63:48
+#define RECT_EXPAND_ONE_COLOR_COLOR 0x0000C7F4
+#define RECT_EXPAND_ONE_COLOR_SIZE 0x0000C7F8
+#define RECT_EXPAND_ONE_COLOR_SIZE_WIDTH 15:0
+#define RECT_EXPAND_ONE_COLOR_SIZE_HEIGHT 31:16
+#define RECT_EXPAND_ONE_COLOR_POINT 0x0000C7FC
+#define RECT_EXPAND_ONE_COLOR_POINT_X 15:0
+#define RECT_EXPAND_ONE_COLOR_POINT_Y 31:16
+#define RECT_EXPAND_ONE_COLOR_DATA_MAX_DWORDS 128
+#define RECT_EXPAND_ONE_COLOR_DATA(i) 0x0000C800\
+ +(i)*4
+
+#define RECT_EXPAND_TWO_COLOR_CLIP 0x0000CBE4
+#define RECT_EXPAND_TWO_COLOR_CLIP_POINT0_X 15:0
+#define RECT_EXPAND_TWO_COLOR_CLIP_POINT0_Y 31:16
+#define RECT_EXPAND_TWO_COLOR_CLIP_POINT1_X 47:32
+#define RECT_EXPAND_TWO_COLOR_CLIP_POINT1_Y 63:48
+#define RECT_EXPAND_TWO_COLOR_COLOR_0 0x0000CBEC
+#define RECT_EXPAND_TWO_COLOR_COLOR_1 0x0000CBF0
+#define RECT_EXPAND_TWO_COLOR_SIZE_IN 0x0000CBF4
+#define RECT_EXPAND_TWO_COLOR_SIZE_IN_WIDTH 15:0
+#define RECT_EXPAND_TWO_COLOR_SIZE_IN_HEIGHT 31:16
+#define RECT_EXPAND_TWO_COLOR_SIZE_OUT 0x0000CBF8
+#define RECT_EXPAND_TWO_COLOR_SIZE_OUT_WIDTH 15:0
+#define RECT_EXPAND_TWO_COLOR_SIZE_OUT_HEIGHT 31:16
+#define RECT_EXPAND_TWO_COLOR_POINT 0x0000CBFC
+#define RECT_EXPAND_TWO_COLOR_POINT_X 15:0
+#define RECT_EXPAND_TWO_COLOR_POINT_Y 31:16
+#define RECT_EXPAND_TWO_COLOR_DATA_MAX_DWORDS 128
+#define RECT_EXPAND_TWO_COLOR_DATA(i) 0x0000CC00\
+ +(i)*4
+
+#define STRETCH_BLIT_FORMAT 0x0000E300
+#define STRETCH_BLIT_FORMAT_DEPTH8 0x00000004
+#define STRETCH_BLIT_FORMAT_DEPTH16 0x00000007
+#define STRETCH_BLIT_FORMAT_DEPTH24 0x00000004
+#define STRETCH_BLIT_FORMAT_X8R8G8B8 0x00000004
+#define STRETCH_BLIT_FORMAT_YUYV 0x00000005
+#define STRETCH_BLIT_FORMAT_UYVY 0x00000006
+#define STRETCH_BLIT_CLIP_POINT 0x0000E308
+#define STRETCH_BLIT_CLIP_POINT_X 15:0
+#define STRETCH_BLIT_CLIP_POINT_Y 31:16
+#define STRETCH_BLIT_CLIP_POINT 0x0000E308
+#define STRETCH_BLIT_CLIP_SIZE 0x0000E30C
+#define STRETCH_BLIT_CLIP_SIZE_WIDTH 15:0
+#define STRETCH_BLIT_CLIP_SIZE_HEIGHT 31:16
+#define STRETCH_BLIT_DST_POINT 0x0000E310
+#define STRETCH_BLIT_DST_POINT_X 15:0
+#define STRETCH_BLIT_DST_POINT_Y 31:16
+#define STRETCH_BLIT_DST_SIZE 0x0000E314
+#define STRETCH_BLIT_DST_SIZE_WIDTH 15:0
+#define STRETCH_BLIT_DST_SIZE_HEIGHT 31:16
+#define STRETCH_BLIT_DU_DX 0x0000E318
+#define STRETCH_BLIT_DV_DY 0x0000E31C
+#define STRETCH_BLIT_SRC_SIZE 0x0000E400
+#define STRETCH_BLIT_SRC_SIZE_WIDTH 15:0
+#define STRETCH_BLIT_SRC_SIZE_HEIGHT 31:16
+#define STRETCH_BLIT_SRC_FORMAT 0x0000E404
+#define STRETCH_BLIT_SRC_FORMAT_PITCH 15:0
+#define STRETCH_BLIT_SRC_FORMAT_ORIGIN 23:16
+#define STRETCH_BLIT_SRC_FORMAT_ORIGIN_CENTER 0x00000001
+#define STRETCH_BLIT_SRC_FORMAT_ORIGIN_CORNER 0x00000002
+#define STRETCH_BLIT_SRC_FORMAT_FILTER 31:24
+#define STRETCH_BLIT_SRC_FORMAT_FILTER_POINT_SAMPLE 0x00000000
+#define STRETCH_BLIT_SRC_FORMAT_FILTER_BILINEAR 0x00000001
+#define STRETCH_BLIT_SRC_OFFSET 0x0000E408
+#define STRETCH_BLIT_SRC_POINT 0x0000E40C
+#define STRETCH_BLIT_SRC_POINT_U 15:0
+#define STRETCH_BLIT_SRC_POINT_V 31:16
diff --git a/src/nv_hw.c b/src/nv_hw.c
new file mode 100644
index 0000000..b5bb015
--- /dev/null
+++ b/src/nv_hw.c
@@ -0,0 +1,1257 @@
+ /***************************************************************************\
+|* *|
+|* Copyright 1993-2003 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-2003 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_hw.c,v 1.4 2003/11/03 05:11:25 tsi Exp $ */
+
+#include "nv_local.h"
+#include "compiler.h"
+#include "nv_include.h"
+
+
+void NVLockUnlock (
+ NVPtr pNv,
+ Bool Lock
+)
+{
+ CARD8 cr11;
+
+ VGA_WR08(pNv->PCIO, 0x3D4, 0x1F);
+ VGA_WR08(pNv->PCIO, 0x3D5, Lock ? 0x99 : 0x57);
+
+ VGA_WR08(pNv->PCIO, 0x3D4, 0x11);
+ cr11 = VGA_RD08(pNv->PCIO, 0x3D5);
+ if(Lock) cr11 |= 0x80;
+ else cr11 &= ~0x80;
+ VGA_WR08(pNv->PCIO, 0x3D5, cr11);
+}
+
+int NVShowHideCursor (
+ NVPtr pNv,
+ int ShowHide
+)
+{
+ int current = pNv->CurrentState->cursor1;
+
+ pNv->CurrentState->cursor1 = (pNv->CurrentState->cursor1 & 0xFE) |
+ (ShowHide & 0x01);
+ VGA_WR08(pNv->PCIO, 0x3D4, 0x31);
+ VGA_WR08(pNv->PCIO, 0x3D5, pNv->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). *
+* *
+\****************************************************************************/
+
+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 void nvGetClocks(NVPtr pNv, unsigned int *MClk, unsigned int *NVClk)
+{
+ unsigned int pll, N, M, MB, NB, P;
+
+ if(pNv->twoStagePLL) {
+ pll = pNv->PRAMDAC0[0x0504/4];
+ M = pll & 0xFF;
+ N = (pll >> 8) & 0xFF;
+ P = (pll >> 16) & 0x0F;
+ pll = pNv->PRAMDAC0[0x0574/4];
+ if(pll & 0x80000000) {
+ MB = pll & 0xFF;
+ NB = (pll >> 8) & 0xFF;
+ } else {
+ MB = 1;
+ NB = 1;
+ }
+ *MClk = ((N * NB * pNv->CrystalFreqKHz) / (M * MB)) >> P;
+
+ pll = pNv->PRAMDAC0[0x0500/4];
+ M = pll & 0xFF;
+ N = (pll >> 8) & 0xFF;
+ P = (pll >> 16) & 0x0F;
+ pll = pNv->PRAMDAC0[0x0570/4];
+ if(pll & 0x80000000) {
+ MB = pll & 0xFF;
+ NB = (pll >> 8) & 0xFF;
+ } else {
+ MB = 1;
+ NB = 1;
+ }
+ *NVClk = ((N * NB * pNv->CrystalFreqKHz) / (M * MB)) >> P;
+ } else
+ if(((pNv->Chipset & 0x0ff0) == 0x0300) ||
+ ((pNv->Chipset & 0x0ff0) == 0x0330))
+ {
+ pll = pNv->PRAMDAC0[0x0504/4];
+ M = pll & 0x0F;
+ N = (pll >> 8) & 0xFF;
+ P = (pll >> 16) & 0x07;
+ if(pll & 0x00000080) {
+ MB = (pll >> 4) & 0x07;
+ NB = (pll >> 19) & 0x1f;
+ } else {
+ MB = 1;
+ NB = 1;
+ }
+ *MClk = ((N * NB * pNv->CrystalFreqKHz) / (M * MB)) >> P;
+
+ pll = pNv->PRAMDAC0[0x0500/4];
+ M = pll & 0x0F;
+ N = (pll >> 8) & 0xFF;
+ P = (pll >> 16) & 0x07;
+ if(pll & 0x00000080) {
+ MB = (pll >> 4) & 0x07;
+ NB = (pll >> 19) & 0x1f;
+ } else {
+ MB = 1;
+ NB = 1;
+ }
+ *NVClk = ((N * NB * pNv->CrystalFreqKHz) / (M * MB)) >> P;
+ } else {
+ pll = pNv->PRAMDAC0[0x0504/4];
+ M = pll & 0xFF;
+ N = (pll >> 8) & 0xFF;
+ P = (pll >> 16) & 0x0F;
+ *MClk = (N * pNv->CrystalFreqKHz / M) >> P;
+
+ pll = pNv->PRAMDAC0[0x0500/4];
+ M = pll & 0xFF;
+ N = (pll >> 8) & 0xFF;
+ P = (pll >> 16) & 0x0F;
+ *NVClk = (N * pNv->CrystalFreqKHz / M) >> P;
+ }
+}
+
+
+static void nv4CalcArbitration (
+ nv4_fifo_info *fifo,
+ nv4_sim_state *arb
+)
+{
+ int data, pagemiss, cas,width, video_enable, bpp;
+ 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;
+
+ 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;
+ bpp = arb->pix_bpp;
+ 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--;
+ }
+ }
+ 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,
+ NVPtr pNv
+)
+{
+ nv4_fifo_info fifo_data;
+ nv4_sim_state sim_data;
+ unsigned int MClk, NVClk, cfg1;
+
+ nvGetClocks(pNv, &MClk, &NVClk);
+
+ cfg1 = pNv->PFB[0x00000204/4];
+ sim_data.pix_bpp = (char)pixelDepth;
+ sim_data.enable_video = 0;
+ sim_data.enable_mp = 0;
+ sim_data.memory_width = (pNv->PEXTDEV[0x0000/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, width, video_enable, bpp;
+ int nvclks, mclks, pclks, vpagemiss, crtpagemiss;
+ int nvclk_fill;
+ 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, crtc_drain_rate;
+ int vus_m;
+ int vpm_us, us_video, cpm_us, us_crt,clwm;
+ int clwm_rnd_down;
+ int m2us, us_pipe_min, p1clk, p2;
+ int 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;
+ width = arb->memory_width/64;
+ video_enable = arb->enable_video;
+ bpp = arb->pix_bpp;
+ mp_enable = arb->enable_mp;
+ clwm = 0;
+
+ cbs = 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_min = us_m_min + us_n + us_p;
+
+ vus_m = mclk_loop *1000*1000 / mclk_freq; /* Mclk latency in us */
+
+ if(video_enable) {
+ 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;
+ }
+ }
+ }
+
+
+ /*
+ 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;
+
+ /* 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--;
+ }
+ }
+
+ 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;
+
+ fifo->video_lwm = 1024; fifo->video_burst_size = 512;
+ }
+}
+
+static void nv10UpdateArbitrationSettings (
+ unsigned VClk,
+ unsigned pixelDepth,
+ unsigned *burst,
+ unsigned *lwm,
+ NVPtr pNv
+)
+{
+ nv10_fifo_info fifo_data;
+ nv10_sim_state sim_data;
+ unsigned int MClk, NVClk, cfg1;
+
+ nvGetClocks(pNv, &MClk, &NVClk);
+
+ cfg1 = pNv->PFB[0x0204/4];
+ sim_data.pix_bpp = (char)pixelDepth;
+ sim_data.enable_video = 1;
+ sim_data.enable_mp = 0;
+ sim_data.memory_type = (pNv->PFB[0x0200/4] & 0x01) ? 1 : 0;
+ sim_data.memory_width = (pNv->PEXTDEV[0x0000/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,
+ NVPtr pNv
+)
+{
+ 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 = pNv->PRAMDAC0[0x0500/4];
+ M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F;
+ NVClk = (N * pNv->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 void CalcVClock (
+ int clockIn,
+ int *clockOut,
+ U032 *pllOut,
+ NVPtr pNv
+)
+{
+ unsigned lowM, highM;
+ unsigned DeltaNew, DeltaOld;
+ unsigned VClk, Freq;
+ unsigned M, N, P;
+
+ DeltaOld = 0xFFFFFFFF;
+
+ VClk = (unsigned)clockIn;
+
+ if (pNv->CrystalFreqKHz == 13500) {
+ lowM = 7;
+ highM = 13;
+ } else {
+ lowM = 8;
+ highM = 14;
+ }
+
+ for (P = 0; P <= 4; P++) {
+ Freq = VClk << P;
+ if ((Freq >= 128000) && (Freq <= 350000)) {
+ for (M = lowM; M <= highM; M++) {
+ N = ((VClk << P) * M) / pNv->CrystalFreqKHz;
+ if(N <= 255) {
+ Freq = ((pNv->CrystalFreqKHz * N) / M) >> P;
+ if (Freq > VClk)
+ DeltaNew = Freq - VClk;
+ else
+ DeltaNew = VClk - Freq;
+ if (DeltaNew < DeltaOld) {
+ *pllOut = (P << 16) | (N << 8) | M;
+ *clockOut = Freq;
+ DeltaOld = DeltaNew;
+ }
+ }
+ }
+ }
+ }
+}
+
+static void CalcVClock2Stage (
+ int clockIn,
+ int *clockOut,
+ U032 *pllOut,
+ U032 *pllBOut,
+ NVPtr pNv
+)
+{
+ unsigned DeltaNew, DeltaOld;
+ unsigned VClk, Freq;
+ unsigned M, N, P;
+
+ DeltaOld = 0xFFFFFFFF;
+
+ *pllBOut = 0x80000401; /* fixed at x4 for now */
+
+ VClk = (unsigned)clockIn;
+
+ for (P = 0; P <= 6; P++) {
+ Freq = VClk << P;
+ if ((Freq >= 400000) && (Freq <= 1000000)) {
+ for (M = 1; M <= 13; M++) {
+ N = ((VClk << P) * M) / (pNv->CrystalFreqKHz << 2);
+ if((N >= 5) && (N <= 255)) {
+ Freq = (((pNv->CrystalFreqKHz << 2) * N) / M) >> P;
+ if (Freq > VClk)
+ DeltaNew = Freq - VClk;
+ else
+ DeltaNew = VClk - Freq;
+ if (DeltaNew < DeltaOld) {
+ *pllOut = (P << 16) | (N << 8) | M;
+ *clockOut = Freq;
+ DeltaOld = DeltaNew;
+ }
+ }
+ }
+ }
+ }
+}
+
+/*
+ * Calculate extended mode parameters (SVGA) and save in a
+ * mode state structure.
+ */
+void NVCalcStateExt (
+ NVPtr pNv,
+ RIVA_HW_STATE *state,
+ int bpp,
+ int width,
+ int hDisplaySize,
+ int height,
+ int dotClock,
+ int flags
+)
+{
+ int pixelDepth, VClk;
+ /*
+ * 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;
+ if(pNv->twoStagePLL)
+ CalcVClock2Stage(dotClock, &VClk, &state->pll, &state->pllB, pNv);
+ else
+ CalcVClock(dotClock, &VClk, &state->pll, pNv);
+
+ switch (pNv->Architecture)
+ {
+ case NV_ARCH_04:
+ nv4UpdateArbitrationSettings(VClk,
+ pixelDepth * 8,
+ &(state->arbitration0),
+ &(state->arbitration1),
+ pNv);
+ state->cursor0 = 0x00;
+ state->cursor1 = 0xbC;
+ 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:
+ case NV_ARCH_30:
+ default:
+ if(((pNv->Chipset & 0xffff) == 0x01A0) ||
+ ((pNv->Chipset & 0xffff) == 0x01f0))
+ {
+ nForceUpdateArbitrationSettings(VClk,
+ pixelDepth * 8,
+ &(state->arbitration0),
+ &(state->arbitration1),
+ pNv);
+ } else {
+ nv10UpdateArbitrationSettings(VClk,
+ pixelDepth * 8,
+ &(state->arbitration0),
+ &(state->arbitration1),
+ pNv);
+ }
+ state->cursor0 = 0x80 | (pNv->CursorStart >> 17);
+ state->cursor1 = (pNv->CursorStart >> 11) << 2;
+ state->cursor2 = pNv->CursorStart >> 24;
+ if (flags & V_DBLSCAN)
+ state->cursor1 |= 2;
+ state->pllsel = 0x10000700;
+ state->config = pNv->PFB[0x00000200/4];
+ state->general = bpp == 16 ? 0x00101100 : 0x00100100;
+ state->repaint1 = hDisplaySize < 1280 ? 0x04 : 0x00;
+ break;
+ }
+
+ if(bpp != 8) /* DirectColor */
+ state->general |= 0x00000030;
+
+ state->repaint0 = (((width / 8) * pixelDepth) & 0x700) >> 3;
+ state->pixel = (pixelDepth > 2) ? 3 : pixelDepth;
+}
+
+
+void NVLoadStateExt (
+ NVPtr pNv,
+ RIVA_HW_STATE *state
+)
+{
+ int i;
+
+ pNv->PMC[0x0140/4] = 0x00000000;
+ pNv->PMC[0x0200/4] = 0xFFFF00FF;
+ pNv->PMC[0x0200/4] = 0xFFFFFFFF;
+
+ pNv->PTIMER[0x0200] = 0x00000008;
+ pNv->PTIMER[0x0210] = 0x00000003;
+ pNv->PTIMER[0x0140] = 0x00000000;
+ pNv->PTIMER[0x0100] = 0xFFFFFFFF;
+
+ if(pNv->Architecture == NV_ARCH_04) {
+ pNv->PFB[0x0200/4] = state->config;
+ } else {
+ pNv->PFB[0x0240/4] = 0;
+ pNv->PFB[0x0244/4] = pNv->FbMapSize - 1;
+ pNv->PFB[0x0250/4] = 0;
+ pNv->PFB[0x0254/4] = pNv->FbMapSize - 1;
+ pNv->PFB[0x0260/4] = 0;
+ pNv->PFB[0x0264/4] = pNv->FbMapSize - 1;
+ pNv->PFB[0x0270/4] = 0;
+ pNv->PFB[0x0274/4] = pNv->FbMapSize - 1;
+ pNv->PFB[0x0280/4] = 0;
+ pNv->PFB[0x0284/4] = pNv->FbMapSize - 1;
+ pNv->PFB[0x0290/4] = 0;
+ pNv->PFB[0x0294/4] = pNv->FbMapSize - 1;
+ pNv->PFB[0x02A0/4] = 0;
+ pNv->PFB[0x02A4/4] = pNv->FbMapSize - 1;
+ pNv->PFB[0x02B0/4] = 0;
+ pNv->PFB[0x02B4/4] = pNv->FbMapSize - 1;
+ }
+
+ pNv->PRAMIN[0x0000] = 0x80000010;
+ pNv->PRAMIN[0x0001] = 0x80011201;
+ pNv->PRAMIN[0x0002] = 0x80000011;
+ pNv->PRAMIN[0x0003] = 0x80011202;
+ pNv->PRAMIN[0x0004] = 0x80000012;
+ pNv->PRAMIN[0x0005] = 0x80011203;
+ pNv->PRAMIN[0x0006] = 0x80000013;
+ pNv->PRAMIN[0x0007] = 0x80011204;
+ pNv->PRAMIN[0x0008] = 0x80000014;
+ pNv->PRAMIN[0x0009] = 0x80011205;
+ pNv->PRAMIN[0x000A] = 0x80000015;
+ pNv->PRAMIN[0x000B] = 0x80011206;
+ pNv->PRAMIN[0x000C] = 0x80000016;
+ pNv->PRAMIN[0x000D] = 0x80011207;
+ pNv->PRAMIN[0x000E] = 0x80000017;
+ pNv->PRAMIN[0x000F] = 0x80011208;
+ pNv->PRAMIN[0x0800] = 0x00003000;
+ pNv->PRAMIN[0x0801] = pNv->FbMapSize - 1;
+ pNv->PRAMIN[0x0802] = 0x00000002;
+ pNv->PRAMIN[0x0803] = 0x00000002;
+ if(pNv->Architecture >= NV_ARCH_10)
+ pNv->PRAMIN[0x0804] = 0x01008062;
+ else
+ pNv->PRAMIN[0x0804] = 0x01008042;
+ pNv->PRAMIN[0x0805] = 0x00000000;
+ pNv->PRAMIN[0x0806] = 0x12001200;
+ pNv->PRAMIN[0x0807] = 0x00000000;
+ pNv->PRAMIN[0x0808] = 0x01008043;
+ pNv->PRAMIN[0x0809] = 0x00000000;
+ pNv->PRAMIN[0x080A] = 0x00000000;
+ pNv->PRAMIN[0x080B] = 0x00000000;
+ pNv->PRAMIN[0x080C] = 0x01008044;
+ pNv->PRAMIN[0x080D] = 0x00000002;
+ pNv->PRAMIN[0x080E] = 0x00000000;
+ pNv->PRAMIN[0x080F] = 0x00000000;
+ pNv->PRAMIN[0x0810] = 0x01008019;
+ pNv->PRAMIN[0x0811] = 0x00000000;
+ pNv->PRAMIN[0x0812] = 0x00000000;
+ pNv->PRAMIN[0x0813] = 0x00000000;
+ pNv->PRAMIN[0x0814] = 0x0100A05C;
+ pNv->PRAMIN[0x0815] = 0x00000000;
+ pNv->PRAMIN[0x0816] = 0x00000000;
+ pNv->PRAMIN[0x0817] = 0x00000000;
+ pNv->PRAMIN[0x0818] = 0x0100805F;
+ pNv->PRAMIN[0x0819] = 0x00000000;
+ pNv->PRAMIN[0x081A] = 0x12001200;
+ pNv->PRAMIN[0x081B] = 0x00000000;
+ pNv->PRAMIN[0x081C] = 0x0100804A;
+ pNv->PRAMIN[0x081D] = 0x00000002;
+ pNv->PRAMIN[0x081E] = 0x00000000;
+ pNv->PRAMIN[0x081F] = 0x00000000;
+ pNv->PRAMIN[0x0820] = 0x01018077;
+ pNv->PRAMIN[0x0821] = 0x00000000;
+ pNv->PRAMIN[0x0822] = 0x01201200;
+ pNv->PRAMIN[0x0823] = 0x00000000;
+ pNv->PRAMIN[0x0824] = 0x00003002;
+ pNv->PRAMIN[0x0825] = 0x00007FFF;
+ pNv->PRAMIN[0x0826] = pNv->FbUsableSize | 0x00000002;
+ pNv->PRAMIN[0x0827] = 0x00000002;
+
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ pNv->PRAMIN[0x0804] |= 0x00080000;
+ pNv->PRAMIN[0x0808] |= 0x00080000;
+ pNv->PRAMIN[0x080C] |= 0x00080000;
+ pNv->PRAMIN[0x0810] |= 0x00080000;
+ pNv->PRAMIN[0x0814] |= 0x00080000;
+ pNv->PRAMIN[0x0818] |= 0x00080000;
+ pNv->PRAMIN[0x081C] |= 0x00080000;
+ pNv->PRAMIN[0x0820] |= 0x00080000;
+
+ pNv->PRAMIN[0x080D] = 0x00000001;
+ pNv->PRAMIN[0x081D] = 0x00000001;
+#endif
+
+ if(pNv->Architecture < NV_ARCH_10) {
+ if((pNv->Chipset & 0x0fff) == 0x0020) {
+ pNv->PRAMIN[0x0824] |= 0x00020000;
+ pNv->PRAMIN[0x0826] += pNv->FbAddress;
+ }
+ pNv->PGRAPH[0x0080/4] = 0x000001FF;
+ pNv->PGRAPH[0x0080/4] = 0x1230C000;
+ pNv->PGRAPH[0x0084/4] = 0x72111101;
+ pNv->PGRAPH[0x0088/4] = 0x11D5F071;
+ pNv->PGRAPH[0x008C/4] = 0x0004FF31;
+
+ pNv->PGRAPH[0x0140/4] = 0x00000000;
+ pNv->PGRAPH[0x0100/4] = 0xFFFFFFFF;
+ pNv->PGRAPH[0x0170/4] = 0x10010100;
+ pNv->PGRAPH[0x0710/4] = 0xFFFFFFFF;
+ pNv->PGRAPH[0x0720/4] = 0x00000001;
+
+ pNv->PGRAPH[0x0810/4] = 0x00000000;
+ } else {
+ pNv->PGRAPH[0x0080/4] = 0xFFFFFFFF;
+ pNv->PGRAPH[0x0080/4] = 0x00000000;
+
+ pNv->PGRAPH[0x0140/4] = 0x00000000;
+ pNv->PGRAPH[0x0100/4] = 0xFFFFFFFF;
+ pNv->PGRAPH[0x0144/4] = 0x10010100;
+ pNv->PGRAPH[0x0714/4] = 0xFFFFFFFF;
+ pNv->PGRAPH[0x0720/4] = 0x00000001;
+
+ if(pNv->Architecture == NV_ARCH_10) {
+ pNv->PGRAPH[0x0084/4] = 0x00118700;
+ pNv->PGRAPH[0x0088/4] = 0x24E00810;
+ pNv->PGRAPH[0x008C/4] = 0x55DE0030;
+
+ for(i = 0; i < 32; i++)
+ pNv->PGRAPH[(0x0B00/4) + i] = pNv->PFB[(0x0240/4) + i];
+
+ pNv->PGRAPH[0x640/4] = 0;
+ pNv->PGRAPH[0x644/4] = 0;
+ pNv->PGRAPH[0x684/4] = pNv->FbMapSize - 1;
+ pNv->PGRAPH[0x688/4] = pNv->FbMapSize - 1;
+
+ pNv->PGRAPH[0x0810/4] = 0x00000000;
+ } else {
+ if(pNv->Architecture >= NV_ARCH_30) {
+ pNv->PGRAPH[0x0084/4] = 0x40108700;
+ pNv->PGRAPH[0x0890/4] = 0x00140000;
+ pNv->PGRAPH[0x008C/4] = 0xf00e0431;
+ pNv->PGRAPH[0x0090/4] = 0x00008000;
+ pNv->PGRAPH[0x0610/4] = 0xf04b1f36;
+ pNv->PGRAPH[0x0B80/4] = 0x1002d888;
+ pNv->PGRAPH[0x0B88/4] = 0x62ff007f;
+ } else {
+ pNv->PGRAPH[0x0084/4] = 0x00118700;
+ pNv->PGRAPH[0x008C/4] = 0xF20E0431;
+ pNv->PGRAPH[0x0090/4] = 0x00000000;
+ pNv->PGRAPH[0x009C/4] = 0x00000040;
+
+ if((pNv->Chipset & 0x0ff0) >= 0x0250) {
+ pNv->PGRAPH[0x0890/4] = 0x00080000;
+ pNv->PGRAPH[0x0610/4] = 0x304B1FB6;
+ pNv->PGRAPH[0x0B80/4] = 0x18B82880;
+ pNv->PGRAPH[0x0B84/4] = 0x44000000;
+ pNv->PGRAPH[0x0098/4] = 0x40000080;
+ pNv->PGRAPH[0x0B88/4] = 0x000000ff;
+ } else {
+ pNv->PGRAPH[0x0880/4] = 0x00080000;
+ pNv->PGRAPH[0x0094/4] = 0x00000005;
+ pNv->PGRAPH[0x0B80/4] = 0x45CAA208;
+ pNv->PGRAPH[0x0B84/4] = 0x24000000;
+ pNv->PGRAPH[0x0098/4] = 0x00000040;
+ pNv->PGRAPH[0x0750/4] = 0x00E00038;
+ pNv->PGRAPH[0x0754/4] = 0x00000030;
+ pNv->PGRAPH[0x0750/4] = 0x00E10038;
+ pNv->PGRAPH[0x0754/4] = 0x00000030;
+ }
+ }
+
+ for(i = 0; i < 32; i++)
+ pNv->PGRAPH[(0x0900/4) + i] = pNv->PFB[(0x0240/4) + i];
+
+ pNv->PGRAPH[0x09A4/4] = pNv->PFB[0x0200/4];
+ pNv->PGRAPH[0x09A8/4] = pNv->PFB[0x0204/4];
+ pNv->PGRAPH[0x0750/4] = 0x00EA0000;
+ pNv->PGRAPH[0x0754/4] = pNv->PFB[0x0200/4];
+ pNv->PGRAPH[0x0750/4] = 0x00EA0004;
+ pNv->PGRAPH[0x0754/4] = pNv->PFB[0x0204/4];
+
+ pNv->PGRAPH[0x0820/4] = 0;
+ pNv->PGRAPH[0x0824/4] = 0;
+ pNv->PGRAPH[0x0864/4] = pNv->FbMapSize - 1;
+ pNv->PGRAPH[0x0868/4] = pNv->FbMapSize - 1;
+
+ pNv->PGRAPH[0x0B20/4] = 0x00000000;
+ }
+ }
+ pNv->PGRAPH[0x053C/4] = 0;
+ pNv->PGRAPH[0x0540/4] = 0;
+ pNv->PGRAPH[0x0544/4] = 0x00007FFF;
+ pNv->PGRAPH[0x0548/4] = 0x00007FFF;
+
+ pNv->PFIFO[0x0140] = 0x00000000;
+ pNv->PFIFO[0x0141] = 0x00000001;
+ pNv->PFIFO[0x0480] = 0x00000000;
+ pNv->PFIFO[0x0494] = 0x00000000;
+ pNv->PFIFO[0x0481] = 0x00000100;
+ pNv->PFIFO[0x0490] = 0x00000000;
+ pNv->PFIFO[0x0491] = 0x00000000;
+ pNv->PFIFO[0x048B] = 0x00001209;
+ pNv->PFIFO[0x0400] = 0x00000000;
+ pNv->PFIFO[0x0414] = 0x00000000;
+ pNv->PFIFO[0x0084] = 0x03000100;
+ pNv->PFIFO[0x0085] = 0x00000110;
+ pNv->PFIFO[0x0086] = 0x00000112;
+ pNv->PFIFO[0x0143] = 0x0000FFFF;
+ pNv->PFIFO[0x0496] = 0x0000FFFF;
+ pNv->PFIFO[0x0050] = 0x00000000;
+ pNv->PFIFO[0x0040] = 0xFFFFFFFF;
+ pNv->PFIFO[0x0415] = 0x00000001;
+ pNv->PFIFO[0x048C] = 0x00000000;
+ pNv->PFIFO[0x04A0] = 0x00000000;
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ pNv->PFIFO[0x0489] = 0x800F0078;
+#else
+ pNv->PFIFO[0x0489] = 0x000F0078;
+#endif
+ pNv->PFIFO[0x0488] = 0x00000001;
+ pNv->PFIFO[0x0480] = 0x00000001;
+ pNv->PFIFO[0x0494] = 0x00000001;
+ pNv->PFIFO[0x0495] = 0x00000001;
+ pNv->PFIFO[0x0140] = 0x00000001;
+
+ if(pNv->Architecture >= NV_ARCH_10) {
+ if(pNv->twoHeads) {
+ pNv->PCRTC0[0x0860/4] = state->head;
+ pNv->PCRTC0[0x2860/4] = state->head2;
+ }
+ pNv->PRAMDAC[0x0404/4] |= (1 << 25);
+
+ pNv->PMC[0x8704/4] = 1;
+ pNv->PMC[0x8140/4] = 0;
+ pNv->PMC[0x8920/4] = 0;
+ pNv->PMC[0x8924/4] = 0;
+ pNv->PMC[0x8908/4] = pNv->FbMapSize - 1;
+ pNv->PMC[0x890C/4] = pNv->FbMapSize - 1;
+ pNv->PMC[0x1588/4] = 0;
+
+ pNv->PCRTC[0x0810/4] = state->cursorConfig;
+
+ if(pNv->FlatPanel) {
+ if((pNv->Chipset & 0x0ff0) == 0x0110) {
+ pNv->PRAMDAC[0x0528/4] = state->dither;
+ } else
+ if((pNv->Chipset & 0x0ff0) >= 0x0170) {
+ pNv->PRAMDAC[0x083C/4] = state->dither;
+ }
+
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x53);
+ VGA_WR08(pNv->PCIO, 0x03D5, 0);
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x54);
+ VGA_WR08(pNv->PCIO, 0x03D5, 0);
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x21);
+ VGA_WR08(pNv->PCIO, 0x03D5, 0xfa);
+ }
+
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x41);
+ VGA_WR08(pNv->PCIO, 0x03D5, state->extra);
+ }
+
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x19);
+ VGA_WR08(pNv->PCIO, 0x03D5, state->repaint0);
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x1A);
+ VGA_WR08(pNv->PCIO, 0x03D5, state->repaint1);
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x25);
+ VGA_WR08(pNv->PCIO, 0x03D5, state->screen);
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x28);
+ VGA_WR08(pNv->PCIO, 0x03D5, state->pixel);
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x2D);
+ VGA_WR08(pNv->PCIO, 0x03D5, state->horiz);
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x1B);
+ VGA_WR08(pNv->PCIO, 0x03D5, state->arbitration0);
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x20);
+ VGA_WR08(pNv->PCIO, 0x03D5, state->arbitration1);
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x30);
+ VGA_WR08(pNv->PCIO, 0x03D5, state->cursor0);
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x31);
+ VGA_WR08(pNv->PCIO, 0x03D5, state->cursor1);
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x2F);
+ VGA_WR08(pNv->PCIO, 0x03D5, state->cursor2);
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x39);
+ VGA_WR08(pNv->PCIO, 0x03D5, state->interlace);
+
+ if(!pNv->FlatPanel) {
+ pNv->PRAMDAC0[0x050C/4] = state->pllsel;
+ pNv->PRAMDAC0[0x0508/4] = state->vpll;
+ if(pNv->twoHeads)
+ pNv->PRAMDAC0[0x0520/4] = state->vpll2;
+ if(pNv->twoStagePLL) {
+ pNv->PRAMDAC0[0x0578/4] = state->vpllB;
+ pNv->PRAMDAC0[0x057C/4] = state->vpll2B;
+ }
+ } else {
+ pNv->PRAMDAC[0x0848/4] = state->scale;
+ }
+ pNv->PRAMDAC[0x0600/4] = state->general;
+
+ pNv->PCRTC[0x0140/4] = 0;
+ pNv->PCRTC[0x0100/4] = 1;
+
+ pNv->CurrentState = state;
+}
+
+void NVUnloadStateExt
+(
+ NVPtr pNv,
+ RIVA_HW_STATE *state
+)
+{
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x19);
+ state->repaint0 = VGA_RD08(pNv->PCIO, 0x03D5);
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x1A);
+ state->repaint1 = VGA_RD08(pNv->PCIO, 0x03D5);
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x25);
+ state->screen = VGA_RD08(pNv->PCIO, 0x03D5);
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x28);
+ state->pixel = VGA_RD08(pNv->PCIO, 0x03D5);
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x2D);
+ state->horiz = VGA_RD08(pNv->PCIO, 0x03D5);
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x1B);
+ state->arbitration0 = VGA_RD08(pNv->PCIO, 0x03D5);
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x20);
+ state->arbitration1 = VGA_RD08(pNv->PCIO, 0x03D5);
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x30);
+ state->cursor0 = VGA_RD08(pNv->PCIO, 0x03D5);
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x31);
+ state->cursor1 = VGA_RD08(pNv->PCIO, 0x03D5);
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x2F);
+ state->cursor2 = VGA_RD08(pNv->PCIO, 0x03D5);
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x39);
+ state->interlace = VGA_RD08(pNv->PCIO, 0x03D5);
+ state->vpll = pNv->PRAMDAC0[0x0508/4];
+ if(pNv->twoHeads)
+ state->vpll2 = pNv->PRAMDAC0[0x0520/4];
+ if(pNv->twoStagePLL) {
+ state->vpllB = pNv->PRAMDAC0[0x0578/4];
+ state->vpll2B = pNv->PRAMDAC0[0x057C/4];
+ }
+ state->pllsel = pNv->PRAMDAC0[0x050C/4];
+ state->general = pNv->PRAMDAC[0x0600/4];
+ state->scale = pNv->PRAMDAC[0x0848/4];
+ state->config = pNv->PFB[0x0200/4];
+
+ if(pNv->Architecture >= NV_ARCH_10) {
+ if(pNv->twoHeads) {
+ state->head = pNv->PCRTC0[0x0860/4];
+ state->head2 = pNv->PCRTC0[0x2860/4];
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x44);
+ state->crtcOwner = VGA_RD08(pNv->PCIO, 0x03D5);
+ }
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x41);
+ state->extra = VGA_RD08(pNv->PCIO, 0x03D5);
+ state->cursorConfig = pNv->PCRTC[0x0810/4];
+
+ if((pNv->Chipset & 0x0ff0) == 0x0110) {
+ state->dither = pNv->PRAMDAC[0x0528/4];
+ } else
+ if((pNv->Chipset & 0x0ff0) >= 0x0170) {
+ state->dither = pNv->PRAMDAC[0x083C/4];
+ }
+ }
+}
+
+void NVSetStartAddress (
+ NVPtr pNv,
+ CARD32 start
+)
+{
+ pNv->PCRTC[0x800/4] = start;
+}
+
+
diff --git a/src/riva_const.h b/src/riva_const.h
new file mode 100644
index 0000000..31dc8d5
--- /dev/null
+++ b/src/riva_const.h
@@ -0,0 +1,14 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_const.h,v 1.1 2003/07/31 20:24:29 mvojkovi Exp $ */
+
+#ifndef __RIVA_CONST_H__
+#define __RIVA_CONST_H__
+
+#define RIVA_VERSION 4000
+#define RIVA_NAME "RIVA128"
+#define RIVA_DRIVER_NAME "riva128"
+#define RIVA_MAJOR_VERSION 1
+#define RIVA_MINOR_VERSION 0
+#define RIVA_PATCHLEVEL 1
+
+#endif /* __RIVA_CONST_H__ */
+
diff --git a/src/riva_cursor.c b/src/riva_cursor.c
new file mode 100644
index 0000000..7dcaed9
--- /dev/null
+++ b/src/riva_cursor.c
@@ -0,0 +1,165 @@
+/*
+ * 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/riva_cursor.c,v 1.1 2003/07/31 20:24:29 mvojkovi Exp $ */
+
+#include "riva_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)
+
+
+static void
+RivaConvertCursor1555(RivaPtr pRiva, 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 ( m & 1 )
+ *dst = ( b & 1) ? pRiva->curFg : pRiva->curBg;
+ else
+ *dst = TRANSPARENT_PIXEL;
+ b >>= 1;
+ m >>= 1;
+ dst++;
+ }
+ }
+}
+
+
+static void
+RivaTransformCursor (RivaPtr pRiva)
+{
+ CARD32 *tmp;
+ int i, dwords;
+
+ dwords = (32 * 32) >> 1;
+ if(!(tmp = ALLOCATE_LOCAL(dwords * 4))) return;
+ RivaConvertCursor1555(pRiva, pRiva->curImage, (CARD16*)tmp);
+
+ for(i = 0; i < dwords; i++)
+ pRiva->riva.CURSOR[i] = tmp[i];
+
+ DEALLOCATE_LOCAL(tmp);
+}
+
+static void
+RivaLoadCursorImage( ScrnInfoPtr pScrn, unsigned char *src )
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ /* save copy of image for color changes */
+ memcpy(pRiva->curImage, src, 256);
+
+ RivaTransformCursor(pRiva);
+}
+
+static void
+RivaSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ pRiva->riva.PRAMDAC[0x0000300/4] = (x & 0xFFFF) | (y << 16);
+}
+
+static void
+RivaSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+ CARD32 fore, back;
+
+ fore = ConvertToRGB555(fg);
+ back = ConvertToRGB555(bg);
+
+ if ((pRiva->curFg != fore) || (pRiva->curBg != back)) {
+ pRiva->curFg = fore;
+ pRiva->curBg = back;
+
+ RivaTransformCursor(pRiva);
+ }
+}
+
+
+static void
+RivaShowCursor(ScrnInfoPtr pScrn)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+ /* Enable cursor - X-Windows mode */
+ pRiva->riva.ShowHideCursor(&pRiva->riva, 1);
+}
+
+static void
+RivaHideCursor(ScrnInfoPtr pScrn)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+ /* Disable cursor */
+ pRiva->riva.ShowHideCursor(&pRiva->riva, 0);
+}
+
+static Bool
+RivaUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
+{
+ return TRUE;
+}
+
+
+Bool
+RivaCursorInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RivaPtr pRiva = RivaPTR(pScrn);
+ xf86CursorInfoPtr infoPtr;
+
+ infoPtr = xf86CreateCursorInfoRec();
+ if(!infoPtr) return FALSE;
+
+ pRiva->CursorInfoRec = infoPtr;
+
+ infoPtr->MaxWidth = infoPtr->MaxHeight = 32;
+ infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32;
+ infoPtr->SetCursorColors = RivaSetCursorColors;
+ infoPtr->SetCursorPosition = RivaSetCursorPosition;
+ infoPtr->LoadCursorImage = RivaLoadCursorImage;
+ infoPtr->HideCursor = RivaHideCursor;
+ infoPtr->ShowCursor = RivaShowCursor;
+ infoPtr->UseHWCursor = RivaUseHWCursor;
+
+ return(xf86InitCursor(pScreen, infoPtr));
+}
diff --git a/src/riva_dac.c b/src/riva_dac.c
new file mode 100644
index 0000000..348e526
--- /dev/null
+++ b/src/riva_dac.c
@@ -0,0 +1,280 @@
+/*
+ * 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/riva_dac.c,v 1.2 2003/09/16 00:17:46 mvojkovi Exp $ */
+
+#include "riva_include.h"
+
+Bool
+RivaDACInit(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;
+
+
+ RivaPtr pRiva = RivaPTR(pScrn);
+ RivaRegPtr rivaReg = &pRiva->ModeReg;
+ RivaFBLayout *pLayout = &pRiva->CurrentLayout;
+ vgaRegPtr pVga;
+
+ /*
+ * 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;
+
+ 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;
+
+ rivaReg->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);
+
+ rivaReg->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);
+
+ rivaReg->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;
+ rivaReg->interlace = Set8Bits(horizTotal);
+ rivaReg->horiz |= SetBitField(horizTotal,8:8,4:4);
+ } else {
+ rivaReg->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;
+
+ pRiva->riva.CalcStateExt(&pRiva->riva,
+ rivaReg,
+ i,
+ pLayout->displayWidth,
+ mode->CrtcHDisplay,
+ pScrn->virtualY,
+ mode->Clock,
+ mode->Flags);
+
+ rivaReg->cursorConfig = 0x02000100;
+ if(mode->Flags & V_DBLSCAN)
+ rivaReg->cursorConfig |= (1 << 4);
+
+ return (TRUE);
+}
+
+void
+RivaDACRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, RivaRegPtr rivaReg,
+ Bool primary)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+ int restore = VGA_SR_MODE;
+
+ restore |= primary ? (VGA_SR_CMAP | VGA_SR_FONTS) : VGA_SR_CMAP;
+ pRiva->riva.LoadStateExt(&pRiva->riva, rivaReg);
+ vgaHWRestore(pScrn, vgaReg, restore);
+}
+
+/*
+ * RivaDACSave
+ *
+ * This function saves the video state.
+ */
+void
+RivaDACSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, RivaRegPtr rivaReg,
+ Bool saveFonts)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ pRiva->riva.LockUnlock(&pRiva->riva, 0);
+
+ vgaHWSave(pScrn, vgaReg, VGA_SR_CMAP | VGA_SR_MODE |
+ (saveFonts? VGA_SR_FONTS : 0));
+ pRiva->riva.UnloadStateExt(&pRiva->riva, rivaReg);
+}
+
+#define DEPTH_SHIFT(val, w) ((val << (8 - w)) | (val >> ((w << 1) - 8)))
+#define MAKE_INDEX(in, w) (DEPTH_SHIFT(in, w) * 3)
+
+void
+RivaDACLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
+ VisualPtr pVisual )
+{
+ int i, index;
+ RivaPtr pRiva = RivaPTR(pScrn);
+ vgaRegPtr pVga;
+
+ pVga = &VGAHWPTR(pScrn)->ModeReg;
+
+ if(pRiva->CurrentLayout.depth != 8)
+ return;
+
+ 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;
+ }
+ 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 void
+Riva_I2CGetBits(I2CBusPtr b, int *clock, int *data)
+{
+ RivaPtr pRiva = RivaPTR(xf86Screens[b->scrnIndex]);
+ unsigned char val;
+
+ /* Get the result. */
+ VGA_WR08(pRiva->riva.PCIO, 0x3d4, pRiva->DDCBase);
+ val = VGA_RD08(pRiva->riva.PCIO, 0x3d5);
+
+ *clock = (val & DDC_SCL_READ_MASK) != 0;
+ *data = (val & DDC_SDA_READ_MASK) != 0;
+}
+
+static void
+Riva_I2CPutBits(I2CBusPtr b, int clock, int data)
+{
+ RivaPtr pRiva = RivaPTR(xf86Screens[b->scrnIndex]);
+ unsigned char val;
+
+ VGA_WR08(pRiva->riva.PCIO, 0x3d4, pRiva->DDCBase + 1);
+ val = VGA_RD08(pRiva->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(pRiva->riva.PCIO, 0x3d4, pRiva->DDCBase + 1);
+ VGA_WR08(pRiva->riva.PCIO, 0x3d5, val | 0x1);
+}
+
+Bool
+RivaDACi2cInit(ScrnInfoPtr pScrn)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+ I2CBusPtr I2CPtr;
+
+ I2CPtr = xf86CreateI2CBusRec();
+ if(!I2CPtr) return FALSE;
+
+ pRiva->I2C = I2CPtr;
+
+ I2CPtr->BusName = "DDC";
+ I2CPtr->scrnIndex = pScrn->scrnIndex;
+ I2CPtr->I2CPutBits = Riva_I2CPutBits;
+ I2CPtr->I2CGetBits = Riva_I2CGetBits;
+ I2CPtr->AcknTimeout = 5;
+
+ if (!xf86I2CBusInit(I2CPtr)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
diff --git a/src/riva_dga.c b/src/riva_dga.c
new file mode 100644
index 0000000..cbe4224
--- /dev/null
+++ b/src/riva_dga.c
@@ -0,0 +1,305 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_dga.c,v 1.1 2003/07/31 20:24:29 mvojkovi Exp $ */
+
+#include "riva_local.h"
+#include "riva_include.h"
+#include "riva_type.h"
+#include "riva_proto.h"
+#include "xaalocal.h"
+#include "dgaproc.h"
+
+
+static Bool Riva_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
+ int *, int *, int *);
+static Bool Riva_SetMode(ScrnInfoPtr, DGAModePtr);
+static int Riva_GetViewport(ScrnInfoPtr);
+static void Riva_SetViewport(ScrnInfoPtr, int, int, int);
+static void Riva_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
+static void Riva_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
+static void Riva_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int,
+ unsigned long);
+
+static
+DGAFunctionRec Riva_DGAFuncs = {
+ Riva_OpenFramebuffer,
+ NULL,
+ Riva_SetMode,
+ Riva_SetViewport,
+ Riva_GetViewport,
+ RivaSync,
+ Riva_FillRect,
+ Riva_BlitRect,
+ Riva_BlitTransRect
+};
+
+
+
+static DGAModePtr
+RivaSetupDGAMode(
+ 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;
+ RivaPtr pRiva = RivaPTR(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 <= pRiva->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(!pRiva->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 = pRiva->FbStart;
+ mode->bytesPerScanline = pitch * Bpp;
+ mode->imageWidth = pitch;
+ mode->imageHeight = pRiva->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
+RivaDGAInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RivaPtr pRiva = RivaPTR(pScrn);
+ DGAModePtr modes = NULL;
+ int num = 0;
+
+ /* 8 */
+ modes = RivaSetupDGAMode (pScrn, modes, &num, 8, 8,
+ (pScrn->bitsPerPixel == 8),
+ (pScrn->bitsPerPixel != 8) ? 0 : pScrn->displayWidth,
+ 0, 0, 0, PseudoColor);
+
+ /* 15 */
+ modes = RivaSetupDGAMode (pScrn, modes, &num, 16, 15,
+ (pScrn->bitsPerPixel == 16),
+ (pScrn->depth != 15) ? 0 : pScrn->displayWidth,
+ 0x7c00, 0x03e0, 0x001f, TrueColor);
+
+ /* 32 */
+ modes = RivaSetupDGAMode (pScrn, modes, &num, 32, 24,
+ (pScrn->bitsPerPixel == 32),
+ (pScrn->bitsPerPixel != 32) ? 0 : pScrn->displayWidth,
+ 0xff0000, 0x00ff00, 0x0000ff, TrueColor);
+
+ pRiva->numDGAModes = num;
+ pRiva->DGAModes = modes;
+
+ return DGAInit(pScreen, &Riva_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
+Riva_SetMode(
+ ScrnInfoPtr pScrn,
+ DGAModePtr pMode
+){
+ static RivaFBLayout SavedLayouts[MAXSCREENS];
+ int index = pScrn->pScreen->myNum;
+
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ if(!pMode) { /* restore the original mode */
+ if(pRiva->DGAactive)
+ memcpy(&pRiva->CurrentLayout, &SavedLayouts[index], sizeof(RivaFBLayout));
+
+ pScrn->currentMode = pRiva->CurrentLayout.mode;
+ RivaSwitchMode(index, pScrn->currentMode, 0);
+ RivaAdjustFrame(index, pScrn->frameX0, pScrn->frameY0, 0);
+ pRiva->DGAactive = FALSE;
+ } else {
+ if(!pRiva->DGAactive) { /* save the old parameters */
+ memcpy(&SavedLayouts[index], &pRiva->CurrentLayout, sizeof(RivaFBLayout));
+ pRiva->DGAactive = TRUE;
+ }
+
+ /* update CurrentLayout */
+ pRiva->CurrentLayout.bitsPerPixel = pMode->bitsPerPixel;
+ pRiva->CurrentLayout.depth = pMode->depth;
+ pRiva->CurrentLayout.displayWidth = pMode->bytesPerScanline /
+ (pMode->bitsPerPixel >> 3);
+ pRiva->CurrentLayout.weight.red = BitsSet(pMode->red_mask);
+ pRiva->CurrentLayout.weight.green = BitsSet(pMode->green_mask);
+ pRiva->CurrentLayout.weight.blue = BitsSet(pMode->blue_mask);
+ /* RivaModeInit() will set the mode field */
+ RivaSwitchMode(index, pMode->mode, 0);
+ }
+
+ return TRUE;
+}
+
+
+
+static int
+Riva_GetViewport(
+ ScrnInfoPtr pScrn
+){
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ return pRiva->DGAViewportStatus;
+}
+
+static void
+Riva_SetViewport(
+ ScrnInfoPtr pScrn,
+ int x, int y,
+ int flags
+){
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ RivaAdjustFrame(pScrn->pScreen->myNum, x, y, flags);
+
+ while(VGA_RD08(pRiva->riva.PCIO, 0x3da) & 0x08);
+ while(!(VGA_RD08(pRiva->riva.PCIO, 0x3da) & 0x08));
+
+ pRiva->DGAViewportStatus = 0;
+}
+
+static void
+Riva_FillRect (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned long color
+){
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ if(!pRiva->AccelInfoRec) return;
+
+ (*pRiva->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0);
+ (*pRiva->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
+
+ SET_SYNC_FLAG(pRiva->AccelInfoRec);
+}
+
+static void
+Riva_BlitRect(
+ ScrnInfoPtr pScrn,
+ int srcx, int srcy,
+ int w, int h,
+ int dstx, int dsty
+){
+ RivaPtr pRiva = RivaPTR(pScrn);
+ int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
+ int ydir = (srcy < dsty) ? -1 : 1;
+
+ if(!pRiva->AccelInfoRec) return;
+
+ (*pRiva->AccelInfoRec->SetupForScreenToScreenCopy)(
+ pScrn, xdir, ydir, GXcopy, ~0, -1);
+
+ (*pRiva->AccelInfoRec->SubsequentScreenToScreenCopy)(
+ pScrn, srcx, srcy, dstx, dsty, w, h);
+
+ SET_SYNC_FLAG(pRiva->AccelInfoRec);
+}
+
+
+static void
+Riva_BlitTransRect(
+ ScrnInfoPtr pScrn,
+ int srcx, int srcy,
+ int w, int h,
+ int dstx, int dsty,
+ unsigned long color
+){
+ /* not implemented... yet */
+}
+
+
+static Bool
+Riva_OpenFramebuffer(
+ ScrnInfoPtr pScrn,
+ char **name,
+ unsigned char **mem,
+ int *size,
+ int *offset,
+ int *flags
+){
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ *name = NULL; /* no special device */
+ *mem = (unsigned char*)pRiva->FbAddress;
+ *size = pRiva->FbMapSize;
+ *offset = 0;
+ *flags = DGA_NEED_ROOT;
+
+ return TRUE;
+}
diff --git a/src/riva_driver.c b/src/riva_driver.c
new file mode 100644
index 0000000..1b4ca07
--- /dev/null
+++ b/src/riva_driver.c
@@ -0,0 +1,1384 @@
+/*
+ * 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/riva_driver.c,v 1.5 2003/11/03 05:11:26 tsi Exp $ */
+
+#include "riva_include.h"
+
+#include "xf86int10.h"
+
+/*
+ * Forward definitions for the functions that make up the driver.
+ */
+/* Mandatory functions */
+static Bool RivaPreInit(ScrnInfoPtr pScrn, int flags);
+static Bool RivaScreenInit(int Index, ScreenPtr pScreen, int argc,
+ char **argv);
+static Bool RivaEnterVT(int scrnIndex, int flags);
+static Bool RivaEnterVTFBDev(int scrnIndex, int flags);
+static void RivaLeaveVT(int scrnIndex, int flags);
+static Bool RivaCloseScreen(int scrnIndex, ScreenPtr pScreen);
+static Bool RivaSaveScreen(ScreenPtr pScreen, int mode);
+
+/* Optional functions */
+static void RivaFreeScreen(int scrnIndex, int flags);
+static ModeStatus RivaValidMode(int scrnIndex, DisplayModePtr mode,
+ Bool verbose, int flags);
+
+/* Internally used functions */
+
+static Bool RivaMapMem(ScrnInfoPtr pScrn);
+static Bool RivaMapMemFBDev(ScrnInfoPtr pScrn);
+static Bool RivaUnmapMem(ScrnInfoPtr pScrn);
+static void RivaSave(ScrnInfoPtr pScrn);
+static void RivaRestore(ScrnInfoPtr pScrn);
+static Bool RivaModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+
+
+/*
+ * 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[] = {
+ "vgaHWUnmapMem",
+ "vgaHWDPMSSet",
+ "vgaHWFreeHWRec",
+ "vgaHWGetHWRec",
+ "vgaHWGetIndex",
+ "vgaHWInit",
+ "vgaHWMapMem",
+ "vgaHWProtect",
+ "vgaHWRestore",
+ "vgaHWSave",
+ "vgaHWSaveScreen",
+ 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
+};
+
+static const char *ddcSymbols[] = {
+ "xf86PrintEDID",
+ "xf86DoEDID_DDC2",
+ "xf86SetDDCproperties",
+ NULL
+};
+
+#ifdef XFree86LOADER
+static const char *vbeSymbols[] = {
+ "VBEInit",
+ "vbeFree",
+ "vbeDoEDID",
+ NULL
+};
+#endif
+
+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(rivaSetup);
+
+static XF86ModuleVersionInfo rivaVersRec =
+{
+ "riva",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ RIVA_MAJOR_VERSION, RIVA_MINOR_VERSION, RIVA_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV, /* This is a video driver */
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0,0,0,0}
+};
+
+XF86ModuleData riva128ModuleData = { &rivaVersRec, rivaSetup, NULL };
+#endif
+
+
+typedef enum {
+ OPTION_SW_CURSOR,
+ OPTION_HW_CURSOR,
+ OPTION_NOACCEL,
+ OPTION_SHOWCACHE,
+ OPTION_SHADOW_FB,
+ OPTION_FBDEV,
+ OPTION_ROTATE
+} RivaOpts;
+
+
+static const OptionInfoRec RivaOptions[] = {
+ { 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 },
+ { -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 RivaRamdacRec DacInit = {
+ FALSE, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL,
+ 0, NULL, NULL, NULL, NULL
+};
+
+
+
+static Bool
+RivaGetRec(ScrnInfoPtr pScrn)
+{
+ /*
+ * Allocate an RivaRec, 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(RivaRec), 1);
+ /* Initialise it */
+
+ RivaPTR(pScrn)->Dac = DacInit;
+ return TRUE;
+}
+
+static void
+RivaFreeRec(ScrnInfoPtr pScrn)
+{
+ if (pScrn->driverPrivate == NULL)
+ return;
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+}
+
+
+#ifdef XFree86LOADER
+
+static pointer
+rivaSetup(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;
+
+ LoaderRefSymLists(vgahwSymbols, xaaSymbols, fbSymbols,
+ ramdacSymbols, shadowSymbols,
+ i2cSymbols, ddcSymbols, vbeSymbols,
+ fbdevHWSymbols, int10Symbols, NULL);
+ }
+ return (pointer)1;
+}
+
+
+#endif /* XFree86LOADER */
+
+const OptionInfoRec *
+RivaAvailableOptions(int chipid, int busid)
+{
+ return RivaOptions;
+}
+
+
+Bool
+RivaGetScrnInfoRec(PciChipsets *chips, int chip)
+{
+ ScrnInfoPtr pScrn;
+
+ pScrn = xf86ConfigPciEntity(NULL, 0, chip,
+ chips, NULL, NULL, NULL,
+ NULL, NULL);
+
+ if(!pScrn) return FALSE;
+
+ pScrn->driverVersion = RIVA_VERSION;
+ pScrn->driverName = RIVA_DRIVER_NAME;
+ pScrn->name = RIVA_NAME;
+
+ pScrn->Probe = NULL;
+ pScrn->PreInit = RivaPreInit;
+ pScrn->ScreenInit = RivaScreenInit;
+ pScrn->SwitchMode = RivaSwitchMode;
+ pScrn->AdjustFrame = RivaAdjustFrame;
+ pScrn->EnterVT = RivaEnterVT;
+ pScrn->LeaveVT = RivaLeaveVT;
+ pScrn->FreeScreen = RivaFreeScreen;
+ pScrn->ValidMode = RivaValidMode;
+
+ return TRUE;
+}
+
+/* Usually mandatory */
+Bool
+RivaSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ return RivaModeInit(xf86Screens[scrnIndex], mode);
+}
+
+/*
+ * This function is used to initialize the Start Address - the first
+ * displayed location in the video memory.
+ */
+/* Usually mandatory */
+void
+RivaAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ int startAddr;
+ RivaPtr pRiva = RivaPTR(pScrn);
+ RivaFBLayout *pLayout = &pRiva->CurrentLayout;
+
+ if(pRiva->ShowCache && y && pScrn->vtSema)
+ y += pScrn->virtualY - 1;
+
+ startAddr = (((y*pLayout->displayWidth)+x)*(pLayout->bitsPerPixel/8));
+ pRiva->riva.SetStartAddress(&pRiva->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
+RivaEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+
+ if (!RivaModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+ RivaAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ return TRUE;
+}
+
+static Bool
+RivaEnterVTFBDev(int scrnIndex, int flags)
+{
+ 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
+RivaLeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ RivaRestore(pScrn);
+ pRiva->riva.LockUnlock(&pRiva->riva, 1);
+}
+
+
+
+/*
+ * 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
+RivaCloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ if (pScrn->vtSema) {
+ RivaRestore(pScrn);
+ pRiva->riva.LockUnlock(&pRiva->riva, 1);
+ }
+
+ RivaUnmapMem(pScrn);
+ vgaHWUnmapMem(pScrn);
+ if (pRiva->AccelInfoRec)
+ XAADestroyInfoRec(pRiva->AccelInfoRec);
+ if (pRiva->CursorInfoRec)
+ xf86DestroyCursorInfoRec(pRiva->CursorInfoRec);
+ if (pRiva->ShadowPtr)
+ xfree(pRiva->ShadowPtr);
+ if (pRiva->DGAModes)
+ xfree(pRiva->DGAModes);
+ if ( pRiva->expandBuffer )
+ xfree(pRiva->expandBuffer);
+
+ pScrn->vtSema = FALSE;
+ pScreen->CloseScreen = pRiva->CloseScreen;
+ return (*pScreen->CloseScreen)(scrnIndex, pScreen);
+}
+
+/* Free up any persistent data structures */
+
+/* Optional */
+static void
+RivaFreeScreen(int scrnIndex, int flags)
+{
+ /*
+ * 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]);
+ RivaFreeRec(xf86Screens[scrnIndex]);
+}
+
+
+/* Checks if a mode is suitable for the selected chipset. */
+
+/* Optional */
+static ModeStatus
+RivaValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+{
+ return (MODE_OK);
+}
+
+static void
+rivaProbeDDC(ScrnInfoPtr pScrn, int index)
+{
+ vbeInfoPtr pVbe;
+
+ if (xf86LoadSubModule(pScrn, "vbe")) {
+ pVbe = VBEInit(NULL,index);
+ ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
+ vbeFree(pVbe);
+ }
+}
+
+
+Bool RivaI2CInit(ScrnInfoPtr pScrn)
+{
+ char *mod = "i2c";
+
+ if (xf86LoadSubModule(pScrn, mod)) {
+ xf86LoaderReqSymLists(i2cSymbols,NULL);
+
+ mod = "ddc";
+ if(xf86LoadSubModule(pScrn, mod)) {
+ xf86LoaderReqSymLists(ddcSymbols, NULL);
+ return RivaDACi2cInit(pScrn);
+ }
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Couldn't load %s module. DDC probing can't be done\n", mod);
+
+ return FALSE;
+}
+
+/* Mandatory */
+Bool
+RivaPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ RivaPtr pRiva;
+ MessageType from;
+ int i;
+ ClockRangePtr clockRanges;
+ const char *s;
+
+ if (flags & PROBE_DETECT) {
+ rivaProbeDDC( pScrn, xf86GetEntityInfo(pScrn->entityList[0])->index );
+ return TRUE;
+ }
+
+ /*
+ * 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 RivaRec driverPrivate */
+ if (!RivaGetRec(pScrn)) {
+ return FALSE;
+ }
+ pRiva = RivaPTR(pScrn);
+
+ /* Get the entity, and make sure it is PCI. */
+ pRiva->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+ if (pRiva->pEnt->location.type != BUS_PCI)
+ return FALSE;
+
+ /* Find the PCI info for this screen */
+ pRiva->PciInfo = xf86GetPciInfoForEntity(pRiva->pEnt->index);
+ pRiva->PciTag = pciTag(pRiva->PciInfo->bus, pRiva->PciInfo->device,
+ pRiva->PciInfo->func);
+
+ pRiva->Primary = xf86IsPrimaryPci(pRiva->PciInfo);
+
+ /* Initialize the card through int10 interface if needed */
+ if (xf86LoadSubModule(pScrn, "int10")) {
+ xf86LoaderReqSymLists(int10Symbols, NULL);
+#if !defined(__alpha__)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initializing int10\n");
+ pRiva->pInt = xf86InitInt10(pRiva->pEnt->index);
+#endif
+ }
+
+ xf86SetOperatingState(resVgaIo, pRiva->pEnt->index, ResUnusedOpr);
+ xf86SetOperatingState(resVgaMem, pRiva->pEnt->index, ResDisableOpr);
+
+ /* Set pScrn->monitor */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ pRiva->ChipRev = pRiva->PciInfo->chipRev;
+ if((pRiva->PciInfo->vendor != 0x12D2) || (pRiva->PciInfo->chipType != 0x0018))
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "This is not a RIVA 128\n");
+ xf86FreeInt10(pRiva->pInt);
+ return FALSE;
+ }
+
+ pScrn->chipset = "RIVA 128";
+
+ /*
+ * The first thing we should figure out is the depth, bpp, etc.
+ */
+
+ if (!xf86SetDepthBpp(pScrn, 15, 0, 0, Support32bppFb)) {
+ xf86FreeInt10(pRiva->pInt);
+ return FALSE;
+ } else {
+ /* Check that the returned depth is one we support */
+ switch (pScrn->depth) {
+ case 8:
+ case 15:
+ case 24:
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by this driver\n",
+ pScrn->depth);
+ xf86FreeInt10(pRiva->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(pRiva->pInt);
+ return FALSE;
+ }
+ }
+
+ if (!xf86SetDefaultVisual(pScrn, -1)) {
+ xf86FreeInt10(pRiva->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(pRiva->pInt);
+ return FALSE;
+ }
+ }
+
+ /* The vgahw module should be loaded here when needed */
+ if (!xf86LoadSubModule(pScrn, "vgahw")) {
+ xf86FreeInt10(pRiva->pInt);
+ return FALSE;
+ }
+
+ xf86LoaderReqSymLists(vgahwSymbols, NULL);
+
+ /*
+ * Allocate a vgaHWRec
+ */
+ if (!vgaHWGetHWRec(pScrn)) {
+ xf86FreeInt10(pRiva->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 (!(pRiva->Options = xalloc(sizeof(RivaOptions))))
+ return FALSE;
+ memcpy(pRiva->Options, RivaOptions, sizeof(RivaOptions));
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pRiva->Options);
+
+ /* Set the bits per RGB for 8bpp mode */
+ if (pScrn->depth == 8)
+ pScrn->rgbBits = 8;
+
+ from = X_DEFAULT;
+ pRiva->HWCursor = TRUE;
+ /*
+ * The preferred method is to use the "hw cursor" option as a tri-state
+ * option, with the default set above.
+ */
+ if (xf86GetOptValBool(pRiva->Options, OPTION_HW_CURSOR, &pRiva->HWCursor)) {
+ from = X_CONFIG;
+ }
+ /* For compatibility, accept this too (as an override) */
+ if (xf86ReturnOptValBool(pRiva->Options, OPTION_SW_CURSOR, FALSE)) {
+ from = X_CONFIG;
+ pRiva->HWCursor = FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
+ pRiva->HWCursor ? "HW" : "SW");
+ if (xf86ReturnOptValBool(pRiva->Options, OPTION_NOACCEL, FALSE)) {
+ pRiva->NoAccel = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
+ }
+ if (xf86ReturnOptValBool(pRiva->Options, OPTION_SHOWCACHE, FALSE)) {
+ pRiva->ShowCache = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShowCache enabled\n");
+ }
+ if (xf86ReturnOptValBool(pRiva->Options, OPTION_SHADOW_FB, FALSE)) {
+ pRiva->ShadowFB = TRUE;
+ pRiva->NoAccel = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using \"Shadow Framebuffer\" - acceleration disabled\n");
+ }
+ if (xf86ReturnOptValBool(pRiva->Options, OPTION_FBDEV, FALSE)) {
+ pRiva->FBDev = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using framebuffer device\n");
+ }
+ if (pRiva->FBDev) {
+ /* check for linux framebuffer device */
+ if (!xf86LoadSubModule(pScrn, "fbdevhw")) {
+ xf86FreeInt10(pRiva->pInt);
+ return FALSE;
+ }
+
+ xf86LoaderReqSymLists(fbdevHWSymbols, NULL);
+ if (!fbdevHWInit(pScrn, pRiva->PciInfo, NULL)) {
+ xf86FreeInt10(pRiva->pInt);
+ return FALSE;
+ }
+ pScrn->SwitchMode = fbdevHWSwitchMode;
+ pScrn->AdjustFrame = fbdevHWAdjustFrame;
+ pScrn->EnterVT = RivaEnterVTFBDev;
+ pScrn->LeaveVT = fbdevHWLeaveVT;
+ pScrn->ValidMode = fbdevHWValidMode;
+ }
+ pRiva->Rotate = 0;
+ if ((s = xf86GetOptValString(pRiva->Options, OPTION_ROTATE))) {
+ if(!xf86NameCmp(s, "CW")) {
+ pRiva->ShadowFB = TRUE;
+ pRiva->NoAccel = TRUE;
+ pRiva->HWCursor = FALSE;
+ pRiva->Rotate = 1;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Rotating screen clockwise - acceleration disabled\n");
+ } else
+ if(!xf86NameCmp(s, "CCW")) {
+ pRiva->ShadowFB = TRUE;
+ pRiva->NoAccel = TRUE;
+ pRiva->HWCursor = FALSE;
+ pRiva->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 (pRiva->pEnt->device->MemBase != 0) {
+ /* Require that the config file value matches one of the PCI values. */
+ if (!xf86CheckPciMemBase(pRiva->PciInfo, pRiva->pEnt->device->MemBase)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "MemBase 0x%08lX doesn't match any PCI base register.\n",
+ pRiva->pEnt->device->MemBase);
+ xf86FreeInt10(pRiva->pInt);
+ RivaFreeRec(pScrn);
+ return FALSE;
+ }
+ pRiva->FbAddress = pRiva->pEnt->device->MemBase;
+ from = X_CONFIG;
+ } else {
+ int i = 1;
+ pRiva->FbBaseReg = i;
+ if (pRiva->PciInfo->memBase[i] != 0) {
+ pRiva->FbAddress = pRiva->PciInfo->memBase[i] & 0xff800000;
+ from = X_PROBED;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No valid FB address in PCI config space\n");
+ xf86FreeInt10(pRiva->pInt);
+ RivaFreeRec(pScrn);
+ return FALSE;
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
+ (unsigned long)pRiva->FbAddress);
+
+ if (pRiva->pEnt->device->IOBase != 0) {
+ /* Require that the config file value matches one of the PCI values. */
+ if (!xf86CheckPciMemBase(pRiva->PciInfo, pRiva->pEnt->device->IOBase)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "IOBase 0x%08lX doesn't match any PCI base register.\n",
+ pRiva->pEnt->device->IOBase);
+ xf86FreeInt10(pRiva->pInt);
+ RivaFreeRec(pScrn);
+ return FALSE;
+ }
+ pRiva->IOAddress = pRiva->pEnt->device->IOBase;
+ from = X_CONFIG;
+ } else {
+ int i = 0;
+ if (pRiva->PciInfo->memBase[i] != 0) {
+ pRiva->IOAddress = pRiva->PciInfo->memBase[i] & 0xffffc000;
+ from = X_PROBED;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No valid MMIO address in PCI config space\n");
+ xf86FreeInt10(pRiva->pInt);
+ RivaFreeRec(pScrn);
+ return FALSE;
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n",
+ (unsigned long)pRiva->IOAddress);
+
+ if (xf86RegisterResources(pRiva->pEnt->index, NULL, ResExclusive)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "xf86RegisterResources() found resource conflicts\n");
+ xf86FreeInt10(pRiva->pInt);
+ RivaFreeRec(pScrn);
+ return FALSE;
+ }
+
+ Riva3Setup(pScrn);
+
+ /*
+ * If the user has specified the amount of memory in the XF86Config
+ * file, we respect that setting.
+ */
+ if (pRiva->pEnt->device->videoRam != 0) {
+ pScrn->videoRam = pRiva->pEnt->device->videoRam;
+ from = X_CONFIG;
+ } else {
+ if (pRiva->FBDev) {
+ pScrn->videoRam = fbdevHWGetVidmem(pScrn)/1024;
+ } else {
+ pScrn->videoRam = pRiva->riva.RamAmountKBytes;
+ }
+ from = X_PROBED;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kBytes\n",
+ pScrn->videoRam);
+
+ pRiva->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(pRiva->pInt);
+ return FALSE;
+ }
+ }
+
+ pRiva->FbUsableSize = pRiva->FbMapSize - (32 * 1024);
+
+ /*
+ * Setup the ClockRanges, which describe what clock ranges are available,
+ * and what sort of modes they can be used for.
+ */
+
+ pRiva->MinClock = 12000;
+ pRiva->MaxClock = pRiva->riva.MaxVClockFreqKHz;
+
+ clockRanges = xnfcalloc(sizeof(ClockRange), 1);
+ clockRanges->next = NULL;
+ clockRanges->minClock = pRiva->MinClock;
+ clockRanges->maxClock = pRiva->MaxClock;
+ clockRanges->clockIndex = -1; /* programmable */
+ clockRanges->interlaceAllowed = TRUE;
+ clockRanges->doubleScanAllowed = TRUE;
+
+
+ /*
+ * 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 RivaValidMode() 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,
+ pRiva->FbUsableSize,
+ LOOKUP_BEST_REFRESH);
+
+ if (i < 1 && pRiva->FBDev) {
+ fbdevHWUseBuildinMode(pScrn);
+ pScrn->displayWidth = pScrn->virtualX; /* FIXME: might be wrong */
+ i = 1;
+ }
+ if (i == -1) {
+ xf86FreeInt10(pRiva->pInt);
+ RivaFreeRec(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(pRiva->pInt);
+ RivaFreeRec(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(pRiva->pInt);
+ RivaFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86LoaderReqSymLists(fbSymbols, NULL);
+
+ /* Load XAA if needed */
+ if (!pRiva->NoAccel) {
+ if (!xf86LoadSubModule(pScrn, "xaa")) {
+ xf86FreeInt10(pRiva->pInt);
+ RivaFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(xaaSymbols, NULL);
+ }
+
+ /* Load ramdac if needed */
+ if (pRiva->HWCursor) {
+ if (!xf86LoadSubModule(pScrn, "ramdac")) {
+ xf86FreeInt10(pRiva->pInt);
+ RivaFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(ramdacSymbols, NULL);
+ }
+
+ /* Load shadowfb if needed */
+ if (pRiva->ShadowFB) {
+ if (!xf86LoadSubModule(pScrn, "shadowfb")) {
+ xf86FreeInt10(pRiva->pInt);
+ RivaFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(shadowSymbols, NULL);
+ }
+
+ pRiva->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel;
+ pRiva->CurrentLayout.depth = pScrn->depth;
+ pRiva->CurrentLayout.displayWidth = pScrn->displayWidth;
+ pRiva->CurrentLayout.weight.red = pScrn->weight.red;
+ pRiva->CurrentLayout.weight.green = pScrn->weight.green;
+ pRiva->CurrentLayout.weight.blue = pScrn->weight.blue;
+ pRiva->CurrentLayout.mode = pScrn->currentMode;
+
+ xf86FreeInt10(pRiva->pInt);
+
+ pRiva->pInt = NULL;
+ return TRUE;
+}
+
+
+/*
+ * Map the framebuffer and MMIO memory.
+ */
+
+static Bool
+RivaMapMem(ScrnInfoPtr pScrn)
+{
+ RivaPtr pRiva;
+
+ pRiva = RivaPTR(pScrn);
+
+ /*
+ * Map IO registers to virtual address space
+ */
+ pRiva->IOBase = xf86MapPciMem(pScrn->scrnIndex,
+ VIDMEM_MMIO | VIDMEM_READSIDEEFFECT,
+ pRiva->PciTag, pRiva->IOAddress, 0x1000000);
+ if (pRiva->IOBase == NULL)
+ return FALSE;
+
+ pRiva->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
+ pRiva->PciTag, pRiva->FbAddress,
+ pRiva->FbMapSize);
+ if (pRiva->FbBase == NULL)
+ return FALSE;
+
+ pRiva->FbStart = pRiva->FbBase;
+
+ return TRUE;
+}
+
+Bool
+RivaMapMemFBDev(ScrnInfoPtr pScrn)
+{
+ RivaPtr pRiva;
+
+ pRiva = RivaPTR(pScrn);
+
+ pRiva->FbBase = fbdevHWMapVidmem(pScrn);
+ if (pRiva->FbBase == NULL)
+ return FALSE;
+
+ pRiva->IOBase = fbdevHWMapMMIO(pScrn);
+ if (pRiva->IOBase == NULL)
+ return FALSE;
+
+ pRiva->FbStart = pRiva->FbBase;
+
+ return TRUE;
+}
+
+/*
+ * Unmap the framebuffer and MMIO memory.
+ */
+
+static Bool
+RivaUnmapMem(ScrnInfoPtr pScrn)
+{
+ RivaPtr pRiva;
+
+ pRiva = RivaPTR(pScrn);
+
+ /*
+ * Unmap IO registers to virtual address space
+ */
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pRiva->IOBase, 0x1000000);
+ pRiva->IOBase = NULL;
+
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pRiva->FbBase, pRiva->FbMapSize);
+ pRiva->FbBase = NULL;
+ pRiva->FbStart = NULL;
+
+ return TRUE;
+}
+
+
+/*
+ * Initialise a new mode.
+ */
+
+static Bool
+RivaModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ vgaRegPtr vgaReg;
+ RivaPtr pRiva = RivaPTR(pScrn);
+ RivaRegPtr rivaReg;
+
+
+ /* Initialise the ModeReg values */
+ if (!vgaHWInit(pScrn, mode))
+ return FALSE;
+ pScrn->vtSema = TRUE;
+
+ vgaReg = &hwp->ModeReg;
+ rivaReg = &pRiva->ModeReg;
+
+ if(!(*pRiva->ModeInit)(pScrn, mode))
+ return FALSE;
+
+ pRiva->riva.LockUnlock(&pRiva->riva, 0);
+
+ /* Program the registers */
+ vgaHWProtect(pScrn, TRUE);
+
+ (*pRiva->Restore)(pScrn, vgaReg, rivaReg, FALSE);
+
+ RivaResetGraphics(pScrn);
+
+ vgaHWProtect(pScrn, FALSE);
+
+ pRiva->CurrentLayout.mode = mode;
+
+ return TRUE;
+}
+
+/*
+ * Restore the initial (text) mode.
+ */
+static void
+RivaRestore(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ vgaRegPtr vgaReg = &hwp->SavedReg;
+ RivaPtr pRiva = RivaPTR(pScrn);
+ RivaRegPtr rivaReg = &pRiva->SavedReg;
+
+
+ pRiva->riva.LockUnlock(&pRiva->riva, 0);
+
+ /* Only restore text mode fonts/text for the primary card */
+ vgaHWProtect(pScrn, TRUE);
+ (*pRiva->Restore)(pScrn, vgaReg, rivaReg, pRiva->Primary);
+ vgaHWProtect(pScrn, FALSE);
+}
+
+static void
+RivaDPMSSet(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;
+ }
+
+ /* vgaHWDPMSSet will merely cut the dac output */
+ vgaHWDPMSSet(pScrn, PowerManagementMode, flags);
+
+ hwp->writeCrtc(hwp, 0x1A, crtc1A);
+}
+
+
+/* Mandatory */
+
+/* This gets called at the start of each server generation */
+
+static Bool
+RivaScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ ScrnInfoPtr pScrn;
+ vgaHWPtr hwp;
+ RivaPtr pRiva;
+ RivaRamdacPtr Rivadac;
+ int ret;
+ VisualPtr visual;
+ unsigned char *FBStart;
+ int width, height, displayWidth;
+ BoxRec AvailFBArea;
+
+ /*
+ * First get the ScrnInfoRec
+ */
+ pScrn = xf86Screens[pScreen->myNum];
+
+
+ hwp = VGAHWPTR(pScrn);
+ pRiva = RivaPTR(pScrn);
+ Rivadac = &pRiva->Dac;
+
+ /* Map the Riva memory and MMIO areas */
+ if (pRiva->FBDev) {
+ if (!RivaMapMemFBDev(pScrn))
+ return FALSE;
+ } else {
+ if (!RivaMapMem(pScrn))
+ return FALSE;
+ }
+
+ /* Map the VGA memory when the primary video */
+ if (pRiva->Primary && !pRiva->FBDev) {
+ hwp->MapSize = 0x10000;
+ if (!vgaHWMapMem(pScrn))
+ return FALSE;
+ }
+
+ if (pRiva->FBDev) {
+ fbdevHWSave(pScrn);
+ if (!fbdevHWModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+ } else {
+ /* Save the current state */
+ RivaSave(pScrn);
+ /* Initialise the first mode */
+ if (!RivaModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+ }
+
+
+ /* Darken the screen for aesthetic reasons and set the viewport */
+ RivaSaveScreen(pScreen, SCREEN_SAVER_ON);
+ pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+
+ /*
+ * 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) {
+ 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;
+
+
+ /*
+ * Call the framebuffer layer's ScreenInit function, and fill in other
+ * pScreen fields.
+ */
+
+ width = pScrn->virtualX;
+ height = pScrn->virtualY;
+ displayWidth = pScrn->displayWidth;
+
+
+ if(pRiva->Rotate) {
+ height = pScrn->virtualX;
+ width = pScrn->virtualY;
+ }
+
+ if(pRiva->ShadowFB) {
+ pRiva->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
+ pRiva->ShadowPtr = xalloc(pRiva->ShadowPitch * height);
+ displayWidth = pRiva->ShadowPitch / (pScrn->bitsPerPixel >> 3);
+ FBStart = pRiva->ShadowPtr;
+ } else {
+ pRiva->ShadowPtr = NULL;
+ FBStart = pRiva->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 RivaScreenInit\n",
+ pScrn->bitsPerPixel);
+ ret = FALSE;
+ break;
+ }
+ if (!ret)
+ return FALSE;
+
+
+ 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);
+
+
+ if(!pRiva->ShadowFB) /* hardware cursor needs to wrap this layer */
+ RivaDGAInit(pScreen);
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pScrn->displayWidth;
+ AvailFBArea.y2 = (min(pRiva->FbUsableSize, 32*1024*1024)) /
+ (pScrn->displayWidth * pScrn->bitsPerPixel / 8);
+ xf86InitFBManager(pScreen, &AvailFBArea);
+
+ if (!pRiva->NoAccel)
+ RivaAccelInit(pScreen);
+
+ miInitializeBackingStore(pScreen);
+ xf86SetBackingStore(pScreen);
+ xf86SetSilkenMouse(pScreen);
+
+
+ /* Initialize software cursor.
+ Must precede creation of the default colormap */
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+
+
+ /* Initialize HW cursor layer.
+ Must follow software cursor initialization*/
+ if (pRiva->HWCursor) {
+ if(!RivaCursorInit(pScreen))
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Hardware cursor initialization failed\n");
+ }
+
+ /* Initialise default colourmap */
+ if (!miCreateDefColormap(pScreen))
+ return FALSE;
+
+
+ /* Initialize colormap layer.
+ Must follow initialization of the default colormap */
+ if(!xf86HandleColormaps(pScreen, 256, 8,
+ (pRiva->FBDev ? fbdevHWLoadPalette : Rivadac->LoadPalette),
+ NULL, CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR))
+ return FALSE;
+
+
+ if(pRiva->ShadowFB) {
+ RefreshAreaFuncPtr refreshArea = RivaRefreshArea;
+
+ if(pRiva->Rotate) {
+ pRiva->PointerMoved = pScrn->PointerMoved;
+ pScrn->PointerMoved = RivaPointerMoved;
+
+ switch(pScrn->bitsPerPixel) {
+ case 8: refreshArea = RivaRefreshArea8; break;
+ case 16: refreshArea = RivaRefreshArea16; break;
+ case 32: refreshArea = RivaRefreshArea32; break;
+ }
+ }
+
+ ShadowFBInit(pScreen, refreshArea);
+ }
+
+ xf86DPMSInit(pScreen, RivaDPMSSet, 0);
+
+
+ pScrn->memPhysBase = pRiva->FbAddress;
+ pScrn->fbOffset = 0;
+
+ pScreen->SaveScreen = RivaSaveScreen;
+
+ /* Wrap the current CloseScreen function */
+ pRiva->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = RivaCloseScreen;
+
+ /* Report any unused options (only for the first generation) */
+ if (serverGeneration == 1) {
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+ }
+ /* Done */
+ return TRUE;
+}
+
+/* Free up any persistent data structures */
+
+
+/* Do screen blanking */
+
+/* Mandatory */
+static Bool
+RivaSaveScreen(ScreenPtr pScreen, int mode)
+{
+ return vgaHWSaveScreen(pScreen, mode);
+}
+
+static void
+RivaSave(ScrnInfoPtr pScrn)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+ RivaRegPtr rivaReg = &pRiva->SavedReg;
+ vgaHWPtr pVga = VGAHWPTR(pScrn);
+ vgaRegPtr vgaReg = &pVga->SavedReg;
+
+ (*pRiva->Save)(pScrn, vgaReg, rivaReg, pRiva->Primary);
+}
+
diff --git a/src/riva_include.h b/src/riva_include.h
new file mode 100644
index 0000000..e64d78f
--- /dev/null
+++ b/src/riva_include.h
@@ -0,0 +1,59 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_include.h,v 1.1 2003/07/31 20:24:31 mvojkovi Exp $ */
+
+#ifndef __RIVA_INCLUDE_H__
+#define __RIVA_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 "riva_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 "riva_local.h"
+#include "riva_type.h"
+#include "riva_proto.h"
+
+#endif /* __RIVA_INCLUDE_H__ */
diff --git a/src/riva_local.h b/src/riva_local.h
new file mode 100644
index 0000000..efe0c7e
--- /dev/null
+++ b/src/riva_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/riva_local.h,v 1.2 2003/11/03 05:11:26 tsi Exp $ */
+
+#ifndef __RIVA_LOCAL_H__
+#define __RIVA_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 RIVA_WR08(p,i,d) MMIO_OUT8((pointer)(p), (i), (d))
+#define RIVA_RD08(p,i) MMIO_IN8((pointer)(p), (i))
+#define RIVA_WR16(p,i,d) MMIO_OUT16((pointer)(p), (i), (d))
+#define RIVA_RD16(p,i) MMIO_IN16((pointer)(p), (i))
+#define RIVA_WR32(p,i,d) MMIO_OUT32((pointer)(p), (i), (d))
+#define RIVA_RD32(p,i) MMIO_IN32((pointer)(p), (i))
+
+/* VGA I/O is now always done through MMIO */
+#define VGA_WR08(p,i,d) RIVA_WR08(p,i,d)
+#define VGA_RD08(p,i) RIVA_RD08(p,i)
+
+#endif /* __RIVA_LOCAL_H__ */
diff --git a/src/riva_proto.h b/src/riva_proto.h
new file mode 100644
index 0000000..75f5d01
--- /dev/null
+++ b/src/riva_proto.h
@@ -0,0 +1,41 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_proto.h,v 1.1 2003/07/31 20:24:31 mvojkovi Exp $ */
+
+#ifndef __RIVA_PROTO_H__
+#define __RIVA_PROTO_H__
+
+/* in riva_driver.c */
+Bool RivaSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
+void RivaAdjustFrame(int scrnIndex, int x, int y, int flags);
+Bool RivaI2CInit(ScrnInfoPtr pScrn);
+const OptionInfoRec * RivaAvailableOptions(int chipid, int busid);
+Bool RivaGetScrnInfoRec(PciChipsets *chips, int chip);
+
+/* in riva_dac.c */
+Bool RivaDACInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+void RivaDACSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg,
+ RivaRegPtr rivaReg, Bool saveFonts);
+void RivaDACRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg,
+ RivaRegPtr rivaReg, Bool restoreFonts);
+void RivaDACLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
+ LOCO *colors, VisualPtr pVisual );
+Bool RivaDACi2cInit(ScrnInfoPtr pScrn);
+
+
+/* in riva_setup.c */
+void RivaEnterLeave(ScrnInfoPtr pScrn, Bool enter);
+void Riva3Setup(ScrnInfoPtr pScrn);
+
+/* in riva_cursor.c */
+Bool RivaCursorInit(ScreenPtr pScreen);
+
+/* in riva_xaa.c */
+Bool RivaAccelInit(ScreenPtr pScreen);
+void RivaSync(ScrnInfoPtr pScrn);
+void RivaResetGraphics(ScrnInfoPtr pScrn);
+
+/* in riva_dga.c */
+Bool RivaDGAInit(ScreenPtr pScreen);
+
+
+#endif /* __RIVA_PROTO_H__ */
+
diff --git a/src/riva_setup.c b/src/riva_setup.c
new file mode 100644
index 0000000..6a0d32e
--- /dev/null
+++ b/src/riva_setup.c
@@ -0,0 +1,279 @@
+/*
+ * 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/riva_setup.c,v 1.1 2003/07/31 20:24:31 mvojkovi Exp $ */
+
+#include "riva_include.h"
+
+/*
+ * Override VGA I/O routines.
+ */
+static void RivaWriteCrtc(vgaHWPtr pVga, CARD8 index, CARD8 value)
+{
+ RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
+ VGA_WR08(pRiva->riva.PCIO, pVga->IOBase + VGA_CRTC_INDEX_OFFSET, index);
+ VGA_WR08(pRiva->riva.PCIO, pVga->IOBase + VGA_CRTC_DATA_OFFSET, value);
+}
+static CARD8 RivaReadCrtc(vgaHWPtr pVga, CARD8 index)
+{
+ RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
+ VGA_WR08(pRiva->riva.PCIO, pVga->IOBase + VGA_CRTC_INDEX_OFFSET, index);
+ return (VGA_RD08(pRiva->riva.PCIO, pVga->IOBase + VGA_CRTC_DATA_OFFSET));
+}
+static void RivaWriteGr(vgaHWPtr pVga, CARD8 index, CARD8 value)
+{
+ RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
+ VGA_WR08(pRiva->riva.PVIO, VGA_GRAPH_INDEX, index);
+ VGA_WR08(pRiva->riva.PVIO, VGA_GRAPH_DATA, value);
+}
+static CARD8 RivaReadGr(vgaHWPtr pVga, CARD8 index)
+{
+ RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
+ VGA_WR08(pRiva->riva.PVIO, VGA_GRAPH_INDEX, index);
+ return (VGA_RD08(pRiva->riva.PVIO, VGA_GRAPH_DATA));
+}
+static void RivaWriteSeq(vgaHWPtr pVga, CARD8 index, CARD8 value)
+{
+ RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
+ VGA_WR08(pRiva->riva.PVIO, VGA_SEQ_INDEX, index);
+ VGA_WR08(pRiva->riva.PVIO, VGA_SEQ_DATA, value);
+}
+static CARD8 RivaReadSeq(vgaHWPtr pVga, CARD8 index)
+{
+ RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
+ VGA_WR08(pRiva->riva.PVIO, VGA_SEQ_INDEX, index);
+ return (VGA_RD08(pRiva->riva.PVIO, VGA_SEQ_DATA));
+}
+static void RivaWriteAttr(vgaHWPtr pVga, CARD8 index, CARD8 value)
+{
+ RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
+ volatile CARD8 tmp;
+
+ tmp = VGA_RD08(pRiva->riva.PCIO, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
+ if (pVga->paletteEnabled)
+ index &= ~0x20;
+ else
+ index |= 0x20;
+ VGA_WR08(pRiva->riva.PCIO, VGA_ATTR_INDEX, index);
+ VGA_WR08(pRiva->riva.PCIO, VGA_ATTR_DATA_W, value);
+}
+static CARD8 RivaReadAttr(vgaHWPtr pVga, CARD8 index)
+{
+ RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
+ volatile CARD8 tmp;
+
+ tmp = VGA_RD08(pRiva->riva.PCIO, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
+ if (pVga->paletteEnabled)
+ index &= ~0x20;
+ else
+ index |= 0x20;
+ VGA_WR08(pRiva->riva.PCIO, VGA_ATTR_INDEX, index);
+ return (VGA_RD08(pRiva->riva.PCIO, VGA_ATTR_DATA_R));
+}
+static void RivaWriteMiscOut(vgaHWPtr pVga, CARD8 value)
+{
+ RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
+ VGA_WR08(pRiva->riva.PVIO, VGA_MISC_OUT_W, value);
+}
+static CARD8 RivaReadMiscOut(vgaHWPtr pVga)
+{
+ RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
+ return (VGA_RD08(pRiva->riva.PVIO, VGA_MISC_OUT_R));
+}
+static void RivaEnablePalette(vgaHWPtr pVga)
+{
+ RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
+ volatile CARD8 tmp;
+
+ tmp = VGA_RD08(pRiva->riva.PCIO, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
+ VGA_WR08(pRiva->riva.PCIO, VGA_ATTR_INDEX, 0x00);
+ pVga->paletteEnabled = TRUE;
+}
+static void RivaDisablePalette(vgaHWPtr pVga)
+{
+ RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
+ volatile CARD8 tmp;
+
+ tmp = VGA_RD08(pRiva->riva.PCIO, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
+ VGA_WR08(pRiva->riva.PCIO, VGA_ATTR_INDEX, 0x20);
+ pVga->paletteEnabled = FALSE;
+}
+static void RivaWriteDacMask(vgaHWPtr pVga, CARD8 value)
+{
+ RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
+ VGA_WR08(pRiva->riva.PDIO, VGA_DAC_MASK, value);
+}
+static CARD8 RivaReadDacMask(vgaHWPtr pVga)
+{
+ RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
+ return (VGA_RD08(pRiva->riva.PDIO, VGA_DAC_MASK));
+}
+static void RivaWriteDacReadAddr(vgaHWPtr pVga, CARD8 value)
+{
+ RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
+ VGA_WR08(pRiva->riva.PDIO, VGA_DAC_READ_ADDR, value);
+}
+static void RivaWriteDacWriteAddr(vgaHWPtr pVga, CARD8 value)
+{
+ RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
+ VGA_WR08(pRiva->riva.PDIO, VGA_DAC_WRITE_ADDR, value);
+}
+static void RivaWriteDacData(vgaHWPtr pVga, CARD8 value)
+{
+ RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
+ VGA_WR08(pRiva->riva.PDIO, VGA_DAC_DATA, value);
+}
+static CARD8 RivaReadDacData(vgaHWPtr pVga)
+{
+ RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
+ return (VGA_RD08(pRiva->riva.PDIO, VGA_DAC_DATA));
+}
+
+
+
+static xf86MonPtr
+RivaProbeDDC (ScrnInfoPtr pScrn)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+ xf86MonPtr MonInfo = NULL;
+
+ if(!pRiva->I2C) return NULL;
+
+ pRiva->DDCBase = 0x3e;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Probing for EDID...\n");
+
+ if ((MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, pRiva->I2C))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ " ... found one\n");
+ xf86PrintEDID( MonInfo );
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ " ... none found\n");
+ }
+
+ return MonInfo;
+}
+
+void
+Riva3Setup(ScrnInfoPtr pScrn)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+ vgaHWPtr pVga = VGAHWPTR(pScrn);
+ CARD32 regBase = pRiva->IOAddress;
+ CARD32 frameBase = pRiva->FbAddress;
+ xf86MonPtr monitor;
+ int mmioFlags;
+
+ pRiva->Save = RivaDACSave;
+ pRiva->Restore = RivaDACRestore;
+ pRiva->ModeInit = RivaDACInit;
+
+ pRiva->Dac.LoadPalette = RivaDACLoadPalette;
+
+ /*
+ * Override VGA I/O routines.
+ */
+ pVga->writeCrtc = RivaWriteCrtc;
+ pVga->readCrtc = RivaReadCrtc;
+ pVga->writeGr = RivaWriteGr;
+ pVga->readGr = RivaReadGr;
+ pVga->writeAttr = RivaWriteAttr;
+ pVga->readAttr = RivaReadAttr;
+ pVga->writeSeq = RivaWriteSeq;
+ pVga->readSeq = RivaReadSeq;
+ pVga->writeMiscOut = RivaWriteMiscOut;
+ pVga->readMiscOut = RivaReadMiscOut;
+ pVga->enablePalette = RivaEnablePalette;
+ pVga->disablePalette = RivaDisablePalette;
+ pVga->writeDacMask = RivaWriteDacMask;
+ pVga->readDacMask = RivaReadDacMask;
+ pVga->writeDacWriteAddr = RivaWriteDacWriteAddr;
+ pVga->writeDacReadAddr = RivaWriteDacReadAddr;
+ pVga->writeDacData = RivaWriteDacData;
+ pVga->readDacData = RivaReadDacData;
+ /*
+ * 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 *)pRiva;
+ pVga->MMIOOffset = 0;
+
+ /*
+ * No IRQ in use.
+ */
+ pRiva->riva.EnableIRQ = 0;
+ pRiva->riva.IO = VGA_IOBASE_COLOR;
+
+ mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT;
+
+ pRiva->riva.PRAMDAC = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pRiva->PciTag,
+ regBase+0x00680000, 0x00003000);
+ pRiva->riva.PFB = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pRiva->PciTag,
+ regBase+0x00100000, 0x00001000);
+ pRiva->riva.PFIFO = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pRiva->PciTag,
+ regBase+0x00002000, 0x00002000);
+ pRiva->riva.PGRAPH = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pRiva->PciTag,
+ regBase+0x00400000, 0x00002000);
+ pRiva->riva.PEXTDEV = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pRiva->PciTag,
+ regBase+0x00101000, 0x00001000);
+ pRiva->riva.PTIMER = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pRiva->PciTag,
+ regBase+0x00009000, 0x00001000);
+ pRiva->riva.PMC = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pRiva->PciTag,
+ regBase+0x00000000, 0x00009000);
+ pRiva->riva.FIFO = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pRiva->PciTag,
+ regBase+0x00800000, 0x00010000);
+ pRiva->riva.PRAMIN = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pRiva->PciTag,
+ frameBase+0x00C00000, 0x00008000);
+
+ /*
+ * These registers are read/write as 8 bit values. Probably have to map
+ * sparse on alpha.
+ */
+ pRiva->riva.PCIO = (U008 *)xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
+ pRiva->PciTag, regBase+0x00601000,
+ 0x00003000);
+ pRiva->riva.PDIO = (U008 *)xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
+ pRiva->PciTag, regBase+0x00681000,
+ 0x00003000);
+ pRiva->riva.PVIO = (U008 *)xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
+ pRiva->PciTag, regBase+0x000C0000,
+ 0x00001000);
+
+ pRiva->riva.PCRTC = pRiva->riva.PGRAPH;
+
+ RivaGetConfig(pRiva);
+
+ pRiva->riva.LockUnlock(&pRiva->riva, 0);
+
+ RivaI2CInit(pScrn);
+
+ monitor = RivaProbeDDC(pScrn);
+
+ if(monitor)
+ xf86SetDDCproperties(pScrn, monitor);
+
+ pRiva->Dac.maxPixelClock = pRiva->riva.MaxVClockFreqKHz;
+}
diff --git a/src/riva_shadow.c b/src/riva_shadow.c
new file mode 100644
index 0000000..90f1f12
--- /dev/null
+++ b/src/riva_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/riva_shadow.c,v 1.1 2003/07/31 20:24:31 mvojkovi Exp $ */
+
+#include "riva_local.h"
+#include "riva_include.h"
+#include "riva_type.h"
+#include "shadowfb.h"
+#include "servermd.h"
+
+
+void
+RivaRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ RivaPtr pRiva = RivaPTR(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 = pRiva->ShadowPtr + (pbox->y1 * pRiva->ShadowPitch) +
+ (pbox->x1 * Bpp);
+ dst = pRiva->FbStart + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp);
+
+ while(height--) {
+ memcpy(dst, src, width);
+ dst += FBPitch;
+ src += pRiva->ShadowPitch;
+ }
+
+ pbox++;
+ }
+}
+
+void
+RivaPointerMoved(int index, int x, int y)
+{
+ ScrnInfoPtr pScrn = xf86Screens[index];
+ RivaPtr pRiva = RivaPTR(pScrn);
+ int newX, newY;
+
+ if(pRiva->Rotate == 1) {
+ newX = pScrn->pScreen->height - y - 1;
+ newY = x;
+ } else {
+ newX = y;
+ newY = pScrn->pScreen->width - x - 1;
+ }
+
+ (*pRiva->PointerMoved)(index, newX, newY);
+}
+
+void
+RivaRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+ int count, width, height, y1, y2, dstPitch, srcPitch;
+ CARD8 *dstPtr, *srcPtr, *src;
+ CARD32 *dst;
+
+ dstPitch = pScrn->displayWidth;
+ srcPitch = -pRiva->Rotate * pRiva->ShadowPitch;
+
+ while(num--) {
+ width = pbox->x2 - pbox->x1;
+ y1 = pbox->y1 & ~3;
+ y2 = (pbox->y2 + 3) & ~3;
+ height = (y2 - y1) >> 2; /* in dwords */
+
+ if(pRiva->Rotate == 1) {
+ dstPtr = pRiva->FbStart +
+ (pbox->x1 * dstPitch) + pScrn->virtualX - y2;
+ srcPtr = pRiva->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1;
+ } else {
+ dstPtr = pRiva->FbStart +
+ ((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
+ srcPtr = pRiva->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 += pRiva->Rotate;
+ dstPtr += dstPitch;
+ }
+
+ pbox++;
+ }
+}
+
+
+void
+RivaRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+ int count, width, height, y1, y2, dstPitch, srcPitch;
+ CARD16 *dstPtr, *srcPtr, *src;
+ CARD32 *dst;
+
+ dstPitch = pScrn->displayWidth;
+ srcPitch = -pRiva->Rotate * pRiva->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(pRiva->Rotate == 1) {
+ dstPtr = (CARD16*)pRiva->FbStart +
+ (pbox->x1 * dstPitch) + pScrn->virtualX - y2;
+ srcPtr = (CARD16*)pRiva->ShadowPtr +
+ ((1 - y2) * srcPitch) + pbox->x1;
+ } else {
+ dstPtr = (CARD16*)pRiva->FbStart +
+ ((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
+ srcPtr = (CARD16*)pRiva->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 += pRiva->Rotate;
+ dstPtr += dstPitch;
+ }
+
+ pbox++;
+ }
+}
+
+
+void
+RivaRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+ int count, width, height, dstPitch, srcPitch;
+ CARD32 *dstPtr, *srcPtr, *src, *dst;
+
+ dstPitch = pScrn->displayWidth;
+ srcPitch = -pRiva->Rotate * pRiva->ShadowPitch >> 2;
+
+ while(num--) {
+ width = pbox->x2 - pbox->x1;
+ height = pbox->y2 - pbox->y1;
+
+ if(pRiva->Rotate == 1) {
+ dstPtr = (CARD32*)pRiva->FbStart +
+ (pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2;
+ srcPtr = (CARD32*)pRiva->ShadowPtr +
+ ((1 - pbox->y2) * srcPitch) + pbox->x1;
+ } else {
+ dstPtr = (CARD32*)pRiva->FbStart +
+ ((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1;
+ srcPtr = (CARD32*)pRiva->ShadowPtr +
+ (pbox->y1 * srcPitch) + pbox->x2 - 1;
+ }
+
+ while(width--) {
+ src = srcPtr;
+ dst = dstPtr;
+ count = height;
+ while(count--) {
+ *(dst++) = *src;
+ src += srcPitch;
+ }
+ srcPtr += pRiva->Rotate;
+ dstPtr += dstPitch;
+ }
+
+ pbox++;
+ }
+}
+
+
+
diff --git a/src/riva_type.h b/src/riva_type.h
new file mode 100644
index 0000000..7913128
--- /dev/null
+++ b/src/riva_type.h
@@ -0,0 +1,122 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_type.h,v 1.1 2003/07/31 20:24:31 mvojkovi Exp $ */
+
+#ifndef __Riva_STRUCT_H__
+#define __Riva_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* RivaRegPtr;
+
+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, RivaRegPtr, Bool);
+ void (*Restore)(ScrnInfoPtr, vgaRegPtr, RivaRegPtr, Bool);
+ Bool (*ModeInit)(ScrnInfoPtr, DisplayModePtr);
+} RivaRamdacRec, *RivaRamdacPtr;
+
+typedef struct {
+ int bitsPerPixel;
+ int depth;
+ int displayWidth;
+ rgb weight;
+ DisplayModePtr mode;
+} RivaFBLayout;
+
+typedef struct {
+ RIVA_HW_INST riva;
+ RIVA_HW_STATE SavedReg;
+ RIVA_HW_STATE ModeReg;
+ EntityInfoPtr pEnt;
+ pciVideoPtr PciInfo;
+ PCITAG PciTag;
+ xf86AccessRec Access;
+ int ChipRev;
+ Bool Primary;
+ CARD32 IOAddress;
+ unsigned long FbAddress;
+ int FbBaseReg;
+ unsigned char * IOBase;
+ unsigned char * FbBase;
+ unsigned char * FbStart;
+ long FbMapSize;
+ long FbUsableSize;
+ RivaRamdacRec 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, RivaRegPtr, Bool);
+ void (*Restore)(ScrnInfoPtr, vgaRegPtr, RivaRegPtr, Bool);
+ Bool (*ModeInit)(ScrnInfoPtr, DisplayModePtr);
+ void (*PointerMoved)(int index, int x, int y);
+ CloseScreenProcPtr CloseScreen;
+ Bool FBDev;
+ /* Color expansion */
+ unsigned char *expandBuffer;
+ unsigned char *expandFifo;
+ int expandWidth;
+ int expandRows;
+ CARD32 FgColor;
+ CARD32 BgColor;
+ int Rotate;
+ RivaFBLayout CurrentLayout;
+ /* Cursor */
+ CARD32 curFg, curBg;
+ CARD32 curImage[64];
+ /* Misc flags */
+ unsigned int opaqueMonochrome;
+ int currentRop;
+ /* I2C / DDC */
+ I2CBusPtr I2C;
+ xf86Int10InfoPtr pInt;
+ OptionInfoPtr Options;
+ unsigned char DDCBase;
+} RivaRec, *RivaPtr;
+
+#define RivaPTR(p) ((RivaPtr)((p)->driverPrivate))
+
+void RivaRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+void RivaRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+void RivaRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+void RivaRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+void RivaPointerMoved(int index, int x, int y);
+
+int RivaGetConfig(RivaPtr);
+
+#endif /* __Riva_STRUCT_H__ */
diff --git a/src/riva_xaa.c b/src/riva_xaa.c
new file mode 100644
index 0000000..240e9ec
--- /dev/null
+++ b/src/riva_xaa.c
@@ -0,0 +1,554 @@
+ /***************************************************************************\
+|* *|
+|* 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/riva_xaa.c,v 1.1 2003/07/31 20:24:31 mvojkovi Exp $ */
+
+#include "riva_include.h"
+#include "xaalocal.h"
+#include "xaarop.h"
+
+#include "miline.h"
+
+static void
+RivaSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2)
+{
+ int height = y2-y1 + 1;
+ int width = x2-x1 + 1;
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ RIVA_FIFO_FREE(pRiva->riva, Clip, 2);
+ pRiva->riva.Clip->TopLeft = (y1 << 16) | (x1 & 0xffff);
+ pRiva->riva.Clip->WidthHeight = (height << 16) | width;
+}
+
+
+static void
+RivaDisableClipping(ScrnInfoPtr pScrn)
+{
+ RivaSetClippingRectangle(pScrn, 0, 0, 0x7fff, 0x7fff);
+}
+
+/*
+ * Set pattern. Internal routine. The upper bits of the colors
+ * are the ALPHA bits. 0 == transparency.
+ */
+static void
+RivaSetPattern(RivaPtr pRiva, int clr0, int clr1, int pat0, int pat1)
+{
+ RIVA_FIFO_FREE(pRiva->riva, Patt, 4);
+ pRiva->riva.Patt->Color0 = clr0;
+ pRiva->riva.Patt->Color1 = clr1;
+ pRiva->riva.Patt->Monochrome[0] = pat0;
+ pRiva->riva.Patt->Monochrome[1] = pat1;
+}
+
+/*
+ * Set ROP. Translate X rop into ROP3. Internal routine.
+ */
+static void
+RivaSetRopSolid(RivaPtr pRiva, int rop)
+{
+ if (pRiva->currentRop != rop) {
+ if (pRiva->currentRop >= 16)
+ RivaSetPattern(pRiva, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
+ pRiva->currentRop = rop;
+ RIVA_FIFO_FREE(pRiva->riva, Rop, 1);
+ pRiva->riva.Rop->Rop3 = XAACopyROP[rop];
+ }
+}
+
+static void
+RivaSetRopPattern(RivaPtr pRiva, int rop)
+{
+ if (pRiva->currentRop != (rop + 16)) {
+ pRiva->currentRop = rop + 16; /* +16 is important */
+ RIVA_FIFO_FREE(pRiva->riva, Rop, 1);
+ pRiva->riva.Rop->Rop3 = XAAPatternROP[rop];
+ }
+}
+
+/*
+ * Fill solid rectangles.
+ */
+static
+void RivaSetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned planemask)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ RivaSetRopSolid(pRiva, rop);
+ RIVA_FIFO_FREE(pRiva->riva, Bitmap, 1);
+ pRiva->riva.Bitmap->Color1A = color;
+}
+
+static void
+RivaSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ RIVA_FIFO_FREE(pRiva->riva, Bitmap, 2);
+ pRiva->riva.Bitmap->UnclippedRectangle[0].TopLeft = (x << 16) | y;
+ write_mem_barrier();
+ pRiva->riva.Bitmap->UnclippedRectangle[0].WidthHeight = (w << 16) | h;
+ write_mem_barrier();
+}
+
+/*
+ * Screen to screen BLTs.
+ */
+static void
+RivaSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop,
+ unsigned planemask, int transparency_color)
+{
+ RivaSetRopSolid(RivaPTR(pScrn), rop);
+}
+
+static void
+RivaSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2, int w, int h)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ RIVA_FIFO_FREE(pRiva->riva, Blt, 3);
+ pRiva->riva.Blt->TopLeftSrc = (y1 << 16) | x1;
+ pRiva->riva.Blt->TopLeftDst = (y2 << 16) | x2;
+ write_mem_barrier();
+ pRiva->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
+RivaSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny,
+ int fg, int bg, int rop, unsigned planemask)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ RivaSetRopPattern(pRiva, 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 |= pRiva->opaqueMonochrome;
+ bg = (bg == -1) ? 0 : bg | pRiva->opaqueMonochrome;
+ };
+ RivaSetPattern(pRiva, bg, fg, patternx, patterny);
+ RIVA_FIFO_FREE(pRiva->riva, Bitmap, 1);
+ pRiva->riva.Bitmap->Color1A = fg;
+}
+
+static void
+RivaSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int x, int y, int w, int h)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ RIVA_FIFO_FREE(pRiva->riva, Bitmap, 2);
+ pRiva->riva.Bitmap->UnclippedRectangle[0].TopLeft = (x << 16) | y;
+ write_mem_barrier();
+ pRiva->riva.Bitmap->UnclippedRectangle[0].WidthHeight = (w << 16) | h;
+ write_mem_barrier();
+}
+
+
+void
+RivaResetGraphics(ScrnInfoPtr pScrn)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ if(pRiva->NoAccel) return;
+
+ RIVA_FIFO_FREE(pRiva->riva, Patt, 1);
+ pRiva->riva.Patt->Shape = 0;
+ RivaDisableClipping(pScrn);
+ pRiva->currentRop = 16; /* to force RivaSetRopSolid to reset the pattern */
+ RivaSetRopSolid(pRiva, GXcopy);
+}
+
+
+
+/*
+ * Synchronise with graphics engine. Make sure it is idle before returning.
+ * Should attempt to yield CPU if busy for awhile.
+ */
+void RivaSync(ScrnInfoPtr pScrn)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+ RIVA_BUSY(pRiva->riva);
+}
+
+/* Color expansion */
+static void
+RivaSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ RivaSetRopSolid(pRiva, rop);
+
+ if ( bg == -1 )
+ {
+ /* Transparent case */
+ bg = 0x80000000;
+ pRiva->expandFifo = (unsigned char*)&pRiva->riva.Bitmap->MonochromeData1C;
+ }
+ else
+ {
+ pRiva->expandFifo = (unsigned char*)&pRiva->riva.Bitmap->MonochromeData01E;
+ if (pScrn->depth == 16)
+ {
+ bg = ((bg & 0x0000F800) << 8)
+ | ((bg & 0x000007E0) << 5)
+ | ((bg & 0x0000001F) << 3)
+ | 0xFF000000;
+ }
+ else
+ {
+ bg |= pRiva->opaqueMonochrome;
+ };
+ }
+ pRiva->FgColor = fg;
+ pRiva->BgColor = bg;
+}
+
+static void
+RivaSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ int t = pRiva->expandWidth;
+ CARD32 *pbits = (CARD32*)pRiva->expandBuffer;
+ CARD32 *d = (CARD32*)pRiva->expandFifo;
+
+ while(t >= 16)
+ {
+ RIVA_FIFO_FREE(pRiva->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(pRiva->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 (!(--pRiva->expandRows)) { /* hardware bug workaround */
+ RIVA_FIFO_FREE(pRiva->riva, Blt, 1);
+ write_mem_barrier();
+ pRiva->riva.Blt->TopLeftSrc = 0;
+ }
+ write_mem_barrier();
+}
+
+static void
+RivaSubsequentColorExpandScanlineFifo(ScrnInfoPtr pScrn, int bufno)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ if ( --pRiva->expandRows ) {
+ RIVA_FIFO_FREE(pRiva->riva, Bitmap, pRiva->expandWidth);
+ } else { /* hardware bug workaround */
+ RIVA_FIFO_FREE(pRiva->riva, Blt, 1);
+ write_mem_barrier();
+ pRiva->riva.Blt->TopLeftSrc = 0;
+ }
+ write_mem_barrier();
+}
+
+static void
+RivaSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x,
+ int y, int w, int h,
+ int skipleft)
+{
+ int bw;
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ bw = (w + 31) & ~31;
+ pRiva->expandWidth = bw >> 5;
+
+ if ( pRiva->BgColor == 0x80000000 )
+ {
+ /* Use faster transparent method */
+ RIVA_FIFO_FREE(pRiva->riva, Bitmap, 5);
+ pRiva->riva.Bitmap->ClipC.TopLeft = (y << 16) | ((x+skipleft)
+ & 0xFFFF);
+ pRiva->riva.Bitmap->ClipC.BottomRight = ((y+h) << 16) | ((x+w)&0xffff);
+ pRiva->riva.Bitmap->Color1C = pRiva->FgColor;
+ pRiva->riva.Bitmap->WidthHeightC = (h << 16) | bw;
+ write_mem_barrier();
+ pRiva->riva.Bitmap->PointC = (y << 16) | (x & 0xFFFF);
+ write_mem_barrier();
+ }
+ else
+ {
+ /* Opaque */
+ RIVA_FIFO_FREE(pRiva->riva, Bitmap, 7);
+ pRiva->riva.Bitmap->ClipE.TopLeft = (y << 16) | ((x+skipleft)
+ & 0xFFFF);
+ pRiva->riva.Bitmap->ClipE.BottomRight = ((y+h) << 16) | ((x+w)&0xffff);
+ pRiva->riva.Bitmap->Color0E = pRiva->BgColor;
+ pRiva->riva.Bitmap->Color1E = pRiva->FgColor;
+ pRiva->riva.Bitmap->WidthHeightInE = (h << 16) | bw;
+ pRiva->riva.Bitmap->WidthHeightOutE = (h << 16) | bw;
+ write_mem_barrier();
+ pRiva->riva.Bitmap->PointE = (y << 16) | (x & 0xFFFF);
+ write_mem_barrier();
+ }
+
+ pRiva->expandRows = h;
+
+ if(pRiva->expandWidth > (pRiva->riva.FifoEmptyCount >> 2)) {
+ pRiva->AccelInfoRec->ScanlineColorExpandBuffers = &pRiva->expandBuffer;
+ pRiva->AccelInfoRec->SubsequentColorExpandScanline =
+ RivaSubsequentColorExpandScanline;
+ } else {
+ pRiva->AccelInfoRec->ScanlineColorExpandBuffers = &pRiva->expandFifo;
+ pRiva->AccelInfoRec->SubsequentColorExpandScanline =
+ RivaSubsequentColorExpandScanlineFifo;
+ RIVA_FIFO_FREE(pRiva->riva, Bitmap, pRiva->expandWidth);
+ }
+}
+
+static void
+RivaSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, unsigned planemask)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ RivaSetRopSolid(pRiva, rop);
+ pRiva->FgColor = color;
+}
+
+static void
+RivaSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len, int dir)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ RIVA_FIFO_FREE(pRiva->riva, Line, 3);
+ pRiva->riva.Line->Color = pRiva->FgColor;
+ pRiva->riva.Line->Lin[0].point0 = ((y << 16) | ( x & 0xffff));
+ write_mem_barrier();
+ if ( dir ==DEGREES_0 )
+ pRiva->riva.Line->Lin[0].point1 = ((y << 16) | (( x + len ) & 0xffff));
+ else
+ pRiva->riva.Line->Lin[0].point1 = (((y + len) << 16) | ( x & 0xffff));
+ write_mem_barrier();
+}
+
+static void
+RivaSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2, int flags)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+ Bool lastPoint = !(flags & OMIT_LAST);
+
+ RIVA_FIFO_FREE(pRiva->riva, Line, lastPoint ? 5 : 3);
+ pRiva->riva.Line->Color = pRiva->FgColor;
+ pRiva->riva.Line->Lin[0].point0 = ((y1 << 16) | (x1 & 0xffff));
+ write_mem_barrier();
+ pRiva->riva.Line->Lin[0].point1 = ((y2 << 16) | (x2 & 0xffff));
+ write_mem_barrier();
+ if (lastPoint)
+ {
+ pRiva->riva.Line->Lin[1].point0 = ((y2 << 16) | (x2 & 0xffff));
+ write_mem_barrier();
+ pRiva->riva.Line->Lin[1].point1 = (((y2 + 1) << 16) | (x2 & 0xffff));
+ write_mem_barrier();
+ }
+}
+
+static void
+RivaValidatePolyArc(
+ 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
+RivaValidatePolyPoint(
+ 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
+RivaAccelInit(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoPtr;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ pRiva->AccelInfoRec = infoPtr = XAACreateInfoRec();
+ if(!infoPtr) return FALSE;
+
+ /* fill out infoPtr here */
+ infoPtr->Flags = LINEAR_FRAMEBUFFER | PIXMAP_CACHE | OFFSCREEN_PIXMAPS;
+
+ /* sync */
+ infoPtr->Sync = RivaSync;
+
+ /* solid fills */
+ infoPtr->SolidFillFlags = NO_PLANEMASK;
+ infoPtr->SetupForSolidFill = RivaSetupForSolidFill;
+ infoPtr->SubsequentSolidFillRect = RivaSubsequentSolidFillRect;
+
+ /* screen to screen copy */
+ infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY | NO_PLANEMASK;
+ infoPtr->SetupForScreenToScreenCopy = RivaSetupForScreenToScreenCopy;
+ infoPtr->SubsequentScreenToScreenCopy = RivaSubsequentScreenToScreenCopy;
+
+ /* 8x8 mono patterns */
+ /*
+ * Set pattern opaque bits based on pixel format.
+ */
+ pRiva->opaqueMonochrome = ~((1 << pScrn->depth) - 1);
+
+ infoPtr->Mono8x8PatternFillFlags = HARDWARE_PATTERN_SCREEN_ORIGIN |
+ HARDWARE_PATTERN_PROGRAMMED_BITS |
+ NO_PLANEMASK;
+ infoPtr->SetupForMono8x8PatternFill = RivaSetupForMono8x8PatternFill;
+ infoPtr->SubsequentMono8x8PatternFillRect =
+ RivaSubsequentMono8x8PatternFillRect;
+
+ /* Color expansion */
+ infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
+ BIT_ORDER_IN_BYTE_LSBFIRST |
+ NO_PLANEMASK |
+ CPU_TRANSFER_PAD_DWORD |
+ LEFT_EDGE_CLIPPING |
+ LEFT_EDGE_CLIPPING_NEGATIVE_X;
+
+ infoPtr->NumScanlineColorExpandBuffers = 1;
+
+ infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
+ RivaSetupForScanlineCPUToScreenColorExpandFill;
+ infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
+ RivaSubsequentScanlineCPUToScreenColorExpandFill;
+
+ pRiva->expandFifo = (unsigned char*)&pRiva->riva.Bitmap->MonochromeData01E;
+
+ /* Allocate buffer for color expansion and also image writes in the
+ future */
+ pRiva->expandBuffer = xnfalloc(((pScrn->virtualX*pScrn->bitsPerPixel)/8) + 8);
+
+
+ infoPtr->ScanlineColorExpandBuffers = &pRiva->expandBuffer;
+ infoPtr->SubsequentColorExpandScanline = RivaSubsequentColorExpandScanline;
+
+ infoPtr->SolidLineFlags = infoPtr->SolidFillFlags;
+ infoPtr->SetupForSolidLine = RivaSetupForSolidLine;
+ infoPtr->SubsequentSolidHorVertLine =
+ RivaSubsequentSolidHorVertLine;
+ infoPtr->SubsequentSolidTwoPointLine =
+ RivaSubsequentSolidTwoPointLine;
+ infoPtr->SetClippingRectangle = RivaSetClippingRectangle;
+ infoPtr->DisableClipping = RivaDisableClipping;
+ infoPtr->ClippingFlags = HARDWARE_CLIP_SOLID_LINE;
+ miSetZeroLineBias(pScreen, OCTANT1 | OCTANT3 | OCTANT4 | OCTANT6);
+
+ infoPtr->ValidatePolyArc = RivaValidatePolyArc;
+ infoPtr->PolyArcMask = GCFunction | GCLineWidth | GCPlaneMask;
+ infoPtr->ValidatePolyPoint = RivaValidatePolyPoint;
+ infoPtr->PolyPointMask = GCFunction | GCPlaneMask;
+
+ RivaResetGraphics(pScrn);
+
+ return(XAAInit(pScreen, infoPtr));
+}
+