xserver/hw/xorg/drivers/ati Imakefile, NONE, 1.1 Makefile.am, NONE, 1.1 ati.c, NONE, 1.1 ati.h, NONE, 1.1 atiaccel.c, NONE, 1.1 atiaccel.h, NONE, 1.1 atiadapter.c, NONE, 1.1 atiadapter.h, NONE, 1.1 atiadjust.c, NONE, 1.1 atiadjust.h, NONE, 1.1 atiaudio.c, NONE, 1.1 atiaudio.h, NONE, 1.1 atibank.c, NONE, 1.1 atibank.h, NONE, 1.1 atibus.c, NONE, 1.1 atibus.h, NONE, 1.1 atichip.c, NONE, 1.1 atichip.h, NONE, 1.1 aticlock.c, NONE, 1.1 aticlock.h, NONE, 1.1 aticonfig.c, NONE, 1.1 aticonfig.h, NONE, 1.1 aticonsole.c, NONE, 1.1 aticonsole.h, NONE, 1.1 aticrtc.h, NONE, 1.1 aticursor.c, NONE, 1.1 aticursor.h, NONE, 1.1 atidac.c, NONE, 1.1 atidac.h, NONE, 1.1 atidecoder.c, NONE, 1.1 atidecoder.h, NONE, 1.1 atidga.c, NONE, 1.1 atidga.h, NONE, 1.1 atidsp.c, NONE, 1.1 atidsp.h, NONE, 1.1 atii2c.c, NONE, 1.1 atii2c.h, NONE, 1.1 atiident.c, NONE, 1.1 atiident.h, NONE, 1.1 atiio.h, NONE, 1.1 atiload.c, NONE, 1.1 atiload.h, NONE, 1.1 atilock.c, NONE, 1.1 atilock.h, NONE, 1.1 atimach64.c, NONE, 1.1 atimach64.h, NONE, 1.1 atimach64accel.c, NONE, 1.1 atimach64accel.h, NONE, 1.1 atimach64cursor.c, NONE, 1.1 atimach64cursor.h, NONE, 1.1 atimach64i2c.c, NONE, 1.1 atimach64i2c.h, NONE, 1.1 atimach64io.c, NONE, 1.1 atimach64io.h, NONE, 1.1 atimach64xv.c, NONE, 1.1 atimach64xv.h, NONE, 1.1 atimisc.c, NONE, 1.1 atimode.c, NONE, 1.1 atimode.h, NONE, 1.1 atimodule.c, NONE, 1.1 atimodule.h, NONE, 1.1 atimono.h, NONE, 1.1 atioption.c, NONE, 1.1 atioption.h, NONE, 1.1 atipreinit.c, NONE, 1.1 atipreinit.h, NONE, 1.1 atiprint.c, NONE, 1.1 atiprint.h, NONE, 1.1 atipriv.h, NONE, 1.1 atiprobe.c, NONE, 1.1 atiprobe.h, NONE, 1.1 atiproto.h, NONE, 1.1 atiregs.h, NONE, 1.1 atirgb514.c, NONE, 1.1 atirgb514.h, NONE, 1.1 atiscreen.c, NONE, 1.1 atiscreen.h, NONE, 1.1 atistruct.h, NONE, 1.1 atituner.c, NONE, 1.1 atituner.h, NONE, 1.1 atiutil.c, NONE, 1.1 atiutil.h, NONE, 1.1 ativalid.c, NONE, 1.1 ativalid.h, NONE, 1.1 ativersion.h, NONE, 1.1 ativga.c, NONE, 1.1 ativga.h, NONE, 1.1 ativgaio.c, NONE, 1.1 ativgaio.h, NONE, 1.1 atividmem.c, NONE, 1.1 atividmem.h, NONE, 1.1 atiwonder.c, NONE, 1.1 atiwonder.h, NONE, 1.1 atiwonderio.c, NONE, 1.1 atiwonderio.h, NONE, 1.1 atixv.c, NONE, 1.1 atixv.h, NONE, 1.1 r128.h, NONE, 1.1 r128_accel.c, NONE, 1.1 r128_common.h, NONE, 1.1 r128_cursor.c, NONE, 1.1 r128_dga.c, NONE, 1.1 r128_dri.c, NONE, 1.1 r128_dri.h, NONE, 1.1 r128_dripriv.h, NONE, 1.1 r128_driver.c, NONE, 1.1 r128_misc.c, NONE, 1.1 r128_probe.c, NONE, 1.1 r128_probe.h, NONE, 1.1 r128_reg.h, NONE, 1.1 r128_sarea.h, NONE, 1.1 r128_version.h, NONE, 1.1 r128_video.c, NONE, 1.1 radeon.h, NONE, 1.1 radeon_accel.c, NONE, 1.1 radeon_accelfuncs.c, NONE, 1.1 radeon_common.h, NONE, 1.1 radeon_cursor.c, NONE, 1.1 radeon_dga.c, NONE, 1.1 radeon_dri.c, NONE, 1.1 radeon_dri.h, NONE, 1.1 radeon_dripriv.h, NONE, 1.1 radeon_driver.c, NONE, 1.1 radeon_macros.h, NONE, 1.1 radeon_misc.c, NONE, 1.1 radeon_probe.c, NONE, 1.1 radeon_probe.h, NONE, 1.1 radeon_reg.h, NONE, 1.1 radeon_sarea.h, NONE, 1.1 radeon_version.h, NONE, 1.1 radeon_video.c, NONE, 1.1

Daniel Stone xserver-commit at pdx.freedesktop.org
Sun Apr 25 23:52:16 EST 2004


Committed by: daniel

Update of /cvs/xserver/xserver/hw/xorg/drivers/ati
In directory pdx:/tmp/cvs-serv17025/hw/xorg/drivers/ati

Added Files:
	Imakefile Makefile.am ati.c ati.h atiaccel.c atiaccel.h 
	atiadapter.c atiadapter.h atiadjust.c atiadjust.h atiaudio.c 
	atiaudio.h atibank.c atibank.h atibus.c atibus.h atichip.c 
	atichip.h aticlock.c aticlock.h aticonfig.c aticonfig.h 
	aticonsole.c aticonsole.h aticrtc.h aticursor.c aticursor.h 
	atidac.c atidac.h atidecoder.c atidecoder.h atidga.c atidga.h 
	atidsp.c atidsp.h atii2c.c atii2c.h atiident.c atiident.h 
	atiio.h atiload.c atiload.h atilock.c atilock.h atimach64.c 
	atimach64.h atimach64accel.c atimach64accel.h 
	atimach64cursor.c atimach64cursor.h atimach64i2c.c 
	atimach64i2c.h atimach64io.c atimach64io.h atimach64xv.c 
	atimach64xv.h atimisc.c atimode.c atimode.h atimodule.c 
	atimodule.h atimono.h atioption.c atioption.h atipreinit.c 
	atipreinit.h atiprint.c atiprint.h atipriv.h atiprobe.c 
	atiprobe.h atiproto.h atiregs.h atirgb514.c atirgb514.h 
	atiscreen.c atiscreen.h atistruct.h atituner.c atituner.h 
	atiutil.c atiutil.h ativalid.c ativalid.h ativersion.h 
	ativga.c ativga.h ativgaio.c ativgaio.h atividmem.c 
	atividmem.h atiwonder.c atiwonder.h atiwonderio.c 
	atiwonderio.h atixv.c atixv.h r128.h r128_accel.c 
	r128_common.h r128_cursor.c r128_dga.c r128_dri.c r128_dri.h 
	r128_dripriv.h r128_driver.c r128_misc.c r128_probe.c 
	r128_probe.h r128_reg.h r128_sarea.h r128_version.h 
	r128_video.c radeon.h radeon_accel.c radeon_accelfuncs.c 
	radeon_common.h radeon_cursor.c radeon_dga.c radeon_dri.c 
	radeon_dri.h radeon_dripriv.h radeon_driver.c radeon_macros.h 
	radeon_misc.c radeon_probe.c radeon_probe.h radeon_reg.h 
	radeon_sarea.h radeon_version.h radeon_video.c 
Log Message:
Xizzle is dead, long live Xorg.

Re-import the DDX from X11R6.7, complete with automakey goodness, and do the
requisite configure.ac, et al, updates; also import the XKB extension from the
6.7 DIX.

Currently it'll link and then hang solid in RADEONInitAccel(), or the next
function if you enable NoAccel.


--- NEW FILE: Imakefile ---
XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/Imakefile,v 1.52tsi Exp $
XCOMM
XCOMM Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
XCOMM
XCOMM Permission to use, copy, modify, distribute, and sell this software and
XCOMM its documentation for any purpose is hereby granted without fee, provided
XCOMM that the above copyright notice appear in all copies and that both that
XCOMM copyright notice and this permission notice appear in supporting
XCOMM documentation, and that the name of Marc Aurele La France not be used in
XCOMM advertising or publicity pertaining to distribution of the software
XCOMM without specific, written prior permission.  Marc Aurele La France makes
XCOMM no representations about the suitability of this software for any
XCOMM purpose.  It is provided "as-is" without express or implied warranty.
XCOMM
XCOMM MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
XCOMM SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
XCOMM FITNESS.  IN NO EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY
XCOMM SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
XCOMM RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
XCOMM CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
XCOMM CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
XCOMM

#define IHaveModules
#include <Server.tmpl>

#ifdef ATIDriverCCOptions
CCOPTIONS = ATIDriverCCOptions
#endif

#if DoLoadableServer

MODSRCS1 = atimodule.c
MODSRCS2 = atiload.c atimisc.c
MODSRCS3 = r128_misc.c
MODSRCS4 = radeon_misc.c

MODOBJS1 = atimodule.o
MODOBJS2 = atiload.o atimisc.o
MODOBJS3 = r128_misc.o
MODOBJS4 = radeon_misc.o

#endif

#if BuildXF86DRI

DRISRCS3 = r128_dri.c
DRISRCS4 = radeon_dri.c

DRIOBJS3 = r128_dri.o
DRIOBJS4 = radeon_dri.o

DRIINCLUDES = -I$(SERVERSRC)/GL/dri -I$(LIBSRC)/GL/dri -I$(TOP)/include
DRIDEFINES  = $(GLX_DEFINES)

#endif

/*
 * The following configuration logic is only meant as a first cut, and is
 * therefore incomplete.  ...And, no, you do NOT have permission to move this
 * into xfree86.cf...
 *
 * Currently, ATIAvoidCPIO >MUST< be #define'd as YES for those platforms
 * (architecture/OS combinations) that neither provide nor emulate a
 * little-endian undirected PIO address space of at least 64 kB in size.
 *
 * "Undirected" means the driver does not need to determine the identity nor
 * location of the responding adapter before accessing a particular location in
 * the PIO address space.
 *
 * #define'ing ATIAvoidCPIO to YES generates a driver that will only support
 * PCI/AGP Mach64 adapters using a linear aperture and the accelerator CRTC.
 * The resulting driver will also require the same of the environment on server
 * entry.
 *
 * For testing purposes, #define'ing ATIAvoidCPIO as YES is also supported on
 * platforms that do, in fact, provide or emulate a PIO address space as
 * described above, but this should not be the default driver configuration.
 *
 * Currently, ATIAvoidNonPCI needs to be set to YES for those platforms that do
 * not tolerate PCI master aborts.
 */
#if defined(i386Architecture) || \
    defined(ia64Architecture) || \
    defined(AMD64Architecture) || \
    defined(AlphaArchitecture)
# ifndef ATIAvoidCPIO
#  define ATIAvoidCPIO NO
# endif
#elif defined(SparcArchitecture) || 1
# undef ATIAvoidCPIO    /* Clobber any previous setting */
# define ATIAvoidCPIO YES
#endif

#if defined(PpcArchitecture)
# undef ATIAvoidNonPCI
# define ATIAvoidNonPCI YES
#elif !defined(ATIAvoidNonPCI)
# define ATIAvoidNonPCI NO
#endif

#if ATIAvoidNonPCI

NONPCIDEFINES = -DAVOID_NON_PCI

#endif

#if ATIAvoidCPIO

CPIODEFINES = -DAVOID_CPIO

#else

CPIOSRCS1 = ativgaio.c
CPIOSRCS2 = atibank.c ativga.c atiwonder.c atiwonderio.c

CPIOOBJS1 = ativgaio.o
CPIOOBJS2 = atibank.o ativga.o atiwonder.o atiwonderio.o

#endif

/*
 * For now, disable DGA on SPARC.
 */
#if defined(SparcArchitecture)
# undef ATIAvoidDGA
# define ATIAvoidDGA YES
#endif

#ifndef ATIAvoidDGA
#define ATIAvoidDGA NO
#endif

#if ATIAvoidDGA

DGADEFINES = -DAVOID_DGA

#else

DGASRCS2 = atidga.c
DGAOBJS2 = atidga.o

#endif

DEFINES = $(CPIODEFINES) $(DGADEFINES) $(NONPCIDEFINES) $(DRIDEFINES)

SRCS1 = ati.c atiadapter.c atibus.c atichip.c atiident.c atioption.c \
        atiprobe.c atividmem.c $(CPIOSRCS1) $(MODSRCS1) \
        radeon_probe.c r128_probe.c
SRCS2 = atiaccel.c atiadjust.c atiaudio.c aticlock.c aticonfig.c aticonsole.c \
        aticursor.c atidac.c atidecoder.c atidsp.c atii2c.c atilock.c \
        atimach64.c atimach64accel.c atimach64cursor.c atimach64i2c.c \
        atimach64io.c atimach64xv.c atimode.c atipreinit.c atiprint.c \
        atirgb514.c atiscreen.c atituner.c atiutil.c ativalid.c \
        atixv.c $(CPIOSRCS2) $(DGASRCS2) $(MODSRCS2)
SRCS3 = r128_accel.c r128_cursor.c r128_dga.c r128_driver.c \
        r128_video.c $(DRISRCS3) $(MODSRCS3)
SRCS4 = radeon_accel.c radeon_cursor.c radeon_dga.c radeon_driver.c \
        radeon_video.c $(DRISRCS4) $(MODSRCS4)

OBJS1 = ati.o atiadapter.o atibus.o atichip.o atiident.o atioption.o \
        atiprobe.o atividmem.o $(CPIOOBJS1) $(MODOBJS1) \
        radeon_probe.o r128_probe.o
OBJS2 = atiaccel.o atiadjust.o atiaudio.o aticlock.o aticonfig.o aticonsole.o \
        aticursor.o atidac.o atidecoder.o atidsp.o atii2c.o atilock.o \
        atimach64.o atimach64accel.o atimach64cursor.o atimach64i2c.o \
        atimach64io.o atimach64xv.o atimode.o atipreinit.o atiprint.o \
        atirgb514.o atiscreen.o atituner.o atiutil.o ativalid.o \
        atixv.o $(CPIOOBJS2) $(DGAOBJS2) $(MODOBJS2)
OBJS3 = r128_accel.o r128_cursor.o r128_dga.o r128_driver.o \
        r128_video.o $(DRIOBJS3) $(MODOBJS3)
OBJS4 = radeon_accel.o radeon_cursor.o radeon_dga.o radeon_driver.o \
        radeon_video.o $(DRIOBJS4) $(MODOBJS4)

SRCS = $(SRCS1) $(SRCS2) $(SRCS3) $(SRCS4)
OBJS = $(OBJS1) $(OBJS2) $(OBJS3) $(OBJS4)

#if defined(XF86DriverSDK)
INCLUDES = -I. -I../../include
#else
INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(XF86SRC) \
           -I$(XF86SRC)/vbe -I$(XF86SRC)/int10 \
           -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \
           -I$(XF86SRC)/rac -I$(XF86SRC)/ramdac \
           -I$(XF86SRC)/shadowfb -I$(XF86SRC)/xaa \
           -I$(XF86SRC)/xf4bpp -I$(XF86SRC)/xf1bpp \
           -I$(XF86SRC)/vgahw -I$(XF86SRC)/fbdevhw \
           -I$(SERVERSRC)/mfb -I$(SERVERSRC)/fb -I$(SERVERSRC)/mi \
           -I$(SERVERSRC)/miext/shadow \
           -I$(SERVERSRC)/render -I$(SERVERSRC)/Xext -I$(SERVERSRC)/include \
           $(DRIINCLUDES) -I$(FONTINCSRC) -I$(EXTINCSRC) -I$(XINCLUDESRC)
#endif

#if MakeHasPosixVariableSubstitutions
SubdirLibraryRule($(OBJS))
#endif

ModuleObjectRule()

ObjectModuleTarget(ati,$(OBJS1))
ObjectModuleTarget(atimisc,$(OBJS2))
ObjectModuleTarget(r128,$(OBJS3))
ObjectModuleTarget(radeon,$(OBJS4))

InstallObjectModule(ati,$(MODULEDIR),drivers)
InstallObjectModule(atimisc,$(MODULEDIR),drivers)
InstallObjectModule(r128,$(MODULEDIR),drivers)
InstallObjectModule(radeon,$(MODULEDIR),drivers)

#if !defined(XF86DriverSDK)
#if 0
InstallModuleManPage(ati)
#endif

InstallModuleManPage(r128)

InstallModuleManPage(radeon)
#endif

DependTarget()

InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(ati.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(ati.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atiaccel.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atiaccel.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atiadapter.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atiadapter.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atiadjust.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atiadjust.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atiaudio.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atiaudio.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atibank.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atibank.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atibus.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atibus.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atichip.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atichip.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(aticlock.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(aticlock.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(aticonfig.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(aticonfig.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(aticonsole.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(aticonsole.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(aticrtc.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(aticursor.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(aticursor.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atidac.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atidac.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atidecoder.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atidecoder.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atidga.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atidga.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atidsp.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atidsp.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atiident.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atiident.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atii2c.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atii2c.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atiio.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atiload.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atiload.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atilock.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atilock.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atimach64.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atimach64.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atimach64accel.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atimach64accel.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atimach64cursor.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atimach64cursor.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atimach64i2c.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atimach64i2c.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atimach64io.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atimach64io.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atimach64xv.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atimach64xv.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atimisc.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atimode.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atimode.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atimodule.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atimodule.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atimono.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atioption.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atioption.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atipreinit.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atipreinit.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atiprint.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atiprint.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atipriv.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atiprobe.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atiprobe.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atiproto.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atiregs.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atirgb514.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atirgb514.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atiscreen.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atiscreen.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atistruct.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atituner.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atituner.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atiutil.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atiutil.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(ativalid.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(ativalid.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(ativersion.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(ativga.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(ativga.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(ativgaio.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(ativgaio.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atividmem.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atividmem.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atiwonder.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atiwonder.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atiwonderio.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atiwonderio.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atixv.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(atixv.h,$(DRIVERSDKDIR)/drivers/ati)

InstallDriverSDKNonExecFile(r128.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(r128_accel.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(r128_cursor.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(r128_dga.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(r128_dri.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(r128_dri.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(r128_dripriv.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(r128_driver.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(r128_misc.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(r128_probe.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(r128_probe.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(r128_reg.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(r128_sarea.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(r128_version.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(r128_video.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(r128_common.h,$(DRIVERSDKDIR)/drivers/ati)

InstallDriverSDKNonExecFile(radeon.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(radeon_accel.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(radeon_cursor.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(radeon_dga.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(radeon_dri.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(radeon_dri.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(radeon_dripriv.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(radeon_driver.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(radeon_macros.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(radeon_misc.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(radeon_probe.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(radeon_probe.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(radeon_reg.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(radeon_sarea.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(radeon_version.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(radeon_video.c,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(radeon_common.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(radeon_accelfuncs.c,$(DRIVERSDKDIR)/drivers/ati)

InstallDriverSDKObjectModule(ati,$(DRIVERSDKMODULEDIR),drivers)
InstallDriverSDKObjectModule(atimisc,$(DRIVERSDKMODULEDIR),drivers)
InstallDriverSDKObjectModule(r128,$(DRIVERSDKMODULEDIR),drivers)
InstallDriverSDKObjectModule(radeon,$(DRIVERSDKMODULEDIR),drivers)

/* Remove instances of ati2 module */
#if DoLoadableServer

#undef ATI2DriverModuleName
#if MakeDllModules
# define ATI2DriverModuleName ati2_drv.so
#else
# define ATI2DriverModuleName ati2_drv.o
#endif

all::
	RemoveFile($(BUILDMODULEDIR)/drivers/ATI2DriverModuleName)

install::
	RemoveFile($(DESTDIR)$(MODULEDIR)/drivers/ATI2DriverModuleName)

install.sdk::
	RemoveFile($(DESTDIR)$(DRIVERSDKMODULEDIR)/drivers/ATI2DriverModuleName)

#endif

--- NEW FILE: Makefile.am ---
AM_CFLAGS = $(XORG_CFLAGS)

INCLUDES = $(XORG_INCS) \
	   -I$(top_srcdir)/mi \
	   -I$(top_srcdir)/fb \
	   -I$(top_srcdir)/hw/xorg/fbdevhw \
           -I$(top_srcdir)/hw/xorg/loader \
	   -I$(top_srcdir)/hw/xorg/ddc \
           -I$(top_srcdir)/hw/xorg/rac \
	   -I$(top_srcdir)/hw/xorg/vbe \
	   -I$(top_srcdir)/hw/xorg/int10 \
           -I$(top_srcdir)/hw/xorg/i2c \
	   -I$(top_srcdir)/hw/xorg/parser \
	   -I$(top_srcdir)/hw/xorg/shadowfb \
	   -I$(top_srcdir)/hw/xorg/vgahw \
           -I$(top_srcdir)/hw/xorg/Xi \
	   -I$(top_srcdir)/hw/xorg/xaa \
	   -I$(top_srcdir)/hw/xorg/ramdac \
	   -I$(top_srcdir)/os

lib_LIBRARIES = libati.a

if DRI
R128DRI_SOURCES = \
	r128_dri.c \
	r128_dri.h

RADEONDRI_SOURCES = \
	radeon_dri.c \
	radeon_dri.h \
	radeon_dripriv.h
endif

libatimisc_a_SOURCES = \
	ati.c \
	ati.h \
	atiaccel.c \
	atiaccel.h \
	atiadapter.c \
	atiadapter.h \
	atiadjust.c \
	atiadjust.h \
	atiaudio.c \
	atiaudio.h \
	atibank.c \
	atibank.h \
	atibus.c \
	atibus.h \
	atichip.c \
	atichip.h \
	aticlock.c \
	aticlock.h \
	aticonfig.c \
	aticonfig.h \
	aticonsole.c \
	aticonsole.h \
	aticrtc.h \
	aticursor.c \
	aticursor.h \
	atidac.c \
	atidac.h \
	atidecoder.c \
	atidecoder.h \
	atidga.c \
	atidga.h \
	atidsp.c \
	atidsp.h \
	atii2c.c \
	atii2c.h \
	atiident.c \
	atiident.h \
	atiio.h \
	atiload.c \
	atiload.h \
	atilock.c \
	atilock.h \
	atimach64.c \
	atimach64.h \
	atimach64accel.c \
	atimach64accel.h \
	atimach64cursor.c \
	atimach64cursor.h \
	atimach64i2c.c \
	atimach64i2c.h \
	atimach64io.c \
	atimach64io.h \
	atimach64xv.c \
	atimach64xv.h \
	atimisc.c \
	atimode.c \
	atimode.h \
	atimono.h \
	atioption.c \
	atioption.h \
	atipreinit.c \
	atipreinit.h \
	atiprint.c \
	atiprint.h \
	atipriv.h \
	atiprobe.c \
	atiprobe.h \
	atiproto.h \
	atiregs.h \
	atirgb514.c \
	atirgb514.h \
	atiscreen.c \
	atiscreen.h \
	atistruct.h \
	atituner.c \
	atituner.h \
	atiutil.c \
	atiutil.h \
	ativalid.c \
	ativalid.h \
	ativersion.h \
	ativga.c \
	ativga.h \
	ativgaio.c \
	ativgaio.h \
	atividmem.c \
	atividmem.h \
	atiwonder.c \
	atiwonder.h \
	atiwonderio.c \
	atiwonderio.h \
	atixv.c \
	atixv.h

libr128_a_SOURCES = \
	r128.h \
	r128_accel.c \
	r128_common.h \
	r128_cursor.c \
	r128_dga.c \
	r128_dripriv.h \
	r128_driver.c \
	r128_misc.c \
	r128_probe.c \
	r128_probe.h \
	r128_reg.h \
	r128_sarea.h \
	r128_version.h \
	r128_video.c \
	$(R128DRI_SOURCES)

libradeon_a_SOURCES = \
	radeon.h \
	radeon_accel.c \
	radeon_common.h \
	radeon_cursor.c \
	radeon_dga.c \
	radeon_driver.c \
	radeon_macros.h \
	radeon_misc.c \
	radeon_probe.c \
	radeon_probe.h \
	radeon_reg.h \
	radeon_sarea.h \
	radeon_version.h \
	radeon_video.c \
	$(RADEONDRI_SOURCES)

libati_a_SOURCES = $(libatimisc_a_SOURCES) $(libr128_a_SOURCES) $(libradeon_a_SOURCES)

EXTRA_DIST = radeon_accelfuncs.c

--- NEW FILE: ati.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/ati.c,v 1.23 2003/04/25 14:37:35 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

/*************************************************************************/

/*
 * Author:  Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * This is the ATI driver for XFree86.
 *
 * John Donne once said "No man is an island", and I am most certainly not an
 * exception.  Contributions, intentional or not, to this and previous versions
 * of this driver by the following are hereby acknowledged:
 *
 * Thomas Roell, Per Lindqvist, Doug Evans, Rik Faith, Arthur Tateishi,
 * Alain Hebert, Ton van Rosmalen, David Chambers, William Shubert,
 * ATI Technologies Incorporated, Robert Wolff, David Dawes, Mark Weaver,
 * Hans Nasten, Kevin Martin, Frederic Rienthaler, Marc Bolduc, Reuben Sumner,
 * Benjamin T. Yang, James Fast Kane, Randall Hopper, W. Marcus Miller,
 * Henrik Harmsen, Christian Lupien, Precision Insight Incorporated,
 * Mark Vojkovich, Huw D M Davies, Andrew C Aitchison, Ani Joshi,
 * Kostas Gewrgiou, Jakub Jelinek, David S. Miller, A E Lawrence,
 * Linus Torvalds, William Blew, Ignacio Garcia Etxebarria, Patrick Chase,
 * Vladimir Dergachev, Egbert Eich, Mike A. Harris
 *
 * ... and, many, many others from around the world.
 *
 * In addition, this work would not have been possible without the active
 * support, both moral and otherwise, of the staff and management of Computing
 * and Network Services at the University of Alberta, in Edmonton, Alberta,
 * Canada.
 *
 * The driver is intended to support all ATI adapters since their VGA Wonder
 * V3, including OEM counterparts.
 */

#include "atiident.h"
#include "atioption.h"
#include "atiprobe.h"
#include "ativersion.h"

/* The root of all evil... */
DriverRec ATI =
{
    ATI_VERSION_CURRENT,
    "ati",
    ATIIdentify,
    ATIProbe,
    ATIAvailableOptions,
    NULL,
    0
};

--- NEW FILE: ati.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/ati.h,v 1.9 2003/01/01 19:16:30 tsi Exp $ */
/*
 * Copyright 1999 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATI_H___
#define ___ATI_H___ 1

#include "xf86Pci.h"
#include "xf86PciInfo.h"

#include "xf86.h"

#include "xf86_ansic.h"
#include "xf86_OSproc.h"

extern DriverRec ATI;

#endif /* ___ATI_H___ */

--- NEW FILE: atiaccel.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiaccel.c,v 1.13 2003/04/24 21:19:22 tsi Exp $ */
/*
 * Copyright 2001 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

#include "atiaccel.h"
#include "atiadapter.h"
#include "atimach64accel.h"
#include "atistruct.h"

/*
 * ATIInitializeAcceleration --
 *
 * This function is called to initialise both the framebuffer manager and XAA
 * on a screen.
 */
Bool
ATIInitializeAcceleration
(
    ScreenPtr   pScreen,
    ScrnInfoPtr pScreenInfo,
    ATIPtr      pATI
)
{
    int maxScanlines = 32767, maxPixelArea, PixelArea;

    if (pATI->OptionAccel)
    {
        if (!(pATI->pXAAInfo = XAACreateInfoRec()))
            return FALSE;

        switch (pATI->Adapter)
        {
            case ATI_ADAPTER_MACH64:
                maxScanlines = ATIMach64AccelInit(pATI, pATI->pXAAInfo);
                break;

            default:
                break;
        }
    }

#ifndef AVOID_CPIO

    if (!pATI->BankInfo.BankSize)

#endif /* AVOID_CPIO */

    {
        /*
         * Note:  If PixelArea exceeds the engine's maximum, the excess is
         *        never used, even though it would be useful for such things
         *        as XVideo buffers.
         */
        maxPixelArea = maxScanlines * pScreenInfo->displayWidth;
        PixelArea = pScreenInfo->videoRam * 1024 * 8 / pATI->bitsPerPixel;
        if (PixelArea > maxPixelArea)
            PixelArea = maxPixelArea;
        xf86InitFBManagerArea(pScreen, PixelArea, 2);
    }

    if (!pATI->OptionAccel || XAAInit(pScreen, pATI->pXAAInfo))
        return TRUE;

    XAADestroyInfoRec(pATI->pXAAInfo);
    pATI->pXAAInfo = NULL;
    return FALSE;
}

FBLinearPtr
ATIResizeOffscreenLinear
(
    ScreenPtr   pScreen,
    FBLinearPtr pLinear,
    int         Size
)
{
    if (Size <= 0)
    {
        xf86FreeOffscreenLinear(pLinear);
        return NULL;
    }

    if (pLinear)
    {
        if ((pLinear->size >= Size) ||
            xf86ResizeOffscreenLinear(pLinear, Size))
        {
            pLinear->MoveLinearCallback = NULL;
            pLinear->RemoveLinearCallback = NULL;
            return pLinear;
        }

        xf86FreeOffscreenLinear(pLinear);
    }

    pLinear = xf86AllocateOffscreenLinear(pScreen, Size, 16, NULL, NULL, NULL);

    if (!pLinear)
    {
        int maxSize;

        xf86QueryLargestOffscreenLinear(pScreen, &maxSize, 16,
            PRIORITY_EXTREME);

        if (maxSize < Size)
            return NULL;

        xf86PurgeUnlockedOffscreenAreas(pScreen);
        pLinear =
            xf86AllocateOffscreenLinear(pScreen, Size, 16, NULL, NULL, NULL);
    }

    return pLinear;
}

--- NEW FILE: atiaccel.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiaccel.h,v 1.5 2003/04/23 21:51:27 tsi Exp $ */
/*
 * Copyright 2001 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIACCEL_H___
#define ___ATIACCEL_H___ 1

#include "atipriv.h"
#include "atiproto.h"

#include "xf86str.h"
#include "xf86fbman.h"

extern Bool        ATIInitializeAcceleration FunctionPrototype((ScreenPtr,
                                                                ScrnInfoPtr,
                                                                ATIPtr));

extern FBLinearPtr ATIResizeOffscreenLinear  FunctionPrototype((ScreenPtr,
                                                                FBLinearPtr,
                                                                int));

#endif /* ___ATIACCEL_H___ */

--- NEW FILE: atiadapter.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiadapter.c,v 1.17 2003/01/01 19:16:30 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

#include "atiadapter.h"

/*
 * Adapter-related definitions.
 */
const char *ATIAdapterNames[] =
{
    "Unknown",

#ifndef AVOID_CPIO

    "ATI EGA Wonder800",
    "ATI EGA Wonder800+",
    "IBM VGA or compatible",
    "ATI VGA Basic16",
    "ATI VGA Wonder V3",
    "ATI VGA Wonder V4",
    "ATI VGA Wonder V5",
    "ATI VGA Wonder+",
    "ATI VGA Wonder XL or XL24",
    "ATI VGA Wonder VLB or PCI",
    "IBM 8514/A or compatible",
    "ATI Mach8",
    "ATI Mach32",

#endif /* AVOID_CPIO */

    "ATI Mach64",
    "ATI Rage128",
    "ATI Radeon"
};

--- NEW FILE: atiadapter.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiadapter.h,v 1.10 2003/01/01 19:16:30 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIADAPTER_H___
#define ___ATIADAPTER_H___ 1

/*
 * Adapter-related definitions.
 */
typedef enum
{
    ATI_ADAPTER_NONE = 0,

#ifndef AVOID_CPIO

    ATI_ADAPTER_EGA,
    ATI_ADAPTER_EGA_PLUS,
    ATI_ADAPTER_VGA,
    ATI_ADAPTER_BASIC,
    ATI_ADAPTER_V3,
    ATI_ADAPTER_V4,
    ATI_ADAPTER_V5,
    ATI_ADAPTER_PLUS,
    ATI_ADAPTER_XL,
    ATI_ADAPTER_NONISA,
    ATI_ADAPTER_8514A,
    ATI_ADAPTER_MACH8,
    ATI_ADAPTER_MACH32,

#endif /* AVOID_CPIO */

    ATI_ADAPTER_MACH64,
    ATI_ADAPTER_RAGE128,
    ATI_ADAPTER_RADEON,
    ATI_ADAPTER_MAX     /* Must be last */
} ATIAdapterType;

extern const char *ATIAdapterNames[];

#endif /* ___ATIADAPTER_H___ */

--- NEW FILE: atiadjust.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiadjust.c,v 1.15 2003/04/23 21:51:27 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

#include "ati.h"
#include "atiadjust.h"
#include "atichip.h"
#include "aticrtc.h"
#include "atilock.h"
#include "atimach64io.h"
#include "atiwonderio.h"

/*
 * The display start address is expressed in units of 32-bit (VGA) or 64-bit
 * (accelerator) words where all planar modes are considered as 4bpp modes.
 * These functions ensure the start address does not exceed architectural
 * limits.  Also, to avoid colour changes while panning, these 32-bit or 64-bit
 * boundaries may not fall within a pixel.
 */

/*
 * ATIAjustPreInit --
 *
 * This function calculates values needed to speed up the setting of the
 * display start address.
 */
void
ATIAdjustPreInit
(
    ATIPtr      pATI
)
{
    unsigned long MaxBase;

#ifndef AVOID_CPIO

    if ((pATI->CPIO_VGAWonder) &&
        (pATI->Chip <= ATI_CHIP_18800_1) &&
        (pATI->VideoRAM == 256) &&
        (pATI->depth >= 8))
    {
        /* Strange, to say the least ... */
        pATI->AdjustDepth = (pATI->bitsPerPixel + 3) >> 2;
        pATI->AdjustMask = (unsigned long)(-32);
    }
    else

#endif /* AVOID_CPIO */

    {
        pATI->AdjustDepth = (pATI->bitsPerPixel + 7) >> 3;

        pATI->AdjustMask = 64;
        while (pATI->AdjustMask % (unsigned long)(pATI->AdjustDepth))
            pATI->AdjustMask += 64;
        pATI->AdjustMask =
            ~(((pATI->AdjustMask / (unsigned long)(pATI->AdjustDepth)) >> 3) -
              1);
    }

    switch (pATI->NewHW.crtc)
    {

#ifndef AVOID_CPIO

        case ATI_CRTC_VGA:
            if (pATI->Chip >= ATI_CHIP_264CT)
            {
                pATI->AdjustMaxBase = MaxBits(CRTC_OFFSET_VGA) << 2;
                if (pATI->depth <= 4)
                    pATI->AdjustMaxBase <<= 1;
            }
            else if (!pATI->CPIO_VGAWonder)
            {
                pATI->AdjustMaxBase = 0xFFFFU << 3;
            }
            else if (pATI->Chip <= ATI_CHIP_28800_6)
            {
                pATI->AdjustMaxBase = 0x03FFFFU << 3;
            }
            else /* Mach32 & Mach64 */
            {
                pATI->AdjustMaxBase = 0x0FFFFFU << 3;
            }
            break;

#endif /* AVOID_CPIO */

        case ATI_CRTC_MACH64:
            pATI->AdjustMaxBase = MaxBits(CRTC_OFFSET) << 3;
            break;

        default:
            pATI->AdjustMaxBase = 0;
            break;
    }

    MaxBase = (pATI->AdjustMaxBase / (unsigned long)pATI->AdjustDepth) |
        ~pATI->AdjustMask;

    pATI->AdjustMaxX = MaxBase % pATI->displayWidth;
    pATI->AdjustMaxY = MaxBase / pATI->displayWidth;
}

/*
 * ATIAdjustFrame --
 *
 * This function is used to initialise the SVGA Start Address - the first
 * displayed location in video memory.  This is used to implement the virtual
 * window.
 */
void
ATIAdjustFrame
(
    int scrnIndex,
    int x,
    int y,
    int flags
)
{
    ScrnInfoPtr pScreenInfo = xf86Screens[scrnIndex];
    ATIPtr      pATI = ATIPTR(pScreenInfo);
    int         Base, xy;

    /*
     * Assume the caller has already done its homework in ensuring the physical
     * screen is still contained in the virtual resolution.
     */
    if (y >= pATI->AdjustMaxY)
    {
        y = pATI->AdjustMaxY;
        if (x > pATI->AdjustMaxX)
            y--;
    }

    Base = ((((y * pATI->displayWidth) + x) & pATI->AdjustMask) *
            pATI->AdjustDepth) >> 3;

    if (!pATI->currentMode)
    {
        /*
         * Not in DGA.  This reverse-calculates pScreenInfo->frame[XY][01] so
         * that the cursor does not move on mode switches.
         */
        xy = (Base << 3) / pATI->AdjustDepth;
        pScreenInfo->frameX0 = xy % pATI->displayWidth;
        pScreenInfo->frameY0 = xy / pATI->displayWidth;
        pScreenInfo->frameX1 =
            pScreenInfo->frameX0 + pScreenInfo->currentMode->HDisplay - 1;
        pScreenInfo->frameY1 =
            pScreenInfo->frameY0 + pScreenInfo->currentMode->VDisplay - 1;
    }

    /* Unlock registers */
    ATIUnlock(pATI);

#ifndef AVOID_CPIO

    if ((pATI->NewHW.crtc == ATI_CRTC_VGA) && (pATI->Chip < ATI_CHIP_264CT))
    {
        PutReg(CRTX(pATI->CPIO_VGABase), 0x0CU, GetByte(Base, 1));
        PutReg(CRTX(pATI->CPIO_VGABase), 0x0DU, GetByte(Base, 0));

        if (pATI->CPIO_VGAWonder)
        {
            if (pATI->Chip <= ATI_CHIP_18800_1)
                ATIModifyExtReg(pATI, 0xB0U, -1, 0x3FU, Base >> 10);
            else
            {
                ATIModifyExtReg(pATI, 0xB0U, -1, 0xBFU, Base >> 10);
                ATIModifyExtReg(pATI, 0xA3U, -1, 0xEFU, Base >> 13);

                /*
                 * I don't know if this also applies to Mach64's, but give it a
                 * shot...
                 */
                if (pATI->Chip >= ATI_CHIP_68800)
                    ATIModifyExtReg(pATI, 0xADU, -1, 0xF3U, Base >> 16);
            }
        }
    }
    else
    /*
     * On integrated controllers, there is only one set of CRTC control bits,
     * many of which are simultaneously accessible through both VGA and
     * accelerator I/O ports.  Given VGA's architectural limitations, setting
     * the CRTC's offset register to more than 256k needs to be done through
     * the accelerator port.
     */
    if (pATI->depth <= 4)
    {
        outr(CRTC_OFF_PITCH, SetBits(pATI->displayWidth >> 4, CRTC_PITCH) |
            SetBits(Base, CRTC_OFFSET));
    }
    else

#endif /* AVOID_CPIO */

    {

#ifndef AVOID_CPIO

        if (pATI->NewHW.crtc == ATI_CRTC_VGA)
            Base <<= 1;                 /* LSBit must be zero */

#endif /* AVOID_CPIO */

        outr(CRTC_OFF_PITCH, SetBits(pATI->displayWidth >> 3, CRTC_PITCH) |
            SetBits(Base, CRTC_OFFSET));
    }
}

--- NEW FILE: atiadjust.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiadjust.h,v 1.8 2003/01/01 19:16:30 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIADJUST_H___
#define ___ATIADJUST_H___ 1

#include "atipriv.h"
#include "atiproto.h"

extern void ATIAdjustPreInit FunctionPrototype((ATIPtr));
extern void ATIAdjustFrame   FunctionPrototype((int, int, int, int));

#endif /* ___ATIADJUST_H___ */

--- NEW FILE: atiaudio.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiaudio.c,v 1.1 2003/07/24 22:08:27 tsi Exp $ */
/*
 * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

#include "atiaudio.h"

/*
 * Audio chip definitions.
 */
const char *ATIAudioNames[] =
{
    "Philips TEA5582",
    "Mono with audio mux",
    "Philips TDA9850",
    "Sony CXA2020S",
    "ITT MSP3410D",
    "Crystal CS4236B",
    "Philips TDA9851",
    "ITT MSP3415",
    "ITT MSP3430",
    "Unknown type (9)",
    "Unknown type (10)",
    "Unknown type (11)",
    "Unknown type (12)",
    "Unknown type (13)",
    "Unknown type (14)",
    "No audio"
};

--- NEW FILE: atiaudio.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiaudio.h,v 1.1 2003/07/24 22:08:27 tsi Exp $ */
/*
 * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIAUDIO_H___
#define ___ATIAUDIO_H___ 1

/*
 * Audio chip definitions.
 */
typedef enum
{
    ATI_AUDIO_TEA5582,
    ATI_AUDIO_MONO,
    ATI_AUDIO_TDA9850,
    ATI_AUDIO_CXA2020S,
    ATI_AUDIO_MSP3410D,
    ATI_AUDIO_CS4236B,
    ATI_AUDIO_TDA9851,
    ATI_AUDIO_MSP3415,
    ATI_AUDIO_MSP3430,
    ATI_AUDIO_9,
    ATI_AUDIO_10,
    ATI_AUDIO_11,
    ATI_AUDIO_12,
    ATI_AUDIO_13,
    ATI_AUDIO_14,
    ATI_AUDIO_NONE
} ATIAudioType;

extern const char *ATIAudioNames[];

#endif /* ___ATIAUDIO_H___ */

--- NEW FILE: atibank.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atibank.c,v 1.12 2003/01/01 19:16:30 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

#include "ati.h"
#include "atibank.h"
#include "atimach64io.h"
#include "atiwonderio.h"

#ifndef AVOID_CPIO

/*
 * ATI VGA Wonder V3 adapters use an ATI 18800 chip and are single-banked.
 * Bank selection is done with bits 0x1E of ATI extended VGA register index
 * 0xB2.
 */

/*
 * ATIV3SetBank --
 *
 * Set an ATI 18800's bank number.
 */
void
ATIV3SetBank
(
    ATIPtr       pATI,
    unsigned int iBank
)
{
    ATIModifyExtReg(pATI, 0xB2U, -1, (CARD8)(~0x1EU), SetBits(iBank, 0x1EU));
}

/*
 * ATIV3SetReadWrite --
 *
 * Set an ATI 18800's bank number.
 */
int
ATIV3SetReadWrite
(
    ScreenPtr    pScreen,
    unsigned int iBank
)
{
    ATIPtr pATI = ATIPTR(XF86SCRNINFO(pScreen));

    ATIModifyExtReg(pATI, 0xB2U, -1, (CARD8)(~0x1EU), SetBits(iBank, 0x1EU));
    return 0;
}

/*
 * ATI VGA Wonder V4 and V5 adapters use an ATI 18800-1 chip.  Bank selection
 * is done with ATI extended VGA register index 0xB2.  The format is:
 *
 *   0xE0 - Read bank select bits 0x07
 *   0x1E - Write bank select bits 0x0F
 *   0x01 - Read bank select bit 0x08.
 */

/*
 * ATIV4V5SetBank --
 *
 * Set an ATI 18800-1's read and write bank numbers.
 */
void
ATIV4V5SetBank
(
    ATIPtr       pATI,
    unsigned int iBank
)
{
    pATI->B2Reg = SetBits(iBank, 0x1EU) | SetBits(iBank, 0xE0U) |
        SetBits(GetBits(iBank, 0x08U), 0x01U);
    ATIPutExtReg(0xB2U, pATI->B2Reg);
}

/*
 * ATIV4V5SetRead --
 *
 * Set an ATI 18800-1's read bank number.
 */
int
ATIV4V5SetRead
(
    ScreenPtr    pScreen,
    unsigned int iBank
)
{
    ATIPtr pATI  = ATIPTR(XF86SCRNINFO(pScreen));
    CARD8  B2Reg = (pATI->B2Reg & 0x1EU) | SetBits(iBank, 0xE0U) |
                   SetBits(GetBits(iBank, 0x08U), 0x01U);

    if (B2Reg != pATI->B2Reg)
    {
        ATIPutExtReg(0xB2U, B2Reg);
        pATI->B2Reg = B2Reg;
    }

    return 0;
}

/*
 * ATIV4V5SetWrite --
 *
 * Set an ATI 18800-1's write bank number.
 */
int
ATIV4V5SetWrite
(
    ScreenPtr    pScreen,
    unsigned int iBank
)
{
    ATIPtr pATI = ATIPTR(XF86SCRNINFO(pScreen));
    CARD8  B2Reg = (pATI->B2Reg & 0xE1U) | SetBits(iBank, 0x1EU);

    if (B2Reg != pATI->B2Reg)
    {
        ATIPutExtReg(0xB2U, B2Reg);
        pATI->B2Reg = B2Reg;
    }
    return 0;
}

/*
 * ATIV4V5SetReadWrite --
 *
 * Set an ATI 18800-1's read and write bank numbers.
 */
int
ATIV4V5SetReadWrite
(
    ScreenPtr    pScreen,
    unsigned int iBank
)
{
    ATIV4V5SetBank(ATIPTR(XF86SCRNINFO(pScreen)), iBank);
    return 0;
}

/*
 * In addition to ATI extended register index 0xB2, 28800's, 68800's and
 * 88800's define banking bits in bits 0x0F of ATI extended VGA register index
 * 0xAE.  These are only needed for adapters with more than 1MB of video
 * memory, and it is questionable whether or not they are actually implemented
 * by 28800's and 88800's.  ATI extended VGA register index 0xAE is defined as
 * follows:
 *
 *    0xF0 - reserved
 *    0x0C - read bank select bits 0x30
 *    0x03 - write bank select bits 0x30
 */

/*
 * ATIx8800SetBank --
 *
 * Set an ATI 28800's, 68800's or 88800's read and write bank numbers.
 */
void
ATIx8800SetBank
(
    ATIPtr       pATI,
    unsigned int iBank
)
{
    ATIV4V5SetBank(pATI, iBank);
    iBank = GetBits(iBank, 0x30U);
    ATIModifyExtReg(pATI, 0xAEU, -1, (CARD8)(~0x0FU),
        SetBits(iBank, 0x03U) | SetBits(iBank, 0x0CU));
}

/*
 * ATIx8800SetRead --
 *
 * Set an ATI 28800's, 68800's or 88800's read bank numbers.
 */
int
ATIx8800SetRead
(
    ScreenPtr    pScreen,
    unsigned int iBank
)
{
    (void)ATIV4V5SetRead(pScreen, iBank);
    ATIModifyExtReg(ATIPTR(XF86SCRNINFO(pScreen)), 0xAEU, -1, (CARD8)(~0x0CU),
        SetBits(GetBits(iBank, 0x30U), 0x0CU));
    return 0;
}

/*
 * ATIx8800SetWrite --
 *
 * Set an ATI 28800's, 68800's or 88800's write bank numbers.
 */
int
ATIx8800SetWrite
(
    ScreenPtr    pScreen,
    unsigned int iBank
)
{
    (void)ATIV4V5SetWrite(pScreen, iBank);
    ATIModifyExtReg(ATIPTR(XF86SCRNINFO(pScreen)), 0xAEU, -1, (CARD8)(~0x03U),
        SetBits(GetBits(iBank, 0x30U), 0x03U));
    return 0;
}

/*
 * ATIx8800SetReadWrite --
 *
 * Set an ATI 28800's, 68800's or 88800's read and write bank numbers.
 */
int
ATIx8800SetReadWrite
(
    ScreenPtr    pScreen,
    unsigned int iBank
)
{
    ATIx8800SetBank(ATIPTR(XF86SCRNINFO(pScreen)), iBank);
    return 0;
}

/*
 * Functions to simulate a banked VGA aperture using a Mach64's small dual
 * paged apertures.  There are two sets of these:  one for packed modes, the
 * other for planar modes.
 */

static CARD32
ATIMach64MassagePackedBankNumber
(
    CARD8 iBank
)
{
    iBank <<= 1;
    return ((iBank + 1) << 16) | iBank;
}

/*
 * ATIMach64SetBankPacked --
 *
 * Set read and write bank numbers for small dual paged apertures.
 */
void
ATIMach64SetBankPacked
(
    ATIPtr       pATI,
    unsigned int iBank
)
{
    CARD32 tmp = ATIMach64MassagePackedBankNumber(iBank);

    outr(MEM_VGA_RP_SEL, tmp);
    outr(MEM_VGA_WP_SEL, tmp);
}

/*
 * ATIMach64SetReadPacked --
 *
 * Set read bank number for small dual paged apertures.
 */
int
ATIMach64SetReadPacked
(
    ScreenPtr    pScreen,
    unsigned int iBank
)
{
    ATIPtr pATI = ATIPTR(XF86SCRNINFO(pScreen));

    outr(MEM_VGA_RP_SEL, ATIMach64MassagePackedBankNumber(iBank));
    return 0;
}

/*
 * ATIMach64SetWritePacked --
 *
 * Set write bank number for small dual paged apertures.
 */
int
ATIMach64SetWritePacked
(
    ScreenPtr    pScreen,
    unsigned int iBank
)
{
    ATIPtr pATI = ATIPTR(XF86SCRNINFO(pScreen));

    outr(MEM_VGA_WP_SEL, ATIMach64MassagePackedBankNumber(iBank));
    return 0;
}

/*
 * ATIMach64SetReadWritePacked --
 *
 * Set read and write bank numbers for small dual paged apertures.
 */
int
ATIMach64SetReadWritePacked
(
    ScreenPtr    pScreen,
    unsigned int iBank
)
{
    ATIMach64SetBankPacked(ATIPTR(XF86SCRNINFO(pScreen)), iBank);
    return 0;
}

static CARD32
ATIMach64MassagePlanarBankNumber
(
    CARD8 iBank
)
{
    iBank <<= 3;
    return ((iBank + 4) << 16) | iBank;
}

/*
 * ATIMach64SetBankPlanar --
 *
 * Set read and write bank numbers for small dual paged apertures.
 */
void
ATIMach64SetBankPlanar
(
    ATIPtr       pATI,
    unsigned int iBank
)
{
    CARD32 tmp = ATIMach64MassagePlanarBankNumber(iBank);

    outr(MEM_VGA_RP_SEL, tmp);
    outr(MEM_VGA_WP_SEL, tmp);
}

/*
 * ATIMach64SetReadPlanar --
 *
 * Set read bank number for small dual paged apertures.
 */
int
ATIMach64SetReadPlanar
(
    ScreenPtr    pScreen,
    unsigned int iBank
)
{
    ATIPtr pATI = ATIPTR(XF86SCRNINFO(pScreen));

    outr(MEM_VGA_RP_SEL, ATIMach64MassagePlanarBankNumber(iBank));
    return 0;
}

/*
 * ATIMach64SetWritePlanar --
 *
 * Set write bank number for small dual paged apertures.
 */
int
ATIMach64SetWritePlanar
(
    ScreenPtr    pScreen,
    unsigned int iBank
)
{
    ATIPtr pATI = ATIPTR(XF86SCRNINFO(pScreen));

    outr(MEM_VGA_WP_SEL, ATIMach64MassagePlanarBankNumber(iBank));
    return 0;
}

/*
 * ATIMach64SetReadWritePlanar --
 *
 * Set read and write bank numbers for small dual paged apertures.
 */
int
ATIMach64SetReadWritePlanar
(
    ScreenPtr    pScreen,
    unsigned int iBank
)
{
    ATIMach64SetBankPlanar(ATIPTR(XF86SCRNINFO(pScreen)), iBank);
    return 0;
}

#endif /* AVOID_CPIO */

--- NEW FILE: atibank.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atibank.h,v 1.8 2003/01/01 19:16:30 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIBANK_H___
#define ___ATIBANK_H___ 1

#include "atipriv.h"
#include "atiproto.h"

#include "mibank.h"

#ifndef AVOID_CPIO

/*
 * Banking definitions.
 */

/*
 * Bank selection function for VGA Wonder V3 adapters (which are
 * single-banked).
 */
#define ATIV3SetRead     ATIV3SetReadWrite
#define ATIV3SetWrite    ATIV3SetReadWrite
extern miBankProc        ATIV3SetReadWrite;

/*
 * Bank selection functions for VGA Wonder V4 and V5 adapters.
 */
extern miBankProc        ATIV4V5SetRead,
                         ATIV4V5SetWrite,
                         ATIV4V5SetReadWrite;

/*
 * Bank selection functions for 28800-x, 68800-x and 88800 based adapters.
 */
extern miBankProc        ATIx8800SetRead,
                         ATIx8800SetWrite,
                         ATIx8800SetReadWrite;

/*
 * Bank selection functions used to simulate a banked VGA aperture with a
 * Mach64's small dual paged apertures.  There are two sets of these:  one for
 * packed modes, and one for planar modes.
 */
extern miBankProc        ATIMach64SetReadPacked,
                         ATIMach64SetWritePacked,
                         ATIMach64SetReadWritePacked;
extern miBankProc        ATIMach64SetReadPlanar,
                         ATIMach64SetWritePlanar,
                         ATIMach64SetReadWritePlanar;

/*
 * The CRT save/restore code also needs a separate banking interface that can
 * used before ATIScreenInit() is called.
 */

typedef void ATIBankProc FunctionPrototype((ATIPtr, unsigned int));
typedef ATIBankProc     *ATIBankProcPtr;

extern ATIBankProc       ATIV3SetBank,
                         ATIV4V5SetBank,
                         ATIx8800SetBank,
                         ATIMach64SetBankPacked,
                         ATIMach64SetBankPlanar;

#endif /* AVOID_CPIO */

#endif /* ___ATIBANK_H___ */

--- NEW FILE: atibus.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atibus.c,v 1.18 2003/01/22 21:44:10 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

#include "ati.h"
#include "atiadapter.h"
#include "atibus.h"
#include "atichip.h"
#include "atiio.h"
#include "atistruct.h"
#include "ativersion.h"

/*
 * Definitions related to an adapter's system bus interface.
 */

const char *ATIBusNames[] =
{
    "16-Bit ISA",
    "EISA",
    "16-Bit MicroChannel",
    "32-Bit MicroChannel",
    "386SX Local Bus",
    "386DX Local Bus",
    "VESA Local Bus",
    "PCI",
    "AGP"
};

/*
 * ATIClaimResources --
 *
 * This function registers most of the bus resources used by an adapter.  The
 * exceptions are PCI-configured resources and non-PCI non-AGP linear
 * apertures, both of which are registered by ATIPreInit().  This function also
 * attempts to register unshareable resources for inactive PCI adapters,
 * whether or not they are relocatable.
 */
static void
ATIClaimResources
(
    ATIPtr pATI,
    Bool   Active
)
{
    resPtr   pResources;

#ifndef AVOID_CPIO

    resRange Resources[2] = {{0, 0, 0}, _END};

    /* Claim VGA and VGAWonder resources */
    if ((pATI->VGAAdapter != ATI_ADAPTER_NONE) && (Active || !pATI->SharedVGA))
    {
        /*
         * 18800-x's are the only ATI controllers that decode all ISA aliases
         * of VGA and VGA Wonder I/O ports.  Other x8800's do not decode >any<
         * VGA aliases, but do decode VGA Wonder aliases whose most significant
         * nibble is zero.
         */
        xf86ClaimFixedResources(
            (pATI->Chip <= ATI_CHIP_18800_1) ?
            (pATI->SharedVGA ? resVgaSparseShared : resVgaSparseExclusive) :
            (pATI->SharedVGA ? resVgaShared : resVgaExclusive),
            pATI->iEntity);

        if (pATI->CPIO_VGAWonder)
        {
            if (pATI->SharedVGA)
                Resources[0].type = ResShrIoSparse | ResBus;
            else
                Resources[0].type = ResExcIoSparse | ResBus;
            Resources[0].rBase = pATI->CPIO_VGAWonder;
            if (pATI->Chip <= ATI_CHIP_18800_1)
                Resources[0].rMask = 0x03FEU;
            else
                Resources[0].rMask = 0xF3FEU;

            xf86ClaimFixedResources(Resources, pATI->iEntity);

            (void)memcpy(pATI->VGAWonderResources,
                Resources, SizeOf(Resources));
        }
    }

    if (!Active && pATI->SharedAccelerator)
        return;

    /* Claim 8514/A resources */
    if (pATI->ChipHasSUBSYS_CNTL)
        xf86ClaimFixedResources(
            pATI->SharedAccelerator ? res8514Shared : res8514Exclusive,
            pATI->iEntity);

    /* Claim Mach64 sparse I/O resources */
    if ((pATI->Adapter == ATI_ADAPTER_MACH64) &&
        (pATI->CPIODecoding == SPARSE_IO))
    {
        if (pATI->SharedAccelerator)
            Resources[0].type = ResShrIoSparse | ResBus;
        else
            Resources[0].type = ResExcIoSparse | ResBus;
        Resources[0].rBase = pATI->CPIOBase;
        Resources[0].rMask = 0x03FCU;

        xf86ClaimFixedResources(Resources, pATI->iEntity);
    }

    if (Active)
        return;

#else /* AVOID_CPIO */

    if (pATI->SharedAccelerator)
        return;

#endif /* AVOID_CPIO */

    /* Register unshared relocatable resources for inactive adapters */
    do
    {
        pResources = xf86RegisterResources(pATI->iEntity, NULL, ResExclusive);
        if (!pResources)
            return;

        pResources = xf86ReallocatePciResources(pATI->iEntity, pResources);
    } while (!pResources);

    xf86Msg(X_WARNING,
        ATI_NAME ":  Unable to register the following resources for inactive"
        " adapter:\n");
    xf86PrintResList(1, pResources);
    xf86FreeResList(pResources);
}

/*
 * ATIClaimBusSlot --
 *
 * Claim an adapter and register its resources.
 */
int
ATIClaimBusSlot
(
    DriverPtr pDriver,
    int       Chipset,
    GDevPtr   pGDev,
    Bool      Active,
    ATIPtr    pATI
)
{
    pciVideoPtr pVideo = pATI->PCIInfo;

    if (pVideo)
        pATI->iEntity =
            xf86ClaimPciSlot(pVideo->bus, pVideo->device, pVideo->func,
                pDriver, Chipset, pGDev, Active);
    else
        pATI->iEntity = xf86ClaimIsaSlot(pDriver, Chipset, pGDev, Active);

    if (pATI->iEntity >= 0)
        ATIClaimResources(pATI, Active);

    return pATI->iEntity;
}

--- NEW FILE: atibus.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atibus.h,v 1.11 2003/01/01 19:16:30 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIBUS_H___

#if !defined(___ATI_H___) && defined(XFree86Module)
# error missing #include "ati.h" before #include "atibus.h"
# undef XFree86Module
#endif

#define ___ATIBUS_H___ 1

#include "atipriv.h"
#include "atiproto.h"

#include "xf86str.h"

/*
 * Definitions related to an adapter's system bus interface.
 */
typedef enum
{
    ATI_BUS_ISA = 0,
    ATI_BUS_EISA,
    ATI_BUS_MCA16,
    ATI_BUS_MCA32,
    ATI_BUS_SXLB,
    ATI_BUS_DXLB,
    ATI_BUS_VLB,
    ATI_BUS_PCI,
    ATI_BUS_AGP
} ATIBusType;

extern const char *ATIBusNames[];

extern int ATIClaimBusSlot FunctionPrototype((DriverPtr, int, GDevPtr, Bool,
                                              ATIPtr));

#endif /* ___ATIBUS_H___ */

--- NEW FILE: atichip.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atichip.c,v 1.38tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

#include "ati.h"
#include "atibus.h"
#include "atichip.h"
#include "atimach64io.h"
#include "ativersion.h"

/*
 * Chip-related definitions.
 */
const char *ATIChipNames[] =
{
    "Unknown",

#ifndef AVOID_CPIO

    "IBM VGA or compatible",
    "ATI 18800",
    "ATI 18800-1",
    "ATI 28800-2",
    "ATI 28800-4",
    "ATI 28800-5",
    "ATI 28800-6",
    "IBM 8514/A",
    "Chips & Technologies 82C480",
    "ATI 38800-1",
    "ATI 68800",
    "ATI 68800-3",
    "ATI 68800-6",
    "ATI 68800LX",
    "ATI 68800AX",

#endif /* AVOID_CPIO */

    "ATI 88800GX-C",
    "ATI 88800GX-D",
    "ATI 88800GX-E",
    "ATI 88800GX-F",
    "ATI 88800GX",
    "ATI 88800CX",
    "ATI 264CT",
    "ATI 264ET",
    "ATI 264VT",
    "ATI 3D Rage",
    "ATI 264VT-B",
    "ATI 3D Rage II",
    "ATI 264VT3",
    "ATI 3D Rage II+DVD",
    "ATI 3D Rage LT",
    "ATI 264VT4",
    "ATI 3D Rage IIc",
    "ATI 3D Rage Pro",
    "ATI 3D Rage LT Pro",
    "ATI 3D Rage XL or XC",
    "ATI 3D Rage Mobility",
    "ATI unknown Mach64",
    "ATI Rage 128 GL",
    "ATI Rage 128 VR",
    "ATI Rage 128 Pro GL",
    "ATI Rage 128 Pro VR",
    "ATI Rage 128 Pro ULTRA",
    "ATI Rage 128 Mobility M3",
    "ATI Rage 128 Mobility M4",
    "ATI unknown Rage 128"
    "ATI Radeon 7200",
    "ATI Radeon 7000 (VE)",
    "ATI Radeon Mobility M6",
    "ATI Radeon IGP320",
    "ATI Radeon IGP330/340/350",
    "ATI Radeon 7000 IGP",
    "ATI Radeon 7500",
    "ATI Radeon Mobility M7",
    "ATI Radeon 8500/9100",
    "ATI Radeon 9000",
    "ATI Radeon Mobility M9",
    "ATI Radeon 9000 IGP",
    "ATI Radeon 9200",
    "ATI Radeon Mobility M9+",
    "ATI Radeon 9700/9500",
    "ATI Radeon 9600",
    "ATI Radeon 9800",
    "ATI Radeon 9800XT",
    "ATI unknown Radeon",
    "ATI Rage HDTV"
};

const char *ATIFoundryNames[] =
    { "SGS", "NEC", "KCS", "UMC", "TSMC", "5", "6", "UMC" };

#ifndef AVOID_CPIO

/*
 * ATIMach32ChipID --
 *
 * Set variables whose value is dependent upon an 68800's CHIP_ID register.
 */
void
ATIMach32ChipID
(
    ATIPtr pATI
)
{
    CARD16 IOValue     = inw(CHIP_ID);
    pATI->ChipType     = GetBits(IOValue, CHIP_CODE_0 | CHIP_CODE_1);
    pATI->ChipClass    = GetBits(IOValue, CHIP_CLASS);
    pATI->ChipRevision = GetBits(IOValue, CHIP_REV);
    pATI->ChipRev      = pATI->ChipRevision;
    if (IOValue == 0xFFFFU)
        IOValue = 0;
    switch (GetBits(IOValue, CHIP_CODE_0 | CHIP_CODE_1))
    {
        case OldChipID('A', 'A'):
            pATI->Chip = ATI_CHIP_68800_3;
            break;

        case OldChipID('X', 'X'):
            pATI->Chip = ATI_CHIP_68800_6;
            break;

        case OldChipID('L', 'X'):
            pATI->Chip = ATI_CHIP_68800LX;
            break;

        case OldChipID('A', 'X'):
            pATI->Chip = ATI_CHIP_68800AX;
            break;

        default:
            pATI->Chip = ATI_CHIP_68800;
            break;
    }
}

#endif /* AVOID_CPIO */

/*
 * ATIMach64ChipID --
 *
 * Set variables whose value is dependent upon a Mach64's CONFIG_CHIP_ID
 * register.
 */
void
ATIMach64ChipID
(
    ATIPtr       pATI,
    const CARD16 ExpectedChipType
)
{
    pATI->config_chip_id = inr(CONFIG_CHIP_ID);
    pATI->ChipType       = GetBits(pATI->config_chip_id, 0xFFFFU);
    pATI->ChipClass      = GetBits(pATI->config_chip_id, CFG_CHIP_CLASS);
    pATI->ChipRevision   = GetBits(pATI->config_chip_id, CFG_CHIP_REV);
    pATI->ChipVersion    = GetBits(pATI->config_chip_id, CFG_CHIP_VERSION);
    pATI->ChipFoundry    = GetBits(pATI->config_chip_id, CFG_CHIP_FOUNDRY);
    pATI->ChipRev        = pATI->ChipRevision;
    switch (pATI->ChipType)
    {
        case OldChipID('G', 'X'):
            pATI->ChipType = OldToNewChipID(pATI->ChipType);
        case NewChipID('G', 'X'):
            switch (pATI->ChipRevision)
            {
                case 0x00U:
                    pATI->Chip = ATI_CHIP_88800GXC;
                    break;

                case 0x01U:
                    pATI->Chip = ATI_CHIP_88800GXD;
                    break;

                case 0x02U:
                    pATI->Chip = ATI_CHIP_88800GXE;
                    break;

                case 0x03U:
                    pATI->Chip = ATI_CHIP_88800GXF;
                    break;

                default:
                    pATI->Chip = ATI_CHIP_88800GX;
                    break;
            }
            break;

        case OldChipID('C', 'X'):
            pATI->ChipType = OldToNewChipID(pATI->ChipType);
        case NewChipID('C', 'X'):
            pATI->Chip = ATI_CHIP_88800CX;
            break;

        case OldChipID('C', 'T'):
            pATI->ChipType = OldToNewChipID(pATI->ChipType);
        case NewChipID('C', 'T'):
            pATI->ChipRevision =
                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
            pATI->Chip = ATI_CHIP_264CT;
            pATI->BusType = ATI_BUS_PCI;
            break;

        case OldChipID('E', 'T'):
            pATI->ChipType = OldToNewChipID(pATI->ChipType);
        case NewChipID('E', 'T'):
            pATI->ChipRevision =
                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
            pATI->Chip = ATI_CHIP_264ET;
            pATI->BusType = ATI_BUS_PCI;
            break;

        case OldChipID('V', 'T'):
            pATI->ChipType = OldToNewChipID(pATI->ChipType);
        case NewChipID('V', 'T'):
            pATI->ChipRevision =
                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
            pATI->Chip = ATI_CHIP_264VT;
            pATI->BusType = ATI_BUS_PCI;
            /* Some early GT's are detected as VT's */
            if (ExpectedChipType && (pATI->ChipType != ExpectedChipType))
            {
                if (ExpectedChipType == NewChipID('G', 'T'))
                    pATI->Chip = ATI_CHIP_264GT;
                else
                    xf86Msg(X_WARNING,
                            ATI_NAME ":  Mach64 chip type probe discrepancy"
                            " detected:  PCI=0x%04X;  CHIP_ID=0x%04X.\n",
                            ExpectedChipType, pATI->ChipType);
            }
            else if (pATI->ChipVersion)
                pATI->Chip = ATI_CHIP_264VTB;
            break;

        case OldChipID('G', 'T'):
            pATI->ChipType = OldToNewChipID(pATI->ChipType);
        case NewChipID('G', 'T'):
            pATI->ChipRevision =
                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
            pATI->BusType = ATI_BUS_PCI;
            if (!pATI->ChipVersion)
                pATI->Chip = ATI_CHIP_264GT;
            else
                pATI->Chip = ATI_CHIP_264GTB;
            break;

        case OldChipID('V', 'U'):
            pATI->ChipType = OldToNewChipID(pATI->ChipType);
        case NewChipID('V', 'U'):
            pATI->ChipRevision =
                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
            pATI->Chip = ATI_CHIP_264VT3;
            pATI->BusType = ATI_BUS_PCI;
            break;

        case OldChipID('G', 'U'):
            pATI->ChipType = OldToNewChipID(pATI->ChipType);
        case NewChipID('G', 'U'):
            pATI->ChipRevision =
                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
            pATI->Chip = ATI_CHIP_264GTDVD;
            pATI->BusType = ATI_BUS_PCI;
            break;

        case OldChipID('L', 'G'):
            pATI->ChipType = OldToNewChipID(pATI->ChipType);
        case NewChipID('L', 'G'):
            pATI->ChipRevision =
                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
            pATI->Chip = ATI_CHIP_264LT;
            pATI->BusType = ATI_BUS_PCI;
            break;

        case OldChipID('V', 'V'):
            pATI->ChipType = OldToNewChipID(pATI->ChipType);
        case NewChipID('V', 'V'):
            pATI->ChipRevision =
                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
            pATI->Chip = ATI_CHIP_264VT4;
            pATI->BusType = ATI_BUS_PCI;
            break;

        case OldChipID('G', 'V'):
        case OldChipID('G', 'Y'):
            pATI->ChipType = OldToNewChipID(pATI->ChipType);
        case NewChipID('G', 'V'):
        case NewChipID('G', 'Y'):
            pATI->ChipRevision =
                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
            pATI->Chip = ATI_CHIP_264GT2C;
            pATI->BusType = ATI_BUS_PCI;
            break;

        case OldChipID('G', 'W'):
        case OldChipID('G', 'Z'):
            pATI->ChipType = OldToNewChipID(pATI->ChipType);
        case NewChipID('G', 'W'):
        case NewChipID('G', 'Z'):
            pATI->ChipRevision =
                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
            pATI->Chip = ATI_CHIP_264GT2C;
            pATI->BusType = ATI_BUS_AGP;
            break;

        case OldChipID('G', 'I'):
        case OldChipID('G', 'P'):
        case OldChipID('G', 'Q'):
            pATI->ChipType = OldToNewChipID(pATI->ChipType);
        case NewChipID('G', 'I'):
        case NewChipID('G', 'P'):
        case NewChipID('G', 'Q'):
            pATI->ChipRevision =
                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
            pATI->Chip = ATI_CHIP_264GTPRO;
            pATI->BusType = ATI_BUS_PCI;
            break;

        case OldChipID('G', 'B'):
        case OldChipID('G', 'D'):
            pATI->ChipType = OldToNewChipID(pATI->ChipType);
        case NewChipID('G', 'B'):
        case NewChipID('G', 'D'):
            pATI->ChipRevision =
                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
            pATI->Chip = ATI_CHIP_264GTPRO;
            pATI->BusType = ATI_BUS_AGP;
            break;

        case OldChipID('L', 'I'):
        case OldChipID('L', 'P'):
        case OldChipID('L', 'Q'):
            pATI->ChipType = OldToNewChipID(pATI->ChipType);
        case NewChipID('L', 'I'):
        case NewChipID('L', 'P'):
        case NewChipID('L', 'Q'):
            pATI->ChipRevision =
                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
            pATI->Chip = ATI_CHIP_264LTPRO;
            pATI->BusType = ATI_BUS_PCI;
            pATI->LCDVBlendFIFOSize = 800;
            break;

        case OldChipID('L', 'B'):
        case OldChipID('L', 'D'):
            pATI->ChipType = OldToNewChipID(pATI->ChipType);
        case NewChipID('L', 'B'):
        case NewChipID('L', 'D'):
            pATI->ChipRevision =
                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
            pATI->Chip = ATI_CHIP_264LTPRO;
            pATI->BusType = ATI_BUS_AGP;
            pATI->LCDVBlendFIFOSize = 800;
            break;

        case OldChipID('G', 'L'):
        case OldChipID('G', 'O'):
        case OldChipID('G', 'R'):
        case OldChipID('G', 'S'):
            pATI->ChipType = OldToNewChipID(pATI->ChipType);
        case NewChipID('G', 'L'):
        case NewChipID('G', 'O'):
        case NewChipID('G', 'R'):
        case NewChipID('G', 'S'):
            pATI->ChipRevision =
                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
            pATI->Chip = ATI_CHIP_264XL;
            pATI->BusType = ATI_BUS_PCI;
            pATI->LCDVBlendFIFOSize = 1024;
            break;

        case OldChipID('G', 'M'):
        case OldChipID('G', 'N'):
            pATI->ChipType = OldToNewChipID(pATI->ChipType);
        case NewChipID('G', 'M'):
        case NewChipID('G', 'N'):
            pATI->ChipRevision =
                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
            pATI->Chip = ATI_CHIP_264XL;
            pATI->BusType = ATI_BUS_AGP;
            pATI->LCDVBlendFIFOSize = 1024;
            break;

        case OldChipID('L', 'R'):
        case OldChipID('L', 'S'):
            pATI->ChipType = OldToNewChipID(pATI->ChipType);
        case NewChipID('L', 'R'):
        case NewChipID('L', 'S'):
            pATI->ChipRevision =
                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
            pATI->Chip = ATI_CHIP_MOBILITY;
            pATI->BusType = ATI_BUS_PCI;
            pATI->LCDVBlendFIFOSize = 1024;
            break;

        case OldChipID('L', 'M'):
        case OldChipID('L', 'N'):
            pATI->ChipType = OldToNewChipID(pATI->ChipType);
        case NewChipID('L', 'M'):
        case NewChipID('L', 'N'):
            pATI->ChipRevision =
                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
            pATI->Chip = ATI_CHIP_MOBILITY;
            pATI->BusType = ATI_BUS_AGP;
            pATI->LCDVBlendFIFOSize = 1024;
            break;

        default:
            pATI->Chip = ATI_CHIP_Mach64;
            break;
    }
}

/*
 * ATIChipID --
 *
 * This returns the ATI_CHIP_* value (generally) associated with a particular
 * ChipID/ChipRev combination.
 */
ATIChipType
ATIChipID
(
    const CARD16 ChipID,
    const CARD8  ChipRev
)
{
    switch (ChipID)
    {

#ifndef AVOID_CPIO

        case OldChipID('A', 'A'):  case NewChipID('A', 'A'):
            return ATI_CHIP_68800_3;

        case OldChipID('X', 'X'):  case NewChipID('X', 'X'):
            return ATI_CHIP_68800_6;

        case OldChipID('L', 'X'):
            return ATI_CHIP_68800LX;

        case OldChipID('A', 'X'):  case NewChipID('A', 'X'):
            return ATI_CHIP_68800AX;

#endif /* AVOID_CPIO */

        case OldChipID('G', 'X'):  case NewChipID('G', 'X'):
            switch (ChipRev)
            {
                case 0x00U:
                    return ATI_CHIP_88800GXC;

                case 0x01U:
                    return ATI_CHIP_88800GXD;

                case 0x02U:
                    return ATI_CHIP_88800GXE;

                case 0x03U:
                    return ATI_CHIP_88800GXF;

                default:
                    return ATI_CHIP_88800GX;
            }

        case OldChipID('C', 'X'):  case NewChipID('C', 'X'):
            return ATI_CHIP_88800CX;

        case OldChipID('C', 'T'):  case NewChipID('C', 'T'):
            return ATI_CHIP_264CT;

        case OldChipID('E', 'T'):  case NewChipID('E', 'T'):
            return ATI_CHIP_264ET;

        case OldChipID('V', 'T'):  case NewChipID('V', 'T'):
            /* For simplicity, ignore ChipID discrepancy that can occur here */
            if (!(ChipRev & GetBits(CFG_CHIP_VERSION, CFG_CHIP_REV)))
                return ATI_CHIP_264VT;
            return ATI_CHIP_264VTB;

        case OldChipID('G', 'T'):  case NewChipID('G', 'T'):
            if (!(ChipRev & GetBits(CFG_CHIP_VERSION, CFG_CHIP_REV)))
                return ATI_CHIP_264GT;
            return ATI_CHIP_264GTB;

        case OldChipID('V', 'U'):  case NewChipID('V', 'U'):
            return ATI_CHIP_264VT3;

        case OldChipID('G', 'U'):  case NewChipID('G', 'U'):
            return ATI_CHIP_264GTDVD;

        case OldChipID('L', 'G'):  case NewChipID('L', 'G'):
            return ATI_CHIP_264LT;

        case OldChipID('V', 'V'):  case NewChipID('V', 'V'):
            return ATI_CHIP_264VT4;

        case OldChipID('G', 'V'):  case NewChipID('G', 'V'):
        case OldChipID('G', 'W'):  case NewChipID('G', 'W'):
        case OldChipID('G', 'Y'):  case NewChipID('G', 'Y'):
        case OldChipID('G', 'Z'):  case NewChipID('G', 'Z'):
            return ATI_CHIP_264GT2C;

        case OldChipID('G', 'B'):  case NewChipID('G', 'B'):
        case OldChipID('G', 'D'):  case NewChipID('G', 'D'):
        case OldChipID('G', 'I'):  case NewChipID('G', 'I'):
        case OldChipID('G', 'P'):  case NewChipID('G', 'P'):
        case OldChipID('G', 'Q'):  case NewChipID('G', 'Q'):
            return ATI_CHIP_264GTPRO;

        case OldChipID('L', 'B'):  case NewChipID('L', 'B'):
        case OldChipID('L', 'D'):  case NewChipID('L', 'D'):
        case OldChipID('L', 'I'):  case NewChipID('L', 'I'):
        case OldChipID('L', 'P'):  case NewChipID('L', 'P'):
        case OldChipID('L', 'Q'):  case NewChipID('L', 'Q'):
            return ATI_CHIP_264LTPRO;

        case OldChipID('G', 'L'):  case NewChipID('G', 'L'):
        case OldChipID('G', 'M'):  case NewChipID('G', 'M'):
        case OldChipID('G', 'N'):  case NewChipID('G', 'N'):
        case OldChipID('G', 'O'):  case NewChipID('G', 'O'):
        case OldChipID('G', 'R'):  case NewChipID('G', 'R'):
        case OldChipID('G', 'S'):  case NewChipID('G', 'S'):
            return ATI_CHIP_264XL;

        case OldChipID('L', 'M'):  case NewChipID('L', 'M'):
        case OldChipID('L', 'N'):  case NewChipID('L', 'N'):
        case OldChipID('L', 'R'):  case NewChipID('L', 'R'):
        case OldChipID('L', 'S'):  case NewChipID('L', 'S'):
            return ATI_CHIP_MOBILITY;

        case NewChipID('R', 'E'):
        case NewChipID('R', 'F'):
        case NewChipID('R', 'G'):
        case NewChipID('S', 'K'):
        case NewChipID('S', 'L'):
        case NewChipID('S', 'M'):
        /* "SN" is listed as ATI_CHIP_RAGE128_4X in ATI docs */
        case NewChipID('S', 'N'):
            return ATI_CHIP_RAGE128GL;

        case NewChipID('R', 'K'):
        case NewChipID('R', 'L'):
        /*
         * ATI documentation lists SE/SF/SG under both ATI_CHIP_RAGE128VR
         * and ATI_CHIP_RAGE128_4X, and lists SH/SK/SL under Rage 128 4X only.
         * I'm stuffing them here for now until this can be clarified as ATI
         * documentation doesn't mention their details. <mharris at redhat.com>
         */
        case NewChipID('S', 'E'):
        case NewChipID('S', 'F'):
        case NewChipID('S', 'G'):
        case NewChipID('S', 'H'):
            return ATI_CHIP_RAGE128VR;

     /* case NewChipID('S', 'H'): */
     /* case NewChipID('S', 'K'): */
     /* case NewChipID('S', 'L'): */
     /* case NewChipID('S', 'N'): */
     /*     return ATI_CHIP_RAGE128_4X; */

        case NewChipID('P', 'A'):
        case NewChipID('P', 'B'):
        case NewChipID('P', 'C'):
        case NewChipID('P', 'D'):
        case NewChipID('P', 'E'):
        case NewChipID('P', 'F'):
            return ATI_CHIP_RAGE128PROGL;

        case NewChipID('P', 'G'):
        case NewChipID('P', 'H'):
        case NewChipID('P', 'I'):
        case NewChipID('P', 'J'):
        case NewChipID('P', 'K'):
        case NewChipID('P', 'L'):
        case NewChipID('P', 'M'):
        case NewChipID('P', 'N'):
        case NewChipID('P', 'O'):
        case NewChipID('P', 'P'):
        case NewChipID('P', 'Q'):
        case NewChipID('P', 'R'):
        case NewChipID('P', 'S'):
        case NewChipID('P', 'T'):
        case NewChipID('P', 'U'):
        case NewChipID('P', 'V'):
        case NewChipID('P', 'W'):
        case NewChipID('P', 'X'):
            return ATI_CHIP_RAGE128PROVR;

        case NewChipID('T', 'F'):
        case NewChipID('T', 'L'):
        case NewChipID('T', 'R'):
        case NewChipID('T', 'S'):
        case NewChipID('T', 'T'):
        case NewChipID('T', 'U'):
            return ATI_CHIP_RAGE128PROULTRA;

        case NewChipID('L', 'E'):
        case NewChipID('L', 'F'):
        /*
         * "LK" and "LL" are not in any ATI documentation I can find
         * - mharris
         */
        case NewChipID('L', 'K'):
        case NewChipID('L', 'L'):
            return ATI_CHIP_RAGE128MOBILITY3;

        case NewChipID('M', 'F'):
        case NewChipID('M', 'L'):
            return ATI_CHIP_RAGE128MOBILITY4;

        case NewChipID('Q', 'D'):
        case NewChipID('Q', 'E'):
        case NewChipID('Q', 'F'):
        case NewChipID('Q', 'G'):
            return ATI_CHIP_RADEON;

        case NewChipID('Q', 'Y'):
        case NewChipID('Q', 'Z'):
            return ATI_CHIP_RADEONVE;

        case NewChipID('L', 'Y'):
        case NewChipID('L', 'Z'):
            return ATI_CHIP_RADEONMOBILITY6;

        case NewChipID('A', '6'):
        case NewChipID('C', '6'):
             return ATI_CHIP_RS100;

        case NewChipID('A', '7'):
        case NewChipID('C', '7'):
             return ATI_CHIP_RS200;

        case NewChipID('D', '7'):
        case NewChipID('B', '7'):
             return ATI_CHIP_RS250;

        case NewChipID('L', 'W'):
        case NewChipID('L', 'X'):
            return ATI_CHIP_RADEONMOBILITY7;

        case NewChipID('Q', 'H'):
        case NewChipID('Q', 'I'):
        case NewChipID('Q', 'J'):
        case NewChipID('Q', 'K'):
        case NewChipID('Q', 'L'):
        case NewChipID('Q', 'M'):
        case NewChipID('Q', 'N'):
        case NewChipID('Q', 'O'):
        case NewChipID('Q', 'h'):
        case NewChipID('Q', 'i'):
        case NewChipID('Q', 'j'):
        case NewChipID('Q', 'k'):
        case NewChipID('Q', 'l'):
        case NewChipID('B', 'B'):
            return ATI_CHIP_R200;

        case NewChipID('Q', 'W'):
        case NewChipID('Q', 'X'):
            return ATI_CHIP_RV200;

        case NewChipID('I', 'f'):
        case NewChipID('I', 'g'):
            return ATI_CHIP_RV250;

        case NewChipID('L', 'd'):
        case NewChipID('L', 'f'):
        case NewChipID('L', 'g'):
            return ATI_CHIP_RADEONMOBILITY9;

        case NewChipID('X', '4'):
        case NewChipID('X', '5'):
             return ATI_CHIP_RS300;

        case NewChipID('Y', '\''):
        case NewChipID('Y', 'a'):
        case NewChipID('Y', 'b'):
        case NewChipID('Y', 'd'):
            return ATI_CHIP_RV280;

        case NewChipID('\\', 'a'):
        case NewChipID('\\', 'c'):
            return ATI_CHIP_RADEONMOBILITY9PLUS;

        case NewChipID('A', 'D'):
        case NewChipID('A', 'E'):
        case NewChipID('A', 'F'):
        case NewChipID('A', 'G'):
        case NewChipID('N', 'D'):
        case NewChipID('N', 'E'):
        case NewChipID('N', 'F'):
        case NewChipID('N', 'G'):
            return ATI_CHIP_R300;

        case NewChipID('A', 'H'):
        case NewChipID('A', 'I'):
        case NewChipID('A', 'J'):
        case NewChipID('A', 'K'):
        case NewChipID('N', 'H'):
        case NewChipID('N', 'I'):
        case NewChipID('N', 'K'):
            return ATI_CHIP_R350;

        case NewChipID('A', 'P'):
        case NewChipID('A', 'Q'):
        case NewChipID('A', 'R'):
        case NewChipID('A', 'S'):
        case NewChipID('A', 'T'):
        case NewChipID('A', 'V'):
        case NewChipID('N', 'P'):
        case NewChipID('N', 'Q'):
        case NewChipID('N', 'R'):
        case NewChipID('N', 'S'):
        case NewChipID('N', 'T'):
        case NewChipID('N', 'V'):
            return ATI_CHIP_RV350;

        case NewChipID('N', 'J'):
            return ATI_CHIP_R360;

        case NewChipID('H', 'D'):
            return ATI_CHIP_HDTV;

        default:
            /*
             * Treat anything else as an unknown Radeon.  Please keep the above
             * up-to-date however, as it serves as a central chip list.
             */
            return ATI_CHIP_Radeon;
    }
}

--- NEW FILE: atichip.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atichip.h,v 1.26tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATICHIP_H___
#define ___ATICHIP_H___ 1

#include "atipriv.h"
#include "atiregs.h"

#include <X11/Xmd.h>

/*
 * Chip-related definitions.
 */
typedef enum
{
    ATI_CHIP_NONE = 0,

#ifndef AVOID_CPIO

    ATI_CHIP_VGA,               /* Generic VGA */
    ATI_CHIP_18800,
    ATI_CHIP_18800_1,
    ATI_CHIP_28800_2,
    ATI_CHIP_28800_4,
    ATI_CHIP_28800_5,
    ATI_CHIP_28800_6,
    ATI_CHIP_8514A,             /* 8514/A */
    ATI_CHIP_CT480,             /* 8514/A clone */
    ATI_CHIP_38800_1,           /* Mach8 */
    ATI_CHIP_68800,             /* Mach32 */
    ATI_CHIP_68800_3,           /* Mach32 */
    ATI_CHIP_68800_6,           /* Mach32 */
    ATI_CHIP_68800LX,           /* Mach32 */
    ATI_CHIP_68800AX,           /* Mach32 */

#endif /* AVOID_CPIO */

    ATI_CHIP_88800GXC,          /* Mach64 */
    ATI_CHIP_88800GXD,          /* Mach64 */
    ATI_CHIP_88800GXE,          /* Mach64 */
    ATI_CHIP_88800GXF,          /* Mach64 */
    ATI_CHIP_88800GX,           /* Mach64 */
    ATI_CHIP_88800CX,           /* Mach64 */
    ATI_CHIP_264CT,             /* Mach64 */
    ATI_CHIP_264ET,             /* Mach64 */
    ATI_CHIP_264VT,             /* Mach64 */
    ATI_CHIP_264GT,             /* Mach64 */
    ATI_CHIP_264VTB,            /* Mach64 */
    ATI_CHIP_264GTB,            /* Mach64 */
    ATI_CHIP_264VT3,            /* Mach64 */
    ATI_CHIP_264GTDVD,          /* Mach64 */
    ATI_CHIP_264LT,             /* Mach64 */
    ATI_CHIP_264VT4,            /* Mach64 */
    ATI_CHIP_264GT2C,           /* Mach64 */
    ATI_CHIP_264GTPRO,          /* Mach64 */
    ATI_CHIP_264LTPRO,          /* Mach64 */
    ATI_CHIP_264XL,             /* Mach64 */
    ATI_CHIP_MOBILITY,          /* Mach64 */
    ATI_CHIP_Mach64,            /* Last among Mach64's */
    ATI_CHIP_RAGE128GL,         /* Rage128 */
    ATI_CHIP_RAGE128VR,         /* Rage128 */
    ATI_CHIP_RAGE128PROGL,      /* Rage128 */
    ATI_CHIP_RAGE128PROVR,      /* Rage128 */
    ATI_CHIP_RAGE128PROULTRA,   /* Rage128 */
    ATI_CHIP_RAGE128MOBILITY3,  /* Rage128 */
    ATI_CHIP_RAGE128MOBILITY4,  /* Rage128 */
    ATI_CHIP_Rage128,           /* Last among Rage128's */
    ATI_CHIP_RADEON,            /* Radeon */
    ATI_CHIP_RADEONVE,          /* Radeon VE */
    ATI_CHIP_RADEONMOBILITY6,   /* Radeon M6 */
    ATI_CHIP_RS100,             /* IGP320 */
    ATI_CHIP_RS200,             /* IGP340 */
    ATI_CHIP_RS250,             /* Radoen 7000 IGP */
    ATI_CHIP_RV200,             /* RV200 */
    ATI_CHIP_RADEONMOBILITY7,   /* Radeon M7 */
    ATI_CHIP_R200,              /* R200 */
    ATI_CHIP_RV250,             /* RV250 */
    ATI_CHIP_RADEONMOBILITY9,   /* Radeon M9 */
    ATI_CHIP_RS300,             /* Radoen 9000 IGP */
    ATI_CHIP_RV280,             /* RV250 */
    ATI_CHIP_RADEONMOBILITY9PLUS,   /* Radeon M9+ */
    ATI_CHIP_R300,              /* R300 */
    ATI_CHIP_RV350,             /* RV350 */
    ATI_CHIP_R350,              /* R350 */
    ATI_CHIP_R360,              /* R360 */
    ATI_CHIP_Radeon,            /* Last among Radeon's */
    ATI_CHIP_HDTV               /* HDTV */
} ATIChipType;

extern const char *ATIChipNames[];

/*
 * Foundry codes for 264xT's.
 */
typedef enum
{
    ATI_FOUNDRY_SGS,    /* SGS-Thompson */
    ATI_FOUNDRY_NEC,    /* NEC */
    ATI_FOUNDRY_KSC,    /* KSC (?) */
    ATI_FOUNDRY_UMC,    /* United Microelectronics Corporation */
    ATI_FOUNDRY_TSMC,   /* Taiwan Semiconductor Manufacturing Company */
    ATI_FOUNDRY_5,
    ATI_FOUNDRY_6,
    ATI_FOUNDRY_UMCA    /* UMC alternate */
} ATIFoundryType;

extern const char *ATIFoundryNames[];

#ifndef AVOID_CPIO

extern void        ATIMach32ChipID FunctionPrototype((ATIPtr));

#endif /* AVOID_CPIO */

extern void        ATIMach64ChipID FunctionPrototype((ATIPtr, const CARD16));
extern ATIChipType ATIChipID       FunctionPrototype((const CARD16,
                                                      const CARD8));

#define OldChipID(_1, _0) \
    (SetBits(_0 - 'A', CHIP_CODE_0) | SetBits(_1 - 'A', CHIP_CODE_1))

#define NewChipID(_1, _0) \
    (SetBits(_0, CFG_CHIP_TYPE0) | SetBits(_1, CFG_CHIP_TYPE1))

#define OldToNewChipID(_ChipID) \
    (SetBits(GetBits(_ChipID, CHIP_CODE_0) + 'A', CFG_CHIP_TYPE0) | \
     SetBits(GetBits(_ChipID, CHIP_CODE_1) + 'A', CFG_CHIP_TYPE1))

#define NewToOldChipID(_ChipID) \
    (SetBits(GetBits(_ChipID, CFG_CHIP_TYPE0) - 'A', CHIP_CODE_0) | \
    (SetBits(GetBits(_ChipID, CFG_CHIP_TYPE1) - 'A', CHIP_CODE_1))

#endif /* ___ATICHIP_H___ */

--- NEW FILE: aticlock.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/aticlock.c,v 1.21 2003/04/23 21:51:27 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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
[...1569 lines suppressed...]
            /*
             * Here, only update in-core data.  It will be written out later by
             * ATIRGB514Set().
             */
            tmp = (pATIHW->clock << 1) + 0x20U;
            pATIHW->ibmrgb514[tmp] =
                (SetBits(N, 0x3FU) | SetBits(D, 0xC0U)) ^ 0xC0U;
            pATIHW->ibmrgb514[tmp + 1] = SetBits(M, 0x3FU);
            break;

        default:
            break;
    }

    (void)in8(M64_DAC_WRITE);    /* Clear DAC counter */

    /* Restore register */
    if (!(crtc_gen_cntl & CRTC_EXT_DISP_EN))
        outr(CRTC_GEN_CNTL, crtc_gen_cntl);
}

--- NEW FILE: aticlock.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/aticlock.h,v 1.8 2003/01/01 19:16:31 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATICLOCK_H___
#define ___ATICLOCK_H___ 1

#include "atipriv.h"
#include "atiproto.h"

#include "xf86str.h"

/*
 * Definitions related to non-programmable clock generators.
 */
typedef enum
{
    ATI_CLOCK_NONE = 0,
    ATI_CLOCK_VGA = 1,
    ATI_CLOCK_CRYSTALS = 2,
    ATI_CLOCK_18810,
    ATI_CLOCK_18811_0,
    ATI_CLOCK_18811_1,
    ATI_CLOCK_2494AM,
    ATI_CLOCK_MACH64A,
    ATI_CLOCK_MACH64B,
    ATI_CLOCK_MACH64C
} ATIClockType;
extern const char *ATIClockNames[];

/*
 * Definitions related to programmable clock generators.
 */
typedef enum
{
    ATI_CLOCK_UNKNOWN = -1,
    ATI_CLOCK_FIXED = 0,        /* Further described by ATIClockType */
    ATI_CLOCK_ICS2595,
    ATI_CLOCK_STG1703,
    ATI_CLOCK_CH8398,
    ATI_CLOCK_INTERNAL,
    ATI_CLOCK_ATT20C408,
    ATI_CLOCK_IBMRGB514,
    ATI_CLOCK_MAX               /* Must be last */
} ATIProgrammableClockType;

typedef struct
{
    CARD16 MinN, MaxN;          /* Feedback divider and ... */
    CARD16 NAdjust;             /* ... its adjustment and ... */
    CARD16 N1, N2;              /* ... its restrictions */
    CARD16 MinM, MaxM;          /* Reference divider and ... */
    CARD16 MAdjust;             /* ... its adjustment */
    CARD16 NumD, *PostDividers; /* Post-dividers */
    const char *ClockName;
} ClockRec, *ClockPtr;
extern ClockRec ATIClockDescriptors[];

extern void ATIClockPreInit   FunctionPrototype((ScrnInfoPtr, ATIPtr, GDevPtr,
                                                 ClockRangePtr));
extern void ATIClockSave      FunctionPrototype((ScrnInfoPtr, ATIPtr,
                                                 ATIHWPtr));
extern Bool ATIClockCalculate FunctionPrototype((int, ATIPtr, ATIHWPtr,
                                                 DisplayModePtr));
extern void ATIClockSet       FunctionPrototype((ATIPtr, ATIHWPtr));

#endif /* ___ATICLOCK_H___ */

--- NEW FILE: aticonfig.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/aticonfig.c,v 1.15tsi Exp $*/
/*
 * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

#include "ati.h"
#include "atiadapter.h"
#include "atichip.h"
#include "aticonfig.h"
#include "aticursor.h"
#include "atioption.h"
#include "atistruct.h"

/*
 * Non-publicised XF86Config options.
 */
typedef enum
{
    ATI_OPTION_BIOS_DISPLAY,    /* Allow BIOS interference */
    ATI_OPTION_CRT_SCREEN,      /* Legacy negation of "PanelDisplay" */
    ATI_OPTION_DEVEL,           /* Intentionally undocumented */
    ATI_OPTION_BLEND,           /* Force horizontal blending of small modes */
    ATI_OPTION_LCDSYNC          /* Use XF86Config panel mode porches */
} ATIPrivateOptionType;

/*
 * ATIProcessOptions --
 *
 * This function extracts options from what was parsed out of the XF86Config
 * file.
 */
void
ATIProcessOptions
(
    ScrnInfoPtr pScreenInfo,
    ATIPtr      pATI
)
{
    OptionInfoPtr PublicOption = xnfalloc(ATIPublicOptionSize);
    OptionInfoRec PrivateOption[] =
    {
        {                       /* ON:  Let BIOS change display(s) */
            ATI_OPTION_BIOS_DISPLAY,    /* OFF:  Don't */
            "biosdisplay",
            OPTV_BOOLEAN,
            {0, },
            FALSE
        },
        {                       /* Negation of "PanelDisplay" public option */
            ATI_OPTION_CRT_SCREEN,
            "crtscreen",
            OPTV_BOOLEAN,
            {0, },
            FALSE
        },
        {                       /* ON:   Ease exploration of loose ends */
            ATI_OPTION_DEVEL,   /* OFF:  Fit for public consumption */
            "tsi",
            OPTV_BOOLEAN,
            {0, },
            FALSE
        },
        {                       /* ON:   Horizontally blend most modes */
            ATI_OPTION_BLEND,   /* OFF:  Use pixel replication more often */
            "lcdblend",
            OPTV_BOOLEAN,
            {0, },
            FALSE
        },
        {                       /* ON:   Use XF86Config porch timings */
            ATI_OPTION_LCDSYNC, /* OFF:  Use porches from mode on entry */
            "lcdsync",
            OPTV_BOOLEAN,
            {0, },
            FALSE
        },
        {
            -1,
            NULL,
            OPTV_NONE,
            {0, },
            FALSE
        }
    };

    (void)memcpy(PublicOption, ATIPublicOptions, ATIPublicOptionSize);

#   define Accel         PublicOption[ATI_OPTION_ACCEL].value.bool
#   define BIOSDisplay   PrivateOption[ATI_OPTION_BIOS_DISPLAY].value.bool
#   define Blend         PrivateOption[ATI_OPTION_BLEND].value.bool
#   define CRTDisplay    PublicOption[ATI_OPTION_CRT_DISPLAY].value.bool
#   define CRTScreen     PrivateOption[ATI_OPTION_CRT_SCREEN].value.bool
#   define CSync         PublicOption[ATI_OPTION_CSYNC].value.bool
#   define Devel         PrivateOption[ATI_OPTION_DEVEL].value.bool
#   define HWCursor      PublicOption[ATI_OPTION_HWCURSOR].value.bool

#ifndef AVOID_CPIO

#   define Linear        PublicOption[ATI_OPTION_LINEAR].value.bool

#endif /* AVOID_CPIO */

#   define CacheMMIO     PublicOption[ATI_OPTION_MMIO_CACHE].value.bool
#   define TestCacheMMIO PublicOption[ATI_OPTION_TEST_MMIO_CACHE].value.bool
#   define PanelDisplay  PublicOption[ATI_OPTION_PANEL_DISPLAY].value.bool
#   define ProbeClocks   PublicOption[ATI_OPTION_PROBE_CLOCKS].value.bool
#   define ShadowFB      PublicOption[ATI_OPTION_SHADOW_FB].value.bool
#   define SWCursor      PublicOption[ATI_OPTION_SWCURSOR].value.bool
#   define LCDSync       PrivateOption[ATI_OPTION_LCDSYNC].value.bool

#   define ReferenceClock \
        PublicOption[ATI_OPTION_REFERENCE_CLOCK].value.freq.freq

    /* Pick up XF86Config options */
    xf86CollectOptions(pScreenInfo, NULL);

    /* Set non-zero defaults */

#ifndef AVOID_CPIO

    if (pATI->Adapter >= ATI_ADAPTER_MACH64)

#endif /* AVOID_CPIO */

    {
        Accel = CacheMMIO = HWCursor = TRUE;

#ifndef AVOID_CPIO

        Linear = TRUE;

#endif /* AVOID_CPIO */

    }

    ReferenceClock = ((double)157500000.0) / ((double)11.0);

#ifndef AVOID_CPIO

    if (pATI->PCIInfo)

#endif /* AVOID_CPIO */

    {
        ShadowFB = TRUE;
    }

    Blend = PanelDisplay = TRUE;

    xf86ProcessOptions(pScreenInfo->scrnIndex, pScreenInfo->options,
        PublicOption);
    xf86ProcessOptions(pScreenInfo->scrnIndex, pScreenInfo->options,
        PrivateOption);

#ifndef AVOID_CPIO

    /* Disable linear apertures if the OS doesn't support them */
    if (!xf86LinearVidMem() && Linear)
    {
        if (PublicOption[ATI_OPTION_LINEAR].found)
            xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
                "OS does not support linear apertures.\n");
        Linear = FALSE;
    }

#endif /* AVOID_CPIO */

    /* Move option values into driver private structure */
    pATI->OptionAccel = Accel;
    pATI->OptionBIOSDisplay = BIOSDisplay;
    pATI->OptionBlend = Blend;
    pATI->OptionCRTDisplay = CRTDisplay;
    pATI->OptionCSync = CSync;
    pATI->OptionDevel = Devel;

#ifndef AVOID_CPIO

    pATI->OptionLinear = Linear;

#endif /* AVOID_CPIO */

    pATI->OptionMMIOCache = CacheMMIO;
    pATI->OptionTestMMIOCache = TestCacheMMIO;
    pATI->OptionProbeClocks = ProbeClocks;
    pATI->OptionShadowFB = ShadowFB;
    pATI->OptionLCDSync = LCDSync;

    /* "CRTScreen" is now "NoPanelDisplay" */
    if ((PanelDisplay != CRTScreen) ||
        PublicOption[ATI_OPTION_PANEL_DISPLAY].found)
        pATI->OptionPanelDisplay = PanelDisplay;
    else
        pATI->OptionPanelDisplay = !CRTScreen;

    /* Validate and set cursor options */
    pATI->Cursor = ATI_CURSOR_SOFTWARE;
    if (SWCursor || !HWCursor)
    {
        if (HWCursor && PublicOption[ATI_OPTION_HWCURSOR].found)
            xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
                "Option \"sw_cursor\" overrides Option \"hw_cursor\".\n");
    }
    else if (pATI->Chip < ATI_CHIP_264CT)
    {
        if (HWCursor && PublicOption[ATI_OPTION_HWCURSOR].found)
            xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
                "Option \"hw_cursor\" not supported in this configuration.\n");
    }
    else
    {
        pATI->Cursor = ATI_CURSOR_HARDWARE;
    }

    /* Only set the reference clock if it hasn't already been determined */
    if (!pATI->ReferenceNumerator || !pATI->ReferenceDenominator)
    {
        switch ((int)(ReferenceClock / ((double)100000.0)))
        {
            case 143:
                pATI->ReferenceNumerator = 157500;
                pATI->ReferenceDenominator = 11;
                break;

            case 286:
                pATI->ReferenceNumerator = 315000;
                pATI->ReferenceDenominator = 11;
                break;

            default:
                pATI->ReferenceNumerator =
                    (int)(ReferenceClock / ((double)1000.0));
                pATI->ReferenceDenominator = 1;
                break;
        }
    }

    xfree(PublicOption);
}

--- NEW FILE: aticonfig.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/aticonfig.h,v 1.5 2003/01/01 19:16:31 tsi Exp $ */
/*
 * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATICONFIG_H___
#define ___ATICONFIG_H___ 1

#include "atipriv.h"
#include "atiproto.h"

#include "xf86str.h"

extern void ATIProcessOptions FunctionPrototype((ScrnInfoPtr, ATIPtr));

#endif /* ___ATICONFIG_H___ */

--- NEW FILE: aticonsole.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/aticonsole.c,v 1.22 2003/11/13 18:42:47 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

#include "atiadapter.h"
#include "aticonsole.h"
#include "aticrtc.h"
#include "atii2c.h"
#include "atilock.h"
#include "atimach64.h"
#include "atimode.h"
#include "atistruct.h"
#include "ativga.h"
#include "atividmem.h"

#include "xf86.h"

/*
 * ATISaveScreen --
 *
 * This function is a screen saver hook for DIX.
 */
Bool
ATISaveScreen
(
    ScreenPtr pScreen,
    int       Mode
)
{
    ScrnInfoPtr pScreenInfo;
    ATIPtr      pATI;

    if ((Mode != SCREEN_SAVER_ON) && (Mode != SCREEN_SAVER_CYCLE))
        SetTimeSinceLastInputEvent();

    if (!pScreen)
        return TRUE;

    pScreenInfo = xf86Screens[pScreen->myNum];
    if (!pScreenInfo->vtSema)
        return TRUE;

    pATI = ATIPTR(pScreenInfo);
    switch (pATI->NewHW.crtc)
    {

#ifndef AVOID_CPIO

        case ATI_CRTC_VGA:
            ATIVGASaveScreen(pATI, Mode);
            break;

#endif /* AVOID_CPIO */

        case ATI_CRTC_MACH64:
            ATIMach64SaveScreen(pATI, Mode);
            break;

        default:
            break;
    }

    return TRUE;
}

/*
 * ATISetDPMSMode --
 *
 * This function sets the adapter's VESA Display Power Management Signaling
 * mode.
 */
void
ATISetDPMSMode
(
    ScrnInfoPtr pScreenInfo,
    int         DPMSMode,
    int         flags
)
{
    ATIPtr pATI;

    if (!pScreenInfo || !pScreenInfo->vtSema)
        return;

    pATI = ATIPTR(pScreenInfo);

    switch (pATI->Adapter)
    {
        case ATI_ADAPTER_MACH64:
            ATIMach64SetDPMSMode(pScreenInfo, pATI, DPMSMode);
            break;

        default:

#ifndef AVOID_CPIO

            /* Assume EGA/VGA */
            ATIVGASetDPMSMode(pATI, DPMSMode);
            break;

        case ATI_ADAPTER_NONE:
        case ATI_ADAPTER_8514A:
        case ATI_ADAPTER_MACH8:

#endif /* AVOID_CPIO */

            break;
    }
}

/*
 * ATIEnterGraphics --
 *
 * This function sets the hardware to a graphics video state.
 */
Bool
ATIEnterGraphics
(
    ScreenPtr   pScreen,
    ScrnInfoPtr pScreenInfo,
    ATIPtr      pATI
)
{
    /* Map apertures */
    if (!ATIMapApertures(pScreenInfo->scrnIndex, pATI))
        return FALSE;

    /* Unlock device */
    ATIUnlock(pATI);

    /* Calculate hardware data */
    if (pScreen &&
        !ATIModeCalculate(pScreenInfo->scrnIndex, pATI, &pATI->NewHW,
            pScreenInfo->currentMode))
        return FALSE;

    pScreenInfo->vtSema = TRUE;

    /* Save current state */
    ATIModeSave(pScreenInfo, pATI, &pATI->OldHW);

    /* Set graphics state */
    ATIModeSet(pScreenInfo, pATI, &pATI->NewHW);

    /* Possibly blank the screen */
    if (pScreen)
       (void)ATISaveScreen(pScreen, SCREEN_SAVER_ON);

    /* Position the screen */
    (*pScreenInfo->AdjustFrame)(pScreenInfo->scrnIndex,
        pScreenInfo->frameX0, pScreenInfo->frameY0, 0);

    SetTimeSinceLastInputEvent();

    return TRUE;
}

/*
 * ATILeaveGraphics --
 *
 * This function restores the hardware to its previous state.
 */
void
ATILeaveGraphics
(
    ScrnInfoPtr pScreenInfo,
    ATIPtr      pATI
)
{
    if (pScreenInfo->vtSema)
    {
        /* If not exiting, save graphics video state */
        if (!xf86ServerIsExiting())
            ATIModeSave(pScreenInfo, pATI, &pATI->NewHW);

        /* Restore mode in effect on server entry */
        ATIModeSet(pScreenInfo, pATI, &pATI->OldHW);

        pScreenInfo->vtSema = FALSE;
    }

    /* Lock device */
    ATILock(pATI);

    /* Unmap apertures */

#ifdef AVOID_DGA

    if (!pATI->Closeable)

#else /* AVOID_DGA */

    if (!pATI->Closeable || !pATI->nDGAMode)

#endif /* AVOID_DGA */

        ATIUnmapApertures(pScreenInfo->scrnIndex, pATI);

    SetTimeSinceLastInputEvent();
}

/*
 * ATISwitchMode --
 *
 * This function switches to another graphics video state.
 */
Bool
ATISwitchMode
(
    int            iScreen,
    DisplayModePtr pMode,
    int            flags
)
{
    ScrnInfoPtr pScreenInfo = xf86Screens[iScreen];
    ATIPtr      pATI        = ATIPTR(pScreenInfo);

    /* Calculate new hardware data */
    if (!ATIModeCalculate(iScreen, pATI, &pATI->NewHW, pMode))
        return FALSE;

    /* Set new hardware state */
    if (pScreenInfo->vtSema)
    {
        pScreenInfo->currentMode = pMode;
        ATIModeSet(pScreenInfo, pATI, &pATI->NewHW);
    }

    SetTimeSinceLastInputEvent();

    return TRUE;
}

/*
 * ATIEnterVT --
 *
 * This function sets the server's virtual console to a graphics video state.
 */
Bool
ATIEnterVT
(
    int iScreen,
    int flags
)
{
    ScrnInfoPtr pScreenInfo = xf86Screens[iScreen];
    ScreenPtr   pScreen     = pScreenInfo->pScreen;
    ATIPtr      pATI        = ATIPTR(pScreenInfo);
    PixmapPtr   pScreenPixmap;
    DevUnion    PixmapPrivate;
    Bool        Entered;

    if (!ATIEnterGraphics(NULL, pScreenInfo, pATI))
        return FALSE;

    /* The rest of this isn't needed for shadowfb */
    if (pATI->OptionShadowFB)
        return TRUE;

#ifndef AVOID_CPIO

    /* If used, modify banking interface */
    if (!miModifyBanking(pScreen, &pATI->BankInfo))
        return FALSE;

#endif /* AVOID_CPIO */

    pScreenPixmap = (*pScreen->GetScreenPixmap)(pScreen);
    PixmapPrivate = pScreenPixmap->devPrivate;
    if (!PixmapPrivate.ptr)
        pScreenPixmap->devPrivate = pScreenInfo->pixmapPrivate;

    /* Tell framebuffer about remapped aperture */
    Entered = (*pScreen->ModifyPixmapHeader)(pScreenPixmap,
        -1, -1, -1, -1, -1, pATI->pMemory);

    if (!PixmapPrivate.ptr)
    {
        pScreenInfo->pixmapPrivate = pScreenPixmap->devPrivate;
        pScreenPixmap->devPrivate.ptr = NULL;
    }

    return Entered;
}

/*
 * ATILeaveVT --
 *
 * This function restores the server's virtual console to its state on server
 * entry.
 */
void
ATILeaveVT
(
    int iScreen,
    int flags
)
{
    ScrnInfoPtr pScreenInfo = xf86Screens[iScreen];

    ATILeaveGraphics(pScreenInfo, ATIPTR(pScreenInfo));
}

/*
 * ATIFreeScreen --
 *
 * This function frees all driver data related to a screen.
 */
void
ATIFreeScreen
(
    int iScreen,
    int flags
)
{
    ScreenPtr   pScreen     = screenInfo.screens[iScreen];
    ScrnInfoPtr pScreenInfo = xf86Screens[iScreen];
    ATIPtr      pATI        = ATIPTR(pScreenInfo);

    if (pATI->Closeable || (serverGeneration > 1))
        ATII2CFreeScreen(iScreen);

    if (pATI->Closeable)
        (void)(*pScreen->CloseScreen)(iScreen, pScreen);

    ATILeaveGraphics(pScreenInfo, pATI);

#ifndef AVOID_CPIO

    xfree(pATI->OldHW.frame_buffer);
    xfree(pATI->NewHW.frame_buffer);

#endif /* AVOID_CPIO */

    xfree(pATI->pShadow);

#ifndef AVOID_DGA

    xfree(pATI->pDGAMode);

#endif /* AVOID_DGA */

    xfree(pATI);
    pScreenInfo->driverPrivate = NULL;
}

--- NEW FILE: aticonsole.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/aticonsole.h,v 1.9 2003/01/01 19:16:31 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATICONSOLE_H___
#define ___ATICONSOLE_H___ 1

#include "atipriv.h"
#include "atiproto.h"

#include "xf86str.h"

extern Bool ATISaveScreen    FunctionPrototype((ScreenPtr, int));
extern void ATISetDPMSMode   FunctionPrototype((ScrnInfoPtr, int, int));

extern Bool ATIEnterGraphics FunctionPrototype((ScreenPtr, ScrnInfoPtr,
                                                ATIPtr));
extern void ATILeaveGraphics FunctionPrototype((ScrnInfoPtr, ATIPtr));

extern Bool ATISwitchMode    FunctionPrototype((int, DisplayModePtr, int));

extern Bool ATIEnterVT       FunctionPrototype((int, int));
extern void ATILeaveVT       FunctionPrototype((int, int));

extern void ATIFreeScreen    FunctionPrototype((int, int));

#endif /* ___ATICONSOLE_H___ */

--- NEW FILE: aticrtc.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/aticrtc.h,v 1.8 2003/01/01 19:16:31 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATICRTC_H___
#define ___ATICRTC_H___ 1

/*
 * CRTC related definitions.
 */
typedef enum
{

#ifndef AVOID_CPIO

    ATI_CRTC_VGA,       /* Use VGA CRTC */
    ATI_CRTC_8514,      /* Use 8514/Mach8/Mach32 accelerator CRTC */

#endif /* AVOID_CPIO */

    ATI_CRTC_MACH64     /* Use Mach64 accelerator CRTC */
} ATICRTCType;

#endif /* ___ATICRTC_H___ */

--- NEW FILE: aticursor.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/aticursor.c,v 1.4 2003/04/23 21:51:27 tsi Exp $ */
/*
 * Copyright 2001 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

#include "atiadapter.h"
#include "aticursor.h"
#include "atimach64cursor.h"
#include "atistruct.h"

#include "xf86.h"

/*
 * ATIInitializeCursor --
 *
 * This function initialises the screen cursor.
 */
Bool
ATIInitializeCursor
(
    ScreenPtr pScreen,
    ATIPtr    pATI
)
{
    /* Initialise software cursor */
    if (!miDCInitialize(pScreen, xf86GetPointerScreenFuncs()))
        return FALSE;

    if (pATI->Cursor == ATI_CURSOR_SOFTWARE)
        return TRUE;

    if (!(pATI->pCursorInfo = xf86CreateCursorInfoRec()))
        return FALSE;

    switch (pATI->Adapter)
    {
        case ATI_ADAPTER_MACH64:
            if (ATIMach64CursorInit(pATI->pCursorInfo))
                break;
            /* Fall through */

        default:
            xf86DestroyCursorInfoRec(pATI->pCursorInfo);
            pATI->pCursorInfo = NULL;
            return FALSE;
    }

    if (xf86InitCursor(pScreen, pATI->pCursorInfo))
    {
        xf86SetSilkenMouse(pScreen);
        return TRUE;
    }

    xf86DestroyCursorInfoRec(pATI->pCursorInfo);
    pATI->pCursorInfo = NULL;
    return FALSE;
}

--- NEW FILE: aticursor.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/aticursor.h,v 1.3 2003/01/01 19:16:31 tsi Exp $ */
/*
 * Copyright 2001 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATICURSOR_H___
#define ___ATICURSOR_H___ 1

#include "atipriv.h"
#include "atiproto.h"

#include "screenint.h"

/*
 * Cursor related definitions.
 */
typedef enum
{
    ATI_CURSOR_SOFTWARE,        /* Software cursor */
    ATI_CURSOR_HARDWARE,        /* Hardware cursor provided by CRTC */
    ATI_CURSOR_DAC              /* Hardware cursor provided by RAMDAC */
} ATICursorType;

extern Bool ATIInitializeCursor FunctionPrototype((ScreenPtr, ATIPtr));

#endif /* ___ATICURSOR_H___ */

--- NEW FILE: atidac.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atidac.c,v 1.18 2003/02/25 17:58:13 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

#include "ati.h"
#include "atidac.h"
#include "atimach64io.h"
#include "atimono.h"

/*
 * RAMDAC-related definitions.
 */
const SymTabRec ATIDACDescriptors[] =
{   /* Keep this table in ascending DACType order */
    {ATI_DAC_ATI68830,      "ATI 68830 or similar"},
    {ATI_DAC_SC11483,       "Sierra 11483 or similar"},
    {ATI_DAC_ATI68875,      "ATI 68875 or similar"},
    {ATI_DAC_TVP3026_A,     "TI ViewPoint3026 or similar"},
    {ATI_DAC_GENERIC,       "Brooktree 476 or similar"},
    {ATI_DAC_BT481,         "Brooktree 481 or similar"},
    {ATI_DAC_ATT20C491,     "AT&T 20C491 or similar"},
    {ATI_DAC_SC15026,       "Sierra 15026 or similar"},
    {ATI_DAC_MU9C1880,      "Music 9C1880 or similar"},
    {ATI_DAC_IMSG174,       "Inmos G174 or similar"},
    {ATI_DAC_ATI68860_B,    "ATI 68860 (Revision B) or similar"},
    {ATI_DAC_ATI68860_C,    "ATI 68860 (Revision C) or similar"},
    {ATI_DAC_TVP3026_B,     "TI ViewPoint3026 or similar"},
    {ATI_DAC_STG1700,       "SGS-Thompson 1700 or similar"},
    {ATI_DAC_ATT20C498,     "AT&T 20C498 or similar"},
    {ATI_DAC_STG1702,       "SGS-Thompson 1702 or similar"},
    {ATI_DAC_SC15021,       "Sierra 15021 or similar"},
    {ATI_DAC_ATT21C498,     "AT&T 21C498 or similar"},
    {ATI_DAC_STG1703,       "SGS-Thompson 1703 or similar"},
    {ATI_DAC_CH8398,        "Chrontel 8398 or similar"},
    {ATI_DAC_ATT20C408,     "AT&T 20C408 or similar"},
    {ATI_DAC_INTERNAL,      "Internal"},
    {ATI_DAC_IBMRGB514,     "IBM RGB 514 or similar"},
    {ATI_DAC_UNKNOWN,       "Unknown"}          /* Must be last */
};

#ifndef AVOID_CPIO

/*
 * ATISetDACIOPorts --
 *
 * This function sets up DAC access I/O port numbers.
 */
void
ATISetDACIOPorts
(
    ATIPtr      pATI,
    ATICRTCType crtc
)
{
    switch (crtc)
    {
        case ATI_CRTC_VGA:
            pATI->CPIO_DAC_DATA = VGA_DAC_DATA;
            pATI->CPIO_DAC_MASK = VGA_DAC_MASK;
            pATI->CPIO_DAC_READ = VGA_DAC_READ;
            pATI->CPIO_DAC_WRITE = VGA_DAC_WRITE;
            pATI->CPIO_DAC_WAIT = GENS1(pATI->CPIO_VGABase);
            break;

        case ATI_CRTC_8514:
            pATI->CPIO_DAC_DATA = IBM_DAC_DATA;
            pATI->CPIO_DAC_MASK = IBM_DAC_MASK;
            pATI->CPIO_DAC_READ = IBM_DAC_READ;
            pATI->CPIO_DAC_WRITE = IBM_DAC_WRITE;
            pATI->CPIO_DAC_WAIT = pATI->CPIO_DAC_MASK;
            break;

        case ATI_CRTC_MACH64:
            pATI->CPIO_DAC_DATA = ATIIOPort(DAC_REGS) + 1;
            pATI->CPIO_DAC_MASK = ATIIOPort(DAC_REGS) + 2;
            pATI->CPIO_DAC_READ = ATIIOPort(DAC_REGS) + 3;
            pATI->CPIO_DAC_WRITE = ATIIOPort(DAC_REGS) + 0;
            pATI->CPIO_DAC_WAIT = pATI->CPIOBase;
            break;

        default:
            break;
    }
}

#endif /* AVOID_CPIO */

/*
 * ATIGetDACCmdReg --
 *
 * Setup to access a RAMDAC's command register.
 */
CARD8
ATIGetDACCmdReg
(
    ATIPtr pATI
)
{

#ifdef AVOID_CPIO

    (void)in8(M64_DAC_WRITE);           /* Reset to PEL mode */
    (void)in8(M64_DAC_MASK);
    (void)in8(M64_DAC_MASK);
    (void)in8(M64_DAC_MASK);
    return in8(M64_DAC_MASK);

#else /* AVOID_CPIO */

    (void)inb(pATI->CPIO_DAC_WRITE);    /* Reset to PEL mode */
    (void)inb(pATI->CPIO_DAC_MASK);
    (void)inb(pATI->CPIO_DAC_MASK);
    (void)inb(pATI->CPIO_DAC_MASK);
    return inb(pATI->CPIO_DAC_MASK);

#endif /* AVOID_CPIO */

}

/*
 * ATIDACPreInit --
 *
 * This function initialises the fields in an ATIHWRec that relate to DACs.
 */
void
ATIDACPreInit
(
    ScrnInfoPtr pScreenInfo,
    ATIPtr      pATI,
    ATIHWPtr    pATIHW
)
{
    int Index, Index2;
    CARD8 maxColour = (1 << pATI->rgbBits) - 1;

    pATIHW->dac_read = pATIHW->dac_write = 0x00U;
    pATIHW->dac_mask = 0xFFU;

    /*
     * Set colour lookup table.  The first entry has already been zeroed out.
     */
    if (pATI->depth > 8)
        for (Index = 1;  Index < (NumberOf(pATIHW->lut) / 3);  Index++)
        {
            Index2 = Index * 3;
            pATIHW->lut[Index2 + 0] =
                pATIHW->lut[Index2 + 1] =
                pATIHW->lut[Index2 + 2] = Index;
        }
    else
    {
        /*
         * Initialise hardware colour map so that use of uninitialised
         * software colour map entries can easily be seen.  For 256-colour
         * modes, this doesn't remain effective for very long...
         */
        pATIHW->lut[3] = pATIHW->lut[4] = pATIHW->lut[5] = 0xFFU;
        for (Index = 2;  Index < (NumberOf(pATIHW->lut) / 3);  Index++)
        {
            Index2 = Index * 3;
            pATIHW->lut[Index2 + 0] = maxColour;
            pATIHW->lut[Index2 + 1] = 0x00U;
            pATIHW->lut[Index2 + 2] = maxColour;
        }

#ifndef AVOID_CPIO

        if (pATI->depth == 1)
        {
            rgb blackColour = pScreenInfo->display->blackColour,
                whiteColour = pScreenInfo->display->whiteColour;

            if (blackColour.red > maxColour)
                blackColour.red = maxColour;
            if (blackColour.green > maxColour)
                blackColour.green = maxColour;
            if (blackColour.blue > maxColour)
                blackColour.blue = maxColour;
            if (whiteColour.red > maxColour)
                whiteColour.red = maxColour;
            if (whiteColour.green > maxColour)
                whiteColour.green = maxColour;
            if (whiteColour.blue > maxColour)
                whiteColour.blue = maxColour;

            if ((blackColour.red == whiteColour.red) &&
                (blackColour.green == whiteColour.green) &&
                (blackColour.blue == whiteColour.blue))
            {
                blackColour.red ^= maxColour;
                blackColour.green ^= maxColour;
                blackColour.blue ^= maxColour;
            }

            pATIHW->lut[(MONO_BLACK * 3) + 0] = blackColour.red;
            pATIHW->lut[(MONO_BLACK * 3) + 1] = blackColour.green;
            pATIHW->lut[(MONO_BLACK * 3) + 2] = blackColour.blue;
            pATIHW->lut[(MONO_WHITE * 3) + 0] = whiteColour.red;
            pATIHW->lut[(MONO_WHITE * 3) + 1] = whiteColour.green;
            pATIHW->lut[(MONO_WHITE * 3) + 2] = whiteColour.blue;
        }

        if (pATIHW->crtc == ATI_CRTC_VGA)
        {
            /* Initialise overscan to black */
            Index = pATIHW->attr[17] * 3;
            pATIHW->lut[Index + 0] =
                pATIHW->lut[Index + 1] =
                pATIHW->lut[Index + 2] = 0x00U;
        }

#endif /* AVOID_CPIO */

    }
}

/*
 * ATIDACSave --
 *
 * This function is called to save the current RAMDAC state into an ATIHWRec
 * structure occurrence.
 */
void
ATIDACSave
(
    ATIPtr   pATI,
    ATIHWPtr pATIHW
)
{
    int Index;

#ifdef AVOID_CPIO

    pATIHW->dac_read = in8(M64_DAC_READ);
    DACDelay;
    pATIHW->dac_write = in8(M64_DAC_WRITE);
    DACDelay;
    pATIHW->dac_mask = in8(M64_DAC_MASK);
    DACDelay;

    /* Save DAC's colour lookup table */
    out8(M64_DAC_MASK, 0xFFU);
    DACDelay;
    out8(M64_DAC_READ, 0x00U);
    DACDelay;
    for (Index = 0;  Index < NumberOf(pATIHW->lut);  Index++)
    {
        pATIHW->lut[Index] = in8(M64_DAC_DATA);
        DACDelay;
    }

    out8(M64_DAC_MASK, pATIHW->dac_mask);
    DACDelay;
    out8(M64_DAC_READ, pATIHW->dac_read);
    DACDelay;

#else /* AVOID_CPIO */

    ATISetDACIOPorts(pATI, pATIHW->crtc);

    pATIHW->dac_read = inb(pATI->CPIO_DAC_READ);
    DACDelay;
    pATIHW->dac_write = inb(pATI->CPIO_DAC_WRITE);
    DACDelay;
    pATIHW->dac_mask = inb(pATI->CPIO_DAC_MASK);
    DACDelay;

    /* Save DAC's colour lookup table */
    outb(pATI->CPIO_DAC_MASK, 0xFFU);
    DACDelay;
    outb(pATI->CPIO_DAC_READ, 0x00U);
    DACDelay;
    for (Index = 0;  Index < NumberOf(pATIHW->lut);  Index++)
    {
        pATIHW->lut[Index] = inb(pATI->CPIO_DAC_DATA);
        DACDelay;
    }

    outb(pATI->CPIO_DAC_MASK, pATIHW->dac_mask);
    DACDelay;
    outb(pATI->CPIO_DAC_READ, pATIHW->dac_read);
    DACDelay;

#endif /* AVOID_CPIO */

}

/*
 * ATIDACSet --
 *
 * This function loads RAMDAC data from an ATIHWRec structure occurrence.
 */
void
ATIDACSet
(
    ATIPtr   pATI,
    ATIHWPtr pATIHW
)
{
    int Index;

#ifdef AVOID_CPIO

    /* Load DAC's colour lookup table */
    out8(M64_DAC_MASK, 0xFFU);
    DACDelay;
    out8(M64_DAC_WRITE, 0x00U);
    DACDelay;
    for (Index = 0;  Index < NumberOf(pATIHW->lut);  Index++)
    {
        out8(M64_DAC_DATA, pATIHW->lut[Index]);
        DACDelay;
    }

    out8(M64_DAC_MASK, pATIHW->dac_mask);
    DACDelay;
    out8(M64_DAC_READ, pATIHW->dac_read);
    DACDelay;
    out8(M64_DAC_WRITE, pATIHW->dac_write);
    DACDelay;

#else /* AVOID_CPIO */

    ATISetDACIOPorts(pATI, pATIHW->crtc);

    /* Load DAC's colour lookup table */
    outb(pATI->CPIO_DAC_MASK, 0xFFU);
    DACDelay;
    outb(pATI->CPIO_DAC_WRITE, 0x00U);
    DACDelay;
    for (Index = 0;  Index < NumberOf(pATIHW->lut);  Index++)
    {
        outb(pATI->CPIO_DAC_DATA, pATIHW->lut[Index]);
        DACDelay;
    }

    outb(pATI->CPIO_DAC_MASK, pATIHW->dac_mask);
    DACDelay;
    outb(pATI->CPIO_DAC_READ, pATIHW->dac_read);
    DACDelay;
    outb(pATI->CPIO_DAC_WRITE, pATIHW->dac_write);
    DACDelay;

#endif /* AVOID_CPIO */

}

/*
 * ATILoadPalette --
 *
 * This function updates the RAMDAC's LUT and the in-memory copy of it in
 * NewHW.
 */
void
ATILoadPalette
(
    ScrnInfoPtr pScreenInfo,
    int         nColours,
    int         *Indices,
    LOCO        *Colours,
    VisualPtr   pVisual
)
{
    ATIPtr pATI = ATIPTR(pScreenInfo);
    CARD8  *LUTEntry;
    int    i, j, Index;

    if (((pVisual->class | DynamicClass) == DirectColor) &&
        ((1 << pVisual->nplanes) > (SizeOf(pATI->NewHW.lut) / 3)))
    {
        int reds = pVisual->redMask >> pVisual->offsetRed;
        int greens = pVisual->greenMask >> pVisual->offsetGreen;
        int blues = pVisual->blueMask >> pVisual->offsetBlue;

        int redShift = 8 - pATI->weight.red;
        int greenShift = 8 - pATI->weight.green;
        int blueShift = 8 - pATI->weight.blue;

        int redMult = 3 << redShift;
        int greenMult = 3 << greenShift;
        int blueMult = 3 << blueShift;

        int minShift;

        CARD8 fChanged[SizeOf(pATI->NewHW.lut) / 3];

        (void)memset(fChanged, SizeOf(fChanged), 0);

        minShift = redShift;
        if (minShift > greenShift)
            minShift = greenShift;
        if (minShift > blueShift)
            minShift = blueShift;

        for (i = 0;  i < nColours;  i++)
        {
            if((Index = Indices[i]) < 0)
                continue;

            if (Index <= reds)
            {
                j = Index * redMult;
                pATI->NewHW.lut[j + 0] = Colours[Index].red;
                fChanged[j / 3] = TRUE;
            }
            if (Index <= greens)
            {
                j = Index * greenMult;
                pATI->NewHW.lut[j + 1] = Colours[Index].green;
                fChanged[j / 3] = TRUE;
            }
            if (Index <= blues)
            {
                j = Index * blueMult;
                pATI->NewHW.lut[j + 2] = Colours[Index].blue;
                fChanged[j / 3] = TRUE;
            }
        }

        if (pScreenInfo->vtSema || pATI->currentMode)
        {
            /* Rewrite LUT entries that could have been changed */
            i = 1 << minShift;
            LUTEntry = pATI->NewHW.lut;

            for (Index = 0;
                 Index < (SizeOf(pATI->NewHW.lut) / 3);
                 Index += i, LUTEntry += i * 3)
            {
                if (!fChanged[Index])
                    continue;

#ifdef AVOID_CPIO

                out8(M64_DAC_WRITE, Index);
                DACDelay;
                out8(M64_DAC_DATA, LUTEntry[0]);
                DACDelay;
                out8(M64_DAC_DATA, LUTEntry[1]);
                DACDelay;
                out8(M64_DAC_DATA, LUTEntry[2]);
                DACDelay;

#else /* AVOID_CPIO */

                outb(pATI->CPIO_DAC_WRITE, Index);
                DACDelay;
                outb(pATI->CPIO_DAC_DATA, LUTEntry[0]);
                DACDelay;
                outb(pATI->CPIO_DAC_DATA, LUTEntry[1]);
                DACDelay;
                outb(pATI->CPIO_DAC_DATA, LUTEntry[2]);
                DACDelay;

#endif /* AVOID_CPIO */

            }
        }
    }
    else
    {
        for (i = 0;  i < nColours;  i++)
        {
            Index = Indices[i];
            if ((Index < 0) || (Index >= (SizeOf(pATI->NewHW.lut) / 3)))
                continue;

            LUTEntry = &pATI->NewHW.lut[Index * 3];
            LUTEntry[0] = Colours[Index].red;
            LUTEntry[1] = Colours[Index].green;
            LUTEntry[2] = Colours[Index].blue;

            if (pScreenInfo->vtSema || pATI->currentMode)
            {

#ifdef AVOID_CPIO

                out8(M64_DAC_WRITE, Index);
                DACDelay;
                out8(M64_DAC_DATA, LUTEntry[0]);
                DACDelay;
                out8(M64_DAC_DATA, LUTEntry[1]);
                DACDelay;
                out8(M64_DAC_DATA, LUTEntry[2]);
                DACDelay;

#else /* AVOID_CPIO */

                outb(pATI->CPIO_DAC_WRITE, Index);
                DACDelay;
                outb(pATI->CPIO_DAC_DATA, LUTEntry[0]);
                DACDelay;
                outb(pATI->CPIO_DAC_DATA, LUTEntry[1]);
                DACDelay;
                outb(pATI->CPIO_DAC_DATA, LUTEntry[2]);
                DACDelay;

#endif /* AVOID_CPIO */

            }
        }
    }
}

--- NEW FILE: atidac.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atidac.h,v 1.15 2003/01/01 19:16:31 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIDAC_H___

#if !defined(___ATI_H___) && defined(XFree86Module)
# error missing #include "ati.h" before #include "atidac.h"
# undef XFree86Module
#endif

#define ___ATIDAC_H___ 1

#include "aticrtc.h"
#include "atipriv.h"
#include "atiproto.h"

#include "xf86str.h"

#include "colormapst.h"

/*
 * RAMDAC-related definitions.
 */
#define ATI_DAC_MAX_TYPE         MaxBits(DACTYPE)
#define ATI_DAC_MAX_SUBTYPE      MaxBits(BIOS_INIT_DAC_SUBTYPE)

#define ATI_DAC(_Type, _Subtype) (((_Type) << 4) | (_Subtype))

#define ATI_DAC_ATI68830         ATI_DAC(0x0U, 0x0U)
#define ATI_DAC_SC11483          ATI_DAC(0x1U, 0x0U)
#define ATI_DAC_ATI68875         ATI_DAC(0x2U, 0x0U)
#define ATI_DAC_TVP3026_A        ATI_DAC(0x2U, 0x7U)
#define ATI_DAC_GENERIC          ATI_DAC(0x3U, 0x0U)
#define ATI_DAC_BT481            ATI_DAC(0x4U, 0x0U)
#define ATI_DAC_ATT20C491        ATI_DAC(0x4U, 0x1U)
#define ATI_DAC_SC15026          ATI_DAC(0x4U, 0x2U)
#define ATI_DAC_MU9C1880         ATI_DAC(0x4U, 0x3U)
#define ATI_DAC_IMSG174          ATI_DAC(0x4U, 0x4U)
#define ATI_DAC_ATI68860_B       ATI_DAC(0x5U, 0x0U)
#define ATI_DAC_ATI68860_C       ATI_DAC(0x5U, 0x1U)
#define ATI_DAC_TVP3026_B        ATI_DAC(0x5U, 0x7U)
#define ATI_DAC_STG1700          ATI_DAC(0x6U, 0x0U)
#define ATI_DAC_ATT20C498        ATI_DAC(0x6U, 0x1U)
#define ATI_DAC_STG1702          ATI_DAC(0x7U, 0x0U)
#define ATI_DAC_SC15021          ATI_DAC(0x7U, 0x1U)
#define ATI_DAC_ATT21C498        ATI_DAC(0x7U, 0x2U)
#define ATI_DAC_STG1703          ATI_DAC(0x7U, 0x3U)
#define ATI_DAC_CH8398           ATI_DAC(0x7U, 0x4U)
#define ATI_DAC_ATT20C408        ATI_DAC(0x7U, 0x5U)
#define ATI_DAC_INTERNAL         ATI_DAC(0x8U, 0x0U)
#define ATI_DAC_IBMRGB514        ATI_DAC(0x9U, 0x0U)
#define ATI_DAC_UNKNOWN          ATI_DAC((ATI_DAC_MAX_TYPE << 2) + 3, \
                                         ATI_DAC_MAX_SUBTYPE)
extern const SymTabRec ATIDACDescriptors[];

#ifdef AVOID_CPIO

#   define DACDelay     /* Nothing */

#else /* AVOID_CPIO */

#   define DACDelay                         \
        do                                  \
        {                                   \
            (void)inb(pATI->CPIO_DAC_WAIT); \
            (void)inb(pATI->CPIO_DAC_WAIT); \
        } while (0)

    extern void ATISetDACIOPorts FunctionPrototype((ATIPtr, ATICRTCType));

#endif /* AVOID_CPIO */

extern CARD8 ATIGetDACCmdReg     FunctionPrototype((ATIPtr));

extern void ATIDACPreInit        FunctionPrototype((ScrnInfoPtr, ATIPtr,
                                                    ATIHWPtr));
extern void ATIDACSave           FunctionPrototype((ATIPtr, ATIHWPtr));
extern void ATIDACSet            FunctionPrototype((ATIPtr, ATIHWPtr));

extern void ATILoadPalette       FunctionPrototype((ScrnInfoPtr, int, int *,
                                                    LOCO *, VisualPtr));

#endif /* ___ATIDAC_H___ */

--- NEW FILE: atidecoder.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atidecoder.c,v 1.1 2003/07/24 22:08:28 tsi Exp $ */
/*
 * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

#include "atidecoder.h"

/*
 * Video decoder definitions.
 */
const char *ATIDecoderNames[] =
{
    "No decoder",
    "BrookTree BT819",
    "Brooktree BT829",
    "Brooktree BT829A",
    "Philips SA7111",
    "Philips SA7112",
    "ATI Rage Theater",
    "Unknown type (7)",
    "Unknown type (8)",
    "Unknown type (9)",
    "Unknown type (10)",
    "Unknown type (11)",
    "Unknown type (12)",
    "Unknown type (13)",
    "Unknown type (14)",
    "Unknown type (15)"
};

--- NEW FILE: atidecoder.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atidecoder.h,v 1.1 2003/07/24 22:08:28 tsi Exp $ */
/*
 * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIDECODER_H___
#define ___ATIDECODER_H___ 1

/*
 * Video decoder definitions.
 */
typedef enum
{
    ATI_DECODER_NONE,
    ATI_DECODER_BT819,
    ATI_DECODER_BT829,
    ATI_DECODER_BT829A,
    ATI_DECODER_SA7111,
    ATI_DECODER_SA7112,
    ATI_DECODER_THEATER,
    ATI_DECODER_7,
    ATI_DECODER_8,
    ATI_DECODER_9,
    ATI_DECODER_10,
    ATI_DECODER_11,
    ATI_DECODER_12,
    ATI_DECODER_13,
    ATI_DECODER_14,
    ATI_DECODER_15
} ATIDecoderType;

extern const char *ATIDecoderNames[];

#endif /* ___ATIDECODER_H___ */

--- NEW FILE: atidga.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atidga.c,v 1.10 2003/04/23 21:51:27 tsi Exp $ */
/*
 * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 AVOID_DGA

#include "ati.h"
#include "atiadjust.h"
#include "atichip.h"
#include "atidac.h"
#include "atidga.h"
#include "atiident.h"
#include "atimode.h"
#include "atistruct.h"

#include "dgaproc.h"

/*
 * ATIDGAOpenFramebuffer --
 *
 * This function returns various framebuffer attributes to a DGA client.
 */
static Bool
ATIDGAOpenFramebuffer
(
    ScrnInfoPtr   pScreenInfo,
    char          **DeviceName,
    unsigned char **ApertureBase,
    int           *ApertureSize,
    int           *ApertureOffset,
    int           *flags
)
{
    ATIPtr pATI = ATIPTR(pScreenInfo);

    *DeviceName = NULL;         /* No special device */
    *ApertureBase = (unsigned char *)(pATI->LinearBase);
    *ApertureSize = pScreenInfo->videoRam * 1024;
    *ApertureOffset = 0;        /* Always */
    *flags = 0;                 /* Root premissions OS-dependent */

    return TRUE;
}

static int
BitsSet
(
    unsigned long data
)
{
    unsigned long mask = 1;
    int           set  = 0;

    for (;  mask;  mask <<= 1)
        if (data & mask)
            set++;

    return set;
}

/*
 * ATIDGASetMode --
 *
 * This function sets a graphics mode for a DGA client.
 */
static Bool
ATIDGASetMode
(
    ScrnInfoPtr pScreenInfo,
    DGAModePtr  pDGAMode
)
{
    ATIPtr         pATI    = ATIPTR(pScreenInfo);
    DisplayModePtr pMode;
    int            iScreen = pScreenInfo->scrnIndex;
    int            frameX0, frameY0;

    if (pDGAMode)
    {
        pMode = pDGAMode->mode;
        pATI->depth = pDGAMode->depth;
        pATI->bitsPerPixel = pDGAMode->bitsPerPixel;
        pATI->displayWidth =
            pDGAMode->bytesPerScanline * 8 / pATI->bitsPerPixel;
        pATI->weight.red = BitsSet(pDGAMode->red_mask);
        pATI->weight.green = BitsSet(pDGAMode->green_mask);
        pATI->weight.blue = BitsSet(pDGAMode->blue_mask);
        frameX0 = frameY0 = 0;
        if (!pATI->currentMode)
            pATI->currentMode = pScreenInfo->currentMode;
    }
    else
    {
        if (!(pMode = pATI->currentMode))
            return TRUE;

        pATI->depth = pScreenInfo->depth;
        pATI->bitsPerPixel = pScreenInfo->bitsPerPixel;
        pATI->displayWidth = pScreenInfo->displayWidth;
        pATI->weight = pScreenInfo->weight;
        frameX0 = pScreenInfo->frameX0;
        frameY0 = pScreenInfo->frameY0;
    }

    pATI->XModifier = pATI->bitsPerPixel / UnitOf(pATI->bitsPerPixel);
    ATIAdjustPreInit(pATI);
    ATIModePreInit(pScreenInfo, pATI, &pATI->NewHW);

    if (!(*pScreenInfo->SwitchMode)(iScreen, pMode, 0))
        return FALSE;
    if (!pDGAMode)
        pATI->currentMode = NULL;
    (*pScreenInfo->AdjustFrame)(iScreen, frameX0, frameY0, 0);

    return TRUE;
}

/*
 * ATIDGASetViewport --
 *
 * This function sets the display start address for a DGA client.
 */
static void
ATIDGASetViewport
(
    ScrnInfoPtr pScreenInfo,
    int         x,
    int         y,
    int         flags
)
{
    (*pScreenInfo->AdjustFrame)(pScreenInfo->pScreen->myNum, x, y, flags);
}

/*
 * ATIDGAGetViewport --
 *
 * This function returns the current status of prior DGA requests to set the
 * adapter's display start address.
 */
static int
ATIDGAGetViewport
(
    ScrnInfoPtr pScreenInfo
)
{
    return 0;   /* There are never any pending requests */
}

/*
 * ATIDGAFillRect --
 *
 * This function calls XAA solid fill primitives to fill a rectangle.
 */
static void
ATIDGAFillRect
(
    ScrnInfoPtr   pScreenInfo,
    int           x,
    int           y,
    int           w,
    int           h,
    unsigned long colour
)
{
    ATIPtr        pATI     = ATIPTR(pScreenInfo);
    XAAInfoRecPtr pXAAInfo = pATI->pXAAInfo;

    (*pXAAInfo->SetupForSolidFill)(pScreenInfo, (int)colour, GXcopy,
                                   (CARD32)(~0));
    (*pXAAInfo->SubsequentSolidFillRect)(pScreenInfo, x, y, w, h);

    if (pScreenInfo->bitsPerPixel == pATI->bitsPerPixel)
        SET_SYNC_FLAG(pXAAInfo);
}

/*
 * ATIDGABlitRect --
 *
 * This function calls XAA screen-to-screen copy primitives to copy a
 * rectangle.
 */
static void
ATIDGABlitRect
(
    ScrnInfoPtr pScreenInfo,
    int         xSrc,
    int         ySrc,
    int         w,
    int         h,
    int         xDst,
    int         yDst
)
{
    ATIPtr        pATI     = ATIPTR(pScreenInfo);
    XAAInfoRecPtr pXAAInfo = pATI->pXAAInfo;
    int           xdir     = ((xSrc < xDst) && (ySrc == yDst)) ? -1 : 1;
    int           ydir     = (ySrc < yDst) ? -1 : 1;

    (*pXAAInfo->SetupForScreenToScreenCopy)(pScreenInfo,
        xdir, ydir, GXcopy, (CARD32)(~0), -1);
    (*pXAAInfo->SubsequentScreenToScreenCopy)(pScreenInfo,
        xSrc, ySrc, xDst, yDst, w, h);

    if (pScreenInfo->bitsPerPixel == pATI->bitsPerPixel)
        SET_SYNC_FLAG(pXAAInfo);
}

/*
 * ATIDGABlitTransRect --
 *
 * This function calls XAA screen-to-screen copy primitives to transparently
 * copy a rectangle.
 */
static void
ATIDGABlitTransRect
(
    ScrnInfoPtr   pScreenInfo,
    int           xSrc,
    int           ySrc,
    int           w,
    int           h,
    int           xDst,
    int           yDst,
    unsigned long colour
)
{
    ATIPtr        pATI     = ATIPTR(pScreenInfo);
    XAAInfoRecPtr pXAAInfo = pATI->pXAAInfo;
    int           xdir     = ((xSrc < xDst) && (ySrc == yDst)) ? -1 : 1;
    int           ydir     = (ySrc < yDst) ? -1 : 1;

    pATI->XAAForceTransBlit = TRUE;

    (*pXAAInfo->SetupForScreenToScreenCopy)(pScreenInfo,
        xdir, ydir, GXcopy, (CARD32)(~0), (int)colour);

    pATI->XAAForceTransBlit = FALSE;

    (*pXAAInfo->SubsequentScreenToScreenCopy)(pScreenInfo,
        xSrc, ySrc, xDst, yDst, w, h);

    if (pScreenInfo->bitsPerPixel == pATI->bitsPerPixel)
        SET_SYNC_FLAG(pXAAInfo);
}

/*
 * ATIDGAAddModes --
 *
 * This function translates DisplayModeRec's into DGAModeRec's.
 */
static void
ATIDGAAddModes
(
    ScrnInfoPtr pScreenInfo,
    ATIPtr      pATI,
    int         flags,
    int         depth,
    int         bitsPerPixel,
    int         redMask,
    int         greenMask,
    int         blueMask,
    int         visualClass
)
{
    DisplayModePtr pMode         = pScreenInfo->modes;
    DGAModePtr     pDGAMode;
    int            displayWidth  = pScreenInfo->displayWidth;
    int            videoBits     = pScreenInfo->videoRam * 1024 * 8;
    int            xViewportStep = 64 / UnitOf(bitsPerPixel);
    int            modePitch, bitsPerScanline, maxViewportY;

    if (bitsPerPixel != pScreenInfo->bitsPerPixel)
        displayWidth = 0;

    while (1)
    {
        /* Weed out multiscanned modes */
        if ((pMode->VScan <= 1) ||
            ((pMode->VScan == 2) && !(pMode->Flags & V_DBLSCAN)))
        {
            /*
             * For code simplicity, ensure DGA mode pitch is a multiple of 64
             * bytes.
             */
            if (!(modePitch = displayWidth))
            {
                modePitch = ((64 * 8) / UnitOf(bitsPerPixel)) - 1;
                modePitch = (pMode->HDisplay + modePitch) & ~modePitch;
            }

            /* Ensure the mode fits in video memory */
            if ((modePitch * bitsPerPixel * pMode->VDisplay) <= videoBits)
            {
                /* Stop generating modes on out-of-memory conditions */
                pDGAMode = xrealloc(pATI->pDGAMode,
                    (pATI->nDGAMode + 1) * SizeOf(DGAModeRec));
                if (!pDGAMode)
                    break;

                pATI->pDGAMode = pDGAMode;
                pDGAMode += pATI->nDGAMode;
                pATI->nDGAMode++;
                (void)memset(pDGAMode, 0, SizeOf(DGAModeRec));

                /* Fill in the mode structure */
                pDGAMode->mode = pMode;
                pDGAMode->flags = flags;
                if (bitsPerPixel == pScreenInfo->bitsPerPixel)
                {
                    pDGAMode->flags |= DGA_PIXMAP_AVAILABLE;
                    pDGAMode->address = pATI->pMemory;

                    if (pATI->pXAAInfo)
                        pDGAMode->flags &= ~DGA_CONCURRENT_ACCESS;
                }
                if ((pMode->Flags & V_DBLSCAN) || (pMode->VScan > 1))
                    pDGAMode->flags |= DGA_DOUBLESCAN;
                if (pMode->Flags & V_INTERLACE)
                    pDGAMode->flags |= DGA_INTERLACED;

                pDGAMode->byteOrder = pScreenInfo->imageByteOrder;
                pDGAMode->depth = depth;
                pDGAMode->bitsPerPixel = bitsPerPixel;
                pDGAMode->red_mask = redMask;
                pDGAMode->green_mask = greenMask;
                pDGAMode->blue_mask = blueMask;
                pDGAMode->visualClass = visualClass;

                pDGAMode->viewportWidth = pMode->HDisplay;
                pDGAMode->viewportHeight = pMode->VDisplay;
                pDGAMode->xViewportStep = xViewportStep;
                pDGAMode->yViewportStep = 1;

                bitsPerScanline = modePitch * bitsPerPixel;
                pDGAMode->bytesPerScanline = bitsPerScanline / 8;
                pDGAMode->imageWidth = pDGAMode->pixmapWidth = modePitch;
                pDGAMode->imageHeight = pDGAMode->pixmapHeight =
                    videoBits / bitsPerScanline;

                pDGAMode->maxViewportX =
                    pDGAMode->imageWidth - pDGAMode->viewportWidth;
                pDGAMode->maxViewportY =
                    pDGAMode->imageHeight - pDGAMode->viewportHeight;
                maxViewportY =
                    ((((pATI->AdjustMaxBase * 8) / bitsPerPixel) +
                      xViewportStep) / modePitch) - 1;
                if (maxViewportY < pDGAMode->maxViewportY)
                    pDGAMode->maxViewportY = maxViewportY;
            }
        }

        if ((pMode = pMode->next) == pScreenInfo->modes)
        {
            if (!displayWidth)
                break;

            displayWidth = 0;
        }
    }
}

/*
 * ATIDGAInit --
 *
 * This function initialises the driver's support for the DGA extension.
 */
Bool
ATIDGAInit
(
    ScreenPtr   pScreen,
    ScrnInfoPtr pScreenInfo,
    ATIPtr      pATI
)
{
    XAAInfoRecPtr pXAAInfo;
    int           flags;

    if (!pATI->nDGAMode)
    {

#ifndef AVOID_CPIO

        /*
         * Contrary to previous extension versions, DGA 2 does not support
         * banked framebuffers.  Also, disable DGA when non-DGA server modes
         * are planar.
         */
        if (pATI->BankInfo.BankSize || (pScreenInfo->depth <= 4))
            return FALSE;

#endif /* AVOID_CPIO */

        /* Set up DGA callbacks */
        pATI->ATIDGAFunctions.OpenFramebuffer = ATIDGAOpenFramebuffer;
        pATI->ATIDGAFunctions.SetMode         = ATIDGASetMode;
        pATI->ATIDGAFunctions.SetViewport     = ATIDGASetViewport;
        pATI->ATIDGAFunctions.GetViewport     = ATIDGAGetViewport;

        flags = 0;
        if ((pXAAInfo = pATI->pXAAInfo))
        {
            pATI->ATIDGAFunctions.Sync = pXAAInfo->Sync;
            if (pXAAInfo->SetupForSolidFill &&
                pXAAInfo->SubsequentSolidFillRect)
            {
                flags |= DGA_FILL_RECT;
                pATI->ATIDGAFunctions.FillRect = ATIDGAFillRect;
            }
            if (pXAAInfo->SetupForScreenToScreenCopy &&
                pXAAInfo->SubsequentScreenToScreenCopy)
            {
                flags |= DGA_BLIT_RECT | DGA_BLIT_RECT_TRANS;
                pATI->ATIDGAFunctions.BlitRect      = ATIDGABlitRect;
                pATI->ATIDGAFunctions.BlitTransRect = ATIDGABlitTransRect;
            }
        }
        if (!flags)
            flags = DGA_CONCURRENT_ACCESS;

        ATIDGAAddModes(pScreenInfo, pATI, flags,
            8, 8, 0, 0, 0, PseudoColor);

        if ((pATI->Chip >= ATI_CHIP_264CT) &&
            (pATI->Chipset == ATI_CHIPSET_ATI))
        {
            ATIDGAAddModes(pScreenInfo, pATI, flags,
                15, 16, 0x7C00U, 0x03E0U, 0x001FU, TrueColor);

            ATIDGAAddModes(pScreenInfo, pATI, flags,
                16, 16, 0xF800U, 0x07E0U, 0x001FU, TrueColor);

            ATIDGAAddModes(pScreenInfo, pATI, flags,
                24, 24, 0x00FF0000U, 0x0000FF00U, 0x000000FFU, TrueColor);

            ATIDGAAddModes(pScreenInfo, pATI, flags,
                24, 32, 0x00FF0000U, 0x0000FF00U, 0x000000FFU, TrueColor);

            if (pATI->DAC != ATI_DAC_INTERNAL)      /* Not first revision */
            {
                ATIDGAAddModes(pScreenInfo, pATI, flags,
                    15, 16, 0x7C00U, 0x03E0U, 0x001FU, DirectColor);

                ATIDGAAddModes(pScreenInfo, pATI, flags,
                    16, 16, 0xF800U, 0x07E0U, 0x001FU, DirectColor);

                ATIDGAAddModes(pScreenInfo, pATI, flags,
                    24, 24, 0x00FF0000U, 0x0000FF00U, 0x000000FFU, DirectColor);

                ATIDGAAddModes(pScreenInfo, pATI, flags,
                    24, 32, 0x00FF0000U, 0x0000FF00U, 0x000000FFU, DirectColor);
            }
        }
    }

    return DGAInit(pScreen, &pATI->ATIDGAFunctions, pATI->pDGAMode,
                   pATI->nDGAMode);
}

#endif /* AVOID_DGA */

--- NEW FILE: atidga.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atidga.h,v 1.7 2003/04/23 21:51:28 tsi Exp $ */
/*
 * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIDGA_H___
#define ___ATIDGA_H___ 1

#ifndef AVOID_DGA

#include "atipriv.h"
#include "atiproto.h"

#include "xf86str.h"

extern Bool ATIDGAInit FunctionPrototype((ScreenPtr, ScrnInfoPtr, ATIPtr));

#endif /* AVOID_DGA */

#endif /* ___ATIDGA_H___ */

--- NEW FILE: atidsp.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atidsp.c,v 1.21 2003/09/24 02:43:18 dawes Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

#include "ati.h"
#include "atichip.h"
#include "aticrtc.h"
#include "atidsp.h"
#include "atimach64io.h"
#include "atividmem.h"

/*
 * ATIDSPPreInit --
 *
 * This function initialises global variables used to set DSP registers on a
 * VT-B or later.
 */
Bool
ATIDSPPreInit
(
    int    iScreen,
    ATIPtr pATI
)
{
    CARD32 IOValue, dsp_config, dsp_on_off, vga_dsp_config, vga_dsp_on_off;
    int trp;

    /*
     * VT-B's and later have additional post-dividers that are not powers of
     * two.
     */
    pATI->ClockDescriptor.NumD = 8;

    /* Retrieve XCLK settings */
    IOValue = ATIMach64GetPLLReg(PLL_XCLK_CNTL);
    pATI->XCLKPostDivider = GetBits(IOValue, PLL_XCLK_SRC_SEL);
    pATI->XCLKReferenceDivider = 1;
    switch (pATI->XCLKPostDivider)
    {
        case 0:  case 1:  case 2:  case 3:
            break;

        case 4:
            pATI->XCLKReferenceDivider = 3;
            pATI->XCLKPostDivider = 0;
            break;

        default:
            xf86DrvMsg(iScreen, X_ERROR,
                "Unsupported XCLK source:  %d.\n", pATI->XCLKPostDivider);
            return FALSE;
    }

    pATI->XCLKPostDivider -= GetBits(IOValue, PLL_MFB_TIMES_4_2B);
    pATI->XCLKFeedbackDivider = ATIMach64GetPLLReg(PLL_MCLK_FB_DIV);

    xf86DrvMsgVerb(iScreen, X_INFO, 2,
        "Engine XCLK %.3f MHz;  Refresh rate code %ld.\n",
        ATIDivide(pATI->XCLKFeedbackDivider * pATI->ReferenceNumerator,
                  pATI->XCLKReferenceDivider * pATI->ClockDescriptor.MaxM *
                  pATI->ReferenceDenominator, 1 - pATI->XCLKPostDivider, 0) /
        (double)1000.0,
        GetBits(pATI->LockData.mem_cntl, CTL_MEM_REFRESH_RATE_B));

    /* Compute maximum RAS delay and friends */
    trp = GetBits(pATI->LockData.mem_cntl, CTL_MEM_TRP);
    pATI->XCLKPageFaultDelay = GetBits(pATI->LockData.mem_cntl, CTL_MEM_TRCD) +
        GetBits(pATI->LockData.mem_cntl, CTL_MEM_TCRD) + trp + 2;
    pATI->XCLKMaxRASDelay = GetBits(pATI->LockData.mem_cntl, CTL_MEM_TRAS) +
        trp + 2;
    pATI->DisplayFIFODepth = 32;

    if (pATI->Chip < ATI_CHIP_264VT4)
    {
        pATI->XCLKPageFaultDelay += 2;
        pATI->XCLKMaxRASDelay += 3;
        pATI->DisplayFIFODepth = 24;
    }

    switch (pATI->MemoryType)
    {
        case MEM_264_DRAM:
            if (pATI->VideoRAM <= 1024)
            {
                pATI->DisplayLoopLatency = 10;
            }
            else
            {
                pATI->DisplayLoopLatency = 8;
                pATI->XCLKPageFaultDelay += 2;
            }
            break;

        case MEM_264_EDO:
        case MEM_264_PSEUDO_EDO:
            if (pATI->VideoRAM <= 1024)
            {
                pATI->DisplayLoopLatency = 9;
            }
            else
            {
                pATI->DisplayLoopLatency = 8;
                pATI->XCLKPageFaultDelay++;
            }
            break;

        case MEM_264_SDRAM:
            if (pATI->VideoRAM <= 1024)
            {
                pATI->DisplayLoopLatency = 11;
            }
            else
            {
                pATI->DisplayLoopLatency = 10;
                pATI->XCLKPageFaultDelay++;
            }
            break;

        case MEM_264_SGRAM:
            pATI->DisplayLoopLatency = 8;
            pATI->XCLKPageFaultDelay += 3;
            break;

        default:                /* Set maximums */
            pATI->DisplayLoopLatency = 11;
            pATI->XCLKPageFaultDelay += 3;
            break;
    }

    if (pATI->XCLKMaxRASDelay <= pATI->XCLKPageFaultDelay)
        pATI->XCLKMaxRASDelay = pATI->XCLKPageFaultDelay + 1;

    /* Allow BIOS to override */
    dsp_config = inr(DSP_CONFIG);
    dsp_on_off = inr(DSP_ON_OFF);
    vga_dsp_config = inr(VGA_DSP_CONFIG);
    vga_dsp_on_off = inr(VGA_DSP_ON_OFF);

    if (dsp_config)
        pATI->DisplayLoopLatency = GetBits(dsp_config, DSP_LOOP_LATENCY);

    if ((!dsp_on_off && (pATI->Chip < ATI_CHIP_264GTPRO)) ||
        ((dsp_on_off == vga_dsp_on_off) &&
         (!dsp_config || !((dsp_config ^ vga_dsp_config) & DSP_XCLKS_PER_QW))))
    {
        if (ATIDivide(GetBits(vga_dsp_on_off, VGA_DSP_OFF),
                      GetBits(vga_dsp_config, VGA_DSP_XCLKS_PER_QW), 5, 1) > 24)
            pATI->DisplayFIFODepth = 32;
        else
            pATI->DisplayFIFODepth = 24;
    }

    return TRUE;
}

/*
 * ATIDSPSave --
 *
 * This function is called to remember DSP register values on VT-B and later
 * controllers.
 */
void
ATIDSPSave
(
    ATIPtr   pATI,
    ATIHWPtr pATIHW
)
{
    pATIHW->dsp_on_off = inr(DSP_ON_OFF);
    pATIHW->dsp_config = inr(DSP_CONFIG);
}


/*
 * ATIDSPCalculate --
 *
 * This function sets up DSP register values for a VTB or later.  Note that
 * this would be slightly different if VCLK 0 or 1 were used for the mode
 * instead.  In that case, this function would set VGA_DSP_CONFIG and
 * VGA_DSP_ON_OFF, would have to zero out DSP_CONFIG and DSP_ON_OFF, and would
 * have to consider that VGA_DSP_CONFIG is partitioned slightly differently
 * than DSP_CONFIG.
 */
void
ATIDSPCalculate
(
    ATIPtr         pATI,
    ATIHWPtr       pATIHW,
    DisplayModePtr pMode
)
{
    int Multiplier, Divider;
    int RASMultiplier = pATI->XCLKMaxRASDelay, RASDivider = 1;
    int dsp_precision, dsp_on, dsp_off, dsp_xclks;
    int tmp, vshift, xshift;

#   define Maximum_DSP_PRECISION ((int)MaxBits(DSP_PRECISION))

    /* Compute a memory-to-screen bandwidth ratio */
    Multiplier = pATI->XCLKFeedbackDivider *
        pATI->ClockDescriptor.PostDividers[pATIHW->PostDivider];
    Divider = pATIHW->FeedbackDivider * pATI->XCLKReferenceDivider;

#ifndef AVOID_CPIO

    if (pATI->depth >= 8)

#endif /* AVOID_CPIO */

    {
        Divider *= pATI->bitsPerPixel / 4;
    }

    /* Start by assuming a display FIFO width of 64 bits */
    vshift = (6 - 2) - pATI->XCLKPostDivider;

#ifndef AVOID_CPIO

    if (pATIHW->crtc == ATI_CRTC_VGA)
        vshift--;               /* Nope, it's 32 bits wide */

#endif /* AVOID_CPIO */

    if (pATI->OptionPanelDisplay && (pATI->LCDPanelID >= 0))
    {
        /* Compensate for horizontal stretching */
        Multiplier *= pATI->LCDHorizontal;
        Divider *= pMode->HDisplay & ~7;

        RASMultiplier *= pATI->LCDHorizontal;
        RASDivider *= pMode->HDisplay & ~7;
    }

    /* Determine dsp_precision first */
    tmp = ATIDivide(Multiplier * pATI->DisplayFIFODepth, Divider, vshift, -1);
    for (dsp_precision = -5;  tmp;  dsp_precision++)
        tmp >>= 1;
    if (dsp_precision < 0)
        dsp_precision = 0;
    else if (dsp_precision > Maximum_DSP_PRECISION)
        dsp_precision = Maximum_DSP_PRECISION;

    xshift = 6 - dsp_precision;
    vshift += xshift;

    /* Move on to dsp_off */
    dsp_off = ATIDivide(Multiplier * (pATI->DisplayFIFODepth - 1), Divider,
        vshift, -1) - ATIDivide(1, 1, vshift - xshift, 1);

    /* Next is dsp_on */

#ifndef AVOID_CPIO

    if ((pATIHW->crtc == ATI_CRTC_VGA) /* && (dsp_precision < 3) */)
    {
        /*
         * TODO:  I don't yet know why something like this appears necessary.
         *        But I don't have time to explore this right now.
         */
        dsp_on = ATIDivide(Multiplier * 5, Divider, vshift + 2, 1);
    }
    else

#endif /* AVOID_CPIO */

    {
        dsp_on = ATIDivide(Multiplier, Divider, vshift, 1);
        tmp = ATIDivide(RASMultiplier, RASDivider, xshift, 1);
        if (dsp_on < tmp)
            dsp_on = tmp;
        dsp_on += (tmp * 2) +
            ATIDivide(pATI->XCLKPageFaultDelay, 1, xshift, 1);
    }

    /* Calculate rounding factor and apply it to dsp_on */
    tmp = ((1 << (Maximum_DSP_PRECISION - dsp_precision)) - 1) >> 1;
    dsp_on = ((dsp_on + tmp) / (tmp + 1)) * (tmp + 1);

    if (dsp_on >= ((dsp_off / (tmp + 1)) * (tmp + 1)))
    {
        dsp_on = dsp_off - ATIDivide(Multiplier, Divider, vshift, -1);
        dsp_on = (dsp_on / (tmp + 1)) * (tmp + 1);
    }

    /* Last but not least:  dsp_xclks */
    dsp_xclks = ATIDivide(Multiplier, Divider, vshift + 5, 1);

    /* Build DSP register contents */
    pATIHW->dsp_on_off = SetBits(dsp_on, DSP_ON) |
        SetBits(dsp_off, DSP_OFF);
    pATIHW->dsp_config = SetBits(dsp_precision, DSP_PRECISION) |
        SetBits(dsp_xclks, DSP_XCLKS_PER_QW) |
        SetBits(pATI->DisplayLoopLatency, DSP_LOOP_LATENCY);
}

/*
 * ATIDSPSet --
 *
 * This function is called to set DSP registers on VT-B and later controllers.
 */
void
ATIDSPSet
(
    ATIPtr   pATI,
    ATIHWPtr pATIHW
)
{
    outr(DSP_ON_OFF, pATIHW->dsp_on_off);
    outr(DSP_CONFIG, pATIHW->dsp_config);
}

--- NEW FILE: atidsp.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atidsp.h,v 1.10 2003/01/01 19:16:32 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIDSP_H___
#define ___ATIDSP_H___ 1

#include "atipriv.h"
#include "atiproto.h"

#include "xf86str.h"

extern Bool ATIDSPPreInit   FunctionPrototype((int, ATIPtr));
extern void ATIDSPSave      FunctionPrototype((ATIPtr, ATIHWPtr));
extern void ATIDSPCalculate FunctionPrototype((ATIPtr, ATIHWPtr,
                                               DisplayModePtr));
extern void ATIDSPSet       FunctionPrototype((ATIPtr, ATIHWPtr));

#endif /* ___ATIDSP_H___ */

--- NEW FILE: atii2c.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atii2c.c,v 1.3 2003/11/10 18:41:20 tsi Exp $ */
/*
 * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

#include "atiadapter.h"
#include "atii2c.h"
#include "atiload.h"
#include "atimach64i2c.h"
#include "atistruct.h"

#include "xf86.h"

/* This is derived from GATOS code, with a liberal sprinkling of bug fixes */

/*
 * Some local macros for use by the mid-level I2C functions.
 */

#define ATII2CDelay                                            \
    (*pI2CBus->I2CUDelay)(pI2CBus, pI2CBus->HoldTime)


#define ATII2CSCLDirOff                                        \
    if (pATII2C->SCLDir != 0)                                  \
        (*pATII2C->I2CSetBits)(pATII2C, pATI,                  \
            pATII2C->I2CCur & ~pATII2C->SCLDir)

#define ATII2CSCLDirOn                                         \
    if (pATII2C->SCLDir != 0)                                  \
        (*pATII2C->I2CSetBits)(pATII2C, pATI,                  \
            pATII2C->I2CCur | pATII2C->SCLDir)

#define ATII2CSDADirOff                                        \
    if (pATII2C->SDADir != 0)                                  \
        (*pATII2C->I2CSetBits)(pATII2C, pATI,                  \
            pATII2C->I2CCur & ~pATII2C->SDADir)

#define ATII2CSDADirOn                                         \
    if (pATII2C->SDADir != 0)                                  \
        (*pATII2C->I2CSetBits)(pATII2C, pATI,                  \
            pATII2C->I2CCur | pATII2C->SDADir)


#define ATII2CSCLBitGet                                        \
    ((*pATII2C->I2CGetBits)(pATI) & pATII2C->SCLGet)

#define ATII2CSCLBitOff                                        \
    do                                                         \
    {                                                          \
        (*pATII2C->I2CSetBits)(pATII2C, pATI,                  \
            pATII2C->I2CCur & ~pATII2C->SCLSet);               \
        ATII2CDelay;                                           \
    } while (0)

#define ATII2CSCLBitOn                                         \
    do                                                         \
    {                                                          \
        (*pATII2C->I2CSetBits)(pATII2C, pATI,                  \
            pATII2C->I2CCur | pATII2C->SCLSet);                \
        do      /* Wait until all devices have released SCL */ \
        {                                                      \
            ATII2CDelay;                                       \
        } while (ATII2CSCLBitGet == 0);                        \
    } while (0)


#define ATII2CSDABitGet                                        \
    ((*pATII2C->I2CGetBits)(pATI) & pATII2C->SDAGet)

#define ATII2CSDABitOff                                        \
    do                                                         \
    {                                                          \
        (*pATII2C->I2CSetBits)(pATII2C, pATI,                  \
            pATII2C->I2CCur & ~pATII2C->SDASet);               \
        ATII2CDelay;                                           \
    } while (0)

#define ATII2CSDABitOn                                         \
    do                                                         \
    {                                                          \
        (*pATII2C->I2CSetBits)(pATII2C, pATI,                  \
            pATII2C->I2CCur | pATII2C->SDASet);                \
        ATII2CDelay;                                           \
    } while (0)

#define ATII2CSDABitSet(_flag)                                 \
    do                                                         \
    {                                                          \
        if (_flag)                                             \
            ATII2CSDABitOn;                                    \
        else                                                   \
            ATII2CSDABitOff;                                   \
    } while (0)


/*
 * ATII2CAddress --
 *
 * This function puts a Start bit and an 8-bit address on the I2C bus.
 */
static Bool
ATII2CAddress
(
    I2CDevPtr    pI2CDev,
    I2CSlaveAddr Address
)
{
    I2CBusPtr pI2CBus = pI2CDev->pI2CBus;
    ATII2CPtr pATII2C = pI2CBus->DriverPrivate.ptr;
    ATIPtr    pATI    = pATII2C->pATI;

    /*
     * Set I2C line directions to out-bound.  SCL will remain out-bound until
     * next I2C Stop.
     */
    ATII2CSCLDirOn;
    ATII2CSDADirOn;

    /*
     * Send Start bit.  This is a pull-down of the data line while the clock
     * line is pulled up.
     */
    ATII2CSDABitOn;
    ATII2CSCLBitOn;
    ATII2CSDABitOff;
    ATII2CSCLBitOff;

    /* Send low byte of device address */
    if ((*pI2CBus->I2CPutByte)(pI2CDev, (I2CByte)Address))
    {
        /* Send top byte of address, if appropriate */
        if (((Address & 0x00F8U) != 0x00F0U) &&
            ((Address & 0x00FEU) != 0x0000U))
            return TRUE;

        if ((*pI2CBus->I2CPutByte)(pI2CDev, (I2CByte)(Address >> 8)))
            return TRUE;
    }

    /* Kill I2C transaction on failure */
    (*pI2CBus->I2CStop)(pI2CDev);
    return FALSE;
}

/*
 * ATII2CStop --
 *
 * This function puts a stop signal on the I2C bus.
 */
static void
ATII2CStop
(
    I2CDevPtr pI2CDev
)
{
    I2CBusPtr pI2CBus = pI2CDev->pI2CBus;
    ATII2CPtr pATII2C = pI2CBus->DriverPrivate.ptr;
    ATIPtr    pATI    = pATII2C->pATI;

    ATII2CSDADirOn;             /* Set data line direction to out-bound */

    /*
     * Send Stop bit.  This is a pull-up of the data line while the clock line
     * is pulled up.
     */
    ATII2CSDABitOff;
    ATII2CSCLBitOn;
    ATII2CSDABitOn;
    ATII2CSCLBitOff;

    /* Reset I2C line directions to in-bound */
    ATII2CSCLDirOff;
    ATII2CSDADirOff;
}

/*
 * ATII2CPutByte --
 *
 * This function puts an 8-bit value on the I2C bus, starting with its MSB.
 */
static Bool
ATII2CPutByte
(
    I2CDevPtr pI2CDev,
    I2CByte   Data
)
{
    I2CBusPtr pI2CBus = pI2CDev->pI2CBus;
    ATII2CPtr pATII2C = pI2CBus->DriverPrivate.ptr;
    ATIPtr    pATI    = pATII2C->pATI;
    int       i;
    Bool      Result;

    ATII2CSDADirOn;             /* Set data line direction to out-bound */

    /* Send data byte */
    for (i = 0;  i < 8;  i++)
    {
        ATII2CSDABitSet(Data & 0x80U);
        ATII2CSCLBitOn;
        ATII2CSCLBitOff;

        Data <<= 1;
    }

    ATII2CSDABitOn;             /* Release data line */

    ATII2CSDADirOff;            /* Set data line direction to in-bound */

    ATII2CSCLBitOn;             /* Start bit-read clock pulse */

    /* Get [N]ACK bit */
    if (ATII2CSDABitGet)
        Result = FALSE;
    else
        Result = TRUE;

    ATII2CSCLBitOff;            /* End clock pulse */

    return Result;
}

/*
 * ATII2CGetByte --
 *
 * This function retrieves an 8-bit value from the I2C bus.
 */
static Bool
ATII2CGetByte
(
    I2CDevPtr pI2CDev,
    I2CByte   *pData,
    Bool      Last
)
{
    I2CBusPtr     pI2CBus = pI2CDev->pI2CBus;
    ATII2CPtr     pATII2C = pI2CBus->DriverPrivate.ptr;
    ATIPtr        pATI    = pATII2C->pATI;
    unsigned long Value   = 1;

    do
    {
        ATII2CSCLBitOn;         /* Start bit-read clock pulse */

        /* Accumulate bit into byte value */
        Value <<= 1;
        if (ATII2CSDABitGet)
            Value++;

        ATII2CSCLBitOff;        /* End clock pulse */
    } while (Value <= (unsigned long)((I2CByte)(-1)));

    *pData = (I2CByte)Value;

    ATII2CSDADirOn;             /* Set data line direction to out-bound */

    /* Send [N]ACK bit */
    ATII2CSDABitSet(Last);
    ATII2CSCLBitOn;
    ATII2CSCLBitOff;

    if (!Last)
        ATII2CSDABitOn;         /* Release data line */

    ATII2CSDADirOff;            /* Set data line direction to in-bound */

    return TRUE;
}

/*
 * ATICreateI2CBusRec --
 *
 * This function is called to initialise an I2CBusRec.
 */
I2CBusPtr
ATICreateI2CBusRec
(
    int    iScreen,
    ATIPtr pATI,
    char   *BusName
)
{
    I2CBusPtr pI2CBus;
    ATII2CPtr pATII2C = xnfcalloc(1, SizeOf(ATII2CRec));

    if (!(pI2CBus = xf86CreateI2CBusRec()))
    {
        xf86DrvMsg(iScreen, X_WARNING, "Unable to allocate I2C Bus record.\n");
        xfree(pATII2C);
        return NULL;
    }

    /* Fill in generic structure fields */
    pI2CBus->BusName           = BusName;
    pI2CBus->scrnIndex         = iScreen;

    pI2CBus->I2CAddress        = ATII2CAddress;
    pI2CBus->I2CStop           = ATII2CStop;
    pI2CBus->I2CPutByte        = ATII2CPutByte;
    pI2CBus->I2CGetByte        = ATII2CGetByte;

    pI2CBus->DriverPrivate.ptr = pATII2C;

    pATII2C->pATI              = pATI;

    if (xf86I2CBusInit(pI2CBus))
        return pI2CBus;

    xf86DrvMsg(iScreen, X_WARNING,
        "I2C bus %s initialisation failure.\n", BusName);
    xf86DestroyI2CBusRec(pI2CBus, TRUE, TRUE);
    xfree(pATII2C);
    return NULL;
}

/*
 * ATII2CPreInit --
 *
 * This is called by ATIPreInit() to create I2C bus record(s) for the adapter.
 */
void
ATII2CPreInit
(
    ScrnInfoPtr pScreenInfo,
    ATIPtr      pATI
)
{
    switch (pATI->Adapter)
    {
        case ATI_ADAPTER_MACH64:
            if (!ATILoadModule(pScreenInfo, "i2c", ATIi2cSymbols))
                return;

            ATIMach64I2CPreInit(pScreenInfo, pATI);
            break;

        default:
            break;
    }
}

/*
 * ATII2CFreeScreen --
 *
 * This is called by ATIFreeScreen() to remove the driver's I2C interface.
 */
void
ATII2CFreeScreen
(
    int iScreen
)
{
    I2CBusPtr pI2CBus, *ppI2CBus;
    ATII2CPtr pATII2C;
    int nI2CBus;

    nI2CBus = xf86I2CGetScreenBuses(iScreen, &ppI2CBus);
    while (--nI2CBus >= 0)
    {
        pI2CBus = ppI2CBus[nI2CBus];
        pATII2C = pI2CBus->DriverPrivate.ptr;

        xf86DestroyI2CBusRec(pI2CBus, TRUE, TRUE);
        xfree(pATII2C);
    }

    xfree(ppI2CBus);
}

--- NEW FILE: atii2c.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atii2c.h,v 1.1 2003/07/24 22:08:28 tsi Exp $ */
/*
 * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATII2C_H___
#define ___ATII2C_H___ 1

#include "atipriv.h"
#include "atiproto.h"

#include "xf86str.h"

#include "xf86i2c.h"

typedef struct _ATII2CRec ATII2CRec, *ATII2CPtr;

struct _ATII2CRec
{
    ATIPtr pATI;
    void   (*I2CSetBits) FunctionPrototype((ATII2CPtr, ATIPtr, CARD32));
    CARD32 (*I2CGetBits) FunctionPrototype((ATIPtr));
    CARD32 SCLDir, SCLGet, SCLSet;
    CARD32 SDADir, SDAGet, SDASet;
    CARD32 I2CCur;
};

extern void      ATII2CPreInit       FunctionPrototype((ScrnInfoPtr, ATIPtr));
extern I2CBusPtr ATICreateI2CBusRec  FunctionPrototype((int, ATIPtr, char *));
extern void      ATII2CFreeScreen    FunctionPrototype((int));

#endif /* ___ATII2C_H___ */

--- NEW FILE: atiident.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiident.c,v 1.11 2003/01/01 19:16:32 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

#include "ati.h"
#include "atiident.h"
#include "atiutil.h"
#include "ativersion.h"

#include "r128_probe.h"
#include "radeon_probe.h"

const char *ATIChipsetNames[] =
{
    "ati",

#ifndef AVOID_CPIO

    "ativga",
    "ibmvga",
    "ibm8514",
    "vgawonder",
    "mach8",
    "mach32",

#endif /* AVOID_CPIO */

    "mach64",
    "rage128",
    "radeon"
};

static SymTabRec ATIPublicChipsetNames[] =
{
    {ATI_CHIPSET_ATI, "ati"},

#ifndef AVOID_CPIO

    {ATI_CHIPSET_ATIVGA, "ativga"},
#ifdef __MAYBE_NOT__
    {ATI_CHIPSET_IBMVGA, "ibmvga"},
#endif
#ifdef __NOT_YET__
    {ATI_CHIPSET_IBM8514, "ibm8514"},
#endif

#endif /* AVOID_CPIO */

    {-1, NULL}
};

/*
 * ATIIdentify --
 *
 * Print the driver's list of chipset names.
 */
void
ATIIdentify
(
    int flags
)
{
    xf86PrintChipsets(ATI_NAME,
        (NumberOf(ATIPublicChipsetNames) <= 2) ?
            "ATI driver (version " ATI_VERSION_NAME ") for chipset" :
            "ATI driver (version " ATI_VERSION_NAME ") for chipsets",
        ATIPublicChipsetNames);
    R128Identify(flags);
    RADEONIdentify(flags);
}

/*
 * ATIIdentProbe --
 *
 * This function determines if the user specified a chipset name acceptable to
 * the driver.  It returns an ATIChipsetType or -1.
 */
int
ATIIdentProbe
(
    const char *ChipsetName
)
{
    int              Chipset;

    static SymTabRec SpecificNames[] =
    {

#ifndef AVOID_CPIO

        {ATI_CHIPSET_VGAWONDER, "vgawonder"},
#ifdef __NOT_YET__
        {ATI_CHIPSET_MACH8, "mach8"},
#endif
        {ATI_CHIPSET_MACH32, "mach32"},

#endif /* AVOID_CPIO */

        {ATI_CHIPSET_MACH64, "mach64"},
        {ATI_CHIPSET_RAGE128, "rage128"},
        {ATI_CHIPSET_RADEON, "radeon"},
        {-1, NULL}
    };

    /* If no Chipset specification, default to "ati" */
    if (!ChipsetName || !*ChipsetName)
        return ATI_CHIPSET_ATI;

    Chipset = xf86StringToToken(ATIPublicChipsetNames, ChipsetName);
    if (Chipset != -1)
        return Chipset;

    /* Check for some other chipset names */
    return xf86StringToToken(SpecificNames, ChipsetName);
}

--- NEW FILE: atiident.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiident.h,v 1.10 2003/01/01 19:16:32 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIIDENT_H___
#define ___ATIIDENT_H___ 1

#include "atiproto.h"

typedef enum
{
    ATI_CHIPSET_ATI,

#ifndef AVOID_CPIO

    ATI_CHIPSET_ATIVGA,
    ATI_CHIPSET_IBMVGA,
    ATI_CHIPSET_IBM8514,
    ATI_CHIPSET_VGAWONDER,
    ATI_CHIPSET_MACH8,
    ATI_CHIPSET_MACH32,

#endif /* AVOID_CPIO */

    ATI_CHIPSET_MACH64,
    ATI_CHIPSET_RAGE128,
    ATI_CHIPSET_RADEON,
    ATI_CHIPSET_MAX             /* Must be last */
} ATIChipsetType;

extern const char *ATIChipsetNames[];

extern void ATIIdentify   FunctionPrototype((int));
extern int  ATIIdentProbe FunctionPrototype((const char *));

#endif /* ___ATIIDENT_H___ */

--- NEW FILE: atiio.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiio.h,v 1.14 2003/01/01 19:16:32 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIIO_H___

#if !defined(___ATI_H___) && defined(XFree86Module)
# error missing #include "ati.h" before #include "atiio.h"
# undef XFree86Module
#endif

#define ___ATIIO_H___ 1

#include "atiregs.h"

#include "compiler.h"

/* I/O decoding definitions */
typedef enum
{
    SPARSE_IO,
    BLOCK_IO
} ATIIODecodingType;

#ifndef AVOID_CPIO

/* Wait until "n" queue entries are free */
#define ibm8514WaitQueue(_n)                      \
    {                                             \
        while (inw(GP_STAT) & (0x0100U >> (_n))); \
    }
#define ATIWaitQueue(_n)                                    \
    {                                                       \
        while (inw(EXT_FIFO_STATUS) & (0x010000U >> (_n))); \
    }

/* Wait until GP is idle and queue is empty */
#define WaitIdleEmpty()                      \
    {                                        \
        while (inw(GP_STAT) & (GPBUSY | 1)); \
    }
#define ProbeWaitIdleEmpty()              \
    {                                     \
        int _i;                           \
        CARD16 _value;                    \
        for (_i = 0;  _i < 100000;  _i++) \
        {                                 \
            _value = inw(GP_STAT);        \
            if (_value == (CARD16)(-1))   \
                break;                    \
            if (!(_value & (GPBUSY | 1))) \
                break;                    \
        }                                 \
    }

/* Wait until GP has data available */
#define WaitDataReady()                    \
    {                                      \
        while (!(inw(GP_STAT) & DATARDY)); \
    }

#endif /* AVOID_CPIO */

#endif /* ___ATIIO_H___ */

--- NEW FILE: atiload.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiload.c,v 1.15 2003/08/29 21:07:57 tsi Exp $ */
/*
 * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 "aticursor.h"
#include "atiload.h"
#include "atistruct.h"

/*
 * All symbol lists belong here.  They are externalised so that they can be
 * referenced elsewhere.  Note the naming convention for these things...
 */

const char *ATIint10Symbols[] =
{
    "xf86FreeInt10",
    "xf86InitInt10",
    "xf86int10Addr",
    NULL
};

const char *ATIddcSymbols[] =
{
    "xf86PrintEDID",
    "xf86SetDDCProperties",
    NULL
};

const char *ATIvbeSymbols[] =
{
    "VBEInit",
    "vbeDoEDID",
    "vbeFree",
    NULL
};

#ifndef AVOID_CPIO

const char *ATIxf1bppSymbols[] =
{
    "xf1bppScreenInit",
    NULL
};

const char *ATIxf4bppSymbols[] =
{
    "xf4bppScreenInit",
    NULL
};

#endif /* AVOID_CPIO */

const char *ATIfbSymbols[] =
{
    "fbPictureInit",
    "fbScreenInit",
    NULL
};

const char *ATIshadowfbSymbols[] =
{
    "ShadowFBInit",
    NULL
};

const char *ATIxaaSymbols[] =
{
    "XAACreateInfoRec",
    "XAADestroyInfoRec",
    "XAAInit",
    NULL
};

const char *ATIramdacSymbols[] =
{
    "xf86CreateCursorInfoRec",
    "xf86DestroyCursorInfoRec",
    "xf86InitCursor",
    NULL
};

const char *ATIi2cSymbols[] =
{
    "xf86CreateI2CBusRec",
    "xf86DestroyI2CBusRec",
    "xf86I2CBusInit",
    "xf86I2CDevInit",
    "xf86I2CFindDev",
    "xf86I2CGetScreenBuses",
    NULL
};

/*
 * ATILoadModule --
 *
 * Load a specific module and register with the loader those of its entry
 * points that are referenced by this driver.
 */
pointer
ATILoadModule
(
    ScrnInfoPtr  pScreenInfo,
    const char  *Module,
    const char **SymbolList
)
{
    pointer pModule = xf86LoadSubModule(pScreenInfo, Module);

    if (pModule)
        xf86LoaderReqSymLists(SymbolList, NULL);

    return pModule;
}

/*
 * ATILoadModules --
 *
 * This function loads other modules required for a screen.
 */
pointer
ATILoadModules
(
    ScrnInfoPtr pScreenInfo,
    ATIPtr      pATI
)
{
    /* Load shadow frame buffer code if needed */
    if (pATI->OptionShadowFB &&
        !ATILoadModule(pScreenInfo, "shadowfb", ATIshadowfbSymbols))
        return NULL;

    /* Load XAA if needed */
    if (pATI->OptionAccel &&
        !ATILoadModule(pScreenInfo, "xaa", ATIxaaSymbols))
        return NULL;

    /* Load ramdac module if needed */
    if ((pATI->Cursor > ATI_CURSOR_SOFTWARE) &&
        !ATILoadModule(pScreenInfo, "ramdac", ATIramdacSymbols))
        return NULL;

    /* Load depth-specific entry points */
    switch (pATI->bitsPerPixel)
    {

#ifndef AVOID_CPIO

        case 1:
            return ATILoadModule(pScreenInfo, "xf1bpp", ATIxf1bppSymbols);

        case 4:
            return ATILoadModule(pScreenInfo, "xf4bpp", ATIxf4bppSymbols);

#endif /* AVOID_CPIO */

        case 8:
        case 16:
        case 24:
        case 32:
            return ATILoadModule(pScreenInfo, "fb", ATIfbSymbols);

        default:
            return NULL;
    }
}

#endif /* XFree86LOADER */

--- NEW FILE: atiload.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiload.h,v 1.6 2003/07/24 22:08:28 tsi Exp $ */
/*
 * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATILOAD_H___
#define ___ATILOAD_H___ 1

#ifdef XFree86LOADER

#include "atipriv.h"
#include "atiproto.h"

#include "xf86str.h"

extern const char *ATIint10Symbols[], *ATIddcSymbols[], *ATIvbeSymbols[],

#ifndef AVOID_CPIO

                  *ATIxf1bppSymbols[], *ATIxf4bppSymbols[],

#endif /* AVOID_CPIO */

                  *ATIfbSymbols[], *ATIshadowfbSymbols[], *ATIxaaSymbols[],
                  *ATIramdacSymbols[], *ATIi2cSymbols[];

extern pointer ATILoadModule  FunctionPrototype((ScrnInfoPtr, const char *,
                                                 const char **));
extern pointer ATILoadModules FunctionPrototype((ScrnInfoPtr, ATIPtr));

#else /* XFree86LOADER */

#define ATILoadModule(pScreenInfo, Module, SymboList) ((pointer)1)
#define ATILoadModules(pScreenInfo, pATI)             ((pointer)1)

#endif /* XFree86LOADER */

#endif /* ___ATILOAD_H___ */

--- NEW FILE: atilock.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atilock.c,v 1.20tsi Exp $ */
/*
 * Copyright 1999 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

#include "ati.h"
#include "atiadapter.h"
#include "atichip.h"
#include "atilock.h"
#include "atimach64io.h"
#include "atiwonderio.h"

/*
 * ATIUnlock --
 *
 * This function is entered to unlock registers and disable unwanted
 * emulations.  It saves the current state for later restoration by ATILock().
 */
void
ATIUnlock
(
    ATIPtr pATI
)
{
    CARD32 tmp;

#ifndef AVOID_CPIO

    CARD32 saved_lcd_gen_ctrl = 0, lcd_gen_ctrl = 0;

#endif /* AVOID_CPIO */

    if (pATI->Unlocked)
        return;
    pATI->Unlocked = TRUE;

#ifndef AVOID_CPIO

    if (pATI->ChipHasSUBSYS_CNTL)
    {
        /* Save register values to be modified */
        pATI->LockData.clock_sel = inw(CLOCK_SEL);
        if (pATI->Chip >= ATI_CHIP_68800)
        {
            pATI->LockData.misc_options = inw(MISC_OPTIONS);
            pATI->LockData.mem_bndry = inw(MEM_BNDRY);
            pATI->LockData.mem_cfg = inw(MEM_CFG);
        }

        tmp = inw(SUBSYS_STAT) & _8PLANE;

        /* Reset the 8514/A and disable all interrupts */
        outw(SUBSYS_CNTL, tmp | (GPCTRL_RESET | CHPTEST_NORMAL));
        outw(SUBSYS_CNTL, tmp | (GPCTRL_ENAB | CHPTEST_NORMAL | RVBLNKFLG |
            RPICKFLAG | RINVALIDIO | RGPIDLE));

        /* Ensure VGA is enabled */
        outw(CLOCK_SEL, pATI->LockData.clock_sel &~DISABPASSTHRU);
        if (pATI->Chip >= ATI_CHIP_68800)
        {
            outw(MISC_OPTIONS, pATI->LockData.misc_options &
                ~(DISABLE_VGA | DISABLE_DAC));

            /* Disable any video memory boundary */
            outw(MEM_BNDRY, pATI->LockData.mem_bndry &
                ~(MEM_PAGE_BNDRY | MEM_BNDRY_ENA));

            /* Disable direct video memory aperture */
            outw(MEM_CFG, pATI->LockData.mem_cfg &
                ~(MEM_APERT_SEL | MEM_APERT_PAGE | MEM_APERT_LOC));
        }

        /* Wait for all activity to die down */
        ProbeWaitIdleEmpty();
    }
    else if (pATI->Chip >= ATI_CHIP_88800GXC)

#endif /* AVOID_CPIO */

    {
        /* Reset everything */
        pATI->LockData.bus_cntl = inr(BUS_CNTL);
        if (pATI->Chip < ATI_CHIP_264VT4)
        {
            pATI->LockData.bus_cntl =
                (pATI->LockData.bus_cntl & ~BUS_HOST_ERR_INT_EN) |
                BUS_HOST_ERR_INT;
            if (pATI->Chip < ATI_CHIP_264VTB)
                pATI->LockData.bus_cntl =
                    (pATI->LockData.bus_cntl & ~BUS_FIFO_ERR_INT_EN) |
                        BUS_FIFO_ERR_INT;
        }
        tmp = pATI->LockData.bus_cntl & ~BUS_ROM_DIS;
        if (pATI->Chip < ATI_CHIP_264VTB)
            tmp |= SetBits(15, BUS_FIFO_WS);
        else
            tmp &= ~BUS_MASTER_DIS;
        if (pATI->Chip >= ATI_CHIP_264VT)
            tmp |= BUS_EXT_REG_EN;              /* Enable Block 1 */
        outr(BUS_CNTL, tmp);
        pATI->LockData.crtc_int_cntl = inr(CRTC_INT_CNTL);
        outr(CRTC_INT_CNTL, (pATI->LockData.crtc_int_cntl & ~CRTC_INT_ENS) |
            CRTC_INT_ACKS);
        pATI->LockData.gen_test_cntl = inr(GEN_TEST_CNTL) &
            (GEN_OVR_OUTPUT_EN | GEN_OVR_POLARITY | GEN_CUR_EN |
                GEN_BLOCK_WR_EN);
        tmp = pATI->LockData.gen_test_cntl & ~GEN_CUR_EN;
        outr(GEN_TEST_CNTL, tmp | GEN_GUI_EN);
        outr(GEN_TEST_CNTL, tmp);
        outr(GEN_TEST_CNTL, tmp | GEN_GUI_EN);
        tmp = pATI->LockData.crtc_gen_cntl = inr(CRTC_GEN_CNTL) &
            ~(CRTC_EN | CRTC_LOCK_REGS);
        if (pATI->Chip >= ATI_CHIP_264XL)
            tmp = (tmp & ~CRTC_INT_ENS_X) | CRTC_INT_ACKS_X;
        outr(CRTC_GEN_CNTL, tmp | CRTC_EN);
        outr(CRTC_GEN_CNTL, tmp);
        outr(CRTC_GEN_CNTL, tmp | CRTC_EN);
        if ((pATI->LCDPanelID >= 0) && (pATI->Chip != ATI_CHIP_264LT))
        {
            pATI->LockData.lcd_index = inr(LCD_INDEX);
            if (pATI->Chip >= ATI_CHIP_264XL)
                outr(LCD_INDEX, pATI->LockData.lcd_index &
                    ~(LCD_MONDET_INT_EN | LCD_MONDET_INT));

            /*
             * Prevent BIOS initiated display switches on dual-CRT controllers.
             */
            if (!pATI->OptionBIOSDisplay && (pATI->Chip != ATI_CHIP_264XL))
            {
                pATI->LockData.scratch_reg3 = inr(SCRATCH_REG3);
                outr(SCRATCH_REG3,
                    pATI->LockData.scratch_reg3 | DISPLAY_SWITCH_DISABLE);
            }
        }

        pATI->LockData.mem_cntl = inr(MEM_CNTL);
        if (pATI->Chip < ATI_CHIP_264CT)
            outr(MEM_CNTL, pATI->LockData.mem_cntl &
                ~(CTL_MEM_BNDRY | CTL_MEM_BNDRY_EN));

        /* Disable feature connector on integrated controllers */
        tmp = pATI->LockData.dac_cntl = inr(DAC_CNTL);
        if (pATI->Chip >= ATI_CHIP_264CT)
            tmp &= ~DAC_FEA_CON_EN;

#ifndef AVOID_CPIO

        /* Ensure VGA aperture is enabled */
        pATI->LockData.config_cntl = inr(CONFIG_CNTL);
        tmp |= DAC_VGA_ADR_EN;
        outr(CONFIG_CNTL, pATI->LockData.config_cntl & ~CFG_VGA_DIS);

#endif /* AVOID_CPIO */

        outr(DAC_CNTL, tmp);

        if (pATI->Chip >= ATI_CHIP_264VTB)
        {
            pATI->LockData.mpp_config = inr(MPP_CONFIG);
            pATI->LockData.mpp_strobe_seq = inr(MPP_STROBE_SEQ);
            pATI->LockData.tvo_cntl = inr(TVO_CNTL);

            if (pATI->Chip >= ATI_CHIP_264GT2C)
            {
                pATI->LockData.hw_debug = inr(HW_DEBUG);

                if (pATI->Chip >= ATI_CHIP_264GTPRO)
                {
                    if (!(pATI->LockData.hw_debug & CMDFIFO_SIZE_EN))
                        outr(HW_DEBUG,
                            pATI->LockData.hw_debug | CMDFIFO_SIZE_EN);

                    pATI->LockData.i2c_cntl_0 =
                        inr(I2C_CNTL_0) | (I2C_CNTL_STAT | I2C_CNTL_HPTR_RST);
                    outr(I2C_CNTL_0,
                        pATI->LockData.i2c_cntl_0 & ~I2C_CNTL_INT_EN);
                    pATI->LockData.i2c_cntl_1 = inr(I2C_CNTL_1);
                }
                else
                {
                    if (pATI->LockData.hw_debug & CMDFIFO_SIZE_DIS)
                        outr(HW_DEBUG,
                            pATI->LockData.hw_debug & ~CMDFIFO_SIZE_DIS);
                }
            }
        }

#ifndef AVOID_CPIO

    }

    if (pATI->VGAAdapter != ATI_ADAPTER_NONE)
    {
        if (pATI->CPIO_VGAWonder)
        {
            /*
             * Ensure all registers are read/write and disable all non-VGA
             * emulations.
             */
            pATI->LockData.b1 = ATIGetExtReg(0xB1U);
            ATIModifyExtReg(pATI, 0xB1U, pATI->LockData.b1, 0xFCU, 0x00U);
            pATI->LockData.b4 = ATIGetExtReg(0xB4U);
            ATIModifyExtReg(pATI, 0xB4U, pATI->LockData.b4, 0x00U, 0x00U);
            pATI->LockData.b5 = ATIGetExtReg(0xB5U);
            ATIModifyExtReg(pATI, 0xB5U, pATI->LockData.b5, 0xBFU, 0x00U);
            pATI->LockData.b6 = ATIGetExtReg(0xB6U);
            ATIModifyExtReg(pATI, 0xB6U, pATI->LockData.b6, 0xDDU, 0x00U);
            pATI->LockData.b8 = ATIGetExtReg(0xB8U);
            ATIModifyExtReg(pATI, 0xB8U, pATI->LockData.b8, 0xC0U, 0x00U);
            pATI->LockData.b9 = ATIGetExtReg(0xB9U);
            ATIModifyExtReg(pATI, 0xB9U, pATI->LockData.b9, 0x7FU, 0x00U);
            if (pATI->Chip > ATI_CHIP_18800)
            {
                pATI->LockData.be = ATIGetExtReg(0xBEU);
                ATIModifyExtReg(pATI, 0xBEU, pATI->LockData.be, 0xFAU, 0x01U);
                if (pATI->Chip >= ATI_CHIP_28800_2)
                {
                    pATI->LockData.a6 = ATIGetExtReg(0xA6U);
                    ATIModifyExtReg(pATI, 0xA6U, pATI->LockData.a6,
                        0x7FU, 0x00U);
                    pATI->LockData.ab = ATIGetExtReg(0xABU);
                    ATIModifyExtReg(pATI, 0xABU, pATI->LockData.ab,
                        0xE7U, 0x00U);
                }
            }
        }

        if (pATI->LCDPanelID >= 0)
        {
            if (pATI->Chip == ATI_CHIP_264LT)
            {
                saved_lcd_gen_ctrl = inr(LCD_GEN_CTRL);

                /* Setup to unlock non-shadow registers */
                lcd_gen_ctrl = saved_lcd_gen_ctrl & ~SHADOW_RW_EN;
                outr(LCD_GEN_CTRL, lcd_gen_ctrl);
            }
            else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
                        (pATI->Chip == ATI_CHIP_264XL) ||
                        (pATI->Chip == ATI_CHIP_MOBILITY)) */
            {
                saved_lcd_gen_ctrl = ATIMach64GetLCDReg(LCD_GEN_CNTL);

                /* Setup to unlock non-shadow registers */
                lcd_gen_ctrl = saved_lcd_gen_ctrl &
                    ~(CRTC_RW_SELECT | SHADOW_RW_EN);
                ATIMach64PutLCDReg(LCD_GEN_CNTL, lcd_gen_ctrl);
            }
        }

        ATISetVGAIOBase(pATI, inb(R_GENMO));

        /*
         * There's a bizarre interaction here.  If bit 0x80 of CRTC[17] is on,
         * then CRTC[3] is read-only.  If bit 0x80 of CRTC[3] is off, then
         * CRTC[17] is write-only (or a read attempt actually returns bits from
         * C/EGA's light pen position).  This means that if both conditions are
         * met, CRTC[17]'s value on server entry cannot be retrieved.
         */

        pATI->LockData.crt03 = tmp = GetReg(CRTX(pATI->CPIO_VGABase), 0x03U);
        if ((tmp & 0x80U) ||
            ((outb(CRTD(pATI->CPIO_VGABase), tmp | 0x80U),
                tmp = inb(CRTD(pATI->CPIO_VGABase))) & 0x80U))
        {
            /* CRTC[16-17] should be readable */
            pATI->LockData.crt11 = tmp =
                GetReg(CRTX(pATI->CPIO_VGABase), 0x11U);
            if (tmp & 0x80U)            /* Unprotect CRTC[0-7] */
                outb(CRTD(pATI->CPIO_VGABase), tmp & 0x7FU);
        }
        else
        {
            /*
             * Could not make CRTC[17] readable, so unprotect CRTC[0-7]
             * replacing VSyncEnd with zero.  This zero will be replaced after
             * acquiring the needed access.
             */
            unsigned int VSyncEnd, VBlankStart, VBlankEnd;
            CARD8 crt07, crt09;

            PutReg(CRTX(pATI->CPIO_VGABase), 0x11U, 0x20U);
            /* Make CRTC[16-17] readable */
            PutReg(CRTX(pATI->CPIO_VGABase), 0x03U, tmp | 0x80U);
            /* Make vertical synch pulse as wide as possible */
            crt07 = GetReg(CRTX(pATI->CPIO_VGABase), 0x07U);
            crt09 = GetReg(CRTX(pATI->CPIO_VGABase), 0x09U);
            VBlankStart = (((crt09 & 0x20U) << 4) | ((crt07 & 0x08U) << 5) |
                GetReg(CRTX(pATI->CPIO_VGABase), 0x15U)) + 1;
            VBlankEnd = (VBlankStart & 0x0300U) |
                GetReg(CRTX(pATI->CPIO_VGABase), 0x16U);
            if (VBlankEnd <= VBlankStart)
                VBlankEnd += 0x0100U;
            VSyncEnd = (((crt07 & 0x80U) << 2) | ((crt07 & 0x04U) << 6) |
                GetReg(CRTX(pATI->CPIO_VGABase), 0x10U)) + 0x0FU;
            if (VSyncEnd >= VBlankEnd)
                VSyncEnd = VBlankEnd - 1;
            pATI->LockData.crt11 = (VSyncEnd & 0x0FU) | 0x20U;
            PutReg(CRTX(pATI->CPIO_VGABase), 0x11U, pATI->LockData.crt11);
            pATI->LockData.crt11 |= 0x80U;
        }

        if (pATI->LCDPanelID >= 0)
        {
            /* Setup to unlock shadow registers */
            lcd_gen_ctrl |= SHADOW_RW_EN;

            if (pATI->Chip == ATI_CHIP_264LT)
                outr(LCD_GEN_CTRL, lcd_gen_ctrl);
            else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
                        (pATI->Chip == ATI_CHIP_264XL) ||
                        (pATI->Chip == ATI_CHIP_MOBILITY)) */
                ATIMach64PutLCDReg(LCD_GEN_CNTL, lcd_gen_ctrl);

            /* Unlock shadow registers */
            ATISetVGAIOBase(pATI, inb(R_GENMO));

            pATI->LockData.shadow_crt03 = tmp =
                GetReg(CRTX(pATI->CPIO_VGABase), 0x03U);
            if ((tmp & 0x80U) ||
                ((outb(CRTD(pATI->CPIO_VGABase), tmp | 0x80U),
                    tmp = inb(CRTD(pATI->CPIO_VGABase))) & 0x80U))
            {
                /* CRTC[16-17] should be readable */
                pATI->LockData.shadow_crt11 = tmp =
                    GetReg(CRTX(pATI->CPIO_VGABase), 0x11U);
                if (tmp & 0x80U)            /* Unprotect CRTC[0-7] */
                {
                    outb(CRTD(pATI->CPIO_VGABase), tmp & 0x7FU);
                }
                else if (!tmp && pATI->LockData.crt11)
                {
                    pATI->LockData.shadow_crt11 = tmp = pATI->LockData.crt11;
                    outb(CRTD(pATI->CPIO_VGABase), tmp & 0x7FU);
                }
            }
            else
            {
                /*
                 * Could not make CRTC[17] readable, so unprotect CRTC[0-7]
                 * replacing VSyncEnd with zero.  This zero will be replaced
                 * after acquiring the needed access.
                 */
                unsigned int VSyncEnd, VBlankStart, VBlankEnd;
                CARD8 crt07, crt09;

                PutReg(CRTX(pATI->CPIO_VGABase), 0x11U, 0x20U);
                /* Make CRTC[16-17] readable */
                PutReg(CRTX(pATI->CPIO_VGABase), 0x03U, tmp | 0x80U);
                /* Make vertical synch pulse as wide as possible */
                crt07 = GetReg(CRTX(pATI->CPIO_VGABase), 0x07U);
                crt09 = GetReg(CRTX(pATI->CPIO_VGABase), 0x09U);
                VBlankStart = (((crt09 & 0x20U) << 4) |
                    ((crt07 & 0x08U) << 5) |
                    GetReg(CRTX(pATI->CPIO_VGABase), 0x15U)) + 1;
                VBlankEnd = (VBlankStart & 0x0300U) |
                    GetReg(CRTX(pATI->CPIO_VGABase), 0x16U);
                if (VBlankEnd <= VBlankStart)
                    VBlankEnd += 0x0100U;
                VSyncEnd = (((crt07 & 0x80U) << 2) | ((crt07 & 0x04U) << 6) |
                    GetReg(CRTX(pATI->CPIO_VGABase), 0x10U)) + 0x0FU;
                if (VSyncEnd >= VBlankEnd)
                    VSyncEnd = VBlankEnd - 1;
                pATI->LockData.shadow_crt11 = (VSyncEnd & 0x0FU) | 0x20U;
                PutReg(CRTX(pATI->CPIO_VGABase), 0x11U,
                    pATI->LockData.shadow_crt11);
                pATI->LockData.shadow_crt11 |= 0x80U;
            }

            /* Restore selection */
            if (pATI->Chip == ATI_CHIP_264LT)
            {
                outr(LCD_GEN_CTRL, saved_lcd_gen_ctrl);
            }
            else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
                        (pATI->Chip == ATI_CHIP_264XL) ||
                        (pATI->Chip == ATI_CHIP_MOBILITY)) */
            {
                ATIMach64PutLCDReg(LCD_GEN_CNTL, saved_lcd_gen_ctrl);

                /* Restore LCD index */
                out8(LCD_INDEX, GetByte(pATI->LockData.lcd_index, 0));
            }
        }

#endif /* AVOID_CPIO */

    }
}

/*
 * ATILock --
 *
 * This function restores the state saved by ATIUnlock() above.
 */
void
ATILock
(
    ATIPtr pATI
)
{

#ifndef AVOID_CPIO

    CARD32 tmp, saved_lcd_gen_ctrl = 0, lcd_gen_ctrl = 0;

#endif /* AVOID_CPIO */

    if (!pATI->Unlocked)
        return;
    pATI->Unlocked = FALSE;

#ifndef AVOID_CPIO

    if (pATI->VGAAdapter != ATI_ADAPTER_NONE)
    {
        if (pATI->LCDPanelID >= 0)
        {
            if (pATI->Chip == ATI_CHIP_264LT)
            {
                saved_lcd_gen_ctrl = inr(LCD_GEN_CTRL);

                /* Setup to lock non-shadow registers */
                lcd_gen_ctrl = saved_lcd_gen_ctrl & ~SHADOW_RW_EN;
                outr(LCD_GEN_CTRL, lcd_gen_ctrl);
            }
            else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
                        (pATI->Chip == ATI_CHIP_264XL) ||
                        (pATI->Chip == ATI_CHIP_MOBILITY)) */
            {
                saved_lcd_gen_ctrl = ATIMach64GetLCDReg(LCD_GEN_CNTL);

                /* Setup to lock non-shadow registers */
                lcd_gen_ctrl = saved_lcd_gen_ctrl &
                    ~(CRTC_RW_SELECT | SHADOW_RW_EN);
                ATIMach64PutLCDReg(LCD_GEN_CNTL, lcd_gen_ctrl);
            }
        }

        ATISetVGAIOBase(pATI, inb(R_GENMO));

        /* Restore VGA locks */
        PutReg(CRTX(pATI->CPIO_VGABase), 0x03U, pATI->LockData.crt03);
        PutReg(CRTX(pATI->CPIO_VGABase), 0x11U, pATI->LockData.crt11);

        if (pATI->LCDPanelID >= 0)
        {
            /* Setup to lock shadow registers */
            lcd_gen_ctrl |= SHADOW_RW_EN;

            if (pATI->Chip == ATI_CHIP_264LT)
                outr(LCD_GEN_CTRL, lcd_gen_ctrl);
            else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
                        (pATI->Chip == ATI_CHIP_264XL) ||
                        (pATI->Chip == ATI_CHIP_MOBILITY)) */
                ATIMach64PutLCDReg(LCD_GEN_CNTL, lcd_gen_ctrl);

            /* Lock shadow registers */
            ATISetVGAIOBase(pATI, inb(R_GENMO));

            PutReg(CRTX(pATI->CPIO_VGABase), 0x03U,
                pATI->LockData.shadow_crt03);
            PutReg(CRTX(pATI->CPIO_VGABase), 0x11U,
                pATI->LockData.shadow_crt11);

            /* Restore selection */
            if (pATI->Chip == ATI_CHIP_264LT)
                outr(LCD_GEN_CTRL, saved_lcd_gen_ctrl);
            else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
                        (pATI->Chip == ATI_CHIP_264XL) ||
                        (pATI->Chip == ATI_CHIP_MOBILITY)) */
                ATIMach64PutLCDReg(LCD_GEN_CNTL, saved_lcd_gen_ctrl);
        }

        if (pATI->CPIO_VGAWonder)
        {
            /*
             * Restore emulation and protection bits in ATI extended VGA
             * registers.
             */
            ATIModifyExtReg(pATI, 0xB1U, -1, 0xFCU, pATI->LockData.b1);
            ATIModifyExtReg(pATI, 0xB4U, -1, 0x00U, pATI->LockData.b4);
            ATIModifyExtReg(pATI, 0xB5U, -1, 0xBFU, pATI->LockData.b5);
            ATIModifyExtReg(pATI, 0xB6U, -1, 0xDDU, pATI->LockData.b6);
            ATIModifyExtReg(pATI, 0xB8U, -1, 0xC0U, pATI->LockData.b8 & 0x03U);
            ATIModifyExtReg(pATI, 0xB9U, -1, 0x7FU, pATI->LockData.b9);
            if (pATI->Chip > ATI_CHIP_18800)
            {
                ATIModifyExtReg(pATI, 0xBEU, -1, 0xFAU, pATI->LockData.be);
                if (pATI->Chip >= ATI_CHIP_28800_2)
                {
                    ATIModifyExtReg(pATI, 0xA6U, -1, 0x7FU, pATI->LockData.a6);
                    ATIModifyExtReg(pATI, 0xABU, -1, 0xE7U, pATI->LockData.ab);
                }
            }
            ATIModifyExtReg(pATI, 0xB8U, -1, 0xC0U, pATI->LockData.b8);
        }
    }

    if (pATI->ChipHasSUBSYS_CNTL)
    {
        tmp = inw(SUBSYS_STAT) & _8PLANE;

        /* Reset the 8514/A and disable all interrupts */
        outw(SUBSYS_CNTL, tmp | (GPCTRL_RESET | CHPTEST_NORMAL));
        outw(SUBSYS_CNTL, tmp | (GPCTRL_ENAB | CHPTEST_NORMAL | RVBLNKFLG |
            RPICKFLAG | RINVALIDIO | RGPIDLE));

        /* Restore modified accelerator registers */
        outw(CLOCK_SEL, pATI->LockData.clock_sel);
        if (pATI->Chip >= ATI_CHIP_68800)
        {
            outw(MISC_OPTIONS, pATI->LockData.misc_options);
            outw(MEM_BNDRY, pATI->LockData.mem_bndry);
            outw(MEM_CFG, pATI->LockData.mem_cfg);
        }

        /* Wait for all activity to die down */
        ProbeWaitIdleEmpty();
    }
    else if (pATI->Chip >= ATI_CHIP_88800GXC)

#endif /* AVOID_CPIO */

    {
        /* Reset everything */
        outr(BUS_CNTL, pATI->LockData.bus_cntl);

        outr(CRTC_INT_CNTL, pATI->LockData.crtc_int_cntl);

        outr(GEN_TEST_CNTL, pATI->LockData.gen_test_cntl | GEN_GUI_EN);
        outr(GEN_TEST_CNTL, pATI->LockData.gen_test_cntl);
        outr(GEN_TEST_CNTL, pATI->LockData.gen_test_cntl | GEN_GUI_EN);

        outr(CRTC_GEN_CNTL, pATI->LockData.crtc_gen_cntl | CRTC_EN);
        outr(CRTC_GEN_CNTL, pATI->LockData.crtc_gen_cntl);
        outr(CRTC_GEN_CNTL, pATI->LockData.crtc_gen_cntl | CRTC_EN);

#ifndef AVOID_CPIO

        outr(CONFIG_CNTL, pATI->LockData.config_cntl);

#endif /* AVOID_CPIO */

        outr(DAC_CNTL, pATI->LockData.dac_cntl);
        if (pATI->Chip < ATI_CHIP_264CT)
            outr(MEM_CNTL, pATI->LockData.mem_cntl);
        if ((pATI->LCDPanelID >= 0) && (pATI->Chip != ATI_CHIP_264LT))
        {
            outr(LCD_INDEX, pATI->LockData.lcd_index);
            if (!pATI->OptionBIOSDisplay && (pATI->Chip != ATI_CHIP_264XL))
                outr(SCRATCH_REG3, pATI->LockData.scratch_reg3);
        }
        if (pATI->Chip >= ATI_CHIP_264VTB)
        {
            outr(MPP_CONFIG, pATI->LockData.mpp_config);
            outr(MPP_STROBE_SEQ, pATI->LockData.mpp_strobe_seq);
            outr(TVO_CNTL, pATI->LockData.tvo_cntl);
            if (pATI->Chip >= ATI_CHIP_264GT2C)
            {
                outr(HW_DEBUG, pATI->LockData.hw_debug);
                if (pATI->Chip >= ATI_CHIP_264GTPRO)
                {
                    outr(I2C_CNTL_0, pATI->LockData.i2c_cntl_0);
                    outr(I2C_CNTL_1, pATI->LockData.i2c_cntl_1);
                }
            }
        }
    }
}

--- NEW FILE: atilock.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atilock.h,v 1.5 2003/01/01 19:16:32 tsi Exp $ */
/*
 * Copyright 1999 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATILOCK_H___
#define ___ATILOCK_H___ 1

#include "atipriv.h"
#include "atiproto.h"

extern void ATIUnlock FunctionPrototype((ATIPtr));
extern void ATILock   FunctionPrototype((ATIPtr));

#endif /* ___ATILOCK_H___ */

--- NEW FILE: atimach64.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64.c,v 1.52 2003/04/23 21:51:28 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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
[...1142 lines suppressed...]
                lcd_gen_ctrl = ATIMach64GetLCDReg(LCD_GEN_CNTL);
            }

            if (DPMSMode == DPMSModeOn)
                lcd_gen_ctrl |= LCD_ON;
            else
                lcd_gen_ctrl &= ~LCD_ON;

            if (pATI->Chip == ATI_CHIP_264LT)
                outr(LCD_GEN_CTRL, lcd_gen_ctrl);
            else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
                        (pATI->Chip == ATI_CHIP_264XL) ||
                        (pATI->Chip == ATI_CHIP_MOBILITY)) */
            {
                ATIMach64PutLCDReg(LCD_GEN_CNTL, lcd_gen_ctrl);
                outr(LCD_INDEX, lcd_index);
            }
        }
    }
}

--- NEW FILE: atimach64.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64.h,v 1.17 2003/04/23 21:51:28 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIMACH64_H___
#define ___ATIMACH64_H___ 1

#include "atipriv.h"
#include "atiproto.h"

extern void ATIMach64PreInit     FunctionPrototype((ScrnInfoPtr, ATIPtr,
                                                    ATIHWPtr));
extern void ATIMach64Save        FunctionPrototype((ATIPtr, ATIHWPtr));
extern void ATIMach64Calculate   FunctionPrototype((ATIPtr, ATIHWPtr,
                                                    DisplayModePtr));
extern void ATIMach64Set         FunctionPrototype((ATIPtr, ATIHWPtr));

extern void ATIMach64SaveScreen  FunctionPrototype((ATIPtr, int));
extern void ATIMach64SetDPMSMode FunctionPrototype((ScrnInfoPtr, ATIPtr, int));

#endif /* ___ATIMACH64_H___ */

--- NEW FILE: atimach64accel.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64accel.c,v 1.1 2003/04/23 21:51:28 tsi Exp $ */
/*
 * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */
/*
 * Copyright 1999-2000 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 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
 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

#include "ati.h"
#include "atichip.h"
#include "atimach64accel.h"
#include "atimach64io.h"
#include "atipriv.h"
#include "atiregs.h"

#include "miline.h"

/* Used to test MMIO cache integrity in ATIMach64Sync() */
#define TestRegisterCaching(_Register)                   \
    if (RegisterIsCached(_Register) &&                   \
        (CacheSlot(_Register) != inm(_Register)))        \
    {                                                    \
        UncacheRegister(_Register);                      \
        xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,    \
            #_Register " MMIO write cache disabled!\n"); \
    }

/*
 * X-to-Mach64 mix translation table.
 */
static CARD8 ATIMach64ALU[16] =
{
    MIX_0,                       /* GXclear */
    MIX_AND,                     /* GXand */
    MIX_SRC_AND_NOT_DST,         /* GXandReverse */
    MIX_SRC,                     /* GXcopy */
    MIX_NOT_SRC_AND_DST,         /* GXandInverted */
    MIX_DST,                     /* GXnoop */
    MIX_XOR,                     /* GXxor */
    MIX_OR,                      /* GXor */
    MIX_NOR,                     /* GXnor */
    MIX_XNOR,                    /* GXequiv */
    MIX_NOT_DST,                 /* GXinvert */
    MIX_SRC_OR_NOT_DST,          /* GXorReverse */
    MIX_NOT_SRC,                 /* GXcopyInverted */
    MIX_NOT_SRC_OR_DST,          /* GXorInverted */
    MIX_NAND,                    /* GXnand */
    MIX_1                        /* GXset */
};

/*
 * ATIMach64ValidateClip --
 *
 * This function ensures the current scissor settings do not interfere with
 * the current draw request.
 */
static void
ATIMach64ValidateClip
(
    ATIPtr pATI,
    int    sc_left,
    int    sc_right,
    int    sc_top,
    int    sc_bottom
)
{
    if ((sc_left < (int)pATI->sc_left) || (sc_right > (int)pATI->sc_right))
    {
        outf(SC_LEFT_RIGHT, pATI->sc_left_right);
        pATI->sc_left = pATI->NewHW.sc_left;
        pATI->sc_right = pATI->NewHW.sc_right;
    }

    if ((sc_top < (int)pATI->sc_top) || (sc_bottom > (int)pATI->sc_bottom))
    {
        outf(SC_TOP_BOTTOM, pATI->sc_top_bottom);
        pATI->sc_top = pATI->NewHW.sc_top;
        pATI->sc_bottom = pATI->NewHW.sc_bottom;
    }
}

/*
 * ATIMach64Sync --
 *
 * This is called to wait for the draw engine to become idle.
 */
void
ATIMach64Sync
(
    ScrnInfoPtr pScreenInfo
)
{
    ATIPtr pATI = ATIPTR(pScreenInfo);

    ATIMach64WaitForIdle(pATI);
    if (pATI->pXAAInfo)
        pATI->pXAAInfo->NeedToSync = FALSE;

    if (pATI->OptionMMIOCache && pATI->OptionTestMMIOCache)
    {
        /*
         * For debugging purposes, attempt to verify that each cached register
         * should actually be cached.
         */
        TestRegisterCaching(SRC_CNTL);

        TestRegisterCaching(HOST_CNTL);

        TestRegisterCaching(PAT_REG0);
        TestRegisterCaching(PAT_REG1);
        TestRegisterCaching(PAT_CNTL);

        if (RegisterIsCached(SC_LEFT_RIGHT) &&  /* Special case */
            (CacheSlot(SC_LEFT_RIGHT) !=
             (SetWord(inm(SC_RIGHT), 1) | SetWord(inm(SC_LEFT), 0))))
        {
            UncacheRegister(SC_LEFT_RIGHT);
            xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
                "SC_LEFT_RIGHT write cache disabled!\n");
        }

        if (RegisterIsCached(SC_TOP_BOTTOM) &&  /* Special case */
            (CacheSlot(SC_TOP_BOTTOM) !=
             (SetWord(inm(SC_BOTTOM), 1) | SetWord(inm(SC_TOP), 0))))
        {
            UncacheRegister(SC_TOP_BOTTOM);
            xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
                "SC_TOP_BOTTOM write cache disabled!\n");
        }

        TestRegisterCaching(DP_BKGD_CLR);
        TestRegisterCaching(DP_FRGD_CLR);
        TestRegisterCaching(DP_WRITE_MASK);
        TestRegisterCaching(DP_MIX);

        TestRegisterCaching(CLR_CMP_CLR);
        TestRegisterCaching(CLR_CMP_MSK);
        TestRegisterCaching(CLR_CMP_CNTL);

        if (pATI->Block1Base)
        {
            TestRegisterCaching(OVERLAY_Y_X_START);
            TestRegisterCaching(OVERLAY_Y_X_END);

            TestRegisterCaching(OVERLAY_GRAPHICS_KEY_CLR);
            TestRegisterCaching(OVERLAY_GRAPHICS_KEY_MSK);

            TestRegisterCaching(OVERLAY_KEY_CNTL);

            TestRegisterCaching(OVERLAY_SCALE_INC);
            TestRegisterCaching(OVERLAY_SCALE_CNTL);

            TestRegisterCaching(SCALER_HEIGHT_WIDTH);

            TestRegisterCaching(SCALER_TEST);

            TestRegisterCaching(VIDEO_FORMAT);

            if (pATI->Chip < ATI_CHIP_264VTB)
            {
                TestRegisterCaching(BUF0_OFFSET);
                TestRegisterCaching(BUF0_PITCH);
                TestRegisterCaching(BUF1_OFFSET);
                TestRegisterCaching(BUF1_PITCH);
            }
            else
            {
                TestRegisterCaching(SCALER_BUF0_OFFSET);
                TestRegisterCaching(SCALER_BUF1_OFFSET);
                TestRegisterCaching(SCALER_BUF_PITCH);

                TestRegisterCaching(OVERLAY_EXCLUSIVE_HORZ);
                TestRegisterCaching(OVERLAY_EXCLUSIVE_VERT);

                if (pATI->Chip >= ATI_CHIP_264GTPRO)
                {
                    TestRegisterCaching(SCALER_COLOUR_CNTL);

                    TestRegisterCaching(SCALER_H_COEFF0);
                    TestRegisterCaching(SCALER_H_COEFF1);
                    TestRegisterCaching(SCALER_H_COEFF2);
                    TestRegisterCaching(SCALER_H_COEFF3);
                    TestRegisterCaching(SCALER_H_COEFF4);

                    TestRegisterCaching(SCALER_BUF0_OFFSET_U);
                    TestRegisterCaching(SCALER_BUF0_OFFSET_V);
                    TestRegisterCaching(SCALER_BUF1_OFFSET_U);
                    TestRegisterCaching(SCALER_BUF1_OFFSET_V);
                }
            }
        }
    }

    /*
     * For VTB's and later, the first CPU read of the framebuffer will return
     * zeroes, so do it here.  This appears to be due to some kind of engine
     * caching of framebuffer data I haven't found any way of disabling, or
     * otherwise circumventing.  Thanks to Mark Vojkovich for the suggestion.
     */
    pATI = *(volatile ATIPtr *)pATI->pMemory;
}

/*
 * ATIMach64SetupForScreenToScreenCopy --
 *
 * This function sets up the draw engine for a series of screen-to-screen copy
 * operations.
 */
static void
ATIMach64SetupForScreenToScreenCopy
(
    ScrnInfoPtr  pScreenInfo,
    int          xdir,
    int          ydir,
    int          rop,
    unsigned int planemask,
    int          TransparencyColour
)
{
    ATIPtr pATI = ATIPTR(pScreenInfo);

    ATIMach64WaitForFIFO(pATI, 3);
    outf(DP_WRITE_MASK, planemask);
    outf(DP_SRC, DP_MONO_SRC_ALLONES |
        SetBits(SRC_BLIT, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC));
    outf(DP_MIX, SetBits(ATIMach64ALU[rop], DP_FRGD_MIX));

#ifdef AVOID_DGA

    if (TransparencyColour == -1)

#else /* AVOID_DGA */

    if (!pATI->XAAForceTransBlit && (TransparencyColour == -1))

#endif /* AVOID_DGA */

    {
        outf(CLR_CMP_CNTL, CLR_CMP_FN_FALSE);
    }
    else
    {
        ATIMach64WaitForFIFO(pATI, 2);
        outf(CLR_CMP_CLR, TransparencyColour);
        outf(CLR_CMP_CNTL, CLR_CMP_FN_EQUAL | CLR_CMP_SRC_2D);
    }

    pATI->dst_cntl = 0;

    if (ydir > 0)
        pATI->dst_cntl |= DST_Y_DIR;
    if (xdir > 0)
        pATI->dst_cntl |= DST_X_DIR;

    if (pATI->XModifier == 1)
        outf(DST_CNTL, pATI->dst_cntl);
    else
        pATI->dst_cntl |= DST_24_ROT_EN;
}

/*
 * ATIMach64SubsequentScreenToScreenCopy --
 *
 * This function performs a screen-to-screen copy operation.
 */
static void
ATIMach64SubsequentScreenToScreenCopy
(
    ScrnInfoPtr pScreenInfo,
    int         xSrc,
    int         ySrc,
    int         xDst,
    int         yDst,
    int         w,
    int         h
)
{
    ATIPtr pATI = ATIPTR(pScreenInfo);

    xSrc *= pATI->XModifier;
    xDst *= pATI->XModifier;
    w    *= pATI->XModifier;

    /* Disable clipping if it gets in the way */
    ATIMach64ValidateClip(pATI, xDst, xDst + w - 1, yDst, yDst + h - 1);

    if (!(pATI->dst_cntl & DST_X_DIR))
    {
        xSrc += w - 1;
        xDst += w - 1;
    }

    if (!(pATI->dst_cntl & DST_Y_DIR))
    {
        ySrc += h - 1;
        yDst += h - 1;
    }

    if (pATI->XModifier != 1)
        outf(DST_CNTL, pATI->dst_cntl | SetBits((xDst / 4) % 6, DST_24_ROT));

    ATIMach64WaitForFIFO(pATI, 4);
    outf(SRC_Y_X, SetWord(xSrc, 1) | SetWord(ySrc, 0));
    outf(SRC_WIDTH1, w);
    outf(DST_Y_X, SetWord(xDst, 1) | SetWord(yDst, 0));
    outf(DST_HEIGHT_WIDTH, SetWord(w, 1) | SetWord(h, 0));
}

/*
 * ATIMach64SetupForSolidFill --
 *
 * This function sets up the draw engine for a series of solid fills.
 */
static void
ATIMach64SetupForSolidFill
(
    ScrnInfoPtr  pScreenInfo,
    int          colour,
    int          rop,
    unsigned int planemask
)
{
    ATIPtr pATI = ATIPTR(pScreenInfo);

    ATIMach64WaitForFIFO(pATI, 5);
    outf(DP_WRITE_MASK, planemask);
    outf(DP_SRC, DP_MONO_SRC_ALLONES |
        SetBits(SRC_FRGD, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC));
    outf(DP_FRGD_CLR, colour);
    outf(DP_MIX, SetBits(ATIMach64ALU[rop], DP_FRGD_MIX));

    outf(CLR_CMP_CNTL, CLR_CMP_FN_FALSE);

    if (pATI->XModifier == 1)
        outf(DST_CNTL, DST_X_DIR | DST_Y_DIR);
}

/*
 * ATIMach64SubsequentSolidFillRect --
 *
 * This function performs a solid rectangle fill.
 */
static void
ATIMach64SubsequentSolidFillRect
(
    ScrnInfoPtr pScreenInfo,
    int         x,
    int         y,
    int         w,
    int         h
)
{
    ATIPtr pATI = ATIPTR(pScreenInfo);

    if (pATI->XModifier != 1)
    {
        x *= pATI->XModifier;
        w *= pATI->XModifier;

        outf(DST_CNTL, SetBits((x / 4) % 6, DST_24_ROT) |
            (DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN));
    }

    /* Disable clipping if it gets in the way */
    ATIMach64ValidateClip(pATI, x, x + w - 1, y, y + h - 1);

    ATIMach64WaitForFIFO(pATI, 2);
    outf(DST_Y_X, SetWord(x, 1) | SetWord(y, 0));
    outf(DST_HEIGHT_WIDTH, SetWord(w, 1) | SetWord(h, 0));
}

/*
 * ATIMach64SetupForSolidLine --
 *
 * This function sets up the draw engine for a series of solid lines.  It is
 * not used for 24bpp because the engine doesn't support it.
 */
static void
ATIMach64SetupForSolidLine
(
    ScrnInfoPtr  pScreenInfo,
    int          colour,
    int          rop,
    unsigned int planemask
)
{
    ATIPtr pATI = ATIPTR(pScreenInfo);

    ATIMach64WaitForFIFO(pATI, 5);
    outf(DP_WRITE_MASK, planemask);
    outf(DP_SRC, DP_MONO_SRC_ALLONES |
        SetBits(SRC_FRGD, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC));
    outf(DP_FRGD_CLR, colour);
    outf(DP_MIX, SetBits(ATIMach64ALU[rop], DP_FRGD_MIX));

    outf(CLR_CMP_CNTL, CLR_CMP_FN_FALSE);

    ATIMach64ValidateClip(pATI, pATI->NewHW.sc_left, pATI->NewHW.sc_right,
        pATI->NewHW.sc_top, pATI->NewHW.sc_bottom);
}

/*
 * ATIMach64SubsequentSolidHorVertLine --
 *
 * This is called to draw a solid horizontal or vertical line.  This does a
 * one-pixel wide solid fill.
 */
static void
ATIMach64SubsequentSolidHorVertLine
(
    ScrnInfoPtr pScreenInfo,
    int         x,
    int         y,
    int         len,
    int         dir
)
{
    ATIPtr pATI = ATIPTR(pScreenInfo);

    ATIMach64WaitForFIFO(pATI, 3);
    outf(DST_CNTL, DST_X_DIR | DST_Y_DIR);
    outf(DST_Y_X, SetWord(x, 1) | SetWord(y, 0));

    if (dir == DEGREES_0)
        outf(DST_HEIGHT_WIDTH, SetWord(len, 1) | SetWord(1, 0));
    else /* if (dir == DEGREES_270) */
        outf(DST_HEIGHT_WIDTH, SetWord(1, 1) | SetWord(len, 0));
}

/*
 * ATIMach64SubsequentSolidBresenhamLine --
 *
 * This function draws a line using the Bresenham line engine.
 */
static void
ATIMach64SubsequentSolidBresenhamLine
(
    ScrnInfoPtr pScreenInfo,
    int         x,
    int         y,
    int         major,
    int         minor,
    int         err,
    int         len,
    int         octant
)
{
    ATIPtr pATI = ATIPTR(pScreenInfo);
    CARD32 dst_cntl = DST_LAST_PEL;

    if (octant & YMAJOR)
        dst_cntl |= DST_Y_MAJOR;

    if (!(octant & XDECREASING))
        dst_cntl |= DST_X_DIR;

    if (!(octant & YDECREASING))
        dst_cntl |= DST_Y_DIR;

    ATIMach64WaitForFIFO(pATI, 6);
    outf(DST_CNTL, dst_cntl);
    outf(DST_Y_X, SetWord(x, 1) | SetWord(y, 0));
    outf(DST_BRES_ERR, minor + err);
    outf(DST_BRES_INC, minor);
    outf(DST_BRES_DEC, minor - major);
    outf(DST_BRES_LNTH, len);
}

/*
 * ATIMach64SetupForMono8x8PatternFill --
 *
 * This function sets up the draw engine for a series of 8x8 1bpp pattern
 * fills.
 */
static void
ATIMach64SetupForMono8x8PatternFill
(
    ScrnInfoPtr  pScreenInfo,
    int          patx,
    int          paty,
    int          fg,
    int          bg,
    int          rop,
    unsigned int planemask
)
{
    ATIPtr pATI = ATIPTR(pScreenInfo);

    ATIMach64WaitForFIFO(pATI, 3);
    outf(DP_WRITE_MASK, planemask);
    outf(DP_SRC, DP_MONO_SRC_PATTERN |
        SetBits(SRC_FRGD, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC));
    outf(DP_FRGD_CLR, fg);

    if (bg == -1)
    {
        outf(DP_MIX, SetBits(ATIMach64ALU[rop], DP_FRGD_MIX) |
            SetBits(MIX_DST, DP_BKGD_MIX));
    }
    else
    {
        ATIMach64WaitForFIFO(pATI, 2);
        outf(DP_BKGD_CLR, bg);
        outf(DP_MIX, SetBits(ATIMach64ALU[rop], DP_FRGD_MIX) |
            SetBits(ATIMach64ALU[rop], DP_BKGD_MIX));
    }

    ATIMach64WaitForFIFO(pATI, 4);
    outf(PAT_REG0, patx);
    outf(PAT_REG1, paty);
    outf(PAT_CNTL, PAT_MONO_EN);

    outf(CLR_CMP_CNTL, CLR_CMP_FN_FALSE);

    if (pATI->XModifier == 1)
        outf(DST_CNTL, DST_X_DIR | DST_Y_DIR);
}

/*
 * ATIMach64SubsequentMono8x8PatternFillRect --
 *
 * This function performs an 8x8 1bpp pattern fill.
 */
static void
ATIMach64SubsequentMono8x8PatternFillRect
(
    ScrnInfoPtr pScreenInfo,
    int         patx,
    int         paty,
    int         x,
    int         y,
    int         w,
    int         h
)
{
    ATIPtr pATI = ATIPTR(pScreenInfo);

    if (pATI->XModifier != 1)
    {
        x *= pATI->XModifier;
        w *= pATI->XModifier;

        outf(DST_CNTL, SetBits((x / 4) % 6, DST_24_ROT) |
            (DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN));
    }

    /* Disable clipping if it gets in the way */
    ATIMach64ValidateClip(pATI, x, x + w - 1, y, y + h - 1);

    ATIMach64WaitForFIFO(pATI, 2);
    outf(DST_Y_X, SetWord(x, 1) | SetWord(y, 0));
    outf(DST_HEIGHT_WIDTH, SetWord(w, 1) | SetWord(h, 0));
}

/*
 * ATIMach64SetupForScanlineCPUToScreenColorExpandFill --
 *
 * This function sets up the engine for a series of colour expansion fills.
 */
static void
ATIMach64SetupForScanlineCPUToScreenColorExpandFill
(
    ScrnInfoPtr  pScreenInfo,
    int          fg,
    int          bg,
    int          rop,
    unsigned int planemask
)
{
    ATIPtr pATI = ATIPTR(pScreenInfo);

    ATIMach64WaitForFIFO(pATI, 3);
    outf(DP_WRITE_MASK, planemask);
    outf(DP_SRC, DP_MONO_SRC_HOST |
        SetBits(SRC_FRGD, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC));
    outf(DP_FRGD_CLR, fg);

    if (bg == -1)
    {
        outf(DP_MIX, SetBits(ATIMach64ALU[rop], DP_FRGD_MIX) |
            SetBits(MIX_DST, DP_BKGD_MIX));
    }
    else
    {
        ATIMach64WaitForFIFO(pATI, 2);
        outf(DP_BKGD_CLR, bg);
        outf(DP_MIX, SetBits(ATIMach64ALU[rop], DP_FRGD_MIX) |
            SetBits(ATIMach64ALU[rop], DP_BKGD_MIX));
    }

    outf(CLR_CMP_CNTL, CLR_CMP_FN_FALSE);

    if (pATI->XModifier == 1)
        outf(DST_CNTL, DST_X_DIR | DST_Y_DIR);
}

/*
 * ATIMach64SubsequentScanlineCPUToScreenColorExpandFill --
 *
 * This function sets up the engine for a single colour expansion fill.
 */
static void
ATIMach64SubsequentScanlineCPUToScreenColorExpandFill
(
    ScrnInfoPtr pScreenInfo,
    int         x,
    int         y,
    int         w,
    int         h,
    int         skipleft
)
{
    ATIPtr pATI = ATIPTR(pScreenInfo);

    if (pATI->XModifier != 1)
    {
        x *= pATI->XModifier;
        w *= pATI->XModifier;
        skipleft *= pATI->XModifier;

        outf(DST_CNTL, SetBits((x / 4) % 6, DST_24_ROT) |
            (DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN));
    }

    pATI->ExpansionBitmapWidth = (w + 31) / 32;

    ATIMach64WaitForFIFO(pATI, 3);
    pATI->sc_left = x + skipleft;
    pATI->sc_right = x + w - 1;
    outf(SC_LEFT_RIGHT,
        SetWord(pATI->sc_right, 1) | SetWord(pATI->sc_left, 0));
    outf(DST_Y_X, SetWord(x, 1) | SetWord(y, 0));
    outf(DST_HEIGHT_WIDTH,
        SetWord(pATI->ExpansionBitmapWidth * 32, 1) | SetWord(h, 0));
}

/*
 * ATIMach64SubsequentColorExpandScanline --
 *
 * This function feeds a bitmap scanline to the engine for a colour expansion
 * fill.  This is written to do burst transfers for those platforms that can do
 * them, and to improve CPU/engine concurrency.
 */
static void
ATIMach64SubsequentColorExpandScanline
(
    ScrnInfoPtr pScreenInfo,
    int         iBuffer
)
{
    ATIPtr          pATI         = ATIPTR(pScreenInfo);
    CARD32          *pBitmapData = pATI->ExpansionBitmapScanlinePtr[iBuffer];
    int             w            = pATI->ExpansionBitmapWidth;
    int             nDWord;

    while (w > 0)
    {
        /*
         * Transfers are done in chunks of up to 64 bytes in length (32 on
         * earlier controllers).
         */
        nDWord = w;
        if (nDWord > pATI->nHostFIFOEntries)
            nDWord = pATI->nHostFIFOEntries;

        /* Make enough FIFO slots available */
        ATIMach64WaitForFIFO(pATI, nDWord);

        /*
         * Always start transfers on a chuck-sized boundary.  Note that
         * HOST_DATA_0 is actually on a 512-byte boundary, but *pBitmapData can
         * only be guaranteed to be on a chunk-sized boundary.
         *
         * Transfer current chunk.  With any luck, the compiler won't mangle
         * this too badly...
         */

#       if defined(ATIMove32)

        {
            ATIMove32(pATI->pHOST_DATA, pBitmapData, nDWord);
        }

#       else

        {
            volatile CARD32 *pDst;
            CARD32          *pSrc;
            unsigned int    iDWord;

            iDWord = 16 - nDWord;
            pDst = (volatile CARD32 *)pATI->pHOST_DATA - iDWord;
            pSrc = pBitmapData - iDWord;

            switch (iDWord)
            {
                case  0:  MMIO_MOVE32(pDst +  0, 0, *(pSrc +  0));
                case  1:  MMIO_MOVE32(pDst +  1, 0, *(pSrc +  1));
                case  2:  MMIO_MOVE32(pDst +  2, 0, *(pSrc +  2));
                case  3:  MMIO_MOVE32(pDst +  3, 0, *(pSrc +  3));
                case  4:  MMIO_MOVE32(pDst +  4, 0, *(pSrc +  4));
                case  5:  MMIO_MOVE32(pDst +  5, 0, *(pSrc +  5));
                case  6:  MMIO_MOVE32(pDst +  6, 0, *(pSrc +  6));
                case  7:  MMIO_MOVE32(pDst +  7, 0, *(pSrc +  7));
                case  8:  MMIO_MOVE32(pDst +  8, 0, *(pSrc +  8));
                case  9:  MMIO_MOVE32(pDst +  9, 0, *(pSrc +  9));
                case 10:  MMIO_MOVE32(pDst + 10, 0, *(pSrc + 10));
                case 11:  MMIO_MOVE32(pDst + 11, 0, *(pSrc + 11));
                case 12:  MMIO_MOVE32(pDst + 12, 0, *(pSrc + 12));
                case 13:  MMIO_MOVE32(pDst + 13, 0, *(pSrc + 13));
                case 14:  MMIO_MOVE32(pDst + 14, 0, *(pSrc + 14));
                case 15:  MMIO_MOVE32(pDst + 15, 0, *(pSrc + 15));

                default:    /* Muffle compiler */
                    break;
            }
        }

#       endif

        /* Step to next chunk */
        pBitmapData += nDWord;
        w -= nDWord;
        pATI->nAvailableFIFOEntries -= nDWord;
    }

    pATI->EngineIsBusy = TRUE;
}

/*
 * ATIMach64AccelInit --
 *
 * This function fills in structure fields needed for acceleration on Mach64
 * variants.
 */
int
ATIMach64AccelInit
(
    ATIPtr        pATI,
    XAAInfoRecPtr pXAAInfo
)
{
    /* This doesn't seem quite right... */
    if (pATI->XModifier == 1)
    {
        pXAAInfo->Flags = PIXMAP_CACHE | OFFSCREEN_PIXMAPS;

#ifndef AVOID_CPIO

        if (!pATI->BankInfo.BankSize)

#endif /* AVOID_CPIO */

        {
            pXAAInfo->Flags |= LINEAR_FRAMEBUFFER;
        }
    }

    /* Sync */
    pXAAInfo->Sync = ATIMach64Sync;

    /* Screen-to-screen copy */
    pXAAInfo->SetupForScreenToScreenCopy = ATIMach64SetupForScreenToScreenCopy;
    pXAAInfo->SubsequentScreenToScreenCopy =
        ATIMach64SubsequentScreenToScreenCopy;

    /* Solid fills */
    pXAAInfo->SetupForSolidFill = ATIMach64SetupForSolidFill;
    pXAAInfo->SubsequentSolidFillRect = ATIMach64SubsequentSolidFillRect;

    /* 8x8 mono pattern fills */
    pXAAInfo->Mono8x8PatternFillFlags =

#if X_BYTE_ORDER != X_LITTLE_ENDIAN

        BIT_ORDER_IN_BYTE_MSBFIRST |

#endif /* X_BYTE_ORDER */

        HARDWARE_PATTERN_PROGRAMMED_BITS | HARDWARE_PATTERN_SCREEN_ORIGIN;
    pXAAInfo->SetupForMono8x8PatternFill = ATIMach64SetupForMono8x8PatternFill;
    pXAAInfo->SubsequentMono8x8PatternFillRect =
        ATIMach64SubsequentMono8x8PatternFillRect;

    /*
     * Use scanline version of colour expansion, not only for the non-ix86
     * case, but also to avoid PCI retries.
     */
    pXAAInfo->ScanlineCPUToScreenColorExpandFillFlags =
        LEFT_EDGE_CLIPPING | LEFT_EDGE_CLIPPING_NEGATIVE_X |
        CPU_TRANSFER_PAD_DWORD | SCANLINE_PAD_DWORD;
    if (pATI->XModifier != 1)
        pXAAInfo->ScanlineCPUToScreenColorExpandFillFlags |= TRIPLE_BITS_24BPP;
    pXAAInfo->NumScanlineColorExpandBuffers = 1;

    /* Align bitmap data on a 64-byte boundary */
    pATI->ExpansionBitmapWidth =        /* DWord size in bits */
        ((pATI->displayWidth * pATI->XModifier) + 31) & ~31U;
    pATI->ExpansionBitmapScanlinePtr[1] =
        (CARD32 *)xnfalloc((pATI->ExpansionBitmapWidth >> 3) + 63);
    pATI->ExpansionBitmapScanlinePtr[0] =
        (pointer)(((unsigned long)pATI->ExpansionBitmapScanlinePtr[1] + 63) &
                  ~63UL);
    pXAAInfo->ScanlineColorExpandBuffers =
        (CARD8 **)pATI->ExpansionBitmapScanlinePtr;
    pXAAInfo->SetupForScanlineCPUToScreenColorExpandFill =
        ATIMach64SetupForScanlineCPUToScreenColorExpandFill;
    pXAAInfo->SubsequentScanlineCPUToScreenColorExpandFill =
        ATIMach64SubsequentScanlineCPUToScreenColorExpandFill;
    pXAAInfo->SubsequentColorExpandScanline =
        ATIMach64SubsequentColorExpandScanline;

    /* The engine does not support the following primitives for 24bpp */
    if (pATI->XModifier != 1)
        return ATIMach64MaxY;

    /* Solid lines */
    pXAAInfo->SetupForSolidLine = ATIMach64SetupForSolidLine;
    pXAAInfo->SubsequentSolidHorVertLine = ATIMach64SubsequentSolidHorVertLine;
    pXAAInfo->SubsequentSolidBresenhamLine =
        ATIMach64SubsequentSolidBresenhamLine;

    return ATIMach64MaxY;
}

--- NEW FILE: atimach64accel.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64accel.h,v 1.1 2003/04/23 21:51:29 tsi Exp $ */
/*
 * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIMACH64ACCEL_H___
#define ___ATIMACH64ACCEL_H___ 1

#include "atipriv.h"
#include "atiproto.h"

#include "xaa.h"

#define ATIMach64MaxX  8191
#define ATIMach64MaxY 32767

extern int  ATIMach64AccelInit FunctionPrototype((ATIPtr, XAAInfoRecPtr));
extern void ATIMach64Sync      FunctionPrototype((ScrnInfoPtr));

#endif /* ___ATIMACH64ACCEL_H___ */

--- NEW FILE: atimach64cursor.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64cursor.c,v 1.1 2003/04/23 21:51:29 tsi Exp $ */
/*
 * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

#include "ati.h"
#include "aticrtc.h"
#include "atimach64accel.h"
#include "atimach64cursor.h"
#include "atimach64io.h"

/*
 * ATIMach64SetCursorColours --
 *
 * Set hardware cursor foreground and background colours.
 */
static void
ATIMach64SetCursorColours
(
    ScrnInfoPtr pScreenInfo,
    int         fg,
    int         bg
)
{
    ATIPtr pATI = ATIPTR(pScreenInfo);

    outr(CUR_CLR0, SetBits(fg, CUR_CLR));
    outr(CUR_CLR1, SetBits(bg, CUR_CLR));
}

/*
 * ATIMach64SetCursorPosition --
 *
 * Set position of hardware cursor.
 */
static void
ATIMach64SetCursorPosition
(
    ScrnInfoPtr pScreenInfo,
    int         x,
    int         y
)
{
    ATIPtr pATI = ATIPTR(pScreenInfo);
    CARD16 CursorXOffset, CursorYOffset;

    /* Adjust x & y when the cursor is partially obscured */
    if (x < 0)
    {
        if ((CursorXOffset = -x) > 63)
            CursorXOffset = 63;
        x = 0;
    }
    else
    {
        CursorXOffset = pScreenInfo->frameX1 - pScreenInfo->frameX0;
        if (x > CursorXOffset)
            x = CursorXOffset;
        CursorXOffset = 0;
    }

    if (y < 0)
    {
        if ((CursorYOffset = -y) > 63)
            CursorYOffset = 63;
        y = 0;
    }
    else
    {
        CursorYOffset = pScreenInfo->frameY1 - pScreenInfo->frameY0;
        if (y > CursorYOffset)
            y = CursorYOffset;
        CursorYOffset = 0;
    }

    /* Adjust for multiscanned modes */
    if (pScreenInfo->currentMode->Flags & V_DBLSCAN)
        y *= 2;
    if (pScreenInfo->currentMode->VScan > 1)
        y *= pScreenInfo->currentMode->VScan;

    do
    {
        if (CursorYOffset != pATI->CursorYOffset)
        {
            pATI->CursorYOffset = CursorYOffset;
            outr(CUR_OFFSET, ((CursorYOffset << 4) + pATI->CursorOffset) >> 3);
        }
        else if (CursorXOffset == pATI->CursorXOffset)
            break;

        pATI->CursorXOffset = CursorXOffset;
        outr(CUR_HORZ_VERT_OFF, SetBits(CursorXOffset, CUR_HORZ_OFF) |
            SetBits(CursorYOffset, CUR_VERT_OFF));
    } while (0);

    outr(CUR_HORZ_VERT_POSN,
        SetBits(x, CUR_HORZ_POSN) | SetBits(y, CUR_VERT_POSN));
}

/*
 * ATIMach64LoadCursorImage --
 *
 * Copy hardware cursor image into offscreen video memory.
 */
static void
ATIMach64LoadCursorImage
(
    ScrnInfoPtr pScreenInfo,
    CARD8       *pImage
)
{
    ATIPtr           pATI     = ATIPTR(pScreenInfo);
    CARD32          *pSrc     = (pointer)pImage;
    volatile CARD32 *pDst     = pATI->pCursorImage;

    /* Synchronise video memory accesses */
    ATIMach64Sync(pScreenInfo);

#   if defined(ATIMove32)

    {
        ATIMove32(pDst, pSrc, 256);
    }

#   else

    {
        /* This is lengthy, but it does maximise burst modes */
        pDst[  0] = pSrc[  0];  pDst[  1] = pSrc[  1];
        pDst[  2] = pSrc[  2];  pDst[  3] = pSrc[  3];
        pDst[  4] = pSrc[  4];  pDst[  5] = pSrc[  5];
        pDst[  6] = pSrc[  6];  pDst[  7] = pSrc[  7];
        pDst[  8] = pSrc[  8];  pDst[  9] = pSrc[  9];
        pDst[ 10] = pSrc[ 10];  pDst[ 11] = pSrc[ 11];
        pDst[ 12] = pSrc[ 12];  pDst[ 13] = pSrc[ 13];
        pDst[ 14] = pSrc[ 14];  pDst[ 15] = pSrc[ 15];
        pDst[ 16] = pSrc[ 16];  pDst[ 17] = pSrc[ 17];
        pDst[ 18] = pSrc[ 18];  pDst[ 19] = pSrc[ 19];
        pDst[ 20] = pSrc[ 20];  pDst[ 21] = pSrc[ 21];
        pDst[ 22] = pSrc[ 22];  pDst[ 23] = pSrc[ 23];
        pDst[ 24] = pSrc[ 24];  pDst[ 25] = pSrc[ 25];
        pDst[ 26] = pSrc[ 26];  pDst[ 27] = pSrc[ 27];
        pDst[ 28] = pSrc[ 28];  pDst[ 29] = pSrc[ 29];
        pDst[ 30] = pSrc[ 30];  pDst[ 31] = pSrc[ 31];
        pDst[ 32] = pSrc[ 32];  pDst[ 33] = pSrc[ 33];
        pDst[ 34] = pSrc[ 34];  pDst[ 35] = pSrc[ 35];
        pDst[ 36] = pSrc[ 36];  pDst[ 37] = pSrc[ 37];
        pDst[ 38] = pSrc[ 38];  pDst[ 39] = pSrc[ 39];
        pDst[ 40] = pSrc[ 40];  pDst[ 41] = pSrc[ 41];
        pDst[ 42] = pSrc[ 42];  pDst[ 43] = pSrc[ 43];
        pDst[ 44] = pSrc[ 44];  pDst[ 45] = pSrc[ 45];
        pDst[ 46] = pSrc[ 46];  pDst[ 47] = pSrc[ 47];
        pDst[ 48] = pSrc[ 48];  pDst[ 49] = pSrc[ 49];
        pDst[ 50] = pSrc[ 50];  pDst[ 51] = pSrc[ 51];
        pDst[ 52] = pSrc[ 52];  pDst[ 53] = pSrc[ 53];
        pDst[ 54] = pSrc[ 54];  pDst[ 55] = pSrc[ 55];
        pDst[ 56] = pSrc[ 56];  pDst[ 57] = pSrc[ 57];
        pDst[ 58] = pSrc[ 58];  pDst[ 59] = pSrc[ 59];
        pDst[ 60] = pSrc[ 60];  pDst[ 61] = pSrc[ 61];
        pDst[ 62] = pSrc[ 62];  pDst[ 63] = pSrc[ 63];
        pDst[ 64] = pSrc[ 64];  pDst[ 65] = pSrc[ 65];
        pDst[ 66] = pSrc[ 66];  pDst[ 67] = pSrc[ 67];
        pDst[ 68] = pSrc[ 68];  pDst[ 69] = pSrc[ 69];
        pDst[ 70] = pSrc[ 70];  pDst[ 71] = pSrc[ 71];
        pDst[ 72] = pSrc[ 72];  pDst[ 73] = pSrc[ 73];
        pDst[ 74] = pSrc[ 74];  pDst[ 75] = pSrc[ 75];
        pDst[ 76] = pSrc[ 76];  pDst[ 77] = pSrc[ 77];
        pDst[ 78] = pSrc[ 78];  pDst[ 79] = pSrc[ 79];
        pDst[ 80] = pSrc[ 80];  pDst[ 81] = pSrc[ 81];
        pDst[ 82] = pSrc[ 82];  pDst[ 83] = pSrc[ 83];
        pDst[ 84] = pSrc[ 84];  pDst[ 85] = pSrc[ 85];
        pDst[ 86] = pSrc[ 86];  pDst[ 87] = pSrc[ 87];
        pDst[ 88] = pSrc[ 88];  pDst[ 89] = pSrc[ 89];
        pDst[ 90] = pSrc[ 90];  pDst[ 91] = pSrc[ 91];
        pDst[ 92] = pSrc[ 92];  pDst[ 93] = pSrc[ 93];
        pDst[ 94] = pSrc[ 94];  pDst[ 95] = pSrc[ 95];
        pDst[ 96] = pSrc[ 96];  pDst[ 97] = pSrc[ 97];
        pDst[ 98] = pSrc[ 98];  pDst[ 99] = pSrc[ 99];
        pDst[100] = pSrc[100];  pDst[101] = pSrc[101];
        pDst[102] = pSrc[102];  pDst[103] = pSrc[103];
        pDst[104] = pSrc[104];  pDst[105] = pSrc[105];
        pDst[106] = pSrc[106];  pDst[107] = pSrc[107];
        pDst[108] = pSrc[108];  pDst[109] = pSrc[109];
        pDst[110] = pSrc[110];  pDst[111] = pSrc[111];
        pDst[112] = pSrc[112];  pDst[113] = pSrc[113];
        pDst[114] = pSrc[114];  pDst[115] = pSrc[115];
        pDst[116] = pSrc[116];  pDst[117] = pSrc[117];
        pDst[118] = pSrc[118];  pDst[119] = pSrc[119];
        pDst[120] = pSrc[120];  pDst[121] = pSrc[121];
        pDst[122] = pSrc[122];  pDst[123] = pSrc[123];
        pDst[124] = pSrc[124];  pDst[125] = pSrc[125];
        pDst[126] = pSrc[126];  pDst[127] = pSrc[127];
        pDst[128] = pSrc[128];  pDst[129] = pSrc[129];
        pDst[130] = pSrc[130];  pDst[131] = pSrc[131];
        pDst[132] = pSrc[132];  pDst[133] = pSrc[133];
        pDst[134] = pSrc[134];  pDst[135] = pSrc[135];
        pDst[136] = pSrc[136];  pDst[137] = pSrc[137];
        pDst[138] = pSrc[138];  pDst[139] = pSrc[139];
        pDst[140] = pSrc[140];  pDst[141] = pSrc[141];
        pDst[142] = pSrc[142];  pDst[143] = pSrc[143];
        pDst[144] = pSrc[144];  pDst[145] = pSrc[145];
        pDst[146] = pSrc[146];  pDst[147] = pSrc[147];
        pDst[148] = pSrc[148];  pDst[149] = pSrc[149];
        pDst[150] = pSrc[150];  pDst[151] = pSrc[151];
        pDst[152] = pSrc[152];  pDst[153] = pSrc[153];
        pDst[154] = pSrc[154];  pDst[155] = pSrc[155];
        pDst[156] = pSrc[156];  pDst[157] = pSrc[157];
        pDst[158] = pSrc[158];  pDst[159] = pSrc[159];
        pDst[160] = pSrc[160];  pDst[161] = pSrc[161];
        pDst[162] = pSrc[162];  pDst[163] = pSrc[163];
        pDst[164] = pSrc[164];  pDst[165] = pSrc[165];
        pDst[166] = pSrc[166];  pDst[167] = pSrc[167];
        pDst[168] = pSrc[168];  pDst[169] = pSrc[169];
        pDst[170] = pSrc[170];  pDst[171] = pSrc[171];
        pDst[172] = pSrc[172];  pDst[173] = pSrc[173];
        pDst[174] = pSrc[174];  pDst[175] = pSrc[175];
        pDst[176] = pSrc[176];  pDst[177] = pSrc[177];
        pDst[178] = pSrc[178];  pDst[179] = pSrc[179];
        pDst[180] = pSrc[180];  pDst[181] = pSrc[181];
        pDst[182] = pSrc[182];  pDst[183] = pSrc[183];
        pDst[184] = pSrc[184];  pDst[185] = pSrc[185];
        pDst[186] = pSrc[186];  pDst[187] = pSrc[187];
        pDst[188] = pSrc[188];  pDst[189] = pSrc[189];
        pDst[190] = pSrc[190];  pDst[191] = pSrc[191];
        pDst[192] = pSrc[192];  pDst[193] = pSrc[193];
        pDst[194] = pSrc[194];  pDst[195] = pSrc[195];
        pDst[196] = pSrc[196];  pDst[197] = pSrc[197];
        pDst[198] = pSrc[198];  pDst[199] = pSrc[199];
        pDst[200] = pSrc[200];  pDst[201] = pSrc[201];
        pDst[202] = pSrc[202];  pDst[203] = pSrc[203];
        pDst[204] = pSrc[204];  pDst[205] = pSrc[205];
        pDst[206] = pSrc[206];  pDst[207] = pSrc[207];
        pDst[208] = pSrc[208];  pDst[209] = pSrc[209];
        pDst[210] = pSrc[210];  pDst[211] = pSrc[211];
        pDst[212] = pSrc[212];  pDst[213] = pSrc[213];
        pDst[214] = pSrc[214];  pDst[215] = pSrc[215];
        pDst[216] = pSrc[216];  pDst[217] = pSrc[217];
        pDst[218] = pSrc[218];  pDst[219] = pSrc[219];
        pDst[220] = pSrc[220];  pDst[221] = pSrc[221];
        pDst[222] = pSrc[222];  pDst[223] = pSrc[223];
        pDst[224] = pSrc[224];  pDst[225] = pSrc[225];
        pDst[226] = pSrc[226];  pDst[227] = pSrc[227];
        pDst[228] = pSrc[228];  pDst[229] = pSrc[229];
        pDst[230] = pSrc[230];  pDst[231] = pSrc[231];
        pDst[232] = pSrc[232];  pDst[233] = pSrc[233];
        pDst[234] = pSrc[234];  pDst[235] = pSrc[235];
        pDst[236] = pSrc[236];  pDst[237] = pSrc[237];
        pDst[238] = pSrc[238];  pDst[239] = pSrc[239];
        pDst[240] = pSrc[240];  pDst[241] = pSrc[241];
        pDst[242] = pSrc[242];  pDst[243] = pSrc[243];
        pDst[244] = pSrc[244];  pDst[245] = pSrc[245];
        pDst[246] = pSrc[246];  pDst[247] = pSrc[247];
        pDst[248] = pSrc[248];  pDst[249] = pSrc[249];
        pDst[250] = pSrc[250];  pDst[251] = pSrc[251];
        pDst[252] = pSrc[252];  pDst[253] = pSrc[253];
        pDst[254] = pSrc[254];  pDst[255] = pSrc[255];
    }

#endif

}

/*
 * ATIMach64HideCursor --
 *
 * Turn off hardware cursor.
 */
static void
ATIMach64HideCursor
(
    ScrnInfoPtr pScreenInfo
)
{
    ATIPtr pATI = ATIPTR(pScreenInfo);

    if (!(pATI->NewHW.gen_test_cntl & GEN_CUR_EN))
        return;

    pATI->NewHW.gen_test_cntl &= ~GEN_CUR_EN;
    out8(GEN_TEST_CNTL, GetByte(pATI->NewHW.gen_test_cntl, 0));
}

/*
 * ATIMach64ShowCursor --
 *
 * Turn on hardware cursor.
 */
static void
ATIMach64ShowCursor
(
    ScrnInfoPtr pScreenInfo
)
{
    ATIPtr pATI = ATIPTR(pScreenInfo);

    if (pATI->NewHW.gen_test_cntl & GEN_CUR_EN)
        return;

    pATI->NewHW.gen_test_cntl |= GEN_CUR_EN;
    out8(GEN_TEST_CNTL, GetByte(pATI->NewHW.gen_test_cntl, 0));
}

/*
 * ATIMach64UseHWCursor --
 *
 * Notify cursor layer whether a hardware cursor is configured.
 */
static Bool
ATIMach64UseHWCursor
(
    ScreenPtr pScreen,
    CursorPtr pCursor
)
{
    ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
    ATIPtr      pATI        = ATIPTR(pScreenInfo);

    if (!pATI->CursorBase)
        return FALSE;

#ifndef AVOID_CPIO

    /*
     * For some reason, the hardware cursor isn't vertically scaled when a VGA
     * doublescanned or multiscanned mode is in effect.
     */
    if (pATI->NewHW.crtc == ATI_CRTC_MACH64)
        return TRUE;
    if ((pScreenInfo->currentMode->Flags & V_DBLSCAN) ||
        (pScreenInfo->currentMode->VScan > 1))
        return FALSE;

#endif /* AVOID_CPIO */

    return TRUE;
}

/*
 * ATIMach64CursorInit --
 *
 * Initialise xf86CursorInfoRec fields with information specific to Mach64
 * variants.
 */
Bool
ATIMach64CursorInit
(
    xf86CursorInfoPtr pCursorInfo
)
{
    /*
     * For Mach64 variants, toggling hardware cursors off and on causes display
     * artifacts.  Ask the cursor support layers to always paint the cursor
     * (whether or not it is entirely transparent) and to not hide the cursor
     * when reloading its image.  The two remaining reasons for turning off the
     * hardware cursor are when it moves to a different screen or on a switch
     * to a different virtual console.
     */
    pCursorInfo->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
        HARDWARE_CURSOR_INVERT_MASK |
        HARDWARE_CURSOR_SHOW_TRANSPARENT |
        HARDWARE_CURSOR_UPDATE_UNHIDDEN |
        HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |

#if X_BYTE_ORDER != X_LITTLE_ENDIAN

        HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |

#endif /* X_BYTE_ORDER */

        HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1;
    pCursorInfo->MaxWidth = pCursorInfo->MaxHeight = 64;

    pCursorInfo->SetCursorColors = ATIMach64SetCursorColours;
    pCursorInfo->SetCursorPosition = ATIMach64SetCursorPosition;
    pCursorInfo->LoadCursorImage = ATIMach64LoadCursorImage;
    pCursorInfo->HideCursor = ATIMach64HideCursor;
    pCursorInfo->ShowCursor = ATIMach64ShowCursor;
    pCursorInfo->UseHWCursor = ATIMach64UseHWCursor;

    return TRUE;
}

--- NEW FILE: atimach64cursor.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64cursor.h,v 1.1 2003/04/23 21:51:29 tsi Exp $ */
/*
 * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIMACH64CURSOR_H___
#define ___ATIMACH64CURSOR_H___ 1

#include "atiproto.h"

#include "xf86Cursor.h"

extern Bool ATIMach64CursorInit FunctionPrototype((xf86CursorInfoPtr));

#endif /* ___ATIMACH64CURSOR_H___ */

--- NEW FILE: atimach64i2c.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64i2c.c,v 1.1 2003/07/24 22:08:28 tsi Exp $ */
/*
 * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

#include "ati.h"
#include "atichip.h"
#include "atii2c.h"
#include "atimach64i2c.h"
#include "atimach64io.h"
#include "atituner.h"

/* MPP_CONFIG register values */
#define MPP_INIT     pATI->NewHW.mpp_config

#define MPP_WRITE    (MPP_INIT                                               )
#define MPP_WRITEINC (MPP_INIT | (MPP_AUTO_INC_EN                           ))
#define MPP_READ     (MPP_INIT | (                  MPP_BUFFER_MODE_PREFETCH))
#define MPP_READINC  (MPP_INIT | (MPP_AUTO_INC_EN | MPP_BUFFER_MODE_PREFETCH))

/*
 * ATIMach64MPPWaitForIdle --
 *
 * Support function to wait for the Multimedia Peripheral Port to become idle.
 * Currently, this function's return value indicates whether or not the port
 * became idle within 512 polling iterations.  For now, this value is ignored
 * by the rest of the code, but might be used in the future.
 */
static Bool
ATIMach64MPPWaitForIdle
(
    ATIPtr pATI
)
{
    CARD32 Count = 0x0200;

    while (in8(MPP_CONFIG + 3) & GetByte(MPP_BUSY, 3))
    {
        if (!--Count)
            return FALSE;
        usleep(1);              /* XXX Excessive? */
    }

    return TRUE;
}

/*
 * ATIMach64MPPSetAddress --
 *
 * Sets a 16-bit ImpacTV address on the Multimedia Peripheral Port.
 */
static void
ATIMach64MPPSetAddress
(
    ATIPtr pATI,
    CARD16 Address
)
{
    ATIMach64MPPWaitForIdle(pATI);
    outr(MPP_CONFIG, MPP_WRITEINC);
    outr(MPP_ADDR, 0x00000008U);
    out8(MPP_DATA, (CARD8)Address);
    ATIMach64MPPWaitForIdle(pATI);
    out8(MPP_DATA, (CARD8)(Address >> 8));
    ATIMach64MPPWaitForIdle(pATI);
    outr(MPP_CONFIG, MPP_WRITE);
    outr(MPP_ADDR, 0x00000018U);
    ATIMach64MPPWaitForIdle(pATI);
}

/*
 * ATIMach64ImpacTVProbe --
 *
 * This probes for an ImpacTV chip and returns its chip ID, or 0.
 */
static int
ATIMach64ImpacTVProbe
(
    int    iScreen,
    ATIPtr pATI
)
{
    CARD8 ChipID = 0;

    /* Assume ATIModePreInit() has already been called */
    outr(MPP_STROBE_SEQ, pATI->NewHW.mpp_strobe_seq);
    outr(TVO_CNTL, pATI->NewHW.tvo_cntl);

    outr(MPP_CONFIG, MPP_READ);
    ATIMach64MPPWaitForIdle(pATI);
    outr(MPP_ADDR, 0x0000000AU);
    if (!(ChipID = in8(MPP_DATA)))
    {
         ATIMach64MPPWaitForIdle(pATI);
         outr(MPP_ADDR, 0x00000023U);
         if ((ChipID = in8(MPP_DATA)) != 0x54U)
         {
             ATIMach64MPPWaitForIdle(pATI);
             outr(MPP_ADDR, 0x0000000BU);
             ChipID = in8(MPP_DATA);
         }
    }
    ATIMach64MPPWaitForIdle(pATI);
    outr(MPP_CONFIG, MPP_WRITE);

    if (ChipID)
        xf86DrvMsg(iScreen, X_PROBED, "ImpacTV chip ID 0x%02X detected.\n",
            ChipID);

    return (int)(CARD16)ChipID;
}

/*
 * ATIMach64ImpacTVSetBits --
 *
 * Controls I2C SDA and SCL lines through ImpacTV.
 */
static void
ATIMach64ImpacTVSetBits
(
    ATII2CPtr pATII2C,
    ATIPtr    pATI,
    CARD32    Bits
)
{
    pATII2C->I2CCur = Bits;

    ATIMach64MPPSetAddress(pATI, IT_I2C_CNTL);

    outr(MPP_CONFIG, MPP_WRITE);

    out8(MPP_DATA, (CARD8)Bits);

    ATIMach64MPPWaitForIdle(pATI);
}

/*
 * ATIMach64ImpacTVGetBits --
 *
 * Returns the status of an ImpacTV's I2C control lines.
 */
static CARD32
ATIMach64ImpacTVGetBits
(
    ATIPtr    pATI
)
{
    ATIMach64MPPSetAddress(pATI, IT_I2C_CNTL);

    outr(MPP_CONFIG, MPP_READ);

    ATIMach64MPPWaitForIdle(pATI);

    return in8(MPP_DATA);
}

/*
 * ATIMach64I2C_CNTLSetBits --
 *
 * Controls SDA and SCL lines through a 3D Rage Pro's hardware assisted I2C.
 */
static void
ATIMach64I2C_CNTLSetBits
(
    ATII2CPtr pATII2C,
    ATIPtr    pATI,
    CARD32    Bits
)
{
    pATII2C->I2CCur = Bits;

    out8(I2C_CNTL_0 + 1, (CARD8)Bits);
}

/*
 * ATIMach64I2C_CNTLGetBits --
 *
 * Returns the status of a 3D Rage Pro's hardware assisted I2C control lines.
 */
static CARD32
ATIMach64I2C_CNTLGetBits
(
    ATIPtr    pATI
)
{
    return in8(I2C_CNTL_0 + 1);
}

/*
 * ATIMach64GP_IOSetBits --
 *
 * Controls SDA and SCL control lines through a Mach64's GP_IO register.
 */
static void
ATIMach64GP_IOSetBits
(
    ATII2CPtr pATII2C,
    ATIPtr    pATI,
    CARD32    Bits
)
{
    pATII2C->I2CCur = Bits;

    outr(GP_IO, Bits);
}

/*
 * ATIMach64GP_IOGetBits --
 *
 * Returns the status of I2C control lines through a Mach64's GP_IO register.
 */
static CARD32
ATIMach64GP_IOGetBits
(
    ATIPtr    pATI
)
{
    return inr(GP_IO);
}

#define GPIO1_MASK \
    (DAC_GIO_STATE_1 | DAC_GIO_DIR_1)
#define GPIO2_MASK \
    (GEN_GIO2_DATA_OUT | GEN_GIO2_DATA_IN | GEN_GIO2_WRITE)

/*
 * ATIMach64DAC_GENSetBits --
 *
 * Controls SDA and SCL control lines through a Mach64's GEN_TEST_CNTL and
 * DAC_CNTL registers.
 */
static void
ATIMach64DAC_GENSetBits
(
    ATII2CPtr pATII2C,
    ATIPtr    pATI,
    CARD32    Bits
)
{
    CARD32 tmp;

    pATII2C->I2CCur = Bits;

    tmp = inr(DAC_CNTL) & ~GPIO1_MASK;
    outr(DAC_CNTL, tmp | (Bits & GPIO1_MASK));
    tmp = inr(GEN_TEST_CNTL) & ~GPIO2_MASK;
    outr(GEN_TEST_CNTL, tmp | (Bits & GPIO2_MASK));
}

/*
 * ATIMach64DAC_GENGetBits --
 *
 * Returns the status of I2C control lines through a Mach64's GEN_TEST_CNTL and
 * DAC_CNTL registers.
 */
static CARD32
ATIMach64DAC_GENGetBits
(
    ATIPtr    pATI
)
{
    return (inr(DAC_CNTL) & GPIO1_MASK) | (inr(GEN_TEST_CNTL) & GPIO2_MASK);
}

/*
 * ATITVAddOnProbe --
 *
 * Probe for an ATI-TV add-on card at specific addresses on an I2C bus.
 */
static Bool
ATITVAddOnProbe
(
    ScrnInfoPtr pScreenInfo,
    ATIPtr      pATI,
    I2CBusPtr   pI2CBus
)
{
    I2CDevPtr pI2CDev = xnfcalloc(1, SizeOf(I2CDevRec));
    int       Index;
    I2CByte   tmp;

    static const CARD8 ATITVAddOnAddresses[] = {0x70, 0x40, 0x78, 0x72, 0x42};

    pI2CDev->DevName      = "ATI-TV Add-on";
    pI2CDev->pI2CBus      = pI2CBus;
    pI2CDev->StartTimeout = pI2CBus->StartTimeout;
    pI2CDev->BitTimeout   = pI2CBus->BitTimeout;
    pI2CDev->AcknTimeout  = pI2CBus->AcknTimeout;
    pI2CDev->ByteTimeout  = pI2CBus->ByteTimeout;

    for (Index = 0;  Index < NumberOf(ATITVAddOnAddresses);  Index++)
    {
        pI2CDev->SlaveAddr = ATITVAddOnAddresses[Index];

        if (xf86I2CFindDev(pI2CBus, pI2CDev->SlaveAddr))
            continue;

        tmp = 0xFFU;

        if (!(*pI2CBus->I2CWriteRead)(pI2CDev, &tmp, 1, NULL, 0) ||
            !(*pI2CBus->I2CWriteRead)(pI2CDev, NULL, 0, &tmp, 1) ||
            (tmp == 0xFFU) || ((tmp = tmp & 0x1FU) == /*ATI_TUNER_NONE*/0))
            continue;

        if (!xf86I2CDevInit(pI2CDev))
        {
            xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
                "Failed to register I2C device for ATI-TV add-on.\n");
            break;
        }

        if (pATI->Tuner != tmp)
        {
            if (pATI->Tuner != ATI_TUNER_NONE)
                xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
                    "Tuner type mismatch:  BIOS 0x%x, ATI-TV 0x%x.\n",
                    pATI->Tuner, tmp);

            pATI->Tuner = tmp;
        }

        xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
            "%s tuner detected on ATI-TV add-on adapter at I2C bus address"
            " 0x%2x.\n", ATITuners[pATI->Tuner].name, pI2CDev->SlaveAddr);

        return TRUE;
    }

    xfree(pI2CDev);
    return FALSE;
}

/*
 * ATIMach64I2CPreInit --
 *
 * This function potentially allocates an I2CBusRec and initialises it with
 * ATI-specific and Mach64-specific information.
 */
void
ATIMach64I2CPreInit
(
    ScrnInfoPtr pScreenInfo,
    ATIPtr      pATI
)
{
    I2CBusPtr pI2CBus;
    ATII2CPtr pATII2C;

    if ((pATI->Chip < ATI_CHIP_264CT) || (pATI->Chip >= ATI_CHIP_Mach64))
        return;

    /* Create an I2CBusRec and generically prime it */
    if (!(pI2CBus = ATICreateI2CBusRec(pScreenInfo->scrnIndex, pATI, "Mach64")))
        return;

    pATII2C = pI2CBus->DriverPrivate.ptr;

    switch (pATI->Chip)
    {
        case ATI_CHIP_264GTPRO:
        case ATI_CHIP_264LTPRO:
        case ATI_CHIP_264XL:
        case ATI_CHIP_MOBILITY:
            /*
             * These have I2C-specific registers.  Assume older I2C access
             * mechanisms are inoperative.
             */
            pATII2C->I2CSetBits = ATIMach64I2C_CNTLSetBits;
            pATII2C->I2CGetBits = ATIMach64I2C_CNTLGetBits;
            pATII2C->SCLDir = pATII2C->SDADir = 0;
            pATII2C->SCLGet = pATII2C->SCLSet = GetByte(I2C_CNTL_SCL, 1);
            pATII2C->SDAGet = pATII2C->SDASet = GetByte(I2C_CNTL_SDA, 1);

            out8(I2C_CNTL_1 + 2, GetByte(I2C_SEL, 2));
            out8(I2C_CNTL_0 + 0,
                GetByte(I2C_CNTL_STAT | I2C_CNTL_HPTR_RST, 0));
            break;

        case ATI_CHIP_264VTB:
        case ATI_CHIP_264GTB:
        case ATI_CHIP_264VT3:
        case ATI_CHIP_264GTDVD:
        case ATI_CHIP_264LT:
        case ATI_CHIP_264VT4:
        case ATI_CHIP_264GT2C:
            /* If an ImpacTV chip is found, use it to provide I2C access */
            if (ATIMach64ImpacTVProbe(pScreenInfo->scrnIndex, pATI))
            {
                pATII2C->I2CSetBits = ATIMach64ImpacTVSetBits;
                pATII2C->I2CGetBits = ATIMach64ImpacTVGetBits;
                pATII2C->SCLDir = IT_SCL_DIR;
                pATII2C->SCLGet = IT_SCL_GET;
                pATII2C->SCLSet = IT_SCL_SET;
                pATII2C->SDADir = IT_SDA_DIR;
                pATII2C->SDAGet = IT_SDA_GET;
                pATII2C->SDASet = IT_SDA_SET;

                ATIMach64MPPSetAddress(pATI, IT_I2C_CNTL);
                outr(MPP_CONFIG, MPP_WRITEINC);
                out8(MPP_DATA, 0x00U);
                out8(MPP_DATA, 0x55U);
                out8(MPP_DATA, 0x00U);
                out8(MPP_DATA, 0x00U);
                ATIMach64MPPWaitForIdle(pATI);
                break;
            }
            /* Otherwise, fall through to the older case */

        case ATI_CHIP_264VT:
        case ATI_CHIP_264GT:
            /* First try GIO pins 11 (clock) and 4 (data) */
            pATII2C->I2CSetBits = ATIMach64GP_IOSetBits;
            pATII2C->I2CGetBits = ATIMach64GP_IOGetBits;
            pATII2C->SCLDir = GP_IO_DIR_B;
            pATII2C->SCLGet = pATII2C->SCLSet = GP_IO_B;
            pATII2C->SDADir = GP_IO_DIR_4;
            pATII2C->SDAGet = pATII2C->SDASet = GP_IO_4;

            if (ATITVAddOnProbe(pScreenInfo, pATI, pI2CBus))
                break;

            /* Next, try pins 10 (clock) and 12 (data) */
            pATII2C->SCLDir = GP_IO_DIR_A;
            pATII2C->SCLGet = pATII2C->SCLSet = GP_IO_A;
            pATII2C->SDADir = GP_IO_DIR_C;
            pATII2C->SDAGet = pATII2C->SDASet = GP_IO_C;

            if (ATITVAddOnProbe(pScreenInfo, pATI, pI2CBus))
                break;
            /* Otherwise, fall back to ATI's first I2C implementation */

        default:
            /*
             * First generation integrated controllers access GIO pin 1 (clock)
             * though DAC_CNTL, and pin 2 (data) through GEN_TEST_CNTL.
             */
            pATII2C->I2CSetBits = ATIMach64DAC_GENSetBits;
            pATII2C->I2CGetBits = ATIMach64DAC_GENGetBits;
            pATII2C->SCLDir = DAC_GIO_DIR_1;
            pATII2C->SCLGet = pATII2C->SCLSet = DAC_GIO_STATE_1;
            pATII2C->SDADir = GEN_GIO2_WRITE;
            pATII2C->SDAGet = GEN_GIO2_DATA_IN;
            pATII2C->SDASet = GEN_GIO2_DATA_OUT;

            (void)ATITVAddOnProbe(pScreenInfo, pATI, pI2CBus);
            break;
    }
}

--- NEW FILE: atimach64i2c.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64i2c.h,v 1.1 2003/07/24 22:08:28 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIMACH64I2C_H___
#define ___ATIMACH64I2C_H___ 1

#include "atipriv.h"
#include "atiproto.h"

#include "xf86str.h"

extern void ATIMach64I2CPreInit FunctionPrototype((ScrnInfoPtr, ATIPtr));

#endif /* ___ATIMACH64I2C_H___ */

--- NEW FILE: atimach64io.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64io.c,v 1.6 2003/04/23 21:51:29 tsi Exp $ */
/*
 * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

#include "ati.h"
#include "atichip.h"
#include "atimach64io.h"

/*
 * ATIMach64AccessPLLReg --
 *
 * This function sets up the addressing required to access, for read or write,
 * a 264xT's PLL registers.
 */
void
ATIMach64AccessPLLReg
(
    ATIPtr      pATI,
    const CARD8 Index,
    const Bool  Write
)
{
    CARD8 clock_cntl1 = in8(CLOCK_CNTL + 1) &
        ~GetByte(PLL_WR_EN | PLL_ADDR, 1);

    /* Set PLL register to be read or written */
    out8(CLOCK_CNTL + 1, clock_cntl1 |
        GetByte(SetBits(Index, PLL_ADDR) | SetBits(Write, PLL_WR_EN), 1));
}

/*
 * ATIMach64PollEngineStatus --
 *
 * This function refreshes the driver's view of the draw engine's status.  This
 * has been moved into a separate compilation unit to prevent inlining.
 */
void
ATIMach64PollEngineStatus
(
    ATIPtr pATI
)
{
    CARD32 IOValue;
    int    Count;

    if (pATI->Chip < ATI_CHIP_264VTB)
    {
        /*
         * TODO:  Deal with locked engines.
         */
        IOValue = inm(FIFO_STAT);
        pATI->EngineIsLocked = GetBits(IOValue, FIFO_ERR);

        /*
         * The following counts the number of bits in FIFO_STAT_BITS, and is
         * derived from miSetVisualTypes() (formerly cfbSetVisualTypes()).
         */
        IOValue = GetBits(IOValue, FIFO_STAT_BITS);
        Count = (IOValue >> 1) & 0x36DBU;
        Count = IOValue - Count - ((Count >> 1) & 0x36DBU);
        Count = ((Count + (Count >> 3)) & 0x71C7U) % 0x3FU;
        Count = pATI->nFIFOEntries - Count;
        if (Count > pATI->nAvailableFIFOEntries)
            pATI->nAvailableFIFOEntries = Count;

        /*
         * If the command FIFO is non-empty, then the engine isn't idle.
         */
        if (pATI->nAvailableFIFOEntries < pATI->nFIFOEntries)
        {
            pATI->EngineIsBusy = TRUE;
            return;
        }
    }

    IOValue = inm(GUI_STAT);
    pATI->EngineIsBusy = GetBits(IOValue, GUI_ACTIVE);
    Count = GetBits(IOValue, GUI_FIFO);
    if (Count > pATI->nAvailableFIFOEntries)
        pATI->nAvailableFIFOEntries = Count;
}

--- NEW FILE: atimach64io.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64io.h,v 1.15 2003/04/23 21:51:29 tsi Exp $ */
/*
 * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIMACH64IO_H___

#if !defined(___ATI_H___) && defined(XFree86Module)
# error Missing #include "ati.h" before #include "atimach64io.h"
# undef XFree86Module
#endif

#define ___ATIMACH64IO_H___ 1

#include "atiio.h"
#include "atistruct.h"

/*
 * A few important notes on some of the I/O statements provided:
 *
 * inl/outl     32-bit R/W through PIO space.  The register is specified as the
 *              actual PIO address.  These are actually defined in compiler.h.
 *
 * inw/outw     16-bit counterparts to inl/outl.  Not used for Mach64 support.
 *
 * inb/outb     8-bit counterparts to inl/outl.
 *
 * inm/outm     32-bit R/W through MMIO space.  The register is specified as
 *              the actual MMIO offset (with Block 1 following Block 0), which,
 *              in this case, is equivalent to the register's IOPortTag from
 *              atiregs.h.  Can be used for those few non-FIFO'ed registers
 *              outside of Block 0's first 256 bytes.  inm() can also be used
 *              for FIFO'ed registers if, and only if, it can be guaranteed to
 *              not have been previously FIFO'ed (e.g. when the engine is
 *              idle).  pATI->pBlock array elements must have been previously
 *              set up by ATIMapApertures().
 *
 * outf         32-bit write through MMIO cache.  Identical to outm() but
 *              intended for FIFO'ed registers.  There is no inf() provided.
 *
 * inr/outr     32-bit R/W through PIO or MMIO.  Which one depends on the
 *              machine architecture.  The register is specified as a IOPortTag
 *              from atiregs.h.  Can only be used for registers in the first
 *              256 bytes of MMIO space (in Block 0).  Note that all of these
 *              registers are non-FIFO'ed.
 *
 * in8/out8     8-bit counterparts to inr/outr.
 *
 * For portability reasons, inr/outr/in8/out8 should be used in preference to
 * inl/outl/inb/outb to/from any register space starting with CRTC_H_TOTAL_DISP
 * but before DST_OFF_PITCH (in the order defined by atiregs.h).  None of
 * inm/outm/outf should ever be used for these registers.
 *
 * outf()'s should be grouped together as much as possible, while respecting
 * any ordering constraints the engine might impose.  Groups larger than 16
 * outf()'s should be split up into two or more groups as needed (but not
 * necessarily wanted).  The outf() groups that result should be immediately
 * preceeded by an ATIMach64WaitForFIFO(n) call, where "n" is the number of
 * outf()'s in the group with the exception that groups containing a single
 * outf() should not be thus preceeded.  This means "n" should not be less than
 * 2, nor larger than 16.
 */

/*
 * Cave canem (or it WILL bite you):  All Mach64 non-VGA registers are
 * ================================   little-endian, no matter how they are
 *                                    accessed (nor by what).
 */

#define inm(_Register)                                                   \
    MMIO_IN32(pATI->pBlock[GetBits(_Register, BLOCK_SELECT)],            \
              (_Register) & MM_IO_SELECT)
#define outm(_Register, _Value)                                          \
    MMIO_OUT32(pATI->pBlock[GetBits(_Register, BLOCK_SELECT)],           \
               (_Register) & MM_IO_SELECT, _Value)

#ifdef AVOID_CPIO

#   define inr(_Register) \
        MMIO_IN32(pATI->pBlock[0], (_Register) & MM_IO_SELECT)
#   define outr(_Register, _Value) \
        MMIO_OUT32(pATI->pBlock[0], (_Register) & MM_IO_SELECT, _Value)

#   define in8(_Register)                                                \
        MMIO_IN8(pATI->pBlock[0],                                        \
                 (_Register) & (MM_IO_SELECT | IO_BYTE_SELECT))
#   define out8(_Register, _Value)                                       \
        MMIO_OUT8(pATI->pBlock[0],                                       \
                  (_Register) & (MM_IO_SELECT | IO_BYTE_SELECT), _Value)

/* Cause a cpp syntax error if any of these are used */
#undef inb
#undef inw
#undef inl
#undef outb
#undef outw
#undef outl

#define inb()            /* Nothing */
#define inw()            /* Nothing */
#define inl()            /* Nothing */
#define outb()           /* Nothing */
#define outw()           /* Nothing */
#define outl()           /* Nothing */

#else /* AVOID_CPIO */

#   define ATIIOPort(_PortTag)                                 \
        (((pATI->CPIODecoding == SPARSE_IO) ?                  \
          ((_PortTag) & (SPARSE_IO_SELECT | IO_BYTE_SELECT)) : \
          ((_PortTag) & (BLOCK_IO_SELECT | IO_BYTE_SELECT))) | \
         pATI->CPIOBase)

#   define inr(_Register) \
        inl(ATIIOPort(_Register))
#   define outr(_Register, _Value) \
        outl(ATIIOPort(_Register), _Value)

#   define in8(_Register) \
        inb(ATIIOPort(_Register))
#   define out8(_Register, _Value) \
        outb(ATIIOPort(_Register), _Value)

#endif /* AVOID_CPIO */

extern void ATIMach64PollEngineStatus FunctionPrototype((ATIPtr));

/*
 * MMIO cache definitions.
 *
 * Many FIFO'ed registers can be cached by the driver.  Registers that qualify
 * for caching must not contain values that can change without driver
 * intervention.  Thus registers that contain hardware counters, strobe lines,
 * etc., cannot be cached.  This caching is intended to minimise FIFO use.
 * There is therefore not much point to enable it for non-FIFO'ed registers.
 *
 * The cache for a particular 32-bit register is enabled by coding a
 * CacheRegister() line for that register in the ATIMach64Set() function.  The
 * integrity of the cache for a particular register should be verified by the
 * ATIMach64Sync() function.  This code should be kept in register order, as
 * defined in atiregs.h.
 */
#define CacheByte(___Register) pATI->MMIOCached[CacheSlotOf(___Register) >> 3]
#define CacheBit(___Register)  (0x80U >> (CacheSlotOf(___Register) & 0x07U))

#define RegisterIsCached(__Register) \
    (CacheByte(__Register) & CacheBit(__Register))
#define CacheSlot(__Register) pATI->MMIOCache[CacheSlotOf(__Register)]

#define CacheRegister(__Register) \
    CacheByte(__Register) |= CacheBit(__Register)
#define UncacheRegister(__Register) \
    CacheByte(__Register) &= ~CacheBit(__Register)

/* This would be quite a bit slower as a function */
#define outf(_Register, _Value)                                        \
    do                                                                 \
    {                                                                  \
        CARD32 _IOValue = (_Value);                                    \
                                                                       \
        if (!RegisterIsCached(_Register) ||                            \
            (_IOValue != CacheSlot(_Register)))                        \
        {                                                              \
            while (!pATI->nAvailableFIFOEntries--)                     \
                ATIMach64PollEngineStatus(pATI);                       \
            MMIO_OUT32(pATI->pBlock[GetBits(_Register, BLOCK_SELECT)], \
                       (_Register) & MM_IO_SELECT, _IOValue);          \
            CacheSlot(_Register) = _IOValue;                           \
            pATI->EngineIsBusy = TRUE;                                 \
        }                                                              \
    } while (0)

/*
 * This is no longer as critical, especially for _n == 1.  However,
 * there is still a need to ensure _n <= pATI->nFIFOEntries.
 */
#define ATIMach64WaitForFIFO(_pATI, _n)           \
    while ((_pATI)->nAvailableFIFOEntries < (_n)) \
        ATIMach64PollEngineStatus(_pATI)

#define ATIMach64WaitForIdle(_pATI)         \
    while ((_pATI)->EngineIsBusy)           \
        ATIMach64PollEngineStatus(_pATI)

/*
 * An outf() variant to write two registers such that the second register is
 * is always written whenever either is to be changed.
 */
#define outq(_Register1, _Register2, _Value1, _Value2)                  \
    do                                                                  \
    {                                                                   \
        CARD32 _IOValue1 = (_Value1),                                   \
               _IOValue2 = (_Value2);                                   \
                                                                        \
        if (!RegisterIsCached(_Register1) ||                            \
            (_IOValue1 != CacheSlot(_Register1)))                       \
        {                                                               \
            ATIMach64WaitForFIFO(pATI, 2);                              \
            pATI->nAvailableFIFOEntries -= 2;                           \
            MMIO_OUT32(pATI->pBlock[GetBits(_Register1, BLOCK_SELECT)], \
                       (_Register1) & MM_IO_SELECT, _IOValue1);         \
            MMIO_OUT32(pATI->pBlock[GetBits(_Register2, BLOCK_SELECT)], \
                       (_Register2) & MM_IO_SELECT, _IOValue2);         \
            CacheSlot(_Register1) = _IOValue1;                          \
            CacheSlot(_Register2) = _IOValue2;                          \
            pATI->EngineIsBusy = TRUE;                                  \
        }                                                               \
        else if (!RegisterIsCached(_Register2) ||                       \
                 (_IOValue2 != CacheSlot(_Register2)))                  \
        {                                                               \
            while (!pATI->nAvailableFIFOEntries--)                      \
                ATIMach64PollEngineStatus(pATI);                        \
            MMIO_OUT32(pATI->pBlock[GetBits(_Register2, BLOCK_SELECT)], \
                       (_Register2) & MM_IO_SELECT, _IOValue2);         \
            CacheSlot(_Register2) = _IOValue2;                          \
            pATI->EngineIsBusy = TRUE;                                  \
        }                                                               \
    } while (0)

extern void ATIMach64AccessPLLReg FunctionPrototype((ATIPtr, const CARD8,
                                                     const Bool));

#define ATIMach64GetPLLReg(_Index)                  \
    (                                               \
        ATIMach64AccessPLLReg(pATI, _Index, FALSE), \
        in8(CLOCK_CNTL + 2)                         \
    )
#define ATIMach64PutPLLReg(_Index, _Value)          \
    do                                              \
    {                                               \
        ATIMach64AccessPLLReg(pATI, _Index, TRUE);  \
        out8(CLOCK_CNTL + 2, _Value);               \
    } while (0)

#define ATIMach64GetLCDReg(_Index)                       \
    (                                                    \
        out8(LCD_INDEX, SetBits(_Index, LCD_REG_INDEX)), \
        inr(LCD_DATA)                                    \
    )
#define ATIMach64PutLCDReg(_Index, _Value)               \
    do                                                   \
    {                                                    \
        out8(LCD_INDEX, SetBits(_Index, LCD_REG_INDEX)); \
        outr(LCD_DATA, _Value);                          \
    } while (0)

#define ATIMach64GetTVReg(_Index)                          \
    (                                                      \
        out8(TV_OUT_INDEX, SetBits(_Index, TV_REG_INDEX)), \
        inr(TV_OUT_DATA)                                   \
    )
#define ATIMach64PutTVReg(_Index, _Value)                  \
    do                                                     \
    {                                                      \
        out8(TV_OUT_INDEX, SetBits(_Index, TV_REG_INDEX)); \
        outr(TV_OUT_DATA, _Value);                         \
    } while (0)

/*
 * Block transfer definitions.
 */

#if defined(GCCUSESGAS) && \
    (defined(i386) || defined(__i386) || defined(__i386__))

#define ATIMove32(_pDst, _pSrc, _nCount) \
    do                                   \
    {                                    \
        long d0, d1, d2;                 \
        __asm__ __volatile__             \
        (                                \
            "cld\n\t"                    \
            "rep ; movsl"                \
            : "=&c" (d0),                \
              "=&D" (d1),                \
              "=&S" (d2)                 \
            : "0" (_nCount),             \
              "1" (_pDst),               \
              "2" (_pSrc)                \
            : "memory"                   \
        );                               \
    } while (0)

#endif

#endif /* ___ATIMACH64IO_H___ */

--- NEW FILE: atimach64xv.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64xv.c,v 1.7 2003/11/10 18:22:18 tsi Exp $ */
/*
 * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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
[...1454 lines suppressed...]
}

/*
 * ATIMach64CloseXVideo --
 *
 * This function is called during screen termination to clean up after
 * initialisation of Mach64 XVideo support.
 */
void
ATIMach64CloseXVideo
(
    ScreenPtr   pScreen,
    ScrnInfoPtr pScreenInfo,
    ATIPtr      pATI
)
{
    ATIMach64StopVideo(pScreenInfo, pATI, TRUE);

    REGION_UNINIT(pScreen, &pATI->VideoClip);
}

--- NEW FILE: atimach64xv.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64xv.h,v 1.1 2003/04/23 21:51:29 tsi Exp $ */
/*
 * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIMACH64XV_H___
#define ___ATIMACH64XV_H___ 1

#include "atipriv.h"
#include "atiproto.h"

#include "xf86str.h"
#include "xf86xv.h"

extern int  ATIMach64XVInitialiseAdaptor
            FunctionPrototype((ScreenPtr, ScrnInfoPtr, ATIPtr,
                              XF86VideoAdaptorPtr **));

extern void ATIMach64CloseXVideo
            FunctionPrototype((ScreenPtr, ScrnInfoPtr, ATIPtr));

#endif /* ___ATIMACH64XV_H___ */

--- NEW FILE: atimisc.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimisc.c,v 1.8tsi Exp $ */
/*
 * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 "atiload.h"
#include "ativersion.h"

/* Module loader interface for subsidiary driver module */

static XF86ModuleVersionInfo ATIVersionRec =
{
    "atimisc",
    MODULEVENDORSTRING,
    MODINFOSTRING1,
    MODINFOSTRING2,
    XORG_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())
        {
            if (!LoaderSymbol(ATI_NAME))
                xf86LoadOneModule(ATI_DRIVER_NAME, Options);

            /* ati & atimisc module versions must match */
            do
            {
                XF86ModuleData *pModuleData = LoaderSymbol("atiModuleData");

                if (pModuleData)
                {
                    XF86ModuleVersionInfo *pModuleInfo = pModuleData->vers;

                    if ((pModuleInfo->majorversion == ATI_VERSION_MAJOR) &&
                        (pModuleInfo->minorversion == ATI_VERSION_MINOR) &&
                        (pModuleInfo->patchlevel == ATI_VERSION_PATCH))
                        break;
                }

                xf86Msg(X_ERROR,
                        "\"ati\" and \"atimisc\" module versions must"
                        " match.\n");

                if (ErrorMajor)
                    *ErrorMajor = (int)LDR_MISMATCH;
                if (ErrorMinor)
                    *ErrorMinor = (int)LDR_MISMATCH;

                return NULL;
            } while (0);
        }

        /*
         * Tell loader about symbols from other modules that this module might
         * refer to.
         */
        xf86LoaderRefSymLists(
            ATIint10Symbols,
            ATIddcSymbols,
            ATIvbeSymbols,

#ifndef AVOID_CPIO

            ATIxf1bppSymbols,
            ATIxf4bppSymbols,

#endif /* AVOID_CPIO */

            ATIfbSymbols,
            ATIshadowfbSymbols,
            ATIxaaSymbols,
            ATIramdacSymbols,
            ATIi2cSymbols,
            NULL);

        Inited = TRUE;
    }

    return (pointer)TRUE;
}

/* The following record must be called atimiscModuleData */
XF86ModuleData atimiscModuleData =
{
    &ATIVersionRec,
    ATISetup,
    NULL
};

#endif /* XFree86LOADER */

--- NEW FILE: atimode.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimode.c,v 1.18 2004/01/05 16:42:03 tsi Exp $ */
/*
 * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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
[...1145 lines suppressed...]
    pATI->CursorXOffset = pATI->CursorYOffset = (CARD16)(-1);

#ifndef AVOID_CPIO

    /* Restore video memory */
    ATISwap(pScreenInfo->scrnIndex, pATI, pATIHW, TRUE);

    if (pATI->VGAAdapter != ATI_ADAPTER_NONE)
        ATIVGASaveScreen(pATI, SCREEN_SAVER_OFF);       /* Turn on screen */

#endif /* AVOID_CPIO */

    if ((xf86GetVerbosity() > 3) && (pATIHW == &pATI->NewHW))
    {
        xf86ErrorFVerb(4, "\n After setting mode \"%s\":\n\n",
            pScreenInfo->currentMode->name);
        ATIPrintMode(pScreenInfo->currentMode);
        ATIPrintRegisters(pATI);
    }
}

--- NEW FILE: atimode.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimode.h,v 1.5 2003/01/01 19:16:32 tsi Exp $ */
/*
 * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIMODE_H___
#define ___ATIMODE_H___ 1

#include "atipriv.h"
#include "atiproto.h"

#include "xf86str.h"

extern void ATIModePreInit   FunctionPrototype((ScrnInfoPtr, ATIPtr,
                                                ATIHWPtr));
extern void ATIModeSave      FunctionPrototype((ScrnInfoPtr, ATIPtr,
                                                ATIHWPtr));
extern Bool ATIModeCalculate FunctionPrototype((int, ATIPtr, ATIHWPtr,
                                                DisplayModePtr));
extern void ATIModeSet       FunctionPrototype((ScrnInfoPtr, ATIPtr,
                                                ATIHWPtr));

#endif /* ___ATIMODE_H___ */

--- NEW FILE: atimodule.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimodule.c,v 1.16 2003/05/28 14:08:03 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 "atimodule.h"
#include "ativersion.h"

/* Module loader interface */

const char *ATISymbols[] =
{
    "ATIPreInit",
    "ATIScreenInit",
    "ATISwitchMode",
    "ATIAdjustFrame",
    "ATIEnterVT",
    "ATILeaveVT",
    "ATIFreeScreen",
    "ATIValidMode",
    NULL
};

const char *R128Symbols[] =
{
    "R128PreInit",
    "R128ScreenInit",
    "R128SwitchMode",
    "R128AdjustFrame",
    "R128EnterVT",
    "R128LeaveVT",
    "R128FreeScreen",
    "R128ValidMode",
    "R128Options",
    NULL
};

const char *RADEONSymbols[] =
{
    "RADEONPreInit",
    "RADEONScreenInit",
    "RADEONSwitchMode",
    "RADEONAdjustFrame",
    "RADEONEnterVT",
    "RADEONLeaveVT",
    "RADEONFreeScreen",
    "RADEONValidMode",
    "RADEONOptions",
    "RADEONHandleMessage",
    NULL
};

static XF86ModuleVersionInfo ATIVersionRec =
{
    ATI_DRIVER_NAME,
    MODULEVENDORSTRING,
    MODINFOSTRING1,
    MODINFOSTRING2,
    XORG_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)
    {
        Inited = TRUE;
        xf86AddDriver(&ATI, Module, 0);

        xf86LoaderRefSymLists(
            ATISymbols,
            R128Symbols,
            RADEONSymbols,
            NULL);
    }

    return (pointer)1;
}

/* The following record must be called atiModuleData */
XF86ModuleData atiModuleData =
{
    &ATIVersionRec,
    ATISetup,
    NULL
};

#endif /* XFree86LOADER */

--- NEW FILE: atimodule.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimodule.h,v 1.9 2003/01/01 19:16:32 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

#if defined(XFree86LOADER) && !defined(___ATIMODULE_H___)
#define ___ATIMODULE_H___ 1

extern const char *ATISymbols[];
extern const char *R128Symbols[];
extern const char *RADEONSymbols[];

#endif /* ___ATIMODULE_H___ */

--- NEW FILE: atimono.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimono.h,v 1.7 2003/01/01 19:16:33 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIMONO_H___
#define ___ATIMONO_H___ 1

#ifndef BIT_PLANE
#   define BIT_PLANE 3
#endif

#ifndef MONO_BLACK
#   define MONO_BLACK 0x00U
#endif

#ifndef MONO_WHITE
#   define MONO_WHITE 0x3FU
#endif

#ifndef MONO_OVERSCAN
#   define MONO_OVERSCAN 0x01U
#endif

#endif /* ___ATIMONO_H___ */

--- NEW FILE: atioption.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atioption.c,v 1.22 2003/04/23 21:51:29 tsi Exp $ */
/*
 * Copyright 1999 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

#include "atioption.h"
#include "atiutil.h"

#include "radeon_probe.h"
#include "r128_probe.h"

/*
 * Recognised XF86Config options.
 */
const OptionInfoRec ATIPublicOptions[] =
{
    {
        ATI_OPTION_ACCEL,
        "accel",
        OPTV_BOOLEAN,
        {0, },
        FALSE
    },
    {
        ATI_OPTION_CRT_DISPLAY,
        "crt_display",
        OPTV_BOOLEAN,
        {0, },
        FALSE
    },
    {
        ATI_OPTION_CSYNC,
        "composite_sync",
        OPTV_BOOLEAN,
        {0, },
        FALSE
    },
    {
        ATI_OPTION_HWCURSOR,
        "hw_cursor",
        OPTV_BOOLEAN,
        {0, },
        FALSE,
    },

#ifndef AVOID_CPIO

    {
        ATI_OPTION_LINEAR,
        "linear",
        OPTV_BOOLEAN,
        {0, },
        FALSE
    },

#endif /* AVOID_CPIO */

    {
        ATI_OPTION_MMIO_CACHE,
        "mmio_cache",
        OPTV_BOOLEAN,
        {0, },
        FALSE
    },
    {
        ATI_OPTION_TEST_MMIO_CACHE,
        "test_mmio_cache",
        OPTV_BOOLEAN,
        {0, },
        FALSE
    },
    {
        ATI_OPTION_PANEL_DISPLAY,
        "panel_display",
        OPTV_BOOLEAN,
        {0, },
        FALSE
    },
    {
        ATI_OPTION_PROBE_CLOCKS,
        "probe_clocks",
        OPTV_BOOLEAN,
        {0, },
        FALSE
    },
    {
        ATI_OPTION_REFERENCE_CLOCK,
        "reference_clock",
        OPTV_FREQ,
        {0, },
        FALSE
    },
    {
        ATI_OPTION_SHADOW_FB,
        "shadow_fb",
        OPTV_BOOLEAN,
        {0, },
        FALSE
    },
    {
        ATI_OPTION_SWCURSOR,
        "sw_cursor",
        OPTV_BOOLEAN,
        {0, },
        FALSE,
    },
    {
        -1,
        NULL,
        OPTV_NONE,
        {0, },
        FALSE
    }
};

const unsigned long ATIPublicOptionSize = SizeOf(ATIPublicOptions);

/*
 * ATIAvailableOptions --
 *
 * Return recognised options that are intended for public consumption.
 */
const OptionInfoRec *
ATIAvailableOptions
(
    int ChipId,
    int BusId
)
{
    const OptionInfoRec *pOptions;

    if ((pOptions = R128AvailableOptions(ChipId, BusId)))
        return pOptions;

    if ((pOptions = RADEONAvailableOptions(ChipId, BusId)))
        return pOptions;

    return ATIPublicOptions;
}

--- NEW FILE: atioption.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atioption.h,v 1.12 2003/04/23 21:51:29 tsi Exp $ */
/*
 * Copyright 1999 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIOPTION_H___
#define ___ATIOPTION_H___ 1

#include "atiproto.h"

#include "xf86str.h"

/*
 * Documented XF86Config options.
 */
typedef enum
{
    ATI_OPTION_ACCEL,
    ATI_OPTION_CRT_DISPLAY,
    ATI_OPTION_CSYNC,
    ATI_OPTION_HWCURSOR,

#ifndef AVOID_CPIO

    ATI_OPTION_LINEAR,

#endif /* AVOID_CPIO */

    ATI_OPTION_MMIO_CACHE,
    ATI_OPTION_TEST_MMIO_CACHE,
    ATI_OPTION_PANEL_DISPLAY,
    ATI_OPTION_PROBE_CLOCKS,
    ATI_OPTION_REFERENCE_CLOCK,
    ATI_OPTION_SHADOW_FB,
    ATI_OPTION_SWCURSOR
} ATIPublicOptionType;

extern const OptionInfoRec   ATIPublicOptions[];
extern const unsigned long   ATIPublicOptionSize;

extern const OptionInfoRec * ATIAvailableOptions FunctionPrototype((int, int));

#endif /* ___ATIOPTION_H___ */

--- NEW FILE: atipreinit.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atipreinit.c,v 1.74 2003/12/22 17:48:09 tsi Exp $ */
/*
 * Copyright 1999 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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
[...3445 lines suppressed...]
    } while ((pMode = pMode->next) != pScreenInfo->modes);

    /* Initialise XVideo extension support */
    ATIXVPreInit(pATI);

    /* Initialise CRTC code */
    ATIModePreInit(pScreenInfo, pATI, &pATI->NewHW);

    /* Set up for I2C */
    ATII2CPreInit(pScreenInfo, pATI);

    if (!pScreenInfo->chipset || !*pScreenInfo->chipset)
        pScreenInfo->chipset = (char *)ATIChipsetNames[0];

    ATILock(pATI);
    ATIPrintNoiseIfRequested(pATI, BIOS, BIOSSize);
    ATIUnmapApertures(pScreenInfo->scrnIndex, pATI);

    return TRUE;
}

--- NEW FILE: atipreinit.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atipreinit.h,v 1.6 2003/01/01 19:16:33 tsi Exp $ */
/*
 * Copyright 1999 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIPREINIT_H___
#define ___ATIPREINIT_H___ 1

#include "atiproto.h"

#include "xf86str.h"

extern Bool ATIPreInit FunctionPrototype((ScrnInfoPtr, int));

#endif /* ___ATIPREINIT_H___ */

--- NEW FILE: atiprint.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiprint.c,v 1.28 2003/11/07 13:45:26 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

#include "ati.h"
#include "atiadapter.h"
#include "atichip.h"
#include "atidac.h"
#include "atimach64io.h"
#include "atiprint.h"
#include "atiwonderio.h"

/*
 * ATIPrintBIOS --
 *
 * Display various parts of the BIOS when the server is invoked with -verbose.
 */
void
ATIPrintBIOS
(
    const CARD8        *BIOS,
    const unsigned int Length   /* A multiple of 512 */
)
{
    unsigned char *Char = NULL;
    unsigned int  Index;
    unsigned char Printable[17];

    if (xf86GetVerbosity() <= 4)
        return;

    (void)memset(Printable, 0, SizeOf(Printable));

    xf86ErrorFVerb(5, "\n BIOS image:");

    for (Index = 0;  Index < Length;  Index++)
    {
        if (!(Index & (4U - 1U)))
        {
            if (!(Index & (16U - 1U)))
            {
                if (Printable[0])
                    xf86ErrorFVerb(5, "  |%s|", Printable);
                Char = Printable;
                xf86ErrorFVerb(5, "\n 0x%08X: ", Index);
            }
            xf86ErrorFVerb(5, " ");
        }
        xf86ErrorFVerb(5, "%02X", BIOS[Index]);
        if (isprint(BIOS[Index]))
            *Char++ = BIOS[Index];
        else
            *Char++ = '.';
    }

    xf86ErrorFVerb(5, "  |%s|\n", Printable);
}

#ifndef AVOID_CPIO

/*
 * ATIPrintIndexedRegisters --
 *
 * Display a set of indexed byte-size registers when the server is invoked with
 * -verbose.
 */
static void
ATIPrintIndexedRegisters
(
    const IOADDRESS Port,
    const CARD8     StartIndex,
    const CARD8     EndIndex,
    const char      *Name,
    const IOADDRESS GenS1
)
{
    int Index;

    xf86ErrorFVerb(4, "\n %s register values:", Name);
    for (Index = StartIndex;  Index < EndIndex;  Index++)
    {
        if (!(Index & (4U - 1U)))
        {
            if (!(Index & (16U - 1U)))
                xf86ErrorFVerb(4, "\n 0x%02X: ", Index);
            xf86ErrorFVerb(4, " ");
        }
        if (Port == ATTRX)
            (void)inb(GenS1);           /* Reset flip-flop */
        xf86ErrorFVerb(4, "%02X", GetReg(Port, Index));
    }

    if (Port == ATTRX)
    {
        (void)inb(GenS1);               /* Reset flip-flop */
        outb(ATTRX, 0x20U);             /* Turn on PAS bit */
    }

    xf86ErrorFVerb(4, "\n");
}

#endif /* AVOID_CPIO */

/*
 * ATIMach64PrintRegisters --
 *
 * Display a Mach64's main register bank when the server is invoked with
 * -verbose.
 */
static void
ATIMach64PrintRegisters
(
    ATIPtr     pATI,
    CARD8      *crtc,
    const char *Description
)
{
    CARD32 IOValue;
    CARD8 dac_read, dac_mask, dac_data, dac_write;
    int Index, Limit;

#ifndef AVOID_CPIO

    int Step;

#endif /* AVOID_CPIO */

    xf86ErrorFVerb(4, "\n Mach64 %s register values:", Description);

#ifdef AVOID_CPIO

    if (pATI->pBlock[1])
        Limit = DWORD_SELECT;
    else
        Limit = MM_IO_SELECT;

    for (Index = 0;  Index <= Limit;  Index += UnitOf(MM_IO_SELECT))
    {
        if (!(Index & SetBits(3, MM_IO_SELECT)))
            xf86ErrorFVerb(4, "\n 0x%04X: ", Index);
        if (Index == (DAC_REGS & DWORD_SELECT))
        {
            dac_read = in8(DAC_REGS + 3);
            DACDelay;
            dac_mask = in8(DAC_REGS + 2);
            DACDelay;
            dac_data = in8(DAC_REGS + 1);
            DACDelay;
            dac_write = in8(DAC_REGS + 0);
            DACDelay;

            xf86ErrorFVerb(4, " %02X%02X%02X%02X",
                dac_read, dac_mask, dac_data, dac_write);

            out8(DAC_REGS + 2, dac_mask);
            DACDelay;
            out8(DAC_REGS + 3, dac_read);
            DACDelay;
        }
        else
        {
            IOValue = inm(Index);

            if ((Index == (CRTC_GEN_CNTL & DWORD_SELECT)) &&
                (IOValue & CRTC_EXT_DISP_EN))
                *crtc = ATI_CRTC_MACH64;

            xf86ErrorFVerb(4, " %08lX", (unsigned long)IOValue);
        }
    }

#else /* AVOID_CPIO */

    Limit = ATIIOPort(IOPortTag(0x1FU, 0x3FU));
    Step = ATIIOPort(IOPortTag(0x01U, 0x01U)) - pATI->CPIOBase;
    for (Index = pATI->CPIOBase;  Index <= Limit;  Index += Step)
    {
        if (!(((Index - pATI->CPIOBase) / Step) & 0x03U))
            xf86ErrorFVerb(4, "\n 0x%04X: ", Index);
        if (Index == (int)ATIIOPort(DAC_REGS))
        {
            dac_read = in8(DAC_REGS + 3);
            DACDelay;
            dac_mask = in8(DAC_REGS + 2);
            DACDelay;
            dac_data = in8(DAC_REGS + 1);
            DACDelay;
            dac_write = in8(DAC_REGS + 0);
            DACDelay;

            xf86ErrorFVerb(4, " %02X%02X%02X%02X",
                dac_read, dac_mask, dac_data, dac_write);

            out8(DAC_REGS + 2, dac_mask);
            DACDelay;
            out8(DAC_REGS + 3, dac_read);
            DACDelay;
        }
        else
        {
            IOValue = inl(Index);

            if ((Index == (int)ATIIOPort(CRTC_GEN_CNTL)) &&
                (IOValue & CRTC_EXT_DISP_EN))
                *crtc = ATI_CRTC_MACH64;

            xf86ErrorFVerb(4, " %08lX", (unsigned long)IOValue);
        }
    }

#endif /* AVOID_CPIO */

    xf86ErrorFVerb(4, "\n");
}

/*
 * ATIMach64PrintPLLRegisters --
 *
 * Display an integrated Mach64's PLL registers when the server is invoked with
 * -verbose.
 */
static void
ATIMach64PrintPLLRegisters
(
    ATIPtr pATI
)
{
    int Index, Limit;
    CARD8 PLLReg[MaxBits(PLL_ADDR) + 1];

    for (Limit = 0;  Limit < SizeOf(PLLReg);  Limit++)
        PLLReg[Limit] = ATIMach64GetPLLReg(Limit);

    /* Determine how many PLL registers there really are */
    while ((Limit = Limit >> 1))
        for (Index = 0;  Index < Limit;  Index++)
            if (PLLReg[Index] != PLLReg[Index + Limit])
                goto FoundLimit;
FoundLimit:
    Limit <<= 1;

    xf86ErrorFVerb(4, "\n Mach64 PLL register values:");
    for (Index = 0;  Index < Limit;  Index++)
    {
        if (!(Index & 3))
        {
            if (!(Index & 15))
                xf86ErrorFVerb(4, "\n 0x%02X: ", Index);
            xf86ErrorFVerb(4, " ");
        }
        xf86ErrorFVerb(4, "%02X", PLLReg[Index]);
    }

    xf86ErrorFVerb(4, "\n");
}

/*
 * ATIRGB514PrintRegisters --
 *
 * Display IBM RGB 514 registers when the server is invoked with -verbose.
 */
static void
ATIRGB514PrintRegisters
(
    ATIPtr pATI
)
{
    CARD32 crtc_gen_cntl, dac_cntl;
    CARD8  index_lo, index_hi, index_ctl;
    int    Index;

    /* Temporarily switch to Mach64 CRTC */
    crtc_gen_cntl = inr(CRTC_GEN_CNTL);
    if (!(crtc_gen_cntl & CRTC_EXT_DISP_EN))
        outr(CRTC_GEN_CNTL, crtc_gen_cntl | CRTC_EXT_DISP_EN);

    /* Temporarily switch to IBM RGB 514 registers */
    dac_cntl = inr(DAC_CNTL);
    outr(DAC_CNTL, (dac_cntl & ~DAC_EXT_SEL_RS3) | DAC_EXT_SEL_RS2);

    index_lo = in8(M64_DAC_WRITE);
    index_hi = in8(M64_DAC_DATA);
    index_ctl = in8(M64_DAC_READ);

    out8(M64_DAC_WRITE, 0x00U);
    out8(M64_DAC_DATA, 0x00U);
    out8(M64_DAC_READ, 0x01U);  /* Auto-increment */

    xf86ErrorFVerb(4, "\n IBM RGB 514 registers:");
    for (Index = 0;  Index < 0x0800;  Index++)
    {
        if (!(Index & 3))
        {
            if (!(Index & 15))
            {
                xf86ErrorFVerb(4, "\n 0x%04X: ", Index);

                /* Need to rewrite index every so often... */
                if ((Index == 0x0100) || (Index == 0x0500))
                {
                    out8(M64_DAC_WRITE, 0x00U);
                    out8(M64_DAC_DATA, Index >> 8);
                }
            }

            xf86ErrorFVerb(4, " ");
        }

        xf86ErrorFVerb(4, "%02X", in8(M64_DAC_MASK));
    }

    /* Restore registers */
    out8(M64_DAC_WRITE, index_lo);
    out8(M64_DAC_DATA, index_hi);
    out8(M64_DAC_READ, index_ctl);
    outr(DAC_CNTL, dac_cntl);
    if (!(crtc_gen_cntl & CRTC_EXT_DISP_EN))
        outr(CRTC_GEN_CNTL, crtc_gen_cntl);

    xf86ErrorFVerb(4, "\n");
}

/*
 * ATIPrintRegisters --
 *
 * Display various registers when the server is invoked with -verbose.
 */
void
ATIPrintRegisters
(
    ATIPtr pATI
)
{
    pciVideoPtr  pVideo;
    pciConfigPtr pPCI;
    int          Index;
    CARD32       lcd_index, tv_out_index, lcd_gen_ctrl;
    CARD8        dac_read, dac_mask, dac_write;
    CARD8        crtc;

#ifndef AVOID_CPIO

    CARD8 genmo, seq1 = 0;

    crtc = ATI_CRTC_VGA;

    if (pATI->VGAAdapter != ATI_ADAPTER_NONE)
    {
        xf86ErrorFVerb(4, "\n Miscellaneous output register value:  0x%02X.\n",
            genmo = inb(R_GENMO));

        if (genmo & 0x01U)
        {
            if (pATI->Chip == ATI_CHIP_264LT)
            {
                lcd_gen_ctrl = inr(LCD_GEN_CTRL);

                outr(LCD_GEN_CTRL, lcd_gen_ctrl & ~SHADOW_RW_EN);
                ATIPrintIndexedRegisters(CRTX(ColourIOBase), 0, 64,
                    "Non-shadow colour CRT controller", 0);

                outr(LCD_GEN_CTRL, lcd_gen_ctrl | SHADOW_RW_EN);
                ATIPrintIndexedRegisters(CRTX(ColourIOBase), 0, 64,
                    "Shadow colour CRT controller", 0);

                outr(LCD_GEN_CTRL, lcd_gen_ctrl);
            }
            else if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
                     (pATI->Chip == ATI_CHIP_264XL) ||
                     (pATI->Chip == ATI_CHIP_MOBILITY))
            {
                lcd_index = inr(LCD_INDEX);
                lcd_gen_ctrl = ATIMach64GetLCDReg(LCD_GEN_CNTL);

                ATIMach64PutLCDReg(LCD_GEN_CNTL,
                    lcd_gen_ctrl & ~(CRTC_RW_SELECT | SHADOW_RW_EN));
                ATIPrintIndexedRegisters(CRTX(ColourIOBase), 0, 64,
                    "Non-shadow colour CRT controller", 0);

                ATIMach64PutLCDReg(LCD_GEN_CNTL,
                    (lcd_gen_ctrl & ~CRTC_RW_SELECT) | SHADOW_RW_EN);
                ATIPrintIndexedRegisters(CRTX(ColourIOBase), 0, 64,
                    "Shadow colour CRT controller", 0);

                ATIMach64PutLCDReg(LCD_GEN_CNTL, lcd_gen_ctrl);
                outr(LCD_INDEX, lcd_index);
            }
            else
            {
                ATIPrintIndexedRegisters(CRTX(ColourIOBase), 0, 64,
                    "Colour CRT controller", 0);
            }

            ATIPrintIndexedRegisters(ATTRX, 0, 32, "Attribute controller",
                GENS1(ColourIOBase));
        }
        else
        {
            if (pATI->Chip == ATI_CHIP_264LT)
            {
                lcd_gen_ctrl = inr(LCD_GEN_CTRL);

                outr(LCD_GEN_CTRL, lcd_gen_ctrl & ~SHADOW_RW_EN);
                ATIPrintIndexedRegisters(CRTX(MonochromeIOBase), 0, 64,
                    "Non-shadow monochrome CRT controller", 0);

                outr(LCD_GEN_CTRL, lcd_gen_ctrl | SHADOW_RW_EN);
                ATIPrintIndexedRegisters(CRTX(MonochromeIOBase), 0, 64,
                    "Shadow monochrome CRT controller", 0);

                outr(LCD_GEN_CTRL, lcd_gen_ctrl);
            }
            else if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
                     (pATI->Chip == ATI_CHIP_264XL) ||
                     (pATI->Chip == ATI_CHIP_MOBILITY))
            {
                lcd_index = inr(LCD_INDEX);
                lcd_gen_ctrl = ATIMach64GetLCDReg(LCD_GEN_CNTL);

                ATIMach64PutLCDReg(LCD_GEN_CNTL,
                    lcd_gen_ctrl & ~(CRTC_RW_SELECT | SHADOW_RW_EN));
                ATIPrintIndexedRegisters(CRTX(MonochromeIOBase), 0, 64,
                    "Non-shadow monochrome CRT controller", 0);

                ATIMach64PutLCDReg(LCD_GEN_CNTL,
                    (lcd_gen_ctrl & ~CRTC_RW_SELECT) | SHADOW_RW_EN);
                ATIPrintIndexedRegisters(CRTX(MonochromeIOBase), 0, 64,
                    "Shadow monochrome CRT controller", 0);

                ATIMach64PutLCDReg(LCD_GEN_CNTL, lcd_gen_ctrl);
                outr(LCD_INDEX, lcd_index);
            }
            else
            {
                ATIPrintIndexedRegisters(CRTX(MonochromeIOBase), 0, 64,
                    "Monochrome CRT controller", 0);
            }

            ATIPrintIndexedRegisters(ATTRX, 0, 32, "Attribute controller",
                GENS1(MonochromeIOBase));
        }

        ATIPrintIndexedRegisters(GRAX, 0, 16, "Graphics controller", 0);
        ATIPrintIndexedRegisters(SEQX, 0, 8, "Sequencer", 0);

        if (pATI->CPIO_VGAWonder)
            ATIPrintIndexedRegisters(pATI->CPIO_VGAWonder,
                xf86ServerIsOnlyProbing() ? 0x80U : pATI->VGAOffset, 0xC0U,
                "ATI extended VGA", 0);
    }

    if (pATI->ChipHasSUBSYS_CNTL)
    {
        xf86ErrorFVerb(4, "\n 8514/A register values:");
        for (Index = 0x02E8U;  Index <= 0x0FEE8;  Index += 0x0400U)
        {
            if (!((Index - 0x02E8U) & 0x0C00U))
                xf86ErrorFVerb(4, "\n 0x%04X: ", Index);
            xf86ErrorFVerb(4, " %04X", inw(Index));
        }

        if (pATI->Adapter >= ATI_ADAPTER_MACH8)
        {
            xf86ErrorFVerb(4, "\n\n Mach8/Mach32 register values:");
            for (Index = 0x02EEU;  Index <= 0x0FEEE;  Index += 0x0400U)
            {
                if (!((Index - 0x02EEU) & 0x0C00U))
                    xf86ErrorFVerb(4, "\n 0x%04X: ", Index);
                xf86ErrorFVerb(4, " %04X", inw(Index));
            }
        }

        xf86ErrorFVerb(4, "\n");
    }
    else

#endif /* AVOID_CPIO */

    if (pATI->Chip == ATI_CHIP_264LT)
    {
        lcd_gen_ctrl = inr(LCD_GEN_CTRL);

        outr(LCD_GEN_CTRL, lcd_gen_ctrl & ~SHADOW_RW_EN);
        ATIMach64PrintRegisters(pATI, &crtc, "non-shadow");

        outr(LCD_GEN_CTRL, lcd_gen_ctrl | SHADOW_RW_EN);
        ATIMach64PrintRegisters(pATI, &crtc, "shadow");

        outr(LCD_GEN_CTRL, lcd_gen_ctrl);

        ATIMach64PrintPLLRegisters(pATI);
    }
    else if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
             (pATI->Chip == ATI_CHIP_264XL) ||
             (pATI->Chip == ATI_CHIP_MOBILITY))
    {
        lcd_index = inr(LCD_INDEX);
        lcd_gen_ctrl = ATIMach64GetLCDReg(LCD_GEN_CNTL);

        ATIMach64PutLCDReg(LCD_GEN_CNTL,
            lcd_gen_ctrl & ~(CRTC_RW_SELECT | SHADOW_RW_EN));
        ATIMach64PrintRegisters(pATI, &crtc, "non-shadow");

        ATIMach64PutLCDReg(LCD_GEN_CNTL,
            (lcd_gen_ctrl & ~CRTC_RW_SELECT) | SHADOW_RW_EN);
        ATIMach64PrintRegisters(pATI, &crtc, "shadow");

        if (pATI->Chip != ATI_CHIP_264XL)
        {
            ATIMach64PutLCDReg(LCD_GEN_CNTL, lcd_gen_ctrl | CRTC_RW_SELECT);
            ATIMach64PrintRegisters(pATI, &crtc, "secondary");
        }

        ATIMach64PutLCDReg(LCD_GEN_CNTL, lcd_gen_ctrl);

        ATIMach64PrintPLLRegisters(pATI);

        xf86ErrorFVerb(4, "\n LCD register values:");
        for (Index = 0;  Index < 64;  Index++)
        {
            if (!(Index & 3))
                xf86ErrorFVerb(4, "\n 0x%02X: ", Index);
            xf86ErrorFVerb(4, " %08X", ATIMach64GetLCDReg(Index));
        }

        outr(LCD_INDEX, lcd_index);

        tv_out_index = inr(TV_OUT_INDEX);

        xf86ErrorFVerb(4, "\n\n TV_OUT register values:");
        for (Index = 0;  Index < 256;  Index++)
        {
            if (!(Index & 3))
                xf86ErrorFVerb(4, "\n 0x%02X: ", Index);
            xf86ErrorFVerb(4, " %08X", ATIMach64GetTVReg(Index));
        }

        outr(TV_OUT_INDEX, tv_out_index);

        xf86ErrorFVerb(4, "\n");
    }
    else

#ifndef AVOID_CPIO

    if (pATI->Chip >= ATI_CHIP_88800GXC)

#endif /* AVOID_CPIO */

    {

#ifdef AVOID_CPIO

        ATIMach64PrintRegisters(pATI, &crtc, "MMIO");

#else /* AVOID_CPIO */

        ATIMach64PrintRegisters(pATI, &crtc,
            (pATI->CPIODecoding == SPARSE_IO) ? "sparse" : "block");

#endif /* AVOID_CPIO */

        if (pATI->Chip >= ATI_CHIP_264CT)
            ATIMach64PrintPLLRegisters(pATI);

        if (pATI->DAC == ATI_DAC_IBMRGB514)
            ATIRGB514PrintRegisters(pATI);
    }

#ifdef AVOID_CPIO

    dac_read = in8(M64_DAC_READ);
    DACDelay;
    dac_write = in8(M64_DAC_WRITE);
    DACDelay;
    dac_mask = in8(M64_DAC_MASK);
    DACDelay;

    xf86ErrorFVerb(4, "\n"
               " DAC read index:   0x%02X\n"
               " DAC write index:  0x%02X\n"
               " DAC mask:         0x%02X\n\n"
               " DAC colour lookup table:",
        dac_read, dac_write, dac_mask);

    out8(M64_DAC_MASK, 0xFFU);
    DACDelay;
    out8(M64_DAC_READ, 0x00U);
    DACDelay;

    for (Index = 0;  Index < 256;  Index++)
    {
        if (!(Index & 3))
            xf86ErrorFVerb(4, "\n 0x%02X:", Index);
        xf86ErrorFVerb(4, "  %02X", in8(M64_DAC_DATA));
        DACDelay;
        xf86ErrorFVerb(4, " %02X", in8(M64_DAC_DATA));
        DACDelay;
        xf86ErrorFVerb(4, " %02X", in8(M64_DAC_DATA));
        DACDelay;
    }

    out8(M64_DAC_MASK, dac_mask);
    DACDelay;
    out8(M64_DAC_READ, dac_read);
    DACDelay;

#else /* AVOID_CPIO */

    ATISetDACIOPorts(pATI, crtc);

    /* Temporarily turn off CLKDIV2 while reading DAC's LUT */
    if (pATI->Adapter == ATI_ADAPTER_NONISA)
    {
        seq1 = GetReg(SEQX, 0x01U);
        if (seq1 & 0x08U)
            PutReg(SEQX, 0x01U, seq1 & ~0x08U);
    }

    dac_read = inb(pATI->CPIO_DAC_READ);
    DACDelay;
    dac_write = inb(pATI->CPIO_DAC_WRITE);
    DACDelay;
    dac_mask = inb(pATI->CPIO_DAC_MASK);
    DACDelay;

    xf86ErrorFVerb(4, "\n"
               " DAC read index:   0x%02X\n"
               " DAC write index:  0x%02X\n"
               " DAC mask:         0x%02X\n\n"
               " DAC colour lookup table:",
        dac_read, dac_write, dac_mask);

    outb(pATI->CPIO_DAC_MASK, 0xFFU);
    DACDelay;
    outb(pATI->CPIO_DAC_READ, 0x00U);
    DACDelay;

    for (Index = 0;  Index < 256;  Index++)
    {
        if (!(Index & 3))
            xf86ErrorFVerb(4, "\n 0x%02X:", Index);
        xf86ErrorFVerb(4, "  %02X", inb(pATI->CPIO_DAC_DATA));
        DACDelay;
        xf86ErrorFVerb(4, " %02X", inb(pATI->CPIO_DAC_DATA));
        DACDelay;
        xf86ErrorFVerb(4, " %02X", inb(pATI->CPIO_DAC_DATA));
        DACDelay;
    }

    outb(pATI->CPIO_DAC_MASK, dac_mask);
    DACDelay;
    outb(pATI->CPIO_DAC_READ, dac_read);
    DACDelay;

    if ((pATI->Adapter == ATI_ADAPTER_NONISA) && (seq1 & 0x08U))
        PutReg(SEQX, 0x01U, seq1);

#endif /* AVOID_CPIO */

    if ((pVideo = pATI->PCIInfo))
    {
        pPCI = pVideo->thisCard;
        xf86ErrorFVerb(4, "\n\n PCI configuration register values:");
        for (Index = 0;  Index < 256;  Index+= 4)
        {
            if (!(Index & 15))
                xf86ErrorFVerb(4, "\n 0x%02X: ", Index);
            xf86ErrorFVerb(4, " 0x%08lX",
			   (unsigned long)pciReadLong(pPCI->tag, Index));
        }
    }

    xf86ErrorFVerb(4, "\n");

#ifndef AVOID_CPIO

    if (pATI->pBank)
        xf86ErrorFVerb(4, "\n Banked aperture at 0x%0lX.",
            (unsigned long)pATI->pBank);
    else
        xf86ErrorFVerb(4, "\n No banked aperture.");

    if (pATI->pMemory == pATI->pBank)
    {
        xf86ErrorFVerb(4, "\n No linear aperture.\n");
    }
    else

#else /* AVOID_CPIO */

    if (pATI->pMemory)

#endif /* AVOID_CPIO */

    {
        xf86ErrorFVerb(4, "\n Linear aperture at %p.\n", pATI->pMemory);
    }

    if (pATI->pBlock[0])
    {
        xf86ErrorFVerb(4, " Block 0 aperture at %p.\n", pATI->pBlock[0]);
        if (inr(CONFIG_CHIP_ID) == pATI->config_chip_id)
            xf86ErrorFVerb(4, " MMIO registers are correctly mapped.\n");
        else
            xf86ErrorFVerb(4, " MMIO mapping is in error!\n");
        if (pATI->pBlock[1])
            xf86ErrorFVerb(4, " Block 1 aperture at %p.\n",
                pATI->pBlock[1]);
    }
    else
    {
        xf86ErrorFVerb(4, " No MMIO aperture.\n");
    }

    if (pATI->pCursorImage)
        xf86ErrorFVerb(4, " Hardware cursor image aperture at %p.\n",
            pATI->pCursorImage);
    else
        xf86ErrorFVerb(4, " No hardware cursor image aperture.\n");

    xf86ErrorFVerb(4, "\n");
}

/*
 * A table to associate mode attributes with character strings.
 */
static const SymTabRec ModeAttributeNames[] =
{
    {V_PHSYNC,    "+hsync"},
    {V_NHSYNC,    "-hsync"},
    {V_PVSYNC,    "+vsync"},
    {V_NVSYNC,    "-vsync"},
    {V_PCSYNC,    "+csync"},
    {V_NCSYNC,    "-csync"},
    {V_INTERLACE, "interlace"},
    {V_DBLSCAN,   "doublescan"},
    {V_CSYNC,     "composite"},
    {V_DBLCLK,    "dblclk"},
    {V_CLKDIV2,   "clkdiv2"},
    {0,           NULL}
};

/*
 * ATIPrintMode --
 *
 * This function displays a mode's timing information.
 */
void
ATIPrintMode
(
    DisplayModePtr pMode
)
{
    const SymTabRec *pSymbol  = ModeAttributeNames;
    int             flags     = pMode->Flags;
    double          mClock, hSync, vRefresh;

    mClock = (double)pMode->SynthClock;
    if (pMode->HSync > 0.0)
        hSync = pMode->HSync;
    else
        hSync = mClock / pMode->HTotal;
    if (pMode->VRefresh > 0.0)
    {
        vRefresh = pMode->VRefresh;
    }
    else
    {
        vRefresh = (hSync * 1000.0) / pMode->VTotal;
        if (flags & V_INTERLACE)
            vRefresh *= 2.0;
        if (flags & V_DBLSCAN)
            vRefresh /= 2.0;
        if (pMode->VScan > 1)
            vRefresh /= pMode->VScan;
    }

    xf86ErrorFVerb(4, " Dot clock:           %7.3f MHz\n", mClock / 1000.0);
    xf86ErrorFVerb(4, " Horizontal sync:     %7.3f kHz\n", hSync);
    xf86ErrorFVerb(4, " Vertical refresh:    %7.3f Hz (%s)\n", vRefresh,
        (flags & V_INTERLACE) ? "I" : "NI");
    if ((pMode->ClockIndex >= 0) && (pMode->ClockIndex < MAXCLOCKS))
        xf86ErrorFVerb(4, " Clock index:         %d\n", pMode->ClockIndex);
    xf86ErrorFVerb(4, " Horizontal timings:  %4d %4d %4d %4d\n"
                      " Vertical timings:    %4d %4d %4d %4d\n",
        pMode->HDisplay, pMode->HSyncStart, pMode->HSyncEnd, pMode->HTotal,
        pMode->VDisplay, pMode->VSyncStart, pMode->VSyncEnd, pMode->VTotal);

    if (flags & V_HSKEW)
    {
        flags &= ~V_HSKEW;
        xf86ErrorFVerb(4, " Horizontal skew:     %4d\n", pMode->HSkew);
    }

    if (pMode->VScan >= 1)
        xf86ErrorFVerb(4, " Vertical scan:       %4d\n", pMode->VScan);

    xf86ErrorFVerb(4, " Flags:              ");
    for (;  pSymbol->token;  pSymbol++)
    {
        if (flags & pSymbol->token)
        {
            xf86ErrorFVerb(4, " %s", pSymbol->name);
            flags &= ~pSymbol->token;
            if (!flags)
                break;
        }
    }

    xf86ErrorFVerb(4, "\n");
}

--- NEW FILE: atiprint.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiprint.h,v 1.10 2003/01/01 19:16:33 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIPRINT_H___
#define ___ATIPRINT_H___ 1

#include "atipriv.h"
#include "atiproto.h"

#include "xf86str.h"

extern void ATIPrintBIOS      FunctionPrototype((const CARD8 *,
                                                 const unsigned int));
extern void ATIPrintRegisters FunctionPrototype((ATIPtr));
extern void ATIPrintMode      FunctionPrototype((DisplayModePtr));

#endif /* ___ATIPRINT_H___ */

--- NEW FILE: atipriv.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atipriv.h,v 1.5 2003/01/01 19:16:33 tsi Exp $ */
/*
 * Copyright 1999 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIPRIV_H___
#define ___ATIPRIV_H___ 1

/* Forward pointer definitions */
typedef struct _ATIHWRec *ATIHWPtr;
typedef struct _ATIRec   *ATIPtr;

#endif /* ___ATIPRIV_H___ */

--- NEW FILE: atiprobe.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiprobe.c,v 1.62tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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
[...2317 lines suppressed...]
            }

            xfree(pATI);
        }

        xfree(ATIGDevs);
    }

    xfree(ATIPtrs);

    /* Call Rage 128 driver probe */
    if (DoRage128 && R128Probe(pDriver, flags))
        ProbeSuccess = TRUE;

    /* Call Radeon driver probe */
    if (DoRadeon && RADEONProbe(pDriver, flags))
        ProbeSuccess = TRUE;

    return ProbeSuccess;
}

--- NEW FILE: atiprobe.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiprobe.h,v 1.8 2003/01/01 19:16:33 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIPROBE_H___
#define ___ATIPROBE_H___ 1

#include "atiproto.h"

#include "xf86str.h"

extern Bool ATIProbe FunctionPrototype((DriverPtr, int));

#endif /* ___ATIPROBE_H___ */

--- NEW FILE: atiproto.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiproto.h,v 1.8 2003/04/23 21:51:30 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIPROTO_H___
#define ___ATIPROTO_H___ 1

#include <X11/Xfuncproto.h>

/*
 * This isn't quite ready for Xfuncproto.h yet.
 */

#ifndef FunctionPrototype
#   if NeedFunctionPrototypes
#       define FunctionPrototype(FunctionArgumentTypes) FunctionArgumentTypes
#   else
#       define FunctionPrototype(FunctionArgumentTypes) ()
#   endif
#endif

#ifndef NestedPrototype
#   if NeedNestedPrototypes
#       define NestedPrototype(NestedArgumentTypes) NestedArgumentTypes
#   else
#       define NestedPrototype(NestedArgumentTypes) ()
#   endif
#endif

#endif /* ___ATIPROTO_H___ */

--- NEW FILE: atiregs.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiregs.h,v 1.24 2003/04/23 21:51:30 tsi Exp $ */
/*
 * Copyright 1994 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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
[...2689 lines suppressed...]
#define MIX_HALF__SRC_MINUS_DST		0x0016u
#define MIX_AVERAGE			0x0017u
#define MIX_DST_MINUS_SRC_SAT		0x0018u
#define MIX_SRC_MINUS_DST_SAT		0x001au
#define MIX_HALF__DST_MINUS_SRC_SAT	0x001cu
#define MIX_HALF__SRC_MINUS_DST_SAT	0x001eu
#define MIX_AVERAGE_SAT			0x001fu
#define MIX_FN_PAINT			MIX_SRC

/* Video/Graphics mix functions for overlay */
#define OVERLAY_MIX_FALSE		0x00u
#define OVERLAY_MIX_TRUE		0x01u
/*	?				0x02u */
/*	?				0x03u */
#define OVERLAY_MIX_NOT_EQUAL		0x04u
#define OVERLAY_MIX_EQUAL		0x05u
/*	?				0x06u */
/*	?				0x07u */

#endif /* ___ATIREGS_H___ */

--- NEW FILE: atirgb514.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atirgb514.c,v 1.4 2003/01/01 19:16:34 tsi Exp $ */
/*
 * Copyright 2001 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

#include "ati.h"
#include "aticrtc.h"
#include "atimach64io.h"
#include "atirgb514.h"

/*
 * ATIRGB514PreInit --
 *
 * This function fills in the IBM RGB 514 portion of an ATIHWRec that is common
 * to all video modes generated by the server.
 */
void
ATIRGB514PreInit
(
    ATIPtr   pATI,
    ATIHWPtr pATIHW
)
{
    /* Get a work copy of IBM RGB 514 registers */
    ATIRGB514Save(pATI, pATIHW);

    /* Miscellaneous Clock Control */
    pATIHW->ibmrgb514[0x0002U] = 0x01U;

    /* Sync Control */
    pATIHW->ibmrgb514[0x0003U] &= ~0x80U;

    /* Horizontal Sync Control */
    pATIHW->ibmrgb514[0x0004U] = 0x00U;

    /* Power Management */
    pATIHW->ibmrgb514[0x0005U] = 0x00U;

    /* DAC Operation */
    pATIHW->ibmrgb514[0x0006U] &= ~0x04U;

    /* Palette Control */
    pATIHW->ibmrgb514[0x0007U] = 0x00U;

    /* PLL Control */
    pATIHW->ibmrgb514[0x0010U] = 0x01U;

    /* Cursor control */
    pATIHW->ibmrgb514[0x0030U] &= ~0x03U;       /* For now */

    /* Border (i.e. overscan) */
    pATIHW->ibmrgb514[0x0060U] = 0x00U;
    pATIHW->ibmrgb514[0x0061U] = 0x00U;
    pATIHW->ibmrgb514[0x0062U] = 0x00U;

    /* Miscellaneous Control */
    pATIHW->ibmrgb514[0x0070U] &= ~0x20U;
    pATIHW->ibmrgb514[0x0071U] = 0x41U; /* See workaround in ATIRGB514Set() */

#ifndef AVOID_CPIO

    if (pATIHW->crtc == ATI_CRTC_VGA)
    {
        /* Pixel Format */
        pATIHW->ibmrgb514[0x000AU] = 0x03U;

        /* Miscellaneous Control */
        pATIHW->ibmrgb514[0x0070U] |= 0x40U;

        /* VRAM Mask */
        pATIHW->ibmrgb514[0x0090U] = 0x03U;
    }
    else

#endif /* AVOID_CPIO */

    {
        /* Miscellaneous Control */
        pATIHW->ibmrgb514[0x0070U] &= ~0x40U;

        /* VRAM Mask */
        pATIHW->ibmrgb514[0x0090U] = 0x00U;
        pATIHW->ibmrgb514[0x0091U] = 0x00U;

        /* Pixel Format */
        switch (pATI->depth)
        {
            case 8:
                pATIHW->ibmrgb514[0x000AU] = 0x03U;
                pATIHW->ibmrgb514[0x000BU] = 0x00U;
                break;

            case 15:
                pATIHW->ibmrgb514[0x000AU] = 0x04U;
                pATIHW->ibmrgb514[0x000CU] = 0xC4U;
                break;

            case 16:
                pATIHW->ibmrgb514[0x000AU] = 0x04U;
                pATIHW->ibmrgb514[0x000CU] = 0xC6U;
                break;

            case 24:
                if (pATI->bitsPerPixel == 24)
                {
                    pATIHW->ibmrgb514[0x000AU] = 0x05U;
                    pATIHW->ibmrgb514[0x000DU] = 0x01U;
                }
                else
                {
                    pATIHW->ibmrgb514[0x000AU] = 0x06U;
                    pATIHW->ibmrgb514[0x000EU] = 0x03U;
                }
                break;

            default:
                break;
        }
    }

    if (pATI->rgbBits == 8)
        pATIHW->ibmrgb514[0x0071U] |= 0x04U;
}

/*
 * ATIRGB514Save --
 *
 * This function saves IBM RGB514 related data into an ATIHWRec.
 */
void
ATIRGB514Save
(
    ATIPtr   pATI,
    ATIHWPtr pATIHW
)
{
    CARD32 crtc_gen_cntl, dac_cntl;
    CARD8  index_lo, index_hi, index_ctl;
    int    Index;

    /* Temporarily switch to Mach64 CRTC */
    crtc_gen_cntl = inr(CRTC_GEN_CNTL);
    if (!(crtc_gen_cntl & CRTC_EXT_DISP_EN))
        outr(CRTC_GEN_CNTL, crtc_gen_cntl | CRTC_EXT_DISP_EN);

    /* Temporarily switch to IBM RGB 514 registers */
    dac_cntl = inr(DAC_CNTL) & ~(DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3);
    outr(DAC_CNTL, dac_cntl | DAC_EXT_SEL_RS2);

    index_lo = in8(M64_DAC_WRITE);
    index_hi = in8(M64_DAC_DATA);
    index_ctl = in8(M64_DAC_READ);

    out8(M64_DAC_WRITE, 0x00U);
    out8(M64_DAC_DATA, 0x00U);
    out8(M64_DAC_READ, 0x01U);  /* Auto-increment */

    /* Save IBM RGB 514 registers */
    for (Index = 0;  Index < NumberOf(pATIHW->ibmrgb514);  Index++)
    {
        /* Need to rewrite the index every so often... */
        if ((Index == 0x0100) || (Index == 0x0500))
        {
            out8(M64_DAC_WRITE, 0);
            out8(M64_DAC_DATA, Index >> 8);
        }
        pATIHW->ibmrgb514[Index] = in8(M64_DAC_MASK);
    }

    /* Restore registers */
    out8(M64_DAC_WRITE, index_lo);
    out8(M64_DAC_DATA, index_hi);
    out8(M64_DAC_READ, index_ctl);
    outr(DAC_CNTL, dac_cntl);
    if (!(crtc_gen_cntl & CRTC_EXT_DISP_EN))
        outr(CRTC_GEN_CNTL, crtc_gen_cntl);
}

/*
 * ATIRGB514Calculate --
 *
 * This function fills in the IBM RGB 514 portion of an ATIHWRec that is
 * specific to a display mode.  pATIHW->ibmrgb514 has already been
 * initialised by a previous call to ATIRGB514PreInit().
 */
void
ATIRGB514Calculate
(
    ATIPtr         pATI,
    ATIHWPtr       pATIHW,
    DisplayModePtr pMode
)
{
    if (pATI->OptionCSync || (pMode->Flags & (V_CSYNC | V_PCSYNC)))
        pATIHW->ibmrgb514[0x0006U] |= 0x08U;
    else
        pATIHW->ibmrgb514[0x0006U] &= ~0x08U;

    if (pMode->Flags & V_INTERLACE)
        pATIHW->ibmrgb514[0x0071U] |= 0x20U;
    else
        pATIHW->ibmrgb514[0x0071U] &= ~0x20U;
}

/*
 * ATIRGB514Set --
 *
 * This function is called to set an IBM RGB514's registers.
 */
void
ATIRGB514Set
(
    ATIPtr   pATI,
    ATIHWPtr pATIHW
)
{
    CARD32 crtc_gen_cntl, dac_cntl;
    CARD8  index_lo, index_hi, index_ctl;
    int    Index;

    /* Temporarily switch to Mach64 CRTC */
    crtc_gen_cntl = inr(CRTC_GEN_CNTL);
    if (!(crtc_gen_cntl & CRTC_EXT_DISP_EN))
        outr(CRTC_GEN_CNTL, crtc_gen_cntl | CRTC_EXT_DISP_EN);

    /* Temporarily switch to IBM RGB 514 registers */
    dac_cntl = inr(DAC_CNTL) & ~(DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3);
    outr(DAC_CNTL, dac_cntl | DAC_EXT_SEL_RS2);

    index_lo = in8(M64_DAC_WRITE);
    index_hi = in8(M64_DAC_DATA);
    index_ctl = in8(M64_DAC_READ);

    out8(M64_DAC_WRITE, 0x00U);
    out8(M64_DAC_DATA, 0x00U);
    out8(M64_DAC_READ, 0x01U);  /* Auto-increment */

    /* Load IBM RGB 514 registers */
    for (Index = 0;  Index < NumberOf(pATIHW->ibmrgb514);  Index++)
         out8(M64_DAC_MASK, pATIHW->ibmrgb514[Index]);

#ifndef AVOID_CPIO

    /* Deal with documented anomaly */
    if (pATIHW->crtc == ATI_CRTC_VGA)
    {
        /* Reset Miscellaneous Control 2 */
        out8(M64_DAC_WRITE, 0x71U);
        out8(M64_DAC_DATA, 0x00U);
        out8(M64_DAC_MASK, pATIHW->ibmrgb514[0x0071U] & ~0x41U);
    }

#endif /* AVOID_CPIO */

    /* Restore registers */
    out8(M64_DAC_WRITE, index_lo);
    out8(M64_DAC_DATA, index_hi);
    out8(M64_DAC_READ, index_ctl);
    outr(DAC_CNTL, dac_cntl);
    if (!(crtc_gen_cntl & CRTC_EXT_DISP_EN))
        outr(CRTC_GEN_CNTL, crtc_gen_cntl);
}

--- NEW FILE: atirgb514.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atirgb514.h,v 1.3 2003/01/01 19:16:34 tsi Exp $ */
/*
 * Copyright 2001 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIRGB514_H___
#define ___ATIRGB514_H___ 1

#include "atipriv.h"
#include "atiproto.h"

#include "xf86str.h"

extern void ATIRGB514PreInit   FunctionPrototype((ATIPtr, ATIHWPtr));
extern void ATIRGB514Save      FunctionPrototype((ATIPtr, ATIHWPtr));
extern void ATIRGB514Calculate FunctionPrototype((ATIPtr, ATIHWPtr,
                                                  DisplayModePtr));
extern void ATIRGB514Set       FunctionPrototype((ATIPtr, ATIHWPtr));

#endif /* ___ATIRGB514_H___ */

--- NEW FILE: atiscreen.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiscreen.c,v 1.30 2003/04/23 21:51:30 tsi Exp $ */
/*
 * Copyright 1999 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

#include "ati.h"
#include "atiaccel.h"
#include "aticonsole.h"
#include "aticursor.h"
#include "atidac.h"
#include "atidga.h"
#include "atiscreen.h"
#include "atistruct.h"
#include "atixv.h"

#include "shadowfb.h"
#include "xf86cmap.h"

#include "fb.h"

#include "mibank.h"
#include "micmap.h"
#include "mipointer.h"

/*
 * ATIRefreshArea --
 *
 * This function is called by the shadow frame buffer code to refresh the
 * hardware frame buffer.
 */
static void
ATIRefreshArea
(
    ScrnInfoPtr pScreenInfo,
    int         nBox,
    BoxPtr      pBox
)
{
    ATIPtr  pATI = ATIPTR(pScreenInfo);
    pointer pSrc, pDst;
    int     offset, w, h;

    while (nBox-- > 0)
    {
        w = (pBox->x2 - pBox->x1) * pATI->AdjustDepth;
        h = pBox->y2 - pBox->y1;
        offset = (pBox->y1 * pATI->FBPitch) + (pBox->x1 * pATI->AdjustDepth);
        pSrc = (char *)pATI->pShadow + offset;
        pDst = (char *)pATI->pMemory + offset;

        while (h-- > 0)
        {
            (void)memcpy(pDst, pSrc, w);
            pSrc = (char *)pSrc + pATI->FBPitch;
            pDst = (char *)pDst + pATI->FBPitch;
        }

        pBox++;
    }
}

/*
 * ATIScreenInit --
 *
 * This function is called by DIX to initialise the screen.
 */
Bool
ATIScreenInit
(
    int       iScreen,
    ScreenPtr pScreen,
    int       argc,
    char      **argv
)
{
    ScrnInfoPtr  pScreenInfo = xf86Screens[iScreen];
    ATIPtr       pATI        = ATIPTR(pScreenInfo);
    pointer      pFB;
    int          VisualMask;

    /* Set video hardware state */
    if (!ATIEnterGraphics(pScreen, pScreenInfo, pATI))
        return FALSE;

    /* Re-initialise mi's visual list */
    miClearVisualTypes();

    if ((pATI->depth > 8) && (pATI->DAC == ATI_DAC_INTERNAL))
        VisualMask = TrueColorMask;
    else
        VisualMask = miGetDefaultVisualMask(pATI->depth);

    if (!miSetVisualTypes(pATI->depth, VisualMask, pATI->rgbBits,
                          pScreenInfo->defaultVisual))
        return FALSE;

    if (!miSetPixmapDepths())
        return FALSE;

    pFB = pATI->pMemory;
    pATI->FBPitch = PixmapBytePad(pATI->displayWidth, pATI->depth);
    if (pATI->OptionShadowFB)
    {
        if ((pATI->pShadow = xalloc(pATI->FBPitch * pScreenInfo->virtualY)))
        {
            pFB = pATI->pShadow;
        }
        else
        {
            xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
                "Insufficient virtual memory for shadow frame buffer.\n");
            pATI->OptionShadowFB = FALSE;
        }
    }

    /* Initialise framebuffer layer */
    switch (pATI->bitsPerPixel)
    {

#ifndef AVOID_CPIO
#if 0

        case 1:
            pATI->Closeable = xf1bppScreenInit(pScreen, pFB,
                pScreenInfo->virtualX, pScreenInfo->virtualY,
                pScreenInfo->xDpi, pScreenInfo->yDpi, pATI->displayWidth);
            break;

        case 4:
            pATI->Closeable = xf4bppScreenInit(pScreen, pFB,
                pScreenInfo->virtualX, pScreenInfo->virtualY,
                pScreenInfo->xDpi, pScreenInfo->yDpi, pATI->displayWidth);
            break;
#endif

#endif /* AVOID_CPIO */

        case 8:
        case 16:
        case 24:
        case 32:
            pATI->Closeable = fbScreenInit(pScreen, pFB,
                pScreenInfo->virtualX, pScreenInfo->virtualY,
                pScreenInfo->xDpi, pScreenInfo->yDpi, pATI->displayWidth,
                pATI->bitsPerPixel);
            break;

        default:
            return FALSE;
    }

    if (!pATI->Closeable)
        return FALSE;

    /* Fixup RGB ordering */
    if (pATI->depth > 8)
    {
        VisualPtr pVisual = pScreen->visuals + pScreen->numVisuals;

        while (--pVisual >= pScreen->visuals)
        {
            if ((pVisual->class | DynamicClass) != DirectColor)
                continue;

            pVisual->offsetRed = pScreenInfo->offset.red;
            pVisual->offsetGreen = pScreenInfo->offset.green;
            pVisual->offsetBlue = pScreenInfo->offset.blue;

            pVisual->redMask = pScreenInfo->mask.red;
            pVisual->greenMask = pScreenInfo->mask.green;
            pVisual->blueMask = pScreenInfo->mask.blue;
        }
    }

    /* If applicable, initialise RENDER extension */
    if (pATI->bitsPerPixel > 4)
    {
        if (pATI->OptionShadowFB)
        {
            if (serverGeneration == 1)
                xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
                    "RENDER extension not supported with a shadowed"
                    " framebuffer.\n");
        }

#ifndef AVOID_CPIO

        else if (pATI->BankInfo.BankSize)
        {
            if (serverGeneration == 1)
                xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
                    "RENDER extension not supported with a banked"
                    " framebuffer.\n");
        }

#endif /* AVOID_CPIO */

        else if (!fbPictureInit(pScreen, NULL, 0) &&
                 (serverGeneration == 1))
        {
            xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
                "RENDER extension initialisation failed.\n");
        }
    }

    xf86SetBlackWhitePixels(pScreen);

#ifndef AVOID_CPIO

    /* Initialise banking if needed */
    if (!miInitializeBanking(pScreen,
                             pScreenInfo->virtualX, pScreenInfo->virtualY,
                             pATI->displayWidth, &pATI->BankInfo))
        return FALSE;

#endif /* AVOID_CPIO */

    /* Setup acceleration */
    if (!ATIInitializeAcceleration(pScreen, pScreenInfo, pATI))
        return FALSE;

#ifndef AVOID_DGA

    /* Initialise DGA support */
    (void)ATIDGAInit(pScreen, pScreenInfo, pATI);

#endif /* AVOID_DGA */

    /* Initialise backing store */
    miInitializeBackingStore(pScreen);
    xf86SetBackingStore(pScreen);

    /* Initialise cursor */
    if (!ATIInitializeCursor(pScreen, pATI))
        return FALSE;

    /* Create default colourmap */
    if (!miCreateDefColormap(pScreen))
        return FALSE;

#ifdef AVOID_CPIO

    if (!xf86HandleColormaps(pScreen, 256, pATI->rgbBits, ATILoadPalette, NULL,
                             CMAP_PALETTED_TRUECOLOR |
                             CMAP_LOAD_EVEN_IF_OFFSCREEN))
            return FALSE;

#else /* AVOID_CPIO */

    if (pATI->depth > 1)
        if (!xf86HandleColormaps(pScreen, (pATI->depth == 4) ? 16 : 256,
                                 pATI->rgbBits, ATILoadPalette, NULL,
                                 CMAP_PALETTED_TRUECOLOR |
                                 CMAP_LOAD_EVEN_IF_OFFSCREEN))
            return FALSE;

#endif /* AVOID_CPIO */

    /* Initialise shadow framebuffer */
    if (pATI->OptionShadowFB &&
        !ShadowFBInit(pScreen, ATIRefreshArea))
        return FALSE;

    /* Initialise DPMS support */
    (void)xf86DPMSInit(pScreen, ATISetDPMSMode, 0);

    /* Initialise XVideo support */
    (void)ATIInitializeXVideo(pScreen, pScreenInfo, pATI);

    /* Set pScreen->SaveScreen and wrap CloseScreen vector */
    pScreen->SaveScreen = ATISaveScreen;
    pATI->CloseScreen = pScreen->CloseScreen;
    pScreen->CloseScreen = ATICloseScreen;

    if (serverGeneration == 1)
        xf86ShowUnusedOptions(pScreenInfo->scrnIndex, pScreenInfo->options);

    return TRUE;
}

/*
 * ATICloseScreen --
 *
 * This function is called by DIX to close the screen.
 */
Bool
ATICloseScreen
(
    int       iScreen,
    ScreenPtr pScreen
)
{
    ScrnInfoPtr pScreenInfo = xf86Screens[iScreen];
    ATIPtr      pATI        = ATIPTR(pScreenInfo);
    Bool        Closed      = TRUE;

    ATICloseXVideo(pScreen, pScreenInfo, pATI);

    if (pATI->pXAAInfo)
    {
        XAADestroyInfoRec(pATI->pXAAInfo);
        pATI->pXAAInfo = NULL;
    }

    if ((pScreen->CloseScreen = pATI->CloseScreen))
    {
        pATI->CloseScreen = NULL;
        Closed = (*pScreen->CloseScreen)(iScreen, pScreen);
    }

    pATI->Closeable = FALSE;

    if (pATI->pCursorInfo)
    {
        xf86DestroyCursorInfoRec(pATI->pCursorInfo);
        pATI->pCursorInfo = NULL;
    }

    ATILeaveGraphics(pScreenInfo, pATI);

    xfree(pATI->ExpansionBitmapScanlinePtr[1]);
    pATI->ExpansionBitmapScanlinePtr[0] =
        pATI->ExpansionBitmapScanlinePtr[1] = NULL;

    xfree(pATI->pShadow);
    pATI->pShadow = NULL;
    pScreenInfo->pScreen = NULL;

    return Closed;
}

--- NEW FILE: atiscreen.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiscreen.h,v 1.6 2003/01/01 19:16:34 tsi Exp $ */
/*
 * Copyright 1999 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATISCREEN_H___
#define ___ATISCREEN_H___ 1

#include "atiproto.h"

#include "screenint.h"

extern Bool ATIScreenInit  FunctionPrototype((int, ScreenPtr, int, char **));
extern Bool ATICloseScreen FunctionPrototype((int, ScreenPtr));

#endif /* ___ATISCREEN_H___ */

--- NEW FILE: atistruct.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atistruct.h,v 1.41tsi Exp $ */
/*
 * Copyright 1999 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATISTRUCT_H___
#define ___ATISTRUCT_H___ 1

#include "atibank.h"
#include "aticlock.h"
#include "atiregs.h"

#include "xaa.h"
#include "xf86Cursor.h"
#include "xf86Pci.h"
#include "xf86Resources.h"

#define CacheSlotOf(____Register) ((____Register) / UnitOf(DWORD_SELECT))

/*
 * This is probably as good a place as any to put this note, as it applies to
 * the entire driver, but especially here.  CARD8's are used rather than the
 * appropriate enum types because the latter would nearly quadruple storage
 * requirements (they are stored as int's).  This reduces the usefulness of
 * enum types to their ability to declare index values.  I've also elected to
 * forgo the strong typing capabilities of enum types.  C is not terribly adept
 * at strong typing anyway.
 */

/* A structure for local data related to video modes */
typedef struct _ATIHWRec
{
    /* Clock number for mode */
    CARD8 clock;

    /* The CRTC used to drive the screen (VGA, 8514, Mach64) */
    CARD8 crtc;

    /* Colour lookup table */
    CARD8 lut[256 * 3];

#ifndef AVOID_CPIO

    /* VGA registers */
    CARD8 genmo, crt[25], seq[5], gra[9], attr[21];

    /* VGA Wonder registers */
    CARD8             a3,         a6, a7,             ab, ac, ad, ae,
          b0, b1, b2, b3,     b5, b6,     b8, b9, ba,         bd, be, bf;

    /* Shadow VGA CRTC registers */
    CARD8 shadow_vga[25];

#endif /* AVOID_CPIO */

    /* Generic DAC registers */
    CARD8 dac_read, dac_write, dac_mask;

    /* IBM RGB 514 registers */
    CARD8 ibmrgb514[0x0092U];   /* All that's needed for now */

    /* Mach64 PLL registers */
    CARD8 pll_vclk_cntl, pll_vclk_post_div,
          pll_vclk0_fb_div, pll_vclk1_fb_div,
          pll_vclk2_fb_div, pll_vclk3_fb_div,
          pll_xclk_cntl, pll_ext_vpll_cntl;

    /* Mach64 CPIO registers */
    CARD32 crtc_h_total_disp, crtc_h_sync_strt_wid,
           crtc_v_total_disp, crtc_v_sync_strt_wid,
           crtc_off_pitch, crtc_gen_cntl, dsp_config, dsp_on_off,
           ovr_clr, ovr_wid_left_right, ovr_wid_top_bottom,
           cur_clr0, cur_clr1, cur_offset,
           cur_horz_vert_posn, cur_horz_vert_off,
           clock_cntl, bus_cntl, mem_cntl, mem_vga_wp_sel, mem_vga_rp_sel,
           dac_cntl, gen_test_cntl, config_cntl, mpp_config, mpp_strobe_seq,
           tvo_cntl;

    /* LCD registers */
    CARD32 lcd_index, config_panel, lcd_gen_ctrl,
           horz_stretching, vert_stretching, ext_vert_stretch;

    /* Shadow Mach64 CRTC registers */
    CARD32 shadow_h_total_disp, shadow_h_sync_strt_wid,
           shadow_v_total_disp, shadow_v_sync_strt_wid;

    /* Mach64 MMIO Block 0 registers and related subfields */
    CARD32 dst_off_pitch;
    CARD16 dst_x, dst_y, dst_height;
    CARD32 dst_bres_err, dst_bres_inc, dst_bres_dec, dst_cntl;
    CARD32 src_off_pitch;
    CARD16 src_x, src_y, src_width1, src_height1,
           src_x_start, src_y_start, src_width2, src_height2;
    CARD32 src_cntl;
    CARD32 host_cntl;
    CARD32 pat_reg0, pat_reg1, pat_cntl;
    CARD16 sc_left, sc_right, sc_top, sc_bottom;
    CARD32 dp_bkgd_clr, dp_frgd_clr, dp_write_mask, dp_chain_mask,
           dp_pix_width, dp_mix, dp_src;
    CARD32 clr_cmp_clr, clr_cmp_msk, clr_cmp_cntl;
    CARD32 context_mask, context_load_cntl;

    /* Mach64 MMIO Block 1 registers */
    CARD32 overlay_y_x_start, overlay_y_x_end, overlay_graphics_key_clr,
           overlay_graphics_key_msk, overlay_key_cntl, overlay_scale_inc,
           overlay_scale_cntl, scaler_height_width, scaler_test,
           scaler_buf0_offset, scaler_buf1_offset, scaler_buf_pitch,
           video_format, overlay_exclusive_horz, overlay_exclusive_vert,
           buf0_offset, buf0_pitch, buf1_offset, buf1_pitch,
           scaler_colour_cntl, scaler_h_coeff0, scaler_h_coeff1,
           scaler_h_coeff2, scaler_h_coeff3, scaler_h_coeff4, gui_cntl,
           scaler_buf0_offset_u, scaler_buf0_offset_v, scaler_buf1_offset_u,
           scaler_buf1_offset_v;

    /* Clock map pointers */
    const CARD8 *ClockMap, *ClockUnmap;

    /* Clock programming data */
    int FeedbackDivider, ReferenceDivider, PostDivider;

#ifndef AVOID_CPIO

    /* This is used by ATISwap() */
    pointer frame_buffer;
    ATIBankProcPtr SetBank;
    unsigned int nBank, nPlane;

#endif /* AVOID_CPIO */

} ATIHWRec;

/*
 * This structure defines the driver's private area.
 */
typedef struct _ATIRec
{
    /*
     * Definitions related to XF86Config "Chipset" specifications.
     */
    CARD8 Chipset;

    /*
     * Adapter-related definitions.
     */
    CARD8 Adapter;

#ifndef AVOID_CPIO

    CARD8 VGAAdapter;

#endif /* AVOID_CPIO */

    /*
     * Chip-related definitions.
     */
    CARD32 config_chip_id;
    CARD16 ChipType;
    CARD8 Chip;
    CARD8 ChipClass, ChipRevision, ChipRev, ChipVersion, ChipFoundry;

#ifndef AVOID_CPIO

    CARD8 Coprocessor, ChipHasSUBSYS_CNTL;

#endif /* AVOID_CPIO */

    /*
     * Processor I/O decoding definitions.
     */
    CARD8 CPIODecoding;
    IOADDRESS CPIOBase;

#ifndef AVOID_CPIO

    /*
     * Processor I/O port definition for VGA.
     */
    IOADDRESS CPIO_VGABase;

    /*
     * Processor I/O port definitions for VGA Wonder.
     */
    IOADDRESS CPIO_VGAWonder;
    CARD8 B2Reg;        /* The B2 mirror */
    CARD8 VGAOffset;    /* Low index for CPIO_VGAWonder */

#endif /* AVOID_CPIO */

    /*
     * DAC-related definitions.
     */

#ifndef AVOID_CPIO

    IOADDRESS CPIO_DAC_MASK, CPIO_DAC_DATA, CPIO_DAC_READ, CPIO_DAC_WRITE,
              CPIO_DAC_WAIT;

#endif /* AVOID_CPIO */

    CARD16 DAC;
    CARD8 rgbBits;

    /*
     * Definitions related to system bus interface.
     */
    pciVideoPtr PCIInfo;
    CARD8 BusType;
    CARD8 SharedAccelerator;

#ifndef AVOID_CPIO

    CARD8 SharedVGA;
    resRange VGAWonderResources[2];

#endif /* AVOID_CPIO */

    /*
     * Definitions related to video memory.
     */
    CARD8 MemoryType;
    int VideoRAM;

    /*
     * BIOS-related definitions.
     */
    unsigned long BIOSBase;
    CARD8 I2CType, Tuner, Decoder, Audio;

    /*
     * Definitions related to video memory apertures.
     */
    pointer pMemory, pShadow;
    pointer pMemoryLE;          /* Always little-endian */
    unsigned long LinearBase;
    int LinearSize, FBPitch;

#ifndef AVOID_CPIO

    /*
     * Banking interface.
     */
    miBankInfoRec BankInfo;
    pointer pBank;
    CARD8 UseSmallApertures;

#endif /* AVOID_CPIO */

    /*
     * Definitions related to MMIO register apertures.
     */
    pointer pMMIO, pBlock[2];
    unsigned long Block0Base, Block1Base;

    /*
     * XAA interface.
     */
    XAAInfoRecPtr pXAAInfo;
    int nAvailableFIFOEntries, nFIFOEntries, nHostFIFOEntries;
    CARD8 EngineIsBusy, EngineIsLocked, XModifier;
    CARD32 dst_cntl;    /* For SetupFor/Subsequent communication */
    CARD32 sc_left_right, sc_top_bottom;
    CARD16 sc_left, sc_right, sc_top, sc_bottom;        /* Current scissors */
    pointer pHOST_DATA; /* Current HOST_DATA_* transfer window address */
    CARD32 *ExpansionBitmapScanlinePtr[2];
    int ExpansionBitmapWidth;

    /*
     * Cursor-related definitions.
     */
    xf86CursorInfoPtr pCursorInfo;
    pointer pCursorPage, pCursorImage;
    unsigned long CursorBase;
    CARD32 CursorOffset;
    CARD16 CursorXOffset, CursorYOffset;
    CARD8 Cursor;

    /*
     * MMIO cache.
     */
    CARD32 MMIOCache[CacheSlotOf(DWORD_SELECT) + 1];
    CARD8  MMIOCached[(CacheSlotOf(DWORD_SELECT) + 8) >> 3];

    /*
     * Clock-related definitions.
     */
    int ClockNumberToProgramme, ReferenceNumerator, ReferenceDenominator;
    int ProgrammableClock, maxClock;
    ClockRec ClockDescriptor;
    CARD16 BIOSClocks[16];
    CARD8 Clock;

    /*
     * DSP register data.
     */
    int XCLKFeedbackDivider, XCLKReferenceDivider, XCLKPostDivider;
    CARD16 XCLKMaxRASDelay, XCLKPageFaultDelay,
           DisplayLoopLatency, DisplayFIFODepth;

    /*
     * LCD panel data.
     */
    int LCDPanelID, LCDClock, LCDHorizontal, LCDVertical;
    unsigned LCDHSyncStart, LCDHSyncWidth, LCDHBlankWidth;
    unsigned LCDVSyncStart, LCDVSyncWidth, LCDVBlankWidth;
    int LCDVBlendFIFOSize;

    /*
     * Data used by ATIAdjustFrame().
     */
    int AdjustDepth, AdjustMaxX, AdjustMaxY;
    unsigned long AdjustMask, AdjustMaxBase;

    /*
     * DGA and non-DGA common data.
     */
    DisplayModePtr currentMode;
    CARD8 depth, bitsPerPixel;
    short int displayWidth;
    int pitchInc;
    rgb weight;

#ifndef AVOID_DGA

    /*
     * DGA-related data.
     */
    DGAModePtr pDGAMode;
    DGAFunctionRec ATIDGAFunctions;
    int nDGAMode;

    /*
     * XAAForceTransBlit alters the behavior of 'SetupForScreenToScreenCopy',
     * such that ~0 is interpreted as a legitimate transparency key.
     */
    CARD8 XAAForceTransBlit;

#endif /* AVOID_DGA */

    /*
     * XVideo-related data.
     */
    DevUnion XVPortPrivate[1];
    FBLinearPtr pXVBuffer;
    RegionRec VideoClip;
    int SurfacePitch, SurfaceOffset;
    CARD8 AutoPaint, DoubleBuffer, CurrentBuffer, ActiveSurface;

    /*
     * Data saved by ATIUnlock() and restored by ATILock().
     */
    struct
    {
        /* Mach64 registers */
        CARD32 crtc_int_cntl, crtc_gen_cntl, i2c_cntl_0, hw_debug,
               scratch_reg3, bus_cntl, lcd_index, mem_cntl, i2c_cntl_1,
               dac_cntl, gen_test_cntl, mpp_config, mpp_strobe_seq, tvo_cntl;

#ifndef AVOID_CPIO

        CARD32 config_cntl;

        /* Mach8/Mach32 registers */
        CARD16 clock_sel, misc_options, mem_bndry, mem_cfg;

        /* VGA Wonder registers */
        CARD8 a6, ab, b1, b4, b5, b6, b8, b9, be;

        /* VGA registers */
        CARD8 crt03, crt11;

        /* VGA shadow registers */
        CARD8 shadow_crt03, shadow_crt11;

#endif /* AVOID_CPIO */

    } LockData;

    /* Mode data */
    ATIHWRec OldHW, NewHW;
    int MaximumInterlacedPitch;
    Bool InterlacedSeen;

    /*
     * Resource Access Control entity index.
     */
    int iEntity;

    /*
     * Driver options.
     */
    CARD8 OptionAccel:1;        /* Use hardware draw engine */
    CARD8 OptionBIOSDisplay:1;  /* Allow BIOS interference */
    CARD8 OptionBlend:1;        /* Force horizontal blending */
    CARD8 OptionCRTDisplay:1;   /* Display on both CRT and digital panel */
    CARD8 OptionCSync:1;        /* Use composite sync */
    CARD8 OptionDevel:1;        /* Intentionally undocumented */

#ifndef AVOID_CPIO

    CARD8 OptionLinear:1;       /* Use linear fb aperture when available */

#endif /* AVOID_CPIO */

    CARD8 OptionMMIOCache:1;    /* Cache MMIO writes */
    CARD8 OptionTestMMIOCache:1;/* Test MMIO cache integrity */
    CARD8 OptionPanelDisplay:1; /* Prefer digital panel over CRT */
    CARD8 OptionProbeClocks:1;  /* Force probe for fixed clocks */
    CARD8 OptionShadowFB:1;     /* Use shadow frame buffer */
    CARD8 OptionLCDSync:1;      /* Temporary */

    /*
     * State flags.
     */
    CARD8 Unlocked, Mapped, Closeable;
    CARD8 MMIOInLinear;

    /*
     * Wrapped functions.
     */
    CloseScreenProcPtr CloseScreen;
} ATIRec;

#define ATIPTR(_p) ((ATIPtr)((_p)->driverPrivate))

#endif /* ___ATISTRUCT_H___ */

--- NEW FILE: atituner.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atituner.c,v 1.1 2003/07/24 22:08:28 tsi Exp $ */
/*
 * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

#include "atituner.h"

/* Temporary interface glitch */
#if 0
# include "fi12x6.h"
#else
    typedef enum {
        FI12x6_TYPE_UNKNOWN = -1,
        FI12x6_TYPE_FI1236 = 0,
        FI12x6_TYPE_FI1216,
        FI12x6_TYPE_FI1216MF,
        FI12x6_TYPE_TEMIC_FN5AL,
        FI12x6_TYPE_MT2032,
        FI12x6_TYPE_MAX             /* Must be last */
    } FI12x6TunerType;
#endif

/*
 * TV tuner definitions.
 */
const SymTabRec ATITuners[] =
{
    {
        FI12x6_TYPE_UNKNOWN,
        "No tuner"
    },
    {
        FI12x6_TYPE_FI1236,
        "Philips FI1236 MK1 NTSC M/N North America"
    },
    {
        FI12x6_TYPE_FI1236,
        "Philips FI1236 MK2 NTSC M/N Japan"
    },
    {
        FI12x6_TYPE_FI1216,
        "Philips FI1216 MK2 PAL B/G"
    },
    {
        FI12x6_TYPE_UNKNOWN,
        "Philips FI1246 MK2 PAL I"
    },
    {
        FI12x6_TYPE_FI1216MF,
        "Philips FI1216 MF MK2 PAL B/G, SECAM L/L"
    },
    {
        FI12x6_TYPE_FI1236,
        "Philips FI1236 MK2 NTSC M/N North America"
    },
    {
        FI12x6_TYPE_UNKNOWN,
        "Philips FI1256 MK2 SECAM D/K"
    },
    {
        FI12x6_TYPE_FI1236,
        "Philips FM1236 MK2 NTSC M/N North America"
    },
    {
        FI12x6_TYPE_FI1216,
        "Philips FI1216 MK2 PAL B/G - External Tuner POD"
    },
    {
        FI12x6_TYPE_UNKNOWN,
        "Philips FI1246 MK2 PAL I - External Tuner POD"
    },
    {
        FI12x6_TYPE_FI1216MF,
        "Philips FI1216 MF MK2 PAL B/G, SECAM L/L - External Tuner POD"
    },
    {
        FI12x6_TYPE_FI1236,
        "Philips FI1236 MK2 NTSC M/N North America - External Tuner POD"
    },
    {
        FI12x6_TYPE_TEMIC_FN5AL,
        "Temic FN5AL.RF3X7595 PAL I/B/G/DK & SECAM DK"
    },
    {
        FI12x6_TYPE_FI1216MF,
        "Philips FQ1216 ME/P"
    },
    {
        FI12x6_TYPE_UNKNOWN,
        "Unknown type (15)"
    },
    {
        FI12x6_TYPE_UNKNOWN,
        "Alps TSBH5 NTSC M/N North America"
    },
    {
        FI12x6_TYPE_UNKNOWN,
        "Alps TSC?? NTSC M/N North America"
    },
    {
        FI12x6_TYPE_UNKNOWN,
        "Alps TSCH5 NTSC M/N North America with FM"
    },
    {
        FI12x6_TYPE_UNKNOWN,
        "Unknown type (19)"
    },
    {
        FI12x6_TYPE_UNKNOWN,
        "Unknown type (20)"
    },
    {
        FI12x6_TYPE_UNKNOWN,
        "Unknown type (21)"
    },
    {
        FI12x6_TYPE_UNKNOWN,
        "Unknown type (22)"
    },
    {
        FI12x6_TYPE_UNKNOWN,
        "Unknown type (23)"
    },
    {
        FI12x6_TYPE_UNKNOWN,
        "Unknown type (24)"
    },
    {
        FI12x6_TYPE_UNKNOWN,
        "Unknown type (25)"
    },
    {
        FI12x6_TYPE_UNKNOWN,
        "Unknown type (26)"
    },
    {
        FI12x6_TYPE_UNKNOWN,
        "Unknown type (27)"
    },
    {
        FI12x6_TYPE_UNKNOWN,
        "Unknown type (28)"
    },
    {
        FI12x6_TYPE_MT2032,
        "Microtune MT2032"
    },
    {
        FI12x6_TYPE_UNKNOWN,
        "Unknown type (30)"
    },
    {
        FI12x6_TYPE_UNKNOWN,
        "Unknown type (31)"
    }
};

--- NEW FILE: atituner.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atituner.h,v 1.1 2003/07/24 22:08:28 tsi Exp $ */
/*
 * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATITUNER_H___
#define ___ATITUNER_H___ 1

#include "xf86str.h"

/*
 * TV Tuner definitions.  Most of these are from Philips.
 */
typedef enum
{
    ATI_TUNER_NONE,
    ATI_TUNER_FI1236MK1NA,
    ATI_TUNER_FI1236MK2J,
    ATI_TUNER_FI1216MK2BG,
    ATI_TUNER_FI1246MK2I,
    ATI_TUNER_FI1216MFMK2,
    ATI_TUNER_FI1236MK2NA,
    ATI_TUNER_FI1256MK2DK,
    ATI_TUNER_FM1236MK2NA,
    ATI_TUNER_FI1216MK2BGEXT,
    ATI_TUNER_FI1246MK2IEXT,
    ATI_TUNER_FI1216MFMK2EXT,
    ATI_TUNER_FI1236MK2NAEXT,
    ATI_TUNER_TEMIC_FN5AL,
    ATI_TUNER_FQ1216MEP,
    ATI_TUNER_15,
    ATI_TUNER_ALPS_TSBH5,
    ATI_TUNER_ALPS_TSCXX,
    ATI_TUNER_ALPS_TSCH5,
    ATI_TUNER_19,
    ATI_TUNER_20,
    ATI_TUNER_21,
    ATI_TUNER_22,
    ATI_TUNER_23,
    ATI_TUNER_24,
    ATI_TUNER_25,
    ATI_TUNER_26,
    ATI_TUNER_27,
    ATI_TUNER_28,
    ATI_TUNER_MT2032,
    ATI_TUNER_30,
    ATI_TUNER_31
} ATITunerType;

extern const SymTabRec ATITuners[];

#endif /* ___ATITUNER_H___ */

--- NEW FILE: atiutil.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiutil.c,v 1.8 2003/01/01 19:16:34 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

#include "atiutil.h"

/*
 * ATIReduceRatio --
 *
 * Reduce a fraction by factoring out the largest common divider of the
 * fraction's numerator and denominator.
 */
void
ATIReduceRatio
(
    int *Numerator,
    int *Denominator
)
{
    int Multiplier, Divider, Remainder;

    Multiplier = *Numerator;
    Divider = *Denominator;

    while ((Remainder = Multiplier % Divider))
    {
        Multiplier = Divider;
        Divider = Remainder;
    }

    *Numerator /= Divider;
    *Denominator /= Divider;
}

/*
 * ATIDivide --
 *
 * Using integer arithmetic and avoiding overflows, this function finds the
 * rounded integer that best approximates
 *
 *         Numerator      Shift
 *        ----------- * 2
 *        Denominator
 *
 * using the specified rounding (floor (<0), nearest (=0) or ceiling (>0)).
 */
int
ATIDivide
(
    int       Numerator,
    int       Denominator,
    int       Shift,
    const int RoundingKind
)
{
    int Rounding = 0;                           /* Default to floor */

#define MaxInt ((int)((unsigned int)(-1) >> 2))

    ATIReduceRatio(&Numerator, &Denominator);

    /* Deal with left shifts but try to keep the denominator even */
    if (Denominator & 1)
    {
        if (Denominator <= MaxInt)
        {
            Denominator <<= 1;
            Shift++;
        }
    }
    else while ((Shift > 0) && !(Denominator & 3))
    {
        Denominator >>= 1;
        Shift--;
    }

    /* Deal with right shifts */
    while (Shift < 0)
    {
        if ((Numerator & 1) && (Denominator <= MaxInt))
            Denominator <<= 1;
        else
            Numerator >>= 1;

        Shift++;
    }

    if (!RoundingKind)                          /* Nearest */
        Rounding = Denominator >> 1;
    else if (RoundingKind > 0)                  /* Ceiling */
        Rounding = Denominator - 1;

    return ((Numerator / Denominator) << Shift) +
            ((((Numerator % Denominator) << Shift) + Rounding) / Denominator);
}

--- NEW FILE: atiutil.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiutil.h,v 1.8 2003/01/01 19:16:34 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIUTIL_H___
#define ___ATIUTIL_H___ 1

#include "atiproto.h"

/*
 * Prevent the C standard's insistence on unsigned long sizeof's from causing
 * counter-intuitive results.
 */
#define SizeOf(_object) ((int)sizeof(_object))
#define NumberOf(_what) (SizeOf(_what) / SizeOf(_what[0]))

#define __ONE_MICROSECOND__ 100         /* This'll need calibration */

#define ATIDelay(_microseconds)                            \
    {                                                      \
        unsigned int _i, _j;                               \
        for (_i = 0;  _i < _microseconds;  _i++)           \
            for (_j = 0;  _j < __ONE_MICROSECOND__;  _j++) \
                /* Nothing */;                             \
    }

/*
 * Macros to get/set a contiguous bit field.  Arguments should not be
 * self-modifying.
 */
#define UnitOf(___Value)                                \
        (((((___Value) ^ ((___Value) - 1)) + 1) >> 1) | \
         ((((___Value) ^ ((___Value) - 1)) >> 1) + 1))

#define GetBits(__Value, _Mask) (((__Value) & (_Mask)) / UnitOf(_Mask))
#define SetBits(__Value, _Mask) (((__Value) * UnitOf(_Mask)) & (_Mask))

#define MaxBits(__Mask)         GetBits(__Mask, __Mask)

#define _ByteMask(__Byte)       ((CARD8)(-1) << (8 * (__Byte)))
#define GetByte(_Value, _Byte)  GetBits(_Value, _ByteMask(_Byte))
#define SetByte(_Value, _Byte)  SetBits(_Value, _ByteMask(_Byte))

#define _WordMask(__Word)       ((CARD16)(-1) << (16 * (__Word)))
#define GetWord(_Value, _Word)  GetBits(_Value, _WordMask(_Word))
#define SetWord(_Value, _Word)  SetBits(_Value, _WordMask(_Word))

extern void ATIReduceRatio FunctionPrototype((int *, int *));
extern int  ATIDivide      FunctionPrototype((int, int, int, const int));

#endif /* ___ATIUTIL_H___ */

--- NEW FILE: ativalid.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/ativalid.c,v 1.17 2003/10/30 17:36:58 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

#include "atiadapter.h"
#include "atichip.h"
#include "aticrtc.h"
#include "atistruct.h"
#include "ativalid.h"

#include "xf86.h"

/*
 * ATIValidMode --
 *
 * This checks for hardware-related limits on mode timings.
 */
ModeStatus
ATIValidMode
(
    int iScreen,
    DisplayModePtr pMode,
    Bool Verbose,
    int flags
)
{
    ScrnInfoPtr pScreenInfo = xf86Screens[iScreen];
    ATIPtr      pATI        = ATIPTR(pScreenInfo);
    Bool        InterlacedSeen;
    int         HBlankWidth, HAdjust, VScan, VInterlace;

#ifndef AVOID_CPIO

    int VDisplay, VTotal;

#endif /* AVOID_CPIO */

    if (flags & MODECHECK_FINAL)
    {
        /*
         * This is the final check before the common layer accepts a mode.
         * pScreenInfo->displayWidth is set to the proposed virtual pitch
         * should the mode be accepted.  The only check needed here is for
         * 18800's and 28800's, which don't support interlaced modes if the
         * pitch is over half the chipset's maximum pitch.
         */
        if (pATI->MaximumInterlacedPitch)
        {
            /*
             * Ensure no interlaced modes have a scanline pitch larger than the
             * limit.
             */
            if (pMode->Flags & V_INTERLACE)
                InterlacedSeen = TRUE;
            else
                InterlacedSeen = pATI->InterlacedSeen;

            if (InterlacedSeen &&
                (pScreenInfo->displayWidth > pATI->MaximumInterlacedPitch))
                return MODE_INTERLACE_WIDTH;

            pATI->InterlacedSeen = InterlacedSeen;
        }

        return MODE_OK;
    }

    /*
     * The following is done for every mode in the monitor section that
     * survives the common layer's basic checks.
     */
    if (pMode->VScan <= 1)
        VScan = 1;
    else
        VScan = pMode->VScan;

    if (pMode->Flags & V_DBLSCAN)
        VScan <<= 1;

    if (pATI->OptionPanelDisplay && (pATI->LCDPanelID >= 0))
    {
        if ((pMode->CrtcHDisplay > pATI->LCDHorizontal) ||
            (pMode->CrtcVDisplay > pATI->LCDVertical))
            return MODE_PANEL;

        if (!pATI->OptionLCDSync || (pMode->type & M_T_BUILTIN))
        {
            if ((pMode->HDisplay > pATI->LCDHorizontal) ||
                (pMode->VDisplay > pATI->LCDVertical))
                return MODE_PANEL;

            return MODE_OK;
        }

        /*
         * Adjust effective timings for monitor checks.  Here the modeline
         * clock is ignored.  Horizontal timings are scaled by the stretch
         * ratio used for the displayed area.  The vertical porch is scaled by
         * the native resolution's aspect ratio.  This seems rather arbitrary,
         * and it is, but it does make all applicable VESA modes sync on a
         * panel after stretching.  This has the unfortunate, but necessary,
         * side-effect of changing the mode's horizontal sync and vertical
         * refresh rates.  With some exceptions, this tends to increase the
         * mode's horizontal sync rate, and decrease its vertical refresh rate.
         */
        pMode->SynthClock = pATI->LCDClock;

        pMode->CrtcHTotal = pMode->CrtcHBlankEnd =
            ATIDivide(pMode->CrtcHTotal * pATI->LCDHorizontal,
                pMode->CrtcHDisplay, -3, 1) << 3;
        pMode->CrtcHSyncEnd =
            ATIDivide(pMode->CrtcHSyncEnd * pATI->LCDHorizontal,
                pMode->CrtcHDisplay, -3, 1) << 3;
        pMode->CrtcHSyncStart =
            ATIDivide(pMode->CrtcHSyncStart * pATI->LCDHorizontal,
                pMode->CrtcHDisplay, -3, -1) << 3;
        pMode->CrtcHDisplay = pMode->CrtcHBlankStart = pATI->LCDHorizontal;

        pMode->CrtcVTotal = pMode->CrtcVBlankEnd =
            ATIDivide((pMode->CrtcVTotal - pMode->CrtcVDisplay) *
                pATI->LCDVertical, pATI->LCDHorizontal, 0, 1) +
                pATI->LCDVertical;
        pMode->CrtcVSyncEnd =
            ATIDivide((pMode->CrtcVSyncEnd - pMode->CrtcVDisplay) *
                pATI->LCDVertical, pATI->LCDHorizontal, 0, 1) +
                pATI->LCDVertical;
        pMode->CrtcVSyncStart =
            ATIDivide((pMode->CrtcVSyncStart - pMode->CrtcVDisplay) *
                pATI->LCDVertical, pATI->LCDHorizontal, 0, -1) +
                pATI->LCDVertical;
        pMode->CrtcVDisplay = pMode->CrtcVBlankStart = pATI->LCDVertical;

        /*
         * The CRTC only stretches the mode's displayed area, not its porches.
         * Reverse-engineer the mode's timings back into the user specified
         * values so that the stretched mode is produced when the CRTC is
         * eventually programmed.  The reverse-engineered mode is then checked
         * against CRTC limits below.
         */
        pMode->Clock = pATI->LCDClock;

        HAdjust = pATI->LCDHorizontal - pMode->HDisplay;
#       define ATIReverseHorizontal(_x) \
            (pMode->_x - HAdjust)

        pMode->HSyncStart = ATIReverseHorizontal(CrtcHSyncStart);
        pMode->HSyncEnd = ATIReverseHorizontal(CrtcHSyncEnd);
        pMode->HTotal = ATIReverseHorizontal(CrtcHTotal);

        VInterlace = GetBits(pMode->Flags, V_INTERLACE) + 1;
#       define ATIReverseVertical(_y) \
            ((((pMode->_y - pATI->LCDVertical) * VInterlace) / VScan) + \
             pMode->VDisplay)

        pMode->VSyncStart = ATIReverseVertical(CrtcVSyncStart);
        pMode->VSyncEnd = ATIReverseVertical(CrtcVSyncEnd);
        pMode->VTotal = ATIReverseVertical(CrtcVTotal);

#       undef ATIReverseHorizontal
#       undef ATIReverseVertical
    }

    HBlankWidth = (pMode->HTotal >> 3) - (pMode->HDisplay >> 3);
    if (!HBlankWidth)
        return MODE_HBLANK_NARROW;

    switch (pATI->NewHW.crtc)
    {

#ifndef AVOID_CPIO

        case ATI_CRTC_VGA:
            /* Prevent overscans */
            if (HBlankWidth > 63)
                return MODE_HBLANK_WIDE;

            if (pMode->HDisplay > 2048)
                return MODE_BAD_HVALUE;

            if (VScan > 64)
                return MODE_BAD_VSCAN;

            VDisplay = pMode->VDisplay * VScan;
            VTotal = pMode->VTotal * VScan;

            if ((pMode->Flags & V_INTERLACE) && (pATI->Chip < ATI_CHIP_264CT))
            {
                VDisplay >>= 1;
                VTotal >>= 1;
            }

            if ((VDisplay > 2048) || (VTotal > 2050))
                return MODE_BAD_VVALUE;

            if (pATI->Adapter != ATI_ADAPTER_VGA)
                break;

            if ((VDisplay > 1024) || (VTotal > 1025))
                return MODE_BAD_VVALUE;

            break;

#endif /* AVOID_CPIO */

        case ATI_CRTC_MACH64:
            if (VScan > 2)
                return MODE_NO_VSCAN;

            break;

        default:
            break;
    }

    return MODE_OK;
}

--- NEW FILE: ativalid.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/ativalid.h,v 1.9 2003/10/30 17:36:58 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIVALID_H___
#define ___ATIVALID_H___ 1

#include "atiproto.h"

#include "xf86str.h"

extern ModeStatus ATIValidMode FunctionPrototype((int, DisplayModePtr, Bool,
                                                  int));

#endif /* ___ATIVALID_H___ */

--- NEW FILE: ativersion.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/ativersion.h,v 1.65tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIVERSION_H___
#define ___ATIVERSION_H___ 1

#undef  ATI_NAME
#undef  ATI_DRIVER_NAME
#undef  ATI_VERSION_MAJOR
#undef  ATI_VERSION_MINOR
#undef  ATI_VERSION_PATCH
#undef  ATI_VERSION_CURRENT
#undef  ATI_VERSION_EVALUATE
#undef  ATI_VERSION_STRINGIFY
#undef  ATI_VERSION_NAME

#define ATI_NAME          "ATI"
#define ATI_DRIVER_NAME   "ati"

#define ATI_VERSION_MAJOR 6
#define ATI_VERSION_MINOR 5
#define ATI_VERSION_PATCH 6

#ifndef ATI_VERSION_EXTRA
#define ATI_VERSION_EXTRA ""
#endif

#define ATI_VERSION_CURRENT \
    ((ATI_VERSION_MAJOR << 20) | (ATI_VERSION_MINOR << 10) | ATI_VERSION_PATCH)

#define ATI_VERSION_EVALUATE(__x) #__x
#define ATI_VERSION_STRINGIFY(_x) ATI_VERSION_EVALUATE(_x)
#define ATI_VERSION_NAME                                        \
    ATI_VERSION_STRINGIFY(ATI_VERSION_MAJOR) "."                \
    ATI_VERSION_STRINGIFY(ATI_VERSION_MINOR) "."                \
    ATI_VERSION_STRINGIFY(ATI_VERSION_PATCH) ATI_VERSION_EXTRA

#endif /* ___ATIVERSION_H___ */

--- NEW FILE: ativga.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/ativga.c,v 1.20 2003/04/23 21:51:31 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

#include "ati.h"
#include "atiadapter.h"
#include "atichip.h"
#include "atimono.h"
#include "atistruct.h"
#include "ativga.h"
#include "ativgaio.h"

#ifndef DPMS_SERVER
# define DPMS_SERVER
#endif
#include <X11/extensions/dpms.h>

#ifndef AVOID_CPIO

/*
 * ATIVGAPreInit --
 *
 * This function is called to set up VGA-related data that is common to all
 * video modes generated by the driver.
 */
void
ATIVGAPreInit
(
    ATIPtr      pATI,
    ATIHWPtr    pATIHW
)
{
    int Index;

    /* Initialise sequencer register values */
    pATIHW->seq[0] = 0x03U;
    if (pATI->depth == 1)
        pATIHW->seq[2] = 0x01U << BIT_PLANE;
    else
        pATIHW->seq[2] = 0x0FU;
    if (pATI->depth <= 4)
        pATIHW->seq[4] = 0x06U;
    else if (pATI->Adapter == ATI_ADAPTER_VGA)
        pATIHW->seq[4] = 0x0EU;
    else
        pATIHW->seq[4] = 0x0AU;

    /* Initialise CRTC register values */
    if ((pATI->depth >= 8) &&
        ((pATI->Chip >= ATI_CHIP_264CT) ||
         (pATI->CPIO_VGAWonder &&
          (pATI->Chip <= ATI_CHIP_18800_1) &&
          (pATI->VideoRAM == 256))))
        pATIHW->crt[19] = pATI->displayWidth >> 3;
    else
        pATIHW->crt[19] = pATI->displayWidth >> 4;
    if ((pATI->depth >= 8) && (pATI->Adapter == ATI_ADAPTER_VGA))
        pATIHW->crt[23] = 0xC3U;
    else
        pATIHW->crt[23] = 0xE3U;
    pATIHW->crt[24] = 0xFFU;

    /* Initialise attribute controller register values */
    if (pATI->depth == 1)
    {
        Bool FlipPixels = xf86GetFlipPixels();

        for (Index = 0;  Index < 16;  Index++)
            if (((Index & (0x01U << BIT_PLANE)) != 0) != FlipPixels)
                pATIHW->attr[Index] = MONO_WHITE;
            else
                pATIHW->attr[Index] = MONO_BLACK;
        pATIHW->attr[16] = 0x01U;
        pATIHW->attr[17] = MONO_OVERSCAN;
    }
    else
    {
        for (Index = 0;  Index < 16;  Index++)
            pATIHW->attr[Index] = Index;
        if (pATI->depth <= 4)
            pATIHW->attr[16] = 0x81U;
        else if (pATI->Adapter == ATI_ADAPTER_VGA)
            pATIHW->attr[16] = 0x41U;
        else
            pATIHW->attr[16] = 0x01U;
        pATIHW->attr[17] = 0xFFU;
    }
    pATIHW->attr[18] = 0x0FU;

    /* Initialise graphics controller register values */
    if (pATI->depth == 1)
        pATIHW->gra[4] = BIT_PLANE;
    else if (pATI->depth <= 4)
        pATIHW->gra[5] = 0x02U;
    else if (pATI->Chip >= ATI_CHIP_264CT)
        pATIHW->gra[5] = 0x40U;
    if (pATI->UseSmallApertures && (pATI->Chip >= ATI_CHIP_264CT) &&
        ((pATI->Chip >= ATI_CHIP_264VT) || !pATI->LinearBase))
        pATIHW->gra[6] = 0x01U;         /* 128kB aperture */
    else
        pATIHW->gra[6] = 0x05U;         /* 64kB aperture */
    pATIHW->gra[7] = 0x0FU;
    pATIHW->gra[8] = 0xFFU;
}

/*
 * ATIVGASave --
 *
 * This function is called to save the VGA portion of the current video state.
 */
void
ATIVGASave
(
    ATIPtr      pATI,
    ATIHWPtr    pATIHW
)
{
    int Index;

    /* Save miscellaneous output register */
    pATIHW->genmo = inb(R_GENMO);
    ATISetVGAIOBase(pATI, pATIHW->genmo);

    /* Save sequencer registers */
    for (Index = 0;  Index < NumberOf(pATIHW->seq);  Index++)
        pATIHW->seq[Index] = GetReg(SEQX, Index);

    /* Save CRTC registers */
    for (Index = 0;  Index < NumberOf(pATIHW->crt);  Index++)
        pATIHW->crt[Index] = GetReg(CRTX(pATI->CPIO_VGABase), Index);

    /* Save attribute controller registers */
    for (Index = 0;  Index < NumberOf(pATIHW->attr);  Index++)
    {
        (void)inb(GENS1(pATI->CPIO_VGABase));   /* Reset flip-flop */
        pATIHW->attr[Index] = GetReg(ATTRX, Index);
    }

    /* Save graphics controller registers */
    for (Index = 0;  Index < NumberOf(pATIHW->gra);  Index++)
        pATIHW->gra[Index] = GetReg(GRAX, Index);
}

/*
 * ATIVGACalculate --
 *
 * This function fills in the VGA portion of an ATIHWRec.
 */
void
ATIVGACalculate
(
    ATIPtr         pATI,
    ATIHWPtr       pATIHW,
    DisplayModePtr pMode
)
{
    int Index, VDisplay;

    /* If not already done, adjust horizontal timings */
    if (!pMode->CrtcHAdjusted)
    {
        pMode->CrtcHAdjusted = TRUE;
        pMode->CrtcHDisplay = (pMode->HDisplay >> 3) - 1;
        pMode->CrtcHBlankStart = (pMode->HDisplay >> 3);
        if ((pATI->Chip == ATI_CHIP_18800_1) ||
            (pATI->Chip >= ATI_CHIP_264CT))
            pMode->CrtcHBlankStart--;
        pMode->CrtcHSyncStart = pMode->HSyncStart >> 3;
        pMode->CrtcHSyncEnd = pMode->HSyncEnd >> 3;
        pMode->CrtcHBlankEnd = (pMode->HTotal >> 3) - 1;
        pMode->CrtcHTotal = (pMode->HTotal >> 3) - 5;
        pMode->CrtcHSkew = pMode->HSkew;

        /* Check sync pulse width */
        Index = pMode->CrtcHSyncEnd - pMode->CrtcHSyncStart - 0x1F;
        if (Index > 0)
        {
            pMode->CrtcHSyncStart += Index / 2;
            pMode->CrtcHSyncEnd = pMode->CrtcHSyncStart + 0x1F;
        }

        /* Check blank pulse width */
        Index = pMode->CrtcHBlankEnd - pMode->CrtcHBlankStart - 0x3F;
        if (Index > 0)
        {
            if ((pMode->CrtcHBlankEnd - Index) > pMode->CrtcHSyncEnd)
            {
                pMode->CrtcHBlankStart += Index / 2;
                if (pMode->CrtcHBlankStart >= pMode->CrtcHSyncStart)
                    pMode->CrtcHBlankStart = pMode->CrtcHSyncStart - 1;
                pMode->CrtcHBlankEnd = pMode->CrtcHBlankStart + 0x3F;
            }
            else
            {
                Index -= 0x40;
                if (Index > 0)
                {
                    pMode->CrtcHBlankStart += Index / 2;
                    if (pMode->CrtcHBlankStart >= pMode->CrtcHSyncStart)
                        pMode->CrtcHBlankStart = pMode->CrtcHSyncStart - 1;
                    pMode->CrtcHBlankEnd = pMode->CrtcHBlankStart + 0x7F;
                }
            }
        }
    }

    /*
     * Because of the use of CRTC[23] bit 0x04's for vertical doubling, it is
     * necessary to always re-adjust vertical timings here.
     */
    pMode->CrtcVDisplay = pMode->VDisplay;
    pMode->CrtcVBlankStart = pMode->VDisplay;
    pMode->CrtcVSyncStart = pMode->VSyncStart;
    pMode->CrtcVSyncEnd = pMode->VSyncEnd;
    pMode->CrtcVBlankEnd = pMode->VTotal;
    pMode->CrtcVTotal = pMode->VTotal;

    /* Adjust for doublescanned modes */
    if (pMode->Flags & V_DBLSCAN)
    {
        pMode->CrtcVDisplay <<= 1;
        pMode->CrtcVBlankStart <<= 1;
        pMode->CrtcVSyncStart <<= 1;
        pMode->CrtcVSyncEnd <<= 1;
        pMode->CrtcVBlankEnd <<= 1;
        pMode->CrtcVTotal <<= 1;
    }

    /* Adjust for multiscanned modes */
    if (pMode->VScan > 1)
    {
        pMode->CrtcVDisplay *= pMode->VScan;
        pMode->CrtcVBlankStart *= pMode->VScan;
        pMode->CrtcVSyncStart *= pMode->VScan;
        pMode->CrtcVSyncEnd *= pMode->VScan;
        pMode->CrtcVBlankEnd *= pMode->VScan;
        pMode->CrtcVTotal *= pMode->VScan;
    }

    /* Set up miscellaneous output register value */
    pATIHW->genmo = 0x23U;
    if ((pMode->Flags & (V_PHSYNC | V_NHSYNC)) &&
        (pMode->Flags & (V_PVSYNC | V_NVSYNC)))
    {
        if (pMode->Flags & V_NHSYNC)
            pATIHW->genmo |= 0x40U;
        if (pMode->Flags & V_NVSYNC)
            pATIHW->genmo |= 0x80U;
    }
    else
    {
        pMode->Flags &= ~(V_PHSYNC | V_NHSYNC | V_PVSYNC | V_NVSYNC);

        if (pATI->OptionPanelDisplay && (pATI->LCDPanelID >= 0))
            VDisplay = pATI->LCDVertical;
        else
            VDisplay = pMode->CrtcVDisplay;

        if (VDisplay < 400)
        {
            pMode->Flags |= V_PHSYNC | V_NVSYNC;
            pATIHW->genmo |= 0x80U;
        }
        else if (VDisplay < 480)
        {
            pMode->Flags |= V_NHSYNC | V_PVSYNC;
            pATIHW->genmo |= 0x40U;
        }
        else if (VDisplay < 768)
        {
            pMode->Flags |= V_NHSYNC | V_NVSYNC;
            pATIHW->genmo |= 0xC0U;
        }
        else
        {
            pMode->Flags |= V_PHSYNC | V_PVSYNC;
        }
    }

    /* Adjust for interlaced modes */
    if ((pMode->Flags & V_INTERLACE) && (pATI->Chip < ATI_CHIP_264CT))
    {
        pMode->CrtcVDisplay >>= 1;
        pMode->CrtcVBlankStart >>= 1;
        pMode->CrtcVSyncStart >>= 1;
        pMode->CrtcVSyncEnd >>= 1;
        pMode->CrtcVBlankEnd >>= 1;
        pMode->CrtcVTotal >>= 1;
    }

    if (pMode->CrtcVTotal > 1024)
    {
        pATIHW->crt[23] |= 0x04U;
        pMode->CrtcVDisplay >>= 1;
        pMode->CrtcVBlankStart >>= 1;
        pMode->CrtcVSyncStart >>= 1;
        pMode->CrtcVSyncEnd >>= 1;
        pMode->CrtcVBlankEnd >>= 1;
        pMode->CrtcVTotal >>= 1;
    }
    else
    {
        pATIHW->crt[23] &= ~0x04U;
    }

    pMode->CrtcVDisplay--;
    if (pATI->Chip == ATI_CHIP_18800)
        pMode->CrtcVBlankStart++;
    else
        pMode->CrtcVBlankStart--;
    pMode->CrtcVBlankEnd--;
    if (pATI->Chip < ATI_CHIP_264CT)
        pMode->CrtcVBlankEnd--;
    pMode->CrtcVTotal -= 2;
    pMode->CrtcVAdjusted = TRUE;        /* Redundant */

    /* Check sync pulse width */
    Index = pMode->CrtcVSyncEnd - pMode->CrtcVSyncStart - 0x0F;
    if (Index > 0)
    {
        pMode->CrtcVSyncStart += Index / 2;
        pMode->CrtcVSyncEnd = pMode->CrtcVSyncStart + 0x0F;
    }

    /* Check blank pulse width */
    Index = pMode->CrtcVBlankEnd - pMode->CrtcVBlankStart - 0x00FF;
    if (Index > 0)
    {
        if ((pMode->CrtcVBlankEnd - Index) > pMode->CrtcVSyncEnd)
        {
            pMode->CrtcVBlankStart += Index / 2;
            if (pMode->CrtcVBlankStart >= pMode->CrtcVSyncStart)
                pMode->CrtcVBlankStart = pMode->CrtcVSyncStart - 1;
            pMode->CrtcVBlankEnd = pMode->CrtcVBlankStart + 0x00FF;
        }
        else
        {
            Index -= 0x0100;
            if (Index > 0)
            {
                pMode->CrtcVBlankStart += Index / 2;
                if (pMode->CrtcVBlankStart >= pMode->CrtcVSyncStart)
                    pMode->CrtcVBlankStart = pMode->CrtcVSyncStart - 1;
                pMode->CrtcVBlankEnd = pMode->CrtcVBlankStart + 0x01FF;
            }
        }
    }

    /* Set up sequencer register values */
    if (pMode->Flags & V_CLKDIV2)
        pATIHW->seq[1] = 0x09U;
    else
        pATIHW->seq[1] = 0x01U;

    /* Set up CRTC register values */
    pATIHW->crt[0] = pMode->CrtcHTotal;
    pATIHW->crt[1] = pMode->CrtcHDisplay;
    pATIHW->crt[2] = pMode->CrtcHBlankStart;
    pATIHW->crt[3] = (pMode->CrtcHBlankEnd & 0x1FU) | 0x80U;
    Index = ((pMode->CrtcHSkew << 2) + 0x10U) & ~0x1FU;
    if (Index < 0x0080)
        pATIHW->crt[3] |= Index;
    pATIHW->crt[4] = pMode->CrtcHSyncStart;
    pATIHW->crt[5] = ((pMode->CrtcHBlankEnd & 0x20U) << 2) |
                     ((pMode->CrtcHSyncEnd & 0x1FU)      );
    pATIHW->crt[6] = pMode->CrtcVTotal & 0xFFU;
    pATIHW->crt[7] = ((pMode->CrtcVTotal & 0x0100U) >> 8) |
                     ((pMode->CrtcVDisplay & 0x0100U) >> 7) |
                     ((pMode->CrtcVSyncStart & 0x0100U) >> 6) |
                     ((pMode->CrtcVBlankStart & 0x0100U) >> 5) |
                     0x10U |
                     ((pMode->CrtcVTotal & 0x0200U) >> 4) |
                     ((pMode->CrtcVDisplay & 0x0200U) >> 3) |
                     ((pMode->CrtcVSyncStart & 0x0200U) >> 2);
    pATIHW->crt[9] = ((pMode->CrtcVBlankStart & 0x0200U) >> 4) | 0x40U;
    /*
     * Doublescanned modes are missing the top scanline.  Convert
     * doublescanning to multiscanning, using the doublescan bit only as a last
     * resort.
     */
    if ((Index = pMode->VScan) <= 0)
        Index = 1;
    if (pMode->Flags & V_DBLSCAN)
        Index <<= 1;
    Index--;
    pATIHW->crt[9] |= (Index & 0x1FU) | ((Index & 0x20U) << 2);
    pATIHW->crt[16] = pMode->CrtcVSyncStart & 0xFFU;
    pATIHW->crt[17] = (pMode->CrtcVSyncEnd & 0x0FU) | 0x20U;
    pATIHW->crt[18] = pMode->CrtcVDisplay & 0xFFU;
    pATIHW->crt[21] = pMode->CrtcVBlankStart & 0xFFU;
    pATIHW->crt[22] = pMode->CrtcVBlankEnd & 0xFFU;
}

/*
 * ATIVGASet --
 *
 * This function is called to load the VGA portion of a video state.
 */
void
ATIVGASet
(
    ATIPtr      pATI,
    ATIHWPtr    pATIHW
)
{
    int Index;

    /* Set VGA I/O base */
    ATISetVGAIOBase(pATI, pATIHW->genmo);

    /* Load miscellaneous output register */
    outb(GENMO, pATIHW->genmo);

    /* Load sequencer in reverse index order;  this also ends its reset */
    for (Index = NumberOf(pATIHW->seq);  --Index >= 0;  )
        PutReg(SEQX, Index, pATIHW->seq[Index]);

    /* Load CRTC registers */
    for (Index = 0;  Index < NumberOf(pATIHW->crt);  Index++)
        PutReg(CRTX(pATI->CPIO_VGABase), Index, pATIHW->crt[Index]);

    /* Load attribute controller registers */
    for (Index = 0;  Index < NumberOf(pATIHW->attr);  Index++)
    {
        (void)inb(GENS1(pATI->CPIO_VGABase));   /* Reset flip-flop & delay */
        outb(ATTRX, Index);
        outb(ATTRX, pATIHW->attr[Index]);
    }

    /* Load graphics controller registers */
    for (Index = 0;  Index < NumberOf(pATIHW->gra);  Index++)
        PutReg(GRAX, Index, pATIHW->gra[Index]);
}

/*
 * ATIVGASaveScreen --
 *
 * This function blanks or unblanks a VGA screen.
 */
void
ATIVGASaveScreen
(
    ATIPtr pATI,
    int    Mode
)
{
    (void)inb(GENS1(pATI->CPIO_VGABase));       /* Reset flip-flop */

    switch (Mode)
    {
        case SCREEN_SAVER_OFF:
        case SCREEN_SAVER_FORCER:
            outb(ATTRX, 0x20U);                /* Turn PAS on */
            break;

        case SCREEN_SAVER_ON:
        case SCREEN_SAVER_CYCLE:
            outb(ATTRX, 0x00U);                /* Turn PAS off */
            break;

        default:
            break;
    }
}

/*
 * ATIVGASetDPMSMode --
 *
 * This function sets a VGA's VESA Display Power Management Signaling mode.
 */
void
ATIVGASetDPMSMode
(
    ATIPtr pATI,
    int    DPMSMode
)
{
    CARD8 seq1, crt17;

    switch (DPMSMode)
    {
        case DPMSModeOn:        /* HSync on, VSync on */
            seq1 = 0x00U;
            crt17 = 0x80U;
            break;

        case DPMSModeStandby:   /* HSync off, VSync on -- unsupported */
            seq1 = 0x20U;
            crt17 = 0x80U;
            break;

        case DPMSModeSuspend:   /* HSync on, VSync off -- unsupported */
            seq1 = 0x20U;
            crt17 = 0x80U;
            break;

        case DPMSModeOff:       /* HSync off, VSync off */
            seq1 = 0x20U;
            crt17 = 0x00U;
            break;

        default:                /* Muffle compiler */
            return;
    }

    PutReg(SEQX, 0x00U, 0x01U); /* Start synchonous reset */
    seq1 |= GetReg(SEQX, 0x01U) & ~0x20U;
    PutReg(SEQX, 0x01U, seq1);
    crt17 |= GetReg(CRTX(pATI->CPIO_VGABase), 0x17U) & ~0x80U;
    usleep(10000);
    PutReg(CRTX(pATI->CPIO_VGABase), 0x17U, crt17);
    PutReg(SEQX, 0x01U, 0x03U); /* End synchonous reset */
}

#endif /* AVOID_CPIO */

--- NEW FILE: ativga.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/ativga.h,v 1.10 2003/01/01 19:16:34 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIVGA_H___
#define ___ATIVGA_H___ 1

#include "atipriv.h"
#include "atiproto.h"

#include "xf86str.h"

#ifndef AVOID_CPIO

extern void ATIVGAPreInit     FunctionPrototype((ATIPtr, ATIHWPtr));
extern void ATIVGASave        FunctionPrototype((ATIPtr, ATIHWPtr));
extern void ATIVGACalculate   FunctionPrototype((ATIPtr, ATIHWPtr,
                                                 DisplayModePtr));
extern void ATIVGASet         FunctionPrototype((ATIPtr, ATIHWPtr));

extern void ATIVGASaveScreen  FunctionPrototype((ATIPtr, int));
extern void ATIVGASetDPMSMode FunctionPrototype((ATIPtr, int));

#endif /* AVOID_CPIO */

#endif /* ___ATIVGA_H___ */

--- NEW FILE: ativgaio.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/ativgaio.c,v 1.4 2003/01/01 19:16:34 tsi Exp $ */
/*
 * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

#include "ati.h"
#include "atistruct.h"
#include "ativgaio.h"

#ifndef AVOID_CPIO

/*
 * ATISetVGAIOBase --
 *
 * This sets vgaIOBase according to the value of the passed value of the
 * miscellaneous output register.
 */
void
ATISetVGAIOBase
(
    ATIPtr      pATI,
    const CARD8 misc
)
{
    pATI->CPIO_VGABase = (misc & 0x01U) ? ColourIOBase : MonochromeIOBase;
}

#endif /* AVOID_CPIO */

--- NEW FILE: ativgaio.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/ativgaio.h,v 1.5 2003/01/01 19:16:34 tsi Exp $ */
/*
 * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIVGAIO_H___

#if !defined(___ATI_H___) && defined(XFree86Module)
# error missing #include "ati.h" before #include "ativgaio.h"
# undef XFree86Module
#endif

#define ___ATIVGAIO_H___ 1

#include "atiio.h"
#include "atipriv.h"
#include "atiproto.h"

#ifndef AVOID_CPIO

extern void ATISetVGAIOBase FunctionPrototype((ATIPtr, const CARD8));

/* Odds and ends to ease reading and writting of indexed registers */
#define GetReg(_Register, _Index) \
    (                             \
        outb(_Register, _Index),  \
        inb((_Register) + 1)      \
    )
#define PutReg(_Register, _Index, _Value) \
    do                                    \
    {                                     \
        outb(_Register, _Index);          \
        outb((_Register) + 1, _Value);    \
    } while (0)

#endif /* AVOID_CPIO */

#endif /* ___ATIVGAIO_H___ */

--- NEW FILE: atividmem.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atividmem.c,v 1.15 2003/04/23 21:51:31 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

#include "ati.h"
#include "atiadapter.h"
#include "atistruct.h"
#include "atividmem.h"

/* Memory types for 68800's and 88800GX's */
const char *ATIMemoryTypeNames_Mach[] =
{
    "DRAM (256Kx4)",
    "VRAM (256Kx4, x8, x16)",
    "VRAM (256Kx16 with short shift register)",
    "DRAM (256Kx16)",
    "Graphics DRAM (256Kx16)",
    "Enhanced VRAM (256Kx4, x8, x16)",
    "Enhanced VRAM (256Kx16 with short shift register)",
    "Unknown video memory type"
};

/* Memory types for 88800CX's */
const char *ATIMemoryTypeNames_88800CX[] =
{
    "DRAM (256Kx4, x8, x16)",
    "EDO DRAM (256Kx4, x8, x16)",
    "Unknown video memory type",
    "DRAM (256Kx16 with assymetric RAS/CAS)",
    "Unknown video memory type",
    "Unknown video memory type",
    "Unknown video memory type",
    "Unknown video memory type"
};

/* Memory types for 264xT's */
const char *ATIMemoryTypeNames_264xT[] =
{
    "Disabled video memory",
    "DRAM",
    "EDO DRAM",
    "Pseudo-EDO DRAM",
    "SDRAM (1:1)",
    "SGRAM (1:1)",
    "SGRAM (2:1) 32-bit",
    "Unknown video memory type"
};

#ifndef AVOID_CPIO

/*
 * ATIUnmapVGA --
 *
 * Unmap VGA aperture.
 */
static void
ATIUnmapVGA
(
    int    iScreen,
    ATIPtr pATI
)
{
    if (!pATI->pBank)
        return;

    xf86UnMapVidMem(iScreen, pATI->pBank, 0x00010000U);

    pATI->pBank = pATI->BankInfo.pBankA = pATI->BankInfo.pBankB = NULL;
}

#endif /* AVOID_CPIO */

/*
 * ATIUnmapLinear --
 *
 * Unmap linear aperture.
 */
static void
ATIUnmapLinear
(
    int    iScreen,
    ATIPtr pATI
)
{

#ifdef AVOID_CPIO

    if (!pATI->pMemory)
        return;

#else /* AVOID_CPIO */

    if (pATI->pMemory != pATI->pBank)

#endif /* AVOID_CPIO */

    {
        xf86UnMapVidMem(iScreen, pATI->pMemory, pATI->LinearSize);

#if X_BYTE_ORDER != X_LITTLE_ENDIAN

        if (pATI->pMemoryLE)
            xf86UnMapVidMem(iScreen, pATI->pMemoryLE, pATI->LinearSize);

#endif /* X_BYTE_ORDER */

    }

    pATI->pMemory = pATI->pMemoryLE = NULL;
}

/*
 * ATIUnmapMMIO --
 *
 * Unmap MMIO registers.
 */
static void
ATIUnmapMMIO
(
    int    iScreen,
    ATIPtr pATI
)
{
    if (pATI->pMMIO)
        xf86UnMapVidMem(iScreen, pATI->pMMIO, getpagesize());

    pATI->pMMIO = pATI->pBlock[0] = pATI->pBlock[1] = NULL;
}

/*
 * ATIUnmapCursor --
 *
 * Unmap hardware cursor image area.
 */
static void
ATIUnmapCursor
(
    int    iScreen,
    ATIPtr pATI
)
{
    if (pATI->pCursorPage)
        xf86UnMapVidMem(iScreen, pATI->pCursorPage, getpagesize());

    pATI->pCursorPage = pATI->pCursorImage = NULL;
}

/*
 * ATIMapApertures --
 *
 * This function maps all apertures used by the driver.
 */
Bool
ATIMapApertures
(
    int    iScreen,
    ATIPtr pATI
)
{
    pciVideoPtr   pVideo;
    PCITAG        Tag;
    unsigned long PageSize;

    if (pATI->Mapped)
        return TRUE;

#ifndef AVOID_CPIO

    if (pATI->VGAAdapter == ATI_ADAPTER_NONE)

#endif /* AVOID_CPIO */

    {
        if (!pATI->LinearBase && !pATI->Block0Base)
            return FALSE;
    }

    PageSize = getpagesize();

    if ((pVideo = pATI->PCIInfo))
        Tag = ((pciConfigPtr)(pVideo->thisCard))->tag;
    else
        Tag = 0;

#ifndef AVOID_CPIO

    /* Map VGA aperture */
    if (pATI->VGAAdapter != ATI_ADAPTER_NONE)
    {
        /*
         * No relocation, resizing, caching or write-combining of this
         * aperture is supported.  Hence, the hard-coded values here...
         */
        if (pVideo)
            pATI->pBank = xf86MapPciMem(iScreen, VIDMEM_MMIO,
                Tag, 0x000A0000U, 0x00010000U);
        else
            pATI->pBank = xf86MapVidMem(iScreen, VIDMEM_MMIO,
                0x000A0000U, 0x00010000U);

        if (!pATI->pBank)
            return FALSE;

        pATI->pMemory =
            pATI->BankInfo.pBankA =
            pATI->BankInfo.pBankB = pATI->pBank;

        pATI->Mapped = TRUE;
    }

#endif /* AVOID_CPIO */

    /* Map linear aperture */
    if (pATI->LinearBase)
    {
        if (pVideo)
            pATI->pMemory = xf86MapPciMem(iScreen, VIDMEM_FRAMEBUFFER,
                Tag, pATI->LinearBase, pATI->LinearSize);
        else
            pATI->pMemory = xf86MapVidMem(iScreen, VIDMEM_FRAMEBUFFER,
                pATI->LinearBase, pATI->LinearSize);

        if (!pATI->pMemory)
        {

#ifndef AVOID_CPIO

            ATIUnmapVGA(iScreen, pATI);

#endif /* AVOID_CPIO */

            pATI->Mapped = FALSE;
            return FALSE;
        }

        pATI->Mapped = TRUE;

#if X_BYTE_ORDER == X_LITTLE_ENDIAN

        if ((pATI->CursorBase >= pATI->LinearBase) &&
            ((pATI->CursorOffset + 0x00000400UL) <= (CARD32)pATI->LinearSize))
            pATI->pCursorImage = (char *)pATI->pMemory + pATI->CursorOffset;

        pATI->pMemoryLE = pATI->pMemory;

#else /* if X_BYTE_ORDER != X_LITTLE_ENDIAN */

        /*
         * Map the little-endian aperture (used for video, etc.).  Note that
         * caching of this area is _not_ wanted.
         */
        if (pVideo)
        {
            pATI->pMemoryLE = xf86MapPciMem(iScreen, VIDMEM_MMIO, Tag,
                pATI->LinearBase - 0x00800000U, pATI->LinearSize);

            if (!pATI->pMemoryLE)
            {
                ATIUnmapLinear(iScreen, pATI);

#ifndef AVOID_CPIO

                ATIUnmapVGA(iScreen, pATI);

#endif /* AVOID_CPIO */

                pATI->Mapped = FALSE;
                return FALSE;
            }
        }

#endif /* X_BYTE_ORDER */

    }

    /* Map MMIO aperture */
    if (pATI->Block0Base)
    {
        unsigned long MMIOBase = pATI->Block0Base & ~(PageSize - 1);

        if (pVideo)
            pATI->pMMIO = xf86MapPciMem(iScreen, VIDMEM_MMIO,
                Tag, MMIOBase, PageSize);
        else
            pATI->pMMIO = xf86MapVidMem(iScreen, VIDMEM_MMIO,
                MMIOBase, PageSize);

        if (!pATI->pMMIO)
        {

#if X_BYTE_ORDER == X_LITTLE_ENDIAN

            ATIUnmapCursor(iScreen, pATI);

#endif /* X_BYTE_ORDER */

            ATIUnmapLinear(iScreen, pATI);

#ifndef AVOID_CPIO

            ATIUnmapVGA(iScreen, pATI);

#endif /* AVOID_CPIO */

            pATI->Mapped = FALSE;
            return FALSE;
        }

        pATI->Mapped = TRUE;

        pATI->pBlock[0] = (char *)pATI->pMMIO +
            (pATI->Block0Base - MMIOBase);

        if (pATI->Block1Base)
            pATI->pBlock[1] = (char *)pATI->pBlock[0] - 0x00000400U;

#if X_BYTE_ORDER == X_LITTLE_ENDIAN

        if (!pATI->pCursorImage)

#endif /* X_BYTE_ORDER */

        {
            if ((pATI->CursorBase >= MMIOBase) &&
                ((pATI->CursorBase + 0x00000400UL) <= (MMIOBase + PageSize)))
                pATI->pCursorImage = (char *)pATI->pMMIO +
                    (pATI->CursorBase - MMIOBase);
        }
    }

    /* Map hardware cursor image area */
    if (pATI->CursorBase && !pATI->pCursorImage)
    {
        unsigned long CursorBase = pATI->CursorBase & ~(PageSize - 1);

        if (pVideo)
            pATI->pCursorPage = xf86MapPciMem(iScreen, VIDMEM_FRAMEBUFFER,
                Tag, CursorBase, PageSize);
        else
            pATI->pCursorPage = xf86MapVidMem(iScreen, VIDMEM_FRAMEBUFFER,
                CursorBase, PageSize);

        if (!pATI->pCursorPage)
        {
            ATIUnmapCursor(iScreen, pATI);
            ATIUnmapMMIO(iScreen, pATI);
            ATIUnmapLinear(iScreen, pATI);

#ifndef AVOID_CPIO

            ATIUnmapVGA(iScreen, pATI);

#endif /* AVOID_CPIO */

            pATI->Mapped = FALSE;
            return FALSE;
        }

        pATI->pCursorImage = (char *)pATI->pCursorPage +
            (pATI->CursorBase - CursorBase);
    }

    return TRUE;
}

/*
 * ATIUnmapApertures --
 *
 * This function unmaps all apertures used by the driver.
 */
void
ATIUnmapApertures
(
    int    iScreen,
    ATIPtr pATI
)
{
    if (!pATI->Mapped)
        return;
    pATI->Mapped = FALSE;

    /* Unmap hardware cursor image area */
    ATIUnmapCursor(iScreen, pATI);

    /* Unmap MMIO area */
    ATIUnmapMMIO(iScreen, pATI);

    /* Unmap linear aperture */
    ATIUnmapLinear(iScreen, pATI);

#ifndef AVOID_CPIO

    /* Unmap VGA aperture */
    ATIUnmapVGA(iScreen, pATI);

#endif /* AVOID_CPIO */

}

--- NEW FILE: atividmem.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atividmem.h,v 1.9 2003/01/01 19:16:35 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIVIDMEM_H___
#define ___ATIVIDMEM_H___ 1

#include "atiproto.h"
#include "atipriv.h"

/* Memory types for 68800's and 88800GX's */
typedef enum
{
    MEM_MACH_DRAMx4,
    MEM_MACH_VRAM,
    MEM_MACH_VRAMssr,
    MEM_MACH_DRAMx16,
    MEM_MACH_GDRAM,
    MEM_MACH_EVRAM,
    MEM_MACH_EVRAMssr,
    MEM_MACH_TYPE_7
} ATIMachMemoryType;
extern const char *ATIMemoryTypeNames_Mach[];

/* Memory types for 88800CX's */
typedef enum
{
    MEM_CX_DRAM,
    MEM_CX_EDO,
    MEM_CX_TYPE_2,
    MEM_CX_DRAM_A,
    MEM_CX_TYPE_4,
    MEM_CX_TYPE_5,
    MEM_CX_TYPE_6,
    MEM_CX_TYPE_7
} ATICXMemoryType;
extern const char *ATIMemoryTypeNames_88800CX[];

/* Memory types for 264xT's */
typedef enum
{
    MEM_264_NONE,
    MEM_264_DRAM,
    MEM_264_EDO,
    MEM_264_PSEUDO_EDO,
    MEM_264_SDRAM,
    MEM_264_SGRAM,
    MEM_264_SGRAM32,
    MEM_264_TYPE_7
} ATI264MemoryType;
extern const char *ATIMemoryTypeNames_264xT[];

extern Bool ATIMapApertures   FunctionPrototype((int, ATIPtr));
extern void ATIUnmapApertures FunctionPrototype((int, ATIPtr));

#endif /* ___ATIVIDMEM_H___ */

--- NEW FILE: atiwonder.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiwonder.c,v 1.14 2003/01/01 19:16:35 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

/*
 * The ATI x8800 chips use special registers for their extended VGA features.
 * These registers are accessible through an index I/O port and a data I/O
 * port.  BIOS initialisation stores the index port number in the Graphics
 * register bank (0x03CE), indices 0x50 and 0x51.  Unfortunately, for all but
 * the 18800-x series of adapters, these registers are write-only (a.k.a. black
 * holes).  On all but 88800's, the index port number can be found in the short
 * integer at offset 0x10 in the BIOS.  For 88800's, this driver will use
 * 0x01CE or 0x03CE as the index port number, depending on the I/O port
 * decoding used.  The data port number is one more than the index port number
 * (i.e. 0x01CF).  These ports differ slightly in their I/O behaviour from the
 * normal VGA ones:
 *
 *    write:  outw(0x01CE, (data << 8) | index);        (16-bit, not used)
 *            outb(0x01CE, index);  outb(0x01CF, data); (8-bit)
 *    read:   outb(0x01CE, index);  data = inb(0x01CF);
 *
 * Two consecutive byte-writes to the data port will not work.  Furthermore an
 * index written to 0x01CE is usable only once.  Note also that the setting of
 * ATI extended registers (especially those with clock selection bits) should
 * be bracketed by a sequencer reset.
 *
 * The number of these extended VGA registers varies by chipset.  The 18800
 * series have 16, the 28800 series have 32, while 68800's and 88800's have 64.
 * The last 16 on each have almost identical definitions.  Thus, the BIOS sets
 * up an indexing scheme whereby the last 16 extended VGA registers are
 * accessed at indices 0xB0 through 0xBF on all chipsets.
 */

#include "ati.h"
#include "atichip.h"
#include "atiwonder.h"
#include "atiwonderio.h"

#ifndef AVOID_CPIO

/*
 * ATIVGAWonderPreInit --
 *
 * This function is called to initialise the VGA Wonder part of an ATIHWRec
 * that is common to all modes generated by the driver.
 */
void
ATIVGAWonderPreInit
(
    ATIPtr      pATI,
    ATIHWPtr    pATIHW
)
{
    pATIHW->b3 = ATIGetExtReg(0xB3U) & 0x20U;
    if (pATI->depth <= 4)
        pATIHW->b6 = 0x40U;
    else
        pATIHW->b6 = 0x04U;
    if (pATI->Chip <= ATI_CHIP_18800)
        pATIHW->ba = 0x08U;
    else if (pATI->Chip >= ATI_CHIP_28800_2)
    {
        if (pATI->VideoRAM > 256)
            pATIHW->b6 |= 0x01U;
        pATIHW->bf = ATIGetExtReg(0xBFU) & 0x5FU;
        pATIHW->a3 = ATIGetExtReg(0xA3U) & 0x67U;
        pATIHW->ab = ATIGetExtReg(0xABU) & 0xE7U;
        pATIHW->ae = ATIGetExtReg(0xAEU) & 0xE0U;
    }
}

/*
 * ATIVGAWonderSave --
 *
 * This function is called to save the VGA Wonder portion of the current video
 * state.
 */
void
ATIVGAWonderSave
(
    ATIPtr      pATI,
    ATIHWPtr    pATIHW
)
{
    pATIHW->b0 = ATIGetExtReg(0xB0U);
    pATIHW->b1 = ATIGetExtReg(0xB1U);
    pATIHW->b2 = ATIGetExtReg(0xB2U);
    pATIHW->b3 = ATIGetExtReg(0xB3U);
    pATIHW->b5 = ATIGetExtReg(0xB5U);
    pATIHW->b6 = ATIGetExtReg(0xB6U);
    pATIHW->b8 = ATIGetExtReg(0xB8U);
    pATIHW->b9 = ATIGetExtReg(0xB9U);
    pATIHW->ba = ATIGetExtReg(0xBAU);
    pATIHW->bd = ATIGetExtReg(0xBDU);
    if (pATI->Chip > ATI_CHIP_18800)
    {
        pATIHW->be = ATIGetExtReg(0xBEU);
        if (pATI->Chip >= ATI_CHIP_28800_2)
        {
            pATIHW->bf = ATIGetExtReg(0xBFU);
            pATIHW->a3 = ATIGetExtReg(0xA3U);
            pATIHW->a6 = ATIGetExtReg(0xA6U);
            pATIHW->a7 = ATIGetExtReg(0xA7U);
            pATIHW->ab = ATIGetExtReg(0xABU);
            pATIHW->ac = ATIGetExtReg(0xACU);
            pATIHW->ad = ATIGetExtReg(0xADU);
            pATIHW->ae = ATIGetExtReg(0xAEU);
        }
    }
}

/*
 * ATIVGAWonderCalculate --
 *
 * This function fills in the VGA Wonder portion of an ATIHWRec structure
 * occurrence.
 */
void
ATIVGAWonderCalculate
(
    ATIPtr         pATI,
    ATIHWPtr       pATIHW,
    DisplayModePtr pMode
)
{
    /* Set up the default horizontal display enable skew */
    if ((pATI->Chip >= ATI_CHIP_28800_2) && (pATI->Chip <= ATI_CHIP_28800_6) &&
        !(pMode->Flags & V_HSKEW))
    {
        /*
         * Modes using the higher clock frequencies need a non-zero Display
         * Enable Skew.  The following number has been empirically determined
         * to be somewhere between 4.2 and 4.7 MHz.
         */
#       define DisplayEnableSkewThreshold 4500

        /* Set a reasonable default Display Enable Skew */
        pMode->HSkew = pMode->CrtcHSkew =
            ATIDivide(pMode->SynthClock, DisplayEnableSkewThreshold, 0, 0);
    }
    pMode->Flags |= V_HSKEW;

    /*
     * Fill in mode-specific VGA Wonder data.
     */
    pATIHW->b0 = 0x00U;
    if (pATI->depth >= 8)
        pATIHW->b0 = 0x20U;
    if (pATI->Chip >= ATI_CHIP_28800_2)
    {
        if (pATI->VideoRAM > 512)
            pATIHW->b0 |= 0x08U;
        else if (pATI->VideoRAM > 256)
            pATIHW->b0 |= 0x10U;
    }
    else if (pATI->depth <= 4)
    {
        if (pATI->VideoRAM > 256)
            pATIHW->b0 |= 0x08U;
    }
    else
    {
        if (pATI->VideoRAM > 256)
            pATIHW->b0 |= 0x18U;
        else
            pATIHW->b0 |= 0x06U;
    }
    pATIHW->b1 = ATIGetExtReg(0xB1U) & 0x04U;
    /*
     * Setting the following bit causes hangs on return to text mode from
     * packed modes on 18800-1's.  The hang occurs because the adapter's I/O
     * response is completely disabled when the register is rewritten.  The
     * adapter can then only be re-enabled with a powerdown.  The bit, when on,
     * blanks out the overscan.
     */
    if ((pATI->Chip == ATI_CHIP_18800_1) && (pATI->depth >= 8))
        pATIHW->b5 = 0x00U;
    else
        pATIHW->b5 = 0x01U;
    pATIHW->b8 = ATIGetExtReg(0xB8U) & 0xC0U;
    pATIHW->b9 = ATIGetExtReg(0xB9U) & 0x7FU;
    pATIHW->bd = ATIGetExtReg(0xBDU) & 0x02U;
    if (pATI->Chip <= ATI_CHIP_18800)
        pATIHW->b2 = ATIGetExtReg(0xB2U) & 0xC0U;
    else
    {
        pATIHW->b2 = 0x00U;
        pATIHW->be = (ATIGetExtReg(0xBEU) & 0x30U) | 0x09U;
        if (pATI->Chip >= ATI_CHIP_28800_2)
        {
            pATIHW->a6 = (ATIGetExtReg(0xA6U) & 0x38U) | 0x04U;
            pATIHW->a7 = (ATIGetExtReg(0xA7U) & 0xBEU)        ;
            pATIHW->ac = (ATIGetExtReg(0xACU) & 0x8EU)        ;
        }
    }
    if (pMode->Flags & V_INTERLACE)
    {                                   /* Enable interlace */
        if (pATI->Chip <= ATI_CHIP_18800)
            pATIHW->b2 |= 0x01U;
        else
            pATIHW->be |= 0x02U;
    }
#if 0   /* This is no longer needed but is left in for reference */
    if (pMode->Flags & V_DBLSCAN)       /* Enable doublescan */
        pATIHW->b1 |= 0x08U;
#endif
    if (pATI->OptionCSync || (pMode->Flags & (V_CSYNC | V_PCSYNC)))
        pATIHW->bd |= 0x08U;            /* Enable composite sync */
    if (pMode->Flags & V_NCSYNC)
        pATIHW->bd |= 0x09U;            /* Invert composite sync */
    if (pMode->HSkew > 0)
    {
        if (pMode->HSkew <= 3)
            pATIHW->b5 |= 0x04U;
        else if (pATI->Chip >= ATI_CHIP_28800_2)
            switch ((pMode->HSkew + 4) >> 3)
            {
                case 1:         /* Use ATI override */
                    pATIHW->crt[3] &= ~0x60U;
                    pATIHW->b0 |= 0x01U;
                    break;
                case 2:         /* Use ATI override */
                    pATIHW->crt[3] &= ~0x60U;
                    pATIHW->a6 |= 0x01U;
                    break;
                case 3:
                    pATIHW->crt[3] |= 0x60U;
                    break;
                case 4:
                    pATIHW->a7 |= 0x40U;
                    break;
                case 5:
                    pATIHW->ac |= 0x10U;
                    break;
                case 6:
                    pATIHW->ac |= 0x20U;
                    break;
                default:
                    break;
            }
    }
}

/*
 * ATIVGAWonderSet --
 *
 * This function loads the VGA Wonder portion of a video state.
 */
void
ATIVGAWonderSet
(
    ATIPtr      pATI,
    ATIHWPtr    pATIHW
)
{
    if (pATI->Chip <= ATI_CHIP_18800)
        ATIModifyExtReg(pATI, 0xB2U, -1, 0x00U, pATIHW->b2);
    else
    {
        ATIModifyExtReg(pATI, 0xBEU, -1, 0x00U, pATIHW->be);
        if (pATI->Chip >= ATI_CHIP_28800_2)
        {
            ATIModifyExtReg(pATI, 0xBFU, -1, 0x00U, pATIHW->bf);
            ATIModifyExtReg(pATI, 0xA3U, -1, 0x00U, pATIHW->a3);
            ATIModifyExtReg(pATI, 0xA6U, -1, 0x00U, pATIHW->a6);
            ATIModifyExtReg(pATI, 0xA7U, -1, 0x00U, pATIHW->a7);
            ATIModifyExtReg(pATI, 0xABU, -1, 0x00U, pATIHW->ab);
            ATIModifyExtReg(pATI, 0xACU, -1, 0x00U, pATIHW->ac);
            ATIModifyExtReg(pATI, 0xADU, -1, 0x00U, pATIHW->ad);
            ATIModifyExtReg(pATI, 0xAEU, -1, 0x00U, pATIHW->ae);
        }
    }
    ATIModifyExtReg(pATI, 0xB0U, -1, 0x00U, pATIHW->b0);
    ATIModifyExtReg(pATI, 0xB1U, -1, 0x00U, pATIHW->b1);
    ATIModifyExtReg(pATI, 0xB3U, -1, 0x00U, pATIHW->b3);
    ATIModifyExtReg(pATI, 0xB5U, -1, 0x00U, pATIHW->b5);
    ATIModifyExtReg(pATI, 0xB6U, -1, 0x00U, pATIHW->b6);
    ATIModifyExtReg(pATI, 0xB8U, -1, 0x00U, pATIHW->b8);
    ATIModifyExtReg(pATI, 0xB9U, -1, 0x00U, pATIHW->b9);
    ATIModifyExtReg(pATI, 0xBAU, -1, 0x00U, pATIHW->ba);
    ATIModifyExtReg(pATI, 0xBDU, -1, 0x00U, pATIHW->bd);
}

#endif /* AVOID_CPIO */

--- NEW FILE: atiwonder.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiwonder.h,v 1.9 2003/01/01 19:16:35 tsi Exp $ */
/*
 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIWONDER_H___
#define ___ATIWONDER_H___ 1

#include "atipriv.h"
#include "atiproto.h"

#include "xf86str.h"

#ifndef AVOID_CPIO

extern void ATIVGAWonderPreInit   FunctionPrototype((ATIPtr, ATIHWPtr));
extern void ATIVGAWonderSave      FunctionPrototype((ATIPtr, ATIHWPtr));
extern void ATIVGAWonderCalculate FunctionPrototype((ATIPtr, ATIHWPtr,
                                                     DisplayModePtr));
extern void ATIVGAWonderSet       FunctionPrototype((ATIPtr, ATIHWPtr));

#endif /* AVOID_CPIO */

#endif /* ___ATIWONDER_H___ */

--- NEW FILE: atiwonderio.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiwonderio.c,v 1.4 2003/01/01 19:16:35 tsi Exp $ */
/*
 * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

#include "ati.h"
#include "atichip.h"
#include "atiwonderio.h"

#ifndef AVOID_CPIO

/*
 * ATIModifyExtReg --
 *
 * This function is called to modify certain bits in an ATI extended VGA
 * register while preserving its other bits.  The function will not write the
 * register if it turns out its value would not change.  This helps prevent
 * server hangs on older adapters.
 */
void
ATIModifyExtReg
(
    ATIPtr      pATI,
    const CARD8 Index,
    int         CurrentValue,
    const CARD8 CurrentMask,
    CARD8       NewValue
)
{
    /* Possibly retrieve the current value */
    if (CurrentValue < 0)
        CurrentValue = ATIGetExtReg(Index);

    /* Compute new value */
    NewValue &= (CARD8)(~CurrentMask);
    NewValue |= CurrentValue & CurrentMask;

    /* Check if value will be changed */
    if (CurrentValue == NewValue)
        return;

    /*
     * The following is taken from ATI's VGA Wonder programmer's reference
     * manual which says that this is needed to "ensure the proper state of the
     * 8/16 bit ROM toggle".  I suspect a timing glitch appeared in the 18800
     * after its die was cast.  18800-1 and later chips do not exhibit this
     * problem.
     */
    if ((pATI->Chip <= ATI_CHIP_18800) && (Index == 0xB2U) &&
       ((NewValue ^ 0x40U) & CurrentValue & 0x40U))
    {
        CARD8 misc = inb(R_GENMO);
        CARD8 bb = ATIGetExtReg(0xBBU);

        outb(GENMO, (misc & 0xF3U) | 0x04U | ((bb & 0x10U) >> 1));
        CurrentValue &= (CARD8)(~0x40U);
        ATIPutExtReg(0xB2U, CurrentValue);
        ATIDelay(5);
        outb(GENMO, misc);
        ATIDelay(5);
        if (CurrentValue != NewValue)
            ATIPutExtReg(0xB2U, NewValue);
    }
    else
        ATIPutExtReg(Index, NewValue);
}

#endif /* AVOID_CPIO */

--- NEW FILE: atiwonderio.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiwonderio.h,v 1.4 2003/01/01 19:16:35 tsi Exp $ */
/*
 * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIWONDERIO_H___

#if !defined(___ATI_H___) && defined(XFree86Module)
# error missing #include "ati.h" before #include "atiwonderio.h"
# undef XFree86Module
#endif

#define ___ATIWONDERIO_H___ 1

#include "atistruct.h"
#include "ativgaio.h"

#ifndef AVOID_CPIO

extern void ATIModifyExtReg FunctionPrototype((ATIPtr, const CARD8, int,
                                               const CARD8, CARD8));

#define ATIGetExtReg(_Index)                    \
    GetReg(pATI->CPIO_VGAWonder, _Index)
#define ATIPutExtReg(_Index, _Value)            \
    PutReg(pATI->CPIO_VGAWonder, _Index, _Value)

#endif /* AVOID_CPIO */

#endif /* ___ATIWONDERIO_H___ */

--- NEW FILE: atixv.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atixv.c,v 1.5 2003/04/25 04:09:54 tsi Exp $ */
/*
 * Copyright 2001 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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.
 */

#include "atiadapter.h"
#include "atimach64xv.h"
#include "atistruct.h"
#include "atixv.h"

/*
 * ATIXVFreeAdaptorInfo --
 *
 * Free XVideo adaptor information.
 */
static void
ATIXVFreeAdaptorInfo
(
    XF86VideoAdaptorPtr *ppAdaptor,
    int                 nAdaptor
)
{
    if (!ppAdaptor)
        return;

    while (nAdaptor > 0)
        xfree(ppAdaptor[--nAdaptor]);

    xfree(ppAdaptor);
}

/*
 * ATIXVInitializeAdaptor --
 *
 * This is called by the server's XVideo support layer to initialise an XVideo
 * adapter.
 */
static int
ATIXVInitializeAdaptor
(
    ScrnInfoPtr         pScreenInfo,
    XF86VideoAdaptorPtr **pppAdaptor
)
{
    ScreenPtr           pScreen    = screenInfo.screens[pScreenInfo->scrnIndex];
    ATIPtr              pATI       = ATIPTR(pScreenInfo);
    XF86VideoAdaptorPtr *ppAdaptor = NULL;
    int                 nAdaptor;

    switch (pATI->Adapter)
    {
        case ATI_ADAPTER_MACH64:
            nAdaptor = ATIMach64XVInitialiseAdaptor(pScreen, pScreenInfo, pATI,
                &ppAdaptor);
            break;

        default:
            nAdaptor = 0;
            break;
    }

    if (pppAdaptor)
        *pppAdaptor = ppAdaptor;
    else
        ATIXVFreeAdaptorInfo(ppAdaptor, nAdaptor);

    return nAdaptor;
}

/*
 * ATIXVPreInit --
 *
 * This function is called by ATIPreInit() to set up the environment required
 * to support the XVideo extension.
 */
void
ATIXVPreInit
(
    ATIPtr      pATI
)
{

#ifndef AVOID_CPIO

    /* Currently a linear aperture is needed ... */
    if (!pATI->LinearBase)
        return;

#endif /* AVOID_CPIO */

    (void)xf86XVRegisterGenericAdaptorDriver(ATIXVInitializeAdaptor);
}

/*
 * ATIInitializeXVideo --
 *
 * This function is called to initialise XVideo extension support on a screen.
 */
Bool
ATIInitializeXVideo
(
    ScreenPtr   pScreen,
    ScrnInfoPtr pScreenInfo,
    ATIPtr      pATI
)
{
    XF86VideoAdaptorPtr *ppAdaptor;
    int                 nAdaptor;
    Bool                result;

    if (!(pScreenInfo->memPhysBase = pATI->LinearBase))
        return FALSE;

    pScreenInfo->fbOffset = 0;

    nAdaptor = xf86XVListGenericAdaptors(pScreenInfo, &ppAdaptor);
    result = xf86XVScreenInit(pScreen, ppAdaptor, nAdaptor);

    ATIXVFreeAdaptorInfo(ppAdaptor, nAdaptor);

    return result;
}

/*
 * ATICloseXVideo --
 *
 * This function is called during screen termination to clean up after XVideo
 * initialisation.
 */
void
ATICloseXVideo
(
    ScreenPtr   pScreen,
    ScrnInfoPtr pScreenInfo,
    ATIPtr      pATI
)
{
    switch (pATI->Adapter)
    {
        case ATI_ADAPTER_MACH64:
            ATIMach64CloseXVideo(pScreen, pScreenInfo, pATI);
            break;

        default:
            break;
    }
}

--- NEW FILE: atixv.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atixv.h,v 1.4 2003/04/23 21:51:31 tsi Exp $ */
/*
 * Copyright 2001 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 ___ATIXV_H___
#define ___ATIXV_H___ 1

#include "atipriv.h"
#include "atiproto.h"

#include "xf86str.h"

extern void ATIXVPreInit        FunctionPrototype((ATIPtr));
extern Bool ATIInitializeXVideo FunctionPrototype((ScreenPtr, ScrnInfoPtr,
                                                   ATIPtr));
extern void ATICloseXVideo      FunctionPrototype((ScreenPtr, ScrnInfoPtr,
                                                   ATIPtr));

#endif /* ___ATIXV_H___ */

--- NEW FILE: r128.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h,v 1.26 2003/11/06 18:37:58 tsi Exp $ */
/*
 * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario,
 *                      Precision Insight, Inc., Cedar Park, Texas, and
 *                      VA Linux Systems Inc., Fremont, 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, PRECISION INSIGHT, 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:
 *   Rickard E. Faith <faith at valinux.com>
 *   Kevin E. Martin <martin at valinux.com>
 *
 */

#ifndef _R128_H_
#define _R128_H_

#include "xf86str.h"

				/* PCI support */
#include "xf86Pci.h"

				/* XAA and Cursor Support */
#include "xaa.h"
#include "xf86Cursor.h"

				/* DDC support */
#include "xf86DDC.h"

				/* Xv support */
#include "xf86xv.h"

				/* DRI support */
#ifdef XF86DRI
#define _XF86DRI_SERVER_
#include "r128_dripriv.h"
#include "dri.h"
#include "GL/glxint.h"
#endif

#define R128_DEBUG          0   /* Turn off debugging output               */
#define R128_IDLE_RETRY    32   /* Fall out of idle loops after this count */
#define R128_TIMEOUT  2000000   /* Fall out of wait loops after this count */
#define R128_MMIOSIZE  0x4000

#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;
    CARD32     config_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;
    CARD32     tmds_transmitter_cntl;

				/* 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;
    unsigned      min_pll_freq;
    unsigned      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                 */

    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              */

    CARD8             BIOSDisplay;  /* Device the BIOS is set to display to  */

    Bool              HasPanelRegs; /* Current chip can connect to a 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               HOverPlus;
    int               HSyncWidth;
    int               HBlank;
    int               VOverPlus;
    int               VSyncWidth;
    int               VBlank;
    int               PanelPwrDly;

    R128PLLRec        pll;
    R128RAMPtr        ram;

    R128SaveRec       SavedReg;     /* Original (text) mode                  */
    R128SaveRec       ModeReg;      /* Current mode                          */
    Bool              (*CloseScreen)(int, ScreenPtr);
    void              (*BlockHandler)(int, pointer, pointer, pointer);

    Bool              PaletteSavedOnVT; /* Palette saved on last VT switch   */

    XAAInfoRecPtr     accel;
    Bool              accelOn;
    xf86CursorInfoPtr cursor;
    unsigned long     cursor_start;
    unsigned long     cursor_end;

    /*
     * XAAForceTransBlit is used to change the behavior of the XAA
     * SetupForScreenToScreenCopy function, to make it DGA-friendly.
     */
    Bool              XAAForceTransBlit;

    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_w;
    int               scanline_h;
#ifdef XF86DRI
    int               scanline_hpass;
    int               scanline_x1clip;
    int               scanline_x2clip;
    int               scanline_rop;
    int               scanline_fg;
    int               scanline_bg;
#endif /* XF86DRI */
    int               scanline_words;
    int               scanline_direct;
    int               scanline_bpp; /* Only used for ImageWrite */

    DGAModePtr        DGAModes;
    int               numDGAModes;
    Bool              DGAactive;
    int               DGAViewportStatus;
    DGAFunctionRec    DGAFuncs;

    R128FBLayout      CurrentLayout;
#ifdef XF86DRI
    Bool              directRenderingEnabled;
    DRIInfoPtr        pDRIInfo;
    int               drmFD;
    drmContext        drmCtx;
    int               numVisualConfigs;
    __GLXvisualConfig *pVisualConfigs;
    R128ConfigPrivPtr pVisualConfigsPriv;

    drmHandle         fbHandle;

    drmSize           registerSize;
    drmHandle         registerHandle;

    Bool              IsPCI;            /* Current card is a PCI card */
    drmSize           pciSize;
    drmHandle         pciMemHandle;
    unsigned char     *PCI;             /* Map */

    Bool              allowPageFlip;    /* Enable 3d page flipping */
    Bool              have3DWindows;    /* Are there any 3d clients? */
    int               drmMinor;

    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 */

				/* 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/indirect buffer data */
    unsigned long     bufStart;        /* Offset into AGP space */
    drmHandle         bufHandle;       /* Handle from drmAddMap */
    drmSize           bufMapSize;      /* Size of map */
    int               bufSize;         /* Size of buffers (in MB) */
    unsigned char     *buf;            /* Map */
    int               bufNumBufs;      /* Number of buffers */
    drmBufMapPtr      buffers;         /* Buffer 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;

				/* CCE 2D accleration */
    drmBufPtr         indirectBuffer;
    int               indirectStart;

				/* DRI screen private data */
    int               fbX;
    int               fbY;
    int               backX;
    int               backY;
    int               depthX;
    int               depthY;

    int               frontOffset;
    int               frontPitch;
    int               backOffset;
    int               backPitch;
    int               depthOffset;
    int               depthPitch;
    int               spanOffset;
    int               textureOffset;
    int               textureSize;
    int               log2TexGran;

				/* Saved scissor values */
    CARD32            sc_left;
    CARD32            sc_right;
    CARD32            sc_top;
    CARD32            sc_bottom;

    CARD32            re_top_left;
    CARD32            re_width_height;

    CARD32            aux_sc_cntl;

    int               irq;
    CARD32            gen_int_cntl;

    Bool              DMAForXv;
#endif

    XF86VideoAdaptorPtr adaptor;
    void              (*VideoTimerCallback)(ScrnInfoPtr, Time);
    int               videoKey;
    Bool              showCache;
    OptionInfoPtr     Options;

    Bool              isDFP;
    Bool              isPro2;
    I2CBusPtr         pI2CBus;
    CARD32            DDCReg;

} 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 unsigned    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);

#define R128CCE_START(pScrn, info)					\
do {									\
    int _ret = drmCommandNone(info->drmFD, DRM_R128_CCE_START);		\
    if (_ret) {								\
	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,				\
		   "%s: CCE start %d\n", __FUNCTION__, _ret);		\
    }									\
} while (0)

#define R128CCE_STOP(pScrn, info)					\
do {									\
    int _ret = R128CCEStop(pScrn);					\
    if (_ret) {								\
	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,				\
		   "%s: CCE stop %d\n", __FUNCTION__, _ret);		\
    }									\
} while (0)

#define R128CCE_RESET(pScrn, info)					\
do {									\
    if (info->directRenderingEnabled					\
	&& R128CCE_USE_RING_BUFFER(info->CCEMode)) {			\
	int _ret = drmCommandNone(info->drmFD, DRM_R128_CCE_RESET);	\
	if (_ret) {							\
	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,			\
		       "%s: CCE reset %d\n", __FUNCTION__, _ret);	\
	}								\
    }									\
} while (0)

extern drmBufPtr   R128CCEGetBuffer(ScrnInfoPtr pScrn);
#endif

extern void        R128CCEFlushIndirect(ScrnInfoPtr pScrn, int discard);
extern void        R128CCEReleaseIndirect(ScrnInfoPtr pScrn);
extern void        R128CCEWaitForIdle(ScrnInfoPtr pScrn);
extern int         R128CCEStop(ScrnInfoPtr pScrn);


#define CCE_PACKET0( reg, n )						\
	(R128_CCE_PACKET0 | ((n) << 16) | ((reg) >> 2))
#define CCE_PACKET1( reg0, reg1 )					\
	(R128_CCE_PACKET1 | (((reg1) >> 2) << 11) | ((reg0) >> 2))
#define CCE_PACKET2()							\
	(R128_CCE_PACKET2)
#define CCE_PACKET3( pkt, n )						\
	(R128_CCE_PACKET3 | (pkt) | ((n) << 16))


#define R128_VERBOSE	0

#define RING_LOCALS	CARD32 *__head; int __count;

#define R128CCE_REFRESH(pScrn, info)					\
do {									\
   if ( R128_VERBOSE ) {						\
      xf86DrvMsg( pScrn->scrnIndex, X_INFO, "REFRESH( %d ) in %s\n",	\
		  !info->CCEInUse , __FUNCTION__ );			\
   }									\
   if ( !info->CCEInUse ) {						\
      R128CCEWaitForIdle(pScrn);					\
      BEGIN_RING( 6 );							\
      OUT_RING_REG( R128_RE_TOP_LEFT,     info->re_top_left );		\
      OUT_RING_REG( R128_RE_WIDTH_HEIGHT, info->re_width_height );	\
      OUT_RING_REG( R128_AUX_SC_CNTL,     info->aux_sc_cntl );		\
      ADVANCE_RING();							\
      info->CCEInUse = TRUE;						\
   }									\
} while (0)

#define BEGIN_RING( n ) do {						\
   if ( R128_VERBOSE ) {						\
      xf86DrvMsg( pScrn->scrnIndex, X_INFO,				\
		  "BEGIN_RING( %d ) in %s\n", n, __FUNCTION__ );	\
   }									\
   if ( !info->indirectBuffer ) {					\
      info->indirectBuffer = R128CCEGetBuffer( pScrn );			\
      info->indirectStart = 0;						\
   } else if ( (info->indirectBuffer->used + 4*(n)) >			\
                info->indirectBuffer->total ) {				\
      R128CCEFlushIndirect( pScrn, 1 );					\
   }									\
   __head = (pointer)((char *)info->indirectBuffer->address +		\
		       info->indirectBuffer->used);			\
   __count = 0;								\
} while (0)

#define ADVANCE_RING() do {						\
   if ( R128_VERBOSE ) {						\
      xf86DrvMsg( pScrn->scrnIndex, X_INFO,				\
		  "ADVANCE_RING() used: %d+%d=%d/%d\n",			\
		  info->indirectBuffer->used - info->indirectStart,	\
		  __count * (int)sizeof(CARD32),			\
		  info->indirectBuffer->used - info->indirectStart +	\
		  __count * (int)sizeof(CARD32),			\
		  info->indirectBuffer->total - info->indirectStart );	\
   }									\
   info->indirectBuffer->used += __count * (int)sizeof(CARD32);		\
} while (0)

#define OUT_RING( x ) do {						\
   if ( R128_VERBOSE ) {						\
      xf86DrvMsg( pScrn->scrnIndex, X_INFO,				\
		  "   OUT_RING( 0x%08x )\n", (unsigned int)(x) );	\
   }									\
   MMIO_OUT32(&__head[__count++], 0, (x));				\
} while (0)

#define OUT_RING_REG( reg, val )					\
do {									\
   OUT_RING( CCE_PACKET0( reg, 0 ) );					\
   OUT_RING( val );							\
} while (0)

#define FLUSH_RING()							\
do {									\
   if ( R128_VERBOSE )							\
      xf86DrvMsg( pScrn->scrnIndex, X_INFO,				\
		  "FLUSH_RING in %s\n", __FUNCTION__ );			\
   if ( info->indirectBuffer ) {					\
      R128CCEFlushIndirect( pScrn, 0 );					\
   }									\
} while (0)

#endif

--- NEW FILE: r128_accel.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c,v 1.17 2003/10/03 20:11:11 herrb Exp $ */
/*
 * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario,
 *                      Precision Insight, Inc., Cedar Park, Texas, and
 *                      VA Linux Systems Inc., Fremont, 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.
[...1766 lines suppressed...]
/* 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
    if (info->directRenderingEnabled)
	R128CCEAccelInit(pScrn, a);
    else
#endif
	R128MMIOAccelInit(pScrn, a);

    R128EngineInit(pScrn);
    return XAAInit(pScreen, a);
}

--- NEW FILE: r128_common.h ---
/* r128_common.h -- common header definitions for R128 2D/3D/DRM suite
 * Created: Sun Apr  9 18:16:28 2000 by kevin at precisioninsight.com
 *
 * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
 * Copyright 2002 Tungsten Graphics, 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
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * Author:
 *   Gareth Hughes <gareth at valinux.com>
 *   Kevin E. Martin <martin at valinux.com>
 *
 * Converted to common header format:
 *   Jens Owen <jens at tungstengraphics.com>
 *
 * $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_common.h,v 1.2 2002/12/16 16:19:10 dawes Exp $
 *
 */

#ifndef _R128_COMMON_H_
#define _R128_COMMON_H_

#include "X11/Xmd.h"

/*
 * WARNING: If you change any of these defines, make sure to change
 * the kernel include file as well (r128_drm.h)
 */

/* Driver specific DRM command indices
 * NOTE: these are not OS specific, but they are driver specific
 */
#define DRM_R128_INIT           0x00
#define DRM_R128_CCE_START      0x01
#define DRM_R128_CCE_STOP       0x02
#define DRM_R128_CCE_RESET      0x03
#define DRM_R128_CCE_IDLE       0x04
#define DRM_R128_UNDEFINED1     0x05
#define DRM_R128_RESET          0x06
#define DRM_R128_SWAP           0x07
#define DRM_R128_CLEAR          0x08
#define DRM_R128_VERTEX         0x09
#define DRM_R128_INDICES        0x0a
#define DRM_R128_BLIT           0x0b
#define DRM_R128_DEPTH          0x0c
#define DRM_R128_STIPPLE        0x0d
#define DRM_R128_UNDEFINED2     0x0e
#define DRM_R128_INDIRECT       0x0f
#define DRM_R128_FULLSCREEN     0x10
#define DRM_R128_CLEAR2         0x11
#define DRM_R128_GETPARAM       0x12
#define DRM_R128_FLIP           0x13

#define DRM_R128_FRONT_BUFFER	0x1
#define DRM_R128_BACK_BUFFER	0x2
#define DRM_R128_DEPTH_BUFFER	0x4

typedef struct {
   enum {
      DRM_R128_INIT_CCE    = 0x01,
      DRM_R128_CLEANUP_CCE = 0x02
   } func;
   unsigned long sarea_priv_offset;
   int is_pci;
   int cce_mode;
   int cce_secure;		/* FIXME: Deprecated, we should remove this */
   int ring_size;
   int usec_timeout;

   unsigned int fb_bpp;
   unsigned int front_offset, front_pitch;
   unsigned int back_offset, back_pitch;
   unsigned int depth_bpp;
   unsigned int depth_offset, depth_pitch;
   unsigned int span_offset;

   unsigned long fb_offset;
   unsigned long mmio_offset;
   unsigned long ring_offset;
   unsigned long ring_rptr_offset;
   unsigned long buffers_offset;
   unsigned long agp_textures_offset;
} drmR128Init;

typedef struct {
   int flush;
   int idle;
} drmR128CCEStop;

typedef struct {
   int idx;
   int start;
   int end;
   int discard;
} drmR128Indirect;

typedef struct {
   int idx;
   int pitch;
   int offset;
   int format;
   unsigned short x, y;
   unsigned short width, height;
} drmR128Blit;

typedef struct {
   enum {
      DRM_R128_WRITE_SPAN         = 0x01,
      DRM_R128_WRITE_PIXELS       = 0x02,
      DRM_R128_READ_SPAN          = 0x03,
      DRM_R128_READ_PIXELS        = 0x04
   } func;
   int n;
   int *x;
   int *y;
   unsigned int *buffer;
   unsigned char *mask;
} drmR128Depth;

typedef struct {
   int prim;
   int idx;                        /* Index of vertex buffer */
   int count;                      /* Number of vertices in buffer */
   int discard;                    /* Client finished with buffer? */
} drmR128Vertex;

typedef struct {
   unsigned int *mask;
} drmR128Stipple;

typedef struct {
   unsigned int flags;
   unsigned int clear_color;
   unsigned int clear_depth;
   unsigned int color_mask;
   unsigned int depth_mask;
} drmR128Clear;

typedef struct {
   enum {
      DRM_R128_INIT_FULLSCREEN    = 0x01,
      DRM_R128_CLEANUP_FULLSCREEN = 0x02
   } func;
} drmR128Fullscreen;

typedef struct drm_r128_getparam {
	int param;
	int *value;
} drmR128GetParam;

#define R128_PARAM_IRQ_NR            1

#endif

--- NEW FILE: r128_cursor.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_cursor.c,v 1.5tsi Exp $ */
/*
 * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario,
 *                      Precision Insight, Inc., Cedar Park, Texas, and
 *                      VA Linux Systems Inc., Fremont, 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, PRECISION INSIGHT, 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:
 *   Rickard E. Faith <faith at valinux.com>
 *   Kevin E. Martin <martin at valinux.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.
 *
 */

				/* Driver data structures */
#include "r128.h"
#include "r128_reg.h"

				/* X and server generic header files */
#include "xf86.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        = (pointer)image;
    CARD32        *d        = (pointer)(info->FB + info->cursor_start);
    int           y;
    CARD32        save;

    save = INREG(R128_CRTC_GEN_CNTL);
    OUTREG(R128_CRTC_GEN_CNTL, save & (CARD32)~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
				 | HARDWARE_CURSOR_SHOW_TRANSPARENT
				 | HARDWARE_CURSOR_UPDATE_UNHIDDEN
#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);
}

--- NEW FILE: r128_dga.c ---
(This appears to be a binary file; contents omitted.)

--- NEW FILE: r128_dri.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c,v 1.31 2003/09/28 20:15:53 alanh Exp $ */
/*
 * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario,
 *                      Precision Insight, Inc., Cedar Park, Texas, and
 *                      VA Linux Systems Inc., Fremont, 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.
[...1450 lines suppressed...]
static void R128DRITransitionTo2d(ScreenPtr pScreen)
{
    ScrnInfoPtr         pScrn      = xf86Screens[pScreen->myNum];
    R128InfoPtr         info       = R128PTR(pScrn);
    R128SAREAPrivPtr    pSAREAPriv = DRIGetSAREAPrivate(pScreen);

    /* Shut down shadowing if we've made it back to the front page */
    if (pSAREAPriv->pfCurrentPage == 0) {
	R128DisablePageFlip(pScreen);
    } else {
	xf86DrvMsg(pScreen->myNum, X_WARNING,
		   "[dri] R128DRITransitionTo2d: "
		   "kernel failed to unflip buffers.\n");
    }

    info->have3DWindows = 0;

    if (info->cursor_start)
        xf86ForceHWCursor(pScreen, FALSE);
}

--- NEW FILE: r128_dri.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h,v 1.6 2001/03/21 17:02:21 dawes Exp $ */
/*
 * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario,
 *                      Precision Insight, Inc., Cedar Park, Texas, and
 *                      VA Linux Systems Inc., Fremont, 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, PRECISION INSIGHT, 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 at valinux.com>
 *   Rickard E. Faith <faith at valinux.com>
 *   Gareth Hughes <gareth at valinux.com>
 *
 */

#ifndef _R128_DRI_
#define _R128_DRI_

#include "xf86drm.h"
#include "r128_common.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     1
#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_BUFFER_SIZE  2 /* MB (must be page aligned) */
#define R128_DEFAULT_AGP_TEX_SIZE 1 /* MB (must be page aligned) */

#define R128_DEFAULT_CCE_TIMEOUT  10000  /* usecs */

#define R128_AGP_MAX_MODE         4

#define R128_CARD_TYPE_R128          1
#define R128_CARD_TYPE_R128_PRO      2
#define R128_CARD_TYPE_R128_MOBILITY 3

#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 {
    /* 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           IsPCI;        /* Current card is a PCI card */
    int           AGPMode;

    int           frontOffset;  /* Start of front buffer */
    int           frontPitch;
    int           backOffset;   /* Start of shared back buffer */
    int           backPitch;
    int           depthOffset;  /* Start of shared depth buffer */
    int           depthPitch;
    int           spanOffset;   /* Start of scratch spanline */
    int           textureOffset;/* Start of texture data in frame buffer */
    int           textureSize;
    int           log2TexGran;

    /* MMIO register data */
    drmHandle     registerHandle;
    drmSize       registerSize;

    /* CCE AGP Texture data */
    drmHandle     agpTexHandle;
    drmSize       agpTexMapSize;
    int           log2AGPTexGran;
    int           agpTexOffset;
    unsigned int  sarea_priv_offset;
} R128DRIRec, *R128DRIPtr;

#endif

--- NEW FILE: r128_dripriv.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dripriv.h,v 1.2 2000/11/09 03:24:35 martin Exp $ */
/*
 * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario,
 *                      Precision Insight, Inc., Cedar Park, Texas, and
 *                      VA Linux Systems Inc., Fremont, 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, PRECISION INSIGHT, 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:
 *   Rickard E. Faith <faith at valinux.com>
 *   Kevin E. Martin <martin at valinux.com>
 *
 */

#ifndef _R128_DRIPRIV_H_
#define _R128_DRIPRIV_H_

#include "GL/glxint.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

--- NEW FILE: r128_driver.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c,v 1.88 2004/01/29 02:51:17 dawes Exp $ */
/*
 * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario,
 *                      Precision Insight, Inc., Cedar Park, Texas, and
 *                      VA Linux Systems Inc., Fremont, 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.
[...3636 lines suppressed...]
#endif
		lvds_gen_cntl |= (R128_LVDS_ON | R128_LVDS_EN);
		lvds_gen_cntl &= ~R128_LVDS_DISPLAY_DIS;
	} else {
#if 0
		lvds_gen_cntl &= ~R128_LVDS_BL_MOD_LEVEL_MASK;
		lvds_gen_cntl |= (0xFF /* backlight_conv[0] */ <<
				  R128_LVDS_BL_MOD_LEVEL_SHIFT);
#endif
		lvds_gen_cntl |= R128_LVDS_DISPLAY_DIS;
		OUTREG(R128_LVDS_GEN_CNTL, lvds_gen_cntl);
		usleep(10);
		lvds_gen_cntl &= ~(R128_LVDS_ON | R128_LVDS_EN | R128_LVDS_BLON
				   | R128_LVDS_DIGON);
	}

	OUTREG(R128_LVDS_GEN_CNTL, lvds_gen_cntl);

	return 0;
 }

--- NEW FILE: r128_misc.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_misc.c,v 1.5 2003/01/01 19:16:35 tsi Exp $ */
/*
 * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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_probe.h"
#include "r128_version.h"

#include "xf86.h"

/* Module loader interface for subsidiary driver module */

static XF86ModuleVersionInfo R128VersionRec =
{
    R128_DRIVER_NAME,
    MODULEVENDORSTRING,
    MODINFOSTRING1,
    MODINFOSTRING2,
    XORG_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);

        R128LoaderRefSymLists();

        Inited = TRUE;
    }

    return (pointer)TRUE;
}

/* The following record must be called r128ModuleData */
XF86ModuleData r128ModuleData =
{
    &R128VersionRec,
    R128Setup,
    NULL
};

#endif /* XFree86LOADER */

--- NEW FILE: r128_probe.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.c,v 1.17 2003/02/07 20:41:15 martin Exp $ */
/*
 * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario,
 *                      Precision Insight, Inc., Cedar Park, Texas, and
 *                      VA Linux Systems Inc., Fremont, 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, PRECISION INSIGHT, 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:
 *   Rickard E. Faith <faith at valinux.com>
 *   Kevin E. Martin <martin at valinux.com>
 *
 * Modified by Marc Aurele La France <tsi at 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"

#ifdef XFree86LOADER

/*
 * The following exists to prevent the compiler from considering entry points
 * defined in a separate module from being constants.
 */
static xf86PreInitProc     * const volatile PreInitProc     = R128PreInit;
static xf86ScreenInitProc  * const volatile ScreenInitProc  = R128ScreenInit;
static xf86SwitchModeProc  * const volatile SwitchModeProc  = R128SwitchMode;
static xf86AdjustFrameProc * const volatile AdjustFrameProc = R128AdjustFrame;
static xf86EnterVTProc     * const volatile EnterVTProc     = R128EnterVT;
static xf86LeaveVTProc     * const volatile LeaveVTProc     = R128LeaveVT;
static xf86FreeScreenProc  * const volatile FreeScreenProc  = R128FreeScreen;
static xf86ValidModeProc   * const volatile ValidModeProc   = R128ValidMode;

#define R128PreInit     PreInitProc
#define R128ScreenInit  ScreenInitProc
#define R128SwitchMode  SwitchModeProc
#define R128AdjustFrame AdjustFrameProc
#define R128EnterVT     EnterVTProc
#define R128LeaveVT     LeaveVTProc
#define R128FreeScreen  FreeScreenProc
#define R128ValidMode   ValidModeProc

#endif

SymTabRec R128Chipsets[] = {
    /* FIXME: The chipsets with (PCI/AGP) are not known wether they are AGP or
     *        PCI, so I've labeled them as such in hopes users will submit
     *        data if we're unable to gather it from official documentation
     */
    { PCI_CHIP_RAGE128LE, "ATI Rage 128 Mobility M3 LE (PCI)" },
    { PCI_CHIP_RAGE128LF, "ATI Rage 128 Mobility M3 LF (AGP)" },
    { PCI_CHIP_RAGE128MF, "ATI Rage 128 Mobility M4 MF (AGP)" },
    { PCI_CHIP_RAGE128ML, "ATI Rage 128 Mobility M4 ML (AGP)" },
    { PCI_CHIP_RAGE128PA, "ATI Rage 128 Pro GL PA (PCI/AGP)" },
    { PCI_CHIP_RAGE128PB, "ATI Rage 128 Pro GL PB (PCI/AGP)" },
    { PCI_CHIP_RAGE128PC, "ATI Rage 128 Pro GL PC (PCI/AGP)" },
    { PCI_CHIP_RAGE128PD, "ATI Rage 128 Pro GL PD (PCI)" },
    { PCI_CHIP_RAGE128PE, "ATI Rage 128 Pro GL PE (PCI/AGP)" },
    { PCI_CHIP_RAGE128PF, "ATI Rage 128 Pro GL PF (AGP)" },
    { PCI_CHIP_RAGE128PG, "ATI Rage 128 Pro VR PG (PCI/AGP)" },
    { PCI_CHIP_RAGE128PH, "ATI Rage 128 Pro VR PH (PCI/AGP)" },
    { PCI_CHIP_RAGE128PI, "ATI Rage 128 Pro VR PI (PCI/AGP)" },
    { PCI_CHIP_RAGE128PJ, "ATI Rage 128 Pro VR PJ (PCI/AGP)" },
    { PCI_CHIP_RAGE128PK, "ATI Rage 128 Pro VR PK (PCI/AGP)" },
    { PCI_CHIP_RAGE128PL, "ATI Rage 128 Pro VR PL (PCI/AGP)" },
    { PCI_CHIP_RAGE128PM, "ATI Rage 128 Pro VR PM (PCI/AGP)" },
    { PCI_CHIP_RAGE128PN, "ATI Rage 128 Pro VR PN (PCI/AGP)" },
    { PCI_CHIP_RAGE128PO, "ATI Rage 128 Pro VR PO (PCI/AGP)" },
    { PCI_CHIP_RAGE128PP, "ATI Rage 128 Pro VR PP (PCI)" },
    { PCI_CHIP_RAGE128PQ, "ATI Rage 128 Pro VR PQ (PCI/AGP)" },
    { PCI_CHIP_RAGE128PR, "ATI Rage 128 Pro VR PR (PCI)" },
    { PCI_CHIP_RAGE128PS, "ATI Rage 128 Pro VR PS (PCI/AGP)" },
    { PCI_CHIP_RAGE128PT, "ATI Rage 128 Pro VR PT (PCI/AGP)" },
    { PCI_CHIP_RAGE128PU, "ATI Rage 128 Pro VR PU (PCI/AGP)" },
    { PCI_CHIP_RAGE128PV, "ATI Rage 128 Pro VR PV (PCI/AGP)" },
    { PCI_CHIP_RAGE128PW, "ATI Rage 128 Pro VR PW (PCI/AGP)" },
    { PCI_CHIP_RAGE128PX, "ATI Rage 128 Pro VR PX (PCI/AGP)" },
    { PCI_CHIP_RAGE128RE, "ATI Rage 128 GL RE (PCI)" },
    { PCI_CHIP_RAGE128RF, "ATI Rage 128 GL RF (AGP)" },
    { PCI_CHIP_RAGE128RG, "ATI Rage 128 RG (AGP)" },
    { PCI_CHIP_RAGE128RK, "ATI Rage 128 VR RK (PCI)" },
    { PCI_CHIP_RAGE128RL, "ATI Rage 128 VR RL (AGP)" },
    { PCI_CHIP_RAGE128SE, "ATI Rage 128 4X SE (PCI/AGP)" },
    { PCI_CHIP_RAGE128SF, "ATI Rage 128 4X SF (PCI/AGP)" },
    { PCI_CHIP_RAGE128SG, "ATI Rage 128 4X SG (PCI/AGP)" },
    { PCI_CHIP_RAGE128SH, "ATI Rage 128 4X SH (PCI/AGP)" },
    { PCI_CHIP_RAGE128SK, "ATI Rage 128 4X SK (PCI/AGP)" },
    { PCI_CHIP_RAGE128SL, "ATI Rage 128 4X SL (PCI/AGP)" },
    { PCI_CHIP_RAGE128SM, "ATI Rage 128 4X SM (AGP)" },
    { PCI_CHIP_RAGE128SN, "ATI Rage 128 4X SN (PCI/AGP)" },
    { PCI_CHIP_RAGE128TF, "ATI Rage 128 Pro ULTRA TF (AGP)" },
    { PCI_CHIP_RAGE128TL, "ATI Rage 128 Pro ULTRA TL (AGP)" },
    { PCI_CHIP_RAGE128TR, "ATI Rage 128 Pro ULTRA TR (AGP)" },
    { PCI_CHIP_RAGE128TS, "ATI Rage 128 Pro ULTRA TS (AGP?)" },
    { PCI_CHIP_RAGE128TT, "ATI Rage 128 Pro ULTRA TT (AGP?)" },
    { PCI_CHIP_RAGE128TU, "ATI Rage 128 Pro ULTRA TU (AGP?)" },
    { -1,                 NULL }
};

PciChipsets R128PciChipsets[] = {
    { 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 },
    { PCI_CHIP_RAGE128PA, PCI_CHIP_RAGE128PA, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128PB, PCI_CHIP_RAGE128PB, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128PC, PCI_CHIP_RAGE128PC, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128PD, PCI_CHIP_RAGE128PD, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128PE, PCI_CHIP_RAGE128PE, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128PF, PCI_CHIP_RAGE128PF, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128PG, PCI_CHIP_RAGE128PG, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128PH, PCI_CHIP_RAGE128PH, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128PI, PCI_CHIP_RAGE128PI, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128PJ, PCI_CHIP_RAGE128PJ, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128PK, PCI_CHIP_RAGE128PK, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128PL, PCI_CHIP_RAGE128PL, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128PM, PCI_CHIP_RAGE128PM, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128PN, PCI_CHIP_RAGE128PN, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128PO, PCI_CHIP_RAGE128PO, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128PP, PCI_CHIP_RAGE128PP, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128PQ, PCI_CHIP_RAGE128PQ, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128PR, PCI_CHIP_RAGE128PR, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128PS, PCI_CHIP_RAGE128PS, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128PT, PCI_CHIP_RAGE128PT, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128PU, PCI_CHIP_RAGE128PU, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128PV, PCI_CHIP_RAGE128PV, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128PW, PCI_CHIP_RAGE128PW, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128PX, PCI_CHIP_RAGE128PX, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128RE, PCI_CHIP_RAGE128RE, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128RF, PCI_CHIP_RAGE128RF, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128RG, PCI_CHIP_RAGE128RG, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128RK, PCI_CHIP_RAGE128RK, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128RL, PCI_CHIP_RAGE128RL, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128SE, PCI_CHIP_RAGE128SE, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128SF, PCI_CHIP_RAGE128SF, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128SG, PCI_CHIP_RAGE128SG, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128SH, PCI_CHIP_RAGE128SH, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128SK, PCI_CHIP_RAGE128SK, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128SL, PCI_CHIP_RAGE128SL, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128SM, PCI_CHIP_RAGE128SM, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128SN, PCI_CHIP_RAGE128SN, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128TF, PCI_CHIP_RAGE128TF, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128TL, PCI_CHIP_RAGE128TL, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128TR, PCI_CHIP_RAGE128TR, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128TS, PCI_CHIP_RAGE128TS, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128TT, PCI_CHIP_RAGE128TT, RES_SHARED_VGA },
    { PCI_CHIP_RAGE128TU, PCI_CHIP_RAGE128TU, RES_SHARED_VGA },
    { -1,                 -1,                 RES_UNDEFINED }
};

/* Return the options for supported chipset 'n'; NULL otherwise */
const OptionInfoRec *
R128AvailableOptions(int chipid, int busid)
{
    int i;

    /*
     * Return options defined in the r128 submodule which will have been
     * loaded by this point.
     */
    if ((chipid >> 16) == PCI_VENDOR_ATI)
	chipid -= PCI_VENDOR_ATI << 16;
    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);
    }

    xfree(usedChips);
    xfree(devSections);

    return foundScreen;
}

--- NEW FILE: r128_probe.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.h,v 1.6 2002/04/06 19:06:06 tsi Exp $ */
/*
 * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
 *                VA Linux Systems Inc., Fremont, 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 at valinux.com>
 *
 * Modified by Marc Aurele La France <tsi at 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 const OptionInfoRec * 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 void                  R128LoaderRefSymLists
			     FunctionPrototype((void));
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 ModeStatus            R128ValidMode
			     FunctionPrototype((int, DisplayModePtr, Bool,
						int));

extern const OptionInfoRec   R128Options[];

#endif /* _R128_PROBE_H_ */

--- NEW FILE: r128_reg.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h,v 1.16 2003/04/06 20:36:36 martin Exp $ */
/*
 * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario,
 *                      Precision Insight, Inc., Cedar Park, Texas, and
 *                      VA Linux Systems Inc., Fremont, 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.
[...1472 lines suppressed...]
#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

/* hmm copyed blindly (no specs) from radeon.h ... */
#define R128_RE_TOP_LEFT                  0x26c0
#       define R128_RE_LEFT_SHIFT         0
#       define R128_RE_TOP_SHIFT          16
#define R128_RE_WIDTH_HEIGHT              0x1c44
#       define R128_RE_WIDTH_SHIFT        0
#       define R128_RE_HEIGHT_SHIFT       16

#endif

--- NEW FILE: r128_sarea.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_sarea.h,v 1.8 2003/09/28 20:15:54 alanh Exp $ */
/*
 * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario,
 *                      Precision Insight, Inc., Cedar Park, Texas, and
 *                      VA Linux Systems Inc., Fremont, 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, PRECISION INSIGHT, 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 at valinux.com>
 *   Gareth Hughes <gareth at valinux.com>
 *
 */

#ifndef _R128_SAREA_H_
#define _R128_SAREA_H_

#include <X11/Xmd.h>

/* WARNING: If you change any of these defines, make sure to change the
 * defines in the kernel file (r128_drm.h)
 */
#ifndef __R128_SAREA_DEFINES__
#define __R128_SAREA_DEFINES__

/* What needs to be changed for the current vertex buffer?
 */
#define R128_UPLOAD_CONTEXT		0x001
#define R128_UPLOAD_SETUP		0x002
#define R128_UPLOAD_TEX0		0x004
#define R128_UPLOAD_TEX1		0x008
#define R128_UPLOAD_TEX0IMAGES		0x010
#define R128_UPLOAD_TEX1IMAGES		0x020
#define R128_UPLOAD_CORE		0x040
#define R128_UPLOAD_MASKS		0x080
#define R128_UPLOAD_WINDOW		0x100
#define R128_UPLOAD_CLIPRECTS		0x200	/* handled client-side */
#define R128_REQUIRE_QUIESCENCE		0x400
#define R128_UPLOAD_ALL			0x7ff

#define R128_FRONT			0x1
#define R128_BACK			0x2
#define R128_DEPTH			0x4

/* Primitive types
 */
#define R128_POINTS			0x1
#define R128_LINES			0x2
#define R128_LINE_STRIP			0x3
#define R128_TRIANGLES			0x4
#define R128_TRIANGLE_FAN		0x5
#define R128_TRIANGLE_STRIP		0x6

/* Vertex/indirect buffer size
 */
#define R128_BUFFER_SIZE		16384

/* Byte offsets for indirect buffer data
 */
#define R128_INDEX_PRIM_OFFSET		20
#define R128_HOSTDATA_BLIT_OFFSET	32

/* Keep these small for testing
 */
#define R128_NR_SAREA_CLIPRECTS		12

/* 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_CARD_HEAP			0
#define R128_AGP_HEAP			1
#define R128_NR_TEX_HEAPS		2
#define R128_NR_TEX_REGIONS		64
#define R128_LOG_TEX_GRANULARITY	16

#define R128_NR_CONTEXT_REGS		12

#define R128_MAX_TEXTURE_LEVELS		11
#define R128_MAX_TEXTURE_UNITS		2

#endif /* __R128_SAREA_DEFINES__ */

typedef struct {
    /* Context state - can be written in one large chunk */
    unsigned int dst_pitch_offset_c;
    unsigned int dp_gui_master_cntl_c;
    unsigned int sc_top_left_c;
    unsigned int sc_bottom_right_c;
    unsigned int z_offset_c;
    unsigned int z_pitch_c;
    unsigned int z_sten_cntl_c;
    unsigned int tex_cntl_c;
    unsigned int misc_3d_state_cntl_reg;
    unsigned int texture_clr_cmp_clr_c;
    unsigned int texture_clr_cmp_msk_c;
    unsigned int fog_color_c;

    /* Texture state */
    unsigned int tex_size_pitch_c;
    unsigned int constant_color_c;

    /* Setup state */
    unsigned int pm4_vc_fpu_setup;
    unsigned int setup_cntl;

    /* Mask state */
    unsigned int dp_write_mask;
    unsigned int sten_ref_mask_c;
    unsigned int plane_3d_mask_c;

    /* Window state */
    unsigned int window_xy_offset;

    /* Core state */
    unsigned int scale_3d_cntl;
} r128_context_regs_t;

/* Setup registers for each texture unit
 */
typedef struct {
    unsigned int tex_cntl;
    unsigned int tex_combine_cntl;
    unsigned int tex_size_pitch;
    unsigned int tex_offset[R128_MAX_TEXTURE_LEVELS];
    unsigned int tex_border_color;
} r128_texture_regs_t;

typedef struct {
    /* The channel for communication of state information to the kernel
     * on firing a vertex buffer.
     */
    r128_context_regs_t	ContextState;
    r128_texture_regs_t	TexState[R128_MAX_TEXTURE_UNITS];
    unsigned int dirty;
    unsigned int vertsize;
    unsigned int vc_format;

    /* The current cliprects, or a subset thereof.
     */
    XF86DRIClipRectRec boxes[R128_NR_SAREA_CLIPRECTS];
    unsigned int nbox;

    /* Counters for throttling of rendering clients.
     */
    unsigned int last_frame;
    unsigned int last_dispatch;

    /* 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 */
    drmTextureRegion texList[R128_NR_TEX_HEAPS][R128_NR_TEX_REGIONS+1];
				/* last time texture was uploaded */
    unsigned int texAge[R128_NR_TEX_HEAPS];

    int ctxOwner;		/* last context to upload state */
    int pfAllowPageFlip;	/* set by the 2d driver, read by the client */
    int pfCurrentPage;		/* set by kernel, read by others */
} R128SAREAPriv, *R128SAREAPrivPtr;

#endif

--- NEW FILE: r128_version.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_version.h,v 1.6 2003/01/01 19:16:35 tsi Exp $ */
/*
 * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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

#undef  R128_NAME
#undef  R128_DRIVER_NAME
#undef  R128_VERSION_MAJOR
#undef  R128_VERSION_MINOR
#undef  R128_VERSION_PATCH
#undef  R128_VERSION_CURRENT
#undef  R128_VERSION_EVALUATE
#undef  R128_VERSION_STRINGIFY
#undef  R128_VERSION_NAME

#define R128_NAME          "R128"
#define R128_DRIVER_NAME   "r128"

#define R128_VERSION_MAJOR 4
#define R128_VERSION_MINOR 0
#define R128_VERSION_PATCH 1

#ifndef R128_VERSION_EXTRA
#define R128_VERSION_EXTRA ""
#endif

#define R128_VERSION_CURRENT \
    ((R128_VERSION_MAJOR << 20) | \
     (R128_VERSION_MINOR << 10) | \
     (R128_VERSION_PATCH))

#define R128_VERSION_EVALUATE(__x) #__x
#define R128_VERSION_STRINGIFY(_x) R128_VERSION_EVALUATE(_x)
#define R128_VERSION_NAME                                         \
    R128_VERSION_STRINGIFY(R128_VERSION_MAJOR) "."                \
    R128_VERSION_STRINGIFY(R128_VERSION_MINOR) "."                \
    R128_VERSION_STRINGIFY(R128_VERSION_MINOR) R128_VERSION_EXTRA

#endif /* _R128_VERSION_H_ */

--- NEW FILE: r128_video.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_video.c,v 1.30 2003/11/10 18:22:18 tsi Exp $ */

#include "r128.h"
#include "r128_reg.h"

#ifdef XF86DRI
#include "r128_common.h"
#include "r128_sarea.h"
#endif

#include "xf86.h"
#include "dixstruct.h"

#include <X11/extensions/Xv.h>
#include "fourcc.h"

#define OFF_DELAY       250  /* milliseconds */
#define FREE_DELAY      15000

[...981 lines suppressed...]
	if(pPriv->videoStatus & OFF_TIMER) {
	    if(pPriv->offTime < now) {
		unsigned char *R128MMIO = info->MMIO;
		OUTREG(R128_OV0_SCALE_CNTL, 0);
		pPriv->videoStatus = FREE_TIMER;
		pPriv->freeTime = now + FREE_DELAY;
	    }
	} else {  /* FREE_TIMER */
	    if(pPriv->freeTime < now) {
		if(pPriv->linear) {
		   xf86FreeOffscreenLinear(pPriv->linear);
		   pPriv->linear = NULL;
		}
		pPriv->videoStatus = 0;
		info->VideoTimerCallback = NULL;
	    }
	}
    } else  /* shouldn't get here */
	info->VideoTimerCallback = NULL;
}

--- NEW FILE: radeon.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h,v 1.43 2003/11/06 18:38:00 tsi Exp $ */
/*
 * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
 *                VA Linux Systems Inc., Fremont, 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 at xfree86.org>
 *   Rickard E. Faith <faith at valinux.com>
 *   Alan Hourihane <alanh at fairlite.demon.co.uk>
 *
 */

#ifndef _RADEON_H_
#define _RADEON_H_

#include "xf86str.h"

				/* PCI support */
#include "xf86Pci.h"

				/* XAA and Cursor Support */
#include "xaa.h"
#include "xf86Cursor.h"

				/* DDC support */
#include "xf86DDC.h"

				/* Xv support */
#include "xf86xv.h"

				/* DRI support */
#ifdef XF86DRI
#define _XF86DRI_SERVER_
#include "radeon_dripriv.h"
#include "dri.h"
#include "GL/glxint.h"
#endif

				/* Render support */
#ifdef RENDER
#include "picturestr.h"
#endif

#define RADEON_DEBUG            0 /* Turn off debugging output               */
#define RADEON_IDLE_RETRY      16 /* Fall out of idle loops after this count */
#define RADEON_TIMEOUT    2000000 /* Fall out of wait loops after this count */
#define RADEON_MMIOSIZE   0x80000

#define RADEON_VBIOS_SIZE 0x00010000
#define RADEON_USE_RMX 0x80000000 /* mode flag for using RMX
				   * Need to comfirm this is not used
				   * for something else.
				   */

#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 {
				/* 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;
    CARD32            surface_cntl;
    CARD32            bios_5_scratch;
				/* 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;
    CARD32            disp_merge_cntl;
    CARD32            grph_buffer_cntl;
    CARD32            crtc_more_cntl;

				/* CRTC2 registers */
    CARD32            crtc2_gen_cntl;

    CARD32            dac2_cntl;
    CARD32            disp_output_cntl;
    CARD32            disp_hw_debug;
    CARD32            disp2_merge_cntl;
    CARD32            grph2_buffer_cntl;
    CARD32            crtc2_h_total_disp;
    CARD32            crtc2_h_sync_strt_wid;
    CARD32            crtc2_v_total_disp;
    CARD32            crtc2_v_sync_strt_wid;
    CARD32            crtc2_offset;
    CARD32            crtc2_offset_cntl;
    CARD32            crtc2_pitch;
				/* Flat panel registers */
    CARD32            fp_crtc_h_total_disp;
    CARD32            fp_crtc_v_total_disp;
    CARD32            fp_gen_cntl;
    CARD32            fp2_gen_cntl;
    CARD32            fp_h_sync_strt_wid;
    CARD32            fp2_h_sync_strt_wid;
    CARD32            fp_horz_stretch;
    CARD32            fp_panel_cntl;
    CARD32            fp_v_sync_strt_wid;
    CARD32            fp2_v_sync_strt_wid;
    CARD32            fp_vert_stretch;
    CARD32            lvds_gen_cntl;
    CARD32            lvds_pll_cntl;
    CARD32            tmds_pll_cntl;
    CARD32            tmds_transmitter_cntl;

				/* Computed values for PLL */
    CARD32            dot_clock_freq;
    CARD32            pll_output_freq;
    int               feedback_div;
    int               post_div;

				/* PLL registers */
    unsigned          ppll_ref_div;
    unsigned          ppll_div_3;
    CARD32            htotal_cntl;

				/* Computed values for PLL2 */
    CARD32            dot_clock_freq_2;
    CARD32            pll_output_freq_2;
    int               feedback_div_2;
    int               post_div_2;

				/* PLL2 registers */
    CARD32            p2pll_ref_div;
    CARD32            p2pll_div_0;
    CARD32            htotal_cntl2;

				/* Pallet */
    Bool              palette_valid;
    CARD32            palette[256];
    CARD32            palette2[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 enum {
    MT_NONE,
    MT_CRT,
    MT_LCD,
    MT_DFP,
    MT_CTV,
    MT_STV
} RADEONMonitorType;

typedef enum {
    DDC_NONE_DETECTED,
    DDC_MONID,
    DDC_DVI,
    DDC_VGA,
    DDC_CRT2
} RADEONDDCType;

typedef enum {
    CONNECTOR_NONE,
    CONNECTOR_PROPRIETARY,
    CONNECTOR_CRT,
    CONNECTOR_DVI_I,
    CONNECTOR_DVI_D
} RADEONConnectorType;

typedef enum {
    CHIP_FAMILY_UNKNOW,
    CHIP_FAMILY_LEGACY,
    CHIP_FAMILY_RADEON,
    CHIP_FAMILY_RV100,
    CHIP_FAMILY_RS100,    /* U1 (IGP320M) or A3 (IGP320)*/
    CHIP_FAMILY_RV200,
    CHIP_FAMILY_RS200,    /* U2 (IGP330M/340M/350M) or A4 (IGP330/340/345/350), RS250 (IGP 7000) */
    CHIP_FAMILY_R200,
    CHIP_FAMILY_RV250,
    CHIP_FAMILY_RS300,    /* Radeon 9000 IGP */
    CHIP_FAMILY_RV280,
    CHIP_FAMILY_R300,
    CHIP_FAMILY_R350,
    CHIP_FAMILY_RV350,
    CHIP_FAMILY_LAST
} RADEONChipFamily;

typedef struct {
    CARD32 freq;
    CARD32 value;
}RADEONTMDSPll;

typedef struct {
    EntityInfoPtr     pEnt;
    pciVideoPtr       PciInfo;
    PCITAG            PciTag;
    int               Chipset;
    RADEONChipFamily  ChipFamily;

    Bool              FBDev;

    unsigned long     LinearAddr;       /* Frame buffer physical address     */
    unsigned long     MMIOAddr;         /* MMIO region physical address      */
    unsigned long     BIOSAddr;         /* BIOS physical address             */

    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          */

				/* VE/M6 support */
    RADEONMonitorType DisplayType;      /* Monitor connected on              */
    RADEONDDCType     DDCType;
    RADEONConnectorType ConnectorType;
    Bool              HasCRTC2;         /* All cards except original Radeon  */
    Bool              IsMobility;       /* Mobile chips for laptops */
    Bool              IsIGP;            /* IGP chips */
    Bool              IsSecondary;      /* Second Screen                     */
    Bool              IsSwitching;      /* Flag for switching mode           */
    Bool              Clone;            /* Force second head to clone primary*/
    RADEONMonitorType CloneType;
    RADEONDDCType     CloneDDCType;
    DisplayModePtr    CloneModes;
    DisplayModePtr    CurCloneMode;
    int               CloneFrameX0;
    int               CloneFrameY0;
    Bool              OverlayOnCRTC2;
    Bool              PanelOff;         /* Force panel (LCD/DFP) off         */
    int               FPBIOSstart;      /* Start of the flat panel info      */
    Bool              ddc_mode;         /* Validate mode by matching exactly
					 * the modes supported in DDC data
					 */
    Bool              R300CGWorkaround;

				/* EDID or BIOS values for FPs */
    int               PanelXRes;
    int               PanelYRes;
    int               HOverPlus;
    int               HSyncWidth;
    int               HBlank;
    int               VOverPlus;
    int               VSyncWidth;
    int               VBlank;
    int               PanelPwrDly;
    int               DotClock;
    int               RefDivider;
    int               FeedbackDivider;
    int               PostDivider;
    Bool              UseBiosDividers;
				/* EDID data using DDC interface */
    Bool              ddc_bios;
    Bool              ddc1;
    Bool              ddc2;
    I2CBusPtr         pI2CBus;
    CARD32            DDCReg;

    RADEONPLLRec      pll;
    RADEONTMDSPll     tmds_pll[4];
    int               RamWidth;
    float	      sclk;		/* in MHz */
    float	      mclk;		/* in MHz */
    Bool	      IsDDR;
    int               DispPriority;

    RADEONSaveRec     SavedReg;         /* Original (text) mode              */
    RADEONSaveRec     ModeReg;          /* Current mode                      */
    Bool              (*CloseScreen)(int, ScreenPtr);

    void              (*BlockHandler)(int, pointer, pointer, pointer);

    Bool              PaletteSavedOnVT; /* Palette saved on last VT switch   */

    XAAInfoRecPtr     accel;
    Bool              accelOn;
    xf86CursorInfoPtr cursor;
    unsigned long     cursor_start;
    unsigned long     cursor_end;
#ifdef ARGB_CURSOR
    Bool	      cursor_argb;
#endif
    int               cursor_fg;
    int               cursor_bg;

    /*
     * XAAForceTransBlit is used to change the behavior of the XAA
     * SetupForScreenToScreenCopy function, to make it DGA-friendly.
     */
    Bool              XAAForceTransBlit;

    int               fifo_slots;       /* Free slots in the FIFO (64 max)   */
    int               pix24bpp;         /* Depth of pixmap for 24bpp fb      */
    Bool              dac6bits;         /* Use 6 bit DAC?                    */

				/* Computed values for Radeon */
    int               pitch;
    int               datatype;
    CARD32            dp_gui_master_cntl;
    CARD32            dp_gui_master_cntl_clip;
    CARD32            trans_color;

				/* 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_w;
    int               scanline_h;
    int               scanline_h_w;
    int               scanline_words;
    int               scanline_direct;
    int               scanline_bpp;     /* Only used for ImageWrite */
    int               scanline_fg;
    int               scanline_bg;
    int               scanline_hpass;
    int               scanline_x1clip;
    int               scanline_x2clip;

				/* Saved values for DashedTwoPointLine */
    int               dashLen;
    CARD32            dashPattern;
    int               dash_fg;
    int               dash_bg;

    DGAModePtr        DGAModes;
    int               numDGAModes;
    Bool              DGAactive;
    int               DGAViewportStatus;
    DGAFunctionRec    DGAFuncs;

    RADEONFBLayout    CurrentLayout;
#ifdef XF86DRI
    Bool              noBackBuffer;
    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           pciSize;
    drmHandle         pciMemHandle;
    unsigned char     *PCI;             /* Map */

    Bool              depthMoves;       /* Enable depth moves -- slow! */
    Bool              allowPageFlip;    /* Enable 3d page flipping */
    Bool              have3DWindows;    /* Are there any 3d clients? */
    int               drmMinor;

    drmSize           gartSize;
    drmHandle         agpMemHandle;     /* Handle from drmAgpAlloc */
    unsigned long     gartOffset;
    unsigned char     *AGP;             /* Map */
    int               agpMode;
    int               agpFastWrite;

    CARD32            pciCommand;

    Bool              CPRuns;           /* CP is running */
    Bool              CPInUse;          /* CP has been used by X server */
    Bool              CPStarted;        /* CP has started */
    int               CPMode;           /* CP mode that server/clients use */
    int               CPFifoSize;       /* Size of the CP command FIFO */
    int               CPusecTimeout;    /* CP timeout in usecs */

				/* CP ring buffer data */
    unsigned long     ringStart;        /* Offset into GART 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 GART space */
    drmHandle         ringReadPtrHandle; /* Handle from drmAddMap */
    drmSize           ringReadMapSize;  /* Size of map */
    unsigned char     *ringReadPtr;     /* Map */

				/* CP vertex/indirect buffer data */
    unsigned long     bufStart;         /* Offset into GART space */
    drmHandle         bufHandle;        /* Handle from drmAddMap */
    drmSize           bufMapSize;       /* Size of map */
    int               bufSize;          /* Size of buffers (in MB) */
    unsigned char     *buf;             /* Map */
    int               bufNumBufs;       /* Number of buffers */
    drmBufMapPtr      buffers;          /* Buffer map */

				/* CP GART Texture data */
    unsigned long     gartTexStart;      /* Offset into GART space */
    drmHandle         gartTexHandle;     /* Handle from drmAddMap */
    drmSize           gartTexMapSize;    /* Size of map */
    int               gartTexSize;       /* Size of GART tex space (in MB) */
    unsigned char     *gartTex;          /* Map */
    int               log2GARTTexGran;

				/* CP accleration */
    drmBufPtr         indirectBuffer;
    int               indirectStart;

				/* DRI screen private data */
    int               fbX;
    int               fbY;
    int               backX;
    int               backY;
    int               depthX;
    int               depthY;

    int               frontOffset;
    int               frontPitch;
    int               backOffset;
    int               backPitch;
    int               depthOffset;
    int               depthPitch;
    int               textureOffset;
    int               textureSize;
    int               log2TexGran;

    CARD32            frontPitchOffset;
    CARD32            backPitchOffset;
    CARD32            depthPitchOffset;

    CARD32            dst_pitch_offset;

				/* offscreen memory management */
    int               backLines;
    FBAreaPtr         backArea;
    int               depthTexLines;
    FBAreaPtr         depthTexArea;

				/* Saved scissor values */
    CARD32            sc_left;
    CARD32            sc_right;
    CARD32            sc_top;
    CARD32            sc_bottom;

    CARD32            re_top_left;
    CARD32            re_width_height;

    CARD32            aux_sc_cntl;

    int               irq;

#ifdef PER_CONTEXT_SAREA
    int               perctx_sarea_size;
#endif
#endif

				/* XVideo */
    XF86VideoAdaptorPtr adaptor;
    void              (*VideoTimerCallback)(ScrnInfoPtr, Time);
    FBLinearPtr       videoLinear;
    int               videoKey;

				/* general */
    Bool              showCache;
    OptionInfoPtr     Options;
#ifdef XFree86LOADER
    XF86ModReqInfo    xaaReq;
#endif
} 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        RADEONWaitForIdleMMIO(ScrnInfoPtr pScrn);
#ifdef XF86DRI
extern void        RADEONWaitForIdleCP(ScrnInfoPtr pScrn);
#endif

extern void        RADEONDoAdjustFrame(ScrnInfoPtr pScrn, int x, int y,
				       int clone);

extern void        RADEONEngineReset(ScrnInfoPtr pScrn);
extern void        RADEONEngineFlush(ScrnInfoPtr pScrn);
extern void        RADEONEngineRestore(ScrnInfoPtr pScrn);

extern unsigned    RADEONINPLL(ScrnInfoPtr pScrn, int addr);
extern void        RADEONWaitForVerticalSync(ScrnInfoPtr pScrn);
extern void        RADEONWaitForVerticalSync2(ScrnInfoPtr pScrn);

extern void        RADEONSelectBuffer(ScrnInfoPtr pScrn, int buffer);

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 pScreen);
extern void        RADEONResetVideo(ScrnInfoPtr pScrn);
extern void        R300CGWorkaround(ScrnInfoPtr pScrn);

#ifdef XF86DRI
extern Bool        RADEONDRIScreenInit(ScreenPtr pScreen);
extern void        RADEONDRICloseScreen(ScreenPtr pScreen);
extern void        RADEONDRIResume(ScreenPtr pScreen);
extern Bool        RADEONDRIFinishScreenInit(ScreenPtr pScreen);

extern drmBufPtr   RADEONCPGetBuffer(ScrnInfoPtr pScrn);
extern void        RADEONCPFlushIndirect(ScrnInfoPtr pScrn, int discard);
extern void        RADEONCPReleaseIndirect(ScrnInfoPtr pScrn);
extern int         RADEONCPStop(ScrnInfoPtr pScrn,  RADEONInfoPtr info);


#define RADEONCP_START(pScrn, info)					\
do {									\
    int _ret = drmCommandNone(info->drmFD, DRM_RADEON_CP_START);	\
    if (_ret) {								\
	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,				\
		   "%s: CP start %d\n", __FUNCTION__, _ret);		\
    }									\
    info->CPStarted = TRUE;                                             \
} while (0)

#define RADEONCP_STOP(pScrn, info)					\
do {									\
    int _ret;								\
     if (info->CPStarted) {						\
        _ret = RADEONCPStop(pScrn, info);				\
        if (_ret) {							\
	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,			\
		   "%s: CP stop %d\n", __FUNCTION__, _ret);		\
        }								\
        info->CPStarted = FALSE;                                        \
   }									\
    RADEONEngineRestore(pScrn);						\
    info->CPRuns = FALSE;						\
} while (0)

#define RADEONCP_RESET(pScrn, info)					\
do {									\
    if (RADEONCP_USE_RING_BUFFER(info->CPMode)) {			\
	int _ret = drmCommandNone(info->drmFD, DRM_RADEON_CP_RESET);	\
	if (_ret) {							\
	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,			\
		       "%s: CP reset %d\n", __FUNCTION__, _ret);	\
	}								\
    }									\
} while (0)

#define RADEONCP_REFRESH(pScrn, info)					\
do {									\
    if (!info->CPInUse) {						\
	RADEON_WAIT_UNTIL_IDLE();					\
	BEGIN_RING(6);							\
	OUT_RING_REG(RADEON_RE_TOP_LEFT,     info->re_top_left);	\
	OUT_RING_REG(RADEON_RE_WIDTH_HEIGHT, info->re_width_height);	\
	OUT_RING_REG(RADEON_AUX_SC_CNTL,     info->aux_sc_cntl);	\
	ADVANCE_RING();							\
	info->CPInUse = TRUE;						\
    }									\
} while (0)


#define CP_PACKET0(reg, n)						\
	(RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2))
#define CP_PACKET1(reg0, reg1)						\
	(RADEON_CP_PACKET1 | (((reg1) >> 2) << 11) | ((reg0) >> 2))
#define CP_PACKET2()							\
	(RADEON_CP_PACKET2)
#define CP_PACKET3(pkt, n)						\
	(RADEON_CP_PACKET3 | (pkt) | ((n) << 16))


#define RADEON_VERBOSE	0

#define RING_LOCALS	CARD32 *__head = NULL; int __count = 0

#define BEGIN_RING(n) do {						\
    if (RADEON_VERBOSE) {						\
	xf86DrvMsg(pScrn->scrnIndex, X_INFO,				\
		   "BEGIN_RING(%d) in %s\n", n, __FUNCTION__);		\
    }									\
    if (!info->indirectBuffer) {					\
	info->indirectBuffer = RADEONCPGetBuffer(pScrn);		\
	info->indirectStart = 0;					\
    } else if (info->indirectBuffer->used + (n) * (int)sizeof(CARD32) >	\
	       info->indirectBuffer->total) {				\
	RADEONCPFlushIndirect(pScrn, 1);				\
    }									\
    __head = (pointer)((char *)info->indirectBuffer->address +		\
		       info->indirectBuffer->used);			\
    __count = 0;							\
} while (0)

#define ADVANCE_RING() do {						\
    if (RADEON_VERBOSE) {						\
	xf86DrvMsg(pScrn->scrnIndex, X_INFO,				\
		   "ADVANCE_RING() start: %d used: %d count: %d\n",	\
		   info->indirectStart,					\
		   info->indirectBuffer->used,				\
		   __count * (int)sizeof(CARD32));			\
    }									\
    info->indirectBuffer->used += __count * (int)sizeof(CARD32);	\
} while (0)

#define OUT_RING(x) do {						\
    if (RADEON_VERBOSE) {						\
	xf86DrvMsg(pScrn->scrnIndex, X_INFO,				\
		   "   OUT_RING(0x%08x)\n", (unsigned int)(x));		\
    }									\
    __head[__count++] = (x);						\
} while (0)

#define OUT_RING_REG(reg, val)						\
do {									\
    OUT_RING(CP_PACKET0(reg, 0));					\
    OUT_RING(val);							\
} while (0)

#define FLUSH_RING()							\
do {									\
    if (RADEON_VERBOSE)							\
	xf86DrvMsg(pScrn->scrnIndex, X_INFO,				\
		   "FLUSH_RING in %s\n", __FUNCTION__);			\
    if (info->indirectBuffer) {						\
	RADEONCPFlushIndirect(pScrn, 0);				\
    }									\
} while (0)


#define RADEON_WAIT_UNTIL_2D_IDLE()					\
do {									\
    BEGIN_RING(2);							\
    OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));				\
    OUT_RING((RADEON_WAIT_2D_IDLECLEAN |				\
	      RADEON_WAIT_HOST_IDLECLEAN));				\
    ADVANCE_RING();							\
} while (0)

#define RADEON_WAIT_UNTIL_3D_IDLE()					\
do {									\
    BEGIN_RING(2);							\
    OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));				\
    OUT_RING((RADEON_WAIT_3D_IDLECLEAN |				\
	      RADEON_WAIT_HOST_IDLECLEAN));				\
    ADVANCE_RING();							\
} while (0)

#define RADEON_WAIT_UNTIL_IDLE()					\
do {									\
    if (RADEON_VERBOSE) {						\
	xf86DrvMsg(pScrn->scrnIndex, X_INFO,				\
		   "WAIT_UNTIL_IDLE() in %s\n", __FUNCTION__);		\
    }									\
    BEGIN_RING(2);							\
    OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));				\
    OUT_RING((RADEON_WAIT_2D_IDLECLEAN |				\
	      RADEON_WAIT_3D_IDLECLEAN |				\
	      RADEON_WAIT_HOST_IDLECLEAN));				\
    ADVANCE_RING();							\
} while (0)

#define RADEON_FLUSH_CACHE()						\
do {									\
    BEGIN_RING(2);							\
    OUT_RING(CP_PACKET0(RADEON_RB2D_DSTCACHE_CTLSTAT, 0));		\
    OUT_RING(RADEON_RB2D_DC_FLUSH);					\
    ADVANCE_RING();							\
} while (0)

#define RADEON_PURGE_CACHE()						\
do {									\
    BEGIN_RING(2);							\
    OUT_RING(CP_PACKET0(RADEON_RB2D_DSTCACHE_CTLSTAT, 0));		\
    OUT_RING(RADEON_RB2D_DC_FLUSH_ALL);					\
    ADVANCE_RING();							\
} while (0)

#endif /* XF86DRI */

#endif /* _RADEON_H_ */

--- NEW FILE: radeon_accel.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c,v 1.36 2003/11/10 18:41:22 tsi Exp $ */
/*
 * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
 *                VA Linux Systems Inc., Fremont, 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 at xfree86.org>
 *   Rickard E. Faith <faith at valinux.com>
 *   Alan Hourihane <alanh at fairlite.demon.co.uk>
 *
 * Credits:
 *
 *   Thanks to Ani Joshi <ajoshi at 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
 *
 */

				/* Driver data structures */
#include "radeon.h"
#include "radeon_macros.h"
#include "radeon_probe.h"
#include "radeon_reg.h"
#include "radeon_version.h"
#ifdef XF86DRI
#define _XF86DRI_SERVER_
#include "radeon_dri.h"
#include "radeon_sarea.h"
#endif

				/* Line support */
#include "miline.h"

				/* X and server generic header files */
#include "xf86.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          */
};

extern int gRADEONEntityIndex;

/* 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);
	RADEONEngineRestore(pScrn);
#ifdef XF86DRI
	if (info->directRenderingEnabled) {
	    RADEONCP_RESET(pScrn, info);
	    RADEONCP_START(pScrn, info);
	}
#endif
    }
}

/* 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;
    CARD32         host_path_cntl;

    RADEONEngineFlush(pScrn);

    clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX);
    if (info->R300CGWorkaround) R300CGWorkaround(pScrn);

    /* Some ASICs have bugs with dynamic-on feature, which are
     * ASIC-version dependent, so we force all blocks on for now
     */
    if (info->HasCRTC2) {
	CARD32 tmp;

	tmp = INPLL(pScrn, RADEON_SCLK_CNTL);
	OUTPLL(RADEON_SCLK_CNTL, ((tmp & ~RADEON_DYN_STOP_LAT_MASK) |
				  RADEON_CP_MAX_DYN_STOP_LAT |
				  RADEON_SCLK_FORCEON_MASK));

	if (info->ChipFamily == CHIP_FAMILY_RV200) {
	    tmp = INPLL(pScrn, RADEON_SCLK_MORE_CNTL);
	    OUTPLL(RADEON_SCLK_MORE_CNTL, tmp | RADEON_SCLK_MORE_FORCEON);
	}
    }

    mclk_cntl = INPLL(pScrn, RADEON_MCLK_CNTL);
    OUTPLL(RADEON_MCLK_CNTL, (mclk_cntl |
			      RADEON_FORCEON_MCLKA |
			      RADEON_FORCEON_MCLKB |
			      RADEON_FORCEON_YCLKA |
			      RADEON_FORCEON_YCLKB |
			      RADEON_FORCEON_MC |
			      RADEON_FORCEON_AIC));

    /* Soft resetting HDP thru RBBM_SOFT_RESET register can cause some
     * unexpected behaviour on some machines.  Here we use
     * RADEON_HOST_PATH_CNTL to reset it.
     */
    host_path_cntl = INREG(RADEON_HOST_PATH_CNTL);
    rbbm_soft_reset = INREG(RADEON_RBBM_SOFT_RESET);

    if ((info->ChipFamily == CHIP_FAMILY_R300) ||
	(info->ChipFamily == CHIP_FAMILY_R350) ||
	(info->ChipFamily == CHIP_FAMILY_RV350)) {
	CARD32 tmp;

	OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset |
					RADEON_SOFT_RESET_CP |
					RADEON_SOFT_RESET_HI |
					RADEON_SOFT_RESET_E2));
	INREG(RADEON_RBBM_SOFT_RESET);
	OUTREG(RADEON_RBBM_SOFT_RESET, 0);
	tmp = INREG(RADEON_RB2D_DSTCACHE_MODE);
	OUTREG(RADEON_RB2D_DSTCACHE_MODE, tmp | (1 << 17)); /* FIXME */
    } else {
	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));
	INREG(RADEON_RBBM_SOFT_RESET);
	OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset & (CARD32)
					~(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)));
	INREG(RADEON_RBBM_SOFT_RESET);
    }

    OUTREG(RADEON_HOST_PATH_CNTL, host_path_cntl | RADEON_HDP_SOFT_RESET);
    INREG(RADEON_HOST_PATH_CNTL);
    OUTREG(RADEON_HOST_PATH_CNTL, host_path_cntl);

    if ((info->ChipFamily != CHIP_FAMILY_R300) &&
        (info->ChipFamily != CHIP_FAMILY_R350) &&
        (info->ChipFamily != CHIP_FAMILY_RV350))
	OUTREG(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset);

    OUTREG(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index);
    OUTPLL(RADEON_MCLK_CNTL, mclk_cntl);
    if (info->R300CGWorkaround) R300CGWorkaround(pScrn);
}

/* Restore the acceleration hardware to its previous state */
void RADEONEngineRestore(ScrnInfoPtr pScrn)
{
    RADEONInfoPtr  info       = RADEONPTR(pScrn);
    unsigned char *RADEONMMIO = info->MMIO;
    int            pitch64;

    RADEONTRACE(("EngineRestore (%d/%d)\n",
		 info->CurrentLayout.pixel_code,
		 info->CurrentLayout.bitsPerPixel));

    RADEONWaitForFifo(pScrn, 1);

    /* NOTE: The following RB2D_DSTCACHE_MODE setting will cause the
     * R300 to hang.  ATI does not see a reason to change it from the
     * default BIOS settings (even on non-R300 cards).  This setting
     * might be removed in future versions of the Radeon driver.
     */

    /* Turn of all automatic flushing - we'll do it all */
    if ((info->ChipFamily != CHIP_FAMILY_R300) &&
	(info->ChipFamily != CHIP_FAMILY_R350) &&
	(info->ChipFamily != CHIP_FAMILY_RV350))
	OUTREG(RADEON_RB2D_DSTCACHE_MODE, 0);

    pitch64 = ((pScrn->displayWidth * (pScrn->bitsPerPixel / 8) + 0x3f)) >> 6;

    RADEONWaitForFifo(pScrn, 1);
    OUTREG(RADEON_DEFAULT_OFFSET, ((INREG(RADEON_DISPLAY_BASE_ADDR) >> 10)
				   | (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

    /* Restore SURFACE_CNTL - only the first head contains valid data -ReneR */
    if (!info->IsSecondary) {
	OUTREG(RADEON_SURFACE_CNTL, info->ModeReg.surface_cntl);
    }

    RADEONWaitForFifo(pScrn, 1);
    OUTREG(RADEON_DEFAULT_SC_BOTTOM_RIGHT, (RADEON_DEFAULT_SC_RIGHT_MAX
					    | RADEON_DEFAULT_SC_BOTTOM_MAX));
    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);

    RADEONWaitForIdleMMIO(pScrn);
}

/* Initialize the acceleration hardware */
void RADEONEngineInit(ScrnInfoPtr pScrn)
{
    RADEONInfoPtr  info       = RADEONPTR(pScrn);
    unsigned char *RADEONMMIO = info->MMIO;

    RADEONTRACE(("EngineInit (%d/%d)\n",
		 info->CurrentLayout.pixel_code,
		 info->CurrentLayout.bitsPerPixel));

    OUTREG(RADEON_RB3D_CNTL, 0);
#if defined(__powerpc__)
#if defined(XF86_DRI)
    if(!info->directRenderingEnabled)
#endif
    {
	OUTREG(RADEON_MC_FB_LOCATION, 0xffff0000);
	OUTREG(RADEON_MC_AGP_LOCATION, 0xfffff000);
    }
#endif

    RADEONEngineReset(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:
	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));

    info->dp_gui_master_cntl =
	((info->datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
	 | RADEON_GMC_CLR_CMP_CNTL_DIS);

#ifdef XF86DRI
    info->sc_left         = 0x00000000;
    info->sc_right        = RADEON_DEFAULT_SC_RIGHT_MAX;
    info->sc_top          = 0x00000000;
    info->sc_bottom       = RADEON_DEFAULT_SC_BOTTOM_MAX;

    info->re_top_left     = 0x00000000;
    info->re_width_height = ((0x7ff << RADEON_RE_WIDTH_SHIFT) |
			     (0x7ff << RADEON_RE_HEIGHT_SHIFT));

    info->aux_sc_cntl     = 0x00000000;
#endif

    RADEONEngineRestore(pScrn);
}

#define ACCEL_MMIO
#define ACCEL_PREAMBLE()        unsigned char *RADEONMMIO = info->MMIO
#define BEGIN_ACCEL(n)          RADEONWaitForFifo(pScrn, (n))
#define OUT_ACCEL_REG(reg, val) OUTREG(reg, val)
#define FINISH_ACCEL()

#include "radeon_accelfuncs.c"

#undef ACCEL_MMIO
#undef ACCEL_PREAMBLE
#undef BEGIN_ACCEL
#undef OUT_ACCEL_REG
#undef FINISH_ACCEL

#ifdef XF86DRI

#define ACCEL_CP
#define ACCEL_PREAMBLE()						\
    RING_LOCALS;							\
    RADEONCP_REFRESH(pScrn, info)
#define BEGIN_ACCEL(n)          BEGIN_RING(2*(n))
#define OUT_ACCEL_REG(reg, val) OUT_RING_REG(reg, val)
#define FINISH_ACCEL()          ADVANCE_RING()

#include "radeon_accelfuncs.c"

#undef ACCEL_CP
#undef ACCEL_PREAMBLE
#undef BEGIN_ACCEL
#undef OUT_ACCEL_REG
#undef FINISH_ACCEL

/* Stop the CP */
int RADEONCPStop(ScrnInfoPtr pScrn, RADEONInfoPtr info)
{
    drmRadeonCPStop  stop;
    int              ret, i;

    stop.flush = 1;
    stop.idle  = 1;

    ret = drmCommandWrite(info->drmFD, DRM_RADEON_CP_STOP, &stop,
			  sizeof(drmRadeonCPStop));

    if (ret == 0) {
	return 0;
    } else if (errno != EBUSY) {
	return -errno;
    }

    stop.flush = 0;

    i = 0;
    do {
	ret = drmCommandWrite(info->drmFD, DRM_RADEON_CP_STOP, &stop,
			      sizeof(drmRadeonCPStop));
    } while (ret && errno == EBUSY && i++ < RADEON_IDLE_RETRY);

    if (ret == 0) {
	return 0;
    } else if (errno != EBUSY) {
	return -errno;
    }

    stop.idle = 0;

    if (drmCommandWrite(info->drmFD, DRM_RADEON_CP_STOP,
			&stop, sizeof(drmRadeonCPStop))) {
	return -errno;
    } else {
	return 0;
    }
}

/* Get an indirect buffer for the CP 2D acceleration commands  */
drmBufPtr RADEONCPGetBuffer(ScrnInfoPtr pScrn)
{
    RADEONInfoPtr  info = RADEONPTR(pScrn);
    drmDMAReq      dma;
    drmBufPtr      buf = NULL;
    int            indx = 0;
    int            size = 0;
    int            i = 0;
    int            ret;

#if 0
    /* FIXME: pScrn->pScreen has not been initialized when this is first
     * called from RADEONSelectBuffer via RADEONDRICPInit.  We could use
     * the screen index from pScrn, which is initialized, and then get
     * the screen from screenInfo.screens[index], but that is a hack.
     */
    dma.context = DRIGetContext(pScrn->pScreen);
#else
    /* This is the X server's context */
    dma.context = 0x00000001;
#endif

    dma.send_count    = 0;
    dma.send_list     = NULL;
    dma.send_sizes    = NULL;
    dma.flags         = 0;
    dma.request_count = 1;
    dma.request_size  = RADEON_BUFFER_SIZE;
    dma.request_list  = &indx;
    dma.request_sizes = &size;
    dma.granted_count = 0;

    while (1) {
	do {
	    ret = drmDMA(info->drmFD, &dma);
	    if (ret && ret != -EBUSY) {
		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
			   "%s: CP GetBuffer %d\n", __FUNCTION__, ret);
	    }
	} while ((ret == -EBUSY) && (i++ < RADEON_TIMEOUT));

	if (ret == 0) {
	    buf = &info->buffers->list[indx];
	    buf->used = 0;
	    if (RADEON_VERBOSE) {
		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
			   "   GetBuffer returning %d %p\n",
			   buf->idx, buf->address);
	    }
	    return buf;
	}

	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
		   "GetBuffer timed out, resetting engine...\n");
	RADEONEngineReset(pScrn);
	RADEONEngineRestore(pScrn);

	/* Always restart the engine when doing CP 2D acceleration */
	RADEONCP_RESET(pScrn, info);
	RADEONCP_START(pScrn, info);
    }
}

/* Flush the indirect buffer to the kernel for submission to the card */
void RADEONCPFlushIndirect(ScrnInfoPtr pScrn, int discard)
{
    RADEONInfoPtr      info   = RADEONPTR(pScrn);
    drmBufPtr          buffer = info->indirectBuffer;
    int                start  = info->indirectStart;
    drmRadeonIndirect  indirect;

    if (!buffer) return;
    if (start == buffer->used && !discard) return;

    if (RADEON_VERBOSE) {
	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Flushing buffer %d\n",
		   buffer->idx);
    }

    indirect.idx     = buffer->idx;
    indirect.start   = start;
    indirect.end     = buffer->used;
    indirect.discard = discard;

    drmCommandWriteRead(info->drmFD, DRM_RADEON_INDIRECT,
			&indirect, sizeof(drmRadeonIndirect));

    if (discard) {
	info->indirectBuffer = RADEONCPGetBuffer(pScrn);
	info->indirectStart  = 0;
    } else {
	/* Start on a double word boundary */
	info->indirectStart  = buffer->used = (buffer->used + 7) & ~7;
	if (RADEON_VERBOSE) {
	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "   Starting at %d\n",
		       info->indirectStart);
	}
    }
}

/* Flush and release the indirect buffer */
void RADEONCPReleaseIndirect(ScrnInfoPtr pScrn)
{
    RADEONInfoPtr      info   = RADEONPTR(pScrn);
    drmBufPtr          buffer = info->indirectBuffer;
    int                start  = info->indirectStart;
    drmRadeonIndirect  indirect;

    info->indirectBuffer = NULL;
    info->indirectStart  = 0;

    if (!buffer) return;

    if (RADEON_VERBOSE) {
	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Releasing buffer %d\n",
		   buffer->idx);
    }

    indirect.idx     = buffer->idx;
    indirect.start   = start;
    indirect.end     = buffer->used;
    indirect.discard = 1;

    drmCommandWriteRead(info->drmFD, DRM_RADEON_INDIRECT,
			&indirect, sizeof(drmRadeonIndirect));
}
#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())) {
	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "XAACreateInfoRec Error\n");
	return FALSE;
    }

#ifdef XF86DRI
    if (info->directRenderingEnabled)
	RADEONAccelInitCP(pScreen, a);
    else
#endif
	RADEONAccelInitMMIO(pScreen, a);

    RADEONEngineInit(pScrn);

    if (!XAAInit(pScreen, a)) {
	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "XAAInit Error\n");
	return FALSE;
    }

    return TRUE;
}

--- NEW FILE: radeon_accelfuncs.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accelfuncs.c,v 1.7tsi Exp $ */
/*
 * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
 *                VA Linux Systems Inc., Fremont, 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.
 *
[...1312 lines suppressed...]
		 * without a source rop. To show run 'xtest's ptimg
		 */
					  | ROP_NEEDS_SOURCE
					  | SCANLINE_PAD_DWORD
					  | LEFT_EDGE_CLIPPING
					  | LEFT_EDGE_CLIPPING_NEGATIVE_X);

#if 0
				/* Color 8x8 Pattern Fill */
    a->SetupForColor8x8PatternFill
	= FUNC_NAME(RADEONSetupForColor8x8PatternFill);
    a->SubsequentColor8x8PatternFillRect
	= FUNC_NAME(RADEONSubsequentColor8x8PatternFillRect);
    a->Color8x8PatternFillFlags         = (HARDWARE_PATTERN_PROGRAMMED_ORIGIN
					   | HARDWARE_PATTERN_SCREEN_ORIGIN
					   | BIT_ORDER_IN_BYTE_LSBFIRST);
#endif
}

#undef FUNC_NAME

--- NEW FILE: radeon_common.h ---
/* radeon_common.h -- common header definitions for Radeon 2D/3D/DRM suite
 *
 * Copyright 2000 VA Linux Systems, Inc., Fremont, California.
 * Copyright 2002 Tungsten Graphics, 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
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * Author:
 *   Gareth Hughes <gareth at valinux.com>
 *   Kevin E. Martin <martin at valinux.com>
 *   Keith Whitwell <keith at tungstengraphics.com>
 *
 * Converted to common header format:
 *   Jens Owen <jens at tungstengraphics.com>
 *
 * $XdotOrg: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_common.h,v 1.1.4.3.4.1 2004/03/04 17:47:39 eich Exp $
 * $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_common.h,v 1.8tsi Exp $
 *
 */

#ifndef _RADEON_COMMON_H_
#define _RADEON_COMMON_H_

#include "xf86drm.h"

/* WARNING: If you change any of these defines, make sure to change
 * the kernel include file as well (radeon_drm.h)
 */

/* Driver specific DRM command indices
 * NOTE: these are not OS specific, but they are driver specific
 */
#define DRM_RADEON_CP_INIT                0x00
#define DRM_RADEON_CP_START               0x01
#define DRM_RADEON_CP_STOP                0x02
#define DRM_RADEON_CP_RESET               0x03
#define DRM_RADEON_CP_IDLE                0x04
#define DRM_RADEON_RESET                  0x05
#define DRM_RADEON_FULLSCREEN             0x06
#define DRM_RADEON_SWAP                   0x07
#define DRM_RADEON_CLEAR                  0x08
#define DRM_RADEON_VERTEX                 0x09
#define DRM_RADEON_INDICES                0x0a
#define DRM_RADEON_STIPPLE                0x0c
#define DRM_RADEON_INDIRECT               0x0d
#define DRM_RADEON_TEXTURE                0x0e
#define DRM_RADEON_VERTEX2                0x0f
#define DRM_RADEON_CMDBUF                 0x10
#define DRM_RADEON_GETPARAM               0x11
#define DRM_RADEON_FLIP                   0x12
#define DRM_RADEON_ALLOC                  0x13
#define DRM_RADEON_FREE                   0x14
#define DRM_RADEON_INIT_HEAP              0x15
#define DRM_RADEON_IRQ_EMIT               0x16
#define DRM_RADEON_IRQ_WAIT               0x17
#define DRM_RADEON_CP_RESUME              0x18
#define DRM_RADEON_SETPARAM               0x19
#define DRM_RADEON_MAX_DRM_COMMAND_INDEX  0x39


#define RADEON_FRONT	0x1
#define RADEON_BACK	0x2
#define RADEON_DEPTH	0x4
#define RADEON_STENCIL	0x8

#define RADEON_CLEAR_X1        0
#define RADEON_CLEAR_Y1        1
#define RADEON_CLEAR_X2        2
#define RADEON_CLEAR_Y2        3
#define RADEON_CLEAR_DEPTH     4


typedef struct {
   enum {
      DRM_RADEON_INIT_CP    = 0x01,
      DRM_RADEON_CLEANUP_CP = 0x02,
      DRM_RADEON_INIT_R200_CP = 0x03
   } func;
   unsigned long sarea_priv_offset;
   int is_pci;
   int cp_mode;
   int gart_size;
   int ring_size;
   int usec_timeout;

   unsigned int fb_bpp;
   unsigned int front_offset, front_pitch;
   unsigned int back_offset, back_pitch;
   unsigned int depth_bpp;
   unsigned int depth_offset, depth_pitch;

   unsigned long fb_offset;
   unsigned long mmio_offset;
   unsigned long ring_offset;
   unsigned long ring_rptr_offset;
   unsigned long buffers_offset;
   unsigned long gart_textures_offset;
} drmRadeonInit;

typedef struct {
   int flush;
   int idle;
} drmRadeonCPStop;

typedef struct {
   int idx;
   int start;
   int end;
   int discard;
} drmRadeonIndirect;

typedef union drmRadeonClearR {
        float f[5];
        unsigned int ui[5];
} drmRadeonClearRect;

typedef struct drmRadeonClearT {
        unsigned int flags;
        unsigned int clear_color;
        unsigned int clear_depth;
        unsigned int color_mask;
        unsigned int depth_mask;   /* misnamed field:  should be stencil */
        drmRadeonClearRect *depth_boxes;
} drmRadeonClearType;

typedef struct drmRadeonFullscreenT {
        enum {
                RADEON_INIT_FULLSCREEN    = 0x01,
                RADEON_CLEANUP_FULLSCREEN = 0x02
        } func;
} drmRadeonFullscreenType;

typedef struct {
        unsigned int *mask;
} drmRadeonStipple;

typedef struct {
        unsigned int x;
        unsigned int y;
        unsigned int width;
        unsigned int height;
        const void *data;
} drmRadeonTexImage;

typedef struct {
        unsigned int offset;
        int pitch;
        int format;
        int width;                      /* Texture image coordinates */
        int height;
        drmRadeonTexImage *image;
} drmRadeonTexture;


#define RADEON_MAX_TEXTURE_UNITS 3

/* Layout matches drm_radeon_state_t in linux drm_radeon.h.
 */
typedef struct {
	struct {
		unsigned int pp_misc;				/* 0x1c14 */
		unsigned int pp_fog_color;
		unsigned int re_solid_color;
		unsigned int rb3d_blendcntl;
		unsigned int rb3d_depthoffset;
		unsigned int rb3d_depthpitch;
		unsigned int rb3d_zstencilcntl;
		unsigned int pp_cntl;				/* 0x1c38 */
		unsigned int rb3d_cntl;
		unsigned int rb3d_coloroffset;
		unsigned int re_width_height;
		unsigned int rb3d_colorpitch;
	} context;
	struct {
		unsigned int se_cntl;
	} setup1;
	struct {
		unsigned int se_coord_fmt;			/* 0x1c50 */
	} vertex;
	struct {
		unsigned int re_line_pattern;			/* 0x1cd0 */
		unsigned int re_line_state;
		unsigned int se_line_width;			/* 0x1db8 */
	} line;
	struct {
		unsigned int pp_lum_matrix;			/* 0x1d00 */
		unsigned int pp_rot_matrix_0;			/* 0x1d58 */
		unsigned int pp_rot_matrix_1;
	} bumpmap;
	struct {
		unsigned int rb3d_stencilrefmask;		/* 0x1d7c */
		unsigned int rb3d_ropcntl;
		unsigned int rb3d_planemask;
	} mask;
	struct {
		unsigned int se_vport_xscale;			/* 0x1d98 */
		unsigned int se_vport_xoffset;
		unsigned int se_vport_yscale;
		unsigned int se_vport_yoffset;
		unsigned int se_vport_zscale;
		unsigned int se_vport_zoffset;
	} viewport;
	struct {
		unsigned int se_cntl_status;			/* 0x2140 */
	} setup2;
	struct {
		unsigned int re_top_left;	/*ignored*/	/* 0x26c0 */
		unsigned int re_misc;
	} misc;
	struct {
		unsigned int pp_txfilter;
		unsigned int pp_txformat;
		unsigned int pp_txoffset;
		unsigned int pp_txcblend;
		unsigned int pp_txablend;
		unsigned int pp_tfactor;
		unsigned int pp_border_color;
	} texture[RADEON_MAX_TEXTURE_UNITS];
	struct {
		unsigned int se_zbias_factor;
		unsigned int se_zbias_constant;
	} zbias;
	unsigned int dirty;
} drmRadeonState;

/* 1.1 vertex ioctl.  Used in compatibility modes.
 */
typedef struct {
	int prim;
	int idx;			/* Index of vertex buffer */
	int count;			/* Number of vertices in buffer */
	int discard;			/* Client finished with buffer? */
} drmRadeonVertex;

typedef struct {
	unsigned int start;
	unsigned int finish;
	unsigned int prim:8;
	unsigned int stateidx:8;
	unsigned int numverts:16; /* overloaded as offset/64 for elt prims */
        unsigned int vc_format;
} drmRadeonPrim;

typedef struct {
        int idx;                        /* Index of vertex buffer */
        int discard;                    /* Client finished with buffer? */
        int nr_states;
        drmRadeonState *state;
        int nr_prims;
        drmRadeonPrim *prim;
} drmRadeonVertex2;

#define RADEON_MAX_STATES 16
#define RADEON_MAX_PRIMS  64

/* Command buffer.  Replace with true dma stream?
 */
typedef struct {
	int bufsz;
	char *buf;
	int nbox;
        drmClipRect *boxes;
} drmRadeonCmdBuffer;

/* New style per-packet identifiers for use in cmd_buffer ioctl with
 * the RADEON_EMIT_PACKET command.  Comments relate new packets to old
 * state bits and the packet size:
 */
#define RADEON_EMIT_PP_MISC                         0 /* context/7 */
#define RADEON_EMIT_PP_CNTL                         1 /* context/3 */
#define RADEON_EMIT_RB3D_COLORPITCH                 2 /* context/1 */
#define RADEON_EMIT_RE_LINE_PATTERN                 3 /* line/2 */
#define RADEON_EMIT_SE_LINE_WIDTH                   4 /* line/1 */
#define RADEON_EMIT_PP_LUM_MATRIX                   5 /* bumpmap/1 */
#define RADEON_EMIT_PP_ROT_MATRIX_0                 6 /* bumpmap/2 */
#define RADEON_EMIT_RB3D_STENCILREFMASK             7 /* masks/3 */
#define RADEON_EMIT_SE_VPORT_XSCALE                 8 /* viewport/6 */
#define RADEON_EMIT_SE_CNTL                         9 /* setup/2 */
#define RADEON_EMIT_SE_CNTL_STATUS                  10 /* setup/1 */
#define RADEON_EMIT_RE_MISC                         11 /* misc/1 */
#define RADEON_EMIT_PP_TXFILTER_0                   12 /* tex0/6 */
#define RADEON_EMIT_PP_BORDER_COLOR_0               13 /* tex0/1 */
#define RADEON_EMIT_PP_TXFILTER_1                   14 /* tex1/6 */
#define RADEON_EMIT_PP_BORDER_COLOR_1               15 /* tex1/1 */
#define RADEON_EMIT_PP_TXFILTER_2                   16 /* tex2/6 */
#define RADEON_EMIT_PP_BORDER_COLOR_2               17 /* tex2/1 */
#define RADEON_EMIT_SE_ZBIAS_FACTOR                 18 /* zbias/2 */
#define RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT           19 /* tcl/11 */
#define RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED   20 /* material/17 */
#define R200_EMIT_PP_TXCBLEND_0                     21 /* tex0/4 */
#define R200_EMIT_PP_TXCBLEND_1                     22 /* tex1/4 */
#define R200_EMIT_PP_TXCBLEND_2                     23 /* tex2/4 */
#define R200_EMIT_PP_TXCBLEND_3                     24 /* tex3/4 */
#define R200_EMIT_PP_TXCBLEND_4                     25 /* tex4/4 */
#define R200_EMIT_PP_TXCBLEND_5                     26 /* tex5/4 */
#define R200_EMIT_PP_TXCBLEND_6                     27 /* /4 */
#define R200_EMIT_PP_TXCBLEND_7                     28 /* /4 */
#define R200_EMIT_TCL_LIGHT_MODEL_CTL_0             29 /* tcl/6 */
#define R200_EMIT_TFACTOR_0                         30 /* tf/6 */
#define R200_EMIT_VTX_FMT_0                         31 /* vtx/4 */
#define R200_EMIT_VAP_CTL                           32 /* vap/1 */
#define R200_EMIT_MATRIX_SELECT_0                   33 /* msl/5 */
#define R200_EMIT_TEX_PROC_CTL_2                    34 /* tcg/5 */
#define R200_EMIT_TCL_UCP_VERT_BLEND_CTL            35 /* tcl/1 */
#define R200_EMIT_PP_TXFILTER_0                     36 /* tex0/6 */
#define R200_EMIT_PP_TXFILTER_1                     37 /* tex1/6 */
#define R200_EMIT_PP_TXFILTER_2                     38 /* tex2/6 */
#define R200_EMIT_PP_TXFILTER_3                     39 /* tex3/6 */
#define R200_EMIT_PP_TXFILTER_4                     40 /* tex4/6 */
#define R200_EMIT_PP_TXFILTER_5                     41 /* tex5/6 */
#define R200_EMIT_PP_TXOFFSET_0                     42 /* tex0/1 */
#define R200_EMIT_PP_TXOFFSET_1                     43 /* tex1/1 */
#define R200_EMIT_PP_TXOFFSET_2                     44 /* tex2/1 */
#define R200_EMIT_PP_TXOFFSET_3                     45 /* tex3/1 */
#define R200_EMIT_PP_TXOFFSET_4                     46 /* tex4/1 */
#define R200_EMIT_PP_TXOFFSET_5                     47 /* tex5/1 */
#define R200_EMIT_VTE_CNTL                          48 /* vte/1 */
#define R200_EMIT_OUTPUT_VTX_COMP_SEL               49 /* vtx/1 */
#define R200_EMIT_PP_TAM_DEBUG3                     50 /* tam/1 */
#define R200_EMIT_PP_CNTL_X                         51 /* cst/1 */
#define R200_EMIT_RB3D_DEPTHXY_OFFSET               52 /* cst/1 */
#define R200_EMIT_RE_AUX_SCISSOR_CNTL               53 /* cst/1 */
#define R200_EMIT_RE_SCISSOR_TL_0                   54 /* cst/2 */
#define R200_EMIT_RE_SCISSOR_TL_1                   55 /* cst/2 */
#define R200_EMIT_RE_SCISSOR_TL_2                   56 /* cst/2 */
#define R200_EMIT_SE_VAP_CNTL_STATUS                57 /* cst/1 */
#define R200_EMIT_SE_VTX_STATE_CNTL                 58 /* cst/1 */
#define R200_EMIT_RE_POINTSIZE                      59 /* cst/1 */
#define R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0       60 /* cst/4 */
#define R200_EMIT_PP_CUBIC_FACES_0                  61
#define R200_EMIT_PP_CUBIC_OFFSETS_0                62
#define R200_EMIT_PP_CUBIC_FACES_1                  63
#define R200_EMIT_PP_CUBIC_OFFSETS_1                64
#define R200_EMIT_PP_CUBIC_FACES_2                  65
#define R200_EMIT_PP_CUBIC_OFFSETS_2                66
#define R200_EMIT_PP_CUBIC_FACES_3                  67
#define R200_EMIT_PP_CUBIC_OFFSETS_3                68
#define R200_EMIT_PP_CUBIC_FACES_4                  69
#define R200_EMIT_PP_CUBIC_OFFSETS_4                70
#define R200_EMIT_PP_CUBIC_FACES_5                  71
#define R200_EMIT_PP_CUBIC_OFFSETS_5                72
#define RADEON_EMIT_PP_TEX_SIZE_0                   73
#define RADEON_EMIT_PP_TEX_SIZE_1                   74
#define RADEON_EMIT_PP_TEX_SIZE_2                   75
#define RADEON_MAX_STATE_PACKETS                    76


/* Commands understood by cmd_buffer ioctl.  More can be added but
 * obviously these can't be removed or changed:
 */
#define RADEON_CMD_PACKET      1 /* emit one of the register packets above */
#define RADEON_CMD_SCALARS     2 /* emit scalar data */
#define RADEON_CMD_VECTORS     3 /* emit vector data */
#define RADEON_CMD_DMA_DISCARD 4 /* discard current dma buf */
#define RADEON_CMD_PACKET3     5 /* emit hw packet */
#define RADEON_CMD_PACKET3_CLIP 6 /* emit hw packet wrapped in cliprects */
#define RADEON_CMD_SCALARS2     7 /* R200 stopgap */
#define RADEON_CMD_WAIT         8 /* synchronization */

typedef union {
	int i;
	struct {
	   unsigned char cmd_type, pad0, pad1, pad2;
	} header;
	struct {
	   unsigned char cmd_type, packet_id, pad0, pad1;
	} packet;
	struct {
	   unsigned char cmd_type, offset, stride, count;
	} scalars;
	struct {
	   unsigned char cmd_type, offset, stride, count;
	} vectors;
	struct {
	   unsigned char cmd_type, buf_idx, pad0, pad1;
	} dma;
	struct {
	   unsigned char cmd_type, flags, pad0, pad1;
	} wait;
} drmRadeonCmdHeader;


#define RADEON_WAIT_2D  0x1
#define RADEON_WAIT_3D  0x2


typedef struct drm_radeon_getparam {
	int param;
	int *value;
} drmRadeonGetParam;

#define RADEON_PARAM_GART_BUFFER_OFFSET 1
#define RADEON_PARAM_LAST_FRAME         2
#define RADEON_PARAM_LAST_DISPATCH      3
#define RADEON_PARAM_LAST_CLEAR         4
#define RADEON_PARAM_IRQ_NR             5
#define RADEON_PARAM_GART_BASE          6


#define RADEON_MEM_REGION_GART 1
#define RADEON_MEM_REGION_FB   2

typedef struct drm_radeon_mem_alloc {
	int region;
	int alignment;
	int size;
	int *region_offset;	/* offset from start of fb or GART */
} drmRadeonMemAlloc;

typedef struct drm_radeon_mem_free {
	int region;
	int region_offset;
} drmRadeonMemFree;

typedef struct drm_radeon_mem_init_heap {
	int region;
	int size;
	int start;
} drmRadeonMemInitHeap;

/* 1.6: Userspace can request & wait on irq's:
 */
typedef struct drm_radeon_irq_emit {
	int *irq_seq;
} drmRadeonIrqEmit;

typedef struct drm_radeon_irq_wait {
	int irq_seq;
} drmRadeonIrqWait;


/* 1.10: Clients tell the DRM where they think the framebuffer is located in
 * the card's address space, via a new generic ioctl to set parameters
 */

typedef struct drm_radeon_set_param {
	unsigned int param;
	long long    value;
} drmRadeonSetParam;

#define RADEON_SETPARAM_FB_LOCATION     1


#endif

--- NEW FILE: radeon_cursor.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_cursor.c,v 1.25 2003/08/29 21:07:57 tsi Exp $ */
/*
 * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
 *                VA Linux Systems Inc., Fremont, 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 at xfree86.org>
 *   Rickard E. Faith <faith at 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.
 *
 */

				/* Driver data structures */
#include "radeon.h"
#include "radeon_macros.h"
#include "radeon_reg.h"

				/* X and server generic header files */
#include "xf86.h"

/* Mono ARGB cursor colours (premultiplied). */
static CARD32 mono_cursor_color[] = {
	0x00000000, /* White, fully transparent. */
	0x00000000, /* Black, fully transparent. */
	0xffffffff, /* White, fully opaque. */
	0xff000000, /* Black, fully opaque. */
};

#define CURSOR_WIDTH	64
#define CURSOR_HEIGHT	64

/*
 * The cursor bits are always 32bpp.  On MSBFirst buses,
 * configure byte swapping to swap 32 bit units when writing
 * the cursor image.  Byte swapping must always be returned
 * to its previous value before returning.
 */
#if X_BYTE_ORDER == X_BIG_ENDIAN

#define CURSOR_SWAPPING_DECL_MMIO   unsigned char *RADEONMMIO = info->MMIO;
#define CURSOR_SWAPPING_DECL	    CARD32  __surface_cntl;
#define CURSOR_SWAPPING_START() \
    OUTREG(RADEON_SURFACE_CNTL, \
	   ((__surface_cntl = INREG(RADEON_SURFACE_CNTL)) | \
	    RADEON_NONSURF_AP0_SWP_32BPP) & \
	   ~RADEON_NONSURF_AP0_SWP_16BPP)
#define CURSOR_SWAPPING_END()	(OUTREG(RADEON_SURFACE_CNTL, __surface_cntl))

#else

#define CURSOR_SWAPPING_DECL_MMIO
#define CURSOR_SWAPPING_DECL
#define CURSOR_SWAPPING_START()
#define CURSOR_SWAPPING_END()

#endif

/* Set cursor foreground and background colors */
static void RADEONSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
{
    RADEONInfoPtr  info       = RADEONPTR(pScrn);
    CARD32        *pixels     = (CARD32 *)(pointer)(info->FB + info->cursor_start);
    int            pixel, i;
    CURSOR_SWAPPING_DECL_MMIO
    CURSOR_SWAPPING_DECL

#ifdef ARGB_CURSOR
    /* Don't recolour cursors set with SetCursorARGB. */
    if (info->cursor_argb)
       return;
#endif

    fg |= 0xff000000;
    bg |= 0xff000000;

    /* Don't recolour the image if we don't have to. */
    if (fg == info->cursor_fg && bg == info->cursor_bg)
       return;

    CURSOR_SWAPPING_START();

    /* Note: We assume that the pixels are either fully opaque or fully
     * transparent, so we won't premultiply them, and we can just
     * check for non-zero pixel values; those are either fg or bg
     */
    for (i = 0; i < CURSOR_WIDTH * CURSOR_HEIGHT; i++, pixels++)
       if ((pixel = *pixels))
           *pixels = (pixel == info->cursor_fg) ? fg : bg;

    CURSOR_SWAPPING_END();
    info->cursor_fg = fg;
    info->cursor_bg = bg;
}


/* 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;
    int                X2         = pScrn->frameX0 + x;
    int                Y2         = pScrn->frameY0 + y;
    int		       stride     = 256;

    if (x < 0)                        xorigin = -x+1;
    if (y < 0)                        yorigin = -y+1;
    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;

    if (info->Clone) {
	int X0 = 0;
	int Y0 = 0;

	if ((info->CurCloneMode->VDisplay == pScrn->currentMode->VDisplay) &&
	    (info->CurCloneMode->HDisplay == pScrn->currentMode->HDisplay)) {
	    Y2 = y;
	    X2 = x;
	    X0 = pScrn->frameX0;
	    Y0 = pScrn->frameY0;
	} else {
	    if (y < 0)
		Y2 = pScrn->frameY0;

	    if (x < 0)
		X2 = pScrn->frameX0;

	    if (Y2 >= info->CurCloneMode->VDisplay + info->CloneFrameY0) {
		Y0 = Y2 - info->CurCloneMode->VDisplay;
		Y2 = info->CurCloneMode->VDisplay - 1;
	    } else if (Y2 < info->CloneFrameY0) {
		Y0 = Y2;
		Y2 = 0;
	    } else {
		Y2 -= info->CloneFrameY0;
		Y0 = info->CloneFrameY0;
	    }

	    if (X2 >= info->CurCloneMode->HDisplay + info->CloneFrameX0) {
		X0 = X2 - info->CurCloneMode->HDisplay;
		X2 = info->CurCloneMode->HDisplay - 1;
	    } else if (X2 < info->CloneFrameX0) {
		X0 = X2;
		X2 = 0;
	    } else {
		X2 -= info->CloneFrameX0;
		X0 = info->CloneFrameX0;
	    }

	    if (info->CurCloneMode->Flags & V_DBLSCAN)
		Y2 *= 2;
	}

	if ((X0 >= 0 || Y0 >= 0) &&
	    ((info->CloneFrameX0 != X0) || (info->CloneFrameY0 != Y0))) {
	    RADEONDoAdjustFrame(pScrn, X0, Y0, TRUE);
	    info->CloneFrameX0 = X0;
	    info->CloneFrameY0 = Y0;
	}
    }

    if (!info->IsSecondary) {
	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 * stride);
    } else {
	OUTREG(RADEON_CUR2_HORZ_VERT_OFF,  (RADEON_CUR2_LOCK
					    | (xorigin << 16)
					    | yorigin));
	OUTREG(RADEON_CUR2_HORZ_VERT_POSN, (RADEON_CUR2_LOCK
					    | ((xorigin ? 0 : x) << 16)
					    | (yorigin ? 0 : y)));
	OUTREG(RADEON_CUR2_OFFSET,
	       info->cursor_start + pScrn->fbOffset + yorigin * stride);
    }

    if (info->Clone) {
	xorigin = 0;
	yorigin = 0;
	if (X2 < 0) xorigin = -X2 + 1;
	if (Y2 < 0) yorigin = -Y2 + 1;
	if (xorigin >= cursor->MaxWidth)  xorigin = cursor->MaxWidth - 1;
	if (yorigin >= cursor->MaxHeight) yorigin = cursor->MaxHeight - 1;

	OUTREG(RADEON_CUR2_HORZ_VERT_OFF,  (RADEON_CUR2_LOCK
					    | (xorigin << 16)
					    | yorigin));
	OUTREG(RADEON_CUR2_HORZ_VERT_POSN, (RADEON_CUR2_LOCK
					    | ((xorigin ? 0 : X2) << 16)
					    | (yorigin ? 0 : Y2)));
	OUTREG(RADEON_CUR2_OFFSET,
	       info->cursor_start + pScrn->fbOffset + yorigin * stride);
    }
}

/* 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;
    CARD8         *s          = (CARD8 *)(pointer)image;
    CARD32        *d          = (CARD32 *)(pointer)(info->FB + info->cursor_start);
    CARD32         save1      = 0;
    CARD32         save2      = 0;
    CARD8	   chunk;
    CARD32         i, j;
    CURSOR_SWAPPING_DECL

    if (!info->IsSecondary) {
	save1 = INREG(RADEON_CRTC_GEN_CNTL) & ~(CARD32) (3 << 20);
	save1 |= (CARD32) (2 << 20);
	OUTREG(RADEON_CRTC_GEN_CNTL, save1 & (CARD32)~RADEON_CRTC_CUR_EN);
    }

    if (info->IsSecondary || info->Clone) {
	save2 = INREG(RADEON_CRTC2_GEN_CNTL) & ~(CARD32) (3 << 20);
	save2 |= (CARD32) (2 << 20);
	OUTREG(RADEON_CRTC2_GEN_CNTL, save2 & (CARD32)~RADEON_CRTC2_CUR_EN);
    }

#ifdef ARGB_CURSOR
    info->cursor_argb = FALSE;
#endif

    /*
     * Convert the bitmap to ARGB32.
     *
     * HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 always places
     * source in the low bit of the pair and mask in the high bit,
     * and MSBFirst machines set HARDWARE_CURSOR_BIT_ORDER_MSBFIRST
     * (which actually bit swaps the image) to make the bits LSBFirst
     */
    CURSOR_SWAPPING_START();
#define ARGB_PER_CHUNK	(8 * sizeof (chunk) / 2)
    for (i = 0; i < CURSOR_WIDTH * CURSOR_HEIGHT / ARGB_PER_CHUNK; i++) {
        chunk = *s++;
	for (j = 0; j < ARGB_PER_CHUNK; j++, chunk >>= 2)
	    *d++ = mono_cursor_color[chunk & 3];
    }
    CURSOR_SWAPPING_END();

    info->cursor_bg = mono_cursor_color[2];
    info->cursor_fg = mono_cursor_color[3];

    if (!info->IsSecondary)
	OUTREG(RADEON_CRTC_GEN_CNTL, save1);

    if (info->IsSecondary || info->Clone)
	OUTREG(RADEON_CRTC2_GEN_CNTL, save2);

}

/* Hide hardware cursor. */
static void RADEONHideCursor(ScrnInfoPtr pScrn)
{
    RADEONInfoPtr  info       = RADEONPTR(pScrn);
    unsigned char *RADEONMMIO = info->MMIO;

    if (info->IsSecondary || info->Clone)
	OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~RADEON_CRTC2_CUR_EN);

    if (!info->IsSecondary)
	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;

    if (info->IsSecondary || info->Clone)
	OUTREGP(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_CUR_EN,
		~RADEON_CRTC2_CUR_EN);

    if (!info->IsSecondary)
	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;
}

#ifdef ARGB_CURSOR
#include "cursorstr.h"

static Bool RADEONUseHWCursorARGB (ScreenPtr pScreen, CursorPtr pCurs)
{
    ScrnInfoPtr    pScrn = xf86Screens[pScreen->myNum];
    RADEONInfoPtr  info  = RADEONPTR(pScrn);

    if (info->cursor_start &&
	pCurs->bits->height <= CURSOR_HEIGHT && pCurs->bits->width <= CURSOR_WIDTH)
	return TRUE;
    return FALSE;
}

static void RADEONLoadCursorARGB (ScrnInfoPtr pScrn, CursorPtr pCurs)
{
    RADEONInfoPtr  info       = RADEONPTR(pScrn);
    unsigned char *RADEONMMIO = info->MMIO;
    CARD32        *d          = (CARD32 *)(pointer)(info->FB + info->cursor_start);
    int            x, y, w, h;
    CARD32         save1      = 0;
    CARD32         save2      = 0;
    CARD32	  *image = pCurs->bits->argb;
    CARD32	  *i;
    CURSOR_SWAPPING_DECL

    if (!image)
	return;	/* XXX can't happen */

    if (!info->IsSecondary) {
	save1 = INREG(RADEON_CRTC_GEN_CNTL) & ~(CARD32) (3 << 20);
	save1 |= (CARD32) (2 << 20);
	OUTREG(RADEON_CRTC_GEN_CNTL, save1 & (CARD32)~RADEON_CRTC_CUR_EN);
    }

    if (info->IsSecondary || info->Clone) {
	save2 = INREG(RADEON_CRTC2_GEN_CNTL) & ~(CARD32) (3 << 20);
	save2 |= (CARD32) (2 << 20);
	OUTREG(RADEON_CRTC2_GEN_CNTL, save2 & (CARD32)~RADEON_CRTC2_CUR_EN);
    }

#ifdef ARGB_CURSOR
    info->cursor_argb = TRUE;
#endif

    CURSOR_SWAPPING_START();

    w = pCurs->bits->width;
    if (w > CURSOR_WIDTH)
	w = CURSOR_WIDTH;
    h = pCurs->bits->height;
    if (h > CURSOR_HEIGHT)
	h = CURSOR_HEIGHT;
    for (y = 0; y < h; y++)
    {
	i = image;
	image += pCurs->bits->width;
	for (x = 0; x < w; x++)
	    *d++ = *i++;
	/* pad to the right with transparent */
	for (; x < CURSOR_WIDTH; x++)
	    *d++ = 0;
    }
    /* pad below with transparent */
    for (; y < CURSOR_HEIGHT; y++)
	for (x = 0; x < CURSOR_WIDTH; x++)
	    *d++ = 0;

    CURSOR_SWAPPING_END ();

    if (!info->IsSecondary)
	OUTREG(RADEON_CRTC_GEN_CNTL, save1);

    if (info->IsSecondary || info->Clone)
	OUTREG(RADEON_CRTC2_GEN_CNTL, save2);

}

#endif


/* Initialize hardware cursor support. */
Bool RADEONCursorInit(ScreenPtr pScreen)
{
    ScrnInfoPtr        pScrn   = xf86Screens[pScreen->myNum];
    RADEONInfoPtr      info    = RADEONPTR(pScrn);
    xf86CursorInfoPtr  cursor;
    FBAreaPtr          fbarea;
    int                width;
    int		       width_bytes;
    int                height;
    int                size_bytes;

    if (!(cursor = info->cursor = xf86CreateCursorInfoRec())) return FALSE;

    cursor->MaxWidth          = CURSOR_WIDTH;
    cursor->MaxHeight         = CURSOR_HEIGHT;
    cursor->Flags             = (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP
				 | HARDWARE_CURSOR_AND_SOURCE_WITH_MASK
#if X_BYTE_ORDER == X_BIG_ENDIAN
				 /* this is a lie --
				  * HARDWARE_CURSOR_BIT_ORDER_MSBFIRST
				  * actually inverts the bit order, so
				  * this switches to LSBFIRST
				  */
				 | HARDWARE_CURSOR_BIT_ORDER_MSBFIRST
#endif
				 | HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1);

    cursor->SetCursorColors   = RADEONSetCursorColors;
    cursor->SetCursorPosition = RADEONSetCursorPosition;
    cursor->LoadCursorImage   = RADEONLoadCursorImage;
    cursor->HideCursor        = RADEONHideCursor;
    cursor->ShowCursor        = RADEONShowCursor;
    cursor->UseHWCursor       = RADEONUseHWCursor;

#ifdef ARGB_CURSOR
    cursor->UseHWCursorARGB   = RADEONUseHWCursorARGB;
    cursor->LoadCursorARGB    = RADEONLoadCursorARGB;
#endif
    size_bytes                = CURSOR_WIDTH * 4 * CURSOR_HEIGHT;
    width                     = pScrn->displayWidth;
    width_bytes		      = width * (pScrn->bitsPerPixel / 8);
    height                    = (size_bytes + width_bytes - 1) / width_bytes;
    fbarea                    = xf86AllocateOffscreenArea(pScreen,
							  width,
							  height,
							  256,
							  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 +
					      fbarea->box.y1 * width) *
					     info->CurrentLayout.pixel_bytes,
					     256);
	info->cursor_end      = info->cursor_start + size_bytes;
    }

    RADEONTRACE(("RADEONCursorInit (0x%08x-0x%08x)\n",
		 info->cursor_start, info->cursor_end));

    return xf86InitCursor(pScreen, cursor);
}

--- NEW FILE: radeon_dga.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dga.c,v 1.11 2002/09/18 18:14:58 martin Exp $ */
/*
 * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
 *                VA Linux Systems Inc., Fremont, 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 at xfree86.org>
 *
 * Credits:
 *
 *   Thanks to Ove Kåven <ovek at transgaming.com> for writing the Rage 128
 *   DGA support.  Portions of this file are based on the initialization
 *   code for that driver.
 *
 */

				/* Driver data structures */
#include "radeon.h"
#include "radeon_probe.h"

				/* X and server generic header files */
#include "xf86.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);
static void RADEON_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int,
				 unsigned long);


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;
    DGAModePtr      currentMode;
    DisplayModePtr  pMode;
    DisplayModePtr  firstMode;
    unsigned int    size;
    int             pitch;
    int             Bpp      = bitsPerPixel >> 3;

SECOND_PASS:

    pMode = firstMode = pScrn->modes;

    while (1) {
	pitch = pScrn->displayWidth;
	size = pitch * Bpp * pMode->VDisplay;

	if ((!secondPitch || (pitch != secondPitch)) &&
	    (size <= info->FbMapSize)) {

	    if (secondPitch)
		pitch = secondPitch;

	    if (!(newmodes = xrealloc(modes, (*num + 1) * sizeof(DGAModeRec))))
		break;

	    modes       = newmodes;
	    currentMode = modes + *num;

	    currentMode->mode           = pMode;
	    currentMode->flags          = DGA_CONCURRENT_ACCESS;

	    if (pixmap)
		currentMode->flags     |= DGA_PIXMAP_AVAILABLE;

	    if (info->accel) {
	      if (info->accel->SetupForSolidFill &&
		  info->accel->SubsequentSolidFillRect)
		 currentMode->flags    |= DGA_FILL_RECT;
	      if (info->accel->SetupForScreenToScreenCopy &&
		  info->accel->SubsequentScreenToScreenCopy)
		 currentMode->flags    |= DGA_BLIT_RECT | DGA_BLIT_RECT_TRANS;
	      if (currentMode->flags &
		  (DGA_PIXMAP_AVAILABLE | DGA_FILL_RECT |
		   DGA_BLIT_RECT | DGA_BLIT_RECT_TRANS))
		  currentMode->flags   &= ~DGA_CONCURRENT_ACCESS;
	    }
	    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;
	    currentMode->bytesPerScanline = pitch * Bpp;
	    currentMode->imageWidth     = pitch;
	    currentMode->imageHeight    = (info->FbMapSize
					   / currentMode->bytesPerScanline);
	    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);
	    (*num)++;
	}

	pMode = pMode->next;
	if (pMode == firstMode)
	    break;
    }

    if (secondPitch) {
	secondPitch = 0;
	goto SECOND_PASS;
    }

    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;

    info->DGAFuncs.OpenFramebuffer       = RADEON_OpenFramebuffer;
    info->DGAFuncs.CloseFramebuffer      = NULL;
    info->DGAFuncs.SetMode               = RADEON_SetMode;
    info->DGAFuncs.SetViewport           = RADEON_SetViewport;
    info->DGAFuncs.GetViewport           = RADEON_GetViewport;

    info->DGAFuncs.Sync                  = NULL;
    info->DGAFuncs.FillRect              = NULL;
    info->DGAFuncs.BlitRect              = NULL;
    info->DGAFuncs.BlitTransRect         = NULL;

    if (info->accel) {
	info->DGAFuncs.Sync              = info->accel->Sync;
	if (info->accel->SetupForSolidFill &&
	    info->accel->SubsequentSolidFillRect)
	    info->DGAFuncs.FillRect      = RADEON_FillRect;
	if (info->accel->SetupForScreenToScreenCopy &&
	    info->accel->SubsequentScreenToScreenCopy) {
	    info->DGAFuncs.BlitRect      = RADEON_BlitRect;
	    info->DGAFuncs.BlitTransRect = RADEON_BlitTransRect;
	}
    }

    return DGAInit(pScreen, &info->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);
#ifdef XF86DRI
	if (info->directRenderingEnabled) {
	    RADEONCP_STOP(pScrn, info);
	}
#endif
	if (info->accelOn)
	    RADEONEngineInit(pScrn);
#ifdef XF86DRI
	if (info->directRenderingEnabled) {
	    RADEONCP_START(pScrn, info);
	}
#endif
	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);

#ifdef XF86DRI
	if (info->directRenderingEnabled) {
	    RADEONCP_STOP(pScrn, info);
	}
#endif
	if (info->accelOn)
	    RADEONEngineInit(pScrn);
#ifdef XF86DRI
	if (info->directRenderingEnabled) {
	    RADEONCP_START(pScrn, info);
	}
#endif
    }

    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);

    (*info->accel->SetupForSolidFill)(pScrn, color, GXcopy, (CARD32)(~0));
    (*info->accel->SubsequentSolidFillRect)(pScrn, x, y, w, h);

    if (pScrn->bitsPerPixel == info->CurrentLayout.bitsPerPixel)
	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);
    int            xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
    int            ydir = (srcy < dsty) ? -1 : 1;

    (*info->accel->SetupForScreenToScreenCopy)(pScrn, xdir, ydir,
					       GXcopy, (CARD32)(~0), -1);
    (*info->accel->SubsequentScreenToScreenCopy)(pScrn, srcx, srcy,
						 dstx, dsty, w, h);

    if (pScrn->bitsPerPixel == info->CurrentLayout.bitsPerPixel)
	SET_SYNC_FLAG(info->accel);
}

static void RADEON_BlitTransRect(ScrnInfoPtr pScrn,
				 int srcx, int srcy, int w, int h,
				 int dstx, int dsty, unsigned long color)
{
    RADEONInfoPtr  info = RADEONPTR(pScrn);
    int            xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
    int            ydir = (srcy < dsty) ? -1 : 1;

    info->XAAForceTransBlit = TRUE;

    (*info->accel->SetupForScreenToScreenCopy)(pScrn, xdir, ydir,
					       GXcopy, (CARD32)(~0), color);

    info->XAAForceTransBlit = FALSE;

    (*info->accel->SubsequentScreenToScreenCopy)(pScrn, srcx, srcy,
						 dstx, dsty, w, h);

    if (pScrn->bitsPerPixel == info->CurrentLayout.bitsPerPixel)
	SET_SYNC_FLAG(info->accel);
}

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;
}

--- NEW FILE: radeon_dri.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c,v 1.39 2003/11/06 18:38:00 tsi Exp $ */
/*
 * Copyright 2000 ATI Technologies Inc., Markham, Ontario,
 *                VA Linux Systems Inc., Fremont, 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.
 *
[...1871 lines suppressed...]
    RADEONSAREAPrivPtr  pSAREAPriv = DRIGetSAREAPrivate(pScreen);

    /* Shut down shadowing if we've made it back to the front page */
    if (pSAREAPriv->pfCurrentPage == 0) {
	RADEONDisablePageFlip(pScreen);
	xf86FreeOffscreenArea(info->backArea);
	info->backArea = NULL;
    } else {
	xf86DrvMsg(pScreen->myNum, X_WARNING,
		   "[dri] RADEONDRITransitionTo2d: "
		   "kernel failed to unflip buffers.\n");
    }

    xf86FreeOffscreenArea(info->depthTexArea);

    info->have3DWindows = 0;

    if (info->cursor_start)
	    xf86ForceHWCursor (pScreen, FALSE);
}

--- NEW FILE: radeon_dri.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h,v 1.4 2002/10/30 12:52:13 alanh Exp $ */
/*
 * Copyright 2000 ATI Technologies Inc., Markham, Ontario,
 *                VA Linux Systems Inc., Fremont, 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 at xfree86.org>
 *   Rickard E. Faith <faith at valinux.com>
 *
 */

#ifndef _RADEON_DRI_
#define _RADEON_DRI_

#include "xf86drm.h"
#include "radeon_common.h"

/* DRI Driver defaults */
#define RADEON_DEFAULT_CP_PIO_MODE    RADEON_CSQ_PRIPIO_INDPIO
#define RADEON_DEFAULT_CP_BM_MODE     RADEON_CSQ_PRIBM_INDBM
#define RADEON_DEFAULT_AGP_MODE       1
#define RADEON_DEFAULT_AGP_FAST_WRITE 0
#define RADEON_DEFAULT_GART_SIZE      8 /* MB (must be 2^n and > 4MB) */
#define RADEON_DEFAULT_RING_SIZE      1 /* MB (must be page aligned) */
#define RADEON_DEFAULT_BUFFER_SIZE    2 /* MB (must be page aligned) */
#define RADEON_DEFAULT_GART_TEX_SIZE  1 /* MB (must be page aligned) */

#define RADEON_DEFAULT_CP_TIMEOUT     10000  /* usecs */

#define RADEON_AGP_MAX_MODE           4

#define RADEON_CARD_TYPE_RADEON       1

/* Buffer are aligned on 4096 byte boundaries */
#define RADEON_BUFFER_ALIGN           0x00000fff

#define RADEONCP_USE_RING_BUFFER(m)					\
    (((m) == RADEON_CSQ_PRIBM_INDDIS) ||				\
     ((m) == RADEON_CSQ_PRIBM_INDBM))

typedef struct {
    /* 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           IsPCI;	/* Current card is a PCI card */
    int           AGPMode;

    int           frontOffset;  /* Start of front buffer */
    int           frontPitch;
    int           backOffset;   /* Start of shared back buffer */
    int           backPitch;
    int           depthOffset;  /* Start of shared depth buffer */
    int           depthPitch;
    int           textureOffset;/* Start of texture data in frame buffer */
    int           textureSize;
    int           log2TexGran;

    /* MMIO register data */
    drmHandle     registerHandle;
    drmSize       registerSize;

    /* CP in-memory status information */
    drmHandle     statusHandle;
    drmSize       statusSize;

    /* CP GART Texture data */
    drmHandle     gartTexHandle;
    drmSize       gartTexMapSize;
    int           log2GARTTexGran;
    int           gartTexOffset;
    unsigned int  sarea_priv_offset;

#ifdef PER_CONTEXT_SAREA
    drmSize      perctx_sarea_size;
#endif
} RADEONDRIRec, *RADEONDRIPtr;

#endif

--- NEW FILE: radeon_dripriv.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dripriv.h,v 1.3 2002/04/24 16:20:40 martin Exp $ */
/*
 * Copyright 2000 ATI Technologies Inc., Markham, Ontario,
 *                VA Linux Systems Inc., Fremont, 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 at xfree86.org>
 *   Rickard E. Faith <faith at valinux.com>
 *
 */

#ifndef _RADEON_DRIPRIV_H_
#define _RADEON_DRIPRIV_H_

#include "GL/glxint.h"
#include "xf86drm.h"
#include "radeon_common.h"

#define RADEON_MAX_DRAWABLES 256

extern void GlxSetVisualConfigs(int nconfigs, __GLXvisualConfig *configs,
				void **configprivs);

typedef struct {
    /* Nothing here yet */
    int dummy;
} RADEONConfigPrivRec, *RADEONConfigPrivPtr;

typedef struct {
#ifdef PER_CONTEXT_SAREA
    drmContext ctx_id;
    drmHandle sarea_handle;
#else
    /* Nothing here yet */
    int dummy;
#endif
} RADEONDRIContextRec, *RADEONDRIContextPtr;

#endif

--- NEW FILE: radeon_driver.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c,v 1.117 2004/02/19 22:38:12 tsi Exp $ */
/*
 * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
 *                VA Linux Systems Inc., Fremont, 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.
 *
[...7286 lines suppressed...]
		} else if (info->DisplayType == MT_CRT) {
		    if ((pRADEONEnt->HasSecondary) || info->Clone) {
			RADEONDacPowerSet(pScrn, FALSE, pRADEONEnt->ReversedDAC);
		    } else {
			/* single CRT, turning both DACs off, we don't really know 
			 * which DAC is actually connected.
			 */
			RADEONDacPowerSet(pScrn, FALSE, TRUE);
			if (info->HasCRTC2) /* don't apply this to old radeon (singel CRTC) card */
			    RADEONDacPowerSet(pScrn, FALSE, FALSE);
		    }
		}
	    }
	}
    }

#ifdef XF86DRI
    if (info->CPStarted) DRIUnlock(pScrn->pScreen);
#endif
}

--- NEW FILE: radeon_macros.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_macros.h,v 1.2 2003/07/08 15:39:48 tsi Exp $ */
/*
 * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
 *                VA Linux Systems Inc., Fremont, 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 at xfree86.org>
 *   Rickard E. Faith <faith at valinux.com>
 *   Alan Hourihane <alanh at fairlite.demon.co.uk>
 *
 * 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.
 *
 */


#ifndef _RADEON_MACROS_H_
#define _RADEON_MACROS_H_

#ifdef XFree86Module
#include "xf86_ansic.h"
#endif
#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 *)(pointer)(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)

#define OUTPLL(addr, val)						\
do {									\
    OUTREG8(RADEON_CLOCK_CNTL_INDEX, (((addr) & 0x3f) |			\
				      RADEON_PLL_WR_EN));		\
    OUTREG(RADEON_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(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_CNTL2, INREG(RADEON_DAC_CNTL2) &		\
	       (CARD32)~RADEON_DAC2_PALETTE_ACC_CTL);			\
    } else {								\
	OUTREG(RADEON_DAC_CNTL2, INREG(RADEON_DAC_CNTL2) |		\
	       RADEON_DAC2_PALETTE_ACC_CTL);				\
    }									\
} while (0)


#endif

--- NEW FILE: radeon_misc.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_misc.c,v 1.7 2003/01/01 19:16:35 tsi Exp $ */
/*
 * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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 "radeon_probe.h"
#include "radeon_version.h"

#include "xf86.h"

/* Module loader interface for subsidiary driver module */

static XF86ModuleVersionInfo RADEONVersionRec =
{
    RADEON_DRIVER_NAME,
    MODULEVENDORSTRING,
    MODINFOSTRING1,
    MODINFOSTRING2,
    XORG_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);

        RADEONLoaderRefSymLists();

        Inited = TRUE;
    }

    return (pointer)TRUE;
}

/* The following record must be called radeonModuleData */
XF86ModuleData radeonModuleData =
{
    &RADEONVersionRec,
    RADEONSetup,
    NULL
};

#endif /* XFree86LOADER */

--- NEW FILE: radeon_probe.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_probe.c,v 1.30 2003/10/07 22:47:12 martin Exp $ */
/*
 * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
 *                VA Linux Systems Inc., Fremont, 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 at xfree86.org>
 *   Rickard E. Faith <faith at valinux.com>
 *
 * Modified by Marc Aurele La France <tsi at 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"
#define _XF86MISC_SERVER_
#include <X11/extensions/xf86misc.h>
#include "xf86Resources.h"

#ifdef XFree86LOADER

/*
 * The following exists to prevent the compiler from considering entry points
 * defined in a separate module from being constants.
 */
static xf86PreInitProc     *const volatile PreInitProc     = RADEONPreInit;
static xf86ScreenInitProc  *const volatile ScreenInitProc  = RADEONScreenInit;
static xf86SwitchModeProc  *const volatile SwitchModeProc  = RADEONSwitchMode;
static xf86AdjustFrameProc *const volatile AdjustFrameProc = RADEONAdjustFrame;
static xf86EnterVTProc     *const volatile EnterVTProc     = RADEONEnterVT;
static xf86LeaveVTProc     *const volatile LeaveVTProc     = RADEONLeaveVT;
static xf86FreeScreenProc  *const volatile FreeScreenProc  = RADEONFreeScreen;
static xf86ValidModeProc   *const volatile ValidModeProc   = RADEONValidMode;
#ifdef X_XF86MiscPassMessage
static xf86HandleMessageProc *const volatile HandleMessageProc
							= RADEONHandleMessage;
#endif

#define RADEONPreInit       PreInitProc
#define RADEONScreenInit    ScreenInitProc
#define RADEONSwitchMode    SwitchModeProc
#define RADEONAdjustFrame   AdjustFrameProc
#define RADEONEnterVT       EnterVTProc
#define RADEONLeaveVT       LeaveVTProc
#define RADEONFreeScreen    FreeScreenProc
#define RADEONValidMode     ValidModeProc
#ifdef X_XF86MiscPassMessage
# define RADEONHandleMessage HandleMessageProc
#endif

#endif

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)" },
    { PCI_CHIP_RV100_QY, "ATI Radeon VE/7000 QY (AGP/PCI)" },
    { PCI_CHIP_RV100_QZ, "ATI Radeon VE/7000 QZ (AGP/PCI)" },
    { PCI_CHIP_RADEON_LW, "ATI Radeon Mobility M7 LW (AGP)" },
    { PCI_CHIP_RADEON_LX, "ATI Mobility FireGL 7800 M7 LX (AGP)" },
    { PCI_CHIP_RADEON_LY, "ATI Radeon Mobility M6 LY (AGP)" },
    { PCI_CHIP_RADEON_LZ, "ATI Radeon Mobility M6 LZ (AGP)" },
    { PCI_CHIP_RS100_4136, "ATI Radeon IGP320 (A3) 4136" },
    { PCI_CHIP_RS100_4336, "ATI Radeon IGP320M (U1) 4336" },
    { PCI_CHIP_RS200_4137, "ATI Radeon IGP330/340/350 (A4) 4137" },
    { PCI_CHIP_RS200_4337, "ATI Radeon IGP330M/340M/350M (U2) 4337" },
    { PCI_CHIP_RS250_4237, "ATI Radeon 7000 IGP (A4+) 4237" },
    { PCI_CHIP_RS250_4437, "ATI Radeon Mobility 7000 IGP 4437" },
    { PCI_CHIP_R200_QH, "ATI FireGL 8700/8800 QH (AGP)" },
    { PCI_CHIP_R200_QL, "ATI Radeon 8500 QL (AGP)" },
    { PCI_CHIP_R200_QM, "ATI Radeon 9100 QM (AGP)" },
    { PCI_CHIP_R200_BB, "ATI Radeon 8500 AIW BB (AGP)" },
    { PCI_CHIP_R200_BC, "ATI Radeon 8500 AIW BC (AGP)" },
    { PCI_CHIP_RV200_QW, "ATI Radeon 7500 QW (AGP/PCI)" },
    { PCI_CHIP_RV200_QX, "ATI Radeon 7500 QX (AGP/PCI)" },
    { PCI_CHIP_RV250_If, "ATI Radeon 9000/PRO If (AGP/PCI)" },
    { PCI_CHIP_RV250_Ig, "ATI Radeon 9000 Ig (AGP/PCI)" },
    { PCI_CHIP_RV250_Ld, "ATI FireGL Mobility 9000 (M9) Ld (AGP)" },
    { PCI_CHIP_RV250_Lf, "ATI Radeon Mobility 9000 (M9) Lf (AGP)" },
    { PCI_CHIP_RV250_Lg, "ATI Radeon Mobility 9000 (M9) Lg (AGP)" },
    { PCI_CHIP_RS300_5834, "ATI Radeon 9100 IGP (A5) 5834" },
    { PCI_CHIP_RS300_5835, "ATI Radeon Mobility 9100 IGP (U3) 5835" },
    { PCI_CHIP_RV280_5960, "ATI Radeon 9200PRO 5960 (AGP)" },
    { PCI_CHIP_RV280_5961, "ATI Radeon 9200 5961 (AGP)" },
    { PCI_CHIP_RV280_5962, "ATI Radeon 9200 5962 (AGP)" },
    { PCI_CHIP_RV280_5964, "ATI Radeon 9200SE 5964 (AGP)" },
    { PCI_CHIP_RV280_5C61, "ATI Radeon Mobility 9200 (M9+) 5C61 (AGP)" },
    { PCI_CHIP_RV280_5C63, "ATI Radeon Mobility 9200 (M9+) 5C63 (AGP)" },
    { PCI_CHIP_R300_AD, "ATI Radeon 9500 AD (AGP)" },
    { PCI_CHIP_R300_AE, "ATI Radeon 9500 AE (AGP)" },
    { PCI_CHIP_R300_AF, "ATI Radeon 9600TX AF (AGP)" },
    { PCI_CHIP_R300_AG, "ATI FireGL Z1 AG (AGP)" },
    { PCI_CHIP_R300_ND, "ATI Radeon 9700 Pro ND (AGP)" },
    { PCI_CHIP_R300_NE, "ATI Radeon 9700/9500Pro NE (AGP)" },
    { PCI_CHIP_R300_NF, "ATI Radeon 9700 NF (AGP)" },
    { PCI_CHIP_R300_NG, "ATI FireGL X1 NG (AGP)" },
    { PCI_CHIP_RV350_AP, "ATI Radeon 9600 AP (AGP)" },
    { PCI_CHIP_RV350_AQ, "ATI Radeon 9600SE AQ (AGP)" },
    { PCI_CHIP_RV360_AR, "ATI Radeon 9600XT AR (AGP)" },
    { PCI_CHIP_RV350_AS, "ATI Radeon 9600 AS (AGP)" },
    { PCI_CHIP_RV350_AT, "ATI FireGL T2 AT (AGP)" },
    { PCI_CHIP_RV350_AV, "ATI FireGL RV360 AV (AGP)" },
    { PCI_CHIP_RV350_NP, "ATI Radeon Mobility 9600 (M10) NP (AGP)" },
    { PCI_CHIP_RV350_NQ, "ATI Radeon Mobility 9600 (M10) NQ (AGP)" },
    { PCI_CHIP_RV350_NR, "ATI Radeon Mobility 9600 (M11) NR (AGP)" },
    { PCI_CHIP_RV350_NS, "ATI Radeon Mobility 9600 (M10) NS (AGP)" },
    { PCI_CHIP_RV350_NT, "ATI FireGL Mobility T2 (M10) NT (AGP)" },
    { PCI_CHIP_RV350_NV, "ATI FireGL Mobility T2 (M11) NV (AGP)" },
    { PCI_CHIP_R350_AH, "ATI Radeon 9800SE AH (AGP)" },
    { PCI_CHIP_R350_AI, "ATI Radeon 9800 AI (AGP)" },
    { PCI_CHIP_R350_AJ, "ATI Radeon 9800 AJ (AGP)" },
    { PCI_CHIP_R350_AK, "ATI FireGL X2 AK (AGP)" },
    { PCI_CHIP_R350_NH, "ATI Radeon 9800PRO NH (AGP)" },
    { PCI_CHIP_R350_NI, "ATI Radeon 9800 NI (AGP)" },
    { PCI_CHIP_R350_NK, "ATI FireGL X2 NK (AGP)" },
    { PCI_CHIP_R360_NJ, "ATI Radeon 9800XT NJ (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 },
    { PCI_CHIP_RV100_QY, PCI_CHIP_RV100_QY, RES_SHARED_VGA },
    { PCI_CHIP_RV100_QZ, PCI_CHIP_RV100_QZ, RES_SHARED_VGA },
    { PCI_CHIP_RADEON_LW, PCI_CHIP_RADEON_LW, RES_SHARED_VGA },
    { PCI_CHIP_RADEON_LX, PCI_CHIP_RADEON_LX, RES_SHARED_VGA },
    { PCI_CHIP_RADEON_LY, PCI_CHIP_RADEON_LY, RES_SHARED_VGA },
    { PCI_CHIP_RADEON_LZ, PCI_CHIP_RADEON_LZ, RES_SHARED_VGA },
    { PCI_CHIP_RS100_4136, PCI_CHIP_RS100_4136, RES_SHARED_VGA },
    { PCI_CHIP_RS100_4336, PCI_CHIP_RS100_4336, RES_SHARED_VGA },
    { PCI_CHIP_RS200_4137, PCI_CHIP_RS200_4137, RES_SHARED_VGA },
    { PCI_CHIP_RS200_4337, PCI_CHIP_RS200_4337, RES_SHARED_VGA },
    { PCI_CHIP_RS250_4237, PCI_CHIP_RS250_4237, RES_SHARED_VGA },
    { PCI_CHIP_RS250_4437, PCI_CHIP_RS250_4437, RES_SHARED_VGA },
    { PCI_CHIP_R200_QH, PCI_CHIP_R200_QH, RES_SHARED_VGA },
    { PCI_CHIP_R200_QL, PCI_CHIP_R200_QL, RES_SHARED_VGA },
    { PCI_CHIP_R200_QM, PCI_CHIP_R200_QM, RES_SHARED_VGA },
    { PCI_CHIP_R200_BB, PCI_CHIP_R200_BB, RES_SHARED_VGA },
    { PCI_CHIP_R200_BC, PCI_CHIP_R200_BC, RES_SHARED_VGA },
    { PCI_CHIP_RV200_QW, PCI_CHIP_RV200_QW, RES_SHARED_VGA },
    { PCI_CHIP_RV200_QX, PCI_CHIP_RV200_QX, RES_SHARED_VGA },
    { PCI_CHIP_RV250_If, PCI_CHIP_RV250_If, RES_SHARED_VGA },
    { PCI_CHIP_RV250_Ig, PCI_CHIP_RV250_Ig, RES_SHARED_VGA },
    { PCI_CHIP_RV250_Ld, PCI_CHIP_RV250_Ld, RES_SHARED_VGA },
    { PCI_CHIP_RV250_Lf, PCI_CHIP_RV250_Lf, RES_SHARED_VGA },
    { PCI_CHIP_RV250_Lg, PCI_CHIP_RV250_Lg, RES_SHARED_VGA },
    { PCI_CHIP_RS300_5834, PCI_CHIP_RS300_5834, RES_SHARED_VGA },
    { PCI_CHIP_RS300_5835, PCI_CHIP_RS300_5835, RES_SHARED_VGA },
    { PCI_CHIP_RV280_5960, PCI_CHIP_RV280_5960, RES_SHARED_VGA },
    { PCI_CHIP_RV280_5961, PCI_CHIP_RV280_5961, RES_SHARED_VGA },
    { PCI_CHIP_RV280_5962, PCI_CHIP_RV280_5962, RES_SHARED_VGA },
    { PCI_CHIP_RV280_5964, PCI_CHIP_RV280_5964, RES_SHARED_VGA },
    { PCI_CHIP_RV280_5C61, PCI_CHIP_RV280_5C61, RES_SHARED_VGA },
    { PCI_CHIP_RV280_5C63, PCI_CHIP_RV280_5C63, RES_SHARED_VGA },
    { PCI_CHIP_R300_AD, PCI_CHIP_R300_AD, RES_SHARED_VGA },
    { PCI_CHIP_R300_AE, PCI_CHIP_R300_AE, RES_SHARED_VGA },
    { PCI_CHIP_R300_AF, PCI_CHIP_R300_AF, RES_SHARED_VGA },
    { PCI_CHIP_R300_AG, PCI_CHIP_R300_AG, RES_SHARED_VGA },
    { PCI_CHIP_R300_ND, PCI_CHIP_R300_ND, RES_SHARED_VGA },
    { PCI_CHIP_R300_NE, PCI_CHIP_R300_NE, RES_SHARED_VGA },
    { PCI_CHIP_R300_NF, PCI_CHIP_R300_NF, RES_SHARED_VGA },
    { PCI_CHIP_R300_NG, PCI_CHIP_R300_NG, RES_SHARED_VGA },
    { PCI_CHIP_RV350_AP, PCI_CHIP_RV350_AP, RES_SHARED_VGA },
    { PCI_CHIP_RV350_AQ, PCI_CHIP_RV350_AQ, RES_SHARED_VGA },
    { PCI_CHIP_RV360_AR, PCI_CHIP_RV360_AR, RES_SHARED_VGA },
    { PCI_CHIP_RV350_AS, PCI_CHIP_RV350_AS, RES_SHARED_VGA },
    { PCI_CHIP_RV350_AT, PCI_CHIP_RV350_AT, RES_SHARED_VGA },
    { PCI_CHIP_RV350_AV, PCI_CHIP_RV350_AV, RES_SHARED_VGA },
    { PCI_CHIP_RV350_NP, PCI_CHIP_RV350_NP, RES_SHARED_VGA },
    { PCI_CHIP_RV350_NQ, PCI_CHIP_RV350_NQ, RES_SHARED_VGA },
    { PCI_CHIP_RV350_NR, PCI_CHIP_RV350_NR, RES_SHARED_VGA },
    { PCI_CHIP_RV350_NS, PCI_CHIP_RV350_NS, RES_SHARED_VGA },
    { PCI_CHIP_RV350_NT, PCI_CHIP_RV350_NT, RES_SHARED_VGA },
    { PCI_CHIP_RV350_NV, PCI_CHIP_RV350_NV, RES_SHARED_VGA },
    { PCI_CHIP_R350_AH, PCI_CHIP_R350_AH, RES_SHARED_VGA },
    { PCI_CHIP_R350_AI, PCI_CHIP_R350_AI, RES_SHARED_VGA },
    { PCI_CHIP_R350_AJ, PCI_CHIP_R350_AJ, RES_SHARED_VGA },
    { PCI_CHIP_R350_AK, PCI_CHIP_R350_AK, RES_SHARED_VGA },
    { PCI_CHIP_R350_NH, PCI_CHIP_R350_NH, RES_SHARED_VGA },
    { PCI_CHIP_R350_NI, PCI_CHIP_R350_NI, RES_SHARED_VGA },
    { PCI_CHIP_R350_NK, PCI_CHIP_R350_NK, RES_SHARED_VGA },
    { PCI_CHIP_R360_NJ, PCI_CHIP_R360_NJ, RES_SHARED_VGA },
    { -1,                 -1,                 RES_UNDEFINED }
};

int gRADEONEntityIndex = -1;

/* Return the options for supported chipset 'n'; NULL otherwise */
const OptionInfoRec *
RADEONAvailableOptions(int chipid, int busid)
{
    int  i;

    /*
     * Return options defined in the radeon submodule which will have been
     * loaded by this point.
     */
    if ((chipid >> 16) == PCI_VENDOR_ATI)
	chipid -= PCI_VENDOR_ATI << 16;
    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;
    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++) {
	    ScrnInfoPtr    pScrn = NULL;
	    EntityInfoPtr  pEnt;
	    pEnt = xf86GetEntityInfo(usedChips[i]);
	    if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i],
					     RADEONPciChipsets, 0, 0, 0,
					     0, 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;
#ifdef X_XF86MiscPassMessage
		pScrn->HandleMessage = RADEONHandleMessage;
#endif
		pScrn->AdjustFrame   = RADEONAdjustFrame;
		pScrn->EnterVT       = RADEONEnterVT;
		pScrn->LeaveVT       = RADEONLeaveVT;
		pScrn->FreeScreen    = RADEONFreeScreen;
		pScrn->ValidMode     = RADEONValidMode;
		foundScreen          = TRUE;
	    }

	    pEnt = xf86GetEntityInfo(usedChips[i]);

            /* create a RADEONEntity for all chips, even with
               old single head Radeon, need to use pRADEONEnt
               for new monitor detection routines
            */
            {
		DevUnion   *pPriv;
		RADEONEntPtr pRADEONEnt;

		xf86SetEntitySharable(usedChips[i]);

		if (gRADEONEntityIndex == -1)
		    gRADEONEntityIndex = xf86AllocateEntityPrivateIndex();

		pPriv = xf86GetEntityPrivate(pEnt->index,
					     gRADEONEntityIndex);

		if (!pPriv->ptr) {
		    int j;
		    int instance = xf86GetNumEntityInstances(pEnt->index);

		    for (j = 0; j < instance; j++)
			xf86SetEntityInstanceForScreen(pScrn, pEnt->index, j);

		    pPriv->ptr = xnfcalloc(sizeof(RADEONEntRec), 1);
		    pRADEONEnt = pPriv->ptr;
		    pRADEONEnt->HasSecondary = FALSE;
		    pRADEONEnt->IsSecondaryRestored = FALSE;
		} else {
		    pRADEONEnt = pPriv->ptr;
		    pRADEONEnt->HasSecondary = TRUE;
		}
	    }
	    xfree(pEnt);
	}
    }

    xfree(usedChips);
    xfree(devSections);

    return foundScreen;
}

--- NEW FILE: radeon_probe.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_probe.h,v 1.13 2003/10/30 17:37:00 tsi Exp $ */
/*
 * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
 *                VA Linux Systems Inc., Fremont, 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 at xfree86.org>
 *
 * Modified by Marc Aurele La France <tsi at xfree86.org> for ATI driver merge.
 */

#ifndef _RADEON_PROBE_H_
#define _RADEON_PROBE_H_ 1

#include "atiproto.h"

#include "xf86str.h"
#include "xf86DDC.h"

#define _XF86MISC_SERVER_
#include <X11/extensions/xf86misc.h>

typedef struct
{
    Bool HasSecondary;

    /*
     * The next two are used to make sure CRTC2 is restored before CRTC_EXT,
     * otherwise it could lead to blank screens.
     */
    Bool IsSecondaryRestored;
    Bool RestorePrimary;

    ScrnInfoPtr pSecondaryScrn;
    ScrnInfoPtr pPrimaryScrn;

    int MonType1;
    int MonType2;
    xf86MonPtr MonInfo1;
    xf86MonPtr MonInfo2;
    Bool ReversedDAC;	  /* TVDAC used as primary dac */
    Bool ReversedTMDS;    /* DDC_DVI is used for external TMDS */
} RADEONEntRec, *RADEONEntPtr;

/* radeon_probe.c */
extern const OptionInfoRec *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 void                 RADEONLoaderRefSymLists
			    FunctionPrototype((void));
extern Bool                 RADEONPreInit
			    FunctionPrototype((ScrnInfoPtr, int));
extern Bool                 RADEONScreenInit
			    FunctionPrototype((int, ScreenPtr, int, char **));
extern Bool                 RADEONSwitchMode
			    FunctionPrototype((int, DisplayModePtr, int));
#ifdef X_XF86MiscPassMessage
extern Bool                 RADEONHandleMessage
			    FunctionPrototype((int, const char*, const char*,
					       char**));
#endif
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 ModeStatus           RADEONValidMode
			    FunctionPrototype((int, DisplayModePtr, Bool,
					       int));

extern const OptionInfoRec  RADEONOptions[];

#endif /* _RADEON_PROBE_H_ */

--- NEW FILE: radeon_reg.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h,v 1.31 2003/11/10 18:41:23 tsi Exp $ */
/*
 * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
 *                VA Linux Systems Inc., Fremont, 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.
 *
[...2087 lines suppressed...]
#define RADEON_SS_LIGHT_RANGE_CUTOFF_ADDR        32
#define RADEON_SS_VERT_GUARD_CLIP_ADJ_ADDR       48
#define RADEON_SS_VERT_GUARD_DISCARD_ADJ_ADDR    49
#define RADEON_SS_HORZ_GUARD_CLIP_ADJ_ADDR       50
#define RADEON_SS_HORZ_GUARD_DISCARD_ADJ_ADDR    51
#define RADEON_SS_SHININESS                      60

#define RADEON_TV_MASTER_CNTL                    0x0800
#       define RADEON_TVCLK_ALWAYS_ONb           (1 << 30)
#define RADEON_TV_DAC_CNTL                       0x088c
#       define RADEON_TV_DAC_CMPOUT              (1 << 5)
#define RADEON_TV_PRE_DAC_MUX_CNTL               0x0888
#       define RADEON_Y_RED_EN                   (1 << 0)
#       define RADEON_C_GRN_EN                   (1 << 1)
#       define RADEON_CMP_BLU_EN                 (1 << 2)
#       define RADEON_RED_MX_FORCE_DAC_DATA      (6 << 4)
#       define RADEON_GRN_MX_FORCE_DAC_DATA      (6 << 8)
#       define RADEON_BLU_MX_FORCE_DAC_DATA      (6 << 12)
#       define RADEON_TV_FORCE_DAC_DATA_SHIFT    16
#endif

--- NEW FILE: radeon_sarea.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h,v 1.5 2002/10/30 12:52:14 alanh Exp $ */
/*
 * Copyright 2000 ATI Technologies Inc., Markham, Ontario,
 *                VA Linux Systems Inc., Fremont, 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 at xfree86.org>
 *   Gareth Hughes <gareth at valinux.com>
 *
 */

#ifndef _RADEON_SAREA_H_
#define _RADEON_SAREA_H_

/* WARNING: If you change any of these defines, make sure to change the
 * defines in the kernel file (radeon_drm.h)
 */
#ifndef __RADEON_SAREA_DEFINES__
#define __RADEON_SAREA_DEFINES__

/* What needs to be changed for the current vertex buffer? */
#define RADEON_UPLOAD_CONTEXT		0x00000001
#define RADEON_UPLOAD_VERTFMT		0x00000002
#define RADEON_UPLOAD_LINE		0x00000004
#define RADEON_UPLOAD_BUMPMAP		0x00000008
#define RADEON_UPLOAD_MASKS		0x00000010
#define RADEON_UPLOAD_VIEWPORT		0x00000020
#define RADEON_UPLOAD_SETUP		0x00000040
#define RADEON_UPLOAD_TCL		0x00000080
#define RADEON_UPLOAD_MISC		0x00000100
#define RADEON_UPLOAD_TEX0		0x00000200
#define RADEON_UPLOAD_TEX1		0x00000400
#define RADEON_UPLOAD_TEX2		0x00000800
#define RADEON_UPLOAD_TEX0IMAGES	0x00001000
#define RADEON_UPLOAD_TEX1IMAGES	0x00002000
#define RADEON_UPLOAD_TEX2IMAGES	0x00004000
#define RADEON_UPLOAD_CLIPRECTS		0x00008000 /* handled client-side */
#define RADEON_REQUIRE_QUIESCENCE	0x00010000
#define RADEON_UPLOAD_ZBIAS		0x00020000
#define RADEON_UPLOAD_ALL		0x0002ffff
#define RADEON_UPLOAD_CONTEXT_ALL       0x000201ff

#define RADEON_FRONT			0x1
#define RADEON_BACK			0x2
#define RADEON_DEPTH			0x4
#define RADEON_STENCIL                  0x8

/* Primitive types */
#define RADEON_POINTS			0x1
#define RADEON_LINES			0x2
#define RADEON_LINE_STRIP		0x3
#define RADEON_TRIANGLES		0x4
#define RADEON_TRIANGLE_FAN		0x5
#define RADEON_TRIANGLE_STRIP		0x6
#define RADEON_3VTX_POINTS		0x9
#define RADEON_3VTX_LINES		0xa

/* Vertex/indirect buffer size */
#define RADEON_BUFFER_SIZE		65536

/* Byte offsets for indirect buffer data */
#define RADEON_INDEX_PRIM_OFFSET	20
#define RADEON_HOSTDATA_BLIT_OFFSET	32

#define RADEON_SCRATCH_REG_OFFSET	32

/* Keep these small for testing */
#define RADEON_NR_SAREA_CLIPRECTS	12

/* There are 2 heaps (local/GART).  Each region within a heap is a
 * minimum of 64k, and there are at most 64 of them per heap.
 */
#define RADEON_CARD_HEAP		0
#define RADEON_GART_HEAP		1
#define RADEON_NR_TEX_HEAPS		2
#define RADEON_NR_TEX_REGIONS		64
#define RADEON_LOG_TEX_GRANULARITY	16

#define RADEON_MAX_TEXTURE_LEVELS	12
#define RADEON_MAX_TEXTURE_UNITS	3

/* Blits have strict offset rules.  All blit offset must be aligned on
 * a 1K-byte boundary.
 */
#define RADEON_OFFSET_SHIFT		10
#define RADEON_OFFSET_ALIGN		(1 << RADEON_OFFSET_SHIFT)
#define RADEON_OFFSET_MASK		(RADEON_OFFSET_ALIGN - 1)

#endif /* __RADEON_SAREA_DEFINES__ */

typedef struct {
    unsigned int red;
    unsigned int green;
    unsigned int blue;
    unsigned int alpha;
} radeon_color_regs_t;

typedef struct {
    /* Context state */
    unsigned int pp_misc;
    unsigned int pp_fog_color;
    unsigned int re_solid_color;
    unsigned int rb3d_blendcntl;
    unsigned int rb3d_depthoffset;
    unsigned int rb3d_depthpitch;
    unsigned int rb3d_zstencilcntl;

    unsigned int pp_cntl;
    unsigned int rb3d_cntl;
    unsigned int rb3d_coloroffset;
    unsigned int re_width_height;
    unsigned int rb3d_colorpitch;
    unsigned int se_cntl;

    /* Vertex format state */
    unsigned int se_coord_fmt;

    /* Line state */
    unsigned int re_line_pattern;
    unsigned int re_line_state;

    unsigned int se_line_width;

    /* Bumpmap state */
    unsigned int pp_lum_matrix;

    unsigned int pp_rot_matrix_0;
    unsigned int pp_rot_matrix_1;

    /* Mask state */
    unsigned int rb3d_stencilrefmask;
    unsigned int rb3d_ropcntl;
    unsigned int rb3d_planemask;

    /* Viewport state */
    unsigned int se_vport_xscale;
    unsigned int se_vport_xoffset;
    unsigned int se_vport_yscale;
    unsigned int se_vport_yoffset;
    unsigned int se_vport_zscale;
    unsigned int se_vport_zoffset;

    /* Setup state */
    unsigned int se_cntl_status;

    /* Misc state */
    unsigned int re_top_left;
    unsigned int re_misc;
} radeon_context_regs_t;

/* Setup registers for each texture unit */
typedef struct {
    unsigned int pp_txfilter;
    unsigned int pp_txformat;
    unsigned int pp_txoffset;
    unsigned int pp_txcblend;
    unsigned int pp_txablend;
    unsigned int pp_tfactor;
    unsigned int pp_border_color;
} radeon_texture_regs_t;

typedef struct {
    /* The channel for communication of state information to the kernel
     * on firing a vertex buffer.
     */
    radeon_context_regs_t ContextState;
    radeon_texture_regs_t TexState[RADEON_MAX_TEXTURE_UNITS];
    unsigned int dirty;
    unsigned int vertsize;
    unsigned int vc_format;

    /* The current cliprects, or a subset thereof */
    XF86DRIClipRectRec boxes[RADEON_NR_SAREA_CLIPRECTS];
    unsigned int nbox;

    /* Counters for throttling of rendering clients */
    unsigned int last_frame;
    unsigned int last_dispatch;
    unsigned int last_clear;

    /* 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 */
    drmTextureRegion texList[RADEON_NR_TEX_HEAPS][RADEON_NR_TEX_REGIONS+1];
				/* last time texture was uploaded */
    unsigned int texAge[RADEON_NR_TEX_HEAPS];

    int ctxOwner;		/* last context to upload state */
    int pfAllowPageFlip;	/* set by the 2d driver, read by the client */
    int pfCurrentPage;		/* set by kernel, read by others */
    int crtc2_base;		/* for pageflipping with CloneMode */
} RADEONSAREAPriv, *RADEONSAREAPrivPtr;

#endif

--- NEW FILE: radeon_version.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_version.h,v 1.10 2003/09/28 20:15:57 alanh Exp $ */
/*
 * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
 *
 * 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

#undef  RADEON_NAME
#undef  RADEON_DRIVER_NAME
#undef  R200_DRIVER_NAME
#undef  RADEON_VERSION_MAJOR
#undef  RADEON_VERSION_MINOR
#undef  RADEON_VERSION_PATCH
#undef  RADEON_VERSION_CURRENT
#undef  RADEON_VERSION_EVALUATE
#undef  RADEON_VERSION_STRINGIFY
#undef  RADEON_VERSION_NAME

#define RADEON_NAME          "RADEON"
#define RADEON_DRIVER_NAME   "radeon"
#define R200_DRIVER_NAME     "r200"

#define RADEON_VERSION_MAJOR 4
#define RADEON_VERSION_MINOR 0
#define RADEON_VERSION_PATCH 1

#ifndef RADEON_VERSION_EXTRA
#define RADEON_VERSION_EXTRA ""
#endif

#define RADEON_VERSION_CURRENT \
    ((RADEON_VERSION_MAJOR << 20) | \
     (RADEON_VERSION_MINOR << 10) | \
     (RADEON_VERSION_PATCH))

#define RADEON_VERSION_EVALUATE(__x) #__x
#define RADEON_VERSION_STRINGIFY(_x) RADEON_VERSION_EVALUATE(_x)
#define RADEON_VERSION_NAME                                             \
    RADEON_VERSION_STRINGIFY(RADEON_VERSION_MAJOR) "."                  \
    RADEON_VERSION_STRINGIFY(RADEON_VERSION_MINOR) "."                  \
    RADEON_VERSION_STRINGIFY(RADEON_VERSION_PATCH) RADEON_VERSION_EXTRA

#endif /* _RADEON_VERSION_H_ */

--- NEW FILE: radeon_video.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_video.c,v 1.30 2003/11/10 18:22:18 tsi Exp $ */

#include "radeon.h"
#include "radeon_macros.h"
#include "radeon_probe.h"
#include "radeon_reg.h"

#include "xf86.h"
#include "dixstruct.h"

#include <X11/extensions/Xv.h>
#include "fourcc.h"

#define OFF_DELAY       250  /* milliseconds */
#define FREE_DELAY      15000

#define OFF_TIMER       0x01
#define FREE_TIMER      0x02
#define CLIENT_VIDEO_ON 0x04
[...1413 lines suppressed...]

    if (!(offscreenImages = xalloc(sizeof(XF86OffscreenImageRec))))
	return;

    offscreenImages[0].image = &Images[0];
    offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES |
			       VIDEO_CLIP_TO_VIEWPORT;
    offscreenImages[0].alloc_surface = RADEONAllocateSurface;
    offscreenImages[0].free_surface = RADEONFreeSurface;
    offscreenImages[0].display = RADEONDisplaySurface;
    offscreenImages[0].stop = RADEONStopSurface;
    offscreenImages[0].setAttribute = RADEONSetSurfaceAttribute;
    offscreenImages[0].getAttribute = RADEONGetSurfaceAttribute;
    offscreenImages[0].max_width = 1024;
    offscreenImages[0].max_height = 1024;
    offscreenImages[0].num_attributes = NUM_ATTRIBUTES;
    offscreenImages[0].attributes = Attributes;

    xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1);
}




More information about the xserver-commit mailing list