diff options
Diffstat (limited to 'xc')
65 files changed, 24492 insertions, 0 deletions
diff --git a/xc/config/cf/OpenBSDLib.rules b/xc/config/cf/OpenBSDLib.rules new file mode 100644 index 000000000..9037183f2 --- /dev/null +++ b/xc/config/cf/OpenBSDLib.rules @@ -0,0 +1,162 @@ +XCOMM $OpenBSD: OpenBSDLib.rules,v 1.1 2000/10/09 20:43:58 matthieu Exp $ + + + + +/* + * OpenBSD shared library rules + */ + +XCOMM $XFree86: xc/config/cf/OpenBSDLib.rules,v 1.1 2000/11/06 19:24:00 dawes Exp $ + +#ifndef UseElfFormat +#define UseElfFormat NO +#endif + +#ifndef HasSharedLibraries +#define HasSharedLibraries YES +#endif +#ifndef ForceNormalLib +#define ForceNormalLib YES +#endif + +#ifndef BaseShLibReqs +#define BaseShLibReqs /* -lc implied by $(CC) */ +#endif + +#ifndef SharedDataSeparation +#define SharedDataSeparation NO +#endif +#ifndef SharedCodeDef +#define SharedCodeDef /**/ +#endif +#ifndef SharedLibraryDef +#define SharedLibraryDef /**/ +#endif +#ifndef ShLibIncludeFile +#define ShLibIncludeFile <bsdLib.tmpl> +#endif +#ifndef SharedLibraryLoadFlags +#define SharedLibraryLoadFlags -shared PositionIndependentCFlags -Wl,-rpath,$(USRLIBDIR) +#endif +#ifndef PositionIndependentCFlags +#define PositionIndependentCFlags -fPIC +#endif +#ifndef PositionIndependentCplusplusFlags +#define PositionIndependentCplusplusFlags -fPIC +#endif +#if UseElfFormat +#ifndef ExtraLoadFlags +#ifdef UseInstalled +#define ExtraLoadFlags -Wl,-rpath,$(USRLIBDIRPATH) +#else +#define ExtraLoadFlags -Wl,-rpath,$(USRLIBDIRPATH) -Wl,-rpath-link,$(BUILDLIBDIR) +#endif +#endif +#endif +/* + * InstallSharedLibrary - generate rules to install the shared library. + * NOTE: file must be executable, hence "INSTBINFLAGS" + */ +#ifndef InstallSharedLibrary +#define InstallSharedLibrary(libname,rev,dest) @@\ +install:: Concat(lib,libname.so.rev) @@\ + MakeDir($(DESTDIR)dest) @@\ + $(INSTALL) $(INSTALLFLAGS) $(INSTBINFLAGS) Concat(lib,libname.so.rev) $(DESTDIR)dest +#endif /* InstallSharedLibrary */ + +/* + * InstallSharedLibraryData - generate rules to install the shared library data + */ +#ifndef InstallSharedLibraryData +#define InstallSharedLibraryData(libname,rev,dest) +#endif /* InstallSharedLibraryData */ + + +/* + * SharedLibraryTarget - generate rules to create a shared library; + * build it into a different name so that we do not hose people by having + * the library gone for long periods. + */ +#ifndef SharedLibraryTarget +#ifdef UseInstalled +#define LinkBuildSonameLibrary(lib) true +#else +#define LinkBuildSonameLibrary(lib) (RemoveFile($(BUILDLIBDIR)/lib); \ + cd $(BUILDLIBDIR); $(LN) $(BUILDINCTOP)/$(CURRENT_DIR)/lib .) +#endif + +#define SharedLibraryTarget(libname,rev,solist,down,up) @@\ +AllTarget(Concat(lib,libname.so.rev)) @@\ + @@\ +Concat(lib,libname.so.rev): solist @@\ + $(RM) $@~ @@\ + set -x; \ @@\ + (cd down; $(CC) -o up/$@~ $(SHLIBLDFLAGS) -Wl,-soname,$@\ @@\ + solist $(REQUIREDLIBS) BaseShLibReqs); @@\ + LinkBuildSonameLibrary($@) @@\ + $(RM) $@ @@\ + $(MV) $@~ $@ @@\ + @@\ +clean:: @@\ + $(RM) Concat(lib,libname.so.rev) + +#endif /* SharedLibraryTarget */ + + +/* + * SharedDepLibraryTarget - generate rules to create a shared library. + */ +#ifndef SharedDepLibraryTarget +#define SharedDepLibraryTarget(libname,rev,deplist,solist,down,up) @@\ +AllTarget(Concat(lib,libname.so.rev)) @@\ + @@\ +Concat(lib,libname.so.rev): deplist $(EXTRALIBRARYDEPS) @@\ + $(RM) $@~ @@\ + (cd down; $(CC) -o up/$@~ $(SHLIBLDFLAGS) solist $(REQUIREDLIBS)) @@\ + $(RM) $@ @@\ + $(MV) $@~ $@ @@\ + LinkBuildLibrary($@) @@\ + @@\ +clean:: @@\ + $(RM) Concat(lib,libname.so.rev) + +#endif /* SharedDepLibraryTarget */ + +#ifndef SharedDepModuleTarget +#define SharedDepModuleTarget(name,deps,solist) @@\ +AllTarget(name) @@\ + @@\ +name: deps @@\ + $(RM) $@~ @@\ + $(CC) -o $@~ $(SHLIBLDFLAGS) solist $(REQUIREDLIBS) @@\ + $(RM) $@ @@\ + $(MV) $@~ $@ @@\ + @@\ +clean:: @@\ + $(RM) name + +#endif /* SharedDepModuleTarget */ + +/* + * SharedLibraryDataTarget - generate rules to create shlib data file; + */ +#ifndef SharedLibraryDataTarget +#define SharedLibraryDataTarget(libname,rev,salist) +#endif /* SharedLibraryTarget */ + +/* + * DynamicModuleTarget - build a module to be dynamically loaded + */ +#ifdef DynamicModuleTarget +#undef DynamicModuleTarget +#define DynamicModuleTarget(module,modlist) @@\ +AllTarget(module) @@\ + @@\ +module: modlist @@\ + RemoveFile($@) @@\ + $(CC) -o $@ $(SHLIBLDFLAGS) modlist @@\ + @@\ +clean:: @@\ + RemoveFile(module) +#endif /* DynamicModuleTarget */ diff --git a/xc/config/cf/darwin.cf b/xc/config/cf/darwin.cf new file mode 100644 index 000000000..f3f507cac --- /dev/null +++ b/xc/config/cf/darwin.cf @@ -0,0 +1,104 @@ +XCOMM $XFree86: xc/config/cf/darwin.cf,v 1.1 2000/11/02 02:51:06 dawes Exp $ + +/* Darwin / MacOS-X configuration by John Carmack <johnc@idsoftware.com> */ + +/* imake determines the default values by parsing uname */ +#define OSName DefaultOSName +#define OSMajorVersion DefaultOSMajorVersion +#define OSMinorVersion DefaultOSMinorVersion +#define OSTeenyVersion 0 + +#define HasSnprintf YES +#define HasPutenv YES +#define HasBSD44Sockets YES +#define BuildGlxExt NO +#ifndef HasShm +# define HasShm YES +#endif + +/* + * This enables some settings for developers. + */ +#define XFree86Devel NO + +/* we don't need -lm */ +#define MathLibrary /**/ + +/* we don't have a termcap library */ +#define TermcapLibrary /**/ + +/* we don't have a dbm library */ +#define DBMLibrary /**/ + +/* our cpp isn't in /lib/cpp */ +#define CppCmd /usr/bin/cpp + +/* we have a gcc compatible compiler, but its not called gcc */ +#define CcCmd /usr/bin/cc + +/* if -c isn't passed, there are problems with the cfb libs when + * they include an object file without any symbols + */ +#define RanlibCmd ranlib -c + +/* uncommenting this line will get -g instead of -O, which builds + * a lot faster and gets debug info + */ +#if 0 +#define DefaultCDebugFlags -g +#endif + +/* default flags to pass to cc */ +#if XFree86Devel +# define DefaultCCOptions -Wall -Wpointer-arith -Wstrict-prototypes \ + -Wmissing-prototypes -Wmissing-declarations \ + -Wredundant-decls -Wnested-externs +#else +# define DefaultCCOptions -Wall -Wpointer-arith +#endif + +/* a lot of xfree86 code needs __powerpc__ to avoid doing outport asm + * + * __DARWIN__ will be used for platform specific #ifdefs that can't + * be handled by existing X defines + * + * there is an unfortunate symbol collision with the appkit for TIFFFaxBlackCodes + * + * We need to define BSD44SOCKETS to get unix domain socket namelen calculated right + */ +#define StandardDefines -D__powerpc__ -D__DARWIN__ + +/* programs/rgb/rgb.h and others needs this */ +#define HasNdbm YES + +/* set this to NO to just build the client libs, which should work without + * having to write any platform specific code. + */ +#define BuildServer YES + +/* our custom X server */ +#define XDarwinServer YES + +/* pex? bah. I'm not going to bother getting the device + * dependent part of this working. If I get the time, i'll + * get glx working instead. + */ +#define BuildPexExt NO + +/* no direct graphics extension */ +#define BuildXF86DGA NO + +/* no extra tablets and weird input devices */ +#define BuildXInputExt NO + +/* no Display Power Management extension */ +#define BuildDPMSExt NO + +/* no Render extension */ +#define BuildRender NO + +#define BuildXvExt NO + +/* include all the xfree rules */ +/* I haven't tracked down why this is needed, but it is... */ +#include <xfree86.cf> diff --git a/xc/extras/ogl-sample/README.XF86 b/xc/extras/ogl-sample/README.XF86 new file mode 100644 index 000000000..54334cff0 --- /dev/null +++ b/xc/extras/ogl-sample/README.XF86 @@ -0,0 +1,14 @@ + +This is an import of selected parts of SGI's ogl-sample distribution, +which is available from their CVS repository at :pserver:cvs@oss.sgi.com/cvs. + +Currently only the GLw components have been imported. Others may be +imported at a later date. + +When importing, use the vendor tag OGL_SAMPLE, and tag OGL_SAMPLE-yyyymmdd, +where yyyymmdd indicates the date of the snapshot from the ogl-sample +CVS repository. + + + +$XFree86: xc/extras/ogl-sample/README.XF86,v 1.2 2000/11/06 21:57:10 dawes Exp $ diff --git a/xc/extras/ogl-sample/main/doc/man/manglw/Distfile b/xc/extras/ogl-sample/main/doc/man/manglw/Distfile new file mode 100755 index 000000000..e5a9fb568 --- /dev/null +++ b/xc/extras/ogl-sample/main/doc/man/manglw/Distfile @@ -0,0 +1,13 @@ +# +# $Date: 2000/11/08 02:53:56 $ $Revision: 1.1 $ +# $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/doc/man/manglw/Attic/Distfile,v 1.1 2000/11/08 02:53:56 dawes Exp $ +# + +DISTDIR_SI = /xc/doc/man/GL/glw + +DISTFILES_SI = \ + glwcreatemdrawingarea.3gl \ + glwdrawingarea.3gl \ + glwdrawingareamakecurrent.3gl \ + glwdrawingareaswapbuffers.3gl \ + $(NULL) diff --git a/xc/extras/ogl-sample/main/doc/man/manglw/GNUmakefile b/xc/extras/ogl-sample/main/doc/man/manglw/GNUmakefile new file mode 100755 index 000000000..8806e8b2d --- /dev/null +++ b/xc/extras/ogl-sample/main/doc/man/manglw/GNUmakefile @@ -0,0 +1,85 @@ +#!gmake +# +# License Applicability. Except to the extent portions of this file are +# made subject to an alternative license as permitted in the SGI Free +# Software License B, Version 1.1 (the "License"), the contents of this +# file are subject only to the provisions of the License. You may not use +# this file except in compliance with the License. You may obtain a copy +# of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +# Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +# +# http://oss.sgi.com/projects/FreeB +# +# Note that, as provided in the License, the Software is distributed on an +# "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +# DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +# CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +# PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +# +# Original Code. The Original Code is: OpenGL Sample Implementation, +# Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +# Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +# Copyright in any portions created by third parties is as indicated +# elsewhere herein. All Rights Reserved. +# +# Additional Notice Provisions: The application programming interfaces +# established by SGI in conjunction with the Original Code are The +# OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +# April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +# 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +# Window System(R) (Version 1.3), released October 19, 1998. This software +# was created using the OpenGL(R) version 1.2.1 Sample Implementation +# published by SGI, but has not been independently verified as being +# compliant with the OpenGL(R) version 1.2.1 Specification. +# +# $Date: 2000/11/08 02:53:56 $ $Revision: 1.1 $ +# $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/doc/man/manglw/Attic/GNUmakefile,v 1.1 2000/11/08 02:53:56 dawes Exp $ + +COMMONPREF = standard +include $(ROOT)/usr/include/make/commondefs + +DEPTH = .. +LANGOPT = c +PREFIX = GLw +IDB_PATH = /usr/share/catman/g_man/cat3/glw + +MANPREF = man +include $(DEPTH)/mandefs + +APIFILE = $(ROOT)/usr/include/GL/gl.h + +VERSION = Version 1.0 +DATE = Aug 1998 +MMFLAGS = -rs2 + +LEGALSUF1 = gl# +LEGALSUF2 = gl# +LEGALSUF3 = gl# +LEGALSUF4 = gl# +LEGALSUF5 = gl# + +LOCALPRINTLISTFILTER = | sed -e '/^intro\.p$$/d' | (echo intro.p ; cat ) + +default: + $(MAKE) manpages + +headers headers_install libs libs_install apps: + +distsi: default + $(MAKE) $(COMMONPREF)$@ + +distoss: + $(MAKE) $(COMMONPREF)$@ + +manpages: $(patsubst %.gl,%.3gl,$(wildcard *.gl)) + +install: manpages + for file in *.3gl; do \ + install -D -m 644 $$file ${ROOT}/usr/man/man3/`basename $$file .3gl`.3gl ; \ + done + +clobber: + rm -f *.3gl + +include $(DEPTH)/manrules +include $(COMMONRULES) diff --git a/xc/extras/ogl-sample/main/doc/man/manglw/glwcreatemdrawingarea.gl b/xc/extras/ogl-sample/main/doc/man/manglw/glwcreatemdrawingarea.gl new file mode 100755 index 000000000..ab839f737 --- /dev/null +++ b/xc/extras/ogl-sample/main/doc/man/manglw/glwcreatemdrawingarea.gl @@ -0,0 +1,50 @@ +.\" ** +.\" ** (c) Copyright 1993, 1994, 1995, 1996 Silicon Graphics, Inc. +.\" ** +.\" ** (c) Copyright 1989, 1990, 1991 Open Software Foundation, Inc. +.\" ** All Rights Reserved. +.\" ** +.\" ** (c) Copyright 1987, 1988, 1989, by Hewlett-Packard Company +.\" ** +.\" ** (c) Copyright 1987, 1988 by Digital Equipment Corporation, +.\" ** Maynard, MA. All Rights Reserved. +.\" ** +.\" ** +.TH GLwCreateMDrawingArea 3X "" "" "" "" +.SH NAME +\fBGLwCreateMDrawingArea \(em Create a Motif/OpenGL Drawing Widget.\fP +.iX "GLwCreateMDrawingArea" +.iX "creation functions" +.sp 1 +.SH SYNOPSIS +\fB#include <X11/GLw/GLwMDrawA.h>\fP +.br +Widget \fBGLwCreateMDrawingArea\fP( Widget \fIparent\fP, + String \fIname\fP, + ArgList \fIarglist\fP, + Cardinal \fIargcount\fP ) +.fi +\fP +.SH DESCRIPTION +\fBGLwCreateMDrawingArea\fP creates an instance of a GLwMDrawingArea +widget and returns the associated widget ID. +.sp 1 +.IP "\fIparent\fP" .95i +Specifies the parent widget ID +.IP "\fIname\fP" .95i +Specifies the name of the created widget +.IP "\fIarglist\fP" .95i +Specifies the argument list +.IP "\fIargcount\fP" .95i +Specifies the number of attribute/value pairs in the argument list +(\fIarglist\fP) +.sp 1 +.PP +For a complete definition of GLwMDrawingArea and its associated resources, see +\fBGLwDrawingArea(3X)\fP. +.sp 1 +.SH RETURN VALUE +Returns the GLwMDrawingArea widget ID. +.sp 1 +.SH SEE ALSO +\fBGLwDrawingArea(3X)\fP. diff --git a/xc/extras/ogl-sample/main/doc/man/manglw/glwdrawingarea.gl b/xc/extras/ogl-sample/main/doc/man/manglw/glwdrawingarea.gl new file mode 100755 index 000000000..f25a4f5c6 --- /dev/null +++ b/xc/extras/ogl-sample/main/doc/man/manglw/glwdrawingarea.gl @@ -0,0 +1,485 @@ +.\" ** +.\" ** (c) Copyright 1993, 1994, 1995, 1996 Silicon Graphics, Inc. +.\" ** +.\" ** (c) Copyright 1989, 1990, 1991 Open Software Foundation, Inc. +.\" ** All Rights Reserved. +.\" ** +.\" ** (c) Copyright 1987, 1988, 1989, by Hewlett-Packard Company +.\" ** +.\" ** (c) Copyright 1987, 1988 by Digital Equipment Corporation, +.\" ** Maynard, MA. All Rights Reserved. +.\" ** +.\" ** +.TH GLwDrawingArea 3X "" "" "" "" +.SH NAME +\fBGLwDrawingArea, GLwMDrawingArea \(em OpenGL drawing widgets.\fP +.iX "GLwDrawingArea" "GLwMDrawingArea" +.iX "widget class" "OpenGL" "Draw" +.sp 1 +.SH SYNOPSIS +\fB#include <X11/GLw/GLwDrawA.h> +.br +\fBld ... -lGLw -lGL -l<anywidgetlibrary> -lXext -lXt -lX11 -lm +.sp +\fB#include <X11/GLw/GLwMDrawA.h> +.br +\fBld ... -lGLw -lGL -lXm -lXext -lXt -lX11 -lm +.sp 1 +.SH DESCRIPTION +\fBGLwDrawingArea\fP and \fBGLwMDrawingArea\fP are widgets suitable +for OpenGL drawing. They +provide a window with the appropriate visual and colormaps needed for +OpenGL, based on supplied parameters. GLwDrawingArea and +GLwMDrawingArea also provide +callbacks for redraw, resize, input, and initialization. +.PP +GLwDrawingArea is not a part of any widget set, but depends only on Xt. +GLwDrawingArea can be used with any widget set. GLwMDrawingArea +is identical to +GLwDrawingArea except that it is a subclass of the Motif\(Tm widget +class XmPrimitive and +has resources and defaults suitable for use with Motif. For example, +GLwMDrawingArea provides the default Motif background and foreground colors +for resources, and deals better with keyboard traversal. Although the +GLwDrawingArea widget can be used in a Motif program, it is recommended that +GLwMDrawingArea be used instead. +.PP +Since both GLwDrawingArea and GLwMDrawingArea +widgets behave almost identically, the +remainder of this manual page will refer only to GLwDrawingArea, except when +the behaviors differ. Unless explicitly stated, all statements +about GLwDrawingArea also apply to GLwMDrawingArea. +.PP +Among the information provided when creating a GLwDrawingArea is +information necessary to determine the visual. This may be provided +in three ways, all of them through resources. A specific visualInfo +structure may be passed in. (This visualInfo must have been obtained +elsewhere; it is the application designer's responsibility to make +sure that it is compatible with the OpenGL rendering done by the +application). Alternatively, an attribute list may be provided. This +attribute list is formatted identically to that used for direct open +GL programming. Finally, each attribute can be specified as an +individual resource. The latter method is the simplest, and is the +only method that works from resource files. +.PP +In addition to allocating the visual, the GLwDrawingArea will also +allocate the colormap unless one is provided by the application. (If +one is provided it is the application writer's responsibility to +guarantee compatibility between the colormap and the visual). If +an application creates multiple GLwDrawingAreas with the same visual, +the same colormap will be used. (However the colormap +will not be shared among separate applications). +.PP +Creating the widget does not actually create the window until it is +realized, and consequently, the application should not perform any +OpenGL operations +to the window immediately after creation. Instead the application +must wait until after it has realized the window. Alternatively, the +\fBginit\fP callback may be used to indicate when the window has been +created. Upon receiving this callback, the application can perform +all OpenGL initialization for the window, and can subsequently perform +other operations on it. The initialization is discussed in more +detail below. +.PP +Applications select which GLwDrawingArea they are accessing using either +\fBglXMakeCurrent\fP or the convenience function +\fBGLwDrawingAreaMakeCurrent\fP which uses a widget instead of a +display and window. If there is only one GLwDrawingArea this need +only be called once, however if there is more than one GLwDrawingArea +it should be called at the start of each callback. +Callbacks in this case include not only +callbacks provided by the widget itself, but any other callback that +leads to GL activity such as a timeout or a workproc. +.PP +If an application is using double buffering, it may call +\fBGLwDrawingAreaSwapBuffers\fP instead of \fBglXSwapBuffers\fP. This +allows the use of the widget instead of the display and window. +.ne 5 +.SS "GLwDrawingArea Classes" +GLwDrawingArea inherits behavior and resources from the \fBCore\fP class. +.br +The class pointer is \fBglwDrawingAreaWidgetClass\fP. +.br +The class name is \fBGLwDrawingArea\fP. +.PP +.ne 5 +.SS "GLwMDrawingArea Classes" +GLwMDrawingArea inherits behavior and resources from the +\fBXmPrimitive\fP and \fBCore\fP classes. +.br +The class pointer is \fBglwMDrawingAreaWidgetClass\fP. +.br +The class name is \fBGLwMDrawingArea\fP. +.sp 1 +.SS "New Resources" +The following tables define a set of widget resources used by the programmer +to specify data. The programmer can also set the resource values for the +inherited classes to set attributes for this widget. To reference a +resource by name or by class in a .Xdefaults file, remove the \fBGLwN\fP or +\fBGLwC\fP prefix and use the remaining letters. +There are two tables included. The first table includes resources +that correspond directly to the attributes used by \fBglXChooseVisual\fP. +As with \fBglXChooseVisual\fP, all Boolean resources default to FALSE +and all integer resources default to 0, except redSize, greenSize and +blueSize which default to 1. These resources can all be +set only at creation time, and are used to determine the visual. If +either the \fIGLwNattribList\fP or \fIGLwNvisualInfo\fP resource is +set, these resources are ignored. The specific meaning of these +resources is discussed in the \fBglXChooseVisual\fP manual page and +will not be discussed here. +.sp 1 +.ne 18 +.TS +center allbox; +lBp8 lBp8 lBp8 lBp8 +lp8 lp8 lp8 lp8. +Name Class Type OpenGL attribute +GLwNbufferSize GLwCBufferSize int GLX_BUFFER_SIZE +GLwNlevel GLwCLevel int GLX_LEVEL +GLwNrgba GLwCRgba Boolean GLX_RGBA +GLwNdoublebuffer GLwCDoublebuffer Boolean GLX_DOUBLEBUFFER +GLwNstereo GLwCStereo Boolean GLX_STEREO +GLwNauxBuffers GLwCAuxBuffers Boolean GLX_AUX_BUFFERS +GLwNredSize GLwCColorSize int GLX_RED_SIZE +GLwNgreenSize GLwCColorSize int GLX_GREEN_SIZE +GLwNblueSize GLwCColorSize int GLX_BLUE_SIZE +GLwNalphaSize GLwCAlphaSize int GLX_ALPHA_SIZE +GLwNdepthSize GLwCDepthSize int GLX_DEPTH_SIZE +GLwNstencilSize GLwCStencilSize int GLX_STENCIL_SIZE +GLwNaccumRedSize GLwCAccumColorSize int GLX_ACCUM_RED_SIZE +GLwNaccumGreenSize GLwCAccumColorSize int GLX_ACCUM_GREEN_SIZE +GLwNaccumBlueSize GLwCAccumColorSize int GLX_ACCUM_BLUE_SIZE +GLwNaccumAlphaSize GLwCAccumAlphaSize int GLX_ACCUM_ALPHA_SIZE +.TE +.sp 1 +.PP +The following table lists other resources of the GLwDrawingArea +widget. each of these will be described subsequently. +The codes in the access column indicate if the given resource can be +set at creation time (\fBC\fP), +set by using \fBXtSetValues\fP (\fBS\fP), +retrieved by using \fBXtGetValues\fP (\fBG\fP), or is not applicable +(\fBN/A\fP). +.sp 1 +.ne 12 +.TS +center; +lp8B lp8B lp8B lp8B lp8B +lp8 lp8 lp8 lp8 lp8. +Name Class Type Def Acc +_ +GLwNallocateBackground GLwCAllocateColors Boolean F CG +GLwNallocateOtherColors GLwCAllocateColors Boolean F CG +GLwNattribList GLwCAttribList int * NULL CG +GLwNexposeCallback GLwCCallback XtCallbackList NULL C +GLwNginitCallback GLwCCallback XtCallbackList NULL C +GLwNinputCallback GLwCCallback XtCallbackList NULL C +GLwNinstallBackground GLwCInstallBackground Boolean T CG +GLwNinstallColormap GLwCInstallColormap Boolean T CG +GLwNresizeCallback GLwCCallback XtCallbackList NULL C +GLwNvisualInfo GLwCVisualInfo XVisualInfo* NULL CG +.TE +.sp 1 +.IP "\fBGLwNallocateBackground\fP" +If TRUE, the background pixel and pixmap will be allocated if +appropriate using the newly calculated colormap and visual. If FALSE, +they will retain values calculated using the parent's colormap and +visual. Applications which wish to have X clear their background for +them will usually set this to TRUE. Applications clearing their own +background will often set this to FALSE, although they may set this to +TRUE if they query the background for their own use. One reason to +leave this resource FALSE is that if color index mode is in use this +avoid using up a pixel from the newly allocated colormap. Also, on +hardware that supports only one colormap, the application may need to +do more careful color allocation to avoid flashing between the OpenGL +colormap and the default X colormap. +(Note that because of the way Xt works, the background colors +are originally calculated using the default colormap; if this resource +is set they can be recalculated correctly. If a colormap was +explicitly supplied to the widget rather than being dynamically +calculated, these resources are always calculated using that colormap.) +.IP "\fBGLwNallocateOtherColors\fP" +This is similar to \fBGLwNallocateBackground\fP, but allocates other +colors normally allocated by widgets. Although the GLwDrawingArea +and GLwMDrawingArea widget do not make use of these colors the +application may choose to query them. For the non-Motif +GLwDrawingArea widget there are no other colors allocated, so this +resource is a no-op. For the Motif GLwMDrawingArea are widget, the +XmPrimitive resources \fBXmNforeground\fP, \fBXmNhighlightColor\fP, +and \fBXmNhighlightPixmap\fP are calculated. +.IP "\fBGLwNattribList\fP" +Contains the list of attributes suitable for a call to +\fBglXChooseVisual\fP. If this resource is NULL, it is calculated +based on the attribute resources. If it is not NULL, the attribute +resources are ignored. +.IP "\fBGLwNexposeCallback\fP" +Specifies the list of callbacks that is +called when the widget receives an exposure event. +The callback reason is \fBGLwCR_EXPOSE\fP. +The callback structure also includes the exposure event. The +application will generally want to redraw the scene. +.IP "\fBGLwNginitCallback\fP" +Specifies the list of callbacks that is +called when the widget is first realized. Since no OpenGL operations can +be done before the widget is realized, this callback can be used to +perform any appropriate OpenGL initialization such as creating a context. +The callback reason is \fBGLwCR_GINIT\fP. +.IP "\fBGLwNinputCallback\fP" +Specifies the list of callbacks that is +called when the widget receives a keyboard +or mouse event. By default, the input callback is called on each key +press and key release, on each mouse button press and release, and +whenever the mouse is moved while a button is pressed. However this +can be changed by providing a different translation table. +The callback structure also includes the input event. +The callback reason is \fBGLwCR_INPUT\fP. +.IP "" +The input callback is provided as a programming convenience, as it +provides a convenient way to catch all input events. However, a more +modular program can often be obtained by providing specific actions and +translations in the application rather than using a single catch all +callback. Use of explicit translations can also provide for more +customization. +.IP "\fBGLwNinstallBackground\fP" +If set to TRUE, the background is installed on the window. If set to +FALSE, the window has no background. This resource has no effect +unless \fBGLwNallocateBackground\fP is also TRUE. +.IP "\fBGLwNinstallColormap\fP" +If set to TRUE, the widget will call \fIXSetWMColormapWindows\fP to +tell the window manager to install the colormap when the window's +shell has focus. If set to FALSE, this will not be called. For +applications with multiple GLwDrawingAreas sharing a single colormap, +it is most efficient to set this resource to TRUE for exactly one +GLwDrawingArea with each colormap. If an application needs +additional control over the order of colormaps, this resource can be +set to FALSE, with the application calling \fIXSetWMColormapWindows\fP +explicitly. +.IP "\fBGLwNresizeCallback\fP" +Specifies the list of callbacks that is +called when the GLwDrawingArea is resized. +The callback reason is \fBGLwCR_RESIZE\fP. +.IP "\fBGLwNvisualInfo\fP" +Contains a pointer to the window's visual info structure. If NULL, +the visualInfo is calculated at widget creation time based on the +\fIGLwNattributeList\fP resource (which is itself calculated from the +various resources). If \fBGLwNvisualInfo\fP is not NULL the +\fIGLwNattributList\fP and the attribute resources are ignored. +.sp 1 +.SS "Inherited Resources" +Both GLwDrawingArea and GLwMDrawingArea inherit behavior and resources +from the core superclass. Other than the behavior of the colormap and +background resources described previously, all defaults are the same as +for core. +.PP +In addition, the Motif version GLwMDrawingArea also inherits from XmPrimitive. +The behavior of the color resources has been described previously. +The \fITraversalOn\fP resource is disabled for this widget, but if +keyboard input is required it should be enabled. (Also, the +application should call \fBXmProcessTraversal(widget, XmTRAVERSE_CURRENT)\fP +whenever mouse button 1 is clicked in the widget. This is similar to +the requirements of the Motif Drawing area.) Because Motif gets +confused by having multiple visuals in one top level shell, +\fBXmNhighlightOnEnter\fP has been disabled, and +\fBXmNhighlightThickness\fP has been set to 0. +.SS "Callback Information" +A pointer to the following structure is passed to each callback: +.sp 1 +.ne 6 +.nf +.ta .25i 1.3i +\fBtypedef struct\fP +{ + \fBint\fP \fIreason\fP; + \fBXEvent\fP \fI*event\fP; + \fBDimension\fP \fIwidth, height\fP; +} \fBGLwDrawingAreaCallbackStruct\fP; +.fi +.sp 1 +.IP "\fIreason\fP" .75i +Indicates why the callback was invoked. Appropriate values are +stated in the above resource descriptions. For Motif programmers, the +values \fBGLwCR_EXPOSE\fP, \fBGLwCR_RESIZE\fP, and \fBGLwCR_INPUT\fP +are equal to \fBXmCR_EXPOSE\fP, \fBXmCR_RESIZE\fP, and +\fBXmCR_INPUT\fP respectively. \fBGLwCR_GINIT\fP does not have a +Motif equivalent. +.IP "\fIevent\fP" .75i +Points to the \fBXEvent\fP that triggered the callback. +This is NULL for \fBGLwNginitCallback and \fBGLwNresizeCallback\fP. +.IP "\fIwidth\fP and \fIheight\fP" .75i +Are set to the width and height of the window. +.br +.ne 10 +.sp 1 \"Adds space before the SS +.SS "Translations" +GLwDrawingArea has the translations listed below. +\fB +.nf +.ta 1.5i +.ne 5 +<KeyDown>: glwInput() +<KeyUp>: glwInput() +<BtnDown>: glwInput() +<BtnUp>: glwInput() +<BtnMotion>: glwInput() +.fi +.PP +GLwMDrawingArea has the following additional translation: +\fB +.nf +.ta 1.5i +<Key>osfHelp: PrimitiveHelp() +.fi +.PP +An application wishing to catch other events than these defaults can +do so by installing a different translation table. +\fP +.sp 1 \"Adds space before the SS +.SS "Action Routines" +The GLwDrawingArea has the following action routine: +.IP "\fBglwInput()\fP:" +Called whenever one of the above translations specifies that input has +occurred. Its sole purpose is to call the input callback. +.sp 1 +.SH INITIALIZATION +.PP +When the widget is initially created (e.g. through +\fBXtCreateWidget(3X)\fP) the associated window is not actually +created. Instead, window creation is delayed until the widget is +realized. However, \fBglXchooseVisual\fP is called immediately, so +information based on its results is available. +.PP +Between the time the widget is created and it is realized, +the following apply: +.TP +\(bu +No OpenGL operations can be done to the window +.TP +\(bu +No resize callbacks are generated. +.TP +\(bu +The normal window is available (XtWindow returns NULL). +.TP +\(bu +\fBGLwDrawingAreaMakeCurrent\fP (and \fBglXMakeCurrent\fP) should not +be called. +.PP +When the widget is realized, the following actions take place: +.PP +.TP +\(bu +The window is created. +.TP +\(bu +The \fBginit\fP callback is called. The user may use this callback to +perform any needed OpenGL initialization to the window. +.sp 1 +.SH NOTES +.PP +When using the input callback to receive keyboard input, the keycode +in the event must be converted to a KeySym. Use +\fBXLookupKeysym(3X)\fP or \fBXLookupString(3X)\fP to do the +conversion. Keyboard input can also be dealt using translations, in +which case no such conversion is required. +.PP +Motif programmers should keep in mind that OSF uses virtual +bindings and replaces some of the key bindings. As a common example, +if the ESC key is to be used to exit the program (as it often is in GL +programs), the translation should specify <key>osfCancel instead of +<key>Escape. +.PP +Motif programmers may also create a GLwMDrawingArea widget with the Motif +style \fBGLwCreateMDrawingArea\fP. +.sp 1 +.ne 10 +.SH EXAMPLE +Here are some code fragments that create a GLwDrawingArea widget, and manage +the appropriate callbacks. +.sp +.nf +\f(CW + #include <stdlib.h> + #include <X11/GLw/GLwDrawA.h> + static GLXContext glx_context; /* assume only one context */ + . . . + + main() + { + Arg args[10]; + int n; + + Widget parent; /* The parent of the gl widget */ + Widget glw; /* The GLwDrawingArea widget */ + . . . + + /* Create the widget using RGB mode. This can also be set + * in an X Defaults file + */ + n = 0; + XtSetArg(args[n], GLwNrgba, True); n++; + glw = XtCreateManagedWidget("glw", glwDrawingAreaWidgetClass, + parent, args, n); + XtAddCallback(glw, GLwNexposeCallback, exposeCB, NULL); + XtAddCallback(glw, GLwNresizeCallback, resizeCB, NULL); + XtAddCallback(glw, GLwNginitCallback, ginitCB, NULL); + /* Also add input callback if needed */ + . . . + } + + static void + exposeCB(Widget w, XtPointer client_data, + GLwDrawingAreaCallbackStruct *call_data) + { + GLwDrawingAreaMakeCurrent(w, glx_context); + /* redraw the display */ + } + + static void + resizeCB(Widget w, XtPointer client_data, + GLwDrawingAreaCallbackStruct *call_data) + { + GLwDrawingAreaMakeCurrent(w, glx_context); + /* perform any resize actions */ + } + + static void + ginitCB(Widget w, XtPointer client_data, + GLwDrawingAreaCallbackStruct *call_data) + { + Arg args[1]; + XVisualInfo *vi; + + XtSetArg(args[0], GLwNvisualInfo, &vi); + XtGetValues(w, args, 1); + + /* create a visual context */ + glx_context = glXCreateContext(XtDisplay(w), vi, + NULL, GL_FALSE); + GLwDrawingAreaMakeCurrent(w, glx_context); + /* Perform any necessary graphics initialization.*/ + } +\fP +.fi +.P +The Motif program need only differ by including +\fBGLwMDrawingArea.h\fP instead of \fBGLwDrawingArea.h\fP and by creating a widget of type +\fBGLwMDrawingAreaWidgetClass\fP instead of \fBGLwDrawingAreaWidgetClass\fP. As an +alternative, the Motif program could use \fBGLwCreateMDraw(3X)\fP instead. +.sp 1 +.SH WARNINGS +.PP +If a GLwDrawingArea widget is created as a child of an already realized +widget, the GLwDrawingArea widget will be created immediately, without giving +the user an opportunity to add the \fBginit\fP callback. In such a +case, initialization should be done immediately after creating the +widget rather than by using the callback. +.PP +If the non-Motif GLwDrawingArea widget is used in a Motif program and +keyboard traversal is attempted, the behavior is undefined if the user +traverses into the GLwDrawingArea widget. +.SH SEE ALSO +\fBglXChooseVisual(3G)\fP, \fBGLwDrawingAreaMakeCurrent(3X)\fP, +\fBglXMakeCurrent(3G)\fP, \fBGLwDrawingAreaSwapBuffers(3X)\fP +\fBGLwCreateMDraw(3X)\fP, \fBCore(3X)\fP, \fBXmPrimitive(3X)\fP, +\fBVirtualBindings(3X)\fP, \fBXSetWMColormapWindows(3X11)\fP +and the OpenGL spec. diff --git a/xc/extras/ogl-sample/main/doc/man/manglw/glwdrawingareamakecurrent.gl b/xc/extras/ogl-sample/main/doc/man/manglw/glwdrawingareamakecurrent.gl new file mode 100755 index 000000000..de51e4d51 --- /dev/null +++ b/xc/extras/ogl-sample/main/doc/man/manglw/glwdrawingareamakecurrent.gl @@ -0,0 +1,30 @@ +.\" ** +.\" ** (c) Copyright 1993, 1994, 1995, 1996 Silicon Graphics, Inc. +.\" ** +.\" ** (c) Copyright 1989, 1990, 1991 Open Software Foundation, Inc. +.\" ** All Rights Reserved. +.\" ** +.\" ** (c) Copyright 1987, 1988, 1989, by Hewlett-Packard Company +.\" ** +.\" ** (c) Copyright 1987, 1988 by Digital Equipment Corporation, +.\" ** Maynard, MA. All Rights Reserved. +.\" ** +.\" ** +.TH GLwDrawingAreaMakeCurrent 3X "" "" "" "" +.SH NAME +\fBGLwDrawingAreaMakeCurrent \(em Make the current GLwDrawingArea current.\fP +.iX "GLwDrawingAreaMakeCurrent" +.iX "GLwDrawingArea" +.sp 1 +.SH SYNOPSIS +\fB#include <X11/GLw/GLwDraw.h>\fP +.br +void \fBGLwDrawingAreaMakeCurrent\fP( Widget \fIw\fP, + GLXContext \fIctx\fP ) +.fi +.SH DESCRIPTION +\fBGLwDrawingAreaMakeCurrent\fP is a front end to \fBglXMakeCurrent\fP, +however instead of passing in a Display and a Window, a Widget is +passed in. +.SH SEE ALSO +\fBGLwMDrawingArea(3X)\fP, \fBglXMakeCurrent(3G)\fP. diff --git a/xc/extras/ogl-sample/main/doc/man/manglw/glwdrawingareaswapbuffers.gl b/xc/extras/ogl-sample/main/doc/man/manglw/glwdrawingareaswapbuffers.gl new file mode 100755 index 000000000..c7a28b411 --- /dev/null +++ b/xc/extras/ogl-sample/main/doc/man/manglw/glwdrawingareaswapbuffers.gl @@ -0,0 +1,30 @@ +.\" ** +.\" ** (c) Copyright 1993, 1994, 1995, 1996 Silicon Graphics, Inc. +.\" ** +.\" ** (c) Copyright 1989, 1990, 1991 Open Software Foundation, Inc. +.\" ** All Rights Reserved. +.\" ** +.\" ** (c) Copyright 1987, 1988, 1989, by Hewlett-Packard Company +.\" ** +.\" ** (c) Copyright 1987, 1988 by Digital Equipment Corporation, +.\" ** Maynard, MA. All Rights Reserved. +.\" ** +.\" ** +.TH GLwDrawingAreaSwapBuffers 3X "" "" "" "" +.SH NAME +\fBGLwDrawingAreaSwapBuffers \(em Swap buffers in a GLwDrawingArea.\fP +.iX "GLwDrawingAreaSwapBuffers" +.iX "GLwDrawingArea" +.sp 1 +.SH SYNOPSIS +\fB#include <X11/GLw/GLwDraw.h>\fP +.br +void \fBGLwDrawingAreaSwapBuffers\fP( Widget \fIw\fP ) +.br +.fi +.SH DESCRIPTION +\fBGLwDrawingAreaSwapBuffers\fP is a front end to \fBglXSwapBuffers\fP, +however instead of passing in a Display and a Window, a Widget is +passed in. +.SH SEE ALSO +\fBGLwMDrawingArea(3X)\fP, \fBglXSwapBuffers(3G)\fP. diff --git a/xc/extras/ogl-sample/main/gfx/lib/glw/Distfile b/xc/extras/ogl-sample/main/gfx/lib/glw/Distfile new file mode 100755 index 000000000..0d95e763b --- /dev/null +++ b/xc/extras/ogl-sample/main/gfx/lib/glw/Distfile @@ -0,0 +1,15 @@ +# +# $Date: 2000/11/08 02:53:56 $ $Revision: 1.1 $ +# $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/gfx/lib/glw/Attic/Distfile,v 1.1 2000/11/08 02:53:56 dawes Exp $ +# + +DISTFILES_SI = \ + GLwDrawA.h /xc/include/GL/GLwDrawA.h \ + GLwMDrawA.h /xc/include/GL/GLwMDrawA.h \ + Imakefile /xc/lib/GL/glw/Imakefile \ + GLwDrawAP.h /xc/lib/GL/glw/GLwDrawAP.h \ + GLwMDrawAP.h /xc/lib/GL/glw/GLwMDrawAP.h \ + GLwDAUtil.c /xc/lib/GL/glw/GLwDAUtil.c \ + GLwDrawA.c /xc/lib/GL/glw/GLwDrawA.c \ + GLwMDrawA.c /xc/lib/GL/glw/GLwMDrawA.c \ + $(NULL) diff --git a/xc/extras/ogl-sample/main/gfx/lib/glw/GLwDAUtil.c b/xc/extras/ogl-sample/main/gfx/lib/glw/GLwDAUtil.c new file mode 100755 index 000000000..24a8e0299 --- /dev/null +++ b/xc/extras/ogl-sample/main/gfx/lib/glw/GLwDAUtil.c @@ -0,0 +1,77 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +** $Date: 2000/11/08 02:53:56 $ $Revision: 1.1 $ +*/ +/* utility routines for GLX. + * Since these routines are used both in the Motif and X versions of + * the widget, they cannot peek directly into the structure + * + * $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/gfx/lib/glw/Attic/GLwDAUtil.c,v 1.1 2000/11/08 02:53:56 dawes Exp $ + */ + +/* $XFree86: xc/extras/ogl-sample/main/gfx/lib/glw/GLwDAUtil.c,v 1.2 2000/11/02 20:39:06 dawes Exp $ */ + +#include <X11/IntrinsicP.h> +#include <X11/StringDefs.h> +#include <GL/glx.h> +#include <GL/gl.h> + +/* + * By default only a static library is created because most of the UNIX + * loaders, if not all, complain about unresolved symbols even if the + * application doesn't use the modules in which such symbols are referenced. + * However, if your system supports libraries with weak symbols (e.g. + * Solaris, FreeBSD and Linux) it is possible to fool the loader using these + * weak symbols. + */ +#ifdef USE_XM_STUBS +#pragma weak _XmPrimitiveHighlightPixmapDefault = _Xm_Stub_Pointer_ +#pragma weak _XmHighlightColorDefault = _Xm_Stub_Pointer_ +#pragma weak _XmForegroundColorDefault = _Xm_Stub_Pointer_ +#pragma weak _XmBackgroundColorDefault = _Xm_Stub_Pointer_ +#pragma weak _XmStrings = _Xm_Stub_Pointer_ +#pragma weak xmPrimitiveClassRec = _Xm_Stub_Pointer_ + +static XtPointer _Xm_Stub_Pointer_ = NULL; +#endif + +void GLwDrawingAreaMakeCurrent (Widget w, GLXContext ctx) +{ + glXMakeCurrent (XtDisplay(w), XtWindow(w), ctx); +} + +void GLwDrawingAreaSwapBuffers (Widget w) +{ + glXSwapBuffers (XtDisplay(w), XtWindow(w)); +} diff --git a/xc/extras/ogl-sample/main/gfx/lib/glw/GLwDrawA.c b/xc/extras/ogl-sample/main/gfx/lib/glw/GLwDrawA.c new file mode 100755 index 000000000..330e63763 --- /dev/null +++ b/xc/extras/ogl-sample/main/gfx/lib/glw/GLwDrawA.c @@ -0,0 +1,738 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +** $Date: 2000/11/08 02:53:56 $ $Revision: 1.1 $ +*/ +/* +** $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/gfx/lib/glw/Attic/GLwDrawA.c,v 1.1 2000/11/08 02:53:56 dawes Exp $ +*/ + +#include <stdio.h> +#include <GL/glx.h> +#include <GL/gl.h> +#ifdef __GLX_MOTIF +#include "GLwMDrawAP.h" +#else /* not __GLX_MOTIF */ +#include "GLwDrawAP.h" +#include <X11/IntrinsicP.h> +#include <X11/StringDefs.h> +#endif /* __GLX_MOTIF */ +#include <assert.h> + +#ifdef __GLX_MOTIF +/* The MOTIF version differs only in the inclusion of the primitive + * widget class and in a vew variable and type name differences. + * Rather than put ifdefs all over the place, we just use a few defines + * to make it use motif types and names + */ +#define GLwDrawingAreaWidget GLwMDrawingAreaWidget +#define GLwDrawingAreaClassRec GLwMDrawingAreaClassRec +#define glwDrawingAreaClassRec glwMDrawingAreaClassRec +#define glwDrawingAreaWidgetClass glwMDrawingAreaWidgetClass +#define GLwDrawingAreaRec GLwMDrawingAreaRec +#endif /* __GLX_MOTIF */ + +/* forward definitions */ +/* resource default procs */ +static void createColormap(GLwDrawingAreaWidget w, + int offset, XrmValue *value); + +/* widget methods */ +static void Initialize(GLwDrawingAreaWidget req, GLwDrawingAreaWidget new, + ArgList args, Cardinal *num_args); +static void Realize(Widget w, Mask *valueMask, + XSetWindowAttributes *attributes); +static void Redraw(GLwDrawingAreaWidget w, XEvent *event, Region region); +static void Resize(GLwDrawingAreaWidget glw); +static void Destroy(GLwDrawingAreaWidget glw); + +#define offset(field) XtOffset(GLwDrawingAreaWidget, glwDrawingArea.field) + +static char defaultTranslations[] = +#ifdef __GLX_MOTIF + "<Key>osfHelp:PrimitiveHelp() \n" +#endif + "<KeyDown>: glwInput() \n\ + <KeyUp>: glwInput() \n\ + <BtnDown>: glwInput() \n\ + <BtnUp>: glwInput() \n\ + <BtnMotion>: glwInput() "; + +static void glwInput(GLwDrawingAreaWidget glw, XEvent *event, + String *, Cardinal *); + +static XtActionsRec actions[] = { + { "glwInput", (XtActionProc) glwInput }, /* key or mouse input */ +}; + +/* + * There is a bit of unusual handling of the resources here. + * Because Xt insists on allocating the colormap resource when it is + * processing the core resources (even if we redeclare the colormap + * resource here, we need to do a little trick. When Xt first allocates + * the colormap, we allow it to allocate the default one, since we have + * not yet determined the appropriate visual (which is determined from + * resources parsed after the colormap). We also let it allocate colors + * in that default colormap. + * + * In the initialize proc we calculate the actual visual. Then, we + * reobtain the colormap resource using XtGetApplicationResources in + * the initialize proc. If requested, we also reallocate colors in + * that colormap using the same method. + */ + +static XtResource resources[] = { + /* The GLX attributes. Add any new attributes here */ + + {GLwNbufferSize, GLwCBufferSize, XtRInt, sizeof (int), + offset(bufferSize), XtRImmediate, (XtPointer) 0}, + + {GLwNlevel, GLwCLevel, XtRInt, sizeof (int), + offset(level), XtRImmediate, (XtPointer) 0}, + + {GLwNrgba, GLwCRgba, XtRBoolean, sizeof (Boolean), + offset(rgba), XtRImmediate, (XtPointer) FALSE}, + + {GLwNdoublebuffer, GLwCDoublebuffer, XtRBoolean, sizeof (Boolean), + offset(doublebuffer), XtRImmediate, (XtPointer) FALSE}, + + {GLwNstereo, GLwCStereo, XtRBoolean, sizeof (Boolean), + offset(stereo), XtRImmediate, (XtPointer) FALSE}, + + {GLwNauxBuffers, GLwCAuxBuffers, XtRInt, sizeof (int), + offset(auxBuffers), XtRImmediate, (XtPointer) 0}, + + {GLwNredSize, GLwCColorSize, XtRInt, sizeof (int), + offset(redSize), XtRImmediate, (XtPointer) 1}, + + {GLwNgreenSize, GLwCColorSize, XtRInt, sizeof (int), + offset(greenSize), XtRImmediate, (XtPointer) 1}, + + {GLwNblueSize, GLwCColorSize, XtRInt, sizeof (int), + offset(blueSize), XtRImmediate, (XtPointer) 1}, + + {GLwNalphaSize, GLwCAlphaSize, XtRInt, sizeof (int), + offset(alphaSize), XtRImmediate, (XtPointer) 0}, + + {GLwNdepthSize, GLwCDepthSize, XtRInt, sizeof (int), + offset(depthSize), XtRImmediate, (XtPointer) 0}, + + {GLwNstencilSize, GLwCStencilSize, XtRInt, sizeof (int), + offset(stencilSize), XtRImmediate, (XtPointer) 0}, + + {GLwNaccumRedSize, GLwCAccumColorSize, XtRInt, sizeof (int), + offset(accumRedSize), XtRImmediate, (XtPointer) 0}, + + {GLwNaccumGreenSize, GLwCAccumColorSize, XtRInt, sizeof (int), + offset(accumGreenSize), XtRImmediate, (XtPointer) 0}, + + {GLwNaccumBlueSize, GLwCAccumColorSize, XtRInt, sizeof (int), + offset(accumBlueSize), XtRImmediate, (XtPointer) 0}, + + {GLwNaccumAlphaSize, GLwCAccumAlphaSize, XtRInt, sizeof (int), + offset(accumAlphaSize), XtRImmediate, (XtPointer) 0}, + + /* the attribute list */ + {GLwNattribList, GLwCAttribList, XtRPointer, sizeof(int *), + offset(attribList), XtRImmediate, (XtPointer) NULL}, + + /* the visual info */ + {GLwNvisualInfo, GLwCVisualInfo, GLwRVisualInfo, sizeof (XVisualInfo *), + offset(visualInfo), XtRImmediate, (XtPointer) NULL}, + +/* miscellaneous resources */ + {GLwNinstallColormap, GLwCInstallColormap, XtRBoolean, sizeof (Boolean), + offset(installColormap), XtRImmediate, (XtPointer) TRUE}, + + {GLwNallocateBackground, GLwCAllocateColors, XtRBoolean, sizeof (Boolean), + offset(allocateBackground), XtRImmediate, (XtPointer) FALSE}, + + {GLwNallocateOtherColors, GLwCAllocateColors, XtRBoolean, sizeof (Boolean), + offset(allocateOtherColors), XtRImmediate, (XtPointer) FALSE}, + + {GLwNinstallBackground, GLwCInstallBackground, XtRBoolean, sizeof (Boolean), + offset(installBackground), XtRImmediate, (XtPointer) TRUE}, + + {GLwNginitCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList), + offset(ginitCallback), XtRImmediate, (XtPointer) NULL}, + + {GLwNinputCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList), + offset(inputCallback), XtRImmediate, (XtPointer) NULL}, + + {GLwNresizeCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList), + offset(resizeCallback), XtRImmediate, (XtPointer) NULL}, + + {GLwNexposeCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList), + offset(exposeCallback), XtRImmediate, (XtPointer) NULL}, + +#ifdef __GLX_MOTIF + /* Changes to Motif primitive resources */ + {XmNtraversalOn, XmCTraversalOn, XmRBoolean, sizeof (Boolean), + XtOffset (GLwDrawingAreaWidget, primitive.traversal_on), XmRImmediate, + (XtPointer) FALSE}, + + /* highlighting is normally disabled, as when Motif tries to disable + * highlighting, it tries to reset the color back to the parent's + * background (usually Motif blue). Unfortunately, that is in a + * different colormap, and doesn't work too well. + */ + {XmNhighlightOnEnter, XmCHighlightOnEnter, XmRBoolean, sizeof (Boolean), + XtOffset (GLwDrawingAreaWidget, primitive.highlight_on_enter), + XmRImmediate, (XtPointer) FALSE}, + + {XmNhighlightThickness, XmCHighlightThickness, XmRHorizontalDimension, + sizeof (Dimension), + XtOffset (GLwDrawingAreaWidget, primitive.highlight_thickness), + XmRImmediate, (XtPointer) 0}, + +#endif /* __GLX_MOTIF */ +}; + +/* The following resources are reobtained using XtGetApplicationResources + * in the initialize proc. + */ +/* The colormap */ +static XtResource initializeResources[] = { + /* reobtain the colormap with the new visual */ + {XtNcolormap, XtCColormap, XtRColormap, sizeof(Colormap), + XtOffset(GLwDrawingAreaWidget, core.colormap), + XtRCallProc,(XtPointer) createColormap}, +}; + +/* reallocate any colors we need in the new colormap */ + +/* The background is obtained only if the allocateBackground resource is TRUE*/ +static XtResource backgroundResources[] = { +#ifdef __GLX_MOTIF + { + XmNbackground, XmCBackground, XmRPixel, + sizeof (Pixel), XtOffset(GLwDrawingAreaWidget, core.background_pixel), + XmRCallProc, (XtPointer) _XmBackgroundColorDefault + }, + { + XmNbackgroundPixmap, XmCPixmap, XmRXmBackgroundPixmap, + sizeof (Pixmap), XtOffset(GLwDrawingAreaWidget, core.background_pixmap), + XmRImmediate, (XtPointer) XmUNSPECIFIED_PIXMAP + }, + +#else /* ! __GLX_MOTIF */ + {XtNbackground, XtCBackground, XtRPixel,sizeof(Pixel), + XtOffset(GLwDrawingAreaWidget,core.background_pixel), + XtRString, (XtPointer)"XtDefaultBackground"}, + {XtNbackgroundPixmap, XtCPixmap, XtRPixmap, sizeof(Pixmap), + XtOffset(GLwDrawingAreaWidget,core.background_pixmap), + XtRImmediate, (XtPointer)XtUnspecifiedPixmap}, +#endif /* __GLX_MOTIF */ +}; + +/* The other colors such as the foreground are allocated only if + * allocateOtherColors are set. These resources only exist in Motif. + */ + +#ifdef __GLX_MOTIF +static XtResource otherColorResources[] = { + { + XmNforeground, XmCForeground, XmRPixel, + sizeof (Pixel), XtOffset(GLwDrawingAreaWidget, primitive.foreground), + XmRCallProc, (XtPointer) _XmForegroundColorDefault + }, + + { + XmNhighlightColor, XmCHighlightColor, XmRPixel, sizeof (Pixel), + XtOffset(GLwDrawingAreaWidget, primitive.highlight_color), + XmRCallProc, (XtPointer) _XmHighlightColorDefault + }, + + { + XmNhighlightPixmap, XmCHighlightPixmap, XmRPrimHighlightPixmap, + sizeof (Pixmap), + XtOffset(GLwDrawingAreaWidget, primitive.highlight_pixmap), + XmRCallProc, (XtPointer) _XmPrimitiveHighlightPixmapDefault + }, +}; +#endif /* __GLX_MOTIF */ + +struct attribInfo +{ + int offset; + int attribute; +}; + +static struct attribInfo intAttribs[] = +{ + { offset(bufferSize), GLX_BUFFER_SIZE }, + { offset(level), GLX_LEVEL }, + { offset(auxBuffers), GLX_AUX_BUFFERS }, + { offset(redSize), GLX_RED_SIZE }, + { offset(greenSize), GLX_GREEN_SIZE }, + { offset(blueSize), GLX_BLUE_SIZE }, + { offset(alphaSize), GLX_ALPHA_SIZE }, + { offset(depthSize), GLX_DEPTH_SIZE }, + { offset(stencilSize), GLX_STENCIL_SIZE }, + { offset(accumRedSize), GLX_ACCUM_RED_SIZE }, + { offset(accumGreenSize), GLX_ACCUM_GREEN_SIZE }, + { offset(accumBlueSize), GLX_ACCUM_BLUE_SIZE }, + { offset(accumAlphaSize), GLX_ACCUM_ALPHA_SIZE }, + { 0, None }, +}; + +static struct attribInfo booleanAttribs[] = +{ + { offset(rgba), GLX_RGBA }, + { offset(doublebuffer), GLX_DOUBLEBUFFER }, + { offset(stereo), GLX_STEREO }, + { 0, None }, +}; + +#undef offset + + +GLwDrawingAreaClassRec glwDrawingAreaClassRec = +{ + { /* core fields */ +#ifdef __GLX_MOTIF + /* superclass */ (WidgetClass) &xmPrimitiveClassRec, + /* class_name */ "GLwMDrawingArea", +#else /* not __GLX_MOTIF */ + /* superclass */ (WidgetClass) &widgetClassRec, + /* class_name */ "GLwDrawingArea", +#endif /* __GLX_MOTIF */ + /* widget_size */ sizeof(GLwDrawingAreaRec), + /* class_initialize */ NULL, + /* class_part_initialize */ NULL, + /* class_inited */ FALSE, + /* initialize */ (XtInitProc) Initialize, + /* initialize_hook */ NULL, + /* realize */ Realize, + /* actions */ actions, + /* num_actions */ XtNumber(actions), + /* resources */ resources, + /* num_resources */ XtNumber(resources), + /* xrm_class */ NULLQUARK, + /* compress_motion */ TRUE, + /* compress_exposure */ TRUE, + /* compress_enterleave */ TRUE, + /* visible_interest */ TRUE, + /* destroy */ (XtWidgetProc) Destroy, + /* resize */ (XtWidgetProc) Resize, + /* expose */ (XtExposeProc) Redraw, + /* set_values */ NULL, + /* set_values_hook */ NULL, + /* set_values_almost */ XtInheritSetValuesAlmost, + /* get_values_hook */ NULL, + /* accept_focus */ NULL, + /* version */ XtVersion, + /* callback_private */ NULL, + /* tm_table */ defaultTranslations, + /* query_geometry */ XtInheritQueryGeometry, + /* display_accelerator */ XtInheritDisplayAccelerator, + /* extension */ NULL + }, +#ifdef __GLX_MOTIF /* primitive resources */ + { + /* border_highlight */ XmInheritBorderHighlight, + /* border_unhighlight */ XmInheritBorderUnhighlight, + /* translations */ XtInheritTranslations, + /* arm_and_activate */ NULL, + /* get_resources */ NULL, + /* num get_resources */ 0, + /* extension */ NULL, + } +#endif /* __GLX_MOTIF */ +}; + +WidgetClass glwDrawingAreaWidgetClass = (WidgetClass)&glwDrawingAreaClassRec; + +static void error(Widget w, char *string) +{ + char buf[100]; +#ifdef __GLX_MOTIF + sprintf (buf, "GLwMDrawingArea: %s\n", string); +#else + sprintf (buf, "GLwDrawingArea: %s\n", string); +#endif + XtAppError(XtWidgetToApplicationContext(w), buf); +} + +static void warning(Widget w, char *string) +{ + char buf[100]; +#ifdef __GLX_MOTIF + sprintf (buf, "GLwMDraw: %s\n", string); +#else + sprintf (buf, "GLwDraw: %s\n", string); +#endif + XtAppWarning(XtWidgetToApplicationContext(w), buf); +} + +/* resource initialization methods */ +/* Initialize the attribList based on the attributes */ +static void createAttribList(GLwDrawingAreaWidget w) +{ + int listLength; + register struct attribInfo *ap; + int *ip; + + /* first find out how long a list we need */ + listLength=1; /* include the terminating NULL */ + for (ap = booleanAttribs; ap->attribute; ap++) + { + if (*(Boolean *)(((char *)w)+ap->offset)) + listLength++; /* one word for a boolean */ + } + for (ap = intAttribs; ap->attribute; ap++) + { + if (*(int *)(((char *)w)+ap->offset)) + listLength+=2; /* one word for an int */ + } + w->glwDrawingArea.attribList = (int *)XtMalloc(listLength*sizeof(int)); + ip = w->glwDrawingArea.attribList; + for (ap = booleanAttribs; ap->attribute; ap++) + { + if (*(Boolean *)(((char *)w)+ap->offset)) + *ip++ = ap->attribute; + } + for (ap = intAttribs; ap->attribute; ap++) + { + if (*(int *)(((char *)w)+ap->offset)) + { + *ip++ = ap->attribute; + *ip++ = *(int *)(((char *)w)+ap->offset); + } + } + *ip = None; +} + +/* Initialize the visualInfo based on the attribute list */ +static void createVisualInfo(GLwDrawingAreaWidget w) +{ + static XVisualInfo *visualInfo; + + assert(w->glwDrawingArea.attribList); + w->glwDrawingArea.visualInfo = glXChooseVisual(XtDisplay(w), + XScreenNumberOfScreen(XtScreen(w)), + w->glwDrawingArea.attribList); + if (!w->glwDrawingArea.visualInfo) + error((Widget)w,"requested visual not supported"); +} + +/* Initialize the colormap based on the visual info. + * This routine maintains a cache of visual-infos to colormaps. If two + * widgets share the same visual info, they share the same colormap. + * This function is called by the callProc of the colormap resource entry. + */ +static void createColormap(GLwDrawingAreaWidget w, + int offset, XrmValue *value) +{ + static struct cmapCache + { + Visual *visual; + Colormap cmap; + int screen; + } *cmapCache; + static int cacheEntries=0; + static int cacheMalloced=0; + + register int i; + + assert(w->glwDrawingArea.visualInfo); + + /* see if we can find it in the cache */ + for (i=0; i<cacheEntries; i++) + if (cmapCache[i].visual == w->glwDrawingArea.visualInfo->visual && + cmapCache[i].screen == w->glwDrawingArea.visualInfo->screen) + { + value->addr = (XtPointer) (&cmapCache[i].cmap); + return; + } + /* not in the cache, create a new entry */ + if (cacheEntries >= cacheMalloced) + { + /* need to malloc a new one. Since we are likely to have only a + * few colormaps, we allocate one the first time, and double + * each subsequent time. + */ + if (cacheMalloced == 0) + { + cacheMalloced = 1; + cmapCache = (struct cmapCache *)XtMalloc(sizeof(struct cmapCache)); + } + else + { + cacheMalloced <<= 1; + cmapCache = (struct cmapCache *)XtRealloc((char *) cmapCache, + sizeof(struct cmapCache)* + cacheMalloced); + } + } + + cmapCache[cacheEntries].cmap = XCreateColormap (XtDisplay(w), + RootWindow(XtDisplay(w), + w->glwDrawingArea.visualInfo->screen), + w->glwDrawingArea.visualInfo->visual, + AllocNone); + cmapCache[cacheEntries].visual = w->glwDrawingArea.visualInfo->visual; + cmapCache[cacheEntries].screen = w->glwDrawingArea.visualInfo->screen; + value->addr = (XtPointer) (&cmapCache[cacheEntries++].cmap); +} + +static void +Initialize (GLwDrawingAreaWidget req, GLwDrawingAreaWidget new, + ArgList args, Cardinal *num_args) +{ + + if (req->core.width == 0) + new->core.width = 100; + if (req->core.height == 0) + new->core.width = 100; + + /* create the attribute list if needed */ + if (new->glwDrawingArea.attribList == NULL) + { + new->glwDrawingArea.myList = TRUE; + createAttribList(new); + } + else + new->glwDrawingArea.myList = FALSE; + + /* determine the visual info if needed */ + if (new->glwDrawingArea.visualInfo == NULL) + { + new->glwDrawingArea.myVisual = TRUE; + createVisualInfo(new); + } + else + new->glwDrawingArea.myVisual = FALSE; + + new->core.depth = new->glwDrawingArea.visualInfo->depth; + + /* Reobtain the colormap and colors in it using XtGetApplicationResources*/ + XtGetApplicationResources((Widget) new, new, + initializeResources, + XtNumber(initializeResources), + args, *num_args); + + /* obtain the color resources if appropriate */ + if (req->glwDrawingArea.allocateBackground) + XtGetApplicationResources((Widget) new, new, + backgroundResources, + XtNumber(backgroundResources), + args, *num_args); + +#ifdef __GLX_MOTIF + if (req->glwDrawingArea.allocateOtherColors) + XtGetApplicationResources((Widget) new, new, + otherColorResources, + XtNumber(otherColorResources), + args, *num_args); +#endif /* __GLX_MOTIF */ + +} + +static void +Realize(Widget w, Mask *valueMask, XSetWindowAttributes *attributes) +{ + register GLwDrawingAreaWidget glw = (GLwDrawingAreaWidget)w; + GLwDrawingAreaCallbackStruct cb; + + /* if we haven't requested that the background be both installed and + * allocated, don't install it. + */ + if (!(glw->glwDrawingArea.installBackground && + glw->glwDrawingArea.allocateBackground)) + *valueMask &= ~CWBackPixel; + + XtCreateWindow (w, (unsigned int)InputOutput, + glw->glwDrawingArea.visualInfo->visual, + *valueMask, attributes); + + /* if appropriate, call XSetWMColormapWindows to install the colormap */ + if (glw->glwDrawingArea.installColormap) + { + Widget parentShell = XtParent(w); + Status status; + Window *windowsReturn; + int countReturn; + + while (parentShell && !XtIsShell(parentShell)) + parentShell = XtParent(parentShell); + if (parentShell && XtWindow(parentShell)) + { + /* check to see if there is already a property */ + status = XGetWMColormapWindows(XtDisplay(parentShell), + XtWindow(parentShell), + &windowsReturn, &countReturn); + + /* if no property, just create one */ + if (!status) + { + Window windows[2]; + windows[0] = XtWindow(w); + windows[1] = XtWindow(parentShell); + XSetWMColormapWindows(XtDisplay(parentShell), + XtWindow(parentShell), + windows, 2); + } + /* there was a property, add myself to the beginning */ + else + { + Window *windows = (Window *)XtMalloc((sizeof(Window))* + (countReturn+1)); + register int i; + windows[0] = XtWindow(w); + for (i=0; i<countReturn; i++) + windows[i+1] = windowsReturn[i]; + XSetWMColormapWindows(XtDisplay(parentShell), + XtWindow(parentShell), + windows, countReturn+1); + XtFree((char *) windows); + XFree((char *) windowsReturn); + } + } + else + warning((Widget)w, + "Could not set colormap property on parent shell"); + } + cb.reason = GLwCR_GINIT; + cb.event = NULL; + cb.width = glw->core.width; + cb.height = glw->core.height; + XtCallCallbackList((Widget) glw, glw->glwDrawingArea.ginitCallback, &cb); +} + +static void +Redraw(GLwDrawingAreaWidget w, XEvent *event, Region region) +{ + GLwDrawingAreaCallbackStruct cb; + XtCallbackList cblist; + + cb.reason = GLwCR_EXPOSE; + cb.event = event; + cb.width = w->core.width; + cb.height = w->core.height; + XtCallCallbackList ((Widget) w, w->glwDrawingArea.exposeCallback, &cb); +} + +static void +Resize(GLwDrawingAreaWidget glw) +{ + GLwDrawingAreaCallbackStruct cb; + + /* if we get a resize event before being realized, we can't handle it */ + if (!XtIsRealized((Widget)glw)) + return; + cb.reason = GLwCR_RESIZE; + cb.event = NULL; + cb.width = glw->core.width; + cb.height = glw->core.height; + XtCallCallbackList ((Widget) glw, glw->glwDrawingArea.resizeCallback, &cb); +} + +static void +Destroy(GLwDrawingAreaWidget glw) +{ + if (glw->glwDrawingArea.myList && glw->glwDrawingArea.attribList) + XtFree ((XtPointer)glw->glwDrawingArea.attribList); + if (glw->glwDrawingArea.myVisual && glw->glwDrawingArea.visualInfo) + XFree ((XtPointer)glw->glwDrawingArea.visualInfo); + + /* if my colormap was installed, remove it */ + if (glw->glwDrawingArea.installColormap) + { + Widget parentShell = XtParent(glw); + Status status; + Window *windowsReturn; + int countReturn; + register int i; + + /* find the parent shell */ + while (parentShell && !XtIsShell(parentShell)) + parentShell = XtParent(parentShell); + + if (parentShell && XtWindow(parentShell)) + { + /* make sure there is a property */ + status = XGetWMColormapWindows(XtDisplay(parentShell), + XtWindow(parentShell), + &windowsReturn, &countReturn); + + /* if no property, just return. If there was a property, + * continue + */ + if (status) + { + /* search for a match */ + for (i=0; i<countReturn; i++) + { + if (windowsReturn[i] == XtWindow(glw)) + { + /* we found a match, now copu the rest down */ + for (i++; i<countReturn; i++) + { + windowsReturn[i-1] = windowsReturn[i]; + } + XSetWMColormapWindows(XtDisplay(parentShell), + XtWindow(parentShell), + windowsReturn, countReturn-1); + break; /* from outer for */ + } + } + XFree((char *) windowsReturn); + } + } + } +} + +/* Action routine for keyboard and mouse events */ +/* ARGSUSED */ +static void glwInput (GLwDrawingAreaWidget glw, XEvent *event, + String * params, Cardinal * numParams) +{ + GLwDrawingAreaCallbackStruct cb; + + cb.reason = GLwCR_INPUT; + cb.event = event; + cb.width = glw->core.width; + cb.height = glw->core.height; + XtCallCallbackList ((Widget) glw, glw->glwDrawingArea.inputCallback, &cb); +} + +#ifdef __GLX_MOTIF +/* Provide a Motif-style create routine */ +Widget GLwCreateMDrawingArea(Widget parent, char *name, + ArgList arglist, Cardinal argcount) +{ + return (XtCreateWidget (name, glwMDrawingAreaWidgetClass, parent, arglist, + argcount)); +} +#endif diff --git a/xc/extras/ogl-sample/main/gfx/lib/glw/GLwDrawA.h b/xc/extras/ogl-sample/main/gfx/lib/glw/GLwDrawA.h new file mode 100755 index 000000000..3408a1999 --- /dev/null +++ b/xc/extras/ogl-sample/main/gfx/lib/glw/GLwDrawA.h @@ -0,0 +1,228 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +** $Date: 2000/11/08 02:53:56 $ $Revision: 1.1 $ +*/ +/* +** $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/gfx/lib/glw/Attic/GLwDrawA.h,v 1.1 2000/11/08 02:53:56 dawes Exp $ +*/ + +/* +** This file has been slightly modified from the original by Carlos A. M. dos +** Santos <casantos@cpmet.ufpel.tche.br> for integration into XFree86 source +** tree and for generating both Motif(TM) 1.2 and 2.x versions of the widgets +** in the same library. +*/ +/* $XFree86: xc/extras/ogl-sample/main/gfx/lib/glw/GLwDrawA.h,v 1.2 2000/11/02 20:39:07 dawes Exp $ */ + +#ifndef _GLwDrawA_h +#define _GLwDrawA_h + +#ifdef __GLX_MOTIF +# ifndef __GLX_INCLUDE_XM_H /* Defined during library compilation */ +# include <Xm/Xm.h> /* We need to know about XmVERSION early */ +# endif +#endif + +#include <GL/glx.h> +#include <GL/gl.h> + +/**************************************************************** + * + * GLwDrawingArea widgets + * + ****************************************************************/ + +/* Resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + attribList AttribList int * NULL + visualInfo VisualInfo VisualInfo NULL + installColormap InstallColormap Boolean TRUE + allocateBackground AllocateColors Boolean FALSE + allocateOtherColors AllocateColors Boolean FALSE + installBackground InstallBackground Boolean TRUE + exposeCallback Callback Pointer NULL + ginitCallback Callback Pointer NULL + inputCallback Callback Pointer NULL + resizeCallback Callback Pointer NULL + +*** The following resources all correspond to the GLX configuration +*** attributes and are used to create the attribList if it is NULL + bufferSize BufferSize int 0 + level Level int 0 + rgba Rgba Boolean FALSE + doublebuffer Doublebuffer Boolean FALSE + stereo Stereo Boolean FALSE + auxBuffers AuxBuffers int 0 + redSize ColorSize int 1 + greenSize ColorSize int 1 + blueSize ColorSize int 1 + alphaSize AlphaSize int 0 + depthSize DepthSize int 0 + stencilSize StencilSize int 0 + accumRedSize AccumColorSize int 0 + accumGreenSize AccumColorSize int 0 + accumBlueSize AccumColorSize int 0 + accumAlphaSize AccumAlphaSize int 0 +*/ + +#define GLwNattribList "attribList" +#define GLwCAttribList "AttribList" +#define GLwNvisualInfo "visualInfo" +#define GLwCVisualInfo "VisualInfo" +#define GLwRVisualInfo "VisualInfo" + +#define GLwNinstallColormap "installColormap" +#define GLwCInstallColormap "InstallColormap" +#define GLwNallocateBackground "allocateBackground" +#define GLwNallocateOtherColors "allocateOtherColors" +#define GLwCAllocateColors "AllocateColors" +#define GLwNinstallBackground "installBackground" +#define GLwCInstallBackground "InstallBackground" + +#define GLwCCallback "Callback" +#define GLwNexposeCallback "exposeCallback" +#define GLwNginitCallback "ginitCallback" +#define GLwNresizeCallback "resizeCallback" +#define GLwNinputCallback "inputCallback" + +#define GLwNbufferSize "bufferSize" +#define GLwCBufferSize "BufferSize" +#define GLwNlevel "level" +#define GLwCLevel "Level" +#define GLwNrgba "rgba" +#define GLwCRgba "Rgba" +#define GLwNdoublebuffer "doublebuffer" +#define GLwCDoublebuffer "Doublebuffer" +#define GLwNstereo "stereo" +#define GLwCStereo "Stereo" +#define GLwNauxBuffers "auxBuffers" +#define GLwCAuxBuffers "AuxBuffers" +#define GLwNredSize "redSize" +#define GLwNgreenSize "greenSize" +#define GLwNblueSize "blueSize" +#define GLwCColorSize "ColorSize" +#define GLwNalphaSize "alphaSize" +#define GLwCAlphaSize "AlphaSize" +#define GLwNdepthSize "depthSize" +#define GLwCDepthSize "DepthSize" +#define GLwNstencilSize "stencilSize" +#define GLwCStencilSize "StencilSize" +#define GLwNaccumRedSize "accumRedSize" +#define GLwNaccumGreenSize "accumGreenSize" +#define GLwNaccumBlueSize "accumBlueSize" +#define GLwCAccumColorSize "AccumColorSize" +#define GLwNaccumAlphaSize "accumAlphaSize" +#define GLwCAccumAlphaSize "AccumAlphaSize" + +#ifdef __GLX_MOTIF + +#if XmVERSION == 1 +/* +# define _GLwMDrawingAreaClassRec _GLwM1DrawingAreaClassRec +# define _GLwMDrawingAreaRec _GLwM1DrawingAreaRec +*/ +# define glwMDrawingAreaWidgetClass glwM1DrawingAreaWidgetClass +# define GLwCreateMDrawingArea GLwCreateM1DrawingArea +#elif XmVERSION == 2 +/* +# define _GLwMDrawingAreaClassRec _GLwM2DrawingAreaClassRec +# define _GLwMDrawingAreaRec _GLwM2DrawingAreaRec +*/ +# define glwMDrawingAreaWidgetClass glwM2DrawingAreaWidgetClass +# define GLwCreateMDrawingArea GLwCreateM2DrawingArea +#else +#error "Sorry, unknown Motif version." +#endif /* XmVERSION */ + +typedef struct _GLwMDrawingAreaClassRec *GLwMDrawingAreaWidgetClass; +typedef struct _GLwMDrawingAreaRec *GLwMDrawingAreaWidget; + +extern WidgetClass glwMDrawingAreaWidgetClass; + +#else /* not __GLX_MOTIF */ + +typedef struct _GLwDrawingAreaClassRec *GLwDrawingAreaWidgetClass; +typedef struct _GLwDrawingAreaRec *GLwDrawingAreaWidget; + +extern WidgetClass glwDrawingAreaWidgetClass; + +#endif /* __GLX_MOTIF */ + +/* Callback reasons */ +#ifdef __GLX_MOTIF +#define GLwCR_EXPOSE XmCR_EXPOSE +#define GLwCR_RESIZE XmCR_RESIZE +#define GLwCR_INPUT XmCR_INPUT +#else /* not __GLX_MOTIF */ +/* The same values as Motif, but don't use Motif constants */ +#define GLwCR_EXPOSE 38 +#define GLwCR_RESIZE 39 +#define GLwCR_INPUT 40 +#endif /* __GLX_MOTIF */ + +#define GLwCR_GINIT 32135 /* Arbitrary number that should neverr clash*/ + +typedef struct +{ + int reason; + XEvent *event; + Dimension width, height; /* for resize callback */ +} GLwDrawingAreaCallbackStruct; + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/* front ends to glXMakeCurrent and glXSwapBuffers */ +extern void GLwDrawingAreaMakeCurrent (Widget w, GLXContext ctx); +extern void GLwDrawingAreaSwapBuffers (Widget w); + +#ifdef __GLX_MOTIF +#ifdef _NO_PROTO +extern Widget GLwCreateMDrawingArea (); +#else /* _NO_PROTO */ + +extern Widget GLwCreateMDrawingArea (Widget parent, char *name, + ArgList arglist, Cardinal argcount); +#endif /* _NO_PROTO */ + +#endif /* __GLX_MOTIF */ + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* _GLwDrawA_h */ diff --git a/xc/extras/ogl-sample/main/gfx/lib/glw/GLwDrawAP.h b/xc/extras/ogl-sample/main/gfx/lib/glw/GLwDrawAP.h new file mode 100755 index 000000000..2e9e7d482 --- /dev/null +++ b/xc/extras/ogl-sample/main/gfx/lib/glw/GLwDrawAP.h @@ -0,0 +1,131 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +** $Date: 2000/11/08 02:53:56 $ $Revision: 1.1 $ +*/ +/* +** $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/gfx/lib/glw/Attic/GLwDrawAP.h,v 1.1 2000/11/08 02:53:56 dawes Exp $ +*/ + +/* +** This file has been slightly modified from the original by Carlos A. M. dos +** Santos <casantos@cpmet.ufpel.tche.br> for integration into XFree86 source +** tree and for generating both Motif(TM) 1.2 and 2.x versions of the widgets +** in the same library. +*/ +/* $XFree86: xc/extras/ogl-sample/main/gfx/lib/glw/GLwDrawAP.h,v 1.2 2000/11/02 20:39:07 dawes Exp $ */ + +#ifndef _GLwDrawAP_h +#define _GLwDrawAP_h + +#ifdef __GLX_MOTIF +# ifndef __GLX_INCLUDE_PRIMITIVE_P_H /* Used during library compilation */ +# include <Xm/PrimitiveP.h> +# endif +# include <GL/GLwMDrawA.h> /* includes IntrinsicP.h */ +#else +# include <X11/IntrinsicP.h> +# include <GL/GLwDrawA.h> +#endif + +typedef struct _GLwDrawingAreaClassPart +{ + char* extension; +} GLwDrawingAreaClassPart; + +#ifdef __GLX_MOTIF +typedef struct _GLwMDrawingAreaClassRec { + CoreClassPart core_class; + XmPrimitiveClassPart primitive_class; + GLwDrawingAreaClassPart glwDrawingArea_class; +} GLwMDrawingAreaClassRec; + +extern GLwMDrawingAreaClassRec glwMDrawingAreaClassRec; + +#else /* not __GLX_MOTIF */ + +typedef struct _GLwDrawingAreaClassRec { + CoreClassPart core_class; + GLwDrawingAreaClassPart glwDrawingArea_class; +} GLwDrawingAreaClassRec; + +extern GLwDrawingAreaClassRec glwDrawingAreaClassRec; +#endif /* __GLX_MOTIF */ + +typedef struct { + /* resources */ + int * attribList; + XVisualInfo * visualInfo; + Boolean myList; /* TRUE if we malloced the attribList*/ + Boolean myVisual; /* TRUE if we created the visualInfo*/ + Boolean installColormap; + Boolean allocateBackground; + Boolean allocateOtherColors; + Boolean installBackground; + XtCallbackList ginitCallback; + XtCallbackList resizeCallback; + XtCallbackList exposeCallback; + XtCallbackList inputCallback; + /* specific attributes; add as we get new attributes */ + int bufferSize; + int level; + Boolean rgba; + Boolean doublebuffer; + Boolean stereo; + int auxBuffers; + int redSize; + int greenSize; + int blueSize; + int alphaSize; + int depthSize; + int stencilSize; + int accumRedSize; + int accumGreenSize; + int accumBlueSize; + int accumAlphaSize; +} GLwDrawingAreaPart; + +#ifdef __GLX_MOTIF +typedef struct _GLwMDrawingAreaRec { + CorePart core; + XmPrimitivePart primitive; + GLwDrawingAreaPart glwDrawingArea; +} GLwMDrawingAreaRec; +#else /* not __GLX_MOTIF */ +typedef struct _GLwDrawingAreaRec { + CorePart core; + GLwDrawingAreaPart glwDrawingArea; +} GLwDrawingAreaRec; +#endif /* __GLX_MOTIF */ + +#endif /* _GLwDrawP_h */ diff --git a/xc/extras/ogl-sample/main/gfx/lib/glw/GLwMDrawA.c b/xc/extras/ogl-sample/main/gfx/lib/glw/GLwMDrawA.c new file mode 100755 index 000000000..215ece61d --- /dev/null +++ b/xc/extras/ogl-sample/main/gfx/lib/glw/GLwMDrawA.c @@ -0,0 +1,43 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +** $Date: 2000/11/08 02:53:56 $ $Revision: 1.1 $ +*/ +/* +** $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/gfx/lib/glw/Attic/GLwMDrawA.c,v 1.1 2000/11/08 02:53:56 dawes Exp $ +*/ + +#ifndef __GLX_MOTIF +#define __GLX_MOTIF 1 +#endif +#include "GLwDrawA.c" diff --git a/xc/extras/ogl-sample/main/gfx/lib/glw/GLwMDrawA.h b/xc/extras/ogl-sample/main/gfx/lib/glw/GLwMDrawA.h new file mode 100755 index 000000000..ba2265307 --- /dev/null +++ b/xc/extras/ogl-sample/main/gfx/lib/glw/GLwMDrawA.h @@ -0,0 +1,51 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +** $Date: 2000/11/08 02:53:56 $ $Revision: 1.1 $ +*/ +/* +** $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/gfx/lib/glw/Attic/GLwMDrawA.h,v 1.1 2000/11/08 02:53:56 dawes Exp $ +*/ + +/* +** This file has been slightly modified from the original by Carlos A. M. dos +** Santos <casantos@cpmet.ufpel.tche.br> for integration into XFree86 source +** tree and for generating both Motif(TM) 1.2 and 2.x versions of the widgets +** in the same library. +*/ +/* $XFree86: xc/extras/ogl-sample/main/gfx/lib/glw/GLwMDrawA.h,v 1.2 2000/11/02 20:39:07 dawes Exp $ */ + +#ifndef __GLX_MOTIF +#define __GLX_MOTIF 1 +#endif +#include <GL/GLwDrawA.h> diff --git a/xc/extras/ogl-sample/main/gfx/lib/glw/GLwMDrawAP.h b/xc/extras/ogl-sample/main/gfx/lib/glw/GLwMDrawAP.h new file mode 100755 index 000000000..2541bd4b4 --- /dev/null +++ b/xc/extras/ogl-sample/main/gfx/lib/glw/GLwMDrawAP.h @@ -0,0 +1,51 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +** $Date: 2000/11/08 02:53:56 $ $Revision: 1.1 $ +*/ +/* +** $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/gfx/lib/glw/Attic/GLwMDrawAP.h,v 1.1 2000/11/08 02:53:56 dawes Exp $ +*/ + +/* +** This file has been slightly modified from the original by Carlos A. M. dos +** Santos <casantos@cpmet.ufpel.tche.br> for integration into XFree86 source +** tree and for generating both Motif(TM) 1.2 and 2.x versions of the widgets +** in the same library. +*/ +/* $XFree86: xc/extras/ogl-sample/main/gfx/lib/glw/GLwMDrawAP.h,v 1.2 2000/11/02 20:39:07 dawes Exp $ */ + +#ifndef __GLX_MOTIF +#define __GLX_MOTIF 1 +#endif +#include <GL/GLwDrawAP.h> diff --git a/xc/extras/ogl-sample/main/gfx/lib/glw/GNUmakefile b/xc/extras/ogl-sample/main/gfx/lib/glw/GNUmakefile new file mode 100755 index 000000000..719638855 --- /dev/null +++ b/xc/extras/ogl-sample/main/gfx/lib/glw/GNUmakefile @@ -0,0 +1,76 @@ +#!gmake +# +# License Applicability. Except to the extent portions of this file are +# made subject to an alternative license as permitted in the SGI Free +# Software License B, Version 1.1 (the "License"), the contents of this +# file are subject only to the provisions of the License. You may not use +# this file except in compliance with the License. You may obtain a copy +# of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +# Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +# +# http://oss.sgi.com/projects/FreeB +# +# Note that, as provided in the License, the Software is distributed on an +# "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +# DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +# CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +# PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +# +# Original Code. The Original Code is: OpenGL Sample Implementation, +# Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +# Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +# Copyright in any portions created by third parties is as indicated +# elsewhere herein. All Rights Reserved. +# +# Additional Notice Provisions: The application programming interfaces +# established by SGI in conjunction with the Original Code are The +# OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +# April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +# 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +# Window System(R) (Version 1.3), released October 19, 1998. This software +# was created using the OpenGL(R) version 1.2.1 Sample Implementation +# published by SGI, but has not been independently verified as being +# compliant with the OpenGL(R) version 1.2.1 Specification. +# +# $Date: 2000/11/08 02:53:56 $ $Revision: 1.1 $ +# $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/gfx/lib/glw/Attic/GNUmakefile,v 1.1 2000/11/08 02:53:56 dawes Exp $ + +include $(ROOT)/usr/include/make/commondefs + +TARGET = libGLw.a + +TARGETS = $(TARGET) + +CFILES = \ + GLwDrawA.c \ + $(NULL) + +MOTIF_CFILES = \ + GLwMDrawA.c \ + GLwDAUtil.c \ + $(NULL) + +ifeq ($(HAVE_MOTIF),1) +LCDEFS += -D__GLX_MOTIF=1 +CFILES += $(MOTIF_CFILES) +ifeq ($(OS),Linux) +# assume motif is in / rather than $ROOT +LCINCS += -I/usr/X11R6/include +endif +endif + +INSTALLFLAGS += -srcdst + +default libs: $(TARGET) + +headers headers_install apps: + +libs_install install: default + $(INSTALL) -F $(ROOT)/usr/include/X11/GLw GLwDrawA.h + $(INSTALL) -F $(ROOT)/usr/include/X11/GLw GLwMDrawA.h + $(INSTALL) -F $(LIB_LOCATION) $(TARGET); + +$(TARGET): $(OBJECTS) + $(AR) crl $@ $(OBJECTS); + +include $(COMMONRULES) diff --git a/xc/extras/ogl-sample/main/gfx/lib/glw/Imakefile b/xc/extras/ogl-sample/main/gfx/lib/glw/Imakefile new file mode 100755 index 000000000..9d8c9000e --- /dev/null +++ b/xc/extras/ogl-sample/main/gfx/lib/glw/Imakefile @@ -0,0 +1,50 @@ +XCOMM License Applicability. Except to the extent portions of this file are +XCOMM made subject to an alternative license as permitted in the SGI Free +XCOMM Software License B, Version 1.1 (the "License"), the contents of this +XCOMM file are subject only to the provisions of the License. You may not use +XCOMM this file except in compliance with the License. You may obtain a copy +XCOMM of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +XCOMM Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +XCOMM +XCOMM http://oss.sgi.com/projects/FreeB +XCOMM +XCOMM Note that, as provided in the License, the Software is distributed on an +XCOMM "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +XCOMM DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +XCOMM CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +XCOMM PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +XCOMM +XCOMM Original Code. The Original Code is: OpenGL Sample Implementation, +XCOMM Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +XCOMM Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +XCOMM Copyright in any portions created by third parties is as indicated +XCOMM elsewhere herein. All Rights Reserved. +XCOMM +XCOMM Additional Notice Provisions: The application programming interfaces +XCOMM established by SGI in conjunction with the Original Code are The +XCOMM OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +XCOMM April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +XCOMM 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +XCOMM Window System(R) (Version 1.3), released October 19, 1998. This software +XCOMM was created using the OpenGL(R) version 1.2.1 Sample Implementation +XCOMM published by SGI, but has not been independently verified as being +XCOMM compliant with the OpenGL(R) version 1.2.1 Specification. +XCOMM + +#include <Library.tmpl> + +OBJS = \ + GLwDAUtil.o \ + GLwDrawA.o \ + GLwMDrawA.o + +INCLUDES = \ + -I$(TOP)/include \ + -I$(TOP)/include/GL + +NormalLibraryObjectRule() + +NormalLibraryTarget(GLw, $(OBJS)) + +DependTarget() +CleanTarget() diff --git a/xc/lib/GLw/GLwM1DrawA.c b/xc/lib/GLw/GLwM1DrawA.c new file mode 100644 index 000000000..ac6b38f8c --- /dev/null +++ b/xc/lib/GLw/GLwM1DrawA.c @@ -0,0 +1,55 @@ +/* + * (c) Copyright 1993, Silicon Graphics, Inc. + * ALL RIGHTS RESERVED + * Permission to use, copy, modify, and distribute this software for + * any purpose and without fee is hereby granted, provided that the above + * copyright notice appear in all copies and that both the copyright notice + * and this permission notice appear in supporting documentation, and that + * the name of Silicon Graphics, Inc. not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. + * + * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" + * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT, + * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY + * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, + * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF + * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN + * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE + * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE. + * + * + * US Government Users Restricted Rights + * Use, duplication, or disclosure by the Government is subject to + * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph + * (c)(1)(ii) of the Rights in Technical Data and Computer Software + * clause at DFARS 252.227-7013 and/or in similar or successor + * clauses in the FAR or the DOD or NASA FAR Supplement. + * Unpublished-- rights reserved under the copyright laws of the + * United States. Contractor/manufacturer is Silicon Graphics, + * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311. + * + * OpenGL(TM) is a trademark of Silicon Graphics, Inc. + */ +/* $XFree86: xc/lib/GLw/GLwM1DrawA.c,v 1.1 2000/11/02 20:39:07 dawes Exp $ */ + +#define __GLX_MOTIF 1 + +#define XmVERSION 1 +#define XmREVISION 2 +#define XmVersion (XmVERSION * 1000 + XmREVISION) +#define XmVERSION_STRING "GLwDrawingArea fake M*tif 1.X" +#define XmUPDATE_LEVEL 0 + +/* Include our fake Motif headers */ +#include "GLwXm/Xm.h" +#include "GLwXm/PrimitiveP.h" + +#define __GLX_INCLUDE_XM_H +#define __GLX_INCLUDE_PRIMITIVE_P_H + +#include "GLwDrawA.c" diff --git a/xc/lib/GLw/GLwM2DrawA.c b/xc/lib/GLw/GLwM2DrawA.c new file mode 100644 index 000000000..eb313514c --- /dev/null +++ b/xc/lib/GLw/GLwM2DrawA.c @@ -0,0 +1,55 @@ +/* + * (c) Copyright 1993, Silicon Graphics, Inc. + * ALL RIGHTS RESERVED + * Permission to use, copy, modify, and distribute this software for + * any purpose and without fee is hereby granted, provided that the above + * copyright notice appear in all copies and that both the copyright notice + * and this permission notice appear in supporting documentation, and that + * the name of Silicon Graphics, Inc. not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. + * + * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" + * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT, + * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY + * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, + * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF + * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN + * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE + * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE. + * + * + * US Government Users Restricted Rights + * Use, duplication, or disclosure by the Government is subject to + * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph + * (c)(1)(ii) of the Rights in Technical Data and Computer Software + * clause at DFARS 252.227-7013 and/or in similar or successor + * clauses in the FAR or the DOD or NASA FAR Supplement. + * Unpublished-- rights reserved under the copyright laws of the + * United States. Contractor/manufacturer is Silicon Graphics, + * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311. + * + * OpenGL(TM) is a trademark of Silicon Graphics, Inc. + */ +/* $XFree86: xc/lib/GLw/GLwM2DrawA.c,v 1.1 2000/11/02 20:39:07 dawes Exp $ */ + +#define __GLX_MOTIF 2 + +#define XmVERSION 2 +#define XmREVISION 0 +#define XmVersion (XmVERSION * 1000 + XmREVISION) +#define XmVERSION_STRING "GLwDrawingArea fake M*tif 2.X" +#define XmUPDATE_LEVEL 0 + +/* Include our fake Motif headers */ +#include "GLwXm/Xm.h" +#include "GLwXm/PrimitiveP.h" + +#define __GLX_INCLUDE_XM_H +#define __GLX_INCLUDE_PRIMITIVE_P_H + +#include "GLwDrawA.c" diff --git a/xc/lib/GLw/GLwXm/PrimitiveP.h b/xc/lib/GLw/GLwXm/PrimitiveP.h new file mode 100644 index 000000000..ccd03fa2d --- /dev/null +++ b/xc/lib/GLw/GLwXm/PrimitiveP.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2000 by 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, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE XFREE86 PROJECT 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. + * + * Except as contained in this notice, the name of the XFree86 Project shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization from the + * XFree86 Project. + */ +/* $XFree86: xc/lib/GLw/GLwXm/PrimitiveP.h,v 1.1 2000/11/02 20:39:08 dawes Exp $ */ + +/* + * This file is a fake Motif(TM) header intended to allow the compilation of + * libGLw without having a real Motif. Do not use this file to compile any + * application because it declares only a small subset of the API! + */ + +#ifndef GLWXM_PRIMITIVE_P_H +#define GLWXM_PRIMITIVE_P_H + +#include "GLwXm/XmP.h" + +/* primitive instance part */ +typedef struct { + Pixel foreground; + Dimension shadow_thickness; + Pixel top_shadow_color; + Pixmap top_shadow_pixmap; + Pixel bottom_shadow_color; + Pixmap bottom_shadow_pixmap; + Dimension highlight_thickness; + Pixel highlight_color; + Pixmap highlight_pixmap; + XtCallbackList help_callback; + XtPointer user_data; + Boolean traversal_on; + Boolean highlight_on_enter; + Boolean have_traversal; + unsigned char unit_type; + XmNavigationType navigation_type; + Boolean highlight_drawn; + Boolean highlighted; + GC highlight_GC; + GC top_shadow_GC; + GC bottom_shadow_GC; +#if XmVERSION > 1 + XtCallbackList convert_callback; + XtCallbackList popup_handler_callback; + XmDirection layout_direction; +#endif +} XmPrimitivePart; + +/* primitive class part */ +typedef struct { + XtWidgetProc border_highlight; + XtWidgetProc border_unhighlight; + String translations; + XtActionProc arm_and_activate; + XmSyntheticResource *syn_resources; + int num_syn_resources; + XtPointer extension; +} XmPrimitiveClassPart; + +/* class record */ +typedef struct _XmPrimitiveClassRec { + CoreClassPart core_class; + XmPrimitiveClassPart primitive_class; +} XmPrimitiveClassRec; + +/* declare class record */ +extern XmPrimitiveClassRec xmPrimitiveClassRec; + +#endif /* GLWXM_PRIMITIVE_P_H */ diff --git a/xc/lib/GLw/GLwXm/Xm.h b/xc/lib/GLw/GLwXm/Xm.h new file mode 100644 index 000000000..0020048b8 --- /dev/null +++ b/xc/lib/GLw/GLwXm/Xm.h @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2000 by 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, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE XFREE86 PROJECT 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. + * + * Except as contained in this notice, the name of the XFree86 Project shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization from the + * XFree86 Project. + */ +/* $XFree86: xc/lib/GLw/GLwXm/Xm.h,v 1.1 2000/11/02 20:39:08 dawes Exp $ */ + +/* + * This file is a fake Motif(TM) header intended to allow the compilation of + * libGLw without having a real Motif. Do not use this file to compile any + * application because it declares only a small subset of the API! + */ + +#ifndef GLWXM_H +#define GLWXM_H + +#include <X11/Intrinsic.h> +#include <X11/Shell.h> +#include <X11/Xatom.h> +#include "GLwXm/XmStrDefs.h" + +enum { + XmATTACH_NONE, + XmATTACH_FORM, + XmATTACH_OPPOSITE_FORM, + XmATTACH_WIDGET, + XmATTACH_OPPOSITE_WIDGET, + XmATTACH_POSITION, + XmATTACH_SELF +}; + +enum { + XmCR_NONE, + XmCR_HELP, + XmCR_VALUE_CHANGED, + XmCR_INCREMENT, + XmCR_DECREMENT, + XmCR_PAGE_INCREMENT, + XmCR_PAGE_DECREMENT, + XmCR_TO_TOP, + XmCR_TO_BOTTOM, + XmCR_DRAG, + XmCR_ACTIVATE, + XmCR_ARM, + XmCR_DISARM, + XmCR_DUMMY13, + XmCR_DUMMY14, + XmCR_DUMMY15, + XmCR_MAP, + XmCR_UNMAP, + XmCR_FOCUS, + XmCR_LOSING_FOCUS, + XmCR_MODIFYING_TEXT_VALUE, + XmCR_MOVING_INSERT_CURSOR, + XmCR_EXECUTE, + XmCR_SINGLE_SELECT, + XmCR_MULTIPLE_SELECT, + XmCR_EXTENDED_SELECT, + XmCR_BROWSE_SELECT, + XmCR_DEFAULT_ACTION, + XmCR_CLIPBOARD_DATA_REQUEST, + XmCR_CLIPBOARD_DATA_DELETE, + XmCR_CASCADING, + XmCR_OK, + XmCR_CANCEL, + XmCR_DUMMY33, + XmCR_APPLY, + XmCR_NO_MATCH, + XmCR_COMMAND_ENTERED, + XmCR_COMMAND_CHANGED, + XmCR_EXPOSE, + XmCR_RESIZE, + XmCR_INPUT, + XmCR_GAIN_PRIMARY, + XmCR_LOSE_PRIMARY, + XmCR_CREATE, + XmCR_TEAR_OFF_ACTIVATE, + XmCR_TEAR_OFF_DEACTIVATE, + XmCR_OBSCURED_TRAVERSAL, +#if XmVERSION < 2 + XmCR_PROTOCOLS +#else + XmCR_FOCUS_MOVED, + XmCR_DUMMY48, + XmCR_DUMMY49, + XmCR_DUMMY50, + XmCR_DUMMY51, + XmCR_DUMMY52, + XmCR_DUMMY53, + XmCR_REPOST, + XmCR_COLLAPSED, + XmCR_EXPANDED, + XmCR_SELECT, + XmCR_DRAG_START, + XmCR_NO_FONT, + XmCR_NO_RENDITION, + XmCR_POST, + XmCR_SPIN_NEXT, + XmCR_SPIN_PRIOR, + XmCR_SPIN_FIRST, + XmCR_SPIN_LAST, + XmCR_PAGE_SCROLLER_INCREMENT, + XmCR_PAGE_SCROLLER_DECREMENT, + XmCR_MAJOR_TAB, + XmCR_MINOR_TAB, + XmCR_PROTOCOLS = 6666 +#endif +}; + +typedef unsigned char XmDirection; + +typedef struct { + int reason; + XEvent *event; + Window window; +} XmDrawingAreaCallbackStruct; + +#define XmUNSPECIFIED_PIXMAP 2 + +typedef unsigned char XmNavigationType; + +#endif /* GLWXM_H */ diff --git a/xc/lib/GLw/GLwXm/XmP.h b/xc/lib/GLw/GLwXm/XmP.h new file mode 100644 index 000000000..6e7228805 --- /dev/null +++ b/xc/lib/GLw/GLwXm/XmP.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2000 by 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, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE XFREE86 PROJECT 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. + * + * Except as contained in this notice, the name of the XFree86 Project shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization from the + * XFree86 Project. + */ +/* $XFree86: xc/lib/GLw/GLwXm/XmP.h,v 1.1 2000/11/02 20:39:08 dawes Exp $ */ + +/* + * This file is a fake Motif(TM) header intended to allow the compilation of + * libGLw without having a real Motif. Do not use this file to compile any + * application because it declares only a small subset of the API! + */ + +#ifndef GLWXM_P_H +#define GLWXM_P_H + +#include "GLwXm/Xm.h" +#include <X11/IntrinsicP.h> + +#define XmInheritBorderHighlight ((XtWidgetProc) _XtInherit) +#define XmInheritBorderUnhighlight ((XtWidgetProc) _XtInherit) + +void _XmBackgroundColorDefault(Widget widget, int offset, XrmValue *value); +void _XmForegroundColorDefault(Widget widget, int offset, XrmValue *value); +void _XmHighlightColorDefault(Widget widget, int offset, XrmValue *value); +void _XmPrimitiveHighlightPixmapDefault(Widget widget, int offset, + XrmValue *value); + +typedef enum { + XmSYNTHETIC_NONE, + XmSYNTHETIC_LOAD +} XmImportOperator; + +typedef void (*XmExportProc)(Widget, int, XtArgVal *); + +typedef XmImportOperator (*XmImportProc)(Widget, int, XtArgVal*); + +typedef struct _XmSyntheticResource { + String resource_name; + Cardinal resource_size; + Cardinal resource_offset; + XmExportProc export_proc; + XmImportProc import_proc; +} XmSyntheticResource; + +#endif /* GLWXM_P_H */ diff --git a/xc/lib/GLw/GLwXm/XmStrDefs.h b/xc/lib/GLw/GLwXm/XmStrDefs.h new file mode 100644 index 000000000..8fe7e67fa --- /dev/null +++ b/xc/lib/GLw/GLwXm/XmStrDefs.h @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2000 by 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, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE XFREE86 PROJECT 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. + * + * Except as contained in this notice, the name of the XFree86 Project shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization from the + * XFree86 Project. + */ +/* $XFree86: xc/lib/GLw/GLwXm/XmStrDefs.h,v 1.1 2000/11/02 20:39:08 dawes Exp $ */ + +/* + * This file is a fake Motif(TM) header intended to allow the compilation of + * libGLw without having a real Motif. Do not use this file to compile any + * application because it declares only a small subset of the API! + */ + +#ifndef GLWXM_STRDEFS_H +#define GLWXM_STRDEFS_H + +#ifndef _XmConst +#define _XmConst /**/ +#endif + +#ifdef XMSTRINGDEFINES + +#define XmCBackgroundPixmap "BackgroundPixmap" +#define XmRBackgroundPixmap "BackgroundPixmap" +#define XmRBooleanDimension "BooleanDimension" +#define XmNbottomAttachment "bottomAttachment" +#define XmNbottomWidget "bottomWidget" +#define XmCForegroundThreshold "ForegroundThreshold" +#define XmNforegroundThreshold "foregroundThreshold" +#define XmCHighlightColor "HighlightColor" +#define XmNhighlightColor "highlightColor" +#define XmCHighlightOnEnter "HighlightOnEnter" +#define XmNhighlightOnEnter "highlightOnEnter" +#define XmCHighlightThickness "HighlightThickness" +#define XmNhighlightThickness "highlightThickness" +#define XmCHighlightPixmap "HighlightPixmap" +#define XmNhighlightPixmap "highlightPixmap" +#define XmRHighlightPixmap "HighlightPixmap" +#define XmRHorizontalDimension "HorizontalDimension" +#define XmNleftAttachment "leftAttachment" +#define XmNrightAttachment "rightAttachment" +#define XmRStringDirection "StringDirection" +#define XmNtopAttachment "topAttachment" +#define XmCTraversalOn "TraversalOn" +#define XmNtraversalOn "traversalOn" +#define XmRXmBackgroundPixmap "XmBackgroundPixmap" + +#else /* XMSTRINGDEFINES */ + +extern _XmConst char _XmStrings[]; + +#define XmCBackgroundPixmap ((char *)&_XmStrings[299]) +#define XmRBackgroundPixmap ((char *)&_XmStrings[10844]) +#define XmRBooleanDimension ((char *)&_XmStrings[10872]) +#define XmNbottomAttachment ((char *)&_XmStrings[5017]) +#define XmNbottomWidget ((char *)&_XmStrings[5099]) +#define XmCHighlightColor ((char *)&_XmStrings[1844]) +#define XmNhighlightColor ((char *)&_XmStrings[6996]) +#define XmCHighlightOnEnter ((char *)&_XmStrings[1859]) +#define XmNhighlightOnEnter ((char *)&_XmStrings[7011]) +#define XmCHighlightThickness ((char *)&_XmStrings[1892]) +#define XmNhighlightThickness ((char *)&_XmStrings[7044]) +#define XmCForegroundThreshold ((char *)&_XmStrings[1808]) +#define XmNforegroundThreshold ((char *)&_XmStrings[6914]) +#define XmCHighlightPixmap ((char *)&_XmStrings[1876]) +#define XmNhighlightPixmap ((char *)&_XmStrings[7028]) +#define XmRHighlightPixmap ((char *)&_XmStrings[11299]) +#define XmRHorizontalDimension ((char *)&_XmStrings[11315]) +#define XmNleftAttachment ((char *)&_XmStrings[7523]) +#define XmNrightAttachment ((char *)&_XmStrings[9077]) +#define XmRStringDirection ((char *)&_XmStrings[11981]) +#define XmNtopAttachment ((char *)&_XmStrings[10165]) +#define XmCTraversalOn ((char *)&_XmStrings[4318]) +#define XmNtraversalOn ((char *)&_XmStrings[10361]) +#define XmRXmBackgroundPixmap ((char *)&_XmStrings[12210]) + +#endif /* XMSTRINGDEFINES */ + +/* copy Xt constant definitions */ +#include <X11/StringDefs.h> + +#define XmCBackground XtCBackground +#define XmNbackground XtNbackground +#define XmNbackgroundPixmap XtNbackgroundPixmap +#define XmCBoolean XtCBoolean +#define XmRBoolean XtRBoolean +#define XmRCallProc XtRCallProc +#define XmCForeground XtCForeground +#define XmNforeground XtNforeground +#define XmRImmediate XtRImmediate +#define XmRPixel XtRPixel +#define XmCPixmap XtCPixmap +#define XmNpixmap XtNpixmap +#define XmRPixmap XtRPixmap +#define XmRPrimHighlightPixmap XmRHighlightPixmap +#define XmRString XtRString +#define XmRStringArray XtRStringArray +#define XmRStringTable XtRStringTable + +#endif /* GLWXM_STRDEFS_H */ diff --git a/xc/lib/GLw/Imakefile b/xc/lib/GLw/Imakefile new file mode 100644 index 000000000..790b242df --- /dev/null +++ b/xc/lib/GLw/Imakefile @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2000 by 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, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE XFREE86 PROJECT 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. + * + * Except as contained in this notice, the name of the XFree86 Project shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization from the + * XFree86 Project. + */ + +XCOMM $XFree86: xc/lib/GLw/Imakefile,v 1.2 2000/11/02 21:20:10 dawes Exp $ + +XCOMM +XCOMM Imakefile for GLw library - lots of modifications for XFree86 by +XCOMM Carlos A. M. dos Santos <casantos@cpmet.ufpel.tche.br> +XCOMM + +XCOMM Uncomment this and set the correct values if your Motif installation +XCOMM is out of the standard X tree and your Imake configuration is not +XCOMM correct (unfortunatelly, a common mistake). + +XCOMM MOTIF_INCLUDES = -I/usr/local/include +XCOMM MOTIF_LDFLAGS = -L/usr/local/lib + +#define DoNormalLib NormalLibGLw +#define DoSharedLib SharedLibGLw +#define DoDebugLib DebugLibGLw +#define DoProfileLib ProfileLibGLw + +#define HasSharedData NO +#define LibName GLw +#define SoRev SOGLWREV +#define IncSubdir GL + +REQUIREDLIBS = $(LDPRELIBS) $(XLIB) + +DEFINES = + +#if GLwUseXmStubs +SHAREDCODEDEF = SharedCodeDef -DUSE_XM_STUBS +#endif + +GLWSRCDIR = $(OGLSAMPLESRCDIR)/main/gfx/lib/glw + +INCLUDES = $(MOTIF_INCLUDES) -I. + +LOCAL_LDFLAGS = $(MOTIF_LDFLAGS) + +LINTLIBS = $(LINTXLIB) $(LINTXTOOL) + +HEADERS = GLwDrawA.h GLwDrawAP.h GLwMDrawA.h GLwMDrawAP.h +SRCS = GLwDrawA.c GLwM1DrawA.c GLwM2DrawA.c GLwDAUtil.c +OBJS = GLwDrawA.o GLwM1DrawA.o GLwM2DrawA.o GLwDAUtil.o + +#include <Library.tmpl> + +LinkSourceFile(GLwDAUtil.c,$(GLWSRCDIR)) +LinkSourceFile(GLwDrawA.c,$(GLWSRCDIR)) +LinkSourceFile(GLwMDrawA.c,$(GLWSRCDIR)) +LinkSourceFile(GLwDrawA.h,$(GLWSRCDIR)) +LinkSourceFile(GLwDrawAP.h,$(GLWSRCDIR)) +LinkSourceFile(GLwMDrawA.h,$(GLWSRCDIR)) +LinkSourceFile(GLwMDrawAP.h,$(GLWSRCDIR)) + +DependTarget() diff --git a/xc/lib/GLw/README.html b/xc/lib/GLw/README.html new file mode 100644 index 000000000..02b599b6a --- /dev/null +++ b/xc/lib/GLw/README.html @@ -0,0 +1,242 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<HTML> +<HEAD> +<TITLE>GL widgets for Xt/Motif - XFree86 implementation</TITLE> +<META NAME="generator" CONTENT="Only VIM and me."> +</HEAD> +<BODY BGCOLOR="#FFFFFF"> + +<!-- $XFree86: xc/lib/GLw/README.html,v 1.2 2000/11/06 21:57:10 dawes Exp $ --> + +<H1 ALIGN=CENTER>GL widgets for Xt/Motif</H1> +<H2 ALIGN=CENTER>XFree86 implementation</H1> +<P ALIGN=CENTER>by Carlos A. M. dos Santos<BR>casantos@cpmet.ufpel.tche.br</P> + +<HR NOSHADE> + +<H3>1. Introduction</H3> +<P> +This directory contains the source code for SGI's OpenGL Xt/Motif(TM) widgets, +slightly modified to generate both Motif 1.x and 2.x versions of +the widget even if Motif is not available, as in the XFree86 distribution of +the X Window System. This code is based on that distributed by Silicon +Graphics as part of it's OpenGL Sample Implementation, not on the modified version +distributed with Mesa. + + +<H3>2. Installation</H3> +<P> +This code is intended to be compiled as part of the normal XFree86 building +process, under the xc/lib/GLw directory. To compile the library out of the X +source tree, follow instructions below. + +<H3>2.1. Requirements</H3> +<P> +Gzip and tar are needed to extract the files from the distribution <A +HREF="http://www.inf.ufrgs.br/~casantos/libGLw/GLw.tar.gz">archive</A>. Tar is +a standard UNIX utility but if you don't have it use GNU tar, available in +source form at <A +HREF="ftp://ftp.gnu.org/pub/gnu/">ftp://ftp.gnu.org/pub/gnu/</A>. Gzip is not +a standard UNIX utility, though available in many systems. You may obtain it +(also source form) at the same FTP server as GNU tar. + +<P> +You need xmkmf and imake too. Depending on your operating system you may need +to install some kind of X Window System development kit, so check the vendor +documentation first. I was told that some UNIX systems don't have imake: +report this as a bug (to your vendor, not me). + +<P> +Of course you will need a C compiler. + +<H3>2.2. Steps</H3> +<P> +<OL> + <LI>Extract the source code from the distribution archive. + <P> + <CODE> + gzip -dc GLw.tar.gz | tar xf - + </CODE> + <P> + <LI>Go to the surce code directory and generate the makefile. + <P> + <CODE> + cd GLw<BR> + xmkmf + </CODE> + <P>For LessTif, use "mxmkmf" instead of "xmkmf". Imake support + is much better in recent versions of LessTif (since late july 2000). + If your Motif or OpenGL libraries and/or include files are installed in + non-standard locations (some UNIX vendors seem to be very creative :-) + then edit the file named Imakefile, remove the leading XCOMM of the + lines containing MOTIF_INCLUDES and MOTIF_LDFLAGS and set the + appropriate values. + <P> + <LI>Compile the code with + <P> + <CODE> + make includes<BR> + make standalone + </CODE> + <P> + <LI>Install the library and manual pages with + <P> + <CODE> + make install<BR> + make install.man + </CODE> + <P> + <LI>Optionally, you may compile two test programs: xmdemo and xtdemo. You need OpenGL + (or Mesa) for both and Motif (or LessTif) for xmdemo. There are four + extra make targers for these programs: demos, stand-demos, stand-xmdemo + and stand-xtdemo. You may use them with: + <P> + <CODE> + make stand-demos<BR> + ./xmdemo + ./xtdemo + </CODE> +</OL> + +<H3>2.3. Creating a shared library</H3> +<P> +By default only a static library is created because most of the UNIX loaders, +if not all, complain about unresolved symbols even if the application doesn't +use the modules in which such symbols are referenced. However, if your system +supports libraries with weak symbols (e.g. Solaris, FreeBSD and Linux) it is +possible to fool the loader. All you have to do is edit the Imakefile, +changing "#define SharedLibGLw" and "#define GLwUseXmStubs" to YES, then +repeat the compilation process starting from step 2 in the previous section. + +<H3>2.4. Problems</H3> +<P> +If you have trouble, ask for help in the XFree86 "xperts" mailing list. Look +at <A HREF="http://www.xfree86.org">http://www.xfree86.org</A> for +instructions on how to subscribe. In desperation, send an email to <A +HREF="mailto:casantos@cpmet.ufpel.tche.br">casantos@cpmet.ufpel.tche.br</A>. + +<P> +PLEASE DO NOT SEND ME EMAIL ASKING HOW TO INSTALL OR CONFIGURE YOUR OPERATING +SYSTEM, MODEM, NETWORK CARD, BREAD TOASTER, COFEE MAKER OR WHATEVER ELSE! + + +<H3>3. Copyrights</H3> +<P> +Most of the code is covered by the following license terms: +<BLOCKQUOTE> +<P> +License Applicability. Except to the extent portions of this file are +made subject to an alternative license as permitted in the SGI Free +Software License B, Version 1.1 (the "License"), the contents of this +file are subject only to the provisions of the License. You may not use +this file except in compliance with the License. You may obtain a copy +of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +<P> +<A +HREF="http://oss.sgi.com/projects/FreeB">http://oss.sgi.com/projects/FreeB</A> +<P> +Note that, as provided in the License, the Software is distributed on an +"AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +<P> +Original Code. The Original Code is: OpenGL Sample Implementation, +Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +Inc. The Original Code is Copyright © 1991-2000 Silicon Graphics, Inc. +Copyright in any portions created by third parties is as indicated +elsewhere herein. All Rights Reserved. +<P> +Additional Notice Provisions: The application programming interfaces +established by SGI in conjunction with the Original Code are The +OpenGL® Graphics System: A Specification (Version 1.2.1), released +April 1, 1999; The OpenGL® Graphics System Utility Library (Version +1.3), released November 4, 1998; and OpenGL® Graphics with the X +Window System® (Version 1.3), released October 19, 1998. This software +was created using the OpenGL® version 1.2.1 Sample Implementation +published by SGI, but has not been independently verified as being +compliant with the OpenGL® version 1.2.1 Specification. +</BLOCKQUOTE> + +<P> +The demonstration programs are covered by the following license terms: + +<BLOCKQUOTE> +<P> +Copyright © Mark J. Kilgard, 1995, 1996. + +<P> +NOTICE: This source code distribution contains source code contained in +the book "Programming OpenGL for the X Window System" (ISBN: +0-201-48359-9) published by Addison-Wesley. The programs and associated +files contained in the distribution were developed by Mark J. Kilgard and +are Copyright 1994, 1995, 1996 by Mark J. Kilgard (unless otherwise +noted). The programs are not in the public domain, but they are freely +distributable without licensing fees. These programs are provided without +guarantee or warrantee expressed or implied. +</BLOCKQUOTE> + +<P> +The files contained in directory GLwXm are fake Motif headers, covered by +the XFree86 license, they permit us to generate both Motif 1.x and 2.x +versions of the widget without having Motif. Notice that they are NOT part of +a standard Motif distribution and shall not be used to compile any other code. + + +<H3>4. Thanks</H3> + +<P> +Many thanks to Silicon Graphics and Mark J. Kilgard for making their +software free. + + +<H3>5. No thanks</H3> + +<BLOCKQUOTE> +<P> +<STRONG> +THIS SECTION CONTAINS MY PERSONAL OPINIONS AND +DOESN'T REPRESENT AN OFFICIAL POSITION OF THE XFree86 PROJECT. +</STRONG> +</BLOCKQUOTE> + +<P> +The first incarnation of this version of libGLw used eight header files from +<A HREF="http://www.lesstif.org/">LessTif</A>, four for each Motif version. +LessTif is covered by the GNU Library General Public License (LGPL) whose +terms are not compatible with the XFree86 licensing policy. Since the +copyright holder of LessTif is the <A HREF="http://www.fsf.org/">Free Software +Foundation</A> (FSF), I asked Richard Stallman, president of FSF and so called +"leader of the Free Software movement", permission to redistribute a copy of +those eight headers under XFree86 terms, still maintaining the FSF copyright. + +<P> +Observe that I was not asking him to change the license of LessTif as a whole, +but only to allow me to distribute copies of some header files containing +function prototypes, variable declarations and data type definitions. Even so, +Stallman said no because the files contained "more than 6000 lines of code". +Which code? The LessTif headers are mostly copies of the Motif ones and don't +contain any original GNU "code"! I can't still imagine a reason for Stallman's +negative answer except for paranoia. He seems to ignore what Motif is and +that LessTif's API is simply a copy of Motif's one. + +<P> +After spending some time, I made my own headers, that became much smaller than +the previous ones because I included only a subset of the Motif API and merged +everything into four files: 417 lines instead 6000. Humm, perhaps I should be +grateful to Sallman too :-). + + +<H3>6. Trademarks</H3> + +<P> +<UL> + <LI>OpenGL is a trademark of Silicon Graphics, Inc. + <LI>Motif is a trademark of the Open Group. +</UL> + +<HR NOSHADE> + +</BODY> +</HTML> diff --git a/xc/lib/GLw/README.txt b/xc/lib/GLw/README.txt new file mode 100644 index 000000000..f3eb83f3f --- /dev/null +++ b/xc/lib/GLw/README.txt @@ -0,0 +1,199 @@ + GL widgets for Xt/Motif + + XFree86 implementation + + by Carlos A. M. dos Santos + casantos@cpmet.ufpel.tche.br + + ------------------------------------------------------------------------ + +1. Introduction + +This directory contains the source code for SGI's OpenGL Xt/Motif(TM) +widgets, slightly modified to generate both Motif 1.x and 2.x versions of +the widget even if Motif is not available, as in the XFree86 distribution of +the X Window System. This code is based on that distributed by Silicon +Graphics as part of it's OpenGL Sample Implementation, not on the modified +version distributed with Mesa. + +2. Installation + +This code is intended to be compiled as part of the normal XFree86 building +process, under the xc/lib/GLw directory. To compile the library out of the X +source tree, follow instructions below. + +2.1. Requirements + +Gzip and tar are needed to extract the files from the distribution archive. +Tar is a standard UNIX utility but if you don't have it use GNU tar, +available in source form at ftp://ftp.gnu.org/pub/gnu/. Gzip is not a +standard UNIX utility, though available in many systems. You may obtain it +(also source form) at the same FTP server as GNU tar. + +You need xmkmf and imake too. Depending on your operating system you may +need to install some kind of X Window System development kit, so check the +vendor documentation first. I was told that some UNIX systems don't have +imake: report this as a bug (to your vendor, not me). + +Of course you will need a C compiler. + +2.2. Steps + + 1. Extract the source code from the distribution archive. + + gzip -dc GLw.tar.gz | tar xf - + + 2. Go to the surce code directory and generate the makefile. + + cd GLw + xmkmf + + For LessTif, use "mxmkmf" instead of "xmkmf". Imake support is much + better in recent versions of LessTif (since late july 2000). If your + Motif or OpenGL libraries and/or include files are installed in + non-standard locations (some UNIX vendors seem to be very creative :-) + then edit the file named Imakefile, remove the leading XCOMM of the + lines containing MOTIF_INCLUDES and MOTIF_LDFLAGS and set the + appropriate values. + + 3. Compile the code with + + make includes + make standalone + + 4. Install the library and manual pages with + + make install + make install.man + + 5. Optionally, you may compile two test programs: xmdemo and xtdemo. You + need OpenGL (or Mesa) for both and Motif (or LessTif) for xmdemo. There + are four extra make targers for these programs: demos, stand-demos, + stand-xmdemo and stand-xtdemo. You may use them with: + + make stand-demos + ./xmdemo ./xtdemo + +2.3. Creating a shared library + +By default only a static library is created because most of the UNIX +loaders, if not all, complain about unresolved symbols even if the +application doesn't use the modules in which such symbols are referenced. +However, if your system supports libraries with weak symbols (e.g. Solaris, +FreeBSD and Linux) it is possible to fool the loader. All you have to do is +edit the Imakefile, changing "#define SharedLibGLw" and "#define +GLwUseXmStubs" to YES, then repeat the compilation process starting from +step 2 in the previous section. + +2.4. Problems + +If you have trouble, ask for help in the XFree86 "xperts" mailing list. Look +at http://www.xfree86.org for instructions on how to subscribe. In +desperation, send an email to casantos@cpmet.ufpel.tche.br. + +PLEASE DO NOT SEND ME EMAIL ASKING HOW TO INSTALL OR CONFIGURE YOUR +OPERATING SYSTEM, MODEM, NETWORK CARD, BREAD TOASTER, COFEE MAKER OR +WHATEVER ELSE! + +3. Copyrights + +Most of the code is covered by the following license terms: + + License Applicability. Except to the extent portions of this file + are made subject to an alternative license as permitted in the SGI + Free Software License B, Version 1.1 (the "License"), the contents + of this file are subject only to the provisions of the License. + You may not use this file except in compliance with the License. + You may obtain a copy of the License at Silicon Graphics, Inc., + attn: Legal Services, 1600 Amphitheatre Parkway, Mountain View, CA + 94043-1351, or at: + + http://oss.sgi.com/projects/FreeB + + Note that, as provided in the License, the Software is distributed + on an "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND + CONDITIONS DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED + WARRANTIES AND CONDITIONS OF MERCHANTABILITY, SATISFACTORY + QUALITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. + + Original Code. The Original Code is: OpenGL Sample Implementation, + Version 1.2.1, released January 26, 2000, developed by Silicon + Graphics, Inc. The Original Code is Copyright © 1991-2000 Silicon + Graphics, Inc. Copyright in any portions created by third parties + is as indicated elsewhere herein. All Rights Reserved. + + Additional Notice Provisions: The application programming + interfaces established by SGI in conjunction with the Original + Code are The OpenGL® Graphics System: A Specification (Version + 1.2.1), released April 1, 1999; The OpenGL® Graphics System + Utility Library (Version 1.3), released November 4, 1998; and + OpenGL® Graphics with the X Window System® (Version 1.3), released + October 19, 1998. This software was created using the OpenGL® + version 1.2.1 Sample Implementation published by SGI, but has not + been independently verified as being compliant with the OpenGL® + version 1.2.1 Specification. + +The demonstration programs are covered by the following license terms: + + Copyright © Mark J. Kilgard, 1995, 1996. + + NOTICE: This source code distribution contains source code + contained in the book "Programming OpenGL for the X Window System" + (ISBN: 0-201-48359-9) published by Addison-Wesley. The programs + and associated files contained in the distribution were developed + by Mark J. Kilgard and are Copyright 1994, 1995, 1996 by Mark J. + Kilgard (unless otherwise noted). The programs are not in the + public domain, but they are freely distributable without licensing + fees. These programs are provided without guarantee or warrantee + expressed or implied. + +The files contained in directory GLwXm are fake Motif headers, covered by +the XFree86 license, they permit us to generate both Motif 1.x and 2.x +versions of the widget without having Motif. Notice that they are NOT part +of a standard Motif distribution and shall not be used to compile any other +code. + +4. Thanks + +Many thanks to Silicon Graphics and Mark J. Kilgard for making their +software free. + +5. No thanks + + THIS SECTION CONTAINS MY PERSONAL OPINIONS AND DOESN'T REPRESENT + AN OFFICIAL POSITION OF THE XFree86 PROJECT. + +The first incarnation of this version of libGLw used eight header files from +LessTif, four for each Motif version. LessTif is covered by the GNU Library +General Public License (LGPL) whose terms are not compatible with the +XFree86 licensing policy. Since the copyright holder of LessTif is the Free +Software Foundation (FSF), I asked Richard Stallman, president of FSF and so +called "leader of the Free Software movement", permission to redistribute a +copy of those eight headers under XFree86 terms, still maintaining the FSF +copyright. + +Observe that I was not asking him to change the license of LessTif as a +whole, but only to allow me to distribute copies of some header files +containing function prototypes, variable declarations and data type +definitions. Even so, Stallman said no because the files contained "more +than 6000 lines of code". Which code? The LessTif headers are mostly copies +of the Motif ones and don't contain any original GNU "code"! I can't still +imagine a reason for Stallman's negative answer except for paranoia. He +seems to ignore what Motif is and that LessTif's API is simply a copy of +Motif's one. + +After spending some time, I made my own headers, that became much smaller +than the previous ones because I included only a subset of the Motif API and +merged everything into four files: 417 lines instead 6000. Humm, perhaps I +should be grateful to Sallman too :-). + +6. Trademarks + + * OpenGL is a trademark of Silicon Graphics, Inc. + * Motif is a trademark of the Open Group. + + ------------------------------------------------------------------------ + + + +$XFree86: xc/lib/GLw/README.txt,v 1.2 2000/11/06 21:57:10 dawes Exp $ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atimisc.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/atimisc.c new file mode 100644 index 000000000..080ba715c --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atimisc.c @@ -0,0 +1,81 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimisc.c,v 1.1 2000/10/30 23:02:12 tsi Exp $ */ +/* + * Copyright 2000 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of Marc Aurele La France not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Marc Aurele La France makes no representations + * about the suitability of this software for any purpose. It is provided + * "as-is" without express or implied warranty. + * + * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO + * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef XFree86LOADER + +#include "ati.h" +#include "ativersion.h" + +/* Module loader interface for subsidiary driver module */ + +static XF86ModuleVersionInfo ATIVersionRec = +{ + ATI_DRIVER_NAME, + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XF86_VERSION_CURRENT, + ATI_VERSION_MAJOR, ATI_VERSION_MINOR, ATI_VERSION_PATCH, + ABI_CLASS_VIDEODRV, + ABI_VIDEODRV_VERSION, + MOD_CLASS_VIDEODRV, + {0, 0, 0, 0} +}; + +/* + * ATISetup -- + * + * This function is called every time the module is loaded. + */ +static pointer +ATISetup +( + pointer Module, + pointer Options, + int *ErrorMajor, + int *ErrorMinor +) +{ + static Bool Inited = FALSE; + + if (!Inited) + { + /* Ensure main driver module is loaded, but not as a submodule */ + if (!xf86ServerIsOnlyDetecting() && !LoaderSymbol(ATI_NAME)) + xf86LoadOneModule(ATI_DRIVER_NAME, Options); + + Inited = TRUE; + } + + return (pointer)TRUE; +} + +/* The following record must be called atimiscModuleData */ +XF86ModuleData atimiscModuleData = +{ + &ATIVersionRec, + ATISetup, + NULL +}; + +#endif /* XFree86LOADER */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.cpp b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.cpp new file mode 100644 index 000000000..2f5408b34 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.cpp @@ -0,0 +1,70 @@ +.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128.cpp,v 1.1 2000/11/02 16:55:29 tsi Exp $ +.\" shorthand for double quote that works everywhere. +.ds q \N'34' +.TH R128 __drivermansuffix__ "Version 4.0.1" "XFree86" +.SH NAME +r128 \- ATI Rage 128 video driver +.SH SYNOPSIS +.nf +.B "Section \*qDevice\*q" +.BI " Identifier \*q" devname \*q +.B " Driver \*qr128\*q" +\ \ ... +.B EndSection +.fi +.SH DESCRIPTION +.B r128 +is an XFree86 driver for ATI Rage 128 based video cards. It contains +full support for 8, 15, 16 and 24 bit pixel depths, hardware +acceleration of drawing primitives, hardware cursor, video modes up to +1800x1440 @ 70Hz, doublescan modes (e.g., 320x200 and 320x240), gamma +correction at all pixel depths, a fully programming dot clock and robust +text mode restoration for VT switching. +.SH SUPPORTED HARDWARE +The +.B r128 +driver supports all ATI Rage 128 based video cards including the Rage +Fury AGP 32MB, the XPERT 128 AGP 16MB and the XPERT 99 AGP 8MB. +.SH CONFIGURATION DETAILS +Please refer to XF86Config(__filemansuffix__) for general configuration +details. This section only covers configuration details specific to this +driver. +.PP +The driver auto-detects all device information necessary to initialize +the card. However, if you have problems with auto-detection, you can +specify: +.PP +.RS 4 +VideoRam - in kilobytes +.br +MemBase - physical address of the linear framebuffer +.br +IOBase - physical address of the MMIO registers +.br +ChipID - PCI DEVICE ID +.RE +.PP +In addition, the following driver +.B Options +are supported: +.TP +.BI "Option \*qSWcursor\*q \*q" boolean \*q +Selects software cursor. The default is +.B off. +.TP +.BI "Option \*qNoAccel\*q \*q" boolean \*q +Enables or disables all hardware acceleration. The default is to +.B enable +hardware acceleration. +.TP +.BI "Option \*qDac6Bit\*q \*q" boolean \*q +Enables or disables the use of 6 bits per color component when in 8 bpp +mode (emulates VGA mode). By default, all 8 bits per color component +are used. The default is +.B off. +.SH "SEE ALSO" +XFree86(1), XF86Config(__filemansuffix__), xf86config(1), Xserver(1), X(__miscmansuffix__) +.SH AUTHORS +.nf +Rickard E. (Rik) Faith \fIfaith@precisioninsight.com\fP +Kevin E. Martin \fIkevin@precisioninsight.com\fP diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h new file mode 100644 index 000000000..cde3f03f6 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h @@ -0,0 +1,395 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h,v 1.1 2000/11/02 16:55:29 tsi Exp $ */ +/* + * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario + * and Precision Insight, Inc., Cedar Park, Texas. + * + * 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 on + * 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, PRECISION INSIGHT AND/OR THEIR 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: + * Rickard E. Faith <faith@precisioninsight.com> + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#ifndef _R128_H_ +#define _R128_H_ + + /* Xv support */ +#include "xf86xv.h" +#include "Xv.h" + + /* vgahw module (for VC save/restore only) */ +#include "vgaHW.h" + +#include "fbdevhw.h" + + /* XAA and Cursor Support */ +#include "xaa.h" +#include "xaalocal.h" +#include "xf86Cursor.h" + + + /* PCI support */ +#include "xf86PciInfo.h" +#include "xf86Pci.h" + + /* DDC support */ +#include "xf86DDC.h" + + /* VESA support */ +#include "vbe.h" + + /* DRI support */ +#ifdef XF86DRI +#include "GL/glxint.h" +#include "GL/glxtokens.h" +#include "xf86drm.h" +#include "xf86drmR128.h" +#include "sarea.h" +#define _XF86DRI_SERVER_ +#include "xf86dri.h" +#include "dri.h" +#include "r128_dri.h" +#include "r128_dripriv.h" +#include "r128_sarea.h" +#endif + +#ifdef RENDER +#include "picturestr.h" +#endif + +#define R128_DEBUG 0 /* Turn off debugging output */ +#define R128_TIMEOUT 2000000 /* Fall out of wait loops after this count */ +#define R128_MMIOSIZE 0x80000 + +#define R128_VBIOS_SIZE 0x00010000 + +#if R128_DEBUG +#define R128TRACE(x) \ + do { \ + ErrorF("(**) %s(%d): ", R128_NAME, pScrn->scrnIndex); \ + ErrorF x; \ + } while (0); +#else +#define R128TRACE(x) +#endif + + +/* Other macros */ +#define R128_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) +#define R128_ALIGN(x,bytes) (((x) + ((bytes) - 1)) & ~((bytes) - 1)) +#define R128PTR(pScrn) ((R128InfoPtr)(pScrn)->driverPrivate) + +typedef struct { /* All values in XCLKS */ + int ML; /* Memory Read Latency */ + int MB; /* Memory Burst Length */ + int Trcd; /* RAS to CAS delay */ + int Trp; /* RAS percentage */ + int Twr; /* Write Recovery */ + int CL; /* CAS Latency */ + int Tr2w; /* Read to Write Delay */ + int Rloop; /* Loop Latency */ + int Rloop_fudge; /* Add to ML to get Rloop */ + char *name; +} R128RAMRec, *R128RAMPtr; + +typedef struct { + /* Common registers */ + CARD32 ovr_clr; + CARD32 ovr_wid_left_right; + CARD32 ovr_wid_top_bottom; + CARD32 ov0_scale_cntl; + CARD32 mpp_tb_config; + CARD32 mpp_gp_config; + CARD32 subpic_cntl; + CARD32 viph_control; + CARD32 i2c_cntl_1; + CARD32 gen_int_cntl; + CARD32 cap0_trig_cntl; + CARD32 cap1_trig_cntl; + CARD32 bus_cntl; + + /* Other registers to save for VT switches */ + CARD32 dp_datatype; + CARD32 gen_reset_cntl; + CARD32 clock_cntl_index; + CARD32 amcgpio_en_reg; + CARD32 amcgpio_mask; + + /* CRTC registers */ + CARD32 crtc_gen_cntl; + CARD32 crtc_ext_cntl; + CARD32 dac_cntl; + CARD32 crtc_h_total_disp; + CARD32 crtc_h_sync_strt_wid; + CARD32 crtc_v_total_disp; + CARD32 crtc_v_sync_strt_wid; + CARD32 crtc_offset; + CARD32 crtc_offset_cntl; + CARD32 crtc_pitch; + + /* CRTC2 registers */ + CARD32 crtc2_gen_cntl; + + /* Flat panel registers */ + CARD32 fp_crtc_h_total_disp; + CARD32 fp_crtc_v_total_disp; + CARD32 fp_gen_cntl; + CARD32 fp_h_sync_strt_wid; + CARD32 fp_horz_stretch; + CARD32 fp_panel_cntl; + CARD32 fp_v_sync_strt_wid; + CARD32 fp_vert_stretch; + CARD32 lvds_gen_cntl; + CARD32 tmds_crc; + + /* Computed values for PLL */ + CARD32 dot_clock_freq; + CARD32 pll_output_freq; + int feedback_div; + int post_div; + + /* PLL registers */ + CARD32 ppll_ref_div; + CARD32 ppll_div_3; + CARD32 htotal_cntl; + + /* DDA register */ + CARD32 dda_config; + CARD32 dda_on_off; + + /* Pallet */ + Bool palette_valid; + CARD32 palette[256]; +} R128SaveRec, *R128SavePtr; + +typedef struct { + CARD16 reference_freq; + CARD16 reference_div; + CARD32 min_pll_freq; + CARD32 max_pll_freq; + CARD16 xclk; +} R128PLLRec, *R128PLLPtr; + +typedef struct { + int bitsPerPixel; + int depth; + int displayWidth; + int pixel_code; + int pixel_bytes; + DisplayModePtr mode; +} R128FBLayout; + +typedef struct { + EntityInfoPtr pEnt; + pciVideoPtr PciInfo; + PCITAG PciTag; + int Chipset; + Bool Primary; + + Bool FBDev; + + unsigned long LinearAddr; /* Frame buffer physical address */ + unsigned long MMIOAddr; /* MMIO region physical address */ + unsigned long BIOSAddr; /* BIOS physical address */ + Bool BIOSFromPCI; /* BIOS is read from PCI space */ + + unsigned char *MMIO; /* Map of MMIO region */ + unsigned char *FB; /* Map of frame buffer */ + + CARD32 MemCntl; + CARD32 BusCntl; + unsigned long FbMapSize; /* Size of frame buffer, in bytes */ + int Flags; /* Saved copy of mode flags */ + + Bool HasPanelRegs; /* Current chip can connect to a FP */ + Bool CRTOnly; /* Only use External CRT instead of FP */ + CARD8 *VBIOS; /* Video BIOS for mode validation on FPs */ + int FPBIOSstart; /* Start of the flat panel info */ + + /* Computed values for FPs */ + int PanelXRes; + int PanelYRes; + int PanelPwrDly; + + R128PLLRec pll; + R128RAMPtr ram; + + R128SaveRec SavedReg; /* Original (text) mode */ + R128SaveRec ModeReg; /* Current mode */ + Bool (*CloseScreen)(int, ScreenPtr); + + Bool PaletteSavedOnVT; /* Palette saved on last VT switch */ + + XAAInfoRecPtr accel; + Bool accelOn; + xf86CursorInfoPtr cursor; + unsigned long cursor_start; + unsigned long cursor_end; + + int fifo_slots; /* Free slots in the FIFO (64 max) */ + int pix24bpp; /* Depth of pixmap for 24bpp framebuffer */ + Bool dac6bits; /* Use 6 bit DAC? */ + + /* Computed values for Rage 128 */ + int pitch; + int datatype; + CARD32 dp_gui_master_cntl; + + /* Saved values for ScreenToScreenCopy */ + int xdir; + int ydir; + + /* ScanlineScreenToScreenColorExpand support */ + unsigned char *scratch_buffer[1]; + unsigned char *scratch_save; + int scanline_x; + int scanline_y; + int scanline_h; + int scanline_h_w; + int scanline_words; + int scanline_direct; + int scanline_bpp; /* Only used for ImageWrite */ + + DGAModePtr DGAModes; + int numDGAModes; + Bool DGAactive; + int DGAViewportStatus; + + R128FBLayout CurrentLayout; +#ifdef XF86DRI + Bool directRenderingEnabled; + DRIInfoPtr pDRIInfo; + int drmFD; + int numVisualConfigs; + __GLXvisualConfig *pVisualConfigs; + R128ConfigPrivPtr pVisualConfigsPriv; + + drmHandle fbHandle; + + drmSize registerSize; + drmHandle registerHandle; + + Bool IsPCI; /* Current card is a PCI card */ + + drmSize agpSize; + drmHandle agpMemHandle; /* Handle from drmAgpAlloc */ + unsigned long agpOffset; + unsigned char *AGP; /* Map */ + int agpMode; + + Bool CCEInUse; /* CCE is currently active */ + int CCEMode; /* CCE mode that server/clients use */ + int CCEFifoSize; /* Size of the CCE command FIFO */ + Bool CCESecure; /* CCE security enabled */ + int CCEusecTimeout; /* CCE timeout in usecs */ + Bool CCE2D; /* CCE is used for X server 2D prims */ + + /* CCE ring buffer data */ + unsigned long ringStart; /* Offset into AGP space */ + drmHandle ringHandle; /* Handle from drmAddMap */ + drmSize ringMapSize; /* Size of map */ + int ringSize; /* Size of ring (in MB) */ + unsigned char *ring; /* Map */ + int ringSizeLog2QW; + + unsigned long ringReadOffset; /* Offset into AGP space */ + drmHandle ringReadPtrHandle; /* Handle from drmAddMap */ + drmSize ringReadMapSize; /* Size of map */ + unsigned char *ringReadPtr; /* Map */ + + /* CCE vertex buffer data */ + unsigned long vbStart; /* Offset into AGP space */ + drmHandle vbHandle; /* Handle from drmAddMap */ + drmSize vbMapSize; /* Size of map */ + int vbSize; /* Size of vert bufs (in MB) */ + unsigned char *vb; /* Map */ + int vbBufSize; /* Size of individual vert buf */ + int vbNumBufs; /* Number of vert bufs */ + drmBufMapPtr vbBufs; /* Buffer map */ + + /* CCE indirect buffer data */ + unsigned long indStart; /* Offset into AGP space */ + drmHandle indHandle; /* Handle from drmAddMap */ + drmSize indMapSize; /* Size of map */ + int indSize; /* Size of indirect bufs (in MB) */ + unsigned char *ind; /* Map */ + + /* CCE AGP Texture data */ + unsigned long agpTexStart; /* Offset into AGP space */ + drmHandle agpTexHandle; /* Handle from drmAddMap */ + drmSize agpTexMapSize; /* Size of map */ + int agpTexSize; /* Size of AGP tex space (in MB) */ + unsigned char *agpTex; /* Map */ + int log2AGPTexGran; + + /* DRI screen private data */ + int fbX; + int fbY; + int backX; + int backY; + int depthX; + int depthY; + int textureX; + int textureY; + int textureSize; + int log2TexGran; +#endif + XF86VideoAdaptorPtr adaptor; +} R128InfoRec, *R128InfoPtr; + +#define R128WaitForFifo(pScrn, entries) \ +do { \ + if (info->fifo_slots < entries) R128WaitForFifoFunction(pScrn, entries); \ + info->fifo_slots -= entries; \ +} while (0) + +extern void R128WaitForFifoFunction(ScrnInfoPtr pScrn, int entries); +extern void R128WaitForIdle(ScrnInfoPtr pScrn); +extern void R128EngineReset(ScrnInfoPtr pScrn); +extern void R128EngineFlush(ScrnInfoPtr pScrn); + +extern int R128INPLL(ScrnInfoPtr pScrn, int addr); +extern void R128WaitForVerticalSync(ScrnInfoPtr pScrn); + +extern Bool R128AccelInit(ScreenPtr pScreen); +extern void R128EngineInit(ScrnInfoPtr pScrn); +extern Bool R128CursorInit(ScreenPtr pScreen); +extern Bool R128DGAInit(ScreenPtr pScreen); + +extern int R128MinBits(int val); + +extern void R128InitVideo(ScreenPtr pScreen); + +#ifdef XF86DRI +extern Bool R128DRIScreenInit(ScreenPtr pScreen); +extern void R128DRICloseScreen(ScreenPtr pScreen); +extern Bool R128DRIFinishScreenInit(ScreenPtr pScreen); +extern void R128CCEStart(ScrnInfoPtr pScrn); +extern void R128CCEStop(ScrnInfoPtr pScrn); +extern void R128CCEResetRing(ScrnInfoPtr pScrn); +extern void R128CCEWaitForIdle(ScrnInfoPtr pScrn); +#endif + +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c new file mode 100644 index 000000000..7595b7fe4 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c @@ -0,0 +1,1084 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c,v 1.1 2000/11/02 16:55:30 tsi Exp $ */ +/* + * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario + * and Precision Insight, Inc., Cedar Park, Texas. + * + * 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 on + * 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, PRECISION INSIGHT AND/OR THEIR 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: + * Rickard E. Faith <faith@precisioninsight.com> + * Kevin E. Martin <kevin@precisioninsight.com> + * Alan Hourihane <ahourihane@valinux.com> + * + * Credits: + * + * Thanks to Alan Hourihane <alanh@fairlite.demon..co.uk> and SuSE for + * providing source code to their 3.3.x Rage 128 driver. Portions of + * this file are based on the acceleration code for that driver. + * + * References: + * + * RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical + * Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April + * 1999. + * + * RAGE 128 Software Development Manual (Technical Reference Manual P/N + * SDK-G04000 Rev. 0.01), ATI Technologies: June 1999. + * + * Notes on unimplemented XAA optimizations: + * + * SetClipping: The Rage128 doesn't support the full 16bit registers needed + * for XAA clip rect support. + * SolidFillTrap: This will probably work if we can compute the correct + * Bresenham error values. + * TwoPointLine: The Rage 128 supports Bresenham lines instead. + * DashedLine with non-power-of-two pattern length: Apparently, there is + * no way to set the length of the pattern -- it is always + * assumed to be 8 or 32 (or 1024?). + * ScreenToScreenColorExpandFill: See p. 4-17 of the Technical Reference + * Manual where it states that monochrome expansion of frame + * buffer data is not supported. + * CPUToScreenColorExpandFill, direct: The implementation here uses a hybrid + * direct/indirect method. If we had more data registers, + * then we could do better. If XAA supported a trigger write + * address, the code would be simpler. + * (Alan Hourihane) Update. We now use purely indirect and clip the full + * rectangle. Seems as the direct method has some problems + * with this, although this indirect method is much faster + * than the old method of setting up the engine per scanline. + * This code was the basis of the Radeon work we did. + * Color8x8PatternFill: Apparently, an 8x8 color brush cannot take an 8x8 + * pattern from frame buffer memory. + * ImageWrites: See CPUToScreenColorExpandFill. + * + */ + +#define R128_IMAGEWRITE 0 /* Disable ImageWrites - faster in software */ +#define R128_TRAPEZOIDS 0 /* Trapezoids don't work */ + + /* X and server generic header files */ +#include "Xarch.h" +#include "xf86.h" +#include "xf86_ansic.h" +#include "xf86_OSproc.h" +#include "xf86fbman.h" + + /* Line support */ +#include "miline.h" + + /* XAA and cursor support */ +#include "xaa.h" +#include "xf86Cursor.h" + + /* Driver data structures */ +#include "r128.h" +#include "r128_reg.h" + +static struct { + int rop; + int pattern; +} R128_ROP[] = { + { R128_ROP3_ZERO, R128_ROP3_ZERO }, /* GXclear */ + { R128_ROP3_DSa, R128_ROP3_DPa }, /* Gxand */ + { R128_ROP3_SDna, R128_ROP3_PDna }, /* GXandReverse */ + { R128_ROP3_S, R128_ROP3_P }, /* GXcopy */ + { R128_ROP3_DSna, R128_ROP3_DPna }, /* GXandInverted */ + { R128_ROP3_D, R128_ROP3_D }, /* GXnoop */ + { R128_ROP3_DSx, R128_ROP3_DPx }, /* GXxor */ + { R128_ROP3_DSo, R128_ROP3_DPo }, /* GXor */ + { R128_ROP3_DSon, R128_ROP3_DPon }, /* GXnor */ + { R128_ROP3_DSxn, R128_ROP3_PDxn }, /* GXequiv */ + { R128_ROP3_Dn, R128_ROP3_Dn }, /* GXinvert */ + { R128_ROP3_SDno, R128_ROP3_PDno }, /* GXorReverse */ + { R128_ROP3_Sn, R128_ROP3_Pn }, /* GXcopyInverted */ + { R128_ROP3_DSno, R128_ROP3_DPno }, /* GXorInverted */ + { R128_ROP3_DSan, R128_ROP3_DPan }, /* GXnand */ + { R128_ROP3_ONE, R128_ROP3_ONE } /* GXset */ +}; + +/* Flush all dirty data in the Pixel Cache to memory. */ +void R128EngineFlush(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int i; + + OUTREGP(R128_PC_NGUI_CTLSTAT, R128_PC_FLUSH_ALL, ~R128_PC_FLUSH_ALL); + for (i = 0; i < R128_TIMEOUT; i++) { + if (!(INREG(R128_PC_NGUI_CTLSTAT) & R128_PC_BUSY)) break; + } +} + +/* Reset graphics card to known state. */ +void R128EngineReset(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + CARD32 clock_cntl_index; + CARD32 mclk_cntl; + CARD32 gen_reset_cntl; + + R128EngineFlush(pScrn); + + clock_cntl_index = INREG(R128_CLOCK_CNTL_INDEX); + mclk_cntl = INPLL(pScrn, R128_MCLK_CNTL); + + OUTPLL(R128_MCLK_CNTL, mclk_cntl | R128_FORCE_GCP | R128_FORCE_PIPE3D_CP); + + gen_reset_cntl = INREG(R128_GEN_RESET_CNTL); + + OUTREG(R128_GEN_RESET_CNTL, gen_reset_cntl | R128_SOFT_RESET_GUI); + INREG(R128_GEN_RESET_CNTL); + OUTREG(R128_GEN_RESET_CNTL, gen_reset_cntl & ~R128_SOFT_RESET_GUI); + INREG(R128_GEN_RESET_CNTL); + + OUTPLL(R128_MCLK_CNTL, mclk_cntl); + OUTREG(R128_CLOCK_CNTL_INDEX, clock_cntl_index); + OUTREG(R128_GEN_RESET_CNTL, gen_reset_cntl); + +#ifdef XF86DRI + if (R128CCE_USE_RING_BUFFER(info->CCEMode)) R128CCEResetRing(pScrn); +#endif +} + +/* The FIFO has 64 slots. This routines waits until at least `entries' of + these slots are empty. */ +void R128WaitForFifoFunction(ScrnInfoPtr pScrn, int entries) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int i; + + for (;;) { + for (i = 0; i < R128_TIMEOUT; i++) { + info->fifo_slots = INREG(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK; + if (info->fifo_slots >= entries) return; + } + R128TRACE(("FIFO timed out: %d entries, stat=0x%08x, probe=0x%08x\n", + INREG(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK, + INREG(R128_GUI_STAT), + INREG(R128_GUI_PROBE))); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "FIFO timed out, resetting engine...\n"); + R128EngineReset(pScrn); +#ifdef XF86DRI + if (info->CCE2D) R128CCEStart(pScrn); +#endif + } +} + +/* Wait for the graphics engine to be completely idle: the FIFO has + drained, the Pixel Cache is flushed, and the engine is idle. This is a + standard "sync" function that will make the hardware "quiescent". */ +void R128WaitForIdle(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int i; + + R128WaitForFifoFunction(pScrn, 64); + + for (;;) { + for (i = 0; i < R128_TIMEOUT; i++) { + if (!(INREG(R128_GUI_STAT) & R128_GUI_ACTIVE)) { + R128EngineFlush(pScrn); + return; + } + } + R128TRACE(("Idle timed out: %d entries, stat=0x%08x, probe=0x%08x\n", + INREG(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK, + INREG(R128_GUI_STAT), + INREG(R128_GUI_PROBE))); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Idle timed out, resetting engine...\n"); + R128EngineReset(pScrn); +#ifdef XF86DRI + if (info->CCE2D) R128CCEStart(pScrn); +#endif + } +} + +/* Setup for XAA SolidFill. */ +static void R128SetupForSolidFill(ScrnInfoPtr pScrn, + int color, int rop, unsigned int planemask) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + R128WaitForFifo(pScrn, 4); + OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | R128_GMC_BRUSH_SOLID_COLOR + | R128_GMC_SRC_DATATYPE_COLOR + | R128_ROP[rop].pattern)); + OUTREG(R128_DP_BRUSH_FRGD_CLR, color); + OUTREG(R128_DP_WRITE_MASK, planemask); + OUTREG(R128_DP_CNTL, (R128_DST_X_LEFT_TO_RIGHT + | R128_DST_Y_TOP_TO_BOTTOM)); +} + +/* Subsequent XAA SolidFillRect. + + Tests: xtest CH06/fllrctngl, xterm +*/ +static void R128SubsequentSolidFillRect(ScrnInfoPtr pScrn, + int x, int y, int w, int h) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + R128WaitForFifo(pScrn, 2); + OUTREG(R128_DST_Y_X, (y << 16) | x); + OUTREG(R128_DST_WIDTH_HEIGHT, (w << 16) | h); +} + +/* Setup for XAA solid lines. */ +static void R128SetupForSolidLine(ScrnInfoPtr pScrn, + int color, int rop, unsigned int planemask) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + R128WaitForFifo(pScrn, 3); + OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | R128_GMC_BRUSH_SOLID_COLOR + | R128_GMC_SRC_DATATYPE_COLOR + | R128_ROP[rop].pattern)); + OUTREG(R128_DP_BRUSH_FRGD_CLR, color); + OUTREG(R128_DP_WRITE_MASK, planemask); +} + + +/* Subsequent XAA solid Bresenham line. + + Tests: xtest CH06/drwln, ico, Mark Vojkovich's linetest program + + [See http://www.xfree86.org/devel/archives/devel/1999-Jun/0102.shtml for + Mark Vojkovich's linetest program, posted 2Jun99 to devel@xfree86.org.] + + x11perf -line500 + 1024x768@76Hz 1024x768@76Hz + 8bpp 32bpp + not used: 39700.0/sec 34100.0/sec + used: 47600.0/sec 36800.0/sec +*/ +static void R128SubsequentSolidBresenhamLine(ScrnInfoPtr pScrn, + int x, int y, + int major, int minor, + int err, int len, int octant) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int flags = 0; + + if (octant & YMAJOR) flags |= R128_DST_Y_MAJOR; + if (!(octant & XDECREASING)) flags |= R128_DST_X_DIR_LEFT_TO_RIGHT; + if (!(octant & YDECREASING)) flags |= R128_DST_Y_DIR_TOP_TO_BOTTOM; + + R128WaitForFifo(pScrn, 6); + OUTREG(R128_DP_CNTL_XDIR_YDIR_YMAJOR, flags); + OUTREG(R128_DST_Y_X, (y << 16) | x); + OUTREG(R128_DST_BRES_ERR, err); + OUTREG(R128_DST_BRES_INC, minor); + OUTREG(R128_DST_BRES_DEC, -major); + OUTREG(R128_DST_BRES_LNTH, len); +} + +/* Subsequent XAA solid horizontal and vertical lines + + 1024x768@76Hz 8bpp + Without With + x11perf -hseg500 87600.0/sec 798000.0/sec + x11perf -vseg500 38100.0/sec 38000.0/sec +*/ +static void R128SubsequentSolidHorVertLine(ScrnInfoPtr pScrn, + int x, int y, int len, int dir ) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + R128WaitForFifo(pScrn, 1); + OUTREG(R128_DP_CNTL, (R128_DST_X_LEFT_TO_RIGHT + | R128_DST_Y_TOP_TO_BOTTOM)); + + if (dir == DEGREES_0) { + R128SubsequentSolidFillRect(pScrn, x, y, len, 1); + } else { + R128SubsequentSolidFillRect(pScrn, x, y, 1, len); + } +} + +/* Setup for XAA dashed lines. + + Tests: xtest CH05/stdshs, XFree86/drwln + + NOTE: Since we can only accelerate lines with power-of-2 patterns of + length <= 32, these x11perf numbers are not representative of the + speed-up on appropriately-sized patterns. + + 1024x768@76Hz 8bpp + Without With + x11perf -dseg100 218000.0/sec 222000.0/sec + x11perf -dline100 215000.0/sec 221000.0/sec + x11perf -ddline100 178000.0/sec 180000.0/sec +*/ +static void R128SetupForDashedLine(ScrnInfoPtr pScrn, + int fg, int bg, + int rop, unsigned int planemask, + int length, unsigned char *pattern) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + CARD32 pat = *(CARD32 *)pattern; + + switch (length) { + case 2: pat |= pat << 2; /* fall through */ + case 4: pat |= pat << 4; /* fall through */ + case 8: pat |= pat << 8; /* fall through */ + case 16: pat |= pat << 16; + } + + R128WaitForFifo(pScrn, 5); + OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | (bg == -1 + ? R128_GMC_BRUSH_32x1_MONO_FG_LA + : R128_GMC_BRUSH_32x1_MONO_FG_BG) + | R128_ROP[rop].pattern + | R128_GMC_BYTE_LSB_TO_MSB)); + OUTREG(R128_DP_WRITE_MASK, planemask); + OUTREG(R128_DP_BRUSH_FRGD_CLR, fg); + OUTREG(R128_DP_BRUSH_BKGD_CLR, bg); + OUTREG(R128_BRUSH_DATA0, pat); +} + +/* Subsequent XAA dashed line. */ +static void R128SubsequentDashedBresenhamLine(ScrnInfoPtr pScrn, + int x, int y, + int major, int minor, + int err, int len, int octant, + int phase) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int flags = 0; + + if (octant & YMAJOR) flags |= R128_DST_Y_MAJOR; + if (!(octant & XDECREASING)) flags |= R128_DST_X_DIR_LEFT_TO_RIGHT; + if (!(octant & YDECREASING)) flags |= R128_DST_Y_DIR_TOP_TO_BOTTOM; + + R128WaitForFifo(pScrn, 7); + OUTREG(R128_DP_CNTL_XDIR_YDIR_YMAJOR, flags); + OUTREG(R128_DST_Y_X, (y << 16) | x); + OUTREG(R128_BRUSH_Y_X, (phase << 16) | phase); + OUTREG(R128_DST_BRES_ERR, err); + OUTREG(R128_DST_BRES_INC, minor); + OUTREG(R128_DST_BRES_DEC, -major); + OUTREG(R128_DST_BRES_LNTH, len); +} + +#if R128_TRAPEZOIDS + /* This doesn't work. Except in the + lower-left quadrant, all of the pixel + errors appear to be because eL and eR + are not correct. Drawing from right to + left doesn't help. Be aware that the + non-_SUB registers set the sub-pixel + values to 0.5 (0x08), which isn't what + XAA wants. */ +/* Subsequent XAA SolidFillTrap. XAA always passes data that assumes we + fill from top to bottom, so dyL and dyR are always non-negative. */ +static void R128SubsequentSolidFillTrap(ScrnInfoPtr pScrn, int y, int h, + int left, int dxL, int dyL, int eL, + int right, int dxR, int dyR, int eR) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int flags = 0; + int Lymajor = 0; + int Rymajor = 0; + int origdxL = dxL; + int origdxR = dxR; + + R128TRACE(("Trap %d %d; L %d %d %d %d; R %d %d %d %d\n", + y, h, + left, dxL, dyL, eL, + right, dxR, dyR, eR)); + + if (dxL < 0) dxL = -dxL; else flags |= (1 << 0) /* | (1 << 8) */; + if (dxR < 0) dxR = -dxR; else flags |= (1 << 6); + + R128WaitForFifo(pScrn, 11); + +#if 1 + OUTREG(R128_DP_CNTL, flags | (1 << 1) | (1 << 7)); + OUTREG(R128_DST_Y_SUB, ((y) << 4) | 0x0 ); + OUTREG(R128_DST_X_SUB, ((left) << 4)|0x0); + OUTREG(R128_TRAIL_BRES_ERR, eR-dxR); + OUTREG(R128_TRAIL_BRES_INC, dxR); + OUTREG(R128_TRAIL_BRES_DEC, -dyR); + OUTREG(R128_TRAIL_X_SUB, ((right) << 4) | 0x0); + OUTREG(R128_LEAD_BRES_ERR, eL-dxL); + OUTREG(R128_LEAD_BRES_INC, dxL); + OUTREG(R128_LEAD_BRES_DEC, -dyL); + OUTREG(R128_LEAD_BRES_LNTH_SUB, ((h) << 4) | 0x00); +#else + OUTREG(R128_DP_CNTL, flags | (1 << 1) ); + OUTREG(R128_DST_Y_SUB, (y << 4)); + OUTREG(R128_DST_X_SUB, (right << 4)); + OUTREG(R128_TRAIL_BRES_ERR, eL); + OUTREG(R128_TRAIL_BRES_INC, dxL); + OUTREG(R128_TRAIL_BRES_DEC, -dyL); + OUTREG(R128_TRAIL_X_SUB, (left << 4) | 0); + OUTREG(R128_LEAD_BRES_ERR, eR); + OUTREG(R128_LEAD_BRES_INC, dxR); + OUTREG(R128_LEAD_BRES_DEC, -dyR); + OUTREG(R128_LEAD_BRES_LNTH_SUB, h << 4); +#endif +} +#endif + +/* Setup for XAA screen-to-screen copy. + + Tests: xtest CH06/fllrctngl (also tests transparency). +*/ +static void R128SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, + int xdir, int ydir, int rop, + unsigned int planemask, + int trans_color) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + info->xdir = xdir; + info->ydir = ydir; + R128WaitForFifo(pScrn, 3); + OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | R128_GMC_BRUSH_SOLID_COLOR + | R128_GMC_SRC_DATATYPE_COLOR + | R128_ROP[rop].rop + | R128_DP_SRC_SOURCE_MEMORY)); + OUTREG(R128_DP_WRITE_MASK, planemask); + OUTREG(R128_DP_CNTL, ((xdir >= 0 ? R128_DST_X_LEFT_TO_RIGHT : 0) + | (ydir >= 0 + ? R128_DST_Y_TOP_TO_BOTTOM + : 0))); + + if (trans_color != -1) { + /* Set up for transparency */ + R128WaitForFifo(pScrn, 3); + OUTREG(R128_CLR_CMP_CLR_SRC, trans_color); + OUTREG(R128_CLR_CMP_MASK, R128_CLR_CMP_MSK); + OUTREG(R128_CLR_CMP_CNTL, (R128_SRC_CMP_NEQ_COLOR + | R128_CLR_CMP_SRC_SOURCE)); + } +} + +/* Subsequent XAA screen-to-screen copy. */ +static void R128SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, + int xa, int ya, + int xb, int yb, + int w, int h) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + if (info->xdir < 0) xa += w - 1, xb += w - 1; + if (info->ydir < 0) ya += h - 1, yb += h - 1; + + R128WaitForFifo(pScrn, 3); + OUTREG(R128_SRC_Y_X, (ya << 16) | xa); + OUTREG(R128_DST_Y_X, (yb << 16) | xb); + OUTREG(R128_DST_HEIGHT_WIDTH, (h << 16) | w); +} + +/* Setup for XAA mono 8x8 pattern color expansion. Patterns with + transparency use `bg == -1'. This routine is only used if the XAA + pixmap cache is turned on. + + Tests: xtest XFree86/fllrctngl (no other test will test this routine with + both transparency and non-transparency) + + 1024x768@76Hz 8bpp + Without With + x11perf -srect100 38600.0/sec 85700.0/sec + x11perf -osrect100 38600.0/sec 85700.0/sec +*/ +static void R128SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, + int patternx, int patterny, + int fg, int bg, int rop, + unsigned int planemask) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + R128WaitForFifo(pScrn, 6); + OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | (bg == -1 + ? R128_GMC_BRUSH_8X8_MONO_FG_LA + : R128_GMC_BRUSH_8X8_MONO_FG_BG) + | R128_ROP[rop].pattern + | R128_GMC_BYTE_LSB_TO_MSB)); + OUTREG(R128_DP_WRITE_MASK, planemask); + OUTREG(R128_DP_BRUSH_FRGD_CLR, fg); + OUTREG(R128_DP_BRUSH_BKGD_CLR, bg); + OUTREG(R128_BRUSH_DATA0, patternx); + OUTREG(R128_BRUSH_DATA1, patterny); +} + +/* Subsequent XAA 8x8 pattern color expansion. Because they are used in + the setup function, `patternx' and `patterny' are not used here. */ +static void R128SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, + int patternx, int patterny, + int x, int y, int w, int h) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + R128WaitForFifo(pScrn, 3); + OUTREG(R128_BRUSH_Y_X, (patterny << 8) | patternx); + OUTREG(R128_DST_Y_X, (y << 16) | x); + OUTREG(R128_DST_HEIGHT_WIDTH, (h << 16) | w); +} + +#if 0 +/* Setup for XAA color 8x8 pattern fill. + + Tests: xtest XFree86/fllrctngl (with Mono8x8PatternFill off) +*/ +static void R128SetupForColor8x8PatternFill(ScrnInfoPtr pScrn, + int patx, int paty, + int rop, unsigned int planemask, + int trans_color) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + R128TRACE(("Color8x8 %d %d %d\n", trans_color, patx, paty)); + + R128WaitForFifo(pScrn, 2); + OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | R128_GMC_BRUSH_8x8_COLOR + | R128_GMC_SRC_DATATYPE_COLOR + | R128_ROP[rop].rop + | R128_DP_SRC_SOURCE_MEMORY)); + OUTREG(R128_DP_WRITE_MASK, planemask); + + if (trans_color != -1) { + /* Set up for transparency */ + R128WaitForFifo(pScrn, 3); + OUTREG(R128_CLR_CMP_CLR_SRC, trans_color); + OUTREG(R128_CLR_CMP_MASK, R128_CLR_CMP_MSK); + OUTREG(R128_CLR_CMP_CNTL, (R128_SRC_CMP_NEQ_COLOR + | R128_CLR_CMP_SRC_SOURCE)); + } +} + +/* Subsequent XAA 8x8 pattern color expansion. */ +static void R128SubsequentColor8x8PatternFillRect( ScrnInfoPtr pScrn, + int patx, int paty, + int x, int y, int w, int h) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + R128TRACE(("Color8x8 %d,%d %d,%d %d %d\n", patx, paty, x, y, w, h)); + R128WaitForFifo(pScrn, 3); + OUTREG(R128_SRC_Y_X, (paty << 16) | patx); + OUTREG(R128_DST_Y_X, (y << 16) | x); + OUTREG(R128_DST_HEIGHT_WIDTH, (h << 16) | w); +} +#endif + +/* Setup for XAA indirect CPU-to-screen color expansion (indirect). + Because of how the scratch buffer is initialized, this is really a + mainstore-to-screen color expansion. Transparency is supported when `bg + == -1'. + + x11perf -ftext (pure indirect): + 1024x768@76Hz 1024x768@76Hz + 8bpp 32bpp + not used: 685000.0/sec 794000.0/sec + used: 1070000.0/sec 1080000.0/sec + + We could improve this indirect routine by about 10% if the hardware + could accept DWORD padded scanlines, or if XAA could provide bit-packed + data. We might also be able to move to a direct routine if there were + more HOST_DATA registers. + + Implementing the hybrid indirect/direct scheme improved performance in a + few areas: + + 1024x768@76 8bpp + Indirect Hybrid + x11perf -oddsrect10 50100.0/sec 71700.0/sec + x11perf -oddsrect100 4240.0/sec 6660.0/sec + x11perf -bigsrect10 50300.0/sec 71100.0/sec + x11perf -bigsrect100 4190.0/sec 6800.0/sec + x11perf -polytext 584000.0/sec 714000.0/sec + x11perf -polytext16 154000.0/sec 172000.0/sec + x11perf -seg1 1780000.0/sec 1880000.0/sec + x11perf -copyplane10 42900.0/sec 58300.0/sec + x11perf -copyplane100 4400.0/sec 6710.0/sec + x11perf -putimagexy10 5090.0/sec 6670.0/sec + x11perf -putimagexy100 424.0/sec 575.0/sec + + 1024x768@76 -depth 24 -fbbpp 32 + Indirect Hybrid + x11perf -oddsrect100 4240.0/sec 6670.0/sec + x11perf -bigsrect100 4190.0/sec 6800.0/sec + x11perf -polytext 585000.0/sec 719000.0/sec + x11perf -seg1 2960000.0/sec 2990000.0/sec + x11perf -copyplane100 4400.0/sec 6700.0/sec + x11perf -putimagexy100 138.0/sec 191.0/sec + +*/ +static void R128SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int fg, int bg, + int rop, + unsigned int + planemask) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + R128WaitForFifo(pScrn, 4); + OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | R128_GMC_DST_CLIPPING + | R128_GMC_BRUSH_NONE + | (bg == -1 + ? R128_GMC_SRC_DATATYPE_MONO_FG_LA + : R128_GMC_SRC_DATATYPE_MONO_FG_BG) + | R128_ROP[rop].rop + | R128_GMC_BYTE_LSB_TO_MSB + | R128_DP_SRC_SOURCE_HOST_DATA)); + OUTREG(R128_DP_WRITE_MASK, planemask); + OUTREG(R128_DP_SRC_FRGD_CLR, fg); + OUTREG(R128_DP_SRC_BKGD_CLR, bg); +} + +/* Subsequent XAA indirect CPU-to-screen color expansion. This is only + called once for each rectangle. */ +static void R128SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int x, int y, + int w, int h, + int skipleft) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int x1clip = x+skipleft; + int x2clip = x+w; + + info->scanline_h = h; + info->scanline_words = (w + 31) >> 5; + +#if 0 + /* Seems as though the Rage128's doesn't like blitting directly + * as we must be overwriting something too quickly, therefore we + * render to the buffer first and then blit */ + if ((info->scanline_words * h) <= 9) { + /* Turn on direct for less than 9 dword colour expansion */ + info->scratch_buffer[0] + = (unsigned char *)(ADDRREG(R128_HOST_DATA_LAST) + - (info->scanline_words - 1)); + info->scanline_direct = 1; + } else +#endif + { + /* Use indirect for anything else */ + info->scratch_buffer[0] = info->scratch_save; + info->scanline_direct = 0; + } + + if (pScrn->bitsPerPixel == 24) { + x1clip *= 3; + x2clip *= 3; + } + + R128WaitForFifo(pScrn, 4 + (info->scanline_direct ? + (info->scanline_words * h) : 0) ); + OUTREG(R128_SC_TOP_LEFT, (y << 16) | (x1clip & 0xffff)); + OUTREG(R128_SC_BOTTOM_RIGHT, ((y+h-1) << 16) | ((x2clip-1) & 0xffff)); + OUTREG(R128_DST_Y_X, (y << 16) | (x & 0xffff)); + /* Have to pad the width here and use clipping engine */ + OUTREG(R128_DST_HEIGHT_WIDTH, (h << 16) | ((w + 31) & ~31)); +} + +/* Subsequent XAA indirect CPU-to-screen color expandion. This is called + once for each scanline. */ +static void R128SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + CARD32 *p = (CARD32 *)info->scratch_buffer[bufno]; + int i; + int left = info->scanline_words; + volatile CARD32 *d; + + if (info->scanline_direct) return; + --info->scanline_h; + while (left) { + if (left <= 8) { + /* Last scanline - finish write to DATA_LAST */ + if (info->scanline_h == 0) { + R128WaitForFifo(pScrn, left); + /* Unrolling doesn't improve performance */ + for (d = ADDRREG(R128_HOST_DATA_LAST) - (left - 1); left; --left) + *d++ = *p++; + return; + } else { + R128WaitForFifo(pScrn, left); + /* Unrolling doesn't improve performance */ + for (d = ADDRREG(R128_HOST_DATA7) - (left - 1); left; --left) + *d++ = *p++; + } + } else { + R128WaitForFifo(pScrn, 8); + /* Unrolling doesn't improve performance */ + for (d = ADDRREG(R128_HOST_DATA0), i = 0; i < 8; i++) + *d++ = *p++; + left -= 8; + } + } +} + +/* Setup for XAA indirect image write. + + + 1024x768@76Hz 8bpp + Without With + x11perf -putimage10 37500.0/sec 39300.0/sec + x11perf -putimage100 2150.0/sec 1170.0/sec + x11perf -putimage500 108.0/sec 49.8/sec + */ +#if R128_IMAGEWRITE +static void R128SetupForScanlineImageWrite(ScrnInfoPtr pScrn, + int rop, + unsigned int planemask, + int trans_color, + int bpp, + int depth) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + info->scanline_bpp = bpp; + + R128WaitForFifo(pScrn, 2); + OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | R128_GMC_DST_CLIPPING + | R128_GMC_BRUSH_1X8_COLOR + | R128_GMC_SRC_DATATYPE_COLOR + | R128_ROP[rop].rop + | R128_GMC_BYTE_LSB_TO_MSB + | R128_DP_SRC_SOURCE_HOST_DATA)); + OUTREG(R128_DP_WRITE_MASK, planemask); + + if (trans_color != -1) { + /* Set up for transparency */ + R128WaitForFifo(pScrn, 3); + OUTREG(R128_CLR_CMP_CLR_SRC, trans_color); + OUTREG(R128_CLR_CMP_MASK, R128_CLR_CMP_MSK); + OUTREG(R128_CLR_CMP_CNTL, (R128_SRC_CMP_NEQ_COLOR + | R128_CLR_CMP_SRC_SOURCE)); + } +} + +/* Subsequent XAA indirect image write. This is only called once for each + rectangle. */ +static void R128SubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn, + int x, int y, + int w, int h, + int skipleft) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int x1clip = x+skipleft; + int x2clip = x+w; + + int shift = 0; /* 32bpp */ + + if (pScrn->bitsPerPixel == 8) shift = 3; + else if (pScrn->bitsPerPixel == 16) shift = 1; + + info->scanline_h = h; + info->scanline_words = (w * info->scanline_bpp + 31) >> 5; + +#if 0 + /* Seeing as the CPUToScreen doesn't like this, I've done this + * here too, as it uses pretty much the same path. */ + if ((info->scanline_words * h) <= 9) { + /* Turn on direct for less than 9 dword colour expansion */ + info->scratch_buffer[0] + = (unsigned char *)(ADDRREG(R128_HOST_DATA_LAST) + - (info->scanline_words - 1)); + info->scanline_direct = 1; + } else +#endif + { + /* Use indirect for anything else */ + info->scratch_buffer[0] = info->scratch_save; + info->scanline_direct = 0; + } + + if (pScrn->bitsPerPixel == 24) { + x1clip *= 3; + x2clip *= 3; + } + + R128WaitForFifo(pScrn, 4 + (info->scanline_direct ? + (info->scanline_words * h) : 0) ); + OUTREG(R128_SC_TOP_LEFT, (y << 16) | (x1clip & 0xffff)); + OUTREG(R128_SC_BOTTOM_RIGHT, ((y+h-1) << 16) | ((x2clip-1) & 0xffff)); + OUTREG(R128_DST_Y_X, (y << 16) | (x & 0xffff)); + /* Have to pad the width here and use clipping engine */ + OUTREG(R128_DST_HEIGHT_WIDTH, (h << 16) | ((w + shift) & ~shift)); +} + +/* Subsequent XAA indirect iamge write. This is called once for each + scanline. */ +static void R128SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + CARD32 *p = (CARD32 *)info->scratch_buffer[bufno]; + int i; + int left = info->scanline_words; + volatile CARD32 *d; + + if (info->scanline_direct) return; + --info->scanline_h; + while (left) { + if (left <= 8) { + /* Last scanline - finish write to DATA_LAST */ + if (info->scanline_h == 0) { + R128WaitForFifo(pScrn, left); + /* Unrolling doesn't improve performance */ + for (d = ADDRREG(R128_HOST_DATA_LAST) - (left - 1); left; --left) + *d++ = *p++; + return; + } else { + R128WaitForFifo(pScrn, left); + /* Unrolling doesn't improve performance */ + for (d = ADDRREG(R128_HOST_DATA7) - (left - 1); left; --left) + *d++ = *p++; + } + } else { + R128WaitForFifo(pScrn, 8); + /* Unrolling doesn't improve performance */ + for (d = ADDRREG(R128_HOST_DATA0), i = 0; i < 8; i++) + *d++ = *p++; + left -= 8; + } + } +} +#endif + +/* Initialize the acceleration hardware. */ +void R128EngineInit(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + R128TRACE(("EngineInit (%d/%d)\n", info->CurrentLayout.pixel_code, info->CurrentLayout.bitsPerPixel)); + + OUTREG(R128_SCALE_3D_CNTL, 0); + R128EngineReset(pScrn); + + switch (info->CurrentLayout.pixel_code) { + case 8: info->datatype = 2; break; + case 15: info->datatype = 3; break; + case 16: info->datatype = 4; break; + case 24: info->datatype = 5; break; + case 32: info->datatype = 6; break; + default: + R128TRACE(("Unknown depth/bpp = %d/%d (code = %d)\n", + info->CurrentLayout.depth, info->CurrentLayout.bitsPerPixel, + info->CurrentLayout.pixel_code)); + } + info->pitch = (info->CurrentLayout.displayWidth / 8) * (info->CurrentLayout.pixel_bytes == 3 ? 3 : 1); + + R128TRACE(("Pitch for acceleration = %d\n", info->pitch)); + + R128WaitForFifo(pScrn, 2); + OUTREG(R128_DEFAULT_OFFSET, 0); + OUTREG(R128_DEFAULT_PITCH, info->pitch); + + R128WaitForFifo(pScrn, 4); + OUTREG(R128_AUX_SC_CNTL, 0); + OUTREG(R128_DEFAULT_SC_BOTTOM_RIGHT, (R128_DEFAULT_SC_RIGHT_MAX + | R128_DEFAULT_SC_BOTTOM_MAX)); + OUTREG(R128_SC_TOP_LEFT, 0); + OUTREG(R128_SC_BOTTOM_RIGHT, (R128_DEFAULT_SC_RIGHT_MAX + | R128_DEFAULT_SC_BOTTOM_MAX)); + + info->dp_gui_master_cntl = ((info->datatype << R128_GMC_DST_DATATYPE_SHIFT) + | R128_GMC_CLR_CMP_CNTL_DIS + | R128_GMC_AUX_CLIP_DIS); + R128WaitForFifo(pScrn, 1); + OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | R128_GMC_BRUSH_SOLID_COLOR + | R128_GMC_SRC_DATATYPE_COLOR)); + + R128WaitForFifo(pScrn, 8); + OUTREG(R128_DST_BRES_ERR, 0); + OUTREG(R128_DST_BRES_INC, 0); + OUTREG(R128_DST_BRES_DEC, 0); + OUTREG(R128_DP_BRUSH_FRGD_CLR, 0xffffffff); + OUTREG(R128_DP_BRUSH_BKGD_CLR, 0x00000000); + OUTREG(R128_DP_SRC_FRGD_CLR, 0xffffffff); + OUTREG(R128_DP_SRC_BKGD_CLR, 0x00000000); + OUTREG(R128_DP_WRITE_MASK, 0xffffffff); + + R128WaitForFifo(pScrn, 1); +#if X_BYTE_ORDER == X_BIG_ENDIAN + OUTREGP(R128_DP_DATATYPE, + R128_HOST_BIG_ENDIAN_EN, ~R128_HOST_BIG_ENDIAN_EN); +#else + OUTREGP(R128_DP_DATATYPE, 0, ~R128_HOST_BIG_ENDIAN_EN); +#endif + + R128WaitForIdle(pScrn); +} + +#ifdef XF86DRI + /* FIXME: When direct rendering is enabled, we should use the CCE to + draw 2D commands */ +static void R128CCEAccelInit(XAAInfoRecPtr a) +{ + a->Flags = 0; + + /* Sync */ + a->Sync = R128CCEWaitForIdle; + +} +#endif + +static void R128MMIOAccelInit(ScrnInfoPtr pScrn, XAAInfoRecPtr a) +{ + R128InfoPtr info = R128PTR(pScrn); + + a->Flags = (PIXMAP_CACHE + | OFFSCREEN_PIXMAPS + | LINEAR_FRAMEBUFFER); + + /* Sync */ + a->Sync = R128WaitForIdle; + + /* Solid Filled Rectangle */ + a->PolyFillRectSolidFlags = 0; + a->SetupForSolidFill = R128SetupForSolidFill; + a->SubsequentSolidFillRect = R128SubsequentSolidFillRect; + + /* Screen-to-screen Copy */ + /* Transparency uses the wrong colors for + 24 bpp mode -- the transparent part is + correct, but the opaque color is wrong. + This can be seen with netscape's I-bar + cursor when editing in the URL location + box. */ + a->ScreenToScreenCopyFlags = ((pScrn->bitsPerPixel == 24) + ? NO_TRANSPARENCY + : 0); + a->SetupForScreenToScreenCopy = R128SetupForScreenToScreenCopy; + a->SubsequentScreenToScreenCopy = R128SubsequentScreenToScreenCopy; + + /* Mono 8x8 Pattern Fill (Color Expand) */ + a->SetupForMono8x8PatternFill = R128SetupForMono8x8PatternFill; + a->SubsequentMono8x8PatternFillRect = R128SubsequentMono8x8PatternFillRect; + a->Mono8x8PatternFillFlags = (HARDWARE_PATTERN_PROGRAMMED_BITS + | HARDWARE_PATTERN_PROGRAMMED_ORIGIN + | HARDWARE_PATTERN_SCREEN_ORIGIN + | BIT_ORDER_IN_BYTE_LSBFIRST); + + /* Indirect CPU-To-Screen Color Expand */ +#if X_BYTE_ORDER == X_LITTLE_ENDIAN + a->ScanlineCPUToScreenColorExpandFillFlags = LEFT_EDGE_CLIPPING + | LEFT_EDGE_CLIPPING_NEGATIVE_X; +#else + a->ScanlineCPUToScreenColorExpandFillFlags = BIT_ORDER_IN_BYTE_MSBFIRST + | LEFT_EDGE_CLIPPING + | LEFT_EDGE_CLIPPING_NEGATIVE_X; +#endif + a->NumScanlineColorExpandBuffers = 1; + a->ScanlineColorExpandBuffers = info->scratch_buffer; + info->scratch_save = xalloc(((pScrn->virtualX+31)/32*4) + + (pScrn->virtualX + * info->CurrentLayout.pixel_bytes)); + info->scratch_buffer[0] = info->scratch_save; + a->SetupForScanlineCPUToScreenColorExpandFill + = R128SetupForScanlineCPUToScreenColorExpandFill; + a->SubsequentScanlineCPUToScreenColorExpandFill + = R128SubsequentScanlineCPUToScreenColorExpandFill; + a->SubsequentColorExpandScanline = R128SubsequentColorExpandScanline; + + /* Bresenham Solid Lines */ + a->SetupForSolidLine = R128SetupForSolidLine; + a->SubsequentSolidBresenhamLine = R128SubsequentSolidBresenhamLine; + a->SubsequentSolidHorVertLine = R128SubsequentSolidHorVertLine; + + /* Bresenham Dashed Lines*/ + a->SetupForDashedLine = R128SetupForDashedLine; + a->SubsequentDashedBresenhamLine = R128SubsequentDashedBresenhamLine; + a->DashPatternMaxLength = 32; + a->DashedLineFlags = (LINE_PATTERN_LSBFIRST_LSBJUSTIFIED + | LINE_PATTERN_POWER_OF_2_ONLY); + + /* ImageWrite */ +#if R128_IMAGEWRITE + a->NumScanlineImageWriteBuffers = 1; + a->ScanlineImageWriteBuffers = info->scratch_buffer; + info->scratch_buffer[0] = info->scratch_save; + a->SetupForScanlineImageWrite = R128SetupForScanlineImageWrite; + a->SubsequentScanlineImageWriteRect= R128SubsequentScanlineImageWriteRect; + a->SubsequentImageWriteScanline = R128SubsequentImageWriteScanline; + a->ScanlineImageWriteFlags = CPU_TRANSFER_PAD_DWORD + /* Performance tests show that we shouldn't use GXcopy for + * uploads as a memcpy is faster */ + | NO_GXCOPY + | LEFT_EDGE_CLIPPING + | LEFT_EDGE_CLIPPING_NEGATIVE_X + | SCANLINE_PAD_DWORD; +#endif +} + +/* Initialize XAA for supported acceleration and also initialize the + graphics hardware for acceleration. */ +Bool R128AccelInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + XAAInfoRecPtr a; + + if (!(a = info->accel = XAACreateInfoRec())) return FALSE; + +#ifdef XF86DRI + /* FIXME: When direct rendering is enabled, we should use the CCE to + draw 2D commands */ + if (info->CCE2D) R128CCEAccelInit(a); + else +#endif + R128MMIOAccelInit(pScrn, a); + + R128EngineInit(pScrn); + return XAAInit(pScreen, a); +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_cursor.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_cursor.c new file mode 100644 index 000000000..d77c64b5a --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_cursor.c @@ -0,0 +1,289 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_cursor.c,v 1.1 2000/11/02 16:55:31 tsi Exp $ */ +/* + * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario + * and Precision Insight, Inc., Cedar Park, Texas. + * + * 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 on + * 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, PRECISION INSIGHT AND/OR THEIR 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: + * Rickard E. Faith <faith@precisioninsight.com> + * Kevin E. Martin <kevin@precisioninsight.com> + * + * References: + * + * RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical + * Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April + * 1999. + * + * RAGE 128 Software Development Manual (Technical Reference Manual P/N + * SDK-G04000 Rev. 0.01), ATI Technologies: June 1999. + * + */ + + /* X and server generic header files */ +#include "Xarch.h" +#include "xf86.h" +#include "xf86_ansic.h" +#include "xf86_OSproc.h" +#include "xf86fbman.h" + + /* XAA and Cursor Support */ +#include "xaa.h" +#include "xf86Cursor.h" + +#include "xf86xv.h" + + /* PCI support */ +#include "xf86PciInfo.h" +#include "xf86Pci.h" + + /* DDC support */ +#include "xf86DDC.h" + + /* DRI support */ +#ifdef XF86DRI +#include "GL/glxint.h" +#include "xf86drm.h" +#include "sarea.h" +#define _XF86DRI_SERVER_ +#include "xf86dri.h" +#include "dri.h" +#include "r128_dri.h" +#include "r128_dripriv.h" +#include "r128_sarea.h" +#endif + + /* Driver data structures */ +#include "r128.h" +#include "r128_reg.h" + +#if X_BYTE_ORDER == X_BIG_ENDIAN +#define P_SWAP32( a , b ) \ + ((char *)a)[0] = ((char *)b)[3]; \ + ((char *)a)[1] = ((char *)b)[2]; \ + ((char *)a)[2] = ((char *)b)[1]; \ + ((char *)a)[3] = ((char *)b)[0] + +#define P_SWAP16( a , b ) \ + ((char *)a)[0] = ((char *)b)[1]; \ + ((char *)a)[1] = ((char *)b)[0]; \ + ((char *)a)[2] = ((char *)b)[3]; \ + ((char *)a)[3] = ((char *)b)[2] +#endif + + +/* Set cursor foreground and background colors. */ +static void R128SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + OUTREG(R128_CUR_CLR0, bg); + OUTREG(R128_CUR_CLR1, fg); +} + +/* Set cursor position to (x,y) with offset into cursor bitmap at + (xorigin,yorigin). */ +static void R128SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + xf86CursorInfoPtr cursor = info->cursor; + int xorigin = 0; + int yorigin = 0; + int total_y = pScrn->frameY1 - pScrn->frameY0; + + if (x < 0) xorigin = -x; + if (y < 0) yorigin = -y; + if (y > total_y) y = total_y; + if (info->Flags & V_DBLSCAN) y *= 2; + if (xorigin >= cursor->MaxWidth) xorigin = cursor->MaxWidth - 1; + if (yorigin >= cursor->MaxHeight) yorigin = cursor->MaxHeight - 1; + + OUTREG(R128_CUR_HORZ_VERT_OFF, R128_CUR_LOCK | (xorigin << 16) | yorigin); + OUTREG(R128_CUR_HORZ_VERT_POSN, (R128_CUR_LOCK + | ((xorigin ? 0 : x) << 16) + | (yorigin ? 0 : y))); + OUTREG(R128_CUR_OFFSET, info->cursor_start + yorigin * 16); +} + +/* Copy cursor image from `image' to video memory. R128SetCursorPosition + will be called after this, so we can ignore xorigin and yorigin. */ +static void R128LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *image) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + CARD32 *s = (CARD32 *)image; + CARD32 *d = (CARD32 *)(info->FB + info->cursor_start); + int y; + CARD32 save; + + save = INREG(R128_CRTC_GEN_CNTL); + OUTREG(R128_CRTC_GEN_CNTL, save & ~R128_CRTC_CUR_EN); + +#if X_BYTE_ORDER == X_BIG_ENDIAN + switch(info->CurrentLayout.pixel_bytes) { + case 4: + case 3: + for (y = 0; y < 64; y++) { + P_SWAP32(d,s); + d++; s++; + P_SWAP32(d,s); + d++; s++; + P_SWAP32(d,s); + d++; s++; + P_SWAP32(d,s); + d++; s++; + } + break; + case 2: + for (y = 0; y < 64; y++) { + P_SWAP16(d,s); + d++; s++; + P_SWAP16(d,s); + d++; s++; + P_SWAP16(d,s); + d++; s++; + P_SWAP16(d,s); + d++; s++; + } + break; + default: + for (y = 0; y < 64; y++) { + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + } + } +#else + for (y = 0; y < 64; y++) { + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + } +#endif + + /* Set the area after the cursor to be all transparent so that we + won't display corrupted cursors on the screen */ + for (y = 0; y < 64; y++) { + *d++ = 0xffffffff; /* The AND bits */ + *d++ = 0xffffffff; + *d++ = 0x00000000; /* The XOR bits */ + *d++ = 0x00000000; + } + + + OUTREG(R128_CRTC_GEN_CNTL, save); +} + +/* Hide hardware cursor. */ +static void R128HideCursor(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + OUTREGP(R128_CRTC_GEN_CNTL, 0, ~R128_CRTC_CUR_EN); +} + +/* Show hardware cursor. */ +static void R128ShowCursor(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + OUTREGP(R128_CRTC_GEN_CNTL, R128_CRTC_CUR_EN, ~R128_CRTC_CUR_EN); +} + +/* Determine if hardware cursor is in use. */ +static Bool R128UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + + return info->cursor_start ? TRUE : FALSE; +} + +/* Initialize hardware cursor support. */ +Bool R128CursorInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + xf86CursorInfoPtr cursor; + FBAreaPtr fbarea; + int width; + int height; + int size; + + + if (!(cursor = info->cursor = xf86CreateCursorInfoRec())) return FALSE; + + cursor->MaxWidth = 64; + cursor->MaxHeight = 64; + cursor->Flags = (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP + +#if X_BYTE_ORDER == X_LITTLE_ENDIAN + | HARDWARE_CURSOR_BIT_ORDER_MSBFIRST +#endif + | HARDWARE_CURSOR_INVERT_MASK + | HARDWARE_CURSOR_AND_SOURCE_WITH_MASK + | HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 + | HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK); + + cursor->SetCursorColors = R128SetCursorColors; + cursor->SetCursorPosition = R128SetCursorPosition; + cursor->LoadCursorImage = R128LoadCursorImage; + cursor->HideCursor = R128HideCursor; + cursor->ShowCursor = R128ShowCursor; + cursor->UseHWCursor = R128UseHWCursor; + + size = (cursor->MaxWidth/4) * cursor->MaxHeight; + width = pScrn->displayWidth; + height = (size*2 + 1023) / pScrn->displayWidth; + fbarea = xf86AllocateOffscreenArea(pScreen, + width, + height, + 16, + NULL, + NULL, + NULL); + + if (!fbarea) { + info->cursor_start = 0; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Hardware cursor disabled" + " due to insufficient offscreen memory\n"); + } else { + info->cursor_start = R128_ALIGN((fbarea->box.x1 + + width * fbarea->box.y1) + * info->CurrentLayout.pixel_bytes, 16); + info->cursor_end = info->cursor_start + size; + } + + R128TRACE(("R128CursorInit (0x%08x-0x%08x)\n", + info->cursor_start, info->cursor_end)); + + return xf86InitCursor(pScreen, cursor); +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dga.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dga.c new file mode 100644 index 000000000..695d49cdb --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dga.c @@ -0,0 +1,358 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dga.c,v 1.1 2000/11/02 16:55:32 tsi Exp $ */ +/* + * Authors: + * Ove Kåven <ovek@transgaming.com>, + * borrowing some code from the Chips and MGA drivers. + */ + + /* X and server generic header files */ +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" + + /* Driver data structures */ +#include "r128.h" +#include "r128_probe.h" + + /* DGA support */ +#include "dgaproc.h" + + +static Bool R128_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, + int *, int *, int *); +static Bool R128_SetMode(ScrnInfoPtr, DGAModePtr); +static int R128_GetViewport(ScrnInfoPtr); +static void R128_SetViewport(ScrnInfoPtr, int, int, int); +static void R128_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); +static void R128_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); +#if 0 +static void R128_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, + unsigned long); +#endif + +static +DGAFunctionRec R128_DGAFuncs = { + R128_OpenFramebuffer, + NULL, + R128_SetMode, + R128_SetViewport, + R128_GetViewport, + R128WaitForIdle, + R128_FillRect, + R128_BlitRect, +#if 0 + R128_BlitTransRect +#else + NULL +#endif +}; + + +static DGAModePtr +R128SetupDGAMode( + ScrnInfoPtr pScrn, + DGAModePtr modes, + int *num, + int bitsPerPixel, + int depth, + Bool pixmap, + int secondPitch, + unsigned long red, + unsigned long green, + unsigned long blue, + short visualClass +){ + R128InfoPtr info = R128PTR(pScrn); + DGAModePtr newmodes = NULL, currentMode; + DisplayModePtr pMode, firstMode; + int otherPitch, Bpp = bitsPerPixel >> 3; + Bool oneMore; + + pMode = firstMode = pScrn->modes; + + while(pMode) { + + otherPitch = secondPitch ? secondPitch : pMode->HDisplay; + + if(pMode->HDisplay != otherPitch) { + newmodes = xrealloc(modes, (*num + 2) * sizeof(DGAModeRec)); + oneMore = TRUE; + } else { + newmodes = xrealloc(modes, (*num + 1) * sizeof(DGAModeRec)); + oneMore = FALSE; + } + + if(!newmodes) { + xfree(modes); + return NULL; + } + modes = newmodes; + +SECOND_PASS: + + currentMode = modes + *num; + (*num)++; + + currentMode->mode = pMode; + /* FIXME: is concurrent access really possible? */ + currentMode->flags = DGA_CONCURRENT_ACCESS; + if(pixmap) + currentMode->flags |= DGA_PIXMAP_AVAILABLE; + if(info->accel) + currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; + if(pMode->Flags & V_DBLSCAN) + currentMode->flags |= DGA_DOUBLESCAN; + if(pMode->Flags & V_INTERLACE) + currentMode->flags |= DGA_INTERLACED; + currentMode->byteOrder = pScrn->imageByteOrder; + currentMode->depth = depth; + currentMode->bitsPerPixel = bitsPerPixel; + currentMode->red_mask = red; + currentMode->green_mask = green; + currentMode->blue_mask = blue; + currentMode->visualClass = visualClass; + currentMode->viewportWidth = pMode->HDisplay; + currentMode->viewportHeight = pMode->VDisplay; + currentMode->xViewportStep = 8; + currentMode->yViewportStep = 1; + currentMode->viewportFlags = DGA_FLIP_RETRACE; + currentMode->offset = 0; + currentMode->address = (unsigned char*)info->LinearAddr; + + if(oneMore) { /* first one is narrow width */ + currentMode->bytesPerScanline = ((pMode->HDisplay * Bpp) + 3) & ~3L; + currentMode->imageWidth = pMode->HDisplay; + currentMode->imageHeight = pMode->VDisplay; + currentMode->pixmapWidth = currentMode->imageWidth; + currentMode->pixmapHeight = currentMode->imageHeight; + currentMode->maxViewportX = currentMode->imageWidth - + currentMode->viewportWidth; + /* this might need to get clamped to some maximum */ + currentMode->maxViewportY = currentMode->imageHeight - + currentMode->viewportHeight; + oneMore = FALSE; + goto SECOND_PASS; + } else { + currentMode->bytesPerScanline = ((otherPitch * Bpp) + 3) & ~3L; + currentMode->imageWidth = otherPitch; + currentMode->imageHeight = pMode->VDisplay; + currentMode->pixmapWidth = currentMode->imageWidth; + currentMode->pixmapHeight = currentMode->imageHeight; + currentMode->maxViewportX = currentMode->imageWidth - + currentMode->viewportWidth; + /* this might need to get clamped to some maximum */ + currentMode->maxViewportY = currentMode->imageHeight - + currentMode->viewportHeight; + } + + pMode = pMode->next; + if(pMode == firstMode) + break; + } + + return modes; +} + + +Bool +R128DGAInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + DGAModePtr modes = NULL; + int num = 0; + + /* 8 */ + modes = R128SetupDGAMode (pScrn, modes, &num, 8, 8, + (pScrn->bitsPerPixel == 8), + (pScrn->bitsPerPixel != 8) ? 0 : pScrn->displayWidth, + 0, 0, 0, PseudoColor); + + /* 15 */ + modes = R128SetupDGAMode (pScrn, modes, &num, 16, 15, + (pScrn->bitsPerPixel == 16), + (pScrn->depth != 15) ? 0 : pScrn->displayWidth, + 0x7c00, 0x03e0, 0x001f, TrueColor); + + modes = R128SetupDGAMode (pScrn, modes, &num, 16, 15, + (pScrn->bitsPerPixel == 16), + (pScrn->depth != 15) ? 0 : pScrn->displayWidth, + 0x7c00, 0x03e0, 0x001f, DirectColor); + + /* 16 */ + modes = R128SetupDGAMode (pScrn, modes, &num, 16, 16, + (pScrn->bitsPerPixel == 16), + (pScrn->depth != 16) ? 0 : pScrn->displayWidth, + 0xf800, 0x07e0, 0x001f, TrueColor); + + modes = R128SetupDGAMode (pScrn, modes, &num, 16, 16, + (pScrn->bitsPerPixel == 16), + (pScrn->depth != 16) ? 0 : pScrn->displayWidth, + 0xf800, 0x07e0, 0x001f, DirectColor); + + /* 24 */ + modes = R128SetupDGAMode (pScrn, modes, &num, 24, 24, + (pScrn->bitsPerPixel == 24), + (pScrn->bitsPerPixel != 24) ? 0 : pScrn->displayWidth, + 0xff0000, 0x00ff00, 0x0000ff, TrueColor); + + modes = R128SetupDGAMode (pScrn, modes, &num, 24, 24, + (pScrn->bitsPerPixel == 24), + (pScrn->bitsPerPixel != 24) ? 0 : pScrn->displayWidth, + 0xff0000, 0x00ff00, 0x0000ff, DirectColor); + + /* 32 */ + modes = R128SetupDGAMode (pScrn, modes, &num, 32, 24, + (pScrn->bitsPerPixel == 32), + (pScrn->bitsPerPixel != 32) ? 0 : pScrn->displayWidth, + 0xff0000, 0x00ff00, 0x0000ff, TrueColor); + + modes = R128SetupDGAMode (pScrn, modes, &num, 32, 24, + (pScrn->bitsPerPixel == 32), + (pScrn->bitsPerPixel != 32) ? 0 : pScrn->displayWidth, + 0xff0000, 0x00ff00, 0x0000ff, DirectColor); + + info->numDGAModes = num; + info->DGAModes = modes; + + return DGAInit(pScreen, &R128_DGAFuncs, modes, num); +} + + +static Bool +R128_SetMode( + ScrnInfoPtr pScrn, + DGAModePtr pMode +){ + static R128FBLayout SavedLayouts[MAXSCREENS]; + int indx = pScrn->pScreen->myNum; + R128InfoPtr info = R128PTR(pScrn); + + if(!pMode) { /* restore the original mode */ + /* put the ScreenParameters back */ + if(info->DGAactive) + memcpy(&info->CurrentLayout, &SavedLayouts[indx], sizeof(R128FBLayout)); + + pScrn->currentMode = info->CurrentLayout.mode; + + R128SwitchMode(indx, pScrn->currentMode, 0); + R128AdjustFrame(indx, 0, 0, 0); + info->DGAactive = FALSE; + } else { + if(!info->DGAactive) { /* save the old parameters */ + memcpy(&SavedLayouts[indx], &info->CurrentLayout, sizeof(R128FBLayout)); + info->DGAactive = TRUE; + } + + info->CurrentLayout.bitsPerPixel = pMode->bitsPerPixel; + info->CurrentLayout.depth = pMode->depth; + info->CurrentLayout.displayWidth = pMode->bytesPerScanline / + (pMode->bitsPerPixel >> 3); + info->CurrentLayout.pixel_bytes = pMode->bitsPerPixel / 8; + info->CurrentLayout.pixel_code = (pMode->bitsPerPixel != 16 + ? pMode->bitsPerPixel + : pMode->depth); + /* R128ModeInit() will set the mode field */ + + R128SwitchMode(indx, pMode->mode, 0); + } + + return TRUE; +} + + + +static int +R128_GetViewport( + ScrnInfoPtr pScrn +){ + R128InfoPtr info = R128PTR(pScrn); + + return info->DGAViewportStatus; +} + + +static void +R128_SetViewport( + ScrnInfoPtr pScrn, + int x, int y, + int flags +){ + R128InfoPtr info = R128PTR(pScrn); + + R128AdjustFrame(pScrn->pScreen->myNum, x, y, flags); + info->DGAViewportStatus = 0; /* FIXME */ +} + + +static void +R128_FillRect ( + ScrnInfoPtr pScrn, + int x, int y, int w, int h, + unsigned long color +){ + R128InfoPtr info = R128PTR(pScrn); + + if(info->accel) { + (*info->accel->SetupForSolidFill)(pScrn, color, GXcopy, ~0); + (*info->accel->SubsequentSolidFillRect)(pScrn, x, y, w, h); + SET_SYNC_FLAG(info->accel); + } +} + +static void +R128_BlitRect( + ScrnInfoPtr pScrn, + int srcx, int srcy, + int w, int h, + int dstx, int dsty +){ + R128InfoPtr info = R128PTR(pScrn); + + if(info->accel) { + int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; + int ydir = (srcy < dsty) ? -1 : 1; + + (*info->accel->SetupForScreenToScreenCopy)( + pScrn, xdir, ydir, GXcopy, ~0, -1); + (*info->accel->SubsequentScreenToScreenCopy)( + pScrn, srcx, srcy, dstx, dsty, w, h); + SET_SYNC_FLAG(info->accel); + } +} + + +#if 0 +static void +R128_BlitTransRect( + ScrnInfoPtr pScrn, + int srcx, int srcy, + int w, int h, + int dstx, int dsty, + unsigned long color +){ + /* this one should be separate since the XAA function would + prohibit usage of ~0 as the key */ +} +#endif + + +static Bool +R128_OpenFramebuffer( + ScrnInfoPtr pScrn, + char **name, + unsigned char **mem, + int *size, + int *offset, + int *flags +){ + R128InfoPtr info = R128PTR(pScrn); + + *name = NULL; /* no special device */ + *mem = (unsigned char*)info->LinearAddr; + *size = info->FbMapSize; + *offset = 0; + *flags = /* DGA_NEED_ROOT */ 0; /* don't need root, just /dev/mem access */ + + return TRUE; +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c new file mode 100644 index 000000000..816dbebee --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c @@ -0,0 +1,1280 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c,v 1.2 2000/11/03 01:15:49 martin Exp $ */ +/* + * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario + * and Precision Insight, Inc., Cedar Park, Texas. + * + * 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 on + * 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, PRECISION INSIGHT AND/OR THEIR 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: + * Kevin E. Martin <kevin@precisioninsight.com> + * Rickard E. Faith <faith@precisioninsight.com> + * Daryll Strauss <daryll@precisioninsight.com> + * + */ + + + /* X and server generic header files */ +#include "xf86.h" +#include "xf86_ansic.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "xf86RAC.h" +#include "xf86cmap.h" +#include "xf86fbman.h" + + /* Backing store, software cursor, and + colormap initialization */ +#include "mibstore.h" +#include "mipointer.h" +#include "micmap.h" + + /* CFB support */ +#define PSZ 8 +#include "cfb.h" +#undef PSZ +#include "cfb16.h" +#include "cfb24.h" +#include "cfb32.h" +#include "cfb24_32.h" + + /* Driver data structures */ +#include "r128.h" +#include "r128_reg.h" +#include "r128_version.h" + +#define R128_WATERMARK_L 16 +#define R128_WATERMARK_M 8 +#define R128_WATERMARK_N 8 +#define R128_WATERMARK_K 128 + +static int CCEFifoSlots = 0; + +#define R128CCEWaitForFifo(pScrn, entries) \ +do { \ + if (CCEFifoSlots < entries) R128WaitForFifoFunction(pScrn, entries); \ + CCEFifoSlots -= entries; \ +} while (0) + +/* Wait for at least `entries' slots are free. The actual number of + slots available is stored in info->CCEFifoSize. */ +static void R128CCEWaitForFifoFunction(ScrnInfoPtr pScrn, int entries) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int i; + + for (;;) { + for (i = 0; i < R128_TIMEOUT; i++) { + CCEFifoSlots = INREG(R128_PM4_STAT) & R128_PM4_FIFOCNT_MASK; + if (CCEFifoSlots >= entries) return; + } + R128EngineReset(pScrn); + if (info->CCE2D) R128CCEStart(pScrn); + } +} + +/* Wait until the CCE is completely idle: the FIFO has drained and the + CCE is idle. */ +void R128CCEWaitForIdle(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int i; + + if (!info->CCEInUse || info->CCEMode == R128_PM4_NONPM4) return; + + if (R128CCE_USE_RING_BUFFER(info->CCEMode)) { + volatile CARD32 *r128RingReadPtr = + (volatile CARD32 *)(info->ringReadPtr); + R128SAREAPrivPtr pSAREAPriv; + + OUTREGP(R128_PM4_BUFFER_DL_WPTR, + R128_PM4_BUFFER_DL_DONE, ~R128_PM4_BUFFER_DL_DONE); + + pSAREAPriv = (R128SAREAPrivPtr)DRIGetSAREAPrivate(pScrn->pScreen); + + for (;;) { + for (i = 0; i < R128_TIMEOUT; i++) { + if (*r128RingReadPtr == pSAREAPriv->ringWrite) { + int pm4stat = INREG(R128_PM4_STAT); + if ((pm4stat & R128_PM4_FIFOCNT_MASK) >= info->CCEFifoSize + && !(pm4stat & (R128_PM4_BUSY|R128_PM4_GUI_ACTIVE))) { + R128EngineFlush(pScrn); + return; + } + } + } + R128EngineReset(pScrn); + if (info->CCE2D) R128CCEStart(pScrn); + } + } else { + R128CCEWaitForFifoFunction(pScrn, info->CCEFifoSize); + + for (;;) { + for (i = 0; i < R128_TIMEOUT; i++) { + if (!(INREG(R128_PM4_STAT) + & (R128_PM4_BUSY | R128_PM4_GUI_ACTIVE))) { + R128EngineFlush(pScrn); + return; + } + } + R128EngineReset(pScrn); + if (info->CCE2D) R128CCEStart(pScrn); + } + } +} + +/* Reset the ring buffer status, if the engine was reset */ +void R128CCEResetRing(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + R128SAREAPrivPtr pSAREAPriv; + volatile CARD32 *r128RingReadPtr; + + if (!info->CCEInUse || info->CCEMode == R128_PM4_NONPM4) return; + + r128RingReadPtr = (volatile CARD32 *)(info->ringReadPtr); + pSAREAPriv = (R128SAREAPrivPtr)DRIGetSAREAPrivate(pScrn->pScreen); + + OUTREG(R128_PM4_BUFFER_DL_WPTR, 0); + OUTREG(R128_PM4_BUFFER_DL_RPTR, 0); + pSAREAPriv->ringWrite = 0; + *r128RingReadPtr = 0; + + /* Resetting the ring turns off the CCE */ + info->CCEInUse = FALSE; +} + +/* Start the CCE, but only if it is not already in use and the requested + mode is a CCE mode. The mode is stored in info->CCEMode. */ +void R128CCEStart(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + if (info->CCEInUse || info->CCEMode == R128_PM4_NONPM4) return; + + R128WaitForIdle(pScrn); + OUTREG(R128_PM4_BUFFER_CNTL, info->CCEMode | info->ringSizeLog2QW); + (void)INREG(R128_PM4_BUFFER_ADDR); /* as per the sample code */ + OUTREG(R128_PM4_MICRO_CNTL, R128_PM4_MICRO_FREERUN); + info->CCEInUse = TRUE; +} + +/* Stop the CCE, but only if it is in use and the requested mode is not + the non-CCE mode. This function also flushes any outstanding + requests before switching modes.*/ +void R128CCEStop(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + if (!info->CCEInUse || info->CCEMode == R128_PM4_NONPM4) return; + + R128CCEWaitForIdle(pScrn); + OUTREG(R128_PM4_MICRO_CNTL, 0); + OUTREG(R128_PM4_BUFFER_CNTL, R128_PM4_NONPM4); + R128EngineReset(pScrn); + info->CCEInUse = FALSE; +} + +/* Initialize the visual configs that are supported by the hardware. + These are combined with the visual configs that the indirect + rendering core supports, and the intersection is exported to the + client. */ +static Bool R128InitVisualConfigs(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + int numConfigs = 0; + __GLXvisualConfig *pConfigs = 0; + R128ConfigPrivPtr pR128Configs = 0; + R128ConfigPrivPtr *pR128ConfigPtrs = 0; + int i, accum, stencil; + + switch (info->CurrentLayout.pixel_code) { + case 8: /* 8bpp mode is not support */ + case 15: /* FIXME */ + case 24: /* FIXME */ + return FALSE; + +#define R128_USE_ACCUM 1 +#define R128_USE_STENCIL 1 + + case 16: + numConfigs = 1; + if (R128_USE_ACCUM) numConfigs *= 2; + if (R128_USE_STENCIL) numConfigs *= 2; + + if (!(pConfigs + = (__GLXvisualConfig*)xnfcalloc(sizeof(__GLXvisualConfig), + numConfigs))) { + return FALSE; + } + if (!(pR128Configs + = (R128ConfigPrivPtr)xnfcalloc(sizeof(R128ConfigPrivRec), + numConfigs))) { + xfree(pConfigs); + return FALSE; + } + if (!(pR128ConfigPtrs + = (R128ConfigPrivPtr*)xnfcalloc(sizeof(R128ConfigPrivPtr), + numConfigs))) { + xfree(pConfigs); + xfree(pR128Configs); + return FALSE; + } + + i = 0; + for (accum = 0; accum <= R128_USE_ACCUM; accum++) { + for (stencil = 0; stencil <= R128_USE_STENCIL; stencil++) { + pR128ConfigPtrs[i] = &pR128Configs[i]; + + pConfigs[i].vid = -1; + pConfigs[i].class = -1; + pConfigs[i].rgba = TRUE; + pConfigs[i].redSize = 5; + pConfigs[i].greenSize = 6; + pConfigs[i].blueSize = 5; + pConfigs[i].alphaSize = 0; + pConfigs[i].redMask = 0x0000F800; + pConfigs[i].greenMask = 0x000007E0; + pConfigs[i].blueMask = 0x0000001F; + pConfigs[i].alphaMask = 0x00000000; + if (accum) { /* Simulated in software */ + pConfigs[i].accumRedSize = 16; + pConfigs[i].accumGreenSize = 16; + pConfigs[i].accumBlueSize = 16; + pConfigs[i].accumAlphaSize = 0; + } else { + pConfigs[i].accumRedSize = 0; + pConfigs[i].accumGreenSize = 0; + pConfigs[i].accumBlueSize = 0; + pConfigs[i].accumAlphaSize = 0; + } + pConfigs[i].doubleBuffer = TRUE; + pConfigs[i].stereo = FALSE; + pConfigs[i].bufferSize = 16; + pConfigs[i].depthSize = 16; + if (stencil) + pConfigs[i].stencilSize = 8; /* Simulated in software */ + else + pConfigs[i].stencilSize = 0; + pConfigs[i].auxBuffers = 0; + pConfigs[i].level = 0; + pConfigs[i].visualRating = GLX_NONE_EXT; + pConfigs[i].transparentPixel = GLX_NONE; + pConfigs[i].transparentRed = 0; + pConfigs[i].transparentGreen = 0; + pConfigs[i].transparentBlue = 0; + pConfigs[i].transparentAlpha = 0; + pConfigs[i].transparentIndex = 0; + i++; + } + } + break; + case 32: + numConfigs = 1; + if (R128_USE_ACCUM) numConfigs *= 2; + if (R128_USE_STENCIL) numConfigs *= 2; + + if (!(pConfigs + = (__GLXvisualConfig*)xnfcalloc(sizeof(__GLXvisualConfig), + numConfigs))) { + return FALSE; + } + if (!(pR128Configs + = (R128ConfigPrivPtr)xnfcalloc(sizeof(R128ConfigPrivRec), + numConfigs))) { + xfree(pConfigs); + return FALSE; + } + if (!(pR128ConfigPtrs + = (R128ConfigPrivPtr*)xnfcalloc(sizeof(R128ConfigPrivPtr), + numConfigs))) { + xfree(pConfigs); + xfree(pR128Configs); + return FALSE; + } + + i = 0; + for (accum = 0; accum <= R128_USE_ACCUM; accum++) { + for (stencil = 0; stencil <= R128_USE_STENCIL; stencil++) { + pR128ConfigPtrs[i] = &pR128Configs[i]; + + pConfigs[i].vid = -1; + pConfigs[i].class = -1; + pConfigs[i].rgba = TRUE; + pConfigs[i].redSize = 8; + pConfigs[i].greenSize = 8; + pConfigs[i].blueSize = 8; + pConfigs[i].alphaSize = 8; + pConfigs[i].redMask = 0x00FF0000; + pConfigs[i].greenMask = 0x0000FF00; + pConfigs[i].blueMask = 0x000000FF; + pConfigs[i].alphaMask = 0xFF000000; + if (accum) { /* Simulated in software */ + pConfigs[i].accumRedSize = 16; + pConfigs[i].accumGreenSize = 16; + pConfigs[i].accumBlueSize = 16; + pConfigs[i].accumAlphaSize = 16; + } else { + pConfigs[i].accumRedSize = 0; + pConfigs[i].accumGreenSize = 0; + pConfigs[i].accumBlueSize = 0; + pConfigs[i].accumAlphaSize = 0; + } + pConfigs[i].doubleBuffer = TRUE; + pConfigs[i].stereo = FALSE; + pConfigs[i].bufferSize = 24; + if (stencil) { + pConfigs[i].depthSize = 24; + pConfigs[i].stencilSize = 8; + } else { + pConfigs[i].depthSize = 32; + pConfigs[i].stencilSize = 0; + } + pConfigs[i].auxBuffers = 0; + pConfigs[i].level = 0; + pConfigs[i].visualRating = GLX_NONE_EXT; + pConfigs[i].transparentPixel = GLX_NONE; + pConfigs[i].transparentRed = 0; + pConfigs[i].transparentGreen = 0; + pConfigs[i].transparentBlue = 0; + pConfigs[i].transparentAlpha = 0; + pConfigs[i].transparentIndex = 0; + i++; + } + } + break; + } + + info->numVisualConfigs = numConfigs; + info->pVisualConfigs = pConfigs; + info->pVisualConfigsPriv = pR128Configs; + GlxSetVisualConfigs(numConfigs, pConfigs, (void**)pR128ConfigPtrs); + return TRUE; +} + +/* Create the Rage 128-specific context information */ +static Bool R128CreateContext(ScreenPtr pScreen, VisualPtr visual, + drmContext hwContext, void *pVisualConfigPriv, + DRIContextType contextStore) +{ + /* Nothing yet */ + return TRUE; +} + +/* Destroy the Rage 128-specific context information */ +static void R128DestroyContext(ScreenPtr pScreen, drmContext hwContext, + DRIContextType contextStore) +{ + /* Nothing yet */ +} + +/* Called when the X server is woken up to allow the last client's + context to be saved and the X server's context to be loaded. This is + not necessary for the Rage 128 since the client detects when it's + context is not currently loaded and then load's it itself. Since the + registers to start and stop the CCE are privileged, only the X server + can start/stop the engine. */ +static void R128EnterServer(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + + if (info->accel) info->accel->NeedToSync = TRUE; + +#if 1 + if (!info->CCE2D) R128CCEStop(pScrn); +#else + if (info->CCE2D) R128CCEWaitForIdle(pScrn); + else R128CCEStop(pScrn); +#endif +} + +/* Called when the X server goes to sleep to allow the X server's + context to be saved and the last client's context to be loaded. This + is not necessary for the Rage 128 since the client detects when it's + context is not currently loaded and then load's it itself. Since the + registers to start and stop the CCE are privileged, only the X server + can start/stop the engine. */ +static void R128LeaveServer(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + +#if 1 + if (!info->CCE2D) R128CCEStart(pScrn); +#else + if (info->CCE2D) R128CCEWaitForIdle(pScrn); + else R128CCEStart(pScrn); +#endif +} + +/* Contexts can be swapped by the X server if necessary. This callback + is currently only used to perform any functions necessary when + entering or leaving the X server, and in the future might not be + necessary. */ +static void R128DRISwapContext(ScreenPtr pScreen, DRISyncType syncType, + DRIContextType oldContextType, void *oldContext, + DRIContextType newContextType, void *newContext) +{ + if ((syncType==DRI_3D_SYNC) && (oldContextType==DRI_2D_CONTEXT) && + (newContextType==DRI_2D_CONTEXT)) { /* Entering from Wakeup */ + R128EnterServer(pScreen); + } + if ((syncType==DRI_2D_SYNC) && (oldContextType==DRI_NO_CONTEXT) && + (newContextType==DRI_2D_CONTEXT)) { /* Exiting from Block Handler */ + R128LeaveServer(pScreen); + } +} + +/* Initialize the state of the back and depth buffers. */ +static void R128DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 indx) +{ + /* FIXME: This routine needs to have acceleration turned on */ + ScreenPtr pScreen = pWin->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + BoxPtr pbox; + int nbox; + int depth; + + /* FIXME: Use accel when CCE 2D code is written */ + if (info->CCE2D) return; + + /* FIXME: This should be based on the __GLXvisualConfig info */ + switch (pScrn->bitsPerPixel) { + case 8: depth = 0x000000ff; break; + case 16: depth = 0x0000ffff; break; + case 24: depth = 0x00ffffff; break; + case 32: depth = 0xffffffff; break; + default: depth = 0x00000000; break; + } + + /* FIXME: Copy XAAPaintWindow() and use REGION_TRANSLATE() */ + /* FIXME: Only initialize the back and depth buffers for contexts + that request them */ + + pbox = REGION_RECTS(prgn); + nbox = REGION_NUM_RECTS(prgn); + + (*info->accel->SetupForSolidFill)(pScrn, 0, GXcopy, -1); + for (; nbox; nbox--, pbox++) { + (*info->accel->SubsequentSolidFillRect)(pScrn, + pbox->x1 + info->fbX, + pbox->y1 + info->fbY, + pbox->x2 - pbox->x1, + pbox->y2 - pbox->y1); + (*info->accel->SubsequentSolidFillRect)(pScrn, + pbox->x1 + info->backX, + pbox->y1 + info->backY, + pbox->x2 - pbox->x1, + pbox->y2 - pbox->y1); + } + + (*info->accel->SetupForSolidFill)(pScrn, depth, GXcopy, -1); + for (; nbox; nbox--, pbox++) + (*info->accel->SubsequentSolidFillRect)(pScrn, + pbox->x1 + info->depthX, + pbox->y1 + info->depthY, + pbox->x2 - pbox->x1, + pbox->y2 - pbox->y1); + + info->accel->NeedToSync = TRUE; +} + +/* Copy the back and depth buffers when the X server moves a window. */ +static void R128DRIMoveBuffers(WindowPtr pWin, DDXPointRec ptOldOrg, + RegionPtr prgnSrc, CARD32 indx) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + + /* FIXME: This routine needs to have acceleration turned on */ + /* FIXME: Copy XAACopyWindow() and use REGION_TRANSLATE() */ + /* FIXME: Only initialize the back and depth buffers for contexts + that request them */ + + /* FIXME: Use accel when CCE 2D code is written */ + if (info->CCE2D) return; +} + +/* Initialize the AGP state. Request memory for use in AGP space, and + initialize the Rage 128 registers to point to that memory. */ +static Bool R128DRIAgpInit(R128InfoPtr info, ScreenPtr pScreen) +{ + unsigned char *R128MMIO = info->MMIO; + unsigned long mode; + unsigned int vendor, device; + int ret; + unsigned long cntl; + int s, l; + int flags; + + if (drmAgpAcquire(info->drmFD) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] AGP not available\n"); + return FALSE; + } + + /* Modify the mode if the default mode is + not appropriate for this particular + combination of graphics card and AGP + chipset. */ + + mode = drmAgpGetMode(info->drmFD); /* Default mode */ + vendor = drmAgpVendorId(info->drmFD); + device = drmAgpDeviceId(info->drmFD); + + mode &= ~R128_AGP_MODE_MASK; + switch (info->agpMode) { + case 2: mode |= R128_AGP_2X_MODE; + case 1: default: mode |= R128_AGP_1X_MODE; + } + + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n", + mode, vendor, device, + info->PciInfo->vendor, + info->PciInfo->chipType); + + if (drmAgpEnable(info->drmFD, mode) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] AGP not enabled\n"); + drmAgpRelease(info->drmFD); + return FALSE; + } + + info->agpOffset = 0; + + if ((ret = drmAgpAlloc(info->drmFD, info->agpSize*1024*1024, 0, NULL, + &info->agpMemHandle)) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Out of memory (%d)\n", ret); + drmAgpRelease(info->drmFD); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] %d kB allocated with handle 0x%08x\n", + info->agpSize*1024, info->agpMemHandle); + + if (drmAgpBind(info->drmFD, info->agpMemHandle, info->agpOffset) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Could not bind\n"); + drmAgpFree(info->drmFD, info->agpMemHandle); + drmAgpRelease(info->drmFD); + return FALSE; + } + + /* Initialize the CCE ring buffer data */ + info->ringStart = info->agpOffset; + info->ringMapSize = info->ringSize*1024*1024 + 4096; + info->ringSizeLog2QW = R128MinBits(info->ringSize*1024*1024/8) - 1; + + info->ringReadOffset = info->ringStart + info->ringMapSize; + info->ringReadMapSize = 4096; + + /* Reserve space for the vertex buffer */ + info->vbStart = info->ringReadOffset + info->ringReadMapSize; + info->vbMapSize = info->vbSize*1024*1024; + + /* Reserve space for the indirect buffer */ + info->indStart = info->vbStart + info->vbMapSize; + info->indMapSize = info->indSize*1024*1024; + + /* Reserve the rest for AGP textures */ + info->agpTexStart = info->indStart + info->indMapSize; + s = (info->agpSize*1024*1024 - info->agpTexStart); + l = R128MinBits((s-1) / R128_NR_TEX_REGIONS); + if (l < R128_LOG_TEX_GRANULARITY) l = R128_LOG_TEX_GRANULARITY; + info->agpTexMapSize = (s >> l) << l; + info->log2AGPTexGran = l; + + if (info->CCESecure) flags = DRM_READ_ONLY; + else flags = 0; + + if (drmAddMap(info->drmFD, info->ringStart, info->ringMapSize, + DRM_AGP, flags, &info->ringHandle) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[agp] Could not add ring mapping\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] ring handle = 0x%08lx\n", info->ringHandle); + + if (drmMap(info->drmFD, info->ringHandle, info->ringMapSize, + (drmAddressPtr)&info->ring) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Could not map ring\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] Ring mapped at 0x%08lx\n", + (unsigned long)info->ring); + + if (drmAddMap(info->drmFD, info->ringReadOffset, info->ringReadMapSize, + DRM_AGP, flags, &info->ringReadPtrHandle) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[agp] Could not add ring read ptr mapping\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] ring read ptr handle = 0x%08lx\n", + info->ringReadPtrHandle); + + if (drmMap(info->drmFD, info->ringReadPtrHandle, info->ringReadMapSize, + (drmAddressPtr)&info->ringReadPtr) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[agp] Could not map ring read ptr\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] Ring read ptr mapped at 0x%08lx\n", + (unsigned long)info->ringReadPtr); + + if (drmAddMap(info->drmFD, info->vbStart, info->vbMapSize, + DRM_AGP, 0, &info->vbHandle) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[agp] Could not add vertex buffers mapping\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] vertex buffers handle = 0x%08lx\n", info->vbHandle); + + if (drmMap(info->drmFD, info->vbHandle, info->vbMapSize, + (drmAddressPtr)&info->vb) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[agp] Could not map vertex buffers\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] Vertex buffers mapped at 0x%08lx\n", + (unsigned long)info->vb); + + if (drmAddMap(info->drmFD, info->indStart, info->indMapSize, + DRM_AGP, flags, &info->indHandle) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[agp] Could not add indirect buffers mapping\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] indirect buffers handle = 0x%08lx\n", info->indHandle); + + if (drmMap(info->drmFD, info->indHandle, info->indMapSize, + (drmAddressPtr)&info->ind) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[agp] Could not map indirect buffers\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] Indirect buffers mapped at 0x%08lx\n", + (unsigned long)info->ind); + + if (drmAddMap(info->drmFD, info->agpTexStart, info->agpTexMapSize, + DRM_AGP, 0, &info->agpTexHandle) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[agp] Could not add AGP texture map mapping\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] AGP texture map handle = 0x%08lx\n", + info->agpTexHandle); + + if (drmMap(info->drmFD, info->agpTexHandle, info->agpTexMapSize, + (drmAddressPtr)&info->agpTex) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[agp] Could not map AGP texture map\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] AGP Texture map mapped at 0x%08lx\n", + (unsigned long)info->agpTex); + + /* Initialize Rage 128's AGP registers */ + cntl = INREG(R128_AGP_CNTL); + cntl &= ~R128_AGP_APER_SIZE_MASK; + switch (info->agpSize) { + case 256: cntl |= R128_AGP_APER_SIZE_256MB; break; + case 128: cntl |= R128_AGP_APER_SIZE_128MB; break; + case 64: cntl |= R128_AGP_APER_SIZE_64MB; break; + case 32: cntl |= R128_AGP_APER_SIZE_32MB; break; + case 16: cntl |= R128_AGP_APER_SIZE_16MB; break; + case 8: cntl |= R128_AGP_APER_SIZE_8MB; break; + case 4: cntl |= R128_AGP_APER_SIZE_4MB; break; + default: + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[agp] Illegal aperture size %d kB\n", + info->agpSize*1024); + return FALSE; + } + OUTREG(R128_AGP_BASE, info->ringHandle); /* Ring buf is at AGP offset 0 */ + OUTREG(R128_AGP_CNTL, cntl); + + return TRUE; +} + +/* Fake the vertex buffers for PCI cards. */ +static Bool R128DRIPciInit(R128InfoPtr info) +{ + info->vbStart = 0; + info->vbMapSize = info->vbSize*1024*1024; + + return TRUE; +} + +/* Add a map for the MMIO registers that will be accessed by any + DRI-based clients. */ +static Bool R128DRIMapInit(R128InfoPtr info, ScreenPtr pScreen) +{ + int flags; + + if (info->CCESecure) flags = DRM_READ_ONLY; + else flags = 0; + + /* Map registers */ + info->registerSize = R128_MMIOSIZE; + if (drmAddMap(info->drmFD, info->MMIOAddr, info->registerSize, + DRM_REGISTERS, flags, &info->registerHandle) < 0) { + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[drm] register handle = 0x%08lx\n", info->registerHandle); + + return TRUE; +} + +/* Initialize the ring buffer state for use in the X server and any + DRI-based clients. */ +static void R128DRICCEInitRingBuffer(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + unsigned long addr; + + /* FIXME: When we use the CCE for the X server, we should move this + function (and the support functions above) to r128_accel.c */ + + /* The manual (p. 2) says this address is + in "VM space". This means it's an + offset from the start of AGP space. */ + OUTREG(R128_PM4_BUFFER_OFFSET, info->ringStart | 0x02000000); + + OUTREG(R128_PM4_BUFFER_DL_WPTR, 0); + OUTREG(R128_PM4_BUFFER_DL_RPTR, 0); + + /* DL_RPTR_ADDR is a physical address. + This should be in the SAREA. */ + *(volatile long unsigned *)(info->ringReadPtr) = 0; + OUTREG(R128_PM4_BUFFER_DL_RPTR_ADDR, (info->ringReadPtrHandle)); + + /* Set watermark control */ + OUTREG(R128_PM4_BUFFER_WM_CNTL, + ((R128_WATERMARK_L/4) << R128_WMA_SHIFT) + | ((R128_WATERMARK_M/4) << R128_WMB_SHIFT) + | ((R128_WATERMARK_N/4) << R128_WMC_SHIFT) + | ((R128_WATERMARK_K/64) << R128_WB_WM_SHIFT)); + + addr = INREG(R128_PM4_BUFFER_ADDR); /* Force read. Why? Because it's + in the examples... */ + +#if 0 + R128CCEWaitForIdle(pScrn); +#endif + + /* Turn on bus mastering */ + info->BusCntl &= ~R128_BUS_MASTER_DIS; + OUTREGP(R128_BUS_CNTL, 0, ~R128_BUS_MASTER_DIS); +} + +/* Initialize the kernel data structures. */ +static int R128DRIKernelInit(R128InfoPtr info) +{ + drmR128Init drmInfo; + + drmInfo.sarea_priv_offset = sizeof(XF86DRISAREARec); + drmInfo.is_pci = info->IsPCI; + drmInfo.cce_mode = info->CCEMode; + drmInfo.cce_fifo_size = info->CCEFifoSize; + drmInfo.cce_secure = info->CCESecure; + drmInfo.ring_size = info->ringSize*1024*1024; + drmInfo.usec_timeout = info->CCEusecTimeout; + + drmInfo.fb_offset = info->LinearAddr; + drmInfo.agp_ring_offset = info->ringHandle; + drmInfo.agp_read_ptr_offset = info->ringReadPtrHandle; + drmInfo.agp_vertbufs_offset = info->vbHandle; + drmInfo.agp_indbufs_offset = info->indHandle; + drmInfo.agp_textures_offset = info->agpTexHandle; + drmInfo.mmio_offset = info->registerHandle; + + if (drmR128InitCCE(info->drmFD, &drmInfo) < 0) return FALSE; + + return TRUE; +} + +/* Add a map for the vertex buffers that will be accessed by any + DRI-based clients. */ +static Bool R128DRIBufInit(R128InfoPtr info, ScreenPtr pScreen) +{ + /* Initialize vertex buffers */ + if ((info->vbNumBufs = drmAddBufs(info->drmFD, + info->vbMapSize / info->vbBufSize, + info->vbBufSize, + DRM_AGP_BUFFER, + info->vbStart)) <= 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[drm] Could not create vertex buffers list\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[drm] Added %d %d byte vertex buffers\n", + info->vbNumBufs, info->vbBufSize); + + if (drmMarkBufs(info->drmFD, 0.133333, 0.266666)) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[drm] Failed to mark vertex buffers list\n"); + return FALSE; + } + + if (!(info->vbBufs = drmMapBufs(info->drmFD))) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[drm] Failed to map vertex buffers list\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[drm] Mapped %d vertex buffers\n", + info->vbBufs->count); + + return TRUE; +} + +/* Load the microcode for the CCE */ +static void R128DRILoadMicrocode(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int i; + unsigned long R128Microcode[] = { + /* CCE microcode (from ATI) */ + 0, 276838400, 0, 268449792, 2, 142, 2, 145, 0, 1076765731, 0, 1617039951, + 0, 774592877, 0, 1987540286, 0, 2307490946U, 0, 599558925, 0, 589505315, 0, + 596487092, 0, 589505315, 1, 11544576, 1, 206848, 1, 311296, 1, 198656, 2, + 912273422, 11, 262144, 0, 0, 1, 33559837, 1, 7438, 1, 14809, 1, 6615, 12, + 28, 1, 6614, 12, 28, 2, 23, 11, 18874368, 0, 16790922, 1, 409600, 9, 30, 1, + 147854772, 16, 420483072, 3, 8192, 0, 10240, 1, 198656, 1, 15630, 1, 51200, + 10, 34858, 9, 42, 1, 33559823, 2, 10276, 1, 15717, 1, 15718, 2, 43, 1, + 15936948, 1, 570480831, 1, 14715071, 12, 322123831, 1, 33953125, 12, 55, 1, + 33559908, 1, 15718, 2, 46, 4, 2099258, 1, 526336, 1, 442623, 4, 4194365, 1, + 509952, 1, 459007, 3, 0, 12, 92, 2, 46, 12, 176, 1, 15734, 1, 206848, 1, + 18432, 1, 133120, 1, 100670734, 1, 149504, 1, 165888, 1, 15975928, 1, + 1048576, 6, 3145806, 1, 15715, 16, 2150645232U, 2, 268449859, 2, 10307, 12, + 176, 1, 15734, 1, 15735, 1, 15630, 1, 15631, 1, 5253120, 6, 3145810, 16, + 2150645232U, 1, 15864, 2, 82, 1, 343310, 1, 1064207, 2, 3145813, 1, 15728, + 1, 7817, 1, 15729, 3, 15730, 12, 92, 2, 98, 1, 16168, 1, 16167, 1, 16002, + 1, 16008, 1, 15974, 1, 15975, 1, 15990, 1, 15976, 1, 15977, 1, 15980, 0, + 15981, 1, 10240, 1, 5253120, 1, 15720, 1, 198656, 6, 110, 1, 180224, 1, + 103824738, 2, 112, 2, 3145839, 0, 536885440, 1, 114880, 14, 125, 12, + 206975, 1, 33559995, 12, 198784, 0, 33570236, 1, 15803, 0, 15804, 3, + 294912, 1, 294912, 3, 442370, 1, 11544576, 0, 811612160, 1, 12593152, 1, + 11536384, 1, 14024704, 7, 310382726, 0, 10240, 1, 14796, 1, 14797, 1, + 14793, 1, 14794, 0, 14795, 1, 268679168, 1, 9437184, 1, 268449792, 1, + 198656, 1, 9452827, 1, 1075854602, 1, 1075854603, 1, 557056, 1, 114880, 14, + 159, 12, 198784, 1, 1109409213, 12, 198783, 1, 1107312059, 12, 198784, 1, + 1109409212, 2, 162, 1, 1075854781, 1, 1073757627, 1, 1075854780, 1, 540672, + 1, 10485760, 6, 3145894, 16, 274741248, 9, 168, 3, 4194304, 3, 4209949, 0, + 0, 0, 256, 14, 174, 1, 114857, 1, 33560007, 12, 176, 0, 10240, 1, 114858, + 1, 33560018, 1, 114857, 3, 33560007, 1, 16008, 1, 114874, 1, 33560360, 1, + 114875, 1, 33560154, 0, 15963, 0, 256, 0, 4096, 1, 409611, 9, 188, 0, + 10240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0 + }; + + R128WaitForIdle(pScrn); + + OUTREG(R128_PM4_MICROCODE_ADDR, 0); + for (i = 0; i < 256; i += 1) { + OUTREG(R128_PM4_MICROCODE_DATAH, R128Microcode[i*2]); + OUTREG(R128_PM4_MICROCODE_DATAL, R128Microcode[i*2 + 1]); + } +} + +/* Initialize the CCE state, and start the CCE (if used by the X server) */ +static void R128DRICCEInit(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + /* CCEMode is initialized in r128_driver.c */ + switch (info->CCEMode) { + case R128_PM4_NONPM4: info->CCEFifoSize = 0; break; + case R128_PM4_192PIO: info->CCEFifoSize = 192; break; + case R128_PM4_192BM: info->CCEFifoSize = 192; break; + case R128_PM4_128PIO_64INDBM: info->CCEFifoSize = 128; break; + case R128_PM4_128BM_64INDBM: info->CCEFifoSize = 128; break; + case R128_PM4_64PIO_128INDBM: info->CCEFifoSize = 64; break; + case R128_PM4_64BM_128INDBM: info->CCEFifoSize = 64; break; + case R128_PM4_64PIO_64VCBM_64INDBM: info->CCEFifoSize = 64; break; + case R128_PM4_64BM_64VCBM_64INDBM: info->CCEFifoSize = 64; break; + case R128_PM4_64PIO_64VCPIO_64INDPIO: info->CCEFifoSize = 64; break; + } + + if (info->CCE2D) { + /* Make sure the CCE is on for the X server */ + R128CCEStart(pScrn); + } else { + /* Make sure the CCE is off for the X server */ + OUTREG(R128_PM4_MICRO_CNTL, 0); + OUTREG(R128_PM4_BUFFER_CNTL, R128_PM4_NONPM4); + } +} + +/* Initialize the screen-specific data structures for the DRI and the + Rage 128. This is the main entry point to the device-specific + initialization code. It calls device-independent DRI functions to + create the DRI data structures and initialize the DRI state. */ +Bool R128DRIScreenInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + DRIInfoPtr pDRIInfo; + R128DRIPtr pR128DRI; + int major, minor, patch; + drmVersionPtr version; + + /* Check that the GLX, DRI, and DRM modules have been loaded by testing + * for known symbols in each module. */ + if (!xf86LoaderCheckSymbol("GlxSetVisualConfigs")) return FALSE; + if (!xf86LoaderCheckSymbol("DRIScreenInit")) return FALSE; + if (!xf86LoaderCheckSymbol("drmAvailable")) return FALSE; + if (!xf86LoaderCheckSymbol("DRIQueryVersion")) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "R128DRIScreenInit failed (libdri.a too old)\n"); + return FALSE; + } + + /* Check the DRI version */ + DRIQueryVersion(&major, &minor, &patch); + if (major != 3 || minor != 0 || patch < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "R128DRIScreenInit failed " + "(DRI version = %d.%d.%d, expected 3.0.x). " + "Disabling DRI.\n", + major, minor, patch); + return FALSE; + } + + switch (info->CurrentLayout.pixel_code) { + case 8: + /* These modes are not supported (yet). */ + case 15: + case 24: + return FALSE; + + /* Only 16 and 32 color depths are supports currently. */ + case 16: + case 32: + break; + } + + /* Create the DRI data structure, and fill it in before calling the + DRIScreenInit(). */ + if (!(pDRIInfo = DRICreateInfoRec())) return FALSE; + + info->pDRIInfo = pDRIInfo; + pDRIInfo->drmDriverName = R128_DRIVER_NAME; + pDRIInfo->clientDriverName = R128_DRIVER_NAME; + pDRIInfo->busIdString = xalloc(64); + sprintf(pDRIInfo->busIdString, + "PCI:%d:%d:%d", + info->PciInfo->bus, + info->PciInfo->device, + info->PciInfo->func); + pDRIInfo->ddxDriverMajorVersion = R128_VERSION_MAJOR; + pDRIInfo->ddxDriverMinorVersion = R128_VERSION_MINOR; + pDRIInfo->ddxDriverPatchVersion = R128_VERSION_PATCH; + pDRIInfo->frameBufferPhysicalAddress = info->LinearAddr; + pDRIInfo->frameBufferSize = info->FbMapSize; + pDRIInfo->frameBufferStride = (pScrn->displayWidth * + info->CurrentLayout.pixel_bytes); + pDRIInfo->ddxDrawableTableEntry = R128_MAX_DRAWABLES; + pDRIInfo->maxDrawableTableEntry = (SAREA_MAX_DRAWABLES + < R128_MAX_DRAWABLES + ? SAREA_MAX_DRAWABLES + : R128_MAX_DRAWABLES); + +#ifdef NOT_DONE + /* FIXME: Need to extend DRI protocol to pass this size back to + * client for SAREA mapping that includes a device private record + */ + pDRIInfo->SAREASize = + ((sizeof(XF86DRISAREARec) + 0xfff) & 0x1000); /* round to page */ + /* + shared memory device private rec */ +#else + /* For now the mapping works by using a fixed size defined + * in the SAREA header + */ + if (sizeof(XF86DRISAREARec)+sizeof(R128SAREAPriv)>SAREA_MAX) { + ErrorF("Data does not fit in SAREA\n"); + return FALSE; + } + pDRIInfo->SAREASize = SAREA_MAX; +#endif + + if (!(pR128DRI = (R128DRIPtr)xnfcalloc(sizeof(R128DRIRec),1))) { + DRIDestroyInfoRec(info->pDRIInfo); + info->pDRIInfo = NULL; + return FALSE; + } + pDRIInfo->devPrivate = pR128DRI; + pDRIInfo->devPrivateSize = sizeof(R128DRIRec); + pDRIInfo->contextSize = sizeof(R128DRIContextRec); + + pDRIInfo->CreateContext = R128CreateContext; + pDRIInfo->DestroyContext = R128DestroyContext; + pDRIInfo->SwapContext = R128DRISwapContext; + pDRIInfo->InitBuffers = R128DRIInitBuffers; + pDRIInfo->MoveBuffers = R128DRIMoveBuffers; + pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; + + if (!DRIScreenInit(pScreen, pDRIInfo, &info->drmFD)) { + xfree(pDRIInfo->devPrivate); + pDRIInfo->devPrivate = NULL; + DRIDestroyInfoRec(pDRIInfo); + pDRIInfo = NULL; + return FALSE; + } + + /* Check the r128 DRM version */ + version = drmGetVersion(info->drmFD); + if (version) { + if (version->version_major != 1 || + version->version_minor != 0 || + version->version_patchlevel < 0) { + /* incompatible drm version */ + xf86DrvMsg(pScreen->myNum, X_ERROR, + "R128DRIScreenInit failed " + "(DRM version = %d.%d.%d, expected 1.0.x). " + "Disabling DRI.\n", + version->version_major, + version->version_minor, + version->version_patchlevel); + drmFreeVersion(version); + R128DRICloseScreen(pScreen); + return FALSE; + } + drmFreeVersion(version); + } + + /* Initialize AGP */ + if (!info->IsPCI && !R128DRIAgpInit(info, pScreen)) { + R128DRICloseScreen(pScreen); + return FALSE; + } + /* Initialize PCI */ + if (info->IsPCI && !R128DRIPciInit(info)) { + R128DRICloseScreen(pScreen); + return FALSE; + } + + /* DRIScreenInit doesn't add all the + common mappings. Add additional + mappings here. */ + if (!R128DRIMapInit(info, pScreen)) { + R128DRICloseScreen(pScreen); + return FALSE; + } + + /* Initialize the ring buffer */ + if (!info->IsPCI) R128DRICCEInitRingBuffer(pScrn); + + /* Initialize the kernel data structures */ + if (!R128DRIKernelInit(info)) { + R128DRICloseScreen(pScreen); + return FALSE; + } + + /* Initialize vertex buffers list */ + if (!info->IsPCI && !R128DRIBufInit(info, pScreen)) { + R128DRICloseScreen(pScreen); + return FALSE; + } + + /* FIXME: When are these mappings unmapped? */ + + if (!R128InitVisualConfigs(pScreen)) { + R128DRICloseScreen(pScreen); + return FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Visual configs initialized\n"); + + /* Load the CCE Microcode */ + R128DRILoadMicrocode(pScrn); + + /* Reset the Graphics Engine */ + R128EngineReset(pScrn); + + return TRUE; +} + +/* Finish initializing the device-dependent DRI state, and call + DRIFinishScreenInit() to complete the device-independent DRI + initialization. */ +Bool R128DRIFinishScreenInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + R128SAREAPrivPtr pSAREAPriv; + R128DRIPtr pR128DRI; + + /* Init and start the CCE */ + R128DRICCEInit(pScrn); + + pSAREAPriv = (R128SAREAPrivPtr)DRIGetSAREAPrivate(pScreen); + memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); + + info->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT; + /* info->pDRIInfo->driverSwapMethod = DRI_SERVER_SWAP; */ + + pR128DRI = (R128DRIPtr)info->pDRIInfo->devPrivate; + pR128DRI->registerHandle = info->registerHandle; + pR128DRI->registerSize = info->registerSize; + + pR128DRI->ringHandle = info->ringHandle; + pR128DRI->ringMapSize = info->ringMapSize; + pR128DRI->ringSize = info->ringSize*1024*1024; + + pR128DRI->ringReadPtrHandle = info->ringReadPtrHandle; + pR128DRI->ringReadMapSize = info->ringReadMapSize; + + pR128DRI->vbHandle = info->vbHandle; + pR128DRI->vbMapSize = info->vbMapSize; + pR128DRI->vbOffset = info->vbStart; + pR128DRI->vbBufSize = info->vbBufSize; + + pR128DRI->indHandle = info->indHandle; + pR128DRI->indMapSize = info->indMapSize; + + pR128DRI->agpTexHandle = info->agpTexHandle; + pR128DRI->agpTexMapSize = info->agpTexMapSize; + pR128DRI->log2AGPTexGran = info->log2AGPTexGran; + pR128DRI->agpTexOffset = info->agpTexStart; + + pR128DRI->deviceID = info->Chipset; + pR128DRI->width = pScrn->virtualX; + pR128DRI->height = pScrn->virtualY; + pR128DRI->depth = pScrn->depth; + pR128DRI->bpp = pScrn->bitsPerPixel; + + pR128DRI->fbX = info->fbX; + pR128DRI->fbY = info->fbY; + pR128DRI->backX = info->backX; + pR128DRI->backY = info->backY; + pR128DRI->depthX = info->depthX; + pR128DRI->depthY = info->depthY; + pR128DRI->textureX = info->textureX; + pR128DRI->textureY = info->textureY; + pR128DRI->textureSize = info->textureSize; + pR128DRI->log2TexGran = info->log2TexGran; + + pR128DRI->IsPCI = info->IsPCI; + + pR128DRI->CCEMode = info->CCEMode; + pR128DRI->CCEFifoSize = info->CCEFifoSize; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "0x%08lx %d\n", + pR128DRI->registerHandle, pR128DRI->registerSize); + return DRIFinishScreenInit(pScreen); +} + +/* The screen is being closed, so clean up any state and free any + resources used by the DRI. */ +void R128DRICloseScreen(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + + /* Stop the CCE if it is still in use */ + if (info->CCE2D) R128CCEStop(pScrn); + + /* De-allocate vertex buffers */ + if (info->vbBufs) { + drmUnmapBufs(info->vbBufs); + info->vbBufs = NULL; + } + + /* De-allocate all kernel resources */ + drmR128CleanupCCE(info->drmFD); + + /* De-allocate all AGP resources */ + if (info->agpTex) { + drmUnmap(info->agpTex, info->agpTexMapSize); + info->agpTex = NULL; + } + if (info->ind) { + drmUnmap(info->ind, info->indMapSize); + info->ind = NULL; + } + if (info->vb) { + drmUnmap(info->vb, info->vbMapSize); + info->vb = NULL; + } + if (info->ringReadPtr) { + drmUnmap(info->ringReadPtr, info->ringReadMapSize); + info->ringReadPtr = NULL; + } + if (info->ring) { + drmUnmap(info->ring, info->ringMapSize); + info->ring = NULL; + } + if (info->agpMemHandle) { + drmAgpUnbind(info->drmFD, info->agpMemHandle); + drmAgpFree(info->drmFD, info->agpMemHandle); + info->agpMemHandle = 0; + drmAgpRelease(info->drmFD); + } + + /* De-allocate all DRI resources */ + DRICloseScreen(pScreen); + + /* De-allocate all DRI data structures */ + if (info->pDRIInfo) { + if (info->pDRIInfo->devPrivate) { + xfree(info->pDRIInfo->devPrivate); + info->pDRIInfo->devPrivate = NULL; + } + DRIDestroyInfoRec(info->pDRIInfo); + info->pDRIInfo = NULL; + } + if (info->pVisualConfigs) { + xfree(info->pVisualConfigs); + info->pVisualConfigs = NULL; + } + if (info->pVisualConfigsPriv) { + xfree(info->pVisualConfigsPriv); + info->pVisualConfigsPriv = NULL; + } +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h new file mode 100644 index 000000000..d9cdda3aa --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h @@ -0,0 +1,115 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h,v 1.1 2000/11/02 16:55:33 tsi Exp $ */ +/* + * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario + * and Precision Insight, Inc., Cedar Park, Texas. + * + * 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 on + * 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, PRECISION INSIGHT AND/OR THEIR 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: + * Kevin E. Martin <kevin@precisioninsight.com> + * Rickard E. Faith <faith@precisioninsight.com> + * + */ + +#ifndef _R128_DRI_ +#define _R128_DRI_ + +#include <xf86drm.h> + +/* DRI Driver defaults */ +#define R128_DEFAULT_CCE_PIO_MODE R128_PM4_64PIO_64VCBM_64INDBM +#define R128_DEFAULT_CCE_BM_MODE R128_PM4_64BM_64VCBM_64INDBM +#define R128_DEFAULT_AGP_MODE 2 +#define R128_DEFAULT_AGP_SIZE 8 /* MB (must be a power of 2 and > 4MB) */ +#define R128_DEFAULT_RING_SIZE 1 /* MB (must be page aligned) */ +#define R128_DEFAULT_VB_SIZE 1 /* MB (must be page aligned) */ +#define R128_DEFAULT_IND_SIZE 1 /* MB (must be page aligned) */ +#define R128_DEFAULT_AGP_TEX_SIZE 1 /* MB (must be page aligned) */ + +#define R128_DEFAULT_VB_BUF_SIZE 16384 /* bytes */ +#define R128_DEFAULT_CCE_TIMEOUT 10000 /* usecs */ + +#define R128_AGP_MAX_MODE 2 + +#define R128CCE_USE_RING_BUFFER(m) \ +(((m) == R128_PM4_192BM) || \ + ((m) == R128_PM4_128BM_64INDBM) || \ + ((m) == R128_PM4_64BM_128INDBM) || \ + ((m) == R128_PM4_64BM_64VCBM_64INDBM)) + +typedef struct { + /* MMIO register data */ + drmHandle registerHandle; + drmSize registerSize; + + /* CCE ring buffer data */ + drmHandle ringHandle; + drmSize ringMapSize; + int ringSize; + + /* CCE ring read pointer data */ + drmHandle ringReadPtrHandle; + drmSize ringReadMapSize; + + /* CCE vertex buffer data */ + drmHandle vbHandle; + drmSize vbMapSize; + int vbOffset; + int vbBufSize; + + /* CCE indirect buffer data */ + drmHandle indHandle; + drmSize indMapSize; + + /* CCE AGP Texture data */ + drmHandle agpTexHandle; + drmSize agpTexMapSize; + int log2AGPTexGran; + int agpTexOffset; + + /* DRI screen private data */ + int deviceID; /* PCI device ID */ + int width; /* Width in pixels of display */ + int height; /* Height in scanlines of display */ + int depth; /* Depth of display (8, 15, 16, 24) */ + int bpp; /* Bit depth of display (8, 16, 24, 32) */ + + int fbX; /* Start of frame buffer */ + int fbY; + int backX; /* Start of shared back buffer */ + int backY; + int depthX; /* Start of shared depth buffer */ + int depthY; + int textureX; /* Start of texture data in frame buffer */ + int textureY; + int textureSize; + int log2TexGran; + + int IsPCI; /* Current card is a PCI card */ + + int CCEMode; /* CCE mode that server/clients use */ + int CCEFifoSize; /* Size of the CCE command FIFO */ +} R128DRIRec, *R128DRIPtr; + +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dripriv.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dripriv.h new file mode 100644 index 000000000..f26fe2bba --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dripriv.h @@ -0,0 +1,53 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dripriv.h,v 1.1 2000/11/02 16:55:34 tsi Exp $ */ +/* + * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario + * and Precision Insight, Inc., Cedar Park, Texas. + * + * 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 on + * 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, PRECISION INSIGHT AND/OR THEIR 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: + * Rickard E. Faith <faith@precisioninsight.com> + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#ifndef _R128_DRIPRIV_H_ +#define _R128_DRIPRIV_H_ + +#define R128_MAX_DRAWABLES 256 + +extern void GlxSetVisualConfigs(int nconfigs, __GLXvisualConfig *configs, + void **configprivs); + +typedef struct { + /* Nothing here yet */ + int dummy; +} R128ConfigPrivRec, *R128ConfigPrivPtr; + +typedef struct { + /* Nothing here yet */ + int dummy; +} R128DRIContextRec, *R128DRIContextPtr; + +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c new file mode 100644 index 000000000..008c1c553 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c @@ -0,0 +1,2839 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c,v 1.1 2000/11/02 16:55:35 tsi Exp $ */ +/* + * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario + * and Precision Insight, Inc., Cedar Park, Texas. + * + * 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 on + * 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, PRECISION INSIGHT AND/OR THEIR 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: + * Rickard E. Faith <faith@precisioninsight.com> + * Kevin E. Martin <kevin@precisioninsight.com> + * + * Credits: + * + * Thanks to Alan Hourihane <alanh@fairlite.demon..co.uk> and SuSE for + * providing source code to their 3.3.x Rage 128 driver. Portions of + * this file are based on the initialization code for that driver. + * + * References: + * + * RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical + * Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April + * 1999. + * + * RAGE 128 Software Development Manual (Technical Reference Manual P/N + * SDK-G04000 Rev. 0.01), ATI Technologies: June 1999. + * + * This server does not yet support these XFree86 4.0 features: + * DDC1 & DDC2 + * shadowfb + * overlay planes + * DGA + * + * Modified by Marc Aurele La France <tsi@xfree86.org> for ATI driver merge. + */ + + + /* X and server generic header files */ +#include "xf86.h" +#include "xf86_ansic.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "xf86RAC.h" +#include "xf86cmap.h" +#include "xf86fbman.h" +#include "xf86int10.h" + /* Backing store, software cursor, and + colormap initialization */ +#include "mibstore.h" +#include "mipointer.h" +#include "micmap.h" + +#define USE_FB /* not until overlays */ +#ifdef USE_FB +#include "fb.h" +#else + /* CFB support */ +#define PSZ 8 +#include "cfb.h" +#undef PSZ +#include "cfb16.h" +#include "cfb24.h" +#include "cfb32.h" +#include "cfb24_32.h" +#endif + /* Driver data structures */ +#include "r128.h" +#include "r128_probe.h" +#include "r128_reg.h" +#include "r128_version.h" + +#ifndef MAX +#define MAX(a,b) ((a)>(b)?(a):(b)) +#endif + + + /* Forward definitions for driver functions */ +static Bool R128CloseScreen(int scrnIndex, ScreenPtr pScreen); +static Bool R128SaveScreen(ScreenPtr pScreen, int mode); +static void R128Save(ScrnInfoPtr pScrn); +static void R128Restore(ScrnInfoPtr pScrn); +static Bool R128ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); +static void R128DisplayPowerManagementSet(ScrnInfoPtr pScrn, + int PowerManagementMode, int flags); +static Bool R128EnterVTFBDev(int scrnIndex, int flags); +static void R128LeaveVTFBDev(int scrnIndex, int flags); + +typedef enum { + OPTION_NOACCEL, + OPTION_SW_CURSOR, + OPTION_DAC_6BIT, + OPTION_DAC_8BIT, +#ifdef XF86DRI + OPTION_IS_PCI, + OPTION_CCE_PIO, + OPTION_NO_SECURITY, + OPTION_USEC_TIMEOUT, + OPTION_AGP_MODE, + OPTION_AGP_SIZE, + OPTION_RING_SIZE, + OPTION_VERT_SIZE, + OPTION_VBUF_SIZE, + OPTION_USE_CCE_2D, +#endif +#if 0 + /* FIXME: Disable CRTOnly until it is tested */ + OPTION_CRT, +#endif + OPTION_PANEL_WIDTH, + OPTION_PANEL_HEIGHT, + OPTION_PROG_FP_REGS, + OPTION_FBDEV +} R128Opts; + +OptionInfoRec R128Options[] = { + { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_DAC_6BIT, "Dac6Bit", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_DAC_8BIT, "Dac8Bit", OPTV_BOOLEAN, {0}, TRUE }, +#ifdef XF86DRI + { OPTION_IS_PCI, "ForcePCIMode", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_CCE_PIO, "CCEPIOMode", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_NO_SECURITY, "CCENoSecurity", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_USEC_TIMEOUT, "CCEusecTimeout", OPTV_INTEGER, {0}, FALSE }, + { OPTION_AGP_MODE, "AGPMode", OPTV_INTEGER, {0}, FALSE }, + { OPTION_AGP_SIZE, "AGPSize", OPTV_INTEGER, {0}, FALSE }, + { OPTION_RING_SIZE, "RingSize", OPTV_INTEGER, {0}, FALSE }, + { OPTION_VERT_SIZE, "VBListSize", OPTV_INTEGER, {0}, FALSE }, + { OPTION_VBUF_SIZE, "VBSize", OPTV_INTEGER, {0}, FALSE }, + { OPTION_USE_CCE_2D, "UseCCEfor2D", OPTV_BOOLEAN, {0}, FALSE }, +#endif +#if 0 + /* FIXME: Disable CRTOnly until it is tested */ + { OPTION_CRT, "CRTOnly", OPTV_BOOLEAN, {0}, FALSE }, +#endif + { OPTION_PANEL_WIDTH, "PanelWidth", OPTV_INTEGER, {0}, FALSE }, + { OPTION_PANEL_HEIGHT, "PanelHeight", OPTV_INTEGER, {0}, FALSE }, + { OPTION_PROG_FP_REGS, "ProgramFPRegs", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_FBDEV, "UseFBDev", OPTV_BOOLEAN, {0}, FALSE }, + { -1, NULL, OPTV_NONE, {0}, FALSE } +}; + +R128RAMRec R128RAM[] = { /* Memory Specifications + From RAGE 128 Software Development + Manual (Technical Reference Manual P/N + SDK-G04000 Rev 0.01), page 3-21. */ + { 4, 4, 3, 3, 1, 3, 1, 16, 12, "128-bit SDR SGRAM 1:1" }, + { 4, 8, 3, 3, 1, 3, 1, 17, 13, "64-bit SDR SGRAM 1:1" }, + { 4, 4, 1, 2, 1, 2, 1, 16, 12, "64-bit SDR SGRAM 2:1" }, + { 4, 4, 3, 3, 2, 3, 1, 16, 12, "64-bit DDR SGRAM" }, +}; + +static const char *vgahwSymbols[] = { + "vgaHWGetHWRec", + "vgaHWFreeHWRec", + "vgaHWLock", + "vgaHWUnlock", + "vgaHWSave", + "vgaHWRestore", + NULL +}; + +static const char *fbdevHWSymbols[] = { + "fbdevHWInit", + "fbdevHWUseBuildinMode", + + "fbdevHWGetDepth", + "fbdevHWGetVidmem", + + /* colormap */ + "fbdevHWLoadPalette", + + /* ScrnInfo hooks */ + "fbdevHWSwitchMode", + "fbdevHWAdjustFrame", + "fbdevHWEnterVT", + "fbdevHWLeaveVT", + "fbdevHWValidMode", + "fbdevHWRestore", + "fbdevHWModeInit", + "fbdevHWSave", + + "fbdevHWUnmapMMIO", + "fbdevHWUnmapVidmem", + "fbdevHWMapMMIO", + "fbdevHWMapVidmem", + + NULL +}; + +static const char *ddcSymbols[] = { + "xf86PrintEDID", + "xf86DoEDID_DDC1", + "xf86DoEDID_DDC2", + NULL +}; + +#ifdef XFree86LOADER +#ifdef USE_FB +static const char *fbSymbols[] = { + "fbScreenInit", + NULL +}; +#else +static const char *cfbSymbols[] = { + "cfbScreenInit", + "cfb16ScreenInit", + "cfb24ScreenInit", + "cfb32ScreenInit", + "cfb24_32ScreenInit", + NULL +}; +#endif + +static const char *xaaSymbols[] = { + "XAADestroyInfoRec", + "XAACreateInfoRec", + "XAAInit", + "XAAStippleScanlineFuncLSBFirst", + "XAAOverlayFBfuncs", + "XAACachePlanarMonoStipple", + "XAAScreenIndex", + NULL +}; + +static const char *xf8_32bppSymbols[] = { + "xf86Overlay8Plus32Init", + NULL +}; + +static const char *ramdacSymbols[] = { + "xf86InitCursor", + "xf86CreateCursorInfoRec", + "xf86DestroyCursorInfoRec", + NULL +}; + +#ifdef XF86DRI +static const char *drmSymbols[] = { + "drmAddBufs", + "drmAddMap", + "drmAvailable", + "drmCtlAddCommand", + "drmCtlInstHandler", + "drmGetInterruptFromBusID", + "drmMapBufs", + "drmMarkBufs", + "drmUnmapBufs", + "drmFreeVersion", + "drmGetVersion", + NULL +}; + +static const char *driSymbols[] = { + "DRIGetDrawableIndex", + "DRIFinishScreenInit", + "DRIDestroyInfoRec", + "DRICloseScreen", + "DRIDestroyInfoRec", + "DRIScreenInit", + "DRIDestroyInfoRec", + "DRICreateInfoRec", + "DRILock", + "DRIUnlock", + "DRIGetSAREAPrivate", + "DRIGetContext", + "DRIQueryVersion", + "GlxSetVisualConfigs", + NULL +}; +#endif + +static const char *vbeSymbols[] = { + "VBEInit", + "vbeDoEDID", + NULL +}; +#endif + +/* Allocate our private R128InfoRec. */ +static Bool R128GetRec(ScrnInfoPtr pScrn) +{ + if (pScrn->driverPrivate) return TRUE; + + pScrn->driverPrivate = xnfcalloc(sizeof(R128InfoRec), 1); + return TRUE; +} + +/* Free our private R128InfoRec. */ +static void R128FreeRec(ScrnInfoPtr pScrn) +{ + if (!pScrn || !pScrn->driverPrivate) return; + xfree(pScrn->driverPrivate); + pScrn->driverPrivate = NULL; +} + +/* Memory map the MMIO region. Used during pre-init and by R128MapMem, + below. */ +static Bool R128MapMMIO(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + + if (info->FBDev) { + info->MMIO = fbdevHWMapMMIO(pScrn); + } else { + info->MMIO = xf86MapPciMem(pScrn->scrnIndex, + VIDMEM_MMIO | VIDMEM_READSIDEEFFECT, + info->PciTag, + info->MMIOAddr, + R128_MMIOSIZE); + } + + if (!info->MMIO) return FALSE; + return TRUE; +} + +/* Unmap the MMIO region. Used during pre-init and by R128UnmapMem, + below. */ +static Bool R128UnmapMMIO(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + + if (info->FBDev) + fbdevHWUnmapMMIO(pScrn); + else { + xf86UnMapVidMem(pScrn->scrnIndex, info->MMIO, R128_MMIOSIZE); + } + info->MMIO = NULL; + return TRUE; +} + +/* Memory map the frame buffer. Used by R128MapMem, below. */ +static Bool R128MapFB(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + + if (info->FBDev) { + info->FB = fbdevHWMapVidmem(pScrn); + } else { + info->FB = xf86MapPciMem(pScrn->scrnIndex, + VIDMEM_FRAMEBUFFER, + info->PciTag, + info->LinearAddr, + info->FbMapSize); + } + + if (!info->FB) return FALSE; + return TRUE; +} + +/* Unmap the frame buffer. Used by R128UnmapMem, below. */ +static Bool R128UnmapFB(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + + if (info->FBDev) + fbdevHWUnmapVidmem(pScrn); + else + xf86UnMapVidMem(pScrn->scrnIndex, info->FB, info->FbMapSize); + info->FB = NULL; + return TRUE; +} + +/* Memory map the MMIO region and the frame buffer. */ +static Bool R128MapMem(ScrnInfoPtr pScrn) +{ + if (!R128MapMMIO(pScrn)) return FALSE; + if (!R128MapFB(pScrn)) { + R128UnmapMMIO(pScrn); + return FALSE; + } + return TRUE; +} + +/* Unmap the MMIO region and the frame buffer. */ +static Bool R128UnmapMem(ScrnInfoPtr pScrn) +{ + if (!R128UnmapMMIO(pScrn) || !R128UnmapFB(pScrn)) return FALSE; + return TRUE; +} + +/* Read PLL information */ +int R128INPLL(ScrnInfoPtr pScrn, int addr) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + OUTREG8(R128_CLOCK_CNTL_INDEX, addr & 0x1f); + return INREG(R128_CLOCK_CNTL_DATA); +} + +#if 0 +/* Read PAL information (only used for debugging). */ +static int R128INPAL(int idx) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + OUTREG(R128_PALETTE_INDEX, idx << 16); + return INREG(R128_PALETTE_DATA); +} +#endif + +/* Wait for vertical sync. */ +void R128WaitForVerticalSync(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int i; + + OUTREG(R128_GEN_INT_STATUS, R128_VSYNC_INT_AK); + for (i = 0; i < R128_TIMEOUT; i++) { + if (INREG(R128_GEN_INT_STATUS) & R128_VSYNC_INT) break; + } +} + +/* Blank screen. */ +static void R128Blank(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + OUTREGP(R128_CRTC_EXT_CNTL, R128_CRTC_DISPLAY_DIS, ~R128_CRTC_DISPLAY_DIS); +} + +/* Unblank screen. */ +static void R128Unblank(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + OUTREGP(R128_CRTC_EXT_CNTL, 0, ~R128_CRTC_DISPLAY_DIS); +} + +/* Compute log base 2 of val. */ +int R128MinBits(int val) +{ + int bits; + + if (!val) return 1; + for (bits = 0; val; val >>= 1, ++bits); + return bits; +} + +/* Compute n/d with rounding. */ +static int R128Div(int n, int d) +{ + return (n + (d / 2)) / d; +} + +/* Read the Video BIOS block and the FP registers (if applicable). */ +static Bool R128GetBIOSParameters(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + int i; + int FPHeader = 0; + +#define R128ReadBIOS(offset, buffer, length) \ + (info->BIOSFromPCI ? \ + xf86ReadPciBIOS(offset, info->PciTag, 0, buffer, length) : \ + xf86ReadBIOS(info->BIOSAddr, offset, buffer, length)) + +#define R128_BIOS8(v) (info->VBIOS[v]) +#define R128_BIOS16(v) (info->VBIOS[v] | \ + (info->VBIOS[(v) + 1] << 8)) +#define R128_BIOS32(v) (info->VBIOS[v] | \ + (info->VBIOS[(v) + 1] << 8) | \ + (info->VBIOS[(v) + 2] << 16) | \ + (info->VBIOS[(v) + 3] << 24)) + + if (!(info->VBIOS = xalloc(R128_VBIOS_SIZE))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Cannot allocate space for hold Video BIOS!\n"); + return FALSE; + } + + info->BIOSFromPCI = TRUE; + R128ReadBIOS(0x0000, info->VBIOS, R128_VBIOS_SIZE); + if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Video BIOS not detected in PCI space!\n"); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Attempting to read Video BIOS from legacy ISA space!\n"); + info->BIOSFromPCI = FALSE; + info->BIOSAddr = 0x000c0000; + R128ReadBIOS(0x0000, info->VBIOS, R128_VBIOS_SIZE); + } + if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) { + info->BIOSAddr = 0x00000000; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Video BIOS not found!\n"); + } + + if (info->HasPanelRegs) { + info->FPBIOSstart = 0; + + /* FIXME: There should be direct access to the start of the FP info + tables, but until we find out where that offset is stored, we + must search for the ATI signature string: "M3 ". */ + for (i = 4; i < R128_VBIOS_SIZE-8; i++) { + if (R128_BIOS8(i) == 'M' && + R128_BIOS8(i+1) == '3' && + R128_BIOS8(i+2) == ' ' && + R128_BIOS8(i+3) == ' ' && + R128_BIOS8(i+4) == ' ' && + R128_BIOS8(i+5) == ' ' && + R128_BIOS8(i+6) == ' ' && + R128_BIOS8(i+7) == ' ') { + FPHeader = i-2; + break; + } + } + + if (!FPHeader) return TRUE; + + /* Assume that only one panel is attached and supported */ + for (i = FPHeader+20; i < FPHeader+84; i += 2) { + if (R128_BIOS16(i) != 0) { + info->FPBIOSstart = R128_BIOS16(i); + break; + } + } + if (!info->FPBIOSstart) return TRUE; + + if (!info->PanelXRes) + info->PanelXRes = R128_BIOS16(info->FPBIOSstart+25); + if (!info->PanelYRes) + info->PanelYRes = R128_BIOS16(info->FPBIOSstart+27); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel size: %dx%d\n", + info->PanelXRes, info->PanelYRes); + + info->PanelPwrDly = R128_BIOS8(info->FPBIOSstart+56); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel ID: "); + for (i = 1; i <= 24; i++) + ErrorF("%c", R128_BIOS8(info->FPBIOSstart+i)); + ErrorF("\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel Type: "); + i = R128_BIOS16(info->FPBIOSstart+29); + if (i & 1) ErrorF("Color, "); + else ErrorF("Monochrome, "); + if (i & 2) ErrorF("Dual(split), "); + else ErrorF("Single, "); + switch ((i >> 2) & 0x3f) { + case 0: ErrorF("STN"); break; + case 1: ErrorF("TFT"); break; + case 2: ErrorF("Active STN"); break; + case 3: ErrorF("EL"); break; + case 4: ErrorF("Plasma"); break; + default: ErrorF("UNKNOWN"); break; + } + ErrorF("\n"); + if (R128_BIOS8(info->FPBIOSstart+61) & 1) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel Interface: LVDS\n"); + } else { + /* FIXME: Add Non-LVDS flat pael support */ + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Non-LVDS panel interface detected! " + "This support is untested and may not " + "function properly\n"); + } + } + + return TRUE; +} + +/* Read PLL parameters from BIOS block. Default to typical values if there + is no BIOS. */ +static Bool R128GetPLLParameters(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + R128PLLPtr pll = &info->pll; + CARD16 bios_header; + CARD16 pll_info_block; + + + if (!info->VBIOS) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Video BIOS not detected, using default PLL parameters!\n"); + /* These probably aren't going to work for + the card you are using. Specifically, + reference freq can be 29.50MHz, + 28.63MHz, or 14.32MHz. YMMV. */ + pll->reference_freq = 2950; + pll->reference_div = 65; + pll->min_pll_freq = 12500; + pll->max_pll_freq = 25000; + pll->xclk = 10300; + } else { + bios_header = R128_BIOS16(0x48); + pll_info_block = R128_BIOS16(bios_header + 0x30); + R128TRACE(("Header at 0x%04x; PLL Information at 0x%04x\n", + bios_header, pll_info_block)); + + pll->reference_freq = R128_BIOS16(pll_info_block + 0x0e); + pll->reference_div = R128_BIOS16(pll_info_block + 0x10); + pll->min_pll_freq = R128_BIOS32(pll_info_block + 0x12); + pll->max_pll_freq = R128_BIOS32(pll_info_block + 0x16); + pll->xclk = R128_BIOS16(pll_info_block + 0x08); + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "PLL parameters: rf=%d rd=%d min=%d max=%d; xclk=%d\n", + pll->reference_freq, + pll->reference_div, + pll->min_pll_freq, + pll->max_pll_freq, + pll->xclk); + + return TRUE; +} + +/* This is called by R128PreInit to set up the default visual. */ +static Bool R128PreInitVisual(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + + if (!xf86SetDepthBpp(pScrn, 8, 8, 8, (Support24bppFb + | Support32bppFb + | SupportConvert32to24 + ))) + return FALSE; + + switch (pScrn->depth) { + case 8: + case 15: + case 16: + case 24: + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given depth (%d) is not supported by %s driver\n", + pScrn->depth, R128_DRIVER_NAME); + return FALSE; + } + + xf86PrintDepthBpp(pScrn); + + info->fifo_slots = 0; + info->pix24bpp = xf86GetBppFromDepth(pScrn, pScrn->depth); + info->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel; + info->CurrentLayout.depth = pScrn->depth; + info->CurrentLayout.pixel_bytes = pScrn->bitsPerPixel / 8; + info->CurrentLayout.pixel_code = (pScrn->bitsPerPixel != 16 + ? pScrn->bitsPerPixel + : pScrn->depth); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Pixel depth = %d bits stored in %d byte%s (%d bpp pixmaps)\n", + pScrn->depth, + info->CurrentLayout.pixel_bytes, + info->CurrentLayout.pixel_bytes > 1 ? "s" : "", + info->pix24bpp); + + + if (!xf86SetDefaultVisual(pScrn, -1)) return FALSE; + + if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Default visual (%s) is not supported at depth %d\n", + xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); + return FALSE; + } + return TRUE; + +} + +/* This is called by R128PreInit to handle all color weight issues. */ +static Bool R128PreInitWeight(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + + /* Save flag for 6 bit DAC to use for + setting CRTC registers. Otherwise use + an 8 bit DAC, even if xf86SetWeight sets + pScrn->rgbBits to some value other than + 8. */ + info->dac6bits = FALSE; + if (pScrn->depth > 8) { + rgb defaultWeight = { 0, 0, 0 }; + if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight)) return FALSE; + } else { + pScrn->rgbBits = 8; + if (xf86ReturnOptValBool(R128Options, OPTION_DAC_6BIT, FALSE)) { + pScrn->rgbBits = 6; + info->dac6bits = TRUE; + } + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d bits per RGB (%d bit DAC)\n", + pScrn->rgbBits, info->dac6bits ? 6 : 8); + + return TRUE; + +} + +/* This is called by R128PreInit to handle config file overrides for things + like chipset and memory regions. Also determine memory size and type. + If memory type ever needs an override, put it in this routine. */ +static Bool R128PreInitConfig(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + EntityInfoPtr pEnt = info->pEnt; + GDevPtr dev = pEnt->device; + int offset = 0; /* RAM Type */ + MessageType from; + + /* Chipset */ + from = X_PROBED; + if (dev->chipset && *dev->chipset) { + info->Chipset = xf86StringToToken(R128Chipsets, dev->chipset); + from = X_CONFIG; + } else if (dev->chipID >= 0) { + info->Chipset = dev->chipID; + from = X_CONFIG; + } else { + info->Chipset = info->PciInfo->chipType; + } + pScrn->chipset = (char *)xf86TokenToString(R128Chipsets, info->Chipset); + + if (!pScrn->chipset) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "ChipID 0x%04x is not recognized\n", info->Chipset); + return FALSE; + } + + if (info->Chipset < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Chipset \"%s\" is not recognized\n", pScrn->chipset); + return FALSE; + } + + xf86DrvMsg(pScrn->scrnIndex, from, + "Chipset: \"%s\" (ChipID = 0x%04x)\n", + pScrn->chipset, + info->Chipset); + + /* Framebuffer */ + + from = X_PROBED; + info->LinearAddr = info->PciInfo->memBase[0] & 0xfc000000; + if (dev->MemBase) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Linear address override, using 0x%08x instead of 0x%08x\n", + dev->MemBase, + info->LinearAddr); + info->LinearAddr = dev->MemBase; + from = X_CONFIG; + } else if (!info->LinearAddr) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "No valid linear framebuffer address\n"); + return FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, from, + "Linear framebuffer at 0x%08lx\n", info->LinearAddr); + + /* MMIO registers */ + from = X_PROBED; + info->MMIOAddr = info->PciInfo->memBase[2] & 0xffffff00; + if (dev->IOBase) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "MMIO address override, using 0x%08x instead of 0x%08x\n", + dev->IOBase, + info->MMIOAddr); + info->MMIOAddr = dev->IOBase; + from = X_CONFIG; + } else if (!info->MMIOAddr) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid MMIO address\n"); + return FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, from, + "MMIO registers at 0x%08lx\n", info->MMIOAddr); + + /* BIOS */ + from = X_PROBED; + info->BIOSAddr = info->PciInfo->biosBase & 0xfffe0000; + if (dev->BiosBase) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "BIOS address override, using 0x%08x instead of 0x%08x\n", + dev->BiosBase, + info->BIOSAddr); + info->BIOSAddr = dev->BiosBase; + from = X_CONFIG; + } + if (info->BIOSAddr) { + xf86DrvMsg(pScrn->scrnIndex, from, + "BIOS at 0x%08lx\n", info->BIOSAddr); + } + + /* Flat panel (part 1) */ + if (xf86GetOptValBool(R128Options, OPTION_PROG_FP_REGS, + &info->HasPanelRegs)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Turned flat panel register programming %s\n", + info->HasPanelRegs ? "on" : "off"); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "\n\nWARNING: Forcing the driver to use/not use the flat panel registers\nmight damage your flat panel. Use at your *OWN* *RISK*.\n\n"); + } else { + switch (info->Chipset) { + case PCI_CHIP_RAGE128LE: + case PCI_CHIP_RAGE128LF: + case PCI_CHIP_RAGE128MF: + case PCI_CHIP_RAGE128ML: info->HasPanelRegs = TRUE; break; + case PCI_CHIP_RAGE128RE: + case PCI_CHIP_RAGE128RF: + case PCI_CHIP_RAGE128RK: + case PCI_CHIP_RAGE128RL: + case PCI_CHIP_RAGE128PF: + default: info->HasPanelRegs = FALSE; break; + } + } + + /* Read registers used to determine options */ + from = X_PROBED; + R128MapMMIO(pScrn); + R128MMIO = info->MMIO; + if (info->FBDev) + pScrn->videoRam = fbdevHWGetVidmem(pScrn) / 1024; + else + pScrn->videoRam = INREG(R128_CONFIG_MEMSIZE) / 1024; + info->MemCntl = INREG(R128_MEM_CNTL); + + info->BusCntl = INREG(R128_BUS_CNTL); + R128MMIO = NULL; + R128UnmapMMIO(pScrn); + + /* RAM */ + switch (info->MemCntl & 0x3) { + case 0: /* SDR SGRAM 1:1 */ + switch (info->Chipset) { + case PCI_CHIP_RAGE128LE: + case PCI_CHIP_RAGE128LF: + case PCI_CHIP_RAGE128MF: + case PCI_CHIP_RAGE128ML: + case PCI_CHIP_RAGE128RE: + case PCI_CHIP_RAGE128RF: offset = 0; break; /* 128-bit SDR SGRAM 1:1 */ + case PCI_CHIP_RAGE128RK: + case PCI_CHIP_RAGE128RL: + default: offset = 1; break; /* 64-bit SDR SGRAM 1:1 */ + } + break; + case 1: offset = 2; break; /* 64-bit SDR SGRAM 2:1 */ + case 2: offset = 3; break; /* 64-bit DDR SGRAM */ + default: offset = 1; break; /* 64-bit SDR SGRAM 1:1 */ + } + info->ram = &R128RAM[offset]; + + if (dev->videoRam) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Video RAM override, using %d kB instead of %d kB\n", + dev->videoRam, + pScrn->videoRam); + from = X_CONFIG; + pScrn->videoRam = dev->videoRam; + } + pScrn->videoRam &= ~1023; + info->FbMapSize = pScrn->videoRam * 1024; + xf86DrvMsg(pScrn->scrnIndex, from, + "VideoRAM: %d kByte (%s)\n", pScrn->videoRam, info->ram->name); + + /* Flat panel (part 2) */ + if (info->HasPanelRegs) { +#if 1 + info->CRTOnly = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using flat panel for display\n"); +#else + /* Panel CRT mode override */ + if ((info->CRTOnly = xf86ReturnOptValBool(R128Options, + OPTION_CRT, FALSE))) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Using external CRT instead of " + "flat panel for display\n"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using flat panel for display\n"); + } +#endif + + /* Panel width/height overrides */ + info->PanelXRes = 0; + info->PanelYRes = 0; + if (xf86GetOptValInteger(R128Options, + OPTION_PANEL_WIDTH, &(info->PanelXRes))) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Flat panel width: %d\n", info->PanelXRes); + } + if (xf86GetOptValInteger(R128Options, + OPTION_PANEL_HEIGHT, &(info->PanelYRes))) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Flat panel height: %d\n", info->PanelYRes); + } + } else { + info->CRTOnly = FALSE; + } + +#ifdef XF86DRI + /* AGP/PCI */ + if (xf86ReturnOptValBool(R128Options, OPTION_IS_PCI, FALSE)) { + info->IsPCI = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forced into PCI-only mode\n"); + } else { + switch (info->Chipset) { + case PCI_CHIP_RAGE128LE: + case PCI_CHIP_RAGE128RE: + case PCI_CHIP_RAGE128RK: info->IsPCI = TRUE; break; + case PCI_CHIP_RAGE128LF: + case PCI_CHIP_RAGE128MF: + case PCI_CHIP_RAGE128ML: + case PCI_CHIP_RAGE128RF: + case PCI_CHIP_RAGE128RL: + case PCI_CHIP_RAGE128PF: + default: info->IsPCI = FALSE; break; + } + } +#endif + + return TRUE; +} + +static Bool R128PreInitDDC(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + vbeInfoPtr pVbe; + + if (!xf86LoadSubModule(pScrn, "ddc")) return FALSE; + xf86LoaderReqSymLists(ddcSymbols, NULL); + if (xf86LoadSubModule(pScrn, "vbe")) { + pVbe = VBEInit(NULL,info->pEnt->index); + if (!pVbe) return FALSE; + + xf86SetDDCproperties(pScrn,xf86PrintEDID(vbeDoEDID(pVbe,NULL))); + return TRUE; + } else + return FALSE; +} + +/* This is called by R128PreInit to initialize gamma correction. */ +static Bool R128PreInitGamma(ScrnInfoPtr pScrn) +{ + Gamma zeros = { 0.0, 0.0, 0.0 }; + + if (!xf86SetGamma(pScrn, zeros)) return FALSE; + return TRUE; +} + +/* This is called by R128PreInit to validate modes and compute parameters + for all of the valid modes. */ +static Bool R128PreInitModes(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + ClockRangePtr clockRanges; + int modesFound; + char *mod = NULL; + const char *Sym = NULL; + + /* Get mode information */ + pScrn->progClock = TRUE; + clockRanges = xnfcalloc(sizeof(*clockRanges), 1); + clockRanges->next = NULL; + clockRanges->minClock = info->pll.min_pll_freq; + clockRanges->maxClock = info->pll.max_pll_freq * 10; + clockRanges->clockIndex = -1; + if (info->HasPanelRegs) { + clockRanges->interlaceAllowed = FALSE; + clockRanges->doubleScanAllowed = FALSE; + } else { + clockRanges->interlaceAllowed = TRUE; + clockRanges->doubleScanAllowed = TRUE; + } + + modesFound = xf86ValidateModes(pScrn, + pScrn->monitor->Modes, + pScrn->display->modes, + clockRanges, + NULL, /* linePitches */ + 8 * 64, /* minPitch */ + 8 * 1024, /* maxPitch */ + 64 * pScrn->bitsPerPixel, /* pitchInc */ + 128, /* minHeight */ + 2048, /* maxHeight */ + pScrn->virtualX, + pScrn->virtualY, + info->FbMapSize, + LOOKUP_BEST_REFRESH); + + if (modesFound < 1 && info->FBDev) { + fbdevHWUseBuildinMode(pScrn); + pScrn->displayWidth = pScrn->virtualX; /* FIXME: might be wrong */ + modesFound = 1; + } + + if (modesFound == -1) return FALSE; + xf86PruneDriverModes(pScrn); + if (!modesFound || !pScrn->modes) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); + return FALSE; + } + xf86SetCrtcForModes(pScrn, 0); + pScrn->currentMode = pScrn->modes; + xf86PrintModes(pScrn); + + /* Set DPI */ + xf86SetDpi(pScrn, 0, 0); + + /* Get ScreenInit function */ +#ifdef USE_FB + mod = "fb"; + Sym = "fbScreenInit"; +#else + switch (pScrn->bitsPerPixel) { + case 8: mod = "cfb"; Sym = "cfbScreenInit"; break; + case 16: mod = "cfb16"; Sym = "cfb16ScreenInit"; break; + case 24: + if (info->pix24bpp == 24) { + mod = "cfb24"; Sym = "cfb24ScreenInit"; + } else { + mod = "xf24_32bpp"; Sym = "cfb24_32ScreenInit"; + } + break; + case 32: mod = "cfb32"; Sym = "cfb32ScreenInit"; break; + } +#endif + if (mod && !xf86LoadSubModule(pScrn, mod)) return FALSE; + xf86LoaderReqSymbols(Sym, NULL); +#ifdef USE_FB +#ifdef RENDER + xf86LoaderReqSymbols("fbPictureInit", NULL); +#endif +#endif + + info->CurrentLayout.displayWidth = pScrn->displayWidth; + info->CurrentLayout.mode = pScrn->currentMode; + + return TRUE; +} + +/* This is called by R128PreInit to initialize the hardware cursor. */ +static Bool R128PreInitCursor(ScrnInfoPtr pScrn) +{ + if (!xf86ReturnOptValBool(R128Options, OPTION_SW_CURSOR, FALSE)) { + if (!xf86LoadSubModule(pScrn, "ramdac")) return FALSE; + } + return TRUE; +} + +/* This is called by R128PreInit to initialize hardware acceleration. */ +static Bool R128PreInitAccel(ScrnInfoPtr pScrn) +{ + if (!xf86ReturnOptValBool(R128Options, OPTION_NOACCEL, FALSE)) { + if (!xf86LoadSubModule(pScrn, "xaa")) return FALSE; + } + return TRUE; +} + +static Bool R128PreInitInt10(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); +#if 1 + if (xf86LoadSubModule(pScrn, "int10")) { + xf86Int10InfoPtr pInt; + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"initializing int10\n"); + pInt = xf86InitInt10(info->pEnt->index); + xf86FreeInt10(pInt); + } +#endif + return TRUE; +} + +#ifdef XF86DRI +static Bool R128PreInitDRI(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + + if (info->IsPCI) { + info->CCEMode = R128_DEFAULT_CCE_PIO_MODE; + } else if (xf86ReturnOptValBool(R128Options, OPTION_CCE_PIO, FALSE)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forcing CCE into PIO mode\n"); + info->CCEMode = R128_DEFAULT_CCE_PIO_MODE; + } else { + info->CCEMode = R128_DEFAULT_CCE_BM_MODE; + } + + if (xf86ReturnOptValBool(R128Options, OPTION_USE_CCE_2D, FALSE)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using CCE for 2D\n"); + info->CCE2D = TRUE; + } else { + info->CCE2D = FALSE; + } + + if (xf86ReturnOptValBool(R128Options, OPTION_NO_SECURITY, FALSE)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "WARNING!!! CCE Security checks disabled!!! **********\n"); + info->CCESecure = FALSE; + } else { + info->CCESecure = TRUE; + } + + info->agpMode = R128_DEFAULT_AGP_MODE; + info->agpSize = R128_DEFAULT_AGP_SIZE; + info->ringSize = R128_DEFAULT_RING_SIZE; + info->vbSize = R128_DEFAULT_VB_SIZE; + info->indSize = R128_DEFAULT_IND_SIZE; + info->agpTexSize = R128_DEFAULT_AGP_TEX_SIZE; + + info->vbBufSize = R128_DEFAULT_VB_BUF_SIZE; + + info->CCEusecTimeout = R128_DEFAULT_CCE_TIMEOUT; + + if (!info->IsPCI) { + if (xf86GetOptValInteger(R128Options, + OPTION_AGP_MODE, &(info->agpMode))) { + if (info->agpMode < 1 || info->agpMode > R128_AGP_MAX_MODE) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Illegal AGP Mode: %d\n", info->agpMode); + return FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Using AGP %dx mode\n", info->agpMode); + } + + if (xf86GetOptValInteger(R128Options, + OPTION_AGP_SIZE, (int *)&(info->agpSize))) { + switch (info->agpSize) { + case 4: + case 8: + case 16: + case 32: + case 64: + case 128: + case 256: + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Illegal AGP size: %d MB\n", info->agpSize); + return FALSE; + } + } + + if (xf86GetOptValInteger(R128Options, + OPTION_RING_SIZE, &(info->ringSize))) { + if (info->ringSize < 1 || info->ringSize >= (int)info->agpSize) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Illegal ring buffer size: %d MB\n", + info->ringSize); + return FALSE; + } + } + + if (xf86GetOptValInteger(R128Options, + OPTION_VERT_SIZE, &(info->vbSize))) { + if (info->vbSize < 1 || info->vbSize >= (int)info->agpSize) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Illegal vertex buffers list size: %d MB\n", + info->vbSize); + return FALSE; + } + } + + if (xf86GetOptValInteger(R128Options, + OPTION_VBUF_SIZE, &(info->vbBufSize))) { + int numBufs = info->vbSize*1024*1024/info->vbBufSize; + if (numBufs < 2 || numBufs > 512) { /* FIXME: 512 is arbitrary */ + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Illegal individual vertex buffer size: %d bytes\n", + info->vbBufSize); + return FALSE; + } + } + + if (info->ringSize + info->vbSize + info->indSize + info->agpTexSize > + (int)info->agpSize) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Buffers are too big for requested AGP space\n"); + return FALSE; + } + + info->agpTexSize = info->agpSize - (info->ringSize + + info->vbSize + + info->indSize); + } + + if (xf86GetOptValInteger(R128Options, OPTION_USEC_TIMEOUT, + &(info->CCEusecTimeout))) { + /* This option checked by the R128 DRM kernel module */ + } + + return TRUE; +} +#endif + +static void +R128ProbeDDC(ScrnInfoPtr pScrn, int indx) +{ + vbeInfoPtr pVbe; + if (xf86LoadSubModule(pScrn, "vbe")) { + pVbe = VBEInit(NULL,indx); + ConfiguredMonitor = vbeDoEDID(pVbe, NULL); + } +} + +/* R128PreInit is called once at server startup. */ +Bool R128PreInit(ScrnInfoPtr pScrn, int flags) +{ + R128InfoPtr info; + + R128TRACE(("R128PreInit\n")); + +#ifdef XFree86LOADER + /* + * Tell the loader about symbols from other modules that this module might + * refer to. + */ + LoaderRefSymLists(vgahwSymbols, +#ifdef USE_FB + fbSymbols, +#else + cfbSymbols, +#endif + xaaSymbols, + xf8_32bppSymbols, + ramdacSymbols, +#ifdef XF86DRI + drmSymbols, + driSymbols, +#endif + fbdevHWSymbols, + vbeSymbols, + /* ddcsymbols, */ + /* i2csymbols, */ + /* shadowSymbols, */ + NULL); +#endif + + if (pScrn->numEntities != 1) return FALSE; + + if (!R128GetRec(pScrn)) return FALSE; + + info = R128PTR(pScrn); + + info->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); + if (info->pEnt->location.type != BUS_PCI) goto fail; + + if (flags & PROBE_DETECT) { + R128ProbeDDC(pScrn, info->pEnt->index); + return TRUE; + } + + if (!xf86LoadSubModule(pScrn, "vgahw")) return FALSE; + xf86LoaderReqSymLists(vgahwSymbols, NULL); + if (!vgaHWGetHWRec(pScrn)) { + R128FreeRec(pScrn); + return FALSE; + } + + info->PciInfo = xf86GetPciInfoForEntity(info->pEnt->index); + info->PciTag = pciTag(info->PciInfo->bus, + info->PciInfo->device, + info->PciInfo->func); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "PCI bus %d card %d func %d\n", + info->PciInfo->bus, + info->PciInfo->device, + info->PciInfo->func); + + if (xf86RegisterResources(info->pEnt->index, 0, ResNone)) goto fail; + + pScrn->racMemFlags = RAC_FB | RAC_COLORMAP; + pScrn->monitor = pScrn->confScreen->monitor; + + if (!R128PreInitVisual(pScrn)) goto fail; + + /* We can't do this until we have a + pScrn->display. */ + xf86CollectOptions(pScrn, NULL); + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, R128Options); + + if (!R128PreInitWeight(pScrn)) goto fail; + + if (xf86ReturnOptValBool(R128Options, OPTION_FBDEV, FALSE)) { + info->FBDev = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Using framebuffer device\n"); + } + + if (info->FBDev) { + /* check for linux framebuffer device */ + if (!xf86LoadSubModule(pScrn, "fbdevhw")) return FALSE; + xf86LoaderReqSymLists(fbdevHWSymbols, NULL); + if (!fbdevHWInit(pScrn, info->PciInfo, NULL)) return FALSE; + pScrn->SwitchMode = fbdevHWSwitchMode; + pScrn->AdjustFrame = fbdevHWAdjustFrame; + pScrn->EnterVT = R128EnterVTFBDev; + pScrn->LeaveVT = R128LeaveVTFBDev; + pScrn->ValidMode = fbdevHWValidMode; + } + + if (!info->FBDev) + if (!R128PreInitInt10(pScrn)) goto fail; + + if (!R128PreInitConfig(pScrn)) goto fail; + + if (!R128GetBIOSParameters(pScrn)) goto fail; + + if (!R128GetPLLParameters(pScrn)) goto fail; + + if (!R128PreInitDDC(pScrn)) goto fail; + + if (!R128PreInitGamma(pScrn)) goto fail; + + if (!R128PreInitModes(pScrn)) goto fail; + + if (!R128PreInitCursor(pScrn)) goto fail; + + if (!R128PreInitAccel(pScrn)) goto fail; + +#ifdef XF86DRI + if (!R128PreInitDRI(pScrn)) goto fail; +#endif + + /* Free the video bios (if applicable) */ + if (info->VBIOS) { + xfree(info->VBIOS); + info->VBIOS = NULL; + } + + return TRUE; + + fail: + /* Pre-init failed. */ + + /* Free the video bios (if applicable) */ + if (info->VBIOS) { + xfree(info->VBIOS); + info->VBIOS = NULL; + } + + vgaHWFreeHWRec(pScrn); + R128FreeRec(pScrn); + return FALSE; +} + +/* Load a palette. */ +static void R128LoadPalette(ScrnInfoPtr pScrn, int numColors, + int *indices, LOCO *colors, VisualPtr pVisual) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int i; + int idx; + unsigned char r, g, b; + + /* Select palette 0 (main CRTC) if using FP-enabled chip */ + if (info->HasPanelRegs) PAL_SELECT(0); + + if (info->CurrentLayout.depth == 15) { + /* 15bpp mode. This sends 32 values. */ + for (i = 0; i < numColors; i++) { + idx = indices[i]; + r = colors[idx].red; + g = colors[idx].green; + b = colors[idx].blue; + OUTPAL(idx * 8, r, g, b); + } + } + else if (info->CurrentLayout.depth == 16) { + /* 16bpp mode. This sends 64 values. */ + /* There are twice as many green values as + there are values for red and blue. So, + we take each red and blue pair, and + combine it with each of the two green + values. */ + for (i = 0; i < numColors; i++) { + idx = indices[i]; + r = colors[idx / 2].red; + g = colors[idx].green; + b = colors[idx / 2].blue; + OUTPAL(idx * 4, r, g, b); + } + } + else { + /* 8bpp mode. This sends 256 values. */ + for (i = 0; i < numColors; i++) { + idx = indices[i]; + r = colors[idx].red; + b = colors[idx].blue; + g = colors[idx].green; + OUTPAL(idx, r, g, b); + } + } +} + +/* Called at the start of each server generation. */ +Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + BoxRec MemBox; + int y2; + + R128TRACE(("R128ScreenInit %x %d\n", pScrn->memPhysBase, pScrn->fbOffset)); + +#ifdef XF86DRI + /* Turn off the CCE for now. */ + info->CCEInUse = FALSE; +#endif + + if (!R128MapMem(pScrn)) return FALSE; + pScrn->fbOffset = 0; +#ifdef XF86DRI + info->fbX = 0; + info->fbY = 0; +#endif + + info->PaletteSavedOnVT = FALSE; + + R128Save(pScrn); + if (info->FBDev) { + if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) return FALSE; + } else { + if (!R128ModeInit(pScrn, pScrn->currentMode)) return FALSE; + } + + R128SaveScreen(pScreen, SCREEN_SAVER_ON); + pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + + /* Visual setup */ + miClearVisualTypes(); + if (!miSetVisualTypes(pScrn->depth, + miGetDefaultVisualMask(pScrn->depth), + pScrn->rgbBits, + pScrn->defaultVisual)) return FALSE; + miSetPixmapDepths (); + +#ifdef XF86DRI + /* Setup DRI after visuals have been + established, but before cfbScreenInit is + called. cfbScreenInit will eventually + call the driver's InitGLXVisuals call + back. */ + { + /* FIXME: When we move to dynamic allocation of back and depth + buffers, we will want to revisit the following check for 3 + times the virtual size of the screen below. */ + int width_bytes = (pScrn->displayWidth * + info->CurrentLayout.pixel_bytes); + int maxy = info->FbMapSize / width_bytes; + + if (!xf86ReturnOptValBool(R128Options, OPTION_NOACCEL, FALSE) && + (maxy > pScrn->virtualY * 3) +#if 0 + /* FIXME: Disable 3D support for FPs until it is tested */ + && !info->HasPanelRegs +#endif + ) { + info->directRenderingEnabled = R128DRIScreenInit(pScreen); + } else { + xf86DrvMsg(scrnIndex, X_WARNING, + "Static buffer allocation failed -- " + "need at least %d kB video memory\n", + (pScrn->displayWidth * pScrn->virtualY * + info->CurrentLayout.pixel_bytes * 3 + 1023) / 1024); + info->directRenderingEnabled = FALSE; + } + } +#endif + +#ifdef USE_FB + if (!fbScreenInit (pScreen, info->FB, + pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth, + pScrn->bitsPerPixel)) + return FALSE; +#ifdef RENDER + fbPictureInit (pScreen, 0, 0); +#endif +#else + switch (pScrn->bitsPerPixel) { + case 8: + if (!cfbScreenInit(pScreen, info->FB, + pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth)) + return FALSE; + break; + case 16: + if (!cfb16ScreenInit(pScreen, info->FB, + pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth)) + return FALSE; + break; + case 24: + if (info->pix24bpp == 24) { + if (!cfb24ScreenInit(pScreen, info->FB, + pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, + pScrn->displayWidth)) + return FALSE; + } else { + if (!cfb24_32ScreenInit(pScreen, info->FB, + pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, + pScrn->displayWidth)) + return FALSE; + } + break; + case 32: + if (!cfb32ScreenInit(pScreen, info->FB, + pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth)) + return FALSE; + break; + default: + xf86DrvMsg(scrnIndex, X_ERROR, + "Invalid bpp (%d)\n", pScrn->bitsPerPixel); + return FALSE; + } +#endif + xf86SetBlackWhitePixels(pScreen); + + if (pScrn->bitsPerPixel > 8) { + VisualPtr visual; + + for (visual = pScreen->visuals + pScreen->numVisuals; + visual >= pScreen->visuals; + visual--) { + if ((visual->class | DynamicClass) == DirectColor) { + visual->offsetRed = pScrn->offset.red; + visual->offsetGreen = pScrn->offset.green; + visual->offsetBlue = pScrn->offset.blue; + visual->redMask = pScrn->mask.red; + visual->greenMask = pScrn->mask.green; + visual->blueMask = pScrn->mask.blue; + } + } + } + + R128DGAInit(pScreen); + + /* Memory manager setup */ + MemBox.x1 = 0; + MemBox.y1 = 0; + MemBox.x2 = pScrn->displayWidth; + y2 = (info->FbMapSize + / (pScrn->displayWidth * info->CurrentLayout.pixel_bytes)); + if (y2 >= 32768) y2 = 32767; /* because MemBox.y2 is signed short */ + MemBox.y2 = y2; + + /* The acceleration engine uses 14 bit + signed coordinates, so we can't have any + drawable caches beyond this region. */ + if (MemBox.y2 > 8191) MemBox.y2 = 8191; + + if (!xf86InitFBManager(pScreen, &MemBox)) { + xf86DrvMsg(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 width, height; + FBAreaPtr fbarea; + + xf86DrvMsg(scrnIndex, X_INFO, + "Memory manager initialized to (%d,%d) (%d,%d)\n", + MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); + if ((fbarea = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth, + 2, 0, NULL, NULL, NULL))) { + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved area from (%d,%d) to (%d,%d)\n", + fbarea->box.x1, fbarea->box.y1, + fbarea->box.x2, fbarea->box.y2); + } else { + xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve area\n"); + } + if (xf86QueryLargestOffscreenArea(pScreen, &width, &height, 0, 0, 0)) { + xf86DrvMsg(scrnIndex, X_INFO, + "Largest offscreen area available: %d x %d\n", + width, height); + } + } + +#ifdef XF86DRI + /* Allocate frame buffer space for the + shared back and depth buffers as well + as for local textures. */ + if (info->directRenderingEnabled) { + FBAreaPtr fbarea; + int width_bytes = (pScrn->displayWidth * + info->CurrentLayout.pixel_bytes); + int maxy = info->FbMapSize / width_bytes; + int l; + + switch (info->CCEMode) { + case R128_DEFAULT_CCE_PIO_MODE: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in PIO mode\n"); + break; + case R128_DEFAULT_CCE_BM_MODE: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in BM mode\n"); + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in UNKNOWN mode\n"); + break; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB AGP aperture\n", info->agpSize); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB for the ring buffer\n", info->ringSize); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB for vertex buffers\n", info->vbSize); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB for indirect buffers\n", info->indSize); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB for AGP textures\n", info->agpTexSize); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d byte vertex buffers\n", info->vbBufSize); + + /* Allocate the shared back buffer */ + if ((fbarea = xf86AllocateOffscreenArea(pScreen, + pScrn->virtualX, + pScrn->virtualY, + 32, NULL, NULL, NULL))) { + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved back buffer from (%d,%d) to (%d,%d)\n", + fbarea->box.x1, fbarea->box.y1, + fbarea->box.x2, fbarea->box.y2); + + info->backX = fbarea->box.x1; + info->backY = fbarea->box.y1; + } else { + xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve back buffer\n"); + info->backX = -1; + info->backY = -1; + } + + /* Allocate the shared depth buffer */ + if ((fbarea = xf86AllocateOffscreenArea(pScreen, + pScrn->virtualX, + pScrn->virtualY, + 32, NULL, NULL, NULL))) { + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved depth buffer from (%d,%d) to (%d,%d)\n", + fbarea->box.x1, fbarea->box.y1, + fbarea->box.x2, fbarea->box.y2); + + info->depthX = fbarea->box.x1; + info->depthY = fbarea->box.y1; + } else { + xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve depth buffer\n"); + info->depthX = -1; + info->depthY = -1; + } + + /* Allocate local texture space */ + if (((maxy - MemBox.y2 - 1) * width_bytes) > + (pScrn->virtualX * pScrn->virtualY * 2 * + info->CurrentLayout.pixel_bytes)) { + info->textureX = 0; + info->textureY = MemBox.y2 + 1; + info->textureSize = (maxy - MemBox.y2 - 1) * width_bytes; + + l = R128MinBits((info->textureSize-1) / R128_NR_TEX_REGIONS); + if (l < R128_LOG_TEX_GRANULARITY) l = R128_LOG_TEX_GRANULARITY; + + info->log2TexGran = l; + info->textureSize = (info->textureSize >> l) << l; + + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved %d kb for textures: (%d,%d)-(%d,%d)\n", + info->textureSize/1024, + info->textureX, info->textureY, + pScrn->displayWidth, maxy); + } else if ((fbarea = xf86AllocateOffscreenArea(pScreen, + pScrn->virtualX, + pScrn->virtualY * 2, + 32, + NULL, NULL, NULL))) { + info->textureX = fbarea->box.x1; + info->textureY = fbarea->box.y1; + info->textureSize = ((fbarea->box.y2 - fbarea->box.y1) * + (fbarea->box.x2 - fbarea->box.x1) * + info->CurrentLayout.pixel_bytes); + + l = R128MinBits((info->textureSize-1) / R128_NR_TEX_REGIONS); + if (l < R128_LOG_TEX_GRANULARITY) l = R128_LOG_TEX_GRANULARITY; + + info->log2TexGran = l; + info->textureSize = (info->textureSize >> l) << l; + + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved %d kb for textures: (%d,%d)-(%d,%d)\n", + info->textureSize/1024, + fbarea->box.x1, fbarea->box.y1, + fbarea->box.x2, fbarea->box.y2); + } else { + xf86DrvMsg(scrnIndex, X_ERROR, + "Unable to reserve texture space in frame buffer\n"); + info->textureX = -1; + info->textureY = -1; + } + } +#endif + + /* Backing store setup */ + miInitializeBackingStore(pScreen); + xf86SetBackingStore(pScreen); + + /* Set Silken Mouse */ + xf86SetSilkenMouse(pScreen); + + /* Acceleration setup */ + if (!xf86ReturnOptValBool(R128Options, OPTION_NOACCEL, FALSE)) { + if (R128AccelInit(pScreen)) { + xf86DrvMsg(scrnIndex, X_INFO, "Acceleration enabled\n"); + info->accelOn = TRUE; + } else { + xf86DrvMsg(scrnIndex, X_ERROR, + "Acceleration initialization failed\n"); + xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n"); + info->accelOn = FALSE; + } + } else { + xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n"); + info->accelOn = FALSE; + } + + /* Cursor setup */ + miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); + + /* Hardware cursor setup */ + if (!xf86ReturnOptValBool(R128Options, OPTION_SW_CURSOR, FALSE)) { + if (R128CursorInit(pScreen)) { + int width, height; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using hardware cursor (scanline %d)\n", + info->cursor_start / pScrn->displayWidth); + if (xf86QueryLargestOffscreenArea(pScreen, &width, &height, + 0, 0, 0)) { + xf86DrvMsg(scrnIndex, X_INFO, + "Largest offscreen area available: %d x %d\n", + width, height); + } + } else { + xf86DrvMsg(scrnIndex, X_ERROR, + "Hardware cursor initialization failed\n"); + xf86DrvMsg(scrnIndex, X_INFO, "Using software cursor\n"); + } + } else { + xf86DrvMsg(scrnIndex, X_INFO, "Using software cursor\n"); + } + + /* Colormap setup */ + if (!miCreateDefColormap(pScreen)) return FALSE; + if (!xf86HandleColormaps(pScreen, 256, info->dac6bits ? 6 : 8, + (info->FBDev ? fbdevHWLoadPalette : + R128LoadPalette), NULL, + CMAP_PALETTED_TRUECOLOR + | CMAP_RELOAD_ON_MODE_SWITCH +#if 0 /* This option messes up text mode! (eich@suse.de) */ + | CMAP_LOAD_EVEN_IF_OFFSCREEN +#endif + )) return FALSE; + + /* DPMS setup */ +#ifdef DPMSExtension + if (!info->HasPanelRegs || info->CRTOnly) + xf86DPMSInit(pScreen, R128DisplayPowerManagementSet, 0); +#endif + + R128InitVideo(pScreen); + + /* Provide SaveScreen */ + pScreen->SaveScreen = R128SaveScreen; + + /* Wrap CloseScreen */ + info->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = R128CloseScreen; + + /* Note unused options */ + if (serverGeneration == 1) + xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); + +#ifdef XF86DRI + /* DRI finalization */ + if (info->directRenderingEnabled) { + /* Now that mi, cfb, drm and others have + done their thing, complete the DRI + setup. */ + info->directRenderingEnabled = R128DRIFinishScreenInit(pScreen); + } + if (info->directRenderingEnabled) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering disabled\n"); + } +#endif + + return TRUE; +} + +/* Write common registers (initialized to 0). */ +static void R128RestoreCommonRegisters(ScrnInfoPtr pScrn, R128SavePtr restore) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + OUTREG(R128_OVR_CLR, restore->ovr_clr); + OUTREG(R128_OVR_WID_LEFT_RIGHT, restore->ovr_wid_left_right); + OUTREG(R128_OVR_WID_TOP_BOTTOM, restore->ovr_wid_top_bottom); + OUTREG(R128_OV0_SCALE_CNTL, restore->ov0_scale_cntl); + OUTREG(R128_MPP_TB_CONFIG, restore->mpp_tb_config ); + OUTREG(R128_MPP_GP_CONFIG, restore->mpp_gp_config ); + OUTREG(R128_SUBPIC_CNTL, restore->subpic_cntl); + OUTREG(R128_VIPH_CONTROL, restore->viph_control); + OUTREG(R128_I2C_CNTL_1, restore->i2c_cntl_1); + OUTREG(R128_GEN_INT_CNTL, restore->gen_int_cntl); + OUTREG(R128_CAP0_TRIG_CNTL, restore->cap0_trig_cntl); + OUTREG(R128_CAP1_TRIG_CNTL, restore->cap1_trig_cntl); + OUTREG(R128_BUS_CNTL, restore->bus_cntl); +} + +/* Write CRTC registers. */ +static void R128RestoreCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr restore) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + OUTREG(R128_CRTC_GEN_CNTL, restore->crtc_gen_cntl); + + OUTREGP(R128_CRTC_EXT_CNTL, restore->crtc_ext_cntl, + R128_CRTC_VSYNC_DIS | R128_CRTC_HSYNC_DIS | R128_CRTC_DISPLAY_DIS); + + OUTREGP(R128_DAC_CNTL, restore->dac_cntl, + R128_DAC_RANGE_CNTL | R128_DAC_BLANKING); + + OUTREG(R128_CRTC_H_TOTAL_DISP, restore->crtc_h_total_disp); + OUTREG(R128_CRTC_H_SYNC_STRT_WID, restore->crtc_h_sync_strt_wid); + OUTREG(R128_CRTC_V_TOTAL_DISP, restore->crtc_v_total_disp); + OUTREG(R128_CRTC_V_SYNC_STRT_WID, restore->crtc_v_sync_strt_wid); + OUTREG(R128_CRTC_OFFSET, restore->crtc_offset); + OUTREG(R128_CRTC_OFFSET_CNTL, restore->crtc_offset_cntl); + OUTREG(R128_CRTC_PITCH, restore->crtc_pitch); +} + +/* Write flat panel registers */ +static void R128RestoreFPRegisters(ScrnInfoPtr pScrn, R128SavePtr restore) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + CARD32 tmp; + + OUTREG(R128_CRTC2_GEN_CNTL, restore->crtc2_gen_cntl); + OUTREG(R128_FP_CRTC_H_TOTAL_DISP, restore->fp_crtc_h_total_disp); + OUTREG(R128_FP_CRTC_V_TOTAL_DISP, restore->fp_crtc_v_total_disp); + OUTREG(R128_FP_GEN_CNTL, restore->fp_gen_cntl); + OUTREG(R128_FP_H_SYNC_STRT_WID, restore->fp_h_sync_strt_wid); + OUTREG(R128_FP_HORZ_STRETCH, restore->fp_horz_stretch); + OUTREG(R128_FP_PANEL_CNTL, restore->fp_panel_cntl); + OUTREG(R128_FP_V_SYNC_STRT_WID, restore->fp_v_sync_strt_wid); + OUTREG(R128_FP_VERT_STRETCH, restore->fp_vert_stretch); + OUTREG(R128_TMDS_CRC, restore->tmds_crc); + + tmp = INREG(R128_LVDS_GEN_CNTL); + if ((tmp & (R128_LVDS_ON | R128_LVDS_BLON)) == + (restore->lvds_gen_cntl & (R128_LVDS_ON | R128_LVDS_BLON))) { + OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl); + } else { + if (restore->lvds_gen_cntl & (R128_LVDS_ON | R128_LVDS_BLON)) { + OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl & ~R128_LVDS_BLON); + usleep(R128PTR(pScrn)->PanelPwrDly * 1000); + OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl); + } else { + OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl | R128_LVDS_BLON); + usleep(R128PTR(pScrn)->PanelPwrDly * 1000); + OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl); + } + } +} + +static void R128PLLWaitForReadUpdateComplete(ScrnInfoPtr pScrn) +{ + while (INPLL(pScrn, R128_PPLL_REF_DIV) & R128_PPLL_ATOMIC_UPDATE_R); +} + +static void R128PLLWriteUpdate(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + OUTPLLP(pScrn, R128_PPLL_REF_DIV, R128_PPLL_ATOMIC_UPDATE_W, 0xffff); +} + +/* Write PLL registers. */ +static void R128RestorePLLRegisters(ScrnInfoPtr pScrn, R128SavePtr restore) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + OUTREGP(R128_CLOCK_CNTL_INDEX, R128_PLL_DIV_SEL, 0xffff); + + OUTPLLP(pScrn, + R128_PPLL_CNTL, + R128_PPLL_RESET + | R128_PPLL_ATOMIC_UPDATE_EN + | R128_PPLL_VGA_ATOMIC_UPDATE_EN, + 0xffff); + + R128PLLWaitForReadUpdateComplete(pScrn); + OUTPLLP(pScrn, R128_PPLL_REF_DIV, + restore->ppll_ref_div, ~R128_PPLL_REF_DIV_MASK); + R128PLLWriteUpdate(pScrn); + + R128PLLWaitForReadUpdateComplete(pScrn); + OUTPLLP(pScrn, R128_PPLL_DIV_3, + restore->ppll_div_3, ~R128_PPLL_FB3_DIV_MASK); + R128PLLWriteUpdate(pScrn); + OUTPLLP(pScrn, R128_PPLL_DIV_3, + restore->ppll_div_3, ~R128_PPLL_POST3_DIV_MASK); + R128PLLWriteUpdate(pScrn); + + R128PLLWaitForReadUpdateComplete(pScrn); + OUTPLL(R128_HTOTAL_CNTL, restore->htotal_cntl); + R128PLLWriteUpdate(pScrn); + + OUTPLLP(pScrn, R128_PPLL_CNTL, 0, ~R128_PPLL_RESET); + + R128TRACE(("Wrote: 0x%08x 0x%08x 0x%08x (0x%08x)\n", + restore->ppll_ref_div, + restore->ppll_div_3, + restore->htotal_cntl, + INPLL(pScrn, R128_PPLL_CNTL))); + R128TRACE(("Wrote: rd=%d, fd=%d, pd=%d\n", + restore->ppll_ref_div & R128_PPLL_REF_DIV_MASK, + restore->ppll_div_3 & R128_PPLL_FB3_DIV_MASK, + (restore->ppll_div_3 & R128_PPLL_POST3_DIV_MASK) >> 16)); +} + +/* Write DDA registers. */ +static void R128RestoreDDARegisters(ScrnInfoPtr pScrn, R128SavePtr restore) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + OUTREG(R128_DDA_CONFIG, restore->dda_config); + OUTREG(R128_DDA_ON_OFF, restore->dda_on_off); +} + +/* Write palette data. */ +static void R128RestorePalette(ScrnInfoPtr pScrn, R128SavePtr restore) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int i; + + if (!restore->palette_valid) return; + + /* Select palette 0 (main CRTC) if using FP-enabled chip */ + if (info->HasPanelRegs) PAL_SELECT(0); + + OUTPAL_START(0); + for (i = 0; i < 256; i++) OUTPAL_NEXT_CARD32(restore->palette[i]); +} + +/* Write out state to define a new video mode. */ +static void R128RestoreMode(ScrnInfoPtr pScrn, R128SavePtr restore) +{ + R128InfoPtr info = R128PTR(pScrn); + + R128TRACE(("R128RestoreMode(%p)\n", restore)); + R128RestoreCommonRegisters(pScrn, restore); + R128RestoreCrtcRegisters(pScrn, restore); + if (info->HasPanelRegs) + R128RestoreFPRegisters(pScrn, restore); + if (!info->HasPanelRegs || info->CRTOnly) + R128RestorePLLRegisters(pScrn, restore); + R128RestoreDDARegisters(pScrn, restore); + R128RestorePalette(pScrn, restore); +} + +/* Read common registers. */ +static void R128SaveCommonRegisters(ScrnInfoPtr pScrn, R128SavePtr save) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + save->ovr_clr = INREG(R128_OVR_CLR); + save->ovr_wid_left_right = INREG(R128_OVR_WID_LEFT_RIGHT); + save->ovr_wid_top_bottom = INREG(R128_OVR_WID_TOP_BOTTOM); + save->ov0_scale_cntl = INREG(R128_OV0_SCALE_CNTL); + save->mpp_tb_config = INREG(R128_MPP_TB_CONFIG); + save->mpp_gp_config = INREG(R128_MPP_GP_CONFIG); + save->subpic_cntl = INREG(R128_SUBPIC_CNTL); + save->viph_control = INREG(R128_VIPH_CONTROL); + save->i2c_cntl_1 = INREG(R128_I2C_CNTL_1); + save->gen_int_cntl = INREG(R128_GEN_INT_CNTL); + save->cap0_trig_cntl = INREG(R128_CAP0_TRIG_CNTL); + save->cap1_trig_cntl = INREG(R128_CAP1_TRIG_CNTL); + save->bus_cntl = INREG(R128_BUS_CNTL); +} + +/* Read CRTC registers. */ +static void R128SaveCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + save->crtc_gen_cntl = INREG(R128_CRTC_GEN_CNTL); + save->crtc_ext_cntl = INREG(R128_CRTC_EXT_CNTL); + save->dac_cntl = INREG(R128_DAC_CNTL); + save->crtc_h_total_disp = INREG(R128_CRTC_H_TOTAL_DISP); + save->crtc_h_sync_strt_wid = INREG(R128_CRTC_H_SYNC_STRT_WID); + save->crtc_v_total_disp = INREG(R128_CRTC_V_TOTAL_DISP); + save->crtc_v_sync_strt_wid = INREG(R128_CRTC_V_SYNC_STRT_WID); + save->crtc_offset = INREG(R128_CRTC_OFFSET); + save->crtc_offset_cntl = INREG(R128_CRTC_OFFSET_CNTL); + save->crtc_pitch = INREG(R128_CRTC_PITCH); +} + +/* Read flat panel registers */ +static void R128SaveFPRegisters(ScrnInfoPtr pScrn, R128SavePtr save) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + save->crtc2_gen_cntl = INREG(R128_CRTC2_GEN_CNTL); + save->fp_crtc_h_total_disp = INREG(R128_FP_CRTC_H_TOTAL_DISP); + save->fp_crtc_v_total_disp = INREG(R128_FP_CRTC_V_TOTAL_DISP); + save->fp_gen_cntl = INREG(R128_FP_GEN_CNTL); + save->fp_h_sync_strt_wid = INREG(R128_FP_H_SYNC_STRT_WID); + save->fp_horz_stretch = INREG(R128_FP_HORZ_STRETCH); + save->fp_panel_cntl = INREG(R128_FP_PANEL_CNTL); + save->fp_v_sync_strt_wid = INREG(R128_FP_V_SYNC_STRT_WID); + save->fp_vert_stretch = INREG(R128_FP_VERT_STRETCH); + save->lvds_gen_cntl = INREG(R128_LVDS_GEN_CNTL); + save->tmds_crc = INREG(R128_TMDS_CRC); +} + +/* Read PLL registers. */ +static void R128SavePLLRegisters(ScrnInfoPtr pScrn, R128SavePtr save) +{ + save->ppll_ref_div = INPLL(pScrn, R128_PPLL_REF_DIV); + save->ppll_div_3 = INPLL(pScrn, R128_PPLL_DIV_3); + save->htotal_cntl = INPLL(pScrn, R128_HTOTAL_CNTL); + + R128TRACE(("Read: 0x%08x 0x%08x 0x%08x\n", + save->ppll_ref_div, + save->ppll_div_3, + save->htotal_cntl)); + R128TRACE(("Read: rd=%d, fd=%d, pd=%d\n", + save->ppll_ref_div & R128_PPLL_REF_DIV_MASK, + save->ppll_div_3 & R128_PPLL_FB3_DIV_MASK, + (save->ppll_div_3 & R128_PPLL_POST3_DIV_MASK) >> 16)); +} + +/* Read DDA registers. */ +static void R128SaveDDARegisters(ScrnInfoPtr pScrn, R128SavePtr save) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + save->dda_config = INREG(R128_DDA_CONFIG); + save->dda_on_off = INREG(R128_DDA_ON_OFF); +} + +/* Read palette data. */ +static void R128SavePalette(ScrnInfoPtr pScrn, R128SavePtr save) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int i; + + /* Select palette 0 (main CRTC) if using FP-enabled chip */ + if (info->HasPanelRegs) PAL_SELECT(0); + + INPAL_START(0); + for (i = 0; i < 256; i++) save->palette[i] = INPAL_NEXT(); + save->palette_valid = TRUE; +} + +/* Save state that defines current video mode. */ +static void R128SaveMode(ScrnInfoPtr pScrn, R128SavePtr save) +{ + R128TRACE(("R128SaveMode(%p)\n", save)); + + R128SaveCommonRegisters(pScrn, save); + R128SaveCrtcRegisters(pScrn, save); + if (R128PTR(pScrn)->HasPanelRegs) + R128SaveFPRegisters(pScrn, save); + R128SavePLLRegisters(pScrn, save); + R128SaveDDARegisters(pScrn, save); + R128SavePalette(pScrn, save); + + R128TRACE(("R128SaveMode returns %p\n", save)); +} + +/* Save everything needed to restore the original VC state. */ +static void R128Save(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + R128SavePtr save = &info->SavedReg; + vgaHWPtr hwp = VGAHWPTR(pScrn); + + R128TRACE(("R128Save\n")); + if (info->FBDev) { + fbdevHWSave(pScrn); + return; + } + vgaHWUnlock(hwp); + vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_ALL); /* save mode, fonts, cmap */ + vgaHWLock(hwp); + + R128SaveMode(pScrn, save); + + save->dp_datatype = INREG(R128_DP_DATATYPE); + save->gen_reset_cntl = INREG(R128_GEN_RESET_CNTL); + save->clock_cntl_index = INREG(R128_CLOCK_CNTL_INDEX); + save->amcgpio_en_reg = INREG(R128_AMCGPIO_EN_REG); + save->amcgpio_mask = INREG(R128_AMCGPIO_MASK); +} + +/* Restore the original (text) mode. */ +static void R128Restore(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + R128SavePtr restore = &info->SavedReg; + vgaHWPtr hwp = VGAHWPTR(pScrn); + + R128TRACE(("R128Restore\n")); + if (info->FBDev) { + fbdevHWRestore(pScrn); + return; + } + + R128Blank(pScrn); + OUTREG(R128_AMCGPIO_MASK, restore->amcgpio_mask); + OUTREG(R128_AMCGPIO_EN_REG, restore->amcgpio_en_reg); + OUTREG(R128_CLOCK_CNTL_INDEX, restore->clock_cntl_index); + OUTREG(R128_GEN_RESET_CNTL, restore->gen_reset_cntl); + OUTREG(R128_DP_DATATYPE, restore->dp_datatype); + + R128RestoreMode(pScrn, restore); + vgaHWUnlock(hwp); + vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS ); + vgaHWLock(hwp); + + R128WaitForVerticalSync(pScrn); + R128Unblank(pScrn); +} + +/* Define common registers for requested video mode. */ +static void R128InitCommonRegisters(R128SavePtr save, R128InfoPtr info) +{ + save->ovr_clr = 0; + save->ovr_wid_left_right = 0; + save->ovr_wid_top_bottom = 0; + save->ov0_scale_cntl = 0; + save->mpp_tb_config = 0; + save->mpp_gp_config = 0; + save->subpic_cntl = 0; + save->viph_control = 0; + save->i2c_cntl_1 = 0; + save->gen_int_cntl = 0; + save->cap0_trig_cntl = 0; + save->cap1_trig_cntl = 0; + save->bus_cntl = info->BusCntl; + /* + * If bursts are enabled, turn on discards and aborts + */ + if (save->bus_cntl & (R128_BUS_WRT_BURST|R128_BUS_READ_BURST)) + save->bus_cntl |= R128_BUS_RD_DISCARD_EN | R128_BUS_RD_ABORT_EN; +} + +/* Define CRTC registers for requested video mode. */ +static Bool R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save, + DisplayModePtr mode, R128InfoPtr info) +{ + int format; + int hsync_start; + int hsync_wid; + int hsync_fudge; + int vsync_wid; + int bytpp; + int hsync_fudge_default[] = { 0x00, 0x12, 0x09, 0x09, 0x06, 0x05 }; + int hsync_fudge_fp[] = { 0x12, 0x11, 0x09, 0x09, 0x05, 0x05 }; + int hsync_fudge_fp_crt[] = { 0x12, 0x10, 0x08, 0x08, 0x04, 0x04 }; + + switch (info->CurrentLayout.pixel_code) { + case 4: format = 1; bytpp = 0; break; + case 8: format = 2; bytpp = 1; break; + case 15: format = 3; bytpp = 2; break; /* 555 */ + case 16: format = 4; bytpp = 2; break; /* 565 */ + case 24: format = 5; bytpp = 3; break; /* RGB */ + case 32: format = 6; bytpp = 4; break; /* xRGB */ + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Unsupported pixel depth (%d)\n", info->CurrentLayout.bitsPerPixel); + return FALSE; + } + R128TRACE(("Format = %d (%d bytes per pixel)\n", format, bytpp)); + + if (info->HasPanelRegs) + if (info->CRTOnly) hsync_fudge = hsync_fudge_fp_crt[format-1]; + else hsync_fudge = hsync_fudge_fp[format-1]; + else hsync_fudge = hsync_fudge_default[format-1]; + + save->crtc_gen_cntl = (R128_CRTC_EXT_DISP_EN + | R128_CRTC_EN + | (format << 8) + | ((mode->Flags & V_DBLSCAN) + ? R128_CRTC_DBL_SCAN_EN + : 0) + | ((mode->Flags & V_INTERLACE) + ? R128_CRTC_INTERLACE_EN + : 0)); + + save->crtc_ext_cntl = R128_VGA_ATI_LINEAR | R128_XCRT_CNT_EN; + save->dac_cntl = (R128_DAC_MASK_ALL + | R128_DAC_VGA_ADR_EN + | (info->dac6bits ? 0 : R128_DAC_8BIT_EN)); + + save->crtc_h_total_disp = ((((mode->CrtcHTotal / 8) - 1) & 0xffff) + | (((mode->CrtcHDisplay / 8) - 1) << 16)); + + hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8; + if (!hsync_wid) hsync_wid = 1; + if (hsync_wid > 0x3f) hsync_wid = 0x3f; + + hsync_start = mode->CrtcHSyncStart - 8 + hsync_fudge; + + save->crtc_h_sync_strt_wid = ((hsync_start & 0xfff) + | (hsync_wid << 16) + | ((mode->Flags & V_NHSYNC) + ? R128_CRTC_H_SYNC_POL + : 0)); + +#if 1 + /* This works for double scan mode. */ + save->crtc_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff) + | ((mode->CrtcVDisplay - 1) << 16)); +#else + /* This is what cce/nbmode.c example code + does -- is this correct? */ + save->crtc_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff) + | ((mode->CrtcVDisplay + * ((mode->Flags & V_DBLSCAN) ? 2 : 1) - 1) + << 16)); +#endif + + vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart; + if (!vsync_wid) vsync_wid = 1; + if (vsync_wid > 0x1f) vsync_wid = 0x1f; + + save->crtc_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff) + | (vsync_wid << 16) + | ((mode->Flags & V_NVSYNC) + ? R128_CRTC_V_SYNC_POL + : 0)); + save->crtc_offset = 0; + save->crtc_offset_cntl = 0; + save->crtc_pitch = info->CurrentLayout.displayWidth / 8; + + R128TRACE(("Pitch = %d bytes (virtualX = %d, displayWidth = %d)\n", + save->crtc_pitch, pScrn->virtualX, info->CurrentLayout.displayWidth)); + return TRUE; +} + +/* Define CRTC registers for requested video mode. */ +static void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save, + DisplayModePtr mode, R128InfoPtr info) +{ + int xres = mode->CrtcHDisplay; + int yres = mode->CrtcVDisplay; + float Hratio, Vratio; + + if (info->CRTOnly) { + save->crtc_ext_cntl |= R128_CRTC_CRT_ON; + save->crtc2_gen_cntl = 0; + save->fp_gen_cntl = orig->fp_gen_cntl; + save->fp_gen_cntl &= ~(R128_FP_FPON | + R128_FP_CRTC_USE_SHADOW_VEND | + R128_FP_CRTC_HORZ_DIV2_EN | + R128_FP_CRTC_HOR_CRT_DIV2_DIS | + R128_FP_USE_SHADOW_EN); + save->fp_gen_cntl |= (R128_FP_SEL_CRTC2 | + R128_FP_CRTC_DONT_SHADOW_VPAR); + save->fp_panel_cntl = orig->fp_panel_cntl & ~R128_FP_DIGON; + save->lvds_gen_cntl = orig->lvds_gen_cntl & ~(R128_LVDS_ON | + R128_LVDS_BLON); + return; + } + + if (xres > info->PanelXRes) xres = info->PanelXRes; + if (yres > info->PanelYRes) yres = info->PanelYRes; + + Hratio = (float)xres/(float)info->PanelXRes; + Vratio = (float)yres/(float)info->PanelYRes; + + save->fp_horz_stretch = + (((((int)(Hratio * R128_HORZ_STRETCH_RATIO_MAX + 0.5)) + & R128_HORZ_STRETCH_RATIO_MASK) << R128_HORZ_STRETCH_RATIO_SHIFT) | + (orig->fp_horz_stretch & (R128_HORZ_PANEL_SIZE | + R128_HORZ_FP_LOOP_STRETCH | + R128_HORZ_STRETCH_RESERVED))); + save->fp_horz_stretch &= ~R128_HORZ_AUTO_RATIO_FIX_EN; + if (Hratio == 1.0) save->fp_horz_stretch &= ~(R128_HORZ_STRETCH_BLEND | + R128_HORZ_STRETCH_ENABLE); + else save->fp_horz_stretch |= (R128_HORZ_STRETCH_BLEND | + R128_HORZ_STRETCH_ENABLE); + + save->fp_vert_stretch = + (((((int)(Vratio * R128_VERT_STRETCH_RATIO_MAX + 0.5)) + & R128_VERT_STRETCH_RATIO_MASK) << R128_VERT_STRETCH_RATIO_SHIFT) | + (orig->fp_vert_stretch & (R128_VERT_PANEL_SIZE | + R128_VERT_STRETCH_RESERVED))); + save->fp_vert_stretch &= ~R128_VERT_AUTO_RATIO_EN; + if (Vratio == 1.0) save->fp_vert_stretch &= ~(R128_VERT_STRETCH_ENABLE | + R128_VERT_STRETCH_BLEND); + else save->fp_vert_stretch |= (R128_VERT_STRETCH_ENABLE | + R128_VERT_STRETCH_BLEND); + + save->fp_gen_cntl = (orig->fp_gen_cntl & ~(R128_FP_SEL_CRTC2 | + R128_FP_CRTC_USE_SHADOW_VEND | + R128_FP_CRTC_HORZ_DIV2_EN | + R128_FP_CRTC_HOR_CRT_DIV2_DIS | + R128_FP_USE_SHADOW_EN)); + if (orig->fp_gen_cntl & R128_FP_DETECT_SENSE) { + save->fp_gen_cntl |= (R128_FP_CRTC_DONT_SHADOW_VPAR | + R128_FP_TDMS_EN); + } + + save->fp_panel_cntl = orig->fp_panel_cntl; + save->lvds_gen_cntl = orig->lvds_gen_cntl; + + save->tmds_crc = orig->tmds_crc; + + /* Disable CRT output by disabling CRT output and setting the CRT + DAC to use CRTC2, which we set to 0's. In the future, we will + want to use the dual CRTC capabilities of the R128 to allow both + the flat panel and external CRT to either simultaneously display + the same image or display two different images. */ + save->crtc_ext_cntl &= ~R128_CRTC_CRT_ON; + save->dac_cntl |= R128_DAC_CRT_SEL_CRTC2; + save->crtc2_gen_cntl = 0; + + /* WARNING: Be careful about turning on the flat panel */ +#if 1 + save->lvds_gen_cntl |= (R128_LVDS_ON | R128_LVDS_BLON); +#else + save->fp_panel_cntl |= (R128_FP_DIGON | R128_FP_BLON); + save->fp_gen_cntl |= (R128_FP_FPON); +#endif + + save->fp_crtc_h_total_disp = save->crtc_h_total_disp; + save->fp_crtc_v_total_disp = save->crtc_v_total_disp; + save->fp_h_sync_strt_wid = save->crtc_h_sync_strt_wid; + save->fp_v_sync_strt_wid = save->crtc_v_sync_strt_wid; +} + +/* Define PLL registers for requested video mode. */ +static void R128InitPLLRegisters(R128SavePtr save, R128PLLPtr pll, + double dot_clock) +{ + unsigned long freq = dot_clock * 100; + struct { + int divider; + int bitvalue; + } *post_div, + post_divs[] = { + /* From RAGE 128 VR/RAGE 128 GL Register + Reference Manual (Technical Reference + Manual P/N RRG-G04100-C Rev. 0.04), page + 3-17 (PLL_DIV_[3:0]). */ + { 1, 0 }, /* VCLK_SRC */ + { 2, 1 }, /* VCLK_SRC/2 */ + { 4, 2 }, /* VCLK_SRC/4 */ + { 8, 3 }, /* VCLK_SRC/8 */ + + { 3, 4 }, /* VCLK_SRC/3 */ + /* bitvalue = 5 is reserved */ + { 6, 6 }, /* VCLK_SRC/6 */ + { 12, 7 }, /* VCLK_SRC/12 */ + { 0, 0 } + }; + + if (freq > pll->max_pll_freq) freq = pll->max_pll_freq; + if (freq * 12 < pll->min_pll_freq) freq = pll->min_pll_freq / 12; + + for (post_div = &post_divs[0]; post_div->divider; ++post_div) { + save->pll_output_freq = post_div->divider * freq; + if (save->pll_output_freq >= pll->min_pll_freq + && save->pll_output_freq <= pll->max_pll_freq) break; + } + + save->dot_clock_freq = freq; + save->feedback_div = R128Div(pll->reference_div * save->pll_output_freq, + pll->reference_freq); + save->post_div = post_div->divider; + + R128TRACE(("dc=%d, of=%d, fd=%d, pd=%d\n", + save->dot_clock_freq, + save->pll_output_freq, + save->feedback_div, + save->post_div)); + + save->ppll_ref_div = pll->reference_div; + save->ppll_div_3 = (save->feedback_div | (post_div->bitvalue << 16)); + save->htotal_cntl = 0; +} + +/* Define DDA registers for requested video mode. */ +static Bool R128InitDDARegisters(ScrnInfoPtr pScrn, R128SavePtr save, + R128PLLPtr pll, R128InfoPtr info) +{ + int DisplayFifoWidth = 128; + int DisplayFifoDepth = 32; + int XclkFreq; + int VclkFreq; + int XclksPerTransfer; + int XclksPerTransferPrecise; + int UseablePrecision; + int Roff; + int Ron; + + XclkFreq = pll->xclk; + + VclkFreq = R128Div(pll->reference_freq * save->feedback_div, + pll->reference_div * save->post_div); + + XclksPerTransfer = R128Div(XclkFreq * DisplayFifoWidth, + VclkFreq * (info->CurrentLayout.pixel_bytes * 8)); + + UseablePrecision = R128MinBits(XclksPerTransfer) + 1; + + XclksPerTransferPrecise = R128Div((XclkFreq * DisplayFifoWidth) + << (11 - UseablePrecision), + VclkFreq * (info->CurrentLayout.pixel_bytes * 8)); + + Roff = XclksPerTransferPrecise * (DisplayFifoDepth - 4); + + Ron = (4 * info->ram->MB + + 3 * MAX(info->ram->Trcd - 2, 0) + + 2 * info->ram->Trp + + info->ram->Twr + + info->ram->CL + + info->ram->Tr2w + + XclksPerTransfer) << (11 - UseablePrecision); + + if (Ron + info->ram->Rloop >= Roff) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "(Ron = %d) + (Rloop = %d) >= (Roff = %d)\n", + Ron, info->ram->Rloop, Roff); + return FALSE; + } + + save->dda_config = (XclksPerTransferPrecise + | (UseablePrecision << 16) + | (info->ram->Rloop << 20)); + + save->dda_on_off = (Ron << 16) | Roff; + + R128TRACE(("XclkFreq = %d; VclkFreq = %d; per = %d, %d (useable = %d)\n", + XclkFreq, + VclkFreq, + XclksPerTransfer, + XclksPerTransferPrecise, + UseablePrecision)); + R128TRACE(("Roff = %d, Ron = %d, Rloop = %d\n", + Roff, Ron, info->ram->Rloop)); + + return TRUE; +} + + +/* Define initial palette for requested video mode. This doesn't do + anything for XFree86 4.0. */ +static void R128InitPalette(R128SavePtr save) +{ + save->palette_valid = FALSE; +} + +/* Define registers for a requested video mode. */ +static Bool R128Init(ScrnInfoPtr pScrn, DisplayModePtr mode, R128SavePtr save) +{ + R128InfoPtr info = R128PTR(pScrn); + double dot_clock = mode->Clock/1000.0; + +#if R128_DEBUG + ErrorF("%-12.12s %7.2f %4d %4d %4d %4d %4d %4d %4d %4d (%d,%d)", + mode->name, + dot_clock, + + mode->HDisplay, + mode->HSyncStart, + mode->HSyncEnd, + mode->HTotal, + + mode->VDisplay, + mode->VSyncStart, + mode->VSyncEnd, + mode->VTotal, + pScrn->depth, + pScrn->bitsPerPixel); + if (mode->Flags & V_DBLSCAN) ErrorF(" D"); + if (mode->Flags & V_INTERLACE) ErrorF(" I"); + if (mode->Flags & V_PHSYNC) ErrorF(" +H"); + if (mode->Flags & V_NHSYNC) ErrorF(" -H"); + if (mode->Flags & V_PVSYNC) ErrorF(" +V"); + if (mode->Flags & V_NVSYNC) ErrorF(" -V"); + ErrorF("\n"); + ErrorF("%-12.12s %7.2f %4d %4d %4d %4d %4d %4d %4d %4d (%d,%d)", + mode->name, + dot_clock, + + mode->CrtcHDisplay, + mode->CrtcHSyncStart, + mode->CrtcHSyncEnd, + mode->CrtcHTotal, + + mode->CrtcVDisplay, + mode->CrtcVSyncStart, + mode->CrtcVSyncEnd, + mode->CrtcVTotal, + pScrn->depth, + pScrn->bitsPerPixel); + if (mode->Flags & V_DBLSCAN) ErrorF(" D"); + if (mode->Flags & V_INTERLACE) ErrorF(" I"); + if (mode->Flags & V_PHSYNC) ErrorF(" +H"); + if (mode->Flags & V_NHSYNC) ErrorF(" -H"); + if (mode->Flags & V_PVSYNC) ErrorF(" +V"); + if (mode->Flags & V_NVSYNC) ErrorF(" -V"); + ErrorF("\n"); +#endif + + info->Flags = mode->Flags; + + R128InitCommonRegisters(save, info); + if (!R128InitCrtcRegisters(pScrn, save, mode, info)) return FALSE; + if (info->HasPanelRegs) + R128InitFPRegisters(&info->SavedReg, save, mode, info); + R128InitPLLRegisters(save, &info->pll, dot_clock); + if (!R128InitDDARegisters(pScrn, save, &info->pll, info)) + return FALSE; + if (!info->PaletteSavedOnVT) R128InitPalette(save); + + R128TRACE(("R128Init returns %p\n", save)); + return TRUE; +} + +/* Initialize a new mode. */ +static Bool R128ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + R128InfoPtr info = R128PTR(pScrn); + + if (!R128Init(pScrn, mode, &info->ModeReg)) return FALSE; + /* FIXME? DRILock/DRIUnlock here? */ + pScrn->vtSema = TRUE; + R128Blank(pScrn); + R128RestoreMode(pScrn, &info->ModeReg); + R128Unblank(pScrn); + + info->CurrentLayout.mode = mode; + + return TRUE; +} + +static Bool R128SaveScreen(ScreenPtr pScreen, int mode) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + Bool unblank; + + unblank = xf86IsUnblank(mode); + if (unblank) + SetTimeSinceLastInputEvent(); + + if ((pScrn != NULL) && pScrn->vtSema) { + if (unblank) + R128Unblank(pScrn); + else + R128Blank(pScrn); + } + return TRUE; +} + +Bool R128SwitchMode(int scrnIndex, DisplayModePtr mode, int flags) +{ + return R128ModeInit(xf86Screens[scrnIndex], mode); +} + +/* Used to disallow modes that are not supported by the hardware. */ +int R128ValidMode(int scrnIndex, DisplayModePtr mode, + Bool verbose, int flag) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + R128InfoPtr info = R128PTR(pScrn); + + if (info->HasPanelRegs) { + if (mode->Flags & V_INTERLACE) return MODE_NO_INTERLACE; + if (mode->Flags & V_DBLSCAN) return MODE_NO_DBLESCAN; + } + + if (info->HasPanelRegs && !info->CRTOnly && info->VBIOS) { + int i; + for (i = info->FPBIOSstart+64; R128_BIOS16(i) != 0; i += 2) { + int j = R128_BIOS16(i); + + if (mode->CrtcHDisplay == R128_BIOS16(j) && + mode->CrtcVDisplay == R128_BIOS16(j+2)) { + /* Assume we are using expanded mode */ + if (R128_BIOS16(j+5)) j = R128_BIOS16(j+5); + else j += 9; + + mode->Clock = (CARD32)R128_BIOS16(j) * 10; + + mode->HDisplay = mode->CrtcHDisplay = + ((R128_BIOS16(j+10) & 0x01ff)+1)*8; + mode->HSyncStart = mode->CrtcHSyncStart = + ((R128_BIOS16(j+12) & 0x01ff)+1)*8; + mode->HSyncEnd = mode->CrtcHSyncEnd = + mode->CrtcHSyncStart + (R128_BIOS8(j+14) & 0x1f); + mode->HTotal = mode->CrtcHTotal = + ((R128_BIOS16(j+8) & 0x01ff)+1)*8; + + mode->VDisplay = mode->CrtcVDisplay = + (R128_BIOS16(j+17) & 0x07ff)+1; + mode->VSyncStart = mode->CrtcVSyncStart = + (R128_BIOS16(j+19) & 0x07ff)+1; + mode->VSyncEnd = mode->CrtcVSyncEnd = + mode->CrtcVSyncStart + ((R128_BIOS16(j+19) >> 11) & 0x1f); + mode->VTotal = mode->CrtcVTotal = + (R128_BIOS16(j+15) & 0x07ff)+1; + + return MODE_OK; + } + } + return MODE_NOMODE; + } + + return MODE_OK; +} + +/* Adjust viewport into virtual desktop such that (0,0) in viewport space + is (x,y) in virtual space. */ +void R128AdjustFrame(int scrnIndex, int x, int y, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int Base; + + Base = y * info->CurrentLayout.displayWidth + x; + + switch (info->CurrentLayout.pixel_code) { + case 15: + case 16: Base *= 2; break; + case 24: Base *= 3; break; + case 32: Base *= 4; break; + } + + Base &= ~7; /* 3 lower bits are always 0 */ + + if (info->CurrentLayout.pixel_code == 24) + Base += 8 * (Base % 3); /* Must be multiple of 8 and 3 */ + + OUTREG(R128_CRTC_OFFSET, Base); +} + +/* Called when VT switching back to the X server. Reinitialize the video + mode. */ +Bool R128EnterVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + R128InfoPtr info = R128PTR(pScrn); + + R128TRACE(("R128EnterVT\n")); +#ifdef XF86DRI + if (R128PTR(pScrn)->directRenderingEnabled) { + R128CCEStart(pScrn); + DRIUnlock(pScrn->pScreen); + } +#endif + if (!R128ModeInit(pScrn, pScrn->currentMode)) return FALSE; + if (info->accelOn) + R128EngineInit(pScrn); + + info->PaletteSavedOnVT = FALSE; + R128AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + + return TRUE; +} + +/* Called when VT switching away from the X server. Restore the original + text mode. */ +void R128LeaveVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + R128InfoPtr info = R128PTR(pScrn); + R128SavePtr save = &info->ModeReg; + + R128TRACE(("R128LeaveVT\n")); +#ifdef XF86DRI + if (R128PTR(pScrn)->directRenderingEnabled) { + DRILock(pScrn->pScreen, 0); + R128CCEStop(pScrn); + } +#endif + R128SavePalette(pScrn, save); + info->PaletteSavedOnVT = TRUE; + R128Restore(pScrn); +} + +static Bool +R128EnterVTFBDev(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + R128InfoPtr info = R128PTR(pScrn); + R128SavePtr restore = &info->SavedReg; + fbdevHWEnterVT(scrnIndex,flags); + R128RestorePalette(pScrn,restore); + R128EngineInit(pScrn); + return TRUE; +} + +static void R128LeaveVTFBDev(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + R128InfoPtr info = R128PTR(pScrn); + R128SavePtr save = &info->SavedReg; + R128SavePalette(pScrn,save); + fbdevHWLeaveVT(scrnIndex,flags); +} + +/* Called at the end of each server generation. Restore the original text + mode, unmap video memory, and unwrap and call the saved CloseScreen + function. */ +static Bool R128CloseScreen(int scrnIndex, ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + R128InfoPtr info = R128PTR(pScrn); + + R128TRACE(("R128CloseScreen\n")); + +#ifdef XF86DRI + /* Disable direct rendering */ + if (info->directRenderingEnabled) { + R128DRICloseScreen(pScreen); + info->directRenderingEnabled = FALSE; + } +#endif + + if (pScrn->vtSema) { + R128Restore(pScrn); + R128UnmapMem(pScrn); + } + + if (info->accel) XAADestroyInfoRec(info->accel); + info->accel = NULL; + + if (info->scratch_save) xfree(info->scratch_save); + info->scratch_save = NULL; + + if (info->cursor) xf86DestroyCursorInfoRec(info->cursor); + info->cursor = NULL; + + if (info->DGAModes) xfree(info->DGAModes); + info->DGAModes = NULL; + + pScrn->vtSema = FALSE; + + pScreen->CloseScreen = info->CloseScreen; + return (*pScreen->CloseScreen)(scrnIndex, pScreen); +} + +void R128FreeScreen(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + + R128TRACE(("R128FreeScreen\n")); + if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) + vgaHWFreeHWRec(pScrn); + R128FreeRec(pScrn); +} + +#ifdef DPMSExtension +/* Sets VESA Display Power Management Signaling (DPMS) Mode. */ +static void R128DisplayPowerManagementSet(ScrnInfoPtr pScrn, + int PowerManagementMode, int flags) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int mask = (R128_CRTC_DISPLAY_DIS + | R128_CRTC_HSYNC_DIS + | R128_CRTC_VSYNC_DIS); + + switch (PowerManagementMode) { + case DPMSModeOn: + /* Screen: On; HSync: On, VSync: On */ + OUTREGP(R128_CRTC_EXT_CNTL, 0, ~mask); + break; + case DPMSModeStandby: + /* Screen: Off; HSync: Off, VSync: On */ + OUTREGP(R128_CRTC_EXT_CNTL, + R128_CRTC_DISPLAY_DIS | R128_CRTC_HSYNC_DIS, ~mask); + break; + case DPMSModeSuspend: + /* Screen: Off; HSync: On, VSync: Off */ + OUTREGP(R128_CRTC_EXT_CNTL, + R128_CRTC_DISPLAY_DIS | R128_CRTC_VSYNC_DIS, ~mask); + break; + case DPMSModeOff: + /* Screen: Off; HSync: Off, VSync: Off */ + OUTREGP(R128_CRTC_EXT_CNTL, mask, ~mask); + break; + } +} +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_misc.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_misc.c new file mode 100644 index 000000000..bbaf3e4d7 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_misc.c @@ -0,0 +1,84 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_misc.c,v 1.1 2000/11/02 16:55:36 tsi Exp $ */ +/* + * Copyright 2000 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of Marc Aurele La France not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Marc Aurele La France makes no representations + * about the suitability of this software for any purpose. It is provided + * "as-is" without express or implied warranty. + * + * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO + * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef XFree86LOADER + +#include "ativersion.h" + +#include "r128_version.h" + +#include "xf86.h" + +/* Module loader interface for subsidiary driver module */ + +static XF86ModuleVersionInfo R128VersionRec = +{ + R128_DRIVER_NAME, + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XF86_VERSION_CURRENT, + R128_VERSION_MAJOR, R128_VERSION_MINOR, R128_VERSION_PATCH, + ABI_CLASS_VIDEODRV, + ABI_VIDEODRV_VERSION, + MOD_CLASS_VIDEODRV, + {0, 0, 0, 0} +}; + +/* + * R128Setup -- + * + * This function is called every time the module is loaded. + */ +static pointer +R128Setup +( + pointer Module, + pointer Options, + int *ErrorMajor, + int *ErrorMinor +) +{ + static Bool Inited = FALSE; + + if (!Inited) + { + /* Ensure main driver module is loaded, but not as a submodule */ + if (!xf86ServerIsOnlyDetecting() && !LoaderSymbol(ATI_NAME)) + xf86LoadOneModule(ATI_DRIVER_NAME, Options); + + Inited = TRUE; + } + + return (pointer)TRUE; +} + +/* The following record must be called r128ModuleData */ +XF86ModuleData r128ModuleData = +{ + &R128VersionRec, + R128Setup, + NULL +}; + +#endif /* XFree86LOADER */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.c new file mode 100644 index 000000000..03fa17a4c --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.c @@ -0,0 +1,195 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.c,v 1.1 2000/11/02 16:55:37 tsi Exp $ */ +/* + * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario + * and Precision Insight, Inc., Cedar Park, Texas. + * + * 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 on + * 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, PRECISION INSIGHT AND/OR THEIR 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: + * Rickard E. Faith <faith@precisioninsight.com> + * Kevin E. Martin <kevin@precisioninsight.com> + * + * Modified by Marc Aurele La France <tsi@xfree86.org> for ATI driver merge. + */ + +#include "atimodule.h" +#include "ativersion.h" + +#include "r128_probe.h" +#include "r128_version.h" + +#include "xf86PciInfo.h" + +#include "xf86.h" +#include "xf86_ansic.h" +#include "xf86Resources.h" + +SymTabRec R128Chipsets[] = { + { PCI_CHIP_RAGE128RE, "ATI Rage 128 RE (PCI)" }, + { PCI_CHIP_RAGE128RF, "ATI Rage 128 RF (AGP)" }, + { PCI_CHIP_RAGE128RK, "ATI Rage 128 RK (PCI)" }, + { PCI_CHIP_RAGE128RL, "ATI Rage 128 RL (AGP)" }, + { PCI_CHIP_RAGE128PF, "ATI Rage 128 Pro PF (AGP)" }, + { PCI_CHIP_RAGE128LE, "ATI Rage 128 Mobility LE (PCI)" }, + { PCI_CHIP_RAGE128LF, "ATI Rage 128 Mobility LF (AGP)" }, + { PCI_CHIP_RAGE128MF, "ATI Rage 128 Mobility MF (AGP)" }, + { PCI_CHIP_RAGE128ML, "ATI Rage 128 Mobility ML (AGP)" }, + { -1, NULL } +}; + +PciChipsets R128PciChipsets[] = { + { PCI_CHIP_RAGE128RE, PCI_CHIP_RAGE128RE, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128RF, PCI_CHIP_RAGE128RF, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128RK, PCI_CHIP_RAGE128RK, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128RL, PCI_CHIP_RAGE128RL, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128PF, PCI_CHIP_RAGE128PF, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128LE, PCI_CHIP_RAGE128LE, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128LF, PCI_CHIP_RAGE128LF, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128MF, PCI_CHIP_RAGE128MF, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128ML, PCI_CHIP_RAGE128ML, RES_SHARED_VGA }, + { -1, -1, RES_UNDEFINED } +}; + +/* Return the options for supported chipset 'n'; NULL otherwise */ +OptionInfoPtr +R128AvailableOptions(int chipid, int busid) +{ + int i; + + /* + * Return options defined in the r128 submodule which will have been + * loaded by this point. + */ + for (i = 0; R128PciChipsets[i].PCIid > 0; i++) { + if (chipid == R128PciChipsets[i].PCIid) + return R128Options; + } + return NULL; +} + +/* Return the string name for supported chipset 'n'; NULL otherwise. */ +void +R128Identify(int flags) +{ + xf86PrintChipsets(R128_NAME, + "Driver for ATI Rage 128 chipsets", + R128Chipsets); +} + +/* Return TRUE if chipset is present; FALSE otherwise. */ +Bool +R128Probe(DriverPtr drv, int flags) +{ + int numUsed; + int numDevSections, nATIGDev, nR128GDev; + int *usedChips; + GDevPtr *devSections, *ATIGDevs, *R128GDevs; + EntityInfoPtr pEnt; + Bool foundScreen = FALSE; + int i; + + if (!xf86GetPciVideoInfo()) return FALSE; + + /* Collect unclaimed device sections for both driver names */ + nATIGDev = xf86MatchDevice(ATI_NAME, &ATIGDevs); + nR128GDev = xf86MatchDevice(R128_NAME, &R128GDevs); + + if (!(numDevSections = nATIGDev + nR128GDev)) return FALSE; + + if (!ATIGDevs) { + if (!(devSections = R128GDevs)) + numDevSections = 1; + else + numDevSections = nR128GDev; + } if (!R128GDevs) { + devSections = ATIGDevs; + numDevSections = nATIGDev; + } else { + /* Combine into one list */ + devSections = xnfalloc((numDevSections + 1) * sizeof(GDevPtr)); + (void)memcpy(devSections, + ATIGDevs, nATIGDev * sizeof(GDevPtr)); + (void)memcpy(devSections + nATIGDev, + R128GDevs, nR128GDev * sizeof(GDevPtr)); + devSections[numDevSections] = NULL; + xfree(ATIGDevs); + xfree(R128GDevs); + } + + numUsed = xf86MatchPciInstances(R128_NAME, + PCI_VENDOR_ATI, + R128Chipsets, + R128PciChipsets, + devSections, + numDevSections, + drv, + &usedChips); + + if (numUsed<=0) return FALSE; + + if (flags & PROBE_DETECT) + foundScreen = TRUE; + else for (i = 0; i < numUsed; i++) { + pEnt = xf86GetEntityInfo(usedChips[i]); + + if (pEnt->active) { + ScrnInfoPtr pScrn = xf86AllocateScreen(drv, 0); + +#ifdef XFree86LOADER + if (!xf86LoadSubModule(pScrn, "r128")) { + xf86Msg(X_ERROR, + R128_NAME ": Failed to load \"r128\" module.\n"); + xf86DeleteScreen(pScrn->scrnIndex, 0); + continue; + } + + xf86LoaderReqSymLists(R128Symbols, NULL); +#endif + + pScrn->driverVersion = R128_VERSION_CURRENT; + pScrn->driverName = R128_DRIVER_NAME; + pScrn->name = R128_NAME; + pScrn->Probe = R128Probe; + pScrn->PreInit = R128PreInit; + pScrn->ScreenInit = R128ScreenInit; + pScrn->SwitchMode = R128SwitchMode; + pScrn->AdjustFrame = R128AdjustFrame; + pScrn->EnterVT = R128EnterVT; + pScrn->LeaveVT = R128LeaveVT; + pScrn->FreeScreen = R128FreeScreen; + pScrn->ValidMode = R128ValidMode; + + foundScreen = TRUE; + + xf86ConfigActivePciEntity(pScrn, usedChips[i], R128PciChipsets, + 0, 0, 0, 0, 0); + } + xfree(pEnt); + } + + if (numUsed) xfree(usedChips); + xfree(devSections); + + return foundScreen; +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.h new file mode 100644 index 000000000..11d71749f --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.h @@ -0,0 +1,73 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.h,v 1.1 2000/11/02 16:55:37 tsi Exp $ */ +/* + * Copyright 2000 ATI Technologies Inc., Markham, Ontario + * and 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 on + * 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Kevin E. Martin <martin@valinux.com> + * + * Modified by Marc Aurele La France <tsi@xfree86.org> for ATI driver merge. + */ + +#ifndef _R128_PROBE_H_ +#define _R128_PROBE_H_ 1 + +#include "atiproto.h" + +#include "xf86str.h" + +/* r128_probe.c */ +extern OptionInfoPtr R128AvailableOptions + FunctionPrototype((int, int)); +extern void R128Identify + FunctionPrototype((int)); +extern Bool R128Probe + FunctionPrototype((DriverPtr, int)); + +extern SymTabRec R128Chipsets[]; +extern PciChipsets R128PciChipsets[]; + +/* r128_driver.c */ +extern Bool R128PreInit + FunctionPrototype((ScrnInfoPtr, int)); +extern Bool R128ScreenInit + FunctionPrototype((int, ScreenPtr, int, char **)); +extern Bool R128SwitchMode + FunctionPrototype((int, DisplayModePtr, int)); +extern void R128AdjustFrame + FunctionPrototype((int, int, int, int)); +extern Bool R128EnterVT + FunctionPrototype((int, int)); +extern void R128LeaveVT + FunctionPrototype((int, int)); +extern void R128FreeScreen + FunctionPrototype((int, int)); +extern int R128ValidMode + FunctionPrototype((int, DisplayModePtr, Bool, int)); + +extern OptionInfoRec R128Options[]; + +#endif /* _R128_PROBE_H_ */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h new file mode 100644 index 000000000..cc71a015e --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h @@ -0,0 +1,1459 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h,v 1.1 2000/11/02 16:55:37 tsi Exp $ */ +/* + * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario + * and Precision Insight, Inc., Cedar Park, Texas. + * + * 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 on + * 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, PRECISION INSIGHT AND/OR THEIR 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: + * Rickard E. Faith <faith@precisioninsight.com> + * Kevin E. Martin <kevin@precisioninsight.com> + * + * References: + * + * RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical + * Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April + * 1999. + * + * RAGE 128 Software Development Manual (Technical Reference Manual P/N + * SDK-G04000 Rev. 0.01), ATI Technologies: June 1999. + * + */ + +#ifndef _R128_REG_H_ +#define _R128_REG_H_ +#include <compiler.h> + + /* Memory mapped register access macros */ +#define INREG8(addr) MMIO_IN8(R128MMIO, addr) +#define INREG16(addr) MMIO_IN16(R128MMIO, addr) +#define INREG(addr) MMIO_IN32(R128MMIO, addr) +#define OUTREG8(addr, val) MMIO_OUT8(R128MMIO, addr, val) +#define OUTREG16(addr, val) MMIO_OUT16(R128MMIO, addr, val) +#define OUTREG(addr, val) MMIO_OUT32(R128MMIO, addr, val) + +#define ADDRREG(addr) ((volatile CARD32 *)(R128MMIO + (addr))) + + +#define OUTREGP(addr, val, mask) \ + do { \ + CARD32 tmp = INREG(addr); \ + tmp &= (mask); \ + tmp |= (val); \ + OUTREG(addr, tmp); \ + } while (0) + +#define INPLL(pScrn, addr) R128INPLL(pScrn, addr) + +#define OUTPLL(addr, val) \ + do { \ + OUTREG8(R128_CLOCK_CNTL_INDEX, ((addr) & 0x1f) | R128_PLL_WR_EN); \ + OUTREG(R128_CLOCK_CNTL_DATA, val); \ + } while (0) + +#define OUTPLLP(pScrn, addr, val, mask) \ + do { \ + CARD32 tmp = INPLL(pScrn, addr); \ + tmp &= (mask); \ + tmp |= (val); \ + OUTPLL(addr, tmp); \ + } while (0) + +#define OUTPAL_START(idx) \ + do { \ + OUTREG8(R128_PALETTE_INDEX, (idx)); \ + } while (0) + +#define OUTPAL_NEXT(r, g, b) \ + do { \ + OUTREG(R128_PALETTE_DATA, ((r) << 16) | ((g) << 8) | (b)); \ + } while (0) + +#define OUTPAL_NEXT_CARD32(v) \ + do { \ + OUTREG(R128_PALETTE_DATA, (v & 0x00ffffff)); \ + } while (0) + +#define OUTPAL(idx, r, g, b) \ + do { \ + OUTPAL_START((idx)); \ + OUTPAL_NEXT((r), (g), (b)); \ + } while (0) + +#define INPAL_START(idx) \ + do { \ + OUTREG(R128_PALETTE_INDEX, (idx) << 16); \ + } while (0) + +#define INPAL_NEXT() INREG(R128_PALETTE_DATA) + +#define PAL_SELECT(idx) \ + do { \ + if (idx) { \ + OUTREG(R128_DAC_CNTL, INREG(R128_DAC_CNTL) | \ + R128_DAC_PALETTE_ACC_CTL); \ + } else { \ + OUTREG(R128_DAC_CNTL, INREG(R128_DAC_CNTL) & \ + ~R128_DAC_PALETTE_ACC_CTL); \ + } \ + } while (0) + +#define R128_ADAPTER_ID 0x0f2c /* PCI */ +#define R128_AGP_APER_OFFSET 0x0178 +#define R128_AGP_BASE 0x0170 +#define R128_AGP_CNTL 0x0174 +# define R128_AGP_APER_SIZE_256MB (0x00 << 0) +# define R128_AGP_APER_SIZE_128MB (0x20 << 0) +# define R128_AGP_APER_SIZE_64MB (0x30 << 0) +# define R128_AGP_APER_SIZE_32MB (0x38 << 0) +# define R128_AGP_APER_SIZE_16MB (0x3c << 0) +# define R128_AGP_APER_SIZE_8MB (0x3e << 0) +# define R128_AGP_APER_SIZE_4MB (0x3f << 0) +# define R128_AGP_APER_SIZE_MASK (0x3f << 0) +#define R128_AGP_CNTL_B 0x0b44 +#define R128_AGP_COMMAND 0x0f58 /* PCI */ +#define R128_AGP_PLL_CNTL 0x0010 /* PLL */ +#define R128_AGP_STATUS 0x0f54 /* PCI */ +# define R128_AGP_1X_MODE 0x01 +# define R128_AGP_2X_MODE 0x02 +# define R128_AGP_4X_MODE 0x04 +# define R128_AGP_MODE_MASK 0x07 +#define R128_AMCGPIO_A_REG 0x01a0 +#define R128_AMCGPIO_EN_REG 0x01a8 +#define R128_AMCGPIO_MASK 0x0194 +#define R128_AMCGPIO_Y_REG 0x01a4 +#define R128_ATTRDR 0x03c1 /* VGA */ +#define R128_ATTRDW 0x03c0 /* VGA */ +#define R128_ATTRX 0x03c0 /* VGA */ +# define R128_AUX1_SC_EN (1 << 0) +# define R128_AUX1_SC_MODE_OR (0 << 1) +# define R128_AUX1_SC_MODE_NAND (1 << 1) +# define R128_AUX2_SC_EN (1 << 2) +# define R128_AUX2_SC_MODE_OR (0 << 3) +# define R128_AUX2_SC_MODE_NAND (1 << 3) +# define R128_AUX3_SC_EN (1 << 4) +# define R128_AUX3_SC_MODE_OR (0 << 5) +# define R128_AUX3_SC_MODE_NAND (1 << 5) +#define R128_AUX_SC_CNTL 0x1660 +#define R128_AUX1_SC_BOTTOM 0x1670 +#define R128_AUX1_SC_LEFT 0x1664 +#define R128_AUX1_SC_RIGHT 0x1668 +#define R128_AUX1_SC_TOP 0x166c +#define R128_AUX2_SC_BOTTOM 0x1680 +#define R128_AUX2_SC_LEFT 0x1674 +#define R128_AUX2_SC_RIGHT 0x1678 +#define R128_AUX2_SC_TOP 0x167c +#define R128_AUX3_SC_BOTTOM 0x1690 +#define R128_AUX3_SC_LEFT 0x1684 +#define R128_AUX3_SC_RIGHT 0x1688 +#define R128_AUX3_SC_TOP 0x168c +#define R128_AUX_WINDOW_HORZ_CNTL 0x02d8 +#define R128_AUX_WINDOW_VERT_CNTL 0x02dc + +#define R128_BASE_CODE 0x0f0b +#define R128_BIOS_0_SCRATCH 0x0010 +#define R128_BIOS_1_SCRATCH 0x0014 +#define R128_BIOS_2_SCRATCH 0x0018 +#define R128_BIOS_3_SCRATCH 0x001c +#define R128_BIOS_ROM 0x0f30 /* PCI */ +#define R128_BIST 0x0f0f /* PCI */ +#define R128_BRUSH_DATA0 0x1480 +#define R128_BRUSH_DATA1 0x1484 +#define R128_BRUSH_DATA10 0x14a8 +#define R128_BRUSH_DATA11 0x14ac +#define R128_BRUSH_DATA12 0x14b0 +#define R128_BRUSH_DATA13 0x14b4 +#define R128_BRUSH_DATA14 0x14b8 +#define R128_BRUSH_DATA15 0x14bc +#define R128_BRUSH_DATA16 0x14c0 +#define R128_BRUSH_DATA17 0x14c4 +#define R128_BRUSH_DATA18 0x14c8 +#define R128_BRUSH_DATA19 0x14cc +#define R128_BRUSH_DATA2 0x1488 +#define R128_BRUSH_DATA20 0x14d0 +#define R128_BRUSH_DATA21 0x14d4 +#define R128_BRUSH_DATA22 0x14d8 +#define R128_BRUSH_DATA23 0x14dc +#define R128_BRUSH_DATA24 0x14e0 +#define R128_BRUSH_DATA25 0x14e4 +#define R128_BRUSH_DATA26 0x14e8 +#define R128_BRUSH_DATA27 0x14ec +#define R128_BRUSH_DATA28 0x14f0 +#define R128_BRUSH_DATA29 0x14f4 +#define R128_BRUSH_DATA3 0x148c +#define R128_BRUSH_DATA30 0x14f8 +#define R128_BRUSH_DATA31 0x14fc +#define R128_BRUSH_DATA32 0x1500 +#define R128_BRUSH_DATA33 0x1504 +#define R128_BRUSH_DATA34 0x1508 +#define R128_BRUSH_DATA35 0x150c +#define R128_BRUSH_DATA36 0x1510 +#define R128_BRUSH_DATA37 0x1514 +#define R128_BRUSH_DATA38 0x1518 +#define R128_BRUSH_DATA39 0x151c +#define R128_BRUSH_DATA4 0x1490 +#define R128_BRUSH_DATA40 0x1520 +#define R128_BRUSH_DATA41 0x1524 +#define R128_BRUSH_DATA42 0x1528 +#define R128_BRUSH_DATA43 0x152c +#define R128_BRUSH_DATA44 0x1530 +#define R128_BRUSH_DATA45 0x1534 +#define R128_BRUSH_DATA46 0x1538 +#define R128_BRUSH_DATA47 0x153c +#define R128_BRUSH_DATA48 0x1540 +#define R128_BRUSH_DATA49 0x1544 +#define R128_BRUSH_DATA5 0x1494 +#define R128_BRUSH_DATA50 0x1548 +#define R128_BRUSH_DATA51 0x154c +#define R128_BRUSH_DATA52 0x1550 +#define R128_BRUSH_DATA53 0x1554 +#define R128_BRUSH_DATA54 0x1558 +#define R128_BRUSH_DATA55 0x155c +#define R128_BRUSH_DATA56 0x1560 +#define R128_BRUSH_DATA57 0x1564 +#define R128_BRUSH_DATA58 0x1568 +#define R128_BRUSH_DATA59 0x156c +#define R128_BRUSH_DATA6 0x1498 +#define R128_BRUSH_DATA60 0x1570 +#define R128_BRUSH_DATA61 0x1574 +#define R128_BRUSH_DATA62 0x1578 +#define R128_BRUSH_DATA63 0x157c +#define R128_BRUSH_DATA7 0x149c +#define R128_BRUSH_DATA8 0x14a0 +#define R128_BRUSH_DATA9 0x14a4 +#define R128_BRUSH_SCALE 0x1470 +#define R128_BRUSH_Y_X 0x1474 +#define R128_BUS_CNTL 0x0030 +# define R128_BUS_MASTER_DIS (1 << 6) +# define R128_BUS_RD_DISCARD_EN (1 << 24) +# define R128_BUS_RD_ABORT_EN (1 << 25) +# define R128_BUS_MSTR_DISCONNECT_EN (1 << 28) +# define R128_BUS_WRT_BURST (1 << 29) +# define R128_BUS_READ_BURST (1 << 30) +#define R128_BUS_CNTL1 0x0034 +# define R128_BUS_WAIT_ON_LOCK_EN (1 << 4) + +#define R128_CACHE_CNTL 0x1724 +#define R128_CACHE_LINE 0x0f0c /* PCI */ +#define R128_CAP0_TRIG_CNTL 0x0950 /* ? */ +#define R128_CAP1_TRIG_CNTL 0x09c0 /* ? */ +#define R128_CAPABILITIES_ID 0x0f50 /* PCI */ +#define R128_CAPABILITIES_PTR 0x0f34 /* PCI */ +#define R128_CLK_PIN_CNTL 0x0001 /* PLL */ +#define R128_CLOCK_CNTL_DATA 0x000c +#define R128_CLOCK_CNTL_INDEX 0x0008 +# define R128_PLL_WR_EN (1 << 7) +# define R128_PLL_DIV_SEL (3 << 8) +#define R128_CLR_CMP_CLR_3D 0x1a24 +#define R128_CLR_CMP_CLR_DST 0x15c8 +#define R128_CLR_CMP_CLR_SRC 0x15c4 +#define R128_CLR_CMP_CNTL 0x15c0 +# define R128_SRC_CMP_EQ_COLOR (4 << 0) +# define R128_SRC_CMP_NEQ_COLOR (5 << 0) +# define R128_CLR_CMP_SRC_SOURCE (1 << 24) +#define R128_CLR_CMP_MASK 0x15cc +# define R128_CLR_CMP_MSK 0xffffffff +#define R128_CLR_CMP_MASK_3D 0x1A28 +#define R128_COMMAND 0x0f04 /* PCI */ +#define R128_COMPOSITE_SHADOW_ID 0x1a0c +#define R128_CONFIG_APER_0_BASE 0x0100 +#define R128_CONFIG_APER_1_BASE 0x0104 +#define R128_CONFIG_APER_SIZE 0x0108 +#define R128_CONFIG_BONDS 0x00e8 +#define R128_CONFIG_CNTL 0x00e0 +#define R128_CONFIG_MEMSIZE 0x00f8 +#define R128_CONFIG_MEMSIZE_EMBEDDED 0x0114 +#define R128_CONFIG_REG_1_BASE 0x010c +#define R128_CONFIG_REG_APER_SIZE 0x0110 +#define R128_CONFIG_XSTRAP 0x00e4 +#define R128_CONSTANT_COLOR_C 0x1d34 +# define R128_CONSTANT_COLOR_MASK 0x00ffffff +# define R128_CONSTANT_COLOR_ONE 0x00ffffff +# define R128_CONSTANT_COLOR_ZERO 0x00000000 +#define R128_CRC_CMDFIFO_ADDR 0x0740 +#define R128_CRC_CMDFIFO_DOUT 0x0744 +#define R128_CRTC_CRNT_FRAME 0x0214 +#define R128_CRTC_DEBUG 0x021c +#define R128_CRTC_EXT_CNTL 0x0054 +# define R128_CRTC_VGA_XOVERSCAN (1 << 0) +# define R128_VGA_ATI_LINEAR (1 << 3) +# define R128_XCRT_CNT_EN (1 << 6) +# define R128_CRTC_HSYNC_DIS (1 << 8) +# define R128_CRTC_VSYNC_DIS (1 << 9) +# define R128_CRTC_DISPLAY_DIS (1 << 10) +# define R128_CRTC_CRT_ON (1 << 15) +#define R128_CRTC_EXT_CNTL_DPMS_BYTE 0x0055 +# define R128_CRTC_HSYNC_DIS_BYTE (1 << 0) +# define R128_CRTC_VSYNC_DIS_BYTE (1 << 1) +# define R128_CRTC_DISPLAY_DIS_BYTE (1 << 2) +#define R128_CRTC_GEN_CNTL 0x0050 +# define R128_CRTC_DBL_SCAN_EN (1 << 0) +# define R128_CRTC_INTERLACE_EN (1 << 1) +# define R128_CRTC_CSYNC_EN (1 << 4) +# define R128_CRTC_CUR_EN (1 << 16) +# define R128_CRTC_CUR_MODE_MASK (7 << 17) +# define R128_CRTC_ICON_EN (1 << 20) +# define R128_CRTC_EXT_DISP_EN (1 << 24) +# define R128_CRTC_EN (1 << 25) +# define R128_CRTC_DISP_REQ_EN_B (1 << 26) +#define R128_CRTC_GUI_TRIG_VLINE 0x0218 +#define R128_CRTC_H_SYNC_STRT_WID 0x0204 +# define R128_CRTC_H_SYNC_STRT_PIX (0x07 << 0) +# define R128_CRTC_H_SYNC_STRT_CHAR (0x1ff << 3) +# define R128_CRTC_H_SYNC_STRT_CHAR_SHIFT 3 +# define R128_CRTC_H_SYNC_WID (0x3f << 16) +# define R128_CRTC_H_SYNC_WID_SHIFT 16 +# define R128_CRTC_H_SYNC_POL (1 << 23) +#define R128_CRTC_H_TOTAL_DISP 0x0200 +# define R128_CRTC_H_TOTAL (0x01ff << 0) +# define R128_CRTC_H_TOTAL_SHIFT 0 +# define R128_CRTC_H_DISP (0x00ff << 16) +# define R128_CRTC_H_DISP_SHIFT 16 +#define R128_CRTC_OFFSET 0x0224 +#define R128_CRTC_OFFSET_CNTL 0x0228 +#define R128_CRTC_PITCH 0x022c +#define R128_CRTC_STATUS 0x005c +# define R128_CRTC_VBLANK_SAVE (1 << 1) +#define R128_CRTC_V_SYNC_STRT_WID 0x020c +# define R128_CRTC_V_SYNC_STRT (0x7ff << 0) +# define R128_CRTC_V_SYNC_STRT_SHIFT 0 +# define R128_CRTC_V_SYNC_WID (0x1f << 16) +# define R128_CRTC_V_SYNC_WID_SHIFT 16 +# define R128_CRTC_V_SYNC_POL (1 << 23) +#define R128_CRTC_V_TOTAL_DISP 0x0208 +# define R128_CRTC_V_TOTAL (0x07ff << 0) +# define R128_CRTC_V_TOTAL_SHIFT 0 +# define R128_CRTC_V_DISP (0x07ff << 16) +# define R128_CRTC_V_DISP_SHIFT 16 +#define R128_CRTC_VLINE_CRNT_VLINE 0x0210 +# define R128_CRTC_CRNT_VLINE_MASK (0x7ff << 16) +#define R128_CRTC2_CRNT_FRAME 0x0314 +#define R128_CRTC2_DEBUG 0x031c +#define R128_CRTC2_GEN_CNTL 0x03f8 +#define R128_CRTC2_GUI_TRIG_VLINE 0x0318 +#define R128_CRTC2_H_SYNC_STRT_WID 0x0304 +#define R128_CRTC2_H_TOTAL_DISP 0x0300 +#define R128_CRTC2_OFFSET 0x0324 +#define R128_CRTC2_OFFSET_CNTL 0x0328 +#define R128_CRTC2_PITCH 0x032c +#define R128_CRTC2_STATUS 0x03fc +#define R128_CRTC2_V_SYNC_STRT_WID 0x030c +#define R128_CRTC2_V_TOTAL_DISP 0x0308 +#define R128_CRTC2_VLINE_CRNT_VLINE 0x0310 +#define R128_CRTC8_DATA 0x03d5 /* VGA, 0x3b5 */ +#define R128_CRTC8_IDX 0x03d4 /* VGA, 0x3b4 */ +#define R128_CUR_CLR0 0x026c +#define R128_CUR_CLR1 0x0270 +#define R128_CUR_HORZ_VERT_OFF 0x0268 +#define R128_CUR_HORZ_VERT_POSN 0x0264 +#define R128_CUR_OFFSET 0x0260 +# define R128_CUR_LOCK (1 << 31) + +#define R128_DAC_CNTL 0x0058 +# define R128_DAC_RANGE_CNTL (3 << 0) +# define R128_DAC_BLANKING (1 << 2) +# define R128_DAC_CRT_SEL_CRTC2 (1 << 4) +# define R128_DAC_PALETTE_ACC_CTL (1 << 5) +# define R128_DAC_8BIT_EN (1 << 8) +# define R128_DAC_VGA_ADR_EN (1 << 13) +# define R128_DAC_MASK_ALL (0xff << 24) +#define R128_DAC_CRC_SIG 0x02cc +#define R128_DAC_DATA 0x03c9 /* VGA */ +#define R128_DAC_MASK 0x03c6 /* VGA */ +#define R128_DAC_R_INDEX 0x03c7 /* VGA */ +#define R128_DAC_W_INDEX 0x03c8 /* VGA */ +#define R128_DDA_CONFIG 0x02e0 +#define R128_DDA_ON_OFF 0x02e4 +#define R128_DEFAULT_OFFSET 0x16e0 +#define R128_DEFAULT_PITCH 0x16e4 +#define R128_DEFAULT_SC_BOTTOM_RIGHT 0x16e8 +# define R128_DEFAULT_SC_RIGHT_MAX (0x1fff << 0) +# define R128_DEFAULT_SC_BOTTOM_MAX (0x1fff << 16) +#define R128_DESTINATION_3D_CLR_CMP_VAL 0x1820 +#define R128_DESTINATION_3D_CLR_CMP_MSK 0x1824 +#define R128_DEVICE_ID 0x0f02 /* PCI */ +#define R128_DP_BRUSH_BKGD_CLR 0x1478 +#define R128_DP_BRUSH_FRGD_CLR 0x147c +#define R128_DP_CNTL 0x16c0 +# define R128_DST_X_LEFT_TO_RIGHT (1 << 0) +# define R128_DST_Y_TOP_TO_BOTTOM (1 << 1) +#define R128_DP_CNTL_XDIR_YDIR_YMAJOR 0x16d0 +# define R128_DST_Y_MAJOR (1 << 2) +# define R128_DST_Y_DIR_TOP_TO_BOTTOM (1 << 15) +# define R128_DST_X_DIR_LEFT_TO_RIGHT (1 << 31) +#define R128_DP_DATATYPE 0x16c4 +# define R128_HOST_BIG_ENDIAN_EN (1 << 29) +#define R128_DP_GUI_MASTER_CNTL 0x146c +# define R128_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0) +# define R128_GMC_DST_PITCH_OFFSET_CNTL (1 << 1) +# define R128_GMC_SRC_CLIPPING (1 << 2) +# define R128_GMC_DST_CLIPPING (1 << 3) +# define R128_GMC_BRUSH_DATATYPE_MASK (0x0f << 4) +# define R128_GMC_BRUSH_8X8_MONO_FG_BG (0 << 4) +# define R128_GMC_BRUSH_8X8_MONO_FG_LA (1 << 4) +# define R128_GMC_BRUSH_1X8_MONO_FG_BG (4 << 4) +# define R128_GMC_BRUSH_1X8_MONO_FG_LA (5 << 4) +# define R128_GMC_BRUSH_32x1_MONO_FG_BG (6 << 4) +# define R128_GMC_BRUSH_32x1_MONO_FG_LA (7 << 4) +# define R128_GMC_BRUSH_8x8_COLOR (10 << 4) +# define R128_GMC_BRUSH_1X8_COLOR (12 << 4) +# define R128_GMC_BRUSH_SOLID_COLOR (13 << 4) +# define R128_GMC_BRUSH_NONE (15 << 4) +# define R128_GMC_DST_8BPP_CI (2 << 8) +# define R128_GMC_DST_15BPP (3 << 8) +# define R128_GMC_DST_16BPP (4 << 8) +# define R128_GMC_DST_24BPP (5 << 8) +# define R128_GMC_DST_32BPP (6 << 8) +# define R128_GMC_DST_8BPP_RGB (7 << 8) +# define R128_GMC_DST_Y8 (8 << 8) +# define R128_GMC_DST_RGB8 (9 << 8) +# define R128_GMC_DST_VYUY (11 << 8) +# define R128_GMC_DST_YVYU (12 << 8) +# define R128_GMC_DST_AYUV444 (14 << 8) +# define R128_GMC_DST_ARGB4444 (15 << 8) +# define R128_GMC_DST_DATATYPE_MASK (0x0f << 8) +# define R128_GMC_DST_DATATYPE_SHIFT 8 +# define R128_GMC_SRC_DATATYPE_MASK (3 << 12) +# define R128_GMC_SRC_DATATYPE_MONO_FG_BG (0 << 12) +# define R128_GMC_SRC_DATATYPE_MONO_FG_LA (1 << 12) +# define R128_GMC_SRC_DATATYPE_COLOR (3 << 12) +# define R128_GMC_BYTE_PIX_ORDER (1 << 14) +# define R128_GMC_BYTE_MSB_TO_LSB (0 << 14) +# define R128_GMC_BYTE_LSB_TO_MSB (1 << 14) +# define R128_GMC_CONVERSION_TEMP (1 << 15) +# define R128_GMC_CONVERSION_TEMP_6500 (0 << 15) +# define R128_GMC_CONVERSION_TEMP_9300 (1 << 15) +# define R128_GMC_ROP3_MASK (0xff << 16) +# define R128_DP_SRC_SOURCE_MASK (7 << 24) +# define R128_DP_SRC_SOURCE_MEMORY (2 << 24) +# define R128_DP_SRC_SOURCE_HOST_DATA (3 << 24) +# define R128_GMC_3D_FCN_EN (1 << 27) +# define R128_GMC_CLR_CMP_CNTL_DIS (1 << 28) +# define R128_GMC_AUX_CLIP_DIS (1 << 29) +# define R128_GMC_WR_MSK_DIS (1 << 30) +# define R128_GMC_LD_BRUSH_Y_X (1 << 31) +# define R128_ROP3_ZERO 0x00000000 +# define R128_ROP3_DSa 0x00880000 +# define R128_ROP3_SDna 0x00440000 +# define R128_ROP3_S 0x00cc0000 +# define R128_ROP3_DSna 0x00220000 +# define R128_ROP3_D 0x00aa0000 +# define R128_ROP3_DSx 0x00660000 +# define R128_ROP3_DSo 0x00ee0000 +# define R128_ROP3_DSon 0x00110000 +# define R128_ROP3_DSxn 0x00990000 +# define R128_ROP3_Dn 0x00550000 +# define R128_ROP3_SDno 0x00dd0000 +# define R128_ROP3_Sn 0x00330000 +# define R128_ROP3_DSno 0x00bb0000 +# define R128_ROP3_DSan 0x00770000 +# define R128_ROP3_ONE 0x00ff0000 +# define R128_ROP3_DPa 0x00a00000 +# define R128_ROP3_PDna 0x00500000 +# define R128_ROP3_P 0x00f00000 +# define R128_ROP3_DPna 0x000a0000 +# define R128_ROP3_D 0x00aa0000 +# define R128_ROP3_DPx 0x005a0000 +# define R128_ROP3_DPo 0x00fa0000 +# define R128_ROP3_DPon 0x00050000 +# define R128_ROP3_PDxn 0x00a50000 +# define R128_ROP3_PDno 0x00f50000 +# define R128_ROP3_Pn 0x000f0000 +# define R128_ROP3_DPno 0x00af0000 +# define R128_ROP3_DPan 0x005f0000 + + +#define R128_DP_GUI_MASTER_CNTL_C 0x1c84 +#define R128_DP_MIX 0x16c8 +#define R128_DP_SRC_BKGD_CLR 0x15dc +#define R128_DP_SRC_FRGD_CLR 0x15d8 +#define R128_DP_WRITE_MASK 0x16cc +#define R128_DST_BRES_DEC 0x1630 +#define R128_DST_BRES_ERR 0x1628 +#define R128_DST_BRES_INC 0x162c +#define R128_DST_BRES_LNTH 0x1634 +#define R128_DST_BRES_LNTH_SUB 0x1638 +#define R128_DST_HEIGHT 0x1410 +#define R128_DST_HEIGHT_WIDTH 0x143c +#define R128_DST_HEIGHT_WIDTH_8 0x158c +#define R128_DST_HEIGHT_WIDTH_BW 0x15b4 +#define R128_DST_HEIGHT_Y 0x15a0 +#define R128_DST_OFFSET 0x1404 +#define R128_DST_PITCH 0x1408 +#define R128_DST_PITCH_OFFSET 0x142c +#define R128_DST_PITCH_OFFSET_C 0x1c80 +# define R128_PITCH_SHIFT 21 +#define R128_DST_WIDTH 0x140c +#define R128_DST_WIDTH_HEIGHT 0x1598 +#define R128_DST_WIDTH_X 0x1588 +#define R128_DST_WIDTH_X_INCY 0x159c +#define R128_DST_X 0x141c +#define R128_DST_X_SUB 0x15a4 +#define R128_DST_X_Y 0x1594 +#define R128_DST_Y 0x1420 +#define R128_DST_Y_SUB 0x15a8 +#define R128_DST_Y_X 0x1438 + +#define R128_EXT_MEM_CNTL 0x0144 + +#define R128_FCP_CNTL 0x0012 /* PLL */ +#define R128_FLUSH_1 0x1704 +#define R128_FLUSH_2 0x1708 +#define R128_FLUSH_3 0x170c +#define R128_FLUSH_4 0x1710 +#define R128_FLUSH_5 0x1714 +#define R128_FLUSH_6 0x1718 +#define R128_FLUSH_7 0x171c +#define R128_FOG_3D_TABLE_START 0x1810 +#define R128_FOG_3D_TABLE_END 0x1814 +#define R128_FOG_3D_TABLE_DENSITY 0x181c +#define R128_FOG_TABLE_INDEX 0x1a14 +#define R128_FOG_TABLE_DATA 0x1a18 +#define R128_FP_CRTC_H_TOTAL_DISP 0x0250 +#define R128_FP_CRTC_V_TOTAL_DISP 0x0254 +#define R128_FP_GEN_CNTL 0x0284 +# define R128_FP_FPON (1 << 0) +# define R128_FP_TDMS_EN (1 << 2) +# define R128_FP_DETECT_SENSE (1 << 8) +# define R128_FP_SEL_CRTC2 (1 << 13) +# define R128_FP_CRTC_DONT_SHADOW_VPAR (1 << 16) +# define R128_FP_CRTC_USE_SHADOW_VEND (1 << 18) +# define R128_FP_CRTC_HORZ_DIV2_EN (1 << 20) +# define R128_FP_CRTC_HOR_CRT_DIV2_DIS (1 << 21) +# define R128_FP_USE_SHADOW_EN (1 << 24) +#define R128_FP_H_SYNC_STRT_WID 0x02c4 +#define R128_FP_HORZ_STRETCH 0x028c +# define R128_HORZ_STRETCH_RATIO_MASK 0xffff +# define R128_HORZ_STRETCH_RATIO_SHIFT 0 +# define R128_HORZ_STRETCH_RATIO_MAX 4096 +# define R128_HORZ_PANEL_SIZE (0xff << 16) +# define R128_HORZ_PANEL_SHIFT 16 +# define R128_HORZ_STRETCH_PIXREP (0 << 25) +# define R128_HORZ_STRETCH_BLEND (1 << 25) +# define R128_HORZ_STRETCH_ENABLE (1 << 26) +# define R128_HORZ_FP_LOOP_STRETCH (0x7 << 27) +# define R128_HORZ_STRETCH_RESERVED (1 << 30) +# define R128_HORZ_AUTO_RATIO_FIX_EN (1 << 31) + +#define R128_FP_PANEL_CNTL 0x0288 +# define R128_FP_DIGON (1 << 0) +# define R128_FP_BLON (1 << 1) +#define R128_FP_V_SYNC_STRT_WID 0x02c8 +#define R128_FP_VERT_STRETCH 0x0290 +# define R128_VERT_PANEL_SIZE (0x7ff << 0) +# define R128_VERT_PANEL_SHIFT 0 +# define R128_VERT_STRETCH_RATIO_MASK 0x3ff +# define R128_VERT_STRETCH_RATIO_SHIFT 11 +# define R128_VERT_STRETCH_RATIO_MAX 1024 +# define R128_VERT_STRETCH_ENABLE (1 << 24) +# define R128_VERT_STRETCH_LINEREP (0 << 25) +# define R128_VERT_STRETCH_BLEND (1 << 25) +# define R128_VERT_AUTO_RATIO_EN (1 << 26) +# define R128_VERT_STRETCH_RESERVED 0xf8e00000 + +#define R128_GEN_INT_CNTL 0x0040 +#define R128_GEN_INT_STATUS 0x0044 +# define R128_VSYNC_INT_AK (1 << 2) +# define R128_VSYNC_INT (1 << 2) +#define R128_GEN_RESET_CNTL 0x00f0 +# define R128_SOFT_RESET_GUI (1 << 0) +# define R128_SOFT_RESET_VCLK (1 << 8) +# define R128_SOFT_RESET_PCLK (1 << 9) +# define R128_SOFT_RESET_DISPENG_XCLK (1 << 11) +# define R128_SOFT_RESET_MEMCTLR_XCLK (1 << 12) +#define R128_GENENB 0x03c3 /* VGA */ +#define R128_GENFC_RD 0x03ca /* VGA */ +#define R128_GENFC_WT 0x03da /* VGA, 0x03ba */ +#define R128_GENMO_RD 0x03cc /* VGA */ +#define R128_GENMO_WT 0x03c2 /* VGA */ +#define R128_GENS0 0x03c2 /* VGA */ +#define R128_GENS1 0x03da /* VGA, 0x03ba */ +#define R128_GPIO_MONID 0x0068 +# define R128_GPIO_MONID_A_0 (1 << 0) +# define R128_GPIO_MONID_A_1 (1 << 1) +# define R128_GPIO_MONID_A_2 (1 << 2) +# define R128_GPIO_MONID_A_3 (1 << 3) +# define R128_GPIO_MONID_Y_0 (1 << 8) +# define R128_GPIO_MONID_Y_1 (1 << 9) +# define R128_GPIO_MONID_Y_2 (1 << 10) +# define R128_GPIO_MONID_Y_3 (1 << 11) +# define R128_GPIO_MONID_EN_0 (1 << 16) +# define R128_GPIO_MONID_EN_1 (1 << 17) +# define R128_GPIO_MONID_EN_2 (1 << 18) +# define R128_GPIO_MONID_EN_3 (1 << 19) +# define R128_GPIO_MONID_MASK_0 (1 << 24) +# define R128_GPIO_MONID_MASK_1 (1 << 25) +# define R128_GPIO_MONID_MASK_2 (1 << 26) +# define R128_GPIO_MONID_MASK_3 (1 << 27) +#define R128_GPIO_MONIDB 0x006c +#define R128_GRPH8_DATA 0x03cf /* VGA */ +#define R128_GRPH8_IDX 0x03ce /* VGA */ +#define R128_GUI_DEBUG0 0x16a0 +#define R128_GUI_DEBUG1 0x16a4 +#define R128_GUI_DEBUG2 0x16a8 +#define R128_GUI_DEBUG3 0x16ac +#define R128_GUI_DEBUG4 0x16b0 +#define R128_GUI_DEBUG5 0x16b4 +#define R128_GUI_DEBUG6 0x16b8 +#define R128_GUI_PROBE 0x16bc +#define R128_GUI_SCRATCH_REG0 0x15e0 +#define R128_GUI_SCRATCH_REG1 0x15e4 +#define R128_GUI_SCRATCH_REG2 0x15e8 +#define R128_GUI_SCRATCH_REG3 0x15ec +#define R128_GUI_SCRATCH_REG4 0x15f0 +#define R128_GUI_SCRATCH_REG5 0x15f4 +#define R128_GUI_STAT 0x1740 +# define R128_GUI_FIFOCNT_MASK 0x0fff +# define R128_GUI_ACTIVE (1 << 31) + +#define R128_HEADER 0x0f0e /* PCI */ +#define R128_HOST_DATA0 0x17c0 +#define R128_HOST_DATA1 0x17c4 +#define R128_HOST_DATA2 0x17c8 +#define R128_HOST_DATA3 0x17cc +#define R128_HOST_DATA4 0x17d0 +#define R128_HOST_DATA5 0x17d4 +#define R128_HOST_DATA6 0x17d8 +#define R128_HOST_DATA7 0x17dc +#define R128_HOST_DATA_LAST 0x17e0 +#define R128_HOST_PATH_CNTL 0x0130 +#define R128_HTOTAL_CNTL 0x0009 /* PLL */ +#define R128_HW_DEBUG 0x0128 +#define R128_HW_DEBUG2 0x011c + +#define R128_I2C_CNTL_1 0x0094 /* ? */ +#define R128_INTERRUPT_LINE 0x0f3c /* PCI */ +#define R128_INTERRUPT_PIN 0x0f3d /* PCI */ +#define R128_IO_BASE 0x0f14 /* PCI */ + +#define R128_LATENCY 0x0f0d /* PCI */ +#define R128_LEAD_BRES_DEC 0x1608 +#define R128_LEAD_BRES_ERR 0x1600 +#define R128_LEAD_BRES_INC 0x1604 +#define R128_LEAD_BRES_LNTH 0x161c +#define R128_LEAD_BRES_LNTH_SUB 0x1624 +#define R128_LVDS_GEN_CNTL 0x02d0 +# define R128_LVDS_ON (1 << 0) +# define R128_LVDS_BLON (1 << 19) +# define R128_LVDS_SEL_CRTC2 (1 << 23) +# define R128_HSYNC_DELAY_SHIFT 28 +# define R128_HSYNC_DELAY_MASK (0xf << 28) + +#define R128_MAX_LATENCY 0x0f3f /* PCI */ +#define R128_MCLK_CNTL 0x000f /* PLL */ +# define R128_FORCE_GCP (1 << 16) +# define R128_FORCE_PIPE3D_CP (1 << 17) +# define R128_FORCE_RCP (1 << 18) +#define R128_MDGPIO_A_REG 0x01ac +#define R128_MDGPIO_EN_REG 0x01b0 +#define R128_MDGPIO_MASK 0x0198 +#define R128_MDGPIO_Y_REG 0x01b4 +#define R128_MEM_ADDR_CONFIG 0x0148 +#define R128_MEM_BASE 0x0f10 /* PCI */ +#define R128_MEM_CNTL 0x0140 +#define R128_MEM_INIT_LAT_TIMER 0x0154 +#define R128_MEM_INTF_CNTL 0x014c +#define R128_MEM_SDRAM_MODE_REG 0x0158 +#define R128_MEM_STR_CNTL 0x0150 +#define R128_MEM_VGA_RP_SEL 0x003c +#define R128_MEM_VGA_WP_SEL 0x0038 +#define R128_MIN_GRANT 0x0f3e /* PCI */ +#define R128_MM_DATA 0x0004 +#define R128_MM_INDEX 0x0000 +#define R128_MPLL_CNTL 0x000e /* PLL */ +#define R128_MPP_TB_CONFIG 0x01c0 /* ? */ +#define R128_MPP_GP_CONFIG 0x01c8 /* ? */ + +#define R128_N_VIF_COUNT 0x0248 + +#define R128_OVR_CLR 0x0230 +#define R128_OVR_WID_LEFT_RIGHT 0x0234 +#define R128_OVR_WID_TOP_BOTTOM 0x0238 + +/* first overlay unit (there is only one) */ + +#define R128_OV0_Y_X_START 0x0400 +#define R128_OV0_Y_X_END 0x0404 +#define R128_OV0_EXCLUSIVE_HORZ 0x0408 +# define R128_EXCL_HORZ_START_MASK 0x000000ff +# define R128_EXCL_HORZ_END_MASK 0x0000ff00 +# define R128_EXCL_HORZ_BACK_PORCH_MASK 0x00ff0000 +# define R128_EXCL_HORZ_EXCLUSIVE_EN 0x80000000 +#define R128_OV0_EXCLUSIVE_VERT 0x040C +# define R128_EXCL_VERT_START_MASK 0x000003ff +# define R128_EXCL_VERT_END_MASK 0x03ff0000 +#define R128_OV0_REG_LOAD_CNTL 0x0410 +# define R128_REG_LD_CTL_LOCK 0x00000001L +# define R128_REG_LD_CTL_VBLANK_DURING_LOCK 0x00000002L +# define R128_REG_LD_CTL_STALL_GUI_UNTIL_FLIP 0x00000004L +# define R128_REG_LD_CTL_LOCK_READBACK 0x00000008L +#define R128_OV0_SCALE_CNTL 0x0420 +# define R128_SCALER_PIX_EXPAND 0x00000001L +# define R128_SCALER_Y2R_TEMP 0x00000002L +# define R128_SCALER_HORZ_PICK_NEAREST 0x00000003L +# define R128_SCALER_VERT_PICK_NEAREST 0x00000004L +# define R128_SCALER_SIGNED_UV 0x00000010L +# define R128_SCALER_GAMMA_SEL_MASK 0x00000060L +# define R128_SCALER_GAMMA_SEL_BRIGHT 0x00000000L +# define R128_SCALER_GAMMA_SEL_G22 0x00000020L +# define R128_SCALER_GAMMA_SEL_G18 0x00000040L +# define R128_SCALER_GAMMA_SEL_G14 0x00000060L +# define R128_SCALER_COMCORE_SHIFT_UP_ONE 0x00000080L +# define R128_SCALER_SURFAC_FORMAT 0x00000f00L +# define R128_SCALER_SOURCE_15BPP 0x00000300L +# define R128_SCALER_SOURCE_16BPP 0x00000400L +# define R128_SCALER_SOURCE_32BPP 0x00000600L +# define R128_SCALER_SOURCE_YUV9 0x00000900L +# define R128_SCALER_SOURCE_YUV12 0x00000A00L +# define R128_SCALER_SOURCE_VYUY422 0x00000B00L +# define R128_SCALER_SOURCE_YVYU422 0x00000C00L +# define R128_SCALER_SMART_SWITCH 0x00008000L +# define R128_SCALER_BURST_PER_PLANE 0x00ff0000L +# define R128_SCALER_DOUBLE_BUFFER 0x01000000L +# define R128_SCALER_DIS_LIMIT 0x08000000L +# define R128_SCALER_PRG_LOAD_START 0x10000000L +# define R128_SCALER_INT_EMU 0x20000000L +# define R128_SCALER_ENABLE 0x40000000L +# define R128_SCALER_SOFT_RESET 0x80000000L +#define R128_OV0_V_INC 0x0424 +#define R128_OV0_P1_V_ACCUM_INIT 0x0428 +# define R128_OV0_P1_MAX_LN_IN_PER_LN_OUT 0x00000003L +# define R128_OV0_P1_V_ACCUM_INIT_MASK 0x01ff8000L +#define R128_OV0_P23_V_ACCUM_INIT 0x042C +#define R128_OV0_P1_BLANK_LINES_AT_TOP 0x0430 +# define R128_P1_BLNK_LN_AT_TOP_M1_MASK 0x00000fffL +# define R128_P1_ACTIVE_LINES_M1 0x0fff0000L +#define R128_OV0_P23_BLANK_LINES_AT_TOP 0x0434 +# define R128_P23_BLNK_LN_AT_TOP_M1_MASK 0x000007ffL +# define R128_P23_ACTIVE_LINES_M1 0x07ff0000L +#define R128_OV0_VID_BUF0_BASE_ADRS 0x0440 +# define R128_VIF_BUF0_PITCH_SEL 0x00000001L +# define R128_VIF_BUF0_TILE_ADRS 0x00000002L +# define R128_VIF_BUF0_BASE_ADRS_MASK 0x03fffff0L +# define R128_VIF_BUF0_1ST_LINE_LSBS_MASK 0x48000000L +#define R128_OV0_VID_BUF1_BASE_ADRS 0x0444 +# define R128_VIF_BUF1_PITCH_SEL 0x00000001L +# define R128_VIF_BUF1_TILE_ADRS 0x00000002L +# define R128_VIF_BUF1_BASE_ADRS_MASK 0x03fffff0L +# define R128_VIF_BUF1_1ST_LINE_LSBS_MASK 0x48000000L +#define R128_OV0_VID_BUF2_BASE_ADRS 0x0448 +# define R128_VIF_BUF2_PITCH_SEL 0x00000001L +# define R128_VIF_BUF2_TILE_ADRS 0x00000002L +# define R128_VIF_BUF2_BASE_ADRS_MASK 0x03fffff0L +# define R128_VIF_BUF2_1ST_LINE_LSBS_MASK 0x48000000L +#define R128_OV0_VID_BUF3_BASE_ADRS 0x044C +#define R128_OV0_VID_BUF4_BASE_ADRS 0x0450 +#define R128_OV0_VID_BUF5_BASE_ADRS 0x0454 +#define R128_OV0_VID_BUF_PITCH0_VALUE 0x0460 +#define R128_OV0_VID_BUF_PITCH1_VALUE 0x0464 +#define R128_OV0_AUTO_FLIP_CNTL 0x0470 +#define R128_OV0_DEINTERLACE_PATTERN 0x0474 +#define R128_OV0_H_INC 0x0480 +#define R128_OV0_STEP_BY 0x0484 +#define R128_OV0_P1_H_ACCUM_INIT 0x0488 +#define R128_OV0_P23_H_ACCUM_INIT 0x048C +#define R128_OV0_P1_X_START_END 0x0494 +#define R128_OV0_P2_X_START_END 0x0498 +#define R128_OV0_P3_X_START_END 0x049C +#define R128_OV0_FILTER_CNTL 0x04A0 +#define R128_OV0_FOUR_TAP_COEF_0 0x04B0 +#define R128_OV0_FOUR_TAP_COEF_1 0x04B4 +#define R128_OV0_FOUR_TAP_COEF_2 0x04B8 +#define R128_OV0_FOUR_TAP_COEF_3 0x04BC +#define R128_OV0_FOUR_TAP_COEF_4 0x04C0 +#define R128_OV0_COLOUR_CNTL 0x04E0 +#define R128_OV0_VIDEO_KEY_CLR 0x04E4 +#define R128_OV0_VIDEO_KEY_MSK 0x04E8 +#define R128_OV0_GRAPHICS_KEY_CLR 0x04EC +#define R128_OV0_GRAPHICS_KEY_MSK 0x04F0 +#define R128_OV0_KEY_CNTL 0x04F4 +# define R128_VIDEO_KEY_FN_MASK 0x00000007L +# define R128_VIDEO_KEY_FN_FALSE 0x00000000L +# define R128_VIDEO_KEY_FN_TRUE 0x00000001L +# define R128_VIDEO_KEY_FN_EQ 0x00000004L +# define R128_VIDEO_KEY_FN_NE 0x00000005L +# define R128_GRAPHIC_KEY_FN_MASK 0x00000070L +# define R128_GRAPHIC_KEY_FN_FALSE 0x00000000L +# define R128_GRAPHIC_KEY_FN_TRUE 0x00000010L +# define R128_GRAPHIC_KEY_FN_EQ 0x00000040L +# define R128_GRAPHIC_KEY_FN_NE 0x00000050L +# define R128_CMP_MIX_MASK 0x00000100L +# define R128_CMP_MIX_OR 0x00000000L +# define R128_CMP_MIX_AND 0x00000100L +#define R128_OV0_TEST 0x04F8 + + +#define R128_PALETTE_DATA 0x00b4 +#define R128_PALETTE_INDEX 0x00b0 +#define R128_PC_DEBUG_MODE 0x1760 +#define R128_PC_GUI_CTLSTAT 0x1748 +#define R128_PC_GUI_MODE 0x1744 +# define R128_PC_IGNORE_UNIFY (1 << 5) +#define R128_PC_MISC_CNTL 0x0188 +#define R128_PC_NGUI_CTLSTAT 0x0184 +# define R128_PC_FLUSH_GUI (3 << 0) +# define R128_PC_RI_GUI (1 << 2) +# define R128_PC_FLUSH_ALL 0x00ff +# define R128_PC_BUSY (1 << 31) +#define R128_PC_NGUI_MODE 0x0180 +#define R128_PCI_GART_PAGE 0x017c +#define R128_PLANE_3D_MASK_C 0x1d44 +#define R128_PLL_TEST_CNTL 0x0013 /* PLL */ +#define R128_PMI_CAP_ID 0x0f5c /* PCI */ +#define R128_PMI_DATA 0x0f63 /* PCI */ +#define R128_PMI_NXT_CAP_PTR 0x0f5d /* PCI */ +#define R128_PMI_PMC_REG 0x0f5e /* PCI */ +#define R128_PMI_PMCSR_REG 0x0f60 /* PCI */ +#define R128_PMI_REGISTER 0x0f5c /* PCI */ +#define R128_PPLL_CNTL 0x0002 /* PLL */ +# define R128_PPLL_RESET (1 << 0) +# define R128_PPLL_SLEEP (1 << 1) +# define R128_PPLL_ATOMIC_UPDATE_EN (1 << 16) +# define R128_PPLL_VGA_ATOMIC_UPDATE_EN (1 << 17) +#define R128_PPLL_DIV_0 0x0004 /* PLL */ +#define R128_PPLL_DIV_1 0x0005 /* PLL */ +#define R128_PPLL_DIV_2 0x0006 /* PLL */ +#define R128_PPLL_DIV_3 0x0007 /* PLL */ +# define R128_PPLL_FB3_DIV_MASK 0x07ff +# define R128_PPLL_POST3_DIV_MASK 0x00070000 +#define R128_PPLL_REF_DIV 0x0003 /* PLL */ +# define R128_PPLL_REF_DIV_MASK 0x03ff +# define R128_PPLL_ATOMIC_UPDATE_R (1 << 15) /* same as _W */ +# define R128_PPLL_ATOMIC_UPDATE_W (1 << 15) /* same as _R */ +#define R128_PWR_MNGMT_CNTL_STATUS 0x0f60 /* PCI */ +#define R128_REG_BASE 0x0f18 /* PCI */ +#define R128_REGPROG_INF 0x0f09 /* PCI */ +#define R128_REVISION_ID 0x0f08 /* PCI */ + +#define R128_SC_BOTTOM 0x164c +#define R128_SC_BOTTOM_RIGHT 0x16f0 +#define R128_SC_BOTTOM_RIGHT_C 0x1c8c +#define R128_SC_LEFT 0x1640 +#define R128_SC_RIGHT 0x1644 +#define R128_SC_TOP 0x1648 +#define R128_SC_TOP_LEFT 0x16ec +#define R128_SC_TOP_LEFT_C 0x1c88 +#define R128_SEQ8_DATA 0x03c5 /* VGA */ +#define R128_SEQ8_IDX 0x03c4 /* VGA */ +#define R128_SNAPSHOT_F_COUNT 0x0244 +#define R128_SNAPSHOT_VH_COUNTS 0x0240 +#define R128_SNAPSHOT_VIF_COUNT 0x024c +#define R128_SRC_OFFSET 0x15ac +#define R128_SRC_PITCH 0x15b0 +#define R128_SRC_PITCH_OFFSET 0x1428 +#define R128_SRC_SC_BOTTOM 0x165c +#define R128_SRC_SC_BOTTOM_RIGHT 0x16f4 +#define R128_SRC_SC_RIGHT 0x1654 +#define R128_SRC_X 0x1414 +#define R128_SRC_X_Y 0x1590 +#define R128_SRC_Y 0x1418 +#define R128_SRC_Y_X 0x1434 +#define R128_STATUS 0x0f06 /* PCI */ +#define R128_SUBPIC_CNTL 0x0540 /* ? */ +#define R128_SUB_CLASS 0x0f0a /* PCI */ +#define R128_SURFACE_DELAY 0x0b00 +#define R128_SURFACE0_INFO 0x0b0c +#define R128_SURFACE0_LOWER_BOUND 0x0b04 +#define R128_SURFACE0_UPPER_BOUND 0x0b08 +#define R128_SURFACE1_INFO 0x0b1c +#define R128_SURFACE1_LOWER_BOUND 0x0b14 +#define R128_SURFACE1_UPPER_BOUND 0x0b18 +#define R128_SURFACE2_INFO 0x0b2c +#define R128_SURFACE2_LOWER_BOUND 0x0b24 +#define R128_SURFACE2_UPPER_BOUND 0x0b28 +#define R128_SURFACE3_INFO 0x0b3c +#define R128_SURFACE3_LOWER_BOUND 0x0b34 +#define R128_SURFACE3_UPPER_BOUND 0x0b38 +#define R128_SW_SEMAPHORE 0x013c + +#define R128_TEST_DEBUG_CNTL 0x0120 +#define R128_TEST_DEBUG_MUX 0x0124 +#define R128_TEST_DEBUG_OUT 0x012c +#define R128_TMDS_CRC 0x02a0 +#define R128_TRAIL_BRES_DEC 0x1614 +#define R128_TRAIL_BRES_ERR 0x160c +#define R128_TRAIL_BRES_INC 0x1610 +#define R128_TRAIL_X 0x1618 +#define R128_TRAIL_X_SUB 0x1620 + +#define R128_VCLK_ECP_CNTL 0x0008 /* PLL */ +#define R128_VENDOR_ID 0x0f00 /* PCI */ +#define R128_VGA_DDA_CONFIG 0x02e8 +#define R128_VGA_DDA_ON_OFF 0x02ec +#define R128_VID_BUFFER_CONTROL 0x0900 +#define R128_VIDEOMUX_CNTL 0x0190 +#define R128_VIPH_CONTROL 0x01D0 /* ? */ + +#define R128_WAIT_UNTIL 0x1720 + +#define R128_X_MPLL_REF_FB_DIV 0x000a /* PLL */ +#define R128_XCLK_CNTL 0x000d /* PLL */ +#define R128_XDLL_CNTL 0x000c /* PLL */ +#define R128_XPLL_CNTL 0x000b /* PLL */ + + /* Registers for CCE and Microcode Engine */ +#define R128_PM4_MICROCODE_ADDR 0x07d4 +#define R128_PM4_MICROCODE_RADDR 0x07d8 +#define R128_PM4_MICROCODE_DATAH 0x07dc +#define R128_PM4_MICROCODE_DATAL 0x07e0 + +#define R128_PM4_BUFFER_OFFSET 0x0700 +#define R128_PM4_BUFFER_CNTL 0x0704 +# define R128_PM4_NONPM4 (0 << 28) +# define R128_PM4_192PIO (1 << 28) +# define R128_PM4_192BM (2 << 28) +# define R128_PM4_128PIO_64INDBM (3 << 28) +# define R128_PM4_128BM_64INDBM (4 << 28) +# define R128_PM4_64PIO_128INDBM (5 << 28) +# define R128_PM4_64BM_128INDBM (6 << 28) +# define R128_PM4_64PIO_64VCBM_64INDBM (7 << 28) +# define R128_PM4_64BM_64VCBM_64INDBM (8 << 28) +# define R128_PM4_64PIO_64VCPIO_64INDPIO (15 << 28) +#define R128_PM4_BUFFER_WM_CNTL 0x0708 +# define R128_WMA_SHIFT 0 +# define R128_WMB_SHIFT 8 +# define R128_WMC_SHIFT 16 +# define R128_WB_WM_SHIFT 24 +#define R128_PM4_BUFFER_DL_RPTR_ADDR 0x070c +#define R128_PM4_BUFFER_DL_RPTR 0x0710 +#define R128_PM4_BUFFER_DL_WPTR 0x0714 +# define R128_PM4_BUFFER_DL_DONE (1 << 31) +#define R128_PM4_BUFFER_DL_WPTR_DELAY 0x0718 +# define R128_PRE_WRITE_TIMER_SHIFT 0 +# define R128_PRE_WRITE_LIMIT_SHIFT 23 +#define R128_PM4_VC_FPU_SETUP 0x071c +# define R128_FRONT_DIR_CW (0 << 0) +# define R128_FRONT_DIR_CCW (1 << 0) +# define R128_FRONT_DIR_MASK (1 << 0) +# define R128_BACKFACE_CULL (0 << 1) +# define R128_BACKFACE_POINTS (1 << 1) +# define R128_BACKFACE_LINES (2 << 1) +# define R128_BACKFACE_SOLID (3 << 1) +# define R128_BACKFACE_MASK (3 << 1) +# define R128_FRONTFACE_CULL (0 << 3) +# define R128_FRONTFACE_POINTS (1 << 3) +# define R128_FRONTFACE_LINES (2 << 3) +# define R128_FRONTFACE_SOLID (3 << 3) +# define R128_FRONTFACE_MASK (3 << 3) +# define R128_FPU_COLOR_SOLID (0 << 5) +# define R128_FPU_COLOR_FLAT (1 << 5) +# define R128_FPU_COLOR_GOURAUD (2 << 5) +# define R128_FPU_COLOR_GOURAUD2 (3 << 5) +# define R128_FPU_COLOR_MASK (3 << 5) +# define R128_FPU_SUB_PIX_2BITS (0 << 7) +# define R128_FPU_SUB_PIX_4BITS (1 << 7) +# define R128_FPU_MODE_2D (0 << 8) +# define R128_FPU_MODE_3D (1 << 8) +# define R128_TRAP_BITS_DISABLE (1 << 9) +# define R128_EDGE_ANTIALIAS (1 << 10) +# define R128_SUPERSAMPLE (1 << 11) +# define R128_XFACTOR_2 (0 << 12) +# define R128_XFACTOR_4 (1 << 12) +# define R128_YFACTOR_2 (0 << 13) +# define R128_YFACTOR_4 (1 << 13) +# define R128_FLAT_SHADE_VERTEX_D3D (0 << 14) +# define R128_FLAT_SHADE_VERTEX_OGL (1 << 14) +# define R128_FPU_ROUND_TRUNCATE (0 << 15) +# define R128_FPU_ROUND_NEAREST (1 << 15) +# define R128_WM_SEL_8DW (0 << 16) +# define R128_WM_SEL_16DW (1 << 16) +# define R128_WM_SEL_32DW (2 << 16) +#define R128_PM4_VC_DEBUG_CONFIG 0x07a4 +#define R128_PM4_VC_STAT 0x07a8 +#define R128_PM4_VC_TIMESTAMP0 0x07b0 +#define R128_PM4_VC_TIMESTAMP1 0x07b4 +#define R128_PM4_STAT 0x07b8 +# define R128_PM4_FIFOCNT_MASK 0x0fff +# define R128_PM4_BUSY (1 << 16) +# define R128_PM4_GUI_ACTIVE (1 << 31) +#define R128_PM4_BUFFER_ADDR 0x07f0 +#define R128_PM4_MICRO_CNTL 0x07fc +# define R128_PM4_MICRO_FREERUN (1 << 30) +#define R128_PM4_FIFO_DATA_EVEN 0x1000 +#define R128_PM4_FIFO_DATA_ODD 0x1004 + +#define R128_SCALE_3D_CNTL 0x1a00 +# define R128_SCALE_DITHER_ERR_DIFF (0 << 1) +# define R128_SCALE_DITHER_TABLE (1 << 1) +# define R128_TEX_CACHE_SIZE_FULL (0 << 2) +# define R128_TEX_CACHE_SIZE_HALF (1 << 2) +# define R128_DITHER_INIT_CURR (0 << 3) +# define R128_DITHER_INIT_RESET (1 << 3) +# define R128_ROUND_24BIT (1 << 4) +# define R128_TEX_CACHE_DISABLE (1 << 5) +# define R128_SCALE_3D_NOOP (0 << 6) +# define R128_SCALE_3D_SCALE (1 << 6) +# define R128_SCALE_3D_TEXMAP_SHADE (2 << 6) +# define R128_SCALE_PIX_BLEND (0 << 8) +# define R128_SCALE_PIX_REPLICATE (1 << 8) +# define R128_TEX_CACHE_SPLIT (1 << 9) +# define R128_APPLE_YUV_MODE (1 << 10) +# define R128_TEX_CACHE_PALLETE_MODE (1 << 11) +# define R128_ALPHA_COMB_ADD_CLAMP (0 << 12) +# define R128_ALPHA_COMB_ADD_NCLAMP (1 << 12) +# define R128_ALPHA_COMB_SUB_DST_SRC_CLAMP (2 << 12) +# define R128_ALPHA_COMB_SUB_DST_SRC_NCLAMP (3 << 12) +# define R128_FOG_TABLE (1 << 14) +# define R128_SIGNED_DST_CLAMP (1 << 15) +# define R128_ALPHA_BLEND_SRC_ZERO (0 << 16) +# define R128_ALPHA_BLEND_SRC_ONE (1 << 16) +# define R128_ALPHA_BLEND_SRC_SRCCOLOR (2 << 16) +# define R128_ALPHA_BLEND_SRC_INVSRCCOLOR (3 << 16) +# define R128_ALPHA_BLEND_SRC_SRCALPHA (4 << 16) +# define R128_ALPHA_BLEND_SRC_INVSRCALPHA (5 << 16) +# define R128_ALPHA_BLEND_SRC_DSTALPHA (6 << 16) +# define R128_ALPHA_BLEND_SRC_INVDSTALPHA (7 << 16) +# define R128_ALPHA_BLEND_SRC_DSTCOLOR (8 << 16) +# define R128_ALPHA_BLEND_SRC_INVDSTCOLOR (9 << 16) +# define R128_ALPHA_BLEND_SRC_SAT (10 << 16) +# define R128_ALPHA_BLEND_SRC_BLEND (11 << 16) +# define R128_ALPHA_BLEND_SRC_INVBLEND (12 << 16) +# define R128_ALPHA_BLEND_DST_ZERO (0 << 20) +# define R128_ALPHA_BLEND_DST_ONE (1 << 20) +# define R128_ALPHA_BLEND_DST_SRCCOLOR (2 << 20) +# define R128_ALPHA_BLEND_DST_INVSRCCOLOR (3 << 20) +# define R128_ALPHA_BLEND_DST_SRCALPHA (4 << 20) +# define R128_ALPHA_BLEND_DST_INVSRCALPHA (5 << 20) +# define R128_ALPHA_BLEND_DST_DSTALPHA (6 << 20) +# define R128_ALPHA_BLEND_DST_INVDSTALPHA (7 << 20) +# define R128_ALPHA_BLEND_DST_DSTCOLOR (8 << 20) +# define R128_ALPHA_BLEND_DST_INVDSTCOLOR (9 << 20) +# define R128_ALPHA_TEST_NEVER (0 << 24) +# define R128_ALPHA_TEST_LESS (1 << 24) +# define R128_ALPHA_TEST_LESSEQUAL (2 << 24) +# define R128_ALPHA_TEST_EQUAL (3 << 24) +# define R128_ALPHA_TEST_GREATEREQUAL (4 << 24) +# define R128_ALPHA_TEST_GREATER (5 << 24) +# define R128_ALPHA_TEST_NEQUAL (6 << 24) +# define R128_ALPHA_TEST_ALWAYS (7 << 24) +# define R128_COMPOSITE_SHADOW_CMP_EQUAL (0 << 28) +# define R128_COMPOSITE_SHADOW_CMP_NEQUAL (1 << 28) +# define R128_COMPOSITE_SHADOW (1 << 29) +# define R128_TEX_MAP_ALPHA_IN_TEXTURE (1 << 30) +# define R128_TEX_CACHE_LINE_SIZE_8QW (0 << 31) +# define R128_TEX_CACHE_LINE_SIZE_4QW (1 << 31) +#define R128_SCALE_3D_DATATYPE 0x1a20 + +#define R128_SETUP_CNTL 0x1bc4 +# define R128_DONT_START_TRIANGLE (1 << 0) +# define R128_Z_BIAS (0 << 1) +# define R128_DONT_START_ANY_ON (1 << 2) +# define R128_COLOR_SOLID_COLOR (0 << 3) +# define R128_COLOR_FLAT_VERT_1 (1 << 3) +# define R128_COLOR_FLAT_VERT_2 (2 << 3) +# define R128_COLOR_FLAT_VERT_3 (3 << 3) +# define R128_COLOR_GOURAUD (4 << 3) +# define R128_PRIM_TYPE_TRI (0 << 7) +# define R128_PRIM_TYPE_LINE (1 << 7) +# define R128_PRIM_TYPE_POINT (2 << 7) +# define R128_PRIM_TYPE_POLY_EDGE (3 << 7) +# define R128_TEXTURE_ST_MULT_W (0 << 9) +# define R128_TEXTURE_ST_DIRECT (1 << 9) +# define R128_STARTING_VERTEX_1 (1 << 14) +# define R128_STARTING_VERTEX_2 (2 << 14) +# define R128_STARTING_VERTEX_3 (3 << 14) +# define R128_ENDING_VERTEX_1 (1 << 16) +# define R128_ENDING_VERTEX_2 (2 << 16) +# define R128_ENDING_VERTEX_3 (3 << 16) +# define R128_SU_POLY_LINE_LAST (0 << 18) +# define R128_SU_POLY_LINE_NOT_LAST (1 << 18) +# define R128_SUB_PIX_2BITS (0 << 19) +# define R128_SUB_PIX_4BITS (1 << 19) +# define R128_SET_UP_CONTINUE (1 << 31) + +#define R128_WINDOW_XY_OFFSET 0x1bcc +# define R128_WINDOW_Y_SHIFT 4 +# define R128_WINDOW_X_SHIFT 20 + +#define R128_Z_OFFSET_C 0x1c90 +#define R128_Z_PITCH_C 0x1c94 +#define R128_Z_STEN_CNTL_C 0x1c98 +# define R128_Z_PIX_WIDTH_16 (0 << 1) +# define R128_Z_PIX_WIDTH_24 (1 << 1) +# define R128_Z_PIX_WIDTH_32 (2 << 1) +# define R128_Z_PIX_WIDTH_MASK (3 << 1) +# define R128_Z_TEST_NEVER (0 << 4) +# define R128_Z_TEST_LESS (1 << 4) +# define R128_Z_TEST_LESSEQUAL (2 << 4) +# define R128_Z_TEST_EQUAL (3 << 4) +# define R128_Z_TEST_GREATEREQUAL (4 << 4) +# define R128_Z_TEST_GREATER (5 << 4) +# define R128_Z_TEST_NEQUAL (6 << 4) +# define R128_Z_TEST_ALWAYS (7 << 4) +# define R128_Z_TEST_MASK (7 << 4) +# define R128_STENCIL_TEST_NEVER (0 << 12) +# define R128_STENCIL_TEST_LESS (1 << 12) +# define R128_STENCIL_TEST_LESSEQUAL (2 << 12) +# define R128_STENCIL_TEST_EQUAL (3 << 12) +# define R128_STENCIL_TEST_GREATEREQUAL (4 << 12) +# define R128_STENCIL_TEST_GREATER (5 << 12) +# define R128_STENCIL_TEST_NEQUAL (6 << 12) +# define R128_STENCIL_TEST_ALWAYS (7 << 12) +# define R128_STENCIL_S_FAIL_KEEP (0 << 16) +# define R128_STENCIL_S_FAIL_ZERO (1 << 16) +# define R128_STENCIL_S_FAIL_REPLACE (2 << 16) +# define R128_STENCIL_S_FAIL_INC (3 << 16) +# define R128_STENCIL_S_FAIL_DEC (4 << 16) +# define R128_STENCIL_S_FAIL_INV (5 << 16) +# define R128_STENCIL_ZPASS_KEEP (0 << 20) +# define R128_STENCIL_ZPASS_ZERO (1 << 20) +# define R128_STENCIL_ZPASS_REPLACE (2 << 20) +# define R128_STENCIL_ZPASS_INC (3 << 20) +# define R128_STENCIL_ZPASS_DEC (4 << 20) +# define R128_STENCIL_ZPASS_INV (5 << 20) +# define R128_STENCIL_ZFAIL_KEEP (0 << 24) +# define R128_STENCIL_ZFAIL_ZERO (1 << 24) +# define R128_STENCIL_ZFAIL_REPLACE (2 << 24) +# define R128_STENCIL_ZFAIL_INC (3 << 24) +# define R128_STENCIL_ZFAIL_DEC (4 << 24) +# define R128_STENCIL_ZFAIL_INV (5 << 24) +#define R128_TEX_CNTL_C 0x1c9c +# define R128_Z_ENABLE (1 << 0) +# define R128_Z_WRITE_ENABLE (1 << 1) +# define R128_STENCIL_ENABLE (1 << 3) +# define R128_SHADE_ENABLE (0 << 4) +# define R128_TEXMAP_ENABLE (1 << 4) +# define R128_SEC_TEXMAP_ENABLE (1 << 5) +# define R128_FOG_ENABLE (1 << 7) +# define R128_DITHER_ENABLE (1 << 8) +# define R128_ALPHA_ENABLE (1 << 9) +# define R128_ALPHA_TEST_ENABLE (1 << 10) +# define R128_SPEC_LIGHT_ENABLE (1 << 11) +# define R128_TEX_CHROMA_KEY_ENABLE (1 << 12) +# define R128_ALPHA_IN_TEX_COMPLETE_A (0 << 13) +# define R128_ALPHA_IN_TEX_LSB_A (1 << 13) +# define R128_LIGHT_DIS (0 << 14) +# define R128_LIGHT_COPY (1 << 14) +# define R128_LIGHT_MODULATE (2 << 14) +# define R128_LIGHT_ADD (3 << 14) +# define R128_LIGHT_BLEND_CONSTANT (4 << 14) +# define R128_LIGHT_BLEND_TEXTURE (5 << 14) +# define R128_LIGHT_BLEND_VERTEX (6 << 14) +# define R128_LIGHT_BLEND_CONST_COLOR (7 << 14) +# define R128_ALPHA_LIGHT_DIS (0 << 18) +# define R128_ALPHA_LIGHT_COPY (1 << 18) +# define R128_ALPHA_LIGHT_MODULATE (2 << 18) +# define R128_ALPHA_LIGHT_ADD (3 << 18) +# define R128_ANTI_ALIAS (1 << 21) +# define R128_TEX_CACHE_FLUSH (1 << 23) +# define R128_LOD_BIAS_SHIFT 24 +#define R128_MISC_3D_STATE_CNTL_REG 0x1ca0 +# define R128_REF_ALPHA_MASK 0xff +# define R128_MISC_SCALE_3D_NOOP (0 << 8) +# define R128_MISC_SCALE_3D_SCALE (1 << 8) +# define R128_MISC_SCALE_3D_TEXMAP_SHADE (2 << 8) +# define R128_MISC_SCALE_PIX_BLEND (0 << 10) +# define R128_MISC_SCALE_PIX_REPLICATE (1 << 10) +# define R128_ALPHA_COMB_ADD_CLAMP (0 << 12) +# define R128_ALPHA_COMB_ADD_NO_CLAMP (1 << 12) +# define R128_ALPHA_COMB_SUB_SRC_DST_CLAMP (2 << 12) +# define R128_ALPHA_COMB_SUB_SRC_DST_NO_CLAMP (3 << 12) +# define R128_FOG_VERTEX (0 << 14) +# define R128_FOG_TABLE (1 << 14) +# define R128_ALPHA_BLEND_SRC_ZERO (0 << 16) +# define R128_ALPHA_BLEND_SRC_ONE (1 << 16) +# define R128_ALPHA_BLEND_SRC_SRCCOLOR (2 << 16) +# define R128_ALPHA_BLEND_SRC_INVSRCCOLOR (3 << 16) +# define R128_ALPHA_BLEND_SRC_SRCALPHA (4 << 16) +# define R128_ALPHA_BLEND_SRC_INVSRCALPHA (5 << 16) +# define R128_ALPHA_BLEND_SRC_DESTALPHA (6 << 16) +# define R128_ALPHA_BLEND_SRC_INVDESTALPHA (7 << 16) +# define R128_ALPHA_BLEND_SRC_DESTCOLOR (8 << 16) +# define R128_ALPHA_BLEND_SRC_INVDESTCOLOR (9 << 16) +# define R128_ALPHA_BLEND_SRC_SRCALPHASAT (10 << 16) +# define R128_ALPHA_BLEND_SRC_BOTHSRCALPHA (11 << 16) +# define R128_ALPHA_BLEND_SRC_BOTHINVSRCALPHA (12 << 16) +# define R128_ALPHA_BLEND_SRC_MASK (15 << 16) +# define R128_ALPHA_BLEND_DST_ZERO (0 << 20) +# define R128_ALPHA_BLEND_DST_ONE (1 << 20) +# define R128_ALPHA_BLEND_DST_SRCCOLOR (2 << 20) +# define R128_ALPHA_BLEND_DST_INVSRCCOLOR (3 << 20) +# define R128_ALPHA_BLEND_DST_SRCALPHA (4 << 20) +# define R128_ALPHA_BLEND_DST_INVSRCALPHA (5 << 20) +# define R128_ALPHA_BLEND_DST_DESTALPHA (6 << 20) +# define R128_ALPHA_BLEND_DST_INVDESTALPHA (7 << 20) +# define R128_ALPHA_BLEND_DST_DESTCOLOR (8 << 20) +# define R128_ALPHA_BLEND_DST_INVDESTCOLOR (9 << 20) +# define R128_ALPHA_BLEND_DST_SRCALPHASAT (10 << 20) +# define R128_ALPHA_BLEND_DST_MASK (15 << 20) +# define R128_ALPHA_TEST_NEVER (0 << 24) +# define R128_ALPHA_TEST_LESS (1 << 24) +# define R128_ALPHA_TEST_LESSEQUAL (2 << 24) +# define R128_ALPHA_TEST_EQUAL (3 << 24) +# define R128_ALPHA_TEST_GREATEREQUAL (4 << 24) +# define R128_ALPHA_TEST_GREATER (5 << 24) +# define R128_ALPHA_TEST_NEQUAL (6 << 24) +# define R128_ALPHA_TEST_ALWAYS (7 << 24) +# define R128_ALPHA_TEST_MASK (7 << 24) +#define R128_TEXTURE_CLR_CMP_CLR_C 0x1ca4 +#define R128_TEXTURE_CLR_CMP_MSK_C 0x1ca8 +#define R128_FOG_COLOR_C 0x1cac +# define R128_FOG_BLUE_SHIFT 0 +# define R128_FOG_GREEN_SHIFT 8 +# define R128_FOG_RED_SHIFT 16 +#define R128_PRIM_TEX_CNTL_C 0x1cb0 +# define R128_MIN_BLEND_NEAREST (0 << 1) +# define R128_MIN_BLEND_LINEAR (1 << 1) +# define R128_MIN_BLEND_MIPNEAREST (2 << 1) +# define R128_MIN_BLEND_MIPLINEAR (3 << 1) +# define R128_MIN_BLEND_LINEARMIPNEAREST (4 << 1) +# define R128_MIN_BLEND_LINEARMIPLINEAR (5 << 1) +# define R128_MIN_BLEND_MASK (7 << 1) +# define R128_MAG_BLEND_NEAREST (0 << 4) +# define R128_MAG_BLEND_LINEAR (1 << 4) +# define R128_MAG_BLEND_MASK (7 << 4) +# define R128_MIP_MAP_DISABLE (1 << 7) +# define R128_TEX_CLAMP_S_WRAP (0 << 8) +# define R128_TEX_CLAMP_S_MIRROR (1 << 8) +# define R128_TEX_CLAMP_S_CLAMP (2 << 8) +# define R128_TEX_CLAMP_S_BORDER_COLOR (3 << 8) +# define R128_TEX_CLAMP_S_MASK (3 << 8) +# define R128_TEX_WRAP_S (1 << 10) +# define R128_TEX_CLAMP_T_WRAP (0 << 11) +# define R128_TEX_CLAMP_T_MIRROR (1 << 11) +# define R128_TEX_CLAMP_T_CLAMP (2 << 11) +# define R128_TEX_CLAMP_T_BORDER_COLOR (3 << 11) +# define R128_TEX_CLAMP_T_MASK (3 << 11) +# define R128_TEX_WRAP_T (1 << 13) +# define R128_TEX_PERSPECTIVE_DISABLE (1 << 14) +# define R128_DATATYPE_VQ (0 << 16) +# define R128_DATATYPE_CI4 (1 << 16) +# define R128_DATATYPE_CI8 (2 << 16) +# define R128_DATATYPE_ARGB1555 (3 << 16) +# define R128_DATATYPE_RGB565 (4 << 16) +# define R128_DATATYPE_RGB888 (5 << 16) +# define R128_DATATYPE_ARGB8888 (6 << 16) +# define R128_DATATYPE_RGB332 (7 << 16) +# define R128_DATATYPE_Y8 (8 << 16) +# define R128_DATATYPE_RGB8 (9 << 16) +# define R128_DATATYPE_CI16 (10 << 16) +# define R128_DATATYPE_YUV422 (11 << 16) +# define R128_DATATYPE_YUV422_2 (12 << 16) +# define R128_DATATYPE_AYUV444 (14 << 16) +# define R128_DATATYPE_ARGB4444 (15 << 16) +# define R128_PALLETE_EITHER (0 << 20) +# define R128_PALLETE_1 (1 << 20) +# define R128_PALLETE_2 (2 << 20) +# define R128_PSEUDOCOLOR_DT_RGB565 (0 << 24) +# define R128_PSEUDOCOLOR_DT_ARGB1555 (1 << 24) +# define R128_PSEUDOCOLOR_DT_ARGB4444 (2 << 24) +#define R128_PRIM_TEXTURE_COMBINE_CNTL_C 0x1cb4 +# define R128_COMB_DIS (0 << 0) +# define R128_COMB_COPY (1 << 0) +# define R128_COMB_COPY_INP (2 << 0) +# define R128_COMB_MODULATE (3 << 0) +# define R128_COMB_MODULATE2X (4 << 0) +# define R128_COMB_MODULATE4X (5 << 0) +# define R128_COMB_ADD (6 << 0) +# define R128_COMB_ADD_SIGNED (7 << 0) +# define R128_COMB_BLEND_VERTEX (8 << 0) +# define R128_COMB_BLEND_TEXTURE (9 << 0) +# define R128_COMB_BLEND_CONST (10 << 0) +# define R128_COMB_BLEND_PREMULT (11 << 0) +# define R128_COMB_BLEND_PREV (12 << 0) +# define R128_COMB_BLEND_PREMULT_INV (13 << 0) +# define R128_COMB_ADD_SIGNED2X (14 << 0) +# define R128_COMB_BLEND_CONST_COLOR (15 << 0) +# define R128_COMB_MASK (15 << 0) +# define R128_COLOR_FACTOR_TEX (4 << 4) +# define R128_COLOR_FACTOR_NTEX (5 << 4) +# define R128_COLOR_FACTOR_ALPHA (6 << 4) +# define R128_COLOR_FACTOR_NALPHA (7 << 4) +# define R128_COLOR_FACTOR_MASK (15 << 4) +# define R128_INPUT_FACTOR_CONST_COLOR (2 << 10) +# define R128_INPUT_FACTOR_CONST_ALPHA (3 << 10) +# define R128_INPUT_FACTOR_INT_COLOR (4 << 10) +# define R128_INPUT_FACTOR_INT_ALPHA (5 << 10) +# define R128_INPUT_FACTOR_MASK (15 << 10) +# define R128_COMB_ALPHA_DIS (0 << 14) +# define R128_COMB_ALPHA_COPY (1 << 14) +# define R128_COMB_ALPHA_COPY_INP (2 << 14) +# define R128_COMB_ALPHA_MODULATE (3 << 14) +# define R128_COMB_ALPHA_MODULATE2X (4 << 14) +# define R128_COMB_ALPHA_MODULATE4X (5 << 14) +# define R128_COMB_ALPHA_ADD (6 << 14) +# define R128_COMB_ALPHA_ADD_SIGNED (7 << 14) +# define R128_COMB_ALPHA_ADD_SIGNED2X (14 << 14) +# define R128_COMB_ALPHA_MASK (15 << 14) +# define R128_ALPHA_FACTOR_TEX_ALPHA (6 << 18) +# define R128_ALPHA_FACTOR_NTEX_ALPHA (7 << 18) +# define R128_ALPHA_FACTOR_MASK (15 << 18) +# define R128_INP_FACTOR_A_CONST_ALPHA (1 << 25) +# define R128_INP_FACTOR_A_INT_ALPHA (2 << 25) +# define R128_INP_FACTOR_A_MASK (7 << 25) +#define R128_TEX_SIZE_PITCH_C 0x1cb8 +# define R128_TEX_PITCH_SHIFT 0 +# define R128_TEX_SIZE_SHIFT 4 +# define R128_TEX_HEIGHT_SHIFT 8 +# define R128_TEX_MIN_SIZE_SHIFT 12 +# define R128_SEC_TEX_PITCH_SHIFT 16 +# define R128_SEC_TEX_SIZE_SHIFT 20 +# define R128_SEC_TEX_HEIGHT_SHIFT 24 +# define R128_SEC_TEX_MIN_SIZE_SHIFT 28 +# define R128_TEX_PITCH_MASK (0x0f << 0) +# define R128_TEX_SIZE_MASK (0x0f << 4) +# define R128_TEX_HEIGHT_MASK (0x0f << 8) +# define R128_TEX_MIN_SIZE_MASK (0x0f << 12) +# define R128_SEC_TEX_PITCH_MASK (0x0f << 16) +# define R128_SEC_TEX_SIZE_MASK (0x0f << 20) +# define R128_SEC_TEX_HEIGHT_MASK (0x0f << 24) +# define R128_SEC_TEX_MIN_SIZE_MASK (0x0f << 28) +# define R128_TEX_SIZE_PITCH_SHIFT 0 +# define R128_SEC_TEX_SIZE_PITCH_SHIFT 16 +# define R128_TEX_SIZE_PITCH_MASK (0xffff << 0) +# define R128_SEC_TEX_SIZE_PITCH_MASK (0xffff << 16) +#define R128_PRIM_TEX_0_OFFSET_C 0x1cbc +#define R128_PRIM_TEX_1_OFFSET_C 0x1cc0 +#define R128_PRIM_TEX_2_OFFSET_C 0x1cc4 +#define R128_PRIM_TEX_3_OFFSET_C 0x1cc8 +#define R128_PRIM_TEX_4_OFFSET_C 0x1ccc +#define R128_PRIM_TEX_5_OFFSET_C 0x1cd0 +#define R128_PRIM_TEX_6_OFFSET_C 0x1cd4 +#define R128_PRIM_TEX_7_OFFSET_C 0x1cd8 +#define R128_PRIM_TEX_8_OFFSET_C 0x1cdc +#define R128_PRIM_TEX_9_OFFSET_C 0x1ce0 +#define R128_PRIM_TEX_10_OFFSET_C 0x1ce4 +# define R128_TEX_NO_TILE (0 << 30) +# define R128_TEX_TILED_BY_HOST (1 << 30) +# define R128_TEX_TILED_BY_STORAGE (2 << 30) +# define R128_TEX_TILED_BY_STORAGE2 (3 << 30) + +#define R128_SEC_TEX_CNTL_C 0x1d00 +# define R128_SEC_SELECT_PRIM_ST (0 << 0) +# define R128_SEC_SELECT_SEC_ST (1 << 0) +#define R128_SEC_TEX_COMBINE_CNTL_C 0x1d04 +# define R128_INPUT_FACTOR_PREV_COLOR (8 << 10) +# define R128_INPUT_FACTOR_PREV_ALPHA (9 << 10) +# define R128_INP_FACTOR_A_PREV_ALPHA (4 << 25) +#define R128_SEC_TEX_0_OFFSET_C 0x1d08 +#define R128_SEC_TEX_1_OFFSET_C 0x1d0c +#define R128_SEC_TEX_2_OFFSET_C 0x1d10 +#define R128_SEC_TEX_3_OFFSET_C 0x1d14 +#define R128_SEC_TEX_4_OFFSET_C 0x1d18 +#define R128_SEC_TEX_5_OFFSET_C 0x1d1c +#define R128_SEC_TEX_6_OFFSET_C 0x1d20 +#define R128_SEC_TEX_7_OFFSET_C 0x1d24 +#define R128_SEC_TEX_8_OFFSET_C 0x1d28 +#define R128_SEC_TEX_9_OFFSET_C 0x1d2c +#define R128_SEC_TEX_10_OFFSET_C 0x1d30 +#define R128_CONSTANT_COLOR_C 0x1d34 +# define R128_CONSTANT_BLUE_SHIFT 0 +# define R128_CONSTANT_GREEN_SHIFT 8 +# define R128_CONSTANT_RED_SHIFT 16 +# define R128_CONSTANT_ALPHA_SHIFT 24 +#define R128_PRIM_TEXTURE_BORDER_COLOR_C 0x1d38 +# define R128_PRIM_TEX_BORDER_BLUE_SHIFT 0 +# define R128_PRIM_TEX_BORDER_GREEN_SHIFT 8 +# define R128_PRIM_TEX_BORDER_RED_SHIFT 16 +# define R128_PRIM_TEX_BORDER_ALPHA_SHIFT 24 +#define R128_SEC_TEXTURE_BORDER_COLOR_C 0x1d3c +# define R128_SEC_TEX_BORDER_BLUE_SHIFT 0 +# define R128_SEC_TEX_BORDER_GREEN_SHIFT 8 +# define R128_SEC_TEX_BORDER_RED_SHIFT 16 +# define R128_SEC_TEX_BORDER_ALPHA_SHIFT 24 +#define R128_STEN_REF_MASK_C 0x1d40 +# define R128_STEN_REFERENCE_SHIFT 0 +# define R128_STEN_MASK_SHIFT 16 +# define R128_STEN_WRITE_MASK_SHIFT 24 +#define R128_PLANE_3D_MASK_C 0x1d44 +#define R128_TEX_CACHE_STAT_COUNT 0x1974 + + + /* Constants */ +#define R128_AGP_TEX_OFFSET 0x02000000 + +#define R128_VB_AGE_REG R128_GUI_SCRATCH_REG0 +#define R128_SWAP_AGE_REG R128_GUI_SCRATCH_REG1 + + /* CCE packet types */ +#define R128_CCE_PACKET0 0x00000000 +#define R128_CCE_PACKET0_ONE_REG_WR 0x00008000 +#define R128_CCE_PACKET1 0x40000000 +#define R128_CCE_PACKET2 0x80000000 +#define R128_CCE_PACKET3_NOP 0xC0001000 +#define R128_CCE_PACKET3_PAINT 0xC0001100 +#define R128_CCE_PACKET3_BITBLT 0xC0001200 +#define R128_CCE_PACKET3_SMALLTEXT 0xC0001300 +#define R128_CCE_PACKET3_HOSTDATA_BLT 0xC0001400 +#define R128_CCE_PACKET3_POLYLINE 0xC0001500 +#define R128_CCE_PACKET3_SCALING 0xC0001600 +#define R128_CCE_PACKET3_TRANS_SCALING 0xC0001700 +#define R128_CCE_PACKET3_POLYSCANLINES 0xC0001800 +#define R128_CCE_PACKET3_NEXT_CHAR 0xC0001900 +#define R128_CCE_PACKET3_PAINT_MULTI 0xC0001A00 +#define R128_CCE_PACKET3_BITBLT_MULTI 0xC0001B00 +#define R128_CCE_PACKET3_PLY_NEXTSCAN 0xC0001D00 +#define R128_CCE_PACKET3_SET_SCISSORS 0xC0001E00 +#define R128_CCE_PACKET3_SET_MODE24BPP 0xC0001F00 +#define R128_CCE_PACKET3_CNTL_PAINT 0xC0009100 +#define R128_CCE_PACKET3_CNTL_BITBLT 0xC0009200 +#define R128_CCE_PACKET3_CNTL_SMALLTEXT 0xC0009300 +#define R128_CCE_PACKET3_CNTL_HOSTDATA_BLT 0xC0009400 +#define R128_CCE_PACKET3_CNTL_POLYLINE 0xC0009500 +#define R128_CCE_PACKET3_CNTL_SCALING 0xC0009600 +#define R128_CCE_PACKET3_CNTL_TRANS_SCALING 0xC0009700 +#define R128_CCE_PACKET3_CNTL_POLYSCANLINES 0xC0009800 +#define R128_CCE_PACKET3_CNTL_NEXT_CHAR 0xC0009900 +#define R128_CCE_PACKET3_CNTL_PAINT_MULTI 0xC0009A00 +#define R128_CCE_PACKET3_CNTL_BITBLT_MULTI 0xC0009B00 +#define R128_CCE_PACKET3_CNTL_TRANS_BITBLT 0xC0009C00 +#define R128_CCE_PACKET3_3D_SAVE_CONTEXT 0xC0002000 +#define R128_CCE_PACKET3_3D_PLAY_CONTEXT 0xC0002100 +#define R128_CCE_PACKET3_3D_RNDR_GEN_INDX_PRIM 0xC0002300 +#define R128_CCE_PACKET3_3D_RNDR_GEN_PRIM 0xC0002500 +#define R128_CCE_PACKET3_LOAD_PALETTE 0xC0002C00 +#define R128_CCE_PACKET3_PURGE 0xC0002D00 +#define R128_CCE_PACKET3_NEXT_VERTEX_BUNDLE 0xC0002E00 +# define R128_CCE_PACKET_MASK 0xC0000000 +# define R128_CCE_PACKET_COUNT_MASK 0x3fff0000 +# define R128_CCE_PACKET_MAX_DWORDS (1 << 14) +# define R128_CCE_PACKET0_REG_MASK 0x000007ff +# define R128_CCE_PACKET1_REG0_MASK 0x000007ff +# define R128_CCE_PACKET1_REG1_MASK 0x003ff800 + +#define R128_CCE_VC_FRMT_RHW 0x00000001 +#define R128_CCE_VC_FRMT_DIFFUSE_BGR 0x00000002 +#define R128_CCE_VC_FRMT_DIFFUSE_A 0x00000004 +#define R128_CCE_VC_FRMT_DIFFUSE_ARGB 0x00000008 +#define R128_CCE_VC_FRMT_SPEC_BGR 0x00000010 +#define R128_CCE_VC_FRMT_SPEC_F 0x00000020 +#define R128_CCE_VC_FRMT_SPEC_FRGB 0x00000040 +#define R128_CCE_VC_FRMT_S_T 0x00000080 +#define R128_CCE_VC_FRMT_S2_T2 0x00000100 +#define R128_CCE_VC_FRMT_RHW2 0x00000200 + +#define R128_CCE_VC_CNTL_PRIM_TYPE_NONE 0x00000000 +#define R128_CCE_VC_CNTL_PRIM_TYPE_POINT 0x00000001 +#define R128_CCE_VC_CNTL_PRIM_TYPE_LINE 0x00000002 +#define R128_CCE_VC_CNTL_PRIM_TYPE_POLY_LINE 0x00000003 +#define R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST 0x00000004 +#define R128_CCE_VC_CNTL_PRIM_TYPE_TRI_FAN 0x00000005 +#define R128_CCE_VC_CNTL_PRIM_TYPE_TRI_STRIP 0x00000006 +#define R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2 0x00000007 +#define R128_CCE_VC_CNTL_PRIM_WALK_IND 0x00000010 +#define R128_CCE_VC_CNTL_PRIM_WALK_LIST 0x00000020 +#define R128_CCE_VC_CNTL_PRIM_WALK_RING 0x00000030 +#define R128_CCE_VC_CNTL_NUM_SHIFT 16 + +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_sarea.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_sarea.h new file mode 100644 index 000000000..d9d8d00e6 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_sarea.h @@ -0,0 +1,76 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_sarea.h,v 1.1 2000/11/02 16:55:38 tsi Exp $ */ +/* + * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario + * and Precision Insight, Inc., Cedar Park, Texas. + * + * 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 on + * 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, PRECISION INSIGHT AND/OR THEIR 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: + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#ifndef _R128_SAREA_H_ +#define _R128_SAREA_H_ + +/* There are 2 heaps (local/AGP). Each region within a heap is a + minimum of 64k, and there are at most 64 of them per heap. */ +#define R128_LOCAL_TEX_HEAP 0 +#define R128_AGP_TEX_HEAP 1 +#define R128_NR_TEX_HEAPS 2 +#define R128_NR_TEX_REGIONS 64 +#define R128_LOG_TEX_GRANULARITY 16 + +typedef struct { + unsigned char next, prev; /* indices to form a circular LRU */ + unsigned char in_use; /* owned by a client, or free? */ + int age; /* tracked by clients to update local LRU's */ +} R128TexRegion; + +typedef struct { + /* Maintain an LRU of contiguous regions of texture space. If you + * think you own a region of texture memory, and it has an age + * different to the one you set, then you are mistaken and it has + * been stolen by another client. If global texAge hasn't changed, + * there is no need to walk the list. + * + * These regions can be used as a proxy for the fine-grained texture + * information of other clients - by maintaining them in the same + * lru which is used to age their own textures, clients have an + * approximate lru for the whole of global texture space, and can + * make informed decisions as to which areas to kick out. There is + * no need to choose whether to kick out your own texture or someone + * else's - simply eject them all in LRU order. + */ + /* Last elt is sentinal */ + R128TexRegion texList[R128_NR_TEX_HEAPS][R128_NR_TEX_REGIONS+1]; + /* last time texture was uploaded */ + int texAge[R128_NR_TEX_HEAPS]; + + int ctxOwner; /* last context to upload state */ + + CARD32 ringWrite; /* current ring buffer write index */ +} R128SAREAPriv, *R128SAREAPrivPtr; + +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_version.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_version.h new file mode 100644 index 000000000..3c366c49a --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_version.h @@ -0,0 +1,41 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_version.h,v 1.1 2000/11/02 16:55:39 tsi Exp $ */ +/* + * Copyright 2000 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of Marc Aurele La France not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Marc Aurele La France makes no representations + * about the suitability of this software for any purpose. It is provided + * "as-is" without express or implied warranty. + * + * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO + * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _R128_VERSION_H_ +#define _R128_VERSION_H_ 1 + +#define R128_NAME "R128" +#define R128_DRIVER_NAME "r128" + +#define R128_VERSION_NAME "4.0.1" + +#define R128_VERSION_MAJOR 4 +#define R128_VERSION_MINOR 0 +#define R128_VERSION_PATCH 1 + +#define R128_VERSION_CURRENT \ + ((R128_VERSION_MAJOR << 20) | \ + (R128_VERSION_MINOR << 10) | \ + (R128_VERSION_PATCH)) + +#endif /* _R128_VERSION_H_ */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_video.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_video.c new file mode 100644 index 000000000..8c8977e8f --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_video.c @@ -0,0 +1,796 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_video.c,v 1.1 2000/11/02 16:55:39 tsi Exp $ */ +/* + * Copyright 2000 Stuart R. Anderson and Metro Link, Inc. + * + * 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 on + * 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, PRECISION INSIGHT AND/OR THEIR 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: + * Stuart R. Anderson <anderson@metrolink.com> + * + * Credits: + * + * This code is derived primarily from the GATOS Project run by Stea Greene. + * The initial version of this code was done by Vladimir Dergacheb. + * + * This code was simplified from the GATOS code primarily because I didn't + * have the right hardware handy to test anything beyond simple overlays, + * and because I wanted to complete it in a short time frame that I had + * available. + * + * My apologies to Vladimir as there is more good work in his code that + * should be brought forward. + */ +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "xf86_ansic.h" +#include "compiler.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "xf86fbman.h" +#include "regionstr.h" + +#include "xf86xv.h" +#include "xf86Cursor.h" +#include "Xv.h" +#include "xaalocal.h" +#include "dixstruct.h" +#include "fourcc.h" +#ifdef XF86DRI +#include "r128_dri.h" +#endif + +#include "r128.h" +#include "r128_reg.h" + +/* + * For Debug +#define OUTREG(addr, val) { xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"OUTREG(%s,%x)\n",#addr,val) ;MMIO_OUT32(R128MMIO, addr, val);} +*/ + +#define OFF_DELAY 250 /* milliseconds */ +#define FREE_DELAY 15000 + +#define OFF_TIMER 0x01 +#define FREE_TIMER 0x02 +#define CLIENT_VIDEO_ON 0x04 + +#define TIMER_MASK (OFF_TIMER | FREE_TIMER) + +#ifndef XvExtension +void R128InitVideo(ScreenPtr pScreen) {} +#else +static XF86VideoAdaptorPtr R128SetupImageVideo(ScreenPtr); +static int R128SetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); +static int R128GetPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer); + +static void R128StopVideo(ScrnInfoPtr, pointer, Bool); +static void R128QueryBestSize(ScrnInfoPtr, Bool, + short, short, short, short, unsigned int *, unsigned int *, pointer); +static int R128PutImage( ScrnInfoPtr, + short, short, short, short, short, short, short, short, + int, unsigned char*, short, short, Bool, RegionPtr, pointer); +static int R128QueryImageAttributes(ScrnInfoPtr, + int, unsigned short *, unsigned short *, int *, int *); + +#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) + +#define IMAGE_MAX_WIDTH 2048 +#define IMAGE_MAX_HEIGHT 2048 +#define Y_BUF_SIZE (IMAGE_MAX_WIDTH * IMAGE_MAX_HEIGHT) + +static Atom xvColorKey; + +typedef struct { + int videoStatus; + unsigned char brightness; + unsigned char contrast; + + RegionRec clip; + CARD32 colorKey; + CARD8 overlay_pixel_size; + CARD8 current_buffer; + int overlay_pad; + CARD32 overlay_id; + CARD32 overlay_width; + + CARD32 scale_cntl; + CARD32 video_format; + FBLinearPtr linear; + } R128PortPrivRec, *R128PortPrivPtr; + +void R128InitVideo(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; + XF86VideoAdaptorPtr newAdaptor = NULL; + int num_adaptors; + + R128TRACE(("R128InitVideo called\n")); + + /* Determine if the card supports this */ + if (pScrn->bitsPerPixel != 8) + { + newAdaptor = R128SetupImageVideo(pScreen); + } + + num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); + + if(newAdaptor) { + if(!num_adaptors) { + num_adaptors = 1; + adaptors = &newAdaptor; + } else { + newAdaptors = /* need to free this someplace */ + xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr*)); + if(newAdaptors) { + memcpy(newAdaptors, adaptors, num_adaptors * + sizeof(XF86VideoAdaptorPtr)); + newAdaptors[num_adaptors] = newAdaptor; + adaptors = newAdaptors; + num_adaptors++; + } + } + } + + if(num_adaptors) + xf86XVScreenInit(pScreen, adaptors, num_adaptors); + + if(newAdaptors) + xfree(newAdaptors); +} + +/* client libraries expect an encoding */ +static XF86VideoEncodingRec DummyEncoding[1] = +{ + { + 0, + "XV_IMAGE", + IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT, + {1, 1} + } +}; + +#define NUM_FORMATS 3 + +static XF86VideoFormatRec Formats[NUM_FORMATS] = +{ + {15, TrueColor}, + {16, TrueColor}, + {32, TrueColor} +}; + +#define NUM_ATTRIBUTES 1 + +static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = +{ + {XvSettable | XvGettable, 0, (1<<24)-1, "XV_COLORKEY"}, +}; + +#define NUM_IMAGES 3 + +static XF86ImageRec Images[NUM_IMAGES] = +{ + XVIMAGE_YUY2, + XVIMAGE_YV12, + XVIMAGE_UYVY +}; + +static void +R128ResetVideo(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + R128PortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr; + + R128TRACE(("R128ResetVideo called\n")); + + /* Initialize some of the HW here */ + OUTREG(R128_OV0_EXCLUSIVE_HORZ,0); /* disable exclusive mode */ + OUTREG(R128_OV0_VIDEO_KEY_MSK,0xffff); + OUTREG(R128_OV0_KEY_CNTL, R128_GRAPHIC_KEY_FN_NE); + OUTREG(R128_OV0_GRAPHICS_KEY_CLR,pPriv->colorKey); + /* Only using one buffer for now + OUTREG(R128_OV0_AUTO_FLIP_CNTL,pAPriv->Port[0].auto_flip_cntl); + */ + switch(pScrn->depth){ + case 8: + OUTREG(R128_OV0_GRAPHICS_KEY_MSK,0xff); + break; + case 15: + OUTREG(R128_OV0_GRAPHICS_KEY_MSK,0x7fff); + break; + case 16: + OUTREG(R128_OV0_GRAPHICS_KEY_MSK,0xffff); + break; + case 24: + OUTREG(R128_OV0_GRAPHICS_KEY_MSK,0xffffff); + break; + case 32: + OUTREG(R128_OV0_GRAPHICS_KEY_MSK,0xffffffff); + break; + } + + OUTREG(R128_OV0_REG_LOAD_CNTL,0x0); + OUTREG(R128_OV0_DEINTERLACE_PATTERN,0xAAAAA); + OUTREG(R128_OV0_P1_V_ACCUM_INIT,(2<<20)|1); + OUTREG(R128_OV0_P23_V_ACCUM_INIT,(2<<20)|1); + OUTREG(R128_OV0_P1_H_ACCUM_INIT,(3<<28)); + OUTREG(R128_OV0_P23_H_ACCUM_INIT,(2<<28)); + OUTREG(R128_OV0_STEP_BY,1|(1<<8)); + OUTREG(R128_OV0_FILTER_CNTL,0xf); /* use hardcoded coeff's */ + OUTREG(R128_OV0_FILTER_CNTL,0x0); /* use programmable coeff's */ + OUTREG(R128_OV0_FOUR_TAP_COEF_0 , 0x00002000); + OUTREG(R128_OV0_FOUR_TAP_COEF_1 , 0x0D06200D); + OUTREG(R128_OV0_FOUR_TAP_COEF_2 , 0x0D0A1C0D); + OUTREG(R128_OV0_FOUR_TAP_COEF_3 , 0x0C0E1A0C); + OUTREG(R128_OV0_FOUR_TAP_COEF_4 , 0x0C14140C); + OUTREG(R128_OV0_COLOUR_CNTL,(1<<12)|(1<<20)); + OUTREG(R128_OV0_TEST,0); + OUTREG(R128_OV0_SCALE_CNTL,pPriv->scale_cntl|pPriv->video_format); + OUTREG(R128_CAP0_TRIG_CNTL,0); +} + +static XF86VideoAdaptorPtr +R128SetupImageVideo(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + XF86VideoAdaptorPtr adapt; + R128PortPrivPtr pPriv; + + R128TRACE(("R128SetupImageVideo called\n")); + + if(!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) + + sizeof(R128PortPrivRec) + + sizeof(DevUnion)))) + return NULL; + + adapt->type = XvWindowMask | XvInputMask | XvImageMask; + adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; + adapt->name = "R128 Video Overlay"; + adapt->nEncodings = 1; + adapt->pEncodings = DummyEncoding; + adapt->nFormats = NUM_FORMATS; + adapt->pFormats = Formats; + adapt->nPorts = 1; + adapt->pPortPrivates = (DevUnion*)(&adapt[1]); + + pPriv = (R128PortPrivPtr)(&adapt->pPortPrivates[1]); + + adapt->pPortPrivates[0].ptr = (pointer)(pPriv); + adapt->pAttributes = Attributes; + adapt->nImages = NUM_IMAGES; + adapt->nAttributes = NUM_ATTRIBUTES; + adapt->pImages = Images; + adapt->PutVideo = NULL; + adapt->PutStill = NULL; + adapt->GetVideo = NULL; + adapt->GetStill = NULL; + adapt->StopVideo = R128StopVideo; + adapt->SetPortAttribute = R128SetPortAttribute; + adapt->GetPortAttribute = R128GetPortAttribute; + adapt->QueryBestSize = R128QueryBestSize; + adapt->PutImage = R128PutImage; + adapt->QueryImageAttributes = R128QueryImageAttributes; + + /* gotta uninit this someplace */ + REGION_INIT(pScreen, &pPriv->clip, NullBox, 0); + + info->adaptor = adapt; + + pPriv->colorKey = 0x01; /* a touch of blue */ + pPriv->video_format = R128_SCALER_SOURCE_VYUY422; + pPriv->scale_cntl = R128_SCALER_PRG_LOAD_START|R128_SCALER_DOUBLE_BUFFER; + pPriv->scale_cntl|= R128_SCALER_SMART_SWITCH|R128_SCALER_PIX_EXPAND; + pPriv->scale_cntl|= R128_SCALER_SMART_SWITCH; + + xvColorKey = MAKE_ATOM("XV_COLORKEY"); + + R128ResetVideo(pScrn); + + 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; +} + +static void +R128StopVideo(ScrnInfoPtr pScrn, pointer data, Bool Exit) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + R128PortPrivPtr pPriv = (R128PortPrivPtr) data; + + R128TRACE(("R128StopVideo called\n")); + + REGION_EMPTY(pScrn->pScreen, &pPriv->clip); + + if (Exit) { + if(pPriv->videoStatus & CLIENT_VIDEO_ON) { + OUTREG(R128_OV0_SCALE_CNTL,pPriv->scale_cntl|pPriv->video_format); + } + if(pPriv->linear) { + xf86FreeOffscreenLinear(pPriv->linear); + pPriv->linear = NULL; + } + pPriv->videoStatus = 0; + } else { + if(pPriv->videoStatus & CLIENT_VIDEO_ON) { + } + } +} + +static int +R128SetPortAttribute( + ScrnInfoPtr pScrn, + Atom attribute, + INT32 value, + pointer data +) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + R128PortPrivPtr pPriv = (R128PortPrivPtr) data; + + R128TRACE(("R128SetPortAttribute called\n")); + + if (attribute == xvColorKey) { + pPriv->colorKey = value; + OUTREG(R128_OV0_GRAPHICS_KEY_CLR,pPriv->colorKey); + R128TRACE(("Setting ColorKey to %d\n", pPriv->colorKey)); + return Success; + } + + return Success; +} + +static int +R128GetPortAttribute( + ScrnInfoPtr pScrn, + Atom attribute, + INT32 *value, + pointer data +) +{ + R128PortPrivPtr pPriv = (R128PortPrivPtr) data; + + R128TRACE(("R128GetPortAttribute called\n")); + + if (attribute == xvColorKey) { + R128TRACE(("Getting ColorKey %d\n", pPriv->colorKey)); + *value = pPriv->colorKey; + return Success; + } + + return Success; +} + +static void +R128QueryBestSize( + ScrnInfoPtr pScrn, + Bool motion, + short vid_w, short vid_h, + short drw_w, short drw_h, + unsigned int *p_w, unsigned int *p_h, + pointer data +) +{ + R128TRACE(("R128QueryBestSize called\n")); + *p_w = drw_w; + *p_h = drw_h; +} + +static void +R128DisplayVideo( + ScrnInfoPtr pScrn, + short width, short height, + int xa, int ya, int xb, int yb, + short src_w, short src_h, + short drw_w, short drw_h, + int fboffset +) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + R128PortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr; + int step_by, vert_inc, horz_inc; + + R128TRACE(("R128DisplayVideo called\n")); + + /* calculate step_by factor */ + step_by=src_w/(drw_w*2); + switch(step_by){ + case 0: + OUTREG(R128_OV0_STEP_BY,0x101); + step_by=1; + break; + case 1: + OUTREG(R128_OV0_STEP_BY,0x202); + step_by=2; + break; + case 2: + case 3: + OUTREG(R128_OV0_STEP_BY,0x303); + step_by=4; + break; + default: + OUTREG(R128_OV0_STEP_BY,0x404); + step_by=8; + break; + } + + vert_inc=(src_h<<12)/(drw_h); + horz_inc=(src_w<<12)/(drw_w*step_by); + + OUTREG(R128_OV0_Y_X_START,((xa))|(ya<<16)|(1<<31)); + OUTREG(R128_OV0_Y_X_END,((xb))|((yb)<<16)); + OUTREG(R128_OV0_H_INC,(horz_inc)|((horz_inc<<15))); + OUTREG(R128_OV0_V_INC,(vert_inc<<8)); + OUTREG(R128_OV0_P1_BLANK_LINES_AT_TOP,0xfff|((src_h-1)<<16)); + OUTREG(R128_OV0_P23_BLANK_LINES_AT_TOP,0xfff|((src_h-1)<<16)); + OUTREG(R128_OV0_VID_BUF_PITCH0_VALUE,width<<1); + OUTREG(R128_OV0_VID_BUF_PITCH1_VALUE,width<<1); + OUTREG(R128_OV0_P1_X_START_END,(src_w-1)|((xa&0xf)<<16)); + OUTREG(R128_OV0_P2_X_START_END,(src_w-1)|((xa&0xf)<<16)); + OUTREG(R128_OV0_P3_X_START_END,(src_w-1)|((xa&0xf)<<16)); + + OUTREG(R128_OV0_VID_BUF0_BASE_ADRS,(fboffset)&(~0xf)); + OUTREG(R128_OV0_VID_BUF1_BASE_ADRS,(fboffset)&(~0xf)); + OUTREG(R128_OV0_VID_BUF2_BASE_ADRS,(fboffset)&(~0xf)); + +#if 0 + /* Enable this when double buffering is implemented */ + OUTREG(R128_OV0_VID_BUF3_BASE_ADRS,(fboffset2)&(~0xf)); + OUTREG(R128_OV0_VID_BUF4_BASE_ADRS,(fboffset2)&(~0xf)); + OUTREG(R128_OV0_VID_BUF5_BASE_ADRS,(fboffset2)&(~0xf)); +#endif + + OUTREG(R128_OV0_SCALE_CNTL,pPriv->scale_cntl|R128_SCALER_ENABLE|pPriv->video_format); +} + +static void +R128CopyData( + unsigned char *src, + unsigned char *dst, + int srcPitch, + int dstPitch, + int h, + int w + ) +{ + w <<= 1; + while(h--) { + memcpy(dst, src, w); + src += srcPitch; + dst += dstPitch; + } +} + +static void +R128CopyMungedData( + unsigned char *src1, + unsigned char *src2, + unsigned char *src3, + unsigned char *dst1, + int srcPitch, + int srcPitch2, + int dstPitch, + int h, + int w + ) +{ + CARD32 *dst = (CARD32*)dst1; + int i, j; + + dstPitch >>= 2; + w >>= 1; + + for(j = 0; j < h; j++) { + for(i = 0; i < w; i++) { + dst[i] = src1[i << 1] | (src1[(i << 1) + 1] << 16) | + (src3[i] << 8) | (src2[i] << 24); + } + dst += dstPitch; + src1 += srcPitch; + if(j & 1) { + src2 += srcPitch2; + src3 += srcPitch2; + } + } +} + +static FBLinearPtr +R128AllocateMemory( + ScrnInfoPtr pScrn, + FBLinearPtr linear, + int size +) +{ + ScreenPtr pScreen; + FBLinearPtr new_linear; + + R128TRACE(("R128AllocateMemory(%x,%d) called\n",linear,size)); + + if(linear) { + if(linear->size >= size) + return linear; + + if(xf86ResizeOffscreenLinear(linear, size)) + return linear; + + xf86FreeOffscreenLinear(linear); + } + + pScreen = screenInfo.screens[pScrn->scrnIndex]; + + new_linear = xf86AllocateOffscreenLinear(pScreen, size, 4, + NULL, NULL, NULL); + + if(!new_linear) { + int max_size; + + xf86QueryLargestOffscreenLinear(pScreen, &max_size, 4, + PRIORITY_EXTREME); + + if(max_size < size) return NULL; + + xf86PurgeUnlockedOffscreenAreas(pScreen); + new_linear = xf86AllocateOffscreenLinear(pScreen, size, 4, + NULL, NULL, NULL); + } + + R128TRACE(("returning %x(%x)\n",new_linear,new_linear->offset)); + + return new_linear; +} + +static int +R128PutImage( + ScrnInfoPtr pScrn, + short src_x, short src_y, + short drw_x, short drw_y, + short src_w, short src_h, + short drw_w, short drw_h, + int id, unsigned char* buf, + short width, short height, + Bool Sync, + RegionPtr clipBoxes, pointer data +) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + R128PortPrivPtr pPriv = (R128PortPrivPtr)data; + INT32 xa, xb, ya, yb; + INT32 d_x,d_y,d_width,d_height; + int srcPitch = 0, srcPitch2 = 0; + int dstPitch = 0; + int offset,offset2 = 0,offset3 = 0,fboffset; + int top, left, npixels, nlines, size; + CARD32 video_format; + + R128TRACE(("R128PutImage called\n")); + + switch(id) { + case FOURCC_YV12: + case FOURCC_UYVY: + video_format=R128_SCALER_SOURCE_VYUY422; + break; + case FOURCC_YUY2: + video_format=R128_SCALER_SOURCE_YVYU422; + break; + default: + return BadValue; + } + + /* Clip */ + d_x=drw_x; + d_y=drw_y; + d_width=drw_w; + d_height=drw_h; + if(drw_x<0){ + drw_w+=drw_x; + drw_x=0; + } + if(drw_y<0){ + drw_h+=drw_y; + drw_y=0; + } + if(drw_x+drw_w>pScrn->pScreen->width){ + drw_w=pScrn->pScreen->width-drw_x; + } + if(drw_y+drw_h>pScrn->pScreen->height){ + drw_h=pScrn->pScreen->height-drw_y; + } + if((drw_w<=0)||(drw_h<=0)){ + /* this should not happen, + since we are outside of visible screen, + but just in case */ + return Success; + } + + xa = src_x; + xb = src_x + src_w; + ya = src_y; + yb = src_y + src_h; + + dstPitch = width*info->CurrentLayout.pixel_bytes; + srcPitch=width; + + switch(id) { + case FOURCC_YV12: + size = width * height * 2; /* 16bpp */ + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + default: + size = width * height * 1.5; + break; + } + + if(!(pPriv->linear = R128AllocateMemory(pScrn, pPriv->linear,size))) + return BadAlloc; + + /* copy data */ + top = ya >> 16; + left = (xa >> 16) & ~1; + npixels = ((((xb + 0xffff) >> 16) + 1) & ~1) - left; + + switch(id) { + case FOURCC_YV12: + srcPitch = (width + 3) & ~3; + offset2 = srcPitch * height; + srcPitch2 = ((width >> 1) + 3) & ~3; + offset3 = (srcPitch2 * (height >> 1)) + offset2; + nlines = ((((yb + 0xffff) >> 16) + 1) & ~1) - top; + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + default: + buf += (top * srcPitch) + left; + nlines = ((yb + 0xffff) >> 16) - top; + srcPitch = (width << 1); + break; + } + nlines=src_h; + npixels=src_w; + if(npixels>width) npixels=width; + if(nlines>height) nlines=height; + + /* adjust source rectangle */ + src_x+=((drw_x-d_x)*src_w)/d_width; + src_y+=((drw_y-d_y)*src_h)/d_height; + + src_w=(src_w * drw_w)/d_width; + src_h=(src_h * drw_h)/d_height; + + offset=(src_x+src_y*width)*info->CurrentLayout.pixel_bytes; + fboffset=pPriv->linear->offset*info->CurrentLayout.pixel_bytes; + + if(!(INREG(R128_CRTC_STATUS)&2)){ + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"too fast"); + return Success; + } + + R128DisplayVideo(pScrn, width, height, + drw_x, drw_y, drw_x+drw_w, drw_y+drw_h, + src_w, src_h, drw_w, drw_h, fboffset); + + /* update cliplist */ + if(!RegionsEqual(&pPriv->clip, clipBoxes)) { + REGION_COPY(pScreen, &pPriv->clip, clipBoxes); + /* draw these */ + XAAFillSolidRects(pScrn, pPriv->colorKey, GXcopy, ~0, + REGION_NUM_RECTS(clipBoxes), + REGION_RECTS(clipBoxes)); + } + + + switch(id) { + case FOURCC_YV12: + R128CopyMungedData(buf + (top * srcPitch) + (left >> 1), + buf + offset2, buf + offset3, info->FB+fboffset, + srcPitch, srcPitch2, dstPitch, nlines, npixels); + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + default: + R128CopyData(buf,info->FB+fboffset,srcPitch,dstPitch, + nlines,npixels); + break; + } + + pPriv->videoStatus = CLIENT_VIDEO_ON; + return Success; +} + +static int +R128QueryImageAttributes( + ScrnInfoPtr pScrn, + int id, + unsigned short *w, unsigned short *h, + int *pitches, int *offsets +) +{ + int size, tmp; + R128TRACE(("R128QueryImageAtrributes called\n")); + + if(*w > IMAGE_MAX_WIDTH) *w = IMAGE_MAX_WIDTH; + if(*h > IMAGE_MAX_HEIGHT) *h = IMAGE_MAX_HEIGHT; + + *w = (*w + 1) & ~1; + if(offsets) offsets[0] = 0; + + switch(id) { + case FOURCC_YV12: + *h = (*h + 1) & ~1; + size = (*w + 3) & ~3; + if(pitches) pitches[0] = size; + size *= *h; + if(offsets) offsets[1] = size; + tmp = ((*w >> 1) + 3) & ~3; + if(pitches) pitches[1] = pitches[2] = tmp; + tmp *= (*h >> 1); + size += tmp; + if(offsets) offsets[2] = size; + size += tmp; + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + default: + size = *w << 1; + if(pitches) pitches[0] = size; + size *= *h; + break; + } + + return size; +} +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h new file mode 100644 index 000000000..e9b8b37e0 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h @@ -0,0 +1,406 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h,v 1.1 2000/11/02 16:55:40 tsi Exp $ */ +/* + * + * Copyright 2000 ATI Technologies Inc., Markham, Ontario + * and 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 on + * 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Kevin E. Martin <martin@valinux.com> + * Rickard E. Faith <faith@valinux.com> + * + */ + +#ifndef _RADEON_H_ +#define _RADEON_H_ + + /* Xv support */ +#include "xf86xv.h" +#include "Xv.h" + + /* vgahw module (for VC save/restore only) */ +#include "vgaHW.h" + +#include "fbdevhw.h" + + /* XAA and Cursor Support */ +#include "xaa.h" +#include "xaalocal.h" +#include "xf86Cursor.h" + + + /* PCI support */ +#include "xf86PciInfo.h" +#include "xf86Pci.h" + + /* DDC support */ +#include "xf86DDC.h" + + /* VESA support */ +#include "vbe.h" + + /* DRI support */ +#ifdef XF86DRI +#include "GL/glxint.h" +#include "xf86drm.h" +#include "sarea.h" +#define _XF86DRI_SERVER_ +#include "xf86dri.h" +#include "dri.h" +#include "r128_dri.h" +#include "r128_dripriv.h" +#include "r128_sarea.h" +#endif + +#ifdef RENDER +#include "picturestr.h" +#endif + +/* NOTE: Turn off DRI until it is working */ +#ifdef XF86DRI +#undef XF86DRI +#endif + +#define RADEON_DEBUG 0 /* Turn off debugging output */ +#define RADEON_TIMEOUT 2000000 /* Fall out of wait loops after this count */ +#define RADEON_MMIOSIZE 0x80000 +/* Atomic updates of PLL clock don't seem to always work and stick, thus + * the bit never resets. Here - we use our own check by reading back the + * register we've just wrote to make sure it's got the Right! value */ +#define RADEON_ATOMIC_UPDATE 0 /* Use PLL Atomic updates (seems broken) */ + +#define RADEON_VBIOS_SIZE 0x00010000 + +#if RADEON_DEBUG +#define RADEONTRACE(x) \ + do { \ + ErrorF("(**) %s(%d): ", RADEON_NAME, pScrn->scrnIndex); \ + ErrorF x; \ + } while (0); +#else +#define RADEONTRACE(x) +#endif + + +/* Other macros */ +#define RADEON_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) +#define RADEON_ALIGN(x,bytes) (((x) + ((bytes) - 1)) & ~((bytes) - 1)) +#define RADEONPTR(pScrn) ((RADEONInfoPtr)(pScrn)->driverPrivate) + +typedef struct { /* All values in XCLKS */ + int ML; /* Memory Read Latency */ + int MB; /* Memory Burst Length */ + int Trcd; /* RAS to CAS delay */ + int Trp; /* RAS percentage */ + int Twr; /* Write Recovery */ + int CL; /* CAS Latency */ + int Tr2w; /* Read to Write Delay */ + int Rloop; /* Loop Latency */ + int Rloop_fudge; /* Add to ML to get Rloop */ + char *name; +} RADEONRAMRec, *RADEONRAMPtr; + +typedef struct { + /* Common registers */ + CARD32 ovr_clr; + CARD32 ovr_wid_left_right; + CARD32 ovr_wid_top_bottom; + CARD32 ov0_scale_cntl; + CARD32 mpp_tb_config; + CARD32 mpp_gp_config; + CARD32 subpic_cntl; + CARD32 viph_control; + CARD32 i2c_cntl_1; + CARD32 gen_int_cntl; + CARD32 cap0_trig_cntl; + CARD32 cap1_trig_cntl; + CARD32 bus_cntl; + + /* Other registers to save for VT switches */ + CARD32 dp_datatype; + CARD32 rbbm_soft_reset; + CARD32 clock_cntl_index; + CARD32 amcgpio_en_reg; + CARD32 amcgpio_mask; + + /* CRTC registers */ + CARD32 crtc_gen_cntl; + CARD32 crtc_ext_cntl; + CARD32 dac_cntl; + CARD32 crtc_h_total_disp; + CARD32 crtc_h_sync_strt_wid; + CARD32 crtc_v_total_disp; + CARD32 crtc_v_sync_strt_wid; + CARD32 crtc_offset; + CARD32 crtc_offset_cntl; + CARD32 crtc_pitch; + + /* CRTC2 registers */ + CARD32 crtc2_gen_cntl; + + /* Flat panel registers */ + CARD32 fp_crtc_h_total_disp; + CARD32 fp_crtc_v_total_disp; + CARD32 fp_gen_cntl; + CARD32 fp_h_sync_strt_wid; + CARD32 fp_horz_stretch; + CARD32 fp_panel_cntl; + CARD32 fp_v_sync_strt_wid; + CARD32 fp_vert_stretch; + CARD32 lvds_gen_cntl; + CARD32 tmds_crc; + + /* Computed values for PLL */ + CARD32 dot_clock_freq; + CARD32 pll_output_freq; + int feedback_div; + int post_div; + + /* PLL registers */ + CARD32 ppll_ref_div; + CARD32 ppll_div_3; + CARD32 htotal_cntl; + + /* DDA register */ + CARD32 dda_config; + CARD32 dda_on_off; + + /* Pallet */ + Bool palette_valid; + CARD32 palette[256]; +} RADEONSaveRec, *RADEONSavePtr; + +typedef struct { + CARD16 reference_freq; + CARD16 reference_div; + CARD32 min_pll_freq; + CARD32 max_pll_freq; + CARD16 xclk; +} RADEONPLLRec, *RADEONPLLPtr; + +typedef struct { + int bitsPerPixel; + int depth; + int displayWidth; + int pixel_code; + int pixel_bytes; + DisplayModePtr mode; +} RADEONFBLayout; + +typedef struct { + EntityInfoPtr pEnt; + pciVideoPtr PciInfo; + PCITAG PciTag; + int Chipset; + Bool Primary; + + Bool FBDev; + + unsigned long LinearAddr; /* Frame buffer physical address */ + unsigned long MMIOAddr; /* MMIO region physical address */ + unsigned long BIOSAddr; /* BIOS physical address */ + Bool BIOSFromPCI; /* BIOS is read from PCI space */ + + unsigned char *MMIO; /* Map of MMIO region */ + unsigned char *FB; /* Map of frame buffer */ + CARD8 *VBIOS; /* Video BIOS pointer */ + + CARD32 MemCntl; + CARD32 BusCntl; + unsigned long FbMapSize; /* Size of frame buffer, in bytes */ + int Flags; /* Saved copy of mode flags */ + +#ifdef ENABLE_FLAT_PANEL + Bool HasPanelRegs; /* Current chip can connect to a FP */ + Bool CRTOnly; /* Only use External CRT instead of FP */ + int FPBIOSstart; /* Start of the flat panel info */ + + /* Computed values for FPs */ + int PanelXRes; + int PanelYRes; + int PanelPwrDly; +#endif + + RADEONPLLRec pll; + RADEONRAMPtr ram; + + RADEONSaveRec SavedReg; /* Original (text) mode */ + RADEONSaveRec ModeReg; /* Current mode */ + Bool (*CloseScreen)(int, ScreenPtr); + + Bool PaletteSavedOnVT; /* Palette saved on last VT switch */ + + XAAInfoRecPtr accel; + Bool accelOn; + xf86CursorInfoPtr cursor; + unsigned long cursor_start; + unsigned long cursor_end; + + int fifo_slots; /* Free slots in the FIFO (64 max) */ + int pix24bpp; /* Depth of pixmap for 24bpp framebuffer */ + Bool dac6bits; /* Use 6 bit DAC? */ + + /* Computed values for Radeon */ + int pitch; + int datatype; + CARD32 dp_gui_master_cntl; + + /* Saved values for ScreenToScreenCopy */ + int xdir; + int ydir; + + /* ScanlineScreenToScreenColorExpand support */ + unsigned char *scratch_buffer[1]; + unsigned char *scratch_save; + int scanline_x; + int scanline_y; + int scanline_h; + int scanline_h_w; + int scanline_words; + int scanline_direct; + int scanline_bpp; /* Only used for ImageWrite */ + + DGAModePtr DGAModes; + int numDGAModes; + Bool DGAactive; + int DGAViewportStatus; + + RADEONFBLayout CurrentLayout; +#ifdef XF86DRI + Bool directRenderingEnabled; + DRIInfoPtr pDRIInfo; + int drmFD; + int numVisualConfigs; + __GLXvisualConfig *pVisualConfigs; + RADEONConfigPrivPtr pVisualConfigsPriv; + + drmHandle fbHandle; + + drmSize registerSize; + drmHandle registerHandle; + + Bool IsPCI; /* Current card is a PCI card */ + + drmSize agpSize; + drmHandle agpMemHandle; /* Handle from drmAgpAlloc */ + unsigned long agpOffset; + unsigned char *AGP; /* Map */ + int agpMode; + + Bool CPInUse; /* CP is currently active */ + int CPMode; /* CP mode that server/clients use */ + int CPFifoSize; /* Size of the CP command FIFO */ + Bool CPSecure; /* CP security enabled */ + int CPusecTimeout; /* CP timeout in usecs */ + Bool CP2D; /* CP is used for X server 2D prims */ + + /* CP ring buffer data */ + unsigned long ringStart; /* Offset into AGP space */ + drmHandle ringHandle; /* Handle from drmAddMap */ + drmSize ringMapSize; /* Size of map */ + int ringSize; /* Size of ring (in MB) */ + unsigned char *ring; /* Map */ + int ringSizeLog2QW; + + unsigned long ringReadOffset; /* Offset into AGP space */ + drmHandle ringReadPtrHandle; /* Handle from drmAddMap */ + drmSize ringReadMapSize; /* Size of map */ + unsigned char *ringReadPtr; /* Map */ + + /* CP vertex buffer data */ + unsigned long vbStart; /* Offset into AGP space */ + drmHandle vbHandle; /* Handle from drmAddMap */ + drmSize vbMapSize; /* Size of map */ + int vbSize; /* Size of vert bufs (in MB) */ + unsigned char *vb; /* Map */ + int vbBufSize; /* Size of individual vert buf */ + int vbNumBufs; /* Number of vert bufs */ + drmBufMapPtr vbBufs; /* Buffer map */ + + /* CP indirect buffer data */ + unsigned long indStart; /* Offset into AGP space */ + drmHandle indHandle; /* Handle from drmAddMap */ + drmSize indMapSize; /* Size of map */ + int indSize; /* Size of indirect bufs (in MB) */ + unsigned char *ind; /* Map */ + + /* CP AGP Texture data */ + unsigned long agpTexStart; /* Offset into AGP space */ + drmHandle agpTexHandle; /* Handle from drmAddMap */ + drmSize agpTexMapSize; /* Size of map */ + int agpTexSize; /* Size of AGP tex space (in MB) */ + unsigned char *agpTex; /* Map */ + int log2AGPTexGran; + + /* DRI screen private data */ + int fbX; + int fbY; + int backX; + int backY; + int depthX; + int depthY; + int textureX; + int textureY; + int textureSize; + int log2TexGran; +#endif + XF86VideoAdaptorPtr adaptor; +} RADEONInfoRec, *RADEONInfoPtr; + +#define RADEONWaitForFifo(pScrn, entries) \ +do { \ + if (info->fifo_slots < entries) \ + RADEONWaitForFifoFunction(pScrn, entries); \ + info->fifo_slots -= entries; \ +} while (0) + +extern void RADEONWaitForFifoFunction(ScrnInfoPtr pScrn, int entries); +extern void RADEONWaitForIdle(ScrnInfoPtr pScrn); +extern void RADEONEngineReset(ScrnInfoPtr pScrn); +extern void RADEONEngineFlush(ScrnInfoPtr pScrn); + +extern unsigned RADEONINPLL(ScrnInfoPtr pScrn, int addr); +extern void RADEONWaitForVerticalSync(ScrnInfoPtr pScrn); + +extern Bool RADEONAccelInit(ScreenPtr pScreen); +extern void RADEONEngineInit(ScrnInfoPtr pScrn); +extern Bool RADEONCursorInit(ScreenPtr pScreen); +extern Bool RADEONDGAInit(ScreenPtr pScreen); + +extern int RADEONMinBits(int val); + +extern void RADEONInitVideo(ScreenPtr); + +#ifdef XF86DRI +extern Bool RADEONDRIScreenInit(ScreenPtr pScreen); +extern void RADEONDRICloseScreen(ScreenPtr pScreen); +extern Bool RADEONDRIFinishScreenInit(ScreenPtr pScreen); +extern void RADEONCPStart(ScrnInfoPtr pScrn); +extern void RADEONCPStop(ScrnInfoPtr pScrn); +extern void RADEONCPResetRing(ScrnInfoPtr pScrn); +extern void RADEONCPWaitForIdle(ScrnInfoPtr pScrn); +#endif + +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c new file mode 100644 index 000000000..985137eb3 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c @@ -0,0 +1,972 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c,v 1.2 2000/11/03 09:52:54 alanh Exp $ */ +/* + * Copyright 2000 ATI Technologies Inc., Markham, Ontario + * and 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 on + * 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Kevin E. Martin <martin@valinux.com> + * Rickard E. Faith <faith@valinux.com> + * Alan Hourihane <ahourihane@valinux.com> + * + * Credits: + * + * Thanks to Ani Joshi <ajoshi@shell.unixbox.com> for providing source + * code to his Radeon driver. Portions of this file are based on the + * initialization code for that driver. + * + * References: + * + * !!!! FIXME !!!! + * RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical + * Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April + * 1999. + * + * RAGE 128 Software Development Manual (Technical Reference Manual P/N + * SDK-G04000 Rev. 0.01), ATI Technologies: June 1999. + * + * Notes on unimplemented XAA optimizations: + * + * SetClipping: This has been removed as XAA expects 16bit registers + * for full clipping. + * TwoPointLine: The Radeon supports this. Not Bresenham. + * DashedLine with non-power-of-two pattern length: Apparently, there is + * no way to set the length of the pattern -- it is always + * assumed to be 8 or 32 (or 1024?). + * ScreenToScreenColorExpandFill: See p. 4-17 of the Technical Reference + * Manual where it states that monochrome expansion of frame + * buffer data is not supported. + * CPUToScreenColorExpandFill, direct: The implementation here uses a hybrid + * direct/indirect method. If we had more data registers, + * then we could do better. If XAA supported a trigger write + * address, the code would be simpler. + * Color8x8PatternFill: Apparently, an 8x8 color brush cannot take an 8x8 + * pattern from frame buffer memory. + * ImageWrites: Same as CPUToScreenColorExpandFill + * + */ + +#define RADEON_IMAGEWRITE 0 /* Turned off by default - slower in accel */ + + /* X and server generic header files */ +#include "Xarch.h" +#include "xf86.h" +#include "xf86_ansic.h" +#include "xf86_OSproc.h" +#include "xf86fbman.h" + + /* Line support */ +#include "miline.h" + + /* Driver data structures */ +#include "radeon.h" +#include "radeon_reg.h" + +static struct { + int rop; + int pattern; +} RADEON_ROP[] = { + { RADEON_ROP3_ZERO, RADEON_ROP3_ZERO }, /* GXclear */ + { RADEON_ROP3_DSa, RADEON_ROP3_DPa }, /* Gxand */ + { RADEON_ROP3_SDna, RADEON_ROP3_PDna }, /* GXandReverse */ + { RADEON_ROP3_S, RADEON_ROP3_P }, /* GXcopy */ + { RADEON_ROP3_DSna, RADEON_ROP3_DPna }, /* GXandInverted */ + { RADEON_ROP3_D, RADEON_ROP3_D }, /* GXnoop */ + { RADEON_ROP3_DSx, RADEON_ROP3_DPx }, /* GXxor */ + { RADEON_ROP3_DSo, RADEON_ROP3_DPo }, /* GXor */ + { RADEON_ROP3_DSon, RADEON_ROP3_DPon }, /* GXnor */ + { RADEON_ROP3_DSxn, RADEON_ROP3_PDxn }, /* GXequiv */ + { RADEON_ROP3_Dn, RADEON_ROP3_Dn }, /* GXinvert */ + { RADEON_ROP3_SDno, RADEON_ROP3_PDno }, /* GXorReverse */ + { RADEON_ROP3_Sn, RADEON_ROP3_Pn }, /* GXcopyInverted */ + { RADEON_ROP3_DSno, RADEON_ROP3_DPno }, /* GXorInverted */ + { RADEON_ROP3_DSan, RADEON_ROP3_DPan }, /* GXnand */ + { RADEON_ROP3_ONE, RADEON_ROP3_ONE } /* GXset */ +}; + +/* Flush all dirty data in the Pixel Cache to memory. */ +void RADEONEngineFlush(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int i; + + OUTREGP(RADEON_RB2D_DSTCACHE_CTLSTAT, RADEON_RB2D_DC_FLUSH_ALL, + ~RADEON_RB2D_DC_FLUSH_ALL); + for (i = 0; i < RADEON_TIMEOUT; i++) { + if (!(INREG(RADEON_RB2D_DSTCACHE_CTLSTAT) & RADEON_RB2D_DC_BUSY)) break; + } +} + +/* Reset graphics card to known state. */ +void RADEONEngineReset(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + CARD32 clock_cntl_index; + CARD32 mclk_cntl; + CARD32 rbbm_soft_reset; + + RADEONEngineFlush(pScrn); + + clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX); + mclk_cntl = INPLL(pScrn, RADEON_MCLK_CNTL); + + OUTPLL(RADEON_MCLK_CNTL, (mclk_cntl | 0x003f0000)); + + rbbm_soft_reset = INREG(RADEON_RBBM_SOFT_RESET); + + OUTREG(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset | + RADEON_SOFT_RESET_CP | + RADEON_SOFT_RESET_HI | + RADEON_SOFT_RESET_SE | + RADEON_SOFT_RESET_RE | + RADEON_SOFT_RESET_PP | + RADEON_SOFT_RESET_E2 | + RADEON_SOFT_RESET_RB | + RADEON_SOFT_RESET_HDP); + INREG(RADEON_RBBM_SOFT_RESET); + OUTREG(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset & + ~(RADEON_SOFT_RESET_CP | + RADEON_SOFT_RESET_HI | + RADEON_SOFT_RESET_SE | + RADEON_SOFT_RESET_RE | + RADEON_SOFT_RESET_PP | + RADEON_SOFT_RESET_E2 | + RADEON_SOFT_RESET_RB | + RADEON_SOFT_RESET_HDP)); + INREG(RADEON_RBBM_SOFT_RESET); + + OUTPLL(RADEON_MCLK_CNTL, mclk_cntl); + OUTREG(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index); + OUTREG(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset); + +#ifdef XF86DRI + if (RADEONCP_USE_RING_BUFFER(info->CPMode)) RADEONCPResetRing(pScrn); +#endif +} + +/* The FIFO has 64 slots. This routines waits until at least `entries' of + these slots are empty. */ +void RADEONWaitForFifoFunction(ScrnInfoPtr pScrn, int entries) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int i; + + for (;;) { + for (i = 0; i < RADEON_TIMEOUT; i++) { + info->fifo_slots = + INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK; + if (info->fifo_slots >= entries) return; + } + RADEONTRACE(("FIFO timed out: %d entries, stat=0x%08x\n", + INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK, + INREG(RADEON_RBBM_STATUS))); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "FIFO timed out, resetting engine...\n"); + RADEONEngineReset(pScrn); +#ifdef XF86DRI + if (info->CP2D) RADEONCPStart(pScrn); +#endif + } +} + +/* Wait for the graphics engine to be completely idle: the FIFO has + drained, the Pixel Cache is flushed, and the engine is idle. This is a + standard "sync" function that will make the hardware "quiescent". */ +void RADEONWaitForIdle(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int i; + + RADEONTRACE(("WaitForIdle (entering): %d entries, stat=0x%08x\n", + INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK, + INREG(RADEON_RBBM_STATUS))); + + RADEONWaitForFifoFunction(pScrn, 64); + + for (;;) { + for (i = 0; i < RADEON_TIMEOUT; i++) { + if (!(INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_ACTIVE)) { + RADEONEngineFlush(pScrn); + return; + } + } + RADEONTRACE(("Idle timed out: %d entries, stat=0x%08x\n", + INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK, + INREG(RADEON_RBBM_STATUS))); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Idle timed out, resetting engine...\n"); + RADEONEngineReset(pScrn); +#ifdef XF86DRI + if (info->CP2D) RADEONCPStart(pScrn); +#endif + } +} + +/* Setup for XAA SolidFill. */ +static void RADEONSetupForSolidFill(ScrnInfoPtr pScrn, + int color, int rop, unsigned int planemask) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + RADEONWaitForFifo(pScrn, 4); + OUTREG(RADEON_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | RADEON_GMC_BRUSH_SOLID_COLOR + | RADEON_GMC_SRC_DATATYPE_COLOR + | RADEON_ROP[rop].pattern)); + OUTREG(RADEON_DP_BRUSH_FRGD_CLR, color); + OUTREG(RADEON_DP_WRITE_MASK, planemask); + OUTREG(RADEON_DP_CNTL, (RADEON_DST_X_LEFT_TO_RIGHT + | RADEON_DST_Y_TOP_TO_BOTTOM)); +} + +/* Subsequent XAA SolidFillRect. + + Tests: xtest CH06/fllrctngl, xterm +*/ +static void RADEONSubsequentSolidFillRect(ScrnInfoPtr pScrn, + int x, int y, int w, int h) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + RADEONWaitForFifo(pScrn, 2); + OUTREG(RADEON_DST_Y_X, (y << 16) | x); + OUTREG(RADEON_DST_WIDTH_HEIGHT, (w << 16) | h); +} + +/* Setup for XAA solid lines. */ +static void RADEONSetupForSolidLine(ScrnInfoPtr pScrn, + int color, int rop, unsigned int planemask) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + RADEONWaitForFifo(pScrn, 3); + OUTREG(RADEON_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | RADEON_GMC_BRUSH_SOLID_COLOR + | RADEON_GMC_SRC_DATATYPE_COLOR + | RADEON_ROP[rop].pattern)); + OUTREG(RADEON_DP_BRUSH_FRGD_CLR, color); + OUTREG(RADEON_DP_WRITE_MASK, planemask); +} + + +/* Subsequent XAA solid TwoPointLine line. + + Tests: xtest CH06/drwln, ico, Mark Vojkovich's linetest program + + [See http://www.xfree86.org/devel/archives/devel/1999-Jun/0102.shtml for + Mark Vojkovich's linetest program, posted 2Jun99 to devel@xfree86.org.] +*/ +static void RADEONSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, + int xa, int ya, int xb, int yb, + int flags) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int direction = 0; + + if (xa < xb) direction |= RADEON_DST_X_DIR_LEFT_TO_RIGHT; + if (ya < yb) direction |= RADEON_DST_Y_DIR_TOP_TO_BOTTOM; + + RADEONWaitForFifo(pScrn, 4); + OUTREG(RADEON_DST_Y_X, (ya << 16) | xa); + if (!(flags & OMIT_LAST)) + OUTREG(RADEON_DP_CNTL_XDIR_YDIR_YMAJOR, direction); + OUTREG(RADEON_DST_LINE_START, (ya << 16) | xa); + OUTREG(RADEON_DST_LINE_END, (yb << 16) | xb); +} + +/* Subsequent XAA solid horizontal and vertical lines */ +static void RADEONSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, + int x, int y, int len, int dir ) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + RADEONWaitForFifo(pScrn, 1); + OUTREG(RADEON_DP_CNTL, (RADEON_DST_X_LEFT_TO_RIGHT + | RADEON_DST_Y_TOP_TO_BOTTOM)); + + if (dir == DEGREES_0) { + RADEONSubsequentSolidFillRect(pScrn, x, y, len, 1); + } else { + RADEONSubsequentSolidFillRect(pScrn, x, y, 1, len); + } +} + +/* Setup for XAA dashed lines. + + Tests: xtest CH05/stdshs, XFree86/drwln + + NOTE: Since we can only accelerate lines with power-of-2 patterns of + length <= 32. +*/ +static void RADEONSetupForDashedLine(ScrnInfoPtr pScrn, + int fg, int bg, + int rop, unsigned int planemask, + int length, unsigned char *pattern) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + CARD32 pat = *(CARD32 *)pattern; + + switch (length) { + case 2: pat |= pat << 2; /* fall through */ + case 4: pat |= pat << 4; /* fall through */ + case 8: pat |= pat << 8; /* fall through */ + case 16: pat |= pat << 16; + } + + RADEONWaitForFifo(pScrn, 5); + OUTREG(RADEON_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | (bg == -1 + ? RADEON_GMC_BRUSH_32x1_MONO_FG_LA + : RADEON_GMC_BRUSH_32x1_MONO_FG_BG) + | RADEON_ROP[rop].pattern + | RADEON_GMC_BYTE_LSB_TO_MSB)); + OUTREG(RADEON_DP_WRITE_MASK, planemask); + OUTREG(RADEON_DP_BRUSH_FRGD_CLR, fg); + OUTREG(RADEON_DP_BRUSH_BKGD_CLR, bg); + OUTREG(RADEON_BRUSH_DATA0, pat); +} + +/* Subsequent XAA dashed line. */ +static void RADEONSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn, + int xa, int ya, + int xb, int yb, + int flags, + int phase) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int direction = 0; + + if (xa < xb) direction |= RADEON_DST_X_DIR_LEFT_TO_RIGHT; + if (ya < yb) direction |= RADEON_DST_Y_DIR_TOP_TO_BOTTOM; + + RADEONWaitForFifo(pScrn, 5); + if (!(flags & OMIT_LAST)) + OUTREG(RADEON_DP_CNTL_XDIR_YDIR_YMAJOR, direction); + OUTREG(RADEON_DST_Y_X, (ya << 16) | xa); + OUTREG(RADEON_BRUSH_Y_X, (phase << 16) | phase); + OUTREG(RADEON_DST_LINE_START, (ya << 16) | xa); + OUTREG(RADEON_DST_LINE_END, (yb << 16) | xb); +} + +/* Setup for XAA screen-to-screen copy. + + Tests: xtest CH06/fllrctngl (also tests transparency). +*/ +static void RADEONSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, + int xdir, int ydir, int rop, + unsigned int planemask, + int trans_color) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + info->xdir = xdir; + info->ydir = ydir; + RADEONWaitForFifo(pScrn, 3); + OUTREG(RADEON_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | RADEON_GMC_BRUSH_NONE + | RADEON_GMC_SRC_DATATYPE_COLOR + | RADEON_ROP[rop].rop + | RADEON_DP_SRC_SOURCE_MEMORY)); + OUTREG(RADEON_DP_WRITE_MASK, planemask); + OUTREG(RADEON_DP_CNTL, ((xdir >= 0 + ? RADEON_DST_X_LEFT_TO_RIGHT + : 0) + | (ydir >= 0 + ? RADEON_DST_Y_TOP_TO_BOTTOM + : 0))); + + if (trans_color != -1) { + /* Set up for transparency */ + RADEONWaitForFifo(pScrn, 3); + OUTREG(RADEON_CLR_CMP_CLR_SRC, trans_color); + OUTREG(RADEON_CLR_CMP_MASK, RADEON_CLR_CMP_MSK); + /* Mmmm, Seems as though the transparency compare is opposite to r128 + * It should only draw when source != trans_color, + * this is the opposite of that. */ + OUTREG(RADEON_CLR_CMP_CNTL, (RADEON_SRC_CMP_EQ_COLOR + | RADEON_CLR_CMP_SRC_SOURCE)); + } +} + +/* Subsequent XAA screen-to-screen copy. */ +static void RADEONSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, + int xa, int ya, + int xb, int yb, + int w, int h) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + if (info->xdir < 0) xa += w - 1, xb += w - 1; + if (info->ydir < 0) ya += h - 1, yb += h - 1; + + RADEONWaitForFifo(pScrn, 3); + OUTREG(RADEON_SRC_Y_X, (ya << 16) | xa); + OUTREG(RADEON_DST_Y_X, (yb << 16) | xb); + OUTREG(RADEON_DST_HEIGHT_WIDTH, (h << 16) | w); +} + +/* Setup for XAA mono 8x8 pattern color expansion. Patterns with + transparency use `bg == -1'. This routine is only used if the XAA + pixmap cache is turned on. + + Tests: xtest XFree86/fllrctngl (no other test will test this routine with + both transparency and non-transparency) +*/ +static void RADEONSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, + int patternx, int patterny, + int fg, int bg, int rop, + unsigned int planemask) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + RADEONWaitForFifo(pScrn, 6); + OUTREG(RADEON_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | (bg == -1 + ? RADEON_GMC_BRUSH_8X8_MONO_FG_LA + : RADEON_GMC_BRUSH_8X8_MONO_FG_BG) + | RADEON_ROP[rop].pattern + | RADEON_GMC_BYTE_LSB_TO_MSB)); + OUTREG(RADEON_DP_WRITE_MASK, planemask); + OUTREG(RADEON_DP_BRUSH_FRGD_CLR, fg); + OUTREG(RADEON_DP_BRUSH_BKGD_CLR, bg); + OUTREG(RADEON_BRUSH_DATA0, patternx); + OUTREG(RADEON_BRUSH_DATA1, patterny); +} + +/* Subsequent XAA 8x8 pattern color expansion. Because they are used in + the setup function, `patternx' and `patterny' are not used here. */ +static void RADEONSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, + int patternx, int patterny, + int x, int y, int w, int h) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + RADEONWaitForFifo(pScrn, 3); + OUTREG(RADEON_BRUSH_Y_X, (patterny << 8) | patternx); + OUTREG(RADEON_DST_Y_X, (y << 16) | x); + OUTREG(RADEON_DST_HEIGHT_WIDTH, (h << 16) | w); +} + +#if 0 +/* Setup for XAA color 8x8 pattern fill. + + Tests: xtest XFree86/fllrctngl (with Mono8x8PatternFill off) +*/ +static void RADEONSetupForColor8x8PatternFill(ScrnInfoPtr pScrn, + int patx, int paty, + int rop, unsigned int planemask, + int trans_color) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + ErrorF("Color8x8 %d %d %d\n", trans_color, patx, paty); + + RADEONWaitForFifo(pScrn, 3); + OUTREG(RADEON_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | RADEON_GMC_BRUSH_8x8_COLOR + | RADEON_GMC_SRC_DATATYPE_COLOR + | RADEON_ROP[rop].pattern + | RADEON_DP_SRC_SOURCE_MEMORY)); + OUTREG(RADEON_DP_WRITE_MASK, planemask); + OUTREG(RADEON_SRC_Y_X, (paty << 16) | patx); + + if (trans_color != -1) { + /* Set up for transparency */ + RADEONWaitForFifo(pScrn, 3); + OUTREG(RADEON_CLR_CMP_CLR_SRC, trans_color); + OUTREG(RADEON_CLR_CMP_MASK, RADEON_CLR_CMP_MSK); + /* Mmmm, Seems as though the transparency compare is opposite to r128 + * It should only draw when source != trans_color, + * this is the opposite of that. */ + OUTREG(RADEON_CLR_CMP_CNTL, (RADEON_SRC_CMP_EQ_COLOR + | RADEON_CLR_CMP_SRC_SOURCE)); + } +} + +/* Subsequent XAA 8x8 pattern color expansion. */ +static void RADEONSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn, + int patx, int paty, + int x, int y, int w, int h) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + ErrorF("Color8x8 %d,%d %d,%d %d %d\n", patx, paty, x, y, w, h); + + RADEONWaitForFifo(pScrn, 4); + OUTREG(RADEON_BRUSH_Y_X, (paty << 16) | patx); + OUTREG(RADEON_DST_Y_X, (y << 16) | x); + OUTREG(RADEON_DST_HEIGHT_WIDTH, (h << 16) | w); +} +#endif + +/* Setup for XAA indirect CPU-to-screen color expansion (indirect). + Because of how the scratch buffer is initialized, this is really a + mainstore-to-screen color expansion. Transparency is supported when `bg + == -1'. + Implementing the hybrid indirect/direct scheme improved performance in a + few areas: +*/ +static void RADEONSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int fg, int bg, + int rop, + unsigned int + planemask) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + RADEONWaitForFifo(pScrn, 4); + OUTREG(RADEON_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | RADEON_GMC_DST_CLIPPING + | RADEON_GMC_BRUSH_NONE + | (bg == -1 + ? RADEON_GMC_SRC_DATATYPE_MONO_FG_LA + : RADEON_GMC_SRC_DATATYPE_MONO_FG_BG) + | RADEON_ROP[rop].rop + | RADEON_GMC_BYTE_LSB_TO_MSB + | RADEON_DP_SRC_SOURCE_HOST_DATA)); + OUTREG(RADEON_DP_WRITE_MASK, planemask); + OUTREG(RADEON_DP_SRC_FRGD_CLR, fg); + OUTREG(RADEON_DP_SRC_BKGD_CLR, bg); +} + +/* Subsequent XAA indirect CPU-to-screen color expansion. This is only + called once for each rectangle. */ +static void RADEONSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr + pScrn, + int x, int y, + int w, int h, + int skipleft) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + info->scanline_h = h; + info->scanline_words = (w + 31) >> 5; + + if ((info->scanline_words * h) <= 9) { + /* Turn on direct for less than 9 dword colour expansion */ + info->scratch_buffer[0] + = (unsigned char *)(ADDRREG(RADEON_HOST_DATA_LAST) + - (info->scanline_words - 1)); + info->scanline_direct = 1; + } else { + /* Use indirect for anything else */ + info->scratch_buffer[0] = info->scratch_save; + info->scanline_direct = 0; + } + + RADEONWaitForFifo(pScrn, 4 + (info->scanline_direct ? + (info->scanline_words * h) : 0) ); + OUTREG(RADEON_SC_TOP_LEFT, (y << 16) | ((x+skipleft) & 0xffff)); + /* MMmm, we don't need the -1 on both y+h or x+w, why ? */ + OUTREG(RADEON_SC_BOTTOM_RIGHT, ((y+h) << 16) | ((x+w) & 0xffff)); + OUTREG(RADEON_DST_Y_X, (y << 16) | (x & 0xffff)); + /* Have to pad the width here and use clipping engine */ + OUTREG(RADEON_DST_HEIGHT_WIDTH, (h << 16) | ((w + 31) & ~31)); +} + +/* Subsequent XAA indirect CPU-to-screen color expandion. This is called + once for each scanline. */ +static void RADEONSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + CARD32 *p = (CARD32 *)info->scratch_buffer[bufno]; + int i; + int left = info->scanline_words; + volatile CARD32 *d; + + if (info->scanline_direct) return; + --info->scanline_h; + while (left) { + if (left <= 8) { + /* Last scanline - finish write to DATA_LAST */ + if (info->scanline_h == 0) { + RADEONWaitForFifo(pScrn, left); + /* Unrolling doesn't improve performance */ + for (d = ADDRREG(RADEON_HOST_DATA_LAST) - (left - 1); left; --left) + *d++ = *p++; + return; + } else { + RADEONWaitForFifo(pScrn, left); + /* Unrolling doesn't improve performance */ + for (d = ADDRREG(RADEON_HOST_DATA7) - (left - 1); left; --left) + *d++ = *p++; + } + } else { + RADEONWaitForFifo(pScrn, 8); + /* Unrolling doesn't improve performance */ + for (d = ADDRREG(RADEON_HOST_DATA0), i = 0; i < 8; i++) + *d++ = *p++; + left -= 8; + } + } +} + +#if RADEON_IMAGEWRITE +/* Setup for XAA indirect image write. */ +static void RADEONSetupForScanlineImageWrite(ScrnInfoPtr pScrn, + int rop, + unsigned int planemask, + int trans_color, + int bpp, + int depth) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + info->scanline_bpp = bpp; + + RADEONWaitForFifo(pScrn, 2); + OUTREG(RADEON_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | RADEON_GMC_DST_CLIPPING + | RADEON_GMC_BRUSH_NONE + | RADEON_GMC_SRC_DATATYPE_COLOR + | RADEON_ROP[rop].rop + | RADEON_GMC_BYTE_LSB_TO_MSB + | RADEON_DP_SRC_SOURCE_HOST_DATA)); + OUTREG(RADEON_DP_WRITE_MASK, planemask); + + if (trans_color != -1) { + /* Set up for transparency */ + RADEONWaitForFifo(pScrn, 3); + OUTREG(RADEON_CLR_CMP_CLR_SRC, trans_color); + OUTREG(RADEON_CLR_CMP_MASK, RADEON_CLR_CMP_MSK); + /* Mmmm, Seems as though the transparency compare is opposite to r128 + * It should only draw when source != trans_color, + * this is the opposite of that. */ + OUTREG(RADEON_CLR_CMP_CNTL, (RADEON_SRC_CMP_EQ_COLOR + | RADEON_CLR_CMP_SRC_SOURCE)); + } +} + +/* Subsequent XAA indirect image write. This is only called once for each + rectangle. */ +static void RADEONSubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn, + int x, int y, + int w, int h, + int skipleft) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int shift = 0; /* 32bpp */ + + if (pScrn->bitsPerPixel == 8) shift = 3; + else if (pScrn->bitsPerPixel == 16) shift = 1; + + info->scanline_h = h; + info->scanline_words = (w * info->scanline_bpp + 31) >> 5; + + if ((info->scanline_words * h) <= 9) { + /* Turn on direct for less than 9 dword colour expansion */ + info->scratch_buffer[0] + = (unsigned char *)(ADDRREG(RADEON_HOST_DATA_LAST) + - (info->scanline_words - 1)); + info->scanline_direct = 1; + } else { + /* Use indirect for anything else */ + info->scratch_buffer[0] = info->scratch_save; + info->scanline_direct = 0; + } + + RADEONWaitForFifo(pScrn, 4 + (info->scanline_direct ? + (info->scanline_words * h) : 0) ); + OUTREG(RADEON_SC_TOP_LEFT, (y << 16) | ((x+skipleft) & 0xffff)); + /* MMmm, we don't need the -1 on both y+h or x+w, why ? */ + OUTREG(RADEON_SC_BOTTOM_RIGHT, ((y+h) << 16) | ((x+w) & 0xffff)); + OUTREG(RADEON_DST_Y_X, (y << 16) | (x & 0xffff)); + /* Have to pad the width here and use clipping engine */ + OUTREG(RADEON_DST_HEIGHT_WIDTH, (h << 16) | ((w + shift) & ~shift)); +} + +/* Subsequent XAA indirect image write. This is called once for each + scanline. */ +static void RADEONSubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + CARD32 *p = (CARD32 *)info->scratch_buffer[bufno]; + int i; + int left = info->scanline_words; + volatile CARD32 *d; + + if (info->scanline_direct) return; + --info->scanline_h; + while (left) { + if (left <= 8) { + /* Last scanline - finish write to DATA_LAST */ + if (info->scanline_h == 0) { + RADEONWaitForFifo(pScrn, left); + /* Unrolling doesn't improve performance */ + for (d = ADDRREG(RADEON_HOST_DATA_LAST) - (left - 1); left; --left) + *d++ = *p++; + return; + } else { + RADEONWaitForFifo(pScrn, left); + /* Unrolling doesn't improve performance */ + for (d = ADDRREG(RADEON_HOST_DATA7) - (left - 1); left; --left) + *d++ = *p++; + } + } else { + RADEONWaitForFifo(pScrn, 8); + /* Unrolling doesn't improve performance */ + for (d = ADDRREG(RADEON_HOST_DATA0), i = 0; i < 8; i++) + *d++ = *p++; + left -= 8; + } + } +} +#endif + +/* Initialize the acceleration hardware. */ +void RADEONEngineInit(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int pitch64; + + RADEONTRACE(("EngineInit (%d/%d)\n", + info->CurrentLayout.pixel_code, + info->CurrentLayout.bitsPerPixel)); + + OUTREG(RADEON_SCALE_3D_CNTL, 0); + RADEONEngineReset(pScrn); + + RADEONWaitForFifo(pScrn, 1); + /* turn of all automatic flushing - we'll do it all */ + OUTREG(RADEON_RB2D_DSTCACHE_MODE, 0); + + switch (info->CurrentLayout.pixel_code) { + case 8: info->datatype = 2; break; + case 15: info->datatype = 3; break; + case 16: info->datatype = 4; break; + case 24: info->datatype = 5; break; + case 32: info->datatype = 6; break; + default: + RADEONTRACE(("Unknown depth/bpp = %d/%d (code = %d)\n", + info->CurrentLayout.depth, + info->CurrentLayout.bitsPerPixel, + info->CurrentLayout.pixel_code)); + } + info->pitch = ((info->CurrentLayout.displayWidth / 8) * + (info->CurrentLayout.pixel_bytes == 3 ? 3 : 1)); + + RADEONTRACE(("Pitch for acceleration = %d\n", info->pitch)); + + pitch64 = ((pScrn->displayWidth * (pScrn->bitsPerPixel / 8) + 0x3f)) >> 6; + + RADEONWaitForFifo(pScrn, 1); + OUTREG(RADEON_DEFAULT_OFFSET, (INREG(RADEON_DEFAULT_OFFSET) & 0xC0000000) | + (pitch64 << 22)); + + RADEONWaitForFifo(pScrn, 1); +#if X_BYTE_ORDER == X_BIG_ENDIAN + OUTREGP(RADEON_DP_DATATYPE, + RADEON_HOST_BIG_ENDIAN_EN, ~RADEON_HOST_BIG_ENDIAN_EN); +#else + OUTREGP(RADEON_DP_DATATYPE, 0, ~RADEON_HOST_BIG_ENDIAN_EN); +#endif + + RADEONWaitForFifo(pScrn, 1); + OUTREG(RADEON_DEFAULT_SC_BOTTOM_RIGHT, (RADEON_DEFAULT_SC_RIGHT_MAX + | RADEON_DEFAULT_SC_BOTTOM_MAX)); + info->dp_gui_master_cntl = + ((info->datatype << RADEON_GMC_DST_DATATYPE_SHIFT) + | RADEON_GMC_CLR_CMP_CNTL_DIS); + RADEONWaitForFifo(pScrn, 1); + OUTREG(RADEON_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | RADEON_GMC_BRUSH_SOLID_COLOR + | RADEON_GMC_SRC_DATATYPE_COLOR)); + + RADEONWaitForFifo(pScrn, 7); + OUTREG(RADEON_DST_LINE_START, 0); + OUTREG(RADEON_DST_LINE_END, 0); + OUTREG(RADEON_DP_BRUSH_FRGD_CLR, 0xffffffff); + OUTREG(RADEON_DP_BRUSH_BKGD_CLR, 0x00000000); + OUTREG(RADEON_DP_SRC_FRGD_CLR, 0xffffffff); + OUTREG(RADEON_DP_SRC_BKGD_CLR, 0x00000000); + OUTREG(RADEON_DP_WRITE_MASK, 0xffffffff); + + RADEONWaitForIdle(pScrn); +} + +#ifdef XF86DRI +/* FIXME: When direct rendering is enabled, we should use the CP to + draw 2D commands */ +static void RADEONCPAccelInit(ScrnInfoPtr pScrn, XAAInfoRecPtr a) +{ + a->Flags = 0; + + /* Sync */ +#if 1 + a->Sync = RADEONWaitForIdle; +#else + a->Sync = RADEONCCEWaitForIdle; +#endif + +} +#endif + +static void RADEONMMIOAccelInit(ScrnInfoPtr pScrn, XAAInfoRecPtr a) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + a->Flags = (PIXMAP_CACHE + | OFFSCREEN_PIXMAPS + | LINEAR_FRAMEBUFFER); + + /* Sync */ + a->Sync = RADEONWaitForIdle; + + /* Solid Filled Rectangle */ + a->PolyFillRectSolidFlags = 0; + a->SetupForSolidFill = RADEONSetupForSolidFill; + a->SubsequentSolidFillRect = RADEONSubsequentSolidFillRect; + + /* Screen-to-screen Copy */ + a->ScreenToScreenCopyFlags = 0; + a->SetupForScreenToScreenCopy = RADEONSetupForScreenToScreenCopy; + a->SubsequentScreenToScreenCopy = RADEONSubsequentScreenToScreenCopy; + + /* Mono 8x8 Pattern Fill (Color Expand) */ + a->SetupForMono8x8PatternFill + = RADEONSetupForMono8x8PatternFill; + a->SubsequentMono8x8PatternFillRect + = RADEONSubsequentMono8x8PatternFillRect; + a->Mono8x8PatternFillFlags = (HARDWARE_PATTERN_PROGRAMMED_BITS + | HARDWARE_PATTERN_PROGRAMMED_ORIGIN + | HARDWARE_PATTERN_SCREEN_ORIGIN + | BIT_ORDER_IN_BYTE_LSBFIRST); + + /* Indirect CPU-To-Screen Color Expand */ +#if X_BYTE_ORDER == X_LITTLE_ENDIAN + a->ScanlineCPUToScreenColorExpandFillFlags = LEFT_EDGE_CLIPPING + /* RADEON gets upset, when using HOST provided data + * without a source rop. To show run 'xtest's drwarc */ + | ROP_NEEDS_SOURCE + | LEFT_EDGE_CLIPPING_NEGATIVE_X; +#else + a->ScanlineCPUToScreenColorExpandFillFlags = BIT_ORDER_IN_BYTE_MSBFIRST + /* RADEON gets upset, when using HOST provided data + * without a source rop. To show run 'xtest's drwarc */ + | ROP_NEEDS_SOURCE + | LEFT_EDGE_CLIPPING + | LEFT_EDGE_CLIPPING_NEGATIVE_X; +#endif + a->NumScanlineColorExpandBuffers = 1; + a->ScanlineColorExpandBuffers = info->scratch_buffer; + info->scratch_save = xalloc(((pScrn->virtualX+31)/32*4) + + (pScrn->virtualX + * info->CurrentLayout.pixel_bytes)); + info->scratch_buffer[0] = info->scratch_save; + a->SetupForScanlineCPUToScreenColorExpandFill + = RADEONSetupForScanlineCPUToScreenColorExpandFill; + a->SubsequentScanlineCPUToScreenColorExpandFill + = RADEONSubsequentScanlineCPUToScreenColorExpandFill; + a->SubsequentColorExpandScanline = RADEONSubsequentColorExpandScanline; + + a->SetupForSolidLine = RADEONSetupForSolidLine; + a->SubsequentSolidTwoPointLine = RADEONSubsequentSolidTwoPointLine; + a->SubsequentSolidHorVertLine = RADEONSubsequentSolidHorVertLine; + + a->SetupForDashedLine = RADEONSetupForDashedLine; + a->SubsequentDashedTwoPointLine = RADEONSubsequentDashedTwoPointLine; + a->DashPatternMaxLength = 32; + a->DashedLineFlags = (LINE_PATTERN_LSBFIRST_LSBJUSTIFIED + | LINE_PATTERN_POWER_OF_2_ONLY); + +#if RADEON_IMAGEWRITE + /* ImageWrite */ + a->NumScanlineImageWriteBuffers = 1; + a->ScanlineImageWriteBuffers = info->scratch_buffer; + info->scratch_buffer[0] = info->scratch_save; + a->SetupForScanlineImageWrite = RADEONSetupForScanlineImageWrite; + a->SubsequentScanlineImageWriteRect + = RADEONSubsequentScanlineImageWriteRect; + a->SubsequentImageWriteScanline = RADEONSubsequentImageWriteScanline; + a->ScanlineImageWriteFlags = CPU_TRANSFER_PAD_DWORD + /* Performance tests show that we shouldn't use GXcopy for + * uploads as a memcpy is faster */ + | NO_GXCOPY + /* RADEON gets upset, when using HOST provided data + * without a source rop. To show run 'xtest's ptimg */ + | ROP_NEEDS_SOURCE + | SCANLINE_PAD_DWORD + | LEFT_EDGE_CLIPPING + | LEFT_EDGE_CLIPPING_NEGATIVE_X; +#endif + +#if 0 + /* Color 8x8 Pattern Fill */ + a->SetupForColor8x8PatternFill + = RADEONSetupForColor8x8PatternFill; + a->SubsequentColor8x8PatternFillRect + = RADEONSubsequentColor8x8PatternFillRect; + a->Color8x8PatternFillFlags = + HARDWARE_PATTERN_PROGRAMMED_ORIGIN + | HARDWARE_PATTERN_SCREEN_ORIGIN + | BIT_ORDER_IN_BYTE_LSBFIRST; +#endif +} + +/* Initialize XAA for supported acceleration and also initialize the + graphics hardware for acceleration. */ +Bool RADEONAccelInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + XAAInfoRecPtr a; + + if (!(a = info->accel = XAACreateInfoRec())) return FALSE; + +#ifdef XF86DRI + /* FIXME: When direct rendering is enabled, we should use the CP to + draw 2D commands */ + if (info->CP2D) RADEONCPAccelInit(pScrn, a); + else +#endif + RADEONMMIOAccelInit(pScrn, a); + + RADEONEngineInit(pScrn); + return XAAInit(pScreen, a); +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_cursor.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_cursor.c new file mode 100644 index 000000000..54f8b43d1 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_cursor.c @@ -0,0 +1,266 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_cursor.c,v 1.1 2000/11/02 16:55:41 tsi Exp $ */ +/* + * Copyright 2000 ATI Technologies Inc., Markham, Ontario + * and 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 on + * 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Kevin E. Martin <martin@valinux.com> + * Rickard E. Faith <faith@valinux.com> + * + * References: + * + * !!!! FIXME !!!! + * RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical + * Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April + * 1999. + * + * RAGE 128 Software Development Manual (Technical Reference Manual P/N + * SDK-G04000 Rev. 0.01), ATI Technologies: June 1999. + * + */ + + /* X and server generic header files */ +#include "Xarch.h" +#include "xf86.h" +#include "xf86_ansic.h" +#include "xf86_OSproc.h" +#include "xf86fbman.h" + + /* Driver data structures */ +#include "radeon.h" +#include "radeon_reg.h" + +#if X_BYTE_ORDER == X_BIG_ENDIAN +#define P_SWAP32( a , b ) \ + ((char *)a)[0] = ((char *)b)[3]; \ + ((char *)a)[1] = ((char *)b)[2]; \ + ((char *)a)[2] = ((char *)b)[1]; \ + ((char *)a)[3] = ((char *)b)[0] + +#define P_SWAP16( a , b ) \ + ((char *)a)[0] = ((char *)b)[1]; \ + ((char *)a)[1] = ((char *)b)[0]; \ + ((char *)a)[2] = ((char *)b)[3]; \ + ((char *)a)[3] = ((char *)b)[2] +#endif + + +/* Set cursor foreground and background colors. */ +static void RADEONSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + OUTREG(RADEON_CUR_CLR0, bg); + OUTREG(RADEON_CUR_CLR1, fg); +} + +/* Set cursor position to (x,y) with offset into cursor bitmap at + (xorigin,yorigin). */ +static void RADEONSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + xf86CursorInfoPtr cursor = info->cursor; + int xorigin = 0; + int yorigin = 0; + int total_y = pScrn->frameY1 - pScrn->frameY0; + + if (x < 0) xorigin = -x; + if (y < 0) yorigin = -y; + if (y > total_y) y = total_y; + if (info->Flags & V_DBLSCAN) y *= 2; + if (xorigin >= cursor->MaxWidth) xorigin = cursor->MaxWidth - 1; + if (yorigin >= cursor->MaxHeight) yorigin = cursor->MaxHeight - 1; + + OUTREG(RADEON_CUR_HORZ_VERT_OFF, (RADEON_CUR_LOCK + | (xorigin << 16) + | yorigin)); + OUTREG(RADEON_CUR_HORZ_VERT_POSN, (RADEON_CUR_LOCK + | ((xorigin ? 0 : x) << 16) + | (yorigin ? 0 : y))); + OUTREG(RADEON_CUR_OFFSET, info->cursor_start + yorigin * 16); +} + +/* Copy cursor image from `image' to video memory. RADEONSetCursorPosition + will be called after this, so we can ignore xorigin and yorigin. */ +static void RADEONLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *image) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + CARD32 *s = (CARD32 *)image; + CARD32 *d = (CARD32 *)(info->FB + info->cursor_start); + int y; + CARD32 save; + + save = INREG(RADEON_CRTC_GEN_CNTL); + OUTREG(RADEON_CRTC_GEN_CNTL, save & ~RADEON_CRTC_CUR_EN); + +#if X_BYTE_ORDER == X_BIG_ENDIAN + switch(info->CurrentLayout.pixel_bytes) { + case 4: + case 3: + for (y = 0; y < 64; y++) { + P_SWAP32(d,s); + d++; s++; + P_SWAP32(d,s); + d++; s++; + P_SWAP32(d,s); + d++; s++; + P_SWAP32(d,s); + d++; s++; + } + break; + case 2: + for (y = 0; y < 64; y++) { + P_SWAP16(d,s); + d++; s++; + P_SWAP16(d,s); + d++; s++; + P_SWAP16(d,s); + d++; s++; + P_SWAP16(d,s); + d++; s++; + } + break; + default: + for (y = 0; y < 64; y++) { + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + } + } +#else + for (y = 0; y < 64; y++) { + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + } +#endif + + /* Set the area after the cursor to be all transparent so that we + won't display corrupted cursors on the screen */ + for (y = 0; y < 64; y++) { + *d++ = 0xffffffff; /* The AND bits */ + *d++ = 0xffffffff; + *d++ = 0x00000000; /* The XOR bits */ + *d++ = 0x00000000; + } + + OUTREG(RADEON_CRTC_GEN_CNTL, save); +} + +/* Hide hardware cursor. */ +static void RADEONHideCursor(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_CUR_EN); +} + +/* Show hardware cursor. */ +static void RADEONShowCursor(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + OUTREGP(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_CUR_EN, ~RADEON_CRTC_CUR_EN); +} + +/* Determine if hardware cursor is in use. */ +static Bool RADEONUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + + return info->cursor_start ? TRUE : FALSE; +} + +/* Initialize hardware cursor support. */ +Bool RADEONCursorInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + xf86CursorInfoPtr cursor; + FBAreaPtr fbarea; + int width; + int height; + int size; + + + if (!(cursor = info->cursor = xf86CreateCursorInfoRec())) return FALSE; + + cursor->MaxWidth = 64; + cursor->MaxHeight = 64; + cursor->Flags = (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP + +#if X_BYTE_ORDER == X_LITTLE_ENDIAN + | HARDWARE_CURSOR_BIT_ORDER_MSBFIRST +#endif + | HARDWARE_CURSOR_INVERT_MASK + | HARDWARE_CURSOR_AND_SOURCE_WITH_MASK + | HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 + | HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK); + + cursor->SetCursorColors = RADEONSetCursorColors; + cursor->SetCursorPosition = RADEONSetCursorPosition; + cursor->LoadCursorImage = RADEONLoadCursorImage; + cursor->HideCursor = RADEONHideCursor; + cursor->ShowCursor = RADEONShowCursor; + cursor->UseHWCursor = RADEONUseHWCursor; + + size = (cursor->MaxWidth/4) * cursor->MaxHeight; + width = pScrn->displayWidth; + height = (size*2 + 1023) / pScrn->displayWidth; + fbarea = xf86AllocateOffscreenArea(pScreen, + width, + height, + 16, + NULL, + NULL, + NULL); + + if (!fbarea) { + info->cursor_start = 0; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Hardware cursor disabled" + " due to insufficient offscreen memory\n"); + } else { + info->cursor_start = RADEON_ALIGN((fbarea->box.x1 + + width * fbarea->box.y1) + * info->CurrentLayout.pixel_bytes, + 16); + info->cursor_end = info->cursor_start + size; + } + + RADEONTRACE(("RADEONCursorInit (0x%08x-0x%08x)\n", + info->cursor_start, info->cursor_end)); + + return xf86InitCursor(pScreen, cursor); +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dga.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dga.c new file mode 100644 index 000000000..d466d0b67 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dga.c @@ -0,0 +1,355 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dga.c,v 1.2 2000/11/03 09:52:55 alanh Exp $ */ +/* + * Copyright 2000 ATI Technologies Inc., Markham, Ontario + * and 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 on + * 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Kevin E. Martin <martin@valinux.com> + * + * Credits: + * + * Thanks to Ove Kåven <ovek@transgaming.com> for writing the Rage 128 + * DGA support. Portions of this file are based on the initialization + * code for that driver. + * + */ + + /* X and server generic header files */ +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" + + /* Driver data structures */ +#include "radeon.h" +#include "radeon_probe.h" + + /* DGA support */ +#include "dgaproc.h" + + +static Bool RADEON_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, + int *, int *, int *); +static Bool RADEON_SetMode(ScrnInfoPtr, DGAModePtr); +static int RADEON_GetViewport(ScrnInfoPtr); +static void RADEON_SetViewport(ScrnInfoPtr, int, int, int); +static void RADEON_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); +static void RADEON_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); +#if 0 +static void RADEON_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, + unsigned long); +#endif + +static +DGAFunctionRec RADEON_DGAFuncs = { + RADEON_OpenFramebuffer, + NULL, + RADEON_SetMode, + RADEON_SetViewport, + RADEON_GetViewport, + RADEONWaitForIdle, + RADEON_FillRect, + RADEON_BlitRect, +#if 0 + RADEON_BlitTransRect +#else + NULL +#endif +}; + + +static DGAModePtr RADEONSetupDGAMode(ScrnInfoPtr pScrn, + DGAModePtr modes, + int *num, + int bitsPerPixel, + int depth, + Bool pixmap, + int secondPitch, + unsigned long red, + unsigned long green, + unsigned long blue, + short visualClass) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + DGAModePtr newmodes = NULL, currentMode; + DisplayModePtr pMode, firstMode; + int otherPitch, Bpp = bitsPerPixel >> 3; + Bool oneMore; + + pMode = firstMode = pScrn->modes; + + while (pMode) { + otherPitch = secondPitch ? secondPitch : pMode->HDisplay; + + if (pMode->HDisplay != otherPitch) { + newmodes = xrealloc(modes, (*num + 2) * sizeof(DGAModeRec)); + oneMore = TRUE; + } else { + newmodes = xrealloc(modes, (*num + 1) * sizeof(DGAModeRec)); + oneMore = FALSE; + } + + if (!newmodes) { + xfree(modes); + return NULL; + } + modes = newmodes; + +SECOND_PASS: + + currentMode = modes + *num; + (*num)++; + + currentMode->mode = pMode; + /* FIXME: is concurrent access really possible? */ + currentMode->flags = DGA_CONCURRENT_ACCESS; + if (pixmap) + currentMode->flags |= DGA_PIXMAP_AVAILABLE; + if (info->accel) + currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; + if (pMode->Flags & V_DBLSCAN) + currentMode->flags |= DGA_DOUBLESCAN; + if (pMode->Flags & V_INTERLACE) + currentMode->flags |= DGA_INTERLACED; + currentMode->byteOrder = pScrn->imageByteOrder; + currentMode->depth = depth; + currentMode->bitsPerPixel = bitsPerPixel; + currentMode->red_mask = red; + currentMode->green_mask = green; + currentMode->blue_mask = blue; + currentMode->visualClass = visualClass; + currentMode->viewportWidth = pMode->HDisplay; + currentMode->viewportHeight = pMode->VDisplay; + currentMode->xViewportStep = 8; + currentMode->yViewportStep = 1; + currentMode->viewportFlags = DGA_FLIP_RETRACE; + currentMode->offset = 0; + currentMode->address = (unsigned char*)info->LinearAddr; + + if (oneMore) { /* first one is narrow width */ + currentMode->bytesPerScanline = (((pMode->HDisplay * Bpp) + 3) + & ~3L); + currentMode->imageWidth = pMode->HDisplay; + currentMode->imageHeight = pMode->VDisplay; + currentMode->pixmapWidth = currentMode->imageWidth; + currentMode->pixmapHeight = currentMode->imageHeight; + currentMode->maxViewportX = currentMode->imageWidth - + currentMode->viewportWidth; + /* this might need to get clamped to some maximum */ + currentMode->maxViewportY = (currentMode->imageHeight - + currentMode->viewportHeight); + oneMore = FALSE; + goto SECOND_PASS; + } else { + currentMode->bytesPerScanline = ((otherPitch * Bpp) + 3) & ~3L; + currentMode->imageWidth = otherPitch; + currentMode->imageHeight = pMode->VDisplay; + currentMode->pixmapWidth = currentMode->imageWidth; + currentMode->pixmapHeight = currentMode->imageHeight; + currentMode->maxViewportX = (currentMode->imageWidth - + currentMode->viewportWidth); + /* this might need to get clamped to some maximum */ + currentMode->maxViewportY = (currentMode->imageHeight - + currentMode->viewportHeight); + } + + pMode = pMode->next; + if (pMode == firstMode) + break; + } + + return modes; +} + +Bool RADEONDGAInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + DGAModePtr modes = NULL; + int num = 0; + + /* 8 */ + modes = RADEONSetupDGAMode(pScrn, modes, &num, 8, 8, + (pScrn->bitsPerPixel == 8), + ((pScrn->bitsPerPixel != 8) + ? 0 : pScrn->displayWidth), + 0, 0, 0, PseudoColor); + + /* 15 */ + modes = RADEONSetupDGAMode(pScrn, modes, &num, 16, 15, + (pScrn->bitsPerPixel == 16), + ((pScrn->depth != 15) + ? 0 : pScrn->displayWidth), + 0x7c00, 0x03e0, 0x001f, TrueColor); + + modes = RADEONSetupDGAMode(pScrn, modes, &num, 16, 15, + (pScrn->bitsPerPixel == 16), + ((pScrn->depth != 15) + ? 0 : pScrn->displayWidth), + 0x7c00, 0x03e0, 0x001f, DirectColor); + + /* 16 */ + modes = RADEONSetupDGAMode(pScrn, modes, &num, 16, 16, + (pScrn->bitsPerPixel == 16), + ((pScrn->depth != 16) + ? 0 : pScrn->displayWidth), + 0xf800, 0x07e0, 0x001f, TrueColor); + + modes = RADEONSetupDGAMode(pScrn, modes, &num, 16, 16, + (pScrn->bitsPerPixel == 16), + ((pScrn->depth != 16) + ? 0 : pScrn->displayWidth), + 0xf800, 0x07e0, 0x001f, DirectColor); + + /* 32 */ + modes = RADEONSetupDGAMode(pScrn, modes, &num, 32, 24, + (pScrn->bitsPerPixel == 32), + ((pScrn->bitsPerPixel != 32) + ? 0 : pScrn->displayWidth), + 0xff0000, 0x00ff00, 0x0000ff, TrueColor); + + modes = RADEONSetupDGAMode(pScrn, modes, &num, 32, 24, + (pScrn->bitsPerPixel == 32), + ((pScrn->bitsPerPixel != 32) + ? 0 : pScrn->displayWidth), + 0xff0000, 0x00ff00, 0x0000ff, DirectColor); + + info->numDGAModes = num; + info->DGAModes = modes; + + return DGAInit(pScreen, &RADEON_DGAFuncs, modes, num); +} + +static Bool RADEON_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode) +{ + static RADEONFBLayout SavedLayouts[MAXSCREENS]; + int indx = pScrn->pScreen->myNum; + RADEONInfoPtr info = RADEONPTR(pScrn); + + if (!pMode) { /* restore the original mode */ + /* put the ScreenParameters back */ + if (info->DGAactive) + memcpy(&info->CurrentLayout, &SavedLayouts[indx], + sizeof(RADEONFBLayout)); + + pScrn->currentMode = info->CurrentLayout.mode; + + RADEONSwitchMode(indx, pScrn->currentMode, 0); + RADEONAdjustFrame(indx, 0, 0, 0); + info->DGAactive = FALSE; + } else { + if (!info->DGAactive) { /* save the old parameters */ + memcpy(&SavedLayouts[indx], &info->CurrentLayout, + sizeof(RADEONFBLayout)); + info->DGAactive = TRUE; + } + + info->CurrentLayout.bitsPerPixel = pMode->bitsPerPixel; + info->CurrentLayout.depth = pMode->depth; + info->CurrentLayout.displayWidth = (pMode->bytesPerScanline / + (pMode->bitsPerPixel >> 3)); + info->CurrentLayout.pixel_bytes = pMode->bitsPerPixel / 8; + info->CurrentLayout.pixel_code = (pMode->bitsPerPixel != 16 + ? pMode->bitsPerPixel + : pMode->depth); + /* RADEONModeInit() will set the mode field */ + + RADEONSwitchMode(indx, pMode->mode, 0); + } + + return TRUE; +} + +static int RADEON_GetViewport(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + return info->DGAViewportStatus; +} + +static void RADEON_SetViewport(ScrnInfoPtr pScrn, int x, int y, int flags) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + RADEONAdjustFrame(pScrn->pScreen->myNum, x, y, flags); + info->DGAViewportStatus = 0; /* FIXME */ +} + +static void RADEON_FillRect(ScrnInfoPtr pScrn, + int x, int y, int w, int h, + unsigned long color) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + if (info->accel) { + (*info->accel->SetupForSolidFill)(pScrn, color, GXcopy, ~0); + (*info->accel->SubsequentSolidFillRect)(pScrn, x, y, w, h); + SET_SYNC_FLAG(info->accel); + } +} + +static void RADEON_BlitRect(ScrnInfoPtr pScrn, + int srcx, int srcy, int w, int h, + int dstx, int dsty) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + if (info->accel) { + int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; + int ydir = (srcy < dsty) ? -1 : 1; + + (*info->accel->SetupForScreenToScreenCopy)(pScrn, xdir, ydir, + GXcopy, ~0, -1); + (*info->accel->SubsequentScreenToScreenCopy)(pScrn, srcx, srcy, + dstx, dsty, w, h); + SET_SYNC_FLAG(info->accel); + } +} + +#if 0 +static void RADEON_BlitTransRect(ScrnInfoPtr pScrn, + int srcx, int srcy, int w, int h, + int dstx, int dsty, unsigned long color) +{ + /* this one should be separate since the XAA function would prohibit + usage of ~0 as the key */ +} +#endif + +static Bool RADEON_OpenFramebuffer(ScrnInfoPtr pScrn, + char **name, + unsigned char **mem, + int *size, int *offset, int *flags) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + *name = NULL; /* no special device */ + *mem = (unsigned char*)info->LinearAddr; + *size = info->FbMapSize; + *offset = 0; + *flags = 0; /* DGA_NEED_ROOT; -- don't need root, just /dev/mem access */ + + return TRUE; +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c new file mode 100644 index 000000000..0fa24a9b7 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c @@ -0,0 +1,2953 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c,v 1.2 2000/11/03 09:52:55 alanh Exp $ */ +/* + * Copyright 2000 ATI Technologies Inc., Markhom, Ontario + * and 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 on + * 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Kevin E. Martin <martin@valinux.com> + * Rickard E. Faith <faith@valinux.com> + * + * Credits: + * + * Thanks to Ani Joshi <ajoshi@shell.unixbox.com> for providing source + * code to his Radeon driver. Portions of this file are based on the + * initialization code for that driver. + * + * References: + * + * !!!! FIXME !!!! + * RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical + * Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April + * 1999. + * + * RAGE 128 Software Development Manual (Technical Reference Manual P/N + * SDK-G04000 Rev. 0.01), ATI Technologies: June 1999. + * + * This server does not yet support these XFree86 4.0 features: + * !!!! FIXME !!!! + * DDC1 & DDC2 + * shadowfb + * overlay planes + * + * Modified by Marc Aurele La France (tsi@xfree86.org) for ATI driver merge. + */ + + /* X and server generic header files */ +#include "xf86.h" +#include "xf86_ansic.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "xf86RAC.h" +#include "xf86cmap.h" +#include "xf86fbman.h" +#include "xf86int10.h" + /* Backing store, software cursor, and + colormap initialization */ +#include "mibstore.h" +#include "mipointer.h" +#include "micmap.h" + +#define USE_FB /* not until overlays */ +#ifdef USE_FB +#include "fb.h" +#else + /* CFB support */ +#define PSZ 8 +#include "cfb.h" +#undef PSZ +#include "cfb16.h" +#include "cfb24.h" +#include "cfb32.h" +#include "cfb24_32.h" +#endif + + /* Driver data structures */ +#include "radeon.h" +#include "radeon_probe.h" +#include "radeon_reg.h" +#include "radeon_version.h" + +#ifndef MAX +#define MAX(a,b) ((a)>(b)?(a):(b)) +#endif + + + /* Forward definitions for driver functions */ +static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen); +static Bool RADEONSaveScreen(ScreenPtr pScreen, int mode); +static void RADEONSave(ScrnInfoPtr pScrn); +static void RADEONRestore(ScrnInfoPtr pScrn); +static Bool RADEONModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); +static void RADEONDisplayPowerManagementSet(ScrnInfoPtr pScrn, + int PowerManagementMode, + int flags); +static Bool RADEONEnterVTFBDev(int scrnIndex, int flags); +static void RADEONLeaveVTFBDev(int scrnIndex, int flags); + +typedef enum { + OPTION_NOACCEL, + OPTION_SW_CURSOR, + OPTION_DAC_6BIT, + OPTION_DAC_8BIT, +#ifdef XF86DRI + OPTION_IS_PCI, + OPTION_CP_PIO, + OPTION_NO_SECURITY, + OPTION_USEC_TIMEOUT, + OPTION_AGP_MODE, + OPTION_AGP_SIZE, + OPTION_RING_SIZE, + OPTION_VERT_SIZE, + OPTION_VBUF_SIZE, + OPTION_USE_CP_2D, +#endif +#ifdef ENABLE_FLAT_PANEL + /* Note: Radeon flat panel support has been disabled for now */ +#if 0 + /* FIXME: Disable CRTOnly until it is tested */ + OPTION_CRT, +#endif + OPTION_PANEL_WIDTH, + OPTION_PANEL_HEIGHT, +#endif + OPTION_FBDEV +} RADEONOpts; + +OptionInfoRec RADEONOptions[] = { + { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_DAC_6BIT, "Dac6Bit", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_DAC_8BIT, "Dac8Bit", OPTV_BOOLEAN, {0}, TRUE }, +#ifdef XF86DRI + { OPTION_IS_PCI, "ForcePCIMode", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_CP_PIO, "CPPIOMode", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_NO_SECURITY, "CPNoSecurity", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_USEC_TIMEOUT, "CPusecTimeout", OPTV_INTEGER, {0}, FALSE }, + { OPTION_AGP_MODE, "AGPMode", OPTV_INTEGER, {0}, FALSE }, + { OPTION_AGP_SIZE, "AGPSize", OPTV_INTEGER, {0}, FALSE }, + { OPTION_RING_SIZE, "RingSize", OPTV_INTEGER, {0}, FALSE }, + { OPTION_VERT_SIZE, "VBListSize", OPTV_INTEGER, {0}, FALSE }, + { OPTION_VBUF_SIZE, "VBSize", OPTV_INTEGER, {0}, FALSE }, + { OPTION_USE_CP_2D, "UseCPfor2D", OPTV_BOOLEAN, {0}, FALSE }, +#endif +#ifdef ENABLE_FLAT_PANEL + /* Note: Radeon flat panel support has been disabled for now */ +#if 0 + /* FIXME: Disable CRTOnly until it is tested */ + { OPTION_CRT, "CRTOnly", OPTV_BOOLEAN, {0}, FALSE }, +#endif + { OPTION_PANEL_WIDTH, "PanelWidth", OPTV_INTEGER, {0}, FALSE }, + { OPTION_PANEL_HEIGHT, "PanelHeight", OPTV_INTEGER, {0}, FALSE }, +#endif + { OPTION_FBDEV, "UseFBDev", OPTV_BOOLEAN, {0}, FALSE }, + { -1, NULL, OPTV_NONE, {0}, FALSE } +}; + +RADEONRAMRec RADEONRAM[] = { /* Memory Specifications + From Radeon Manual */ + { 4, 4, 1, 2, 1, 2, 1, 16, 12, "64-bit SDR SDRAM" }, + { 4, 4, 3, 3, 2, 3, 1, 16, 12, "64-bit DDR SDRAM" }, +}; + +static const char *vgahwSymbols[] = { + "vgaHWGetHWRec", + "vgaHWFreeHWRec", + "vgaHWLock", + "vgaHWUnlock", + "vgaHWSave", + "vgaHWRestore", + NULL +}; + +static const char *fbdevHWSymbols[] = { + "fbdevHWInit", + "fbdevHWUseBuildinMode", + + "fbdevHWGetDepth", + "fbdevHWGetVidmem", + + /* colormap */ + "fbdevHWLoadPalette", + + /* ScrnInfo hooks */ + "fbdevHWSwitchMode", + "fbdevHWAdjustFrame", + "fbdevHWEnterVT", + "fbdevHWLeaveVT", + "fbdevHWValidMode", + "fbdevHWRestore", + "fbdevHWModeInit", + "fbdevHWSave", + + "fbdevHWUnmapMMIO", + "fbdevHWUnmapVidmem", + "fbdevHWMapMMIO", + "fbdevHWMapVidmem", + + NULL +}; + +static const char *ddcSymbols[] = { + "xf86PrintEDID", + "xf86DoEDID_DDC1", + "xf86DoEDID_DDC2", + NULL +}; + +#ifdef XFree86LOADER +#ifdef USE_FB +static const char *fbSymbols[] = { + "fbScreenInit", + NULL +}; +#else +static const char *cfbSymbols[] = { + "cfbScreenInit", + "cfb16ScreenInit", + "cfb24ScreenInit", + "cfb32ScreenInit", + "cfb24_32ScreenInit", + NULL +}; +#endif + +static const char *xaaSymbols[] = { + "XAADestroyInfoRec", + "XAACreateInfoRec", + "XAAInit", + "XAAStippleScanlineFuncLSBFirst", + "XAAOverlayFBfuncs", + "XAACachePlanarMonoStipple", + "XAAScreenIndex", + NULL +}; + +static const char *xf8_32bppSymbols[] = { + "xf86Overlay8Plus32Init", + NULL +}; + +static const char *ramdacSymbols[] = { + "xf86InitCursor", + "xf86CreateCursorInfoRec", + "xf86DestroyCursorInfoRec", + NULL +}; + +#ifdef XF86DRI +static const char *drmSymbols[] = { + "drmAddBufs", + "drmAddMap", + "drmAvailable", + "drmCtlAddCommand", + "drmCtlInstHandler", + "drmGetInterruptFromBusID", + "drmMapBufs", + "drmMarkBufs", + "drmUnmapBufs", + "drmFreeVersion", + "drmGetVersion", + NULL +}; + +static const char *driSymbols[] = { + "DRIGetDrawableIndex", + "DRIFinishScreenInit", + "DRIDestroyInfoRec", + "DRICloseScreen", + "DRIDestroyInfoRec", + "DRIScreenInit", + "DRIDestroyInfoRec", + "DRICreateInfoRec", + "DRILock", + "DRIUnlock", + "DRIGetSAREAPrivate", + "DRIGetContext", + "DRIQueryVersion", + "GlxSetVisualConfigs", + NULL +}; +#endif + +static const char *vbeSymbols[] = { + "VBEInit", + "vbeDoEDID", + NULL +}; +#endif + +/* Allocate our private RADEONInfoRec. */ +static Bool RADEONGetRec(ScrnInfoPtr pScrn) +{ + if (pScrn->driverPrivate) return TRUE; + + pScrn->driverPrivate = xnfcalloc(sizeof(RADEONInfoRec), 1); + return TRUE; +} + +/* Free our private RADEONInfoRec. */ +static void RADEONFreeRec(ScrnInfoPtr pScrn) +{ + if (!pScrn || !pScrn->driverPrivate) return; + xfree(pScrn->driverPrivate); + pScrn->driverPrivate = NULL; +} + +/* Memory map the MMIO region. Used during pre-init and by RADEONMapMem, + below. */ +static Bool RADEONMapMMIO(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + if (info->FBDev) { + info->MMIO = fbdevHWMapMMIO(pScrn); + } else { + info->MMIO = xf86MapPciMem(pScrn->scrnIndex, + VIDMEM_MMIO | VIDMEM_READSIDEEFFECT, + info->PciTag, + info->MMIOAddr, + RADEON_MMIOSIZE); + } + + if (!info->MMIO) return FALSE; + return TRUE; +} + +/* Unmap the MMIO region. Used during pre-init and by RADEONUnmapMem, + below. */ +static Bool RADEONUnmapMMIO(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + if (info->FBDev) + fbdevHWUnmapMMIO(pScrn); + else { + xf86UnMapVidMem(pScrn->scrnIndex, info->MMIO, RADEON_MMIOSIZE); + } + info->MMIO = NULL; + return TRUE; +} + +/* Memory map the frame buffer. Used by RADEONMapMem, below. */ +static Bool RADEONMapFB(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + if (info->FBDev) { + info->FB = fbdevHWMapVidmem(pScrn); + } else { + info->FB = xf86MapPciMem(pScrn->scrnIndex, + VIDMEM_FRAMEBUFFER, + info->PciTag, + info->LinearAddr, + info->FbMapSize); + } + + if (!info->FB) return FALSE; + return TRUE; +} + +/* Unmap the frame buffer. Used by RADEONUnmapMem, below. */ +static Bool RADEONUnmapFB(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + if (info->FBDev) + fbdevHWUnmapVidmem(pScrn); + else + xf86UnMapVidMem(pScrn->scrnIndex, info->FB, info->FbMapSize); + info->FB = NULL; + return TRUE; +} + +/* Memory map the MMIO region and the frame buffer. */ +static Bool RADEONMapMem(ScrnInfoPtr pScrn) +{ + if (!RADEONMapMMIO(pScrn)) return FALSE; + if (!RADEONMapFB(pScrn)) { + RADEONUnmapMMIO(pScrn); + return FALSE; + } + return TRUE; +} + +/* Unmap the MMIO region and the frame buffer. */ +static Bool RADEONUnmapMem(ScrnInfoPtr pScrn) +{ + if (!RADEONUnmapMMIO(pScrn) || !RADEONUnmapFB(pScrn)) return FALSE; + return TRUE; +} + +/* Read PLL information */ +unsigned RADEONINPLL(ScrnInfoPtr pScrn, int addr) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + +#if !RADEON_ATOMIC_UPDATE + while ( (INREG8(RADEON_CLOCK_CNTL_INDEX) & 0x9f) != addr) { +#endif + OUTREG8(RADEON_CLOCK_CNTL_INDEX, addr & 0x1f); +#if !RADEON_ATOMIC_UPDATE + } +#endif + return INREG(RADEON_CLOCK_CNTL_DATA); +} + +#if 0 +/* Read PAL information (only used for debugging). */ +static int RADEONINPAL(int idx) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + OUTREG(RADEON_PALETTE_INDEX, idx << 16); + return INREG(RADEON_PALETTE_DATA); +} +#endif + +/* Wait for vertical sync. */ +void RADEONWaitForVerticalSync(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int i; + + OUTREG(RADEON_GEN_INT_STATUS, RADEON_VSYNC_INT_AK); + for (i = 0; i < RADEON_TIMEOUT; i++) { + if (INREG(RADEON_GEN_INT_STATUS) & RADEON_VSYNC_INT) break; + } +} + +/* Blank screen. */ +static void RADEONBlank(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + OUTREGP(RADEON_CRTC_EXT_CNTL, + RADEON_CRTC_DISPLAY_DIS | + RADEON_CRTC_VSYNC_DIS | + RADEON_CRTC_HSYNC_DIS, + ~(RADEON_CRTC_DISPLAY_DIS | + RADEON_CRTC_VSYNC_DIS | + RADEON_CRTC_HSYNC_DIS)); +} + +/* Unblank screen. */ +static void RADEONUnblank(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + OUTREGP(RADEON_CRTC_EXT_CNTL, 0, + ~(RADEON_CRTC_DISPLAY_DIS | + RADEON_CRTC_VSYNC_DIS | + RADEON_CRTC_HSYNC_DIS)); +} + +/* Compute log base 2 of val. */ +int RADEONMinBits(int val) +{ + int bits; + + if (!val) return 1; + for (bits = 0; val; val >>= 1, ++bits); + return bits; +} + +/* Compute n/d with rounding. */ +static int RADEONDiv(int n, int d) +{ + return (n + (d / 2)) / d; +} + +/* Read the Video BIOS block and the FP registers (if applicable). */ +static Bool RADEONGetBIOSParameters(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); +#ifdef ENABLE_FLAT_PANEL + int i; + int FPHeader = 0; +#endif + +#define RADEONReadBIOS(offset, buffer, length) \ + (info->BIOSFromPCI ? \ + xf86ReadPciBIOS(offset, info->PciTag, 0, buffer, length) : \ + xf86ReadBIOS(info->BIOSAddr, offset, buffer, length)) + +#define RADEON_BIOS8(v) (info->VBIOS[v]) +#define RADEON_BIOS16(v) (info->VBIOS[v] | \ + (info->VBIOS[(v) + 1] << 8)) +#define RADEON_BIOS32(v) (info->VBIOS[v] | \ + (info->VBIOS[(v) + 1] << 8) | \ + (info->VBIOS[(v) + 2] << 16) | \ + (info->VBIOS[(v) + 3] << 24)) + + if (!(info->VBIOS = xalloc(RADEON_VBIOS_SIZE))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Cannot allocate space for hold Video BIOS!\n"); + return FALSE; + } + + info->BIOSFromPCI = TRUE; + RADEONReadBIOS(0x0000, info->VBIOS, RADEON_VBIOS_SIZE); + if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Video BIOS not detected in PCI space!\n"); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Attempting to read Video BIOS from legacy ISA space!\n"); + info->BIOSFromPCI = FALSE; + info->BIOSAddr = 0x000c0000; + RADEONReadBIOS(0x0000, info->VBIOS, RADEON_VBIOS_SIZE); + } + if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) { + info->BIOSAddr = 0x00000000; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Video BIOS not found!\n"); + } + +#ifdef ENABLE_FLAT_PANEL + /* Note: Radeon flat panel support has been disabled for now */ + if (info->HasPanelRegs) { + info->FPBIOSstart = 0; + + /* FIXME: There should be direct access to the start of the FP info + tables, but until we find out where that offset is stored, we + must search for the ATI signature string: "M3 ". */ + for (i = 4; i < RADEON_VBIOS_SIZE-8; i++) { + if (RADEON_BIOS8(i) == 'M' && + RADEON_BIOS8(i+1) == '3' && + RADEON_BIOS8(i+2) == ' ' && + RADEON_BIOS8(i+3) == ' ' && + RADEON_BIOS8(i+4) == ' ' && + RADEON_BIOS8(i+5) == ' ' && + RADEON_BIOS8(i+6) == ' ' && + RADEON_BIOS8(i+7) == ' ') { + FPHeader = i-2; + break; + } + } + + if (!FPHeader) return TRUE; + + /* Assume that only one panel is attached and supported */ + for (i = FPHeader+20; i < FPHeader+84; i += 2) { + if (RADEON_BIOS16(i) != 0) { + info->FPBIOSstart = RADEON_BIOS16(i); + break; + } + } + if (!info->FPBIOSstart) return TRUE; + + if (!info->PanelXRes) + info->PanelXRes = RADEON_BIOS16(info->FPBIOSstart+25); + if (!info->PanelYRes) + info->PanelYRes = RADEON_BIOS16(info->FPBIOSstart+27); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel size: %dx%d\n", + info->PanelXRes, info->PanelYRes); + + info->PanelPwrDly = RADEON_BIOS8(info->FPBIOSstart+56); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel ID: "); + for (i = 1; i <= 24; i++) + ErrorF("%c", RADEON_BIOS8(info->FPBIOSstart+i)); + ErrorF("\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel Type: "); + i = RADEON_BIOS16(info->FPBIOSstart+29); + if (i & 1) ErrorF("Color, "); + else ErrorF("Monochrome, "); + if (i & 2) ErrorF("Dual(split), "); + else ErrorF("Single, "); + switch ((i >> 2) & 0x3f) { + case 0: ErrorF("STN"); break; + case 1: ErrorF("TFT"); break; + case 2: ErrorF("Active STN"); break; + case 3: ErrorF("EL"); break; + case 4: ErrorF("Plasma"); break; + default: ErrorF("UNKNOWN"); break; + } + ErrorF("\n"); + if (RADEON_BIOS8(info->FPBIOSstart+61) & 1) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel Interface: LVDS\n"); + } else { + /* FIXME: Add Non-LVDS flat pael support */ + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Non-LVDS panel interface detected! " + "This support is untested and may not " + "function properly\n"); + } + } +#endif + + return TRUE; +} + +/* Read PLL parameters from BIOS block. Default to typical values if there + is no BIOS. */ +static Bool RADEONGetPLLParameters(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONPLLPtr pll = &info->pll; + CARD16 bios_header; + CARD16 pll_info_block; + + if (!info->VBIOS) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Video BIOS not detected, using default PLL parameters!\n"); + /* These probably aren't going to work for + the card you are using. Specifically, + reference freq can be 29.50MHz, + 28.63MHz, or 14.32MHz. YMMV. */ + pll->reference_freq = 2950; + pll->reference_div = 65; + pll->min_pll_freq = 12500; + pll->max_pll_freq = 35000; + pll->xclk = 10300; + } else { + bios_header = RADEON_BIOS16(0x48); + pll_info_block = RADEON_BIOS16(bios_header + 0x30); + RADEONTRACE(("Header at 0x%04x; PLL Information at 0x%04x\n", + bios_header, pll_info_block)); + + pll->reference_freq = RADEON_BIOS16(pll_info_block + 0x0e); + pll->reference_div = RADEON_BIOS16(pll_info_block + 0x10); + pll->min_pll_freq = RADEON_BIOS32(pll_info_block + 0x12); + pll->max_pll_freq = RADEON_BIOS32(pll_info_block + 0x16); + pll->xclk = RADEON_BIOS16(pll_info_block + 0x08); + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "PLL parameters: rf=%d rd=%d min=%d max=%d; xclk=%d\n", + pll->reference_freq, + pll->reference_div, + pll->min_pll_freq, + pll->max_pll_freq, + pll->xclk); + + return TRUE; +} + +/* This is called by RADEONPreInit to set up the default visual. */ +static Bool RADEONPreInitVisual(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + if (!xf86SetDepthBpp(pScrn, 8, 8, 8, Support32bppFb)) + return FALSE; + + switch (pScrn->depth) { + case 8: + case 15: + case 16: + case 24: + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given depth (%d) is not supported by %s driver\n", + pScrn->depth, RADEON_DRIVER_NAME); + return FALSE; + } + + xf86PrintDepthBpp(pScrn); + + info->fifo_slots = 0; + info->pix24bpp = xf86GetBppFromDepth(pScrn, pScrn->depth); + info->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel; + info->CurrentLayout.depth = pScrn->depth; + info->CurrentLayout.pixel_bytes = pScrn->bitsPerPixel / 8; + info->CurrentLayout.pixel_code = (pScrn->bitsPerPixel != 16 + ? pScrn->bitsPerPixel + : pScrn->depth); + + if (info->pix24bpp == 24) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Radeon does NOT support 24bpp\n"); + return FALSE; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Pixel depth = %d bits stored in %d byte%s (%d bpp pixmaps)\n", + pScrn->depth, + info->CurrentLayout.pixel_bytes, + info->CurrentLayout.pixel_bytes > 1 ? "s" : "", + info->pix24bpp); + + + if (!xf86SetDefaultVisual(pScrn, -1)) return FALSE; + + if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Default visual (%s) is not supported at depth %d\n", + xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); + return FALSE; + } + return TRUE; + +} + +/* This is called by RADEONPreInit to handle all color weight issues. */ +static Bool RADEONPreInitWeight(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + /* Save flag for 6 bit DAC to use for + setting CRTC registers. Otherwise use + an 8 bit DAC, even if xf86SetWeight sets + pScrn->rgbBits to some value other than + 8. */ + info->dac6bits = FALSE; + if (pScrn->depth > 8) { + rgb defaultWeight = { 0, 0, 0 }; + if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight)) return FALSE; + } else { + pScrn->rgbBits = 8; + if (xf86ReturnOptValBool(RADEONOptions, OPTION_DAC_6BIT, FALSE)) { + pScrn->rgbBits = 6; + info->dac6bits = TRUE; + } + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d bits per RGB (%d bit DAC)\n", + pScrn->rgbBits, info->dac6bits ? 6 : 8); + + return TRUE; + +} + +/* This is called by RADEONPreInit to handle config file overrides for things + like chipset and memory regions. Also determine memory size and type. + If memory type ever needs an override, put it in this routine. */ +static Bool RADEONPreInitConfig(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + EntityInfoPtr pEnt = info->pEnt; + GDevPtr dev = pEnt->device; + int offset = 0; /* RAM Type */ + MessageType from; + unsigned char *RADEONMMIO; + + /* Chipset */ + from = X_PROBED; + if (dev->chipset && *dev->chipset) { + info->Chipset = xf86StringToToken(RADEONChipsets, dev->chipset); + from = X_CONFIG; + } else if (dev->chipID >= 0) { + info->Chipset = dev->chipID; + from = X_CONFIG; + } else { + info->Chipset = info->PciInfo->chipType; + } + pScrn->chipset = (char *)xf86TokenToString(RADEONChipsets, info->Chipset); + + if (!pScrn->chipset) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "ChipID 0x%04x is not recognized\n", info->Chipset); + return FALSE; + } + + if (info->Chipset < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Chipset \"%s\" is not recognized\n", pScrn->chipset); + return FALSE; + } + + xf86DrvMsg(pScrn->scrnIndex, from, + "Chipset: \"%s\" (ChipID = 0x%04x)\n", + pScrn->chipset, + info->Chipset); + + /* Framebuffer */ + + from = X_PROBED; + info->LinearAddr = info->PciInfo->memBase[0] & 0xfc000000; + if (dev->MemBase) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Linear address override, using 0x%08x instead of 0x%08x\n", + dev->MemBase, + info->LinearAddr); + info->LinearAddr = dev->MemBase; + from = X_CONFIG; + } else if (!info->LinearAddr) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "No valid linear framebuffer address\n"); + return FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, from, + "Linear framebuffer at 0x%08lx\n", info->LinearAddr); + + /* MMIO registers */ + from = X_PROBED; + info->MMIOAddr = info->PciInfo->memBase[2] & 0xffffff00; + if (dev->IOBase) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "MMIO address override, using 0x%08x instead of 0x%08x\n", + dev->IOBase, + info->MMIOAddr); + info->MMIOAddr = dev->IOBase; + from = X_CONFIG; + } else if (!info->MMIOAddr) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid MMIO address\n"); + return FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, from, + "MMIO registers at 0x%08lx\n", info->MMIOAddr); + + /* BIOS */ + from = X_PROBED; + info->BIOSAddr = info->PciInfo->biosBase & 0xfffe0000; + if (dev->BiosBase) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "BIOS address override, using 0x%08x instead of 0x%08x\n", + dev->BiosBase, + info->BIOSAddr); + info->BIOSAddr = dev->BiosBase; + from = X_CONFIG; + } + if (info->BIOSAddr) { + xf86DrvMsg(pScrn->scrnIndex, from, + "BIOS at 0x%08lx\n", info->BIOSAddr); + } + +#ifdef ENABLE_FLAT_PANEL + /* Note: Radeon flat panel support has been disabled for now */ + /* Flat panel (part 1) */ + /* FIXME: Make this an option */ + switch (info->Chipset) { +#if 0 + case PCI_CHIP_RADEON_XX: info->HasPanelRegs = TRUE; break; +#endif + case PCI_CHIP_RADEON_QD: + case PCI_CHIP_RADEON_QE: + case PCI_CHIP_RADEON_QF: + case PCI_CHIP_RADEON_QG: + default: info->HasPanelRegs = FALSE; break; + } +#endif + + /* Read registers used to determine options */ + from = X_PROBED; + RADEONMapMMIO(pScrn); + RADEONMMIO = info->MMIO; + if (info->FBDev) + pScrn->videoRam = fbdevHWGetVidmem(pScrn) / 1024; + else + pScrn->videoRam = INREG(RADEON_CONFIG_MEMSIZE) / 1024; + info->MemCntl = INREG(RADEON_SDRAM_MODE_REG); + info->BusCntl = INREG(RADEON_BUS_CNTL); + RADEONMMIO = NULL; + RADEONUnmapMMIO(pScrn); + + /* RAM */ + switch (info->MemCntl >> 30) { + case 0: offset = 0; break; /* 64-bit SDR SDRAM */ + case 1: offset = 1; break; /* 64-bit DDR SDRAM */ + default: offset = 0; + } + info->ram = &RADEONRAM[offset]; + + if (dev->videoRam) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Video RAM override, using %d kB instead of %d kB\n", + dev->videoRam, + pScrn->videoRam); + from = X_CONFIG; + pScrn->videoRam = dev->videoRam; + } + pScrn->videoRam &= ~1023; + info->FbMapSize = pScrn->videoRam * 1024; + xf86DrvMsg(pScrn->scrnIndex, from, + "VideoRAM: %d kByte (%s)\n", pScrn->videoRam, info->ram->name); + +#ifdef ENABLE_FLAT_PANEL + /* Note: Radeon flat panel support has been disabled for now */ + /* Flat panel (part 2) */ + if (info->HasPanelRegs) { +#if 1 + info->CRTOnly = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using flat panel for display\n"); +#else + /* Panel CRT mode override */ + if ((info->CRTOnly = xf86ReturnOptValBool(RADEONOptions, + OPTION_CRT, FALSE))) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Using external CRT instead of " + "flat panel for display\n"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using flat panel for display\n"); + } +#endif + + /* Panel width/height overrides */ + info->PanelXRes = 0; + info->PanelYRes = 0; + if (xf86GetOptValInteger(RADEONOptions, + OPTION_PANEL_WIDTH, &(info->PanelXRes))) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Flat panel width: %d\n", info->PanelXRes); + } + if (xf86GetOptValInteger(RADEONOptions, + OPTION_PANEL_HEIGHT, &(info->PanelYRes))) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Flat panel height: %d\n", info->PanelYRes); + } + } else { + info->CRTOnly = FALSE; + } +#endif + +#ifdef XF86DRI + /* AGP/PCI */ + if (xf86ReturnOptValBool(RADEONOptions, OPTION_IS_PCI, FALSE)) { + info->IsPCI = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forced into PCI-only mode\n"); + } else { + switch (info->Chipset) { +#if 0 + case PCI_CHIP_RADEON_XX: info->IsPCI = TRUE; break; +#endif + case PCI_CHIP_RADEON_QD: + case PCI_CHIP_RADEON_QE: + case PCI_CHIP_RADEON_QF: + case PCI_CHIP_RADEON_QG: + default: info->IsPCI = FALSE; break; + } + } +#endif + + return TRUE; +} + +static Bool RADEONPreInitDDC(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + vbeInfoPtr pVbe; + + if (!xf86LoadSubModule(pScrn, "ddc")) return FALSE; + xf86LoaderReqSymLists(ddcSymbols, NULL); + if (xf86LoadSubModule(pScrn, "vbe")) { + pVbe = VBEInit(NULL,info->pEnt->index); + if (!pVbe) return FALSE; + + xf86SetDDCproperties(pScrn,xf86PrintEDID(vbeDoEDID(pVbe,NULL))); + return TRUE; + } else + return FALSE; +} + +/* This is called by RADEONPreInit to initialize gamma correction. */ +static Bool RADEONPreInitGamma(ScrnInfoPtr pScrn) +{ + Gamma zeros = { 0.0, 0.0, 0.0 }; + + if (!xf86SetGamma(pScrn, zeros)) return FALSE; + return TRUE; +} + +/* This is called by RADEONPreInit to validate modes and compute parameters + for all of the valid modes. */ +static Bool RADEONPreInitModes(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + ClockRangePtr clockRanges; + int modesFound; + char *mod = NULL; + const char *Sym = NULL; + + /* Get mode information */ + pScrn->progClock = TRUE; + clockRanges = xnfcalloc(sizeof(*clockRanges), 1); + clockRanges->next = NULL; + clockRanges->minClock = info->pll.min_pll_freq; + clockRanges->maxClock = info->pll.max_pll_freq * 10; + clockRanges->clockIndex = -1; +#ifdef ENABLE_FLAT_PANEL + /* Note: Radeon flat panel support has been disabled for now */ + if (info->HasPanelRegs) { + clockRanges->interlaceAllowed = FALSE; + clockRanges->doubleScanAllowed = FALSE; + } else { + clockRanges->interlaceAllowed = TRUE; + clockRanges->doubleScanAllowed = TRUE; + } +#else + clockRanges->interlaceAllowed = TRUE; + clockRanges->doubleScanAllowed = TRUE; +#endif + + modesFound = xf86ValidateModes(pScrn, + pScrn->monitor->Modes, + pScrn->display->modes, + clockRanges, + NULL, /* linePitches */ + 8 * 64, /* minPitch */ + 8 * 1024, /* maxPitch */ + 64 * pScrn->bitsPerPixel, /* pitchInc */ + 128, /* minHeight */ + 2048, /* maxHeight */ + pScrn->virtualX, + pScrn->virtualY, + info->FbMapSize, + LOOKUP_BEST_REFRESH); + + if (modesFound < 1 && info->FBDev) { + fbdevHWUseBuildinMode(pScrn); + pScrn->displayWidth = pScrn->virtualX; /* FIXME: might be wrong */ + modesFound = 1; + } + + if (modesFound == -1) return FALSE; + xf86PruneDriverModes(pScrn); + if (!modesFound || !pScrn->modes) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); + return FALSE; + } + xf86SetCrtcForModes(pScrn, 0); + pScrn->currentMode = pScrn->modes; + xf86PrintModes(pScrn); + + /* Set DPI */ + xf86SetDpi(pScrn, 0, 0); + + /* Get ScreenInit function */ +#ifdef USE_FB + mod = "fb"; + Sym = "fbScreenInit"; +#else + switch (pScrn->bitsPerPixel) { + case 8: mod = "cfb"; Sym = "cfbScreenInit"; break; + case 16: mod = "cfb16"; Sym = "cfb16ScreenInit"; break; + case 32: mod = "cfb32"; Sym = "cfb32ScreenInit"; break; + } +#endif + if (mod && !xf86LoadSubModule(pScrn, mod)) return FALSE; + xf86LoaderReqSymbols(Sym, NULL); + +#ifdef USE_FB +#ifdef RENDER + xf86LoaderReqSymbols("fbPictureInit", NULL); +#endif +#endif + + info->CurrentLayout.displayWidth = pScrn->displayWidth; + info->CurrentLayout.mode = pScrn->currentMode; + + return TRUE; +} + +/* This is called by RADEONPreInit to initialize the hardware cursor. */ +static Bool RADEONPreInitCursor(ScrnInfoPtr pScrn) +{ + if (!xf86ReturnOptValBool(RADEONOptions, OPTION_SW_CURSOR, FALSE)) { + if (!xf86LoadSubModule(pScrn, "ramdac")) return FALSE; + } + return TRUE; +} + +/* This is called by RADEONPreInit to initialize hardware acceleration. */ +static Bool RADEONPreInitAccel(ScrnInfoPtr pScrn) +{ + if (!xf86ReturnOptValBool(RADEONOptions, OPTION_NOACCEL, FALSE)) { + if (!xf86LoadSubModule(pScrn, "xaa")) return FALSE; + } + return TRUE; +} + +static Bool RADEONPreInitInt10(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); +#if 1 + if (xf86LoadSubModule(pScrn, "int10")) { + xf86Int10InfoPtr pInt; + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"initializing int10\n"); + pInt = xf86InitInt10(info->pEnt->index); + xf86FreeInt10(pInt); + } +#endif + return TRUE; +} + +#ifdef XF86DRI +static Bool RADEONPreInitDRI(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + if (info->IsPCI) { + info->CPMode = RADEON_DEFAULT_CP_PIO_MODE; + } else if (xf86ReturnOptValBool(RADEONOptions, OPTION_CP_PIO, FALSE)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forcing CP into PIO mode\n"); + info->CPMode = RADEON_DEFAULT_CP_PIO_MODE; + } else { + info->CPMode = RADEON_DEFAULT_CP_BM_MODE; + } + + if (xf86ReturnOptValBool(RADEONOptions, OPTION_USE_CP_2D, FALSE)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using CP for 2D\n"); + info->CP2D = TRUE; + } else { + info->CP2D = FALSE; + } + + if (xf86ReturnOptValBool(RADEONOptions, OPTION_NO_SECURITY, FALSE)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "WARNING!!! CP Security checks disabled!!! **********\n"); + info->CPSecure = FALSE; + } else { + info->CPSecure = TRUE; + } + + info->agpMode = RADEON_DEFAULT_AGP_MODE; + info->agpSize = RADEON_DEFAULT_AGP_SIZE; + info->ringSize = RADEON_DEFAULT_RING_SIZE; + info->vbSize = RADEON_DEFAULT_VB_SIZE; + info->indSize = RADEON_DEFAULT_IND_SIZE; + info->agpTexSize = RADEON_DEFAULT_AGP_TEX_SIZE; + + info->vbBufSize = RADEON_DEFAULT_VB_BUF_SIZE; + + info->CPusecTimeout = RADEON_DEFAULT_CP_TIMEOUT; + + if (!info->IsPCI) { + if (xf86GetOptValInteger(RADEONOptions, + OPTION_AGP_MODE, &(info->agpMode))) { + if (info->agpMode < 1 || info->agpMode > RADEON_AGP_MAX_MODE) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Illegal AGP Mode: %d\n", info->agpMode); + return FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Using AGP %dx mode\n", info->agpMode); + } + + if (xf86GetOptValInteger(RADEONOptions, + OPTION_AGP_SIZE, (int *)&(info->agpSize))) { + switch (info->agpSize) { + case 4: + case 8: + case 16: + case 32: + case 64: + case 128: + case 256: + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Illegal AGP size: %d MB\n", info->agpSize); + return FALSE; + } + } + + if (xf86GetOptValInteger(RADEONOptions, + OPTION_RING_SIZE, &(info->ringSize))) { + if (info->ringSize < 1 || info->ringSize >= info->agpSize) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Illegal ring buffer size: %d MB\n", + info->ringSize); + return FALSE; + } + } + + if (xf86GetOptValInteger(RADEONOptions, + OPTION_VERT_SIZE, &(info->vbSize))) { + if (info->vbSize < 1 || info->vbSize >= info->agpSize) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Illegal vertex buffers list size: %d MB\n", + info->vbSize); + return FALSE; + } + } + + if (xf86GetOptValInteger(RADEONOptions, + OPTION_VBUF_SIZE, &(info->vbBufSize))) { + int numBufs = info->vbSize*1024*1024/info->vbBufSize; + if (numBufs < 2 || numBufs > 512) { /* FIXME: 512 is arbitrary */ + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Illegal individual vertex buffer size: %d bytes\n", + info->vbBufSize); + return FALSE; + } + } + + if (info->ringSize + info->vbSize + info->indSize + info->agpTexSize > + info->agpSize) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Buffers are too big for requested AGP space\n"); + return FALSE; + } + + info->agpTexSize = info->agpSize - (info->ringSize + + info->vbSize + + info->indSize); + } + + if (xf86GetOptValInteger(RADEONOptions, OPTION_USEC_TIMEOUT, + &(info->CPusecTimeout))) { + /* This option checked by the RADEON DRM kernel module */ + } + + return TRUE; +} +#endif + +static void +RADEONProbeDDC(ScrnInfoPtr pScrn, int indx) +{ + vbeInfoPtr pVbe; + if (xf86LoadSubModule(pScrn, "vbe")) { + pVbe = VBEInit(NULL,indx); + ConfiguredMonitor = vbeDoEDID(pVbe, NULL); + } +} + +/* RADEONPreInit is called once at server startup. */ +Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) +{ + RADEONInfoPtr info; + +#ifdef XFree86LOADER + /* + * Tell the loader about symbols from other modules that this module might + * refer to. + */ + LoaderRefSymLists(vgahwSymbols, +#ifdef USE_FB + fbSymbols, +#else + cfbSymbols, +#endif + xaaSymbols, + xf8_32bppSymbols, + ramdacSymbols, +#ifdef XF86DRI + drmSymbols, + driSymbols, +#endif + fbdevHWSymbols, + vbeSymbols, + /* ddcsymbols, */ + /* i2csymbols, */ + /* shadowSymbols, */ + NULL); +#endif + + RADEONTRACE(("RADEONPreInit\n")); + if (pScrn->numEntities != 1) return FALSE; + + if (!RADEONGetRec(pScrn)) return FALSE; + + info = RADEONPTR(pScrn); + + info->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); + if (info->pEnt->location.type != BUS_PCI) goto fail; + + if (flags & PROBE_DETECT) { + RADEONProbeDDC(pScrn, info->pEnt->index); + return TRUE; + } + + if (!xf86LoadSubModule(pScrn, "vgahw")) return FALSE; + xf86LoaderReqSymLists(vgahwSymbols, NULL); + if (!vgaHWGetHWRec(pScrn)) { + RADEONFreeRec(pScrn); + return FALSE; + } + + info->PciInfo = xf86GetPciInfoForEntity(info->pEnt->index); + info->PciTag = pciTag(info->PciInfo->bus, + info->PciInfo->device, + info->PciInfo->func); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "PCI bus %d card %d func %d\n", + info->PciInfo->bus, + info->PciInfo->device, + info->PciInfo->func); + + if (xf86RegisterResources(info->pEnt->index, 0, ResNone)) goto fail; + + pScrn->racMemFlags = RAC_FB | RAC_COLORMAP; + pScrn->monitor = pScrn->confScreen->monitor; + + if (!RADEONPreInitVisual(pScrn)) goto fail; + + /* We can't do this until we have a + pScrn->display. */ + xf86CollectOptions(pScrn, NULL); + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, RADEONOptions); + + if (!RADEONPreInitWeight(pScrn)) goto fail; + + if (xf86ReturnOptValBool(RADEONOptions, OPTION_FBDEV, FALSE)) { + info->FBDev = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Using framebuffer device\n"); + } + + if (info->FBDev) { + /* check for linux framebuffer device */ + if (!xf86LoadSubModule(pScrn, "fbdevhw")) return FALSE; + xf86LoaderReqSymLists(fbdevHWSymbols, NULL); + if (!fbdevHWInit(pScrn, info->PciInfo, NULL)) return FALSE; + pScrn->SwitchMode = fbdevHWSwitchMode; + pScrn->AdjustFrame = fbdevHWAdjustFrame; + pScrn->EnterVT = RADEONEnterVTFBDev; + pScrn->LeaveVT = RADEONLeaveVTFBDev; + pScrn->ValidMode = fbdevHWValidMode; + } + + if (!info->FBDev) + if (!RADEONPreInitInt10(pScrn)) goto fail; + + if (!RADEONPreInitConfig(pScrn)) goto fail; + + if (!RADEONGetBIOSParameters(pScrn)) goto fail; + + if (!RADEONGetPLLParameters(pScrn)) goto fail; + + if (!RADEONPreInitDDC(pScrn)) goto fail; + + if (!RADEONPreInitGamma(pScrn)) goto fail; + + if (!RADEONPreInitModes(pScrn)) goto fail; + + if (!RADEONPreInitCursor(pScrn)) goto fail; + + if (!RADEONPreInitAccel(pScrn)) goto fail; + +#ifdef XF86DRI + if (!RADEONPreInitDRI(pScrn)) goto fail; +#endif + + /* Free the video bios (if applicable) */ + if (info->VBIOS) { + xfree(info->VBIOS); + info->VBIOS = NULL; + } + + return TRUE; + + fail: + /* Pre-init failed. */ + + /* Free the video bios (if applicable) */ + if (info->VBIOS) { + xfree(info->VBIOS); + info->VBIOS = NULL; + } + + vgaHWFreeHWRec(pScrn); + RADEONFreeRec(pScrn); + return FALSE; +} + +/* Load a palette. */ +static void RADEONLoadPalette(ScrnInfoPtr pScrn, int numColors, + int *indices, LOCO *colors, VisualPtr pVisual) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int i; + int idx; + unsigned char r, g, b; + +#ifdef ENABLE_FLAT_PANEL + /* Note: Radeon flat panel support has been disabled for now */ + /* Select palette 0 (main CRTC) if using FP-enabled chip */ + if (info->HasPanelRegs) PAL_SELECT(0); +#endif + + if (info->CurrentLayout.depth == 15) { + /* 15bpp mode. This sends 32 values. */ + for (i = 0; i < numColors; i++) { + idx = indices[i]; + r = colors[idx].red; + g = colors[idx].green; + b = colors[idx].blue; + RADEONWaitForFifo(pScrn, 32); /* delay */ + OUTPAL(idx * 8, r, g, b); + } + } + else if (info->CurrentLayout.depth == 16) { + /* 16bpp mode. This sends 64 values. */ + /* There are twice as many green values as + there are values for red and blue. So, + we take each red and blue pair, and + combine it with each of the two green + values. */ + for (i = 0; i < numColors; i++) { + idx = indices[i]; + r = colors[idx / 2].red; + g = colors[idx].green; + b = colors[idx / 2].blue; + RADEONWaitForFifo(pScrn, 32); /* delay */ + OUTPAL(idx * 4, r, g, b); + + /* AH - Added to write extra green data - How come this isn't + * needed on R128 ? We didn't load the extra green data in the + * other routine */ + if (idx <= 31) { + r = colors[idx].red; + g = colors[(idx * 2) + 1].green; + b = colors[idx].blue; + RADEONWaitForFifo(pScrn, 32); /* delay */ + OUTPAL(idx * 8, r, g, b); + } + } + } + else { + /* 8bpp mode. This sends 256 values. */ + for (i = 0; i < numColors; i++) { + idx = indices[i]; + r = colors[idx].red; + b = colors[idx].blue; + g = colors[idx].green; + RADEONWaitForFifo(pScrn, 32); /* delay */ + OUTPAL(idx, r, g, b); + } + } +} + +/* Called at the start of each server generation. */ +Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + BoxRec MemBox; + int y2; + + RADEONTRACE(("RADEONScreenInit %x %d\n", + pScrn->memPhysBase, pScrn->fbOffset)); + +#ifdef XF86DRI + /* Turn off the CP for now. */ + info->CPInUse = FALSE; +#endif + + if (!RADEONMapMem(pScrn)) return FALSE; + pScrn->fbOffset = 0; +#ifdef XF86DRI + info->fbX = 0; + info->fbY = 0; +#endif + + info->PaletteSavedOnVT = FALSE; + + RADEONSave(pScrn); + if (info->FBDev) { + if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) return FALSE; + } else { + if (!RADEONModeInit(pScrn, pScrn->currentMode)) return FALSE; + } + + RADEONSaveScreen(pScreen, SCREEN_SAVER_ON); + pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + + /* Visual setup */ + miClearVisualTypes(); + if (!miSetVisualTypes(pScrn->depth, + miGetDefaultVisualMask(pScrn->depth), + pScrn->rgbBits, + pScrn->defaultVisual)) return FALSE; + miSetPixmapDepths (); + +#ifdef XF86DRI + /* Setup DRI after visuals have been + established, but before cfbScreenInit is + called. cfbScreenInit will eventually + call the driver's InitGLXVisuals call + back. */ + { + /* FIXME: When we move to dynamic allocation of back and depth + buffers, we will want to revisit the following check for 3 + times the virtual size of the screen below. */ + int width_bytes = (pScrn->displayWidth * + info->CurrentLayout.pixel_bytes); + int maxy = info->FbMapSize / width_bytes; + + if (!xf86ReturnOptValBool(RADEONOptions, OPTION_NOACCEL, FALSE) && + (maxy > pScrn->virtualY * 3) +#ifdef ENABLE_FLAT_PANEL + /* FIXME: Disable 3D support for FPs until it is tested */ + && !info->HasPanelRegs +#endif + ) { + info->directRenderingEnabled = RADEONDRIScreenInit(pScreen); + } else { + xf86DrvMsg(scrnIndex, X_WARNING, + "Static buffer allocation failed -- " + "need at least %d kB video memory\n", + (pScrn->displayWidth * pScrn->virtualY * + info->CurrentLayout.pixel_bytes * 3 + 1023) / 1024); + info->directRenderingEnabled = FALSE; + } + } +#endif + +#ifdef USE_FB + if (!fbScreenInit (pScreen, info->FB, + pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth, + pScrn->bitsPerPixel)) + return FALSE; +#ifdef RENDER + fbPictureInit (pScreen, 0, 0); +#endif +#else + switch (pScrn->bitsPerPixel) { + case 8: + if (!cfbScreenInit(pScreen, info->FB, + pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth)) + return FALSE; + break; + case 16: + if (!cfb16ScreenInit(pScreen, info->FB, + pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth)) + return FALSE; + break; + case 32: + if (!cfb32ScreenInit(pScreen, info->FB, + pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth)) + return FALSE; + break; + default: + xf86DrvMsg(scrnIndex, X_ERROR, + "Invalid bpp (%d)\n", pScrn->bitsPerPixel); + return FALSE; + } +#endif + xf86SetBlackWhitePixels(pScreen); + + if (pScrn->bitsPerPixel > 8) { + VisualPtr visual; + + for (visual = pScreen->visuals + pScreen->numVisuals; + visual >= pScreen->visuals; + visual--) { + if ((visual->class | DynamicClass) == DirectColor) { + visual->offsetRed = pScrn->offset.red; + visual->offsetGreen = pScrn->offset.green; + visual->offsetBlue = pScrn->offset.blue; + visual->redMask = pScrn->mask.red; + visual->greenMask = pScrn->mask.green; + visual->blueMask = pScrn->mask.blue; + } + } + } + + RADEONDGAInit(pScreen); + + /* Memory manager setup */ + MemBox.x1 = 0; + MemBox.y1 = 0; + MemBox.x2 = pScrn->displayWidth; + y2 = (info->FbMapSize + / (pScrn->displayWidth * info->CurrentLayout.pixel_bytes)); + if (y2 >= 32768) y2 = 32767; /* because MemBox.y2 is signed short */ + MemBox.y2 = y2; + + /* The acceleration engine uses 14 bit + signed coordinates, so we can't have any + drawable caches beyond this region. */ + if (MemBox.y2 > 8191) MemBox.y2 = 8191; + + if (!xf86InitFBManager(pScreen, &MemBox)) { + xf86DrvMsg(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 width, height; + FBAreaPtr fbarea; + + xf86DrvMsg(scrnIndex, X_INFO, + "Memory manager initialized to (%d,%d) (%d,%d)\n", + MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); + if ((fbarea = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth, + 2, 0, NULL, NULL, NULL))) { + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved area from (%d,%d) to (%d,%d)\n", + fbarea->box.x1, fbarea->box.y1, + fbarea->box.x2, fbarea->box.y2); + } else { + xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve area\n"); + } + if (xf86QueryLargestOffscreenArea(pScreen, &width, &height, 0, 0, 0)) { + xf86DrvMsg(scrnIndex, X_INFO, + "Largest offscreen area available: %d x %d\n", + width, height); + } + } + +#ifdef XF86DRI + /* Allocate frame buffer space for the + shared back and depth buffers as well + as for local textures. */ + if (info->directRenderingEnabled) { + FBAreaPtr fbarea; + int width_bytes = (pScrn->displayWidth * + info->CurrentLayout.pixel_bytes); + int maxy = info->FbMapSize / width_bytes; + int l; + + switch (info->CPMode) { + case RADEON_DEFAULT_CP_PIO_MODE: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CP in PIO mode\n"); + break; + case RADEON_DEFAULT_CP_BM_MODE: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CP in BM mode\n"); + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CP in UNKNOWN mode\n"); + break; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB AGP aperture\n", info->agpSize); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB for the ring buffer\n", info->ringSize); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB for vertex buffers\n", info->vbSize); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB for indirect buffers\n", info->indSize); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB for AGP textures\n", info->agpTexSize); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d byte vertex buffers\n", info->vbBufSize); + + /* Allocate the shared back buffer */ + if ((fbarea = xf86AllocateOffscreenArea(pScreen, + pScrn->virtualX, + pScrn->virtualY, + 32, NULL, NULL, NULL))) { + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved back buffer from (%d,%d) to (%d,%d)\n", + fbarea->box.x1, fbarea->box.y1, + fbarea->box.x2, fbarea->box.y2); + + info->backX = fbarea->box.x1; + info->backY = fbarea->box.y1; + } else { + xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve back buffer\n"); + info->backX = -1; + info->backY = -1; + } + + /* Allocate the shared depth buffer */ + if ((fbarea = xf86AllocateOffscreenArea(pScreen, + pScrn->virtualX, + pScrn->virtualY, + 32, NULL, NULL, NULL))) { + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved depth buffer from (%d,%d) to (%d,%d)\n", + fbarea->box.x1, fbarea->box.y1, + fbarea->box.x2, fbarea->box.y2); + + info->depthX = fbarea->box.x1; + info->depthY = fbarea->box.y1; + } else { + xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve depth buffer\n"); + info->depthX = -1; + info->depthY = -1; + } + + /* Allocate local texture space */ + if (((maxy - MemBox.y2 - 1) * width_bytes) > + (pScrn->virtualX * pScrn->virtualY * 2 * + info->CurrentLayout.pixel_bytes)) { + info->textureX = 0; + info->textureY = MemBox.y2 + 1; + info->textureSize = (maxy - MemBox.y2 - 1) * width_bytes; + + l = RADEONMinBits((info->textureSize-1) / RADEON_NR_TEX_REGIONS); + if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY; + + info->log2TexGran = l; + info->textureSize = (info->textureSize >> l) << l; + + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved %d kb for textures: (%d,%d)-(%d,%d)\n", + info->textureSize/1024, + info->textureX, info->textureY, + pScrn->displayWidth, maxy); + } else if ((fbarea = xf86AllocateOffscreenArea(pScreen, + pScrn->virtualX, + pScrn->virtualY * 2, + 32, + NULL, NULL, NULL))) { + info->textureX = fbarea->box.x1; + info->textureY = fbarea->box.y1; + info->textureSize = ((fbarea->box.y2 - fbarea->box.y1) * + (fbarea->box.x2 - fbarea->box.x1) * + info->CurrentLayout.pixel_bytes); + + l = RADEONMinBits((info->textureSize-1) / RADEON_NR_TEX_REGIONS); + if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY; + + info->log2TexGran = l; + info->textureSize = (info->textureSize >> l) << l; + + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved %d kb for textures: (%d,%d)-(%d,%d)\n", + info->textureSize/1024, + fbarea->box.x1, fbarea->box.y1, + fbarea->box.x2, fbarea->box.y2); + } else { + xf86DrvMsg(scrnIndex, X_ERROR, + "Unable to reserve texture space in frame buffer\n"); + info->textureX = -1; + info->textureY = -1; + } + } +#endif + + /* Backing store setup */ + miInitializeBackingStore(pScreen); + xf86SetBackingStore(pScreen); + + /* Set Silken Mouse */ + xf86SetSilkenMouse(pScreen); + + /* Acceleration setup */ + if (!xf86ReturnOptValBool(RADEONOptions, OPTION_NOACCEL, FALSE)) { + if (RADEONAccelInit(pScreen)) { + xf86DrvMsg(scrnIndex, X_INFO, "Acceleration enabled\n"); + info->accelOn = TRUE; + } else { + xf86DrvMsg(scrnIndex, X_ERROR, + "Acceleration initialization failed\n"); + xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n"); + info->accelOn = FALSE; + } + } else { + xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n"); + info->accelOn = FALSE; + } + + /* Cursor setup */ + miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); + + /* Hardware cursor setup */ + if (!xf86ReturnOptValBool(RADEONOptions, OPTION_SW_CURSOR, FALSE)) { + if (RADEONCursorInit(pScreen)) { + int width, height; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using hardware cursor (scanline %d)\n", + info->cursor_start / pScrn->displayWidth); + if (xf86QueryLargestOffscreenArea(pScreen, &width, &height, + 0, 0, 0)) { + xf86DrvMsg(scrnIndex, X_INFO, + "Largest offscreen area available: %d x %d\n", + width, height); + } + } else { + xf86DrvMsg(scrnIndex, X_ERROR, + "Hardware cursor initialization failed\n"); + xf86DrvMsg(scrnIndex, X_INFO, "Using software cursor\n"); + } + } else { + xf86DrvMsg(scrnIndex, X_INFO, "Using software cursor\n"); + } + + /* Colormap setup */ + if (!miCreateDefColormap(pScreen)) return FALSE; + if (!xf86HandleColormaps(pScreen, 256, info->dac6bits ? 6 : 8, + (info->FBDev ? fbdevHWLoadPalette : + RADEONLoadPalette), NULL, + CMAP_PALETTED_TRUECOLOR + | CMAP_RELOAD_ON_MODE_SWITCH +#if 0 /* This option messes up text mode! (eich@suse.de) */ + | CMAP_LOAD_EVEN_IF_OFFSCREEN +#endif + )) return FALSE; + + /* DPMS setup */ +#ifdef DPMSExtension +#ifdef ENABLE_FLAT_PANEL + if (!info->HasPanelRegs || info->CRTOnly) + xf86DPMSInit(pScreen, RADEONDisplayPowerManagementSet, 0); +#else + xf86DPMSInit(pScreen, RADEONDisplayPowerManagementSet, 0); +#endif +#endif + + RADEONInitVideo(pScreen); + + /* Provide SaveScreen */ + pScreen->SaveScreen = RADEONSaveScreen; + + /* Wrap CloseScreen */ + info->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = RADEONCloseScreen; + + /* Note unused options */ + if (serverGeneration == 1) + xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); + +#ifdef XF86DRI + /* DRI finalization */ + if (info->directRenderingEnabled) { + /* Now that mi, cfb, drm and others have + done their thing, complete the DRI + setup. */ + info->directRenderingEnabled = RADEONDRIFinishScreenInit(pScreen); + } + if (info->directRenderingEnabled) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering disabled\n"); + } +#endif + + return TRUE; +} + +/* Write common registers (initialized to 0). */ +static void RADEONRestoreCommonRegisters(ScrnInfoPtr pScrn, + RADEONSavePtr restore) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + OUTREG(RADEON_OVR_CLR, restore->ovr_clr); + OUTREG(RADEON_OVR_WID_LEFT_RIGHT, restore->ovr_wid_left_right); + OUTREG(RADEON_OVR_WID_TOP_BOTTOM, restore->ovr_wid_top_bottom); + OUTREG(RADEON_OV0_SCALE_CNTL, restore->ov0_scale_cntl); + OUTREG(RADEON_MPP_TB_CONFIG, restore->mpp_tb_config ); + OUTREG(RADEON_MPP_GP_CONFIG, restore->mpp_gp_config ); + OUTREG(RADEON_SUBPIC_CNTL, restore->subpic_cntl); + OUTREG(RADEON_VIPH_CONTROL, restore->viph_control); + OUTREG(RADEON_I2C_CNTL_1, restore->i2c_cntl_1); + OUTREG(RADEON_GEN_INT_CNTL, restore->gen_int_cntl); + OUTREG(RADEON_CAP0_TRIG_CNTL, restore->cap0_trig_cntl); + OUTREG(RADEON_CAP1_TRIG_CNTL, restore->cap1_trig_cntl); + OUTREG(RADEON_BUS_CNTL, restore->bus_cntl); +} + +/* Write CRTC registers. */ +static void RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn, + RADEONSavePtr restore) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + OUTREG(RADEON_CRTC_GEN_CNTL, restore->crtc_gen_cntl); + + OUTREGP(RADEON_CRTC_EXT_CNTL, restore->crtc_ext_cntl, + RADEON_CRTC_VSYNC_DIS | + RADEON_CRTC_HSYNC_DIS | + RADEON_CRTC_DISPLAY_DIS); + + OUTREGP(RADEON_DAC_CNTL, restore->dac_cntl, + RADEON_DAC_RANGE_CNTL | + RADEON_DAC_BLANKING); + + OUTREG(RADEON_CRTC_H_TOTAL_DISP, restore->crtc_h_total_disp); + OUTREG(RADEON_CRTC_H_SYNC_STRT_WID, restore->crtc_h_sync_strt_wid); + OUTREG(RADEON_CRTC_V_TOTAL_DISP, restore->crtc_v_total_disp); + OUTREG(RADEON_CRTC_V_SYNC_STRT_WID, restore->crtc_v_sync_strt_wid); + OUTREG(RADEON_CRTC_OFFSET, restore->crtc_offset); + OUTREG(RADEON_CRTC_OFFSET_CNTL, restore->crtc_offset_cntl); + OUTREG(RADEON_CRTC_PITCH, restore->crtc_pitch); +} + +#ifdef ENABLE_FLAT_PANEL +/* Note: Radeon flat panel support has been disabled for now */ +/* Write flat panel registers */ +static void RADEONRestoreFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + CARD32 tmp; + + OUTREG(RADEON_CRTC2_GEN_CNTL, restore->crtc2_gen_cntl); + OUTREG(RADEON_FP_CRTC_H_TOTAL_DISP, restore->fp_crtc_h_total_disp); + OUTREG(RADEON_FP_CRTC_V_TOTAL_DISP, restore->fp_crtc_v_total_disp); + OUTREG(RADEON_FP_GEN_CNTL, restore->fp_gen_cntl); + OUTREG(RADEON_FP_H_SYNC_STRT_WID, restore->fp_h_sync_strt_wid); + OUTREG(RADEON_FP_HORZ_STRETCH, restore->fp_horz_stretch); + OUTREG(RADEON_FP_PANEL_CNTL, restore->fp_panel_cntl); + OUTREG(RADEON_FP_V_SYNC_STRT_WID, restore->fp_v_sync_strt_wid); + OUTREG(RADEON_FP_VERT_STRETCH, restore->fp_vert_stretch); + OUTREG(RADEON_TMDS_CRC, restore->tmds_crc); + + tmp = INREG(RADEON_LVDS_GEN_CNTL); + if ((tmp & (RADEON_LVDS_ON | RADEON_LVDS_BLON)) == + (restore->lvds_gen_cntl & (RADEON_LVDS_ON | RADEON_LVDS_BLON))) { + OUTREG(RADEON_LVDS_GEN_CNTL, restore->lvds_gen_cntl); + } else { + if (restore->lvds_gen_cntl & (RADEON_LVDS_ON | RADEON_LVDS_BLON)) { + OUTREG(RADEON_LVDS_GEN_CNTL, + restore->lvds_gen_cntl & ~RADEON_LVDS_BLON); + usleep(RADEONPTR(pScrn)->PanelPwrDly * 1000); + OUTREG(RADEON_LVDS_GEN_CNTL, restore->lvds_gen_cntl); + } else { + OUTREG(RADEON_LVDS_GEN_CNTL, + restore->lvds_gen_cntl | RADEON_LVDS_BLON); + usleep(RADEONPTR(pScrn)->PanelPwrDly * 1000); + OUTREG(RADEON_LVDS_GEN_CNTL, restore->lvds_gen_cntl); + } + } +} +#endif + +#if RADEON_ATOMIC_UPDATE +static void RADEONPLLWaitForReadUpdateComplete(ScrnInfoPtr pScrn) +{ + while (INPLL(pScrn, RADEON_PPLL_REF_DIV) & RADEON_PPLL_ATOMIC_UPDATE_R); +} + +static void RADEONPLLWriteUpdate(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + OUTPLLP(pScrn, RADEON_PPLL_REF_DIV, RADEON_PPLL_ATOMIC_UPDATE_W, 0xffff); +} +#endif + +/* Write PLL registers. */ +static void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + +#if !RADEON_ATOMIC_UPDATE + while ( (INREG(RADEON_CLOCK_CNTL_INDEX) & RADEON_PLL_DIV_SEL) != + RADEON_PLL_DIV_SEL) { +#endif + OUTREGP(RADEON_CLOCK_CNTL_INDEX, RADEON_PLL_DIV_SEL, 0xffff); +#if !RADEON_ATOMIC_UPDATE + } +#endif + +#if RADEON_ATOMIC_UPDATE + OUTPLLP(pScrn, + RADEON_PPLL_CNTL, + RADEON_PPLL_RESET + | RADEON_PPLL_ATOMIC_UPDATE_EN + | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN, + 0xffff); +#else + OUTPLLP(pScrn, + RADEON_PPLL_CNTL, + RADEON_PPLL_RESET, + 0xffff); +#endif + +#if RADEON_ATOMIC_UPDATE + RADEONPLLWaitForReadUpdateComplete(pScrn); +#endif + while ( (INPLL(pScrn, RADEON_PPLL_REF_DIV) & RADEON_PPLL_REF_DIV_MASK) != + (restore->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK)) { + OUTPLLP(pScrn, RADEON_PPLL_REF_DIV, + restore->ppll_ref_div, ~RADEON_PPLL_REF_DIV_MASK); + } +#if RADEON_ATOMIC_UPDATE + RADEONPLLWriteUpdate(pScrn); +#endif + +#if RADEON_ATOMIC_UPDATE + RADEONPLLWaitForReadUpdateComplete(pScrn); +#endif + while ( (INPLL(pScrn, RADEON_PPLL_DIV_3) & RADEON_PPLL_FB3_DIV_MASK) != + (restore->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK)) { + OUTPLLP(pScrn, RADEON_PPLL_DIV_3, + restore->ppll_div_3, ~RADEON_PPLL_FB3_DIV_MASK); + } +#if RADEON_ATOMIC_UPDATE + RADEONPLLWriteUpdate(pScrn); +#endif + +#if RADEON_ATOMIC_UPDATE + RADEONPLLWaitForReadUpdateComplete(pScrn); +#endif + while ( (INPLL(pScrn, RADEON_PPLL_DIV_3) & RADEON_PPLL_POST3_DIV_MASK) != + (restore->ppll_div_3 & RADEON_PPLL_POST3_DIV_MASK)) { + OUTPLLP(pScrn, RADEON_PPLL_DIV_3, + restore->ppll_div_3, ~RADEON_PPLL_POST3_DIV_MASK); + } +#if RADEON_ATOMIC_UPDATE + RADEONPLLWriteUpdate(pScrn); +#endif + +#if RADEON_ATOMIC_UPDATE + RADEONPLLWaitForReadUpdateComplete(pScrn); +#endif + OUTPLL(RADEON_HTOTAL_CNTL, restore->htotal_cntl); +#if RADEON_ATOMIC_UPDATE + RADEONPLLWriteUpdate(pScrn); +#endif + + OUTPLLP(pScrn, RADEON_PPLL_CNTL, 0, ~RADEON_PPLL_RESET); + + RADEONTRACE(("Wrote: 0x%08x 0x%08x 0x%08x (0x%08x)\n", + restore->ppll_ref_div, + restore->ppll_div_3, + restore->htotal_cntl, + INPLL(pScrn, RADEON_PPLL_CNTL))); + RADEONTRACE(("Wrote: rd=%d, fd=%d, pd=%d\n", + restore->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK, + restore->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK, + (restore->ppll_div_3 & RADEON_PPLL_POST3_DIV_MASK) >> 16)); +} + +/* Write DDA registers. */ +static void RADEONRestoreDDARegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + OUTREG(RADEON_DDA_CONFIG, restore->dda_config); + OUTREG(RADEON_DDA_ON_OFF, restore->dda_on_off); +} + +/* Write palette data. */ +static void RADEONRestorePalette(ScrnInfoPtr pScrn, RADEONSavePtr restore) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int i; + + if (!restore->palette_valid) return; + +#ifdef ENABLE_FLAT_PANEL + /* Note: Radeon flat panel support has been disabled for now */ + /* Select palette 0 (main CRTC) if using FP-enabled chip */ + if (info->HasPanelRegs) PAL_SELECT(0); +#endif + + OUTPAL_START(0); + for (i = 0; i < 256; i++) { + RADEONWaitForFifo(pScrn, 32); /* delay */ + OUTPAL_NEXT_CARD32(restore->palette[i]); + } +} + +/* Write out state to define a new video mode. */ +static void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore) +{ +#ifdef ENABLE_FLAT_PANEL + RADEONInfoPtr info = RADEONPTR(pScrn); +#endif + + RADEONTRACE(("RADEONRestoreMode(%p)\n", restore)); + RADEONRestoreCommonRegisters(pScrn, restore); + RADEONRestoreCrtcRegisters(pScrn, restore); +#ifdef ENABLE_FLAT_PANEL + /* Note: Radeon flat panel support has been disabled for now */ + if (info->HasPanelRegs) + RADEONRestoreFPRegisters(pScrn, restore); + if (!info->HasPanelRegs || info->CRTOnly) + RADEONRestorePLLRegisters(pScrn, restore); +#else + RADEONRestorePLLRegisters(pScrn, restore); +#endif + RADEONRestoreDDARegisters(pScrn, restore); + RADEONRestorePalette(pScrn, restore); +} + +/* Read common registers. */ +static void RADEONSaveCommonRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + save->ovr_clr = INREG(RADEON_OVR_CLR); + save->ovr_wid_left_right = INREG(RADEON_OVR_WID_LEFT_RIGHT); + save->ovr_wid_top_bottom = INREG(RADEON_OVR_WID_TOP_BOTTOM); + save->ov0_scale_cntl = INREG(RADEON_OV0_SCALE_CNTL); + save->mpp_tb_config = INREG(RADEON_MPP_TB_CONFIG); + save->mpp_gp_config = INREG(RADEON_MPP_GP_CONFIG); + save->subpic_cntl = INREG(RADEON_SUBPIC_CNTL); + save->viph_control = INREG(RADEON_VIPH_CONTROL); + save->i2c_cntl_1 = INREG(RADEON_I2C_CNTL_1); + save->gen_int_cntl = INREG(RADEON_GEN_INT_CNTL); + save->cap0_trig_cntl = INREG(RADEON_CAP0_TRIG_CNTL); + save->cap1_trig_cntl = INREG(RADEON_CAP1_TRIG_CNTL); + save->bus_cntl = INREG(RADEON_BUS_CNTL); +} + +/* Read CRTC registers. */ +static void RADEONSaveCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + save->crtc_gen_cntl = INREG(RADEON_CRTC_GEN_CNTL); + save->crtc_ext_cntl = INREG(RADEON_CRTC_EXT_CNTL); + save->dac_cntl = INREG(RADEON_DAC_CNTL); + save->crtc_h_total_disp = INREG(RADEON_CRTC_H_TOTAL_DISP); + save->crtc_h_sync_strt_wid = INREG(RADEON_CRTC_H_SYNC_STRT_WID); + save->crtc_v_total_disp = INREG(RADEON_CRTC_V_TOTAL_DISP); + save->crtc_v_sync_strt_wid = INREG(RADEON_CRTC_V_SYNC_STRT_WID); + save->crtc_offset = INREG(RADEON_CRTC_OFFSET); + save->crtc_offset_cntl = INREG(RADEON_CRTC_OFFSET_CNTL); + save->crtc_pitch = INREG(RADEON_CRTC_PITCH); +} + +#ifdef ENABLE_FLAT_PANEL +/* Note: Radeon flat panel support has been disabled for now */ +/* Read flat panel registers */ +static void RADEONSaveFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + save->crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL); + save->fp_crtc_h_total_disp = INREG(RADEON_FP_CRTC_H_TOTAL_DISP); + save->fp_crtc_v_total_disp = INREG(RADEON_FP_CRTC_V_TOTAL_DISP); + save->fp_gen_cntl = INREG(RADEON_FP_GEN_CNTL); + save->fp_h_sync_strt_wid = INREG(RADEON_FP_H_SYNC_STRT_WID); + save->fp_horz_stretch = INREG(RADEON_FP_HORZ_STRETCH); + save->fp_panel_cntl = INREG(RADEON_FP_PANEL_CNTL); + save->fp_v_sync_strt_wid = INREG(RADEON_FP_V_SYNC_STRT_WID); + save->fp_vert_stretch = INREG(RADEON_FP_VERT_STRETCH); + save->lvds_gen_cntl = INREG(RADEON_LVDS_GEN_CNTL); + save->tmds_crc = INREG(RADEON_TMDS_CRC); +} +#endif + +/* Read PLL registers. */ +static void RADEONSavePLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) +{ + save->ppll_ref_div = INPLL(pScrn, RADEON_PPLL_REF_DIV); + save->ppll_div_3 = INPLL(pScrn, RADEON_PPLL_DIV_3); + save->htotal_cntl = INPLL(pScrn, RADEON_HTOTAL_CNTL); + + RADEONTRACE(("Read: 0x%08x 0x%08x 0x%08x\n", + save->ppll_ref_div, + save->ppll_div_3, + save->htotal_cntl)); + RADEONTRACE(("Read: rd=%d, fd=%d, pd=%d\n", + save->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK, + save->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK, + (save->ppll_div_3 & RADEON_PPLL_POST3_DIV_MASK) >> 16)); +} + +/* Read DDA registers. */ +static void RADEONSaveDDARegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + save->dda_config = INREG(RADEON_DDA_CONFIG); + save->dda_on_off = INREG(RADEON_DDA_ON_OFF); +} + +/* Read palette data. */ +static void RADEONSavePalette(ScrnInfoPtr pScrn, RADEONSavePtr save) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int i; + +#ifdef ENABLE_FLAT_PANEL + /* Note: Radeon flat panel support has been disabled for now */ + /* Select palette 0 (main CRTC) if using FP-enabled chip */ + if (info->HasPanelRegs) PAL_SELECT(0); +#endif + + INPAL_START(0); + for (i = 0; i < 256; i++) save->palette[i] = INPAL_NEXT(); + save->palette_valid = TRUE; +} + +/* Save state that defines current video mode. */ +static void RADEONSaveMode(ScrnInfoPtr pScrn, RADEONSavePtr save) +{ + RADEONTRACE(("RADEONSaveMode(%p)\n", save)); + + RADEONSaveCommonRegisters(pScrn, save); + RADEONSaveCrtcRegisters(pScrn, save); +#ifdef ENABLE_FLAT_PANEL + /* Note: Radeon flat panel support has been disabled for now */ + if (RADEONPTR(pScrn)->HasPanelRegs) + RADEONSaveFPRegisters(pScrn, save); +#endif + RADEONSavePLLRegisters(pScrn, save); + RADEONSaveDDARegisters(pScrn, save); + RADEONSavePalette(pScrn, save); + + RADEONTRACE(("RADEONSaveMode returns %p\n", save)); +} + +/* Save everything needed to restore the original VC state. */ +static void RADEONSave(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + RADEONSavePtr save = &info->SavedReg; + vgaHWPtr hwp = VGAHWPTR(pScrn); + + RADEONTRACE(("RADEONSave\n")); + if (info->FBDev) { + fbdevHWSave(pScrn); + return; + } + vgaHWUnlock(hwp); + vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_ALL); /* save mode, fonts, cmap */ + vgaHWLock(hwp); + + RADEONSaveMode(pScrn, save); + + save->dp_datatype = INREG(RADEON_DP_DATATYPE); + save->rbbm_soft_reset = INREG(RADEON_RBBM_SOFT_RESET); + save->clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX); + save->amcgpio_en_reg = INREG(RADEON_AMCGPIO_EN_REG); + save->amcgpio_mask = INREG(RADEON_AMCGPIO_MASK); +} + +/* Restore the original (text) mode. */ +static void RADEONRestore(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + RADEONSavePtr restore = &info->SavedReg; + vgaHWPtr hwp = VGAHWPTR(pScrn); + + RADEONTRACE(("RADEONRestore\n")); + if (info->FBDev) { + fbdevHWRestore(pScrn); + return; + } + + RADEONBlank(pScrn); + + OUTREG(RADEON_AMCGPIO_MASK, restore->amcgpio_mask); + OUTREG(RADEON_AMCGPIO_EN_REG, restore->amcgpio_en_reg); + OUTREG(RADEON_CLOCK_CNTL_INDEX, restore->clock_cntl_index); + OUTREG(RADEON_RBBM_SOFT_RESET, restore->rbbm_soft_reset); + OUTREG(RADEON_DP_DATATYPE, restore->dp_datatype); + + RADEONRestoreMode(pScrn, restore); + vgaHWUnlock(hwp); + vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS ); + vgaHWLock(hwp); + +#if 0 + RADEONWaitForVerticalSync(pScrn); +#endif + RADEONUnblank(pScrn); +} + +/* Define common registers for requested video mode. */ +static void RADEONInitCommonRegisters(RADEONSavePtr save, RADEONInfoPtr info) +{ + save->ovr_clr = 0; + save->ovr_wid_left_right = 0; + save->ovr_wid_top_bottom = 0; + save->ov0_scale_cntl = 0; + save->mpp_tb_config = 0; + save->mpp_gp_config = 0; + save->subpic_cntl = 0; + save->viph_control = 0; + save->i2c_cntl_1 = 0; + save->rbbm_soft_reset = 0; + save->cap0_trig_cntl = 0; + save->cap1_trig_cntl = 0; + save->bus_cntl = info->BusCntl; + /* + * If bursts are enabled, turn on discards + * Radeon doesn't have write bursts + */ + if (save->bus_cntl & (RADEON_BUS_READ_BURST)) + save->bus_cntl |= RADEON_BUS_RD_DISCARD_EN; +} + +/* Define CRTC registers for requested video mode. */ +static Bool RADEONInitCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, + DisplayModePtr mode, RADEONInfoPtr info) +{ + int format; + int hsync_start; + int hsync_wid; + int hsync_fudge; + int vsync_wid; + int bytpp; + int hsync_fudge_default[] = { 0x00, 0x12, 0x09, 0x09, 0x06, 0x05 }; +#ifdef ENABLE_FLAT_PANEL + /* Note: Radeon flat panel support has been disabled for now */ + int hsync_fudge_fp[] = { 0x12, 0x11, 0x09, 0x09, 0x05, 0x05 }; + int hsync_fudge_fp_crt[] = { 0x12, 0x10, 0x08, 0x08, 0x04, 0x04 }; +#endif + + switch (info->CurrentLayout.pixel_code) { + case 4: format = 1; bytpp = 0; break; + case 8: format = 2; bytpp = 1; break; + case 15: format = 3; bytpp = 2; break; /* 555 */ + case 16: format = 4; bytpp = 2; break; /* 565 */ + case 24: format = 5; bytpp = 3; break; /* RGB */ + case 32: format = 6; bytpp = 4; break; /* xRGB */ + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Unsupported pixel depth (%d)\n", info->CurrentLayout.bitsPerPixel); + return FALSE; + } + RADEONTRACE(("Format = %d (%d bytes per pixel)\n", format, bytpp)); + +#ifdef ENABLE_FLAT_PANEL + /* Note: Radeon flat panel support has been disabled for now */ + if (info->HasPanelRegs) + if (info->CRTOnly) hsync_fudge = hsync_fudge_fp_crt[format-1]; + else hsync_fudge = hsync_fudge_fp[format-1]; + else hsync_fudge = hsync_fudge_default[format-1]; +#else + hsync_fudge = hsync_fudge_default[format-1]; +#endif + + save->crtc_gen_cntl = (RADEON_CRTC_EXT_DISP_EN + | RADEON_CRTC_EN + | (format << 8) + | ((mode->Flags & V_DBLSCAN) + ? RADEON_CRTC_DBL_SCAN_EN + : 0) + | ((mode->Flags & V_INTERLACE) + ? RADEON_CRTC_INTERLACE_EN + : 0)); + + save->crtc_ext_cntl = RADEON_VGA_ATI_LINEAR | RADEON_XCRT_CNT_EN; + save->dac_cntl = (RADEON_DAC_MASK_ALL + | RADEON_DAC_VGA_ADR_EN + | (info->dac6bits ? 0 : RADEON_DAC_8BIT_EN)); + + save->crtc_h_total_disp = ((((mode->CrtcHTotal / 8) - 1) & 0xffff) + | (((mode->CrtcHDisplay / 8) - 1) << 16)); + + hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8; + if (!hsync_wid) hsync_wid = 1; + if (hsync_wid > 0x3f) hsync_wid = 0x3f; + + hsync_start = mode->CrtcHSyncStart - 8 + hsync_fudge; + + save->crtc_h_sync_strt_wid = ((hsync_start & 0x1fff) + | (hsync_wid << 16) + | ((mode->Flags & V_NHSYNC) + ? RADEON_CRTC_H_SYNC_POL + : 0)); + +#if 1 + /* This works for double scan mode. */ + save->crtc_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff) + | ((mode->CrtcVDisplay - 1) << 16)); +#else + /* This is what cce/nbmode.c example code + does -- is this correct? */ + save->crtc_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff) + | ((mode->CrtcVDisplay + * ((mode->Flags & V_DBLSCAN) ? 2 : 1) - 1) + << 16)); +#endif + + vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart; + if (!vsync_wid) vsync_wid = 1; + if (vsync_wid > 0x1f) vsync_wid = 0x1f; + + save->crtc_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff) + | (vsync_wid << 16) + | ((mode->Flags & V_NVSYNC) + ? RADEON_CRTC_V_SYNC_POL + : 0)); + save->crtc_offset = 0; + save->crtc_offset_cntl = 0; + + save->crtc_pitch = ((pScrn->displayWidth * pScrn->bitsPerPixel) + + ((pScrn->bitsPerPixel * 8) -1)) / + (pScrn->bitsPerPixel * 8); + save->crtc_pitch |= save->crtc_pitch << 16; + + RADEONTRACE(("Pitch = %d bytes (virtualX = %d, displayWidth = %d)\n", + save->crtc_pitch, pScrn->virtualX, + info->CurrentLayout.displayWidth)); + return TRUE; +} + +#ifdef ENABLE_FLAT_PANEL +/* Note: Radeon flat panel support has been disabled for now */ +/* Define CRTC registers for requested video mode. */ +static void RADEONInitFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr orig, + RADEONSavePtr save, DisplayModePtr mode, + RADEONInfoPtr info) +{ + int xres = mode->CrtcHDisplay; + int yres = mode->CrtcVDisplay; + float Hratio, Vratio; + + if (info->CRTOnly) { + save->crtc_ext_cntl |= RADEON_CRTC_CRT_ON; + save->crtc2_gen_cntl = 0; + save->fp_gen_cntl = orig->fp_gen_cntl; + save->fp_gen_cntl &= ~(RADEON_FP_FPON | + RADEON_FP_CRTC_USE_SHADOW_VEND | + RADEON_FP_CRTC_HORZ_DIV2_EN | + RADEON_FP_CRTC_HOR_CRT_DIV2_DIS | + RADEON_FP_USE_SHADOW_EN); + save->fp_gen_cntl |= (RADEON_FP_SEL_CRTC2 | + RADEON_FP_CRTC_DONT_SHADOW_VPAR); + save->fp_panel_cntl = orig->fp_panel_cntl & ~RADEON_FP_DIGON; + save->lvds_gen_cntl = orig->lvds_gen_cntl & ~(RADEON_LVDS_ON | + RADEON_LVDS_BLON); + return; + } + + if (xres > info->PanelXRes) xres = info->PanelXRes; + if (yres > info->PanelYRes) yres = info->PanelYRes; + + Hratio = (float)xres/(float)info->PanelXRes; + Vratio = (float)yres/(float)info->PanelYRes; + + save->fp_horz_stretch = + (((((int)(Hratio * RADEON_HORZ_STRETCH_RATIO_MAX + 0.5)) + & RADEON_HORZ_STRETCH_RATIO_MASK) + << RADEON_HORZ_STRETCH_RATIO_SHIFT) | + (orig->fp_horz_stretch & (RADEON_HORZ_PANEL_SIZE | + RADEON_HORZ_FP_LOOP_STRETCH | + RADEON_HORZ_STRETCH_RESERVED))); + save->fp_horz_stretch &= ~RADEON_HORZ_AUTO_RATIO_FIX_EN; + if (Hratio == 1.0) save->fp_horz_stretch &= ~(RADEON_HORZ_STRETCH_BLEND | + RADEON_HORZ_STRETCH_ENABLE); + else save->fp_horz_stretch |= (RADEON_HORZ_STRETCH_BLEND | + RADEON_HORZ_STRETCH_ENABLE); + + save->fp_vert_stretch = + (((((int)(Vratio * RADEON_VERT_STRETCH_RATIO_MAX + 0.5)) + & RADEON_VERT_STRETCH_RATIO_MASK) + << RADEON_VERT_STRETCH_RATIO_SHIFT) | + (orig->fp_vert_stretch & (RADEON_VERT_PANEL_SIZE | + RADEON_VERT_STRETCH_RESERVED))); + save->fp_vert_stretch &= ~RADEON_VERT_AUTO_RATIO_EN; + if (Vratio == 1.0) save->fp_vert_stretch &= ~(RADEON_VERT_STRETCH_ENABLE | + RADEON_VERT_STRETCH_BLEND); + else save->fp_vert_stretch |= (RADEON_VERT_STRETCH_ENABLE | + RADEON_VERT_STRETCH_BLEND); + + save->fp_gen_cntl = (orig->fp_gen_cntl & ~(RADEON_FP_SEL_CRTC2 | + RADEON_FP_CRTC_USE_SHADOW_VEND | + RADEON_FP_CRTC_HORZ_DIV2_EN | + RADEON_FP_CRTC_HOR_CRT_DIV2_DIS | + RADEON_FP_USE_SHADOW_EN)); + if (orig->fp_gen_cntl & RADEON_FP_DETECT_SENSE) { + save->fp_gen_cntl |= (RADEON_FP_CRTC_DONT_SHADOW_VPAR | + RADEON_FP_TDMS_EN); + } + + save->fp_panel_cntl = orig->fp_panel_cntl; + save->lvds_gen_cntl = orig->lvds_gen_cntl; + + save->tmds_crc = orig->tmds_crc; + + /* Disable CRT output by disabling CRT output and setting the CRT + DAC to use CRTC2, which we set to 0's. In the future, we will + want to use the dual CRTC capabilities of the RADEON to allow both + the flat panel and external CRT to either simultaneously display + the same image or display two different images. */ + save->crtc_ext_cntl &= ~RADEON_CRTC_CRT_ON; + save->dac_cntl |= RADEON_DAC_CRT_SEL_CRTC2; + save->crtc2_gen_cntl = 0; + + /* WARNING: Be careful about turning on the flat panel */ +#if 1 + save->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_BLON); +#else + save->fp_panel_cntl |= (RADEON_FP_DIGON | RADEON_FP_BLON); + save->fp_gen_cntl |= (RADEON_FP_FPON); +#endif + + save->fp_crtc_h_total_disp = save->crtc_h_total_disp; + save->fp_crtc_v_total_disp = save->crtc_v_total_disp; + save->fp_h_sync_strt_wid = save->crtc_h_sync_strt_wid; + save->fp_v_sync_strt_wid = save->crtc_v_sync_strt_wid; +} +#endif + +/* Define PLL registers for requested video mode. */ +static void RADEONInitPLLRegisters(RADEONSavePtr save, RADEONPLLPtr pll, + double dot_clock) +{ + unsigned long freq = dot_clock * 100; + struct { + int divider; + int bitvalue; + } *post_div, + post_divs[] = { + /* From RAGE 128 VR/RAGE 128 GL Register + Reference Manual (Technical Reference + Manual P/N RRG-G04100-C Rev. 0.04), page + 3-17 (PLL_DIV_[3:0]). */ + { 1, 0 }, /* VCLK_SRC */ + { 2, 1 }, /* VCLK_SRC/2 */ + { 4, 2 }, /* VCLK_SRC/4 */ + { 8, 3 }, /* VCLK_SRC/8 */ + { 3, 4 }, /* VCLK_SRC/3 */ + { 16, 5 }, /* VCLK_SRC/16 */ + { 6, 6 }, /* VCLK_SRC/6 */ + { 12, 7 }, /* VCLK_SRC/12 */ + { 0, 0 } + }; + + if (freq > pll->max_pll_freq) freq = pll->max_pll_freq; + if (freq * 12 < pll->min_pll_freq) freq = pll->min_pll_freq / 12; + + for (post_div = &post_divs[0]; post_div->divider; ++post_div) { + save->pll_output_freq = post_div->divider * freq; + if (save->pll_output_freq >= pll->min_pll_freq + && save->pll_output_freq <= pll->max_pll_freq) break; + } + + save->dot_clock_freq = freq; + save->feedback_div = RADEONDiv(pll->reference_div + * save->pll_output_freq, + pll->reference_freq); + save->post_div = post_div->divider; + + RADEONTRACE(("dc=%d, of=%d, fd=%d, pd=%d\n", + save->dot_clock_freq, + save->pll_output_freq, + save->feedback_div, + save->post_div)); + + save->ppll_ref_div = pll->reference_div; + save->ppll_div_3 = (save->feedback_div | (post_div->bitvalue << 16)); + save->htotal_cntl = 0; +} + +/* Define DDA registers for requested video mode. */ +static Bool RADEONInitDDARegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, + RADEONPLLPtr pll, RADEONInfoPtr info) +{ + int DisplayFifoWidth = 128; + int DisplayFifoDepth = 32; + int XclkFreq; + int VclkFreq; + int XclksPerTransfer; + int XclksPerTransferPrecise; + int UseablePrecision; + int Roff; + int Ron; + + XclkFreq = pll->xclk; + + VclkFreq = RADEONDiv(pll->reference_freq * save->feedback_div, + pll->reference_div * save->post_div); + + XclksPerTransfer = RADEONDiv(XclkFreq * DisplayFifoWidth, + VclkFreq * + (info->CurrentLayout.pixel_bytes * 8)); + + UseablePrecision = RADEONMinBits(XclksPerTransfer) + 1; + + XclksPerTransferPrecise = RADEONDiv((XclkFreq * DisplayFifoWidth) + << (11 - UseablePrecision), + VclkFreq * + (info->CurrentLayout.pixel_bytes * 8)); + + Roff = XclksPerTransferPrecise * (DisplayFifoDepth - 4); + + Ron = (4 * info->ram->MB + + 3 * MAX(info->ram->Trcd - 2, 0) + + 2 * info->ram->Trp + + info->ram->Twr + + info->ram->CL + + info->ram->Tr2w + + XclksPerTransfer) << (11 - UseablePrecision); + + if (Ron + info->ram->Rloop >= Roff) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "(Ron = %d) + (Rloop = %d) >= (Roff = %d)\n", + Ron, info->ram->Rloop, Roff); + return FALSE; + } + + save->dda_config = (XclksPerTransferPrecise + | (UseablePrecision << 16) + | (info->ram->Rloop << 20)); + + save->dda_on_off = (Ron << 16) | Roff; + + RADEONTRACE(("XclkFreq = %d; VclkFreq = %d; per = %d, %d (useable = %d)\n", + XclkFreq, + VclkFreq, + XclksPerTransfer, + XclksPerTransferPrecise, + UseablePrecision)); + RADEONTRACE(("Roff = %d, Ron = %d, Rloop = %d\n", + Roff, Ron, info->ram->Rloop)); + + return TRUE; +} + + +/* Define initial palette for requested video mode. This doesn't do + anything for XFree86 4.0. */ +static void RADEONInitPalette(RADEONSavePtr save) +{ + save->palette_valid = FALSE; +} + +/* Define registers for a requested video mode. */ +static Bool RADEONInit(ScrnInfoPtr pScrn, DisplayModePtr mode, + RADEONSavePtr save) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + double dot_clock = mode->Clock/1000.0; + +#if RADEON_DEBUG + ErrorF("%-12.12s %7.2f %4d %4d %4d %4d %4d %4d %4d %4d (%d,%d)", + mode->name, + dot_clock, + + mode->HDisplay, + mode->HSyncStart, + mode->HSyncEnd, + mode->HTotal, + + mode->VDisplay, + mode->VSyncStart, + mode->VSyncEnd, + mode->VTotal, + pScrn->depth, + pScrn->bitsPerPixel); + if (mode->Flags & V_DBLSCAN) ErrorF(" D"); + if (mode->Flags & V_INTERLACE) ErrorF(" I"); + if (mode->Flags & V_PHSYNC) ErrorF(" +H"); + if (mode->Flags & V_NHSYNC) ErrorF(" -H"); + if (mode->Flags & V_PVSYNC) ErrorF(" +V"); + if (mode->Flags & V_NVSYNC) ErrorF(" -V"); + ErrorF("\n"); + ErrorF("%-12.12s %7.2f %4d %4d %4d %4d %4d %4d %4d %4d (%d,%d)", + mode->name, + dot_clock, + + mode->CrtcHDisplay, + mode->CrtcHSyncStart, + mode->CrtcHSyncEnd, + mode->CrtcHTotal, + + mode->CrtcVDisplay, + mode->CrtcVSyncStart, + mode->CrtcVSyncEnd, + mode->CrtcVTotal, + pScrn->depth, + pScrn->bitsPerPixel); + if (mode->Flags & V_DBLSCAN) ErrorF(" D"); + if (mode->Flags & V_INTERLACE) ErrorF(" I"); + if (mode->Flags & V_PHSYNC) ErrorF(" +H"); + if (mode->Flags & V_NHSYNC) ErrorF(" -H"); + if (mode->Flags & V_PVSYNC) ErrorF(" +V"); + if (mode->Flags & V_NVSYNC) ErrorF(" -V"); + ErrorF("\n"); +#endif + + info->Flags = mode->Flags; + + RADEONInitCommonRegisters(save, info); + if (!RADEONInitCrtcRegisters(pScrn, save, mode, info)) return FALSE; +#ifdef ENABLE_FLAT_PANEL + /* Note: Radeon flat panel support has been disabled for now */ + if (info->HasPanelRegs) + RADEONInitFPRegisters(pScrn, &info->SavedReg, save, mode, info); +#endif + RADEONInitPLLRegisters(save, &info->pll, dot_clock); + if (!RADEONInitDDARegisters(pScrn, save, &info->pll, info)) + return FALSE; + if (!info->PaletteSavedOnVT) RADEONInitPalette(save); + + RADEONTRACE(("RADEONInit returns %p\n", save)); + return TRUE; +} + +/* Initialize a new mode. */ +static Bool RADEONModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + if (!RADEONInit(pScrn, mode, &info->ModeReg)) return FALSE; + /* FIXME? DRILock/DRIUnlock here? */ + pScrn->vtSema = TRUE; + RADEONBlank(pScrn); + RADEONRestoreMode(pScrn, &info->ModeReg); + RADEONUnblank(pScrn); + + info->CurrentLayout.mode = mode; + + return TRUE; +} + +static Bool RADEONSaveScreen(ScreenPtr pScreen, int mode) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + Bool unblank; + + unblank = xf86IsUnblank(mode); + if (unblank) + SetTimeSinceLastInputEvent(); + + if ((pScrn != NULL) && pScrn->vtSema) { + if (unblank) + RADEONUnblank(pScrn); + else + RADEONBlank(pScrn); + } + return TRUE; +} + +Bool RADEONSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) +{ + return RADEONModeInit(xf86Screens[scrnIndex], mode); +} + +/* Used to disallow modes that are not supported by the hardware. */ +int RADEONValidMode(int scrnIndex, DisplayModePtr mode, + Bool verbose, int flag) +{ +#ifdef ENABLE_FLAT_PANEL + /* Note: Radeon flat panel support has been disabled for now */ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + RADEONInfoPtr info = RADEONPTR(pScrn); + + if (info->HasPanelRegs) { + if (mode->Flags & V_INTERLACE) return MODE_NO_INTERLACE; + if (mode->Flags & V_DBLSCAN) return MODE_NO_DBLESCAN; + } + + if (info->HasPanelRegs && !info->CRTOnly && info->VBIOS) { + int i; + for (i = info->FPBIOSstart+64; RADEON_BIOS16(i) != 0; i += 2) { + int j = RADEON_BIOS16(i); + + if (mode->CrtcHDisplay == RADEON_BIOS16(j) && + mode->CrtcVDisplay == RADEON_BIOS16(j+2)) { + /* Assume we are using expanded mode */ + if (RADEON_BIOS16(j+5)) j = RADEON_BIOS16(j+5); + else j += 9; + + mode->Clock = (CARD32)RADEON_BIOS16(j) * 10; + + mode->HDisplay = mode->CrtcHDisplay = + ((RADEON_BIOS16(j+10) & 0x01ff)+1)*8; + mode->HSyncStart = mode->CrtcHSyncStart = + ((RADEON_BIOS16(j+12) & 0x01ff)+1)*8; + mode->HSyncEnd = mode->CrtcHSyncEnd = + mode->CrtcHSyncStart + (RADEON_BIOS8(j+14) & 0x1f); + mode->HTotal = mode->CrtcHTotal = + ((RADEON_BIOS16(j+8) & 0x01ff)+1)*8; + + mode->VDisplay = mode->CrtcVDisplay = + (RADEON_BIOS16(j+17) & 0x07ff)+1; + mode->VSyncStart = mode->CrtcVSyncStart = + (RADEON_BIOS16(j+19) & 0x07ff)+1; + mode->VSyncEnd = mode->CrtcVSyncEnd = + mode->CrtcVSyncStart + ((RADEON_BIOS16(j+19) >> 11)&0x1f); + mode->VTotal = mode->CrtcVTotal = + (RADEON_BIOS16(j+15) & 0x07ff)+1; + + return MODE_OK; + } + } + return MODE_NOMODE; + } +#endif + + return MODE_OK; +} + +/* Adjust viewport into virtual desktop such that (0,0) in viewport space + is (x,y) in virtual space. */ +void RADEONAdjustFrame(int scrnIndex, int x, int y, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int Base; + + Base = y * info->CurrentLayout.displayWidth + x; + + switch (info->CurrentLayout.pixel_code) { + case 15: + case 16: Base *= 2; break; + case 24: Base *= 3; break; + case 32: Base *= 4; break; + } + + Base &= ~7; /* 3 lower bits are always 0 */ + + OUTREG(RADEON_CRTC_OFFSET, Base); +} + +/* Called when VT switching back to the X server. Reinitialize the video + mode. */ +Bool RADEONEnterVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + RADEONInfoPtr info = RADEONPTR(pScrn); + + RADEONTRACE(("RADEONEnterVT\n")); +#ifdef XF86DRI + if (RADEONPTR(pScrn)->directRenderingEnabled) { + RADEONCPStart(pScrn); + DRIUnlock(pScrn->pScreen); + } +#endif + if (!RADEONModeInit(pScrn, pScrn->currentMode)) return FALSE; + if (info->accelOn) + RADEONEngineInit(pScrn); + + info->PaletteSavedOnVT = FALSE; + RADEONAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + + return TRUE; +} + +/* Called when VT switching away from the X server. Restore the original + text mode. */ +void RADEONLeaveVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONSavePtr save = &info->ModeReg; + + RADEONTRACE(("RADEONLeaveVT\n")); +#ifdef XF86DRI + if (RADEONPTR(pScrn)->directRenderingEnabled) { + DRILock(pScrn->pScreen, 0); + RADEONCPStop(pScrn); + } +#endif + RADEONSavePalette(pScrn, save); + info->PaletteSavedOnVT = TRUE; + RADEONRestore(pScrn); +} + +static Bool +RADEONEnterVTFBDev(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONSavePtr restore = &info->SavedReg; + fbdevHWEnterVT(scrnIndex,flags); + RADEONRestorePalette(pScrn,restore); + RADEONEngineInit(pScrn); + return TRUE; +} + +static void RADEONLeaveVTFBDev(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONSavePtr save = &info->SavedReg; + RADEONSavePalette(pScrn,save); + fbdevHWLeaveVT(scrnIndex,flags); +} + +/* Called at the end of each server generation. Restore the original text + mode, unmap video memory, and unwrap and call the saved CloseScreen + function. */ +static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + RADEONInfoPtr info = RADEONPTR(pScrn); + + RADEONTRACE(("RADEONCloseScreen\n")); + +#ifdef XF86DRI + /* Disable direct rendering */ + if (info->directRenderingEnabled) { + RADEONDRICloseScreen(pScreen); + info->directRenderingEnabled = FALSE; + } +#endif + + if (pScrn->vtSema) { + RADEONRestore(pScrn); + RADEONUnmapMem(pScrn); + } + + if (info->accel) XAADestroyInfoRec(info->accel); + info->accel = NULL; + + if (info->scratch_save) xfree(info->scratch_save); + info->scratch_save = NULL; + + if (info->cursor) xf86DestroyCursorInfoRec(info->cursor); + info->cursor = NULL; + + if (info->DGAModes) xfree(info->DGAModes); + info->DGAModes = NULL; + + pScrn->vtSema = FALSE; + + pScreen->CloseScreen = info->CloseScreen; + return (*pScreen->CloseScreen)(scrnIndex, pScreen); +} + +void RADEONFreeScreen(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + + RADEONTRACE(("RADEONFreeScreen\n")); + if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) + vgaHWFreeHWRec(pScrn); + RADEONFreeRec(pScrn); +} + +#ifdef DPMSExtension +/* Sets VESA Display Power Management Signaling (DPMS) Mode. */ +static void RADEONDisplayPowerManagementSet(ScrnInfoPtr pScrn, + int PowerManagementMode, int flags) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int mask = (RADEON_CRTC_DISPLAY_DIS + | RADEON_CRTC_HSYNC_DIS + | RADEON_CRTC_VSYNC_DIS); + + switch (PowerManagementMode) { + case DPMSModeOn: + /* Screen: On; HSync: On, VSync: On */ + OUTREGP(RADEON_CRTC_EXT_CNTL, 0, ~mask); + break; + case DPMSModeStandby: + /* Screen: Off; HSync: Off, VSync: On */ + OUTREGP(RADEON_CRTC_EXT_CNTL, + RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS, ~mask); + break; + case DPMSModeSuspend: + /* Screen: Off; HSync: On, VSync: Off */ + OUTREGP(RADEON_CRTC_EXT_CNTL, + RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS, ~mask); + break; + case DPMSModeOff: + /* Screen: Off; HSync: Off, VSync: Off */ + OUTREGP(RADEON_CRTC_EXT_CNTL, mask, ~mask); + break; + } +} +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_misc.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_misc.c new file mode 100644 index 000000000..50cf084f1 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_misc.c @@ -0,0 +1,85 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_misc.c,v 1.1 2000/11/02 16:55:43 tsi Exp $ */ +/* + * Copyright 2000 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of Marc Aurele La France not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Marc Aurele La France makes no representations + * about the suitability of this software for any purpose. It is provided + * "as-is" without express or implied warranty. + * + * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO + * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef XFree86LOADER + +#include "ati.h" +#include "ativersion.h" + +#include "radeon_version.h" + +#include "xf86.h" + +/* Module loader interface for subsidiary driver module */ + +static XF86ModuleVersionInfo RADEONVersionRec = +{ + RADEON_DRIVER_NAME, + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XF86_VERSION_CURRENT, + RADEON_VERSION_MAJOR, RADEON_VERSION_MINOR, RADEON_VERSION_PATCH, + ABI_CLASS_VIDEODRV, + ABI_VIDEODRV_VERSION, + MOD_CLASS_VIDEODRV, + {0, 0, 0, 0} +}; + +/* + * RADEONSetup -- + * + * This function is called every time the module is loaded. + */ +static pointer +RADEONSetup +( + pointer Module, + pointer Options, + int *ErrorMajor, + int *ErrorMinor +) +{ + static Bool Inited = FALSE; + + if (!Inited) + { + /* Ensure main driver module is loaded, but not as a submodule */ + if (!xf86ServerIsOnlyDetecting() && !LoaderSymbol(ATI_NAME)) + xf86LoadOneModule(ATI_DRIVER_NAME, Options); + + Inited = TRUE; + } + + return (pointer)TRUE; +} + +/* The following record must be called radeonModuleData */ +XF86ModuleData radeonModuleData = +{ + &RADEONVersionRec, + RADEONSetup, + NULL +}; + +#endif /* XFree86LOADER */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_probe.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_probe.c new file mode 100644 index 000000000..e4200f689 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_probe.c @@ -0,0 +1,185 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_probe.c,v 1.1 2000/11/02 16:55:44 tsi Exp $ */ +/* + * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario + * and Precision Insight, Inc., Cedar Park, Texas. + * + * 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 on + * 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, PRECISION INSIGHT AND/OR THEIR 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: + * Rickard E. Faith <faith@precisioninsight.com> + * Kevin E. Martin <kevin@precisioninsight.com> + * + * Modified by Marc Aurele La France <tsi@xfree86.org> for ATI driver merge. + */ + +#include "atimodule.h" +#include "ativersion.h" + +#include "radeon_probe.h" +#include "radeon_version.h" + +#include "xf86PciInfo.h" + +#include "xf86.h" +#include "xf86_ansic.h" +#include "xf86Resources.h" + +SymTabRec RADEONChipsets[] = { + { PCI_CHIP_RADEON_QD, "ATI Radeon QD (AGP)" }, + { PCI_CHIP_RADEON_QE, "ATI Radeon QE (AGP)" }, + { PCI_CHIP_RADEON_QF, "ATI Radeon QF (AGP)" }, + { PCI_CHIP_RADEON_QG, "ATI Radeon QG (AGP)" }, + { -1, NULL } +}; + +PciChipsets RADEONPciChipsets[] = { + { PCI_CHIP_RADEON_QD, PCI_CHIP_RADEON_QD, RES_SHARED_VGA }, + { PCI_CHIP_RADEON_QE, PCI_CHIP_RADEON_QE, RES_SHARED_VGA }, + { PCI_CHIP_RADEON_QF, PCI_CHIP_RADEON_QF, RES_SHARED_VGA }, + { PCI_CHIP_RADEON_QG, PCI_CHIP_RADEON_QG, RES_SHARED_VGA }, + { -1, -1, RES_UNDEFINED } +}; + +/* Return the options for supported chipset 'n'; NULL otherwise */ +OptionInfoPtr +RADEONAvailableOptions(int chipid, int busid) +{ + int i; + + /* + * Return options defined in the radeon submodule which will have been + * loaded by this point. + */ + for (i = 0; RADEONPciChipsets[i].PCIid > 0; i++) { + if (chipid == RADEONPciChipsets[i].PCIid) + return RADEONOptions; + } + return NULL; +} + +/* Return the string name for supported chipset 'n'; NULL otherwise. */ +void +RADEONIdentify(int flags) +{ + xf86PrintChipsets(RADEON_NAME, + "Driver for ATI Radeon chipsets", + RADEONChipsets); +} + +/* Return TRUE if chipset is present; FALSE otherwise. */ +Bool +RADEONProbe(DriverPtr drv, int flags) +{ + int numUsed; + int numDevSections, nATIGDev, nRadeonGDev; + int *usedChips; + GDevPtr *devSections, *ATIGDevs, *RadeonGDevs; + EntityInfoPtr pEnt; + Bool foundScreen = FALSE; + int i; + + if (!xf86GetPciVideoInfo()) return FALSE; + + /* Collect unclaimed device sections for both driver names */ + nATIGDev = xf86MatchDevice(ATI_NAME, &ATIGDevs); + nRadeonGDev = xf86MatchDevice(RADEON_NAME, &RadeonGDevs); + + if (!(numDevSections = nATIGDev + nRadeonGDev)) return FALSE; + + if (!ATIGDevs) { + if (!(devSections = RadeonGDevs)) + numDevSections = 1; + else + numDevSections = nRadeonGDev; + } if (!RadeonGDevs) { + devSections = ATIGDevs; + numDevSections = nATIGDev; + } else { + /* Combine into one list */ + devSections = xnfalloc((numDevSections + 1) * sizeof(GDevPtr)); + (void)memcpy(devSections, + ATIGDevs, nATIGDev * sizeof(GDevPtr)); + (void)memcpy(devSections + nATIGDev, + RadeonGDevs, nRadeonGDev * sizeof(GDevPtr)); + devSections[numDevSections] = NULL; + xfree(ATIGDevs); + xfree(RadeonGDevs); + } + + numUsed = xf86MatchPciInstances(RADEON_NAME, + PCI_VENDOR_ATI, + RADEONChipsets, + RADEONPciChipsets, + devSections, + numDevSections, + drv, + &usedChips); + + if (numUsed<=0) return FALSE; + + if (flags & PROBE_DETECT) + foundScreen = TRUE; + else for (i = 0; i < numUsed; i++) { + pEnt = xf86GetEntityInfo(usedChips[i]); + + if (pEnt->active) { + ScrnInfoPtr pScrn = xf86AllocateScreen(drv, 0); + +#ifdef XFree86LOADER + if (!xf86LoadSubModule(pScrn, "radeon")) { + xf86Msg(X_ERROR, + RADEON_NAME ": Failed to load \"radeon\" module.\n"); + xf86DeleteScreen(pScrn->scrnIndex, 0); + continue; + } + + xf86LoaderReqSymLists(RADEONSymbols, NULL); +#endif + + pScrn->driverVersion = RADEON_VERSION_CURRENT; + pScrn->driverName = RADEON_DRIVER_NAME; + pScrn->name = RADEON_NAME; + pScrn->Probe = RADEONProbe; + pScrn->PreInit = RADEONPreInit; + pScrn->ScreenInit = RADEONScreenInit; + pScrn->SwitchMode = RADEONSwitchMode; + pScrn->AdjustFrame = RADEONAdjustFrame; + pScrn->EnterVT = RADEONEnterVT; + pScrn->LeaveVT = RADEONLeaveVT; + pScrn->FreeScreen = RADEONFreeScreen; + pScrn->ValidMode = RADEONValidMode; + + foundScreen = TRUE; + + xf86ConfigActivePciEntity(pScrn, usedChips[i], RADEONPciChipsets, + 0, 0, 0, 0, 0); + } + xfree(pEnt); + } + + if (numUsed) xfree(usedChips); + xfree(devSections); + + return foundScreen; +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_probe.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_probe.h new file mode 100644 index 000000000..9cb8bf007 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_probe.h @@ -0,0 +1,73 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_probe.h,v 1.1 2000/11/02 16:55:45 tsi Exp $ */ +/* + * Copyright 2000 ATI Technologies Inc., Markham, Ontario + * and 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 on + * 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Kevin E. Martin <martin@valinux.com> + * + * Modified by Marc Aurele La France <tsi@xfree86.org> for ATI driver merge. + */ + +#ifndef _RADEON_PROBE_H_ +#define _RADEON_PROBE_H_ 1 + +#include "atiproto.h" + +#include "xf86str.h" + +/* radeon_probe.c */ +extern OptionInfoPtr RADEONAvailableOptions + FunctionPrototype((int, int)); +extern void RADEONIdentify + FunctionPrototype((int)); +extern Bool RADEONProbe + FunctionPrototype((DriverPtr, int)); + +extern SymTabRec RADEONChipsets[]; +extern PciChipsets RADEONPciChipsets[]; + +/* radeon_driver.c */ +extern Bool RADEONPreInit + FunctionPrototype((ScrnInfoPtr, int)); +extern Bool RADEONScreenInit + FunctionPrototype((int, ScreenPtr, int, char **)); +extern Bool RADEONSwitchMode + FunctionPrototype((int, DisplayModePtr, int)); +extern void RADEONAdjustFrame + FunctionPrototype((int, int, int, int)); +extern Bool RADEONEnterVT + FunctionPrototype((int, int)); +extern void RADEONLeaveVT + FunctionPrototype((int, int)); +extern void RADEONFreeScreen + FunctionPrototype((int, int)); +extern int RADEONValidMode + FunctionPrototype((int, DisplayModePtr, Bool, int)); + +extern OptionInfoRec RADEONOptions[]; + +#endif /* _RADEON_PROBE_H_ */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h new file mode 100644 index 000000000..e3afbe77d --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h @@ -0,0 +1,1476 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h,v 1.1 2000/11/02 16:55:46 tsi Exp $ */ +/* + * Copyright 2000 ATI Technologies Inc., Markham, Ontario + * and 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 on + * 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Kevin E. Martin <martin@valinux.com> + * Rickard E. Faith <faith@valinux.com> + * + * References: + * + * !!!! FIXME !!!! + * RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical + * Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April + * 1999. + * + * !!!! FIXME !!!! + * RAGE 128 Software Development Manual (Technical Reference Manual P/N + * SDK-G04000 Rev. 0.01), ATI Technologies: June 1999. + * + */ + +/* !!!! FIXME !!!! NOTE: THIS FILE HAS BEEN CONVERTED FROM r128_reg.h + * AND CONTAINS REGISTERS AND REGISTER DEFINITIONS THAT ARE NOT CORRECT + * ON THE RADEON. A FULL AUDIT OF THIS CODE IS NEEDED! */ + +#ifndef _RADEON_REG_H_ +#define _RADEON_REG_H_ +#include <compiler.h> + + /* Memory mapped register access macros */ +#define INREG8(addr) MMIO_IN8(RADEONMMIO, addr) +#define INREG16(addr) MMIO_IN16(RADEONMMIO, addr) +#define INREG(addr) MMIO_IN32(RADEONMMIO, addr) +#define OUTREG8(addr, val) MMIO_OUT8(RADEONMMIO, addr, val) +#define OUTREG16(addr, val) MMIO_OUT16(RADEONMMIO, addr, val) +#define OUTREG(addr, val) MMIO_OUT32(RADEONMMIO, addr, val) + +#define ADDRREG(addr) ((volatile CARD32 *)(RADEONMMIO + (addr))) + + +#define OUTREGP(addr, val, mask) \ + do { \ + CARD32 tmp = INREG(addr); \ + tmp &= (mask); \ + tmp |= (val); \ + OUTREG(addr, tmp); \ + } while (0) + +#define INPLL(pScrn, addr) RADEONINPLL(pScrn, addr) + +#if !RADEON_ATOMIC_UPDATE +#define OUTPLL(addr, val) \ + do { \ + while ( (INREG(RADEON_CLOCK_CNTL_INDEX) & 0x9f) != \ + (addr | RADEON_PLL_WR_EN)) { \ + OUTREG8(RADEON_CLOCK_CNTL_INDEX, (((addr) & 0x1f) | \ + RADEON_PLL_WR_EN)); \ + } \ + OUTREG(RADEON_CLOCK_CNTL_DATA, val); \ + } while (0) +#else +#define OUTPLL(addr, val) \ + do { \ + OUTREG8(RADEON_CLOCK_CNTL_INDEX, (((addr) & 0x1f) | \ + RADEON_PLL_WR_EN)); \ + OUTREG(RADEON_CLOCK_CNTL_DATA, val); \ + } while (0) +#endif + +#define OUTPLLP(pScrn, addr, val, mask) \ + do { \ + CARD32 tmp = INPLL(pScrn, addr); \ + tmp &= (mask); \ + tmp |= (val); \ + OUTPLL(addr, tmp); \ + } while (0) + +#define OUTPAL_START(idx) \ + do { \ + OUTREG8(RADEON_PALETTE_INDEX, (idx)); \ + } while (0) + +#define OUTPAL_NEXT(r, g, b) \ + do { \ + OUTREG(RADEON_PALETTE_DATA, ((r) << 16) | ((g) << 8) | (b)); \ + } while (0) + +#define OUTPAL_NEXT_CARD32(v) \ + do { \ + OUTREG(RADEON_PALETTE_DATA, (v & 0x00ffffff)); \ + } while (0) + +#define OUTPAL(idx, r, g, b) \ + do { \ + OUTPAL_START((idx)); \ + OUTPAL_NEXT((r), (g), (b)); \ + } while (0) + +#define INPAL_START(idx) \ + do { \ + OUTREG(RADEON_PALETTE_INDEX, (idx) << 16); \ + } while (0) + +#define INPAL_NEXT() INREG(RADEON_PALETTE_DATA) + +#define PAL_SELECT(idx) \ + do { \ + if (idx) { \ + OUTREG(RADEON_DAC_CNTL, INREG(RADEON_DAC_CNTL) | \ + RADEON_DAC_PALETTE_ACC_CTL); \ + } else { \ + OUTREG(RADEON_DAC_CNTL, INREG(RADEON_DAC_CNTL) & \ + ~RADEON_DAC_PALETTE_ACC_CTL); \ + } \ + } while (0) + +#define RADEON_ADAPTER_ID 0x0f2c /* PCI */ +#define RADEON_AGP_BASE 0x0170 +#define RADEON_AGP_CNTL 0x0174 +# define RADEON_AGP_APER_SIZE_256MB (0x00 << 0) +# define RADEON_AGP_APER_SIZE_128MB (0x20 << 0) +# define RADEON_AGP_APER_SIZE_64MB (0x30 << 0) +# define RADEON_AGP_APER_SIZE_32MB (0x38 << 0) +# define RADEON_AGP_APER_SIZE_16MB (0x3c << 0) +# define RADEON_AGP_APER_SIZE_8MB (0x3e << 0) +# define RADEON_AGP_APER_SIZE_4MB (0x3f << 0) +# define RADEON_AGP_APER_SIZE_MASK (0x3f << 0) +#define RADEON_AGP_COMMAND 0x0f60 /* PCI */ +#define RADEON_AGP_PLL_CNTL 0x000b /* PLL */ +#define RADEON_AGP_STATUS 0x0f5c /* PCI */ +# define RADEON_AGP_1X_MODE 0x01 +# define RADEON_AGP_2X_MODE 0x02 +# define RADEON_AGP_4X_MODE 0x04 +# define RADEON_AGP_MODE_MASK 0x07 +#define RADEON_AMCGPIO_A_REG 0x01a0 +#define RADEON_AMCGPIO_EN_REG 0x01a8 +#define RADEON_AMCGPIO_MASK 0x0194 +#define RADEON_AMCGPIO_Y_REG 0x01a4 +#define RADEON_ATTRDR 0x03c1 /* VGA */ +#define RADEON_ATTRDW 0x03c0 /* VGA */ +#define RADEON_ATTRX 0x03c0 /* VGA */ +# define RADEON_AUX1_SC_EN (1 << 0) +# define RADEON_AUX1_SC_MODE_OR (0 << 1) +# define RADEON_AUX1_SC_MODE_NAND (1 << 1) +# define RADEON_AUX2_SC_EN (1 << 2) +# define RADEON_AUX2_SC_MODE_OR (0 << 3) +# define RADEON_AUX2_SC_MODE_NAND (1 << 3) +# define RADEON_AUX3_SC_EN (1 << 4) +# define RADEON_AUX3_SC_MODE_OR (0 << 5) +# define RADEON_AUX3_SC_MODE_NAND (1 << 5) +#define RADEON_AUX_SC_CNTL 0x1660 +#define RADEON_AUX1_SC_BOTTOM 0x1670 +#define RADEON_AUX1_SC_LEFT 0x1664 +#define RADEON_AUX1_SC_RIGHT 0x1668 +#define RADEON_AUX1_SC_TOP 0x166c +#define RADEON_AUX2_SC_BOTTOM 0x1680 +#define RADEON_AUX2_SC_LEFT 0x1674 +#define RADEON_AUX2_SC_RIGHT 0x1678 +#define RADEON_AUX2_SC_TOP 0x167c +#define RADEON_AUX3_SC_BOTTOM 0x1690 +#define RADEON_AUX3_SC_LEFT 0x1684 +#define RADEON_AUX3_SC_RIGHT 0x1688 +#define RADEON_AUX3_SC_TOP 0x168c +#define RADEON_AUX_WINDOW_HORZ_CNTL 0x02d8 +#define RADEON_AUX_WINDOW_VERT_CNTL 0x02dc + +#define RADEON_BASE_CODE 0x0f0b +#define RADEON_BIOS_0_SCRATCH 0x0010 +#define RADEON_BIOS_1_SCRATCH 0x0014 +#define RADEON_BIOS_2_SCRATCH 0x0018 +#define RADEON_BIOS_3_SCRATCH 0x001c +#define RADEON_BIOS_ROM 0x0f30 /* PCI */ +#define RADEON_BIST 0x0f0f /* PCI */ +#define RADEON_BRUSH_DATA0 0x1480 +#define RADEON_BRUSH_DATA1 0x1484 +#define RADEON_BRUSH_DATA10 0x14a8 +#define RADEON_BRUSH_DATA11 0x14ac +#define RADEON_BRUSH_DATA12 0x14b0 +#define RADEON_BRUSH_DATA13 0x14b4 +#define RADEON_BRUSH_DATA14 0x14b8 +#define RADEON_BRUSH_DATA15 0x14bc +#define RADEON_BRUSH_DATA16 0x14c0 +#define RADEON_BRUSH_DATA17 0x14c4 +#define RADEON_BRUSH_DATA18 0x14c8 +#define RADEON_BRUSH_DATA19 0x14cc +#define RADEON_BRUSH_DATA2 0x1488 +#define RADEON_BRUSH_DATA20 0x14d0 +#define RADEON_BRUSH_DATA21 0x14d4 +#define RADEON_BRUSH_DATA22 0x14d8 +#define RADEON_BRUSH_DATA23 0x14dc +#define RADEON_BRUSH_DATA24 0x14e0 +#define RADEON_BRUSH_DATA25 0x14e4 +#define RADEON_BRUSH_DATA26 0x14e8 +#define RADEON_BRUSH_DATA27 0x14ec +#define RADEON_BRUSH_DATA28 0x14f0 +#define RADEON_BRUSH_DATA29 0x14f4 +#define RADEON_BRUSH_DATA3 0x148c +#define RADEON_BRUSH_DATA30 0x14f8 +#define RADEON_BRUSH_DATA31 0x14fc +#define RADEON_BRUSH_DATA32 0x1500 +#define RADEON_BRUSH_DATA33 0x1504 +#define RADEON_BRUSH_DATA34 0x1508 +#define RADEON_BRUSH_DATA35 0x150c +#define RADEON_BRUSH_DATA36 0x1510 +#define RADEON_BRUSH_DATA37 0x1514 +#define RADEON_BRUSH_DATA38 0x1518 +#define RADEON_BRUSH_DATA39 0x151c +#define RADEON_BRUSH_DATA4 0x1490 +#define RADEON_BRUSH_DATA40 0x1520 +#define RADEON_BRUSH_DATA41 0x1524 +#define RADEON_BRUSH_DATA42 0x1528 +#define RADEON_BRUSH_DATA43 0x152c +#define RADEON_BRUSH_DATA44 0x1530 +#define RADEON_BRUSH_DATA45 0x1534 +#define RADEON_BRUSH_DATA46 0x1538 +#define RADEON_BRUSH_DATA47 0x153c +#define RADEON_BRUSH_DATA48 0x1540 +#define RADEON_BRUSH_DATA49 0x1544 +#define RADEON_BRUSH_DATA5 0x1494 +#define RADEON_BRUSH_DATA50 0x1548 +#define RADEON_BRUSH_DATA51 0x154c +#define RADEON_BRUSH_DATA52 0x1550 +#define RADEON_BRUSH_DATA53 0x1554 +#define RADEON_BRUSH_DATA54 0x1558 +#define RADEON_BRUSH_DATA55 0x155c +#define RADEON_BRUSH_DATA56 0x1560 +#define RADEON_BRUSH_DATA57 0x1564 +#define RADEON_BRUSH_DATA58 0x1568 +#define RADEON_BRUSH_DATA59 0x156c +#define RADEON_BRUSH_DATA6 0x1498 +#define RADEON_BRUSH_DATA60 0x1570 +#define RADEON_BRUSH_DATA61 0x1574 +#define RADEON_BRUSH_DATA62 0x1578 +#define RADEON_BRUSH_DATA63 0x157c +#define RADEON_BRUSH_DATA7 0x149c +#define RADEON_BRUSH_DATA8 0x14a0 +#define RADEON_BRUSH_DATA9 0x14a4 +#define RADEON_BRUSH_SCALE 0x1470 +#define RADEON_BRUSH_Y_X 0x1474 +#define RADEON_BUS_CNTL 0x0030 +# define RADEON_BUS_MASTER_DIS (1 << 6) +# define RADEON_BUS_RD_DISCARD_EN (1 << 24) +# define RADEON_BUS_RD_ABORT_EN (1 << 25) +# define RADEON_BUS_MSTR_DISCONNECT_EN (1 << 28) +# define RADEON_BUS_WRT_BURST (1 << 29) +# define RADEON_BUS_READ_BURST (1 << 30) +#define RADEON_BUS_CNTL1 0x0034 +# define RADEON_BUS_WAIT_ON_LOCK_EN (1 << 4) + +#define RADEON_CACHE_CNTL 0x1724 +#define RADEON_CACHE_LINE 0x0f0c /* PCI */ +#define RADEON_CAP0_TRIG_CNTL 0x0950 /* ? */ +#define RADEON_CAP1_TRIG_CNTL 0x09c0 /* ? */ +#define RADEON_CAPABILITIES_ID 0x0f50 /* PCI */ +#define RADEON_CAPABILITIES_PTR 0x0f34 /* PCI */ +#define RADEON_CLK_PIN_CNTL 0x0001 /* PLL */ +#define RADEON_CLOCK_CNTL_DATA 0x000c +#define RADEON_CLOCK_CNTL_INDEX 0x0008 +# define RADEON_PLL_WR_EN (1 << 7) +# define RADEON_PLL_DIV_SEL (3 << 8) +#define RADEON_CLR_CMP_CLR_3D 0x1a24 +#define RADEON_CLR_CMP_CLR_DST 0x15c8 +#define RADEON_CLR_CMP_CLR_SRC 0x15c4 +#define RADEON_CLR_CMP_CNTL 0x15c0 +# define RADEON_SRC_CMP_EQ_COLOR (4 << 0) +# define RADEON_SRC_CMP_NEQ_COLOR (5 << 0) +# define RADEON_CLR_CMP_SRC_SOURCE (1 << 24) +#define RADEON_CLR_CMP_MASK 0x15cc +# define RADEON_CLR_CMP_MSK 0xffffffff +#define RADEON_CLR_CMP_MASK_3D 0x1A28 +#define RADEON_COMMAND 0x0f04 /* PCI */ +#define RADEON_COMPOSITE_SHADOW_ID 0x1a0c +#define RADEON_CONFIG_APER_0_BASE 0x0100 +#define RADEON_CONFIG_APER_1_BASE 0x0104 +#define RADEON_CONFIG_APER_SIZE 0x0108 +#define RADEON_CONFIG_BONDS 0x00e8 +#define RADEON_CONFIG_CNTL 0x00e0 +#define RADEON_CONFIG_MEMSIZE 0x00f8 +#define RADEON_CONFIG_MEMSIZE_EMBEDDED 0x0114 +#define RADEON_CONFIG_REG_1_BASE 0x010c +#define RADEON_CONFIG_REG_APER_SIZE 0x0110 +#define RADEON_CONFIG_XSTRAP 0x00e4 +#define RADEON_CONSTANT_COLOR_C 0x1d34 +# define RADEON_CONSTANT_COLOR_MASK 0x00ffffff +# define RADEON_CONSTANT_COLOR_ONE 0x00ffffff +# define RADEON_CONSTANT_COLOR_ZERO 0x00000000 +#define RADEON_CRC_CMDFIFO_ADDR 0x0740 +#define RADEON_CRC_CMDFIFO_DOUT 0x0744 +#define RADEON_CRTC_CRNT_FRAME 0x0214 +#define RADEON_CRTC_DEBUG 0x021c +#define RADEON_CRTC_EXT_CNTL 0x0054 +# define RADEON_CRTC_VGA_XOVERSCAN (1 << 0) +# define RADEON_VGA_ATI_LINEAR (1 << 3) +# define RADEON_XCRT_CNT_EN (1 << 6) +# define RADEON_CRTC_HSYNC_DIS (1 << 8) +# define RADEON_CRTC_VSYNC_DIS (1 << 9) +# define RADEON_CRTC_DISPLAY_DIS (1 << 10) +# define RADEON_CRTC_CRT_ON (1 << 15) +#define RADEON_CRTC_EXT_CNTL_DPMS_BYTE 0x0055 +# define RADEON_CRTC_HSYNC_DIS_BYTE (1 << 0) +# define RADEON_CRTC_VSYNC_DIS_BYTE (1 << 1) +# define RADEON_CRTC_DISPLAY_DIS_BYTE (1 << 2) +#define RADEON_CRTC_GEN_CNTL 0x0050 +# define RADEON_CRTC_DBL_SCAN_EN (1 << 0) +# define RADEON_CRTC_INTERLACE_EN (1 << 1) +# define RADEON_CRTC_CSYNC_EN (1 << 4) +# define RADEON_CRTC_CUR_EN (1 << 16) +# define RADEON_CRTC_CUR_MODE_MASK (7 << 17) +# define RADEON_CRTC_ICON_EN (1 << 20) +# define RADEON_CRTC_EXT_DISP_EN (1 << 24) +# define RADEON_CRTC_EN (1 << 25) +# define RADEON_CRTC_DISP_REQ_EN_B (1 << 26) +#define RADEON_CRTC_GUI_TRIG_VLINE 0x0218 +#define RADEON_CRTC_H_SYNC_STRT_WID 0x0204 +# define RADEON_CRTC_H_SYNC_STRT_PIX (0x07 << 0) +# define RADEON_CRTC_H_SYNC_STRT_CHAR (0x1ff << 3) +# define RADEON_CRTC_H_SYNC_STRT_CHAR_SHIFT 3 +# define RADEON_CRTC_H_SYNC_WID (0x3f << 16) +# define RADEON_CRTC_H_SYNC_WID_SHIFT 16 +# define RADEON_CRTC_H_SYNC_POL (1 << 23) +#define RADEON_CRTC_H_TOTAL_DISP 0x0200 +# define RADEON_CRTC_H_TOTAL (0x01ff << 0) +# define RADEON_CRTC_H_TOTAL_SHIFT 0 +# define RADEON_CRTC_H_DISP (0x00ff << 16) +# define RADEON_CRTC_H_DISP_SHIFT 16 +#define RADEON_CRTC_OFFSET 0x0224 +#define RADEON_CRTC_OFFSET_CNTL 0x0228 +#define RADEON_CRTC_PITCH 0x022c +#define RADEON_CRTC_STATUS 0x005c +# define RADEON_CRTC_VBLANK_SAVE (1 << 1) +#define RADEON_CRTC_V_SYNC_STRT_WID 0x020c +# define RADEON_CRTC_V_SYNC_STRT (0x7ff << 0) +# define RADEON_CRTC_V_SYNC_STRT_SHIFT 0 +# define RADEON_CRTC_V_SYNC_WID (0x1f << 16) +# define RADEON_CRTC_V_SYNC_WID_SHIFT 16 +# define RADEON_CRTC_V_SYNC_POL (1 << 23) +#define RADEON_CRTC_V_TOTAL_DISP 0x0208 +# define RADEON_CRTC_V_TOTAL (0x07ff << 0) +# define RADEON_CRTC_V_TOTAL_SHIFT 0 +# define RADEON_CRTC_V_DISP (0x07ff << 16) +# define RADEON_CRTC_V_DISP_SHIFT 16 +#define RADEON_CRTC_VLINE_CRNT_VLINE 0x0210 +# define RADEON_CRTC_CRNT_VLINE_MASK (0x7ff << 16) +#define RADEON_CRTC2_CRNT_FRAME 0x0314 +#define RADEON_CRTC2_DEBUG 0x031c +#define RADEON_CRTC2_GEN_CNTL 0x03f8 +#define RADEON_CRTC2_GUI_TRIG_VLINE 0x0318 +#define RADEON_CRTC2_H_SYNC_STRT_WID 0x0304 +#define RADEON_CRTC2_H_TOTAL_DISP 0x0300 +#define RADEON_CRTC2_OFFSET 0x0324 +#define RADEON_CRTC2_OFFSET_CNTL 0x0328 +#define RADEON_CRTC2_PITCH 0x032c +#define RADEON_CRTC2_STATUS 0x03fc +#define RADEON_CRTC2_V_SYNC_STRT_WID 0x030c +#define RADEON_CRTC2_V_TOTAL_DISP 0x0308 +#define RADEON_CRTC2_VLINE_CRNT_VLINE 0x0310 +#define RADEON_CRTC8_DATA 0x03d5 /* VGA, 0x3b5 */ +#define RADEON_CRTC8_IDX 0x03d4 /* VGA, 0x3b4 */ +#define RADEON_CUR_CLR0 0x026c +#define RADEON_CUR_CLR1 0x0270 +#define RADEON_CUR_HORZ_VERT_OFF 0x0268 +#define RADEON_CUR_HORZ_VERT_POSN 0x0264 +#define RADEON_CUR_OFFSET 0x0260 +# define RADEON_CUR_LOCK (1 << 31) + +#define RADEON_DAC_CNTL 0x0058 +# define RADEON_DAC_RANGE_CNTL (3 << 0) +# define RADEON_DAC_BLANKING (1 << 2) +# define RADEON_DAC_CRT_SEL_CRTC2 (1 << 4) +# define RADEON_DAC_PALETTE_ACC_CTL (1 << 5) +# define RADEON_DAC_8BIT_EN (1 << 8) +# define RADEON_DAC_VGA_ADR_EN (1 << 13) +# define RADEON_DAC_MASK_ALL (0xff << 24) +#define RADEON_DAC_CRC_SIG 0x02cc +#define RADEON_DAC_DATA 0x03c9 /* VGA */ +#define RADEON_DAC_MASK 0x03c6 /* VGA */ +#define RADEON_DAC_R_INDEX 0x03c7 /* VGA */ +#define RADEON_DAC_W_INDEX 0x03c8 /* VGA */ +#define RADEON_DDA_CONFIG 0x02e0 +#define RADEON_DDA_ON_OFF 0x02e4 +#define RADEON_DEFAULT_OFFSET 0x16e0 +#define RADEON_DEFAULT_PITCH 0x16e4 +#define RADEON_DEFAULT_SC_BOTTOM_RIGHT 0x16e8 +# define RADEON_DEFAULT_SC_RIGHT_MAX (0x1fff << 0) +# define RADEON_DEFAULT_SC_BOTTOM_MAX (0x1fff << 16) +#define RADEON_DESTINATION_3D_CLR_CMP_VAL 0x1820 +#define RADEON_DESTINATION_3D_CLR_CMP_MSK 0x1824 +#define RADEON_DEVICE_ID 0x0f02 /* PCI */ +#define RADEON_DISP_MISC_CNTL 0x0d00 +# define RADEON_SOFT_RESET_GRPH_PP (1 << 0) +#define RADEON_DP_BRUSH_BKGD_CLR 0x1478 +#define RADEON_DP_BRUSH_FRGD_CLR 0x147c +#define RADEON_DP_CNTL 0x16c0 +# define RADEON_DST_X_LEFT_TO_RIGHT (1 << 0) +# define RADEON_DST_Y_TOP_TO_BOTTOM (1 << 1) +#define RADEON_DP_CNTL_XDIR_YDIR_YMAJOR 0x16d0 +# define RADEON_DST_Y_MAJOR (1 << 2) +# define RADEON_DST_Y_DIR_TOP_TO_BOTTOM (1 << 15) +# define RADEON_DST_X_DIR_LEFT_TO_RIGHT (1 << 31) +#define RADEON_DP_DATATYPE 0x16c4 +# define RADEON_HOST_BIG_ENDIAN_EN (1 << 29) +#define RADEON_DP_GUI_MASTER_CNTL 0x146c +# define RADEON_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0) +# define RADEON_GMC_DST_PITCH_OFFSET_CNTL (1 << 1) +# define RADEON_GMC_SRC_CLIPPING (1 << 2) +# define RADEON_GMC_DST_CLIPPING (1 << 3) +# define RADEON_GMC_BRUSH_DATATYPE_MASK (0x0f << 4) +# define RADEON_GMC_BRUSH_8X8_MONO_FG_BG (0 << 4) +# define RADEON_GMC_BRUSH_8X8_MONO_FG_LA (1 << 4) +# define RADEON_GMC_BRUSH_1X8_MONO_FG_BG (4 << 4) +# define RADEON_GMC_BRUSH_1X8_MONO_FG_LA (5 << 4) +# define RADEON_GMC_BRUSH_32x1_MONO_FG_BG (6 << 4) +# define RADEON_GMC_BRUSH_32x1_MONO_FG_LA (7 << 4) +# define RADEON_GMC_BRUSH_8x8_COLOR (10 << 4) +# define RADEON_GMC_BRUSH_1X8_COLOR (12 << 4) +# define RADEON_GMC_BRUSH_SOLID_COLOR (13 << 4) +# define RADEON_GMC_BRUSH_NONE (15 << 4) +# define RADEON_GMC_DST_8BPP_CI (2 << 8) +# define RADEON_GMC_DST_15BPP (3 << 8) +# define RADEON_GMC_DST_16BPP (4 << 8) +# define RADEON_GMC_DST_24BPP (5 << 8) +# define RADEON_GMC_DST_32BPP (6 << 8) +# define RADEON_GMC_DST_8BPP_RGB (7 << 8) +# define RADEON_GMC_DST_Y8 (8 << 8) +# define RADEON_GMC_DST_RGB8 (9 << 8) +# define RADEON_GMC_DST_VYUY (11 << 8) +# define RADEON_GMC_DST_YVYU (12 << 8) +# define RADEON_GMC_DST_AYUV444 (14 << 8) +# define RADEON_GMC_DST_ARGB4444 (15 << 8) +# define RADEON_GMC_DST_DATATYPE_MASK (0x0f << 8) +# define RADEON_GMC_DST_DATATYPE_SHIFT 8 +# define RADEON_GMC_SRC_DATATYPE_MASK (3 << 12) +# define RADEON_GMC_SRC_DATATYPE_MONO_FG_BG (0 << 12) +# define RADEON_GMC_SRC_DATATYPE_MONO_FG_LA (1 << 12) +# define RADEON_GMC_SRC_DATATYPE_COLOR (3 << 12) +# define RADEON_GMC_BYTE_PIX_ORDER (1 << 14) +# define RADEON_GMC_BYTE_MSB_TO_LSB (0 << 14) +# define RADEON_GMC_BYTE_LSB_TO_MSB (1 << 14) +# define RADEON_GMC_CONVERSION_TEMP (1 << 15) +# define RADEON_GMC_CONVERSION_TEMP_6500 (0 << 15) +# define RADEON_GMC_CONVERSION_TEMP_9300 (1 << 15) +# define RADEON_GMC_ROP3_MASK (0xff << 16) +# define RADEON_DP_SRC_SOURCE_MASK (7 << 24) +# define RADEON_DP_SRC_SOURCE_MEMORY (2 << 24) +# define RADEON_DP_SRC_SOURCE_HOST_DATA (3 << 24) +# define RADEON_GMC_3D_FCN_EN (1 << 27) +# define RADEON_GMC_CLR_CMP_CNTL_DIS (1 << 28) +# define RADEON_GMC_AUX_CLIP_DIS (1 << 29) +# define RADEON_GMC_WR_MSK_DIS (1 << 30) +# define RADEON_GMC_LD_BRUSH_Y_X (1 << 31) +# define RADEON_ROP3_ZERO 0x00000000 +# define RADEON_ROP3_DSa 0x00880000 +# define RADEON_ROP3_SDna 0x00440000 +# define RADEON_ROP3_S 0x00cc0000 +# define RADEON_ROP3_DSna 0x00220000 +# define RADEON_ROP3_D 0x00aa0000 +# define RADEON_ROP3_DSx 0x00660000 +# define RADEON_ROP3_DSo 0x00ee0000 +# define RADEON_ROP3_DSon 0x00110000 +# define RADEON_ROP3_DSxn 0x00990000 +# define RADEON_ROP3_Dn 0x00550000 +# define RADEON_ROP3_SDno 0x00dd0000 +# define RADEON_ROP3_Sn 0x00330000 +# define RADEON_ROP3_DSno 0x00bb0000 +# define RADEON_ROP3_DSan 0x00770000 +# define RADEON_ROP3_ONE 0x00ff0000 +# define RADEON_ROP3_DPa 0x00a00000 +# define RADEON_ROP3_PDna 0x00500000 +# define RADEON_ROP3_P 0x00f00000 +# define RADEON_ROP3_DPna 0x000a0000 +# define RADEON_ROP3_D 0x00aa0000 +# define RADEON_ROP3_DPx 0x005a0000 +# define RADEON_ROP3_DPo 0x00fa0000 +# define RADEON_ROP3_DPon 0x00050000 +# define RADEON_ROP3_PDxn 0x00a50000 +# define RADEON_ROP3_PDno 0x00f50000 +# define RADEON_ROP3_Pn 0x000f0000 +# define RADEON_ROP3_DPno 0x00af0000 +# define RADEON_ROP3_DPan 0x005f0000 + + +#define RADEON_DP_GUI_MASTER_CNTL_C 0x1c84 +#define RADEON_DP_MIX 0x16c8 +#define RADEON_DP_SRC_BKGD_CLR 0x15dc +#define RADEON_DP_SRC_FRGD_CLR 0x15d8 +#define RADEON_DP_WRITE_MASK 0x16cc +#define RADEON_DST_BRES_DEC 0x1630 +#define RADEON_DST_BRES_ERR 0x1628 +#define RADEON_DST_BRES_INC 0x162c +#define RADEON_DST_BRES_LNTH 0x1634 +#define RADEON_DST_BRES_LNTH_SUB 0x1638 +#define RADEON_DST_HEIGHT 0x1410 +#define RADEON_DST_HEIGHT_WIDTH 0x143c +#define RADEON_DST_HEIGHT_WIDTH_8 0x158c +#define RADEON_DST_HEIGHT_WIDTH_BW 0x15b4 +#define RADEON_DST_HEIGHT_Y 0x15a0 +#define RADEON_DST_LINE_START 0x1600 +#define RADEON_DST_LINE_END 0x1604 +#define RADEON_DST_OFFSET 0x1404 +#define RADEON_DST_PITCH 0x1408 +#define RADEON_DST_PITCH_OFFSET 0x142c +#define RADEON_DST_PITCH_OFFSET_C 0x1c80 +# define RADEON_PITCH_SHIFT 21 +#define RADEON_DST_WIDTH 0x140c +#define RADEON_DST_WIDTH_HEIGHT 0x1598 +#define RADEON_DST_WIDTH_X 0x1588 +#define RADEON_DST_WIDTH_X_INCY 0x159c +#define RADEON_DST_X 0x141c +#define RADEON_DST_X_SUB 0x15a4 +#define RADEON_DST_X_Y 0x1594 +#define RADEON_DST_Y 0x1420 +#define RADEON_DST_Y_SUB 0x15a8 +#define RADEON_DST_Y_X 0x1438 + +#define RADEON_FCP_CNTL 0x0012 /* PLL */ +#define RADEON_FLUSH_1 0x1704 +#define RADEON_FLUSH_2 0x1708 +#define RADEON_FLUSH_3 0x170c +#define RADEON_FLUSH_4 0x1710 +#define RADEON_FLUSH_5 0x1714 +#define RADEON_FLUSH_6 0x1718 +#define RADEON_FLUSH_7 0x171c +#define RADEON_FOG_3D_TABLE_START 0x1810 +#define RADEON_FOG_3D_TABLE_END 0x1814 +#define RADEON_FOG_3D_TABLE_DENSITY 0x181c +#define RADEON_FOG_TABLE_INDEX 0x1a14 +#define RADEON_FOG_TABLE_DATA 0x1a18 +#define RADEON_FP_CRTC_H_TOTAL_DISP 0x0250 +#define RADEON_FP_CRTC_V_TOTAL_DISP 0x0254 +#define RADEON_FP_GEN_CNTL 0x0284 +# define RADEON_FP_FPON (1 << 0) +# define RADEON_FP_TDMS_EN (1 << 2) +# define RADEON_FP_DETECT_SENSE (1 << 8) +# define RADEON_FP_SEL_CRTC2 (1 << 13) +# define RADEON_FP_CRTC_DONT_SHADOW_VPAR (1 << 16) +# define RADEON_FP_CRTC_USE_SHADOW_VEND (1 << 18) +# define RADEON_FP_CRTC_HORZ_DIV2_EN (1 << 20) +# define RADEON_FP_CRTC_HOR_CRT_DIV2_DIS (1 << 21) +# define RADEON_FP_USE_SHADOW_EN (1 << 24) +#define RADEON_FP_H_SYNC_STRT_WID 0x02c4 +#define RADEON_FP_HORZ_STRETCH 0x028c +# define RADEON_HORZ_STRETCH_RATIO_MASK 0xffff +# define RADEON_HORZ_STRETCH_RATIO_SHIFT 0 +# define RADEON_HORZ_STRETCH_RATIO_MAX 4096 +# define RADEON_HORZ_PANEL_SIZE (0xff << 16) +# define RADEON_HORZ_PANEL_SHIFT 16 +# define RADEON_HORZ_STRETCH_PIXREP (0 << 25) +# define RADEON_HORZ_STRETCH_BLEND (1 << 25) +# define RADEON_HORZ_STRETCH_ENABLE (1 << 26) +# define RADEON_HORZ_FP_LOOP_STRETCH (0x7 << 27) +# define RADEON_HORZ_STRETCH_RESERVED (1 << 30) +# define RADEON_HORZ_AUTO_RATIO_FIX_EN (1 << 31) + +#define RADEON_FP_PANEL_CNTL 0x0288 +# define RADEON_FP_DIGON (1 << 0) +# define RADEON_FP_BLON (1 << 1) +#define RADEON_FP_V_SYNC_STRT_WID 0x02c8 +#define RADEON_FP_VERT_STRETCH 0x0290 +# define RADEON_VERT_PANEL_SIZE (0x7ff << 0) +# define RADEON_VERT_PANEL_SHIFT 0 +# define RADEON_VERT_STRETCH_RATIO_MASK 0x3ff +# define RADEON_VERT_STRETCH_RATIO_SHIFT 11 +# define RADEON_VERT_STRETCH_RATIO_MAX 1024 +# define RADEON_VERT_STRETCH_ENABLE (1 << 24) +# define RADEON_VERT_STRETCH_LINEREP (0 << 25) +# define RADEON_VERT_STRETCH_BLEND (1 << 25) +# define RADEON_VERT_AUTO_RATIO_EN (1 << 26) +# define RADEON_VERT_STRETCH_RESERVED 0xf8e00000 + +#define RADEON_GEN_INT_CNTL 0x0040 +#define RADEON_GEN_INT_STATUS 0x0044 +# define RADEON_VSYNC_INT_AK (1 << 2) +# define RADEON_VSYNC_INT (1 << 2) +#define RADEON_RBBM_SOFT_RESET 0x00f0 +# define RADEON_SOFT_RESET_CP (1 << 0) +# define RADEON_SOFT_RESET_HI (1 << 1) +# define RADEON_SOFT_RESET_SE (1 << 2) +# define RADEON_SOFT_RESET_RE (1 << 3) +# define RADEON_SOFT_RESET_PP (1 << 4) +# define RADEON_SOFT_RESET_E2 (1 << 5) +# define RADEON_SOFT_RESET_RB (1 << 6) +# define RADEON_SOFT_RESET_HDP (1 << 7) +#define RADEON_GENENB 0x03c3 /* VGA */ +#define RADEON_GENFC_RD 0x03ca /* VGA */ +#define RADEON_GENFC_WT 0x03da /* VGA, 0x03ba */ +#define RADEON_GENMO_RD 0x03cc /* VGA */ +#define RADEON_GENMO_WT 0x03c2 /* VGA */ +#define RADEON_GENS0 0x03c2 /* VGA */ +#define RADEON_GENS1 0x03da /* VGA, 0x03ba */ +#define RADEON_GPIO_MONID 0x0068 +# define RADEON_GPIO_MONID_A_0 (1 << 0) +# define RADEON_GPIO_MONID_A_1 (1 << 1) +# define RADEON_GPIO_MONID_A_2 (1 << 2) +# define RADEON_GPIO_MONID_A_3 (1 << 3) +# define RADEON_GPIO_MONID_Y_0 (1 << 8) +# define RADEON_GPIO_MONID_Y_1 (1 << 9) +# define RADEON_GPIO_MONID_Y_2 (1 << 10) +# define RADEON_GPIO_MONID_Y_3 (1 << 11) +# define RADEON_GPIO_MONID_EN_0 (1 << 16) +# define RADEON_GPIO_MONID_EN_1 (1 << 17) +# define RADEON_GPIO_MONID_EN_2 (1 << 18) +# define RADEON_GPIO_MONID_EN_3 (1 << 19) +# define RADEON_GPIO_MONID_MASK_0 (1 << 24) +# define RADEON_GPIO_MONID_MASK_1 (1 << 25) +# define RADEON_GPIO_MONID_MASK_2 (1 << 26) +# define RADEON_GPIO_MONID_MASK_3 (1 << 27) +#define RADEON_GPIO_MONIDB 0x006c +#define RADEON_GRPH8_DATA 0x03cf /* VGA */ +#define RADEON_GRPH8_IDX 0x03ce /* VGA */ +#define RADEON_GUI_DEBUG0 0x16a0 +#define RADEON_GUI_DEBUG1 0x16a4 +#define RADEON_GUI_DEBUG2 0x16a8 +#define RADEON_GUI_DEBUG3 0x16ac +#define RADEON_GUI_DEBUG4 0x16b0 +#define RADEON_GUI_DEBUG5 0x16b4 +#define RADEON_GUI_DEBUG6 0x16b8 +#define RADEON_GUI_SCRATCH_REG0 0x15e0 +#define RADEON_GUI_SCRATCH_REG1 0x15e4 +#define RADEON_GUI_SCRATCH_REG2 0x15e8 +#define RADEON_GUI_SCRATCH_REG3 0x15ec +#define RADEON_GUI_SCRATCH_REG4 0x15f0 +#define RADEON_GUI_SCRATCH_REG5 0x15f4 +#define RADEON_HEADER 0x0f0e /* PCI */ +#define RADEON_HOST_DATA0 0x17c0 +#define RADEON_HOST_DATA1 0x17c4 +#define RADEON_HOST_DATA2 0x17c8 +#define RADEON_HOST_DATA3 0x17cc +#define RADEON_HOST_DATA4 0x17d0 +#define RADEON_HOST_DATA5 0x17d4 +#define RADEON_HOST_DATA6 0x17d8 +#define RADEON_HOST_DATA7 0x17dc +#define RADEON_HOST_DATA_LAST 0x17e0 +#define RADEON_HOST_PATH_CNTL 0x0130 +#define RADEON_HTOTAL_CNTL 0x0009 /* PLL */ +#define RADEON_HW_DEBUG 0x0128 +#define RADEON_HW_DEBUG2 0x011c + +#define RADEON_I2C_CNTL_1 0x0094 /* ? */ +#define RADEON_INTERRUPT_LINE 0x0f3c /* PCI */ +#define RADEON_INTERRUPT_PIN 0x0f3d /* PCI */ +#define RADEON_IO_BASE 0x0f14 /* PCI */ + +#define RADEON_LATENCY 0x0f0d /* PCI */ +#define RADEON_LEAD_BRES_DEC 0x1608 +#define RADEON_LEAD_BRES_LNTH 0x161c +#define RADEON_LEAD_BRES_LNTH_SUB 0x1624 +#define RADEON_LVDS_GEN_CNTL 0x02d0 +# define RADEON_LVDS_ON (1 << 0) +# define RADEON_LVDS_BLON (1 << 19) +# define RADEON_LVDS_SEL_CRTC2 (1 << 23) +# define RADEON_HSYNC_DELAY_SHIFT 28 +# define RADEON_HSYNC_DELAY_MASK (0xf << 28) + +#define RADEON_MAX_LATENCY 0x0f3f /* PCI */ +#define RADEON_MC_AGP_LOCATION 0x014c +#define RADEON_MC_FB_LOCATION 0x0148 +#define RADEON_MCLK_CNTL 0x0012 /* PLL */ +# define RADEON_FORCE_GCP (1 << 16) +# define RADEON_FORCE_PIPE3D_CP (1 << 17) +# define RADEON_FORCE_RCP (1 << 18) +#define RADEON_MDGPIO_A_REG 0x01ac +#define RADEON_MDGPIO_EN_REG 0x01b0 +#define RADEON_MDGPIO_MASK 0x0198 +#define RADEON_MDGPIO_Y_REG 0x01b4 +#define RADEON_MEM_ADDR_CONFIG 0x0148 +#define RADEON_MEM_BASE 0x0f10 /* PCI */ +#define RADEON_MEM_CNTL 0x0140 +#define RADEON_MEM_INIT_LAT_TIMER 0x0154 +#define RADEON_MEM_INTF_CNTL 0x014c +#define RADEON_MEM_SDRAM_MODE_REG 0x0158 +#define RADEON_MEM_STR_CNTL 0x0150 +#define RADEON_MEM_VGA_RP_SEL 0x003c +#define RADEON_MEM_VGA_WP_SEL 0x0038 +#define RADEON_MIN_GRANT 0x0f3e /* PCI */ +#define RADEON_MM_DATA 0x0004 +#define RADEON_MM_INDEX 0x0000 +#define RADEON_MPLL_CNTL 0x000e /* PLL */ +#define RADEON_MPP_TB_CONFIG 0x01c0 /* ? */ +#define RADEON_MPP_GP_CONFIG 0x01c8 /* ? */ + +#define RADEON_N_VIF_COUNT 0x0248 + +#define RADEON_OV0_SCALE_CNTL 0x0420 /* ? */ +#define RADEON_OVR_CLR 0x0230 +#define RADEON_OVR_WID_LEFT_RIGHT 0x0234 +#define RADEON_OVR_WID_TOP_BOTTOM 0x0238 + +/* first overlay unit (there is only one) */ + +#define RADEON_OV0_Y_X_START 0x0400 +#define RADEON_OV0_Y_X_END 0x0404 +#define RADEON_OV0_EXCLUSIVE_HORZ 0x0408 +# define RADEON_EXCL_HORZ_START_MASK 0x000000ff +# define RADEON_EXCL_HORZ_END_MASK 0x0000ff00 +# define RADEON_EXCL_HORZ_BACK_PORCH_MASK 0x00ff0000 +# define RADEON_EXCL_HORZ_EXCLUSIVE_EN 0x80000000 +#define RADEON_OV0_EXCLUSIVE_VERT 0x040C +# define RADEON_EXCL_VERT_START_MASK 0x000003ff +# define RADEON_EXCL_VERT_END_MASK 0x03ff0000 +#define RADEON_OV0_REG_LOAD_CNTL 0x0410 +# define RADEON_REG_LD_CTL_LOCK 0x00000001L +# define RADEON_REG_LD_CTL_VBLANK_DURING_LOCK 0x00000002L +# define RADEON_REG_LD_CTL_STALL_GUI_UNTIL_FLIP 0x00000004L +# define RADEON_REG_LD_CTL_LOCK_READBACK 0x00000008L +#define RADEON_OV0_SCALE_CNTL 0x0420 +# define RADEON_SCALER_PIX_EXPAND 0x00000001L +# define RADEON_SCALER_Y2R_TEMP 0x00000002L +# define RADEON_SCALER_HORZ_PICK_NEAREST 0x00000003L +# define RADEON_SCALER_VERT_PICK_NEAREST 0x00000004L +# define RADEON_SCALER_SIGNED_UV 0x00000010L +# define RADEON_SCALER_GAMMA_SEL_MASK 0x00000060L +# define RADEON_SCALER_GAMMA_SEL_BRIGHT 0x00000000L +# define RADEON_SCALER_GAMMA_SEL_G22 0x00000020L +# define RADEON_SCALER_GAMMA_SEL_G18 0x00000040L +# define RADEON_SCALER_GAMMA_SEL_G14 0x00000060L +# define RADEON_SCALER_COMCORE_SHIFT_UP_ONE 0x00000080L +# define RADEON_SCALER_SURFAC_FORMAT 0x00000f00L +# define RADEON_SCALER_SOURCE_15BPP 0x00000300L +# define RADEON_SCALER_SOURCE_16BPP 0x00000400L +# define RADEON_SCALER_SOURCE_32BPP 0x00000600L +# define RADEON_SCALER_SOURCE_YUV9 0x00000900L +# define RADEON_SCALER_SOURCE_YUV12 0x00000A00L +# define RADEON_SCALER_SOURCE_VYUY422 0x00000B00L +# define RADEON_SCALER_SOURCE_YVYU422 0x00000C00L +# define RADEON_SCALER_SMART_SWITCH 0x00008000L +# define RADEON_SCALER_BURST_PER_PLANE 0x00ff0000L +# define RADEON_SCALER_DOUBLE_BUFFER 0x01000000L +# define RADEON_SCALER_DIS_LIMIT 0x08000000L +# define RADEON_SCALER_PRG_LOAD_START 0x10000000L +# define RADEON_SCALER_INT_EMU 0x20000000L +# define RADEON_SCALER_ENABLE 0x40000000L +# define RADEON_SCALER_SOFT_RESET 0x80000000L +#define RADEON_OV0_V_INC 0x0424 +#define RADEON_OV0_P1_V_ACCUM_INIT 0x0428 +# define RADEON_OV0_P1_MAX_LN_IN_PER_LN_OUT 0x00000003L +# define RADEON_OV0_P1_V_ACCUM_INIT_MASK 0x01ff8000L +#define RADEON_OV0_P23_V_ACCUM_INIT 0x042C +#define RADEON_OV0_P1_BLANK_LINES_AT_TOP 0x0430 +# define RADEON_P1_BLNK_LN_AT_TOP_M1_MASK 0x00000fffL +# define RADEON_P1_ACTIVE_LINES_M1 0x0fff0000L +#define RADEON_OV0_P23_BLANK_LINES_AT_TOP 0x0434 +# define RADEON_P23_BLNK_LN_AT_TOP_M1_MASK 0x000007ffL +# define RADEON_P23_ACTIVE_LINES_M1 0x07ff0000L +#define RADEON_OV0_VID_BUF0_BASE_ADRS 0x0440 +# define RADEON_VIF_BUF0_PITCH_SEL 0x00000001L +# define RADEON_VIF_BUF0_TILE_ADRS 0x00000002L +# define RADEON_VIF_BUF0_BASE_ADRS_MASK 0x03fffff0L +# define RADEON_VIF_BUF0_1ST_LINE_LSBS_MASK 0x48000000L +#define RADEON_OV0_VID_BUF1_BASE_ADRS 0x0444 +# define RADEON_VIF_BUF1_PITCH_SEL 0x00000001L +# define RADEON_VIF_BUF1_TILE_ADRS 0x00000002L +# define RADEON_VIF_BUF1_BASE_ADRS_MASK 0x03fffff0L +# define RADEON_VIF_BUF1_1ST_LINE_LSBS_MASK 0x48000000L +#define RADEON_OV0_VID_BUF2_BASE_ADRS 0x0448 +# define RADEON_VIF_BUF2_PITCH_SEL 0x00000001L +# define RADEON_VIF_BUF2_TILE_ADRS 0x00000002L +# define RADEON_VIF_BUF2_BASE_ADRS_MASK 0x03fffff0L +# define RADEON_VIF_BUF2_1ST_LINE_LSBS_MASK 0x48000000L +#define RADEON_OV0_VID_BUF3_BASE_ADRS 0x044C +#define RADEON_OV0_VID_BUF4_BASE_ADRS 0x0450 +#define RADEON_OV0_VID_BUF5_BASE_ADRS 0x0454 +#define RADEON_OV0_VID_BUF_PITCH0_VALUE 0x0460 +#define RADEON_OV0_VID_BUF_PITCH1_VALUE 0x0464 +#define RADEON_OV0_AUTO_FLIP_CNTL 0x0470 +#define RADEON_OV0_DEINTERLACE_PATTERN 0x0474 +#define RADEON_OV0_H_INC 0x0480 +#define RADEON_OV0_STEP_BY 0x0484 +#define RADEON_OV0_P1_H_ACCUM_INIT 0x0488 +#define RADEON_OV0_P23_H_ACCUM_INIT 0x048C +#define RADEON_OV0_P1_X_START_END 0x0494 +#define RADEON_OV0_P2_X_START_END 0x0498 +#define RADEON_OV0_P3_X_START_END 0x049C +#define RADEON_OV0_FILTER_CNTL 0x04A0 +#define RADEON_OV0_FOUR_TAP_COEF_0 0x04B0 +#define RADEON_OV0_FOUR_TAP_COEF_1 0x04B4 +#define RADEON_OV0_FOUR_TAP_COEF_2 0x04B8 +#define RADEON_OV0_FOUR_TAP_COEF_3 0x04BC +#define RADEON_OV0_FOUR_TAP_COEF_4 0x04C0 +#define RADEON_OV0_COLOUR_CNTL 0x04E0 +#define RADEON_OV0_VIDEO_KEY_CLR 0x04E4 +#define RADEON_OV0_VIDEO_KEY_MSK 0x04E8 +#define RADEON_OV0_GRAPHICS_KEY_CLR 0x04EC +#define RADEON_OV0_GRAPHICS_KEY_MSK 0x04F0 +#define RADEON_OV0_KEY_CNTL 0x04F4 +# define RADEON_VIDEO_KEY_FN_MASK 0x00000007L +# define RADEON_VIDEO_KEY_FN_FALSE 0x00000000L +# define RADEON_VIDEO_KEY_FN_TRUE 0x00000001L +# define RADEON_VIDEO_KEY_FN_EQ 0x00000004L +# define RADEON_VIDEO_KEY_FN_NE 0x00000005L +# define RADEON_GRAPHIC_KEY_FN_MASK 0x00000070L +# define RADEON_GRAPHIC_KEY_FN_FALSE 0x00000000L +# define RADEON_GRAPHIC_KEY_FN_TRUE 0x00000010L +# define RADEON_GRAPHIC_KEY_FN_EQ 0x00000040L +# define RADEON_GRAPHIC_KEY_FN_NE 0x00000050L +# define RADEON_CMP_MIX_MASK 0x00000100L +# define RADEON_CMP_MIX_OR 0x00000000L +# define RADEON_CMP_MIX_AND 0x00000100L +#define RADEON_OV0_TEST 0x04F8 + +#define RADEON_PALETTE_DATA 0x00b4 +#define RADEON_PALETTE_30_DATA 0x00b8 +#define RADEON_PALETTE_INDEX 0x00b0 +#define RADEON_PCI_GART_PAGE 0x017c +#define RADEON_PLANE_3D_MASK_C 0x1d44 +#define RADEON_PLL_TEST_CNTL 0x0013 /* PLL */ +#define RADEON_PMI_CAP_ID 0x0f5c /* PCI */ +#define RADEON_PMI_DATA 0x0f63 /* PCI */ +#define RADEON_PMI_NXT_CAP_PTR 0x0f5d /* PCI */ +#define RADEON_PMI_PMC_REG 0x0f5e /* PCI */ +#define RADEON_PMI_PMCSR_REG 0x0f60 /* PCI */ +#define RADEON_PMI_REGISTER 0x0f5c /* PCI */ +#define RADEON_PPLL_CNTL 0x0002 /* PLL */ +# define RADEON_PPLL_RESET (1 << 0) +# define RADEON_PPLL_SLEEP (1 << 1) +# define RADEON_PPLL_ATOMIC_UPDATE_EN (1 << 16) +# define RADEON_PPLL_VGA_ATOMIC_UPDATE_EN (1 << 17) +# define RADEON_PPLL_ATOMIC_UPDATE_VSYNC (1 << 18) +#define RADEON_PPLL_DIV_0 0x0004 /* PLL */ +#define RADEON_PPLL_DIV_1 0x0005 /* PLL */ +#define RADEON_PPLL_DIV_2 0x0006 /* PLL */ +#define RADEON_PPLL_DIV_3 0x0007 /* PLL */ +# define RADEON_PPLL_FB3_DIV_MASK 0x07ff +# define RADEON_PPLL_POST3_DIV_MASK 0x00070000 +#define RADEON_PPLL_REF_DIV 0x0003 /* PLL */ +# define RADEON_PPLL_REF_DIV_MASK 0x03ff +# define RADEON_PPLL_ATOMIC_UPDATE_R (1 << 15) /* same as _W */ +# define RADEON_PPLL_ATOMIC_UPDATE_W (1 << 15) /* same as _R */ +#define RADEON_PWR_MNGMT_CNTL_STATUS 0x0f60 /* PCI */ +#define RADEON_RBBM_SOFT_RESET 0x00f0 +#define RADEON_RBBM_STATUS 0x0e40 +# define RADEON_RBBM_FIFOCNT_MASK 0x007f +# define RADEON_RBBM_ACTIVE (1 << 31) +#define RADEON_RB2D_DSTCACHE_CTLSTAT 0x342c +# define RADEON_RB2D_DC_FLUSH_ALL 0xf +# define RADEON_RB2D_DC_BUSY (1 << 31) +#define RADEON_RB2D_DSTCACHE_MODE 0x3428 +#define RADEON_REG_BASE 0x0f18 /* PCI */ +#define RADEON_REGPROG_INF 0x0f09 /* PCI */ +#define RADEON_REVISION_ID 0x0f08 /* PCI */ + +#define RADEON_SC_BOTTOM 0x164c +#define RADEON_SC_BOTTOM_RIGHT 0x16f0 +#define RADEON_SC_BOTTOM_RIGHT_C 0x1c8c +#define RADEON_SC_LEFT 0x1640 +#define RADEON_SC_RIGHT 0x1644 +#define RADEON_SC_TOP 0x1648 +#define RADEON_SC_TOP_LEFT 0x16ec +#define RADEON_SC_TOP_LEFT_C 0x1c88 +#define RADEON_SDRAM_MODE_REG 0x0158 +#define RADEON_SEQ8_DATA 0x03c5 /* VGA */ +#define RADEON_SEQ8_IDX 0x03c4 /* VGA */ +#define RADEON_SNAPSHOT_F_COUNT 0x0244 +#define RADEON_SNAPSHOT_VH_COUNTS 0x0240 +#define RADEON_SNAPSHOT_VIF_COUNT 0x024c +#define RADEON_SRC_OFFSET 0x15ac +#define RADEON_SRC_PITCH 0x15b0 +#define RADEON_SRC_PITCH_OFFSET 0x1428 +#define RADEON_SRC_SC_BOTTOM 0x165c +#define RADEON_SRC_SC_BOTTOM_RIGHT 0x16f4 +#define RADEON_SRC_SC_RIGHT 0x1654 +#define RADEON_SRC_X 0x1414 +#define RADEON_SRC_X_Y 0x1590 +#define RADEON_SRC_Y 0x1418 +#define RADEON_SRC_Y_X 0x1434 +#define RADEON_STATUS 0x0f06 /* PCI */ +#define RADEON_SUBPIC_CNTL 0x0540 /* ? */ +#define RADEON_SUB_CLASS 0x0f0a /* PCI */ +#define RADEON_SURFACE_DELAY 0x0b00 +#define RADEON_SURFACE0_INFO 0x0b0c +#define RADEON_SURFACE0_LOWER_BOUND 0x0b04 +#define RADEON_SURFACE0_UPPER_BOUND 0x0b08 +#define RADEON_SURFACE1_INFO 0x0b1c +#define RADEON_SURFACE1_LOWER_BOUND 0x0b14 +#define RADEON_SURFACE1_UPPER_BOUND 0x0b18 +#define RADEON_SURFACE2_INFO 0x0b2c +#define RADEON_SURFACE2_LOWER_BOUND 0x0b24 +#define RADEON_SURFACE2_UPPER_BOUND 0x0b28 +#define RADEON_SURFACE3_INFO 0x0b3c +#define RADEON_SURFACE3_LOWER_BOUND 0x0b34 +#define RADEON_SURFACE3_UPPER_BOUND 0x0b38 +#define RADEON_SW_SEMAPHORE 0x013c + +#define RADEON_TEST_DEBUG_CNTL 0x0120 +#define RADEON_TEST_DEBUG_MUX 0x0124 +#define RADEON_TEST_DEBUG_OUT 0x012c +#define RADEON_TMDS_CRC 0x02a0 +#define RADEON_TRAIL_BRES_DEC 0x1614 +#define RADEON_TRAIL_BRES_ERR 0x160c +#define RADEON_TRAIL_BRES_INC 0x1610 +#define RADEON_TRAIL_X 0x1618 +#define RADEON_TRAIL_X_SUB 0x1620 + +#define RADEON_VCLK_ECP_CNTL 0x0008 /* PLL */ +#define RADEON_VENDOR_ID 0x0f00 /* PCI */ +#define RADEON_VGA_DDA_CONFIG 0x02e8 +#define RADEON_VGA_DDA_ON_OFF 0x02ec +#define RADEON_VID_BUFFER_CONTROL 0x0900 +#define RADEON_VIDEOMUX_CNTL 0x0190 +#define RADEON_VIPH_CONTROL 0x0c40 /* ? */ + +#define RADEON_WAIT_UNTIL 0x1720 + +#define RADEON_X_MPLL_REF_FB_DIV 0x000a /* PLL */ +#define RADEON_XCLK_CNTL 0x000d /* PLL */ +#define RADEON_XDLL_CNTL 0x000c /* PLL */ +#define RADEON_XPLL_CNTL 0x000b /* PLL */ + + /* Registers for CCE and Microcode Engine */ +#define RADEON_CP_ME_RAM_ADDR 0x07d4 +#define RADEON_CP_ME_RAM_RADDR 0x07d8 +#define RADEON_CP_ME_RAM_DATAH 0x07dc +#define RADEON_CP_ME_RAM_DATAL 0x07e0 + +#define RADEON_CP_RB_BASE 0x0700 +#define RADEON_CP_RB_CNTL 0x0704 +#define RADEON_CP_RB_RPTR_ADDR 0x070c +#define RADEON_CP_RB_RPTR 0x0710 +#define RADEON_CP_RB_WPTR 0x0714 +# define RADEON_PM4_BUFFER_DL_DONE (1 << 31) + +#define RADEON_CP_IB_BASE 0x0738 +#define RADEON_CP_IB_BUFSZ 0x073c + +#define RADEON_CP_CSQ_CNTL 0x0740 +# define RADEON_CSQ_PRIDIS_INDDIS (0 << 28) +# define RADEON_CSQ_PRIPIO_INDDIS (1 << 28) +# define RADEON_CSQ_PRIBM_INDDIS (2 << 28) +# define RADEON_CSQ_PRIPIO_INDBM (3 << 28) +# define RADEON_CSQ_PRIBM_INDBM (4 << 28) +# define RADEON_CSQ_PRIPIO_INDPIO (15 << 28) +#define RADEON_CP_RB_WPTR_DELAY 0x0718 +# define RADEON_PRE_WRITE_TIMER_SHIFT 0 +# define RADEON_PRE_WRITE_LIMIT_SHIFT 23 + +#define RADEON_AIC_CNTL 0x01d0 +# define RADEON_PCIGART_TRANSLATE_EN (1 << 0) + +#define RADEON_PM4_VC_FPU_SETUP 0x071c +# define RADEON_FRONT_DIR_CW (0 << 0) +# define RADEON_FRONT_DIR_CCW (1 << 0) +# define RADEON_FRONT_DIR_MASK (1 << 0) +# define RADEON_BACKFACE_CULL (0 << 1) +# define RADEON_BACKFACE_POINTS (1 << 1) +# define RADEON_BACKFACE_LINES (2 << 1) +# define RADEON_BACKFACE_SOLID (3 << 1) +# define RADEON_BACKFACE_MASK (3 << 1) +# define RADEON_FRONTFACE_CULL (0 << 3) +# define RADEON_FRONTFACE_POINTS (1 << 3) +# define RADEON_FRONTFACE_LINES (2 << 3) +# define RADEON_FRONTFACE_SOLID (3 << 3) +# define RADEON_FRONTFACE_MASK (3 << 3) +# define RADEON_FPU_COLOR_SOLID (0 << 5) +# define RADEON_FPU_COLOR_FLAT (1 << 5) +# define RADEON_FPU_COLOR_GOURAUD (2 << 5) +# define RADEON_FPU_COLOR_GOURAUD2 (3 << 5) +# define RADEON_FPU_COLOR_MASK (3 << 5) +# define RADEON_FPU_SUB_PIX_2BITS (0 << 7) +# define RADEON_FPU_SUB_PIX_4BITS (1 << 7) +# define RADEON_FPU_MODE_2D (0 << 8) +# define RADEON_FPU_MODE_3D (1 << 8) +# define RADEON_TRAP_BITS_DISABLE (1 << 9) +# define RADEON_EDGE_ANTIALIAS (1 << 10) +# define RADEON_SUPERSAMPLE (1 << 11) +# define RADEON_XFACTOR_2 (0 << 12) +# define RADEON_XFACTOR_4 (1 << 12) +# define RADEON_YFACTOR_2 (0 << 13) +# define RADEON_YFACTOR_4 (1 << 13) +# define RADEON_FLAT_SHADE_VERTEX_D3D (0 << 14) +# define RADEON_FLAT_SHADE_VERTEX_OGL (1 << 14) +# define RADEON_FPU_ROUND_TRUNCATE (0 << 15) +# define RADEON_FPU_ROUND_NEAREST (1 << 15) +# define RADEON_WM_SEL_8DW (0 << 16) +# define RADEON_WM_SEL_16DW (1 << 16) +# define RADEON_WM_SEL_32DW (2 << 16) +#define RADEON_PM4_VC_DEBUG_CONFIG 0x07a4 +#define RADEON_PM4_VC_STAT 0x07a8 +#define RADEON_PM4_VC_TIMESTAMP0 0x07b0 +#define RADEON_PM4_VC_TIMESTAMP1 0x07b4 +#define RADEON_PM4_STAT 0x07b8 +# define RADEON_PM4_FIFOCNT_MASK 0x0fff +# define RADEON_PM4_BUSY (1 << 16) +# define RADEON_PM4_GUI_ACTIVE (1 << 31) +#define RADEON_PM4_BUFFER_ADDR 0x07f0 +#define RADEON_CP_ME_CNTL 0x07d0 +# define RADEON_CP_ME_FREERUN (1 << 30) +#define RADEON_PM4_FIFO_DATA_EVEN 0x1000 +#define RADEON_PM4_FIFO_DATA_ODD 0x1004 + +#define RADEON_SCALE_3D_CNTL 0x1a00 +# define RADEON_SCALE_DITHER_ERR_DIFF (0 << 1) +# define RADEON_SCALE_DITHER_TABLE (1 << 1) +# define RADEON_TEX_CACHE_SIZE_FULL (0 << 2) +# define RADEON_TEX_CACHE_SIZE_HALF (1 << 2) +# define RADEON_DITHER_INIT_CURR (0 << 3) +# define RADEON_DITHER_INIT_RESET (1 << 3) +# define RADEON_ROUND_24BIT (1 << 4) +# define RADEON_TEX_CACHE_DISABLE (1 << 5) +# define RADEON_SCALE_3D_NOOP (0 << 6) +# define RADEON_SCALE_3D_SCALE (1 << 6) +# define RADEON_SCALE_3D_TEXMAP_SHADE (2 << 6) +# define RADEON_SCALE_PIX_BLEND (0 << 8) +# define RADEON_SCALE_PIX_REPLICATE (1 << 8) +# define RADEON_TEX_CACHE_SPLIT (1 << 9) +# define RADEON_APPLE_YUV_MODE (1 << 10) +# define RADEON_TEX_CACHE_PALLETE_MODE (1 << 11) +# define RADEON_ALPHA_COMB_ADD_CLAMP (0 << 12) +# define RADEON_ALPHA_COMB_ADD_NCLAMP (1 << 12) +# define RADEON_ALPHA_COMB_SUB_DST_SRC_CLAMP (2 << 12) +# define RADEON_ALPHA_COMB_SUB_DST_SRC_NCLAMP (3 << 12) +# define RADEON_FOG_TABLE (1 << 14) +# define RADEON_SIGNED_DST_CLAMP (1 << 15) +# define RADEON_ALPHA_BLEND_SRC_ZERO (0 << 16) +# define RADEON_ALPHA_BLEND_SRC_ONE (1 << 16) +# define RADEON_ALPHA_BLEND_SRC_SRCCOLOR (2 << 16) +# define RADEON_ALPHA_BLEND_SRC_INVSRCCOLOR (3 << 16) +# define RADEON_ALPHA_BLEND_SRC_SRCALPHA (4 << 16) +# define RADEON_ALPHA_BLEND_SRC_INVSRCALPHA (5 << 16) +# define RADEON_ALPHA_BLEND_SRC_DSTALPHA (6 << 16) +# define RADEON_ALPHA_BLEND_SRC_INVDSTALPHA (7 << 16) +# define RADEON_ALPHA_BLEND_SRC_DSTCOLOR (8 << 16) +# define RADEON_ALPHA_BLEND_SRC_INVDSTCOLOR (9 << 16) +# define RADEON_ALPHA_BLEND_SRC_SAT (10 << 16) +# define RADEON_ALPHA_BLEND_SRC_BLEND (11 << 16) +# define RADEON_ALPHA_BLEND_SRC_INVBLEND (12 << 16) +# define RADEON_ALPHA_BLEND_DST_ZERO (0 << 20) +# define RADEON_ALPHA_BLEND_DST_ONE (1 << 20) +# define RADEON_ALPHA_BLEND_DST_SRCCOLOR (2 << 20) +# define RADEON_ALPHA_BLEND_DST_INVSRCCOLOR (3 << 20) +# define RADEON_ALPHA_BLEND_DST_SRCALPHA (4 << 20) +# define RADEON_ALPHA_BLEND_DST_INVSRCALPHA (5 << 20) +# define RADEON_ALPHA_BLEND_DST_DSTALPHA (6 << 20) +# define RADEON_ALPHA_BLEND_DST_INVDSTALPHA (7 << 20) +# define RADEON_ALPHA_BLEND_DST_DSTCOLOR (8 << 20) +# define RADEON_ALPHA_BLEND_DST_INVDSTCOLOR (9 << 20) +# define RADEON_ALPHA_TEST_NEVER (0 << 24) +# define RADEON_ALPHA_TEST_LESS (1 << 24) +# define RADEON_ALPHA_TEST_LESSEQUAL (2 << 24) +# define RADEON_ALPHA_TEST_EQUAL (3 << 24) +# define RADEON_ALPHA_TEST_GREATEREQUAL (4 << 24) +# define RADEON_ALPHA_TEST_GREATER (5 << 24) +# define RADEON_ALPHA_TEST_NEQUAL (6 << 24) +# define RADEON_ALPHA_TEST_ALWAYS (7 << 24) +# define RADEON_COMPOSITE_SHADOW_CMP_EQUAL (0 << 28) +# define RADEON_COMPOSITE_SHADOW_CMP_NEQUAL (1 << 28) +# define RADEON_COMPOSITE_SHADOW (1 << 29) +# define RADEON_TEX_MAP_ALPHA_IN_TEXTURE (1 << 30) +# define RADEON_TEX_CACHE_LINE_SIZE_8QW (0 << 31) +# define RADEON_TEX_CACHE_LINE_SIZE_4QW (1 << 31) +#define RADEON_SCALE_3D_DATATYPE 0x1a20 + +#define RADEON_SETUP_CNTL 0x1bc4 +# define RADEON_DONT_START_TRIANGLE (1 << 0) +# define RADEON_Z_BIAS (0 << 1) +# define RADEON_DONT_START_ANY_ON (1 << 2) +# define RADEON_COLOR_SOLID_COLOR (0 << 3) +# define RADEON_COLOR_FLAT_VERT_1 (1 << 3) +# define RADEON_COLOR_FLAT_VERT_2 (2 << 3) +# define RADEON_COLOR_FLAT_VERT_3 (3 << 3) +# define RADEON_COLOR_GOURAUD (4 << 3) +# define RADEON_PRIM_TYPE_TRI (0 << 7) +# define RADEON_PRIM_TYPE_LINE (1 << 7) +# define RADEON_PRIM_TYPE_POINT (2 << 7) +# define RADEON_PRIM_TYPE_POLY_EDGE (3 << 7) +# define RADEON_TEXTURE_ST_MULT_W (0 << 9) +# define RADEON_TEXTURE_ST_DIRECT (1 << 9) +# define RADEON_STARTING_VERTEX_1 (1 << 14) +# define RADEON_STARTING_VERTEX_2 (2 << 14) +# define RADEON_STARTING_VERTEX_3 (3 << 14) +# define RADEON_ENDING_VERTEX_1 (1 << 16) +# define RADEON_ENDING_VERTEX_2 (2 << 16) +# define RADEON_ENDING_VERTEX_3 (3 << 16) +# define RADEON_SU_POLY_LINE_LAST (0 << 18) +# define RADEON_SU_POLY_LINE_NOT_LAST (1 << 18) +# define RADEON_SUB_PIX_2BITS (0 << 19) +# define RADEON_SUB_PIX_4BITS (1 << 19) +# define RADEON_SET_UP_CONTINUE (1 << 31) + +#define RADEON_WINDOW_XY_OFFSET 0x1bcc +# define RADEON_WINDOW_Y_SHIFT 4 +# define RADEON_WINDOW_X_SHIFT 20 + +#define RADEON_Z_OFFSET_C 0x1c90 +#define RADEON_Z_PITCH_C 0x1c94 +#define RADEON_Z_STEN_CNTL_C 0x1c98 +# define RADEON_Z_PIX_WIDTH_16 (0 << 1) +# define RADEON_Z_PIX_WIDTH_24 (1 << 1) +# define RADEON_Z_PIX_WIDTH_32 (2 << 1) +# define RADEON_Z_PIX_WIDTH_MASK (3 << 1) +# define RADEON_Z_TEST_NEVER (0 << 4) +# define RADEON_Z_TEST_LESS (1 << 4) +# define RADEON_Z_TEST_LESSEQUAL (2 << 4) +# define RADEON_Z_TEST_EQUAL (3 << 4) +# define RADEON_Z_TEST_GREATEREQUAL (4 << 4) +# define RADEON_Z_TEST_GREATER (5 << 4) +# define RADEON_Z_TEST_NEQUAL (6 << 4) +# define RADEON_Z_TEST_ALWAYS (7 << 4) +# define RADEON_Z_TEST_MASK (7 << 4) +# define RADEON_STENCIL_TEST_NEVER (0 << 12) +# define RADEON_STENCIL_TEST_LESS (1 << 12) +# define RADEON_STENCIL_TEST_LESSEQUAL (2 << 12) +# define RADEON_STENCIL_TEST_EQUAL (3 << 12) +# define RADEON_STENCIL_TEST_GREATEREQUAL (4 << 12) +# define RADEON_STENCIL_TEST_GREATER (5 << 12) +# define RADEON_STENCIL_TEST_NEQUAL (6 << 12) +# define RADEON_STENCIL_TEST_ALWAYS (7 << 12) +# define RADEON_STENCIL_S_FAIL_KEEP (0 << 16) +# define RADEON_STENCIL_S_FAIL_ZERO (1 << 16) +# define RADEON_STENCIL_S_FAIL_REPLACE (2 << 16) +# define RADEON_STENCIL_S_FAIL_INC (3 << 16) +# define RADEON_STENCIL_S_FAIL_DEC (4 << 16) +# define RADEON_STENCIL_S_FAIL_INV (5 << 16) +# define RADEON_STENCIL_ZPASS_KEEP (0 << 20) +# define RADEON_STENCIL_ZPASS_ZERO (1 << 20) +# define RADEON_STENCIL_ZPASS_REPLACE (2 << 20) +# define RADEON_STENCIL_ZPASS_INC (3 << 20) +# define RADEON_STENCIL_ZPASS_DEC (4 << 20) +# define RADEON_STENCIL_ZPASS_INV (5 << 20) +# define RADEON_STENCIL_ZFAIL_KEEP (0 << 24) +# define RADEON_STENCIL_ZFAIL_ZERO (1 << 24) +# define RADEON_STENCIL_ZFAIL_REPLACE (2 << 24) +# define RADEON_STENCIL_ZFAIL_INC (3 << 24) +# define RADEON_STENCIL_ZFAIL_DEC (4 << 24) +# define RADEON_STENCIL_ZFAIL_INV (5 << 24) +#define RADEON_TEX_CNTL_C 0x1c9c +# define RADEON_Z_ENABLE (1 << 0) +# define RADEON_Z_WRITE_ENABLE (1 << 1) +# define RADEON_STENCIL_ENABLE (1 << 3) +# define RADEON_SHADE_ENABLE (0 << 4) +# define RADEON_TEXMAP_ENABLE (1 << 4) +# define RADEON_SEC_TEXMAP_ENABLE (1 << 5) +# define RADEON_FOG_ENABLE (1 << 7) +# define RADEON_DITHER_ENABLE (1 << 8) +# define RADEON_ALPHA_ENABLE (1 << 9) +# define RADEON_ALPHA_TEST_ENABLE (1 << 10) +# define RADEON_SPEC_LIGHT_ENABLE (1 << 11) +# define RADEON_TEX_CHROMA_KEY_ENABLE (1 << 12) +# define RADEON_ALPHA_IN_TEX_COMPLETE_A (0 << 13) +# define RADEON_ALPHA_IN_TEX_LSB_A (1 << 13) +# define RADEON_LIGHT_DIS (0 << 14) +# define RADEON_LIGHT_COPY (1 << 14) +# define RADEON_LIGHT_MODULATE (2 << 14) +# define RADEON_LIGHT_ADD (3 << 14) +# define RADEON_LIGHT_BLEND_CONSTANT (4 << 14) +# define RADEON_LIGHT_BLEND_TEXTURE (5 << 14) +# define RADEON_LIGHT_BLEND_VERTEX (6 << 14) +# define RADEON_LIGHT_BLEND_CONST_COLOR (7 << 14) +# define RADEON_ALPHA_LIGHT_DIS (0 << 18) +# define RADEON_ALPHA_LIGHT_COPY (1 << 18) +# define RADEON_ALPHA_LIGHT_MODULATE (2 << 18) +# define RADEON_ALPHA_LIGHT_ADD (3 << 18) +# define RADEON_ANTI_ALIAS (1 << 21) +# define RADEON_TEX_CACHE_FLUSH (1 << 23) +# define RADEON_LOD_BIAS_SHIFT 24 +#define RADEON_MISC_3D_STATE_CNTL_REG 0x1ca0 +# define RADEON_REF_ALPHA_MASK 0xff +# define RADEON_MISC_SCALE_3D_NOOP (0 << 8) +# define RADEON_MISC_SCALE_3D_SCALE (1 << 8) +# define RADEON_MISC_SCALE_3D_TEXMAP_SHADE (2 << 8) +# define RADEON_MISC_SCALE_PIX_BLEND (0 << 10) +# define RADEON_MISC_SCALE_PIX_REPLICATE (1 << 10) +# define RADEON_ALPHA_COMB_ADD_CLAMP (0 << 12) +# define RADEON_ALPHA_COMB_ADD_NO_CLAMP (1 << 12) +# define RADEON_ALPHA_COMB_SUB_SRC_DST_CLAMP (2 << 12) +# define RADEON_ALPHA_COMB_SUB_SRC_DST_NO_CLAMP (3 << 12) +# define RADEON_FOG_VERTEX (0 << 14) +# define RADEON_FOG_TABLE (1 << 14) +# define RADEON_ALPHA_BLEND_SRC_ZERO (0 << 16) +# define RADEON_ALPHA_BLEND_SRC_ONE (1 << 16) +# define RADEON_ALPHA_BLEND_SRC_SRCCOLOR (2 << 16) +# define RADEON_ALPHA_BLEND_SRC_INVSRCCOLOR (3 << 16) +# define RADEON_ALPHA_BLEND_SRC_SRCALPHA (4 << 16) +# define RADEON_ALPHA_BLEND_SRC_INVSRCALPHA (5 << 16) +# define RADEON_ALPHA_BLEND_SRC_DESTALPHA (6 << 16) +# define RADEON_ALPHA_BLEND_SRC_INVDESTALPHA (7 << 16) +# define RADEON_ALPHA_BLEND_SRC_DESTCOLOR (8 << 16) +# define RADEON_ALPHA_BLEND_SRC_INVDESTCOLOR (9 << 16) +# define RADEON_ALPHA_BLEND_SRC_SRCALPHASAT (10 << 16) +# define RADEON_ALPHA_BLEND_SRC_BOTHSRCALPHA (11 << 16) +# define RADEON_ALPHA_BLEND_SRC_BOTHINVSRCALPHA (12 << 16) +# define RADEON_ALPHA_BLEND_SRC_MASK (15 << 16) +# define RADEON_ALPHA_BLEND_DST_ZERO (0 << 20) +# define RADEON_ALPHA_BLEND_DST_ONE (1 << 20) +# define RADEON_ALPHA_BLEND_DST_SRCCOLOR (2 << 20) +# define RADEON_ALPHA_BLEND_DST_INVSRCCOLOR (3 << 20) +# define RADEON_ALPHA_BLEND_DST_SRCALPHA (4 << 20) +# define RADEON_ALPHA_BLEND_DST_INVSRCALPHA (5 << 20) +# define RADEON_ALPHA_BLEND_DST_DESTALPHA (6 << 20) +# define RADEON_ALPHA_BLEND_DST_INVDESTALPHA (7 << 20) +# define RADEON_ALPHA_BLEND_DST_DESTCOLOR (8 << 20) +# define RADEON_ALPHA_BLEND_DST_INVDESTCOLOR (9 << 20) +# define RADEON_ALPHA_BLEND_DST_SRCALPHASAT (10 << 20) +# define RADEON_ALPHA_BLEND_DST_MASK (15 << 20) +# define RADEON_ALPHA_TEST_NEVER (0 << 24) +# define RADEON_ALPHA_TEST_LESS (1 << 24) +# define RADEON_ALPHA_TEST_LESSEQUAL (2 << 24) +# define RADEON_ALPHA_TEST_EQUAL (3 << 24) +# define RADEON_ALPHA_TEST_GREATEREQUAL (4 << 24) +# define RADEON_ALPHA_TEST_GREATER (5 << 24) +# define RADEON_ALPHA_TEST_NEQUAL (6 << 24) +# define RADEON_ALPHA_TEST_ALWAYS (7 << 24) +# define RADEON_ALPHA_TEST_MASK (7 << 24) +#define RADEON_TEXTURE_CLR_CMP_CLR_C 0x1ca4 +#define RADEON_TEXTURE_CLR_CMP_MSK_C 0x1ca8 +#define RADEON_FOG_COLOR_C 0x1cac +# define RADEON_FOG_BLUE_SHIFT 0 +# define RADEON_FOG_GREEN_SHIFT 8 +# define RADEON_FOG_RED_SHIFT 16 +#define RADEON_PRIM_TEX_CNTL_C 0x1cb0 +# define RADEON_MIN_BLEND_NEAREST (0 << 1) +# define RADEON_MIN_BLEND_LINEAR (1 << 1) +# define RADEON_MIN_BLEND_MIPNEAREST (2 << 1) +# define RADEON_MIN_BLEND_MIPLINEAR (3 << 1) +# define RADEON_MIN_BLEND_LINEARMIPNEAREST (4 << 1) +# define RADEON_MIN_BLEND_LINEARMIPLINEAR (5 << 1) +# define RADEON_MIN_BLEND_MASK (7 << 1) +# define RADEON_MAG_BLEND_NEAREST (0 << 4) +# define RADEON_MAG_BLEND_LINEAR (1 << 4) +# define RADEON_MAG_BLEND_MASK (7 << 4) +# define RADEON_MIP_MAP_DISABLE (1 << 7) +# define RADEON_TEX_CLAMP_S_WRAP (0 << 8) +# define RADEON_TEX_CLAMP_S_MIRROR (1 << 8) +# define RADEON_TEX_CLAMP_S_CLAMP (2 << 8) +# define RADEON_TEX_CLAMP_S_BORDER_COLOR (3 << 8) +# define RADEON_TEX_CLAMP_S_MASK (3 << 8) +# define RADEON_TEX_WRAP_S (1 << 10) +# define RADEON_TEX_CLAMP_T_WRAP (0 << 11) +# define RADEON_TEX_CLAMP_T_MIRROR (1 << 11) +# define RADEON_TEX_CLAMP_T_CLAMP (2 << 11) +# define RADEON_TEX_CLAMP_T_BORDER_COLOR (3 << 11) +# define RADEON_TEX_CLAMP_T_MASK (3 << 11) +# define RADEON_TEX_WRAP_T (1 << 13) +# define RADEON_TEX_PERSPECTIVE_DISABLE (1 << 14) +# define RADEON_DATATYPE_VQ (0 << 16) +# define RADEON_DATATYPE_CI4 (1 << 16) +# define RADEON_DATATYPE_CI8 (2 << 16) +# define RADEON_DATATYPE_ARGB1555 (3 << 16) +# define RADEON_DATATYPE_RGB565 (4 << 16) +# define RADEON_DATATYPE_RGB888 (5 << 16) +# define RADEON_DATATYPE_ARGB8888 (6 << 16) +# define RADEON_DATATYPE_RGB332 (7 << 16) +# define RADEON_DATATYPE_Y8 (8 << 16) +# define RADEON_DATATYPE_RGB8 (9 << 16) +# define RADEON_DATATYPE_CI16 (10 << 16) +# define RADEON_DATATYPE_YUV422 (11 << 16) +# define RADEON_DATATYPE_YUV422_2 (12 << 16) +# define RADEON_DATATYPE_AYUV444 (14 << 16) +# define RADEON_DATATYPE_ARGB4444 (15 << 16) +# define RADEON_PALLETE_EITHER (0 << 20) +# define RADEON_PALLETE_1 (1 << 20) +# define RADEON_PALLETE_2 (2 << 20) +# define RADEON_PSEUDOCOLOR_DT_RGB565 (0 << 24) +# define RADEON_PSEUDOCOLOR_DT_ARGB1555 (1 << 24) +# define RADEON_PSEUDOCOLOR_DT_ARGB4444 (2 << 24) +#define RADEON_PRIM_TEXTURE_COMBINE_CNTL_C 0x1cb4 +# define RADEON_COMB_DIS (0 << 0) +# define RADEON_COMB_COPY (1 << 0) +# define RADEON_COMB_COPY_INP (2 << 0) +# define RADEON_COMB_MODULATE (3 << 0) +# define RADEON_COMB_MODULATE2X (4 << 0) +# define RADEON_COMB_MODULATE4X (5 << 0) +# define RADEON_COMB_ADD (6 << 0) +# define RADEON_COMB_ADD_SIGNED (7 << 0) +# define RADEON_COMB_BLEND_VERTEX (8 << 0) +# define RADEON_COMB_BLEND_TEXTURE (9 << 0) +# define RADEON_COMB_BLEND_CONST (10 << 0) +# define RADEON_COMB_BLEND_PREMULT (11 << 0) +# define RADEON_COMB_BLEND_PREV (12 << 0) +# define RADEON_COMB_BLEND_PREMULT_INV (13 << 0) +# define RADEON_COMB_ADD_SIGNED2X (14 << 0) +# define RADEON_COMB_BLEND_CONST_COLOR (15 << 0) +# define RADEON_COMB_MASK (15 << 0) +# define RADEON_COLOR_FACTOR_TEX (4 << 4) +# define RADEON_COLOR_FACTOR_NTEX (5 << 4) +# define RADEON_COLOR_FACTOR_ALPHA (6 << 4) +# define RADEON_COLOR_FACTOR_NALPHA (7 << 4) +# define RADEON_COLOR_FACTOR_MASK (15 << 4) +# define RADEON_INPUT_FACTOR_CONST_COLOR (2 << 10) +# define RADEON_INPUT_FACTOR_CONST_ALPHA (3 << 10) +# define RADEON_INPUT_FACTOR_INT_COLOR (4 << 10) +# define RADEON_INPUT_FACTOR_INT_ALPHA (5 << 10) +# define RADEON_INPUT_FACTOR_MASK (15 << 10) +# define RADEON_COMB_ALPHA_DIS (0 << 14) +# define RADEON_COMB_ALPHA_COPY (1 << 14) +# define RADEON_COMB_ALPHA_COPY_INP (2 << 14) +# define RADEON_COMB_ALPHA_MODULATE (3 << 14) +# define RADEON_COMB_ALPHA_MODULATE2X (4 << 14) +# define RADEON_COMB_ALPHA_MODULATE4X (5 << 14) +# define RADEON_COMB_ALPHA_ADD (6 << 14) +# define RADEON_COMB_ALPHA_ADD_SIGNED (7 << 14) +# define RADEON_COMB_ALPHA_ADD_SIGNED2X (14 << 14) +# define RADEON_COMB_ALPHA_MASK (15 << 14) +# define RADEON_ALPHA_FACTOR_TEX_ALPHA (6 << 18) +# define RADEON_ALPHA_FACTOR_NTEX_ALPHA (7 << 18) +# define RADEON_ALPHA_FACTOR_MASK (15 << 18) +# define RADEON_INP_FACTOR_A_CONST_ALPHA (1 << 25) +# define RADEON_INP_FACTOR_A_INT_ALPHA (2 << 25) +# define RADEON_INP_FACTOR_A_MASK (7 << 25) +#define RADEON_TEX_SIZE_PITCH_C 0x1cb8 +# define RADEON_TEX_PITCH_SHIFT 0 +# define RADEON_TEX_SIZE_SHIFT 4 +# define RADEON_TEX_HEIGHT_SHIFT 8 +# define RADEON_TEX_MIN_SIZE_SHIFT 12 +# define RADEON_SEC_TEX_PITCH_SHIFT 16 +# define RADEON_SEC_TEX_SIZE_SHIFT 20 +# define RADEON_SEC_TEX_HEIGHT_SHIFT 24 +# define RADEON_SEC_TEX_MIN_SIZE_SHIFT 28 +# define RADEON_TEX_PITCH_MASK (0x0f << 0) +# define RADEON_TEX_SIZE_MASK (0x0f << 4) +# define RADEON_TEX_HEIGHT_MASK (0x0f << 8) +# define RADEON_TEX_MIN_SIZE_MASK (0x0f << 12) +# define RADEON_SEC_TEX_PITCH_MASK (0x0f << 16) +# define RADEON_SEC_TEX_SIZE_MASK (0x0f << 20) +# define RADEON_SEC_TEX_HEIGHT_MASK (0x0f << 24) +# define RADEON_SEC_TEX_MIN_SIZE_MASK (0x0f << 28) +# define RADEON_TEX_SIZE_PITCH_SHIFT 0 +# define RADEON_SEC_TEX_SIZE_PITCH_SHIFT 16 +# define RADEON_TEX_SIZE_PITCH_MASK (0xffff << 0) +# define RADEON_SEC_TEX_SIZE_PITCH_MASK (0xffff << 16) +#define RADEON_PRIM_TEX_0_OFFSET_C 0x1cbc +#define RADEON_PRIM_TEX_1_OFFSET_C 0x1cc0 +#define RADEON_PRIM_TEX_2_OFFSET_C 0x1cc4 +#define RADEON_PRIM_TEX_3_OFFSET_C 0x1cc8 +#define RADEON_PRIM_TEX_4_OFFSET_C 0x1ccc +#define RADEON_PRIM_TEX_5_OFFSET_C 0x1cd0 +#define RADEON_PRIM_TEX_6_OFFSET_C 0x1cd4 +#define RADEON_PRIM_TEX_7_OFFSET_C 0x1cd8 +#define RADEON_PRIM_TEX_8_OFFSET_C 0x1cdc +#define RADEON_PRIM_TEX_9_OFFSET_C 0x1ce0 +#define RADEON_PRIM_TEX_10_OFFSET_C 0x1ce4 +# define RADEON_TEX_NO_TILE (0 << 30) +# define RADEON_TEX_TILED_BY_HOST (1 << 30) +# define RADEON_TEX_TILED_BY_STORAGE (2 << 30) +# define RADEON_TEX_TILED_BY_STORAGE2 (3 << 30) + +#define RADEON_SEC_TEX_CNTL_C 0x1d00 +# define RADEON_SEC_SELECT_PRIM_ST (0 << 0) +# define RADEON_SEC_SELECT_SEC_ST (1 << 0) +#define RADEON_SEC_TEX_COMBINE_CNTL_C 0x1d04 +# define RADEON_INPUT_FACTOR_PREV_COLOR (8 << 10) +# define RADEON_INPUT_FACTOR_PREV_ALPHA (9 << 10) +# define RADEON_INP_FACTOR_A_PREV_ALPHA (4 << 25) +#define RADEON_SEC_TEX_0_OFFSET_C 0x1d08 +#define RADEON_SEC_TEX_1_OFFSET_C 0x1d0c +#define RADEON_SEC_TEX_2_OFFSET_C 0x1d10 +#define RADEON_SEC_TEX_3_OFFSET_C 0x1d14 +#define RADEON_SEC_TEX_4_OFFSET_C 0x1d18 +#define RADEON_SEC_TEX_5_OFFSET_C 0x1d1c +#define RADEON_SEC_TEX_6_OFFSET_C 0x1d20 +#define RADEON_SEC_TEX_7_OFFSET_C 0x1d24 +#define RADEON_SEC_TEX_8_OFFSET_C 0x1d28 +#define RADEON_SEC_TEX_9_OFFSET_C 0x1d2c +#define RADEON_SEC_TEX_10_OFFSET_C 0x1d30 +#define RADEON_CONSTANT_COLOR_C 0x1d34 +# define RADEON_CONSTANT_BLUE_SHIFT 0 +# define RADEON_CONSTANT_GREEN_SHIFT 8 +# define RADEON_CONSTANT_RED_SHIFT 16 +# define RADEON_CONSTANT_ALPHA_SHIFT 24 +#define RADEON_PRIM_TEXTURE_BORDER_COLOR_C 0x1d38 +# define RADEON_PRIM_TEX_BORDER_BLUE_SHIFT 0 +# define RADEON_PRIM_TEX_BORDER_GREEN_SHIFT 8 +# define RADEON_PRIM_TEX_BORDER_RED_SHIFT 16 +# define RADEON_PRIM_TEX_BORDER_ALPHA_SHIFT 24 +#define RADEON_SEC_TEXTURE_BORDER_COLOR_C 0x1d3c +# define RADEON_SEC_TEX_BORDER_BLUE_SHIFT 0 +# define RADEON_SEC_TEX_BORDER_GREEN_SHIFT 8 +# define RADEON_SEC_TEX_BORDER_RED_SHIFT 16 +# define RADEON_SEC_TEX_BORDER_ALPHA_SHIFT 24 +#define RADEON_STEN_REF_MASK_C 0x1d40 +# define RADEON_STEN_REFERENCE_SHIFT 0 +# define RADEON_STEN_MASK_SHIFT 16 +# define RADEON_STEN_WRITE_MASK_SHIFT 24 +#define RADEON_PLANE_3D_MASK_C 0x1d44 +#define RADEON_TEX_CACHE_STAT_COUNT 0x1974 + + + /* Constants */ +#define RADEON_AGP_TEX_OFFSET 0x02000000 + +#define RADEON_VB_AGE_REG RADEON_GUI_SCRATCH_REG0 +#define RADEON_SWAP_AGE_REG RADEON_GUI_SCRATCH_REG1 + + /* CCE packet types */ +#define RADEON_CCE_PACKET0 0x00000000 +#define RADEON_CCE_PACKET0_ONE_REG_WR 0x00008000 +#define RADEON_CCE_PACKET1 0x40000000 +#define RADEON_CCE_PACKET2 0x80000000 +#define RADEON_CCE_PACKET3_NOP 0xC0001000 +#define RADEON_CCE_PACKET3_PAINT 0xC0001100 +#define RADEON_CCE_PACKET3_BITBLT 0xC0001200 +#define RADEON_CCE_PACKET3_SMALLTEXT 0xC0001300 +#define RADEON_CCE_PACKET3_HOSTDATA_BLT 0xC0001400 +#define RADEON_CCE_PACKET3_POLYLINE 0xC0001500 +#define RADEON_CCE_PACKET3_SCALING 0xC0001600 +#define RADEON_CCE_PACKET3_TRANS_SCALING 0xC0001700 +#define RADEON_CCE_PACKET3_POLYSCANLINES 0xC0001800 +#define RADEON_CCE_PACKET3_NEXT_CHAR 0xC0001900 +#define RADEON_CCE_PACKET3_PAINT_MULTI 0xC0001A00 +#define RADEON_CCE_PACKET3_BITBLT_MULTI 0xC0001B00 +#define RADEON_CCE_PACKET3_PLY_NEXTSCAN 0xC0001D00 +#define RADEON_CCE_PACKET3_SET_SCISSORS 0xC0001E00 +#define RADEON_CCE_PACKET3_SET_MODE24BPP 0xC0001F00 +#define RADEON_CCE_PACKET3_CNTL_PAINT 0xC0009100 +#define RADEON_CCE_PACKET3_CNTL_BITBLT 0xC0009200 +#define RADEON_CCE_PACKET3_CNTL_SMALLTEXT 0xC0009300 +#define RADEON_CCE_PACKET3_CNTL_HOSTDATA_BLT 0xC0009400 +#define RADEON_CCE_PACKET3_CNTL_POLYLINE 0xC0009500 +#define RADEON_CCE_PACKET3_CNTL_SCALING 0xC0009600 +#define RADEON_CCE_PACKET3_CNTL_TRANS_SCALING 0xC0009700 +#define RADEON_CCE_PACKET3_CNTL_POLYSCANLINES 0xC0009800 +#define RADEON_CCE_PACKET3_CNTL_NEXT_CHAR 0xC0009900 +#define RADEON_CCE_PACKET3_CNTL_PAINT_MULTI 0xC0009A00 +#define RADEON_CCE_PACKET3_CNTL_BITBLT_MULTI 0xC0009B00 +#define RADEON_CCE_PACKET3_CNTL_TRANS_BITBLT 0xC0009C00 +#define RADEON_CCE_PACKET3_3D_SAVE_CONTEXT 0xC0002000 +#define RADEON_CCE_PACKET3_3D_PLAY_CONTEXT 0xC0002100 +#define RADEON_CCE_PACKET3_3D_RNDR_GEN_INDX_PRIM 0xC0002300 +#define RADEON_CCE_PACKET3_3D_RNDR_GEN_PRIM 0xC0002500 +#define RADEON_CCE_PACKET3_LOAD_PALETTE 0xC0002C00 +#define RADEON_CCE_PACKET3_PURGE 0xC0002D00 +#define RADEON_CCE_PACKET3_NEXT_VERTEX_BUNDLE 0xC0002E00 +# define RADEON_CCE_PACKET_MASK 0xC0000000 +# define RADEON_CCE_PACKET_COUNT_MASK 0x3fff0000 +# define RADEON_CCE_PACKET_MAX_DWORDS (1 << 14) +# define RADEON_CCE_PACKET0_REG_MASK 0x000007ff +# define RADEON_CCE_PACKET1_REG0_MASK 0x000007ff +# define RADEON_CCE_PACKET1_REG1_MASK 0x003ff800 + +#define RADEON_CCE_VC_FRMT_RHW 0x00000001 +#define RADEON_CCE_VC_FRMT_DIFFUSE_BGR 0x00000002 +#define RADEON_CCE_VC_FRMT_DIFFUSE_A 0x00000004 +#define RADEON_CCE_VC_FRMT_DIFFUSE_ARGB 0x00000008 +#define RADEON_CCE_VC_FRMT_SPEC_BGR 0x00000010 +#define RADEON_CCE_VC_FRMT_SPEC_F 0x00000020 +#define RADEON_CCE_VC_FRMT_SPEC_FRGB 0x00000040 +#define RADEON_CCE_VC_FRMT_S_T 0x00000080 +#define RADEON_CCE_VC_FRMT_S2_T2 0x00000100 +#define RADEON_CCE_VC_FRMT_RHW2 0x00000200 + +#define RADEON_CCE_VC_CNTL_PRIM_TYPE_NONE 0x00000000 +#define RADEON_CCE_VC_CNTL_PRIM_TYPE_POINT 0x00000001 +#define RADEON_CCE_VC_CNTL_PRIM_TYPE_LINE 0x00000002 +#define RADEON_CCE_VC_CNTL_PRIM_TYPE_POLY_LINE 0x00000003 +#define RADEON_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST 0x00000004 +#define RADEON_CCE_VC_CNTL_PRIM_TYPE_TRI_FAN 0x00000005 +#define RADEON_CCE_VC_CNTL_PRIM_TYPE_TRI_STRIP 0x00000006 +#define RADEON_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2 0x00000007 +#define RADEON_CCE_VC_CNTL_PRIM_WALK_IND 0x00000010 +#define RADEON_CCE_VC_CNTL_PRIM_WALK_LIST 0x00000020 +#define RADEON_CCE_VC_CNTL_PRIM_WALK_RING 0x00000030 +#define RADEON_CCE_VC_CNTL_NUM_SHIFT 16 + +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_version.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_version.h new file mode 100644 index 000000000..e06aead72 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_version.h @@ -0,0 +1,41 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_version.h,v 1.1 2000/11/02 16:55:46 tsi Exp $ */ +/* + * Copyright 2000 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of Marc Aurele La France not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Marc Aurele La France makes no representations + * about the suitability of this software for any purpose. It is provided + * "as-is" without express or implied warranty. + * + * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO + * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _RADEON_VERSION_H_ +#define _RADEON_VERSION_H_ 1 + +#define RADEON_NAME "RADEON" +#define RADEON_DRIVER_NAME "radeon" + +#define RADEON_VERSION_NAME "4.0.1" + +#define RADEON_VERSION_MAJOR 4 +#define RADEON_VERSION_MINOR 0 +#define RADEON_VERSION_PATCH 1 + +#define RADEON_VERSION_CURRENT \ + ((RADEON_VERSION_MAJOR << 20) | \ + (RADEON_VERSION_MINOR << 10) | \ + (RADEON_VERSION_PATCH)) + +#endif /* _RADEON_VERSION_H_ */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_video.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_video.c new file mode 100644 index 000000000..8f629fd73 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_video.c @@ -0,0 +1,798 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_video.c,v 1.1 2000/11/02 16:55:47 tsi Exp $ */ +/* + * Copyright 2000 Stuart R. Anderson and Metro Link, Inc. + * + * 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 on + * 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, PRECISION INSIGHT AND/OR THEIR 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: + * Stuart R. Anderson <anderson@metrolink.com> + * + * Credits: + * + * This code is derived primarily from the GATOS Project run by Stea Greene. + * The initial version of this code was done by Vladimir Dergacheb. + * + * This code was simplified from the GATOS code primarily because I didn't + * have the right hardware handy to test anything beyond simple overlays, + * and because I wanted to complete it in a short time frame that I had + * available. + * + * My apologies to Vladimir as there is more good work in his code that + * should be brought forward. + * + * RADEON ALERT ! + * This is an extremely quick port to the Radeon, it hasn't been tested + * thoroughly, although it appears to work. + */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "xf86_ansic.h" +#include "compiler.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "xf86fbman.h" +#include "regionstr.h" + +#include "xf86xv.h" +#include "xf86Cursor.h" +#include "Xv.h" +#include "xaalocal.h" +#include "dixstruct.h" +#include "fourcc.h" + +#include "radeon.h" +#include "radeon_reg.h" + +/* + * For Debug +#define OUTREG(addr, val) { xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"OUTREG(%s,%x)\n",#addr,val) ;MMIO_OUT32(RADEONMMIO, addr, val);} +*/ + +#define OFF_DELAY 250 /* milliseconds */ +#define FREE_DELAY 15000 + +#define OFF_TIMER 0x01 +#define FREE_TIMER 0x02 +#define CLIENT_VIDEO_ON 0x04 + +#define TIMER_MASK (OFF_TIMER | FREE_TIMER) + +#ifndef XvExtension +void RADEONInitVideo(ScreenPtr pScreen) {} +#else +static XF86VideoAdaptorPtr RADEONSetupImageVideo(ScreenPtr); +static int RADEONSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); +static int RADEONGetPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer); + +static void RADEONStopVideo(ScrnInfoPtr, pointer, Bool); +static void RADEONQueryBestSize(ScrnInfoPtr, Bool, + short, short, short, short, unsigned int *, unsigned int *, pointer); +static int RADEONPutImage( ScrnInfoPtr, + short, short, short, short, short, short, short, short, + int, unsigned char*, short, short, Bool, RegionPtr, pointer); +static int RADEONQueryImageAttributes(ScrnInfoPtr, + int, unsigned short *, unsigned short *, int *, int *); + +#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) + +#define IMAGE_MAX_WIDTH 2048 +#define IMAGE_MAX_HEIGHT 2048 +#define Y_BUF_SIZE (IMAGE_MAX_WIDTH * IMAGE_MAX_HEIGHT) + +static Atom xvColorKey; + +typedef struct { + int videoStatus; + unsigned char brightness; + unsigned char contrast; + + RegionRec clip; + CARD32 colorKey; + CARD8 overlay_pixel_size; + CARD8 current_buffer; + int overlay_pad; + CARD32 overlay_id; + CARD32 overlay_width; + + CARD32 scale_cntl; + CARD32 video_format; + FBLinearPtr linear; + } RADEONPortPrivRec, *RADEONPortPrivPtr; + +void RADEONInitVideo(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; + XF86VideoAdaptorPtr newAdaptor = NULL; + int num_adaptors; + + RADEONTRACE(("RADEONInitVideo called\n")); + + /* Determine if the card supports this */ + if (pScrn->bitsPerPixel != 8) + { + newAdaptor = RADEONSetupImageVideo(pScreen); + } + + num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); + + if(newAdaptor) { + if(!num_adaptors) { + num_adaptors = 1; + adaptors = &newAdaptor; + } else { + newAdaptors = /* need to free this someplace */ + xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr*)); + if(newAdaptors) { + memcpy(newAdaptors, adaptors, num_adaptors * + sizeof(XF86VideoAdaptorPtr)); + newAdaptors[num_adaptors] = newAdaptor; + adaptors = newAdaptors; + num_adaptors++; + } + } + } + + if(num_adaptors) + xf86XVScreenInit(pScreen, adaptors, num_adaptors); + + if(newAdaptors) + xfree(newAdaptors); +} + +/* client libraries expect an encoding */ +static XF86VideoEncodingRec DummyEncoding[1] = +{ + { + 0, + "XV_IMAGE", + IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT, + {1, 1} + } +}; + +#define NUM_FORMATS 3 + +static XF86VideoFormatRec Formats[NUM_FORMATS] = +{ + {15, TrueColor}, + {16, TrueColor}, + {32, TrueColor} +}; + +#define NUM_ATTRIBUTES 1 + +static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = +{ + {XvSettable | XvGettable, 0, (1<<24)-1, "XV_COLORKEY"}, +}; + +#define NUM_IMAGES 3 + +static XF86ImageRec Images[NUM_IMAGES] = +{ + XVIMAGE_YUY2, + XVIMAGE_YV12, + XVIMAGE_UYVY +}; + +static void +RADEONResetVideo(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + RADEONPortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr; + + RADEONTRACE(("RADEONResetVideo called\n")); + + /* Initialize some of the HW here */ + OUTREG(RADEON_OV0_EXCLUSIVE_HORZ,0); /* disable exclusive mode */ + OUTREG(RADEON_OV0_VIDEO_KEY_MSK,0xffff); + OUTREG(RADEON_OV0_KEY_CNTL, RADEON_GRAPHIC_KEY_FN_NE); + OUTREG(RADEON_OV0_GRAPHICS_KEY_CLR,pPriv->colorKey); + /* Only using one buffer for now + OUTREG(RADEON_OV0_AUTO_FLIP_CNTL,pAPriv->Port[0].auto_flip_cntl); + */ + switch(pScrn->depth){ + case 8: + OUTREG(RADEON_OV0_GRAPHICS_KEY_MSK,0xff); + break; + case 15: + OUTREG(RADEON_OV0_GRAPHICS_KEY_MSK,0x7fff); + break; + case 16: + OUTREG(RADEON_OV0_GRAPHICS_KEY_MSK,0xffff); + break; + case 24: + OUTREG(RADEON_OV0_GRAPHICS_KEY_MSK,0xffffff); + break; + case 32: + OUTREG(RADEON_OV0_GRAPHICS_KEY_MSK,0xffffffff); + break; + } + + OUTREG(RADEON_OV0_REG_LOAD_CNTL,0x0); + OUTREG(RADEON_OV0_DEINTERLACE_PATTERN,0xAAAAA); + OUTREG(RADEON_OV0_P1_V_ACCUM_INIT,(2<<20)|1); + OUTREG(RADEON_OV0_P23_V_ACCUM_INIT,(2<<20)|1); + OUTREG(RADEON_OV0_P1_H_ACCUM_INIT,(3<<28)); + OUTREG(RADEON_OV0_P23_H_ACCUM_INIT,(2<<28)); + OUTREG(RADEON_OV0_STEP_BY,1|(1<<8)); + OUTREG(RADEON_OV0_FILTER_CNTL,0xf); /* use hardcoded coeff's */ + OUTREG(RADEON_OV0_FILTER_CNTL,0x0); /* use programmable coeff's */ + OUTREG(RADEON_OV0_FOUR_TAP_COEF_0 , 0x00002000); + OUTREG(RADEON_OV0_FOUR_TAP_COEF_1 , 0x0D06200D); + OUTREG(RADEON_OV0_FOUR_TAP_COEF_2 , 0x0D0A1C0D); + OUTREG(RADEON_OV0_FOUR_TAP_COEF_3 , 0x0C0E1A0C); + OUTREG(RADEON_OV0_FOUR_TAP_COEF_4 , 0x0C14140C); + OUTREG(RADEON_OV0_COLOUR_CNTL,(1<<12)|(1<<20)); + OUTREG(RADEON_OV0_TEST,0); + OUTREG(RADEON_OV0_SCALE_CNTL,pPriv->scale_cntl|pPriv->video_format); + OUTREG(RADEON_CAP0_TRIG_CNTL,0); +} + +static XF86VideoAdaptorPtr +RADEONSetupImageVideo(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + XF86VideoAdaptorPtr adapt; + RADEONPortPrivPtr pPriv; + + RADEONTRACE(("RADEONSetupImageVideo called\n")); + + if(!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) + + sizeof(RADEONPortPrivRec) + + sizeof(DevUnion)))) + return NULL; + + adapt->type = XvWindowMask | XvInputMask | XvImageMask; + adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; + adapt->name = "RADEON Video Overlay"; + adapt->nEncodings = 1; + adapt->pEncodings = DummyEncoding; + adapt->nFormats = NUM_FORMATS; + adapt->pFormats = Formats; + adapt->nPorts = 1; + adapt->pPortPrivates = (DevUnion*)(&adapt[1]); + + pPriv = (RADEONPortPrivPtr)(&adapt->pPortPrivates[1]); + + adapt->pPortPrivates[0].ptr = (pointer)(pPriv); + adapt->pAttributes = Attributes; + adapt->nImages = NUM_IMAGES; + adapt->nAttributes = NUM_ATTRIBUTES; + adapt->pImages = Images; + adapt->PutVideo = NULL; + adapt->PutStill = NULL; + adapt->GetVideo = NULL; + adapt->GetStill = NULL; + adapt->StopVideo = RADEONStopVideo; + adapt->SetPortAttribute = RADEONSetPortAttribute; + adapt->GetPortAttribute = RADEONGetPortAttribute; + adapt->QueryBestSize = RADEONQueryBestSize; + adapt->PutImage = RADEONPutImage; + adapt->QueryImageAttributes = RADEONQueryImageAttributes; + + /* gotta uninit this someplace */ + REGION_INIT(pScreen, &pPriv->clip, NullBox, 0); + + info->adaptor = adapt; + + pPriv->colorKey = 0x01; /* a touch of blue */ + pPriv->video_format = RADEON_SCALER_SOURCE_VYUY422; + pPriv->scale_cntl = RADEON_SCALER_PRG_LOAD_START|RADEON_SCALER_DOUBLE_BUFFER; + pPriv->scale_cntl|= RADEON_SCALER_SMART_SWITCH|RADEON_SCALER_PIX_EXPAND; + pPriv->scale_cntl|= RADEON_SCALER_SMART_SWITCH; + + xvColorKey = MAKE_ATOM("XV_COLORKEY"); + + RADEONResetVideo(pScrn); + + 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; +} + +static void +RADEONStopVideo(ScrnInfoPtr pScrn, pointer data, Bool Exit) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr) data; + + RADEONTRACE(("RADEONStopVideo called\n")); + + REGION_EMPTY(pScrn->pScreen, &pPriv->clip); + + if (Exit) { + if(pPriv->videoStatus & CLIENT_VIDEO_ON) { + OUTREG(RADEON_OV0_SCALE_CNTL,pPriv->scale_cntl|pPriv->video_format); + } + if(pPriv->linear) { + xf86FreeOffscreenLinear(pPriv->linear); + pPriv->linear = NULL; + } + pPriv->videoStatus = 0; + } else { + if(pPriv->videoStatus & CLIENT_VIDEO_ON) { + } + } +} + +static int +RADEONSetPortAttribute( + ScrnInfoPtr pScrn, + Atom attribute, + INT32 value, + pointer data +) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr) data; + + RADEONTRACE(("RADEONSetPortAttribute called\n")); + + if (attribute == xvColorKey) { + pPriv->colorKey = value; + OUTREG(RADEON_OV0_GRAPHICS_KEY_CLR,pPriv->colorKey); + RADEONTRACE(("Setting ColorKey to %d\n", pPriv->colorKey)); + return Success; + } + + return Success; +} + +static int +RADEONGetPortAttribute( + ScrnInfoPtr pScrn, + Atom attribute, + INT32 *value, + pointer data +) +{ + RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr) data; + + RADEONTRACE(("RADEONGetPortAttribute called\n")); + + if (attribute == xvColorKey) { + RADEONTRACE(("Getting ColorKey %d\n", pPriv->colorKey)); + *value = pPriv->colorKey; + return Success; + } + + return Success; +} + +static void +RADEONQueryBestSize( + ScrnInfoPtr pScrn, + Bool motion, + short vid_w, short vid_h, + short drw_w, short drw_h, + unsigned int *p_w, unsigned int *p_h, + pointer data +) +{ + RADEONTRACE(("RADEONQueryBestSize called\n")); + *p_w = drw_w; + *p_h = drw_h; +} + +static void +RADEONDisplayVideo( + ScrnInfoPtr pScrn, + short width, short height, + int xa, int ya, int xb, int yb, + short src_w, short src_h, + short drw_w, short drw_h, + int fboffset +) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + RADEONPortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr; + int step_by, vert_inc, horz_inc; + + RADEONTRACE(("RADEONDisplayVideo called\n")); + + /* calculate step_by factor */ + step_by=src_w/(drw_w*2); + switch(step_by){ + case 0: + OUTREG(RADEON_OV0_STEP_BY,0x101); + step_by=1; + break; + case 1: + OUTREG(RADEON_OV0_STEP_BY,0x202); + step_by=2; + break; + case 2: + case 3: + OUTREG(RADEON_OV0_STEP_BY,0x303); + step_by=4; + break; + default: + OUTREG(RADEON_OV0_STEP_BY,0x404); + step_by=8; + break; + } + + vert_inc=(src_h<<12)/(drw_h); + horz_inc=(src_w<<12)/(drw_w*step_by); + + OUTREG(RADEON_OV0_Y_X_START,((xa))|(ya<<16)|(1<<31)); + OUTREG(RADEON_OV0_Y_X_END,((xb))|((yb)<<16)); + OUTREG(RADEON_OV0_H_INC,(horz_inc)|((horz_inc<<15))); + OUTREG(RADEON_OV0_V_INC,(vert_inc<<8)); + OUTREG(RADEON_OV0_P1_BLANK_LINES_AT_TOP,0xfff|((src_h-1)<<16)); + OUTREG(RADEON_OV0_P23_BLANK_LINES_AT_TOP,0xfff|((src_h-1)<<16)); + OUTREG(RADEON_OV0_VID_BUF_PITCH0_VALUE,width<<1); + OUTREG(RADEON_OV0_VID_BUF_PITCH1_VALUE,width<<1); + OUTREG(RADEON_OV0_P1_X_START_END,(src_w-1)|((xa&0xf)<<16)); + OUTREG(RADEON_OV0_P2_X_START_END,(src_w-1)|((xa&0xf)<<16)); + OUTREG(RADEON_OV0_P3_X_START_END,(src_w-1)|((xa&0xf)<<16)); + + OUTREG(RADEON_OV0_VID_BUF0_BASE_ADRS,(fboffset)&(~0xf)); + OUTREG(RADEON_OV0_VID_BUF1_BASE_ADRS,(fboffset)&(~0xf)); + OUTREG(RADEON_OV0_VID_BUF2_BASE_ADRS,(fboffset)&(~0xf)); + +#if 0 + /* Enable this when double buffering is implemented */ + OUTREG(RADEON_OV0_VID_BUF3_BASE_ADRS,(fboffset2)&(~0xf)); + OUTREG(RADEON_OV0_VID_BUF4_BASE_ADRS,(fboffset2)&(~0xf)); + OUTREG(RADEON_OV0_VID_BUF5_BASE_ADRS,(fboffset2)&(~0xf)); +#endif + + OUTREG(RADEON_OV0_SCALE_CNTL,pPriv->scale_cntl|RADEON_SCALER_ENABLE|pPriv->video_format); +} + +static void +RADEONCopyData( + unsigned char *src, + unsigned char *dst, + int srcPitch, + int dstPitch, + int h, + int w + ) +{ + w <<= 1; + while(h--) { + memcpy(dst, src, w); + src += srcPitch; + dst += dstPitch; + } +} + +static void +RADEONCopyMungedData( + unsigned char *src1, + unsigned char *src2, + unsigned char *src3, + unsigned char *dst1, + int srcPitch, + int srcPitch2, + int dstPitch, + int h, + int w + ) +{ + CARD32 *dst = (CARD32*)dst1; + int i, j; + + dstPitch >>= 2; + w >>= 1; + + for(j = 0; j < h; j++) { + for(i = 0; i < w; i++) { + dst[i] = src1[i << 1] | (src1[(i << 1) + 1] << 16) | + (src3[i] << 8) | (src2[i] << 24); + } + dst += dstPitch; + src1 += srcPitch; + if(j & 1) { + src2 += srcPitch2; + src3 += srcPitch2; + } + } +} + +static FBLinearPtr +RADEONAllocateMemory( + ScrnInfoPtr pScrn, + FBLinearPtr linear, + int size +) +{ + ScreenPtr pScreen; + FBLinearPtr new_linear; + + RADEONTRACE(("RADEONAllocateMemory(%x,%d) called\n",linear,size)); + + if(linear) { + if(linear->size >= size) + return linear; + + if(xf86ResizeOffscreenLinear(linear, size)) + return linear; + + xf86FreeOffscreenLinear(linear); + } + + pScreen = screenInfo.screens[pScrn->scrnIndex]; + + new_linear = xf86AllocateOffscreenLinear(pScreen, size, 4, + NULL, NULL, NULL); + + if(!new_linear) { + int max_size; + + xf86QueryLargestOffscreenLinear(pScreen, &max_size, 4, + PRIORITY_EXTREME); + + if(max_size < size) return NULL; + + xf86PurgeUnlockedOffscreenAreas(pScreen); + new_linear = xf86AllocateOffscreenLinear(pScreen, size, 4, + NULL, NULL, NULL); + } + + RADEONTRACE(("returning %x(%x)\n",new_linear,new_linear->offset)); + + return new_linear; +} + +static int +RADEONPutImage( + ScrnInfoPtr pScrn, + short src_x, short src_y, + short drw_x, short drw_y, + short src_w, short src_h, + short drw_w, short drw_h, + int id, unsigned char* buf, + short width, short height, + Bool Sync, + RegionPtr clipBoxes, pointer data +) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data; + INT32 xa, xb, ya, yb; + INT32 d_x,d_y,d_width,d_height; + int srcPitch = 0, srcPitch2 = 0; + int dstPitch = 0; + int offset,offset2 = 0,offset3 = 0,fboffset; + int top, left, npixels, nlines, size; + CARD32 video_format; + + RADEONTRACE(("RADEONPutImage called\n")); + + switch(id) { + case FOURCC_YV12: + case FOURCC_UYVY: + video_format=RADEON_SCALER_SOURCE_VYUY422; + break; + case FOURCC_YUY2: + video_format=RADEON_SCALER_SOURCE_YVYU422; + break; + default: + return BadValue; + } + + /* Clip */ + d_x=drw_x; + d_y=drw_y; + d_width=drw_w; + d_height=drw_h; + if(drw_x<0){ + drw_w+=drw_x; + drw_x=0; + } + if(drw_y<0){ + drw_h+=drw_y; + drw_y=0; + } + if(drw_x+drw_w>pScrn->pScreen->width){ + drw_w=pScrn->pScreen->width-drw_x; + } + if(drw_y+drw_h>pScrn->pScreen->height){ + drw_h=pScrn->pScreen->height-drw_y; + } + if((drw_w<=0)||(drw_h<=0)){ + /* this should not happen, + since we are outside of visible screen, + but just in case */ + return Success; + } + + xa = src_x; + xb = src_x + src_w; + ya = src_y; + yb = src_y + src_h; + + dstPitch = width*info->CurrentLayout.pixel_bytes; + srcPitch=width; + + switch(id) { + case FOURCC_YV12: + size = width * height * 2; /* 16bpp */ + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + default: + size = width * height * 1.5; + break; + } + + if(!(pPriv->linear = RADEONAllocateMemory(pScrn, pPriv->linear,size))) + return BadAlloc; + + /* copy data */ + top = ya >> 16; + left = (xa >> 16) & ~1; + npixels = ((((xb + 0xffff) >> 16) + 1) & ~1) - left; + + switch(id) { + case FOURCC_YV12: + srcPitch = (width + 3) & ~3; + offset2 = srcPitch * height; + srcPitch2 = ((width >> 1) + 3) & ~3; + offset3 = (srcPitch2 * (height >> 1)) + offset2; + nlines = ((((yb + 0xffff) >> 16) + 1) & ~1) - top; + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + default: + buf += (top * srcPitch) + left; + nlines = ((yb + 0xffff) >> 16) - top; + srcPitch = (width << 1); + break; + } + nlines=src_h; + npixels=src_w; + if(npixels>width) npixels=width; + if(nlines>height) nlines=height; + + /* adjust source rectangle */ + src_x+=((drw_x-d_x)*src_w)/d_width; + src_y+=((drw_y-d_y)*src_h)/d_height; + + src_w=(src_w * drw_w)/d_width; + src_h=(src_h * drw_h)/d_height; + + offset=(src_x+src_y*width)*info->CurrentLayout.pixel_bytes; + fboffset=pPriv->linear->offset*info->CurrentLayout.pixel_bytes; + + if(!(INREG(RADEON_CRTC_STATUS)&2)){ + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"too fast"); + return Success; + } + + RADEONDisplayVideo(pScrn, width, height, + drw_x, drw_y, drw_x+drw_w, drw_y+drw_h, + src_w, src_h, drw_w, drw_h, fboffset); + + /* update cliplist */ + if(!RegionsEqual(&pPriv->clip, clipBoxes)) { + REGION_COPY(pScreen, &pPriv->clip, clipBoxes); + /* draw these */ + XAAFillSolidRects(pScrn, pPriv->colorKey, GXcopy, ~0, + REGION_NUM_RECTS(clipBoxes), + REGION_RECTS(clipBoxes)); + } + + + switch(id) { + case FOURCC_YV12: + RADEONCopyMungedData(buf + (top * srcPitch) + (left >> 1), + buf + offset2, buf + offset3, info->FB+fboffset, + srcPitch, srcPitch2, dstPitch, nlines, npixels); + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + default: + RADEONCopyData(buf,info->FB+fboffset,srcPitch,dstPitch, + nlines,npixels); + break; + } + + pPriv->videoStatus = CLIENT_VIDEO_ON; + return Success; +} + +static int +RADEONQueryImageAttributes( + ScrnInfoPtr pScrn, + int id, + unsigned short *w, unsigned short *h, + int *pitches, int *offsets +) +{ + int size, tmp; + RADEONTRACE(("RADEONQueryImageAtrributes called\n")); + + if(*w > IMAGE_MAX_WIDTH) *w = IMAGE_MAX_WIDTH; + if(*h > IMAGE_MAX_HEIGHT) *h = IMAGE_MAX_HEIGHT; + + *w = (*w + 1) & ~1; + if(offsets) offsets[0] = 0; + + switch(id) { + case FOURCC_YV12: + *h = (*h + 1) & ~1; + size = (*w + 3) & ~3; + if(pitches) pitches[0] = size; + size *= *h; + if(offsets) offsets[1] = size; + tmp = ((*w >> 1) + 3) & ~3; + if(pitches) pitches[1] = pitches[2] = tmp; + tmp *= (*h >> 1); + size += tmp; + if(offsets) offsets[2] = size; + size += tmp; + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + default: + size = *w << 1; + if(pitches) pitches[0] = size; + size *= *h; + break; + } + + return size; +} +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_shadow.c b/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_shadow.c new file mode 100644 index 000000000..a6defb300 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_shadow.c @@ -0,0 +1,258 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_shadow.c,v 1.1 2000/11/03 18:46:14 eich Exp $ */ + +/* + Copyright (c) 1999, 2000 The XFree86 Project Inc. + based on code written by Mark Vojkovich <markv@valinux.com> +*/ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "xf86_ansic.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "shadowfb.h" +#include "servermd.h" +#include "trident.h" + +void +TRIDENTRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int width, height, Bpp, FBPitch; + unsigned char *src, *dst; + + Bpp = pScrn->bitsPerPixel >> 3; + FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel); + + while(num--) { + width = (pbox->x2 - pbox->x1) * Bpp; + height = pbox->y2 - pbox->y1; + src = pTrident->ShadowPtr + (pbox->y1 * pTrident->ShadowPitch) + + (pbox->x1 * Bpp); + dst = pTrident->FbBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp); + + while(height--) { + memcpy(dst, src, width); + dst += FBPitch; + src += pTrident->ShadowPitch; + } + + pbox++; + } +} + +void +TRIDENTShadowUpdate (ScreenPtr pScreen, PixmapPtr pShadow, RegionPtr damage) +{ + ScrnInfoPtr pScrn; + pScrn = xf86Screens[pScreen->myNum]; + + (TRIDENTPTR(pScrn))->RefreshArea (pScrn, REGION_NUM_RECTS(damage), + REGION_RECTS(damage)); +} + +void +TRIDENTPointerMoved(int index, int x, int y) +{ + ScrnInfoPtr pScrn = xf86Screens[index]; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int newX, newY; + + if(pTrident->Rotate == 1) { + newX = pScrn->pScreen->height - y - 1; + newY = x; + } else { + newX = y; + newY = pScrn->pScreen->width - x - 1; + } + + (*pTrident->PointerMoved)(index, newX, newY); +} + +void +TRIDENTRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int count, width, height, y1, y2, dstPitch, srcPitch; + CARD8 *dstPtr, *srcPtr, *src; + CARD32 *dst; + + dstPitch = pScrn->displayWidth; + srcPitch = -pTrident->Rotate * pTrident->ShadowPitch; + + while(num--) { + width = pbox->x2 - pbox->x1; + y1 = pbox->y1 & ~3; + y2 = (pbox->y2 + 3) & ~3; + height = (y2 - y1) >> 2; /* in dwords */ + + if(pTrident->Rotate == 1) { + dstPtr = pTrident->FbBase + + (pbox->x1 * dstPitch) + pScrn->virtualX - y2; + srcPtr = pTrident->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1; + } else { + dstPtr = pTrident->FbBase + + ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; + srcPtr = pTrident->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1; + } + + while(width--) { + src = srcPtr; + dst = (CARD32*)dstPtr; + count = height; + while(count--) { + *(dst++) = src[0] | (src[srcPitch] << 8) | + (src[srcPitch * 2] << 16) | + (src[srcPitch * 3] << 24); + src += srcPitch * 4; + } + srcPtr += pTrident->Rotate; + dstPtr += dstPitch; + } + + pbox++; + } +} + + +void +TRIDENTRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int count, width, height, y1, y2, dstPitch, srcPitch; + CARD16 *dstPtr, *srcPtr, *src; + CARD32 *dst; + + dstPitch = pScrn->displayWidth; + srcPitch = -pTrident->Rotate * pTrident->ShadowPitch >> 1; + + while(num--) { + width = pbox->x2 - pbox->x1; + y1 = pbox->y1 & ~1; + y2 = (pbox->y2 + 1) & ~1; + height = (y2 - y1) >> 1; /* in dwords */ + + if(pTrident->Rotate == 1) { + dstPtr = (CARD16*)pTrident->FbBase + + (pbox->x1 * dstPitch) + pScrn->virtualX - y2; + srcPtr = (CARD16*)pTrident->ShadowPtr + + ((1 - y2) * srcPitch) + pbox->x1; + } else { + dstPtr = (CARD16*)pTrident->FbBase + + ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; + srcPtr = (CARD16*)pTrident->ShadowPtr + + (y1 * srcPitch) + pbox->x2 - 1; + } + + while(width--) { + src = srcPtr; + dst = (CARD32*)dstPtr; + count = height; + while(count--) { + *(dst++) = src[0] | (src[srcPitch] << 16); + src += srcPitch * 2; + } + srcPtr += pTrident->Rotate; + dstPtr += dstPitch; + } + + pbox++; + } +} + + +/* this one could be faster */ +void +TRIDENTRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int count, width, height, y1, y2, dstPitch, srcPitch; + CARD8 *dstPtr, *srcPtr, *src; + CARD32 *dst; + + dstPitch = BitmapBytePad(pScrn->displayWidth * 24); + srcPitch = -pTrident->Rotate * pTrident->ShadowPitch; + + while(num--) { + width = pbox->x2 - pbox->x1; + y1 = pbox->y1 & ~3; + y2 = (pbox->y2 + 3) & ~3; + height = (y2 - y1) >> 2; /* blocks of 3 dwords */ + + if(pTrident->Rotate == 1) { + dstPtr = pTrident->FbBase + + (pbox->x1 * dstPitch) + ((pScrn->virtualX - y2) * 3); + srcPtr = pTrident->ShadowPtr + ((1 - y2) * srcPitch) + (pbox->x1 * 3); + } else { + dstPtr = pTrident->FbBase + + ((pScrn->virtualY - pbox->x2) * dstPitch) + (y1 * 3); + srcPtr = pTrident->ShadowPtr + (y1 * srcPitch) + (pbox->x2 * 3) - 3; + } + + while(width--) { + src = srcPtr; + dst = (CARD32*)dstPtr; + count = height; + while(count--) { + dst[0] = src[0] | (src[1] << 8) | (src[2] << 16) | + (src[srcPitch] << 24); + dst[1] = src[srcPitch + 1] | (src[srcPitch + 2] << 8) | + (src[srcPitch * 2] << 16) | + (src[(srcPitch * 2) + 1] << 24); + dst[2] = src[(srcPitch * 2) + 2] | (src[srcPitch * 3] << 8) | + (src[(srcPitch * 3) + 1] << 16) | + (src[(srcPitch * 3) + 2] << 24); + dst += 3; + src += srcPitch * 4; + } + srcPtr += pTrident->Rotate * 3; + dstPtr += dstPitch; + } + + pbox++; + } +} + +void +TRIDENTRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int count, width, height, dstPitch, srcPitch; + CARD32 *dstPtr, *srcPtr, *src, *dst; + + dstPitch = pScrn->displayWidth; + srcPitch = -pTrident->Rotate * pTrident->ShadowPitch >> 2; + + while(num--) { + width = pbox->x2 - pbox->x1; + height = pbox->y2 - pbox->y1; + + if(pTrident->Rotate == 1) { + dstPtr = (CARD32*)pTrident->FbBase + + (pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2; + srcPtr = (CARD32*)pTrident->ShadowPtr + + ((1 - pbox->y2) * srcPitch) + pbox->x1; + } else { + dstPtr = (CARD32*)pTrident->FbBase + + ((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1; + srcPtr = (CARD32*)pTrident->ShadowPtr + + (pbox->y1 * srcPitch) + pbox->x2 - 1; + } + + while(width--) { + src = srcPtr; + dst = dstPtr; + count = height; + while(count--) { + *(dst++) = *src; + src += srcPitch; + } + srcPtr += pTrident->Rotate; + dstPtr += dstPitch; + } + + pbox++; + } +} + diff --git a/xc/programs/Xserver/hw/xfree86/input/citron/Imakefile b/xc/programs/Xserver/hw/xfree86/input/citron/Imakefile new file mode 100644 index 000000000..6e0fcc6e9 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/input/citron/Imakefile @@ -0,0 +1,31 @@ +XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/input/citron/Imakefile,v 1.1 2000/11/02 02:51:20 dawes Exp $ + +#define IHaveModules +#include <Server.tmpl> + +SRCS = citron.c +OBJS = citron.o + +DRIVER = citron + +INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86SRC)/loader -I$(XF86OSSRC) \ + -I$(SERVERSRC)/include -I$(SERVERSRC)/mi -I$(XINCLUDESRC) -I$(EXTINCSRC) + +#if MakeHasPosixVariableSubstitutions +SubdirLibraryRule($(OBJS)) +#endif + +ModuleObjectRule() + +ObjectModuleTarget($(DRIVER),$(OBJS)) + +InstallObjectModule($(DRIVER),$(MODULEDIR),input) + +#if !defined(XF86DriverSDK) +CppManTarget($(DRIVER),) +InstallModuleManPage($(DRIVER)) +#endif + +DependTarget() + +InstallDriverSDKObjectModule($(DRIVER),$(DRIVERSDKMODULEDIR),input) diff --git a/xc/programs/Xserver/hw/xfree86/input/citron/citron.c b/xc/programs/Xserver/hw/xfree86/input/citron/citron.c new file mode 100644 index 000000000..517c87500 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/input/citron/citron.c @@ -0,0 +1,2421 @@ +/* + * Copyright (c) 1998 Metro Link Incorporated + * + * 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, cpy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE X CONSORTIUM 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. + * + * Except as contained in this notice, the name of the Metro Link shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Metro Link. + * + */ + +/* $XFree86: xc/programs/Xserver/hw/xfree86/input/citron/citron.c,v 1.4 2000/11/03 13:13:31 tsi Exp $ */ + +/* + * Based, in part, on code with the following copyright notice: + * + * Copyright 1999-2000 by Thomas Thanner, Citron GmbH, Germany. <support@citron.de> + * Copyright 1999-2000 by Peter Kunzmann, Citron GmbH, Germany. <support@citron.de> + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and that + * the name of Thomas Thanner and Citron GmbH not be used in advertising or + * publicity pertaining to distribution of the software without specific, written + * prior permission. Thomas Thanner and Citron GmbH makes no representations about + * the suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * THOMAS THANNER AND CITRON GMBH DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, + * IN NO EVENT SHALL THOMAS THANNER OR CITRON GMBH BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RSULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * Citron specific extensions: + * + * 1) Configuration file entries: + * a) "SleepTime" Touch idle time in seconds before sleep mode + * (reduced scanning) is entered. + * 0 = immediately; 65535=never; + * default=65535 + * b) "ActivePWM" PWM duty cycle during regular operation. + * default=255 + * c) "SleepPWM" PWM duty cycle during sleep mode. + * default=255 + * d) "ClickMode" Button click emulation mode; + * 1 = Enter Mode + * 2 = Dual Touch Mode + * 3 = Dual Exit Mode + * 4 = Z-Press Mode + * 5 = Z-Press Exit Mode + * default = 1 + * + * 2) Additional modes in SetMode() function: + * (These modes are only activated if the CIT_MODE_EXT macro is defined + * at compile time. Until now the mode values are not defined, yet) + * a) ClickMode_Enter set the button click emulation mode to 1 + * b) ClickMode_Dual set the button click emulation mode to 2 + * c) ClickMode_DualExit set the button click emulation mode to 3 + * d) ClickMode_ZPress set the button click emulation mode to 4 + * e) ClickMode_ZPressExit set the button click emulation mode to 5 + * + *!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ +/* + --------------------------------------------------------------------------- + Revision history: + + Ver Date Description of changes Name + --------------------------------------------------------------------------- + 2.03 17.09.00 Reconnect when getting breaks changed, changes + when powering off the system and reconnecting + parser for commands from "xcit" added + "cit_ParseCommand" to set the variables not + only on the touch side but also in the priv rec pk + 2.04 19.10.00 reconnect enhanced pk + ============================================================================ + +*/ + + +#define _citron_C_ +#define PK 0 +#define INITT 0 /* Initialisation of touch in first loop */ + +/* ODD version number enables the debug macros */ +/* EVEN version number is for release */ +#define CITOUCH_VERSION 0x204 +char version[]="Touch Driver V2.04 (c) 1999-2000 Citron GmbH"; + + + +/***************************************************************************** + * Standard Headers + ****************************************************************************/ + +#include <misc.h> +#include <xf86.h> +#define NEED_XF86_TYPES +/*#include <xf86Version.h>*/ +#include <xf86_ansic.h> +/* #define XF86_OS_PRIVS for xf86SoundKbdBell */ +#include <xf86_OSproc.h> +#include <xf86Optrec.h> +#include <xf86Xinput.h> +#include <xisb.h> +#include <exevents.h> /* Needed for InitValuator/Proximity stuff*/ + + +/* I have to explicit declare this function, because I get an error if I compile */ +/* with "#define XF86_OS_PRIVS". I also have to put a "SYMVAR(xf86SoundKbdBell)" */ +/* statement into the "/loader/xf86sym.c file" to be able to access this function (PK) */ +extern void xf86SoundKbdBell(int loudness, int pitch, int duration); + +/* #define CI_TIM */ /* Enable timer */ +#define CIT_BEEP /* enable beep feature */ + +/***************************************************************************** + * Local Headers + ****************************************************************************/ +#include "citron.h" + +/***************************************************************************** + * Variables without includable headers + ****************************************************************************/ + +/***************************************************************************** + * defines + ****************************************************************************/ +#define CIT_DEF_MIN_X 0 +#define CIT_DEF_MAX_X 0xFFFF +#define CIT_DEF_MIN_Y 0 +#define CIT_DEF_MAX_Y 0xFFFF + +#define CIT_BUFFER_SIZE 1024 + + + +/****************************************************************************** + * debugging macro + *****************************************************************************/ +#ifdef DBG +#undef DBG +#endif +#ifdef DEBUG +#undef DEBUG +#endif + +static int debug_level = 0; +#if CITOUCH_VERSION & 0x0001 +#define DEBUG +#endif +#ifdef DEBUG +#define DBG(lvl, f) {if ((lvl) <= debug_level) f;} +#else +#define DBG(lvl, f) +#endif + +/* Debugging levels for various routines */ +#define PP 5 /* cit_ProcessPacket */ +#define RI 6 /* cit_ReadInput */ +#define GP 6 /* cit_GetPacket */ +#define DDS 5 /* DDS package */ +#define DC 5 /* cit_DriverComm */ + +#define XFREE86_V4 + +#ifdef XFREE86_V4 +#define WAIT(t) \ + err = xf86WaitForInput(-1, ((t) * 1000)); \ + if (err == -1) { \ + ErrorF("Citron select error\n"); \ + return !Success; \ + } +#else +#define WAIT(t) \ + timeout.tv_sec = 0; \ + timeout.tv_usec = (t) * 1000; \ + SYSCALL(err = select(0, NULL, NULL, NULL, &timeout)); \ + if (err == -1) { \ + ErrorF("Citron select error : %s\n", strerror(errno)); \ + return !Success; \ + } +#endif + + + + +/***************************************************************************** + * Local Variables + ****************************************************************************/ + + +static InputInfoPtr CitronPreInit(InputDriverPtr drv, IDevPtr dev, int flags); + + +InputDriverRec CITRON = { + 1, + "citron", + NULL, + CitronPreInit, + /*CitronUnInit*/ NULL, + NULL, + 0 +}; + +#ifdef XFree86LOADER + + +/* + *************************************************************************** + * + * Dynamic loading functions + * + *************************************************************************** + */ + + +static XF86ModuleVersionInfo VersionRec = +{ + "citron", /* name of module */ + MODULEVENDORSTRING, /* vendor specific string */ + MODINFOSTRING1, + MODINFOSTRING2, + XF86_VERSION_CURRENT, /* Module-specific current version */ + 0, /* Module-specific major version */ + 1, /* Module-specific minor version */ + 1, /* Module-specific patch level */ + ABI_CLASS_XINPUT, + ABI_XINPUT_VERSION, + MOD_CLASS_XINPUT, + {0, 0, 0, 0} /* signature of the version info structure */ +}; + + +/* ************************************************************************ + * [SetupProc] -- + * + * called when the module subsection is found in XF86Config + * + * ************************************************************************/ + +static pointer +SetupProc( pointer module, + pointer options, + int *errmaj, + int *errmin ) +{ +/* xf86LoaderReqSymLists(reqSymbols, NULL); */ + xf86AddInputDriver(&CITRON, module, 0); + DBG(5, ErrorF ("%sSetupProc called\n", CI_INFO)); + + return (pointer) 1; +} + +/***************************************************************************** + * [TearDownProc] + ****************************************************************************/ +static void +TearDownProc (pointer p) +{ + DBG(5, ErrorF ("%sTearDownProc Called\n", CI_INFO)); +} + + +XF86ModuleData citronModuleData = { &VersionRec, SetupProc, TearDownProc}; + +#endif /* XFree86LOADER */ + + + + + +/* + * Be sure to set vmin appropriately for your device's protocol. You want to + * read a full packet before returning + */ +static const char *default_options[] = +{ + + "BaudRate", "19200", + "StopBits", "1", + "DataBits", "8", + "Parity", "None", + "Vmin", "3", + "Vtime", "1", + "FlowControl", "None", + "ClearDTR", "" +}; + + +/***************************************************************************** + * Function Definitions + ****************************************************************************/ + + + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +/* [xf86CitronFeedback] */ +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +/* Online driver parameter change */ +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + +static void +cit_SendtoTouch(DeviceIntPtr dev) +{ + LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate; + cit_PrivatePtr priv = (cit_PrivatePtr)(local->private); + int i,j; + unsigned char buf[MAX_BYTES_TO_TRANSFER*2+2]; + + DBG(DDS, ErrorF("%scit_SendtoTouch(numbytes=0x%02X, data[0]=%02x, data[1]=%02x, data[2]=%02x, data[3]=%02x, ...)\n", CI_INFO, priv->dds.numbytes, + priv->dds.data[0], priv->dds.data[1], priv->dds.data[2], priv->dds.data[3],)); + + j=0; + buf[j++] = CTS_STX; /* transmit start of packet */ + + for(i=0; i<priv->dds.numbytes; i++) + { + if (priv->dds.data[i] >= CTS_CTRLMIN && priv->dds.data[i] <= CTS_CTRLMAX) + { /* data has to be encoded */ + buf[j++] = CTS_ESC; + buf[j++] = priv->dds.data[i] | CTS_ENCODE; + } + else buf[j++] = priv->dds.data[i]; + } + buf[j++] = CTS_ETX; /* end of packet */ + + XisbWrite(priv->buffer, buf, j); + + + for(i=0; i<j; i++) + { + if(i%16 == 0) DBG(DDS, ErrorF("\n")); + DBG(DDS, ErrorF("%02x ",buf[i])); + } + + + DBG(DDS, ErrorF("\n")); +} + + +static void +cit_ParseCommand(DeviceIntPtr dev) +{ + LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate; + cit_PrivatePtr priv = (cit_PrivatePtr)(local->private); + int i; + + DBG(DDS, ErrorF("%scit_ParseCommand(numbytes=0x%02X, data= ", CI_INFO, priv->dds.numbytes)); + + for(i=0; i<priv->dds.numbytes; i++) + DBG(DDS, ErrorF("%02x ", priv->dds.data[i])); + + DBG(DDS,ErrorF("\n")); + + switch(priv->dds.data[0]&0xff) + { + case C_SETPWM: + priv->pwm_active = priv->dds.data[1]; + priv->pwm_sleep = priv->dds.data[2]; + DBG(DDS, ErrorF("%scit_ParseCommand(PWM Active:%d PWM Sleep:%d \n", CI_INFO, priv->pwm_active, priv->pwm_sleep)); + break; + + case C_SETSLEEPMODE: + if(priv->dds.data[1] == 0) + { + priv->sleep_time_act = priv->dds.data[2] | (priv->dds.data[3] << 8); + } + DBG(DDS, ErrorF("%scit_ParseCommand(Sleep Time act:%d \n", CI_INFO, priv->sleep_time_act)); + break; + + case C_SETDOZEMODE: + if(priv->dds.data[1] == 0) + { + priv->doze_time_act = priv->dds.data[2] | (priv->dds.data[3] << 8); + } + DBG(DDS, ErrorF("%scit_ParseCommand(Doze Time act:%d \n", CI_INFO, priv->doze_time_act)); + break; + + case C_SETAREAPRESSURE: + priv->button_threshold = priv->dds.data[1]; + DBG(DDS, ErrorF("%scit_ParseCommand(Button Threshold:%d \n", CI_INFO, priv->button_threshold)); + break; + } +} + + + +static void +cit_DriverComm(DeviceIntPtr dev) +{ + LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate; + cit_PrivatePtr priv = (cit_PrivatePtr)(local->private); + int i; + unsigned short tmp; + + DBG(DC, ErrorF("%scit_DriverComm(numbytes=0x%02X, data[1]=%02x, ...)\n", CI_INFO, priv->dds.numbytes, priv->dds.data[1])); + + i=1; + switch(priv->dds.data[i++]) /* command word */ + { + case D_SETCLICKMODE: + priv->click_mode = priv->dds.data[i++]; + ErrorF("%sClick Mode: %d\n", CI_INFO, priv->click_mode); + break; + + case D_BEEP: + priv->beep = priv->dds.data[i++]; + ErrorF("%sBeep: %s\n", CI_INFO, (priv->beep > 0) ? "activated":"not activated"); + break; + + case D_SETBEEP: + priv->press_vol = priv->dds.data[i++]; + ErrorF("%sBeep Pressure Volume: %d\n", CI_INFO, priv->press_vol); + tmp = priv->dds.data[i++]; + tmp += priv->dds.data[i++] << 8; + priv->press_pitch = tmp; + ErrorF("%sBeep Pressure Pitch: %d\n", CI_INFO, priv->press_pitch); + priv->press_dur = priv->dds.data[i++]; + ErrorF("%sBeep Pressure Duration: %d\n", CI_INFO, priv->press_dur); + priv->rel_vol = priv->dds.data[i++]; + ErrorF("%sBeep Release Volume: %d\n", CI_INFO, priv->rel_vol); + tmp = priv->dds.data[i++]; + tmp += priv->dds.data[i++] << 8; + priv->rel_pitch = tmp; + ErrorF("%sBeep Release Pitch: %d\n", CI_INFO, priv->rel_pitch); + priv->rel_dur = priv->dds.data[i++]; + ErrorF("%sBeep Release Duration: %d\n", CI_INFO, priv->rel_dur); + break; + + default: + ErrorF("%sNot known command: %d\n", CI_WARNING, priv->dds.data[1]); + + } +} + + +static void +xf86CitronPrint (int nr, LedCtrl *ctrl) +{ + DBG(8, ErrorF("%s------------------------------------------\n", CI_INFO)); + DBG(8, ErrorF("%sxf86CitronFeedback%d(dev, ctrl)\n", CI_INFO, nr)); + DBG(8, ErrorF("%s ctrl->led_values.......:%d [0x%08lX]\n", CI_INFO, ctrl->led_values, ctrl->led_values)); + DBG(8, ErrorF("%s ctrl->led_mask.........:%d [0x%08lX]\n", CI_INFO, ctrl->led_mask, ctrl->led_mask)); + DBG(8, ErrorF("%s ctrl->id...............:%d\n", CI_INFO, ctrl->id)); +} + + +static void +xf86CitronFeedback0 (DeviceIntPtr dev, LedCtrl *ctrl) +{ + LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate; + cit_PrivatePtr priv = (cit_PrivatePtr)(local->private); + COMMAND *cmd; + + DBG(DDS, ErrorF("%sEntering xf86CitronFeedback0()...\n",CI_INFO)); + + cmd = (COMMAND *)&ctrl->led_values; + + DBG(DDS, ErrorF("%scmd->packet = %d\n", CI_INFO, cmd->packet)); + + + if(cmd->packet == 0) /* test if first packet has come (with number of bytes in first byte) */ + { + if(cmd->par[0] == 0) /* test if something is to do at all */ + return; + priv->dds.curbyte = 2; + priv->dds.numbytes = cmd->par[0]; + priv->dds.data[0] = cmd->par[1]; + priv->dds.data[1] = cmd->par[2]; + priv->dds.packet = 1; + } + else + { + if(priv->dds.packet == cmd->packet) + { + priv->dds.data[priv->dds.packet*3-1] = cmd->par[0]; + priv->dds.data[priv->dds.packet*3] = cmd->par[1]; + priv->dds.data[priv->dds.packet*3+1] = cmd->par[2]; + priv->dds.packet++; + priv->dds.curbyte += 3; + } + else + DBG(DDS, ErrorF("%sPacket error: should be %d is %d\n", CI_WARNING, priv->dds.packet, cmd->packet)); + + } + DBG(DDS, ErrorF("%snumbytes = %d curbyte=%d\n", CI_INFO, priv->dds.numbytes, priv->dds.curbyte)); + if(priv->dds.curbyte >= priv->dds.numbytes) + { + if(priv->dds.data[0] == DRIVCOMM) + cit_DriverComm(dev); /* process command in the driver */ + else + { + cit_ParseCommand(dev); /* First parse command and set parameters in priv rec */ + cit_SendtoTouch(dev); /* send message to the touch and execute command there */ + } + } + + DBG(DDS, ErrorF("%s 1 led_values = %08x\n", CI_INFO, ctrl->led_values)); + ctrl->led_values = 0x12345678; + DBG(DDS, ErrorF("%s 2 led_values = %08x\n", CI_INFO, ctrl->led_values)); + +} + + +static void +xf86CitronFeedback1 (DeviceIntPtr dev, LedCtrl *ctrl) +{ + static int test = 0; + xf86CitronPrint (1, ctrl); + ctrl->led_values = 0x8765432; + ctrl->led_mask = test++; +} + +static void +xf86CitronFeedback2 (DeviceIntPtr dev, LedCtrl *ctrl) +{ + xf86CitronPrint (2, ctrl); + ctrl->led_values = (unsigned long)GetTimeInMillis(); + ctrl->led_mask = (unsigned long)GetTimeInMillis()&0xff; +} + + + +#if(PK) +/* Hexdump a number of Words */ +/* len is number of words to dump */ +static void hexdump (void *ioaddr, int len) +{ + int i; + unsigned long *ptr = (unsigned long *)ioaddr; + + ErrorF(" ADDR 0-3 4-7 8-B C-F\n"); + ErrorF("---------+-----+----+----+----+----+----+----+----\n"); + + while (len > 0) + { + ErrorF ("%08X: ", (unsigned long)ptr); + + for (i=0;i < ( (len>4)?4:len);i++) + ErrorF (" %08x", *ptr++); + ErrorF ("\n"); + len -= 8; + } + + ErrorF("---------+-----+----+----+----+----+----+----+----\n"); +} +#endif + +#ifdef CIT_TIM +/***************************************************************************** + * [cit_StartTimer] + ****************************************************************************/ + +static void +cit_StartTimer(cit_PrivatePtr priv) +{ + priv->timer_ptr = TimerSet(priv->timer_ptr, 0, priv->timer_val1, + priv->timer_callback, (pointer)priv); + DBG(5, ErrorF ("%scit_StartTimer called PTR=%08x\n", CI_INFO, priv->timer_ptr)); +} + + +/***************************************************************************** + * [cit_CloseTimer] + ****************************************************************************/ +static void +cit_CloseTimer(cit_PrivatePtr priv) +{ + + DBG(5, ErrorF ("%scit_CloseTimer called PTR=%08x\n", CI_INFO, priv->timer_ptr)); + if(priv->timer_ptr) + { + TimerFree(priv->timer_ptr); + priv->timer_ptr = NULL; + } + else + DBG(5, ErrorF ("%scit_CloseTimer: Nothing to close\n", CI_WARNING)); +} + + + +/***************************************************************************** + * [cit_DualTouchTimer] + ****************************************************************************/ +static CARD32 +cit_DualTouchTimer(OsTimerPtr timer, CARD32 now, pointer arg) +{ + cit_PrivatePtr priv = (cit_PrivatePtr) arg; + int sigstate; + + DBG(5, ErrorF ("%scit_DualTouchTimer called %d\n", CI_INFO, GetTimeInMillis())); + + priv->packet[0] = R_EXIT; /* build a exit message */ + priv->packet[1] = LOBYTE(priv->raw_x); + priv->packet[2] = HIBYTE(priv->raw_x); + priv->packet[3] = LOBYTE(priv->raw_y); + priv->packet[4] = HIBYTE(priv->raw_y); + priv->packeti = 5; + priv->fake_exit = TRUE; + sigstate = xf86BlockSIGIO (); + + + priv->local->read_input(priv->local); /* faking up an exit message */ + xf86UnblockSIGIO (sigstate); + + DBG(3, ErrorF ("%scit_DualTouchTimer: Faking Exit Message Sent\n", CI_INFO)); + + return (0); /* stop timer */ +} + +#endif + +/***************************************************************************** + * [CitronPreInit] + ****************************************************************************/ +static InputInfoPtr +CitronPreInit (InputDriverPtr drv, IDevPtr dev, int flags) +{ + LocalDevicePtr local = xf86AllocateInput(drv, 0); + cit_PrivatePtr priv = (cit_PrivatePtr) xcalloc (1, sizeof (cit_PrivateRec)); + char *s; +#if(INITT) + int errmaj, errmin; +#endif + + ErrorF ("%sCitronPreInit called - xcalloc=%d\n", CI_INFO, sizeof(cit_PrivateRec)); +/* DBG(2, ErrorF("\txf86Verbose=%d\n", xf86Verbose));*/ + if ((!local) || (!priv)) + { + ErrorF("%s\t- unable to allocate structures!\n", CI_ERROR); + goto SetupProc_fail; + } + + + /* this results in an xf86strdup that must be freed later */ + local->name = xf86SetStrOption(local->options, "DeviceName", "CiTouch"); + ErrorF("%sDevice name: %s\n", CI_INFO, local->name); + + local->type_name = XI_TOUCHSCREEN; + + /* + * Standard setup for the local device record + */ + local->device_control = DeviceControl; + local->read_input = ReadInput; + local->control_proc = ControlProc; + local->close_proc = CloseProc; + local->switch_mode = SwitchMode; + local->conversion_proc = ConvertProc; + local->dev = NULL; + local->private = priv; + local->private_flags = 0; + local->history_size = xf86SetIntOption(local->options, "HistorySize", 0); + local->flags = XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS; + local->conf_idev = dev; + + xf86CollectInputOptions(local, default_options, NULL); + +/* xf86OptionListReport(local->options); */ + + + + debug_level = xf86SetIntOption(local->options, "DebugLevel", 0); + if(debug_level) + { +#ifdef DEBUG + ErrorF("%sDebug level set to %d\n", CI_CONFIG, debug_level); +#else + ErrorF("%sDebug not available\n", CI_INFO); +#endif + } + + +#if(INITT) + + + DBG(5, ErrorF ("%sOpenSerial will be called\n", CI_INFO)); + + local->fd = xf86OpenSerial (local->options); + if (local->fd == -1) + { + ErrorF ("%s\t- unable to open device %s\n", CI_ERROR, xf86FindOptionValue (local->options, "Device")); + goto SetupProc_fail; + } + + DBG(6, ErrorF("%s\t+ %s opened successfully.\n", CI_INFO, xf86FindOptionValue (local->options, "Device"))); +#endif + + /* + * Process the options for the IRT + */ + priv->screen_num = xf86SetIntOption(local->options, "ScreenNumber", 0); + ErrorF("%sAssociated screen: %d\n", CI_CONFIG, priv->screen_num); + priv->min_x = xf86SetIntOption(local->options, "MinX", CIT_DEF_MIN_X); + ErrorF("%sMinimum x position: %d\n", CI_CONFIG, priv->min_x); + priv->max_x = xf86SetIntOption(local->options, "MaxX", CIT_DEF_MAX_X); + ErrorF("%sMaximum x position: %d\n", CI_CONFIG, priv->max_x); + priv->min_y = xf86SetIntOption(local->options, "MinY", CIT_DEF_MIN_Y); + ErrorF("%sMinimum y position: %d\n", CI_CONFIG, priv->min_y); + priv->max_y = xf86SetIntOption(local->options, "MaxY", CIT_DEF_MAX_Y); + ErrorF("%sMaximum y position: %d\n", CI_CONFIG, priv->max_y); + priv->button_number = xf86SetIntOption(local->options, "ButtonNumber", 1); + ErrorF("%sButton Number: %d\n", CI_CONFIG, priv->button_number); + priv->button_threshold = xf86SetIntOption(local->options, "ButtonThreshold", 10); + ErrorF("%sButton Threshold: %d\n", CI_CONFIG, priv->button_threshold); + priv->sleep_mode = xf86SetIntOption(local->options, "SleepMode", 0); + ErrorF("%sSleep Mode: %d\n", CI_CONFIG, priv->sleep_mode); + priv->sleep_time_act = xf86SetIntOption(local->options, "SleepTime", 65535); + ErrorF("%sSleep Time: %d\n", CI_CONFIG, priv->sleep_time_act); + priv->sleep_time_scan = xf86SetIntOption(local->options, "SleepScan", 65535); + ErrorF("%sSleep Scan: %d\n", CI_CONFIG, priv->sleep_time_scan); + priv->pwm_active = xf86SetIntOption(local->options, "PWMActive", 255); + ErrorF("%sPWM Active: %d\n", CI_CONFIG, priv->pwm_active); + priv->pwm_sleep = xf86SetIntOption(local->options, "PWMSleep", 255); + ErrorF("%sPWM Sleep: %d\n", CI_CONFIG, priv->pwm_sleep); + priv->click_mode = xf86SetIntOption(local->options, "ClickMode", NO_CLICK_MODE); + ErrorF("%sClick Mode: %d\n", CI_CONFIG, priv->click_mode); + priv->origin = xf86SetIntOption(local->options, "Origin", 0); + ErrorF("%sOrigin: %d\n", CI_CONFIG, priv->origin); + priv->doze_mode = xf86SetIntOption(local->options, "DozeMode", 0); + ErrorF("%sDoze Mode: %d\n", CI_CONFIG, priv->doze_mode); + priv->doze_time_act = xf86SetIntOption(local->options, "DozeTime", 10); + ErrorF("%sDoze Time: %d\n", CI_CONFIG, priv->doze_time_act); + priv->doze_time_scan = xf86SetIntOption(local->options, "DozeScan", 25); + ErrorF("%sDoze Scan: %d\n", CI_CONFIG, priv->doze_time_scan); + priv->delta_x = xf86SetIntOption(local->options, "DeltaX", 0) & 0xff; + ErrorF("%sDelta X: %d\n", CI_CONFIG, priv->delta_x); + priv->delta_y = xf86SetIntOption(local->options, "DeltaY", 0) & 0xff; + ErrorF("%sDelta Y: %d\n", CI_CONFIG, priv->delta_y); + priv->beep = xf86SetIntOption(local->options, "Beep", 0); + ErrorF("%sBeep: %s\n", CI_CONFIG, (priv->beep > 0) ? "activated":"not activated"); + priv->press_vol = xf86SetIntOption(local->options, "PressVol", 100); + ErrorF("%sBeep Pressure Volume: %d\n", CI_CONFIG, priv->press_vol); + priv->press_pitch = xf86SetIntOption(local->options, "PressPitch", 880); + ErrorF("%sBeep Pressure Pitch: %d\n", CI_CONFIG, priv->press_pitch); + priv->press_dur = xf86SetIntOption(local->options, "PressDur", 15) & 0xff; + ErrorF("%sBeep Pressure Duration: %d\n", CI_CONFIG, priv->press_dur); + priv->rel_vol = xf86SetIntOption(local->options, "ReleaseVol", 100); + ErrorF("%sBeep Release Volume: %d\n", CI_CONFIG, priv->rel_vol); + priv->rel_pitch = xf86SetIntOption(local->options, "ReleasePitch", 1200); + ErrorF("%sBeep Release Pitch: %d\n", CI_CONFIG, priv->rel_pitch); + priv->rel_dur = xf86SetIntOption(local->options, "ReleaseDur", 10) & 0xff; + ErrorF("%sBeep Release Duration: %d\n", CI_CONFIG, priv->rel_dur); + priv->beam_timeout = xf86SetIntOption(local->options, "BeamTimeout", 30) & 0xffff; + ErrorF("%sBeam Timeout: %d\n", CI_CONFIG, priv->beam_timeout); + priv->touch_time = xf86SetIntOption(local->options, "TouchTime", 0) & 0xff; + ErrorF("%sTouch Time: %d\n", CI_CONFIG, priv->touch_time); + priv->enter_count = xf86SetIntOption(local->options, "EnterCount", 3); + ErrorF("%sEnter Count: %d\n", CI_CONFIG, priv->enter_count); + priv->max_dual_count = xf86SetIntOption(local->options, "DualCount", MAX_DUAL_TOUCH_COUNT); + ErrorF("%sDual Count: %d\n", CI_CONFIG, priv->max_dual_count); + +/* trace the min and max values */ + priv->raw_min_x = CIT_DEF_MAX_X; + priv->raw_max_x = 0; + priv->raw_min_y = CIT_DEF_MAX_Y; + priv->raw_max_y = 0; + +#ifdef CIT_TIM +/* preset timer values */ + priv->timer_ptr = NULL; + priv->timer_val1 = 0; + priv->timer_val2 = 0; + priv->timer_callback = NULL; +#endif + + priv->fake_exit = FALSE; + priv->enter_touched = 0; /* preset */ + priv->local = local; /* save local device pointer */ + + DBG(6, ErrorF("%s\t+ options read\n", CI_INFO)); + s = xf86FindOptionValue (local->options, "ReportingMode"); + if ((s) && (xf86NameCmp (s, "raw") == 0)) + priv->reporting_mode = TS_Raw; + else + priv->reporting_mode = TS_Scaled; + +#if(INITT) + /* + * Create an X Input Serial Buffer, because IRT is connected to a serial port + */ + priv->buffer = XisbNew (local->fd, CIT_BUFFER_SIZE); +#endif + priv->proximity = FALSE; + priv->button_down = FALSE; + priv->dual_touch_count = 0; + priv->dual_flg = 0; + priv->state = 0; + priv->lex_mode = cit_idle; + priv->last_x = 0; + priv->last_y = 0; + priv->query_state = 0; /* first query */ + + +#if(INITT) + DBG (8, XisbTrace (priv->buffer, 1)); + + + /* + * Verify that the IRT is attached and functional + */ + if (QueryHardware (local, &errmaj, &errmin) != Success) + { + ErrorF ("%s\t- Unable to query/initialize Citron hardware.\n", CI_INFO); + goto SetupProc_fail; + } +#endif + + xf86ProcessCommonOptions(local, local->options); + local->flags |= XI86_CONFIGURED; +#if(PK) + if (xf86FindOption (local->options, "DemandLoaded")) + { + DBG (5, ErrorF ("%s\tCitron module was demand loaded\n", CI_INFO)); + xf86AddLocalDevice (local, TRUE); + } + else + xf86AddLocalDevice (local, FALSE); +#endif + + if (local->fd >= 0) + { + RemoveEnabledDevice (local->fd); +#if(INITT) + if (priv->buffer) + { + XisbFree(priv->buffer); + priv->buffer = NULL; + } + xf86CloseSerial(local->fd); +#endif + } + + + /* return the LocalDevice */ + DBG(5, ErrorF ("%sCitronPreInit success\n", CI_INFO)); + return (local); + + + /* + * If something went wrong, cleanup and return NULL + */ + SetupProc_fail: +#if(INITT) + if ((local) && (local->fd)) + xf86CloseSerial (local->fd); +#endif + if ((local) && (local->name)) + xfree (local->name); + if (local) + xfree (local); +#if(INITT) + if ((priv) && (priv->buffer)) + XisbFree (priv->buffer); +#endif + if (priv) + xfree (priv); + ErrorF ("%sCitronPreInit returning NULL\n", CI_ERROR); + return (NULL); +} + + + +/***************************************************************************** + * [DeviceControl] + ****************************************************************************/ +static Bool +DeviceControl (DeviceIntPtr dev, int mode) +{ + Bool RetVal; + + DBG(5, ErrorF ("%sDeviceControl called; mode = %d\n", CI_INFO, mode)); + switch (mode) + { + case DEVICE_INIT: + DBG(6, ErrorF ("%s\tINIT\n", CI_INFO)); + DeviceInit (dev); + RetVal = Success; + break; + case DEVICE_ON: + DBG(6, ErrorF ("%s\tON\n", CI_INFO)); + RetVal = DeviceOn (dev); + break; + case DEVICE_OFF: + DBG(6, ErrorF ("%s\tOFF\n", CI_INFO)); + RetVal = DeviceOff (dev); + break; + case DEVICE_CLOSE: + DBG(6, ErrorF ("%s\tCLOSE\n", CI_INFO)); + RetVal = DeviceClose (dev); + break; + default: + ErrorF ("%sDeviceControl Mode (%d) not found\n", CI_ERROR, mode); + RetVal = BadValue; + } + return(RetVal); +} + +/***************************************************************************** + * [DeviceOn] + ****************************************************************************/ +static Bool +DeviceOn (DeviceIntPtr dev) +{ + LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate; + cit_PrivatePtr priv = (cit_PrivatePtr) (local->private); + int errmaj, errmin; + + DBG(5, ErrorF ("%sDeviceOn called\n", CI_INFO)); + + local->fd = xf86OpenSerial(local->options); + if (local->fd == -1) + { + xf86Msg(X_WARNING, "%s%s: cannot open input device\n", CI_ERROR, local->name); + goto DeviceOn_fail; + } + priv->buffer = XisbNew (local->fd, CIT_BUFFER_SIZE); + if (!priv->buffer) + goto DeviceOn_fail; + + xf86FlushInput(local->fd); + + if (QueryHardware (local, &errmaj, &errmin) != Success) + { + ErrorF ("%s\t- Unable to query/initialize Citron hardware.\n", CI_ERROR); + goto DeviceOn_fail; + } + + AddEnabledDevice (local->fd); + dev->public.on = TRUE; + return (Success); + + /* + * If something went wrong, cleanup + */ + DeviceOn_fail: + if ((local) && (local->fd)) + xf86CloseSerial (local->fd); + + if ((local) && (local->name)) + xfree (local->name); + if (local) + { + xfree (local); + local = NULL; + } + if ((priv) && (priv->buffer)) + XisbFree (priv->buffer); + if (priv) + { + xfree (priv); + priv = NULL; + } + ErrorF ("%sDeviceOn failed\n", CI_ERROR); + return (!Success); + + + +} + +/***************************************************************************** + * [DeviceOff] + ****************************************************************************/ +static Bool +DeviceOff (DeviceIntPtr dev) +{ + DBG(5, ErrorF ("%sDeviceOff called\n", CI_INFO)); + return DeviceClose(dev); +} + +/***************************************************************************** + * [DeviceClose] + ****************************************************************************/ +static Bool +DeviceClose (DeviceIntPtr dev) +{ + LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate; + cit_PrivatePtr priv = (cit_PrivatePtr) (local->private); + int c; + + DBG(5, ErrorF ("%sDeviceClose called\n",CI_INFO)); + + cit_Flush(priv->buffer); + + cit_SendCommand(priv->buffer, C_SOFTRESET, 0); +#ifdef CIT_TIM + cit_CloseTimer(priv); /* Close timer if started */ +#endif + XisbTrace(priv->buffer, 1); /* trace on */ + XisbBlockDuration (priv->buffer, 500000); + c = XisbRead (priv->buffer); + if(c == CTS_NAK) + { + DBG(6, ErrorF ("%sTouch Reset executed\n",CI_INFO)); + } + else + { + DBG(6, ErrorF ("%sTouch Reset not executed\n",CI_ERROR)); + } + + +/* Now free all allocated memory */ + if (local->fd >= 0) + { + RemoveEnabledDevice (local->fd); + if (priv->buffer) + { + XisbFree(priv->buffer); + priv->buffer = NULL; + } + xf86CloseSerial(local->fd); + local->fd = 0; + } + + dev->public.on = FALSE; + ErrorF("%sx-range = [%d..%d]\n", CI_INFO, priv->raw_min_x, priv->raw_max_x); + ErrorF("%sy-range = [%d..%d]\n", CI_INFO, priv->raw_min_y, priv->raw_max_y); + + return (Success); +} + + +/***************************************************************************** + * [DeviceInit] + ****************************************************************************/ +static Bool +DeviceInit (DeviceIntPtr dev) +{ + LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate; + cit_PrivatePtr priv = (cit_PrivatePtr) (local->private); + + unsigned char map[] = + {0, 1}; + + DBG (5, ErrorF("%sDeviceInit called\n", CI_INFO)); + /* + * these have to be here instead of in the SetupProc, because when the + * SetupProc is run and server startup, screenInfo is not setup yet + */ + priv->screen_width = screenInfo.screens[priv->screen_num]->width; + priv->screen_height = screenInfo.screens[priv->screen_num]->height; + + DBG (5, ErrorF("%sScreen Number: %d Screen Width: %d Screen Height: %d\n", CI_INFO, + priv->screen_num, priv->screen_width, priv->screen_height)); + + /* + * Device reports button press for up to 1 button. + */ + if (InitButtonClassDeviceStruct (dev, 1, map) == FALSE) + { + ErrorF ("%sUnable to allocate Citron touchscreen ButtonClassDeviceStruct\n", CI_ERROR); + return !Success; + } + + /* + * Device reports motions on 2 axes in absolute coordinates. + * Axes min and max values are reported in raw coordinates. + * Resolution is computed roughly by the difference between + * max and min values scaled from the approximate size of the + * screen to fit one meter. + * Device may reports touch pressure on the 3rd axis. + */ + if (InitValuatorClassDeviceStruct (dev, 2, xf86GetMotionEvents, + local->history_size, Absolute) == FALSE) + { + ErrorF ("%sUnable to allocate Citron touchscreen ValuatorClassDeviceStruct\n", CI_ERROR); + return !Success; + } + else + { + InitValuatorAxisStruct (dev, 0, priv->min_x, priv->max_x, + CIT_DEF_MAX_X, + CIT_DEF_MIN_X /* min_res */ , + CIT_DEF_MAX_X /* max_res */ ); + InitValuatorAxisStruct (dev, 1, priv->min_y, priv->max_y, + CIT_DEF_MAX_Y, + CIT_DEF_MIN_Y /* min_res */ , + CIT_DEF_MAX_Y /* max_res */ ); + } + + if (InitProximityClassDeviceStruct (dev) == FALSE) + { + ErrorF ("%sUnable to allocate Citron touchscreen ProximityClassDeviceStruct\n", CI_ERROR); + return !Success; + } + + + /* + * Use the LedFeedbackClass to set some driver parameters + */ + + /* ID=0 --> Return driver version (RO) */ + + if (InitLedFeedbackClassDeviceStruct(dev, xf86CitronFeedback0) == FALSE) + { + ErrorF("Unable to allocate CITRON touchscreen LedFeedbackClassDeviceStruct, id=0\n"); + return !Success; + } + /* ID=1 --> ENTER_COUNT */ + if (InitLedFeedbackClassDeviceStruct(dev, xf86CitronFeedback1) == FALSE) + { + ErrorF("Unable to allocate CITRON touchscreen LedFeedbackClassDeviceStruct, id=1\n"); + return !Success; + } + + /* ID=2 --> */ + if (InitLedFeedbackClassDeviceStruct(dev, xf86CitronFeedback2) == FALSE) + { + ErrorF("Unable to allocate CITRON touchscreen LedFeedbackClassDeviceStruct, id=2\n"); + return !Success; + } + + + /* + * Allocate the motion events buffer. + */ + xf86MotionHistoryAllocate (local); + return (Success); +} + +/***************************************************************************** + * [ReadInput] + ****************************************************************************/ +static void +ReadInput (LocalDevicePtr local) +{ + int x, y; + cit_PrivatePtr priv = (cit_PrivatePtr) (local->private); + + DBG(RI, ErrorF("%sReadInput called\n", CI_INFO)); + + /* + * set blocking to -1 on the first call because we know there is data to + * read. Xisb automatically clears it after one successful read so that + * succeeding reads are preceeded by a select with a 0 timeout to prevent + * read from blocking indefinately. + */ + if(!priv->fake_exit) + { + XisbBlockDuration (priv->buffer, -1); + DBG(RI, ErrorF("%sXisbBlockDuration = -1\n", CI_INFO)); + } + while ( +#ifdef CIT_TIM + priv->fake_exit || +#endif + (cit_GetPacket (priv) == Success)) + { + cit_ProcessPacket(priv); + + + + if (priv->reporting_mode == TS_Scaled) + { + x = xf86ScaleAxis (priv->raw_x, 0, priv->screen_width, priv->min_x, + priv->max_x); + y = xf86ScaleAxis (priv->raw_y, 0, priv->screen_height, priv->min_y, + priv->max_y); + DBG(RI, ErrorF("%s\tscaled coordinates: (%d, %d)\n", CI_INFO, x, y)); + } + else + { + x = priv->raw_x; + y = priv->raw_y; + } + + xf86XInputSetScreen (local, priv->screen_num, x, y); + + if ((priv->proximity == FALSE) && (priv->state & CIT_TOUCHED)) + { + priv->proximity = TRUE; + xf86PostProximityEvent (local->dev, 1, 0, 2, x, y); + DBG(RI, ErrorF("%s\tproximity(TRUE, x=%d, y=%d)\n", CI_INFO, x, y)); + } + + /* + * Send events. + * + * We *must* generate a motion before a button change if pointer + * location has changed as DIX assumes this. This is why we always + * emit a motion, regardless of the kind of packet processed. + * First test if coordinates have changed a predefined amount of pixels + */ + + if ( ((x >= (priv->last_x + priv->delta_x)) || + (x <= (priv->last_x - priv->delta_x)) || + (y >= (priv->last_y + priv->delta_y)) || + (y <= (priv->last_y - priv->delta_y))) || + ( ((x < priv->delta_x) || + (x > (priv->screen_width - priv->delta_x))) || + ((y < priv->delta_x) || + (y > (priv->screen_height - priv->delta_y)))) ) + { + xf86PostMotionEvent (local->dev, TRUE, 0, 2, x, y); + DBG(RI, ErrorF("%s\tPostMotionEvent(x=%d, y=%d, last_x=%d, last_y=%d)\n", CI_INFO, + x, y, priv->last_x, priv->last_y)); + + priv->last_x = x; /* save cooked data */ + priv->last_y = y; + } + + /* + * Emit a button press or release. + */ + + if ((priv->button_down == FALSE) && (priv->state & CIT_BUTTON)) + { + if(priv->enter_touched < priv->enter_count) + priv->enter_touched++; + + if(priv->enter_touched == priv->enter_count) + { + priv->enter_touched++; /* increment count one more time to prevent further enter events */ + xf86PostButtonEvent (local->dev, TRUE, + priv->button_number, 1, 0, 2, x, y); + cit_Beep(priv, 1); + + DBG(RI, ErrorF("%s\tPostButtonEvent(DOWN, x=%d, y=%d)\n", CI_INFO, x, y)); + + priv->button_down = TRUE; + } + } + + if ((priv->button_down == TRUE) && !(priv->state & CIT_BUTTON)) + { + xf86PostButtonEvent (local->dev, TRUE, + priv->button_number, 0, 0, 2, x, y); + cit_Beep(priv, 0); + priv->enter_touched = 0; /* reset coordinate report counter */ + DBG(RI, ErrorF("%s\tPostButtonEvent(UP, x=%d, y=%d)\n", CI_INFO, x, y)); + priv->button_down = FALSE; + } + /* + * the untouch should always come after the button release + */ + if ((priv->proximity == TRUE) && !(priv->state & CIT_TOUCHED)) + { + priv->proximity = FALSE; + xf86PostProximityEvent (local->dev, 0, 0, 2, x, y); + DBG(RI, ErrorF("%s\tproximity(FALSE, x=%d, y=%d)\n", CI_INFO, x, y)); + } + + + DBG (RI, ErrorF ("%sTouchScreen: x(%d), y(%d), %s\n", + CI_INFO, x, y, + (priv->state == CIT_TOUCHED) ? "Touched" : "Released")); + +#ifdef CIT_TIM + if(priv->fake_exit) + { + priv->fake_exit = FALSE; /* do not sent any further faked exit messages */ + return; + } +#endif + } + DBG(RI, ErrorF("%sExit ReadInput\n", CI_INFO)); +} + +/***************************************************************************** + * [ControlProc] + ****************************************************************************/ +static int +ControlProc (LocalDevicePtr local, xDeviceCtl * control) +{ + xDeviceTSCalibrationCtl *c = (xDeviceTSCalibrationCtl *) control; + cit_PrivatePtr priv = (cit_PrivatePtr) (local->private); + + DBG(5, ErrorF("%sControlProc called\n", CI_INFO)); + + priv->min_x = c->min_x; + priv->max_x = c->max_x; + priv->min_y = c->min_y; + priv->max_y = c->max_y; + + + return (Success); +} + +/***************************************************************************** + * [CloseProc] + ****************************************************************************/ +static void +CloseProc (LocalDevicePtr local) +{ + DBG(5, ErrorF("%sCloseProc called\n", CI_INFO)); +} + +/***************************************************************************** + * [SwitchMode] + ****************************************************************************/ +static int +SwitchMode (ClientPtr client, DeviceIntPtr dev, int mode) +{ + LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate; + cit_PrivatePtr priv = (cit_PrivatePtr) (local->private); + DBG(5, ErrorF("%sSwitchMode called; mode = %d\n", CI_INFO, mode)); + if ((mode == TS_Raw) || (mode == TS_Scaled)) + { + priv->reporting_mode = mode; + DBG(6, ErrorF("%s\treporting mode = %s\n", CI_INFO, mode==TS_Raw?"raw":"scaled")); + return (Success); + } + else if ((mode == SendCoreEvents) || (mode == DontSendCoreEvents)) + { + xf86XInputSetSendCoreEvents (local, (mode == SendCoreEvents)); + DBG(6, ErrorF("%s\tmode = %sSend Core Events\n", CI_INFO, mode==DontSendCoreEvents?"Don\'t ":"")); + return (Success); + } +#ifdef CIT_MODE_EXT + else if (mode == ClickMode_Enter) + { + priv->click_mode = CM_ENTER; + DBG(6, ErrorF("%s\tset click mode to ENTER\n", CI_INFO)); + return (Success); + } + else if (mode == ClickMode_Dual) + { + priv->click_mode = CM_DUAL; + DBG(6, ErrorF("%s\tset click mode to DUAL TOUCH\n", CI_INFO)); + return (Success); + } + else if (mode == ClickMode_ZPress) + { + priv->click_mode = CM_ZPRESS; + DBG(6, ErrorF("%s\tset click mode to Z-Press\n", CI_INFO)); + return (Success); + } +#endif + else + { + ErrorF("%sUnknown mode for Citron Touchscreen Switchmode Function: 0x%02x!\n", CI_ERROR, mode); + return (!Success); + } +} + +/***************************************************************************** + * [ConvertProc] + ****************************************************************************/ +static Bool +ConvertProc (LocalDevicePtr local, + int first, + int num, + int v0, + int v1, + int v2, + int v3, + int v4, + int v5, + int *x, + int *y) +{ + cit_PrivatePtr priv = (cit_PrivatePtr) (local->private); + + DBG(5, ErrorF("%sConvertProc called(first=%d, num=%d, v0=%d, v1=%d, v2=%d, v3=%d\n", + CI_INFO, first, num, v0, v1, v2, v3)); + if (priv->reporting_mode == TS_Raw) + { + *x = xf86ScaleAxis (v0, 0, priv->screen_width, priv->min_x, + priv->max_x); + *y = xf86ScaleAxis (v1, 0, priv->screen_height, priv->min_y, + priv->max_y); + } + else + { + *x = v0; + *y = v1; + } + DBG(6, ErrorF("%s\t+ x=%d, y=%d\n",CI_INFO, *x, *y)); + return (TRUE); +} + +/***************************************************************************** + * [QueryHardware] + ****************************************************************************/ +static Bool +QueryHardware (LocalDevicePtr local, int *errmaj, int *errmin) +{ + cit_PrivatePtr priv = (cit_PrivatePtr) (local->private); + unsigned char x; + int i, cnt; + int err; /* for WAIT */ + int init = FALSE; + + /* Reset the IRT from any mode and wait for end of warmstart */ + DBG(5, ErrorF("%sQueryHardware called\n", CI_INFO)); + +/* Will not work with XFree86 4.0 */ +/* xf86SerialSendBreak (local->fd, 2); */ + cit_Flush(priv->buffer); + +/* Test if touch is already initialized */ + cit_SendCommand(priv->buffer, C_GETORIGIN, 0); + + /* wait max. 0.5 seconds for acknowledge */ + DBG(6, ErrorF("%s\t* waiting for acknowledge\n", CI_INFO)); +/* WAIT(50); */ + XisbBlockDuration (priv->buffer, 500000); + cnt = 0; + err = FALSE; + + while ((i=XisbRead(priv->buffer)) != -1) + { + DBG(7, ErrorF("%s\t* 0x%02X received - cnt %d\n",CI_INFO, i, cnt)); + { + switch (cnt) + { + + case 0: + if ((unsigned char)i != CTS_STX) + init = TRUE; + break; + + case 1: + if ((unsigned char)i != (CMD_REP_CONV & C_GETORIGIN)) + init = TRUE; + break; + + case 2: + if ((unsigned char)i > 3) + init = TRUE; + break; + + case 3: + if ((unsigned char)i != CTS_ETX) + init = TRUE; + break; + } + } + cnt++; + if(init) + break; + } + /* Touch is physically not connected or sio problem or break */ + cit_Flush(priv->buffer); /* flush the buffer and wait for break */ + if(cnt < 3) + { + WAIT(150); + /* if we have 0 in the buffer I assume we got a break */ + if (XisbRead(priv->buffer) == 0) + { + + DBG(6, ErrorF("%s+ BREAK detected - cnt=%d\n", CI_INFO, cnt)); + init = TRUE; + } + else /* if nothing is in the buffer I assume the touch is not connected */ + { + ErrorF("%sTouch not connected - please connect - cnt=%d\n", CI_ERROR, cnt); + return(Success); /* If success is returned we can later connect */ + } /* the touch again when it was reconnected without */ + } /* restarting X */ + + /* if init is true, we have to (re)initialize the touch */ + if (init) + { + ErrorF("%sTouch not initialized yet\n",CI_INFO); + + /* + * IRT signals end of startup by sending BREAKS with 100 ms length. + * wait a maximum of 2 seconds for at least 2 consecutive breaks + * to be sure the IRT is really initialized + */ + cit_Flush(priv->buffer); /* clear the buffer and wait for break */ + DBG(6, ErrorF("%s\t* waiting for BREAKS...\n", CI_INFO)); + for (i=0, cnt=0; (i<20) && (cnt<2); i++) + { +/* millisleep (105); */ + WAIT(120); /* wait a little bit longer than 100 ms */ + DBG(7, ErrorF("%s\t (loop %d)\n", CI_INFO, i)); + if (XisbRead(priv->buffer) == 0) + { + cnt++; + DBG(6, ErrorF("%s\t+ BREAK %d detected\n", CI_INFO, cnt)); + } + else + { + cnt = 0; + } + } + if (cnt < 2) + { + ErrorF("%sCannot reset Citron Infrared Touch!\n", CI_ERROR); +/* *errmaj = LDR_NOHARDWARE; */ + return (!Success); + } + /* Now initialize IRT to CTS Protocol */ + DBG(6, ErrorF("%s\t* initializing to CTS mode\n", CI_INFO)); + x = 0x0d; + for (i=0; i<2; i++) + { + XisbWrite(priv->buffer, &x, 1); +/* millisleep (50); */ + WAIT(50); + } + x = MODE_D; + XisbWrite(priv->buffer, &x, 1); + + /* wait max. 0.5 seconds for acknowledge */ + DBG(6, ErrorF("%s\t* waiting for acknowledge\n", CI_INFO)); + XisbBlockDuration (priv->buffer, 500000); + cnt = 0; + while ((i=XisbRead(priv->buffer)) != -1) + { + DBG(7, ErrorF("%s\t* 0x%02X received - waiting for CTS_XON\n",CI_INFO, i)); + if ((unsigned char)i == CTS_XON) + break; + if(cnt++ > 100) return (Success); /* emergency stop */ + } + if ((unsigned char)i != CTS_XON) + { + ErrorF("%sNo acknowledge from Citron Infrared Touch!\n", CI_ERROR); +/* *errmaj = LDR_NOHARDWARE; */ + return (!Success); + } + } + /* now we have the touch connected, do the initialization stuff */ + DBG(6, ErrorF("%s\t+ Touch connected!\n",CI_INFO)); + cit_Flush(priv->buffer); + + DBG(6, ErrorF("%s\t+ requesting pressure sensors report\n",CI_INFO)); + if (cit_GetPressureSensors(priv)!=Success) + { + ErrorF("%sNo pressure sensors report received from Citron Touchscreen!\n",CI_ERROR); + } + + DBG(5, ErrorF("%s ClickMode is %d\n",CI_INFO, priv->click_mode)); + if(priv->click_mode == NO_CLICK_MODE) /* no click mode set in XF86Config */ + { + priv->click_mode = (priv->pressure_sensors > 0) ? CM_ZPRESS : CM_ENTER; + DBG(5, ErrorF("%sClickMode set to %d\n",CI_INFO, priv->click_mode)); + } + + cit_SendCommand(priv->buffer, C_SETAREAFLAGS, 1, AOF_ADDEXIT + | AOF_ADDCOORD + | AOF_ACTIVE + | AOF_ADDPRESS); + + cit_SendCommand(priv->buffer, C_SETAREAMODE, 1, AOM_CONT); + + cit_SendCommand(priv->buffer, C_SETCONTTIME, 1, 20); + + cit_SendCommand(priv->buffer, C_SETDUALTOUCHING, 1, DT_ERROR); + + cit_SendCommand(priv->buffer, C_SETAREAPRESSURE, 1, LOBYTE(priv->button_threshold)); + + cit_SendCommand(priv->buffer, C_SETRESOLUTION, 4, + LOBYTE(CIT_DEF_MAX_X), + HIBYTE(CIT_DEF_MAX_X), + LOBYTE(CIT_DEF_MAX_Y), + HIBYTE(CIT_DEF_MAX_Y)); + + cit_SendCommand(priv->buffer, C_SETPWM, 2, + LOBYTE(priv->pwm_active), + LOBYTE(priv->pwm_sleep)); + + cit_SendCommand(priv->buffer, C_SETBEAMTIMEOUT, 2, + LOBYTE(priv->beam_timeout), + HIBYTE(priv->beam_timeout)); + + cit_SendCommand(priv->buffer, C_SETORIGIN, 1, LOBYTE(priv->origin)); + cit_SendCommand(priv->buffer, C_SETTOUCHTIME, 1, LOBYTE(priv->touch_time)); + + cit_SendCommand(priv->buffer, C_SETSLEEPMODE, 5, + LOBYTE(priv->sleep_mode), + LOBYTE(priv->sleep_time_act), + HIBYTE(priv->sleep_time_act), + LOBYTE(priv->sleep_time_scan), + HIBYTE(priv->sleep_time_scan)); + + cit_SendCommand(priv->buffer, C_SETDOZEMODE, 5, + LOBYTE(priv->doze_mode), + LOBYTE(priv->doze_time_act), + HIBYTE(priv->doze_time_act), + LOBYTE(priv->doze_time_scan), + HIBYTE(priv->doze_time_scan)); + + cit_SendCommand(priv->buffer, C_SETTRANSMISSION, 1, TM_TRANSMIT); + cit_SendCommand(priv->buffer, C_SETSCANNING, 1, 1); + + + if(priv->query_state == 0) /* do error reporting only 1 time */ + { + priv->query_state++; + + DBG(6, ErrorF("%s\t+ requesting initial errors report\n",CI_INFO)); + if (cit_GetInitialErrors(priv)!=Success) + { + ErrorF("%sNo initial error report received from Citron Touchscreen!\n",CI_ERROR); + *errmaj = LDR_NOHARDWARE; + return (!Success); + } + DBG(6, ErrorF("\t+ requesting defective beams report\n")); + if (cit_GetDefectiveBeams(priv)!=Success) + { + ErrorF("%sNo defective beams report received from Citron Touchscreen!\n",CI_ERROR); + *errmaj = LDR_NOHARDWARE; + return (!Success); + } + DBG(6, ErrorF("\t+ requesting touch revisions\n")); + if (cit_GetDesignator(priv)!=Success) + { + ErrorF("%sNo designator received from Citron Touchscreen!\n",CI_ERROR); + *errmaj = LDR_NOHARDWARE; + return (!Success); + } + if (cit_GetRevision(priv, GR_SYSMGR)!=Success) + { + ErrorF("%sNo system manager module revision received from Citron Touchscreen!\n",CI_ERROR); + *errmaj = LDR_NOHARDWARE; + return (!Success); + } + if (cit_GetRevision(priv, GR_HARDWARE)!=Success) + { + ErrorF("%sNo hardware module revision received from Citron Touchscreen!\n",CI_ERROR); + *errmaj = LDR_NOHARDWARE; + return (!Success); + } + if (cit_GetRevision(priv, GR_PROCESS)!=Success) + { + ErrorF("%sNo process module revision received from Citron Touchscreen!\n",CI_ERROR); + *errmaj = LDR_NOHARDWARE; + return (!Success); + } + if (cit_GetRevision(priv, GR_PROTOCOL)!=Success) + { + ErrorF("%sNo protocol module revision received from Citron Touchscreen!\n",CI_ERROR); + *errmaj = LDR_NOHARDWARE; + return (!Success); + } + if (cit_GetRevision(priv, GR_HWPARAM)!=Success) + { + ErrorF("%sNo hardware parameter module revision received from Citron Touchscreen!\n",CI_ERROR); + *errmaj = LDR_NOHARDWARE; + return (!Success); + } + } + + DBG(6, ErrorF("%s\t+ Touch initialized - %d\n",CI_INFO, priv->query_state)); + + return (Success); +} + + +/***************************************************************************** + * [cit_GetPacket] + ****************************************************************************/ +static Bool +cit_GetPacket (cit_PrivatePtr priv) +{ + int c; + int errmaj, errmin; + + DBG(GP, ErrorF("%scit_GetPacket called\n", CI_INFO)); + DBG(GP, ErrorF("%s\t* initial lex_mode =%d (%s)\n", CI_INFO, priv->lex_mode, + priv->lex_mode==cit_idle ?"idle": + priv->lex_mode==cit_getID ?"getID": + priv->lex_mode==cit_collect ?"collect": + priv->lex_mode==cit_escape ?"escape": + "???")); + while ((c = XisbRead (priv->buffer)) >= 0) + { +#if(0) + DBG(GP, ErrorF("%s c=%d\n",CI_INFO, c)); +#endif + if (c == CTS_STX) + { + DBG(GP, ErrorF("%s\t+ STX detected\n", CI_INFO)); + /* start of report received */ + if (priv->lex_mode != cit_idle) + DBG(7, ErrorF("%s\t- no ETX received before this STX!\n", CI_WARNING)); + priv->lex_mode = cit_getID; + DBG(GP, ErrorF("%s\t+ new lex_mode == getID\n", CI_INFO)); + } + else if (c == CTS_ETX) + { + DBG(GP, ErrorF("%s\t+ ETX detected\n", CI_INFO)); + /* end of command received */ + /* always IDLE after report completion */ + DBG(GP, ErrorF("%s\t+ new lex_mode == idle\n", CI_INFO)); + if (priv->lex_mode == cit_collect) + { + DBG(GP, ErrorF("%s\t+ Good report received\n", CI_INFO)); + priv->lex_mode = cit_idle; + return (Success); + } + DBG(GP, ErrorF("%s\t- unexpected ETX received!\n", CI_WARNING)); + priv->lex_mode = cit_idle; + } + else if (c == CTS_ESC) + { + DBG(GP, ErrorF("%s\t+ escape detected\n", CI_INFO)); + /* next character is encoded */ + if (priv->lex_mode != cit_collect) + { + DBG(GP, ErrorF("%s\t- unexpected control character received\n", CI_WARNING)); + } + else + { + priv->lex_mode = cit_escape; + DBG(GP, ErrorF("%s\t+ new lex_mode == escape\n", CI_INFO)); + } + } + else if ((c < CTS_CTRLMIN) || (c > CTS_CTRLMAX)) + { + /* regular report data received */ + if (priv->lex_mode == cit_getID) + { /* receive report ID */ + priv->packeti = 0; + priv->packet[priv->packeti++] = (unsigned char)c; + priv->lex_mode = cit_collect; + DBG(GP, ErrorF("%s\t+ identifier captured, new lex_mode == collect\n", CI_INFO)); + } + else if ((priv->lex_mode == cit_collect) || (priv->lex_mode == cit_escape)) + { /* receive command data */ + if (priv->lex_mode == cit_escape) + { /* decode encoded data byte */ + c &= CTS_DECODE; /* decode data */ + priv->lex_mode = cit_collect; + DBG(GP, ErrorF("%s\t+ decoded character = 0x%02X\n", CI_INFO, c)); + DBG(GP, ErrorF("%s\t+ new lex_mode = collect\n", CI_INFO)); + } + if (priv->packeti < CTS_PACKET_SIZE) + { /* add data bytes to buffer */ + priv->packet[priv->packeti++] = (unsigned char)c; + } + else + { + DBG(GP, ErrorF("%s\t- command buffer overrun\n", CI_ERROR)); + /* let's reinitialize the touch - maybe it sends breaks */ + cit_Flush(priv->buffer); + + } + } + else + { + /* this happens e.g. when the touch sends breaks, so we try to reconnect */ + DBG(GP, ErrorF("%s\t- unexpected non control received!\n", CI_WARNING)); + DBG(GP, ErrorF("%s\t- Device not connected - trying to reconnect ...\n", CI_WARNING)); + if (QueryHardware (priv->local, &errmaj, &errmin) != Success) + ErrorF ("%s\t- Unable to query/initialize Citron Touch hardware.\n", CI_ERROR); + else + ErrorF ("%s\t- Citron Touch reconnected\n", CI_INFO); + + } + } + else if (c != CTS_XON && c != CTS_XOFF) + { + DBG(GP, ErrorF("%s\t- unhandled control character received!\n", CI_WARNING)); + } + } + DBG(GP, ErrorF("%scit_GetPacket exit !Success\n", CI_INFO)); + return (!Success); +} + + +/***************************************************************************** + * [cit_Flush] + ****************************************************************************/ +static void +cit_Flush (XISBuffer *b) +{ + DBG(7, ErrorF("%scit_Flush called\n", CI_INFO)); + XisbBlockDuration(b, 0); + while (XisbRead(b) > 0); +} + + + +/***************************************************************************** + * [cit_Beep] + ****************************************************************************/ +static void +cit_Beep(cit_PrivatePtr priv, int press) +{ +#ifdef CIT_BEEP + if(priv->beep == 0) + return; + + /* ring release bell */ + if(press == 0) + + /* [0]: volume, [1]: pitch, [2]: duration */ + /* formula is: ((1193190 / freq) & 0xffff) | */ + /* (((unsigned long)duration * loudness / 50) << 16)) */ + /* .. whatever the inventor wants to intend by it, I don't know (PK) */ + + xf86SoundKbdBell(priv->rel_vol, priv->rel_pitch, priv->rel_dur); + + else + /* ring press bell */ + xf86SoundKbdBell(priv->press_vol,priv->press_pitch, priv->press_dur); + + DBG(7, ErrorF("%scit_Beep called - %s\n", CI_INFO, (press == 0) ? "release" : "press")); +#endif +} + + +/***************************************************************************** + * [cit_SendCommand] + ****************************************************************************/ +static void +cit_SendCommand (XISBuffer *b, unsigned char cmd, int cnt, ...) +{ + va_list ap; + unsigned char data, x; + + va_start(ap, cnt); + + DBG(7, ErrorF("%scit_SendCommand(cmd=0x%02X, cnt=%d, ...)\n", CI_INFO, cmd, cnt)); + x = CTS_STX; + XisbWrite(b, &x, 1); /* transmit start of packet */ + XisbWrite(b, &cmd, 1); /* transmit command code */ + x = CTS_ESC; + while (cnt-- > 0) + { /* encode and transmit optional parameters */ + data = va_arg(ap, int); + if (data >= CTS_CTRLMIN && data <= CTS_CTRLMAX) + { /* data has to be encoded */ + data |= CTS_ENCODE; + XisbWrite(b, &x, 1); /* mark coded data */ + } + XisbWrite(b, &data, 1); /* transmit data */ + } + x = CTS_ETX; + XisbWrite(b, &x, 1); /* transmit end of packet */ + va_end(ap); +} + + +/***************************************************************************** + * [cit_GetInitialErrors] + ****************************************************************************/ +static Bool cit_GetInitialErrors(cit_PrivatePtr priv) +{ + unsigned long errors; + int i; + Bool res; + + cit_Flush(priv->buffer); + cit_SendCommand(priv->buffer, C_GETERRORS, 1, GE_INITIAL); + /* + touch responds within 1 millisecond, + but it takes some time, until the command is sent! + */ + for (i=0; i<5; i++) + { + XisbBlockDuration(priv->buffer, 500000); + res = cit_GetPacket(priv); + if ((res == Success) || (priv->lex_mode == cit_idle)); + break; + } + if (res != Success) + { + DBG(5, ErrorF("%sNo packet received!\n", CI_NOTICE)); + return (!Success); + } + /* examine packet */ + if (priv->packeti != 6) + { + DBG(5, ErrorF("%sWrong packet length (expected 6, received %d bytes)\n", CI_NOTICE, priv->packeti)); + return (!Success); + } + if (priv->packet[0] != (C_GETERRORS & CMD_REP_CONV)) + { + DBG(5, ErrorF("%sWrong packet identifier (expected 0x%02X, received 0x%02X)\n", CI_NOTICE, + (C_GETERRORS & CMD_REP_CONV), priv->packet[0])); + return (!Success); + } + if (priv->packet[1] != GE_INITIAL) + { + DBG(5, ErrorF("%sWrong packet selector (expected 0x%02X, received 0x%02X)\n", CI_NOTICE, + GE_INITIAL, priv->packet[1])); + return (!Success); + } + /* this is our packet! check contents */ + errors = 0x00000001UL * (unsigned long)priv->packet[2] + + 0x00000100UL * (unsigned long)priv->packet[3] + + 0x00010000UL * (unsigned long)priv->packet[4] + + 0x10000000UL * (unsigned long)priv->packet[5]; + DBG(6, ErrorF("%sinitial errors = 0x%08lX\n", CI_NOTICE, errors)); + if (errors == 0x00000000UL) + { + ErrorF("%sNo initialization errors detected.\n", CI_INFO); + } + if (errors & IE_SMCHKSUM) + { + ErrorF("%sSystem Manager Module checksum error!\n", CI_ERROR); + } + if (errors & IE_SMINIT) + { + ErrorF("%sSystem Manager Module initialization error!\n", CI_ERROR); + } + if (errors & IE_HWCHKSUM) + { + ErrorF("%sHardware Module checksum error!\n", CI_ERROR); + } + if (errors & IE_HWINIT) + { + ErrorF("%sHardware Module initialization error!\n", CI_ERROR); + } + if (errors & IE_HW_BEAMS) + { + ErrorF("%s broken beams during initialization detected!\n", CI_ERROR); + } + if (errors & IE_HW_PSU) + { + ErrorF("%s force sensors not operating!\n", CI_ERROR); + } + if (errors & IE_HW_CPU) + { + ErrorF("%s CPU integrity test failed!\n", CI_ERROR); + } + if (errors & IE_HW_IRAM) + { + ErrorF("%s internal RAM error!\n", CI_ERROR); + } + if (errors & IE_HW_XRAM) + { + ErrorF("%s external SRAM error!\n", CI_ERROR); + } + if (errors & IE_PCCHKSUM) + { + ErrorF("%sProcess Module checksum error!\n", CI_ERROR); + } + if (errors & IE_PCINIT) + { + ErrorF("%sProcess Module initialization error!\n", CI_ERROR); + } + if (errors & IE_PTCHKSUM) + { + ErrorF("%sProtocol Module checksum error!\n", CI_ERROR); + } + if (errors & IE_PTINIT) + { + ErrorF("%sProtocol Module initialization error!\n", CI_ERROR); + } + if (errors & IE_BICHK) + { + ErrorF("%sBurnIn Module checksum error!\n", CI_ERROR); + } + if (errors & IE_BIINIT) + { + ErrorF("%sBurnIn Module initialization error!\n", CI_ERROR); + } + if (errors & IE_FPGACHK) + { + ErrorF("%sFPGA configuration checksum error!\n", CI_ERROR); + } + if (errors & IE_HWPCHK) + { + ErrorF("%sHardware Parameter checksum error!\n", CI_ERROR); + } + return (Success); +} + + +/***************************************************************************** + * [cit_GetDefectiveBeams] + ****************************************************************************/ +static Bool cit_GetDefectiveBeams(cit_PrivatePtr priv) +{ + unsigned nx, ny; + int i; + Bool res; + + cit_Flush(priv->buffer); + cit_SendCommand(priv->buffer, C_GETERRORS, 1, GE_DEFECTBEAMS); + /* + touch responds within 1 millisecond, + but it takes some time, until the command is sent! + */ + for (i=0; i<5; i++) + { + XisbBlockDuration(priv->buffer, 500000); + res = cit_GetPacket(priv); + if ((res == Success) || (priv->lex_mode == cit_idle)); + break; + } + if (res != Success) + { + DBG(5, ErrorF("%sNo packet received!\n", CI_NOTICE)); + return (!Success); + } + /* examine packet */ + if (priv->packeti < 6) + { + DBG(5, ErrorF("%sWrong packet length (expected >= 6, received %d bytes)\n", CI_NOTICE, priv->packeti)); + return (!Success); + } + if (priv->packet[0] != (C_GETERRORS & CMD_REP_CONV)) + { + DBG(5, ErrorF("%sWrong packet identifier (expected 0x%02X, received 0x%02X)\n", CI_NOTICE, + (C_GETERRORS & CMD_REP_CONV), priv->packet[0])); + return (!Success); + } + if (priv->packet[1] != GE_DEFECTBEAMS) + { + DBG(5, ErrorF("%sWrong packet selector (expected 0x%02X, received 0x%02X)\n", CI_NOTICE, + GE_DEFECTBEAMS, priv->packet[1])); + return (!Success); + } + /* this is our packet! check contents */ + nx = 0x0001U * (unsigned)priv->packet[2] + + 0x0100U * (unsigned)priv->packet[3]; + + ny = 0x0001U * (unsigned)priv->packet[4] + + 0x0100U * (unsigned)priv->packet[5]; + /* list defective X-beams */ + if (nx > 0) + { + ErrorF("%s%u defective X-Beams detected:\n", CI_ERROR, nx); + for (i=0; i<nx; i++) + { + ErrorF("%s\tX%02u\n", CI_ERROR, (unsigned)priv->packet[6+i]); + } + } + else + { + ErrorF("%sNo defective X-beams detected.\n", CI_INFO); + } + + /* list defective Y-beams */ + if (ny > 0) + { + ErrorF("%s%u defective Y-Beams detected:\n", CI_ERROR, ny); + for (i=0; i<ny; i++) + { + ErrorF("%s\tY%02u\n", CI_ERROR, (unsigned)priv->packet[6+nx+i]); + } + } + else + { + ErrorF("%sNo defective Y-beams detected.\n", CI_INFO); + } + return (Success); +} + + +/***************************************************************************** + * [cit_GetDesignator] + ****************************************************************************/ +static Bool cit_GetDesignator(cit_PrivatePtr priv) +{ + int i,n; + Bool res; + + cit_Flush(priv->buffer); + cit_SendCommand(priv->buffer, C_GETREVISIONS, 1, GR_DESIGNATOR); + /* + touch responds within 1 millisecond, + but it takes some time, until the command is sent and received! + */ + for (i=0; i<5; i++) + { + XisbBlockDuration(priv->buffer, 500000); + res = cit_GetPacket(priv); + if ((res == Success) || (priv->lex_mode == cit_idle)); + break; + } + if (res != Success) + { + DBG(5, ErrorF("%sNo packet received!\n", CI_NOTICE)); + return (!Success); + } + /* examine packet */ + if (priv->packeti < 2+CTS_DESIGNATOR_LEN+CTS_ASSY_LEN) + { + DBG(5, ErrorF("%sWrong packet length (expected >= %d, received %d bytes)\n", CI_NOTICE, + 2+CTS_DESIGNATOR_LEN+CTS_ASSY_LEN, + priv->packeti)); + return (!Success); + } + if (priv->packet[0] != (C_GETREVISIONS & CMD_REP_CONV)) + { + DBG(5, ErrorF("%sWrong packet identifier (expected 0x%02X, received 0x%02X)\n", CI_NOTICE, + (C_GETREVISIONS & CMD_REP_CONV), priv->packet[0])); + return (!Success); + } + if (priv->packet[1] != GR_DESIGNATOR) + { + DBG(5, ErrorF("%sWrong packet selector (expected 0x%02X, received 0x%02X)\n", CI_NOTICE, + GR_DESIGNATOR, priv->packet[1])); + return (!Success); + } + /* this is our packet! check contents */ + ErrorF("%sDesignator \"", CI_INFO); + i = 2; + n = 0; + while (n++ < CTS_DESIGNATOR_LEN && priv->packet[i]!=0) + { + ErrorF("%c", priv->packet[i++]); + } + ErrorF("\"\n%sAssembly \"", CI_INFO); + i = 2 + CTS_DESIGNATOR_LEN; + n = 0; + while (n++ < CTS_ASSY_LEN && priv->packet[i]!=0) + { + ErrorF("%c", priv->packet[i++]); + } + ErrorF("\"\n"); + return (Success); +} + + +/***************************************************************************** + * [cit_GetRevision] + ****************************************************************************/ +static Bool cit_GetRevision(cit_PrivatePtr priv, int selection) +{ + int i,n; + Bool res; + + cit_Flush(priv->buffer); + cit_SendCommand(priv->buffer, C_GETREVISIONS, 1, (unsigned char)selection); + /* + touch responds within 1 millisecond, + but it takes some time, until the command is sent and received! + */ + XisbBlockDuration(priv->buffer, 500000); + while (((res = cit_GetPacket(priv)) != Success) && (priv->lex_mode != cit_idle)); + if (res != Success) + { + DBG(5, ErrorF("%sNo packet received!\n", CI_NOTICE)); + return (!Success); + } + /* examine packet */ + if (priv->packeti < 2) + { + DBG(5, ErrorF("%sWrong packet length (expected >= %d, received %d bytes)\n", CI_NOTICE, + 2, priv->packeti)); + return (!Success); + } + if (priv->packet[0] != (C_GETREVISIONS & CMD_REP_CONV)) + { + DBG(5, ErrorF("%sWrong packet identifier (expected 0x%02X, received 0x%02X)\n", CI_NOTICE, + (C_GETREVISIONS & CMD_REP_CONV), priv->packet[0])); + return (!Success); + } + if (priv->packet[1] != selection) + { + DBG(5, ErrorF("%sWrong packet selector (expected 0x%02X, received 0x%02X)\n", CI_NOTICE, + selection, priv->packet[1])); + return (!Success); + } + /* this is our packet! check contents */ + DBG(5, ErrorF("%s%s module revision ", CI_INFO, + selection == GR_SYSMGR ? "SysMgr " : + selection == GR_HARDWARE ? "Hardware" : + selection == GR_PROCESS ? "Process " : + selection == GR_PROTOCOL ? "Protocol" : + selection == GR_HWPARAM ? "HWParam " : + "???")); + i = 2; + n = 0; + DBG(5, ErrorF("\"")); + while (n < priv->packeti && priv->packet[i]!=0) + { + DBG(5, ErrorF("%c", priv->packet[i])); + i++; + } + DBG(5, ErrorF("\"\n")); + return (Success); +} + + +/***************************************************************************** + * [cit_ProcessPacket] + ****************************************************************************/ +static void cit_ProcessPacket(cit_PrivatePtr priv) +{ + int i; + + DBG(PP, ErrorF("%scit_ProcessPacket called\n", CI_INFO)); + DBG(PP, ErrorF("%s\t+ enter state = 0x%04X, dual touch count=%d\n", CI_INFO, priv->state, priv->dual_touch_count)); + /* examine message identifier */ + + priv->dual_flg = TRUE; /* Dual Touch Error occurred */ +#ifdef CIT_TIM + priv->timer_val1 = 1000; /* Timer delay [ms]*/ + priv->timer_callback = (OsTimerCallback)cit_DualTouchTimer; /* timer callback routine */ + cit_StartTimer(priv); +#endif + + switch (priv->packet[0]) + { + case R_COORD: /* new touch coordinates received */ + if (priv->packeti < 5) + { + DBG(PP, ErrorF("%s\t- coordinate message packet too short (%d bytes)\n", CI_ERROR, priv->packeti)); + break; + } + + + if (priv->dual_touch_count > 0) + priv->dual_touch_count--; + + priv->raw_x = 0x0001U * priv->packet[1] + + 0x0100U * priv->packet[2]; + priv->raw_y = 0x0001U * priv->packet[3] + + 0x0100U * priv->packet[4]; + + priv->raw_min_x = min(priv->raw_min_x, priv->raw_x); + priv->raw_max_x = max(priv->raw_max_x, priv->raw_x); + priv->raw_min_y = min(priv->raw_min_y, priv->raw_y); + priv->raw_max_y = max(priv->raw_max_y, priv->raw_y); + + priv->state |= CIT_TOUCHED; + + DBG(PP, ErrorF("%s\t+ COORD message raw (%d,%d)\n", CI_INFO, priv->raw_x, priv->raw_y)); + break; + + case R_EXIT: /* touch area no longer interrupted */ + if (priv->packeti < 5) + { + DBG(PP, ErrorF("%s\t- exit message packet too short (%d bytes)\n", CI_ERROR, priv->packeti)); + break; + } + + priv->state &= ~(CIT_TOUCHED | CIT_PRESSED); + priv->dual_touch_count = 0; + priv->raw_x = 0x0001U * priv->packet[1] + + 0x0100U * priv->packet[2]; + priv->raw_y = 0x0001U * priv->packet[3] + + 0x0100U * priv->packet[4]; +#ifdef CIT_TIM + cit_CloseTimer(priv); /* close timer if exit message was received */ +#endif + DBG(PP, ErrorF("%s\t+ EXIT message (%d,%d)\n", CI_INFO, priv->raw_x, priv->raw_y)); + break; + + case R_DUALTOUCHERROR: + if (priv->dual_touch_count < priv->max_dual_count) + priv->dual_touch_count++; + DBG(PP, ErrorF("%s\t+ DUAL TOUCH ERROR message received\n", CI_INFO)); + break; + + case R_PRESSURE: /* pressure message received */ + if (priv->packeti < 2) + { + DBG(PP, ErrorF("%s\t- pressure message packet too short (%d bytes)\n", CI_ERROR, priv->packeti)); + break; + } + priv->state |= CIT_TOUCHED; + if (priv->packet[1] == PRESS_EXCEED) + priv->state |= CIT_PRESSED; + else if(priv->packet[1] == PRESS_BELOW) + { + priv->state &= ~CIT_PRESSED; + } + else + DBG(PP, ErrorF("%sPressure Message Error\n", CI_ERROR)); + + DBG(PP, ErrorF("%s\t+ pressure %s message\n", CI_INFO, priv->packet[1] ? "enter":"exit")); + break; + + default: + DBG(PP, ErrorF("%s\t* unhandled message:", CI_ERROR)); + for (i=0; i<priv->packeti; i++) + { + DBG(PP, ErrorF(" 0x%02X", priv->packet[i])); + } + DBG(PP, ErrorF("\n")); + } + /* generate button state */ + switch (priv->click_mode) + { + case CM_ZPRESS: + DBG(PP, ErrorF("%s\t+ ZPress, button ", CI_INFO)); + if (priv->state & CIT_PRESSED) + { + priv->state |= CIT_BUTTON; + DBG(PP, ErrorF("down")); + } + else + { + priv->state &= ~CIT_BUTTON; + DBG(PP, ErrorF("up")); + } + + break; + + case CM_ZPRESSEXIT: + DBG(PP, ErrorF("%s\t+ ZPressExit, button ", CI_INFO)); + if (priv->state & CIT_PRESSED) + { + priv->state |= CIT_BUTTON; + DBG(PP, ErrorF("down")); + } + else if (!(priv->state & CIT_TOUCHED)) + { + priv->state &= ~CIT_BUTTON; + DBG(PP, ErrorF("up")); + } + break; + + case CM_DUAL: + DBG(PP, ErrorF("%s\t+ Dual Touch, button ", CI_INFO)); + if ((priv->dual_touch_count == priv->max_dual_count) && (priv->state & CIT_TOUCHED)) + { + priv->state |= CIT_BUTTON; + DBG(PP, ErrorF("down")); + } + else if (priv->dual_touch_count == 0) + { + priv->state &= ~CIT_BUTTON; + DBG(PP, ErrorF("up")); + } + break; + + case CM_DUALEXIT: + DBG(PP, ErrorF("%s\t+ Dual Exit, button ", CI_INFO)); + if ((priv->dual_touch_count == priv->max_dual_count) && (priv->state & CIT_TOUCHED)) + { + priv->dual_flg = TRUE; + priv->state |= CIT_BUTTON; + DBG(PP, ErrorF("down")); + } + else if (!(priv->state & CIT_TOUCHED)) + { + priv->state &= ~CIT_BUTTON; + DBG(PP, ErrorF("up")); + } + break; + + default: /* default to enter mode */ + DBG(PP, ErrorF("%s\t+ Enter Mode, button ", CI_INFO)); + if (priv->state & CIT_TOUCHED) + { + priv->state |= CIT_BUTTON; + DBG(PP, ErrorF("down")); + } + else + { + priv->state &= ~CIT_BUTTON; + DBG(PP, ErrorF("up")); + } + break; + } + DBG(PP, ErrorF("\n")); + DBG(PP, ErrorF("%s\t+ Click Mode=%d\n", CI_INFO, priv->click_mode)); + DBG(PP+1, ErrorF("%s\t+ exit state = 0x%04X, dual touch count=%d\n", CI_INFO, priv->state, priv->dual_touch_count)); + DBG(PP+1, ErrorF("%s\t raw_x=%d, raw_y=%d\n", CI_INFO, priv->raw_x, priv->raw_y)); +} + + + +/***************************************************************************** + * [cit_GetPressureSensors] + ****************************************************************************/ +static Bool cit_GetPressureSensors(cit_PrivatePtr priv) +{ + int i; + Bool res; + + cit_Flush(priv->buffer); + cit_SendCommand(priv->buffer, C_GETHARDWARE, 1, GH_SENSORCOUNT); + /* + touch responds within 1 millisecond, + but it takes some time, until the command is sent and received! + */ + for (i=0; i<5; i++) + { + XisbBlockDuration(priv->buffer, 500000); + res = cit_GetPacket(priv); + if ((res == Success) || (priv->lex_mode == cit_idle)); + break; + } + if (res != Success) + { + DBG(5, ErrorF("%sNo packet received!\n", CI_NOTICE)); + return (!Success); + } + /* examine packet */ + if (priv->packeti < 2+CTS_SENSORCOUNT_LEN) + { + DBG(5, ErrorF("%sWrong packet length (expected >= %d, received %d bytes)\n", CI_NOTICE, + 2+CTS_SENSORCOUNT_LEN, + priv->packeti)); + return (!Success); + } + if (priv->packet[0] != (C_GETHARDWARE & CMD_REP_CONV)) + { + DBG(5, ErrorF("%sWrong packet identifier (expected 0x%02X, received 0x%02X)\n", CI_NOTICE, + (C_GETHARDWARE & CMD_REP_CONV), priv->packet[0])); + return (!Success); + } + if (priv->packet[1] != GH_SENSORCOUNT) + { + DBG(5, ErrorF("%sWrong packet selector (expected 0x%02X, received 0x%02X)\n", CI_NOTICE, + GH_SENSORCOUNT, priv->packet[1])); + return (!Success); + } + /* this is our packet! check contents */ + ErrorF("%sPressureSensors: \"%d\"\n", CI_INFO, priv->packet[2]); + priv->pressure_sensors = priv->packet[2]; + return (Success); +} + + diff --git a/xc/programs/Xserver/hw/xfree86/input/citron/citron.cpp b/xc/programs/Xserver/hw/xfree86/input/citron/citron.cpp new file mode 100644 index 000000000..444eae0dc --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/input/citron/citron.cpp @@ -0,0 +1,631 @@ +.\" Copyright (c) 2000 Peter Kunzmann <support@@citron.de> +.\" +.\" This is free documentation; you can redistribute it and/or +.\" modify it under the terms of the GNU General Public License as +.\" published by the Free Software Foundation; either version 2 of +.\" the License, or (at your option) any later version. +.\" +.\" The GNU General Public License's references to "object code" +.\" and "executables" are to be interpreted as the output of any +.\" document formatting or typesetting system, including +.\" intermediate and printed output. +.\" +.\" This manual is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" $XFree86: xc/programs/Xserver/hw/xfree86/input/citron/citron.cpp,v 1.1 2000/11/02 02:51:21 dawes Exp $ +.\" +.TH CITRON 4 "Version 4.0.1" "XFREE86" +.SH NAME +citron \- Citron Infrared Touch Driver (CiTouch) +.SH SYNOPSIS +.B "Section ""InputDevice""" +.br +.BI " Identifier """ idevname """" +.br +.B " Driver ""citron""" +.br +.BI " Option ""Device"" """ devpath """" +.br +\ \ ... +.br +.B EndSection +.SH DESCRIPTION +.B citron +is a XFree86 input driver for +.I Citron Infrared Touch +devices. +.PP +The +.B citron +driver acts as a pointer input device, and may be used as the +X server's core pointer. It is connected via a "RS232" with the host. +.SH SUPPORTED HARDWARE +At the moment the following touches are supported. They are also +available as +.I ZPress +touches. + +.B IRT6I5-V2.x + 6.5 inch Infrared Touch + +.B IRT10I4-V4.x + 10.4 inch Infrared Touch + +.B IRT12I1-V2.x + 12.1 inch Infrared Touch + +.B IRT15I1-V1.x + 15.1 inch Infrared Touch + +.SH CONFIGURATION DETAILS +Please refer to XF86Config(5x) for general configuration +details and for options that can be used with all input drivers. This +section only covers configuration details specific to this driver. +For better understanding please read also the +.B CTS +and various +.B IRT +manuals which are available in "pdf" format from Citron web page +.B www.citron.de +or directly from Citron. + +.PP +.PP +The following driver +.B Options +are supported: +.TP 7 +.BI "Option ""Device"" """ devpath """ +Specify the device path for the citron touch. Valid devices are: +.PP +.RS 12 +/dev/ttyS0, /dev/ttyS1, .... +This option is mandatory. +.RE +.PP +.RS 7 +It's important to specify the right device Note: com1 -> /dev/ttyS0, com2 -> /dev/ttyS1 .... + +.RE +.TP 7 +.BI "Option ""ScreenNumber"" """ "screennumber" """ +sets the +.I screennumber +for the +.I citron +InputDevice. +.PP +.RS 7 +.I Default: +ScreenNumber: "0" + +.RE +.TP 7 +.BI "Option ""MinX, MinY"" """ value """ +These are the minimum X and Y values for the +.I citron +input device. +.PP +.RS 7 +Note: MinX, MinY must be less than MaxX, MaxY. +.PP +.I Range: +"0" - "65535" +.PP +.I Default: +MinX: "0" MinY: "0" + + +.RE +.TP 7 +.BI "Option ""MaxX, MaxY"" """ value """ +These are the maximum X and Y values for the +.I citron +input device. +.PP +.RS 7 +Note: MaxX, MaxY must be greater than MinX, MinY. +.PP +.I Range: +"0" - "65535" +.PP +.I Default: +MaxX: "65535" MaxY: "65535" + + +.RE +.TP 7 +.BI "Option ""ButtonNumber"" """ value """ +This value is responsible for the +.I button number +that is returned within the xf86PostButton event message +.PP +.RS 7 +.I Range: +"0" - "255" +.PP +.I Default: +"1" + +.RE +.TP 7 +.BI "Option ""ButtonThreshold"" """ value """ +This value is responsible for the +.I button threshold. +It changes the pressure sensitivity of the touch. A higher number +corresponds to a higher pressure. +.PP +.RS 7 +Note: This feature is only available with pressure sensitive hardware. +.PP +.I Range: +"0" - "255" +.PP +.I Default: +"20" + +.RE +.TP 7 +.B Sleep-Mode +If the IRT is in +.I Doze-Mode +and Touch Zone is not interrupted for another +certain span of time, the so-called +.I Sleep-Mode +is activated. The +.I Sleep-Mode +decreases the scan rate of the beams even further than +the +.I Doze-Mode +does (see below). This way the life expectancy of the beams is +prolonged and the power consumption of the IRT is reduced. +As soon as an interruption of the Touch Zone is detected, the +.I Sleep-Mode +is deactivated and the Touch Zone will again be scanned with +the maximum speed. With the Sleep-Mode activated, +depending on the set scan rate the IRT's response time can be +considerably longer as in normal operation. If, for example, +a scan rate of 500 ms / scan is set, it may last up to a half +of a second until the IRT detects the interruption and deactivates +the +.I Sleep-Mode. + +.PP +.RE +.TP 7 +.BI "Option ""SleepMode"" """ mode """ +This value is responsible for the +.I sleep-mode +of the touch. +.RS 7 +Determines the behaviour of the Sleep-Mode. + +.B 0x00 + No message at either activation or deactivation + +.B 0x01 + Message at activation + +.B 0x02 + Message at deactivation + +.B 0x03 + Message at activation and deactivation + +.B 0x10 +GP_OUT output set according to the Sleep-Mode status + +.I Values: +"0" "1" "2" "3" "16" + +.I Default: +"0" + +.RE +.TP 7 +.BI "Option ""SleepTime"" """ time """ +This value is responsible for the +.I sleep-time +of the touch. It is the activation time in seconds +("0" = immediately activated, "65535" = always deactivated). +.RS 7 +.PP +.I Range: +"0" - "65535" [s] +.PP +.I Default: +"65535" => deactivated + +.RE +.TP 7 +.BI "Option ""SleepScan"" """ scan """ +This value is responsible for the +.I scan-time +of the touch. This is the time interval between two scan operations +while in Sleep-Mode. The time interval is set in steps +of milliseconds. +.RS 7 +.PP +.I Range: +"0" - "65535" [ms] +.PP +.I Default: +"500" + +.RE +.TP 7 +.BI "Option ""PWMActive"" """ value """ +This value determines the mark-to-space ratio of the +.I PWM +output while in normal operation (sleep-mode not active). +Higher values result in longer pulse widths. This output +signal can be used in conjunction with the +.I Citron AWBI +to do backlight-dimming via the touch. +.RS 7 +.PP +.I Range: +"0" - "255" +.PP +.I Default: +"255" (max. brightness) + + +.RE +.TP 7 +.BI "Option ""PWMSleep"" """ value """ +This value determines the mark-to-space ratio of the +.I PWM +output while in sleep-mode (-> +.I SleepMode, SleepScan, SleepTime +) operation (sleep-mode active). +Higher values result in longer pulse widths. +.RS 7 +.PP +.I Range: +"0" - "255" +.PP +.I Default: +"255" (max. brightness) + +.RE +.TP 7 +.BI "Option ""ClickMode"" """ mode """ +With mode one can select between 5 +.I ClickModes + +.I """1"" = ClickMode Enter + +With this mode every interruption of the infrared beams will +activate a ButtonPress event and after the interruption a +ButtonRelease event will be sent. + +.I """2"" = ClickMode Dual + +With this mode every interruption will sent a Proximity event and +every second interruption a ButtonPress event. With the release of +the interruption (while one interruption is still active) a +ButtonRelease event will be sent. + +.I """3"" = ClickMode Dual Exit + +With this mode every interruption will sent a ProximityIn event and +every second interruption a ButtonPress event. With the release of +the interruption (while one interruption is still active) no +ButtonRelease event will be sent. Only if all interruptions are released +a ButtonRelease followed by a ProximityOut event will be sent. + +.I """4"" = ClickMode ZPress + +With this mode every interruption will sent a ProximityIn event. Only if +a certain pressure is exceeded a ButtonPress event will occur. If the +pressure falls below a certain limit a ButtonRelease event will be sent. +After also the interruption is released a ProximityOut event is generated. + +.I """5"" = ClickMode ZPress Exit + +This mode is similat to "Clickmode Dual Exit". +The first interruption of the beams will sent a ProximityIn event. Only if +a certain pressure is exceeded a ButtonPress event will occur. If the +pressure falls below a certain limit no ButtonRelease event will be sent. +After the interruption is also released a ButtonRelease followed by +a ProximityOut event is generated. +.RS 7 +.PP +.I Range: +"1" - "5" +.PP +.I Default: +"1" (ClickMode Enter) + +.RE +.TP 7 +.BI "Option ""Origin"" """ value """ +This value sets the coordinates origin to one of the four corners of +the screen. +The following values are accepted: +"0" TOPLEFT: Origin set to the left-hand side top corner. +"1" TOPRIGHT: Origin set to the right-hand side top corner. +"2" BOTTOMRIGHT: Origin set to the right-hand side bottom corner. +"3" BOTTOMLEFT: Origin set to the left-hand side bottom corner. +.RS 7 +.PP +.I Range: +"0" - "3" +.PP +.I Default: +"0" (TOPLEFT) + +.RE +.TP 7 +.B "Doze-Mode" +If for a certain span of time the Touch Zone is not interrupted, +the so-called Doze-Mode is automatically activated. The activated +Doze-Mode slightly decreases the scan rate of the beams. This way +the power consumption of the IRT is reduced. As soon as an +interruption of the Touch Zone is detected, the Doze-Mode +is deactivated and the Touch Zone will again be scanned with +the maximum speed. + +.RE +.TP 7 +.BI "Option ""DozeMode"" """ mode """ +This value is responsible for the +.I doze-mode +of the touch. +.RS 7 +.PP +Determines the behaviour of the Doze-Mode. +.PP +0x00 No message at either activation or deactivation + +0x01 Message at activation + +0x02 Message at deactivation + +0x03 Message at activation and deactivation + +0x10 GP_OUT output set according to the Doze-Mode status + +If the GP_OUT output is already controlled by the +.I Sleep-Mode +it is no longer available as an output port anymore. +.PP +.I Values: +"0" "1" "2" "3" "16" +.PP +.I Default: +"0" + + + +.RE +.TP 7 +.BI "Option ""DozeTime"" """ time """ +This value is responsible for the +.I doze-time +of the touch. It is the activation time in seconds +("0" = immediately activated, "65535" = always deactivated). +.RS 7 +.PP +.I Range: +"0" - "65535" [s] +.PP +.I Default: +"65535" => deactivated + + +.RE +.TP 7 +.BI "Option ""DozeScan"" """ scan """ +This value is responsible for the +.I scan-time +of the touch. This is the time interval between two scan operations +while in Doze-Mode. The time interval is set in steps +of milliseconds. +.RS 7 +.PP +.I Range: +"0" - "65535" [ms] +.PP +.I Default: +"500" + +.RE +.TP 7 +.BI "Option ""DeltaX"" """ value """ +This value determines a virtual area at the left and right +side of the current cursor position where the cursor didn't move. +Within this area no "MotionNotify" event will be sent. +.RS 7 +.PP +.I Range: +"0" - "255" +.PP +.I Default: +"0" (no deltaX) + + +.RE +.TP 7 +.BI "Option ""DeltaY"" """ value """ +This value determines a virtual area at the top and bottom +of the current cursor position where the cursor didn't move. +Within this area no "MotionNotify" event will be sent. +.RS 7 +.PP +.I Range: +"0" - "255" +.PP +.I Default: +"0" (no deltaY) + +.RE +.TP 7 +.BI "Option ""Beep"" """ value """ +This value determines if a "ButtonPress" and/or a "ButtonRelease" +event should sound the buzzer. "0" deactivates the buzzer while +every other value will activate it. +.RS 7 +.PP +.I Range: +"0" - "1" +.PP +.I Default: +"0" (deactivated) + +.RE +.TP 7 +.BI "Option ""PressVol"" """ value """ +This value determines the volume of the buzzer (0-100%) +when a "ButtonPress" event is sent. +.RS 7 +.PP +.I Range: +"0" - "100" +.PP +.I Default: +"100" + + +.RE +.TP 7 +.BI "Option ""PressPitch"" """ value """ +This value determines the pitch of the tone +when a "ButtonPress" event is sent. +.RS 7 +.PP +.I Range: +"0" - "3000" +.PP +.I Default: +"880" + + + +.RE +.TP 7 +.BI "Option ""PressDur"" """ value """ +This value determines the duration of the tone in ms +when a "ButtonPress" event is sent. +.RS 7 +.PP +.I Range: +"0" - "255" +.PP +.I Default: +"15" + +.RE +.TP 7 +.BI "Option ""ReleaseVol"" """ value """ +This value determines the volume of the buzzer (0-100%) +when a "ButtonRelease" event is sent. +.RS 7 +.PP +.I Range: +"0" - "100" +.PP +.I Default: +"100" + + +.RE +.TP 7 +.BI "Option ""ReleasePitch"" """ value """ +This value determines the pitch of the tone when +when a "ButtonRelease" event is sent. +.RS 7 +.PP +.I Range: +"0" - "3000" +.PP +.I Default: +"1200" + + + +.RE +.TP 7 +.BI "Option ""ReleseDur"" """ value """ +This value determines the duration of the tone in ms when +when a "ButtonRelease" event is sent. +.RS 7 +.PP +.I Range: +"0" - "255" +.PP +.I Default: +"10" + + + +.RE +.TP 7 +.BI "Option ""BeamTimeout"" """ value """ +Determines the time span in seconds, that has to elapse before a beam is +considered defective, blanked-out and excluded from the coordinates +evaluation. +.RS 7 +.PP +.I Range: +"0" - "65535" +.PP +.I Default: +"30" (30 seconds) + + + + +.RE +.TP 7 +.BI "Option ""TouchTime"" """ value """ +Determines the minimum time span in steps of 10ms for a valid +interruption. In order for an interruption to be +reported to the host computer as valid, it needs to remain at +the same spot for at least the time span declared here. +.RS 7 +.PP +.I Range: +"0" - "255" +.PP +.I Default: +"0" (=6,5 ms) + + +.RE +.TP 7 +.BI "Option ""EnterCount"" """ count """ +Number of skipped "enter reports". Reports are sent approx. +every 20ms. +.RS 7 +.PP +.I Range: +"0" - "31" +.PP +.I Default: +"3" (3 skipped messages = 60ms) + + +.RE +.TP 7 +.BI "Option ""DualCount"" """ count """ +Number of skipped "dual touch error". Reports are sent approx. +every 20ms. This option is only available for "ZPress" and +"ZPress Exit" modes. +.RS 7 +.PP +.I Range: +"0" - "31" +.PP +.I Default: +"2" (2 skipped messages = 40ms) + + +.SH "SEE ALSO" +XFree86(1), XF86Config(5x), xf86config(1), Xserver(1), X(1). +.SH AUTHORS +2000 - written by Citron GmbH (support@citron.de) diff --git a/xc/programs/Xserver/hw/xfree86/input/citron/citron.h b/xc/programs/Xserver/hw/xfree86/input/citron/citron.h new file mode 100644 index 000000000..b43d45ce6 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/input/citron/citron.h @@ -0,0 +1,522 @@ +/* + * Copyright (c) 1998 Metro Link Incorporated + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE X CONSORTIUM 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. + * + * Except as contained in this notice, the name of the Metro Link shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Metro Link. + * + */ + +/* $XFree86: xc/programs/Xserver/hw/xfree86/input/citron/citron.h,v 1.1 2000/11/02 02:51:21 dawes Exp $ */ + +/* + * Based, in part, on code with the following copyright notice: + * + * Copyright 1999-2000 by Thomas Thanner, Citron GmbH, Germany. <support@citron.de> + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and that + * the name of Thomas Thanner and Citron GmbH not be used in advertising or + * publicity pertaining to distribution of the software without specific, written + * prior permission. Thomas Thanner and Citron GmbH makes no representations about + * the suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * THOMAS THANNER AND CITRON GMBH DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, + * IN NO EVENT SHALL THOMAS THANNER OR CITRON GMBH BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +#ifndef _citron_H_ +#define _citron_H_ + +/****************************************************************************** + * Definitions + * structs, typedefs, #defines, enums + *****************************************************************************/ + +/* CTS (Citron Touch Software) protocol constants */ +#define CTS_CTRLMIN 0x10 /* Lower end of the control character range */ +#define CTS_XON 0x11 /* Start serial transmission character */ +#define CTS_STX 0x12 /* Start of message delimiter */ +#define CTS_XOFF 0x13 /* Stop serial transmission character */ +#define CTS_ETX 0x14 /* End of message delimiter */ +#define CTS_NAK 0x15 /* Not Acknowledge, send by the IRT just before it resets itself */ +#define CTS_ESC 0x16 /* Escape character to encode non control characters with a value inside the control character range */ +#define CTS_CTRLMAX 0x16 /* Upper end of the control character range */ + +#define CTS_ENCODE 0x40 /* Use this constant to encode non control character with a value inside the control character range */ +#define CTS_DECODE (~0x40) /* Use this constant to decode previously encoded characters. These characters are marked by a leading CTS_ESC. */ + +#define CTS_MSG_MIN 0x18 /* First usable character for message and report identifiers */ +#define CTS_MSG_MAX 0x7F /* Last usable character for message and report identifiers */ + +#define CTS_DESIGNATOR_LEN 32 /* Length of the designator part in the HardwareRevision report */ +#define CTS_ASSY_LEN 16 /* Length of the ASSY part in the HardwareRevision report */ +#define CTS_OEMSTRING_LEN 256 /* Length of the OEM string */ +#define CTS_FPGA_LEN 28 /* Length of the FPGA version string */ +#define CTS_SENSORCOUNT_LEN 1 /* Length of sensorcount report */ + +#define CTS_MAX_HWASSY 32 /* Maximum number of hardware codeable assy numbers */ + +#define CTS_MAX_POLYEDGE 64 /* Maximum number of polygonal area edges */ + +#define CMD_REP_CONV 0x7f /* Use this bit mask to convert a command into a report identifier */ + +#define CTS_PACKET_SIZE (1+CTS_OEMSTRING_LEN) + +/* Area operating modes */ +#define AOM_OFF 0x00 /* No coordinate messages will be generated by this area */ +#define AOM_ENTER 0x01 /* Only the area entry point will be reported in a coordinate message */ +#define AOM_TRACK 0x02 /* Every movement inside the area will be reported in a coordinate message */ +#define AOM_CONT 0x03 /* If the area is touched, coordinate messages will be created in fixed time intervals */ + +/* Modification flags for the area operating mode */ +#define AOF_ADDEXIT 0x01 /* Exit messages will be generated for this area */ +#define AOF_ADDCOORD 0x02 /* The coordinate of the touch point will be reported in addition to the area number */ +#define AOF_ADDPRESS 0x04 /* Pressure messages will be generated for this area */ +#define AOF_PRESSALWAYS 0x08 /* This area requires a permanent pressure to generate coordinate messages */ +#define AOF_PRESSENTER 0x10 /* This area requires only pressure to generate the first coordinate message. */ +#define AOF_PRESSLOCAL 0x20 /* This area has a locally defined pressure sensitivity, If this flag is not set, the pressure sensivity of area0 is used. */ +#define AOF_EXTENDED 0x40 /* This area must be leaved, before any other area will generate coordinate messages */ +#define AOF_ACTIVE 0x80 /* This area is active. Only active areas will generate messages. */ + +/* group ClearArea command parameter values */ +#define CA_ALL 0x00 /* Clear all areas on all pages */ +#define CA_PAGE 0x01 /* Clear all areas of a certain page */ +#define CA_AREA 0x02 /* Clear a single area, however area0 cannot be cleared. area0 will only be reset to its power up default state. */ + +/* SetTransmission command parameter values */ +#define TM_TRANSMIT 0x01 /* Enable the transmission of messages (report will be transmitted always) */ +#define TM_NONE 0x00 /* Disable transmission of messages and disable the XON/XOFF protocol */ +#define TM_RXDFLOW 0x10 /* Enable the XON/XOFF protocol for the transmitter (IRT will send XON/XOFF to the host) */ +#define TM_TXDFLOW 0x20 /* Enable the XON/XOFF protocol for the receiver (host will sned XON/XOFF to the IRT) */ + +/* Sleep- and Doze-Mode command parameters */ +#define TS_QUIET 0x00 /* Disable the generation of TouchSaver messages */ +#define TS_ACTIMSG 0x01 /* Enable the generation of messages on sleep- or doze-mode activation */ +#define TS_PASIMSG 0x02 /* Enable the generation of messages on sleep- or doze-mode deactivation */ +#define TS_SETOUT 0x10 /* The /GP_OUT output of the IRT will reflect the sleep- or doze-mode state, if this flag is set. */ +#define TS_ACTIVE 0x80 /* This is a read only flag to decode the current sleep- or doze-mode state in SleepModeState and DozeModeState reports. */ + +/* SetDualTouching command parameters */ +#define DT_IGNORE 0x00 /* Multiple touches are ignored, no DualTouchError messages will be generated */ +#define DT_ERROR 0x01 /* Multiple touches will be reported by a DualTouchError message */ +#define DT_COORD 0x02 /* The coordinate of the second touch point will be reported in a separate coordinate message. More than 2 touch points will be reported by DualTouchError messages. */ + +/* SetOrigin command parameters */ +#define OR_TOPLEFT 0x00 /* The coordinate origin is in the top left corner of the touch */ +#define OR_TOPRIGHT 0x01 /* The coordinate origin is in the top right corner of the touch */ +#define OR_BOTTOMRIGHT 0x02 /* The coordinate origin is in the bottom right corner of the touch */ +#define OR_BOTTOMLEFT 0x03 /* The coordinate origin is in the bottom left corner of the touch */ + +/* GetSignalValues command parameters */ +#define GS_NOREPORT 0x00 /* Don't report the signal values */ +#define GS_SIGNAL 0x01 /* Report the beam values as used for coordinate generation */ +#define GS_REFERENCE 0x02 /* Report the reference beam values */ +#define GS_BROKEN 0x03 /* Report the results of the broken/not broken beam detection */ +#define GS_RESCAN 0x80 /* Add this flag to rescan the touch before generating the SignalValues report */ + +/* GetPressureValues command parameters */ +#define GP_NOREPORT 0x00 /* Don't report the pressure values */ +#define GP_SIGNAL 0x01 /* Report the signals of the active pressure sensors */ +#define GP_REFERENCE 0x02 /* Report the signals of the calibration sensors */ +#define GP_INTERNAL 0x04 /* Report the internal state of the pressure sensitive unit */ + +/* SetPort/GetPort command parameters */ +#define GP_OCOUT0 0x01 /* Get/Set the /OC_OUT0 port of the IRT */ +#define GP_BIJMP 0x02 /* Get the state of the BurnIn jumper on the IRT */ +#define GP_OCSSAVER 0x04 /* Get/Set the /OC_SSAVER port of the IRT */ +#define GP_OCIN0 0x08 /* Get the state of the /OC_IN0 port of the IRT */ + +/* GetRevisions command parameters */ +#define GR_SYSMGR 0x01 /* Get the version number of the System Manager module */ +#define GR_HARDWARE 0x02 /* Get the version number of the Hardware module */ +#define GR_PROCESS 0x04 /* Get the version number of the Process module */ +#define GR_PROTOCOL 0x08 /* Get the version number of the Protocol module */ +#define GR_HWPARAM 0x10 /* Get the version number of the Hardware Parameters module */ +#define GR_DESIGNATOR 0x20 /* Get the IRT designator and ASSY number */ +#define GR_BURNIN 0x40 /* Get the version number of the Burn-In module */ +#define GR_FPGA 0x80 /* Get the version number of the FPGA module */ + +/* GetErrors command parameters */ +#define GE_INITIAL 0x01 /* Report the errors detected during IRT startup */ +#define GE_DEFECTBEAMS 0x02 /* Report the beams that are marked defect and are therefore excluded from the coordinate calculations */ +#define GE_COMMUNICATION 0x04 /* Report communication errors on the serial link */ +#define GE_COMMAND 0x08 /* Report command errors (invalid parameters, unknown commands, ...) */ +#define GE_CLEAR 0x80 /* Add this flag to clear the errors after reporting */ + +/* GetHardware command parameters */ +#define GH_BEAMCOUNT 0x01 /* Report the number of x and y beams */ +#define GH_SENSORCOUNT 0x02 /* Report the number of pressure sensors */ +#define GH_PERIPHERALS 0x04 /* Report a bit vector that identifies all assembled peripherals on the IRT */ + +/* GetHWVersion command parameters */ +#define HV_SSNO 0x01 /* Report the silicon serial number */ +#define HV_ASSY 0x02 /* Report the hard wired assembly number */ +#define HV_FPGA 0x04 /* Report the FPGA version string */ + +/* InitialError decoding bit masks */ +#define IE_SMCHKSUM 0x00000001UL /* The system manager module has a checksum error */ +#define IE_SMINIT 0x00000002UL /* The system manager module reported an error during initialisation */ +#define IE_HWCHKSUM 0x00000004UL /* The hardware module has a checksum error */ +#define IE_HWINIT 0x00000008UL /* The hardware module reported an error during initialisation */ +#define IE_PCCHKSUM 0x00000010UL /* The process module has a checksum error */ +#define IE_PCINIT 0x00000020UL /* The process module reported an error during initialisation */ +#define IE_PTCHKSUM 0x00000040UL /* The protocol module has a checksum error */ +#define IE_PTINIT 0x00000080UL /* The protocol module reported an error during initialisation */ +#define IE_HW_BEAMS 0x00000100UL /* There were broken beams during hardware initialisation */ +#define IE_HW_PSU 0x00000200UL /* There pressure sensitive unit could not be initialised */ +#define IE_HW_CPU 0x00000400UL /* There was an error in the CPU core detected during startup */ +#define IE_HW_IRAM 0x00000800UL /* There was an error in the initial internal ram check */ +#define IE_HW_XRAM 0x00001000UL /* There was an error in the initial external ram check */ +#define IE_BICHK 0x00002000UL /* The burnin module has a checksum error */ +#define IE_BIINIT 0x00004000UL /* The burnin module reported an error during initialisation */ +#define IE_FPGACHK 0x00008000UL /* The fpga module has a checksum error */ +#define IE_HWPCHK 0x00010000UL /* The hardware parameter module has a checksum error */ + +/* CommunicationError decoding bit masks */ +#define CE_DC2GTDC4 0x00000001UL /* There were more CTS_STX received than CTS_ETX */ +#define CE_DC4GTDC2 0x00000002UL /* There were more CTS_ETX received than CTS_STX */ +#define CE_UNXNONCTRL 0x00000004UL /* Non control character received outside a CTS_STX/CTS_ETX sequence */ +#define CE_UNXCONTROL 0x00000008UL /* Unexpected control character received */ +#define CE_OVERFLOW 0x00000010UL /* The hardware receiver buffer had an overflow */ +#define CE_FRAMING 0x00000020UL /* There were characters with framing errors received */ +#define CE_PARITY 0x00000040UL /* There were characters with invalid parity received */ +#define CE_XOFFTO 0x00000080UL /* No XON was received within the defined timeout after a XOFF */ +#define CE_CMDOVER 0x00000100UL /* The command buffer had an overflow */ +#define CE_RCVROVER 0x00000200UL /* The receiver ring buffer had an overflow */ + +/* CommandError decoding bit masks */ +#define CE_UNKNOWN 0x00000001UL /* Unknown command received */ +#define CE_PARAMCNT 0x00000002UL /* Too much or too less parameters received */ +#define CE_RANGE 0x00000004UL /* One or more parameters were out of range */ + +/* Peripheral indentification bit masks */ +#define PERI_OCOUT0 0x00000001UL /* The /OC_OUT0 port is available */ +#define PERI_BURNIN 0x00000002UL /* The BurnIn jumper is available */ +#define PERI_GP_OUT 0x00000004UL /* The /GP_OUT port is available */ +#define PERI_OCPWM 0x00000008UL /* The /OC_PWM port is available */ +#define PERI_SPEAKER 0x00000010UL /* The speaker port is available */ +#define PERI_GP_IN 0x00000020UL /* The /GP_IN port is available */ +#define PERI_RUNLED 0x00000040UL /* The red blinking indication LED is available */ + +/* SaveSetup/ReadSetup command parameters */ +#define SUP_SERIAL 0x01 /* Save/Read the serial port setup */ +#define SUP_MACRO 0x02 /* Save/Read the macro definitions */ +#define SUP_AREAS 0x04 /* Save/Read the area definitions */ +#define SUP_PERI 0x08 /* Save/Read the peripheral settings */ +#define SUP_COORD 0x10 /* Save/Read the coordinate settings */ + +/* IRT initialisation modes for <f cts_Connect> */ + +#define MODE_A 0x7b /* Initialise the IRT to AFE-Mode A emulation */ +#define MODE_B 0x3c /* Initialise the IRT to Carroll emulation */ +#define MODE_C 0x6f /* Another entry point for Mode-D (for backwards compatibility) */ +#define MODE_D 0x81 /* Initialise the IRT to the CTS protocol */ + +/* Command is for the driver */ +#define DRIVCOMM 0x00 /* Command for driver */ + +/* Command Identifiers for the driver */ +#define D_SETCLICKMODE 0x00 +#define D_BEEP 0x01 +#define D_SETBEEP 0x02 + + +/* Message identifiers */ +#define R_DUALTOUCHERROR 0x18 /* Invalid multiple touches are detected */ +#define R_COORD 0x19 /* Regular coordinate report */ +#define R_EXIT 0x1a /* An area was leaved */ +#define R_PRESSURE 0x1b /* An area was pressed or released */ +#define PRESS_BELOW 0x00 /* Pressure below a certain threshold */ +#define PRESS_EXCEED 0x01 /* Pressure higher than a certain threshold */ + +#define R_SLEEPMODE 0x1c /* The sleep-mode was activated or deactivated */ +#define R_DOZEMODE 0x1d /* The doze-mode was activated or deactivated */ + +/* Special report identifiers */ +#define R_POLYAREADEF 0x2a +#define R_IDLE 0x34 +#define R_SCANTIMING 0x56 + +/* Command identifiers */ +#define C_SOFTRESET 0x80 +#define C_RESETCTS 0x81 +#define C_SAVESETUP 0x83 +#define C_DESTROYSETUP 0x84 +#define C_SETSCANTIMING 0x85 +#define C_GETSCANTIMING 0x86 + +#define C_CLEARAREA 0xa0 +#define C_DEFINEAREA 0xa1 +#define C_GETAREADEF 0xa2 +#define C_GETAREAPAGE 0xa3 +#define C_GETFREEAREASPACE 0xa4 +#define C_SELECTAREAPAGE 0xa5 +#define C_SETAREASTATE 0xa6 +#define C_SETAREAMODE 0xa7 +#define C_SETAREAFLAGS 0xa8 +#define C_SETAREAPRESSURE 0xa9 +#define C_DEFINEPOLYAREA 0xaa + +#define C_GETERRORS 0xb0 +#define C_GETHARDWARE 0xb1 +#define C_GETREVISIONS 0xb2 +#define C_GETSETUP 0xb3 +#define C_GETSINGLEMESSAGE 0xb4 +#define C_GETSINGLESCAN 0xb5 +#define C_GETSIGNALVALUES 0xb6 +#define C_GETPRESSUREVALUES 0xb7 +#define C_GETOEMSTRING 0xb8 +#define C_GETHWVERSIONS 0xb9 +#define C_BIGETFIRSTSESSION 0xba +#define C_BIGETNEXTSESSION 0xbb +#define C_BIGETRECORD 0xbc +#define C_BIERASEDATA 0xbd +#define C_BIGETTICKUNIT 0xbe + +#define C_GETBEAMMINMAX 0xc0 +#define C_GETBEAMTIMEOUT 0xc1 +#define C_GETCONTTIME 0xc2 +#define C_GETDUALTOUCHING 0xc3 +#define C_GETORIGIN 0xc4 +#define C_GETRESOLUTION 0xc5 +#define C_GETSCANNING 0xc6 +#define C_GETTRANSMISSION 0xc7 +#define C_SETBEAMMINMAX 0xc8 +#define C_SETBEAMTIMEOUT 0xc9 +#define C_SETCONTTIME 0xca +#define C_SETDUALTOUCHING 0xcb +#define C_SETORIGIN 0xcc +#define C_SETRESOLUTION 0xcd +#define C_SETSCANNING 0xce +#define C_SETTRANSMISSION 0xcf + +#define C_GETTOUCHTIME 0xd0 +#define C_SETTOUCHTIME 0xd1 + +#define C_CLEARMACRO 0xe0 +#define C_ENDMACRORECORD 0xe1 +#define C_EXECMACRO 0xe2 +#define C_GETFREEMACROSPACE 0xe3 +#define C_STARTMACRORECORD 0xe5 + +#define C_GETPORT 0xf0 +#define C_GETPWM 0xf1 +#define C_GETSOUND 0xf2 +#define C_GETSLEEPMODE 0xf3 +#define C_SETPORT 0xf4 +#define C_SETPWM 0xf5 +#define C_SETSOUND 0xf6 +#define C_SETSLEEPMODE 0xf7 +#define C_GETDOZEMODE 0xf8 +#define C_SETDOZEMODE 0xf9 + +/* touch states */ +#define CIT_TOUCHED 0x01 +#define CIT_PRESSED 0x02 +#define CIT_BUTTON 0x04 + +/* click modes */ +#define CM_ENTER 1 +#define CM_DUAL 2 +#define CM_DUALEXIT 3 +#define CM_ZPRESS 4 +#define CM_ZPRESSEXIT 5 + +#define MAX_DUAL_TOUCH_COUNT 2 + +#define NO_CLICK_MODE 255 /* no click mode set in xf86Config */ + +/* command structure for Feedback Functions */ +typedef struct { + unsigned char par[3]; /* byte parameter */ + char packet; /* packet number 00 - 7F */ +} COMMAND; + + +/* Data exchange with driver (Driver Data Structure) */ +#define MAX_BYTES_TO_TRANSFER 0x20 +#define LAST_PACKET 0x7f + +typedef struct { + short curbyte; /* current byte number */ + short numbytes; /* number of bytes to transmit */ + short packet; /* packet number */ + unsigned char data[MAX_BYTES_TO_TRANSFER]; /* pointer to data area */ +} CitronDDS; + + + + +/***************************************************************************** + * X-Header + ****************************************************************************/ + +#define X_CITOUCH " CiTouch: " +const char *CI_PROBED = {"(--)" X_CITOUCH}; /* Value was probed */ +const char *CI_CONFIG = {"(**)" X_CITOUCH}; /* Value was given in the config file */ +const char *CI_DEFAULT = {"(==)" X_CITOUCH}; /* Value is a default */ +const char *CI_CMDLINE = {"(++)" X_CITOUCH}; /* Value was given on the command line */ +const char *CI_NOTICE = {"(!!)" X_CITOUCH}; /* Notice */ +const char *CI_INFO = {"(II)" X_CITOUCH}; /* Informational message */ +const char *CI_WARNING = {"(WW)" X_CITOUCH}; /* Warning message */ +const char *CI_ERROR = {"(EE)" X_CITOUCH}; /* Error message */ +const char *CI_UNKNOWN = {"(?\?)" X_CITOUCH}; /* Unknown message */ + + + +/***************************************************************************** + * macros + ****************************************************************************/ +#define millisleep(ms) xf86usleep((ms) * 1000) + +#define HIBYTE(x) ( (unsigned char) ( (x) >> 8 ) ) +#define LOBYTE(x) ( (unsigned char) ( (x) & 0xff ) ) + + +/***************************************************************************** + * typedefs + ****************************************************************************/ +typedef enum +{ + cit_idle, cit_getID, cit_collect, cit_escape +} +cit_State; /* Citron Infrared Touch Driver State */ + +typedef struct _cit_privateRec +{ + int min_x; /* Minimum x reported by calibration */ + int max_x; /* Maximum x */ + int min_y; /* Minimum y reported by calibration */ + int max_y; /* Maximum y */ + int button_threshold; /* Z > button threshold = button click */ + int axes; + int dual_touch_count; /* counter for dual touch error events */ + int click_mode; /* one of the CM_ constants */ + int button_number; /* which button to report */ + int reporting_mode; /* TS_Raw or TS_Scaled */ + int screen_num; /* Screen associated with the device */ + int screen_width; /* Width of the associated X screen */ + int screen_height; /* Height of the screen */ + int packeti; /* index into packet */ + int raw_x; /* Raw Coordinates */ + int raw_y; + int sleep_mode; /* sleep mode: 0x00=no message, 0x01=m at activation, 0x02=m at deactivation, */ + /* 0x03= message at act. + deact., 0x10= GP_OUT set */ + int sleep_time_act; /* time until touchsaver gets activate */ + int sleep_time_scan; /* time interval between two scans */ + int pwm_sleep; /* PWM duty cycle during touch saver mode */ + int pwm_active; /* PWM duty cycle during regular operation */ + int state; +/* additional parameters */ + int last_x; /* last cooked data */ + int last_y; + int doze_mode; /* doze mode: 0x00=no message, 0x01=m at activation, 0x02=m at deactivation, */ + /* 0x03= message at act. + deact., 0x10= GP_OUT set */ + int doze_time_act; /* time until touchsaver gets activate */ + int doze_time_scan; /* time interval between scans */ + int origin; /* Coordinates origin */ + int delta_x; /* Delta x - if coordinate changed less than delta x no motion event */ + int delta_y; + int beep; /* 0= no beep, 1=beep enabled */ + int press_vol; /* volume of beep (press event) */ + int press_pitch; /* pitch of beep (press event) */ + int press_dur; /* length of beep in 10ms (press event) */ + int rel_vol; /* volume of beep (release event) */ + int rel_pitch; /* pitch of beep (release event) */ + int rel_dur; /* length of beep in 10ms (release event) */ + int beam_timeout; /* Beam timeout 0= no beam timeout */ + int touch_time; /* minimum time span for a valid interruption */ + int enter_touched; /* button is down due to an enter event */ + int enter_count; /* number of jumed coord reports before a ButtonPress event is sent */ + int max_dual_count; /* number of jumed dualtouch error reports before a ButtonPress event is sent */ + int dual_flg; /* Flag set if dualtouch error report is received , reset by counter */ + int raw_min_x; /* min x,y max x,y value accumulated over the whole session */ + int query_state; /* test if query was already started */ + int raw_max_x; + int raw_min_y; + int raw_max_y; + int pressure_sensors; /* number of pressure sensors */ + OsTimerPtr timer_ptr; /* Timer for general purposes */ + CARD32 timer_val1; /* Timer 1st delay */ + CARD32 timer_val2; /* Timer second delay */ + OsTimerCallback timer_callback; /* timer callback routine */ + int fake_exit; /* tell the ReadInput function there is a exit message (from timer) */ +/* end additional parameters */ + LocalDevicePtr local; /* Pointer to local device */ + Bool button_down; /* is the "button" currently down */ + Bool proximity; + cit_State lex_mode; + XISBuffer *buffer; + unsigned char packet[CTS_PACKET_SIZE]; /* packet being/just read */ + CitronDDS dds; /* Structure for Byte transfer to the driver via LedFeedbackControl */ +} +cit_PrivateRec, *cit_PrivatePtr; + +/****************************************************************************** + * Declarations + *****************************************************************************/ +/*extern void ModuleInit (pointer *, INT32 *);*/ +static MODULESETUPPROTO (SetupProc); +static void TearDownProc (pointer p); +/*static void *SetupProc (XF86OptionPtr, int *, int *);*/ +static Bool DeviceControl (DeviceIntPtr def, int mode); +static Bool DeviceOn (DeviceIntPtr); +static Bool DeviceOff (DeviceIntPtr); +static Bool DeviceClose (DeviceIntPtr); +static Bool DeviceInit (DeviceIntPtr); +static void ReadInput (LocalDevicePtr); +static int ControlProc (LocalDevicePtr, xDeviceCtl *); +static void CloseProc (LocalDevicePtr); +static int SwitchMode (ClientPtr, DeviceIntPtr, int); +static Bool ConvertProc (LocalDevicePtr, int, int, int, int, int, int, int, int, int *, int *); +static Bool QueryHardware (LocalDevicePtr, int *, int *); +static Bool cit_GetPacket (cit_PrivatePtr); +static void cit_Flush(XISBuffer *); +static void cit_SendCommand(XISBuffer *, unsigned char, int, ...); +static Bool cit_GetInitialErrors(cit_PrivatePtr); +static Bool cit_GetDefectiveBeams(cit_PrivatePtr); +static Bool cit_GetDesignator(cit_PrivatePtr); +static Bool cit_GetPressureSensors(cit_PrivatePtr); +static Bool cit_GetRevision(cit_PrivatePtr, int); +static void cit_ProcessPacket(cit_PrivatePtr); +static void cit_Beep(cit_PrivatePtr priv, int press); +#ifdef CIT_TIM +static void cit_StartTimer(cit_PrivatePtr priv); +static void cit_CloseTimer(cit_PrivatePtr priv); +static CARD32 cit_DualTouchTimer(OsTimerPtr timer, CARD32 now, pointer arg); +#endif + + + +/* + * DO NOT PUT ANYTHING AFTER THIS ENDIF + */ +#endif diff --git a/xc/programs/Xserver/hw/xfree86/loader/SparcMulDiv.S b/xc/programs/Xserver/hw/xfree86/loader/SparcMulDiv.S new file mode 100644 index 000000000..e7281593c --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/loader/SparcMulDiv.S @@ -0,0 +1,87 @@ +/* + * Hardware integer division and multiplication routines for SPARC v8 and higher. + * + * Copyright (C) 1996 David S. Miller (davem@redhat.com) + * Copyright (C) 1999 Jakub Jelinek (jj@ultra.linux.cz) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * JAKUB JELINEK OR DAVID MILLER 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. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/SparcMulDiv.S,v 1.1 2000/11/02 19:10:54 dawes Exp $ */ + + .globl urem_sparcv89, umul_sparcv89, udiv_sparcv89 + .globl rem_sparcv89, mul_sparcv89, div_sparcv89 + + .align 32 +urem_sparcv89: + wr %g0, 0x0, %y + nop + nop + nop + udiv %o0, %o1, %o2 + umul %o2, %o1, %o2 + retl + sub %o0, %o2, %o0 + + .align 32 +umul_sparcv89: + umul %o0, %o1, %o0 + retl + rd %y, %o1 + + .align 32 +udiv_sparcv89: + wr %g0, 0x0, %y + nop + nop + retl + udiv %o0, %o1, %o0 + + .align 32 +rem_sparcv89: + sra %o0, 0x1f, %o4 + wr %o4, 0x0, %y + nop + nop + nop + sdivcc %o0, %o1, %o2 + bvs,a 1f + xnor %o2, %g0, %o2 +1: smul %o2, %o1, %o2 + retl + sub %o0, %o2, %o0 + + .align 32 +mul_sparcv89: + smul %o0, %o1, %o0 + retl + rd %y, %o1 + nop + + .align 32 +div_sparcv89: + sra %o0, 0x1f, %o2 + wr %o2, 0x0, %y + nop + nop + nop + sdivcc %o0, %o1, %o0 + bvs,a 1f + xnor %o0, %g0, %o0 +1: retl + nop diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_axp.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_axp.c new file mode 100644 index 000000000..50d338fde --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_axp.c @@ -0,0 +1,98 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_axp.c,v 1.2 2000/11/06 21:57:11 dawes Exp $ */ + +#include <stdio.h> +#include "X.h" +#include "os.h" +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86Axp.h" + +axpDevice lnxGetAXP(void); + +static AXP axpList[] = { + { "Tsunami", NULL, NULL, TSUNAMI }, + { "Eiger", NULL, NULL, TSUNAMI }, + {"Noname", NULL, NULL, LCA }, + { "AlphaBook1", NULL, NULL, LCA }, + {"EB66", NULL, NULL, LCA}, + {"EB64+",NULL,NULL, APECS}, + {"Noritake",NULL,NULL,APECS}, + {"XL",NULL,NULL,APECS}, + {"Avanti",NULL,NULL,APECS}, + {"Mikasa",NULL,"EV5",CIA}, + {"Mikasa",NULL,"EV56",CIA}, + {"Mikasa",NULL,NULL,APECS}, + {"EB164","EB164",NULL,APECS}, + {"EB164","PC164", NULL,CIA}, + {"EB164","RX164",NULL, POLARIS}, + {"EB164","LX164",NULL, PYXIS}, + {"Alcor",NULL,NULL,CIA}, + {"Takara",NULL,NULL,CIA}, + {"Sable",NULL, "EV5",T2_GAMMA}, + {"Sable",NULL,"EV56",T2_GAMMA}, + {"Sable",NULL,NULL,T2}, + {"Rawhide",NULL,NULL,MCPCIA}, + {"Jensen",NULL,NULL,JENSEN}, + {"Miata",NULL,NULL,PYXIS_CIA}, + {"Ruffian",NULL,NULL,PYXIS_CIA}, + {"Nautilus",NULL,NULL,IRONGATE}, + {NULL,NULL,NULL,NONE} +}; + + +axpDevice +lnxGetAXP(void) +{ + FILE *file; + int count = 0; + char res[256]; + char cpu[255]; + char systype[255]; + char sysvari[255]; + if (!(file = fopen("/proc/cpuinfo","r"))) + return SYS_NONE; + do { + if (!fgets(res,0xff,file)) return SYS_NONE; + switch (count) { + case 1: + sscanf(res, "cpu model : %s",cpu); +#ifdef DEBUG + ErrorF("CPU %s\n",cpu); +#endif + break; + case 5: + sscanf(res, "system type : %s",systype); +#ifdef DEBUG + ErrorF("system type : %s\n",systype); +#endif + break; + case 6: + sscanf(res, "system variation : %s",sysvari); +#ifdef DEBUG + ErrorF("system variation: %s\n",sysvari); +#endif + break; + } + count++; + } while (count < 8); + + fclose(file); + + count = 0; + + do { + if (!axpList[count].sysName || !strcmp(axpList[count].sysName,systype)) { + if (axpList[count].sysVari && strcmp(axpList[count].sysVari,sysvari)) { + count++; + continue; + }; + if (axpList[count].cpu && strcmp(axpList[count].cpu,cpu)) { + count++; + continue; + } + return axpList[count].sys; + } + count++; + } while (1); +} + diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/xf86Axp.c b/xc/programs/Xserver/hw/xfree86/os-support/shared/xf86Axp.c new file mode 100644 index 000000000..24d31db59 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/xf86Axp.c @@ -0,0 +1,20 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/xf86Axp.c,v 1.2 2000/11/06 21:57:11 dawes Exp $ */ + +#include "xf86Axp.h" + +axpParams xf86AXPParams[] = { + {SYS_NONE, 0, 0, 0}, + {TSUNAMI, 0, 0, 0}, + {LCA, 1<<24,0xf8000000, 1UL << 32}, + {APECS, 1<<24,0xf8000000, 1UL << 32}, + {T2, 0,0xFC000000, 1UL << 31}, + {T2_GAMMA, 0,0xFC000000, 1UL << 31}, + {CIA, 0,0xE0000000, 1UL << 34}, + {MCPCIA, 0,0xf8000000, 1UL << 31}, + {JENSEN, 0, 0xE000000, 1UL << 32}, + {POLARIS, 0, 0, 0}, + {PYXIS, 0, 0, 0}, + {PYXIS_CIA, 0,0xE0000000, 1UL << 34}, + {IRONGATE, 0, 0, 0} +}; + diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/xf86Axp.h b/xc/programs/Xserver/hw/xfree86/os-support/shared/xf86Axp.h new file mode 100644 index 000000000..23d6f8609 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/xf86Axp.h @@ -0,0 +1,39 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/xf86Axp.h,v 1.2 2000/11/06 21:57:11 dawes Exp $ */ + +#ifndef _XF86_AXP_H_ +#define _XF86_AXP_H_ + +typedef enum { + SYS_NONE, + TSUNAMI, + LCA, + APECS, + T2, + T2_GAMMA, + CIA, + MCPCIA, + JENSEN, + POLARIS, + PYXIS, + PYXIS_CIA, + IRONGATE +} axpDevice; + +typedef struct + { char* sysName; + char* sysVari; + char* cpu; + axpDevice sys; } +AXP; + +typedef struct { + axpDevice id; + unsigned long hae_thresh; + unsigned long hae_mask; + unsigned long size; +} axpParams; + +extern axpParams xf86AXPParams[]; + +#endif + |