summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoridr <idr>2004-03-03 21:16:34 +0000
committeridr <idr>2004-03-03 21:16:34 +0000
commitcbc0b0227a496a06717afd13c5d6811935e0fc14 (patch)
tree3c9f0bb2b788274b4858c389f140e8d12a8789ab
parent12f89c73ed66468dfe4d86bf7041a306a8bc67a9 (diff)
Obtained from: DRI trunk
-rw-r--r--xc/lib/Imakefile12
-rw-r--r--xc/lib/font/fontfile/dirfile.c39
-rw-r--r--xc/lib/font/fontfile/encparse.c7
-rw-r--r--xc/lib/font/fontfile/fontfile.c77
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/savage/Imakefile45
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c968
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/savage/savage_bci.h41
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/savage/savage_cursor.c36
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/savage/savage_dga.c9
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c609
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.h200
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/savage/savage_i2c.c8
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/savage/savage_regs.h289
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/savage/savage_vbe.c25
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/savage/savage_video.c675
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h780
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_agpsupport.h244
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_context.h600
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_drv.h576
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_memory_debug.h460
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/sis_mm.c407
21 files changed, 4600 insertions, 1507 deletions
diff --git a/xc/lib/Imakefile b/xc/lib/Imakefile
index b9882fa95..59afe6e91 100644
--- a/xc/lib/Imakefile
+++ b/xc/lib/Imakefile
@@ -32,14 +32,6 @@ XKBUILIBDIR = xkbui
THRSTUBLIBDIR = XThrStub
#endif
-#if BuildXIElib
-XIELIBDIR = XIE
-#endif
-
-#if BuildPexLib
-PEX5LIBDIR = PEX5
-#endif
-
#if BuildXInputLib
XINPUTLIBDIR = Xi
#endif
@@ -204,8 +196,8 @@ LINTSUBDIRS = $(XAULIBDIR) $(XDMCPLIBDIR) $(THRSTUBLIBDIR) $(X11LIBDIR) \
$(OLDXLIBDIR) $(ICELIBDIR) $(SMLIBDIR) $(XEXTLIBDIR) $(XTLIBDIR) \
$(SSLIBDIR) $(XF86MISCLIBDIR) $(XF86VMLIBDIR) $(XF86DGALIBDIR) \
$(XF86RUSHLIBDIR) $(XMULIBDIR) $(XMUULIBDIR) $(XPMLIBDIR) \
- $(XAW6LIBDIR) $(XAWLIBDIR) $(XIELIBDIR) $(XINPUTLIBDIR) \
- $(XTSTLIBDIR) $(FSLIBDIR) $(PEX5LIBDIR) $(XKBLIBDIR) \
+ $(XAW6LIBDIR) $(XAWLIBDIR) $(XINPUTLIBDIR) \
+ $(XTSTLIBDIR) $(FSLIBDIR) $(XKBLIBDIR) \
$(XKBUILIBDIR) $(LBXUTILDIR) $(XALIBDIR) $(XPRINTLIBDIR) \
$(XVLIBDIR) $(GLXLIBDIR) $(GLULIBDIR) $(GLWLIBDIR) \
$(DPSLIBDIR) $(DPSTKLIBDIR) $(PSRESLIBDIR) $(XINERAMADIR) \
diff --git a/xc/lib/font/fontfile/dirfile.c b/xc/lib/font/fontfile/dirfile.c
index 5f9050192..4bbee959a 100644
--- a/xc/lib/font/fontfile/dirfile.c
+++ b/xc/lib/font/fontfile/dirfile.c
@@ -25,7 +25,7 @@ used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from The Open Group.
*/
-/* $XFree86: xc/lib/font/fontfile/dirfile.c,v 3.15 2002/05/31 18:45:50 dawes Exp $ */
+/* $XFree86: xc/lib/font/fontfile/dirfile.c,v 3.16 2003/04/07 16:23:31 eich Exp $ */
/*
* Author: Keith Packard, MIT X Consortium
@@ -68,6 +68,9 @@ FontFileReadDirectory (char *directory, FontDirectoryPtr *pdir)
FontDirectoryPtr dir = NullFontDirectory;
+ if (strlen(directory) + 1 + sizeof(FontDirFile) > sizeof(dir_file))
+ return BadFontPath;
+
#ifdef FONTDIRATTRIB
/* Check for font directory attributes */
#ifndef __UNIXOS2__
@@ -90,6 +93,8 @@ FontFileReadDirectory (char *directory, FontDirectoryPtr *pdir)
strcat(dir_file, FontDirFile);
file = fopen(dir_file, "r");
if (file) {
+ Bool found_font = FALSE;
+
if (fstat (fileno(file), &statb) == -1)
return BadFontPath;
count = fscanf(file, "%d\n", &i);
@@ -106,6 +111,7 @@ FontFileReadDirectory (char *directory, FontDirectoryPtr *pdir)
if (format[0] == '\0')
sprintf(format, "%%%ds %%%d[^\n]\n",
MAXFONTFILENAMELEN-1, MAXFONTNAMELEN-1);
+
while ((count = fscanf(file, format, file_name, font_name)) != EOF) {
#ifdef __UNIXOS2__
/* strip any existing trailing CR */
@@ -118,14 +124,16 @@ FontFileReadDirectory (char *directory, FontDirectoryPtr *pdir)
fclose(file);
return BadFontPath;
}
- if (!FontFileAddFontFile (dir, font_name, file_name))
- {
- FontFileFreeDir (dir);
- fclose(file);
- return BadFontPath;
- }
+ if (FontFileAddFontFile (dir, font_name, file_name))
+ found_font = TRUE;
+ }
+ if (!found_font) {
+ FontFileFreeDir (dir);
+ fclose(file);
+ return BadFontPath;
}
fclose(file);
+
} else if (errno != ENOENT) {
return BadFontPath;
}
@@ -154,6 +162,9 @@ FontFileDirectoryChanged(FontDirectoryPtr dir)
char dir_file[MAXFONTFILENAMELEN];
struct stat statb;
+ if (strlen(dir->directory) + sizeof(FontDirFile) > sizeof(dir_file))
+ return FALSE;
+
strcpy (dir_file, dir->directory);
strcat (dir_file, FontDirFile);
if (stat (dir_file, &statb) == -1)
@@ -202,6 +213,8 @@ AddFileNameAliases(FontDirectoryPtr dir)
continue;
len = strlen (fileName) - renderer->fileSuffixLen;
+ if (len >= sizeof(copy))
+ continue;
CopyISOLatin1Lowered (copy, fileName, len);
copy[len] = '\0';
name.name = copy;
@@ -251,9 +264,13 @@ ReadFontAlias(char *directory, Bool isFile, FontDirectoryPtr *pdir)
int status = Successful;
struct stat statb;
+ if (strlen(directory) >= sizeof(alias_file))
+ return BadFontPath;
dir = *pdir;
strcpy(alias_file, directory);
if (!isFile) {
+ if (strlen(directory) + 1 + sizeof(FontAliasFile) > sizeof(alias_file))
+ return BadFontPath;
if (directory[strlen(directory) - 1] != '/')
strcat(alias_file, "/");
strcat(alias_file, FontAliasFile);
@@ -286,6 +303,10 @@ ReadFontAlias(char *directory, Bool isFile, FontDirectoryPtr *pdir)
status = AllocError;
break;
case NAME:
+ if (strlen(lexToken) >= sizeof(alias)) {
+ status = BadFontPath;
+ break;
+ }
strcpy(alias, lexToken);
token = lexAlias(file, &lexToken);
switch (token) {
@@ -302,6 +323,10 @@ ReadFontAlias(char *directory, Bool isFile, FontDirectoryPtr *pdir)
status = AllocError;
break;
case NAME:
+ if (strlen(lexToken) >= sizeof(font_name)) {
+ status = BadFontPath;
+ break;
+ }
CopyISOLatin1Lowered(alias, alias, strlen(alias));
CopyISOLatin1Lowered(font_name, lexToken, strlen(lexToken));
if (!FontFileAddFontAlias (dir, alias, font_name))
diff --git a/xc/lib/font/fontfile/encparse.c b/xc/lib/font/fontfile/encparse.c
index 4c9c31bfb..72ed40d75 100644
--- a/xc/lib/font/fontfile/encparse.c
+++ b/xc/lib/font/fontfile/encparse.c
@@ -833,6 +833,7 @@ FontEncReallyReallyLoad(const char *charset,
char file_name[MAXFONTFILENAMELEN], encoding_name[MAXFONTNAMELEN],
buf[MAXFONTFILENAMELEN];
int count, n;
+ static char format[24] = "";
/* As we don't really expect to open encodings that often, we don't
take the trouble of caching encodings directories. */
@@ -848,8 +849,12 @@ FontEncReallyReallyLoad(const char *charset,
}
encoding = NULL;
+ if (!format[0]) {
+ sprintf(format, "%%%ds %%%d[^\n]\n", sizeof(encoding_name) - 1,
+ sizeof(file_name) - 1);
+ }
for(;;) {
- count = fscanf(file, "%s %[^\n]\n", encoding_name, file_name);
+ count = fscanf(file, format, encoding_name, file_name);
if(count == EOF)
break;
if(count != 2)
diff --git a/xc/lib/font/fontfile/fontfile.c b/xc/lib/font/fontfile/fontfile.c
index 1e39413f5..344d872d5 100644
--- a/xc/lib/font/fontfile/fontfile.c
+++ b/xc/lib/font/fontfile/fontfile.c
@@ -25,7 +25,7 @@ used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from The Open Group.
*/
-/* $XFree86: xc/lib/font/fontfile/fontfile.c,v 3.16 2002/05/31 18:45:50 dawes Exp $ */
+/* $XFree86: xc/lib/font/fontfile/fontfile.c,v 3.18 2003/07/07 16:40:11 eich Exp $ */
/*
* Author: Keith Packard, MIT X Consortium
@@ -424,11 +424,16 @@ FontFileOpenFont (pointer client, FontPathElementPtr fpe, Mask flags,
vals.ranges = ranges;
vals.nranges = nranges;
- strcpy (fileName, dir->directory);
- strcat (fileName, scalable->fileName);
- ret = (*scalable->renderer->OpenScalable) (fpe, pFont,
+ if (strlen(dir->directory) + strlen(scalable->fileName) >=
+ sizeof(fileName)) {
+ ret = BadFontName;
+ } else {
+ strcpy (fileName, dir->directory);
+ strcat (fileName, scalable->fileName);
+ ret = (*scalable->renderer->OpenScalable) (fpe, pFont,
flags, entry, fileName, &vals, format, fmask,
non_cachable_font);
+ }
/* In case rasterizer does something bad because of
charset subsetting... */
@@ -497,6 +502,8 @@ FontFileOpenBitmapNCF (FontPathElementPtr fpe, FontPtr *pFont,
dir = (FontDirectoryPtr) fpe->private;
bitmap = &entry->u.bitmap;
+ if(!bitmap || !bitmap->renderer->OpenBitmap)
+ return BadFontName;
strcpy (fileName, dir->directory);
strcat (fileName, bitmap->fileName);
ret = (*bitmap->renderer->OpenBitmap)
@@ -530,6 +537,10 @@ FontFileGetInfoBitmap (FontPathElementPtr fpe, FontInfoPtr pFontInfo,
dir = (FontDirectoryPtr) fpe->private;
bitmap = &entry->u.bitmap;
+ if (strlen(dir->directory) + strlen(bitmap->fileName) >= sizeof(fileName))
+ return BadFontName;
+ if (strlen(dir->directory) + strlen(bitmap->fileName) >= sizeof(fileName))
+ return BadFontName;
strcpy (fileName, dir->directory);
strcat (fileName, bitmap->fileName);
ret = (*bitmap->renderer->GetInfoBitmap) (fpe, pFontInfo, entry, fileName);
@@ -891,10 +902,15 @@ FontFileListOneFontWithInfo (pointer client, FontPathElementPtr fpe,
vals.ranges = FontParseRanges(origName, &vals.nranges);
ranges = vals.ranges;
/* Make a new scaled instance */
- strcpy (fileName, dir->directory);
- strcat (fileName, scalable->fileName);
- ret = (*scalable->renderer->GetInfoScalable)
- (fpe, *pFontInfo, entry, &tmpName, fileName, &vals);
+ if (strlen(dir->directory) + strlen(scalable->fileName) >=
+ sizeof(fileName)) {
+ ret = BadFontName;
+ } else {
+ strcpy (fileName, dir->directory);
+ strcat (fileName, scalable->fileName);
+ ret = (*scalable->renderer->GetInfoScalable)
+ (fpe, *pFontInfo, entry, &tmpName, fileName, &vals);
+ }
if (ranges) xfree(ranges);
}
}
@@ -931,10 +947,15 @@ FontFileListOneFontWithInfo (pointer client, FontPathElementPtr fpe,
bc = &entry->u.bc;
entry = bc->entry;
/* Make a new scaled instance */
- strcpy (fileName, dir->directory);
- strcat (fileName, scalable->fileName);
- ret = (*scalable->renderer->GetInfoScalable)
+ if (strlen(dir->directory) + strlen(scalable->fileName) >=
+ sizeof(fileName)) {
+ ret = BadFontName;
+ } else {
+ strcpy (fileName, dir->directory);
+ strcat (fileName, scalable->fileName);
+ ret = (*scalable->renderer->GetInfoScalable)
(fpe, *pFontInfo, entry, tmpName, fileName, &bc->vals);
+ }
break;
#endif
default:
@@ -1048,26 +1069,22 @@ FontFileListNextFontOrAlias(pointer client, FontPathElementPtr fpe,
return ret;
}
-
-typedef int (*IntFunc) (void);
-static int font_file_type;
-
void
FontFileRegisterLocalFpeFunctions (void)
{
- font_file_type = RegisterFPEFunctions(FontFileNameCheck,
- FontFileInitFPE,
- FontFileFreeFPE,
- FontFileResetFPE,
- FontFileOpenFont,
- FontFileCloseFont,
- FontFileListFonts,
- FontFileStartListFontsWithInfo,
- FontFileListNextFontWithInfo,
- NULL,
- NULL,
- NULL,
- FontFileStartListFontsAndAliases,
- FontFileListNextFontOrAlias,
- FontFileEmptyBitmapSource);
+ RegisterFPEFunctions(FontFileNameCheck,
+ FontFileInitFPE,
+ FontFileFreeFPE,
+ FontFileResetFPE,
+ FontFileOpenFont,
+ FontFileCloseFont,
+ FontFileListFonts,
+ FontFileStartListFontsWithInfo,
+ FontFileListNextFontWithInfo,
+ NULL,
+ NULL,
+ NULL,
+ FontFileStartListFontsAndAliases,
+ FontFileListNextFontOrAlias,
+ FontFileEmptyBitmapSource);
}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/savage/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/savage/Imakefile
index 549b2c625..4c9b0e325 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/savage/Imakefile
+++ b/xc/programs/Xserver/hw/xfree86/drivers/savage/Imakefile
@@ -1,13 +1,38 @@
-XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/Imakefile,v 1.8 2003/02/17 17:06:44 dawes Exp $
/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
- * Copyright 1995-1998 The XFree86 Project, Inc.
+ * 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, sub license,
+ * 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 (including the
+ * next paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS 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.
*/
#define IHaveModules
#include <Server.tmpl>
+#if BuildXF86DRI
+DRISRCS = savage_dri.c
+DRIOBJS = savage_dri.o
+DRIINCLUDES = -I$(SERVERSRC)/GL/dri -I$(LIBSRC)/GL/dri \
+ -I$(XF86OSSRC)/linux/drm/kernel -I$(TOP)/include
+DRIDEFINES = $(GLX_DEFINES)
+#endif
+
SRCS = savage_driver.c \
savage_accel.c \
savage_cursor.c \
@@ -16,7 +41,9 @@ SRCS = savage_driver.c \
savage_image.c \
savage_shadow.c \
savage_vbe.c \
- savage_video.c
+ savage_video.c \
+ savage_hwmc.c \
+ $(DRISRCS)
OBJS = savage_driver.o \
savage_accel.o \
@@ -26,9 +53,11 @@ OBJS = savage_driver.o \
savage_image.o \
savage_shadow.o \
savage_vbe.o \
- savage_video.o
+ savage_video.o \
+ savage_hwmc.o \
+ $(DRIOBJS)
-DEFINES = -DPSZ=8
+DEFINES = -DPSZ=8 $(DRIDEFINES)
#if defined(XF86DriverSDK)
INCLUDES = -I. -I../../include
@@ -42,7 +71,7 @@ INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \
-I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \
-I$(XF86SRC)/rac -I$(XF86SRC)/int10 -I$(SERVERSRC)/render \
-I$(SERVERSRC)/include -I$(XINCLUDESRC) -I$(FONTINCSRC) \
- -I$(EXTINCSRC) -I$(XF86SRC)/vbe -I$(XF86SRC)/shadowfb
+ -I$(EXTINCSRC) -I$(XF86SRC)/vbe -I$(XF86SRC)/shadowfb $(DRIINCLUDES)
#endif
#if MakeHasPosixVariableSubstitutions
@@ -69,6 +98,8 @@ InstallDriverSDKNonExecFile(savage_cursor.c,$(DRIVERSDKDIR)/drivers/savage)
InstallDriverSDKNonExecFile(savage_dga.c,$(DRIVERSDKDIR)/drivers/savage)
InstallDriverSDKNonExecFile(savage_driver.c,$(DRIVERSDKDIR)/drivers/savage)
InstallDriverSDKNonExecFile(savage_driver.h,$(DRIVERSDKDIR)/drivers/savage)
+InstallDriverSDKNonExecFile(savage_dri.c,$(DRIVERSDKDIR)/drivers/i810)
+InstallDriverSDKNonExecFile(savage_dri.h,$(DRIVERSDKDIR)/drivers/i810)
InstallDriverSDKNonExecFile(savage_i2c.c,$(DRIVERSDKDIR)/drivers/savage)
InstallDriverSDKNonExecFile(savage_image.c,$(DRIVERSDKDIR)/drivers/savage)
InstallDriverSDKNonExecFile(savage_regs.h,$(DRIVERSDKDIR)/drivers/savage)
@@ -76,5 +107,7 @@ InstallDriverSDKNonExecFile(savage_shadow.c,$(DRIVERSDKDIR)/drivers/savage)
InstallDriverSDKNonExecFile(savage_vbe.c,$(DRIVERSDKDIR)/drivers/savage)
InstallDriverSDKNonExecFile(savage_vbe.h,$(DRIVERSDKDIR)/drivers/savage)
InstallDriverSDKNonExecFile(savage_video.c,$(DRIVERSDKDIR)/drivers/savage)
+InstallDriverSDKNonExecFile(savage_hwmc.c,$(DRIVERSDKDIR)/drivers/savage)
+InstallDriverSDKNonExecFile(savage.cpp,$(DRIVERSDKDIR)/drivers/savage)
InstallDriverSDKObjectModule(savage,$(DRIVERSDKMODULEDIR),drivers)
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c
index 0ffc8631b..8f010e133 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c,v 1.18 2002/11/08 18:03:32 alanh Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c,v 1.14 2001/12/13 18:01:50 eich Exp $ */
/*
*
@@ -11,6 +11,7 @@
*
* Created 20/03/97 by Sebastien Marineau for 3.3.6
* Modified 17-Nov-2000 by Tim Roberts for 4.0.1
+ * Modified Feb-2004 by Alex Deucher - integrating DRI support
* Revision:
*
*/
@@ -23,6 +24,12 @@
#include "savage_driver.h"
#include "savage_regs.h"
#include "savage_bci.h"
+#include "savage_dri.h"
+
+#ifdef XF86DRI
+#define _XF86DRI_SERVER_
+#include "savage_dri.h"
+#endif
/* Forward declaration of functions used in the driver */
@@ -65,7 +72,7 @@ static void SavageSubsequentSolidBresenhamLine(
int err,
int length,
int octant);
-
+#if 0
static void SavageSubsequentSolidTwoPointLine(
ScrnInfoPtr pScrn,
int x1,
@@ -73,7 +80,7 @@ static void SavageSubsequentSolidTwoPointLine(
int x2,
int y2,
int bias);
-
+#endif
#if 0
static void SavageSetupForScreenToScreenColorExpand(
ScrnInfoPtr pScrn,
@@ -204,6 +211,11 @@ unsigned long readfb( unsigned long addr );
unsigned long writefb( unsigned long addr, unsigned long value );
void writescan( unsigned long scan, unsigned long color );
+static int GetTileAperturePitch(ulong dwWidth, ulong dwBpp);
+void SavageSetGBD_M7(ScrnInfoPtr pScrn);
+void SavageSetGBD_Twister(ScrnInfoPtr pScrn);
+void SavageSetGBD_PM(ScrnInfoPtr pScrn);
+void SavageSetGBD_2000(ScrnInfoPtr pScrn);
/*
* This is used to cache the last known value for routines we want to
@@ -212,8 +224,29 @@ void writescan( unsigned long scan, unsigned long color );
ScrnInfoPtr gpScrn = 0;
-
-
+/*
+ * returns the aperture pitch for tiled mode.
+ * if MM850C_15 = 0 (use NB linear tile mode) the pitch is screen stride aligned to 128bytes
+ * if MM850C_15 = 1 (use MS-1 128bit non-linear tile mode),we should do it as follows
+ * we now only support the later, and don't use Y range flag,see tile surface register
+*/
+static int GetTileAperturePitch(ulong dwWidth, ulong dwBpp)
+{
+ switch (dwBpp) {
+ case 4:
+ case 8:
+ return(0x2000);
+ break;
+ case 16:
+ return(0x1000);
+ break;
+ case 32:
+ return(0x2000);
+ break;
+ default:
+ return(0x2000);
+ }
+}
void
SavageInitialize2DEngine(ScrnInfoPtr pScrn)
@@ -242,7 +275,8 @@ SavageInitialize2DEngine(ScrnInfoPtr pScrn)
/* Disable BCI */
OUTREG(0x48C18, INREG(0x48C18) & 0x3FF0);
/* Setup BCI command overflow buffer */
- OUTREG(0x48C14, (psav->cobOffset >> 11) | (psav->cobIndex << 29));
+ OUTREG(0x48C14, (psav->cobOffset >> 11) | (psav->cobIndex << 29)); /* tim */
+ /*OUTREG(S3_OVERFLOW_BUFFER, psav->cobOffset >> 11 | 0xE0000000);*/ /* S3 */
/* Program shadow status update. */
OUTREG(0x48C10, 0x78207220);
if( psav->ShadowStatus )
@@ -260,12 +294,15 @@ SavageInitialize2DEngine(ScrnInfoPtr pScrn)
break;
case S3_SAVAGE4:
+ case S3_TWISTER:
case S3_PROSAVAGE:
- case S3_SUPERSAVAGE:
+ case S3_PROSAVAGEDDR:
+ case S3_SUPERSAVAGE: /* AGD: S3 does supersavage differently. we may have to fix this. */
/* Disable BCI */
OUTREG(0x48C18, INREG(0x48C18) & 0x3FF0);
- /* Program shadow status update */
- OUTREG(0x48C10, 0x00700040);
+ /* Program shadow status update */ /* AGD: what should this be? */
+ OUTREG(0x48C10, 0x00700040); /* tim */
+ /*OUTREG(0x48C10, 0x0e440f04L);*/ /* S3 */
if( psav->ShadowStatus )
{
OUTREG(0x48C0C, psav->ShadowPhysical | 1 );
@@ -316,9 +353,625 @@ SavageInitialize2DEngine(ScrnInfoPtr pScrn)
SavageSetGBD(pScrn);
}
-
void
-SavageSetGBD( ScrnInfoPtr pScrn )
+SavageSetGBD(ScrnInfoPtr pScrn)
+{
+ SavagePtr psav = SAVPTR(pScrn);
+
+ UnProtectCRTC();
+ UnLockExtRegs();
+ VerticalRetraceWait();
+
+ psav->lDelta = pScrn->virtualX * (pScrn->bitsPerPixel >> 3);
+
+ /*
+ * we can use Option "DisableTile" "TRUE" to disable tile mode
+ * if don't disable tile,we only support tile mode under 16/32bpp
+ */
+ if ((!psav->bDisableTile) && ((pScrn->bitsPerPixel == 16) || (pScrn->bitsPerPixel == 32))) {
+ /* tileing in 16/32 BPP */
+ psav->bTiled = TRUE;
+ psav->lDelta = ((psav->lDelta + 127) >> 7) << 7;
+
+ if (psav->Chipset == S3_SAVAGE_MX)
+ psav->ulAperturePitch = 0x2000;
+ else
+ psav->ulAperturePitch = GetTileAperturePitch(pScrn->virtualX,pScrn->bitsPerPixel);
+
+ /* Use the aperture for linear screen */
+ psav->FBStart = psav->ApertureMap;
+ } else {
+ psav->bTiled = FALSE;
+ /* 32: Alignment for nontiled mode */
+ psav->lDelta = ((psav->lDelta + 31) >> 5) << 5;
+ psav->ulAperturePitch = psav->lDelta;
+ }
+
+ /* if you are using linear mode for 2D, 3D still needs to be tiled, linear AperturePitch/Delta
+ seem to be wrong for savagespan */
+ if (psav->Chipset == S3_SAVAGE_MX)
+ psav->ul3DAperturePitch = 0x2000;
+ else
+ psav->ul3DAperturePitch = GetTileAperturePitch(pScrn->virtualX,pScrn->bitsPerPixel);
+
+ psav->l3DDelta = (((pScrn->virtualX * (pScrn->bitsPerPixel >> 3)) + 127) >> 7) << 7;
+
+ psav->Bpp = pScrn->bitsPerPixel >> 3;
+ psav->cxMemory = psav->lDelta / (psav->Bpp);
+ /*psav->cyMemory = psav->endfb / psav->lDelta - 1;*/
+ psav->cyMemory = (psav->CursorKByte << 10) / (pScrn->displayWidth * (pScrn->bitsPerPixel / 8));
+ /* ??????????? */
+ if (psav->cyMemory > 2048)
+ psav->cyMemory = 2048;
+
+ /*
+ * If tiling, adjust down psav->cyMemory to the last multiple
+ * of a tileheight, so that we don't try to use partial tiles.
+ */
+ if (psav->bTiled) {
+ psav->cyMemory -= (psav->cyMemory % 16);
+ }
+
+ /*
+ * Initialization per GX-3.
+ *
+ * 1. MM48C18 - Disable BCI.
+ * 2. MM48C0C - Enable updating shadow status
+ * and initialize shadow memory address.
+ * 2b. MM48C18 - bit 1 = 1, Enable Command Buffer status updates
+ * (S3_OVERFLOW_BUFFER_PTR)
+ * 3. MM48C10 - Initialize command buffer threshold
+ * (S3_BUFFER_THRESHOLD)
+ * 4. MM48C14 - Setup command buffer offset and size
+ * (S3_OVERFLOW_BUFFER)
+ * 5. MM816C - Enable BCI.
+ * 6. MM48C40 - Setup tiled surface 0 register.
+ * 7. CR31 - bit 0 = 0, Disable address offset bits(CR6A_6-0).
+ * 8. CR50 - bit 7,6,0 = 111, Use Global Bitmap Descriptor.
+ * 9. CR88 - bit 4 = 0, Block write on (linear mode) IFF we know we
+ * have the right kind of SGRAM memory,
+ * bit 4 = 1, Block write off (always off if tiling)
+ * 10.CR69 - Bit 7 = 1, MM81C0 and 81C4 are used to control
+ * primary stream.
+ * 11.MM8128, MM812c - Setup read/write mask registers
+ * 12.MM816C, MM8168 - Set up Global Bitmap Descriptor 1 and 2.
+ */
+ switch (psav->Chipset) {
+ case S3_SAVAGE3D:
+ case S3_SAVAGE_MX:
+ SavageSetGBD_M7(pScrn);
+ break;
+ case S3_SAVAGE4:
+ case S3_TWISTER:
+ case S3_PROSAVAGE:
+ case S3_PROSAVAGEDDR:
+ SavageSetGBD_Twister(pScrn);
+ break;
+ case S3_SUPERSAVAGE:
+ SavageSetGBD_PM(pScrn);
+ break;
+ case S3_SAVAGE2000:
+ SavageSetGBD_2000(pScrn);
+ break;
+ }
+}
+
+void SavageSetGBD_Twister(ScrnInfoPtr pScrn)
+{
+ SavagePtr psav = SAVPTR(pScrn);
+ ulong ulTmp;
+ uchar byte;
+ int bci_enable, tile16, tile32;
+
+ if (psav->Chipset == S3_SAVAGE4) {
+ bci_enable = BCI_ENABLE;
+ tile16 = TILE_FORMAT_DESTINATION16;
+ tile32 = TILE_FORMAT_DESTINATION32;
+ } else {
+ bci_enable = BCI_ENABLE_TWISTER;
+ tile16 = TILE_DESTINATION;
+ tile32 = TILE_DESTINATION;
+ }
+
+ /* MM81C0 and 81C4 are used to control primary stream. */
+ OUTREG32(PRI_STREAM_FBUF_ADDR0,0x00000000);
+ OUTREG32(PRI_STREAM_FBUF_ADDR1,0x00000000);
+
+ /*
+ * Program Primary Stream Stride Register.
+ *
+ * Tell engine if tiling on or off, set primary stream stride, and
+ * if tiling, set tiling bits/pixel and primary stream tile offset.
+ * Note that tile offset (bits 16 - 29) must be scanline width in
+ * bytes/128bytespertile * 256 Qwords/tile. This is equivalent to
+ * lDelta * 2. Remember that if tiling, lDelta is screenwidth in
+ * bytes padded up to an even number of tilewidths.
+ */
+ if (!psav->bTiled) {
+ OUTREG32(PRI_STREAM_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFFE000) |
+ (psav->lDelta & 0x00001fff));
+ }
+ else if (pScrn->bitsPerPixel == 16) {
+ /* Scanline-length-in-bytes/128-bytes-per-tile * 256 Qwords/tile */
+ OUTREG32(PRI_STREAM_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFFE000)
+ | 0x80000000 | (psav->lDelta & 0x00001fff));
+ }
+ else if (pScrn->bitsPerPixel == 32) {
+ OUTREG32(PRI_STREAM_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFFE000)
+ | 0xC0000000 | (psav->lDelta & 0x00001fff));
+ }
+
+ /*
+ * CR69, bit 7 = 1
+ * to use MM streams processor registers to control primary stream.
+ */
+ OUTREG8(CRT_ADDRESS_REG,0x69);
+ byte = INREG8(CRT_DATA_REG) | 0x80;
+ OUTREG8(CRT_DATA_REG,byte);
+
+ OUTREG32(0x8128, 0xFFFFFFFFL);
+ OUTREG32(0x812C, 0xFFFFFFFFL);
+
+ OUTREG32(S3_BCI_GLB_BD_HIGH, bci_enable | S3_LITTLE_ENDIAN | S3_BD64);
+
+
+ /* CR50, bit 7,6,0 = 111, Use GBD.*/
+ OUTREG8(CRT_ADDRESS_REG,0x50);
+ byte = INREG8(CRT_DATA_REG) | 0xC1;
+ OUTREG8(CRT_DATA_REG, byte);
+
+ /*
+ * if MS1NB style linear tiling mode.
+ * bit MM850C[15] = 0 select NB linear tile mode.
+ * bit MM850C[15] = 1 select MS-1 128-bit non-linear tile mode.
+ */
+ ulTmp = INREG32(ADVANCED_FUNC_CTRL) | 0x8000; /* use MS-s style tile mode*/
+ OUTREG32(ADVANCED_FUNC_CTRL,ulTmp);
+
+ /*
+ * Set up Tiled Surface Registers
+ * Bit 25:20 - Surface width in tiles.
+ * Bit 29 - Y Range Flag.
+ * Bit 31:30 = 00, 4 bpp.
+ * = 01, 8 bpp.
+ * = 10, 16 bpp.
+ * = 11, 32 bpp.
+ */
+ /*
+ * Global Bitmap Descriptor Register MM816C - twister/prosavage
+ * bit 24~25: tile format
+ * 00: linear
+ * 01: destination tiling format
+ * 10: texture tiling format
+ * 11: reserved
+ * bit 29: block write disble/enable
+ * 0: disable
+ * 1: enable
+ */
+ /*
+ * Global Bitmap Descriptor Register MM816C - savage4
+ * bit 24~25: tile format
+ * 00: linear
+ * 01: reserved
+ * 10: 16 bpp tiles
+ * 11: 32 bpp tiles
+ * bit 29: block write disable/enable
+ * 0: enable
+ * 1: disable
+ */
+ if (!psav->bTiled) {
+ /*
+ * Do not enable block_write even for non-tiling modes, because
+ * the driver cannot determine if the memory type is the certain
+ * type of SGRAM for which block_write can be used.
+ */
+ psav->GlobalBD.bd1.HighPart.ResBWTile = TILE_FORMAT_LINEAR;/* linear */
+ }
+ else if (pScrn->bitsPerPixel == 16) {
+ psav->GlobalBD.bd1.HighPart.ResBWTile = tile16; /* 16 bpp/destination tiling format */
+
+ ulTmp = (((pScrn->virtualX + 0x3F) & 0x0000FFC0) >> 6) << 20;
+ OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP16);
+ }
+ else if (pScrn->bitsPerPixel == 32) {
+ psav->GlobalBD.bd1.HighPart.ResBWTile = tile32; /* 32 bpp/destination tiling format */
+
+ ulTmp = ( ((pScrn->virtualX + 0x1F) & 0x0000FFE0) >> 5) << 20;
+ OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP32);
+ }
+
+ psav->GlobalBD.bd1.HighPart.ResBWTile |= 0x10;/* disable block write - was 0 */
+ /* HW uses width */
+ psav->GlobalBD.bd1.HighPart.Stride = (ushort) psav->lDelta / (pScrn->bitsPerPixel >> 3);
+ psav->GlobalBD.bd1.HighPart.Bpp = (uchar) (pScrn->bitsPerPixel);
+ psav->GlobalBD.bd1.Offset = 0;
+
+
+ /*
+ * CR88, bit 4 - Block write enabled/disabled.
+ *
+ * Note: Block write must be disabled when writing to tiled
+ * memory. Even when writing to non-tiled memory, block
+ * write should only be enabled for certain types of SGRAM.
+ */
+ OUTREG8(CRT_ADDRESS_REG,0x88);
+ byte = INREG8(CRT_DATA_REG) | DISABLE_BLOCK_WRITE_2D;
+ OUTREG8(CRT_DATA_REG,byte);
+
+ /*
+ * CR31, bit 0 = 0, Disable address offset bits(CR6A_6-0).
+ * bit 0 = 1, Enable 8 Mbytes of display memory thru 64K window
+ * at A000:0.
+ */
+ OUTREG8(CRT_ADDRESS_REG,MEMORY_CONFIG_REG); /* cr31 */
+ byte = INREG8(CRT_DATA_REG) & (~(ENABLE_CPUA_BASE_A0000));
+ OUTREG8(CRT_DATA_REG,byte); /* perhaps this should be 0x0c */
+
+ /* turn on screen */
+ OUTREG8(SEQ_ADDRESS_REG,0x01);
+ byte = INREG8(SEQ_DATA_REG) & ~0x20;
+ OUTREG8(SEQ_DATA_REG,byte);
+
+ /* program the GBD and SBD's */
+ OUTREG32(S3_GLB_BD_LOW,psav->GlobalBD.bd2.LoPart);
+ OUTREG32(S3_GLB_BD_HIGH,psav->GlobalBD.bd2.HiPart | bci_enable | S3_LITTLE_ENDIAN | S3_BD64);
+ OUTREG32(S3_PRI_BD_LOW,psav->GlobalBD.bd2.LoPart);
+ OUTREG32(S3_PRI_BD_HIGH,psav->GlobalBD.bd2.HiPart);
+ OUTREG32(S3_SEC_BD_LOW,psav->GlobalBD.bd2.LoPart);
+ OUTREG32(S3_SEC_BD_HIGH,psav->GlobalBD.bd2.HiPart);
+}
+
+void SavageSetGBD_M7(ScrnInfoPtr pScrn)
+{
+ SavagePtr psav = SAVPTR(pScrn);
+ ulong ulTmp;
+ uchar byte;
+ int bci_enable, tile16, tile32;
+
+ bci_enable = BCI_ENABLE;
+ tile16 = TILE_FORMAT_DESTINATION16;
+ tile32 = TILE_FORMAT_DESTINATION32;
+
+
+ /* following is the enable case */
+
+ /* SR01:turn off screen */
+ OUTREG8 (SEQ_ADDRESS_REG,0x01);
+ byte = INREG8(SEQ_DATA_REG) | 0x20;
+ OUTREG8(SEQ_DATA_REG,byte);
+
+ /*
+ * CR67_3:
+ * = 1 stream processor MMIO address and stride register
+ * are used to control the primary stream
+ * = 0 standard VGA address and stride registers
+ * are used t control the primary streams
+ */
+ OUTREG8(CRT_ADDRESS_REG,0x67);
+ byte = INREG8(CRT_DATA_REG) | 0x08;
+ OUTREG8(CRT_DATA_REG,byte);
+
+ /* IGA 2 */
+ OUTREG16(SEQ_ADDRESS_REG,SELECT_IGA2_READS_WRITES);
+
+ OUTREG8(CRT_ADDRESS_REG,0x67);
+ byte = INREG8(CRT_DATA_REG) | 0x08;
+ OUTREG8(CRT_DATA_REG,byte);
+
+ OUTREG16(SEQ_ADDRESS_REG,SELECT_IGA1);
+
+ /* Set primary stream to bank 0 */
+ OUTREG8(CRT_ADDRESS_REG, MEMORY_CTRL0_REG);/* CRCA */
+ byte = INREG8(CRT_DATA_REG) & ~(MEM_PS1 + MEM_PS2) ;
+ OUTREG8(CRT_DATA_REG,byte);
+ /*
+ * if we have 8MB of frame buffer here then we must really be a 16MB
+ * card and that means that the second device is always in the upper
+ * bank of memory (MHS)
+ */
+ if (psav->videoRambytes >= 0x800000) {
+ /* 16MB Video Memory cursor is at the end in Bank 1 */
+ byte |= 0x3;
+ OUTREG16(CRT_ADDRESS_REG, (byte << 8) | MEMORY_CTRL0_REG);
+ }
+
+ /* MM81C0 and 81C4 are used to control primary stream. */
+ OUTREG32(PRI_STREAM_FBUF_ADDR0,0x00000000);
+ OUTREG32(PRI_STREAM_FBUF_ADDR1,0x00000000);
+ OUTREG32(PRI_STREAM2_FBUF_ADDR0,0x00000000);
+ OUTREG32(PRI_STREAM2_FBUF_ADDR1,0x00000000);
+
+ /*
+ * Program Primary Stream Stride Register.
+ *
+ * Tell engine if tiling on or off, set primary stream stride, and
+ * if tiling, set tiling bits/pixel and primary stream tile offset.
+ * Note that tile offset (bits 16 - 29) must be scanline width in
+ * bytes/128bytespertile * 256 Qwords/tile. This is equivalent to
+ * lDelta * 2. Remember that if tiling, lDelta is screenwidth in
+ * bytes padded up to an even number of tilewidths.
+ */
+ if (!psav->bTiled) {
+ OUTREG32(PRI_STREAM_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFF0000) |
+ (psav->lDelta & 0x00003fff));
+ OUTREG32(PRI_STREAM2_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFF0000) |
+ (psav->lDelta & 0x00003fff));
+ } else if (pScrn->bitsPerPixel == 16) {
+ /* Scanline-length-in-bytes/128-bytes-per-tile * 256 Qwords/tile */
+ OUTREG32(PRI_STREAM_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFF0000)
+ | 0x80000000 | (psav->lDelta & 0x00003fff));
+ OUTREG32(PRI_STREAM2_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFF0000)
+ | 0x80000000 | (psav->lDelta & 0x00003fff));
+
+ } else if (pScrn->bitsPerPixel == 32) {
+ OUTREG32(PRI_STREAM_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFF0000)
+ | 0xC0000000 | (psav->lDelta & 0x00003fff));
+ OUTREG32(PRI_STREAM2_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFF0000)
+ | 0xC0000000 | (psav->lDelta & 0x00003fff));
+ }
+
+ OUTREG32(0x8128, 0xFFFFFFFFL);
+ OUTREG32(0x812C, 0xFFFFFFFFL);
+
+ OUTREG32(S3_BCI_GLB_BD_HIGH, bci_enable | S3_LITTLE_ENDIAN | S3_BD64);
+
+ /* CR50, bit 7,6,0 = 111, Use GBD.*/
+ OUTREG8(CRT_ADDRESS_REG,0x50);
+ byte = INREG8(CRT_DATA_REG) | 0xC1;
+ OUTREG8(CRT_DATA_REG, byte);
+
+ /*
+ * CR78, bit 3 - Block write enabled(1)/disabled(0).
+ * bit 2 - Block write cycle time(0:2 cycles,1: 1 cycle)
+ * Note: Block write must be disabled when writing to tiled
+ * memory. Even when writing to non-tiled memory, block
+ * write should only be enabled for certain types of SGRAM.
+ */
+ OUTREG8(CRT_ADDRESS_REG,0x78);
+ /*byte = INREG8(CRT_DATA_REG) & ~0x0C;*/
+ byte = INREG8(CRT_DATA_REG) | 0xfb;
+ OUTREG8(CRT_DATA_REG,byte);
+
+ /*
+ * Tiled Surface 0 Registers MM48C40:
+ * bit 0~23: tile surface 0 frame buffer offset
+ * bit 24~29:tile surface 0 width
+ * bit 30~31:tile surface 0 bits/pixel
+ * 00: reserved
+ * 01, 8 bits
+ * 10, 16 Bits.
+ * 11, 32 Bits.
+ */
+ /*
+ * Global Bitmap Descriptor Register MM816C
+ * bit 24~25: tile format
+ * 00: linear
+ * 01: reserved
+ * 10: 16 bit
+ * 11: 32 bit
+ * bit 29: block write disble/enable
+ * 0: enable
+ * 1: disable
+ */
+ if (!psav->bTiled) {
+ /*
+ * Do not enable block_write even for non-tiling modes, because
+ * the driver cannot determine if the memory type is the certain
+ * type of SGRAM for which block_write can be used.
+ */
+ psav->GlobalBD.bd1.HighPart.ResBWTile = TILE_FORMAT_LINEAR;/* linear */
+
+ }
+ else if (pScrn->bitsPerPixel == 16) {
+ psav->GlobalBD.bd1.HighPart.ResBWTile = tile16;/* 16 bit */
+
+ ulTmp = ((psav->lDelta / 2) >> 6) << 24;
+ OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP16);
+ }
+ else if (pScrn->bitsPerPixel == 32) {
+ psav->GlobalBD.bd1.HighPart.ResBWTile = tile32;/* 32 bit */
+
+ ulTmp = ((psav->lDelta / 4) >> 5) << 24;
+ OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP32);
+ }
+
+ psav->GlobalBD.bd1.HighPart.ResBWTile |= 0x10;/* disable block write */
+ /* HW uses width */
+ psav->GlobalBD.bd1.HighPart.Stride = (ushort)(psav->lDelta / (pScrn->bitsPerPixel >> 3));
+ psav->GlobalBD.bd1.HighPart.Bpp = (uchar) (pScrn->bitsPerPixel);
+ psav->GlobalBD.bd1.Offset = 0;
+
+
+ /*
+ * CR31, bit 0 = 0, Disable address offset bits(CR6A_6-0).
+ * bit 0 = 1, Enable 8 Mbytes of display memory thru 64K window
+ * at A000:0.
+ */
+ OUTREG8(CRT_ADDRESS_REG,MEMORY_CONFIG_REG); /* cr31 */
+ byte = INREG8(CRT_DATA_REG) & (~(ENABLE_CPUA_BASE_A0000));
+ OUTREG8(CRT_DATA_REG,byte);
+
+ /* program the GBD and SBD's */
+ OUTREG32(S3_GLB_BD_LOW,psav->GlobalBD.bd2.LoPart );
+ /* 8: bci enable */
+ OUTREG32(S3_GLB_BD_HIGH,(psav->GlobalBD.bd2.HiPart
+ | bci_enable | S3_LITTLE_ENDIAN | S3_BD64));
+ OUTREG32(S3_PRI_BD_LOW,psav->GlobalBD.bd2.LoPart);
+ OUTREG32(S3_PRI_BD_HIGH,psav->GlobalBD.bd2.HiPart);
+ OUTREG32(S3_SEC_BD_LOW,psav->GlobalBD.bd2.LoPart);
+ OUTREG32(S3_SEC_BD_HIGH,psav->GlobalBD.bd2.HiPart);
+
+ /* turn on screen */
+ OUTREG8(SEQ_ADDRESS_REG,0x01);
+ byte = INREG8(SEQ_DATA_REG) & ~0X20;
+ OUTREG8(SEQ_DATA_REG,byte);
+}
+
+void SavageSetGBD_PM(ScrnInfoPtr pScrn)
+{
+ SavagePtr psav = SAVPTR(pScrn);
+ ulong ulTmp;
+ uchar byte;
+ int bci_enable, tile16, tile32;
+
+ /* Is supersavage like savage4 or twister?
+ * change the bci_enable and tile bits here.
+ */
+ bci_enable = BCI_ENABLE_TWISTER;
+ tile16 = TILE_DESTINATION;
+ tile32 = TILE_DESTINATION;
+
+
+ /* following is the enable case */
+
+ /* SR01:turn off screen */
+ OUTREG8 (SEQ_ADDRESS_REG,0x01);
+ byte = INREG8(SEQ_DATA_REG) | 0x20;
+ OUTREG8(SEQ_DATA_REG,byte);
+
+ /*
+ * CR67_3:
+ * = 1 stream processor MMIO address and stride register
+ * are used to control the primary stream
+ * = 0 standard VGA address and stride registers
+ * are used t control the primary streams
+ */
+ OUTREG8(CRT_ADDRESS_REG,0x67);
+ byte = INREG8(CRT_DATA_REG) | 0x08;
+ OUTREG8(CRT_DATA_REG,byte);
+
+ /* IGA 2 */
+ OUTREG16(SEQ_ADDRESS_REG,SELECT_IGA2_READS_WRITES);
+
+ OUTREG8(CRT_ADDRESS_REG,0x67);
+ byte = INREG8(CRT_DATA_REG) | 0x08;
+ OUTREG8(CRT_DATA_REG,byte);
+
+ OUTREG16(SEQ_ADDRESS_REG,SELECT_IGA1);
+
+ /*
+ * load ps1 active registers as determined by MM81C0/81C4
+ * load ps2 active registers as determined by MM81B0/81B4
+ */
+ OUTREG8(CRT_ADDRESS_REG,0x65);
+ byte = INREG8(CRT_DATA_REG) | 0x03;
+ OUTREG8(CRT_DATA_REG,byte);
+
+ /*
+ * Program Primary Stream Stride Register.
+ *
+ * Tell engine if tiling on or off, set primary stream stride, and
+ * if tiling, set tiling bits/pixel and primary stream tile offset.
+ * Note that tile offset (bits 16 - 29) must be scanline width in
+ * bytes/128bytespertile * 256 Qwords/tile. This is equivalent to
+ * lDelta * 2. Remember that if tiling, lDelta is screenwidth in
+ * bytes padded up to an even number of tilewidths.
+ */
+ if (!psav->bTiled) {
+ OUTREG32(PRI_STREAM_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFF0000) |
+ (psav->lDelta & 0x00001fff));
+ OUTREG32(PRI_STREAM2_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFF0000) |
+ (psav->lDelta & 0x00001fff));
+ } else if (pScrn->bitsPerPixel == 16) {
+ /* Scanline-length-in-bytes/128-bytes-per-tile * 256 Qwords/tile */
+ OUTREG32(PRI_STREAM_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFF0000)
+ | 0x80000000 | (psav->lDelta & 0x00001fff));
+ OUTREG32(PRI_STREAM2_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFF0000)
+ | 0x80000000 | (psav->lDelta & 0x00001fff));
+
+ } else if (pScrn->bitsPerPixel == 32) {
+ OUTREG32(PRI_STREAM_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFF0000)
+ | 0xC0000000 | (psav->lDelta & 0x00001fff));
+ OUTREG32(PRI_STREAM2_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFF0000)
+ | 0xC0000000 | (psav->lDelta & 0x00001fff));
+ }
+
+ /* MM81C0 and 81C4 are used to control primary stream. */
+ OUTREG32(PRI_STREAM_FBUF_ADDR0,0x80000000);
+ OUTREG32(PRI_STREAM_FBUF_ADDR1,0x00000000);
+ OUTREG32(PRI_STREAM2_FBUF_ADDR0,0x80000000);
+ OUTREG32(PRI_STREAM2_FBUF_ADDR1,0x00000000);
+
+ OUTREG32(0x8128, 0xFFFFFFFFL);
+ OUTREG32(0x812C, 0xFFFFFFFFL);
+
+ /* bit 28:block write disable */
+ OUTREG32(S3_GLB_BD_HIGH, bci_enable | S3_BD64 | 0x10000000);
+
+ /* CR50, bit 7,6,0 = 111, Use GBD.*/
+ OUTREG8(CRT_ADDRESS_REG,0x50);
+ byte = INREG8(CRT_DATA_REG) | 0xC1;
+ OUTREG8(CRT_DATA_REG, byte);
+
+ if (!psav->bTiled) {
+ /*
+ * Do not enable block_write even for non-tiling modes, because
+ * the driver cannot determine if the memory type is the certain
+ * type of SGRAM for which block_write can be used.
+ */
+ psav->GlobalBD.bd1.HighPart.ResBWTile = TILE_FORMAT_LINEAR;/* linear */
+
+ }
+ else if (pScrn->bitsPerPixel == 16) {
+ psav->GlobalBD.bd1.HighPart.ResBWTile = tile16;/* tile format destination */
+
+ ulTmp = (((pScrn->virtualX + 0x3f) & 0x0000ffc0) >> 6) << 20;
+ OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP16);
+ }
+ else if (pScrn->bitsPerPixel == 32) {
+ psav->GlobalBD.bd1.HighPart.ResBWTile = tile32;/* tile format destination */
+
+ ulTmp = (((pScrn->virtualX + 0x1f) & 0x0000ffe0) >> 5) << 20;
+ OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP32);
+ }
+
+ psav->GlobalBD.bd1.HighPart.ResBWTile |= 0x10;/* disable block write */
+ /* HW uses width */
+ psav->GlobalBD.bd1.HighPart.Stride = (ushort)(psav->lDelta / (pScrn->bitsPerPixel >> 3));
+ psav->GlobalBD.bd1.HighPart.Bpp = (uchar) (pScrn->bitsPerPixel);
+ psav->GlobalBD.bd1.Offset = 0;
+
+ /*
+ * CR31, bit 0 = 0, Disable address offset bits(CR6A_6-0).
+ * bit 0 = 1, Enable 8 Mbytes of display memory thru 64K window
+ * at A000:0.
+ */
+ OUTREG8(CRT_ADDRESS_REG,MEMORY_CONFIG_REG);
+ byte = INREG8(CRT_DATA_REG) & (~(ENABLE_CPUA_BASE_A0000));
+ OUTREG8(CRT_DATA_REG,byte);
+
+ /* program the GBD and SBDs */
+ OUTREG32(S3_GLB_BD_LOW,psav->GlobalBD.bd2.LoPart );
+ OUTREG32(S3_GLB_BD_HIGH,(psav->GlobalBD.bd2.HiPart
+ | bci_enable /* AGD: shouldn't BCI be enabled? */
+ | S3_LITTLE_ENDIAN | 0x10000000 | S3_BD64));
+ OUTREG32(S3_PRI_BD_LOW,psav->GlobalBD.bd2.LoPart);
+ OUTREG32(S3_PRI_BD_HIGH,psav->GlobalBD.bd2.HiPart);
+ OUTREG32(S3_SEC_BD_LOW,psav->GlobalBD.bd2.LoPart);
+ OUTREG32(S3_SEC_BD_HIGH,psav->GlobalBD.bd2.HiPart);
+
+ /* turn on screen */
+ OUTREG8(SEQ_ADDRESS_REG,0x01);
+ byte = INREG8(SEQ_DATA_REG) & ~0x20;
+ OUTREG8(SEQ_DATA_REG,byte);
+}
+
+void SavageSetGBD_2000(ScrnInfoPtr pScrn)
{
vgaHWPtr hwp = VGAHWPTR(pScrn);
SavagePtr psav = SAVPTR(pScrn);
@@ -326,6 +979,9 @@ SavageSetGBD( ScrnInfoPtr pScrn )
unsigned int vgaCRReg = hwp->IOBase + 5;
unsigned long GlobalBitmapDescriptor;
+
+/* AGD: no idea how to program savage2000 GBD... for now default to Tim's method */
+
GlobalBitmapDescriptor = 1 | 8 | BCI_BD_BW_DISABLE;
BCI_BD_SET_BPP(GlobalBitmapDescriptor, pScrn->bitsPerPixel);
BCI_BD_SET_STRIDE(GlobalBitmapDescriptor, pScrn->displayWidth);
@@ -354,10 +1010,9 @@ SavageSetGBD( ScrnInfoPtr pScrn )
OUTREG(0x817C, GlobalBitmapDescriptor);
OUTREG(PRI_STREAM_STRIDE, pScrn->displayWidth * pScrn->bitsPerPixel >> 3);
- OUTREG(SEC_STREAM_STRIDE, pScrn->displayWidth * pScrn->bitsPerPixel >> 3);
+ OUTREG(SEC_STREAM_STRIDE, pScrn->displayWidth * pScrn->bitsPerPixel >> 3);
}
-
/* Acceleration init function, sets up pointers to our accelerated functions */
Bool
@@ -417,7 +1072,7 @@ SavageInitAccel(ScreenPtr pScreen)
#if 1
xaaptr->SetupForScreenToScreenCopy = SavageSetupForScreenToScreenCopy;
xaaptr->SubsequentScreenToScreenCopy = SavageSubsequentScreenToScreenCopy;
- xaaptr->ScreenToScreenCopyFlags = NO_TRANSPARENCY | NO_PLANEMASK | ROP_NEEDS_SOURCE;
+ xaaptr->ScreenToScreenCopyFlags = NO_TRANSPARENCY | ROP_NEEDS_SOURCE;
#endif
@@ -438,7 +1093,6 @@ SavageInitAccel(ScreenPtr pScreen)
xaaptr->Mono8x8PatternFillFlags = 0
| HARDWARE_PATTERN_PROGRAMMED_BITS
| HARDWARE_PATTERN_SCREEN_ORIGIN
- | ROP_NEEDS_SOURCE
| BIT_ORDER_IN_BYTE_MSBFIRST
;
if( psav->Chipset == S3_SAVAGE4 )
@@ -480,7 +1134,7 @@ SavageInitAccel(ScreenPtr pScreen)
xaaptr->SolidLineFlags = NO_PLANEMASK;
xaaptr->SetupForSolidLine = SavageSetupForSolidFill;
xaaptr->SubsequentSolidBresenhamLine = SavageSubsequentSolidBresenhamLine;
- xaaptr->SubsequentSolidTwoPointLine = SavageSubsequentSolidTwoPointLine;
+ /*xaaptr->SubsequentSolidTwoPointLine = SavageSubsequentSolidTwoPointLine;*/
#if 0
xaaptr->SubsequentSolidFillTrap = SavageSubsequentSolidFillTrap;
#endif
@@ -555,6 +1209,279 @@ SavageInitAccel(ScreenPtr pScreen)
* enabled the PIXMAP_CACHE flag, then these lines can be omitted.
*/
+#ifdef XF86DRI
+ if (psav->directRenderingEnabled) {
+ SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo;
+ BoxRec MemBox;
+ int cpp = pScrn->bitsPerPixel / 8;
+ int scanlines;
+ /*int widthBytes = pScrn->displayWidth * cpp;*/
+ int widthBytes = psav->lDelta;
+ /*int widthBytes = psav->l3DDelta;*/
+ int bufferSize = ((pScrn->virtualY * widthBytes + SAVAGE_BUFFER_ALIGN)
+ & ~SAVAGE_BUFFER_ALIGN);
+ int tiledwidthBytes,tiledBufferSize;
+
+ pSAVAGEDRIServer->frontbufferSize = bufferSize;
+ /*tiledwidthBytes = psav->lDelta;*/
+ tiledwidthBytes = psav->l3DDelta;
+
+ if (cpp == 2) {
+ tiledBufferSize = ((pScrn->virtualX+63)/64)*((pScrn->virtualY+15)/16)
+ *2048;
+ } else {
+ tiledBufferSize = ((pScrn->virtualX+31)/32)*((pScrn->virtualY+15)/16)
+ *2048;
+ }
+ /*set Depth buffer to 32bpp*/
+ /*tiledwidthBytes_Z = ((pScrn->virtualX + 31)& ~0x0000001F)*4;
+ tiledBufferSize_Z = ((pScrn->virtualX+31)/32)*((pScrn->virtualY+15)/16)
+ *2048;*/
+
+ pSAVAGEDRIServer->backbufferSize = tiledBufferSize;
+ /*pSAVAGEDRIServer->depthbufferSize = tiledBufferSize_Z;*/
+ pSAVAGEDRIServer->depthbufferSize = tiledBufferSize;
+
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO,
+ "virtualX:%d,virtualY:%d\n",
+ pScrn->virtualX,pScrn->virtualY);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO,
+ "bpp:%d,tiledwidthBytes:%d,tiledBufferSize:%d \n",
+ pScrn->bitsPerPixel,
+ tiledwidthBytes,tiledBufferSize);
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO,
+ "bpp:%d,widthBytes:%d,BufferSize:%d \n",
+ pScrn->bitsPerPixel,
+ widthBytes,bufferSize);
+
+ pSAVAGEDRIServer->frontOffset = 0; /* AGD: should probably be pScrn->fbOffset */
+ pSAVAGEDRIServer->frontPitch = widthBytes;
+
+ /* Try for front, back, depth, and two framebuffers worth of
+ * pixmap cache. Should be enough for a fullscreen background
+ * image plus some leftovers.
+ */
+ /* pSAVAGEDRIServer->textureSize = psav->videoRambytes -
+ tiledBufferSize -
+ tiledBufferSize_Z -
+ -0x602000;*/
+ pSAVAGEDRIServer->textureSize = psav->videoRambytes -
+ 4096 - /* hw cursor*/
+ psav->cobSize - /*COB*/
+ bufferSize-
+ tiledBufferSize -
+ tiledBufferSize -
+ 0x200000;
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO,
+ "videoRambytes:0x%08lx \n",
+ psav->videoRambytes);
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO,
+ "textureSize:0x%08lx \n",
+ pSAVAGEDRIServer->textureSize);
+
+ /* If that gives us less than half the available memory, let's
+ * be greedy and grab some more. Sorry, I care more about 3D
+ * performance than playing nicely, and you'll get around a full
+ * framebuffer's worth of pixmap cache anyway.
+ */
+#if 0
+ if ( pSAVAGEDRIServer->textureSize < (int)psav->FbMapSize / 2 ) {
+ pSAVAGEDRIServer->textureSize = psav->FbMapSize - 4 * bufferSize;
+ }
+#endif
+ /* Check to see if there is more room available after the maximum
+ * scanline for textures.
+ */
+#if 0
+ if ( (int)psav->FbMapSize - maxlines * widthBytes - bufferSize * 2
+ > pSAVAGEDRIServer->textureSize ) {
+ pSAVAGEDRIServer->textureSize = (psav->FbMapSize -
+ maxlines * widthBytes -
+ bufferSize * 2);
+ }
+#endif
+ /* Set a minimum usable local texture heap size. This will fit
+ * two 256x256x32bpp textures.
+ */
+ if ( pSAVAGEDRIServer->textureSize < 512 * 1024 ) {
+ pSAVAGEDRIServer->textureOffset = 0;
+ pSAVAGEDRIServer->textureSize = 0;
+ }
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO,
+ "textureSize:0x%08lx \n",
+ pSAVAGEDRIServer->textureSize);
+
+ /* Reserve space for textures */
+ /* if (pSAVAGEDRIServer->textureSize)*/
+ pSAVAGEDRIServer->textureOffset = (psav->videoRambytes -
+ 4096 - /* hw cursor*/
+ psav->cobSize - /*COB*/
+ pSAVAGEDRIServer->textureSize) & ~SAVAGE_BUFFER_ALIGN;
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO,
+ "textureOffset:0x%08lx \n",
+ pSAVAGEDRIServer->textureOffset);
+
+ /* Reserve space for the shared depth buffer */
+ /*pSAVAGEDRIServer->depthOffset = (pSAVAGEDRIServer->textureOffset -
+ tiledBufferSize_Z + SAVAGE_BUFFER_ALIGN) & ~SAVAGE_BUFFER_ALIGN;
+ */
+ pSAVAGEDRIServer->depthOffset = (pSAVAGEDRIServer->textureOffset -
+ tiledBufferSize) & ~SAVAGE_BUFFER_ALIGN;
+ /*pSAVAGEDRIServer->depthPitch = tiledwidthBytes_Z;*/
+ pSAVAGEDRIServer->depthPitch = tiledwidthBytes;
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO,
+ "depthOffset:0x%08lx,depthPicth:%d\n",
+ pSAVAGEDRIServer->depthOffset,pSAVAGEDRIServer->depthPitch);
+
+ /* Reserve space for the shared back buffer */
+ pSAVAGEDRIServer->backOffset = (pSAVAGEDRIServer->depthOffset -
+ tiledBufferSize ) & ~SAVAGE_BUFFER_ALIGN;
+
+ pSAVAGEDRIServer->backPitch = tiledwidthBytes;
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO,
+ "backOffset:0x%08lx,backPicth:%d\n",
+ pSAVAGEDRIServer->backOffset,pSAVAGEDRIServer->backPitch);
+
+ /*scanlines = pSAVAGEDRIServer->backOffset / widthBytes - 1;*/
+ /*if ( scanlines > maxlines ) scanlines = maxlines;*/
+ /* CR47983, XvMC do not work on system with frame buffer less than 32MB.
+ * VBE reports frame buffer size a little less than 16MB, this makes the condition
+ * truns out FALSE.
+ * Now just reduce the level to 14.5MB, things should be OK, while the hwmc frame buffer layout
+ * caculation need more understanding and should be fixed.
+ */
+ /*if total memory is less than 16M, there is no HWMC support */
+ if((psav->videoRambytes < /*16*/(14*1024+512)*1024L) || psav->bDisableXvMC)
+ {
+ psav->hwmcOffset = 0;
+ psav->hwmcSize = 0;
+ }
+ else
+ {
+ psav->hwmcSize = (10*1024+512)*1024; /* HWMC needs 10MB FB */
+ psav->hwmcOffset = (psav->videoRambytes - 0x2000 - psav->hwmcSize) &
+ ~SAVAGE_BUFFER_ALIGN;
+ if (psav->hwmcOffset < bufferSize) {
+ /* If hwmc buffer will lay in on-screen buffer. */
+ psav->hwmcSize = 0;
+ psav->hwmcOffset = 0;
+ }
+ }
+
+ /* CR48438: Title: "Lots of garbage appear on the background when
+ * drag the DVD player XINE window at 1024x768 or higher mode."
+ * hwmc used xserver's memory, now xserver will get less memory.
+ * Both 3D and hwmc's memory usage are considered now.
+ */
+ if (pSAVAGEDRIServer->backOffset < psav->hwmcOffset )
+ psav->cyMemory = pSAVAGEDRIServer->backOffset / widthBytes - 1;
+ else
+ psav->cyMemory = psav->hwmcOffset / widthBytes -1;
+ if (psav->cyMemory > 0x7FFF) {
+ psav->cyMemory = 0x7FFF;
+ }
+
+ scanlines = pSAVAGEDRIServer->backOffset / widthBytes - 1;
+ MemBox.x1 = 0;
+ MemBox.y1 = 0;
+ MemBox.x2 = psav->cxMemory;
+ MemBox.y2 = scanlines; /*psav->cyMemory;*/
+
+ if (!xf86InitFBManager(pScreen, &MemBox)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Memory manager initialization to (%d,%d) (%d,%d) failed\n",
+ MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2 );
+ return FALSE;
+ } else {
+ int tmp,width, height;
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO,
+ "Memory manager initialized to (%d,%d) (%d,%d)\n",
+ MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2 );
+ /*
+ * because the alignment requirement,the on-screen need more memory
+ * than (0,0,virtualX,virtualY), but xf86InitFBManager only subtract
+ * (pScrn->virtualX * pScrn->virtualY from (0,0,cxMemory,cyMemory),so
+ * here,we should reserve some memory for on-screen
+ */
+ tmp = ((psav->cxMemory * pScrn->virtualY - pScrn->virtualX * pScrn->virtualY)
+ + psav->cxMemory -1) / (psav->cxMemory);
+ if (tmp)
+ xf86AllocateOffscreenArea(pScreen, psav->cxMemory,tmp, 0, NULL, NULL, NULL);
+
+ if (xf86QueryLargestOffscreenArea(pScreen, &width,
+ &height, 0, 0, 0 ) ) {
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO,
+ "Largest offscreen area available: %d x %d\n",
+ width, height );
+ }
+ }
+ psav->reserved = 0;
+
+ if(tiledBufferSize > bufferSize)
+ {
+ psav->reserved = xf86AllocateOffscreenLinear(pScreen,
+ (tiledBufferSize - bufferSize),1,0,0,0);
+
+ }
+ if(psav->reserved)
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO,
+ "Reserved for tiled front buffer at offset 0x%08lx ,size:0x%08lx\n",
+ psav->reserved->offset, psav->reserved->size);
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO,
+ "Reserved back buffer at offset 0x%x\n",
+ pSAVAGEDRIServer->backOffset );
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO,
+ "Reserved depth buffer at offset 0x%x\n",
+ pSAVAGEDRIServer->depthOffset );
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO,
+ "Reserved %d kb for textures at offset 0x%x\n",
+ pSAVAGEDRIServer->textureSize/1024,
+ pSAVAGEDRIServer->textureOffset );
+ }
+ else
+#endif
+ {
+ int tmp;
+
+ /*
+ * why this code? because BoxRec members are short int
+ * if cyMemory is bigger than 0x7fff,then it will overflow
+ */
+ if (psav->cyMemory > 0x7FFF) {
+ psav->cyMemory = 0x7FFF;
+ }
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = psav->cxMemory;
+ AvailFBArea.y2 = psav->cyMemory;
+ xf86InitFBManager(pScreen, &AvailFBArea);
+ /*
+ * because the alignment requirement,the on-screen need more memory
+ * than (0,0,virtualX,virtualY), but xf86InitFBManager only subtract
+ * (pScrn->virtualX * pScrn->virtualY from (0,0,cxMemory,cyMemory),so
+ * here,we should reserver some memory for on-screen
+ */
+ tmp = ((psav->cxMemory * pScrn->virtualY - pScrn->virtualX * pScrn->virtualY)
+ + psav->cxMemory -1) / (psav->cxMemory);
+ if (tmp)
+ xf86AllocateOffscreenArea(pScreen, psav->cxMemory,tmp, 0, NULL, NULL, NULL);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using %d lines for offscreen memory.\n",
+ psav->cyMemory - pScrn->virtualY );
+ }
+
+#if 0
AvailFBArea.x1 = 0;
AvailFBArea.y1 = 0;
AvailFBArea.x2 = pScrn->displayWidth;
@@ -563,6 +1490,8 @@ SavageInitAccel(ScreenPtr pScreen)
xf86DrvMsg( pScrn->scrnIndex, X_INFO,
"Using %d lines for offscreen memory.\n",
psav->ScissB - pScrn->virtualY );
+#endif
+
return XAAInit(pScreen, xaaptr);
}
@@ -1008,7 +1937,8 @@ SavageSetupForColor8x8PatternFill(
cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP
| BCI_CMD_DEST_GBD | BCI_CMD_PAT_PBD_COLOR_NEW;
- mix = XAAHelpSolidROP( pScrn, &trans_col, planemask, &rop );
+ /*mix = XAAHelpSolidROP( pScrn, &trans_col, planemask, &rop );*/
+ mix = SavageHelpSolidROP( pScrn, &trans_col, planemask, &rop );
BCI_CMD_SET_ROP(cmd, rop);
bd = BCI_BD_BW_DISABLE;
@@ -1084,7 +2014,7 @@ SavageSubsequentSolidBresenhamLine(
e2+err));
}
-
+#if 0
static void
SavageSubsequentSolidTwoPointLine(
ScrnInfoPtr pScrn,
@@ -1144,7 +2074,7 @@ SavageSubsequentSolidTwoPointLine(
BCI_SEND( BCI_LINE_STEPS( 2 * (min - max), 2 * min ) );
BCI_SEND( BCI_LINE_MISC( max, ym, xp, yp, 2 * min - max ) );
}
-
+#endif
static void
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_bci.h b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_bci.h
index 0d7c4893f..2e58de220 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_bci.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_bci.h
@@ -1,8 +1,45 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_bci.h,v 1.4 2002/10/02 20:39:54 alanh Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_bci.h,v 1.2 2001/10/01 13:44:09 eich Exp $ */
#ifndef _S3BCI_H_
#define _S3BCI_H_
+
+/* BCI Control Register */
+#define S3_BCI_CONTROL 0x816C
+
+/*
+ * High 8 bit of primary bitmap descriptor 2 register.
+ * Bits 25-24: Tile Format 00 = Linear ; 10 = 16 bits; 11 = 32 bits (Savage4)
+ * 00 = Linear ; 01 = Tile; 10 = Texture tiling format/ Destination Tiling format
+ * 11 = Reserved/Destination tiling format.
+ */
+
+
+
+#define TILE_LINEAR 0
+#define TILE_FORMAT_LINEAR 0
+#define TILE_TEXTURE 2
+#define TILE_DESTINATION 1
+#define TILE_FORMAT_DESTINATION16 2
+#define TILE_FORMAT_DESTINATION32 3
+
+/* BD - BCI enable */
+/* savage4, MX, IX, 3D */
+#define BCI_ENABLE 8
+/* twister, prosavage */
+/* not sure which one supersavage fits into */
+#define BCI_ENABLE_TWISTER 0
+
+#define S3_BIG_ENDIAN 4
+#define S3_LITTLE_ENDIAN 0
+#define S3_BD64 1
+
+
+
+/* Global Bitmap Descriptor */
+#define S3_BCI_GLB_BD_LOW 0x8168
+#define S3_BCI_GLB_BD_HIGH 0x816C
+
#define REVERSE_BYTE_ORDER32(dword) {\
unsigned int temp; \
dword = (temp & 0xFF) << 24; \
@@ -71,7 +108,7 @@
#define BCI_BD_TILE_MASK 0x03000000
#define BCI_BD_TILE_NONE 0x00000000
#define BCI_BD_TILE_16 0x02000000
-#define BCI_BD_TILE_32 0x04000000
+#define BCI_BD_TILE_32 0x03000000
#define BCI_BD_GET_BPP(bd) (((bd) >> 16) & 0xFF)
#define BCI_BD_SET_BPP(bd, bpp) ((bd) |= (((bpp) & 0xFF) << 16))
#define BCI_BD_GET_STRIDE(bd) ((bd) & 0xFFFF)
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_cursor.c b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_cursor.c
index 16aaabf3d..614b3e511 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_cursor.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_cursor.c
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_cursor.c,v 1.9 2003/01/18 15:22:29 eich Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_cursor.c,v 1.6 2001/11/02 16:24:51 alanh Exp $ */
/*
* Hardware cursor support for S3 Savage 4.0 driver. Taken with
@@ -24,7 +24,9 @@ static void SavageSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
#define outCRReg(reg, val) (VGAHWPTR(pScrn))->writeCrtc( VGAHWPTR(pScrn), reg, val )
#define inSRReg(reg) (VGAHWPTR(pScrn))->readSeq( VGAHWPTR(pScrn), reg )
#define outSRReg(reg, val) (VGAHWPTR(pScrn))->writeSeq( VGAHWPTR(pScrn), reg, val )
+#if 0
#define inStatus1() (VGAHWPTR(pScrn))->readST01( VGAHWPTR(pScrn) )
+#endif
/*
* certain HW cursor operations seem
@@ -39,27 +41,6 @@ static void SavageSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
}
#define MAX_CURS 64
-/*
- * Disable HW Cursor on stretched LCDs. We don't know how to
- * detect if display is stretched. Therefore we cannot rescale
- * the HW cursor position.
- */
-
-static Bool
-SavageUseHWCursor(ScreenPtr pScr, CursorPtr pCurs)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScr->myNum];
- SavagePtr psav = SAVPTR(pScrn);
-
- if (psav->PanelX != pScrn->currentMode->HDisplay
- || psav->PanelY != pScrn->currentMode->VDisplay) {
- /* BIT 1 : CRT is active, BIT 2 : LCD is active */
- unsigned char cr6d = inCRReg( 0x6d );
- if (cr6d & 0x02)
- return FALSE;
- }
- return TRUE;
-}
Bool
SavageHWCursorInit(ScreenPtr pScreen)
@@ -101,12 +82,8 @@ SavageHWCursorInit(ScreenPtr pScreen)
infoPtr->LoadCursorImage = SavageLoadCursorImage;
infoPtr->HideCursor = SavageHideCursor;
infoPtr->ShowCursor = SavageShowCursor;
+ infoPtr->UseHWCursor = NULL;
- if ((S3_SAVAGE_MOBILE_SERIES(psav->Chipset)
- || (psav->Chipset == S3_PROSAVAGE)) && !psav->CrtOnly)
- infoPtr->UseHWCursor = SavageUseHWCursor;
- else
- infoPtr->UseHWCursor = NULL;
if( !psav->CursorKByte )
psav->CursorKByte = pScrn->videoRam - 4;
@@ -118,9 +95,8 @@ SavageHWCursorInit(ScreenPtr pScreen)
void
SavageShowCursor(ScrnInfoPtr pScrn)
{
- /* Turn cursor on. */
+ /* Turn cursor on. */
outCRReg( 0x45, inCRReg(0x45) | 0x01 );
- SAVPTR(pScrn)->hwc_on = TRUE;
}
@@ -128,12 +104,12 @@ void
SavageHideCursor(ScrnInfoPtr pScrn)
{
/* Turn cursor off. */
+
if( S3_SAVAGE4_SERIES( SAVPTR(pScrn)->Chipset ) )
{
waitHSync(5);
}
outCRReg( 0x45, inCRReg(0x45) & 0xfe );
- SAVPTR(pScrn)->hwc_on = FALSE;
}
static void
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_dga.c b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_dga.c
index 55f057e62..50a36b0e1 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_dga.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_dga.c
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_dga.c,v 1.6 2003/01/18 15:22:29 eich Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_dga.c,v 1.3 2001/05/18 23:35:32 dawes Exp $ */
/*
Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
@@ -275,7 +275,7 @@ Savage_SetMode(
psav->DGAactive = FALSE;
SavageSwitchMode(index, pScrn->currentMode, 0);
- if( psav->hwcursor && psav->hwc_on )
+ if( psav->hwcursor )
SavageShowCursor(pScrn);
} else {
Bool holdBIOS = psav->UseBIOS;
@@ -289,11 +289,8 @@ Savage_SetMode(
pMode->bitsPerPixel, pMode->depth);
#endif
- if( psav->hwcursor && psav->hwc_on) {
+ if( psav->hwcursor )
SavageHideCursor(pScrn);
- psav->hwc_on = TRUE; /* save for later restauration */
- }
-
if(!psav->DGAactive) { /* save the old parameters */
OldDisplayWidth[index] = pScrn->displayWidth;
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c
index cdfe256fb..2d0c16e84 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c,v 1.34 2003/02/25 04:08:21 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c,v 1.24 2001/11/02 16:24:51 alanh Exp $ */
/*
* vim: sw=4 ts=8 ai ic:
*
@@ -18,15 +18,20 @@
#include "globals.h"
#define DPMS_SERVER
#include "extensions/dpms.h"
-
+/*
#ifdef XvExtension
#include "xf86xv.h"
#endif
+*/
#include "savage_driver.h"
+#include "savage_regs.h"
#include "savage_bci.h"
-
+#ifdef XF86DRI
+#define _XF86DRI_SERVER_
+#include "savage_dri.h"
+#endif
/*
@@ -76,16 +81,17 @@ static unsigned int SavageDDC1Read(ScrnInfoPtr pScrn);
static void SavageProbeDDC(ScrnInfoPtr pScrn, int index);
static void SavageGetTvMaxSize(SavagePtr psav);
static Bool SavagePanningCheck(ScrnInfoPtr pScrn);
+static Bool SavageCheckAvailableRamFor3D(ScrnInfoPtr pScrn);
extern ScrnInfoPtr gpScrn;
#define iabs(a) ((int)(a)>0?(a):(-(a)))
#define DRIVER_NAME "savage"
-#define DRIVER_VERSION "1.1.26"
+#define DRIVER_VERSION "1.1.27a"
#define VERSION_MAJOR 1
#define VERSION_MINOR 1
-#define PATCHLEVEL 26
+#define PATCHLEVEL 27
#define SAVAGE_VERSION ((VERSION_MAJOR << 24) | \
(VERSION_MINOR << 16) | \
PATCHLEVEL)
@@ -145,6 +151,8 @@ static SymTabRec SavageChipsets[] = {
{ S3_SAVAGE2000, "Savage2000" },
{ S3_SAVAGE_MX, "MobileSavage" },
{ S3_PROSAVAGE, "ProSavage" },
+ { S3_TWISTER, "Twister"},
+ { S3_PROSAVAGEDDR, "PROSAVAGEDDR"},
{ S3_SUPERSAVAGE, "SuperSavage" },
{ -1, NULL }
};
@@ -162,10 +170,10 @@ static PciChipsets SavagePciChipsets[] = {
{ S3_SAVAGE_MX, PCI_CHIP_SAVAGE_IX, RES_SHARED_VGA },
{ S3_PROSAVAGE, PCI_CHIP_PROSAVAGE_PM, RES_SHARED_VGA },
{ S3_PROSAVAGE, PCI_CHIP_PROSAVAGE_KM, RES_SHARED_VGA },
- { S3_PROSAVAGE, PCI_CHIP_S3TWISTER_P, RES_SHARED_VGA },
- { S3_PROSAVAGE, PCI_CHIP_S3TWISTER_K, RES_SHARED_VGA },
- { S3_PROSAVAGE, PCI_CHIP_PROSAVAGE_DDR, RES_SHARED_VGA },
- { S3_PROSAVAGE, PCI_CHIP_PROSAVAGE_DDRK, RES_SHARED_VGA },
+ { S3_TWISTER, PCI_CHIP_S3TWISTER_P, RES_SHARED_VGA },
+ { S3_TWISTER, PCI_CHIP_S3TWISTER_K, RES_SHARED_VGA },
+ { S3_PROSAVAGEDDR, PCI_CHIP_PROSAVAGE_DDR, RES_SHARED_VGA },
+ { S3_PROSAVAGEDDR, PCI_CHIP_PROSAVAGE_DDRK, RES_SHARED_VGA },
{ S3_SUPERSAVAGE, PCI_CHIP_SUPSAV_MX128, RES_SHARED_VGA },
{ S3_SUPERSAVAGE, PCI_CHIP_SUPSAV_MX64, RES_SHARED_VGA },
{ S3_SUPERSAVAGE, PCI_CHIP_SUPSAV_MX64C, RES_SHARED_VGA },
@@ -193,10 +201,13 @@ typedef enum {
,OPTION_ROTATE
,OPTION_USEBIOS
,OPTION_SHADOW_STATUS
+ ,OPTION_VIDEORAM
,OPTION_CRT_ONLY
,OPTION_TV_ON
,OPTION_TV_PAL
,OPTION_FORCE_INIT
+ ,OPTION_DISABLE_XVMC
+ ,OPTION_DISABLE_TILE
} SavageOpts;
@@ -210,10 +221,13 @@ static const OptionInfoRec SavageOptions[] =
{ OPTION_USEBIOS, "UseBIOS", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_LCDCLOCK, "LCDClock", OPTV_FREQ, {0}, FALSE },
{ OPTION_SHADOW_STATUS, "ShadowStatus", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_VIDEORAM, "VideoRAM", OPTV_INTEGER, {0}, FALSE },
{ OPTION_CRT_ONLY, "CrtOnly", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_TV_ON, "TvOn", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_TV_PAL, "PAL", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_FORCE_INIT,"ForceInit", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_DISABLE_XVMC, "DisableXVMC", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_DISABLE_TILE, "DisableTile", OPTV_BOOLEAN, {0}, FALSE },
{ -1, NULL, OPTV_NONE, {0}, FALSE }
};
@@ -242,6 +256,61 @@ static const char *vgaHWSymbols[] = {
NULL
};
+#ifdef XF86DRI
+static const char *drmSymbols[] = {
+ "drmAvailable",
+ "drmAddBufs",
+ "drmAddMap",
+ "drmCtlInstHandler",
+ "drmGetInterruptFromBusID",
+ "drmFreeVersion",
+ "drmGetVersion",
+ "drmMap",
+ "drmUnmap",
+ "drmMapBufs",
+ "drmUnmapBufs",
+ "drmAgpAcquire",
+ "drmAgpRelease",
+ "drmAgpEnable",
+ "drmAgpAlloc",
+ "drmAgpFree",
+ "drmAgpBind",
+ "drmAgpUnbind",
+ "drmAgpGetMode",
+ "drmAgpBase",
+ "drmAgpSize",
+ "drmAgpVendorId",
+ "drmAgpDeviceId",
+ "drmMGAInitDMA",
+ "drmMGACleanupDMA",
+ "drmMGAFlushDMA",
+ "drmMGAEngineReset",
+ NULL
+};
+
+static const char *driSymbols[] = {
+ "DRIGetDrawableIndex",
+ "DRIFinishScreenInit",
+ "DRIDestroyInfoRec",
+ "DRICloseScreen",
+ "DRIDestroyInfoRec",
+ "DRIScreenInit",
+ "DRIDestroyInfoRec",
+ "DRICreateInfoRec",
+ "DRILock",
+ "DRIUnlock",
+ "DRIGetSAREAPrivate",
+ "DRIGetContext",
+ "DRIQueryVersion",
+ "DRIAdjustFrame",
+ "DRIOpenFullScreen",
+ "DRICloseFullScreen",
+ "GlxSetVisualConfigs",
+ NULL
+};
+#endif
+
+
static const char *ramdacSymbols[] = {
"xf86CreateCursorInfoRec",
#if 0
@@ -279,6 +348,14 @@ static const char *ddcSymbols[] = {
static const char *i2cSymbols[] = {
"xf86CreateI2CBusRec",
"xf86I2CBusInit",
+ "xf86CreateI2CDevRec",
+ "xf86I2CDevInit",
+ "xf86I2CWriteByte",
+ "xf86I2CWriteBytes",
+ "xf86I2CReadByte",
+ "xf86I2CReadBytes",
+ "xf86I2CWriteRead",
+ "xf86DestroyI2CDevRec",
NULL
};
@@ -289,7 +366,9 @@ static const char *xaaSymbols[] = {
"XAADestroyInfoRec",
"XAAFillSolidRects",
"XAAHelpPatternROP",
+#if 0 /* AGD: this is unresolved... */
"XAAHelpSolidROP",
+#endif
"XAAInit",
"XAAScreenIndex",
NULL
@@ -347,6 +426,9 @@ static pointer SavageSetup(pointer module, pointer opts, int *errmaj,
xf86AddDriver(&SAVAGE, module, 0);
LoaderRefSymLists(vgaHWSymbols, fbSymbols, ramdacSymbols,
xaaSymbols, shadowSymbols, vbeSymbols, vbeOptSymbols,
+#ifdef XF86DRI
+ drmSymbols, driSymbols,
+#endif
int10Symbols, i2cSymbols, ddcSymbols, NULL);
return (pointer) 1;
} else {
@@ -454,8 +536,7 @@ WaitQueue4( SavagePtr psav, int v )
return ShadowWait(psav);
}
else
- while( ((ALT_STATUS_WORD0 & 0x001fffff) > slots) && (loop++ < MAXLOOP))
- ;
+ while( ((ALT_STATUS_WORD0 & 0x001fffff) > slots) && (loop++ < MAXLOOP));
return loop >= MAXLOOP;
}
@@ -494,8 +575,7 @@ WaitIdleEmpty3D(SavagePtr psav)
return ShadowWait(psav);
}
loop &= STATUS_WORD0;
- while( ((STATUS_WORD0 & 0x0008ffff) != 0x80000) && (loop++ < MAXLOOP) )
- ;
+ while( ((STATUS_WORD0 & 0x0008ffff) != 0x80000) && (loop++ < MAXLOOP) );
return loop >= MAXLOOP;
}
@@ -509,8 +589,9 @@ WaitIdleEmpty4(SavagePtr psav)
psav->WaitIdleEmpty = ShadowWait;
return ShadowWait(psav);
}
- while( ((ALT_STATUS_WORD0 & 0x00a1ffff) != 0x00a00000) && (loop++ < MAXLOOP) )
- ;
+ /* which is right?*/
+ /*while( ((ALT_STATUS_WORD0 & 0x00a1ffff) != 0x00a00000) && (loop++ < MAXLOOP) );*/ /* tim */
+ while (((ALT_STATUS_WORD0 & 0x00e1ffff) != 0x00e00000) && (loop++ < MAXLOOP)); /* S3 */
return loop >= MAXLOOP;
}
@@ -525,8 +606,7 @@ WaitIdleEmpty2K(SavagePtr psav)
return ShadowWait(psav);
}
loop &= ALT_STATUS_WORD0;
- while( ((ALT_STATUS_WORD0 & 0x009fffff) != 0) && (loop++ < MAXLOOP) )
- ;
+ while( ((ALT_STATUS_WORD0 & 0x009fffff) != 0) && (loop++ < MAXLOOP) );
if( loop >= MAXLOOP )
ResetBCI2K(psav);
return loop >= MAXLOOP;
@@ -544,8 +624,7 @@ WaitIdle3D(SavagePtr psav)
psav->WaitIdle = ShadowWait;
return ShadowWait(psav);
}
- while( (!(STATUS_WORD0 & 0x00080000)) && (loop++ < MAXLOOP) )
- ;
+ while( (!(STATUS_WORD0 & 0x00080000)) && (loop++ < MAXLOOP) );
return loop >= MAXLOOP;
}
@@ -559,8 +638,9 @@ WaitIdle4(SavagePtr psav)
psav->WaitIdle = ShadowWait;
return ShadowWait(psav);
}
- while( (!(ALT_STATUS_WORD0 & 0x00800000)) && (loop++ < MAXLOOP) )
- ;
+ /* which is right?*/
+ /*while( (!(ALT_STATUS_WORD0 & 0x00800000)) && (loop++ < MAXLOOP) );*/ /* tim */
+ while (((ALT_STATUS_WORD0 & 0x00E00000)!=0x00E00000) && (loop++ < MAXLOOP)); /* S3 */
return loop >= MAXLOOP;
}
@@ -575,8 +655,7 @@ WaitIdle2K(SavagePtr psav)
return ShadowWait(psav);
}
loop &= ALT_STATUS_WORD0;
- while( (ALT_STATUS_WORD0 & 0x00900000) && (loop++ < MAXLOOP) )
- ;
+ while( (ALT_STATUS_WORD0 & 0x00900000) && (loop++ < MAXLOOP) );
return loop >= MAXLOOP;
}
@@ -691,6 +770,7 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
char *s = NULL;
unsigned char config1, m, n, n1, n2, sr8, cr66 = 0, tmp;
int mclk;
+ /*int endfb;*/
vgaHWPtr hwp;
int vgaCRIndex, vgaCRReg;
pointer ddc;
@@ -864,6 +944,30 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
psav->NoAccel = TRUE;
}
+ /* Set AGP Mode from config */
+ /* We support 1X 2X and 4X */
+#ifdef XF86DRI
+ from = X_DEFAULT;
+ /*psav->agpMode = SAVAGE_DEFAULT_AGP_MODE;*/
+ psav->agpMode = SAVAGE_MAX_AGP_MODE;
+
+ /* temporatly remove by Jiayo */
+#if 0
+ if (xf86GetOptValInteger(psav->Options,
+ OPTION_AGP_MODE, &(psav->agpMode))) {
+ if (psav->agpMode < 1) {
+ psav->agpMode = 1;
+ }
+ if (psav->agpMode > SAVAGE_MAX_AGP_MODE) {
+ psav->agpMode = SAVAGE_MAX_AGP_MODE;
+ }
+ from = X_CONFIG;
+ }
+#endif
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using AGP %dx mode\n",
+ psav->agpMode);
+#endif
/*
* The SWCursor setting takes priority over HWCursor. The default
@@ -889,6 +993,13 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
xf86DrvMsg(pScrn->scrnIndex, from, "%ssing video BIOS to set modes\n",
psav->UseBIOS ? "U" : "Not u" );
+ pScrn->videoRam = 0;
+ if( xf86GetOptValInteger(psav->Options, OPTION_VIDEORAM, &pScrn->videoRam ) )
+ {
+ xf86DrvMsg( pScrn->scrnIndex, X_CONFIG,
+ "Option: VideoRAM %dkB\n", pScrn->videoRam );
+ }
+
psav->LCDClock = 0.0;
if( xf86GetOptValFreq( psav->Options, OPTION_LCDCLOCK, OPTUNITS_MHZ, &psav->LCDClock ) )
xf86DrvMsg( pScrn->scrnIndex, X_CONFIG,
@@ -923,6 +1034,20 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
xf86DrvMsg( pScrn->scrnIndex, X_CONFIG,
"Option: ForceInit enabled\n" );
+ /* we can use Option "DisableTile TRUE" to disable tile mode */
+ psav->bDisableTile = TRUE; /* AGD: was FALSE; however, I gain about 30 fps
+ defaulting to linear mode, and it seems to render
+ the same either way */
+ if (xf86GetOptValBool(psav->Options, OPTION_DISABLE_TILE,&psav->bDisableTile)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Option: %s Tile Mode and Program it \n",(psav->bDisableTile?"Disable":"Enable"));
+ }
+ psav->bDisableXvMC = FALSE; /* if you want to free up more mem for DRI,etc. */
+ if (xf86GetOptValBool(psav->Options, OPTION_DISABLE_XVMC,&psav->bDisableXvMC)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Option: %s Hardware XvMC support\n",(psav->bDisableXvMC?"Disable":"Enable"));
+ }
+
/* Add more options here. */
if (pScrn->numEntities > 1) {
@@ -986,9 +1111,6 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
} else
psav->ChipRev = psav->PciInfo->chipRev;
- if (pEnt->device->videoRam != 0)
- pScrn->videoRam = pEnt->device->videoRam;
-
xfree(pEnt);
/* maybe throw in some more sanity checks here */
@@ -1079,6 +1201,8 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
break;
case S3_PROSAVAGE:
+ case S3_PROSAVAGEDDR:
+ case S3_TWISTER:
pScrn->videoRam = RamSavageNB[ (config1 & 0xE0) >> 5 ] * 1024;
break;
@@ -1118,7 +1242,10 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
psav->videoRambytes = pScrn->videoRam * 1024;
}
-
+#if 0
+ /* reserved 128K for HWICON and DSTN buffer */
+ endfb = psav->videoRambytes - 0x20000 - 1;
+#endif
/*
* If we're running with acceleration, compute the command overflow
* buffer location. The command overflow buffer must END at a
@@ -1131,6 +1258,7 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
psav->cobIndex = 0;
psav->cobSize = 0;
psav->cobOffset = psav->videoRambytes;
+ /*psav->cobOffset = endfb;*/
}
else if( (S3_SAVAGE4_SERIES(psav->Chipset)) ||
(S3_SUPERSAVAGE == psav->Chipset) ) {
@@ -1143,6 +1271,7 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
psav->cobIndex = 2;
psav->cobSize = 0x8000 << psav->cobIndex;
psav->cobOffset = psav->videoRambytes;
+ /*psav->cobOffset = endfb - psav->cobSize;*/
}
else
{
@@ -1156,15 +1285,25 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
psav->cobIndex = 7;
}
psav->cobOffset = psav->videoRambytes - psav->cobSize;
+ /*psav->cobOffset = endfb - psav->cobSize;*/
}
-
+#if 0
+ /* align cob to 128k */
+ psav->cobOffset = ((endfb - psav->cobSize + 1) + 0x20000) & ~0x20000;
+ endfb = psav->cobOffset - 1;
+#endif
/*
* We place the cursor in high memory, just before the command overflow
* buffer. The cursor must be aligned on a 4k boundary.
*/
psav->CursorKByte = (psav->cobOffset >> 10) - 4;
+#if 0
+ psav->CursorKByte = (endfb >> 10) - 4;
+ endfb = (psav->CursorKByte << 10) - 1;
+ psav->endfb = endfb;
+#endif
/* reset graphics engine to avoid memory corruption */
VGAOUT8(vgaCRIndex, 0x66);
cr66 = VGAIN8(vgaCRReg);
@@ -1188,6 +1327,8 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
case S3_SAVAGE4:
case S3_PROSAVAGE:
case S3_SUPERSAVAGE:
+ case S3_PROSAVAGEDDR:
+ case S3_TWISTER:
psav->WaitQueue = WaitQueue4;
psav->WaitIdle = WaitIdle4;
psav->WaitIdleEmpty = WaitIdleEmpty4;
@@ -1200,8 +1341,51 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
break;
}
+ /* Do the DDC dance. */ /* S3/VIA's DDC code */
+ ddc = xf86LoadSubModule(pScrn, "ddc");
+ if (ddc) {
+ xf86LoaderReqSymLists(ddcSymbols, NULL);
+ switch( psav->Chipset ) {
+ case S3_SAVAGE3D:
+ case S3_SAVAGE_MX:
+ case S3_SUPERSAVAGE:
+ psav->DDCPort = 0xAA;
+ psav->I2CPort = 0xA0;
+ break;
+
+ case S3_SAVAGE4:
+ case S3_PROSAVAGE:
+ case S3_TWISTER:
+ case S3_PROSAVAGEDDR:
+ psav->DDCPort = 0xB1;
+ psav->I2CPort = 0xA0;
+ break;
+
+ case S3_SAVAGE2000:
+ psav->DDCPort = 0xAA;
+ psav->I2CPort = 0xA0;
+ break;
+ }
+
+ if (!SavageDDC1(pScrn->scrnIndex)) {
+ /* DDC1 failed,switch to DDC2 */
+ if (xf86LoadSubModule(pScrn, "i2c")) {
+ xf86LoaderReqSymLists(i2cSymbols,NULL);
+ if (SavageI2CInit(pScrn)) {
+ unsigned char tmp;
+
+ InI2CREG(tmp,psav->DDCPort);
+ OutI2CREG(tmp | 0x13,psav->DDCPort);
+ xf86SetDDCproperties(pScrn,xf86PrintEDID(
+ xf86DoEDID_DDC2(pScrn->scrnIndex,psav->I2C)));
+ OutI2CREG(tmp,psav->DDCPort);
+ }
+ }
+ }
+ }
+
+#if 0 /* Tim's DDC */
/* Do the DDC dance. */
-
if( psav->Chipset != S3_PROSAVAGE ) {
ddc = xf86LoadSubModule(pScrn, "ddc");
if (ddc) {
@@ -1237,6 +1421,7 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
}
}
}
+#endif /* tim's DDC */
/* Savage ramdac speeds */
pScrn->numClocks = 4;
@@ -1285,7 +1470,8 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
/* Check LCD panel information */
- if( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) && !psav->CrtOnly )
+ if( (S3_SAVAGE_MOBILE_SERIES(psav->Chipset) ||
+ S3_MOBILE_TWISTER_SERIES(psav->Chipset)) && !psav->CrtOnly )
{
unsigned char cr6b = hwp->readCrtc( hwp, 0x6b );
@@ -1352,7 +1538,19 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
}
}
- clockRanges = xnfcalloc(sizeof(ClockRange),1);
+#if 0
+ if (psav->CrtOnly && !psav->UseBIOS) {
+ VGAOUT8(0x3c4, 0x31); /* SR31 bit 4 - FP enable */
+ VGAOUT8(0x3c5, VGAIN8(0x3c5) & ~0x10); /* disable FP */
+ if (S3_SAVAGE_MOBILE_SERIES(psav->Chipset) /*||
+ S3_MOBILE_TWISTER_SERIES(psav->Chipset)*/) { /* not sure this works on mobile prosavage */
+ VGAOUT8(0x3c4, 0x31);
+ VGAOUT8(0x3c5, VGAIN8(0x3c5) & ~0x04); /* make sure crtc1 is crt source */
+ }
+ }
+#endif
+
+ clockRanges = xnfalloc(sizeof(ClockRange));
clockRanges->next = NULL;
clockRanges->minClock = psav->minClock;
clockRanges->maxClock = psav->maxClock;
@@ -1475,10 +1673,24 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
static Bool SavageEnterVT(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+#ifdef XF86DRI
+ SavagePtr psav= SAVPTR(pScrn);
+ ScreenPtr pScreen;
+#endif
+
TRACE(("SavageEnterVT(%d)\n", flags));
gpScrn = pScrn;
SavageEnableMMIO(pScrn);
+
+#ifdef XF86DRI
+ if (psav->directRenderingEnabled) {
+ pScreen = screenInfo.screens[scrnIndex];
+ DRIUnlock(pScreen);
+ psav->LockHeld = 0;
+ }
+#endif
+
SavageSave(pScrn);
return SavageModeInit(pScrn, pScrn->currentMode);
}
@@ -1491,11 +1703,24 @@ static void SavageLeaveVT(int scrnIndex, int flags)
SavagePtr psav = SAVPTR(pScrn);
vgaRegPtr vgaSavePtr = &hwp->SavedReg;
SavageRegPtr SavageSavePtr = &psav->SavedReg;
+#ifdef XF86DRI
+ ScreenPtr pScreen;
+#endif
TRACE(("SavageLeaveVT(%d)\n", flags));
gpScrn = pScrn;
+
+#ifdef XF86DRI
+ if (psav->directRenderingEnabled) {
+ pScreen = screenInfo.screens[scrnIndex];
+ DRILock(pScreen, 0);
+ psav->LockHeld = 1;
+ }
+#endif
+
SavageWriteMode(pScrn, vgaSavePtr, SavageSavePtr, FALSE);
SavageDisableMMIO(pScrn);
+
}
@@ -1637,7 +1862,8 @@ static void SavageSave(ScrnInfoPtr pScrn)
/* Save flat panel expansion regsters. */
- if( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) ) {
+ if( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) ||
+ S3_MOBILE_TWISTER_SERIES(psav->Chipset)) {
int i;
for( i = 0; i < 8; i++ ) {
VGAOUT8(0x3c4, 0x54+i);
@@ -1695,6 +1921,13 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr,
TRACE(("SavageWriteMode(%x)\n", restore->mode));
+#ifdef XF86DRI
+ if (psav->directRenderingEnabled) {
+ DRILock(screenInfo.screens[pScrn->scrnIndex], 0);
+ psav->LockHeld = 1;
+ }
+#endif
+
if( Entering &&
(!S3_SAVAGE_MOBILE_SERIES(psav->Chipset) || (psav->ForceInit))
)
@@ -1848,13 +2081,33 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr,
break;
}
+ /* set the correct clock for some BIOSes */
+ VGAOUT8(VGA_MISC_OUT_W,
+ VGAIN8(VGA_MISC_OUT_R) | 0x0C);
+ /* Some BIOSes turn on clock doubling on non-doubled modes */
+ if (pScrn->bitsPerPixel < 24) {
+ VGAOUT8(vgaCRIndex, 0x67);
+ if (!(VGAIN8(vgaCRReg) & 0x10)) {
+ VGAOUT8(0x3c4, 0x15);
+ VGAOUT8(0x3c5, VGAIN8(0x3C5) & ~0x10);
+ VGAOUT8(0x3c4, 0x18);
+ VGAOUT8(0x3c5, VGAIN8(0x3c5) & ~0x80);
+ }
+ }
+
SavageInitialize2DEngine(pScrn);
- SavageSetGBD(pScrn);
VGAOUT16(vgaCRIndex, 0x0140);
SavageSetGBD(pScrn);
+
+#ifdef XF86DRI
+ if (psav->directRenderingEnabled)
+ DRIUnlock(screenInfo.screens[pScrn->scrnIndex]);
+ psav->LockHeld = 0;
+#endif
+
return;
}
@@ -1916,7 +2169,8 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr,
VGAOUT8(0x3c5, restore->SR15);
/* Restore flat panel expansion regsters. */
- if( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) ) {
+ if( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) ||
+ S3_MOBILE_TWISTER_SERIES(psav->Chipset)) {
int i;
for( i = 0; i < 8; i++ ) {
VGAOUT8(0x3c4, 0x54+i);
@@ -2045,7 +2299,7 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr,
VGAOUT8(0x3c5, restore->SR08);
/* now write out cr67 in full, possibly starting STREAMS */
- VerticalRetraceWait(psav);
+ VerticalRetraceWait();
VGAOUT8(vgaCRIndex, 0x67);
#if 0
VGAOUT8(vgaCRReg, 0x50);
@@ -2066,7 +2320,7 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr,
if( !S3_SAVAGE_MOBILE_SERIES(psav->Chipset) )
{
- VerticalRetraceWait(psav);
+ VerticalRetraceWait();
OUTREG(FIFO_CONTROL_REG, restore->MMPR0);
OUTREG(MIU_CONTROL_REG, restore->MMPR1);
OUTREG(STREAMS_TIMEOUT_REG, restore->MMPR2);
@@ -2090,11 +2344,23 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr,
VGAOUT8(vgaCRIndex, 0x3a);
VGAOUT8(vgaCRReg, cr3a);
- if( Entering )
+ if( Entering ) {
+ SavageInitialize2DEngine(pScrn);
+
+ VGAOUT16(vgaCRIndex, 0x0140);
+
SavageSetGBD(pScrn);
+ }
vgaHWProtect(pScrn, FALSE);
+
+#ifdef XF86DRI
+ if (psav->directRenderingEnabled)
+ DRIUnlock(screenInfo.screens[pScrn->scrnIndex]);
+ psav->LockHeld = 0;
+#endif
+
return;
}
@@ -2143,7 +2409,6 @@ static Bool SavageMapMMIO(ScrnInfoPtr pScrn)
}
-
static Bool SavageMapFB(ScrnInfoPtr pScrn)
{
SavagePtr psav = SAVPTR(pScrn);
@@ -2165,6 +2430,28 @@ static Bool SavageMapFB(ScrnInfoPtr pScrn)
}
psav->FBStart = psav->FBBase;
}
+
+ if (psav->Chipset == S3_SUPERSAVAGE)
+ /* paramount aperture 0 is pci base 2 */
+ psav->ApertureBase = psav->PciInfo->memBase[2];
+ else
+ psav->ApertureBase = psav->FrameBufferBase + 0x02000000;
+
+ psav->ApertureMap = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
+ psav->PciTag, psav->ApertureBase,
+ 0x01000000 * 5);
+ if (!psav->ApertureMap) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Internal error: could not map aperture\n");
+ return FALSE;
+ }
+ else
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "map aperture:%p\n",psav->ApertureMap);
+
+ }
+
pScrn->memPhysBase = psav->PciInfo->memBase[0];
pScrn->fbOffset = 0;
@@ -2207,6 +2494,46 @@ static void SavageUnmapMem(ScrnInfoPtr pScrn, int All)
return;
}
+static Bool SavageCheckAvailableRamFor3D(ScrnInfoPtr pScrn)
+{
+ SavagePtr psav = SAVPTR(pScrn);
+ int cpp = pScrn->bitsPerPixel / 8;
+ /*int widthBytes = pScrn->displayWidth * cpp;*/
+ int widthBytes = psav->lDelta;
+ /*int widthBytes = psav->l3DDelta;*/
+ int bufferSize = ((pScrn->virtualY * widthBytes + SAVAGE_BUFFER_ALIGN)
+ & ~SAVAGE_BUFFER_ALIGN);
+ int tiledwidthBytes, tiledBufferSize, RamNeededFor3D;
+ /*tiledwidthBytes = psav->lDelta;*/
+ tiledwidthBytes = psav->l3DDelta;
+
+ if (cpp == 2) {
+ tiledBufferSize = ((pScrn->virtualX+63)/64)*((pScrn->virtualY+15)/16) * 2048;
+ } else {
+ tiledBufferSize = ((pScrn->virtualX+31)/32)*((pScrn->virtualY+15)/16) * 2048;
+ }
+
+ RamNeededFor3D = 4096 + /* hw cursor*/
+ psav->cobSize + /*COB*/
+ bufferSize + /* front buffer */
+ tiledBufferSize + /* back buffer */
+ tiledBufferSize; /* depth buffer */
+
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO,
+ "%d kB of Videoram needed for 3D; %d kB of Videoram available\n",
+ RamNeededFor3D/1024, psav->videoRambytes/1024);
+
+ if (RamNeededFor3D <= psav->videoRambytes) {
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Sufficient Videoram available for 3D\n");
+ return TRUE;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Insufficient Videoram available for 3D\n");
+ xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Try a lower color depth or smaller desktop.\n");
+ xf86DrvMsg(pScrn->scrnIndex,X_ERROR,
+ "For integrated savages try increasing the videoram in the BIOS.\n");
+ return FALSE;
+ }
+}
static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen,
int argc, char **argv)
@@ -2258,6 +2585,29 @@ static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen,
if (!SavageModeInit(pScrn, pScrn->currentMode))
return FALSE;
+#ifdef XF86DRI
+ if (((psav->Chipset == S3_TWISTER)
+ || (psav->Chipset == S3_PROSAVAGE)
+ || (psav->Chipset == S3_SAVAGE4)
+ || (psav->Chipset == S3_SAVAGE_MX)
+ || (psav->Chipset == S3_SAVAGE3D)
+ || (psav->Chipset == S3_SUPERSAVAGE)
+ || (psav->Chipset == S3_PROSAVAGEDDR))
+ && (!psav->NoAccel)
+ && (SavageCheckAvailableRamFor3D(pScrn))) {
+ /* Setup DRI after visuals have been established */
+ psav->directRenderingEnabled = SAVAGEDRIScreenInit(pScreen);
+ } else
+ psav->directRenderingEnabled = FALSE;
+
+ if(psav->directRenderingEnabled) {
+ xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"DRI is enabled\n");
+ }
+ else {
+ xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"DRI isn't enabled\n");
+ }
+#endif
+
miClearVisualTypes();
if (pScrn->bitsPerPixel == 16) {
@@ -2363,6 +2713,18 @@ static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen,
if (xf86DPMSInit(pScreen, SavageDPMS, 0) == FALSE)
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "DPMS initialization failed\n");
+#ifdef XF86DRI
+ if (psav->directRenderingEnabled) {
+ /* complete the DRI setup.*/
+ psav->directRenderingEnabled = SAVAGEDRIFinishScreenInit(pScreen);
+ }
+ if (psav->directRenderingEnabled) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Direct rendering disabled\n");
+ }
+#endif
+
#ifdef XvExtension
if( !psav->NoAccel && !SavagePanningCheck(pScrn) )
SavageInitVideo( pScreen );
@@ -2771,11 +3133,15 @@ static Bool SavageModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
new->CR36 = VGAIN8(vgaCRReg);
VGAOUT8(vgaCRIndex, 0x68);
new->CR68 = VGAIN8(vgaCRReg);
- new->CR69 = 0;
+
+ new->CR69 = 0x80;
+ /*new->CR69 = 0;*/
VGAOUT8(vgaCRIndex, 0x6f);
new->CR6F = VGAIN8(vgaCRReg);
- VGAOUT8(vgaCRIndex, 0x88);
+ VGAOUT8(vgaCRIndex, 0x86);
new->CR86 = VGAIN8(vgaCRReg) | 0x08;
+ VGAOUT8(vgaCRIndex, 0x88);
+ new->CR88 = VGAIN8(vgaCRReg) | DISABLE_BLOCK_WRITE_2D;
VGAOUT8(vgaCRIndex, 0xb0);
new->CRB0 = VGAIN8(vgaCRReg) | 0x80;
}
@@ -2800,6 +3166,13 @@ static Bool SavageCloseScreen(int scrnIndex, ScreenPtr pScreen)
TRACE(("SavageCloseScreen\n"));
+#ifdef XF86DRI
+ if (psav->directRenderingEnabled) {
+ SAVAGEDRICloseScreen(pScreen);
+ psav->directRenderingEnabled=FALSE;
+ }
+#endif
+
if (psav->pVbe)
vbeFree(psav->pVbe);
psav->pVbe = NULL;
@@ -2830,22 +3203,75 @@ static Bool SavageCloseScreen(int scrnIndex, ScreenPtr pScreen)
static Bool SavageSaveScreen(ScreenPtr pScreen, int mode)
{
+#if 0
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+#endif
TRACE(("SavageSaveScreen(0x%x)\n", mode));
-
- if( pScrn->vtSema && SAVPTR(pScrn)->hwcursor && SAVPTR(pScrn)->hwc_on) {
-
+#if 0
+ if( pScrn->vtSema && SAVPTR(pScrn)->hwcursor )
+ {
if( xf86IsUnblank(mode) )
SavageShowCursor( pScrn );
else
SavageHideCursor( pScrn );
- SAVPTR(pScrn)->hwc_on = TRUE;
}
-
- return vgaHWSaveScreen(pScreen, mode);
+#endif
+ return vgaHWSaveScreen(pScreen, mode);
}
+void
+SavageAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ SavagePtr psav = SAVPTR(pScrn);
+ DisplayModePtr currentMode = pScrn->currentMode;
+ int address=0,top=0,left=0;
+
+ TRACE(("SavageAdjustFrame(%d,%d,%x)\n", x, y, flags));
+
+ if (!psav->bTiled) {
+ left = x - x % 64;
+ top = y;
+ address = (top * psav->lDelta) + left * (pScrn->bitsPerPixel >> 3);
+ address = (address >> 5) << 5;
+ } else {
+ top = y - y % TILEHEIGHT;
+ if (pScrn->bitsPerPixel == 16) {
+ left = x - x % TILEWIDTH_16BPP;
+ address = top * psav->lDelta + left * TILE_SIZE_BYTE / TILEWIDTH_16BPP;
+ } else if (pScrn->bitsPerPixel == 32) {
+ left = x - x % TILEWIDTH_32BPP;
+ address = top * psav->lDelta + left * TILE_SIZE_BYTE / TILEWIDTH_32BPP;
+ }
+ }
+
+ /*
+ * because we align the viewport to the width and height of one tile
+ * we shoud update the locate of frame
+ */
+ pScrn->frameX0 = left;
+ pScrn->frameY0 = top;
+ pScrn->frameX1 = left + currentMode->HDisplay - 1;
+ pScrn->frameY1 = top+ currentMode->VDisplay - 1;
+
+ if (psav->Chipset == S3_SAVAGE_MX) {
+ OUTREG32(PRI_STREAM_FBUF_ADDR1, address & 0xFFFFFFFC);/* IGA1 */
+ OUTREG32(PRI_STREAM2_FBUF_ADDR0, address & 0xFFFFFFFC);/* IGA2 */
+ } else if (psav->Chipset == S3_SUPERSAVAGE) {
+ /* IGA1 */
+ OUTREG32(PRI_STREAM_FBUF_ADDR1, address & 0xFFFFFFF8);
+ OUTREG32(PRI_STREAM_FBUF_ADDR0, 0x80000000);
+ /* IGA2 */
+ OUTREG32(PRI_STREAM2_FBUF_ADDR0, ((address & 0xFFFFFFF8) | 0x80000000));
+ } else {
+ OUTREG32(PRI_STREAM_FBUF_ADDR0,address | 0xFFFFFFFC);
+ OUTREG32(PRI_STREAM_FBUF_ADDR1,address | 0x80000000);
+ }
+
+ return;
+}
+#if 0
void SavageAdjustFrame(int scrnIndex, int x, int y, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
@@ -2872,7 +3298,7 @@ void SavageAdjustFrame(int scrnIndex, int x, int y, int flags)
return;
}
-
+#endif
Bool SavageSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
{
@@ -2949,7 +3375,9 @@ void SavageLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indicies,
}
}
+#if 0
#define inStatus1() (hwp->readST01( hwp ))
+#endif
void SavageLoadPaletteSavage4(ScrnInfoPtr pScrn, int numColors, int *indicies,
LOCO *colors, VisualPtr pVisual)
@@ -2962,11 +3390,11 @@ void SavageLoadPaletteSavage4(ScrnInfoPtr pScrn, int numColors, int *indicies,
vgaIOBase = hwp->IOBase;
vgaCRIndex = vgaIOBase + 4;
vgaCRReg = vgaIOBase + 5;
- VerticalRetraceWait(psav);
+ VerticalRetraceWait();
for (i=0; i<numColors; i++) {
if (!(inStatus1()) & 0x08)
- VerticalRetraceWait(psav);
+ VerticalRetraceWait();
index = indicies[i];
VGAOUT8(0x3c8, index);
VGAOUT8(0x3c9, colors[index].red);
@@ -3088,6 +3516,8 @@ void SavageGEReset(ScrnInfoPtr pScrn, int from_timeout, int line, char *file)
break;
case S3_SAVAGE4:
case S3_PROSAVAGE:
+ case S3_PROSAVAGEDDR:
+ case S3_TWISTER:
case S3_SUPERSAVAGE:
success = (ALT_STATUS_WORD0 & 0x0081ffff) == 0x00800000;
break;
@@ -3121,6 +3551,7 @@ void SavageGEReset(ScrnInfoPtr pScrn, int from_timeout, int line, char *file)
OUTREG(MONO_PAT_1, ~0);
SavageSetGBD(pScrn);
+
}
@@ -3191,26 +3622,52 @@ static void SavageDPMS(ScrnInfoPtr pScrn, int mode, int flags)
break;
}
+ if ( (!psav->CrtOnly) && psav->UseBIOS && psav->PanelX ) {
+ SavageSetPanelEnabled(psav, (mode == DPMSModeOn));
+ }
+ else if ((!psav->CrtOnly) && psav->PanelX) {
+ switch (mode) {
+ case DPMSModeOn:
+ VGAOUT8(0x3c4, 0x31); /* SR31 bit 4 - FP enable */
+ VGAOUT8(0x3c5, VGAIN8(0x3c5) | 0x10);
+ break;
+ case DPMSModeStandby:
+ case DPMSModeSuspend:
+ case DPMSModeOff:
+ VGAOUT8(0x3c4, 0x31); /* SR31 bit 4 - FP enable */
+ VGAOUT8(0x3c5, VGAIN8(0x3c5) & ~0x10);
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid DPMS mode %d\n", mode);
+ break;
+ }
+ }
+
VGAOUT8(0x3c4, 0x0d);
VGAOUT8(0x3c5, srd);
return;
}
+static void
+SavageProbeDDC(ScrnInfoPtr pScrn, int index)
+{
+ SavagePtr psav = SAVPTR(pScrn);
+ ConfiguredMonitor = vbeDoEDID(psav->pVbe, NULL);
+}
static unsigned int
SavageDDC1Read(ScrnInfoPtr pScrn)
{
- register vgaHWPtr hwp = VGAHWPTR(pScrn);
register unsigned char tmp;
SavagePtr psav = SAVPTR(pScrn);
- VerticalRetraceWait(psav);
-
- InI2CREG(psav,tmp);
- while (hwp->readST01(hwp)&0x8) {};
- while (!(hwp->readST01(hwp)&0x8)) {};
-
+ UnLockExtRegs();
+
+ VerticalRetraceWait();
+
+ InI2CREG(tmp,psav->I2CPort);
+
return ((unsigned int) (tmp & 0x08));
}
@@ -3219,37 +3676,29 @@ SavageDDC1(int scrnIndex)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
SavagePtr psav = SAVPTR(pScrn);
- unsigned char tmp;
- Bool success = FALSE;
+ uchar byte;
xf86MonPtr pMon;
+
+ UnLockExtRegs();
/* initialize chipset */
- InI2CREG(psav,tmp);
- OutI2CREG(psav,tmp | 0x12);
+ InI2CREG(byte,psav->I2CPort);
+ OutI2CREG(byte | 0x12,psav->I2CPort);
+
+ pMon = xf86DoEDID_DDC1(scrnIndex,vgaHWddc1SetSpeed,SavageDDC1Read);
+ if (!pMon)
+ return FALSE;
+
+ xf86PrintEDID(pMon);
- if ((pMon = xf86PrintEDID(
- xf86DoEDID_DDC1(scrnIndex,vgaHWddc1SetSpeed,SavageDDC1Read))) != NULL)
- success = TRUE;
xf86SetDDCproperties(pScrn,pMon);
/* undo initialization */
- OutI2CREG(psav,tmp);
- return success;
-}
+ OutI2CREG(byte,psav->I2CPort);
-
-static void
-SavageProbeDDC(ScrnInfoPtr pScrn, int index)
-{
- vbeInfoPtr pVbe;
- if (xf86LoadSubModule(pScrn, "vbe")) {
- pVbe = VBEInit(NULL,index);
- ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
- vbeFree(pVbe);
- }
+ return TRUE;
}
-
static void
SavageGetTvMaxSize(SavagePtr psav)
{
@@ -3273,6 +3722,12 @@ SavagePanningCheck(ScrnInfoPtr pScrn)
pMode = pScrn->currentMode;
psav->iResX = pMode->CrtcHDisplay;
psav->iResY = pMode->CrtcVDisplay;
+
+ if ((psav->iResX < psav->PanelX || psav->iResY < psav->PanelY))
+ psav->FPExpansion = TRUE;
+ else
+ psav->FPExpansion = FALSE;
+
if( psav->iResX < pScrn->virtualX || psav->iResY < pScrn->virtualY )
return TRUE;
else
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.h b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.h
index 231139684..f3f4ac5a1 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.h
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.h,v 1.16 2003/01/18 15:22:30 eich Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.h,v 1.11 2001/08/09 19:14:13 dawes Exp $ */
#ifndef SAVAGE_VGAHWMMIO_H
#define SAVAGE_VGAHWMMIO_H
@@ -21,6 +21,30 @@
#include "xf86xv.h"
#include "savage_regs.h"
+#include "savage_vbe.h"
+
+#ifdef XF86DRI
+#define _XF86DRI_SERVER_
+#include "savage_dripriv.h"
+#include "savage_dri.h"
+#include "savage_drm.h"
+#include "dri.h"
+#include "GL/glxint.h"
+#endif
+
+
+#ifndef uint
+typedef unsigned int uint;
+#endif
+#ifndef ulong
+typedef unsigned long ulong;
+#endif
+#ifndef ushort
+typedef unsigned short ushort;
+#endif
+#ifndef uchar
+typedef unsigned char uchar;
+#endif
#define VGAIN8(addr) MMIO_IN8(psav->MapBase+0x8000, addr)
#define VGAIN16(addr) MMIO_IN16(psav->MapBase+0x8000, addr)
@@ -30,10 +54,26 @@
#define VGAOUT16(addr,val) MMIO_OUT16(psav->MapBase+0x8000, addr, val)
#define VGAOUT(addr,val) MMIO_OUT32(psav->MapBase+0x8000, addr, val)
-#define INREG(addr) MMIO_IN32(psav->MapBase, addr)
-#define OUTREG(addr,val) MMIO_OUT32(psav->MapBase, addr, val)
+#define INREG8(addr) MMIO_IN8(psav->MapBase, addr)
#define INREG16(addr) MMIO_IN16(psav->MapBase, addr)
+#define INREG32(addr) MMIO_IN32(psav->MapBase, addr)
+#define OUTREG8(addr,val) MMIO_OUT8(psav->MapBase, addr, val)
#define OUTREG16(addr,val) MMIO_OUT16(psav->MapBase, addr, val)
+#define OUTREG32(addr,val) MMIO_OUT32(psav->MapBase, addr, val)
+#define INREG(addr) INREG32(addr)
+#define OUTREG(addr,val) OUTREG32(addr,val)
+
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
+#define B_O16(x) (x)
+#define B_O32(x) (x)
+#else
+#define B_O16(x) ((((x) & 0xff) << 8) | (((x) & 0xff) >> 8))
+#define B_O32(x) ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) \
+ | (((x) & 0xff0000) >> 8) | (((x) & 0xff000000) >> 24))
+#endif
+#define L_ADD(x) (B_O32(x) & 0xffff) + ((B_O32(x) >> 12) & 0xffff00)
+
+#define SAVAGEIOMAPSIZE 0x80000
#define SAVAGE_CRT_ON 1
#define SAVAGE_LCD_ON 2
@@ -70,6 +110,47 @@ typedef struct {
unsigned int MMPR0, MMPR1, MMPR2, MMPR3;
} SavageRegRec, *SavageRegPtr;
+/* Tiling defines */
+#define TILE_SIZE_BYTE 2048 /* 0x800, 2K */
+
+#define TILEHEIGHT_16BPP 16
+#define TILEHEIGHT_32BPP 16
+#define TILEHEIGHT 16 /* all 16 and 32bpp tiles are 16 lines high */
+
+#define TILEWIDTH_BYTES 128 /* 2048/TILEHEIGHT (** not for use w/8bpp tiling) */
+#define TILEWIDTH8BPP_BYTES 64 /* 2048/TILEHEIGHT_8BPP */
+#define TILEWIDTH_16BPP 64 /* TILEWIDTH_BYTES/2-BYTES-PER-PIXEL */
+#define TILEWIDTH_32BPP 32 /* TILEWIDTH_BYTES/4-BYTES-PER-PIXEL */
+
+/* Bitmap descriptor structures for BCI */
+typedef struct _HIGH {
+ ushort Stride;
+ uchar Bpp;
+ uchar ResBWTile;
+} HIGH;
+
+typedef struct _BMPDESC1 {
+ ulong Offset;
+ HIGH HighPart;
+} BMPDESC1;
+
+typedef struct _BMPDESC2 {
+ ulong LoPart;
+ ulong HiPart;
+} BMPDESC2;
+
+typedef union _BMPDESC {
+ BMPDESC1 bd1;
+ BMPDESC2 bd2;
+} BMPDESC;
+
+typedef struct _StatInfo {
+ int origMode;
+ int pageCnt;
+ pointer statBuf;
+ int realSeg;
+ int realOff;
+} StatInfoRec,*StatInfoPtr;
typedef struct _Savage {
SavageRegRec SavedReg;
@@ -81,15 +162,20 @@ typedef struct _Savage {
int Bpp, Bpl, ScissB;
unsigned PlaneMask;
I2CBusPtr I2C;
+ I2CBusPtr DVI;
+ unsigned char DDCPort;
+ unsigned char I2CPort;
int videoRambytes;
int videoRamKbytes;
int MemOffScreen;
+ /*int endfb;*/
CARD32 CursorKByte;
/* These are physical addresses. */
unsigned long FrameBufferBase;
unsigned long MmioBase;
+ unsigned long ApertureBase;
unsigned long ShadowPhysical;
/* These are linear addresses. */
@@ -97,6 +183,7 @@ typedef struct _Savage {
unsigned char* BciMem;
unsigned char* MapBaseDense;
unsigned char* FBBase;
+ unsigned char* ApertureMap;
unsigned char* FBStart;
CARD32 volatile * ShadowVirtual;
@@ -118,7 +205,6 @@ typedef struct _Savage {
Bool fifo_moderate;
Bool fifo_aggressive;
Bool hwcursor;
- Bool hwc_on;
Bool NoAccel;
Bool shadowFB;
Bool UseBIOS;
@@ -132,6 +218,7 @@ typedef struct _Savage {
int iDevInfo;
int iDevInfoPrim;
+ Bool FPExpansion;
int PanelX; /* panel width */
int PanelY; /* panel height */
int iResX; /* crtc X display */
@@ -140,11 +227,9 @@ typedef struct _Savage {
int YFactor; /* overlay Y factor */
int displayXoffset; /* overlay X offset */
int displayYoffset; /* overlay Y offset */
- int XExpansion; /* expansion factor in x */
- int XExp1;
+ int XExp1; /* expansion ratio in x */
int XExp2;
- int YExpansion; /* expansion factor in x */
- int YExp1;
+ int YExp1; /* expansion ratio in x */
int YExp2;
int cxScreen;
int TVSizeX;
@@ -205,6 +290,60 @@ typedef struct _Savage {
int dwBCIWait2DIdle;
XF86OffscreenImagePtr offscreenImages;
+#ifdef XF86DRI
+ int LockHeld;
+ Bool directRenderingEnabled;
+ DRIInfoPtr pDRIInfo;
+ int drmFD;
+ int numVisualConfigs;
+ __GLXvisualConfig* pVisualConfigs;
+ SAVAGEConfigPrivPtr pVisualConfigsPriv;
+ SAVAGEDRIServerPrivatePtr DRIServerInfo;
+
+
+#if 0
+ Bool haveQuiescense;
+ void (*GetQuiescence)(ScrnInfoPtr pScrn);
+#endif
+
+ int agpMode;
+ FBLinearPtr reserved;
+
+ Bool bDisableXvMC;
+
+ unsigned int surfaceAllocation[7];
+ unsigned int xvmcContext;
+ unsigned int DRIrunning;
+ unsigned int hwmcOffset;
+ unsigned int hwmcSize;
+
+#endif
+ /* Bitmap Descriptors for BCI */
+ BMPDESC GlobalBD;
+ BMPDESC PrimaryBD;
+ BMPDESC SecondBD;
+ /* do we disable tile mode by option? */
+ Bool bDisableTile;
+ /* if we enable tile,we only support tile under 16/32bpp */
+ Bool bTiled;
+ int lDelta;
+ int ulAperturePitch; /* aperture pitch */
+
+ int l3DDelta;
+ int ul3DAperturePitch; /* pitch for 3D */
+ /*
+ * cxMemory is number of pixels across screen width
+ * cyMemory is number of scanlines in available adapter memory.
+ *
+ * cxMemory * cyMemory is used to determine how much memory to
+ * allocate to our heap manager. So make sure that any space at the
+ * end of video memory set aside at bInitializeHardware time is kept
+ * out of the cyMemory calculation.
+ */
+ int cxMemory,cyMemory;
+
+ StatInfoRec StatInfo; /* save the SVGA state */
+
} SavageRec, *SavagePtr;
/* Video flags. */
@@ -213,14 +352,40 @@ typedef struct _Savage {
#define SAVPTR(p) ((SavagePtr)((p)->driverPrivate))
-/* Make the names of these externals driver-unique */
-#define gpScrn savagegpScrn
-#define myOUTREG savageOUTREG
-#define readdw savagereaddw
-#define readfb savagereadfb
-#define writedw savagewritedw
-#define writefb savagewritefb
-#define writescan savagewritescan
+/* add for support DRI */
+#ifdef XF86DRI
+
+#define SAVAGE_FRONT 0x1
+#define SAVAGE_BACK 0x2
+#define SAVAGE_DEPTH 0x4
+#define SAVAGE_STENCIL 0x8
+
+Bool SAVAGEDRIScreenInit( ScreenPtr pScreen );
+Bool SAVAGEInitMC(ScreenPtr pScreen);
+void SAVAGEDRICloseScreen( ScreenPtr pScreen );
+Bool SAVAGEDRIFinishScreenInit( ScreenPtr pScreen );
+
+Bool SAVAGELockUpdate( ScrnInfoPtr pScrn, drmLockFlags flags );
+
+#if 0
+void SAVAGEGetQuiescence( ScrnInfoPtr pScrn );
+void SAVAGEGetQuiescenceShared( ScrnInfoPtr pScrn );
+#endif
+
+void SAVAGESelectBuffer(ScrnInfoPtr pScrn, int which);
+
+#if 0
+Bool SAVAGECleanupDma(ScrnInfoPtr pScrn);
+Bool SAVAGEInitDma(ScrnInfoPtr pScrn, int prim_size);
+#endif
+
+#define SAVAGE_AGP_1X_MODE 0x01
+#define SAVAGE_AGP_2X_MODE 0x02
+#define SAVAGE_AGP_4X_MODE 0x04
+#define SAVAGE_AGP_MODE_MASK 0x07
+
+#endif
+
/* Prototypes. */
@@ -243,6 +408,7 @@ Bool SavageInitAccel(ScreenPtr);
void SavageInitialize2DEngine(ScrnInfoPtr);
void SavageSetGBD(ScrnInfoPtr);
void SavageAccelSync(ScrnInfoPtr);
+/*int SavageHelpSolidROP(ScrnInfoPtr pScrn, int *fg, int pm, int *rop);*/
/* In savage_i2c.c. */
@@ -261,6 +427,7 @@ void SavageRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
void SavageSetTextMode( SavagePtr psav );
void SavageSetVESAMode( SavagePtr psav, int n, int Refresh );
+void SavageSetPanelEnabled( SavagePtr psav, Bool active );
void SavageFreeBIOSModeTable( SavagePtr psav, SavageModeTablePtr* ppTable );
SavageModeTablePtr SavageGetBIOSModeTable( SavagePtr psav, int iDepth );
@@ -269,7 +436,6 @@ unsigned short SavageGetBIOSModes(
int iDepth,
SavageModeEntryPtr s3vModeTable );
-
/* In savage_video.c */
void SavageInitVideo( ScreenPtr pScreen );
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_i2c.c b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_i2c.c
index 01ac3e2d1..f3bda8461 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_i2c.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_i2c.c
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_i2c.c,v 1.3 2002/10/02 20:39:55 alanh Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_i2c.c,v 1.1 2001/02/13 21:15:19 dawes Exp $ */
/*
Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
@@ -48,7 +48,8 @@ SavageI2CPutBits(I2CBusPtr b, int clock, int data)
if(clock) reg |= 0x1;
if(data) reg |= 0x2;
- OutI2CREG(psav,reg);
+ /*OutI2CREG(psav,reg);*/ /*tim*/
+ OutI2CREG(reg,psav->DDCPort); /*s3*/
/*ErrorF("SavageI2CPutBits: %d %d\n", clock, data); */
}
@@ -59,7 +60,8 @@ SavageI2CGetBits(I2CBusPtr b, int *clock, int *data)
SavagePtr psav = SAVPTR(pScrn);
unsigned char reg = 0x10;
- InI2CREG(psav,reg);
+ /*InI2CREG(psav,reg);*/ /*tim*/
+ InI2CREG(reg,psav->DDCPort); /*s3*/
*clock = reg & 0x4;
*data = reg & 0x8;
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_regs.h b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_regs.h
index 602d2bc41..d66b2e3c8 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_regs.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_regs.h
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_regs.h,v 1.12 2002/10/02 20:39:55 alanh Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_regs.h,v 1.10 2001/11/04 22:17:48 alanh Exp $ */
#ifndef _SAVAGE_REGS_H
#define _SAVAGE_REGS_H
@@ -29,12 +29,17 @@
#define S3_SAVAGE3D_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE_MX))
-#define S3_SAVAGE4_SERIES(chip) ((chip==S3_SAVAGE4) || (chip==S3_PROSAVAGE))
+#define S3_SAVAGE4_SERIES(chip) ((chip==S3_SAVAGE4) \
+ || (chip==S3_PROSAVAGE) \
+ || (chip==S3_TWISTER) \
+ || (chip==S3_PROSAVAGEDDR))
#define S3_SAVAGE_MOBILE_SERIES(chip) ((chip==S3_SAVAGE_MX) || (chip==S3_SUPERSAVAGE))
#define S3_SAVAGE_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE2000))
+#define S3_MOBILE_TWISTER_SERIES(chip) ((chip==S3_TWISTER) \
+ ||(chip==S3_PROSAVAGEDDR))
/* Chip tags. These are used to group the adapters into
* related families.
@@ -46,6 +51,8 @@ enum S3CHIPTAGS {
S3_SAVAGE_MX,
S3_SAVAGE4,
S3_PROSAVAGE,
+ S3_TWISTER,
+ S3_PROSAVAGEDDR,
S3_SUPERSAVAGE,
S3_SAVAGE2000,
S3_LAST
@@ -66,6 +73,133 @@ enum S3CHIPTAGS {
#define STREAMS_TIMEOUT_REG 0x8208
#define MISC_TIMEOUT_REG 0x820c
+#define SAVAGE_NEWMMIO_REGBASE_S3 0x1000000 /* 16MB */
+#define SAVAGE_NEWMMIO_REGBASE_S4 0x0000000
+#define SAVAGE_NEWMMIO_REGSIZE 0x0080000 /* 512kb */
+#define SAVAGE_NEWMMIO_VGABASE 0x8000
+
+#define ADVANCED_FUNC_CTRL 0x850C
+
+/*
+ * CR/SR registers MMIO offset
+ * MISC Output Register(W:0x3c2,R:0x3cc) controls CR is 0X83Cx or 0X83Bx
+ * but do we need to set MISC Output Register ???
+ * (Note that CRT_ADDRESS_REG and CRT_DATA_REG are assumed to be COLOR)???
+ */
+#define MMIO_BASE_OF_VGA3C0 0X83C0
+#define MMIO_BASE_OF_VGA3D0 0X83D0
+
+#define ATTR_ADDRESS_REG \
+ (MMIO_BASE_OF_VGA3C0 + (0x03C0 - 0x03C0))
+#define ATTR_DATA_WRITE_REG \
+ (MMIO_BASE_OF_VGA3C0 + (0x03C0 - 0x03C0))
+#define ATTR_DATA_READ_REG \
+ (MMIO_BASE_OF_VGA3C0 + (0x03C1 - 0x03C0))
+#define VIDEO_SUBSYSTEM_ENABLE \
+ (MMIO_BASE_OF_VGA3C0 + (0x03C3 - 0x03C0))
+#define SEQ_ADDRESS_REG \
+ (MMIO_BASE_OF_VGA3C0 + (0x03C4 - 0x03C0))
+#define SEQ_DATA_REG \
+ (MMIO_BASE_OF_VGA3C0 + (0x03C5 - 0x03C0))
+#define DAC_PIXEL_MASK_REG \
+ (MMIO_BASE_OF_VGA3C0 + (0x03C6 - 0x03C0))
+#define DAC_PEL_MASK \
+ (MMIO_BASE_OF_VGA3C0 + (0x03C6 - 0x03C0))
+#define DAC_STATUS_REG \
+ (MMIO_BASE_OF_VGA3C0 + (0x03C7 - 0x03C0))
+#define DAC_ADDRESS_READ_REG \
+ (MMIO_BASE_OF_VGA3C0 + (0x03C7 - 0x03C0))
+#define DAC_ADDRESS_WRITE_REG \
+ (MMIO_BASE_OF_VGA3C0 + (0x03C8 - 0x03C0))
+#define DAC_DATA_REG \
+ (MMIO_BASE_OF_VGA3C0 + (0x03C9 - 0x03C0))
+#define DAC_DATA_REG_PORT \
+ (MMIO_BASE_OF_VGA3C0 + (0x03C9 - 0x03C0))
+#define MISC_OUTPUT_REG_WRITE \
+ (MMIO_BASE_OF_VGA3C0 + (0x03C2 - 0x03C0))
+#define MISC_OUTPUT_REG_READ \
+ (MMIO_BASE_OF_VGA3C0 + (0x03CC - 0x03C0))
+#define GR_ADDRESS_REG \
+ (MMIO_BASE_OF_VGA3C0 + (0x03CE - 0x03C0))
+#define GR_DATA_REG \
+ (MMIO_BASE_OF_VGA3C0 + (0x03CF - 0x03C0))
+#define WAKEUP_REG \
+ (MMIO_BASE_OF_VGA3C0 + (0x0510 - 0x03C0))
+
+#define CRT_ADDRESS_REG \
+ (MMIO_BASE_OF_VGA3D0 + (0x03D4 - 0x03D0))
+#define CRT_DATA_REG \
+ (MMIO_BASE_OF_VGA3D0 + (0x03D5 - 0x03D0))
+#define SYSTEM_CONTROL_REG \
+ (MMIO_BASE_OF_VGA3D0 + (0x03DA - 0x03D0))
+
+/* GX-3 Configuration/Status Registers */
+#define S3_SHADOW_STATUS 0x48C0C
+#define S3_BUFFER_THRESHOLD 0x48C10
+#define S3_OVERFLOW_BUFFER 0x48C14
+#define S3_OVERFLOW_BUFFER_PTR 0x48C18
+
+#define ENABLE_BCI 0x08 /* MM48C18_3 */
+#define ENABLE_COMMAND_OVERFLOW_BUF 0x04 /* MM48C18_2 */
+#define ENABLE_COMMAND_BUF_STATUS_UPDATE 0x02 /* MM48C18_1 */
+#define ENABLE_SHADOW_STATUS_UPDATE 0x01 /* MM48C0C_0 */
+
+
+#define MEMORY_CTRL0_REG 0xCA
+#define MEMORY_CTRL1_REG 0xCB
+#define MEMORY_CTRL2_REG 0xCC
+
+#define MEMORY_CONFIG_REG 0x31
+
+/* bitmap descriptor register */
+#define S3_GLB_BD_LOW 0X8168
+#define S3_GLB_BD_HIGH 0X816C
+#define S3_PRI_BD_LOW 0X8170
+#define S3_PRI_BD_HIGH 0X8174
+#define S3_SEC_BD_LOW 0X8178
+#define S3_SEC_BD_HIGH 0X817c
+
+
+/**** S3 streams processor*****/
+
+#define EXT_MISC_CTRL2 0x67
+/* CR67[2] = 1 : enable stream 1 */
+#define ENABLE_STREAM1 0x04
+/* CR67[1] = 1 : enable stream 2 */
+#define ENABLE_STREAM2 0x02
+/* mask to clear CR67[2,1] */
+#define NO_STREAMS 0xF9
+/* CR67[3] = 1 : Mem-mapped regs */
+#define USE_MM_FOR_PRI_STREAM 0x08
+#define HDM_SHIFT 16
+#define HDSCALE_4 (2 << HDM_SHIFT)
+#define HDSCALE_8 (3 << HDM_SHIFT)
+#define HDSCALE_16 (4 << HDM_SHIFT)
+#define HDSCALE_32 (5 << HDM_SHIFT)
+#define HDSCALE_64 (6 << HDM_SHIFT)
+
+/* Old Streams */
+
+#define ENABLE_STREAMS_OLD 0x0c
+#define NO_STREAMS_OLD 0xf3
+/* CR69[0] = 1 : Mem-mapped regs */
+#define USE_MM_FOR_PRI_STREAM_OLD 0x01
+
+
+#define SELECT_IGA1 0x4026
+#define SELECT_IGA2_READS_WRITES 0x4f26
+
+#define MEM_PS1 0x10 /*CRCA_4 :Primary stream 1*/
+#define MEM_PS2 0x20 /*CRCA_5 :Primary stream 2*/
+#define MEM_SS1 0x40 /*CRCA_6 :Secondary stream 1*/
+#define MEM_SS2 0x80 /*CRCA_7 :Secondary stream 2*/
+
+/*
+ * There are two different streams engines used in the Savage line.
+ * The old engine is in the 3D, 4, Pro, and Twister.
+ * The new engine is in the 2000, MX, IX, and Super.
+ */
+
/* Stream Processor 1 */
/* Primary Stream 1 Frame Buffer Address 0 */
@@ -157,6 +291,35 @@ enum S3CHIPTAGS {
/* Secondary Stream 2 Opaque Overlay Control */
#define SEC_STREAM2_OPAQUE_OVERLAY 0x8180
+/* streams registers for old engine */
+#define PSTREAM_CONTROL_REG 0x8180
+#define COL_CHROMA_KEY_CONTROL_REG 0x8184
+#define SSTREAM_CONTROL_REG 0x8190
+#define CHROMA_KEY_UPPER_BOUND_REG 0x8194
+#define SSTREAM_STRETCH_REG 0x8198
+#define COLOR_ADJUSTMENT_REG 0x819C
+#define BLEND_CONTROL_REG 0x81A0
+#define PSTREAM_FBADDR0_REG 0x81C0
+#define PSTREAM_FBADDR1_REG 0x81C4
+#define PSTREAM_STRIDE_REG 0x81C8
+#define DOUBLE_BUFFER_REG 0x81CC
+/* updated by peterzhu,original define is DOUBLE_BUFFER_REG*/
+#define MULTIPLE_BUFFER_REG 0x81CC
+#define SSTREAM_FBADDR0_REG 0x81D0
+#define SSTREAM_FBADDR1_REG 0x81D4
+#define SSTREAM_STRIDE_REG 0x81D8
+#define SSTREAM_VSCALE_REG 0x81E0
+#define SSTREAM_VINITIAL_REG 0x81E4
+#define SSTREAM_LINES_REG 0x81E8
+#define STREAMS_FIFO_REG 0x81EC
+#define PSTREAM_WINDOW_START_REG 0x81F0
+#define PSTREAM_WINDOW_SIZE_REG 0x81F4
+#define SSTREAM_WINDOW_START_REG 0x81F8
+#define SSTREAM_WINDOW_SIZE_REG 0x81FC
+#define FIFO_CONTROL 0x8200
+#define PSTREAM_FBSIZE_REG 0x8300
+#define SSTREAM_FBSIZE_REG 0x8304
+#define SSTREAM_FBADDR2_REG 0x8308
#define SUBSYS_STAT_REG 0x8504
@@ -168,6 +331,43 @@ enum S3CHIPTAGS {
#define MONO_PAT_0 0xa4e8
#define MONO_PAT_1 0xa4ec
+#define TILED_SURFACE_REGISTER_0 0x48c40
+#define TILED_SURFACE_REGISTER_1 0x48c44
+#define TILED_SURFACE_REGISTER_2 0x48c48
+#define TILED_SURFACE_REGISTER_3 0x48c4c
+#define TILED_SURFACE_REGISTER_4 0x48c50
+
+#define TILED_SURF_BPP4 0x00000000 /* bits 31-30=00 for 4 bits/pixel */
+#define TILED_SURF_BPP8 0x40000000 /* bits 31-30=01 for 8 bits/pixel */
+#define TILED_SURF_BPP16 0x80000000 /* bits 31-30=10 for 16 bits/pixel */
+#define TILED_SURF_BPP32 0xC0000000 /* bits 31-30=11 for 32 bits/pixel */
+
+/* Streams Processor macros */
+#define H_Shift 0
+#define H_Mask (((1L << 11) - 1) << H_Shift)
+#define W_Shift 16
+#define W_Mask (((1L << 11) - 1) << W_Shift)
+
+#define Y_Shift 0
+#define Y_Mask (((1L << 11) - 1) << Y_Shift)
+#define X_Shift 16
+#define X_Mask (((1L << 11) - 1) << X_Shift)
+
+#define XY(x,y) ((((x+1)<<X_Shift)&X_Mask) | (((y+1)<<Y_Shift)&Y_Mask))
+#define WH(w,h) ((((w-1)<<W_Shift)&W_Mask) | (((h)<<H_Shift)&H_Mask))
+
+
+/*
+ * CR88_4 =1 : disable block write
+ * the "2D" is partly to set this apart from "BLOCK_WRITE_DISABLE"
+ * constant used for bitmap descriptor
+ */
+#define DISABLE_BLOCK_WRITE_2D 0x10
+#define BLOCK_WRITE_DISABLE 0x0
+
+/* CR31[0] set = Enable 8MB display memory through 64K window at A0000H. */
+#define ENABLE_CPUA_BASE_A0000 0x01
+
/* Constants for CR69. */
#define CRT_ACTIVE 0x01
@@ -188,6 +388,69 @@ enum S3CHIPTAGS {
#define MAXFIFO 0x7f00
+#define inStatus1() (VGAHWPTR(pScrn))->readST01( VGAHWPTR(pScrn) )
+
+
+/*
+ * unprotect CRTC[0-7]
+ * CR11_7 = 0: Writing to all CRT Controller registers enabled
+ * = 1: Writing to all bits of CR0~CR7 except CR7_4 disabled
+ */
+#define UnProtectCRTC() \
+do { \
+ uchar byte; \
+ OUTREG8(CRT_ADDRESS_REG,0x11); \
+ byte = INREG8(CRT_DATA_REG) & 0X7F; \
+ OUTREG16(CRT_ADDRESS_REG,byte << 8 | 0x11); \
+} while (0)
+
+/*
+ * unlock extended regs
+ * CR38:unlock CR20~CR3F
+ * CR39:unlock CR40~CRFF
+ * SR08:unlock SR09~SRFF
+ */
+#define UnLockExtRegs() \
+do { \
+ OUTREG16(CRT_ADDRESS_REG,0X4838); \
+ OUTREG16(CRT_ADDRESS_REG,0XA039); \
+ OUTREG16(SEQ_ADDRESS_REG,0X0608); \
+} while (0)
+
+#define VerticalRetraceWait() \
+do { \
+ INREG8(CRT_ADDRESS_REG); \
+ OUTREG8(CRT_ADDRESS_REG, 0x17); \
+ if (INREG8(CRT_DATA_REG) & 0x80) { \
+ int i = 0x10000; \
+ while ((INREG8(SYSTEM_CONTROL_REG) & 0x08) == 0x08 && i--) ; \
+ i = 0x10000; \
+ while ((INREG8(SYSTEM_CONTROL_REG) & 0x08) == 0x00 && i--) ; \
+ } \
+} while (0)
+
+/*
+ * Jiayo Hsu, Mar 21, 2002
+ * modify this to scalable schema,because different chips have differnt regs,
+ * besides add in patch code for Paramount(SuperSavage) from 2K
+ */
+#define InI2CREG(a,reg) \
+do { \
+ OUTREG8(CRT_ADDRESS_REG, reg); \
+ if (psav->Chipset == S3_SUPERSAVAGE) \
+ OUTREG8(CRT_DATA_REG, INREG8(CRT_DATA_REG)); \
+ a = INREG8(CRT_DATA_REG); \
+} while (0)
+
+#define OutI2CREG(a,reg) \
+do { \
+ OUTREG8(CRT_ADDRESS_REG, reg); \
+ if (psav->Chipset == S3_SUPERSAVAGE) \
+ OUTREG8(CRT_DATA_REG, a); \
+ OUTREG8(CRT_DATA_REG, a); \
+} while (0)
+
+#if 0 /* tim's code */
/*
* NOTE: don't remove 'VGAIN8(vgaCRIndex);'.
* If not present it will cause lockups on Savage4.
@@ -202,21 +465,17 @@ enum S3CHIPTAGS {
while ((VGAIN8(psav->vgaIOBase + 0x0a) & 0x08) == 0x00) ; \
} \
}
-
-#define I2C_REG 0xa0
-#define InI2CREG(psav,a) \
-{ \
- VGAOUT8(psav->vgaIOBase + 4, I2C_REG); \
- a = VGAIN8(psav->vgaIOBase + 5); \
-}
-
-#define OutI2CREG(psav,a) \
-{ \
- VGAOUT8(psav->vgaIOBase + 4, I2C_REG); \
- VGAOUT8(psav->vgaIOBase + 5, a); \
-}
+#endif /* tim's code */
+#define HZEXP_COMP_1 0x54
+#define HZEXP_BORDER 0x58
#define HZEXP_FACTOR_IGA1 0x59
+
+#define VTEXP_COMP_1 0x56
+#define VTEXP_BORDER 0x5a
#define VTEXP_FACTOR_IGA1 0x5b
+#define EC1_CENTER_ON 0x10
+#define EC1_EXPAND_ON 0x0c
+
#endif /* _SAVAGE_REGS_H */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_vbe.c b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_vbe.c
index f0a0edcba..70059cafb 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_vbe.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_vbe.c
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_vbe.c,v 1.12 2002/10/02 20:39:55 alanh Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_vbe.c,v 1.9 2001/05/19 02:05:55 dawes Exp $ */
#include "savage_driver.h"
#include "savage_vbe.h"
@@ -72,7 +72,7 @@ SavageSetVESAMode( SavagePtr psav, int n, int Refresh )
SavageClearVM86Regs( psav->pInt10 );
psav->pInt10->ax = 0x4f14; /* S3 extensions */
psav->pInt10->bx = 0x0001; /* Set default refresh rate */
- psav->pInt10->cx = n;
+ psav->pInt10->cx = n & 0x3fff;
psav->pInt10->di = Refresh & 0xffff;
xf86ExecX86int10( psav->pInt10 );
@@ -92,7 +92,7 @@ SavageSetVESAMode( SavagePtr psav, int n, int Refresh )
SavageClearVM86Regs( psav->pInt10 );
psav->pInt10->ax = 0x4f14; /* S3 extensions */
psav->pInt10->bx = 0x0003; /* set active devices */
- psav->pInt10->cx = psav->PAL ? 0x08 : 0x04;
+ psav->pInt10->cx = psav->iDevInfo;
xf86ExecX86int10( psav->pInt10 );
/* Re-fetch actual device set. */
@@ -123,6 +123,25 @@ SavageSetVESAMode( SavagePtr psav, int n, int Refresh )
}
+void
+SavageSetPanelEnabled( SavagePtr psav, Bool active )
+{
+ int iDevInfo;
+ if( !psav->PanelX )
+ return; /* no panel */
+ iDevInfo = SavageGetDevice( psav );
+ if( active )
+ iDevInfo |= LCD_ACTIVE;
+ else
+ iDevInfo &= ~LCD_ACTIVE;
+ SavageClearVM86Regs( psav->pInt10 );
+ psav->pInt10->ax = 0x4f14; /* S3 extensions */
+ psav->pInt10->bx = 0x0003; /* set active devices */
+ psav->pInt10->cx = iDevInfo;
+ xf86ExecX86int10( psav->pInt10 );
+}
+
+
/* Function to get supported device list. */
static int SavageGetDevice( SavagePtr psav )
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_video.c b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_video.c
index 38c2cc362..75a1ee80d 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_video.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_video.c
@@ -1,12 +1,22 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_video.c,v 1.11 2003/01/12 03:55:49 tsi Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_video.c,v 1.7 2001/11/21 22:43:01 dawes Exp $ */
#include "Xv.h"
#include "dix.h"
#include "dixstruct.h"
#include "fourcc.h"
-#include "xaalocal.h"
#include "savage_driver.h"
+#include "savage_regs.h"
+#include "savage_bci.h"
+
+/* AGD: Uncomment this to use the BCI copy planar data method on
+ * savages with the old streams engine. It's off by default
+ * as it leaves artifacts on the screen when moving the output
+ * window. It may also be possible to use a similar method
+ * on chips using the new streams engine. That remains to be
+ * seen.
+ */
+/*#define BCI_COPY_DATA 1*/
#define OFF_DELAY 200 /* milliseconds */
#define FREE_DELAY 60000
@@ -17,6 +27,18 @@
#define TIMER_MASK (OFF_TIMER | FREE_TIMER)
+#define HSCALING_Shift 0
+#define HSCALING_Mask (((1L << 16)-1) << HSCALING_Shift)
+#define HSCALING(w0,w1) ((((unsigned int)(((double)w0/(double)w1) * (1 << 15))) \
+ << HSCALING_Shift) \
+ & HSCALING_Mask)
+
+#define VSCALING_Shift 0
+#define VSCALING_Mask (((1L << 20)-1) << VSCALING_Shift)
+#define VSCALING(h0,h1) ((((unsigned int) (((double)h0/(double)h1) * (1 << 15))) \
+ << VSCALING_Shift) \
+ & VSCALING_Mask)
+
#ifndef XvExtension
void SavageInitVideo(ScreenPtr pScreen) {}
void SavageResetVideo(ScrnInfoPtr pScrn) {}
@@ -78,8 +100,9 @@ static void (*SavageDisplayVideo)(
short drw_w, short drw_h
) = NULL;
+static void OverlayTwisterInit(ScrnInfoPtr pScrn);
static void OverlayParamInit(ScrnInfoPtr pScrn);
-static void InitStreamsForExpansion(SavagePtr psav);
+static void InitStreamsForExpansion(ScrnInfoPtr pScrn);
/*static void SavageBlockHandler(int, pointer, pointer, pointer);*/
@@ -212,37 +235,6 @@ typedef struct {
#define GET_PORT_PRIVATE(pScrn) \
(SavagePortPrivPtr)((SAVPTR(pScrn))->adaptor->pPortPrivates[0].ptr)
-/**************************************
- S3 streams processor
-**************************************/
-
-#define EXT_MISC_CTRL2 0x67
-
-/* New streams */
-
-/* CR67[2] = 1 : enable stream 1 */
-#define ENABLE_STREAM1 0x04
-/* CR67[1] = 1 : enable stream 2 */
-#define ENABLE_STREAM2 0x02
-/* mask to clear CR67[2,1] */
-#define NO_STREAMS 0xF9
-/* CR67[3] = 1 : Mem-mapped regs */
-#define USE_MM_FOR_PRI_STREAM 0x08
-
-#define HDM_SHIFT 16
-#define HDSCALE_4 (2 << HDM_SHIFT)
-#define HDSCALE_8 (3 << HDM_SHIFT)
-#define HDSCALE_16 (4 << HDM_SHIFT)
-#define HDSCALE_32 (5 << HDM_SHIFT)
-#define HDSCALE_64 (6 << HDM_SHIFT)
-
-/* Old Streams */
-
-#define ENABLE_STREAMS_OLD 0x0c
-#define NO_STREAMS_OLD 0xf3
-/* CR69[0] = 1 : Mem-mapped regs */
-#define USE_MM_FOR_PRI_STREAM_OLD 0x01
-
/*
* There are two different streams engines used in the Savage line.
@@ -251,34 +243,6 @@ typedef struct {
*/
-/* streams registers for old engine */
-#define PSTREAM_CONTROL_REG 0x8180
-#define COL_CHROMA_KEY_CONTROL_REG 0x8184
-#define SSTREAM_CONTROL_REG 0x8190
-#define CHROMA_KEY_UPPER_BOUND_REG 0x8194
-#define SSTREAM_STRETCH_REG 0x8198
-#define COLOR_ADJUSTMENT_REG 0x819C
-#define BLEND_CONTROL_REG 0x81A0
-#define PSTREAM_FBADDR0_REG 0x81C0
-#define PSTREAM_FBADDR1_REG 0x81C4
-#define PSTREAM_STRIDE_REG 0x81C8
-#define DOUBLE_BUFFER_REG 0x81CC
-#define SSTREAM_FBADDR0_REG 0x81D0
-#define SSTREAM_FBADDR1_REG 0x81D4
-#define SSTREAM_STRIDE_REG 0x81D8
-#define SSTREAM_VSCALE_REG 0x81E0
-#define SSTREAM_VINITIAL_REG 0x81E4
-#define SSTREAM_LINES_REG 0x81E8
-#define STREAMS_FIFO_REG 0x81EC
-#define PSTREAM_WINDOW_START_REG 0x81F0
-#define PSTREAM_WINDOW_SIZE_REG 0x81F4
-#define SSTREAM_WINDOW_START_REG 0x81F8
-#define SSTREAM_WINDOW_SIZE_REG 0x81FC
-#define FIFO_CONTROL 0x8200
-#define PSTREAM_FBSIZE_REG 0x8300
-#define SSTREAM_FBSIZE_REG 0x8304
-#define SSTREAM_FBADDR2_REG 0x8308
-
#define OS_XY(x,y) (((x+1)<<16)|(y+1))
#define OS_WH(x,y) (((x-1)<<16)|(y))
@@ -324,7 +288,29 @@ void SavageInitStreamsOld(ScrnInfoPtr pScrn)
xf86ErrorFVerb(XVTRACE, "SavageInitStreams\n" );
/* Primary stream reflects the frame buffer. */
-
+#if 0
+/* I don't know if these are needed here or not. seems to work either way
+ * and the stride should have already been set properly in SavageSetGBD()
+ */
+ if (!psav->bTiled) {
+ OUTREG(PRI_STREAM_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFFE000) |
+ (psav->lDelta & 0x00001fff));
+ }
+ else if (pScrn->bitsPerPixel == 16) {
+ /* Scanline-length-in-bytes/128-bytes-per-tile * 256 Qwords/tile */
+ OUTREG(PRI_STREAM_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFFE000)
+ | 0x80000000 | (psav->lDelta & 0x00001fff));
+ }
+ else if (pScrn->bitsPerPixel == 32) {
+ OUTREG(PRI_STREAM_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFFE000)
+ | 0xC0000000 | (psav->lDelta & 0x00001fff));
+ }
+ OUTREG(PSTREAM_FBSIZE_REG,
+ pScrn->virtualY * pScrn->virtualX * (pScrn->bitsPerPixel >> 3));
+#endif
switch( pScrn->depth ) {
case 8: format = 0 << 24; break;
case 15: format = 3 << 24; break;
@@ -358,6 +344,12 @@ void SavageInitStreamsOld(ScrnInfoPtr pScrn)
OUTREG( SSTREAM_VINITIAL_REG, 0 );
OUTREG( SSTREAM_WINDOW_START_REG, OS_XY(0xfffe, 0xfffe) );
OUTREG( SSTREAM_WINDOW_SIZE_REG, OS_WH(10,2) );
+
+ if (S3_MOBILE_TWISTER_SERIES(psav->Chipset) &&
+ psav->FPExpansion) {
+ OverlayTwisterInit(pScrn);
+ }
+
}
#undef OUTREG
@@ -381,7 +373,31 @@ void SavageInitStreamsNew(ScrnInfoPtr pScrn)
) {
OverlayParamInit( pScrn );
}
-
+#if 0
+/* I don't know if these are needed here or not. seems to work either way
+ * and the stride should have already been set properly in SavageSetGBD()
+ */
+ /* Primary stream reflects the frame buffer. */
+ OUTREG32(PRI_STREAM_FBUF_ADDR0, pScrn->fbOffset);
+ if (!psav->bTiled) {
+ OUTREG(PRI_STREAM_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFFE000) |
+ (psav->lDelta & 0x00001fff));
+ }
+ else if (pScrn->bitsPerPixel == 16) {
+ /* Scanline-length-in-bytes/128-bytes-per-tile * 256 Qwords/tile */
+ OUTREG(PRI_STREAM_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFFE000)
+ | 0x80000000 | (psav->lDelta & 0x00001fff));
+ }
+ else if (pScrn->bitsPerPixel == 32) {
+ OUTREG(PRI_STREAM_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFFE000)
+ | 0xC0000000 | (psav->lDelta & 0x00001fff));
+ }
+ OUTREG(PSTREAM_FBSIZE_REG,
+ pScrn->virtualX * pScrn->virtualY * (pScrn->bitsPerPixel >> 3));
+#endif
/* Primary stream reflects the frame buffer. */
jDelta = pScrn->displayWidth * pScrn->bitsPerPixel / 8;
@@ -421,7 +437,6 @@ void SavageStreamsOn(ScrnInfoPtr pScrn, int id)
/* Sequence stolen from streams.c in M7 NT driver */
-
xf86EnableIO();
/* Unlock extended registers. */
@@ -430,17 +445,24 @@ void SavageStreamsOn(ScrnInfoPtr pScrn, int id)
VGAOUT16(vgaCRIndex, 0xa039);
VGAOUT16(0x3c4, 0x0608);
+ if(
+ S3_SAVAGE_MOBILE_SERIES(psav->Chipset) &&
+ !psav->CrtOnly &&
+ !psav->TvOn
+ ) {
+ OverlayParamInit( pScrn );
+ }
+
VGAOUT8( vgaCRIndex, EXT_MISC_CTRL2 );
if( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) ||
- (psav->Chipset == S3_SUPERSAVAGE) ||
(psav->Chipset == S3_SAVAGE2000) )
{
jStreamsControl = VGAIN8( vgaCRReg ) | ENABLE_STREAM1;
/* Wait for VBLANK. */
- VerticalRetraceWait(psav);
+ VerticalRetraceWait();
/* Fire up streams! */
@@ -457,11 +479,17 @@ void SavageStreamsOn(ScrnInfoPtr pScrn, int id)
}
else
{
- jStreamsControl = VGAIN8( vgaCRReg ) | ENABLE_STREAMS_OLD;
-
+ if (S3_MOBILE_TWISTER_SERIES(psav->Chipset)
+ && psav->FPExpansion) {
+ jStreamsControl = VGAIN8( vgaCRReg ) | ENABLE_STREAMS_OLD; /* tim */
+ /*jStreamsControl = VGAIN8( vgaCRReg ) | 0x8c;*/ /* S3 */
+ } else {
+ jStreamsControl = VGAIN8( vgaCRReg ) | ENABLE_STREAMS_OLD; /* tim */
+ /*jStreamsControl = VGAIN8( vgaCRReg ) | 0x04;*/ /* S3 */
+ }
/* Wait for VBLANK. */
- VerticalRetraceWait(psav);
+ VerticalRetraceWait();
/* Fire up streams! */
@@ -472,7 +500,7 @@ void SavageStreamsOn(ScrnInfoPtr pScrn, int id)
/* Wait for VBLANK. */
- VerticalRetraceWait(psav);
+ VerticalRetraceWait();
/* Turn on secondary stream TV flicker filter, once we support TV. */
@@ -510,7 +538,7 @@ void SavageStreamsOff(ScrnInfoPtr pScrn)
/* Wait for VBLANK. */
- VerticalRetraceWait(psav);
+ VerticalRetraceWait();
/* Kill streams. */
@@ -869,45 +897,15 @@ SavageSetupImageVideo(ScreenPtr pScreen)
psav->adaptor = adapt;
-#if 0
+ #if 0
psav->BlockHandler = pScreen->BlockHandler;
pScreen->BlockHandler = SavageBlockHandler;
-#endif
+ #endif
return adapt;
}
-static Bool
-RegionsEqual(RegionPtr A, RegionPtr B)
-{
- int *dataA, *dataB;
- int num;
-
- num = REGION_NUM_RECTS(A);
- if(num != REGION_NUM_RECTS(B))
- return FALSE;
-
- if((A->extents.x1 != B->extents.x1) ||
- (A->extents.x2 != B->extents.x2) ||
- (A->extents.y1 != B->extents.y1) ||
- (A->extents.y2 != B->extents.y2))
- return FALSE;
-
- dataA = (int*)REGION_RECTS(A);
- dataB = (int*)REGION_RECTS(B);
-
- while(num--) {
- if((dataA[0] != dataB[0]) || (dataA[1] != dataB[1]))
- return FALSE;
- dataA += 2;
- dataB += 2;
- }
-
- return TRUE;
-}
-
-
/* SavageClipVideo -
Takes the dst box in standard X BoxRec form (top and left
@@ -992,9 +990,8 @@ SavageStopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown)
REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
- SavageStreamsOff( pScrn );
-
if(shutdown) {
+ SavageStreamsOff( pScrn );
if(pPriv->area) {
xf86FreeOffscreenArea(pPriv->area);
pPriv->area = NULL;
@@ -1106,6 +1103,91 @@ SavageQueryBestSize(
if(*p_w > 16384) *p_w = 16384;
}
+#ifdef BCI_COPY_DATA
+/* SavageCopyPlanarDataOld() causes artifacts on the screen when used.
+ * It's probably something with the BCI. Maybe we need a waitforidle() or
+ * something...
+ */
+static void
+SavageCopyPlanarDataOld(
+ ScrnInfoPtr pScrn,
+ unsigned char *srcY, /* Y */
+ unsigned char *srcV, /* V */
+ unsigned char *srcU, /* U */
+ unsigned char *dst,
+ int srcPitch, int srcPitch2,
+ int dstPitch,
+ int h,int w)
+{
+ SavagePtr psav = SAVPTR(pScrn);
+ /* half of the dest buffer for copying the YVU data to it ??? */
+ unsigned char *dstCopy = (unsigned char *)(((unsigned long)dst
+ + 2 * srcPitch * h
+ + 0x0f) & ~0x0f);
+ /* for pixel transfer */
+ unsigned long offsetY = (unsigned long)dstCopy - (unsigned long)psav->FBBase;
+ unsigned long offsetV = offsetY + srcPitch * h;
+ unsigned long offsetU = offsetV + srcPitch2 * (h>>1);
+ unsigned long dstOffset = (unsigned long)dst - (unsigned long)psav->FBBase;
+ int i;
+
+ BCI_GET_PTR;
+
+ /* copy Y planar */
+ for (i=0;i<srcPitch * h;i++) {
+ dstCopy[i] = srcY[i];
+ }
+
+ /* copy V planar */
+ dstCopy = dstCopy + srcPitch * h;
+ for (i=0;i<srcPitch2 * (h>>1);i++) {
+ dstCopy[i] = srcV[i];
+ }
+
+ /* copy U planar */
+ dstCopy = dstCopy + srcPitch2 * (h>>1);
+ for (i=0;i<srcPitch2 * (h>>1);i++) {
+ dstCopy[i] = srcU[i];
+ }
+
+ /*
+ * Transfer pixel data from one memory location to another loction
+ * and reformat the data during the transfer
+ * a. program BCI51 to specify the source information
+ * b. program BCI52 to specify the destination information
+ * c. program BCI53 to specify the source dimensions
+ * d. program BCI54 to specify the destination dimensions
+ * e. (if the data is in YCbCr420 format)program BCI55,BCI56,BCI57 to
+ * locations of the Y,Cb,and Cr data
+ * f. program BCI50(command=011) to specify the formatting options and
+ * kick off the transfer
+ * this command can be used for color space conversion(YCbCr to RGB)
+ * or for oversampling, but not for both simultaneously. it can also be
+ * used to do mastered image transfer when the source is tiled
+ */
+
+ w = (w+0xf)&0xff0;
+ psav->WaitQueue(psav,11);
+ BCI_SEND(0x96070051);
+ BCI_SEND(offsetY);
+
+ BCI_SEND(dstOffset);
+
+ BCI_SEND(((h-1)<<16)|((w-1)>>3));
+
+ BCI_SEND(dstPitch >> 3);
+
+
+ BCI_SEND(offsetU);
+ BCI_SEND(offsetV);
+
+ BCI_SEND((srcPitch2 << 16)| srcPitch2);
+
+ BCI_SEND(0x96010050);
+ BCI_SEND(0x00200003 | srcPitch);
+ BCI_SEND(0xC0170000);
+}
+#endif
static void
SavageCopyData(
@@ -1222,6 +1304,7 @@ SavageDisplayVideoOld(
/*DisplayModePtr mode = pScrn->currentMode;*/
int vgaCRIndex, vgaCRReg, vgaIOBase;
unsigned int ssControl;
+ int scalratio;
vgaIOBase = hwp->IOBase;
@@ -1237,6 +1320,18 @@ SavageDisplayVideoOld(
SavageResetVideo(pScrn);
}
+ /* Calculate horizontal scale factor. */
+ if (S3_MOBILE_TWISTER_SERIES(psav->Chipset)
+ && psav->FPExpansion) {
+ drw_w = (((float)(drw_w * psav->XExp1)/(float)psav->XExp2)+1);
+ drw_h = (float)(drw_h * psav->YExp1)/(float)psav->YExp2+1;
+ dstBox->x1 = (float)(dstBox->x1 * psav->XExp1)/(float)psav->XExp2;
+ dstBox->y1 = (float)(dstBox->y1 * psav->YExp1)/(float)psav->YExp2;
+
+ dstBox->x1 += psav->displayXoffset;
+ dstBox->y1 += psav->displayYoffset;
+ }
+
/* Set surface format. */
OUTREG(SSTREAM_CONTROL_REG,
@@ -1250,7 +1345,8 @@ SavageDisplayVideoOld(
OUTREG(SSTREAM_LINES_REG, src_h );
OUTREG(SSTREAM_VINITIAL_REG, 0 );
- OUTREG(SSTREAM_VSCALE_REG, (src_h << 15) / drw_h );
+ /*OUTREG(SSTREAM_VSCALE_REG, (src_h << 15) / drw_h );*/
+ OUTREG(SSTREAM_VSCALE_REG, VSCALING(src_h,drw_h));
/* Set surface location and stride. */
@@ -1262,8 +1358,14 @@ SavageDisplayVideoOld(
OUTREG(SSTREAM_WINDOW_START_REG, OS_XY(dstBox->x1, dstBox->y1) );
OUTREG(SSTREAM_WINDOW_SIZE_REG, OS_WH(drw_w, drw_h) );
+ /*
+ * Process horizontal scaling
+ * upscaling and downscaling smaller than 2:1 controled by MM8198
+ * MM8190 controls downscaling mode larger than 2:1
+ */
+ scalratio = 0;
ssControl = 0;
-
+#if 0
if( src_w > (drw_w << 1) )
{
/* BUGBUG shouldn't this be >=? */
@@ -1278,14 +1380,36 @@ SavageDisplayVideoOld(
else if( src_w > (drw_w << 6) )
ssControl |= HDSCALE_64;
}
+#endif
+ if (src_w >= (drw_w * 2)) {
+ if (src_w < (drw_w * 4)) {
+ scalratio = HSCALING(2,1);
+ } else if (src_w < (drw_w * 8)) {
+ ssControl |= HDSCALE_4;
+ } else if (src_w < (drw_w * 16)) {
+ ssControl |= HDSCALE_8;
+ } else if (src_w < (drw_w * 32)) {
+ ssControl |= HDSCALE_16;
+ } else if (src_w < (drw_w * 64)) {
+ ssControl |= HDSCALE_32;
+ } else
+ ssControl |= HDSCALE_64;
+ } else
+ scalratio = HSCALING(src_w,drw_w);
ssControl |= src_w;
ssControl |= (1 << 24);
+ /* Wait for VBLANK. */
+ VerticalRetraceWait();
OUTREG(SSTREAM_CONTROL_REG, ssControl);
+ if (scalratio)
+ OUTREG(SSTREAM_STRETCH_REG,scalratio);
+#if 0
/* Set color key on primary. */
SavageSetColorKey( pScrn );
+#endif
/* Set FIFO L2 on second stream. */
@@ -1358,10 +1482,10 @@ SavageDisplayVideoNew(
!psav->CrtOnly &&
!psav->TvOn
) {
- drw_w = (float)(drw_w * psav->XExp1)/(float)psav->XExp2 + 1;
- drw_h = (float)(drw_h * psav->YExp1)/(float)psav->YExp2 + 1;
- dstBox->x1 = (float)(dstBox->x1 * psav->XExp1)/(float)psav->XExp2;
- dstBox->y1 = (float)(dstBox->y1 * psav->YExp1)/(float)psav->YExp2;
+ drw_w = (drw_w * psav->XExp1)/psav->XExp2 + 1;
+ drw_h = (drw_h * psav->YExp1)/psav->YExp2 + 1;
+ dstBox->x1 = (dstBox->x1 * psav->XExp1)/psav->XExp2;
+ dstBox->y1 = (dstBox->y1 * psav->YExp1)/psav->YExp2;
dstBox->x1 += psav->displayXoffset;
dstBox->y1 += psav->displayYoffset;
}
@@ -1378,14 +1502,16 @@ SavageDisplayVideoNew(
* are 2 bytes/pixel.
*/
- OUTREG(SEC_STREAM_FBUF_ADDR0, (offset + (x1>>15)) & 0x3ffff0 );
+ OUTREG(SEC_STREAM_FBUF_ADDR0, (offset + (x1>>15)) & 0x7ffff0 );
OUTREG(SEC_STREAM_STRIDE, pitch & 0xfff );
OUTREG(SEC_STREAM_WINDOW_START, ((dstBox->x1+1) << 16) | (dstBox->y1+1) );
OUTREG(SEC_STREAM_WINDOW_SZ, ((drw_w) << 16) | drw_h );
+#if 0
/* Set color key on primary. */
SavageSetColorKey( pScrn );
+#endif
/* Set FIFO L2 on second stream. */
@@ -1424,6 +1550,20 @@ SavagePutImage(
int top, left, npixels, nlines;
BoxRec dstBox;
CARD32 tmp;
+/* xf86ErrorFVerb(XVTRACE,"SavagePutImage\n"); */
+
+ if( psav->cxScreen != pScrn->currentMode->HDisplay )
+ {
+ /* The mode has changed. Recompute the offsets. */
+
+ if(
+ S3_SAVAGE_MOBILE_SERIES(psav->Chipset) &&
+ !psav->CrtOnly &&
+ !psav->TvOn
+ ) {
+ OverlayParamInit( pScrn );
+ }
+ }
if(drw_w > 16384) drw_w = 16384;
@@ -1501,13 +1641,30 @@ SavagePutImage(
top &= ~1;
tmp = ((top >> 1) * srcPitch2) + (left >> 2);
offsetU += tmp;
- offsetV += tmp;
+ offsetV += tmp;
nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top;
+#ifdef BCI_COPY_DATA
+ if (S3_SAVAGE4_SERIES(psav->Chipset)) {
+ SavageCopyPlanarDataOld(
+ pScrn,
+ buf + (top * srcPitch) + (left >> 1),
+ buf + offsetV,
+ buf + offsetU,
+ dst_start, srcPitch, srcPitch2, dstPitch, nlines, npixels);
+ } else {
+ SavageCopyPlanarData(
+ buf + (top * srcPitch) + (left >> 1),
+ buf + offsetV,
+ buf + offsetU,
+ dst_start, srcPitch, srcPitch2, dstPitch, nlines, npixels);
+ }
+#else
SavageCopyPlanarData(
buf + (top * srcPitch) + (left >> 1),
buf + offsetV,
buf + offsetU,
dst_start, srcPitch, srcPitch2, dstPitch, nlines, npixels);
+#endif
break;
case FOURCC_Y211: /* Y211 */
case FOURCC_RV15: /* RGB15 */
@@ -1519,18 +1676,20 @@ SavagePutImage(
SavageCopyData(buf, dst_start, srcPitch, dstPitch, nlines, npixels);
break;
}
+
+ /* We need to enable the video before we draw the chroma color.
+ Otherwise, we get blue flashes. */
+
+ SavageDisplayVideo(pScrn, id, offset, width, height, dstPitch,
+ x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h);
/* update cliplist */
- if(!RegionsEqual(&pPriv->clip, clipBoxes)) {
+ if(!REGION_EQUAL(pScreen, &pPriv->clip, clipBoxes)) {
REGION_COPY(pScreen, &pPriv->clip, clipBoxes);
/* draw these */
- XAAFillSolidRects(pScrn, pPriv->colorKey, GXcopy, ~0,
- REGION_NUM_RECTS(clipBoxes),
- REGION_RECTS(clipBoxes));
+ xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes);
+
}
-
- SavageDisplayVideo(pScrn, id, offset, width, height, dstPitch,
- x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h);
pPriv->videoStatus = CLIENT_VIDEO_ON;
@@ -1585,51 +1744,6 @@ SavageQueryImageAttributes(
return size;
}
-#if 0
-
-static void
-CHIPSBlockHandler (
- int i,
- pointer blockData,
- pointer pTimeout,
- pointer pReadmask
-){
- ScreenPtr pScreen = screenInfo.screens[i];
- ScrnInfoPtr pScrn = xf86Screens[i];
- CHIPSPtr cPtr = CHIPSPTR(pScrn);
- CHIPSPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn);
- unsigned char mr3c;
-
- pScreen->BlockHandler = cPtr->BlockHandler;
-
- (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
-
- pScreen->BlockHandler = CHIPSBlockHandler;
-
- CHIPSHiQVSync(pScrn);
- if(pPriv->videoStatus & TIMER_MASK) {
- UpdateCurrentTime();
- if(pPriv->videoStatus & OFF_TIMER) {
- if(pPriv->offTime < currentTime.milliseconds) {
- mr3c = cPtr->readMR(cPtr, 0x3C);
- cPtr->writeMR(cPtr, 0x3C, (mr3c & 0xFE));
- pPriv->videoStatus = FREE_TIMER;
- pPriv->freeTime = currentTime.milliseconds + FREE_DELAY;
- }
- } else { /* FREE_TIMER */
- if(pPriv->freeTime < currentTime.milliseconds) {
- if(pPriv->area) {
- xf86FreeOffscreenArea(pPriv->area);
- pPriv->area = NULL;
- }
- pPriv->videoStatus = 0;
- }
- }
- }
-}
-
-#endif
-
/****************** Offscreen stuff ***************/
typedef struct {
@@ -1692,6 +1806,7 @@ SavageStopSurface(
XF86SurfacePtr surface
){
OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr;
+ xf86ErrorFVerb(XVTRACE,"SavageStopSurface\n");
if(pPriv->isOn) {
/*SavagePtr psav = SAVPTR(surface->pScrn);*/
@@ -1754,6 +1869,7 @@ SavageDisplaySurface(
SavagePortPrivPtr portPriv = GET_PORT_PRIVATE(pScrn);
INT32 x1, y1, x2, y2;
BoxRec dstBox;
+ xf86ErrorFVerb(XVTRACE,"SavageDisplaySurface\n");
x1 = src_x;
x2 = src_x + src_w;
@@ -1777,14 +1893,12 @@ SavageDisplaySurface(
dstBox.y1 -= pScrn->frameY0;
dstBox.y2 -= pScrn->frameY0;
- XAAFillSolidRects(pScrn, portPriv->colorKey, GXcopy, ~0,
- REGION_NUM_RECTS(clipBoxes),
- REGION_RECTS(clipBoxes));
-
SavageDisplayVideo(pScrn, surface->id, surface->offsets[0],
surface->width, surface->height, surface->pitches[0],
x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h);
+ xf86XVFillKeyHelper(pScrn->pScreen, portPriv->colorKey, clipBoxes);
+
pPriv->isOn = TRUE;
#if 0
if(portPriv->videoStatus & CLIENT_VIDEO_ON) {
@@ -1831,6 +1945,52 @@ SavageInitOffscreenImages(ScreenPtr pScreen)
xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1);
}
+static
+void PatchEnableSPofPanel(ScrnInfoPtr pScrn)
+{
+ SavagePtr psav = SAVPTR(pScrn);
+
+ UnLockExtRegs();
+
+ if (pScrn->bitsPerPixel == 8) {
+ OUTREG8(CRT_ADDRESS_REG,0x90);
+ OUTREG8(CRT_DATA_REG,INREG8(CRT_DATA_REG)|0x40);
+ }
+ else {
+ OUTREG8(CRT_ADDRESS_REG,0x90);
+ OUTREG8(CRT_DATA_REG,INREG8(CRT_DATA_REG)|0x48);
+ }
+
+ VerticalRetraceWait();
+
+ OUTREG8(CRT_ADDRESS_REG,0x67);
+ OUTREG8(CRT_DATA_REG,(INREG8(CRT_DATA_REG)&0xf3)|0x04);
+
+ OUTREG8(CRT_ADDRESS_REG,0x65);
+ OUTREG8(CRT_DATA_REG,INREG8(CRT_DATA_REG)|0xC0);
+
+ if (pScrn->bitsPerPixel == 8) {
+ OUTREG32(PSTREAM_CONTROL_REG,0x00000000);
+ } else {
+ OUTREG32(PSTREAM_CONTROL_REG,0x02000000);
+ }
+ OUTREG32(PSTREAM_WINDOW_SIZE_REG, 0x0);
+
+}
+
+/*
+ * Function to get lcd factor, display offset for overlay use
+ * Input: pScrn; Output: x,yfactor, displayoffset in pScrn
+ */
+static void OverlayTwisterInit(ScrnInfoPtr pScrn)
+{
+ SavagePtr psav = SAVPTR(pScrn);
+
+ psav->cxScreen = psav->iResX;
+ InitStreamsForExpansion(pScrn);
+ PatchEnableSPofPanel(pScrn);
+}
+
/* Function to get lcd factor, display offset for overlay use
* Input: pScrn; Output: x,yfactor, displayoffset in pScrn
*/
@@ -1839,144 +1999,89 @@ static void OverlayParamInit(ScrnInfoPtr pScrn)
SavagePtr psav = SAVPTR(pScrn);
psav = SAVPTR(pScrn);
- psav->cxScreen = psav->iResX;
- InitStreamsForExpansion(psav);
+ psav->cxScreen = pScrn->currentMode->HDisplay;
+ InitStreamsForExpansion(pScrn);
}
-/* Function to calculate lcd expansion x,yfactor and offset for overlay
+/* Function to calculate lcd expansion x,y factor and offset for overlay
*/
-static void InitStreamsForExpansion(SavagePtr psav)
+static void InitStreamsForExpansion(ScrnInfoPtr pScrn)
{
+ SavagePtr psav = SAVPTR(pScrn);
int PanelSizeX,PanelSizeY;
int ViewPortWidth,ViewPortHeight;
+ int XExpansion, YExpansion;
int XFactor, YFactor;
+ int Hstate, Vstate;
+
+ static CARD32 Xfactors[] = {
+ 0x00010001,
+ 0x00010001, /* 1 */
+ 0,
+ 0x00090008, /* 3 */
+ 0x00050004, /* 4 */
+ 0,
+ 0x00030002, /* 6 */
+ 0x00020001 /* 7 */
+ };
+
+ static CARD32 Yfactors[] = {
+ 0x00010001, 0x00010001,
+ 0, 0x00060005,
+ 0x00050004, 0x00040003,
+ 0, 0x00030002,
+ 0x00020001, 0x00050002,
+ 0x000C0005, 0x00080003,
+ 0x00090004, 0,
+ 0x00030001, 0x00040001,
+ };
+
+
PanelSizeX = psav->PanelX;
PanelSizeY = psav->PanelY;
- ViewPortWidth = psav->iResX;
- ViewPortHeight = psav->iResY;
+ ViewPortWidth = pScrn->currentMode->HDisplay;
+ ViewPortHeight = pScrn->currentMode->VDisplay;
+
if( PanelSizeX == 1408 )
PanelSizeX = 1400;
- psav->XExpansion = 0x00010001;
- psav->YExpansion = 0x00010001;
+
+ XExpansion = 0x00010001;
+ YExpansion = 0x00010001;
+
psav->displayXoffset = 0;
psav->displayYoffset = 0;
+ VGAOUT8(0x3C4, HZEXP_COMP_1);
+ Hstate = VGAIN8(0x3C5);
+ VGAOUT8(0x3C4, VTEXP_COMP_1);
+ Vstate = VGAIN8(0x3C5);
VGAOUT8(0x3C4, HZEXP_FACTOR_IGA1);
- XFactor = VGAIN8(0x3C5) >> 4;
+ XFactor = VGAIN8(0x3C5);
VGAOUT8(0x3C4, VTEXP_FACTOR_IGA1);
- YFactor = VGAIN8(0x3C5) >> 4;
+ YFactor = VGAIN8(0x3C5);
- switch( XFactor )
+ if( Hstate & EC1_EXPAND_ON )
{
- case 1:
- psav->XExpansion = 0x00010001;
- psav->displayXoffset =
- (((PanelSizeX - ViewPortWidth) / 2) + 0x7) & 0xFFF8;
- break;
+ XExpansion = Xfactors[XFactor>>4];
+ }
- case 3:
- psav->XExpansion = 0x00090008;
- psav->displayXoffset =
- (((PanelSizeX - ((9 * ViewPortWidth)/8)) / 2) + 0x7) & 0xFFF8;
- break;
+ if( Vstate & EC1_EXPAND_ON )
+ {
+ YExpansion = Yfactors[YFactor>>4];
+ }
- case 4:
- psav->XExpansion = 0x00050004;
-
- if ((psav->cxScreen == 800) && (PanelSizeX !=1400))
- {
- psav->displayXoffset =
- (((PanelSizeX - ((5 * ViewPortWidth)/4)) / 2) ) & 0xFFF8;
- }
- else
- {
- psav->displayXoffset =
- (((PanelSizeX - ((5 * ViewPortWidth)/4)) / 2) +0x7) & 0xFFF8;
- }
- break;
+ psav->XExp1 = XExpansion >> 16;
+ psav->XExp2 = XExpansion & 0xFFFF;
- case 6:
- psav->XExpansion = 0x00030002;
- psav->displayXoffset =
- (((PanelSizeX - ((3 * ViewPortWidth)/2)) / 2) + 0x7) & 0xFFF8;
- break;
+ psav->YExp1 = YExpansion >> 16;
+ psav->YExp2 = YExpansion & 0xFFFF;
+
+ psav->displayXoffset =
+ ((PanelSizeX - (psav->XExp1 * ViewPortWidth) / psav->XExp2) / 2 + 7) & 0xfff8;
+ psav->displayYoffset =
+ ((PanelSizeY - (psav->YExp1 * ViewPortHeight) / psav->YExp2) / 2);
- case 7:
- psav->XExpansion = 0x00020001;
- psav->displayXoffset =
- (((PanelSizeX - (2 * ViewPortWidth)) / 2) + 0x7) & 0xFFF8;
- break;
- }
-
- switch( YFactor )
- {
- case 0:
- psav->YExpansion = 0x00010001;
- psav->displayYoffset = (PanelSizeY - ViewPortHeight) / 2;
- break;
- case 1:
- psav->YExpansion = 0x00010001;
- psav->displayYoffset = (PanelSizeY - ViewPortHeight) / 2;
- break;
- case 2:
- psav->YExpansion = 0x00040003;
- psav->displayYoffset = (PanelSizeY - ((4 * ViewPortHeight)/3)) / 2;
- break;
- case 4:
- psav->YExpansion = 0x00050004;
- psav->displayYoffset = (PanelSizeY - ((5 * ViewPortHeight)/4)) / 2;
- break;
- case 5:
- psav->YExpansion = 0x00040003;
-
- if((psav->cxScreen == 1024)&&(PanelSizeX ==1400))
- {
- psav->displayYoffset =
- ((PanelSizeY - ((4 * ViewPortHeight)/3)) / 2) - 0x1 ;
- }
- else
- {
- psav->displayYoffset = (PanelSizeY - ((4 * ViewPortHeight)/3)) / 2;
- }
- break;
- case 6:
- psav->YExpansion = 0x00050004;
- psav->displayYoffset = (PanelSizeY - ((5 * ViewPortHeight)/4)) / 2;
- break;
- case 7:
- psav->YExpansion = 0x00030002;
- psav->displayYoffset = (PanelSizeY - ((3 * ViewPortHeight)/2)) / 2;
- break;
- case 8:
- psav->YExpansion = 0x00020001;
- psav->displayYoffset = (PanelSizeY - (2 * ViewPortHeight)) /2;
- break;
- case 9:
- psav->YExpansion = 0x00090004;
- psav->displayYoffset = (PanelSizeY - ((9 * ViewPortHeight)/4)) /2;
- break;
- case 11:
- psav->YExpansion = 0x00110005;
- psav->displayYoffset = (PanelSizeY - ((11 * ViewPortHeight)/5)) /2;
- break;
- case 12:
- psav->YExpansion = 0x00070003;
- psav->displayYoffset = (PanelSizeY - ((7 * ViewPortHeight)/3)) /2;
- break;
- case 14:
- psav->YExpansion = 0x00050002;
- psav->displayYoffset = (PanelSizeY - ((5 * ViewPortHeight)/2)) /2;
- break;
- case 15:
- psav->YExpansion = 0x00040001;
- psav->displayYoffset = (PanelSizeY - (4 * ViewPortHeight)) /2;
- break;
- }
- psav->XExp1 = psav->XExpansion >> 16;
- psav->XExp2 = psav->XExpansion & 0xFFFF;
- psav->YExp1 = psav->YExpansion >> 16;
- psav->YExp2 = psav->YExpansion & 0xFFFF;
} /* InitStreamsForExpansionPM */
#endif /* XvExtension */
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h
index 17262609c..c2c14dbd3 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h
@@ -1,6 +1,12 @@
-/* drmP.h -- Private header for Direct Rendering Manager -*- linux-c -*-
- * Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com
- *
+/**
+ * \file drmP.h
+ * Private header for Direct Rendering Manager
+ *
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All rights reserved.
@@ -23,15 +29,12 @@
* 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.
- *
- * Authors:
- * Rickard E. (Rik) Faith <faith@valinux.com>
- * Gareth Hughes <gareth@valinux.com>
*/
#ifndef _DRM_P_H_
#define _DRM_P_H_
+
#ifdef __KERNEL__
#ifdef __alpha__
/* add include of current.h so that "current" is defined
@@ -48,7 +51,6 @@
#include <linux/init.h>
#include <linux/file.h>
#include <linux/pci.h>
-#include <linux/wrapper.h>
#include <linux/version.h>
#include <linux/sched.h>
#include <linux/smp_lock.h> /* For (un)lock_kernel */
@@ -67,15 +69,27 @@
#include <linux/types.h>
#include <linux/agp_backend.h>
#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,41)
+#define HAS_WORKQUEUE 0
+#else
+#define HAS_WORKQUEUE 1
+#endif
+#if !HAS_WORKQUEUE
#include <linux/tqueue.h>
+#else
+#include <linux/workqueue.h>
+#endif
#include <linux/poll.h>
#include <asm/pgalloc.h>
#include "drm.h"
#include "drm_os_linux.h"
-/* DRM template customization defaults
- */
+
+/***********************************************************************/
+/** \name DRM template customization defaults */
+/*@{*/
+
#ifndef __HAVE_AGP
#define __HAVE_AGP 0
#endif
@@ -88,8 +102,8 @@
#ifndef __HAVE_DMA
#define __HAVE_DMA 0
#endif
-#ifndef __HAVE_DMA_IRQ
-#define __HAVE_DMA_IRQ 0
+#ifndef __HAVE_IRQ
+#define __HAVE_IRQ 0
#endif
#ifndef __HAVE_DMA_WAITLIST
#define __HAVE_DMA_WAITLIST 0
@@ -97,31 +111,31 @@
#ifndef __HAVE_DMA_FREELIST
#define __HAVE_DMA_FREELIST 0
#endif
-#ifndef __HAVE_DMA_HISTOGRAM
-#define __HAVE_DMA_HISTOGRAM 0
-#endif
#define __REALLY_HAVE_AGP (__HAVE_AGP && (defined(CONFIG_AGP) || \
defined(CONFIG_AGP_MODULE)))
#define __REALLY_HAVE_MTRR (__HAVE_MTRR && defined(CONFIG_MTRR))
#define __REALLY_HAVE_SG (__HAVE_SG)
-/* Begin the DRM...
- */
+/*@}*/
-#define DRM_DEBUG_CODE 2 /* Include debugging code (if > 1, then
+
+/***********************************************************************/
+/** \name Begin the DRM... */
+/*@{*/
+
+#define DRM_DEBUG_CODE 2 /**< Include debugging code if > 1, then
also include looping detection. */
-#define DRM_HASH_SIZE 16 /* Size of key hash table */
-#define DRM_KERNEL_CONTEXT 0 /* Change drm_resctx if changed */
-#define DRM_RESERVED_CONTEXTS 1 /* Change drm_resctx if changed */
+#define DRM_HASH_SIZE 16 /**< Size of key hash table. Must be power of 2. */
+#define DRM_KERNEL_CONTEXT 0 /**< Change drm_resctx if changed */
+#define DRM_RESERVED_CONTEXTS 1 /**< Change drm_resctx if changed */
#define DRM_LOOPING_LIMIT 5000000
-#define DRM_BSZ 1024 /* Buffer size for /dev/drm? output */
-#define DRM_TIME_SLICE (HZ/20) /* Time slice for GLXContexts */
-#define DRM_LOCK_SLICE 1 /* Time slice for lock, in jiffies */
+#define DRM_BSZ 1024 /**< Buffer size for /dev/drm? output */
+#define DRM_TIME_SLICE (HZ/20) /**< Time slice for GLXContexts */
+#define DRM_LOCK_SLICE 1 /**< Time slice for lock, in jiffies */
#define DRM_FLAG_DEBUG 0x01
-#define DRM_FLAG_NOCTX 0x02
#define DRM_MEM_DMA 0
#define DRM_MEM_SAREA 1
@@ -144,10 +158,17 @@
#define DRM_MEM_CTXBITMAP 18
#define DRM_MEM_STUB 19
#define DRM_MEM_SGLISTS 20
+#define DRM_MEM_CTXLIST 21
#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
+
+/*@}*/
+
+
+/***********************************************************************/
+/** \name Backward compatibility section */
+/*@{*/
- /* Backward compatibility section */
#ifndef minor
#define minor(x) MINOR((x))
#endif
@@ -172,6 +193,23 @@
pos = n, n = pos->next)
#endif
+#ifndef list_for_each_entry
+#define list_for_each_entry(pos, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member), \
+ prefetch(pos->member.next); \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.next, typeof(*pos), member), \
+ prefetch(pos->member.next))
+#endif
+
+#ifndef list_for_each_entry_safe
+#define list_for_each_entry_safe(pos, n, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member), \
+ n = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
+#endif
+
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19)
static inline struct page * vmalloc_to_page(void * vmalloc_addr)
{
@@ -197,23 +235,48 @@ static inline struct page * vmalloc_to_page(void * vmalloc_addr)
}
#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+#ifndef REMAP_PAGE_RANGE_5_ARGS
#define DRM_RPR_ARG(vma)
#else
#define DRM_RPR_ARG(vma) vma,
#endif
-
#define VM_OFFSET(vma) ((vma)->vm_pgoff << PAGE_SHIFT)
- /* Macros to make printk easier */
+/*@}*/
+
+
+/***********************************************************************/
+/** \name Macros to make printk easier */
+/*@{*/
+
+/**
+ * Error output.
+ *
+ * \param fmt printf() like format string.
+ * \param arg arguments
+ */
#define DRM_ERROR(fmt, arg...) \
printk(KERN_ERR "[" DRM_NAME ":%s] *ERROR* " fmt , __FUNCTION__ , ##arg)
+
+/**
+ * Memory error output.
+ *
+ * \param area memory area where the error occurred.
+ * \param fmt printf() like format string.
+ * \param arg arguments
+ */
#define DRM_MEM_ERROR(area, fmt, arg...) \
printk(KERN_ERR "[" DRM_NAME ":%s:%s] *ERROR* " fmt , __FUNCTION__, \
DRM(mem_stats)[area].name , ##arg)
#define DRM_INFO(fmt, arg...) printk(KERN_INFO "[" DRM_NAME "] " fmt , ##arg)
+/**
+ * Debug output.
+ *
+ * \param fmt printf() like format string.
+ * \param arg arguments
+ */
#if DRM_DEBUG_CODE
#define DRM_DEBUG(fmt, arg...) \
do { \
@@ -236,33 +299,61 @@ static inline struct page * vmalloc_to_page(void * vmalloc_addr)
len += sprintf(&buf[len], fmt , ##arg); \
if (len > DRM_PROC_LIMIT) { ret; *eof = 1; return len - offset; }
- /* Mapping helper macros */
-#define DRM_IOREMAP(map) \
- (map)->handle = DRM(ioremap)( (map)->offset, (map)->size )
+/*@}*/
-#define DRM_IOREMAP_NOCACHE(map) \
- (map)->handle = DRM(ioremap_nocache)((map)->offset, (map)->size)
-#define DRM_IOREMAPFREE(map) \
- do { \
- if ( (map)->handle && (map)->size ) \
- DRM(ioremapfree)( (map)->handle, (map)->size ); \
+/***********************************************************************/
+/** \name Mapping helper macros */
+/*@{*/
+
+#define DRM_IOREMAP(map, dev) \
+ (map)->handle = DRM(ioremap)( (map)->offset, (map)->size, (dev) )
+
+#define DRM_IOREMAP_NOCACHE(map, dev) \
+ (map)->handle = DRM(ioremap_nocache)((map)->offset, (map)->size, (dev))
+
+#define DRM_IOREMAPFREE(map, dev) \
+ do { \
+ if ( (map)->handle && (map)->size ) \
+ DRM(ioremapfree)( (map)->handle, (map)->size, (dev) ); \
} while (0)
-#define DRM_FIND_MAP(_map, _o) \
-do { \
- struct list_head *_list; \
- list_for_each( _list, &dev->maplist->head ) { \
- drm_map_list_t *_entry = (drm_map_list_t *)_list; \
- if ( _entry->map && \
- _entry->map->offset == (_o) ) { \
- (_map) = _entry->map; \
- break; \
- } \
- } \
+/**
+ * Find mapping.
+ *
+ * \param _map matching mapping if found, untouched otherwise.
+ * \param _o offset.
+ *
+ * Expects the existence of a local variable named \p dev pointing to the
+ * drm_device structure.
+ */
+#define DRM_FIND_MAP(_map, _o) \
+do { \
+ struct list_head *_list; \
+ list_for_each( _list, &dev->maplist->head ) { \
+ drm_map_list_t *_entry = list_entry( _list, drm_map_list_t, head ); \
+ if ( _entry->map && \
+ _entry->map->offset == (_o) ) { \
+ (_map) = _entry->map; \
+ break; \
+ } \
+ } \
} while(0)
- /* Internal types and structures */
+/**
+ * Drop mapping.
+ *
+ * \sa #DRM_FIND_MAP.
+ */
+#define DRM_DROP_MAP(_map)
+
+/*@}*/
+
+
+/***********************************************************************/
+/** \name Internal types and structures */
+/*@{*/
+
#define DRM_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
#define DRM_MIN(a,b) ((a)<(b)?(a):(b))
#define DRM_MAX(a,b) ((a)>(b)?(a):(b))
@@ -271,17 +362,52 @@ do { \
#define DRM_BUFCOUNT(x) ((x)->count - DRM_LEFTCOUNT(x))
#define DRM_WAITCOUNT(dev,idx) DRM_BUFCOUNT(&dev->queuelist[idx]->waitlist)
+#define DRM_IF_VERSION(maj, min) (maj << 16 | min)
+/**
+ * Get the private SAREA mapping.
+ *
+ * \param _dev DRM device.
+ * \param _ctx context number.
+ * \param _map output mapping.
+ */
#define DRM_GET_PRIV_SAREA(_dev, _ctx, _map) do { \
(_map) = (_dev)->context_sareas[_ctx]; \
} while(0)
+/**
+ * Test that the hardware lock is held by the caller, returning otherwise.
+ *
+ * \param dev DRM device.
+ * \param filp file pointer of the caller.
+ */
+#define LOCK_TEST_WITH_RETURN( dev, filp ) \
+do { \
+ if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \
+ dev->lock.filp != filp ) { \
+ DRM_ERROR( "%s called without lock held\n", \
+ __FUNCTION__ ); \
+ return -EINVAL; \
+ } \
+} while (0)
+
+/**
+ * Ioctl function type.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg argument.
+ */
typedef int drm_ioctl_t( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
-typedef struct drm_pci_list {
- u16 vendor;
- u16 device;
-} drm_pci_list_t;
+typedef struct drm_pci_id_list
+{
+ int vendor;
+ int device;
+ long driver_private;
+ char *name;
+} drm_pci_id_list_t;
typedef struct drm_ioctl_desc {
drm_ioctl_t *func;
@@ -290,8 +416,7 @@ typedef struct drm_ioctl_desc {
} drm_ioctl_desc_t;
typedef struct drm_devstate {
- pid_t owner; /* X server pid holding x_lock */
-
+ pid_t owner; /**< X server pid holding x_lock */
} drm_devstate_t;
typedef struct drm_magic_entry {
@@ -311,21 +436,24 @@ typedef struct drm_vma_entry {
pid_t pid;
} drm_vma_entry_t;
+/**
+ * DMA buffer.
+ */
typedef struct drm_buf {
- int idx; /* Index into master buflist */
- int total; /* Buffer size */
- int order; /* log-base-2(total) */
- int used; /* Amount of buffer in use (for DMA) */
- unsigned long offset; /* Byte offset (used internally) */
- void *address; /* Address of buffer */
- unsigned long bus_address; /* Bus address of buffer */
- struct drm_buf *next; /* Kernel-only: used for free list */
- __volatile__ int waiting; /* On kernel DMA queue */
- __volatile__ int pending; /* On hardware DMA queue */
- wait_queue_head_t dma_wait; /* Processes waiting */
- pid_t pid; /* PID of holding process */
- int context; /* Kernel queue for this buffer */
- int while_locked;/* Dispatch this buffer while locked */
+ int idx; /**< Index into master buflist */
+ int total; /**< Buffer size */
+ int order; /**< log-base-2(total) */
+ int used; /**< Amount of buffer in use (for DMA) */
+ unsigned long offset; /**< Byte offset (used internally) */
+ void *address; /**< Address of buffer */
+ unsigned long bus_address; /**< Bus address of buffer */
+ struct drm_buf *next; /**< Kernel-only: used for free list */
+ __volatile__ int waiting; /**< On kernel DMA queue */
+ __volatile__ int pending; /**< On hardware DMA queue */
+ wait_queue_head_t dma_wait; /**< Processes waiting */
+ struct file *filp; /**< Pointer to holding file descr */
+ int context; /**< Kernel queue for this buffer */
+ int while_locked;/**< Dispatch this buffer while locked */
enum {
DRM_LIST_NONE = 0,
DRM_LIST_FREE = 1,
@@ -333,68 +461,43 @@ typedef struct drm_buf {
DRM_LIST_PEND = 3,
DRM_LIST_PRIO = 4,
DRM_LIST_RECLAIM = 5
- } list; /* Which list we're on */
+ } list; /**< Which list we're on */
-#if DRM_DMA_HISTOGRAM
- cycles_t time_queued; /* Queued to kernel DMA queue */
- cycles_t time_dispatched; /* Dispatched to hardware */
- cycles_t time_completed; /* Completed by hardware */
- cycles_t time_freed; /* Back on freelist */
-#endif
-
- int dev_priv_size; /* Size of buffer private stoarge */
- void *dev_private; /* Per-buffer private storage */
+ int dev_priv_size; /**< Size of buffer private storage */
+ void *dev_private; /**< Per-buffer private storage */
} drm_buf_t;
-#if DRM_DMA_HISTOGRAM
-#define DRM_DMA_HISTOGRAM_SLOTS 9
-#define DRM_DMA_HISTOGRAM_INITIAL 10
-#define DRM_DMA_HISTOGRAM_NEXT(current) ((current)*10)
-typedef struct drm_histogram {
- atomic_t total;
-
- atomic_t queued_to_dispatched[DRM_DMA_HISTOGRAM_SLOTS];
- atomic_t dispatched_to_completed[DRM_DMA_HISTOGRAM_SLOTS];
- atomic_t completed_to_freed[DRM_DMA_HISTOGRAM_SLOTS];
- atomic_t queued_to_completed[DRM_DMA_HISTOGRAM_SLOTS];
- atomic_t queued_to_freed[DRM_DMA_HISTOGRAM_SLOTS];
-
- atomic_t dma[DRM_DMA_HISTOGRAM_SLOTS];
- atomic_t schedule[DRM_DMA_HISTOGRAM_SLOTS];
- atomic_t ctx[DRM_DMA_HISTOGRAM_SLOTS];
- atomic_t lacq[DRM_DMA_HISTOGRAM_SLOTS];
- atomic_t lhld[DRM_DMA_HISTOGRAM_SLOTS];
-} drm_histogram_t;
-#endif
-
- /* bufs is one longer than it has to be */
+/** bufs is one longer than it has to be */
typedef struct drm_waitlist {
- int count; /* Number of possible buffers */
- drm_buf_t **bufs; /* List of pointers to buffers */
- drm_buf_t **rp; /* Read pointer */
- drm_buf_t **wp; /* Write pointer */
- drm_buf_t **end; /* End pointer */
+ int count; /**< Number of possible buffers */
+ drm_buf_t **bufs; /**< List of pointers to buffers */
+ drm_buf_t **rp; /**< Read pointer */
+ drm_buf_t **wp; /**< Write pointer */
+ drm_buf_t **end; /**< End pointer */
spinlock_t read_lock;
spinlock_t write_lock;
} drm_waitlist_t;
typedef struct drm_freelist {
- int initialized; /* Freelist in use */
- atomic_t count; /* Number of free buffers */
- drm_buf_t *next; /* End pointer */
-
- wait_queue_head_t waiting; /* Processes waiting on free bufs */
- int low_mark; /* Low water mark */
- int high_mark; /* High water mark */
- atomic_t wfh; /* If waiting for high mark */
+ int initialized; /**< Freelist in use */
+ atomic_t count; /**< Number of free buffers */
+ drm_buf_t *next; /**< End pointer */
+
+ wait_queue_head_t waiting; /**< Processes waiting on free bufs */
+ int low_mark; /**< Low water mark */
+ int high_mark; /**< High water mark */
+ atomic_t wfh; /**< If waiting for high mark */
spinlock_t lock;
} drm_freelist_t;
+/**
+ * Buffer entry. There is one of this for each buffer size order.
+ */
typedef struct drm_buf_entry {
- int buf_size;
- int buf_count;
- drm_buf_t *buflist;
+ int buf_size; /**< size */
+ int buf_count; /**< number of buffers */
+ drm_buf_t *buflist; /**< buffer list */
int seg_count;
int page_order;
unsigned long *seglist;
@@ -402,11 +505,19 @@ typedef struct drm_buf_entry {
drm_freelist_t freelist;
} drm_buf_entry_t;
+/**
+ * Hardware lock.
+ *
+ * The lock structure is a simple cache-line aligned integer. To avoid
+ * processor bus contention on a multiprocessor system, there should not be any
+ * other data stored in the same cache line.
+ */
typedef struct drm_hw_lock {
- __volatile__ unsigned int lock;
- char padding[60]; /* Pad to cache line */
+ __volatile__ unsigned int lock; /**< lock variable */
+ char padding[60]; /**< Pad to cache line */
} drm_hw_lock_t;
+/** File private data */
typedef struct drm_file {
int authenticated;
int minor;
@@ -418,86 +529,91 @@ typedef struct drm_file {
struct drm_file *prev;
struct drm_device *dev;
int remove_auth_on_close;
+ unsigned long lock_count;
+#ifdef DRIVER_FILE_FIELDS
+ DRIVER_FILE_FIELDS;
+#endif
} drm_file_t;
-
+/** Wait queue */
typedef struct drm_queue {
- atomic_t use_count; /* Outstanding uses (+1) */
- atomic_t finalization; /* Finalization in progress */
- atomic_t block_count; /* Count of processes waiting */
- atomic_t block_read; /* Queue blocked for reads */
- wait_queue_head_t read_queue; /* Processes waiting on block_read */
- atomic_t block_write; /* Queue blocked for writes */
- wait_queue_head_t write_queue; /* Processes waiting on block_write */
+ atomic_t use_count; /**< Outstanding uses (+1) */
+ atomic_t finalization; /**< Finalization in progress */
+ atomic_t block_count; /**< Count of processes waiting */
+ atomic_t block_read; /**< Queue blocked for reads */
+ wait_queue_head_t read_queue; /**< Processes waiting on block_read */
+ atomic_t block_write; /**< Queue blocked for writes */
+ wait_queue_head_t write_queue; /**< Processes waiting on block_write */
#if 1
- atomic_t total_queued; /* Total queued statistic */
- atomic_t total_flushed;/* Total flushes statistic */
- atomic_t total_locks; /* Total locks statistics */
+ atomic_t total_queued; /**< Total queued statistic */
+ atomic_t total_flushed;/**< Total flushes statistic */
+ atomic_t total_locks; /**< Total locks statistics */
#endif
- drm_ctx_flags_t flags; /* Context preserving and 2D-only */
- drm_waitlist_t waitlist; /* Pending buffers */
- wait_queue_head_t flush_queue; /* Processes waiting until flush */
+ drm_ctx_flags_t flags; /**< Context preserving and 2D-only */
+ drm_waitlist_t waitlist; /**< Pending buffers */
+ wait_queue_head_t flush_queue; /**< Processes waiting until flush */
} drm_queue_t;
+/**
+ * Lock data.
+ */
typedef struct drm_lock_data {
- drm_hw_lock_t *hw_lock; /* Hardware lock */
- pid_t pid; /* PID of lock holder (0=kernel) */
- wait_queue_head_t lock_queue; /* Queue of blocked processes */
- unsigned long lock_time; /* Time of last lock in jiffies */
+ drm_hw_lock_t *hw_lock; /**< Hardware lock */
+ struct file *filp; /**< File descr of lock holder (0=kernel) */
+ wait_queue_head_t lock_queue; /**< Queue of blocked processes */
+ unsigned long lock_time; /**< Time of last lock in jiffies */
} drm_lock_data_t;
+/**
+ * DMA data.
+ */
typedef struct drm_device_dma {
-#if 0
- /* Performance Counters */
- atomic_t total_prio; /* Total DRM_DMA_PRIORITY */
- atomic_t total_bytes; /* Total bytes DMA'd */
- atomic_t total_dmas; /* Total DMA buffers dispatched */
-
- atomic_t total_missed_dma; /* Missed drm_do_dma */
- atomic_t total_missed_lock; /* Missed lock in drm_do_dma */
- atomic_t total_missed_free; /* Missed drm_free_this_buffer */
- atomic_t total_missed_sched;/* Missed drm_dma_schedule */
- atomic_t total_tried; /* Tried next_buffer */
- atomic_t total_hit; /* Sent next_buffer */
- atomic_t total_lost; /* Lost interrupt */
-#endif
-
- drm_buf_entry_t bufs[DRM_MAX_ORDER+1];
- int buf_count;
- drm_buf_t **buflist; /* Vector of pointers info bufs */
+ drm_buf_entry_t bufs[DRM_MAX_ORDER+1]; /**< buffers, grouped by their size order */
+ int buf_count; /**< total number of buffers */
+ drm_buf_t **buflist; /**< Vector of pointers into drm_device_dma::bufs */
int seg_count;
- int page_count;
- unsigned long *pagelist;
+ int page_count; /**< number of pages */
+ unsigned long *pagelist; /**< page list */
unsigned long byte_count;
enum {
_DRM_DMA_USE_AGP = 0x01,
_DRM_DMA_USE_SG = 0x02
} flags;
- /* DMA support */
- drm_buf_t *this_buffer; /* Buffer being sent */
- drm_buf_t *next_buffer; /* Selected buffer to send */
- drm_queue_t *next_queue; /* Queue from which buffer selected*/
- wait_queue_head_t waiting; /* Processes waiting on free bufs */
+ /** \name DMA support */
+ /*@{*/
+ drm_buf_t *this_buffer; /**< Buffer being sent */
+ drm_buf_t *next_buffer; /**< Selected buffer to send */
+ drm_queue_t *next_queue; /**< Queue from which buffer selected*/
+ wait_queue_head_t waiting; /**< Processes waiting on free bufs */
+ /*@}*/
} drm_device_dma_t;
#if __REALLY_HAVE_AGP
+/**
+ * AGP memory entry. Stored as a doubly linked list.
+ */
typedef struct drm_agp_mem {
- unsigned long handle;
- agp_memory *memory;
- unsigned long bound; /* address */
+ unsigned long handle; /**< handle */
+ DRM_AGP_MEM *memory;
+ unsigned long bound; /**< address */
int pages;
- struct drm_agp_mem *prev;
- struct drm_agp_mem *next;
+ struct drm_agp_mem *prev; /**< previous entry */
+ struct drm_agp_mem *next; /**< next entry */
} drm_agp_mem_t;
+/**
+ * AGP data.
+ *
+ * \sa DRM(agp_init)() and drm_device::agp.
+ */
typedef struct drm_agp_head {
- agp_kern_info agp_info;
- drm_agp_mem_t *memory;
- unsigned long mode;
- int enabled;
- int acquired;
+ DRM_AGP_KERN agp_info; /**< AGP device information */
+ drm_agp_mem_t *memory; /**< memory entries */
+ unsigned long mode; /**< AGP mode */
+ int enabled; /**< whether the AGP bus as been enabled */
+ int acquired; /**< whether the AGP device has been acquired */
unsigned long base;
int agp_mtrr;
int cant_use_aperture;
@@ -505,6 +621,9 @@ typedef struct drm_agp_head {
} drm_agp_head_t;
#endif
+/**
+ * Scatter-gather memory.
+ */
typedef struct drm_sg_mem {
unsigned long handle;
void *virtual;
@@ -518,11 +637,25 @@ typedef struct drm_sigdata {
drm_hw_lock_t *lock;
} drm_sigdata_t;
+/**
+ * Mappings list
+ */
typedef struct drm_map_list {
- struct list_head head;
- drm_map_t *map;
+ struct list_head head; /**< list head */
+ drm_map_t *map; /**< mapping */
} drm_map_list_t;
+typedef drm_map_t drm_local_map_t;
+
+/**
+ * Context handle list
+ */
+typedef struct drm_ctx_list {
+ struct list_head head; /**< list head */
+ drm_context_t handle; /**< context handle */
+ drm_file_t *tag; /**< associated fd private data */
+} drm_ctx_list_t;
+
#if __HAVE_VBL_IRQ
typedef struct drm_vbl_sig {
@@ -534,92 +667,126 @@ typedef struct drm_vbl_sig {
#endif
+/**
+ * DRM device structure.
+ */
typedef struct drm_device {
- const char *name; /* Simple driver name */
- char *unique; /* Unique identifier: e.g., busid */
- int unique_len; /* Length of unique field */
- dev_t device; /* Device number for mknod */
- char *devname; /* For /proc/interrupts */
-
- int blocked; /* Blocked due to VC switch? */
- struct proc_dir_entry *root; /* Root for this device's entries */
-
- /* Locks */
- spinlock_t count_lock; /* For inuse, open_count, buf_use */
- struct semaphore struct_sem; /* For others */
-
- /* Usage Counters */
- int open_count; /* Outstanding files open */
- atomic_t ioctl_count; /* Outstanding IOCTLs pending */
- atomic_t vma_count; /* Outstanding vma areas open */
- int buf_use; /* Buffers in use -- cannot alloc */
- atomic_t buf_alloc; /* Buffer allocation in progress */
-
- /* Performance counters */
+ const char *name; /**< Simple driver name */
+ char *unique; /**< Unique identifier: e.g., busid */
+ int unique_len; /**< Length of unique field */
+ dev_t device; /**< Device number for mknod */
+ char *devname; /**< For /proc/interrupts */
+ int minor; /**< Minor device number */
+ int if_version; /**< Highest interface version set */
+
+ int blocked; /**< Blocked due to VC switch? */
+ struct proc_dir_entry *root; /**< Root for this device's entries */
+
+ /** \name Locks */
+ /*@{*/
+ spinlock_t count_lock; /**< For inuse, drm_device::open_count, drm_device::buf_use */
+ struct semaphore struct_sem; /**< For others */
+ /*@}*/
+
+ /** \name Usage Counters */
+ /*@{*/
+ int open_count; /**< Outstanding files open */
+ atomic_t ioctl_count; /**< Outstanding IOCTLs pending */
+ atomic_t vma_count; /**< Outstanding vma areas open */
+ int buf_use; /**< Buffers in use -- cannot alloc */
+ atomic_t buf_alloc; /**< Buffer allocation in progress */
+ /*@}*/
+
+ /** \name Performance counters */
+ /*@{*/
unsigned long counters;
drm_stat_type_t types[15];
atomic_t counts[15];
-
- /* Authentication */
- drm_file_t *file_first;
- drm_file_t *file_last;
- drm_magic_head_t magiclist[DRM_HASH_SIZE];
-
- /* Memory management */
- drm_map_list_t *maplist; /* Linked list of regions */
- int map_count; /* Number of mappable regions */
-
- drm_map_t **context_sareas;
+ /*@}*/
+
+ /** \name Authentication */
+ /*@{*/
+ drm_file_t *file_first; /**< file list head */
+ drm_file_t *file_last; /**< file list tail */
+ drm_magic_head_t magiclist[DRM_HASH_SIZE]; /**< magic hash table */
+ /*@}*/
+
+ /** \name Memory management */
+ /*@{*/
+ drm_map_list_t *maplist; /**< Linked list of regions */
+ int map_count; /**< Number of mappable regions */
+
+ /** \name Context handle management */
+ /*@{*/
+ drm_ctx_list_t *ctxlist; /**< Linked list of context handles */
+ int ctx_count; /**< Number of context handles */
+ struct semaphore ctxlist_sem; /**< For ctxlist */
+
+ drm_map_t **context_sareas; /**< per-context SAREA's */
int max_context;
- drm_vma_entry_t *vmalist; /* List of vmas (for debugging) */
- drm_lock_data_t lock; /* Information on hardware lock */
-
- /* DMA queues (contexts) */
- int queue_count; /* Number of active DMA queues */
- int queue_reserved; /* Number of reserved DMA queues */
- int queue_slots; /* Actual length of queuelist */
- drm_queue_t **queuelist; /* Vector of pointers to DMA queues */
- drm_device_dma_t *dma; /* Optional pointer for DMA support */
-
- /* Context support */
- int irq; /* Interrupt used by board */
- __volatile__ long context_flag; /* Context swapping flag */
- __volatile__ long interrupt_flag; /* Interruption handler flag */
- __volatile__ long dma_flag; /* DMA dispatch flag */
- struct timer_list timer; /* Timer for delaying ctx switch */
- wait_queue_head_t context_wait; /* Processes waiting on ctx switch */
- int last_checked; /* Last context checked for DMA */
- int last_context; /* Last current context */
- unsigned long last_switch; /* jiffies at last context switch */
+ drm_vma_entry_t *vmalist; /**< List of vmas (for debugging) */
+ drm_lock_data_t lock; /**< Information on hardware lock */
+ /*@}*/
+
+ /** \name DMA queues (contexts) */
+ /*@{*/
+ int queue_count; /**< Number of active DMA queues */
+ int queue_reserved; /**< Number of reserved DMA queues */
+ int queue_slots; /**< Actual length of queuelist */
+ drm_queue_t **queuelist; /**< Vector of pointers to DMA queues */
+ drm_device_dma_t *dma; /**< Optional pointer for DMA support */
+ /*@}*/
+
+ /** \name Context support */
+ /*@{*/
+ int irq; /**< Interrupt used by board */
+ int irq_enabled; /**< True if irq handler is enabled */
+ __volatile__ long context_flag; /**< Context swapping flag */
+ __volatile__ long interrupt_flag; /**< Interruption handler flag */
+ __volatile__ long dma_flag; /**< DMA dispatch flag */
+ struct timer_list timer; /**< Timer for delaying ctx switch */
+ wait_queue_head_t context_wait; /**< Processes waiting on ctx switch */
+ int last_checked; /**< Last context checked for DMA */
+ int last_context; /**< Last current context */
+ unsigned long last_switch; /**< jiffies at last context switch */
+ /*@}*/
+
+#if !HAS_WORKQUEUE
struct tq_struct tq;
+#else
+ struct work_struct work;
+#endif
+ /** \name VBLANK IRQ support */
+ /*@{*/
#if __HAVE_VBL_IRQ
- wait_queue_head_t vbl_queue;
+ wait_queue_head_t vbl_queue; /**< VBLANK wait queue */
atomic_t vbl_received;
spinlock_t vbl_lock;
- drm_vbl_sig_t vbl_sigs;
+ drm_vbl_sig_t vbl_sigs; /**< signal list to send on VBLANK */
unsigned int vbl_pending;
#endif
+ /*@}*/
cycles_t ctx_start;
cycles_t lck_start;
-#if __HAVE_DMA_HISTOGRAM
- drm_histogram_t histo;
-#endif
- /* Callback to X server for context switch
- and for heavy-handed reset. */
- char buf[DRM_BSZ]; /* Output buffer */
- char *buf_rp; /* Read pointer */
- char *buf_wp; /* Write pointer */
- char *buf_end; /* End pointer */
- struct fasync_struct *buf_async;/* Processes waiting for SIGIO */
- wait_queue_head_t buf_readers; /* Processes waiting to read */
- wait_queue_head_t buf_writers; /* Processes waiting to ctx switch */
+ char buf[DRM_BSZ]; /**< Output buffer */
+ char *buf_rp; /**< Read pointer */
+ char *buf_wp; /**< Write pointer */
+ char *buf_end; /**< End pointer */
+ struct fasync_struct *buf_async;/**< Processes waiting for SIGIO */
+ wait_queue_head_t buf_readers; /**< Processes waiting to read */
+ wait_queue_head_t buf_writers; /**< Processes waiting to ctx switch */
#if __REALLY_HAVE_AGP
- drm_agp_head_t *agp;
+ drm_agp_head_t *agp; /**< AGP data */
#endif
- struct pci_dev *pdev;
+
+ struct pci_dev *pdev; /**< PCI device structure */
+ int pci_domain; /**< PCI bus domain number */
+ int pci_bus; /**< PCI bus number */
+ int pci_slot; /**< PCI slot number */
+ int pci_func; /**< PCI function number */
#ifdef __alpha__
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3)
struct pci_controler *hose;
@@ -627,17 +794,17 @@ typedef struct drm_device {
struct pci_controller *hose;
#endif
#endif
- drm_sg_mem_t *sg; /* Scatter gather memory */
- unsigned long *ctx_bitmap;
- void *dev_private;
- drm_sigdata_t sigdata; /* For block_all_signals */
+ drm_sg_mem_t *sg; /**< Scatter gather memory */
+ unsigned long *ctx_bitmap; /**< context bitmap */
+ void *dev_private; /**< device private data */
+ drm_sigdata_t sigdata; /**< For block_all_signals */
sigset_t sigmask;
} drm_device_t;
-/* ================================================================
- * Internal function definitions
- */
+/******************************************************************/
+/** \name Internal function definitions */
+/*@{*/
/* Misc. support (drm_init.h) */
extern int DRM(flags);
@@ -660,61 +827,45 @@ extern int DRM(unlock)(struct inode *inode, struct file *filp,
extern int DRM(open_helper)(struct inode *inode, struct file *filp,
drm_device_t *dev);
extern int DRM(flush)(struct file *filp);
-extern int DRM(release_fuck)(struct inode *inode, struct file *filp);
extern int DRM(fasync)(int fd, struct file *filp, int on);
-extern ssize_t DRM(read)(struct file *filp, char *buf, size_t count,
- loff_t *off);
-extern int DRM(write_string)(drm_device_t *dev, const char *s);
-extern unsigned int DRM(poll)(struct file *filp,
- struct poll_table_struct *wait);
/* Mapping support (drm_vm.h) */
-extern struct page *DRM(vm_nopage)(struct vm_area_struct *vma,
- unsigned long address,
- int write_access);
-extern struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
- unsigned long address,
- int write_access);
-extern struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma,
- unsigned long address,
- int write_access);
-extern struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma,
- unsigned long address,
- int write_access);
extern void DRM(vm_open)(struct vm_area_struct *vma);
extern void DRM(vm_close)(struct vm_area_struct *vma);
extern void DRM(vm_shm_close)(struct vm_area_struct *vma);
extern int DRM(mmap_dma)(struct file *filp,
struct vm_area_struct *vma);
extern int DRM(mmap)(struct file *filp, struct vm_area_struct *vma);
+extern unsigned int DRM(poll)(struct file *filp, struct poll_table_struct *wait);
+extern ssize_t DRM(read)(struct file *filp, char *buf, size_t count, loff_t *off);
/* Memory management support (drm_memory.h) */
extern void DRM(mem_init)(void);
extern int DRM(mem_info)(char *buf, char **start, off_t offset,
int request, int *eof, void *data);
extern void *DRM(alloc)(size_t size, int area);
+extern void *DRM(calloc)(size_t nmemb, size_t size, int area);
extern void *DRM(realloc)(void *oldpt, size_t oldsize, size_t size,
int area);
-extern char *DRM(strdup)(const char *s, int area);
-extern void DRM(strfree)(const char *s, int area);
extern void DRM(free)(void *pt, size_t size, int area);
extern unsigned long DRM(alloc_pages)(int order, int area);
extern void DRM(free_pages)(unsigned long address, int order,
int area);
-extern void *DRM(ioremap)(unsigned long offset, unsigned long size);
-extern void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size);
-extern void DRM(ioremapfree)(void *pt, unsigned long size);
+extern void *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev);
+extern void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size,
+ drm_device_t *dev);
+extern void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev);
#if __REALLY_HAVE_AGP
-extern agp_memory *DRM(alloc_agp)(int pages, u32 type);
-extern int DRM(free_agp)(agp_memory *handle, int pages);
-extern int DRM(bind_agp)(agp_memory *handle, unsigned int start);
-extern int DRM(unbind_agp)(agp_memory *handle);
+extern DRM_AGP_MEM *DRM(alloc_agp)(int pages, u32 type);
+extern int DRM(free_agp)(DRM_AGP_MEM *handle, int pages);
+extern int DRM(bind_agp)(DRM_AGP_MEM *handle, unsigned int start);
+extern int DRM(unbind_agp)(DRM_AGP_MEM *handle);
#endif
/* Misc. IOCTL support (drm_ioctl.h) */
-extern int DRM(irq_busid)(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
+extern int DRM(irq_by_busid)(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
extern int DRM(getunique)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int DRM(setunique)(struct inode *inode, struct file *filp,
@@ -725,6 +876,8 @@ extern int DRM(getclient)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int DRM(getstats)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
+extern int DRM(setversion)(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
/* Context IOCTL support (drm_context.h) */
extern int DRM(resctx)( struct inode *inode, struct file *filp,
@@ -771,12 +924,11 @@ extern int DRM(getmagic)(struct inode *inode, struct file *filp,
extern int DRM(authmagic)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
+ /* Placeholder for ioctls past */
+extern int DRM(noop)(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
/* Locking IOCTL support (drm_lock.h) */
-extern int DRM(block)(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int DRM(unblock)(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
extern int DRM(lock_take)(__volatile__ unsigned int *lock,
unsigned int context);
extern int DRM(lock_transfer)(drm_device_t *dev,
@@ -785,12 +937,6 @@ extern int DRM(lock_transfer)(drm_device_t *dev,
extern int DRM(lock_free)(drm_device_t *dev,
__volatile__ unsigned int *lock,
unsigned int context);
-extern int DRM(finish)(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int DRM(flush_unblock)(drm_device_t *dev, int context,
- drm_lock_flags_t flags);
-extern int DRM(flush_block_and_flush)(drm_device_t *dev, int context,
- drm_lock_flags_t flags);
extern int DRM(notifier)(void *priv);
/* Buffer management support (drm_bufs.h) */
@@ -815,23 +961,18 @@ extern int DRM(mapbufs)( struct inode *inode, struct file *filp,
extern int DRM(dma_setup)(drm_device_t *dev);
extern void DRM(dma_takedown)(drm_device_t *dev);
extern void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf);
-extern void DRM(reclaim_buffers)(drm_device_t *dev, pid_t pid);
-#if __HAVE_OLD_DMA
-/* GH: This is a dirty hack for now...
- */
-extern void DRM(clear_next_buffer)(drm_device_t *dev);
-extern int DRM(select_queue)(drm_device_t *dev,
- void (*wrapper)(unsigned long));
-extern int DRM(dma_enqueue)(drm_device_t *dev, drm_dma_t *dma);
-extern int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma);
-#endif
-#if __HAVE_DMA_IRQ
+extern void DRM(reclaim_buffers)( struct file *filp );
+#endif /* __HAVE_DMA */
+
+ /* IRQ support (drm_irq.h) */
+#if __HAVE_IRQ || __HAVE_DMA
extern int DRM(control)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
-extern int DRM(irq_install)( drm_device_t *dev, int irq );
+#endif
+#if __HAVE_IRQ
+extern int DRM(irq_install)( drm_device_t *dev );
extern int DRM(irq_uninstall)( drm_device_t *dev );
-extern void DRM(dma_service)( int irq, void *device,
- struct pt_regs *regs );
+extern irqreturn_t DRM(irq_handler)( DRM_IRQ_ARGS );
extern void DRM(driver_irq_preinstall)( drm_device_t *dev );
extern void DRM(driver_irq_postinstall)( drm_device_t *dev );
extern void DRM(driver_irq_uninstall)( drm_device_t *dev );
@@ -841,30 +982,11 @@ extern int DRM(wait_vblank)(struct inode *inode, struct file *filp,
extern int DRM(vblank_wait)(drm_device_t *dev, unsigned int *vbl_seq);
extern void DRM(vbl_send_signals)( drm_device_t *dev );
#endif
-#if __HAVE_DMA_IRQ_BH
-extern void DRM(dma_immediate_bh)( void *dev );
-#endif
+#if __HAVE_IRQ_BH
+extern void DRM(irq_immediate_bh)( void *dev );
#endif
-#if DRM_DMA_HISTOGRAM
-extern int DRM(histogram_slot)(unsigned long count);
-extern void DRM(histogram_compute)(drm_device_t *dev, drm_buf_t *buf);
#endif
- /* Buffer list support (drm_lists.h) */
-#if __HAVE_DMA_WAITLIST
-extern int DRM(waitlist_create)(drm_waitlist_t *bl, int count);
-extern int DRM(waitlist_destroy)(drm_waitlist_t *bl);
-extern int DRM(waitlist_put)(drm_waitlist_t *bl, drm_buf_t *buf);
-extern drm_buf_t *DRM(waitlist_get)(drm_waitlist_t *bl);
-#endif
-#if __HAVE_DMA_FREELIST
-extern int DRM(freelist_create)(drm_freelist_t *bl, int count);
-extern int DRM(freelist_destroy)(drm_freelist_t *bl);
-extern int DRM(freelist_put)(drm_device_t *dev, drm_freelist_t *bl,
- drm_buf_t *buf);
-extern drm_buf_t *DRM(freelist_get)(drm_freelist_t *bl, int block);
-#endif
-#endif /* __HAVE_DMA */
#if __REALLY_HAVE_AGP
/* AGP/GART support (drm_agpsupport.h) */
@@ -887,10 +1009,10 @@ extern int DRM(agp_unbind)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int DRM(agp_bind)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
-extern agp_memory *DRM(agp_allocate_memory)(size_t pages, u32 type);
-extern int DRM(agp_free_memory)(agp_memory *handle);
-extern int DRM(agp_bind_memory)(agp_memory *handle, off_t start);
-extern int DRM(agp_unbind_memory)(agp_memory *handle);
+extern DRM_AGP_MEM *DRM(agp_allocate_memory)(size_t pages, u32 type);
+extern int DRM(agp_free_memory)(DRM_AGP_MEM *handle);
+extern int DRM(agp_bind_memory)(DRM_AGP_MEM *handle, off_t start);
+extern int DRM(agp_unbind_memory)(DRM_AGP_MEM *handle);
#endif
/* Stub support (drm_stub.h) */
@@ -925,5 +1047,7 @@ extern int DRM(ati_pcigart_cleanup)(drm_device_t *dev,
unsigned long addr,
dma_addr_t bus_addr);
+/*@}*/
+
#endif /* __KERNEL__ */
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_agpsupport.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_agpsupport.h
index 35dd866ff..f83651af8 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_agpsupport.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_agpsupport.h
@@ -1,6 +1,12 @@
-/* drm_agpsupport.h -- DRM support for AGP/GART backend -*- linux-c -*-
- * Created: Mon Dec 13 09:56:45 1999 by faith@precisioninsight.com
- *
+/**
+ * \file drm_agpsupport.h
+ * DRM support for AGP/GART backend
+ *
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
@@ -23,10 +29,6 @@
* 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.
- *
- * Author:
- * Rickard E. (Rik) Faith <faith@valinux.com>
- * Gareth Hughes <gareth@valinux.com>
*/
#define __NO_VERSION__
@@ -35,17 +37,33 @@
#if __REALLY_HAVE_AGP
+
#define DRM_AGP_GET (drm_agp_t *)inter_module_get("drm_agp")
#define DRM_AGP_PUT inter_module_put("drm_agp")
+/**
+ * Pointer to the drm_agp_t structure made available by the agpgart module.
+ */
static const drm_agp_t *drm_agp = NULL;
+/**
+ * AGP information ioctl.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a (output) drm_agp_info structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Verifies the AGP device has been initialized and acquired and fills in the
+ * drm_agp_info structure with the information in drm_agp_head::agp_info.
+ */
int DRM(agp_info)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
- agp_kern_info *kern;
+ DRM_AGP_KERN *kern;
drm_agp_info_t info;
if (!dev->agp || !dev->agp->acquired || !drm_agp->copy_info)
@@ -67,6 +85,18 @@ int DRM(agp_info)(struct inode *inode, struct file *filp,
return 0;
}
+/**
+ * Acquire the AGP device (ioctl).
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument.
+ * \return zero on success or a negative number on failure.
+ *
+ * Verifies the AGP device hasn't been acquired before and calls
+ * drm_agp->acquire().
+ */
int DRM(agp_acquire)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
@@ -74,13 +104,33 @@ int DRM(agp_acquire)(struct inode *inode, struct file *filp,
drm_device_t *dev = priv->dev;
int retcode;
- if (!dev->agp || dev->agp->acquired || !drm_agp->acquire)
+ if (!dev->agp)
+ return -ENODEV;
+ if (dev->agp->acquired)
+ return -EBUSY;
+ if (!drm_agp->acquire)
+ return -EINVAL;
+#ifndef VMAP_4_ARGS
+ if ( dev->agp->cant_use_aperture )
return -EINVAL;
- if ((retcode = drm_agp->acquire())) return retcode;
+#endif
+ if ((retcode = drm_agp->acquire()))
+ return retcode;
dev->agp->acquired = 1;
return 0;
}
+/**
+ * Release the AGP device (ioctl).
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument.
+ * \return zero on success or a negative number on failure.
+ *
+ * Verifies the AGP device has been acquired and calls drm_agp->release().
+ */
int DRM(agp_release)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
@@ -95,11 +145,29 @@ int DRM(agp_release)(struct inode *inode, struct file *filp,
}
+/**
+ * Release the AGP device.
+ *
+ * Calls drm_agp->release().
+ */
void DRM(agp_do_release)(void)
{
- if (drm_agp->release) drm_agp->release();
+ if (drm_agp->release)
+ drm_agp->release();
}
+/**
+ * Enable the AGP bus.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_agp_mode structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Verifies the AGP device has been acquired but not enabled, and calls
+ * drm_agp->enable().
+ */
int DRM(agp_enable)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
@@ -120,6 +188,18 @@ int DRM(agp_enable)(struct inode *inode, struct file *filp,
return 0;
}
+/**
+ * Allocate AGP memory.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_agp_buffer structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Verifies the AGP device is present and has been acquired, allocates the
+ * memory via alloc_agp() and creates a drm_agp_mem entry for it.
+ */
int DRM(agp_alloc)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
@@ -127,11 +207,12 @@ int DRM(agp_alloc)(struct inode *inode, struct file *filp,
drm_device_t *dev = priv->dev;
drm_agp_buffer_t request;
drm_agp_mem_t *entry;
- agp_memory *memory;
+ DRM_AGP_MEM *memory;
unsigned long pages;
u32 type;
- if (!dev->agp || !dev->agp->acquired) return -EINVAL;
+ if (!dev->agp || !dev->agp->acquired)
+ return -EINVAL;
if (copy_from_user(&request, (drm_agp_buffer_t *)arg, sizeof(request)))
return -EFAULT;
if (!(entry = DRM(alloc)(sizeof(*entry), DRM_MEM_AGPLISTS)))
@@ -147,17 +228,18 @@ int DRM(agp_alloc)(struct inode *inode, struct file *filp,
return -ENOMEM;
}
- entry->handle = (unsigned long)memory->memory;
+ entry->handle = (unsigned long)memory->key + 1;
entry->memory = memory;
entry->bound = 0;
entry->pages = pages;
entry->prev = NULL;
entry->next = dev->agp->memory;
- if (dev->agp->memory) dev->agp->memory->prev = entry;
+ if (dev->agp->memory)
+ dev->agp->memory->prev = entry;
dev->agp->memory = entry;
request.handle = entry->handle;
- request.physical = memory->physical;
+ request.physical = memory->physical;
if (copy_to_user((drm_agp_buffer_t *)arg, &request, sizeof(request))) {
dev->agp->memory = entry->next;
@@ -169,17 +251,39 @@ int DRM(agp_alloc)(struct inode *inode, struct file *filp,
return 0;
}
+/**
+ * Search for the AGP memory entry associated with a handle.
+ *
+ * \param dev DRM device structure.
+ * \param handle AGP memory handle.
+ * \return pointer to the drm_agp_mem structure associated with \p handle.
+ *
+ * Walks through drm_agp_head::memory until finding a matching handle.
+ */
static drm_agp_mem_t *DRM(agp_lookup_entry)(drm_device_t *dev,
unsigned long handle)
{
drm_agp_mem_t *entry;
for (entry = dev->agp->memory; entry; entry = entry->next) {
- if (entry->handle == handle) return entry;
+ if (entry->handle == handle)
+ return entry;
}
return NULL;
}
+/**
+ * Unbind AGP memory from the GATT (ioctl).
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_agp_binding structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Verifies the AGP device is present and acquired, looks-up the AGP memory
+ * entry and passes it to the unbind_agp() function.
+ */
int DRM(agp_unbind)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
@@ -187,16 +291,35 @@ int DRM(agp_unbind)(struct inode *inode, struct file *filp,
drm_device_t *dev = priv->dev;
drm_agp_binding_t request;
drm_agp_mem_t *entry;
+ int ret;
- if (!dev->agp || !dev->agp->acquired) return -EINVAL;
+ if (!dev->agp || !dev->agp->acquired)
+ return -EINVAL;
if (copy_from_user(&request, (drm_agp_binding_t *)arg, sizeof(request)))
return -EFAULT;
if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
return -EINVAL;
- if (!entry->bound) return -EINVAL;
- return DRM(unbind_agp)(entry->memory);
+ if (!entry->bound)
+ return -EINVAL;
+ ret = DRM(unbind_agp)(entry->memory);
+ if (ret == 0)
+ entry->bound = 0;
+ return ret;
}
+/**
+ * Bind AGP memory into the GATT (ioctl)
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_agp_binding structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Verifies the AGP device is present and has been acquired and that no memory
+ * is currently bound into the GATT. Looks-up the AGP memory entry and passes
+ * it to bind_agp() function.
+ */
int DRM(agp_bind)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
@@ -213,15 +336,31 @@ int DRM(agp_bind)(struct inode *inode, struct file *filp,
return -EFAULT;
if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
return -EINVAL;
- if (entry->bound) return -EINVAL;
+ if (entry->bound)
+ return -EINVAL;
page = (request.offset + PAGE_SIZE - 1) / PAGE_SIZE;
- if ((retcode = DRM(bind_agp)(entry->memory, page))) return retcode;
+ if ((retcode = DRM(bind_agp)(entry->memory, page)))
+ return retcode;
entry->bound = dev->agp->base + (page << PAGE_SHIFT);
DRM_DEBUG("base = 0x%lx entry->bound = 0x%lx\n",
dev->agp->base, entry->bound);
return 0;
}
+/**
+ * Free AGP memory (ioctl).
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_agp_buffer structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Verifies the AGP device is present and has been acquired and looks up the
+ * AGP memory entry. If the memory it's currently bound, unbind it via
+ * unbind_agp(). Frees it via free_agp() as well as the entry itself
+ * and unlinks from the doubly linked list it's inserted in.
+ */
int DRM(agp_free)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
@@ -230,21 +369,37 @@ int DRM(agp_free)(struct inode *inode, struct file *filp,
drm_agp_buffer_t request;
drm_agp_mem_t *entry;
- if (!dev->agp || !dev->agp->acquired) return -EINVAL;
+ if (!dev->agp || !dev->agp->acquired)
+ return -EINVAL;
if (copy_from_user(&request, (drm_agp_buffer_t *)arg, sizeof(request)))
return -EFAULT;
if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
return -EINVAL;
- if (entry->bound) DRM(unbind_agp)(entry->memory);
+ if (entry->bound)
+ DRM(unbind_agp)(entry->memory);
+
+ if (entry->prev)
+ entry->prev->next = entry->next;
+ else
+ dev->agp->memory = entry->next;
+
+ if (entry->next)
+ entry->next->prev = entry->prev;
- if (entry->prev) entry->prev->next = entry->next;
- else dev->agp->memory = entry->next;
- if (entry->next) entry->next->prev = entry->prev;
DRM(free_agp)(entry->memory, entry->pages);
DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
return 0;
}
+/**
+ * Initialize the AGP resources.
+ *
+ * \return pointer to a drm_agp_head structure.
+ *
+ * Gets the drm_agp_t structure which is made available by the agpgart module
+ * via the inter_module_* functions. Creates and initializes a drm_agp_head
+ * structure.
+ */
drm_agp_head_t *DRM(agp_init)(void)
{
drm_agp_head_t *head = NULL;
@@ -267,44 +422,51 @@ drm_agp_head_t *DRM(agp_init)(void)
head->cant_use_aperture = head->agp_info.cant_use_aperture;
head->page_mask = head->agp_info.page_mask;
#endif
-
- DRM_INFO("AGP %d.%d aperture @ 0x%08lx %ZuMB\n",
- head->agp_info.version.major,
- head->agp_info.version.minor,
- head->agp_info.aper_base,
- head->agp_info.aper_size);
}
return head;
}
+/**
+ * Free the AGP resources.
+ *
+ * Releases the pointer in ::drm_agp.
+ */
void DRM(agp_uninit)(void)
{
DRM_AGP_PUT;
drm_agp = NULL;
}
-agp_memory *DRM(agp_allocate_memory)(size_t pages, u32 type)
+/** Calls drm_agp->allocate_memory() */
+DRM_AGP_MEM *DRM(agp_allocate_memory)(size_t pages, u32 type)
{
- if (!drm_agp->allocate_memory) return NULL;
+ if (!drm_agp->allocate_memory)
+ return NULL;
return drm_agp->allocate_memory(pages, type);
}
-int DRM(agp_free_memory)(agp_memory *handle)
+/** Calls drm_agp->free_memory() */
+int DRM(agp_free_memory)(DRM_AGP_MEM *handle)
{
- if (!handle || !drm_agp->free_memory) return 0;
+ if (!handle || !drm_agp->free_memory)
+ return 0;
drm_agp->free_memory(handle);
return 1;
}
-int DRM(agp_bind_memory)(agp_memory *handle, off_t start)
+/** Calls drm_agp->bind_memory() */
+int DRM(agp_bind_memory)(DRM_AGP_MEM *handle, off_t start)
{
- if (!handle || !drm_agp->bind_memory) return -EINVAL;
+ if (!handle || !drm_agp->bind_memory)
+ return -EINVAL;
return drm_agp->bind_memory(handle, start);
}
-int DRM(agp_unbind_memory)(agp_memory *handle)
+/** Calls drm_agp->unbind_memory() */
+int DRM(agp_unbind_memory)(DRM_AGP_MEM *handle)
{
- if (!handle || !drm_agp->unbind_memory) return -EINVAL;
+ if (!handle || !drm_agp->unbind_memory)
+ return -EINVAL;
return drm_agp->unbind_memory(handle);
}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_context.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_context.h
index 39267b14b..474b5ba01 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_context.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_context.h
@@ -1,4 +1,12 @@
-/* drm_context.h -- IOCTLs for generic contexts -*- linux-c -*-
+/**
+ * \file drm_context.h
+ * IOCTLs for generic contexts
+ *
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
* Created: Fri Nov 24 18:31:37 2000 by gareth@valinux.com
*
* Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
@@ -23,10 +31,9 @@
* 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.
- *
- * Authors:
- * Rickard E. (Rik) Faith <faith@valinux.com>
- * Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
* ChangeLog:
* 2001-11-16 Torsten Duwe <duwe@caldera.de>
* added context constructor/destructor hooks,
@@ -36,12 +43,25 @@
#define __NO_VERSION__
#include "drmP.h"
-#if __HAVE_CTX_BITMAP
+#if !__HAVE_CTX_BITMAP
+#error "__HAVE_CTX_BITMAP must be defined"
+#endif
-/* ================================================================
- * Context bitmap support
- */
+/******************************************************************/
+/** \name Context bitmap support */
+/*@{*/
+
+/**
+ * Free a handle from the context bitmap.
+ *
+ * \param dev DRM device.
+ * \param ctx_handle context handle.
+ *
+ * Clears the bit specified by \p ctx_handle in drm_device::ctx_bitmap and the entry
+ * in drm_device::context_sareas, while holding the drm_device::struct_sem
+ * lock.
+ */
void DRM(ctxbitmap_free)( drm_device_t *dev, int ctx_handle )
{
if ( ctx_handle < 0 ) goto failed;
@@ -60,6 +80,16 @@ failed:
return;
}
+/**
+ * Context bitmap allocation.
+ *
+ * \param dev DRM device.
+ * \return (non-negative) context handle on success or a negative number on failure.
+ *
+ * Find the first zero bit in drm_device::ctx_bitmap and (re)allocates
+ * drm_device::context_sareas to accommodate the new entry while holding the
+ * drm_device::struct_sem lock.
+ */
int DRM(ctxbitmap_next)( drm_device_t *dev )
{
int bit;
@@ -110,6 +140,14 @@ int DRM(ctxbitmap_next)( drm_device_t *dev )
return -1;
}
+/**
+ * Context bitmap initialization.
+ *
+ * \param dev DRM device.
+ *
+ * Allocates and initialize drm_device::ctx_bitmap and drm_device::context_sareas, while holding
+ * the drm_device::struct_sem lock.
+ */
int DRM(ctxbitmap_init)( drm_device_t *dev )
{
int i;
@@ -135,6 +173,14 @@ int DRM(ctxbitmap_init)( drm_device_t *dev )
return 0;
}
+/**
+ * Context bitmap cleanup.
+ *
+ * \param dev DRM device.
+ *
+ * Frees drm_device::ctx_bitmap and drm_device::context_sareas, while holding
+ * the drm_device::struct_sem lock.
+ */
void DRM(ctxbitmap_cleanup)( drm_device_t *dev )
{
down(&dev->struct_sem);
@@ -146,10 +192,24 @@ void DRM(ctxbitmap_cleanup)( drm_device_t *dev )
up(&dev->struct_sem);
}
-/* ================================================================
- * Per Context SAREA Support
- */
+/*@}*/
+/******************************************************************/
+/** \name Per Context SAREA Support */
+/*@{*/
+
+/**
+ * Get per-context SAREA.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument pointing to a drm_ctx_priv_map structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Gets the map from drm_device::context_sareas with the handle specified and
+ * returns its handle.
+ */
int DRM(getsareactx)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
@@ -178,6 +238,18 @@ int DRM(getsareactx)(struct inode *inode, struct file *filp,
return 0;
}
+/**
+ * Set per-context SAREA.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument pointing to a drm_ctx_priv_map structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Searches the mapping specified in \p arg and update the entry in
+ * drm_device::context_sareas with it.
+ */
int DRM(setsareactx)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
@@ -195,7 +267,7 @@ int DRM(setsareactx)(struct inode *inode, struct file *filp,
down(&dev->struct_sem);
list_for_each(list, &dev->maplist->head) {
- r_list = (drm_map_list_t *)list;
+ r_list = list_entry(list, drm_map_list_t, head);
if(r_list->map &&
r_list->map->handle == request.handle)
goto found;
@@ -216,22 +288,29 @@ found:
return 0;
}
-/* ================================================================
- * The actual DRM context handling routines
- */
+/*@}*/
+/******************************************************************/
+/** \name The actual DRM context handling routines */
+/*@{*/
+
+/**
+ * Switch context.
+ *
+ * \param dev DRM device.
+ * \param old old context handle.
+ * \param new new context handle.
+ * \return zero on success or a negative number on failure.
+ *
+ * Attempt to set drm_device::context_flag.
+ */
int DRM(context_switch)( drm_device_t *dev, int old, int new )
{
- char buf[64];
-
if ( test_and_set_bit( 0, &dev->context_flag ) ) {
DRM_ERROR( "Reentering -- FIXME\n" );
return -EBUSY;
}
-#if __HAVE_DMA_HISTOGRAM
- dev->ctx_start = get_cycles();
-#endif
DRM_DEBUG( "Context switch from %d to %d\n", old, new );
@@ -240,16 +319,20 @@ int DRM(context_switch)( drm_device_t *dev, int old, int new )
return 0;
}
- if ( DRM(flags) & DRM_FLAG_NOCTX ) {
- DRM(context_switch_complete)( dev, new );
- } else {
- sprintf( buf, "C %d %d\n", old, new );
- DRM(write_string)( dev, buf );
- }
-
return 0;
}
+/**
+ * Complete context switch.
+ *
+ * \param dev DRM device.
+ * \param new new context handle.
+ * \return zero on success or a negative number on failure.
+ *
+ * Updates drm_device::last_context and drm_device::last_switch. Verifies the
+ * hardware lock is held, clears the drm_device::context_flag and wakes up
+ * drm_device::context_wait.
+ */
int DRM(context_switch_complete)( drm_device_t *dev, int new )
{
dev->last_context = new; /* PRE/POST: This is the _only_ writer. */
@@ -262,17 +345,21 @@ int DRM(context_switch_complete)( drm_device_t *dev, int new )
/* If a context switch is ever initiated
when the kernel holds the lock, release
that lock here. */
-#if __HAVE_DMA_HISTOGRAM
- atomic_inc( &dev->histo.ctx[DRM(histogram_slot)(get_cycles()
- - dev->ctx_start)] );
-
-#endif
clear_bit( 0, &dev->context_flag );
wake_up( &dev->context_wait );
return 0;
}
+/**
+ * Reserve contexts.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument pointing to a drm_ctx_res structure.
+ * \return zero on success or a negative number on failure.
+ */
int DRM(resctx)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
@@ -299,11 +386,23 @@ int DRM(resctx)( struct inode *inode, struct file *filp,
return 0;
}
+/**
+ * Add context.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument pointing to a drm_ctx structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Get a new handle for the context and copy to userspace.
+ */
int DRM(addctx)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
+ drm_ctx_list_t * ctx_entry;
drm_ctx_t ctx;
if ( copy_from_user( &ctx, (drm_ctx_t *)arg, sizeof(ctx) ) )
@@ -324,6 +423,20 @@ int DRM(addctx)( struct inode *inode, struct file *filp,
if ( ctx.handle != DRM_KERNEL_CONTEXT )
DRIVER_CTX_CTOR(ctx.handle); /* XXX: also pass dev ? */
#endif
+ ctx_entry = DRM(alloc)( sizeof(*ctx_entry), DRM_MEM_CTXLIST );
+ if ( !ctx_entry ) {
+ DRM_DEBUG("out of memory\n");
+ return -ENOMEM;
+ }
+
+ INIT_LIST_HEAD( &ctx_entry->head );
+ ctx_entry->handle = ctx.handle;
+ ctx_entry->tag = priv;
+
+ down( &dev->ctxlist_sem );
+ list_add( &ctx_entry->head, &dev->ctxlist->head );
+ ++dev->ctx_count;
+ up( &dev->ctxlist_sem );
if ( copy_to_user( (drm_ctx_t *)arg, &ctx, sizeof(ctx) ) )
return -EFAULT;
@@ -337,6 +450,15 @@ int DRM(modctx)( struct inode *inode, struct file *filp,
return 0;
}
+/**
+ * Get context.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument pointing to a drm_ctx structure.
+ * \return zero on success or a negative number on failure.
+ */
int DRM(getctx)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
@@ -353,6 +475,17 @@ int DRM(getctx)( struct inode *inode, struct file *filp,
return 0;
}
+/**
+ * Switch context.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument pointing to a drm_ctx structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Calls context_switch().
+ */
int DRM(switchctx)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
@@ -367,6 +500,17 @@ int DRM(switchctx)( struct inode *inode, struct file *filp,
return DRM(context_switch)( dev, dev->last_context, ctx.handle );
}
+/**
+ * New context.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument pointing to a drm_ctx structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Calls context_switch_complete().
+ */
int DRM(newctx)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
@@ -383,6 +527,17 @@ int DRM(newctx)( struct inode *inode, struct file *filp,
return 0;
}
+/**
+ * Remove context.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument pointing to a drm_ctx structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * If not the special kernel context, calls ctxbitmap_free() to free the specified context.
+ */
int DRM(rmctx)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
@@ -404,378 +559,21 @@ int DRM(rmctx)( struct inode *inode, struct file *filp,
DRM(ctxbitmap_free)( dev, ctx.handle );
}
- return 0;
-}
-
-
-#else /* __HAVE_CTX_BITMAP */
-
-/* ================================================================
- * Old-style context support
- */
-
+ down( &dev->ctxlist_sem );
+ if ( !list_empty( &dev->ctxlist->head ) ) {
+ drm_ctx_list_t *pos, *n;
-int DRM(context_switch)(drm_device_t *dev, int old, int new)
-{
- char buf[64];
- drm_queue_t *q;
-
-#if 0
- atomic_inc(&dev->total_ctx);
-#endif
-
- if (test_and_set_bit(0, &dev->context_flag)) {
- DRM_ERROR("Reentering -- FIXME\n");
- return -EBUSY;
- }
-
-#if __HAVE_DMA_HISTOGRAM
- dev->ctx_start = get_cycles();
-#endif
-
- DRM_DEBUG("Context switch from %d to %d\n", old, new);
-
- if (new >= dev->queue_count) {
- clear_bit(0, &dev->context_flag);
- return -EINVAL;
- }
-
- if (new == dev->last_context) {
- clear_bit(0, &dev->context_flag);
- return 0;
- }
-
- q = dev->queuelist[new];
- atomic_inc(&q->use_count);
- if (atomic_read(&q->use_count) == 1) {
- atomic_dec(&q->use_count);
- clear_bit(0, &dev->context_flag);
- return -EINVAL;
- }
-
- if (DRM(flags) & DRM_FLAG_NOCTX) {
- DRM(context_switch_complete)(dev, new);
- } else {
- sprintf(buf, "C %d %d\n", old, new);
- DRM(write_string)(dev, buf);
- }
-
- atomic_dec(&q->use_count);
-
- return 0;
-}
-
-int DRM(context_switch_complete)(drm_device_t *dev, int new)
-{
- drm_device_dma_t *dma = dev->dma;
-
- dev->last_context = new; /* PRE/POST: This is the _only_ writer. */
- dev->last_switch = jiffies;
-
- if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
- DRM_ERROR("Lock isn't held after context switch\n");
- }
-
- if (!dma || !(dma->next_buffer && dma->next_buffer->while_locked)) {
- if (DRM(lock_free)(dev, &dev->lock.hw_lock->lock,
- DRM_KERNEL_CONTEXT)) {
- DRM_ERROR("Cannot free lock\n");
- }
- }
-
-#if __HAVE_DMA_HISTOGRAM
- atomic_inc(&dev->histo.ctx[DRM(histogram_slot)(get_cycles()
- - dev->ctx_start)]);
-
-#endif
- clear_bit(0, &dev->context_flag);
- wake_up_interruptible(&dev->context_wait);
-
- return 0;
-}
-
-static int DRM(init_queue)(drm_device_t *dev, drm_queue_t *q, drm_ctx_t *ctx)
-{
- DRM_DEBUG("\n");
-
- if (atomic_read(&q->use_count) != 1
- || atomic_read(&q->finalization)
- || atomic_read(&q->block_count)) {
- DRM_ERROR("New queue is already in use: u%d f%d b%d\n",
- atomic_read(&q->use_count),
- atomic_read(&q->finalization),
- atomic_read(&q->block_count));
- }
-
- atomic_set(&q->finalization, 0);
- atomic_set(&q->block_count, 0);
- atomic_set(&q->block_read, 0);
- atomic_set(&q->block_write, 0);
- atomic_set(&q->total_queued, 0);
- atomic_set(&q->total_flushed, 0);
- atomic_set(&q->total_locks, 0);
-
- init_waitqueue_head(&q->write_queue);
- init_waitqueue_head(&q->read_queue);
- init_waitqueue_head(&q->flush_queue);
-
- q->flags = ctx->flags;
-
- DRM(waitlist_create)(&q->waitlist, dev->dma->buf_count);
-
- return 0;
-}
-
-
-/* drm_alloc_queue:
-PRE: 1) dev->queuelist[0..dev->queue_count] is allocated and will not
- disappear (so all deallocation must be done after IOCTLs are off)
- 2) dev->queue_count < dev->queue_slots
- 3) dev->queuelist[i].use_count == 0 and
- dev->queuelist[i].finalization == 0 if i not in use
-POST: 1) dev->queuelist[i].use_count == 1
- 2) dev->queue_count < dev->queue_slots */
-
-static int DRM(alloc_queue)(drm_device_t *dev)
-{
- int i;
- drm_queue_t *queue;
- int oldslots;
- int newslots;
- /* Check for a free queue */
- for (i = 0; i < dev->queue_count; i++) {
- atomic_inc(&dev->queuelist[i]->use_count);
- if (atomic_read(&dev->queuelist[i]->use_count) == 1
- && !atomic_read(&dev->queuelist[i]->finalization)) {
- DRM_DEBUG("%d (free)\n", i);
- return i;
- }
- atomic_dec(&dev->queuelist[i]->use_count);
- }
- /* Allocate a new queue */
- down(&dev->struct_sem);
-
- queue = DRM(alloc)(sizeof(*queue), DRM_MEM_QUEUES);
- memset(queue, 0, sizeof(*queue));
- atomic_set(&queue->use_count, 1);
-
- ++dev->queue_count;
- if (dev->queue_count >= dev->queue_slots) {
- oldslots = dev->queue_slots * sizeof(*dev->queuelist);
- if (!dev->queue_slots) dev->queue_slots = 1;
- dev->queue_slots *= 2;
- newslots = dev->queue_slots * sizeof(*dev->queuelist);
-
- dev->queuelist = DRM(realloc)(dev->queuelist,
- oldslots,
- newslots,
- DRM_MEM_QUEUES);
- if (!dev->queuelist) {
- up(&dev->struct_sem);
- DRM_DEBUG("out of memory\n");
- return -ENOMEM;
+ list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) {
+ if ( pos->handle == ctx.handle ) {
+ list_del( &pos->head );
+ DRM(free)( pos, sizeof(*pos), DRM_MEM_CTXLIST );
+ --dev->ctx_count;
+ }
}
}
- dev->queuelist[dev->queue_count-1] = queue;
-
- up(&dev->struct_sem);
- DRM_DEBUG("%d (new)\n", dev->queue_count - 1);
- return dev->queue_count - 1;
-}
-
-int DRM(resctx)(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
-{
- drm_ctx_res_t res;
- drm_ctx_t ctx;
- int i;
+ up( &dev->ctxlist_sem );
- DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
- if (copy_from_user(&res, (drm_ctx_res_t *)arg, sizeof(res)))
- return -EFAULT;
- if (res.count >= DRM_RESERVED_CONTEXTS) {
- memset(&ctx, 0, sizeof(ctx));
- for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
- ctx.handle = i;
- if (copy_to_user(&res.contexts[i],
- &i,
- sizeof(i)))
- return -EFAULT;
- }
- }
- res.count = DRM_RESERVED_CONTEXTS;
- if (copy_to_user((drm_ctx_res_t *)arg, &res, sizeof(res)))
- return -EFAULT;
- return 0;
-}
-
-int DRM(addctx)(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
-{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- drm_ctx_t ctx;
-
- if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
- return -EFAULT;
- if ((ctx.handle = DRM(alloc_queue)(dev)) == DRM_KERNEL_CONTEXT) {
- /* Init kernel's context and get a new one. */
- DRM(init_queue)(dev, dev->queuelist[ctx.handle], &ctx);
- ctx.handle = DRM(alloc_queue)(dev);
- }
- DRM(init_queue)(dev, dev->queuelist[ctx.handle], &ctx);
- DRM_DEBUG("%d\n", ctx.handle);
- if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx)))
- return -EFAULT;
- return 0;
-}
-
-int DRM(modctx)(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
-{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- drm_ctx_t ctx;
- drm_queue_t *q;
-
- if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
- return -EFAULT;
-
- DRM_DEBUG("%d\n", ctx.handle);
-
- if (ctx.handle < 0 || ctx.handle >= dev->queue_count) return -EINVAL;
- q = dev->queuelist[ctx.handle];
-
- atomic_inc(&q->use_count);
- if (atomic_read(&q->use_count) == 1) {
- /* No longer in use */
- atomic_dec(&q->use_count);
- return -EINVAL;
- }
-
- if (DRM_BUFCOUNT(&q->waitlist)) {
- atomic_dec(&q->use_count);
- return -EBUSY;
- }
-
- q->flags = ctx.flags;
-
- atomic_dec(&q->use_count);
- return 0;
-}
-
-int DRM(getctx)(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
-{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- drm_ctx_t ctx;
- drm_queue_t *q;
-
- if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
- return -EFAULT;
-
- DRM_DEBUG("%d\n", ctx.handle);
-
- if (ctx.handle >= dev->queue_count) return -EINVAL;
- q = dev->queuelist[ctx.handle];
-
- atomic_inc(&q->use_count);
- if (atomic_read(&q->use_count) == 1) {
- /* No longer in use */
- atomic_dec(&q->use_count);
- return -EINVAL;
- }
-
- ctx.flags = q->flags;
- atomic_dec(&q->use_count);
-
- if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx)))
- return -EFAULT;
-
- return 0;
-}
-
-int DRM(switchctx)(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
-{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- drm_ctx_t ctx;
-
- if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
- return -EFAULT;
- DRM_DEBUG("%d\n", ctx.handle);
- return DRM(context_switch)(dev, dev->last_context, ctx.handle);
-}
-
-int DRM(newctx)(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
-{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- drm_ctx_t ctx;
-
- if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
- return -EFAULT;
- DRM_DEBUG("%d\n", ctx.handle);
- DRM(context_switch_complete)(dev, ctx.handle);
-
- return 0;
-}
-
-int DRM(rmctx)(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
-{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- drm_ctx_t ctx;
- drm_queue_t *q;
- drm_buf_t *buf;
-
- if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
- return -EFAULT;
- DRM_DEBUG("%d\n", ctx.handle);
-
- if (ctx.handle >= dev->queue_count) return -EINVAL;
- q = dev->queuelist[ctx.handle];
-
- atomic_inc(&q->use_count);
- if (atomic_read(&q->use_count) == 1) {
- /* No longer in use */
- atomic_dec(&q->use_count);
- return -EINVAL;
- }
-
- atomic_inc(&q->finalization); /* Mark queue in finalization state */
- atomic_sub(2, &q->use_count); /* Mark queue as unused (pending
- finalization) */
-
- while (test_and_set_bit(0, &dev->interrupt_flag)) {
- schedule();
- if (signal_pending(current)) {
- clear_bit(0, &dev->interrupt_flag);
- return -EINTR;
- }
- }
- /* Remove queued buffers */
- while ((buf = DRM(waitlist_get)(&q->waitlist))) {
- DRM(free_buffer)(dev, buf);
- }
- clear_bit(0, &dev->interrupt_flag);
-
- /* Wakeup blocked processes */
- wake_up_interruptible(&q->read_queue);
- wake_up_interruptible(&q->write_queue);
- wake_up_interruptible(&q->flush_queue);
-
- /* Finalization over. Queue is made
- available when both use_count and
- finalization become 0, which won't
- happen until all the waiting processes
- stop waiting. */
- atomic_dec(&q->finalization);
return 0;
}
-#endif /* __HAVE_CTX_BITMAP */
+/*@}*/
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_drv.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_drv.h
index 41349e8c0..3eec29a0a 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_drv.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_drv.h
@@ -1,4 +1,31 @@
-/* drm_drv.h -- Generic driver template -*- linux-c -*-
+/**
+ * \file drm_drv.h
+ * Generic driver template
+ *
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ *
+ * To use this template, you must at least define the following (samples
+ * given for the MGA driver):
+ *
+ * \code
+ * #define DRIVER_AUTHOR "VA Linux Systems, Inc."
+ *
+ * #define DRIVER_NAME "mga"
+ * #define DRIVER_DESC "Matrox G200/G400"
+ * #define DRIVER_DATE "20001127"
+ *
+ * #define DRIVER_MAJOR 2
+ * #define DRIVER_MINOR 0
+ * #define DRIVER_PATCHLEVEL 2
+ *
+ * #define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( mga_ioctls )
+ *
+ * #define DRM(x) mga_##x
+ * \endcode
+ */
+
+/*
* Created: Thu Nov 23 03:10:50 2000 by gareth@valinux.com
*
* Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
@@ -23,29 +50,6 @@
* 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.
- *
- * Authors:
- * Rickard E. (Rik) Faith <faith@valinux.com>
- * Gareth Hughes <gareth@valinux.com>
- */
-
-/*
- * To use this template, you must at least define the following (samples
- * given for the MGA driver):
- *
- * #define DRIVER_AUTHOR "VA Linux Systems, Inc."
- *
- * #define DRIVER_NAME "mga"
- * #define DRIVER_DESC "Matrox G200/G400"
- * #define DRIVER_DATE "20001127"
- *
- * #define DRIVER_MAJOR 2
- * #define DRIVER_MINOR 0
- * #define DRIVER_PATCHLEVEL 2
- *
- * #define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( mga_ioctls )
- *
- * #define DRM(x) mga_##x
*/
#ifndef __MUST_HAVE_AGP
@@ -54,8 +58,8 @@
#ifndef __HAVE_CTX_BITMAP
#define __HAVE_CTX_BITMAP 0
#endif
-#ifndef __HAVE_DMA_IRQ
-#define __HAVE_DMA_IRQ 0
+#ifndef __HAVE_IRQ
+#define __HAVE_IRQ 0
#endif
#ifndef __HAVE_DMA_QUEUE
#define __HAVE_DMA_QUEUE 0
@@ -84,9 +88,19 @@
#ifndef __HAVE_SG
#define __HAVE_SG 0
#endif
+/* __HAVE_KERNEL_CTX_SWITCH isn't used by any of the drm modules in
+ * the DRI cvs tree, but it is required by the kernel tree's sparc
+ * driver.
+ */
#ifndef __HAVE_KERNEL_CTX_SWITCH
#define __HAVE_KERNEL_CTX_SWITCH 0
#endif
+#ifndef __HAVE_DRIVER_FOPS_READ
+#define __HAVE_DRIVER_FOPS_READ 0
+#endif
+#ifndef __HAVE_DRIVER_FOPS_POLL
+#define __HAVE_DRIVER_FOPS_POLL 0
+#endif
#ifndef DRIVER_PREINIT
#define DRIVER_PREINIT()
@@ -112,6 +126,9 @@
#ifndef DRIVER_IOCTLS
#define DRIVER_IOCTLS
#endif
+#ifndef DRIVER_OPEN_HELPER
+#define DRIVER_OPEN_HELPER( priv, dev )
+#endif
#ifndef DRIVER_FOPS
#define DRIVER_FOPS \
static struct file_operations DRM(fops) = { \
@@ -121,19 +138,20 @@ static struct file_operations DRM(fops) = { \
.release = DRM(release), \
.ioctl = DRM(ioctl), \
.mmap = DRM(mmap), \
- .read = DRM(read), \
.fasync = DRM(fasync), \
.poll = DRM(poll), \
+ .read = DRM(read), \
}
#endif
#ifndef MODULE
-/* DRM(options) is called by the kernel to parse command-line options
- * passed via the boot-loader (e.g., LILO). It calls the insmod option
- * routine, drm_parse_drm.
- */
-/* Use an additional macro to avoid preprocessor troubles */
+/** Use an additional macro to avoid preprocessor troubles */
#define DRM_OPTIONS_FUNC DRM(options)
+/**
+ * Called by the kernel to parse command-line options passed via the
+ * boot-loader (e.g., LILO). It calls the insmod option routine,
+ * parse_options().
+ */
static int __init DRM(options)( char *str )
{
DRM(parse_options)( str );
@@ -144,31 +162,28 @@ __setup( DRIVER_NAME "=", DRM_OPTIONS_FUNC );
#undef DRM_OPTIONS_FUNC
#endif
-/*
- * The default number of instances (minor numbers) to initialize.
- */
-#ifndef DRIVER_NUM_CARDS
-#define DRIVER_NUM_CARDS 1
-#endif
-
-static drm_device_t *DRM(device);
-static int *DRM(minor);
+#define MAX_DEVICES 4
+static drm_device_t DRM(device)[MAX_DEVICES];
static int DRM(numdevs) = 0;
DRIVER_FOPS;
+/** Ioctl table */
static drm_ioctl_desc_t DRM(ioctls)[] = {
[DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { DRM(version), 0, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { DRM(getunique), 0, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { DRM(getmagic), 0, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { DRM(irq_busid), 0, 1 },
+#if __HAVE_IRQ
+ [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { DRM(irq_by_busid), 0, 1 },
+#endif
[DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = { DRM(getmap), 0, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = { DRM(getclient), 0, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = { DRM(getstats), 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION)] = { DRM(setversion), 0, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { DRM(setunique), 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { DRM(block), 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { DRM(unblock), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { DRM(noop), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { DRM(noop), 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { DRM(authmagic), 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { DRM(addmap), 1, 1 },
@@ -192,7 +207,13 @@ static drm_ioctl_desc_t DRM(ioctls)[] = {
[DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { DRM(lock), 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { DRM(unlock), 1, 0 },
+
+#if __HAVE_DMA_FLUSH
+ /* Gamma only, really */
[DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { DRM(finish), 1, 0 },
+#else
+ [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { DRM(noop), 1, 0 },
+#endif
#if __HAVE_DMA
[DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { DRM(addbufs), 1, 1 },
@@ -200,9 +221,9 @@ static drm_ioctl_desc_t DRM(ioctls)[] = {
[DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { DRM(infobufs), 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { DRM(mapbufs), 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { DRM(freebufs), 1, 0 },
-
- /* The DRM_IOCTL_DMA ioctl should be defined by the driver.
- */
+ /* The DRM_IOCTL_DMA ioctl should be defined by the driver. */
+#endif
+#if __HAVE_IRQ || __HAVE_DMA
[DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { DRM(control), 1, 1 },
#endif
@@ -307,7 +328,12 @@ static int DRM(setup)( drm_device_t *dev )
if(dev->maplist == NULL) return -ENOMEM;
memset(dev->maplist, 0, sizeof(*dev->maplist));
INIT_LIST_HEAD(&dev->maplist->head);
- dev->map_count = 0;
+
+ dev->ctxlist = DRM(alloc)(sizeof(*dev->ctxlist),
+ DRM_MEM_CTXLIST);
+ if(dev->ctxlist == NULL) return -ENOMEM;
+ memset(dev->ctxlist, 0, sizeof(*dev->ctxlist));
+ INIT_LIST_HEAD(&dev->ctxlist->head);
dev->vmalist = NULL;
dev->sigdata.lock = dev->lock.hw_lock = NULL;
@@ -316,15 +342,15 @@ static int DRM(setup)( drm_device_t *dev )
dev->queue_reserved = 0;
dev->queue_slots = 0;
dev->queuelist = NULL;
- dev->irq = 0;
+ dev->irq_enabled = 0;
dev->context_flag = 0;
dev->interrupt_flag = 0;
dev->dma_flag = 0;
dev->last_context = 0;
dev->last_switch = 0;
dev->last_checked = 0;
- init_timer( &dev->timer );
init_waitqueue_head( &dev->context_wait );
+ dev->if_version = 0;
dev->ctx_start = 0;
dev->lck_start = 0;
@@ -338,7 +364,8 @@ static int DRM(setup)( drm_device_t *dev )
DRM_DEBUG( "\n" );
- /* The kernel's context could be created here, but is now created
+ /*
+ * The kernel's context could be created here, but is now created
* in drm_dma_enqueue. This is more resource-efficient for
* hardware that does not do DMA, but may mean that
* drm_select_queue fails between the time the interrupt is
@@ -349,6 +376,15 @@ static int DRM(setup)( drm_device_t *dev )
}
+/**
+ * Take down the DRM device.
+ *
+ * \param dev DRM device structure.
+ *
+ * Frees every resource in \p dev.
+ *
+ * \sa drm_device and setup().
+ */
static int DRM(takedown)( drm_device_t *dev )
{
drm_magic_entry_t *pt, *next;
@@ -361,8 +397,8 @@ static int DRM(takedown)( drm_device_t *dev )
DRM_DEBUG( "\n" );
DRIVER_PRETAKEDOWN();
-#if __HAVE_DMA_IRQ
- if ( dev->irq ) DRM(irq_uninstall)( dev );
+#if __HAVE_IRQ
+ if ( dev->irq_enabled ) DRM(irq_uninstall)( dev );
#endif
down( &dev->struct_sem );
@@ -422,51 +458,49 @@ static int DRM(takedown)( drm_device_t *dev )
}
if( dev->maplist ) {
- for(list = dev->maplist->head.next;
- list != &dev->maplist->head;
- list = list_next) {
- list_next = list->next;
+ list_for_each_safe( list, list_next, &dev->maplist->head ) {
r_list = (drm_map_list_t *)list;
- map = r_list->map;
- DRM(free)(r_list, sizeof(*r_list), DRM_MEM_MAPS);
- if(!map) continue;
- switch ( map->type ) {
- case _DRM_REGISTERS:
- case _DRM_FRAME_BUFFER:
+ if ( ( map = r_list->map ) ) {
+ switch ( map->type ) {
+ case _DRM_REGISTERS:
+ case _DRM_FRAME_BUFFER:
#if __REALLY_HAVE_MTRR
- if ( map->mtrr >= 0 ) {
- int retcode;
- retcode = mtrr_del( map->mtrr,
- map->offset,
- map->size );
- DRM_DEBUG( "mtrr_del=%d\n", retcode );
- }
-#endif
- DRM(ioremapfree)( map->handle, map->size );
- break;
- case _DRM_SHM:
- vfree(map->handle);
- break;
-
- case _DRM_AGP:
- /* Do nothing here, because this is all
- * handled in the AGP/GART driver.
- */
- break;
- case _DRM_SCATTER_GATHER:
- /* Handle it, but do nothing, if HAVE_SG
- * isn't defined.
- */
+ if ( map->mtrr >= 0 ) {
+ int retcode;
+ retcode = mtrr_del( map->mtrr,
+ map->offset,
+ map->size );
+ DRM_DEBUG( "mtrr_del=%d\n", retcode );
+ }
+#endif
+ DRM(ioremapfree)( map->handle, map->size, dev );
+ break;
+ case _DRM_SHM:
+ vfree(map->handle);
+ break;
+
+ case _DRM_AGP:
+ /* Do nothing here, because this is all
+ * handled in the AGP/GART driver.
+ */
+ break;
+ case _DRM_SCATTER_GATHER:
+ /* Handle it, but do nothing, if HAVE_SG
+ * isn't defined.
+ */
#if __HAVE_SG
- if(dev->sg) {
- DRM(sg_cleanup)(dev->sg);
- dev->sg = NULL;
- }
+ if(dev->sg) {
+ DRM(sg_cleanup)(dev->sg);
+ dev->sg = NULL;
+ }
#endif
- break;
+ break;
+ }
+ DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
}
- DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
+ list_del( list );
+ DRM(free)(r_list, sizeof(*r_list), DRM_MEM_MAPS);
}
DRM(free)(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
dev->maplist = NULL;
@@ -475,7 +509,9 @@ static int DRM(takedown)( drm_device_t *dev )
#if __HAVE_DMA_QUEUE || __HAVE_MULTIPLE_DMA_QUEUES
if ( dev->queuelist ) {
for ( i = 0 ; i < dev->queue_count ; i++ ) {
+#if __HAVE_DMA_WAITLIST
DRM(waitlist_destroy)( &dev->queuelist[i]->waitlist );
+#endif
if ( dev->queuelist[i] ) {
DRM(free)( dev->queuelist[i],
sizeof(*dev->queuelist[0]),
@@ -496,7 +532,7 @@ static int DRM(takedown)( drm_device_t *dev )
#endif
if ( dev->lock.hw_lock ) {
dev->sigdata.lock = dev->lock.hw_lock = NULL; /* SHM removed */
- dev->lock.pid = 0;
+ dev->lock.filp = 0;
wake_up_interruptible( &dev->lock.lock_queue );
}
up( &dev->struct_sem );
@@ -504,131 +540,142 @@ static int DRM(takedown)( drm_device_t *dev )
return 0;
}
-/*
- * Figure out how many instances to initialize.
- */
-static int drm_count_cards(void)
-{
- int num = 0;
-#if defined(DRIVER_CARD_LIST)
- int i;
- drm_pci_list_t *l;
- u16 device, vendor;
- struct pci_dev *pdev = NULL;
-#endif
-
- DRM_DEBUG( "\n" );
-
-#if defined(DRIVER_COUNT_CARDS)
- num = DRIVER_COUNT_CARDS();
-#elif defined(DRIVER_CARD_LIST)
- for (i = 0, l = DRIVER_CARD_LIST; l[i].vendor != 0; i++) {
- pdev = NULL;
- vendor = l[i].vendor;
- device = l[i].device;
- if(device == 0xffff) device = PCI_ANY_ID;
- if(vendor == 0xffff) vendor = PCI_ANY_ID;
- while ((pdev = pci_find_device(vendor, device, pdev))) {
- num++;
- }
- }
-#else
- num = DRIVER_NUM_CARDS;
-#endif
- DRM_DEBUG("numdevs = %d\n", num);
- return num;
-}
+static drm_pci_id_list_t DRM(pciidlist)[] = {
+ DRIVER_PCI_IDS
+};
-/* drm_init is called via init_module at module load time, or via
- * linux/init/main.c (this is not currently supported).
- */
-static int __init drm_init( void )
+static int DRM(probe)(struct pci_dev *pdev)
{
-
drm_device_t *dev;
- int i;
#if __HAVE_CTX_BITMAP
int retcode;
#endif
- DRM_DEBUG( "\n" );
-
-#ifdef MODULE
- DRM(parse_options)( drm_opts );
-#endif
+ int i;
+ char *desc = NULL;
- DRM(numdevs) = drm_count_cards();
- /* Force at least one instance. */
- if (DRM(numdevs) <= 0)
- DRM(numdevs) = 1;
+ DRM_DEBUG( "\n" );
- DRM(device) = kmalloc(sizeof(*DRM(device)) * DRM(numdevs), GFP_KERNEL);
- if (!DRM(device)) {
- return -ENOMEM;
- }
- DRM(minor) = kmalloc(sizeof(*DRM(minor)) * DRM(numdevs), GFP_KERNEL);
- if (!DRM(minor)) {
- kfree(DRM(device));
- return -ENOMEM;
+ for (i = 0; DRM(pciidlist)[i].vendor != 0; i++) {
+ if ((DRM(pciidlist)[i].vendor == pdev->vendor) &&
+ (DRM(pciidlist)[i].device == pdev->device)) {
+ desc = DRM(pciidlist)[i].name;
+ }
}
+ if (desc == NULL)
+ return -ENODEV;
- DRIVER_PREINIT();
+ if (DRM(numdevs) >= MAX_DEVICES)
+ return -ENODEV;
- DRM(mem_init)();
+ dev = &(DRM(device)[DRM(numdevs)]);
- for (i = 0; i < DRM(numdevs); i++) {
- dev = &(DRM(device)[i]);
- memset( (void *)dev, 0, sizeof(*dev) );
- dev->count_lock = SPIN_LOCK_UNLOCKED;
- sema_init( &dev->struct_sem, 1 );
+ memset( (void *)dev, 0, sizeof(*dev) );
+ dev->count_lock = SPIN_LOCK_UNLOCKED;
+ init_timer( &dev->timer );
+ sema_init( &dev->struct_sem, 1 );
+ sema_init( &dev->ctxlist_sem, 1 );
+
+ if ((dev->minor = DRM(stub_register)(DRIVER_NAME, &DRM(fops),dev)) < 0)
+ return -EPERM;
+ dev->device = MKDEV(DRM_MAJOR, dev->minor );
+ dev->name = DRIVER_NAME;
+
+ dev->pdev = pdev;
+#ifdef __alpha__
+ dev->hose = pdev->sysdata;
+ dev->pci_domain = dev->hose->bus->number;
+#else
+ dev->pci_domain = 0;
+#endif
+ dev->pci_bus = pdev->bus->number;
+ dev->pci_slot = PCI_SLOT(pdev->devfn);
+ dev->pci_func = PCI_FUNC(pdev->devfn);
+ dev->irq = pdev->irq;
- if ((DRM(minor)[i] = DRM(stub_register)(DRIVER_NAME, &DRM(fops),dev)) < 0)
- return -EPERM;
- dev->device = MKDEV(DRM_MAJOR, DRM(minor)[i] );
- dev->name = DRIVER_NAME;
+ DRIVER_PREINIT();
#if __REALLY_HAVE_AGP
- dev->agp = DRM(agp_init)();
+ dev->agp = DRM(agp_init)();
#if __MUST_HAVE_AGP
- if ( dev->agp == NULL ) {
- DRM_ERROR( "Cannot initialize the agpgart module.\n" );
- DRM(stub_unregister)(DRM(minor)[i]);
- DRM(takedown)( dev );
- return -ENOMEM;
- }
+ if ( dev->agp == NULL ) {
+ DRM_ERROR( "Cannot initialize the agpgart module.\n" );
+ DRM(stub_unregister)(dev->minor);
+ DRM(takedown)( dev );
+ return -ENOMEM;
+ }
#endif
#if __REALLY_HAVE_MTRR
- if (dev->agp)
- dev->agp->agp_mtrr = mtrr_add( dev->agp->agp_info.aper_base,
- dev->agp->agp_info.aper_size*1024*1024,
- MTRR_TYPE_WRCOMB,
- 1 );
+ if (dev->agp)
+ dev->agp->agp_mtrr = mtrr_add( dev->agp->agp_info.aper_base,
+ dev->agp->agp_info.aper_size*1024*1024,
+ MTRR_TYPE_WRCOMB,
+ 1 );
#endif
#endif
#if __HAVE_CTX_BITMAP
- retcode = DRM(ctxbitmap_init)( dev );
- if( retcode ) {
- DRM_ERROR( "Cannot allocate memory for context bitmap.\n" );
- DRM(stub_unregister)(DRM(minor)[i]);
- DRM(takedown)( dev );
- return retcode;
- }
+ retcode = DRM(ctxbitmap_init)( dev );
+ if( retcode ) {
+ DRM_ERROR( "Cannot allocate memory for context bitmap.\n" );
+ DRM(stub_unregister)(dev->minor);
+ DRM(takedown)( dev );
+ return retcode;
+ }
#endif
- DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d\n",
- DRIVER_NAME,
- DRIVER_MAJOR,
- DRIVER_MINOR,
- DRIVER_PATCHLEVEL,
- DRIVER_DATE,
- DRM(minor)[i] );
- }
+ DRM(numdevs)++; /* no errors, mark it reserved */
+
+ DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
+ DRIVER_NAME,
+ DRIVER_MAJOR,
+ DRIVER_MINOR,
+ DRIVER_PATCHLEVEL,
+ DRIVER_DATE,
+ dev->minor,
+ desc );
DRIVER_POSTINIT();
return 0;
}
-/* drm_cleanup is called via cleanup_module at module unload time.
+
+/**
+ * Module initialization. Called via init_module at module load time, or via
+ * linux/init/main.c (this is not currently supported).
+ *
+ * \return zero on success or a negative number on failure.
+ *
+ * Initializes an array of drm_device structures, and attempts to
+ * initialize all available devices, using consecutive minors, registering the
+ * stubs and initializing the AGP device.
+ *
+ * Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and
+ * after the initialization for driver customization.
+ */
+static int __init drm_init( void )
+{
+ struct pci_dev *pdev = NULL;
+
+ DRM_DEBUG( "\n" );
+
+#ifdef MODULE
+ DRM(parse_options)( drm_opts );
+#endif
+
+ DRM(mem_init)();
+
+ while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
+ DRM(probe)(pdev);
+ }
+ return 0;
+}
+
+/**
+ * Called via cleanup_module() at module unload time.
+ *
+ * Cleans up all DRM device, calling takedown().
+ *
+ * \sa drm_init().
*/
static void __exit drm_cleanup( void )
{
@@ -639,10 +686,10 @@ static void __exit drm_cleanup( void )
for (i = DRM(numdevs) - 1; i >= 0; i--) {
dev = &(DRM(device)[i]);
- if ( DRM(stub_unregister)(DRM(minor)[i]) ) {
+ if ( DRM(stub_unregister)(dev->minor) ) {
DRM_ERROR( "Cannot unload module\n" );
} else {
- DRM_DEBUG("minor %d unregistered\n", DRM(minor)[i]);
+ DRM_DEBUG("minor %d unregistered\n", dev->minor);
if (i == 0) {
DRM_INFO( "Module unloaded\n" );
}
@@ -672,8 +719,6 @@ static void __exit drm_cleanup( void )
#endif
}
DRIVER_POSTCLEANUP();
- kfree(DRM(minor));
- kfree(DRM(device));
DRM(numdevs) = 0;
}
@@ -681,6 +726,17 @@ module_init( drm_init );
module_exit( drm_cleanup );
+/**
+ * Get version information
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument, pointing to a drm_version structure.
+ * \return zero on success or negative number on failure.
+ *
+ * Fills in the version information in \p arg.
+ */
int DRM(version)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
@@ -716,6 +772,17 @@ int DRM(version)( struct inode *inode, struct file *filp,
return 0;
}
+/**
+ * Open file.
+ *
+ * \param inode device inode
+ * \param filp file pointer.
+ * \return zero on success or a negative number on failure.
+ *
+ * Searches the DRM device with the same minor number, calls open_helper(), and
+ * increments the device open count. If the open count was previous at zero,
+ * i.e., it's the first that the device is open, then calls setup().
+ */
int DRM(open)( struct inode *inode, struct file *filp )
{
drm_device_t *dev = NULL;
@@ -723,7 +790,7 @@ int DRM(open)( struct inode *inode, struct file *filp )
int i;
for (i = 0; i < DRM(numdevs); i++) {
- if (minor(inode->i_rdev) == DRM(minor)[i]) {
+ if (minor(inode->i_rdev) == DRM(device)[i].minor) {
dev = &(DRM(device)[i]);
break;
}
@@ -732,8 +799,6 @@ int DRM(open)( struct inode *inode, struct file *filp )
return -ENODEV;
}
- DRM_DEBUG( "open_count = %d\n", dev->open_count );
-
retcode = DRM(open_helper)( inode, filp, dev );
if ( !retcode ) {
atomic_inc( &dev->counts[_DRM_STAT_OPENS] );
@@ -748,6 +813,18 @@ int DRM(open)( struct inode *inode, struct file *filp )
return retcode;
}
+/**
+ * Release file.
+ *
+ * \param inode device inode
+ * \param filp file pointer.
+ * \return zero on success or a negative number on failure.
+ *
+ * If the hardware lock is held then free it, and take it again for the kernel
+ * context since it's necessary to reclaim buffers. Unlink the file private
+ * data from its list and free it. Decreases the open count and if it reaches
+ * zero calls takedown().
+ */
int DRM(release)( struct inode *inode, struct file *filp )
{
drm_file_t *priv = filp->private_data;
@@ -768,12 +845,12 @@ int DRM(release)( struct inode *inode, struct file *filp )
DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n",
current->pid, (long)dev->device, dev->open_count );
- if ( dev->lock.hw_lock &&
+ if ( priv->lock_count && dev->lock.hw_lock &&
_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) &&
- dev->lock.pid == current->pid ) {
- DRM_DEBUG( "Process %d dead, freeing lock for context %d\n",
- current->pid,
- _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) );
+ dev->lock.filp == filp ) {
+ DRM_DEBUG( "File %p released, freeing lock for context %d\n",
+ filp,
+ _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) );
#if __HAVE_RELEASE
DRIVER_RELEASE();
#endif
@@ -786,9 +863,10 @@ int DRM(release)( struct inode *inode, struct file *filp )
server. */
}
#if __HAVE_RELEASE
- else if ( dev->lock.hw_lock ) {
+ else if ( priv->lock_count && dev->lock.hw_lock ) {
/* The lock is required to reclaim buffers */
DECLARE_WAITQUEUE( entry, current );
+
add_wait_queue( &dev->lock.lock_queue, &entry );
for (;;) {
current->state = TASK_INTERRUPTIBLE;
@@ -799,15 +877,12 @@ int DRM(release)( struct inode *inode, struct file *filp )
}
if ( DRM(lock_take)( &dev->lock.hw_lock->lock,
DRM_KERNEL_CONTEXT ) ) {
- dev->lock.pid = priv->pid;
+ dev->lock.filp = filp;
dev->lock.lock_time = jiffies;
atomic_inc( &dev->counts[_DRM_STAT_LOCKS] );
break; /* Got lock */
}
/* Contention */
-#if 0
- atomic_inc( &dev->total_sleeps );
-#endif
schedule();
if ( signal_pending( current ) ) {
retcode = -ERESTARTSYS;
@@ -823,11 +898,30 @@ int DRM(release)( struct inode *inode, struct file *filp )
}
}
#elif __HAVE_DMA
- DRM(reclaim_buffers)( dev, priv->pid );
+ DRM(reclaim_buffers)( filp );
#endif
DRM(fasync)( -1, filp, 0 );
+ down( &dev->ctxlist_sem );
+ if ( !list_empty( &dev->ctxlist->head ) ) {
+ drm_ctx_list_t *pos, *n;
+
+ list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) {
+ if ( pos->tag == priv &&
+ pos->handle != DRM_KERNEL_CONTEXT ) {
+#ifdef DRIVER_CTX_DTOR
+ DRIVER_CTX_DTOR(pos->handle);
+#endif
+ DRM(ctxbitmap_free)( dev, pos->handle );
+
+ list_del( &pos->head );
+ DRM(free)( pos, sizeof(*pos), DRM_MEM_CTXLIST );
+ }
+ }
+ }
+ up( &dev->ctxlist_sem );
+
down( &dev->struct_sem );
if ( priv->remove_auth_on_close == 1 ) {
drm_file_t *temp = dev->file_first;
@@ -847,7 +941,7 @@ int DRM(release)( struct inode *inode, struct file *filp )
dev->file_last = priv->prev;
}
up( &dev->struct_sem );
-
+
DRM(free)( priv, sizeof(*priv), DRM_MEM_FILES );
/* ========================================================
@@ -872,10 +966,21 @@ int DRM(release)( struct inode *inode, struct file *filp )
spin_unlock( &dev->count_lock );
unlock_kernel();
+
return retcode;
}
-/* DRM(ioctl) is called whenever a process performs an ioctl on /dev/drm.
+/**
+ * Called whenever a process performs an ioctl on /dev/drm.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument.
+ * \return zero on success or negative number on failure.
+ *
+ * Looks up the ioctl function in the ::ioctls table, checking for root
+ * previleges if so required, and dispatches to the respective function.
*/
int DRM(ioctl)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
@@ -916,6 +1021,17 @@ int DRM(ioctl)( struct inode *inode, struct file *filp,
return retcode;
}
+/**
+ * Lock ioctl.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument, pointing to a drm_lock structure.
+ * \return zero on success or negative number on failure.
+ *
+ * Add the current task to the lock wait queue, and attempt to take to lock.
+ */
int DRM(lock)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
@@ -927,11 +1043,8 @@ int DRM(lock)( struct inode *inode, struct file *filp,
#if __HAVE_MULTIPLE_DMA_QUEUES
drm_queue_t *q;
#endif
-#if __HAVE_DMA_HISTOGRAM
- cycles_t start;
- dev->lck_start = start = get_cycles();
-#endif
+ ++priv->lock_count;
if ( copy_from_user( &lock, (drm_lock_t *)arg, sizeof(lock) ) )
return -EFAULT;
@@ -969,7 +1082,7 @@ int DRM(lock)( struct inode *inode, struct file *filp,
}
if ( DRM(lock_take)( &dev->lock.hw_lock->lock,
lock.context ) ) {
- dev->lock.pid = current->pid;
+ dev->lock.filp = filp;
dev->lock.lock_time = jiffies;
atomic_inc( &dev->counts[_DRM_STAT_LOCKS] );
break; /* Got lock */
@@ -1011,6 +1124,10 @@ int DRM(lock)( struct inode *inode, struct file *filp,
DRIVER_DMA_QUIESCENT();
}
#endif
+ /* __HAVE_KERNEL_CTX_SWITCH isn't used by any of the
+ * drm modules in the DRI cvs tree, but it is required
+ * by the Sparc driver.
+ */
#if __HAVE_KERNEL_CTX_SWITCH
if ( dev->last_context != lock.context ) {
DRM(context_switch)(dev, dev->last_context,
@@ -1021,13 +1138,20 @@ int DRM(lock)( struct inode *inode, struct file *filp,
DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" );
-#if __HAVE_DMA_HISTOGRAM
- atomic_inc(&dev->histo.lacq[DRM(histogram_slot)(get_cycles()-start)]);
-#endif
return ret;
}
-
+/**
+ * Unlock ioctl.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument, pointing to a drm_lock structure.
+ * \return zero on success or negative number on failure.
+ *
+ * Transfer and free the lock.
+ */
int DRM(unlock)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
@@ -1046,12 +1170,16 @@ int DRM(unlock)( struct inode *inode, struct file *filp,
atomic_inc( &dev->counts[_DRM_STAT_UNLOCKS] );
+ /* __HAVE_KERNEL_CTX_SWITCH isn't used by any of the drm
+ * modules in the DRI cvs tree, but it is required by the
+ * Sparc driver.
+ */
#if __HAVE_KERNEL_CTX_SWITCH
/* We no longer really hold it, but if we are the next
* agent to request it then we should just be able to
* take it immediately and not eat the ioctl.
*/
- dev->lock.pid = 0;
+ dev->lock.filp = 0;
{
__volatile__ unsigned int *plock = &dev->lock.hw_lock->lock;
unsigned int old, new, prev, ctx;
@@ -1071,13 +1199,9 @@ int DRM(unlock)( struct inode *inode, struct file *filp,
DRM(dma_schedule)( dev, 1 );
#endif
- /* FIXME: Do we ever really need to check this???
- */
- if ( 1 /* !dev->context_flag */ ) {
- if ( DRM(lock_free)( dev, &dev->lock.hw_lock->lock,
- DRM_KERNEL_CONTEXT ) ) {
- DRM_ERROR( "\n" );
- }
+ if ( DRM(lock_free)( dev, &dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT ) ) {
+ DRM_ERROR( "\n" );
}
#endif /* !__HAVE_KERNEL_CTX_SWITCH */
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_memory_debug.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_memory_debug.h
new file mode 100644
index 000000000..2a2e7d794
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_memory_debug.h
@@ -0,0 +1,460 @@
+/**
+ * \file drm_memory.h
+ * Memory management wrappers for DRM.
+ *
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * 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 (including the next
+ * paragraph) 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
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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.
+ */
+
+#define __NO_VERSION__
+#include <linux/config.h>
+#include "drmP.h"
+
+typedef struct drm_mem_stats {
+ const char *name;
+ int succeed_count;
+ int free_count;
+ int fail_count;
+ unsigned long bytes_allocated;
+ unsigned long bytes_freed;
+} drm_mem_stats_t;
+
+static spinlock_t DRM(mem_lock) = SPIN_LOCK_UNLOCKED;
+static unsigned long DRM(ram_available) = 0; /* In pages */
+static unsigned long DRM(ram_used) = 0;
+static drm_mem_stats_t DRM(mem_stats)[] = {
+ [DRM_MEM_DMA] = { "dmabufs" },
+ [DRM_MEM_SAREA] = { "sareas" },
+ [DRM_MEM_DRIVER] = { "driver" },
+ [DRM_MEM_MAGIC] = { "magic" },
+ [DRM_MEM_IOCTLS] = { "ioctltab" },
+ [DRM_MEM_MAPS] = { "maplist" },
+ [DRM_MEM_VMAS] = { "vmalist" },
+ [DRM_MEM_BUFS] = { "buflist" },
+ [DRM_MEM_SEGS] = { "seglist" },
+ [DRM_MEM_PAGES] = { "pagelist" },
+ [DRM_MEM_FILES] = { "files" },
+ [DRM_MEM_QUEUES] = { "queues" },
+ [DRM_MEM_CMDS] = { "commands" },
+ [DRM_MEM_MAPPINGS] = { "mappings" },
+ [DRM_MEM_BUFLISTS] = { "buflists" },
+ [DRM_MEM_AGPLISTS] = { "agplist" },
+ [DRM_MEM_SGLISTS] = { "sglist" },
+ [DRM_MEM_TOTALAGP] = { "totalagp" },
+ [DRM_MEM_BOUNDAGP] = { "boundagp" },
+ [DRM_MEM_CTXBITMAP] = { "ctxbitmap"},
+ [DRM_MEM_CTXLIST] = { "ctxlist" },
+ [DRM_MEM_STUB] = { "stub" },
+ { NULL, 0, } /* Last entry must be null */
+};
+
+void DRM(mem_init)(void)
+{
+ drm_mem_stats_t *mem;
+ struct sysinfo si;
+
+ for (mem = DRM(mem_stats); mem->name; ++mem) {
+ mem->succeed_count = 0;
+ mem->free_count = 0;
+ mem->fail_count = 0;
+ mem->bytes_allocated = 0;
+ mem->bytes_freed = 0;
+ }
+
+ si_meminfo(&si);
+ DRM(ram_available) = si.totalram;
+ DRM(ram_used) = 0;
+}
+
+/* drm_mem_info is called whenever a process reads /dev/drm/mem. */
+
+static int DRM(_mem_info)(char *buf, char **start, off_t offset,
+ int request, int *eof, void *data)
+{
+ drm_mem_stats_t *pt;
+ int len = 0;
+
+ if (offset > DRM_PROC_LIMIT) {
+ *eof = 1;
+ return 0;
+ }
+
+ *eof = 0;
+ *start = &buf[offset];
+
+ DRM_PROC_PRINT(" total counts "
+ " | outstanding \n");
+ DRM_PROC_PRINT("type alloc freed fail bytes freed"
+ " | allocs bytes\n\n");
+ DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB |\n",
+ "system", 0, 0, 0,
+ DRM(ram_available) << (PAGE_SHIFT - 10));
+ DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB |\n",
+ "locked", 0, 0, 0, DRM(ram_used) >> 10);
+ DRM_PROC_PRINT("\n");
+ for (pt = DRM(mem_stats); pt->name; pt++) {
+ DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu %10lu | %6d %10ld\n",
+ pt->name,
+ pt->succeed_count,
+ pt->free_count,
+ pt->fail_count,
+ pt->bytes_allocated,
+ pt->bytes_freed,
+ pt->succeed_count - pt->free_count,
+ (long)pt->bytes_allocated
+ - (long)pt->bytes_freed);
+ }
+
+ if (len > request + offset) return request;
+ *eof = 1;
+ return len - offset;
+}
+
+int DRM(mem_info)(char *buf, char **start, off_t offset,
+ int len, int *eof, void *data)
+{
+ int ret;
+
+ spin_lock(&DRM(mem_lock));
+ ret = DRM(_mem_info)(buf, start, offset, len, eof, data);
+ spin_unlock(&DRM(mem_lock));
+ return ret;
+}
+
+void *DRM(alloc)(size_t size, int area)
+{
+ void *pt;
+
+ if (!size) {
+ DRM_MEM_ERROR(area, "Allocating 0 bytes\n");
+ return NULL;
+ }
+
+ if (!(pt = kmalloc(size, GFP_KERNEL))) {
+ spin_lock(&DRM(mem_lock));
+ ++DRM(mem_stats)[area].fail_count;
+ spin_unlock(&DRM(mem_lock));
+ return NULL;
+ }
+ spin_lock(&DRM(mem_lock));
+ ++DRM(mem_stats)[area].succeed_count;
+ DRM(mem_stats)[area].bytes_allocated += size;
+ spin_unlock(&DRM(mem_lock));
+ return pt;
+}
+
+void *DRM(calloc)(size_t size, size_t nmemb, int area)
+{
+ void *addr;
+
+ addr = DRM(alloc)(nmemb * size, area);
+ if (addr != NULL)
+ memset((void *)addr, 0, size * nmemb);
+
+ return addr;
+}
+
+void *DRM(realloc)(void *oldpt, size_t oldsize, size_t size, int area)
+{
+ void *pt;
+
+ if (!(pt = DRM(alloc)(size, area))) return NULL;
+ if (oldpt && oldsize) {
+ memcpy(pt, oldpt, oldsize);
+ DRM(free)(oldpt, oldsize, area);
+ }
+ return pt;
+}
+
+void DRM(free)(void *pt, size_t size, int area)
+{
+ int alloc_count;
+ int free_count;
+
+ if (!pt) DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n");
+ else kfree(pt);
+ spin_lock(&DRM(mem_lock));
+ DRM(mem_stats)[area].bytes_freed += size;
+ free_count = ++DRM(mem_stats)[area].free_count;
+ alloc_count = DRM(mem_stats)[area].succeed_count;
+ spin_unlock(&DRM(mem_lock));
+ if (free_count > alloc_count) {
+ DRM_MEM_ERROR(area, "Excess frees: %d frees, %d allocs\n",
+ free_count, alloc_count);
+ }
+}
+
+unsigned long DRM(alloc_pages)(int order, int area)
+{
+ unsigned long address;
+ unsigned long bytes = PAGE_SIZE << order;
+ unsigned long addr;
+ unsigned int sz;
+
+ spin_lock(&DRM(mem_lock));
+ if ((DRM(ram_used) >> PAGE_SHIFT)
+ > (DRM_RAM_PERCENT * DRM(ram_available)) / 100) {
+ spin_unlock(&DRM(mem_lock));
+ return 0;
+ }
+ spin_unlock(&DRM(mem_lock));
+
+ address = __get_free_pages(GFP_KERNEL, order);
+ if (!address) {
+ spin_lock(&DRM(mem_lock));
+ ++DRM(mem_stats)[area].fail_count;
+ spin_unlock(&DRM(mem_lock));
+ return 0;
+ }
+ spin_lock(&DRM(mem_lock));
+ ++DRM(mem_stats)[area].succeed_count;
+ DRM(mem_stats)[area].bytes_allocated += bytes;
+ DRM(ram_used) += bytes;
+ spin_unlock(&DRM(mem_lock));
+
+
+ /* Zero outside the lock */
+ memset((void *)address, 0, bytes);
+
+ /* Reserve */
+ for (addr = address, sz = bytes;
+ sz > 0;
+ addr += PAGE_SIZE, sz -= PAGE_SIZE) {
+ SetPageReserved(virt_to_page(addr));
+ }
+
+ return address;
+}
+
+void DRM(free_pages)(unsigned long address, int order, int area)
+{
+ unsigned long bytes = PAGE_SIZE << order;
+ int alloc_count;
+ int free_count;
+ unsigned long addr;
+ unsigned int sz;
+
+ if (!address) {
+ DRM_MEM_ERROR(area, "Attempt to free address 0\n");
+ } else {
+ /* Unreserve */
+ for (addr = address, sz = bytes;
+ sz > 0;
+ addr += PAGE_SIZE, sz -= PAGE_SIZE) {
+ ClearPageReserved(virt_to_page(addr));
+ }
+ free_pages(address, order);
+ }
+
+ spin_lock(&DRM(mem_lock));
+ free_count = ++DRM(mem_stats)[area].free_count;
+ alloc_count = DRM(mem_stats)[area].succeed_count;
+ DRM(mem_stats)[area].bytes_freed += bytes;
+ DRM(ram_used) -= bytes;
+ spin_unlock(&DRM(mem_lock));
+ if (free_count > alloc_count) {
+ DRM_MEM_ERROR(area,
+ "Excess frees: %d frees, %d allocs\n",
+ free_count, alloc_count);
+ }
+}
+
+void *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev)
+{
+ void *pt;
+
+ if (!size) {
+ DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
+ "Mapping 0 bytes at 0x%08lx\n", offset);
+ return NULL;
+ }
+
+ if (!(pt = drm_ioremap(offset, size, dev))) {
+ spin_lock(&DRM(mem_lock));
+ ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count;
+ spin_unlock(&DRM(mem_lock));
+ return NULL;
+ }
+ spin_lock(&DRM(mem_lock));
+ ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
+ DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size;
+ spin_unlock(&DRM(mem_lock));
+ return pt;
+}
+
+void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size, drm_device_t *dev)
+{
+ void *pt;
+
+ if (!size) {
+ DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
+ "Mapping 0 bytes at 0x%08lx\n", offset);
+ return NULL;
+ }
+
+ if (!(pt = drm_ioremap_nocache(offset, size, dev))) {
+ spin_lock(&DRM(mem_lock));
+ ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count;
+ spin_unlock(&DRM(mem_lock));
+ return NULL;
+ }
+ spin_lock(&DRM(mem_lock));
+ ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
+ DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size;
+ spin_unlock(&DRM(mem_lock));
+ return pt;
+}
+
+void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev)
+{
+ int alloc_count;
+ int free_count;
+
+ if (!pt)
+ DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
+ "Attempt to free NULL pointer\n");
+ else
+ drm_ioremapfree(pt, size, dev);
+
+ spin_lock(&DRM(mem_lock));
+ DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_freed += size;
+ free_count = ++DRM(mem_stats)[DRM_MEM_MAPPINGS].free_count;
+ alloc_count = DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
+ spin_unlock(&DRM(mem_lock));
+ if (free_count > alloc_count) {
+ DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
+ "Excess frees: %d frees, %d allocs\n",
+ free_count, alloc_count);
+ }
+}
+
+#if __REALLY_HAVE_AGP
+
+DRM_AGP_MEM *DRM(alloc_agp)(int pages, u32 type)
+{
+ DRM_AGP_MEM *handle;
+
+ if (!pages) {
+ DRM_MEM_ERROR(DRM_MEM_TOTALAGP, "Allocating 0 pages\n");
+ return NULL;
+ }
+
+ if ((handle = DRM(agp_allocate_memory)(pages, type))) {
+ spin_lock(&DRM(mem_lock));
+ ++DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count;
+ DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_allocated
+ += pages << PAGE_SHIFT;
+ spin_unlock(&DRM(mem_lock));
+ return handle;
+ }
+ spin_lock(&DRM(mem_lock));
+ ++DRM(mem_stats)[DRM_MEM_TOTALAGP].fail_count;
+ spin_unlock(&DRM(mem_lock));
+ return NULL;
+}
+
+int DRM(free_agp)(DRM_AGP_MEM *handle, int pages)
+{
+ int alloc_count;
+ int free_count;
+ int retval = -EINVAL;
+
+ if (!handle) {
+ DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
+ "Attempt to free NULL AGP handle\n");
+ return retval;;
+ }
+
+ if (DRM(agp_free_memory)(handle)) {
+ spin_lock(&DRM(mem_lock));
+ free_count = ++DRM(mem_stats)[DRM_MEM_TOTALAGP].free_count;
+ alloc_count = DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count;
+ DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_freed
+ += pages << PAGE_SHIFT;
+ spin_unlock(&DRM(mem_lock));
+ if (free_count > alloc_count) {
+ DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
+ "Excess frees: %d frees, %d allocs\n",
+ free_count, alloc_count);
+ }
+ return 0;
+ }
+ return retval;
+}
+
+int DRM(bind_agp)(DRM_AGP_MEM *handle, unsigned int start)
+{
+ int retcode = -EINVAL;
+
+ if (!handle) {
+ DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
+ "Attempt to bind NULL AGP handle\n");
+ return retcode;
+ }
+
+ if (!(retcode = DRM(agp_bind_memory)(handle, start))) {
+ spin_lock(&DRM(mem_lock));
+ ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count;
+ DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_allocated
+ += handle->page_count << PAGE_SHIFT;
+ spin_unlock(&DRM(mem_lock));
+ return retcode;
+ }
+ spin_lock(&DRM(mem_lock));
+ ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].fail_count;
+ spin_unlock(&DRM(mem_lock));
+ return retcode;
+}
+
+int DRM(unbind_agp)(DRM_AGP_MEM *handle)
+{
+ int alloc_count;
+ int free_count;
+ int retcode = -EINVAL;
+
+ if (!handle) {
+ DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
+ "Attempt to unbind NULL AGP handle\n");
+ return retcode;
+ }
+
+ if ((retcode = DRM(agp_unbind_memory)(handle))) return retcode;
+ spin_lock(&DRM(mem_lock));
+ free_count = ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].free_count;
+ alloc_count = DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count;
+ DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_freed
+ += handle->page_count << PAGE_SHIFT;
+ spin_unlock(&DRM(mem_lock));
+ if (free_count > alloc_count) {
+ DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
+ "Excess frees: %d frees, %d allocs\n",
+ free_count, alloc_count);
+ }
+ return retcode;
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/sis_mm.c b/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/sis_mm.c
new file mode 100644
index 000000000..092096c4c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/sis_mm.c
@@ -0,0 +1,407 @@
+/* sis_mm.c -- Private header for Direct Rendering Manager -*- linux-c -*-
+ * Created: Mon Jan 4 10:05:05 1999 by sclin@sis.com.tw
+ *
+ * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
+ * All rights reserved.
+ *
+ * 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 (including the next
+ * paragraph) 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
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ *
+ * Authors:
+ * Sung-Ching Lin <sclin@sis.com.tw>
+ *
+ */
+
+#include "sis.h"
+#include "drmP.h"
+#include "sis_drm.h"
+#include "sis_drv.h"
+#include "sis_ds.h"
+#if defined(__linux__) && defined(CONFIG_FB_SIS)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+#include <video/sisfb.h>
+#else
+#include <linux/sisfb.h>
+#endif
+#endif
+
+#define MAX_CONTEXT 100
+#define VIDEO_TYPE 0
+#define AGP_TYPE 1
+
+typedef struct {
+ int used;
+ int context;
+ set_t *sets[2]; /* 0 for video, 1 for AGP */
+} sis_context_t;
+
+static sis_context_t global_ppriv[MAX_CONTEXT];
+
+
+static int add_alloc_set(int context, int type, unsigned int val)
+{
+ int i, retval = 0;
+
+ for (i = 0; i < MAX_CONTEXT; i++) {
+ if (global_ppriv[i].used && global_ppriv[i].context == context)
+ {
+ retval = setAdd(global_ppriv[i].sets[type], val);
+ break;
+ }
+ }
+ return retval;
+}
+
+static int del_alloc_set(int context, int type, unsigned int val)
+{
+ int i, retval = 0;
+
+ for (i = 0; i < MAX_CONTEXT; i++) {
+ if (global_ppriv[i].used && global_ppriv[i].context == context)
+ {
+ retval = setDel(global_ppriv[i].sets[type], val);
+ break;
+ }
+ }
+ return retval;
+}
+
+/* fb management via fb device */
+#if defined(__linux__) && defined(CONFIG_FB_SIS)
+
+int sis_fb_init( DRM_IOCTL_ARGS )
+{
+ return 0;
+}
+
+int sis_fb_alloc( DRM_IOCTL_ARGS )
+{
+ drm_sis_mem_t fb;
+ struct sis_memreq req;
+ int retval = 0;
+
+ DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_mem_t *)data, sizeof(fb));
+
+ req.size = fb.size;
+ sis_malloc(&req);
+ if (req.offset) {
+ /* TODO */
+ fb.offset = req.offset;
+ fb.free = req.offset;
+ if (!add_alloc_set(fb.context, VIDEO_TYPE, fb.free)) {
+ DRM_DEBUG("adding to allocation set fails\n");
+ sis_free(req.offset);
+ retval = DRM_ERR(EINVAL);
+ }
+ } else {
+ fb.offset = 0;
+ fb.size = 0;
+ fb.free = 0;
+ }
+
+ DRM_COPY_TO_USER_IOCTL((drm_sis_mem_t *)data, fb, sizeof(fb));
+
+ DRM_DEBUG("alloc fb, size = %d, offset = %ld\n", fb.size, req.offset);
+
+ return retval;
+}
+
+int sis_fb_free( DRM_IOCTL_ARGS )
+{
+ drm_sis_mem_t fb;
+ int retval = 0;
+
+ DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_mem_t *)data, sizeof(fb));
+
+ if (!fb.free)
+ return DRM_ERR(EINVAL);
+
+ if (!del_alloc_set(fb.context, VIDEO_TYPE, fb.free))
+ retval = DRM_ERR(EINVAL);
+ sis_free(fb.free);
+
+ DRM_DEBUG("free fb, offset = 0x%lx\n", fb.free);
+
+ return retval;
+}
+
+#else
+
+/* Called by the X Server to initialize the FB heap. Allocations will fail
+ * unless this is called. Offset is the beginning of the heap from the
+ * framebuffer offset (MaxXFBMem in XFree86).
+ *
+ * Memory layout according to Thomas Winischofer:
+ * |------------------|DDDDDDDDDDDDDDDDDDDDDDDDDDDDD|HHHH|CCCCCCCCCCC|
+ *
+ * X driver/sisfb HW- Command-
+ * framebuffer memory DRI heap Cursor queue
+ */
+int sis_fb_init( DRM_IOCTL_ARGS )
+{
+ DRM_DEVICE;
+ drm_sis_private_t *dev_priv = dev->dev_private;
+ drm_sis_fb_t fb;
+
+ DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_fb_t *)data, sizeof(fb));
+
+ if (dev_priv == NULL) {
+ dev->dev_private = DRM(calloc)(1, sizeof(drm_sis_private_t),
+ DRM_MEM_DRIVER);
+ dev_priv = dev->dev_private;
+ if (dev_priv == NULL)
+ return ENOMEM;
+ }
+
+ if (dev_priv->FBHeap != NULL)
+ return DRM_ERR(EINVAL);
+
+ dev_priv->FBHeap = mmInit(fb.offset, fb.size);
+
+ DRM_DEBUG("offset = %u, size = %u", fb.offset, fb.size);
+
+ return 0;
+}
+
+int sis_fb_alloc( DRM_IOCTL_ARGS )
+{
+ DRM_DEVICE;
+ drm_sis_private_t *dev_priv = dev->dev_private;
+ drm_sis_mem_t fb;
+ PMemBlock block;
+ int retval = 0;
+
+ if (dev_priv == NULL || dev_priv->FBHeap == NULL)
+ return DRM_ERR(EINVAL);
+
+ DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_mem_t *)data, sizeof(fb));
+
+ block = mmAllocMem(dev_priv->FBHeap, fb.size, 0, 0);
+ if (block) {
+ /* TODO */
+ fb.offset = block->ofs;
+ fb.free = (unsigned long)block;
+ if (!add_alloc_set(fb.context, VIDEO_TYPE, fb.free)) {
+ DRM_DEBUG("adding to allocation set fails\n");
+ mmFreeMem((PMemBlock)fb.free);
+ retval = DRM_ERR(EINVAL);
+ }
+ } else {
+ fb.offset = 0;
+ fb.size = 0;
+ fb.free = 0;
+ }
+
+ DRM_COPY_TO_USER_IOCTL((drm_sis_mem_t *)data, fb, sizeof(fb));
+
+ DRM_DEBUG("alloc fb, size = %d, offset = %d\n", fb.size, fb.offset);
+
+ return retval;
+}
+
+int sis_fb_free( DRM_IOCTL_ARGS )
+{
+ DRM_DEVICE;
+ drm_sis_private_t *dev_priv = dev->dev_private;
+ drm_sis_mem_t fb;
+
+ if (dev_priv == NULL || dev_priv->FBHeap == NULL)
+ return DRM_ERR(EINVAL);
+
+ DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_mem_t *)data, sizeof(fb));
+
+ if (!mmBlockInHeap(dev_priv->FBHeap, (PMemBlock)fb.free))
+ return DRM_ERR(EINVAL);
+
+ if (!del_alloc_set(fb.context, VIDEO_TYPE, fb.free))
+ return DRM_ERR(EINVAL);
+ mmFreeMem((PMemBlock)fb.free);
+
+ DRM_DEBUG("free fb, free = 0x%lx\n", fb.free);
+
+ return 0;
+}
+
+#endif
+
+/* agp memory management */
+
+int sis_ioctl_agp_init( DRM_IOCTL_ARGS )
+{
+ DRM_DEVICE;
+ drm_sis_private_t *dev_priv = dev->dev_private;
+ drm_sis_agp_t agp;
+
+ if (dev_priv == NULL) {
+ dev->dev_private = DRM(calloc)(1, sizeof(drm_sis_private_t),
+ DRM_MEM_DRIVER);
+ dev_priv = dev->dev_private;
+ if (dev_priv == NULL)
+ return ENOMEM;
+ }
+
+ if (dev_priv->AGPHeap != NULL)
+ return DRM_ERR(EINVAL);
+
+ DRM_COPY_FROM_USER_IOCTL(agp, (drm_sis_agp_t *)data, sizeof(agp));
+
+ dev_priv->AGPHeap = mmInit(agp.offset, agp.size);
+
+ DRM_DEBUG("offset = %u, size = %u", agp.offset, agp.size);
+
+ return 0;
+}
+
+int sis_ioctl_agp_alloc( DRM_IOCTL_ARGS )
+{
+ DRM_DEVICE;
+ drm_sis_private_t *dev_priv = dev->dev_private;
+ drm_sis_mem_t agp;
+ PMemBlock block;
+ int retval = 0;
+
+ if (dev_priv == NULL || dev_priv->AGPHeap == NULL)
+ return DRM_ERR(EINVAL);
+
+ DRM_COPY_FROM_USER_IOCTL(agp, (drm_sis_mem_t *)data, sizeof(agp));
+
+ block = mmAllocMem(dev_priv->AGPHeap, agp.size, 0, 0);
+ if (block) {
+ /* TODO */
+ agp.offset = block->ofs;
+ agp.free = (unsigned long)block;
+ if (!add_alloc_set(agp.context, AGP_TYPE, agp.free)) {
+ DRM_DEBUG("adding to allocation set fails\n");
+ mmFreeMem((PMemBlock)agp.free);
+ retval = -1;
+ }
+ } else {
+ agp.offset = 0;
+ agp.size = 0;
+ agp.free = 0;
+ }
+
+ DRM_COPY_TO_USER_IOCTL((drm_sis_mem_t *)data, agp, sizeof(agp));
+
+ DRM_DEBUG("alloc agp, size = %d, offset = %d\n", agp.size, agp.offset);
+
+ return retval;
+}
+
+int sis_ioctl_agp_free( DRM_IOCTL_ARGS )
+{
+ DRM_DEVICE;
+ drm_sis_private_t *dev_priv = dev->dev_private;
+ drm_sis_mem_t agp;
+
+ if (dev_priv == NULL || dev_priv->AGPHeap == NULL)
+ return DRM_ERR(EINVAL);
+
+ DRM_COPY_FROM_USER_IOCTL(agp, (drm_sis_mem_t *)data, sizeof(agp));
+
+ if (!mmBlockInHeap(dev_priv->AGPHeap, (PMemBlock)agp.free))
+ return DRM_ERR(EINVAL);
+
+ mmFreeMem((PMemBlock)agp.free);
+ if (!del_alloc_set(agp.context, AGP_TYPE, agp.free))
+ return DRM_ERR(EINVAL);
+
+ DRM_DEBUG("free agp, free = 0x%lx\n", agp.free);
+
+ return 0;
+}
+
+int sis_init_context(int context)
+{
+ int i;
+
+ for (i = 0; i < MAX_CONTEXT ; i++) {
+ if (global_ppriv[i].used &&
+ (global_ppriv[i].context == context))
+ break;
+ }
+
+ if (i >= MAX_CONTEXT) {
+ for (i = 0; i < MAX_CONTEXT ; i++) {
+ if (!global_ppriv[i].used) {
+ global_ppriv[i].context = context;
+ global_ppriv[i].used = 1;
+ global_ppriv[i].sets[0] = setInit();
+ global_ppriv[i].sets[1] = setInit();
+ DRM_DEBUG("init allocation set, socket=%d, "
+ "context = %d\n", i, context);
+ break;
+ }
+ }
+ if ((i >= MAX_CONTEXT) || (global_ppriv[i].sets[0] == NULL) ||
+ (global_ppriv[i].sets[1] == NULL))
+ {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+int sis_final_context(int context)
+{
+ int i;
+
+ for (i=0; i<MAX_CONTEXT; i++) {
+ if (global_ppriv[i].used &&
+ (global_ppriv[i].context == context))
+ break;
+ }
+
+ if (i < MAX_CONTEXT) {
+ set_t *set;
+ unsigned int item;
+ int retval;
+
+ DRM_DEBUG("find socket %d, context = %d\n", i, context);
+
+ /* Video Memory */
+ set = global_ppriv[i].sets[0];
+ retval = setFirst(set, &item);
+ while (retval) {
+ DRM_DEBUG("free video memory 0x%x\n", item);
+#if defined(__linux__) && defined(CONFIG_FB_SIS)
+ sis_free(item);
+#else
+ mmFreeMem((PMemBlock)item);
+#endif
+ retval = setNext(set, &item);
+ }
+ setDestroy(set);
+
+ /* AGP Memory */
+ set = global_ppriv[i].sets[1];
+ retval = setFirst(set, &item);
+ while (retval) {
+ DRM_DEBUG("free agp memory 0x%x\n", item);
+ mmFreeMem((PMemBlock)item);
+ retval = setNext(set, &item);
+ }
+ setDestroy(set);
+
+ global_ppriv[i].used = 0;
+ }
+
+ return 1;
+}