summaryrefslogtreecommitdiff
path: root/driver/xf86-video-mach64/src
diff options
context:
space:
mode:
authorOwain Ainsworth <oga@cvs.openbsd.org>2008-07-12 15:43:43 +0000
committerOwain Ainsworth <oga@cvs.openbsd.org>2008-07-12 15:43:43 +0000
commit6be08682fffb33fb738ea68a2d49333fa547d3ac (patch)
treeea65f842b95b23c12f72c8dd6002c85d5f130e0b /driver/xf86-video-mach64/src
parent6349dabddf7e186738c7f643a3aa94d79c945330 (diff)
Import xf86-video-mach64, version 6.8.0. In the correct directory.
ok matthieu@.
Diffstat (limited to 'driver/xf86-video-mach64/src')
-rw-r--r--driver/xf86-video-mach64/src/Makefile.am110
-rw-r--r--driver/xf86-video-mach64/src/Makefile.in646
-rw-r--r--driver/xf86-video-mach64/src/ati.h34
-rw-r--r--driver/xf86-video-mach64/src/atiadjust.c134
-rw-r--r--driver/xf86-video-mach64/src/atiadjust.h31
-rw-r--r--driver/xf86-video-mach64/src/atiaudio.c50
-rw-r--r--driver/xf86-video-mach64/src/atiaudio.h51
-rw-r--r--driver/xf86-video-mach64/src/atibank.c114
-rw-r--r--driver/xf86-video-mach64/src/atibank.h44
-rw-r--r--driver/xf86-video-mach64/src/atibus.c123
-rw-r--r--driver/xf86-video-mach64/src/atibus.h49
-rw-r--r--driver/xf86-video-mach64/src/atichip.c271
-rw-r--r--driver/xf86-video-mach64/src/atichip.h94
-rw-r--r--driver/xf86-video-mach64/src/aticlock.c443
-rw-r--r--driver/xf86-video-mach64/src/aticlock.h62
-rw-r--r--driver/xf86-video-mach64/src/aticonfig.c506
-rw-r--r--driver/xf86-video-mach64/src/aticonsole.c816
-rw-r--r--driver/xf86-video-mach64/src/aticonsole.h43
-rw-r--r--driver/xf86-video-mach64/src/aticrtc.h42
-rw-r--r--driver/xf86-video-mach64/src/aticursor.h42
-rw-r--r--driver/xf86-video-mach64/src/atidac.c462
-rw-r--r--driver/xf86-video-mach64/src/atidac.h99
-rw-r--r--driver/xf86-video-mach64/src/atidecoder.c50
-rw-r--r--driver/xf86-video-mach64/src/atidecoder.h51
-rw-r--r--driver/xf86-video-mach64/src/atidga.c483
-rw-r--r--driver/xf86-video-mach64/src/atidga.h36
-rw-r--r--driver/xf86-video-mach64/src/atidri.c1640
-rw-r--r--driver/xf86-video-mach64/src/atidri.h49
-rw-r--r--driver/xf86-video-mach64/src/atidripriv.h57
-rw-r--r--driver/xf86-video-mach64/src/atidsp.c302
-rw-r--r--driver/xf86-video-mach64/src/atidsp.h35
-rw-r--r--driver/xf86-video-mach64/src/atii2c.c399
-rw-r--r--driver/xf86-video-mach64/src/atii2c.h48
-rw-r--r--driver/xf86-video-mach64/src/atiload.c98
-rw-r--r--driver/xf86-video-mach64/src/atiload.h32
-rw-r--r--driver/xf86-video-mach64/src/atilock.c537
-rw-r--r--driver/xf86-video-mach64/src/atilock.h31
-rw-r--r--driver/xf86-video-mach64/src/atimach64.c1341
-rw-r--r--driver/xf86-video-mach64/src/atimach64.h36
-rw-r--r--driver/xf86-video-mach64/src/atimach64accel.c1068
-rw-r--r--driver/xf86-video-mach64/src/atimach64accel.h54
-rw-r--r--driver/xf86-video-mach64/src/atimach64cursor.c426
-rw-r--r--driver/xf86-video-mach64/src/atimach64exa.c696
-rw-r--r--driver/xf86-video-mach64/src/atimach64i2c.c469
-rw-r--r--driver/xf86-video-mach64/src/atimach64i2c.h32
-rw-r--r--driver/xf86-video-mach64/src/atimach64io.c103
-rw-r--r--driver/xf86-video-mach64/src/atimach64io.h421
-rw-r--r--driver/xf86-video-mach64/src/atimach64probe.c289
-rw-r--r--driver/xf86-video-mach64/src/atimach64probe.h32
-rw-r--r--driver/xf86-video-mach64/src/atimach64render.c898
-rw-r--r--driver/xf86-video-mach64/src/atimach64version.h59
-rw-r--r--driver/xf86-video-mach64/src/atimach64xv.c1686
-rw-r--r--driver/xf86-video-mach64/src/atimisc.c78
-rw-r--r--driver/xf86-video-mach64/src/atimode.c1084
-rw-r--r--driver/xf86-video-mach64/src/atimode.h35
-rw-r--r--driver/xf86-video-mach64/src/atioption.h98
-rw-r--r--driver/xf86-video-mach64/src/atipcirename.h125
-rw-r--r--driver/xf86-video-mach64/src/atipreinit.c2509
-rw-r--r--driver/xf86-video-mach64/src/atipreinit.h30
-rw-r--r--driver/xf86-video-mach64/src/atiprint.c784
-rw-r--r--driver/xf86-video-mach64/src/atiprint.h34
-rw-r--r--driver/xf86-video-mach64/src/atipriv.h30
-rw-r--r--driver/xf86-video-mach64/src/atiprobe.c475
-rw-r--r--driver/xf86-video-mach64/src/atiprobe.h30
-rw-r--r--driver/xf86-video-mach64/src/atiregs.h2882
-rw-r--r--driver/xf86-video-mach64/src/atirgb514.c283
-rw-r--r--driver/xf86-video-mach64/src/atirgb514.h35
-rw-r--r--driver/xf86-video-mach64/src/atiscreen.c692
-rw-r--r--driver/xf86-video-mach64/src/atiscreen.h31
-rw-r--r--driver/xf86-video-mach64/src/atistruct.h529
-rw-r--r--driver/xf86-video-mach64/src/atituner.c177
-rw-r--r--driver/xf86-video-mach64/src/atituner.h69
-rw-r--r--driver/xf86-video-mach64/src/atiutil.c117
-rw-r--r--driver/xf86-video-mach64/src/atiutil.h67
-rw-r--r--driver/xf86-video-mach64/src/ativalid.c161
-rw-r--r--driver/xf86-video-mach64/src/ativalid.h30
-rw-r--r--driver/xf86-video-mach64/src/ativga.c195
-rw-r--r--driver/xf86-video-mach64/src/ativga.h40
-rw-r--r--driver/xf86-video-mach64/src/ativgaio.c49
-rw-r--r--driver/xf86-video-mach64/src/ativgaio.h56
-rw-r--r--driver/xf86-video-mach64/src/atividmem.c493
-rw-r--r--driver/xf86-video-mach64/src/atividmem.h73
-rw-r--r--driver/xf86-video-mach64/src/atiwonder.c159
-rw-r--r--driver/xf86-video-mach64/src/atiwonder.h38
-rw-r--r--driver/xf86-video-mach64/src/atiwonderio.c66
-rw-r--r--driver/xf86-video-mach64/src/atiwonderio.h46
-rw-r--r--driver/xf86-video-mach64/src/atixv.h34
-rw-r--r--driver/xf86-video-mach64/src/mach64_common.h130
-rw-r--r--driver/xf86-video-mach64/src/mach64_dri.h125
-rw-r--r--driver/xf86-video-mach64/src/mach64_sarea.h162
90 files changed, 27775 insertions, 0 deletions
diff --git a/driver/xf86-video-mach64/src/Makefile.am b/driver/xf86-video-mach64/src/Makefile.am
new file mode 100644
index 000000000..4bc100652
--- /dev/null
+++ b/driver/xf86-video-mach64/src/Makefile.am
@@ -0,0 +1,110 @@
+# Copyright 2005 Adam Jackson.
+# Copyright 2005 Red Hat, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# on the rights to use, copy, modify, merge, publish, distribute, sub
+# license, and/or sell copies of the Software, and to permit persons to whom
+# the Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+# ADAM JACKSON 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.
+
+
+# this is obnoxious:
+# -module lets us name the module exactly how we want
+# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
+# _ladir passes a dummy rpath to libtool so the thing will actually link
+# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
+
+if DRI
+ATIMISC_DRI_SRCS = atidri.c
+endif
+
+if ATIMISC_CPIO
+ATIMISC_CPIO_SOURCES = ativga.c ativgaio.c atibank.c atiwonder.c atiwonderio.c
+endif
+
+if ATIMISC_DGA
+ATIMISC_DGA_SOURCES = atidga.c
+endif
+
+if USE_EXA
+ATIMISC_EXA_SOURCES = atimach64exa.c
+endif
+
+AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@
+
+mach64_drv_la_LTLIBRARIES = mach64_drv.la
+mach64_drv_la_LDFLAGS = -module -avoid-version
+mach64_drv_ladir = @moduledir@/drivers
+mach64_drv_la_SOURCES = \
+ atibus.c atichip.c atiprobe.c atividmem.c \
+ atiadjust.c atiaudio.c aticlock.c aticonfig.c aticonsole.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 \
+ atiload.c atimisc.c atimach64probe.c $(ATIMISC_CPIO_SOURCES) \
+ $(ATIMISC_DGA_SOURCES) $(ATIMISC_DRI_SRCS) $(ATIMISC_EXA_SOURCES)
+
+EXTRA_DIST = \
+ atimach64render.c \
+ \
+ atiadjust.h \
+ atiaudio.h \
+ atibank.h \
+ atibus.h \
+ atichip.h \
+ aticlock.h \
+ aticonsole.h \
+ aticrtc.h \
+ aticursor.h \
+ atidac.h \
+ atidecoder.h \
+ atidga.h \
+ atidri.h \
+ atidripriv.h \
+ atidsp.h \
+ ati.h \
+ atii2c.h \
+ atiload.h \
+ atilock.h \
+ atimach64accel.h \
+ atimach64.h \
+ atimach64i2c.h \
+ atimach64io.h \
+ atimach64probe.h \
+ atimach64version.h \
+ atimode.h \
+ atioption.h \
+ atipreinit.h \
+ atiprint.h \
+ atipriv.h \
+ atiprobe.h \
+ atiregs.h \
+ atirgb514.h \
+ atiscreen.h \
+ atistruct.h \
+ atituner.h \
+ atiutil.h \
+ ativalid.h \
+ ativga.h \
+ ativgaio.h \
+ atividmem.h \
+ atiwonder.h \
+ atiwonderio.h \
+ atixv.h \
+ mach64_common.h \
+ mach64_dri.h \
+ mach64_sarea.h \
+ atipcirename.h
diff --git a/driver/xf86-video-mach64/src/Makefile.in b/driver/xf86-video-mach64/src/Makefile.in
new file mode 100644
index 000000000..519ccf993
--- /dev/null
+++ b/driver/xf86-video-mach64/src/Makefile.in
@@ -0,0 +1,646 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Copyright 2005 Adam Jackson.
+# Copyright 2005 Red Hat, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# on the rights to use, copy, modify, merge, publish, distribute, sub
+# license, and/or sell copies of the Software, and to permit persons to whom
+# the Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+# ADAM JACKSON 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.
+
+# this is obnoxious:
+# -module lets us name the module exactly how we want
+# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
+# _ladir passes a dummy rpath to libtool so the thing will actually link
+# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(mach64_drv_ladir)"
+mach64_drv_laLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(mach64_drv_la_LTLIBRARIES)
+mach64_drv_la_LIBADD =
+am__mach64_drv_la_SOURCES_DIST = atibus.c atichip.c atiprobe.c \
+ atividmem.c atiadjust.c atiaudio.c aticlock.c aticonfig.c \
+ aticonsole.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 \
+ atiload.c atimisc.c atimach64probe.c ativga.c ativgaio.c \
+ atibank.c atiwonder.c atiwonderio.c atidga.c atidri.c \
+ atimach64exa.c
+@ATIMISC_CPIO_TRUE@am__objects_1 = ativga.lo ativgaio.lo atibank.lo \
+@ATIMISC_CPIO_TRUE@ atiwonder.lo atiwonderio.lo
+@ATIMISC_DGA_TRUE@am__objects_2 = atidga.lo
+@DRI_TRUE@am__objects_3 = atidri.lo
+@USE_EXA_TRUE@am__objects_4 = atimach64exa.lo
+am_mach64_drv_la_OBJECTS = atibus.lo atichip.lo atiprobe.lo \
+ atividmem.lo atiadjust.lo atiaudio.lo aticlock.lo aticonfig.lo \
+ aticonsole.lo atidac.lo atidecoder.lo atidsp.lo atii2c.lo \
+ atilock.lo atimach64.lo atimach64accel.lo atimach64cursor.lo \
+ atimach64i2c.lo atimach64io.lo atimach64xv.lo atimode.lo \
+ atipreinit.lo atiprint.lo atirgb514.lo atiscreen.lo \
+ atituner.lo atiutil.lo ativalid.lo atiload.lo atimisc.lo \
+ atimach64probe.lo $(am__objects_1) $(am__objects_2) \
+ $(am__objects_3) $(am__objects_4)
+mach64_drv_la_OBJECTS = $(am_mach64_drv_la_OBJECTS)
+mach64_drv_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(mach64_drv_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(mach64_drv_la_SOURCES)
+DIST_SOURCES = $(am__mach64_drv_la_SOURCES_DIST)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ADMIN_MAN_DIR = @ADMIN_MAN_DIR@
+ADMIN_MAN_SUFFIX = @ADMIN_MAN_SUFFIX@
+AMTAR = @AMTAR@
+APP_MAN_DIR = @APP_MAN_DIR@
+APP_MAN_SUFFIX = @APP_MAN_SUFFIX@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DRIVER_MAN_DIR = @DRIVER_MAN_DIR@
+DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@
+DRIVER_NAME = @DRIVER_NAME@
+DRI_CFLAGS = @DRI_CFLAGS@
+DRI_LIBS = @DRI_LIBS@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FILE_MAN_DIR = @FILE_MAN_DIR@
+FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIB_MAN_DIR = @LIB_MAN_DIR@
+LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@
+LINUXDOC = @LINUXDOC@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MAKE_HTML = @MAKE_HTML@
+MAKE_PDF = @MAKE_PDF@
+MAKE_PS = @MAKE_PS@
+MAKE_TEXT = @MAKE_TEXT@
+MISC_MAN_DIR = @MISC_MAN_DIR@
+MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@
+MKDIR_P = @MKDIR_P@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PCIACCESS_CFLAGS = @PCIACCESS_CFLAGS@
+PCIACCESS_LIBS = @PCIACCESS_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+PS2PDF = @PS2PDF@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+XORG_CFLAGS = @XORG_CFLAGS@
+XORG_LIBS = @XORG_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+moduledir = @moduledir@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+@DRI_TRUE@ATIMISC_DRI_SRCS = atidri.c
+@ATIMISC_CPIO_TRUE@ATIMISC_CPIO_SOURCES = ativga.c ativgaio.c atibank.c atiwonder.c atiwonderio.c
+@ATIMISC_DGA_TRUE@ATIMISC_DGA_SOURCES = atidga.c
+@USE_EXA_TRUE@ATIMISC_EXA_SOURCES = atimach64exa.c
+AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@
+mach64_drv_la_LTLIBRARIES = mach64_drv.la
+mach64_drv_la_LDFLAGS = -module -avoid-version
+mach64_drv_ladir = @moduledir@/drivers
+mach64_drv_la_SOURCES = \
+ atibus.c atichip.c atiprobe.c atividmem.c \
+ atiadjust.c atiaudio.c aticlock.c aticonfig.c aticonsole.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 \
+ atiload.c atimisc.c atimach64probe.c $(ATIMISC_CPIO_SOURCES) \
+ $(ATIMISC_DGA_SOURCES) $(ATIMISC_DRI_SRCS) $(ATIMISC_EXA_SOURCES)
+
+EXTRA_DIST = \
+ atimach64render.c \
+ \
+ atiadjust.h \
+ atiaudio.h \
+ atibank.h \
+ atibus.h \
+ atichip.h \
+ aticlock.h \
+ aticonsole.h \
+ aticrtc.h \
+ aticursor.h \
+ atidac.h \
+ atidecoder.h \
+ atidga.h \
+ atidri.h \
+ atidripriv.h \
+ atidsp.h \
+ ati.h \
+ atii2c.h \
+ atiload.h \
+ atilock.h \
+ atimach64accel.h \
+ atimach64.h \
+ atimach64i2c.h \
+ atimach64io.h \
+ atimach64probe.h \
+ atimach64version.h \
+ atimode.h \
+ atioption.h \
+ atipreinit.h \
+ atiprint.h \
+ atipriv.h \
+ atiprobe.h \
+ atiregs.h \
+ atirgb514.h \
+ atiscreen.h \
+ atistruct.h \
+ atituner.h \
+ atiutil.h \
+ ativalid.h \
+ ativga.h \
+ ativgaio.h \
+ atividmem.h \
+ atiwonder.h \
+ atiwonderio.h \
+ atixv.h \
+ mach64_common.h \
+ mach64_dri.h \
+ mach64_sarea.h \
+ atipcirename.h
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-mach64_drv_laLTLIBRARIES: $(mach64_drv_la_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(mach64_drv_ladir)" || $(MKDIR_P) "$(DESTDIR)$(mach64_drv_ladir)"
+ @list='$(mach64_drv_la_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(mach64_drv_laLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(mach64_drv_ladir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(mach64_drv_laLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(mach64_drv_ladir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-mach64_drv_laLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(mach64_drv_la_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(mach64_drv_ladir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(mach64_drv_ladir)/$$p"; \
+ done
+
+clean-mach64_drv_laLTLIBRARIES:
+ -test -z "$(mach64_drv_la_LTLIBRARIES)" || rm -f $(mach64_drv_la_LTLIBRARIES)
+ @list='$(mach64_drv_la_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+mach64_drv.la: $(mach64_drv_la_OBJECTS) $(mach64_drv_la_DEPENDENCIES)
+ $(mach64_drv_la_LINK) -rpath $(mach64_drv_ladir) $(mach64_drv_la_OBJECTS) $(mach64_drv_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atiadjust.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atiaudio.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atibank.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atibus.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atichip.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aticlock.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aticonfig.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aticonsole.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atidac.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atidecoder.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atidga.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atidri.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atidsp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atii2c.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atiload.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atilock.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atimach64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atimach64accel.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atimach64cursor.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atimach64exa.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atimach64i2c.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atimach64io.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atimach64probe.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atimach64xv.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atimisc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atimode.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atipreinit.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atiprint.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atiprobe.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atirgb514.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atiscreen.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atituner.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atiutil.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ativalid.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ativga.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ativgaio.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atividmem.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atiwonder.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atiwonderio.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(mach64_drv_ladir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-mach64_drv_laLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-mach64_drv_laLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-mach64_drv_laLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-mach64_drv_laLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am \
+ install-mach64_drv_laLTLIBRARIES install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-mach64_drv_laLTLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/driver/xf86-video-mach64/src/ati.h b/driver/xf86-video-mach64/src/ati.h
new file mode 100644
index 000000000..828aae10e
--- /dev/null
+++ b/driver/xf86-video-mach64/src/ati.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 1999 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 <unistd.h>
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+
+#include "xf86.h"
+
+#include "xf86_OSproc.h"
+
+#endif /* ___ATI_H___ */
diff --git a/driver/xf86-video-mach64/src/atiadjust.c b/driver/xf86-video-mach64/src/atiadjust.c
new file mode 100644
index 000000000..267186f48
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atiadjust.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "ati.h"
+#include "atiadjust.h"
+#include "atichip.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;
+
+ {
+ 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);
+ }
+
+ {
+ pATI->AdjustMaxBase = MaxBits(CRTC_OFFSET) << 3;
+ }
+
+ 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);
+
+ {
+ outr(CRTC_OFF_PITCH, SetBits(pATI->displayWidth >> 3, CRTC_PITCH) |
+ SetBits(Base, CRTC_OFFSET));
+ }
+}
diff --git a/driver/xf86-video-mach64/src/atiadjust.h b/driver/xf86-video-mach64/src/atiadjust.h
new file mode 100644
index 000000000..58c6efc4a
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atiadjust.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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"
+
+extern void ATIAdjustPreInit(ATIPtr);
+extern void ATIAdjustFrame(int, int, int, int);
+
+#endif /* ___ATIADJUST_H___ */
diff --git a/driver/xf86-video-mach64/src/atiaudio.c b/driver/xf86-video-mach64/src/atiaudio.c
new file mode 100644
index 000000000..555a4a75a
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atiaudio.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#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"
+};
diff --git a/driver/xf86-video-mach64/src/atiaudio.h b/driver/xf86-video-mach64/src/atiaudio.h
new file mode 100644
index 000000000..bcea8b418
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atiaudio.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2003 by Marc Aurele La France (TSI @ UQV), tsi@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___ */
diff --git a/driver/xf86-video-mach64/src/atibank.c b/driver/xf86-video-mach64/src/atibank.c
new file mode 100644
index 000000000..514a41452
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atibank.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "ati.h"
+#include "atibank.h"
+#include "atimach64io.h"
+#include "atiwonderio.h"
+
+#ifndef AVOID_CPIO
+
+/*
+ * ATIx8800SetBank --
+ *
+ * Set an ATI 28800's, 68800's or 88800's read and write bank numbers.
+ */
+void
+ATIx8800SetBank
+(
+ ATIPtr pATI,
+ unsigned int iBank
+)
+{
+ (void)iBank; /* always called with iBank = 0 */
+
+ ATIPutExtReg(0xB2U, 0x00U);
+ ATIModifyExtReg(pATI, 0xAEU, -1, (CARD8)(~0x0FU), 0x00U);
+}
+
+/*
+ * 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);
+}
+
+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);
+}
+
+#endif /* AVOID_CPIO */
diff --git a/driver/xf86-video-mach64/src/atibank.h b/driver/xf86-video-mach64/src/atibank.h
new file mode 100644
index 000000000..d56da6847
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atibank.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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"
+
+#ifndef AVOID_CPIO
+
+/*
+ * The CRT save/restore code also needs a separate banking interface that can
+ * used before ATIScreenInit() is called.
+ */
+
+typedef void ATIBankProc(ATIPtr, unsigned int);
+typedef ATIBankProc *ATIBankProcPtr;
+
+extern ATIBankProc ATIx8800SetBank,
+ ATIMach64SetBankPacked,
+ ATIMach64SetBankPlanar;
+
+#endif /* AVOID_CPIO */
+
+#endif /* ___ATIBANK_H___ */
diff --git a/driver/xf86-video-mach64/src/atibus.c b/driver/xf86-video-mach64/src/atibus.c
new file mode 100644
index 000000000..69a308911
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atibus.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include "ati.h"
+#include "atibus.h"
+#include "atichip.h"
+#include "atimach64io.h"
+#include "atistruct.h"
+
+/*
+ * Definitions related to an adapter's system bus interface.
+ */
+
+const char *ATIBusNames[] =
+{
+ "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
+)
+{
+
+#ifndef AVOID_CPIO
+
+ resRange Resources[2] = {{0, 0, 0}, _END};
+
+ /* Claim VGA and VGAWonder resources */
+ if ((pATI->VGAAdapter) && (Active))
+ {
+ /*
+ * 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(resVgaShared, pATI->iEntity);
+
+ if (pATI->CPIO_VGAWonder)
+ {
+ Resources[0].type = ResShrIoSparse | ResBus;
+ Resources[0].rBase = pATI->CPIO_VGAWonder;
+ Resources[0].rMask = 0xF3FEU;
+
+ xf86ClaimFixedResources(Resources, pATI->iEntity);
+
+ (void)memcpy(pATI->VGAWonderResources,
+ Resources, SizeOf(Resources));
+ }
+ }
+
+ if (!Active)
+ return;
+
+ /* Claim Mach64 sparse I/O resources */
+ if ((pATI->CPIODecoding == SPARSE_IO))
+ {
+ Resources[0].type = ResShrIoSparse | ResBus;
+ Resources[0].rBase = pATI->CPIOBase;
+ Resources[0].rMask = 0x03FCU;
+
+ xf86ClaimFixedResources(Resources, pATI->iEntity);
+ }
+
+#endif /* AVOID_CPIO */
+
+}
+
+/*
+ * ATIClaimBusSlot --
+ *
+ * Claim an adapter and register its resources.
+ */
+int
+ATIClaimBusSlot
+(
+ Bool Active,
+ ATIPtr pATI
+)
+{
+ if (pATI->iEntity >= 0)
+ ATIClaimResources(pATI, Active);
+
+ return pATI->iEntity;
+}
diff --git a/driver/xf86-video-mach64/src/atibus.h b/driver/xf86-video-mach64/src/atibus.h
new file mode 100644
index 000000000..e5f1afd15
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atibus.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 "xf86str.h"
+
+/*
+ * Definitions related to an adapter's system bus interface.
+ */
+typedef enum
+{
+ ATI_BUS_PCI,
+ ATI_BUS_AGP
+} ATIBusType;
+
+extern const char *ATIBusNames[];
+
+extern int ATIClaimBusSlot(Bool, ATIPtr);
+
+#endif /* ___ATIBUS_H___ */
diff --git a/driver/xf86-video-mach64/src/atichip.c b/driver/xf86-video-mach64/src/atichip.c
new file mode 100644
index 000000000..aac00e677
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atichip.c
@@ -0,0 +1,271 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "ati.h"
+#include "atibus.h"
+#include "atichip.h"
+#include "atimach64io.h"
+#include "atimach64version.h"
+
+const char *ATIFoundryNames[] =
+ { "SGS", "NEC", "KCS", "UMC", "TSMC", "5", "6", "UMC" };
+
+/*
+ * 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, CFG_CHIP_TYPE);
+ pATI->ChipClass = GetBits(pATI->config_chip_id, CFG_CHIP_CLASS);
+ pATI->ChipRev = 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->ChipRevision = GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
+ switch (pATI->ChipType)
+ {
+ case OldChipID('G', 'X'):
+ pATI->ChipType = OldToNewChipID(pATI->ChipType);
+ case NewChipID('G', 'X'):
+ switch (pATI->ChipRev)
+ {
+ 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->Chip = ATI_CHIP_264CT;
+ pATI->BusType = ATI_BUS_PCI;
+ break;
+
+ case OldChipID('E', 'T'):
+ pATI->ChipType = OldToNewChipID(pATI->ChipType);
+ case NewChipID('E', 'T'):
+ 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->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,
+ MACH64_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->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->Chip = ATI_CHIP_264VT3;
+ pATI->BusType = ATI_BUS_PCI;
+ break;
+
+ case OldChipID('G', 'U'):
+ pATI->ChipType = OldToNewChipID(pATI->ChipType);
+ case NewChipID('G', 'U'):
+ 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->Chip = ATI_CHIP_264LT;
+ pATI->BusType = ATI_BUS_PCI;
+ break;
+
+ case OldChipID('V', 'V'):
+ pATI->ChipType = OldToNewChipID(pATI->ChipType);
+ case NewChipID('V', 'V'):
+ 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->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->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->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->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->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->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->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->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->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->Chip = ATI_CHIP_MOBILITY;
+ pATI->BusType = ATI_BUS_AGP;
+ pATI->LCDVBlendFIFOSize = 1024;
+ break;
+
+ default:
+ pATI->Chip = ATI_CHIP_Mach64;
+ break;
+ }
+}
diff --git a/driver/xf86-video-mach64/src/atichip.h b/driver/xf86-video-mach64/src/atichip.h
new file mode 100644
index 000000000..e59d6ebb5
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atichip.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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,
+ 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 */
+} ATIChipType;
+
+/*
+ * 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[];
+
+extern void ATIMach64ChipID(ATIPtr, const CARD16);
+
+#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___ */
diff --git a/driver/xf86-video-mach64/src/aticlock.c b/driver/xf86-video-mach64/src/aticlock.c
new file mode 100644
index 000000000..f4de77f6b
--- /dev/null
+++ b/driver/xf86-video-mach64/src/aticlock.c
@@ -0,0 +1,443 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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.
+ */
+
+/*
+ * For all supported programmable clock generators, the driver will ignore any
+ * XF86Config clock line and programme, as needed, the clock number reserved by
+ * the BIOS for accelerated drivers. The driver's mode initialisation routine
+ * finds integers N, M and D such that
+ *
+ * N
+ * R * ------- MHz
+ * M * D
+ *
+ * best approximates the mode's clock frequency, where R is the crystal-
+ * generated reference frequency (usually 14.318 MHz). D is a power of 2
+ * except for those integrated controllers that also offer odd dividers.
+ * Different clock generators have different restrictions on the value N, M and
+ * D can assume. The driver contains an internal table to record these
+ * restrictions (among other things). The resulting values of N, M and D are
+ * then encoded in a generator-specific way and used to programme the clock.
+ * The Mach64's clock divider is not used in this case.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include "ati.h"
+#include "atichip.h"
+#include "atidac.h"
+#include "atidsp.h"
+#include "atimach64io.h"
+#include "atimode.h"
+#include "atiwonderio.h"
+
+/*
+ * Definitions related to programmable clock generators.
+ */
+static CARD16 ATIPostDividers[] = {1, 2, 4, 8, 16, 32, 64, 128},
+ ATI264xTPostDividers[] = {1, 2, 4, 8, 3, 0, 6, 12};
+ClockRec ATIClockDescriptors[] =
+{
+ {
+ 0, 0, 0, 1, 1,
+ 1, 1, 0,
+ 0, NULL,
+ "Non-programmable"
+ },
+ {
+ 257, 512, 257, 1, 1,
+ 46, 46, 0,
+ 4, ATIPostDividers,
+ "ATI 18818 or ICS 2595 or similar"
+ },
+ {
+ 2, 129, 2, 1, 1,
+ 8, 14, 2,
+ 8, ATIPostDividers,
+ "SGS-Thompson 1703 or similar"
+ },
+ {
+ 16, 263, 8, 8, 9,
+ 4, 12, 2,
+ 4, ATIPostDividers,
+ "Chrontel 8398 or similar"
+ },
+ {
+ 2, 255, 0, 1, 1,
+ 45, 45, 0,
+ 4, ATI264xTPostDividers,
+ "Internal"
+ },
+ {
+ 2, 257, 2, 1, 1,
+ 2, 32, 2,
+ 4, ATIPostDividers,
+ "AT&T 20C408 or similar"
+ },
+ {
+ 65, 128, 65, 1, 1,
+ 2, 14, 0,
+ 4, ATIPostDividers,
+ "IBM RGB 514 or similar"
+ }
+};
+
+/*
+ * ATIClockPreInit --
+ *
+ * This function is called by ATIPreInit() and handles the XF86Config clocks
+ * line (or lack thereof).
+ */
+void
+ATIClockPreInit
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI
+)
+{
+ /*
+ * Recognise supported clock generators. This involves telling the
+ * rest of the server about it and (re-)initializing the XF86Config
+ * clocks line.
+ */
+ pScreenInfo->progClock = TRUE;
+
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
+ "%s programmable clock generator detected.\n",
+ pATI->ClockDescriptor.ClockName);
+ if (pATI->ReferenceDenominator == 1)
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
+ "Reference clock %.3f MHz.\n",
+ (double)pATI->ReferenceNumerator / 1000.0);
+ else
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
+ "Reference clock %.6g/%d (%.3f) MHz.\n",
+ (double)pATI->ReferenceNumerator / 1000.0,
+ pATI->ReferenceDenominator,
+ (double)pATI->ReferenceNumerator /
+ ((double)pATI->ReferenceDenominator * 1000.0));
+
+#if defined(__sparc__)
+ if ((pATI->refclk / 100000) != 286 &&
+ (pATI->refclk / 100000) != 295)
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "If modes do not work on Ultra 5/10 or Blade 100/150,\n"
+ "\tset option \"reference_clock\" to \"28.636 MHz\""
+ " or \"29.5 MHz\"\n");
+ }
+#endif
+
+ if (pATI->ProgrammableClock == ATI_CLOCK_CH8398)
+ { /* First two are fixed */
+ pScreenInfo->numClocks = 2;
+ pScreenInfo->clock[0] = 25175;
+ pScreenInfo->clock[1] = 28322;
+ }
+ else if (pATI->ProgrammableClock == ATI_CLOCK_INTERNAL)
+ {
+ /*
+ * The integrated PLL generates clocks as if the reference
+ * frequency were doubled.
+ */
+ pATI->ReferenceNumerator <<= 1;
+ }
+}
+
+/*
+ * ATIClockCalculate --
+ *
+ * This function is called to generate, if necessary, the data needed for clock
+ * programming, and set clock select bits in various register values.
+ */
+Bool
+ATIClockCalculate
+(
+ int iScreen,
+ ATIPtr pATI,
+ ATIHWPtr pATIHW,
+ DisplayModePtr pMode
+)
+{
+ int N, M, D;
+ int ClockSelect, N1, MinimumGap;
+ int Frequency, Multiple; /* Used as temporaries */
+
+ /* Set default values */
+ pATIHW->FeedbackDivider = pATIHW->ReferenceDivider = pATIHW->PostDivider = 0;
+
+ if (((pATI->ProgrammableClock == ATI_CLOCK_CH8398) &&
+ (pMode->ClockIndex < 2)))
+ {
+ xf86DrvMsg(iScreen, X_ERROR,
+ "First two clocks of Chrontel 8398 clock generator are fixed\n");
+ return FALSE;
+ }
+
+ {
+ /* Generate clock programme word, using units of kHz */
+ MinimumGap = ((unsigned int)(-1)) >> 1;
+
+ /* Loop through reference dividers */
+ for (M = pATI->ClockDescriptor.MinM;
+ M <= pATI->ClockDescriptor.MaxM;
+ M++)
+ {
+ /* Loop through post-dividers */
+ for (D = 0; D < pATI->ClockDescriptor.NumD; D++)
+ {
+ if (!pATI->ClockDescriptor.PostDividers[D])
+ continue;
+
+ /* Limit undivided VCO to maxClock */
+ if (pATI->maxClock &&
+ ((pATI->maxClock / pATI->ClockDescriptor.PostDividers[D]) <
+ pMode->Clock))
+ continue;
+
+ /*
+ * Calculate closest feedback divider and apply its
+ * restrictions.
+ */
+ Multiple = M * pATI->ReferenceDenominator *
+ pATI->ClockDescriptor.PostDividers[D];
+ N = ATIDivide(pMode->Clock * Multiple,
+ pATI->ReferenceNumerator, 0, 0);
+ if (N < pATI->ClockDescriptor.MinN)
+ N = pATI->ClockDescriptor.MinN;
+ else if (N > pATI->ClockDescriptor.MaxN)
+ N = pATI->ClockDescriptor.MaxN;
+ N -= pATI->ClockDescriptor.NAdjust;
+ N1 = (N / pATI->ClockDescriptor.N1) * pATI->ClockDescriptor.N2;
+ if (N > N1)
+ N = ATIDivide(N1 + 1, pATI->ClockDescriptor.N1, 0, 1);
+ N += pATI->ClockDescriptor.NAdjust;
+ N1 += pATI->ClockDescriptor.NAdjust;
+
+ for (; ; N = N1)
+ {
+ /* Pick the closest setting */
+ Frequency = abs(ATIDivide(N * pATI->ReferenceNumerator,
+ Multiple, 0, 0) - pMode->Clock);
+ if ((Frequency < MinimumGap) ||
+ ((Frequency == MinimumGap) &&
+ (pATIHW->FeedbackDivider < N)))
+ {
+ /* Save settings */
+ pATIHW->FeedbackDivider = N;
+ pATIHW->ReferenceDivider = M;
+ pATIHW->PostDivider = D;
+ MinimumGap = Frequency;
+ }
+
+ if (N <= N1)
+ break;
+ }
+ }
+ }
+
+ Multiple = pATIHW->ReferenceDivider * pATI->ReferenceDenominator *
+ pATI->ClockDescriptor.PostDividers[pATIHW->PostDivider];
+ Frequency = pATIHW->FeedbackDivider * pATI->ReferenceNumerator;
+ Frequency = ATIDivide(Frequency, Multiple, 0, 0);
+ if (abs(Frequency - pMode->Clock) > CLOCK_TOLERANCE)
+ {
+ xf86DrvMsg(iScreen, X_ERROR,
+ "Unable to programme clock %.3fMHz for mode %s.\n",
+ (double)(pMode->Clock) / 1000.0, pMode->name);
+ return FALSE;
+ }
+ pMode->SynthClock = Frequency;
+ ClockSelect = pATI->ClockNumberToProgramme;
+
+ xf86ErrorFVerb(4,
+ "\n Programming clock %d to %.3fMHz for mode %s."
+ " N=%d, M=%d, D=%d.\n",
+ ClockSelect, (double)Frequency / 1000.0, pMode->name,
+ pATIHW->FeedbackDivider, pATIHW->ReferenceDivider,
+ pATIHW->PostDivider);
+
+ if (pATI->Chip >= ATI_CHIP_264VTB)
+ ATIDSPCalculate(pATI, pATIHW, pMode);
+ }
+
+ /* Set clock select bits */
+ pATIHW->clock = ClockSelect;
+
+ {
+ pATIHW->clock_cntl = CLOCK_STROBE |
+ SetBits(ClockSelect, CLOCK_SELECT | CLOCK_DIVIDER);
+ }
+
+ return TRUE;
+}
+
+/*
+ * ATIClockSet --
+ *
+ * This function is called to programme a clock for the mode being set.
+ */
+void
+ATIClockSet
+(
+ ATIPtr pATI,
+ ATIHWPtr pATIHW
+)
+{
+ CARD32 crtc_gen_cntl, tmp;
+ CARD8 clock_cntl0;
+ CARD8 tmp2;
+ unsigned int Programme;
+ int N = pATIHW->FeedbackDivider - pATI->ClockDescriptor.NAdjust;
+ int M = pATIHW->ReferenceDivider - pATI->ClockDescriptor.MAdjust;
+ int D = pATIHW->PostDivider;
+
+ /* Temporarily switch to accelerator mode */
+ 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);
+
+ switch (pATI->ProgrammableClock)
+ {
+ case ATI_CLOCK_ICS2595:
+ clock_cntl0 = in8(CLOCK_CNTL);
+
+ Programme = (SetBits(pATIHW->clock, ICS2595_CLOCK) |
+ SetBits(N, ICS2595_FB_DIV) | SetBits(D, ICS2595_POST_DIV)) ^
+ ICS2595_TOGGLE;
+
+ ATIDelay(50000); /* 50 milliseconds */
+
+ (void)xf86DisableInterrupts();
+
+ /* Send all 20 bits of programme word */
+ while (Programme >= CLOCK_BIT)
+ {
+ tmp = (Programme & CLOCK_BIT) | CLOCK_STROBE;
+ out8(CLOCK_CNTL, tmp);
+ ATIDelay(26); /* 26 microseconds */
+ out8(CLOCK_CNTL, tmp | CLOCK_PULSE);
+ ATIDelay(26); /* 26 microseconds */
+ Programme >>= 1;
+ }
+
+ xf86EnableInterrupts();
+
+ /* Restore register */
+ out8(CLOCK_CNTL, clock_cntl0 | CLOCK_STROBE);
+ break;
+
+ case ATI_CLOCK_STG1703:
+ (void)ATIGetDACCmdReg(pATI);
+ (void)in8(M64_DAC_MASK);
+ out8(M64_DAC_MASK, (pATIHW->clock << 1) + 0x20U);
+ out8(M64_DAC_MASK, 0);
+ out8(M64_DAC_MASK, SetBits(N, 0xFFU));
+ out8(M64_DAC_MASK, SetBits(M, 0x1FU) | SetBits(D, 0xE0U));
+ break;
+
+ case ATI_CLOCK_CH8398:
+ tmp = inr(DAC_CNTL) | (DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3);
+ outr(DAC_CNTL, tmp);
+ out8(M64_DAC_WRITE, pATIHW->clock);
+ out8(M64_DAC_DATA, SetBits(N, 0xFFU));
+ out8(M64_DAC_DATA, SetBits(M, 0x3FU) | SetBits(D, 0xC0U));
+ out8(M64_DAC_MASK, 0x04U);
+ outr(DAC_CNTL, tmp & ~(DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3));
+ tmp2 = in8(M64_DAC_WRITE);
+ out8(M64_DAC_WRITE, (tmp2 & 0x70U) | 0x80U);
+ outr(DAC_CNTL, tmp & ~DAC_EXT_SEL_RS2);
+ break;
+
+ case ATI_CLOCK_INTERNAL:
+ /* Reset VCLK generator */
+ ATIMach64PutPLLReg(PLL_VCLK_CNTL, pATIHW->pll_vclk_cntl);
+
+ /* Set post-divider */
+ tmp2 = pATIHW->clock << 1;
+ tmp = ATIMach64GetPLLReg(PLL_VCLK_POST_DIV);
+ tmp &= ~(0x03U << tmp2);
+ tmp |= SetBits(D, 0x03U) << tmp2;
+ ATIMach64PutPLLReg(PLL_VCLK_POST_DIV, tmp);
+
+ /* Set extended post-divider */
+ tmp = ATIMach64GetPLLReg(PLL_XCLK_CNTL);
+ tmp &= ~(SetBits(1, PLL_VCLK0_XDIV) << pATIHW->clock);
+ tmp |= SetBits(D >> 2, PLL_VCLK0_XDIV) << pATIHW->clock;
+ ATIMach64PutPLLReg(PLL_XCLK_CNTL, tmp);
+
+ /* Set feedback divider */
+ tmp = PLL_VCLK0_FB_DIV + pATIHW->clock;
+ ATIMach64PutPLLReg(tmp, SetBits(N, 0xFFU));
+
+ /* End VCLK generator reset */
+ ATIMach64PutPLLReg(PLL_VCLK_CNTL,
+ pATIHW->pll_vclk_cntl & ~PLL_VCLK_RESET);
+
+ /* Reset write bit */
+ ATIMach64AccessPLLReg(pATI, 0, FALSE);
+ break;
+
+ case ATI_CLOCK_ATT20C408:
+ (void)ATIGetDACCmdReg(pATI);
+ tmp = in8(M64_DAC_MASK);
+ (void)ATIGetDACCmdReg(pATI);
+ out8(M64_DAC_MASK, tmp | 1);
+ out8(M64_DAC_WRITE, 1);
+ out8(M64_DAC_MASK, tmp | 9);
+ ATIDelay(400); /* 400 microseconds */
+ tmp2 = (pATIHW->clock << 2) + 0x40U;
+ out8(M64_DAC_WRITE, tmp2);
+ out8(M64_DAC_MASK, SetBits(N, 0xFFU));
+ out8(M64_DAC_WRITE, ++tmp2);
+ out8(M64_DAC_MASK, SetBits(M, 0x3FU) | SetBits(D, 0xC0U));
+ out8(M64_DAC_WRITE, ++tmp2);
+ out8(M64_DAC_MASK, 0x77U);
+ ATIDelay(400); /* 400 microseconds */
+ out8(M64_DAC_WRITE, 1);
+ out8(M64_DAC_MASK, tmp);
+ break;
+
+ case ATI_CLOCK_IBMRGB514:
+ /*
+ * 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);
+}
diff --git a/driver/xf86-video-mach64/src/aticlock.h b/driver/xf86-video-mach64/src/aticlock.h
new file mode 100644
index 000000000..1d3f1b9c3
--- /dev/null
+++ b/driver/xf86-video-mach64/src/aticlock.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 "xf86str.h"
+
+/*
+ * 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(ScrnInfoPtr, ATIPtr);
+extern Bool ATIClockCalculate(int, ATIPtr, ATIHWPtr, DisplayModePtr);
+extern void ATIClockSet(ATIPtr, ATIHWPtr);
+
+#endif /* ___ATICLOCK_H___ */
diff --git a/driver/xf86-video-mach64/src/aticonfig.c b/driver/xf86-video-mach64/src/aticonfig.c
new file mode 100644
index 000000000..9102497fb
--- /dev/null
+++ b/driver/xf86-video-mach64/src/aticonfig.c
@@ -0,0 +1,506 @@
+/*
+ * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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.
+ *
+ * DRI support by:
+ * Leif Delgass <ldelgass@retinalburn.net>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include "ati.h"
+#include "atichip.h"
+#include "aticursor.h"
+#include "atioption.h"
+#include "atistruct.h"
+
+#include "mach64_common.h"
+
+#ifdef TV_OUT
+
+/*
+ * List of supported TV standard names
+ */
+const char *ATITVStandardNames[ATI_TV_STDS_MAX_VALID+1] = {
+ "NTSC",
+ "PAL",
+ "PAL-M",
+ "PAL-60",
+ "NTSC-J",
+ "PAL-CN",
+ "PAL-N",
+ "Reserved1",
+ "Reserved2",
+ "SCART-PAL",
+ "None",
+ "Invalid"
+};
+
+#endif /* TV_OUT */
+
+/*
+ * Recognised XF86Config options.
+ */
+static const OptionInfoRec ATIPublicOptions[] =
+{
+ {
+ ATI_OPTION_PROBE_SPARSE,
+ "probe_sparse",
+ OPTV_BOOLEAN,
+ {0, },
+ FALSE
+ },
+ {
+ 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,
+ },
+
+#ifdef XF86DRI_DEVEL
+
+ {
+ ATI_OPTION_IS_PCI,
+ "force_pci_mode",
+ OPTV_BOOLEAN,
+ {0, },
+ FALSE,
+ },
+ {
+ ATI_OPTION_DMA_MODE,
+ "dma_mode",
+ OPTV_STRING,
+ {0, },
+ FALSE,
+ },
+ {
+ ATI_OPTION_AGP_MODE,
+ "agp_mode",
+ OPTV_INTEGER,
+ {0, },
+ FALSE,
+ },
+ {
+ ATI_OPTION_AGP_SIZE,
+ "agp_size",
+ OPTV_INTEGER,
+ {0, },
+ FALSE,
+ },
+ {
+ ATI_OPTION_LOCAL_TEXTURES,
+ "local_textures",
+ OPTV_BOOLEAN,
+ {0, },
+ FALSE,
+ },
+ {
+ ATI_OPTION_BUFFER_SIZE,
+ "buffer_size",
+ OPTV_INTEGER,
+ {0, },
+ FALSE,
+ },
+
+#endif /* XF86DRI_DEVEL */
+
+#ifdef TV_OUT
+ {
+ ATI_OPTION_TV_OUT,
+ "tv_out",
+ OPTV_BOOLEAN,
+ {0, },
+ FALSE
+ },
+ {
+ ATI_OPTION_TV_STD,
+ "tv_standard",
+ OPTV_STRING,
+ {0, },
+ FALSE
+ },
+
+#endif /* TV_OUT */
+
+ {
+ 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_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,
+ },
+ {
+ ATI_OPTION_ACCELMETHOD,
+ "AccelMethod",
+ OPTV_STRING,
+ {0, },
+ FALSE
+ },
+ {
+ ATI_OPTION_RENDER_ACCEL,
+ "RenderAccel",
+ OPTV_BOOLEAN,
+ {0, },
+ FALSE
+ },
+ {
+ -1,
+ NULL,
+ OPTV_NONE,
+ {0, },
+ FALSE
+ }
+};
+
+static const unsigned long ATIPublicOptionSize = SizeOf(ATIPublicOptions);
+
+const OptionInfoRec *
+ATIOptionsWeak(void) { return ATIPublicOptions; }
+
+/*
+ * 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 ProbeSparse PublicOption[ATI_OPTION_PROBE_SPARSE].value.bool
+# 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
+
+#ifdef XF86DRI_DEVEL
+
+# define IsPCI PublicOption[ATI_OPTION_IS_PCI].value.bool
+# define DMAMode PublicOption[ATI_OPTION_DMA_MODE].value.str
+# define AGPMode PublicOption[ATI_OPTION_AGP_MODE].value.num
+# define AGPSize PublicOption[ATI_OPTION_AGP_SIZE].value.num
+# define LocalTex PublicOption[ATI_OPTION_LOCAL_TEXTURES].value.bool
+# define BufferSize PublicOption[ATI_OPTION_BUFFER_SIZE].value.num
+
+#endif /* XF86DRI_DEVEL */
+
+#ifdef TV_OUT
+
+# define TvOut PublicOption[ATI_OPTION_TV_OUT].value.bool
+# define TvStd PublicOption[ATI_OPTION_TV_STD].value.str
+
+#endif /* TV_OUT */
+
+# 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 ShadowFB PublicOption[ATI_OPTION_SHADOW_FB].value.bool
+# define SWCursor PublicOption[ATI_OPTION_SWCURSOR].value.bool
+# define AccelMethod PublicOption[ATI_OPTION_ACCELMETHOD].value.str
+# define RenderAccel PublicOption[ATI_OPTION_RENDER_ACCEL].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 */
+ Accel = CacheMMIO = HWCursor = TRUE;
+
+ ReferenceClock = ((double)157500000.0) / ((double)11.0);
+
+ ShadowFB = TRUE;
+
+ Blend = PanelDisplay = TRUE;
+
+#ifdef USE_EXA
+ RenderAccel = TRUE;
+#endif
+
+#ifdef XF86DRI_DEVEL
+ DMAMode = "async";
+#endif
+
+#ifdef TV_OUT
+ TvStd = "None"; /* No tv standard change requested */
+#endif
+
+ xf86ProcessOptions(pScreenInfo->scrnIndex, pScreenInfo->options,
+ PublicOption);
+ xf86ProcessOptions(pScreenInfo->scrnIndex, pScreenInfo->options,
+ PrivateOption);
+
+ /* Move option values into driver private structure */
+ pATI->OptionProbeSparse = ProbeSparse;
+ pATI->OptionAccel = Accel;
+ pATI->OptionBIOSDisplay = BIOSDisplay;
+ pATI->OptionBlend = Blend;
+ pATI->OptionCRTDisplay = CRTDisplay;
+ pATI->OptionCSync = CSync;
+ pATI->OptionDevel = Devel;
+
+#ifdef TV_OUT
+
+ if (TvOut && pATI->Chip < ATI_CHIP_264GT) {
+ /* Only allow this for 3D Rage (I) or greater chip ID
+ * AFAIK, no chips before this supported TV-Out
+ * mach64VT has support for TV tuner, but no TV-Out
+ */
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "TV Out not supported for this chip.\n");
+ } else {
+ ATITVStandard std;
+ pATI->OptionTvOut = TvOut;
+ pATI->OptionTvStd = ATI_TV_STD_INVALID;
+ for (std = 0; std < ATI_TV_STDS_MAX_VALID; std++) {
+ if (std != ATI_TV_STD_RESERVED1 && std != ATI_TV_STD_RESERVED2) {
+ if (strncasecmp(TvStd, ATITVStandardNames[std], ATI_TV_STDS_NAME_MAXLEN)==0) {
+ pATI->OptionTvStd = std;
+ break;
+ }
+ }
+ }
+ }
+
+#endif /* TV_OUT */
+
+ pATI->OptionMMIOCache = CacheMMIO;
+ pATI->OptionTestMMIOCache = TestCacheMMIO;
+ 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;
+
+#ifdef XF86DRI_DEVEL
+
+ pATI->OptionIsPCI = IsPCI;
+ pATI->OptionAGPMode = AGPMode;
+ pATI->OptionAGPSize = AGPSize;
+ pATI->OptionLocalTextures = LocalTex;
+ pATI->OptionBufferSize = BufferSize;
+
+ if (strcasecmp(DMAMode, "async")==0)
+ pATI->OptionDMAMode = MACH64_MODE_DMA_ASYNC;
+ else if (strcasecmp(DMAMode, "sync")==0)
+ pATI->OptionDMAMode = MACH64_MODE_DMA_SYNC;
+ else if (strcasecmp(DMAMode, "mmio")==0 )
+ pATI->OptionDMAMode = MACH64_MODE_MMIO;
+ else {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Unkown dma_mode: '%s'\n", DMAMode);
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Valid dma_mode options are: 'async','sync','mmio'\n");
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Defaulting to async DMA mode\n");
+ pATI->OptionDMAMode = MACH64_MODE_DMA_ASYNC;
+ }
+
+#endif /* XF86DRI_DEVEL */
+
+ /* 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;
+ }
+
+ pATI->refclk = (int)ReferenceClock;
+
+ pATI->useEXA = FALSE;
+ if (pATI->OptionAccel)
+ {
+ MessageType from = X_DEFAULT;
+#if defined(USE_EXA)
+#if defined(USE_XAA)
+ if (AccelMethod != NULL)
+ {
+ from = X_CONFIG;
+ if (xf86NameCmp(AccelMethod, "EXA") == 0)
+ pATI->useEXA = TRUE;
+ }
+#else /* USE_XAA */
+ pATI->useEXA = TRUE;
+#endif /* !USE_XAA */
+#endif /* USE_EXA */
+ xf86DrvMsg(pScreenInfo->scrnIndex, from,
+ "Using %s acceleration architecture\n",
+ pATI->useEXA ? "EXA" : "XAA");
+
+#if defined(USE_EXA)
+ if (pATI->useEXA && pATI->Chip >= ATI_CHIP_264GTPRO)
+ pATI->RenderAccelEnabled = TRUE;
+
+ if (pATI->useEXA && !RenderAccel)
+ pATI->RenderAccelEnabled = FALSE;
+#endif
+ }
+
+ xfree(PublicOption);
+}
diff --git a/driver/xf86-video-mach64/src/aticonsole.c b/driver/xf86-video-mach64/src/aticonsole.c
new file mode 100644
index 000000000..8efe897fb
--- /dev/null
+++ b/driver/xf86-video-mach64/src/aticonsole.c
@@ -0,0 +1,816 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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.
+ *
+ * DRI support by:
+ * Manuel Teira
+ * Leif Delgass <ldelgass@retinalburn.net>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "ati.h"
+#include "aticonsole.h"
+#include "atii2c.h"
+#include "atilock.h"
+#include "atimach64.h"
+#include "atimach64io.h"
+#include "atimode.h"
+#include "atistruct.h"
+#include "ativga.h"
+#include "atividmem.h"
+
+#ifdef XF86DRI_DEVEL
+#include "mach64_common.h"
+#include "atidri.h"
+#endif
+
+#ifdef TV_OUT
+
+#include "atichip.h"
+#include "atiprint.h"
+#include "atioption.h"
+#include "vbe.h"
+
+#endif /* TV_OUT */
+
+/*
+ * 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);
+ {
+ ATIMach64SaveScreen(pATI, Mode);
+ }
+
+ 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);
+
+ {
+ ATIMach64SetDPMSMode(pScreenInfo, pATI, DPMSMode);
+ }
+}
+
+#ifdef TV_OUT
+
+static void
+ATIProbeAndSetActiveDisplays
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI
+)
+{
+ vbeInfoPtr pVbe;
+ Bool tv_attached, crt_attached, lcd_attached;
+ int disp_request;
+ ATITVStandard tv_std, tv_std_request;
+
+ if (xf86GetVerbosity() > 3) {
+ xf86ErrorFVerb(4, "\n Before TV-Out queries\n\n");
+ ATIPrintRegisters(pATI);
+ }
+
+ pATI->tvActive = FALSE;
+ pVbe = pATI->pVBE;
+ if (pVbe) {
+ /* LT Pro, XL, Mobility specific BIOS functions */
+ if (pATI->Chip == ATI_CHIP_264LTPRO ||
+ pATI->Chip == ATI_CHIP_264XL ||
+ pATI->Chip == ATI_CHIP_MOBILITY) {
+
+ /* Get attached display(s) - LTPro, XL, Mobility */
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0xa083;
+ pVbe->pInt10->cx = 0x0700; /* ch=0x07 - probe all, 0x01 CRT, 0x02 TV, 0x04 LCD */
+ xf86ExecX86int10(pVbe->pInt10);
+
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "Attached displays: ax=0x%04x, cx=0x%04x\n",
+ pVbe->pInt10->ax, pVbe->pInt10->cx);
+
+ tv_attached = crt_attached = lcd_attached = FALSE;
+ if (pVbe->pInt10->ax & 0xff00) {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Failed to detect attached displays\n");
+ } else {
+
+ if (pVbe->pInt10->cx & 0x3)
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ " CRT attached\n");
+ crt_attached = TRUE;
+ }
+ else
+ crt_attached = FALSE;
+
+ if ((pVbe->pInt10->cx >> 2) & 0x3)
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ " DFP/LCD attached\n");
+ lcd_attached = TRUE;
+ }
+ else
+ lcd_attached = FALSE;
+
+ switch ((pVbe->pInt10->cx >> 4) & 0x3) {
+ case 0:
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ " No TV attached\n");
+ break;
+ case 1:
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ " TV attached (composite connector)\n");
+ tv_attached = TRUE;
+ break;
+ case 2:
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ " TV attached (S-video connector)\n");
+ tv_attached = TRUE;
+ break;
+ case 3:
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ " TV attached (S-video/composite connectors)\n");
+ tv_attached = TRUE;
+ break;
+ default:
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Unrecognized return code: 0x%04x\n",
+ pVbe->pInt10->cx);
+ }
+
+ }
+
+ /* Get active display - LTPro, XL, Mobility */
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0xa084;
+ pVbe->pInt10->bx = 0x0000; /* bh=0x00 get active, bh=0x01 set active */
+ xf86ExecX86int10(pVbe->pInt10);
+
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "Active displays: ax=0x%04x, bx=0x%04x, cx=0x%04x\n",
+ pVbe->pInt10->ax, pVbe->pInt10->bx, pVbe->pInt10->cx);
+
+ if (pVbe->pInt10->ax & 0xff00) {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Failed to detect active display\n");
+ } else {
+ if (pVbe->pInt10->bx & 0x1)
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ " DFP/LCD is active\n");
+
+ if (pVbe->pInt10->bx & 0x2)
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ " CRT is active\n");
+
+ if (pVbe->pInt10->bx & 0x4) {
+
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ " TV is active\n");
+
+ if (!tv_attached) {
+ /* tv not connected - disable tv */
+ disp_request = 0x00;
+ if (crt_attached)
+ disp_request |= 0x02; /* enable CRT */
+ if (lcd_attached && pATI->OptionPanelDisplay)
+ disp_request |= 0x01; /* enable DFP/LCD */
+
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0xa084;
+ pVbe->pInt10->bx = 0x0100; /* bh=0x01 set active */
+ pVbe->pInt10->cx = disp_request;
+ xf86ExecX86int10(pVbe->pInt10);
+
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "TV not present, disabling: ax=0x%04x, bx=0x%04x, cx=0x%04x\n",
+ pVbe->pInt10->ax, pVbe->pInt10->bx, pVbe->pInt10->cx);
+ if (pVbe->pInt10->ax & 0xff00) {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Disabling TV failed\n");
+ }
+ } else {
+ pATI->tvActive = TRUE;
+ }
+
+ } else if (tv_attached && (pVbe->pInt10->bx & 0x0400)) {
+ /* tv connected and available - enable TV */
+ disp_request = 0x04; /* enable TV */
+
+#if 0
+ /* This works, but CRT image is vertically compressed */
+ if (crt_attached)
+ disp_request |= 0x02; /* enable CRT */
+ /* NOTE: For me, LCD+TV does NOT work */
+ /*if (lcd_attached && pATI->OptionPanelDisplay)
+ disp_request |= 0x01; * enable DFP/LCD */
+#endif
+
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0xa084;
+ pVbe->pInt10->bx = 0x0100; /* bh=0x01 set active */
+ pVbe->pInt10->cx = disp_request; /* try to activate TV */
+ xf86ExecX86int10(pVbe->pInt10);
+
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "Setting TV active: ax=0x%04x, bx=0x%04x, cx=0x%04x\n",
+ pVbe->pInt10->ax, pVbe->pInt10->bx, pVbe->pInt10->cx);
+ if (pVbe->pInt10->ax & 0xff00) {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Setting TV active failed\n");
+ } else {
+ pATI->tvActive = TRUE;
+ }
+ }
+ }
+
+ } else { /* pATI->Chip < ATI_CHIP_264LTPRO */
+ /* TVOut Hooks - Check for TVOut BIOS/hardware */
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0xa019;
+ pVbe->pInt10->cx = 0x0000; /* TVOut BIOS query */
+ xf86ExecX86int10(pVbe->pInt10);
+
+ tv_attached = FALSE;
+
+ if (pVbe->pInt10->ax & 0xff00) {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Failed to detect TV-Out BIOS\n");
+ } else {
+ switch (pVbe->pInt10->ax & 0x0003) {
+ case 3:
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "TV-Out BIOS detected and active\n");
+
+ /* TV attached query */
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0xa070;
+ pVbe->pInt10->bx = 0x0002; /* Sub-function: return tv attached info */
+ xf86ExecX86int10(pVbe->pInt10);
+
+ if (pVbe->pInt10->ax & 0xff00) {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Failed to detect if TV is attached\n");
+ } else {
+ switch (pVbe->pInt10->cx & 0x0003) {
+ case 3:
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "TV attached to composite and S-video connectors\n");
+ tv_attached = TRUE;
+ break;
+ case 2:
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "TV attached to S-video connector\n");
+ tv_attached = TRUE;
+ break;
+ case 1:
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "TV attached to composite connector\n");
+ tv_attached = TRUE;
+ break;
+ default:
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "TV is not attached\n");
+ }
+ }
+ break;
+ case 1:
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "TV-Out BIOS service is not available due to"
+ "a system BIOS error or TV-Out hardware not being installed\n");
+ break;
+ default:
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "No TV-Out BIOS or hardware detected\n");
+ }
+ }
+ }
+
+ /* Return TV-Out configuration
+ * see Programmer's Guide under "TV Out Specific Functions"
+ * It's not clear exactly which adapters support these
+ */
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0xa070;
+ pVbe->pInt10->bx = 0x00;
+ xf86ExecX86int10(pVbe->pInt10);
+
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "TV-Out query: ax=0x%04x, bx=0x%04x, cx=0x%04x, dx=0x%04x\n",
+ pVbe->pInt10->ax, pVbe->pInt10->bx, pVbe->pInt10->cx, pVbe->pInt10->dx);
+
+ if (pVbe->pInt10->ax & 0xff00) {
+
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Failed to detect TV-Out configuration.\n");
+
+ } else if (pVbe->pInt10->bx == 0) {
+ if (pVbe->pInt10->dx == 0) {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "TV-Out is not detected.\n");
+ } else {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "TV-Out is detected but not supported.\n");
+ }
+
+ } else if ((pVbe->pInt10->cx & 0xff) == 0) {
+
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "TV-Out is currently disabled.\n");
+ if (tv_attached && pATI->Chip < ATI_CHIP_264LTPRO) {
+ /* Try to enable TV-Out */
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0xa070;
+ pVbe->pInt10->bx = 0x0001; /* Sub-function: Select TV Out */
+ /* cl=0x001 enable, cl=0x000 disable,
+ * cl=0x080 disable with feature connector bit preserved
+ */
+ pVbe->pInt10->cx = 0x0001;
+
+ xf86ExecX86int10(pVbe->pInt10);
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "Setting TV active: ax=0x%04x, bx=0x%04x, cx=0x%04x\n",
+ pVbe->pInt10->ax, pVbe->pInt10->bx, pVbe->pInt10->cx);
+
+ if (pVbe->pInt10->ax & 0xff00) {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Setting TV active failed\n");
+ } else {
+ pATI->tvActive = TRUE;
+ }
+ }
+
+ } else {
+ pATI->tvActive = TRUE;
+
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "TV-Out is currently enabled (TV-Out revision code: %d).\n",
+ (pVbe->pInt10->dx >> 8) & 0xff);
+
+ switch ((pVbe->pInt10->cx >> 8) & 0xff) {
+ case 0:
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, "Reference frequency 29.49892\n");
+ break;
+ case 1:
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, "Reference frequency 28.63636\n");
+ break;
+ case 2:
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, "Reference frequency 14.31818\n");
+ break;
+ case 3:
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, "Reference frequency 27.00000\n");
+ break;
+ default:
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Unknown reference frequency cx=0x%04x\n", pVbe->pInt10->cx);
+
+ }
+
+ /* Return TV standard
+ * see Programmer's Guide under "TV Out Specific Functions"
+ * It's not clear exactly which adapters support these
+ */
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0xa071;
+ pVbe->pInt10->bx = 0x00;
+ xf86ExecX86int10(pVbe->pInt10);
+
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "TV standard query result: ax=0x%04x, bx=0x%04x, cx=0x%04x\n",
+ pVbe->pInt10->ax, pVbe->pInt10->bx, pVbe->pInt10->cx);
+
+ if (pVbe->pInt10->ax & 0xff00) {
+
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Failed to return TV standard.\n");
+ } else {
+ tv_std = pVbe->pInt10->cx & 0x00ff;
+ switch (tv_std) {
+ case ATI_TV_STD_NTSC:
+ case ATI_TV_STD_PAL:
+ case ATI_TV_STD_PALM:
+ case ATI_TV_STD_PAL60:
+ case ATI_TV_STD_NTSCJ:
+ case ATI_TV_STD_PALCN:
+ case ATI_TV_STD_PALN:
+ case ATI_TV_STD_SCARTPAL:
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "Current TV standard: %s\n", ATITVStandardNames[tv_std]);
+ break;
+ default:
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Unrecognized TV standard return code cx=0x%04x\n",
+ pVbe->pInt10->cx);
+ }
+
+ tv_std_request = pATI->OptionTvStd;
+ if (tv_std_request < 0 ||
+ tv_std_request > ATI_TV_STD_NONE ||
+ tv_std_request == ATI_TV_STD_RESERVED1 ||
+ tv_std_request == ATI_TV_STD_RESERVED2) {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Invalid TV standard requested, please check configuration file\n");
+ } else if (tv_std_request != ATI_TV_STD_NONE) {
+ /* Set TV standard if requested (LT Pro not supported) */
+ if (pATI->Chip != ATI_CHIP_264LTPRO &&
+ tv_std_request != tv_std) {
+
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0xa070;
+ pVbe->pInt10->bx = 0x0003; /* sub-function: set TV standard */
+ pVbe->pInt10->cx = tv_std_request;
+ xf86ExecX86int10(pVbe->pInt10);
+ if (pVbe->pInt10->ax & 0xff00)
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Failed to set TV standard\n");
+ else
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_CONFIG,
+ "Set TV standard to %s\n", ATITVStandardNames[tv_std_request]);
+ } else {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Setting TV standard not supported on ATI Rage LT Pro\n");
+ }
+ }
+ }
+
+ }
+ } else {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, "VBE module not loaded\n");
+ }
+}
+
+#endif /* TV_OUT */
+
+/*
+ * 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;
+
+#ifdef TV_OUT
+ if (pATI->OptionTvOut) {
+
+ if (pATI->pVBE) {
+ if (VBEGetVBEMode(pATI->pVBE, &pATI->vbemode)) {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, "Saving VESA mode: 0x%x\n",
+ pATI->vbemode);
+ }
+ }
+ }
+#endif /* TV_OUT */
+
+ /* Save current state */
+ ATIModeSave(pScreenInfo, pATI, &pATI->OldHW);
+
+#ifdef TV_OUT
+ if (pATI->OptionTvOut)
+ ATIProbeAndSetActiveDisplays(pScreenInfo, pATI);
+#endif /* TV_OUT */
+
+ /* 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);
+
+#ifdef TV_OUT
+ if (pATI->OptionTvOut)
+ ATIProbeAndSetActiveDisplays(pScreenInfo, pATI);
+#endif /* TV_OUT */
+
+ /* 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;
+
+#ifdef XF86DRI_DEVEL
+
+ if (pATI->directRenderingEnabled)
+ {
+ DRILock(pScreenInfo->pScreen,0);
+ ATIDRIWaitForIdle(pATI);
+ }
+
+#endif /* XF86DRI_DEVEL */
+
+ /* XXX Workaround for X server not hiding the cursor for Xcursor (but
+ * only for core cursor), leaving a 64x64 garbage upper-left.
+ */
+ if (pATI->pCursorInfo)
+ (*pATI->pCursorInfo->HideCursor)(pScreenInfo);
+
+ ATIModeSet(pScreenInfo, pATI, &pATI->NewHW);
+
+#ifdef XF86DRI_DEVEL
+
+ if (pATI->directRenderingEnabled)
+ {
+ DRIUnlock(pScreenInfo->pScreen);
+ }
+
+#endif /* XF86DRI_DEVEL */
+
+ }
+
+ 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)
+ {
+
+#ifdef XF86DRI_DEVEL
+
+ if (pATI->directRenderingEnabled)
+ {
+ /* get the Mach64 back into shape after resume */
+ ATIDRIResume(pScreen);
+ DRIUnlock(pScreen);
+ }
+
+#endif /* XF86DRI_DEVEL */
+
+ return TRUE;
+ }
+
+ 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;
+ }
+
+#ifdef XF86DRI_DEVEL
+
+ if (pATI->directRenderingEnabled)
+ {
+ /* get the Mach64 back into shape after resume */
+ ATIDRIResume(pScreen);
+ DRIUnlock(pScreen);
+ }
+
+#endif /* XF86DRI_DEVEL */
+
+ 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];
+ ScreenPtr pScreen = pScreenInfo->pScreen;
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+#ifdef XF86DRI_DEVEL
+
+ if (pATI->directRenderingEnabled)
+ {
+ DRILock(pScreen,0);
+ ATIDRIWaitForIdle(pATI);
+ }
+
+#endif /* XF86DRI_DEVEL */
+
+ 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;
+}
diff --git a/driver/xf86-video-mach64/src/aticonsole.h b/driver/xf86-video-mach64/src/aticonsole.h
new file mode 100644
index 000000000..7e1084a57
--- /dev/null
+++ b/driver/xf86-video-mach64/src/aticonsole.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 "xf86str.h"
+
+extern Bool ATISaveScreen(ScreenPtr, int);
+extern void ATISetDPMSMode(ScrnInfoPtr, int, int);
+
+extern Bool ATIEnterGraphics(ScreenPtr, ScrnInfoPtr, ATIPtr);
+extern void ATILeaveGraphics(ScrnInfoPtr, ATIPtr);
+
+extern Bool ATISwitchMode(int, DisplayModePtr, int);
+
+extern Bool ATIEnterVT(int, int);
+extern void ATILeaveVT(int, int);
+
+extern void ATIFreeScreen(int, int);
+
+#endif /* ___ATICONSOLE_H___ */
diff --git a/driver/xf86-video-mach64/src/aticrtc.h b/driver/xf86-video-mach64/src/aticrtc.h
new file mode 100644
index 000000000..dd7ddd064
--- /dev/null
+++ b/driver/xf86-video-mach64/src/aticrtc.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 1997 through 2003 by Marc Aurele La France (TSI @ UQV), tsi@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___ */
diff --git a/driver/xf86-video-mach64/src/aticursor.h b/driver/xf86-video-mach64/src/aticursor.h
new file mode 100644
index 000000000..75bd44c65
--- /dev/null
+++ b/driver/xf86-video-mach64/src/aticursor.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2001 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 "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 ATIMach64CursorInit(ScreenPtr);
+
+#endif /* ___ATICURSOR_H___ */
diff --git a/driver/xf86-video-mach64/src/atidac.c b/driver/xf86-video-mach64/src/atidac.c
new file mode 100644
index 000000000..f94e8ad73
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atidac.c
@@ -0,0 +1,462 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include "ati.h"
+#include "atidac.h"
+#include "atimach64io.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;
+ }
+ }
+}
+
+/*
+ * 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 */
+
+}
+
+/*
+ * ATISetLUTEntry --
+ *
+ * This function is called to set one of a DAC's LUT entries.
+ */
+static void
+ATISetLUTEntry
+(
+ ATIPtr pATI,
+ int Index,
+ CARD8 *LUTEntry
+)
+{
+#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 */
+}
+
+/*
+ * 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, 0, SizeOf(fChanged));
+
+ 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])
+ ATISetLUTEntry(pATI, Index, LUTEntry);
+ }
+ }
+ 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)
+ ATISetLUTEntry(pATI, Index, LUTEntry);
+ }
+ }
+}
diff --git a/driver/xf86-video-mach64/src/atidac.h b/driver/xf86-video-mach64/src/atidac.h
new file mode 100644
index 000000000..ed0198c30
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atidac.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 "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(ATIPtr, ATICRTCType);
+
+#endif /* AVOID_CPIO */
+
+extern CARD8 ATIGetDACCmdReg(ATIPtr);
+
+extern void ATIDACPreInit(ScrnInfoPtr, ATIPtr, ATIHWPtr);
+extern void ATIDACSave(ATIPtr, ATIHWPtr);
+extern void ATIDACSet(ATIPtr, ATIHWPtr);
+
+extern void ATILoadPalette(ScrnInfoPtr, int, int *, LOCO *, VisualPtr);
+
+#endif /* ___ATIDAC_H___ */
diff --git a/driver/xf86-video-mach64/src/atidecoder.c b/driver/xf86-video-mach64/src/atidecoder.c
new file mode 100644
index 000000000..6419fbc28
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atidecoder.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#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)"
+};
diff --git a/driver/xf86-video-mach64/src/atidecoder.h b/driver/xf86-video-mach64/src/atidecoder.h
new file mode 100644
index 000000000..6ade55b90
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atidecoder.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2003 by Marc Aurele La France (TSI @ UQV), tsi@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___ */
diff --git a/driver/xf86-video-mach64/src/atidga.c b/driver/xf86-video-mach64/src/atidga.c
new file mode 100644
index 000000000..fb6d1d738
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atidga.c
@@ -0,0 +1,483 @@
+/*
+ * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 HAVE_CONFIG_H
+#include "config.h"
+#endif
+#ifndef AVOID_DGA
+
+#include <string.h>
+
+#include "ati.h"
+#include "atiadjust.h"
+#include "atichip.h"
+#include "atidac.h"
+#include "atidga.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);
+/*FIXME : use EXA if available */
+#ifdef USE_XAA
+ 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);
+#endif
+}
+
+/*
+ * 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);
+/*FIXME : use EXA if available */
+#ifdef USE_XAA
+ 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);
+#endif
+}
+
+/*
+ * 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);
+/*FIXME : use EXA if available */
+#ifdef USE_XAA
+ 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);
+#endif
+}
+
+/*
+ * 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;
+
+#ifdef USE_XAA
+ if (pATI->pXAAInfo)
+ pDGAMode->flags &= ~DGA_CONCURRENT_ACCESS;
+#endif
+ }
+ 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
+)
+{
+#ifdef USE_XAA
+ XAAInfoRecPtr pXAAInfo;
+#endif
+ int flags;
+
+ if (!pATI->nDGAMode)
+ {
+ /* Set up DGA callbacks */
+ pATI->ATIDGAFunctions.OpenFramebuffer = ATIDGAOpenFramebuffer;
+ pATI->ATIDGAFunctions.SetMode = ATIDGASetMode;
+ pATI->ATIDGAFunctions.SetViewport = ATIDGASetViewport;
+ pATI->ATIDGAFunctions.GetViewport = ATIDGAGetViewport;
+
+ flags = 0;
+#ifdef USE_XAA
+ 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;
+ }
+ }
+#endif
+ if (!flags)
+ flags = DGA_CONCURRENT_ACCESS;
+
+ ATIDGAAddModes(pScreenInfo, pATI, flags,
+ 8, 8, 0, 0, 0, PseudoColor);
+
+ if ((pATI->Chip >= ATI_CHIP_264CT))
+ {
+ 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 */
diff --git a/driver/xf86-video-mach64/src/atidga.h b/driver/xf86-video-mach64/src/atidga.h
new file mode 100644
index 000000000..bfc53f436
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atidga.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 "xf86str.h"
+
+extern Bool ATIDGAInit(ScreenPtr, ScrnInfoPtr, ATIPtr);
+
+#endif /* AVOID_DGA */
+
+#endif /* ___ATIDGA_H___ */
diff --git a/driver/xf86-video-mach64/src/atidri.c b/driver/xf86-video-mach64/src/atidri.c
new file mode 100644
index 000000000..15d00142f
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atidri.c
@@ -0,0 +1,1640 @@
+/* -*- mode: c; c-basic-offset: 3 -*- */
+/*
+ * Copyright 2000 Gareth Hughes
+ * 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
+ * GARETH HUGHES 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+/*
+ * Authors:
+ * Gareth Hughes <gareth@valinux.com>
+ * Leif Delgass <ldelgass@retinalburn.net>
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+
+/* Driver data structures */
+#include "ati.h"
+#include "atibus.h"
+#include "atidri.h"
+#include "atiregs.h"
+#include "atistruct.h"
+
+#include "atimach64io.h"
+#include "atimach64version.h"
+#include "mach64_dri.h"
+#include "mach64_common.h"
+#include "mach64_sarea.h"
+
+/* X and server generic header files */
+#include "xf86.h"
+#include "windowstr.h"
+
+/* GLX/DRI/DRM definitions */
+#define _XF86DRI_SERVER_
+#include "GL/glxtokens.h"
+#include "sarea.h"
+
+static char ATIKernelDriverName[] = "mach64";
+static char ATIClientDriverName[] = "mach64";
+
+/* Initialize the visual configs that are supported by the hardware.
+ * These are combined with the visual configs that the indirect
+ * rendering core supports, and the intersection is exported to the
+ * client.
+ */
+static Bool ATIInitVisualConfigs( ScreenPtr pScreen )
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ int numConfigs = 0;
+ __GLXvisualConfig *pConfigs = NULL;
+ ATIConfigPrivPtr pATIConfigs = NULL;
+ ATIConfigPrivPtr *pATIConfigPtrs = NULL;
+ int i, accum, stencil, db;
+
+ switch ( pATI->bitsPerPixel ) {
+ case 8: /* 8bpp mode is not support */
+ case 15: /* FIXME */
+ case 24: /* FIXME */
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[dri] ATIInitVisualConfigs failed (%d bpp not supported). "
+ "Disabling DRI.\n", pATI->bitsPerPixel);
+ return FALSE;
+
+#define ATI_USE_ACCUM 1
+#define ATI_USE_STENCIL 1
+
+ case 16:
+
+ if ( pATI->depth != 16) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[dri] ATIInitVisualConfigs failed (depth %d at 16 bpp not supported). "
+ "Disabling DRI.\n", pATI->depth);
+ return FALSE;
+ }
+
+ numConfigs = 1;
+ if ( ATI_USE_ACCUM ) numConfigs *= 2;
+ if ( ATI_USE_STENCIL ) numConfigs *= 2;
+ numConfigs *= 2; /* single- and double-buffered */
+
+ pConfigs = (__GLXvisualConfig*)
+ xnfcalloc( sizeof(__GLXvisualConfig), numConfigs );
+ if ( !pConfigs ) {
+ return FALSE;
+ }
+ pATIConfigs = (ATIConfigPrivPtr)
+ xnfcalloc( sizeof(ATIConfigPrivRec), numConfigs );
+ if ( !pATIConfigs ) {
+ xfree( pConfigs );
+ return FALSE;
+ }
+ pATIConfigPtrs = (ATIConfigPrivPtr*)
+ xnfcalloc( sizeof(ATIConfigPrivPtr), numConfigs );
+ if ( !pATIConfigPtrs ) {
+ xfree( pConfigs );
+ xfree( pATIConfigs );
+ return FALSE;
+ }
+
+ i = 0;
+ for (db = 1; db >= 0; db--) {
+ for ( accum = 0 ; accum <= ATI_USE_ACCUM ; accum++ ) {
+ for ( stencil = 0 ; stencil <= ATI_USE_STENCIL ; stencil++ ) {
+ pATIConfigPtrs[i] = &pATIConfigs[i];
+
+ pConfigs[i].vid = -1;
+ pConfigs[i].class = -1;
+ pConfigs[i].rgba = TRUE;
+ pConfigs[i].redSize = 5;
+ pConfigs[i].greenSize = 6;
+ pConfigs[i].blueSize = 5;
+ pConfigs[i].alphaSize = 0;
+ pConfigs[i].redMask = 0x0000F800;
+ pConfigs[i].greenMask = 0x000007E0;
+ pConfigs[i].blueMask = 0x0000001F;
+ pConfigs[i].alphaMask = 0x00000000;
+ if ( accum ) { /* Simulated in software */
+ pConfigs[i].accumRedSize = 16;
+ pConfigs[i].accumGreenSize = 16;
+ pConfigs[i].accumBlueSize = 16;
+ pConfigs[i].accumAlphaSize = 0;
+ } else {
+ pConfigs[i].accumRedSize = 0;
+ pConfigs[i].accumGreenSize = 0;
+ pConfigs[i].accumBlueSize = 0;
+ pConfigs[i].accumAlphaSize = 0;
+ }
+ pConfigs[i].doubleBuffer = db ? TRUE : FALSE;
+ pConfigs[i].stereo = FALSE;
+ pConfigs[i].bufferSize = 16;
+ pConfigs[i].depthSize = 16;
+ if ( stencil ) { /* Simulated in software */
+ pConfigs[i].stencilSize = 8;
+ } else {
+ pConfigs[i].stencilSize = 0;
+ }
+ pConfigs[i].auxBuffers = 0;
+ pConfigs[i].level = 0;
+ if ( accum || stencil ) {
+ pConfigs[i].visualRating = GLX_SLOW_CONFIG;
+ } else {
+ pConfigs[i].visualRating = GLX_NONE;
+ }
+ pConfigs[i].transparentPixel = GLX_NONE;
+ pConfigs[i].transparentRed = 0;
+ pConfigs[i].transparentGreen = 0;
+ pConfigs[i].transparentBlue = 0;
+ pConfigs[i].transparentAlpha = 0;
+ pConfigs[i].transparentIndex = 0;
+ i++;
+ }
+ }
+ }
+ break;
+
+ case 32:
+ numConfigs = 1;
+ if ( ATI_USE_ACCUM ) numConfigs *= 2;
+ if ( ATI_USE_STENCIL ) numConfigs *= 2;
+ numConfigs *= 2; /* single- and double-buffered */
+
+ pConfigs = (__GLXvisualConfig*)
+ xnfcalloc( sizeof(__GLXvisualConfig), numConfigs );
+ if ( !pConfigs ) {
+ return FALSE;
+ }
+ pATIConfigs = (ATIConfigPrivPtr)
+ xnfcalloc( sizeof(ATIConfigPrivRec), numConfigs );
+ if ( !pATIConfigs ) {
+ xfree( pConfigs );
+ return FALSE;
+ }
+ pATIConfigPtrs = (ATIConfigPrivPtr*)
+ xnfcalloc( sizeof(ATIConfigPrivPtr), numConfigs );
+ if ( !pATIConfigPtrs ) {
+ xfree( pConfigs );
+ xfree( pATIConfigs );
+ return FALSE;
+ }
+
+ i = 0;
+ for (db = 1; db >= 0; db--) {
+ for ( accum = 0 ; accum <= ATI_USE_ACCUM ; accum++ ) {
+ for ( stencil = 0 ; stencil <= ATI_USE_STENCIL ; stencil++ ) {
+ pATIConfigPtrs[i] = &pATIConfigs[i];
+
+ pConfigs[i].vid = -1;
+ pConfigs[i].class = -1;
+ pConfigs[i].rgba = TRUE;
+ pConfigs[i].redSize = 8;
+ pConfigs[i].greenSize = 8;
+ pConfigs[i].blueSize = 8;
+ pConfigs[i].alphaSize = 0;
+ pConfigs[i].redMask = 0x00FF0000;
+ pConfigs[i].greenMask = 0x0000FF00;
+ pConfigs[i].blueMask = 0x000000FF;
+ pConfigs[i].alphaMask = 0x00000000;
+ if ( accum ) { /* Simulated in software */
+ pConfigs[i].accumRedSize = 16;
+ pConfigs[i].accumGreenSize = 16;
+ pConfigs[i].accumBlueSize = 16;
+ pConfigs[i].accumAlphaSize = 0;
+ } else {
+ pConfigs[i].accumRedSize = 0;
+ pConfigs[i].accumGreenSize = 0;
+ pConfigs[i].accumBlueSize = 0;
+ pConfigs[i].accumAlphaSize = 0;
+ }
+ pConfigs[i].doubleBuffer = db ? TRUE : FALSE;
+ pConfigs[i].stereo = FALSE;
+ pConfigs[i].bufferSize = 24;
+ if ( stencil ) { /* Simulated in software */
+ pConfigs[i].depthSize = 16;
+ pConfigs[i].stencilSize = 8;
+ } else {
+ pConfigs[i].depthSize = 16;
+ pConfigs[i].stencilSize = 0;
+ }
+ pConfigs[i].auxBuffers = 0;
+ pConfigs[i].level = 0;
+ if ( accum || stencil ) {
+ pConfigs[i].visualRating = GLX_SLOW_CONFIG;
+ } else {
+ pConfigs[i].visualRating = GLX_NONE;
+ }
+ pConfigs[i].transparentPixel = GLX_NONE;
+ pConfigs[i].transparentRed = 0;
+ pConfigs[i].transparentGreen = 0;
+ pConfigs[i].transparentBlue = 0;
+ pConfigs[i].transparentAlpha = 0;
+ pConfigs[i].transparentIndex = 0;
+ i++;
+ }
+ }
+ }
+ break;
+ }
+
+ pATI->numVisualConfigs = numConfigs;
+ pATI->pVisualConfigs = pConfigs;
+ pATI->pVisualConfigsPriv = pATIConfigs;
+ GlxSetVisualConfigs( numConfigs, pConfigs, (void**)pATIConfigPtrs );
+ return TRUE;
+}
+
+/* Create the ATI-specific context information */
+static Bool ATICreateContext( ScreenPtr pScreen, VisualPtr visual,
+ drm_context_t hwContext, void *pVisualConfigPriv,
+ DRIContextType contextStore )
+{
+ /* Nothing yet */
+ return TRUE;
+}
+
+/* Destroy the ATI-specific context information */
+static void ATIDestroyContext( ScreenPtr pScreen, drm_context_t hwContext,
+ DRIContextType contextStore )
+{
+ /* Nothing yet */
+}
+
+/* Called when the X server is woken up to allow the last client's
+ * context to be saved and the X server's context to be loaded.
+ * The client detects when it's context is not currently loaded and
+ * then loads it itself. The X server's context is loaded in the
+ * XAA Sync callback if NeedDRISync is set.
+ */
+static void ATIEnterServer( ScreenPtr pScreen )
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ if ( pATI->directRenderingEnabled ) {
+ ATIDRIMarkSyncInt(pScreenInfo);
+ ATIDRIMarkSyncExt(pScreenInfo);
+ }
+}
+
+/* Called when the X server goes to sleep to allow the X server's
+ * context to be saved and the last client's context to be loaded.
+ * The client detects when it's context is not currently loaded and
+ * then loads it itself. The X server keeps track of it's own state.
+ */
+static void ATILeaveServer( ScreenPtr pScreen )
+{
+ /* Nothing yet */
+}
+
+/* Contexts can be swapped by the X server if necessary. This callback
+ * is currently only used to perform any functions necessary when
+ * entering or leaving the X server, and in the future might not be
+ * necessary.
+ */
+static void ATIDRISwapContext( ScreenPtr pScreen,
+ DRISyncType syncType,
+ DRIContextType oldContextType,
+ void *oldContext,
+ DRIContextType newContextType,
+ void *newContext )
+{
+ if ( ( syncType == DRI_3D_SYNC ) && ( oldContextType == DRI_2D_CONTEXT ) &&
+ ( newContextType == DRI_2D_CONTEXT ) ) {
+ /* Entering from Wakeup */
+ ATIEnterServer( pScreen );
+ }
+ if ( ( syncType == DRI_2D_SYNC ) && ( oldContextType == DRI_NO_CONTEXT ) &&
+ ( newContextType == DRI_2D_CONTEXT ) ) {
+ /* Exiting from Block Handler */
+ ATILeaveServer( pScreen );
+ }
+}
+
+#ifdef USE_XAA
+static void ATIDRITransitionTo2d(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ if (pATI->backArea) {
+ xf86FreeOffscreenArea(pATI->backArea);
+ pATI->backArea = NULL;
+ }
+ if (pATI->depthTexArea) {
+ xf86FreeOffscreenArea(pATI->depthTexArea);
+ pATI->depthTexArea = NULL;
+ }
+ pATI->have3DWindows = FALSE;
+}
+
+static void ATIDRITransitionTo3d(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ FBAreaPtr fbArea;
+ int width, height;
+
+ xf86PurgeUnlockedOffscreenAreas(pScreen);
+
+ xf86QueryLargestOffscreenArea(pScreen, &width, &height, 0, 0, 0);
+
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "Largest offscreen area available: %d x %d\n",
+ width, height);
+
+ fbArea = xf86AllocateOffscreenArea(pScreen, pScreenInfo->displayWidth,
+ height - pATI->depthTexLines -
+ pATI->backLines,
+ pScreenInfo->displayWidth, NULL, NULL, NULL);
+
+ if (!fbArea)
+ xf86DrvMsg(pScreen->myNum, X_ERROR, "Unable to reserve placeholder "
+ "offscreen area, you might experience screen corruption\n");
+
+ if (!pATI->backArea) {
+ pATI->backArea =
+ xf86AllocateOffscreenArea(pScreen, pScreenInfo->displayWidth,
+ pATI->backLines,
+ pScreenInfo->displayWidth,
+ NULL, NULL, NULL);
+ }
+ if (!pATI->backArea)
+ xf86DrvMsg(pScreen->myNum, X_ERROR, "Unable to reserve offscreen area "
+ "for back buffer, you might experience screen corruption\n");
+
+ if (!pATI->depthTexArea) {
+ pATI->depthTexArea =
+ xf86AllocateOffscreenArea(pScreen, pScreenInfo->displayWidth,
+ pATI->depthTexLines,
+ pScreenInfo->displayWidth,
+ NULL, NULL, NULL);
+ }
+ if (!pATI->depthTexArea)
+ xf86DrvMsg(pScreen->myNum, X_ERROR, "Unable to reserve offscreen area "
+ "for depth buffer and textures, you might experience screen corruption\n");
+
+ if (fbArea)
+ xf86FreeOffscreenArea(fbArea);
+
+ pATI->have3DWindows = TRUE;
+}
+#endif /* USE_XAA */
+
+#ifdef USE_EXA
+static void ATIDRITransitionTo2d_EXA(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
+
+ exaEnableDisableFBAccess(pScreen->myNum, FALSE);
+
+ pATI->pExa->offScreenBase = pATIDRIServer->backOffset;
+
+ exaEnableDisableFBAccess(pScreen->myNum, TRUE);
+
+ pATI->have3DWindows = FALSE;
+}
+
+static void ATIDRITransitionTo3d_EXA(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
+
+ exaEnableDisableFBAccess(pScreen->myNum, FALSE);
+
+ pATI->pExa->offScreenBase = pATIDRIServer->textureOffset +
+ pATIDRIServer->textureSize;
+
+ exaEnableDisableFBAccess(pScreen->myNum, TRUE);
+
+ pATI->have3DWindows = TRUE;
+}
+#endif /* USE_EXA */
+
+/* Initialize the state of the back and depth buffers. */
+static void ATIDRIInitBuffers( WindowPtr pWin, RegionPtr prgn, CARD32 indx )
+{
+#ifdef USE_XAA
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
+ XAAInfoRecPtr pXAAInfo = pATI->pXAAInfo;
+ BoxPtr pbox, pboxSave;
+ int nbox, nboxSave;
+ int depth;
+
+ depth = 0x0000ffff;
+
+ if (!pXAAInfo)
+ return;
+
+ if (!pXAAInfo->SetupForSolidFill)
+ return;
+
+ /* FIXME: Only initialize the back and depth buffers for contexts
+ that request them */
+
+ /* FIXME: Use drm clear? (see Radeon driver) */
+
+ pboxSave = pbox = REGION_RECTS(prgn);
+ nboxSave = nbox = REGION_NUM_RECTS(prgn);
+
+ (*pXAAInfo->SetupForSolidFill)(pScreenInfo, 0, GXcopy, (CARD32)(-1));
+ for (; nbox; nbox--, pbox++) {
+ (*pXAAInfo->SubsequentSolidFillRect)(pScreenInfo,
+ pbox->x1 + pATIDRIServer->fbX,
+ pbox->y1 + pATIDRIServer->fbY,
+ pbox->x2 - pbox->x1,
+ pbox->y2 - pbox->y1);
+ (*pXAAInfo->SubsequentSolidFillRect)(pScreenInfo,
+ pbox->x1 + pATIDRIServer->backX,
+ pbox->y1 + pATIDRIServer->backY,
+ pbox->x2 - pbox->x1,
+ pbox->y2 - pbox->y1);
+ }
+
+ pbox = pboxSave;
+ nbox = nboxSave;
+
+ (*pXAAInfo->SetupForSolidFill)(pScreenInfo, depth, GXcopy, (CARD32)(-1));
+ for (; nbox; nbox--, pbox++)
+ (*pXAAInfo->SubsequentSolidFillRect)(pScreenInfo,
+ pbox->x1 + pATIDRIServer->depthX,
+ pbox->y1 + pATIDRIServer->depthY,
+ pbox->x2 - pbox->x1,
+ pbox->y2 - pbox->y1);
+
+ ATIDRIMarkSyncInt(pScreenInfo);
+#endif
+}
+
+/* Copy the back and depth buffers when the X server moves a window.
+ *
+ * Note: this function was copied from the Radeon driver...
+ *
+ * This routine is a modified form of XAADoBitBlt with the calls to
+ * ScreenToScreenBitBlt built in. My routine has the prgnSrc as source
+ * instead of destination. My origin is upside down so the ydir cases
+ * are reversed.
+ */
+static void ATIDRIMoveBuffers( WindowPtr pWin, DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc, CARD32 indx )
+{
+#ifdef USE_XAA
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ XAAInfoRecPtr pXAAInfo = pATI->pXAAInfo;
+
+ int backOffsetPitch = (((pATI->pDRIServerInfo->backPitch/8) << 22) |
+ (pATI->pDRIServerInfo->backOffset >> 3));
+#if 0
+ int depthOffsetPitch = (((pATI->pDRIServerInfo->depthPitch/8) << 22) |
+ (pATI->pDRIServerInfo->depthOffset >> 3));
+#endif
+ BoxPtr pboxTmp, pboxNext, pboxBase;
+ DDXPointPtr pptTmp;
+ int xdir, ydir;
+
+ int screenwidth = pScreenInfo->virtualX;
+ int screenheight = pScreenInfo->virtualY;
+
+ BoxPtr pbox = REGION_RECTS(prgnSrc);
+ int nbox = REGION_NUM_RECTS(prgnSrc);
+
+ BoxPtr pboxNew1 = NULL;
+ BoxPtr pboxNew2 = NULL;
+ DDXPointPtr pptNew1 = NULL;
+ DDXPointPtr pptNew2 = NULL;
+ DDXPointPtr pptSrc = &ptOldOrg;
+
+ int dx = pWin->drawable.x - ptOldOrg.x;
+ int dy = pWin->drawable.y - ptOldOrg.y;
+
+ if (!pXAAInfo)
+ return;
+
+ if (!pXAAInfo->SetupForScreenToScreenCopy)
+ return;
+
+ /* FIXME: Only move the back and depth buffers for contexts
+ * that request them.
+ */
+
+ /* If the copy will overlap in Y, reverse the order */
+ if (dy > 0) {
+ ydir = -1;
+
+ if (nbox > 1) {
+ /* Keep ordering in each band, reverse order of bands */
+ pboxNew1 = (BoxPtr)xalloc(sizeof(BoxRec)*nbox);
+ if (!pboxNew1) return;
+ pptNew1 = (DDXPointPtr)xalloc(sizeof(DDXPointRec)*nbox);
+ if (!pptNew1) {
+ xfree(pboxNew1);
+ return;
+ }
+ pboxBase = pboxNext = pbox+nbox-1;
+ while (pboxBase >= pbox) {
+ while ((pboxNext >= pbox) && (pboxBase->y1 == pboxNext->y1))
+ pboxNext--;
+ pboxTmp = pboxNext+1;
+ pptTmp = pptSrc + (pboxTmp - pbox);
+ while (pboxTmp <= pboxBase) {
+ *pboxNew1++ = *pboxTmp++;
+ *pptNew1++ = *pptTmp++;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew1 -= nbox;
+ pbox = pboxNew1;
+ pptNew1 -= nbox;
+ pptSrc = pptNew1;
+ }
+ } else {
+ /* No changes required */
+ ydir = 1;
+ }
+
+ /* If the regions will overlap in X, reverse the order */
+ if (dx > 0) {
+ xdir = -1;
+
+ if (nbox > 1) {
+ /* reverse order of rects in each band */
+ pboxNew2 = (BoxPtr)xalloc(sizeof(BoxRec)*nbox);
+ pptNew2 = (DDXPointPtr)xalloc(sizeof(DDXPointRec)*nbox);
+ if (!pboxNew2 || !pptNew2) {
+ xfree(pptNew2);
+ xfree(pboxNew2);
+ xfree(pptNew1);
+ xfree(pboxNew1);
+ return;
+ }
+ pboxBase = pboxNext = pbox;
+ while (pboxBase < pbox+nbox) {
+ while ((pboxNext < pbox+nbox)
+ && (pboxNext->y1 == pboxBase->y1))
+ pboxNext++;
+ pboxTmp = pboxNext;
+ pptTmp = pptSrc + (pboxTmp - pbox);
+ while (pboxTmp != pboxBase) {
+ *pboxNew2++ = *--pboxTmp;
+ *pptNew2++ = *--pptTmp;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew2 -= nbox;
+ pbox = pboxNew2;
+ pptNew2 -= nbox;
+ pptSrc = pptNew2;
+ }
+ } else {
+ /* No changes are needed */
+ xdir = 1;
+ }
+
+ (*pXAAInfo->SetupForScreenToScreenCopy)(pScreenInfo, xdir, ydir, GXcopy,
+ (CARD32)(-1), -1);
+
+ for (; nbox-- ; pbox++) {
+ int xa = pbox->x1;
+ int ya = pbox->y1;
+ int destx = xa + dx;
+ int desty = ya + dy;
+ int w = pbox->x2 - xa + 1;
+ int h = pbox->y2 - ya + 1;
+
+ if (destx < 0) xa -= destx, w += destx, destx = 0;
+ if (desty < 0) ya -= desty, h += desty, desty = 0;
+ if (destx + w > screenwidth) w = screenwidth - destx;
+ if (desty + h > screenheight) h = screenheight - desty;
+
+ if (w <= 0) continue;
+ if (h <= 0) continue;
+
+ ATIMach64WaitForFIFO(pATI, 2);
+ outf(SRC_OFF_PITCH, backOffsetPitch);
+ outf(DST_OFF_PITCH, backOffsetPitch);
+
+ (*pXAAInfo->SubsequentScreenToScreenCopy)(pScreenInfo,
+ xa, ya,
+ destx, desty,
+ w, h);
+#if 0
+ /* FIXME: Move depth buffers? */
+ ATIMach64WaitForFIFO(pATI, 2);
+ outf(SRC_OFF_PITCH, depthOffsetPitch);
+ outf(DST_OFF_PITCH, depthOffsetPitch);
+
+ if (pATI->depthMoves)
+ ATIScreenToScreenCopyDepth(pScreenInfo,
+ xa, ya,
+ destx, desty,
+ w, h);
+#endif
+ }
+
+ ATIMach64WaitForFIFO(pATI, 2);
+ outf(SRC_OFF_PITCH, pATI->NewHW.dst_off_pitch);
+ outf(DST_OFF_PITCH, pATI->NewHW.src_off_pitch);
+
+ xfree(pptNew2);
+ xfree(pboxNew2);
+ xfree(pptNew1);
+ xfree(pboxNew1);
+
+ ATIDRIMarkSyncInt(pScreenInfo);
+#endif
+}
+
+/* Compute log base 2 of val. */
+static int Mach64MinBits(int val)
+{
+ int bits;
+
+ if (!val) return 1;
+ for (bits = 0; val; val >>= 1, ++bits);
+ return bits;
+}
+
+static Bool ATIDRISetBufSize( ScreenPtr pScreen, unsigned int maxSize )
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
+
+ if (pATI->OptionBufferSize) {
+ if (pATI->OptionBufferSize < 1 || pATI->OptionBufferSize > maxSize ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR, "[drm] Illegal DMA buffers size: %d MB\n",
+ pATI->OptionBufferSize );
+ return FALSE;
+ }
+ if (pATI->OptionBufferSize > 2) {
+ xf86DrvMsg( pScreen->myNum, X_WARNING, "[drm] Illegal DMA buffers size: %d MB\n",
+ pATI->OptionBufferSize );
+ xf86DrvMsg( pScreen->myNum, X_WARNING, "[drm] Clamping DMA buffers size to 2 MB\n");
+ pATIDRIServer->bufferSize = 2;
+ } else {
+ pATIDRIServer->bufferSize = pATI->OptionBufferSize;
+ xf86DrvMsg( pScreen->myNum, X_CONFIG, "[drm] Using %d MB for DMA buffers\n",
+ pATIDRIServer->bufferSize );
+ }
+ } else {
+ xf86DrvMsg( pScreen->myNum, X_DEFAULT, "[drm] Using %d MB for DMA buffers\n",
+ pATIDRIServer->bufferSize );
+ }
+
+ return TRUE;
+}
+
+static Bool ATIDRISetAgpMode( ScreenPtr pScreen )
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
+
+ unsigned long mode = drmAgpGetMode( pATI->drmFD ); /* Default mode */
+ unsigned int vendor = drmAgpVendorId( pATI->drmFD );
+ unsigned int device = drmAgpDeviceId( pATI->drmFD );
+
+ if (pATI->OptionAGPMode > 0 && pATI->OptionAGPMode <= ATI_AGP_MAX_MODE) {
+ pATIDRIServer->agpMode = pATI->OptionAGPMode;
+ xf86DrvMsg( pScreen->myNum, X_CONFIG, "[agp] Using AGP %dx Mode\n",
+ pATIDRIServer->agpMode );
+ } else if (pATI->OptionAGPMode > 0) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] Illegal AGP Mode: %d\n",
+ pATI->OptionAGPMode );
+ return FALSE;
+ } else {
+ /* If no mode configured, use the default mode obtained from agpgart */
+ if ( mode & AGP_MODE_2X ) {
+ pATIDRIServer->agpMode = 2;
+ } else if ( mode & AGP_MODE_1X ) {
+ pATIDRIServer->agpMode = 1;
+ }
+ xf86DrvMsg( pScreen->myNum, X_DEFAULT, "[agp] Using AGP %dx Mode\n",
+ pATIDRIServer->agpMode );
+ }
+
+ mode &= ~AGP_MODE_MASK;
+ switch ( pATIDRIServer->agpMode ) {
+ case 2: mode |= AGP_MODE_2X;
+ case 1: default: mode |= AGP_MODE_1X;
+ }
+
+ if (pATI->OptionAGPSize) {
+ switch (pATI->OptionAGPSize) {
+ case 128:
+ case 64:
+ case 32:
+ case 16:
+ case 8:
+ case 4:
+ pATIDRIServer->agpSize = pATI->OptionAGPSize;
+ xf86DrvMsg( pScreen->myNum, X_CONFIG, "[agp] Using %d MB AGP aperture\n",
+ pATIDRIServer->agpSize );
+ break;
+ default:
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[agp] Illegal aperture size %d MB\n", pATI->OptionAGPSize );
+ return FALSE;
+ }
+ } else {
+ xf86DrvMsg( pScreen->myNum, X_DEFAULT, "[agp] Using %d MB AGP aperture\n",
+ pATIDRIServer->agpSize );
+ }
+
+ xf86DrvMsg( pScreen->myNum, X_INFO,
+ "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n",
+ mode, vendor, device,
+ PCI_DEV_VENDOR_ID(pATI->PCIInfo),
+ PCI_DEV_DEVICE_ID(pATI->PCIInfo) );
+
+ if ( drmAgpEnable( pATI->drmFD, mode ) < 0 ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] AGP not enabled\n" );
+ drmAgpRelease( pATI->drmFD );
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Initialize the AGP state. Request memory for use in AGP space, and
+ * initialize the Rage Pro registers to point to that memory.
+ */
+static Bool ATIDRIAgpInit( ScreenPtr pScreen )
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
+
+ int ret;
+ unsigned long cntl;
+ int s, l;
+
+ pATIDRIServer->agpSize = ATI_DEFAULT_AGP_SIZE;
+ pATIDRIServer->agpMode = ATI_DEFAULT_AGP_MODE;
+ pATIDRIServer->bufferSize = ATI_DEFAULT_BUFFER_SIZE;
+ pATIDRIServer->ringSize = 16; /* 16 kB ring */
+
+ if ( drmAgpAcquire( pATI->drmFD ) < 0 ) {
+ xf86DrvMsg( pScreen->myNum, X_WARNING, "[agp] AGP not available\n" );
+ return FALSE;
+ }
+
+ if (!ATIDRISetAgpMode( pScreen ))
+ return FALSE;
+
+ pATIDRIServer->agpOffset = 0;
+
+ ret = drmAgpAlloc( pATI->drmFD, pATIDRIServer->agpSize*1024*1024,
+ 0, NULL, &pATIDRIServer->agpHandle );
+ if ( ret < 0 ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] Out of memory (%d)\n", ret );
+ drmAgpRelease( pATI->drmFD );
+ return FALSE;
+ }
+ xf86DrvMsg( pScreen->myNum, X_INFO,
+ "[agp] %d kB allocated with handle 0x%08x\n",
+ pATIDRIServer->agpSize*1024, pATIDRIServer->agpHandle );
+
+ if ( drmAgpBind( pATI->drmFD, pATIDRIServer->agpHandle, pATIDRIServer->agpOffset) < 0 ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] Could not bind\n" );
+ drmAgpFree( pATI->drmFD, pATIDRIServer->agpHandle );
+ drmAgpRelease( pATI->drmFD );
+ return FALSE;
+ }
+
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[agp] Using %d kB for DMA descriptor ring\n", pATIDRIServer->ringSize);
+
+ if ( !ATIDRISetBufSize( pScreen, pATIDRIServer->agpSize ) )
+ return FALSE;
+
+ pATIDRIServer->agpTexSize = pATIDRIServer->agpSize - pATIDRIServer->bufferSize;
+
+ /* Reserve space for the DMA descriptor ring */
+ pATIDRIServer->ringStart = pATIDRIServer->agpOffset;
+ pATIDRIServer->ringMapSize = pATIDRIServer->ringSize*1024; /* ringSize is in kB */
+
+ /* Reserve space for the vertex buffer */
+ pATIDRIServer->bufferStart = pATIDRIServer->ringStart + pATIDRIServer->ringMapSize;
+ pATIDRIServer->bufferMapSize = pATIDRIServer->bufferSize*1024*1024;
+
+ /* Reserve the rest for AGP textures */
+ pATIDRIServer->agpTexStart = pATIDRIServer->bufferStart + pATIDRIServer->bufferMapSize;
+ s = (pATIDRIServer->agpSize*1024*1024 - pATIDRIServer->agpTexStart);
+ l = Mach64MinBits((s-1) / MACH64_NR_TEX_REGIONS);
+ if (l < MACH64_LOG_TEX_GRANULARITY) l = MACH64_LOG_TEX_GRANULARITY;
+ pATIDRIServer->agpTexMapSize = (s >> l) << l;
+ pATIDRIServer->log2AGPTexGran = l;
+
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[agp] Using %d kB for AGP textures\n", pATIDRIServer->agpTexMapSize/1024);
+
+ /* Map DMA descriptor ring */
+ if ( drmAddMap( pATI->drmFD, pATIDRIServer->ringStart, pATIDRIServer->ringMapSize,
+ DRM_AGP, DRM_RESTRICTED, &pATIDRIServer->ringHandle ) < 0 ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[agp] Could not add ring mapping\n" );
+ return FALSE;
+ }
+ xf86DrvMsg( pScreen->myNum, X_INFO,
+ "[agp] ring handle = 0x%08x\n",
+ pATIDRIServer->ringHandle );
+
+ if ( drmMap( pATI->drmFD, pATIDRIServer->ringHandle,
+ pATIDRIServer->ringMapSize, &pATIDRIServer->ringMap ) < 0 ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[agp] Could not map ring\n" );
+ return FALSE;
+ }
+ xf86DrvMsg( pScreen->myNum, X_INFO,
+ "[agp] Ring mapped at 0x%08lx\n",
+ (unsigned long)pATIDRIServer->ringMap );
+
+ /* Map vertex buffers */
+ if ( drmAddMap( pATI->drmFD, pATIDRIServer->bufferStart, pATIDRIServer->bufferMapSize,
+ DRM_AGP, DRM_READ_ONLY, &pATIDRIServer->bufferHandle ) < 0 ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[agp] Could not add vertex buffers mapping\n" );
+ return FALSE;
+ }
+ xf86DrvMsg( pScreen->myNum, X_INFO,
+ "[agp] vertex buffers handle = 0x%08x\n",
+ pATIDRIServer->bufferHandle );
+
+ if ( drmMap( pATI->drmFD, pATIDRIServer->bufferHandle,
+ pATIDRIServer->bufferMapSize, &pATIDRIServer->bufferMap ) < 0 ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[agp] Could not map vertex buffers\n" );
+ return FALSE;
+ }
+ xf86DrvMsg( pScreen->myNum, X_INFO,
+ "[agp] Vertex buffers mapped at 0x%08lx\n",
+ (unsigned long)pATIDRIServer->bufferMap );
+
+ /* Map AGP Textures */
+ if (drmAddMap(pATI->drmFD, pATIDRIServer->agpTexStart, pATIDRIServer->agpTexMapSize,
+ DRM_AGP, 0, &pATIDRIServer->agpTexHandle) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[agp] Could not add AGP texture region mapping\n");
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[agp] AGP texture region handle = 0x%08x\n",
+ pATIDRIServer->agpTexHandle);
+
+ if (drmMap(pATI->drmFD, pATIDRIServer->agpTexHandle, pATIDRIServer->agpTexMapSize,
+ &pATIDRIServer->agpTexMap) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[agp] Could not map AGP texture region\n");
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[agp] AGP Texture region mapped at 0x%08lx\n",
+ (unsigned long)pATIDRIServer->agpTexMap);
+
+ /* Initialize Mach64's AGP registers */
+ cntl = inm( AGP_CNTL );
+ cntl &= ~AGP_APER_SIZE_MASK;
+ switch ( pATIDRIServer->agpSize ) {
+ case 256: cntl |= AGP_APER_SIZE_256MB; break;
+ case 128: cntl |= AGP_APER_SIZE_128MB; break;
+ case 64: cntl |= AGP_APER_SIZE_64MB; break;
+ case 32: cntl |= AGP_APER_SIZE_32MB; break;
+ case 16: cntl |= AGP_APER_SIZE_16MB; break;
+ case 8: cntl |= AGP_APER_SIZE_8MB; break;
+ case 4: cntl |= AGP_APER_SIZE_4MB; break;
+ default:
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[agp] Illegal aperture size %d kB\n",
+ pATIDRIServer->agpSize*1024 );
+ return FALSE;
+ }
+
+ /* 1 = DATA comes in clock in which TRDY sampled (default) */
+ /* 0 = DATA comes in clock after TRDY sampled */
+ cntl |= AGP_TRDY_MODE;
+
+ /* 1 = generate all reads as high priority */
+ /* 0 = generate all reads as their default priority (default) */
+ /* Setting this only works for me at AGP 1x mode (LLD) */
+ if (pATIDRIServer->agpMode == 1) {
+ cntl |= HIGH_PRIORITY_READ_EN;
+ } else {
+ cntl &= ~HIGH_PRIORITY_READ_EN;
+ }
+
+ outm( AGP_BASE, drmAgpBase(pATI->drmFD) );
+ outm( AGP_CNTL, cntl );
+
+ return TRUE;
+}
+
+static Bool ATIDRIPciInit( ScreenPtr pScreen )
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
+
+ pATIDRIServer->bufferSize = ATI_DEFAULT_BUFFER_SIZE;
+ pATIDRIServer->ringSize = 16; /* 16 kB ring */
+
+ if ( !ATIDRISetBufSize( pScreen, (unsigned)(-1) ) )
+ return FALSE;
+
+ /* Set size of the DMA descriptor ring */
+ pATIDRIServer->ringStart = 0;
+ pATIDRIServer->ringMapSize = pATIDRIServer->ringSize*1024; /* ringSize is in kB */
+
+ /* Set size of the vertex buffer */
+ pATIDRIServer->bufferStart = 0;
+ pATIDRIServer->bufferMapSize = pATIDRIServer->bufferSize*1024*1024;
+
+ /* Map DMA descriptor ring */
+ if ( drmAddMap( pATI->drmFD, 0, pATIDRIServer->ringMapSize,
+ DRM_CONSISTENT, DRM_RESTRICTED, &pATIDRIServer->ringHandle ) < 0 ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[pci] Could not add ring mapping\n" );
+ return FALSE;
+ }
+ xf86DrvMsg( pScreen->myNum, X_INFO, "[pci] ring handle = 0x%08x\n",
+ pATIDRIServer->ringHandle );
+
+ if ( drmMap( pATI->drmFD, pATIDRIServer->ringHandle,
+ pATIDRIServer->ringMapSize, &pATIDRIServer->ringMap ) < 0 ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[pci] Could not map ring\n" );
+ return FALSE;
+ }
+ xf86DrvMsg( pScreen->myNum, X_INFO,
+ "[pci] Ring mapped at 0x%08lx\n",
+ (unsigned long)pATIDRIServer->ringMap );
+
+ /* Disable AGP for ForcePCIMode */
+ if ( pATI->BusType != ATI_BUS_PCI ) {
+ outm( AGP_BASE, 0 );
+ outm( AGP_CNTL, 0 );
+ }
+
+ return TRUE;
+}
+
+/* Add a map for the MMIO registers that will be accessed by any
+ * DRI-based clients.
+ */
+static Bool ATIDRIMapInit( ScreenPtr pScreen )
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
+
+ pATIDRIServer->regsSize = getpagesize();
+ if ( drmAddMap( pATI->drmFD, pATI->Block1Base,
+ pATIDRIServer->regsSize,
+ DRM_REGISTERS, DRM_READ_ONLY,
+ &pATIDRIServer->regsHandle ) < 0 ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[drm] failed to map registers\n" );
+ return FALSE;
+ }
+ xf86DrvMsg( pScreen->myNum, X_INFO,
+ "[drm] register handle = 0x%08x\n",
+ pATIDRIServer->regsHandle );
+
+ return TRUE;
+}
+
+/* Initialize the kernel data structures. */
+static Bool ATIDRIKernelInit( ScreenPtr pScreen )
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
+ drmMach64Init info;
+
+ memset( &info, 0, sizeof(drmMach64Init) );
+
+ info.func = DRM_MACH64_INIT_DMA;
+ info.sarea_priv_offset = sizeof(XF86DRISAREARec);
+ info.is_pci = pATIDRIServer->IsPCI;
+ info.dma_mode = pATI->OptionDMAMode;
+
+ info.fb_bpp = pATI->bitsPerPixel;
+ info.front_offset = pATIDRIServer->frontOffset;
+ info.front_pitch = pATIDRIServer->frontPitch;
+ info.back_offset = pATIDRIServer->backOffset;
+ info.back_pitch = pATIDRIServer->backPitch;
+
+ info.depth_bpp = 16;
+ info.depth_offset = pATIDRIServer->depthOffset;
+ info.depth_pitch = pATIDRIServer->depthPitch;
+
+ info.fb_offset = pATI->LinearBase;
+ info.mmio_offset = pATIDRIServer->regsHandle;
+ info.ring_offset = pATIDRIServer->ringHandle;
+ info.buffers_offset = pATIDRIServer->bufferHandle;
+ info.agp_textures_offset = pATIDRIServer->agpTexHandle;
+
+ if ( drmCommandWrite( pATI->drmFD, DRM_MACH64_INIT,
+ &info, sizeof(drmMach64Init) ) < 0 ) {
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+}
+
+/* Add a map for the DMA buffers that will be accessed by any
+ * DRI-based clients.
+ */
+static Bool ATIDRIAddBuffers( ScreenPtr pScreen )
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
+
+ /* Initialize vertex buffers */
+ if ( pATIDRIServer->IsPCI ) {
+ pATIDRIServer->numBuffers = drmAddBufs( pATI->drmFD,
+ pATIDRIServer->bufferMapSize/MACH64_BUFFER_SIZE,
+ MACH64_BUFFER_SIZE,
+ DRM_PCI_BUFFER_RO,
+ 0 );
+ } else {
+ pATIDRIServer->numBuffers = drmAddBufs( pATI->drmFD,
+ pATIDRIServer->bufferMapSize/MACH64_BUFFER_SIZE,
+ MACH64_BUFFER_SIZE,
+ DRM_AGP_BUFFER,
+ pATIDRIServer->bufferStart );
+ }
+ if ( pATIDRIServer->numBuffers <= 0 ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[drm] Could not create DMA buffers list\n" );
+ return FALSE;
+ }
+ xf86DrvMsg( pScreen->myNum, X_INFO,
+ "[drm] Added %d %d byte DMA buffers\n",
+ pATIDRIServer->numBuffers, MACH64_BUFFER_SIZE );
+
+ return TRUE;
+}
+
+static Bool ATIDRIMapBuffers( ScreenPtr pScreen )
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
+
+ pATIDRIServer->drmBuffers = drmMapBufs( pATI->drmFD );
+ if ( !pATIDRIServer->drmBuffers ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[drm] Failed to map DMA buffers list\n" );
+ return FALSE;
+ }
+ xf86DrvMsg( pScreen->myNum, X_INFO,
+ "[drm] Mapped %d DMA buffers at 0x%08lx\n",
+ pATIDRIServer->drmBuffers->count,
+ (unsigned long)pATIDRIServer->drmBuffers->list->address );
+
+ return TRUE;
+}
+
+static Bool ATIDRIIrqInit( ScreenPtr pScreen )
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ if ( pATI->irq <= 0 ) {
+ pATI->irq = drmGetInterruptFromBusID(pATI->drmFD,
+ PCI_CFG_BUS(pATI->PCIInfo),
+ PCI_CFG_DEV(pATI->PCIInfo),
+ PCI_CFG_FUNC(pATI->PCIInfo));
+ if ( pATI->irq <= 0 ) {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "[drm] Couldn't find IRQ for bus id %d:%d:%d\n",
+ PCI_CFG_BUS(pATI->PCIInfo),
+ PCI_CFG_DEV(pATI->PCIInfo),
+ PCI_CFG_FUNC(pATI->PCIInfo));
+ pATI->irq = 0;
+ } else if ((drmCtlInstHandler(pATI->drmFD, pATI->irq)) != 0) {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "[drm] Failed to initialize interrupt handler with IRQ %d\n",
+ pATI->irq);
+ pATI->irq = 0;
+ }
+
+ if (pATI->irq)
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "[drm] Installed interrupt handler, using IRQ %d\n",
+ pATI->irq);
+ else {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "[drm] Falling back to irq-free operation\n");
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+
+}
+
+/* Initialize the screen-specific data structures for the DRI and the
+ * Rage Pro. This is the main entry point to the device-specific
+ * initialization code. It calls device-independent DRI functions to
+ * create the DRI data structures and initialize the DRI state.
+ */
+Bool ATIDRIScreenInit( ScreenPtr pScreen )
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ DRIInfoPtr pDRIInfo;
+ ATIDRIPtr pATIDRI;
+ ATIDRIServerInfoPtr pATIDRIServer;
+ drmVersionPtr version;
+ int major, minor, patch;
+
+ /* Check that the GLX, DRI, and DRM modules have been loaded by testing
+ * for known symbols in each module.
+ */
+ if ( !xf86LoaderCheckSymbol("GlxSetVisualConfigs") ) return FALSE;
+ if ( !xf86LoaderCheckSymbol("drmAvailable") ) return FALSE;
+ if ( !xf86LoaderCheckSymbol("DRIQueryVersion") ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[dri] ATIDRIScreenInit failed (libdri.a too old)\n" );
+ return FALSE;
+ }
+
+ /* Check the DRI version */
+ DRIQueryVersion( &major, &minor, &patch );
+ if ( major != DRIINFO_MAJOR_VERSION || minor < 0 ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[dri] ATIDRIScreenInit failed because of a version mismatch.\n"
+ "[dri] libdri version is %d.%d.%d but version %d.%d.x is needed.\n"
+ "[dri] Disabling the DRI.\n",
+ major, minor, patch,
+ DRIINFO_MAJOR_VERSION, 0 );
+ return FALSE;
+ }
+
+ switch ( pATI->bitsPerPixel ) {
+ case 8:
+ /* These modes are not supported (yet). */
+ case 15:
+ case 24:
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[dri] Direct rendering only supported in 16 and 32 bpp modes\n");
+ return FALSE;
+
+ /* Only 16 and 32 color depths are supported currently. */
+ case 16:
+ if ( pATI->depth != 16) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[dri] Direct rendering not supported for depth %d at fbbpp 16.\n", pATI->depth );
+ return FALSE;
+ }
+ break;
+ case 32:
+ break;
+ }
+
+ /* Create the DRI data structure, and fill it in before calling the
+ * DRIScreenInit().
+ */
+ pDRIInfo = DRICreateInfoRec();
+ if ( !pDRIInfo ) return FALSE;
+
+ pATI->pDRIInfo = pDRIInfo;
+ pDRIInfo->drmDriverName = ATIKernelDriverName;
+ pDRIInfo->clientDriverName = ATIClientDriverName;
+ if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) {
+ pDRIInfo->busIdString = DRICreatePCIBusID(pATI->PCIInfo);
+ } else {
+ pDRIInfo->busIdString = xalloc( 64 );
+ sprintf( pDRIInfo->busIdString,
+ "PCI:%d:%d:%d",
+ PCI_DEV_BUS(pATI->PCIInfo),
+ PCI_DEV_DEV(pATI->PCIInfo),
+ PCI_DEV_FUNC(pATI->PCIInfo) );
+ }
+ pDRIInfo->ddxDriverMajorVersion = MACH64_VERSION_MAJOR;
+ pDRIInfo->ddxDriverMinorVersion = MACH64_VERSION_MINOR;
+ pDRIInfo->ddxDriverPatchVersion = MACH64_VERSION_PATCH;
+ pDRIInfo->frameBufferPhysicalAddress = (void *)pATI->LinearBase;
+ pDRIInfo->frameBufferSize = pATI->LinearSize;
+ pDRIInfo->frameBufferStride = (pScreenInfo->displayWidth *
+ pATI->FBBytesPerPixel);
+ pDRIInfo->ddxDrawableTableEntry = ATI_MAX_DRAWABLES;
+
+ if ( SAREA_MAX_DRAWABLES < ATI_MAX_DRAWABLES ) {
+ pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES;
+ } else {
+ pDRIInfo->maxDrawableTableEntry = ATI_MAX_DRAWABLES;
+ }
+
+ /* For now the mapping works by using a fixed size defined
+ * in the SAREA header
+ */
+ if ( sizeof(XF86DRISAREARec) + sizeof(ATISAREAPrivRec) > SAREA_MAX ) {
+ ErrorF( "[dri] Data does not fit in SAREA\n" );
+ return FALSE;
+ }
+ xf86DrvMsg( pScreenInfo->scrnIndex, X_INFO, "[drm] SAREA %u+%u: %u\n",
+ (unsigned)sizeof(XF86DRISAREARec),
+ (unsigned)sizeof(ATISAREAPrivRec),
+ (unsigned)(sizeof(XF86DRISAREARec) + sizeof(ATISAREAPrivRec)) );
+ pDRIInfo->SAREASize = SAREA_MAX;
+
+ pATIDRI = (ATIDRIPtr) xnfcalloc( sizeof(ATIDRIRec), 1 );
+ if ( !pATIDRI ) {
+ DRIDestroyInfoRec( pATI->pDRIInfo );
+ pATI->pDRIInfo = NULL;
+ xf86DrvMsg( pScreenInfo->scrnIndex, X_ERROR,
+ "[dri] Failed to allocate memory for private record\n" );
+ return FALSE;
+ }
+ pATIDRIServer = (ATIDRIServerInfoPtr)
+ xnfcalloc( sizeof(ATIDRIServerInfoRec), 1 );
+ if ( !pATIDRIServer ) {
+ xfree( pATIDRI );
+ DRIDestroyInfoRec( pATI->pDRIInfo );
+ pATI->pDRIInfo = NULL;
+ xf86DrvMsg( pScreenInfo->scrnIndex, X_ERROR,
+ "[dri] Failed to allocate memory for private record\n" );
+ return FALSE;
+ }
+
+ pATI->pDRIServerInfo = pATIDRIServer;
+
+ pDRIInfo->devPrivate = pATIDRI;
+ pDRIInfo->devPrivateSize = sizeof(ATIDRIRec);
+ pDRIInfo->contextSize = sizeof(ATIDRIContextRec);
+
+ pDRIInfo->CreateContext = ATICreateContext;
+ pDRIInfo->DestroyContext = ATIDestroyContext;
+ pDRIInfo->SwapContext = ATIDRISwapContext;
+ pDRIInfo->InitBuffers = ATIDRIInitBuffers;
+ pDRIInfo->MoveBuffers = ATIDRIMoveBuffers;
+#ifdef USE_XAA
+ if (!pATI->useEXA) {
+ pDRIInfo->TransitionTo2d = ATIDRITransitionTo2d;
+ pDRIInfo->TransitionTo3d = ATIDRITransitionTo3d;
+ }
+#endif /* USE_XAA */
+#ifdef USE_EXA
+ if (pATI->useEXA) {
+ pDRIInfo->TransitionTo2d = ATIDRITransitionTo2d_EXA;
+ pDRIInfo->TransitionTo3d = ATIDRITransitionTo3d_EXA;
+ }
+#endif /* USE_EXA */
+ pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
+
+ pDRIInfo->createDummyCtx = TRUE;
+ pDRIInfo->createDummyCtxPriv = FALSE;
+
+ pATI->have3DWindows = FALSE;
+
+ if ( !DRIScreenInit( pScreen, pDRIInfo, &pATI->drmFD ) ) {
+ xfree( pATIDRIServer );
+ pATI->pDRIServerInfo = NULL;
+ xfree( pDRIInfo->devPrivate );
+ pDRIInfo->devPrivate = NULL;
+ DRIDestroyInfoRec( pDRIInfo );
+ pDRIInfo = NULL;
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[dri] DRIScreenInit Failed\n" );
+ return FALSE;
+ }
+
+ /* Check the DRM lib version.
+ drmGetLibVersion was not supported in version 1.0, so check for
+ symbol first to avoid possible crash or hang.
+ */
+ if (xf86LoaderCheckSymbol("drmGetLibVersion")) {
+ version = drmGetLibVersion(pATI->drmFD);
+ } else {
+ /* drmlib version 1.0.0 didn't have the drmGetLibVersion
+ entry point. Fake it by allocating a version record
+ via drmGetVersion and changing it to version 1.0.0
+ */
+ version = drmGetVersion(pATI->drmFD);
+ version->version_major = 1;
+ version->version_minor = 0;
+ version->version_patchlevel = 0;
+ }
+
+ if (version) {
+ if (version->version_major != 1 ||
+ version->version_minor < 1) {
+ /* incompatible drm library version */
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[dri] ATIDRIScreenInit failed because of a version mismatch.\n"
+ "[dri] libdrm.a module version is %d.%d.%d but version 1.1.x is needed.\n"
+ "[dri] Disabling DRI.\n",
+ version->version_major,
+ version->version_minor,
+ version->version_patchlevel);
+ drmFreeVersion(version);
+ ATIDRICloseScreen(pScreen);
+ return FALSE;
+ }
+ drmFreeVersion(version);
+ }
+
+ /* Check the mach64 DRM version */
+ version = drmGetVersion( pATI->drmFD );
+ if ( version ) {
+ if ( version->version_major != 2 ||
+ version->version_minor < 0 ) {
+ /* Incompatible DRM version */
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[dri] ATIDRIScreenInit failed because of a version mismatch.\n"
+ "[dri] mach64.o kernel module version is %d.%d.%d, but version 2.x is needed (with 2.x >= 2.0).\n"
+ "[dri] Disabling DRI.\n",
+ version->version_major,
+ version->version_minor,
+ version->version_patchlevel );
+ drmFreeVersion( version );
+ ATIDRICloseScreen( pScreen );
+ return FALSE;
+ }
+ drmFreeVersion( version );
+ }
+
+ switch ( pATI->OptionDMAMode ) {
+ case MACH64_MODE_DMA_ASYNC:
+ xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Will request asynchronous DMA mode\n");
+ break;
+ case MACH64_MODE_DMA_SYNC:
+ xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Will request synchronous DMA mode\n");
+ break;
+ case MACH64_MODE_MMIO:
+ xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Will request pseudo-DMA (MMIO) mode\n");
+ break;
+ default:
+ xf86DrvMsg(pScreen->myNum, X_WARNING, "[drm] Unknown DMA mode\n");
+ }
+
+ pATIDRIServer->IsPCI = (pATI->BusType == ATI_BUS_PCI || pATI->OptionIsPCI) ? TRUE : FALSE;
+
+ if ( pATI->BusType != ATI_BUS_PCI && pATI->OptionIsPCI ) {
+ xf86DrvMsg(pScreen->myNum, X_CONFIG, "[dri] Forcing PCI mode\n");
+ }
+
+ /* Initialize AGP */
+ if ( !pATIDRIServer->IsPCI && !ATIDRIAgpInit( pScreen ) ) {
+ pATIDRIServer->IsPCI = TRUE;
+ xf86DrvMsg( pScreen->myNum, X_WARNING, "[agp] AGP failed to initialize -- falling back to PCI mode.\n" );
+ xf86DrvMsg( pScreen->myNum, X_WARNING, "[agp] Make sure you have the agpgart kernel module loaded.\n" );
+ }
+
+ /* Initialize PCI */
+ if ( pATIDRIServer->IsPCI && !ATIDRIPciInit( pScreen ) ) {
+ ATIDRICloseScreen( pScreen );
+ return FALSE;
+ }
+
+ if ( !ATIDRIMapInit( pScreen ) ) {
+ ATIDRICloseScreen( pScreen );
+ return FALSE;
+ }
+
+ if ( !ATIInitVisualConfigs( pScreen ) ) {
+ ATIDRICloseScreen( pScreen );
+ return FALSE;
+ }
+ xf86DrvMsg( pScreenInfo->scrnIndex, X_INFO,
+ "[dri] Visual configs initialized\n" );
+
+ xf86DrvMsg( pScreenInfo->scrnIndex, X_INFO,
+ "[dri] Block 0 base at 0x%08lx\n", pATI->Block0Base );
+
+ return TRUE;
+}
+
+/* Finish initializing the device-dependent DRI state, and call
+ * DRIFinishScreenInit() to complete the device-independent DRI
+ * initialization.
+ */
+Bool ATIDRIFinishScreenInit( ScreenPtr pScreen )
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ ATISAREAPrivPtr pSAREAPriv;
+ ATIDRIPtr pATIDRI;
+ ATIDRIServerInfoPtr pATIDRIServer;
+
+ pATI->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT;
+
+ /* NOTE: DRIFinishScreenInit must be called before *DRIKernelInit
+ * because *DRIKernelInit requires that the hardware lock is held by
+ * the X server, and the first time the hardware lock is grabbed is
+ * in DRIFinishScreenInit.
+ */
+ if ( !DRIFinishScreenInit( pScreen ) ) {
+ ATIDRICloseScreen( pScreen );
+ return FALSE;
+ }
+
+ /* Initialize the DMA buffer list */
+ /* Need to do this before ATIDRIKernelInit so we can init the freelist */
+ if ( !ATIDRIAddBuffers( pScreen ) ) {
+ ATIDRICloseScreen( pScreen );
+ return FALSE;
+ }
+
+ /* Initialize the kernel data structures */
+ if ( !ATIDRIKernelInit( pScreen ) ) {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "[drm] Failed to initialize the mach64.o kernel module\n");
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "[drm] Check the system log for more information.\n");
+ ATIDRICloseScreen( pScreen );
+ return FALSE;
+ }
+
+ if ( !ATIDRIMapBuffers( pScreen ) ) {
+ ATIDRICloseScreen( pScreen );
+ return FALSE;
+ }
+
+ /* Initialize IRQ */
+ ATIDRIIrqInit( pScreen );
+
+ pSAREAPriv = (ATISAREAPrivPtr) DRIGetSAREAPrivate( pScreen );
+ memset( pSAREAPriv, 0, sizeof(*pSAREAPriv) );
+
+ pATIDRI = (ATIDRIPtr)pATI->pDRIInfo->devPrivate;
+ pATIDRIServer = pATI->pDRIServerInfo;
+
+ pATIDRI->width = pScreenInfo->virtualX;
+ pATIDRI->height = pScreenInfo->virtualY;
+ pATIDRI->mem = pScreenInfo->videoRam * 1024;
+ pATIDRI->cpp = pScreenInfo->bitsPerPixel / 8;
+
+ pATIDRI->IsPCI = pATIDRIServer->IsPCI;
+ pATIDRI->AGPMode = pATIDRIServer->agpMode;
+
+ pATIDRI->frontOffset = pATIDRIServer->frontOffset;
+ pATIDRI->frontPitch = pATIDRIServer->frontPitch;
+
+ pATIDRI->backOffset = pATIDRIServer->backOffset;
+ pATIDRI->backPitch = pATIDRIServer->backPitch;
+
+ pATIDRI->depthOffset = pATIDRIServer->depthOffset;
+ pATIDRI->depthPitch = pATIDRIServer->depthPitch;
+
+ pATIDRI->textureOffset = pATIDRIServer->textureOffset;
+ pATIDRI->textureSize = pATIDRIServer->textureSize;
+ pATIDRI->logTextureGranularity = pATIDRIServer->logTextureGranularity;
+
+ pATIDRI->regs = pATIDRIServer->regsHandle;
+ pATIDRI->regsSize = pATIDRIServer->regsSize;
+
+ pATIDRI->agp = pATIDRIServer->agpTexHandle;
+ pATIDRI->agpSize = pATIDRIServer->agpTexMapSize;
+ pATIDRI->logAgpTextureGranularity = pATIDRIServer->log2AGPTexGran;
+ pATIDRI->agpTextureOffset = pATIDRIServer->agpTexStart;
+
+ return TRUE;
+}
+
+/*
+ * This function will attempt to get the Mach64 hardware back into shape
+ * after a resume from disc. Its an extract from ATIDRIAgpInit and ATIDRIFinishScreenInit
+ * This also calls a new ioctl in the mach64 DRM that in its turn is
+ * an extraction of the hardware-affecting bits from mach64_do_init_drm()
+ * (see atidrm.c)
+ * I am assuming here that pATI->pDRIServerInfo doesn't change
+ * elsewhere in incomaptible ways.
+ * How will this code react to resuming after a failed resumeor pci based dri ?
+ */
+void ATIDRIResume( ScreenPtr pScreen )
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
+
+ xf86DrvMsg( pScreen->myNum, X_INFO,
+ "[RESUME] Attempting to re-init Mach64 hardware.\n");
+
+ if (!pATIDRIServer->IsPCI) {
+ if (!ATIDRISetAgpMode(pScreen))
+ return;
+
+ outm( AGP_BASE, drmAgpBase(pATI->drmFD) );
+ }
+}
+
+/* The screen is being closed, so clean up any state and free any
+ * resources used by the DRI.
+ */
+void ATIDRICloseScreen( ScreenPtr pScreen )
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
+ drmMach64Init info;
+
+ /* Stop interrupt generation and handling if used */
+ if ( pATI->irq > 0 ) {
+ if ( drmCtlUninstHandler(pATI->drmFD) != 0 ) {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "[drm] Error uninstalling interrupt handler for IRQ %d\n", pATI->irq);
+ } else {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "[drm] Uninstalled interrupt handler for IRQ %d\n", pATI->irq);
+ }
+ pATI->irq = 0;
+ }
+
+ /* De-allocate DMA buffers */
+ if ( pATIDRIServer->drmBuffers ) {
+ drmUnmapBufs( pATIDRIServer->drmBuffers );
+ pATIDRIServer->drmBuffers = NULL;
+ }
+
+ /* De-allocate all kernel resources */
+ memset(&info, 0, sizeof(drmMach64Init));
+ info.func = DRM_MACH64_CLEANUP_DMA;
+ drmCommandWrite( pATI->drmFD, DRM_MACH64_INIT,
+ &info, sizeof(drmMach64Init) );
+
+ /* De-allocate all AGP resources */
+ if ( pATIDRIServer->agpTexMap ) {
+ drmUnmap( pATIDRIServer->agpTexMap, pATIDRIServer->agpTexMapSize );
+ pATIDRIServer->agpTexMap = NULL;
+ }
+ if ( pATIDRIServer->bufferMap ) {
+ drmUnmap( pATIDRIServer->bufferMap, pATIDRIServer->bufferMapSize );
+ pATIDRIServer->bufferMap = NULL;
+ }
+ if ( pATIDRIServer->ringMap ) {
+ drmUnmap( pATIDRIServer->ringMap, pATIDRIServer->ringMapSize );
+ pATIDRIServer->ringMap = NULL;
+ }
+ if ( pATIDRIServer->agpHandle ) {
+ drmAgpUnbind( pATI->drmFD, pATIDRIServer->agpHandle );
+ drmAgpFree( pATI->drmFD, pATIDRIServer->agpHandle );
+ pATIDRIServer->agpHandle = 0;
+ drmAgpRelease( pATI->drmFD );
+ }
+
+ /* De-allocate all PCI resources */
+ if ( pATIDRIServer->IsPCI && pATIDRIServer->ringHandle ) {
+ drmRmMap( pATI->drmFD, pATIDRIServer->ringHandle );
+ pATIDRIServer->ringHandle = 0;
+ }
+
+ /* De-allocate all DRI resources */
+ DRICloseScreen( pScreen );
+
+ /* De-allocate all DRI data structures */
+ if ( pATI->pDRIInfo ) {
+ if ( pATI->pDRIInfo->devPrivate ) {
+ xfree( pATI->pDRIInfo->devPrivate );
+ pATI->pDRIInfo->devPrivate = NULL;
+ }
+ DRIDestroyInfoRec( pATI->pDRIInfo );
+ pATI->pDRIInfo = NULL;
+ }
+ if ( pATI->pDRIServerInfo ) {
+ xfree( pATI->pDRIServerInfo );
+ pATI->pDRIServerInfo = NULL;
+ }
+ if ( pATI->pVisualConfigs ) {
+ xfree( pATI->pVisualConfigs );
+ pATI->pVisualConfigs = NULL;
+ }
+ if ( pATI->pVisualConfigsPriv ) {
+ xfree( pATI->pVisualConfigsPriv );
+ pATI->pVisualConfigsPriv = NULL;
+ }
+}
diff --git a/driver/xf86-video-mach64/src/atidri.h b/driver/xf86-video-mach64/src/atidri.h
new file mode 100644
index 000000000..52d4b44ad
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atidri.h
@@ -0,0 +1,49 @@
+/* -*- mode: c; c-basic-offset: 3 -*- */
+/*
+ * Copyright 2000 Gareth Hughes
+ * 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
+ * GARETH HUGHES 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:
+ * Gareth Hughes <gareth@valinux.com>
+ * Leif Delgass <ldelgass@retinalburn.net>
+ */
+
+#ifndef __ATIDRI_H__
+#define __ATIDRI_H__ 1
+
+/* DRI driver defaults */
+#define ATI_DEFAULT_AGP_SIZE 8 /* MB (must be a power of 2 and > 4MB) */
+#define ATI_DEFAULT_AGP_MODE 1
+#define ATI_DEFAULT_BUFFER_SIZE 2 /* MB (must be page aligned) */
+
+#define ATI_AGP_MAX_MODE 2
+
+/* Imported from the radeon suspend code writen by cpbotha@ieee.org
+ * to enable suspend/resume support for the mach64 card.
+ */
+extern void ATIDRIResume(ScreenPtr pScreen);
+extern Bool ATIDRIScreenInit(ScreenPtr);
+extern Bool ATIDRIFinishScreenInit(ScreenPtr);
+extern void ATIDRICloseScreen(ScreenPtr);
+
+#endif /* __ATIDRI_H__ */
diff --git a/driver/xf86-video-mach64/src/atidripriv.h b/driver/xf86-video-mach64/src/atidripriv.h
new file mode 100644
index 000000000..28c3ac613
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atidripriv.h
@@ -0,0 +1,57 @@
+/* -*- mode: c; c-basic-offset: 3 -*- */
+/*
+ * 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:
+ * Gareth Hughes <gareth@valinux.com>
+ * Leif Delgass <ldelgass@retinalburn.net>
+ */
+
+#ifndef __ATIDRIPRIV_H__
+#define __ATIDRIPRIV_H__ 1
+
+#include "GL/glxint.h"
+#include "GL/glxtokens.h"
+
+#define ATI_MAX_DRAWABLES 256
+
+typedef struct {
+ /* Nothing here yet */
+ int dummy;
+} ATIConfigPrivRec, *ATIConfigPrivPtr;
+
+typedef struct {
+ /* Nothing here yet */
+ int dummy;
+} ATIDRIContextRec, *ATIDRIContextPtr;
+
+extern void GlxSetVisualConfigs(int, __GLXvisualConfig *, void **);
+
+#endif /* __ATIDRIPRIV_H__ */
diff --git a/driver/xf86-video-mach64/src/atidsp.c b/driver/xf86-video-mach64/src/atidsp.c
new file mode 100644
index 000000000..adea2cdc2
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atidsp.c
@@ -0,0 +1,302 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "ati.h"
+#include "atichip.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;
+
+ {
+ Divider *= pATI->bitsPerPixel / 4;
+ }
+
+ /* Start by assuming a display FIFO width of 64 bits */
+ vshift = (6 - 2) - pATI->XCLKPostDivider;
+
+ 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 */
+ {
+ 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);
+}
diff --git a/driver/xf86-video-mach64/src/atidsp.h b/driver/xf86-video-mach64/src/atidsp.h
new file mode 100644
index 000000000..adf533ca4
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atidsp.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 "xf86str.h"
+
+extern Bool ATIDSPPreInit(int, ATIPtr);
+extern void ATIDSPSave(ATIPtr, ATIHWPtr);
+extern void ATIDSPCalculate(ATIPtr, ATIHWPtr, DisplayModePtr);
+extern void ATIDSPSet(ATIPtr, ATIHWPtr);
+
+#endif /* ___ATIDSP_H___ */
diff --git a/driver/xf86-video-mach64/src/atii2c.c b/driver/xf86-video-mach64/src/atii2c.c
new file mode 100644
index 000000000..a13d64771
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atii2c.c
@@ -0,0 +1,399 @@
+/*
+ * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "atii2c.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)
+
+
+/*
+ * ATII2CStart --
+ *
+ * This function puts a start signal on the I2C bus.
+ */
+static Bool
+ATII2CStart
+(
+ I2CBusPtr pI2CBus,
+ int timeout
+)
+{
+ ATII2CPtr pATII2C = pI2CBus->DriverPrivate.ptr;
+ ATIPtr pATI = pATII2C->pATI;
+
+ (void)timeout;
+
+ /*
+ * 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;
+
+ return TRUE;
+}
+
+/*
+ * ATII2CAddress --
+ *
+ * This function puts an 8-bit address on the I2C bus.
+ */
+static Bool
+ATII2CAddress
+(
+ I2CDevPtr pI2CDev,
+ I2CSlaveAddr Address
+)
+{
+ I2CBusPtr pI2CBus = pI2CDev->pI2CBus;
+
+ /* 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->I2CStart = ATII2CStart;
+ 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
+)
+{
+ if (!xf86LoadSubModule(pScreenInfo, "i2c"))
+ return;
+
+ ATIMach64I2CPreInit(pScreenInfo, pATI);
+}
+
+/*
+ * 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);
+}
diff --git a/driver/xf86-video-mach64/src/atii2c.h b/driver/xf86-video-mach64/src/atii2c.h
new file mode 100644
index 000000000..ba3494e51
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atii2c.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 "xf86str.h"
+
+#include "xf86i2c.h"
+
+typedef struct _ATII2CRec ATII2CRec, *ATII2CPtr;
+
+struct _ATII2CRec
+{
+ ATIPtr pATI;
+ void (*I2CSetBits) (ATII2CPtr, ATIPtr, CARD32);
+ CARD32 (*I2CGetBits) (ATIPtr);
+ CARD32 SCLDir, SCLGet, SCLSet;
+ CARD32 SDADir, SDAGet, SDASet;
+ CARD32 I2CCur;
+};
+
+extern void ATII2CPreInit(ScrnInfoPtr, ATIPtr);
+extern I2CBusPtr ATICreateI2CBusRec(int, ATIPtr, char *);
+extern void ATII2CFreeScreen(int);
+
+#endif /* ___ATII2C_H___ */
diff --git a/driver/xf86-video-mach64/src/atiload.c b/driver/xf86-video-mach64/src/atiload.c
new file mode 100644
index 000000000..621b0b073
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atiload.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "ati.h"
+#include "aticursor.h"
+#include "atiload.h"
+#include "atistruct.h"
+
+/*
+ * ATILoadModules --
+ *
+ * This function loads other modules required for a screen.
+ */
+pointer
+ATILoadModules
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI
+)
+{
+ pointer fbPtr = NULL;
+
+ /* Load shadow frame buffer code if needed */
+ if (pATI->OptionShadowFB &&
+ !xf86LoadSubModule(pScreenInfo, "shadowfb"))
+ return NULL;
+
+ /* Load depth-specific entry points */
+ switch (pATI->bitsPerPixel)
+ {
+ case 8:
+ case 16:
+ case 24:
+ case 32:
+ fbPtr = xf86LoadSubModule(pScreenInfo, "fb");
+ break;
+
+ default:
+ return NULL;
+ }
+ if (!fbPtr)
+ return NULL;
+
+ /* Load ramdac module if needed */
+ if ((pATI->Cursor > ATI_CURSOR_SOFTWARE) &&
+ !xf86LoadSubModule(pScreenInfo, "ramdac"))
+ return NULL;
+
+#ifdef USE_EXA
+ /* Load EXA if needed */
+ if (pATI->useEXA && pATI->OptionAccel)
+ {
+ XF86ModReqInfo req;
+ int errmaj, errmin;
+
+ memset(&req, 0, sizeof(XF86ModReqInfo));
+ req.majorversion = 2;
+ req.minorversion = 0;
+ if (!LoadSubModule(pScreenInfo->module, "exa", NULL, NULL, NULL, &req,
+ &errmaj, &errmin))
+ {
+ LoaderErrorMsg(NULL, "exa", errmaj, errmin);
+ return NULL;
+ }
+ }
+#endif
+#ifdef USE_XAA
+ /* Load XAA if needed */
+ if (!pATI->useEXA && pATI->OptionAccel &&
+ !xf86LoadSubModule(pScreenInfo, "xaa"))
+ return NULL;
+#endif
+
+ return fbPtr;
+}
diff --git a/driver/xf86-video-mach64/src/atiload.h b/driver/xf86-video-mach64/src/atiload.h
new file mode 100644
index 000000000..168224c79
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atiload.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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
+
+#include "atipriv.h"
+
+#include "xf86str.h"
+
+extern pointer ATILoadModules(ScrnInfoPtr, ATIPtr);
+
+#endif /* ___ATILOAD_H___ */
diff --git a/driver/xf86-video-mach64/src/atilock.c b/driver/xf86-video-mach64/src/atilock.c
new file mode 100644
index 000000000..ba7008775
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atilock.c
@@ -0,0 +1,537 @@
+/*
+ * Copyright 1999 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "ati.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;
+
+ {
+ /* 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);
+
+#ifdef XF86DRI_DEVEL
+
+ if (pATI->irq > 0)
+ outr(CRTC_INT_CNTL, (inr(CRTC_INT_CNTL) & ~CRTC_INT_ACKS) |
+ CRTC_VBLANK_INT_EN); /* Enable VBLANK interrupt - handled by DRM */
+
+#endif /* XF86DRI_DEVEL */
+
+ 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))
+ {
+#ifdef TV_OUT
+ pATI->LockData.scratch_reg3 = inr(SCRATCH_REG3) & ~DISPLAY_SWITCH_DISABLE;
+ outr(SCRATCH_REG3, pATI->LockData.scratch_reg3);
+#else
+ pATI->LockData.scratch_reg3 = inr(SCRATCH_REG3);
+ outr(SCRATCH_REG3,
+ pATI->LockData.scratch_reg3 | DISPLAY_SWITCH_DISABLE);
+#endif /* TV_OUT */
+ }
+ }
+
+ 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)
+ {
+ 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);
+ {
+ pATI->LockData.be = ATIGetExtReg(0xBEU);
+ ATIModifyExtReg(pATI, 0xBEU, pATI->LockData.be, 0xFAU, 0x01U);
+ {
+ 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 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)
+ {
+ 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);
+ {
+ ATIModifyExtReg(pATI, 0xBEU, -1, 0xFAU, pATI->LockData.be);
+ {
+ ATIModifyExtReg(pATI, 0xA6U, -1, 0x7FU, pATI->LockData.a6);
+ ATIModifyExtReg(pATI, 0xABU, -1, 0xE7U, pATI->LockData.ab);
+ }
+ }
+ ATIModifyExtReg(pATI, 0xB8U, -1, 0xC0U, pATI->LockData.b8);
+ }
+ }
+
+#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);
+#ifndef TV_OUT
+ if (!pATI->OptionBIOSDisplay && (pATI->Chip != ATI_CHIP_264XL))
+ outr(SCRATCH_REG3, pATI->LockData.scratch_reg3);
+#endif /* TV_OUT */
+ }
+ if (pATI->Chip >= ATI_CHIP_264VTB)
+ {
+ outr(MPP_CONFIG, pATI->LockData.mpp_config);
+ outr(MPP_STROBE_SEQ, pATI->LockData.mpp_strobe_seq);
+#ifndef TV_OUT
+ outr(TVO_CNTL, pATI->LockData.tvo_cntl);
+#endif /* TV_OUT */
+ 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);
+ }
+ }
+ }
+ }
+}
diff --git a/driver/xf86-video-mach64/src/atilock.h b/driver/xf86-video-mach64/src/atilock.h
new file mode 100644
index 000000000..9ded601a2
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atilock.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 1999 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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"
+
+extern void ATIUnlock(ATIPtr);
+extern void ATILock(ATIPtr);
+
+#endif /* ___ATILOCK_H___ */
diff --git a/driver/xf86-video-mach64/src/atimach64.c b/driver/xf86-video-mach64/src/atimach64.c
new file mode 100644
index 000000000..c7b0ecc2c
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atimach64.c
@@ -0,0 +1,1341 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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.
+ */
+/*
+ * DRI support by:
+ * Manuel Teira
+ * Leif Delgass <ldelgass@retinalburn.net>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include "ati.h"
+#include "atibus.h"
+#include "atichip.h"
+#include "atidac.h"
+#include "atimach64.h"
+#include "atimach64accel.h"
+#include "atimach64io.h"
+#include "atirgb514.h"
+
+#ifndef DPMS_SERVER
+# define DPMS_SERVER
+#endif
+#include <X11/extensions/dpms.h>
+
+/*
+ * ATIMach64PreInit --
+ *
+ * This function fills in the Mach64 portion of an ATIHWRec that is common to
+ * all video modes generated by the driver.
+ */
+void
+ATIMach64PreInit
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI,
+ ATIHWPtr pATIHW
+)
+{
+ if ((pATI->LockData.crtc_gen_cntl & CRTC_CSYNC_EN) && !pATI->OptionCSync)
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_NOTICE,
+ "Using composite sync to match input timing.\n");
+ pATI->OptionCSync = TRUE;
+ }
+
+ pATIHW->bus_cntl = inr(BUS_CNTL);
+ if (pATI->Chip < ATI_CHIP_264VT4)
+ pATIHW->bus_cntl = (pATIHW->bus_cntl & ~BUS_HOST_ERR_INT_EN) |
+ BUS_HOST_ERR_INT;
+ if (pATI->Chip < ATI_CHIP_264VTB)
+ {
+ pATIHW->bus_cntl &= ~(BUS_FIFO_ERR_INT_EN | BUS_ROM_DIS);
+ pATIHW->bus_cntl |= SetBits(15, BUS_FIFO_WS) | BUS_FIFO_ERR_INT;
+ }
+ else if (pATI->MMIOInLinear)
+ {
+ pATIHW->bus_cntl &= ~BUS_APER_REG_DIS;
+ }
+ else
+ {
+ pATIHW->bus_cntl |= BUS_APER_REG_DIS;
+ }
+ if (pATI->Chip >= ATI_CHIP_264VT)
+ pATIHW->bus_cntl |= BUS_EXT_REG_EN; /* Enable Block 1 */
+
+#ifdef AVOID_CPIO
+
+ pATIHW->mem_vga_wp_sel = SetBits(0, MEM_VGA_WPS0) |
+ SetBits(1, MEM_VGA_WPS1);
+ pATIHW->mem_vga_rp_sel = SetBits(0, MEM_VGA_RPS0) |
+ SetBits(1, MEM_VGA_RPS1);
+
+#else /* AVOID_CPIO */
+
+ pATIHW->mem_vga_wp_sel = SetBits(0, MEM_VGA_WPS0) |
+ SetBits(pATIHW->nPlane, MEM_VGA_WPS1);
+ pATIHW->mem_vga_rp_sel = SetBits(0, MEM_VGA_RPS0) |
+ SetBits(pATIHW->nPlane, MEM_VGA_RPS1);
+
+#endif /* AVOID_CPIO */
+
+ pATIHW->dac_cntl = inr(DAC_CNTL) &
+ ~(DAC1_CLK_SEL | DAC_PALETTE_ACCESS_CNTL | DAC_8BIT_EN);
+ if (pATI->Chip >= ATI_CHIP_264CT)
+ pATIHW->dac_cntl &= ~DAC_FEA_CON_EN;
+ if (pATI->rgbBits == 8)
+ pATIHW->dac_cntl |= DAC_8BIT_EN;
+
+ pATIHW->gen_test_cntl = pATI->LockData.gen_test_cntl & ~GEN_CUR_EN;
+ if (pATI->DAC == ATI_DAC_IBMRGB514)
+ pATIHW->gen_test_cntl |= GEN_OVR_OUTPUT_EN;
+
+ pATIHW->config_cntl = inr(CONFIG_CNTL);
+
+#ifndef AVOID_CPIO
+
+ if (pATI->VGAAdapter)
+ {
+ pATIHW->config_cntl |= CFG_MEM_VGA_AP_EN;
+ }
+ else
+
+#endif /* AVOID_CPIO */
+
+ {
+ pATIHW->config_cntl &= ~CFG_MEM_VGA_AP_EN;
+ }
+
+ if ((pATI->Chip < ATI_CHIP_264CT))
+ {
+ /* Replace linear aperture size and address */
+ pATIHW->config_cntl &= ~(CFG_MEM_AP_LOC | CFG_MEM_AP_SIZE);
+ pATIHW->config_cntl |= SetBits(pATI->LinearBase >> 22, CFG_MEM_AP_LOC);
+ if ((pATI->Chip < ATI_CHIP_264CT) && (pATI->VideoRAM < 4096))
+ pATIHW->config_cntl |= SetBits(1, CFG_MEM_AP_SIZE);
+ else
+ pATIHW->config_cntl |= SetBits(2, CFG_MEM_AP_SIZE);
+ }
+
+ if (pATI->Chip >= ATI_CHIP_264VTB)
+ {
+ pATIHW->mem_buf_cntl = inr(MEM_BUF_CNTL) | INVALIDATE_RB_CACHE;
+ pATIHW->mem_cntl = (pATI->LockData.mem_cntl &
+ ~(CTL_MEM_LOWER_APER_ENDIAN | CTL_MEM_UPPER_APER_ENDIAN)) |
+ SetBits(CTL_MEM_APER_BYTE_ENDIAN, CTL_MEM_LOWER_APER_ENDIAN);
+
+ switch (pATI->bitsPerPixel)
+ {
+ default:
+ pATIHW->mem_cntl |= SetBits(CTL_MEM_APER_BYTE_ENDIAN,
+ CTL_MEM_UPPER_APER_ENDIAN);
+ break;
+
+ case 16:
+ pATIHW->mem_cntl |= SetBits(CTL_MEM_APER_WORD_ENDIAN,
+ CTL_MEM_UPPER_APER_ENDIAN);
+ break;
+
+ case 32:
+ pATIHW->mem_cntl |= SetBits(CTL_MEM_APER_LONG_ENDIAN,
+ CTL_MEM_UPPER_APER_ENDIAN);
+ break;
+ }
+
+ pATIHW->mpp_config = inr(MPP_CONFIG);
+ pATIHW->mpp_config &=
+ ~(MPP_PRESCALE | MPP_NSTATES | MPP_FORMAT | MPP_WAIT_STATE |
+ MPP_INSERT_WAIT | MPP_TRISTATE_ADDR | MPP_AUTO_INC_EN |
+ MPP_CHKREQ_EN | MPP_BUFFER_SIZE | MPP_BUFFER_MODE | MPP_BUSY);
+ pATIHW->mpp_config |=
+ (MPP_NSTATES_8 | MPP_FORMAT_DA8 | SetBits(4, MPP_WAIT_STATE) |
+ MPP_CHKRDY_EN | MPP_READ_EARLY | MPP_RW_MODE | MPP_EN);
+ pATIHW->mpp_strobe_seq = inr(MPP_STROBE_SEQ);
+ pATIHW->mpp_strobe_seq &= ~(MPP_STB0_SEQ | MPP_STB1_SEQ);
+ pATIHW->mpp_strobe_seq |=
+ SetBits(0x0087U, MPP_STB0_SEQ) | SetBits(0x0083U, MPP_STB1_SEQ);
+ pATIHW->tvo_cntl = 0;
+ }
+
+ /* Draw engine setup */
+ if (pATI->Block0Base)
+ {
+ CARD32 bus_cntl = inr(BUS_CNTL);
+ CARD32 config_cntl = inr(CONFIG_CNTL);
+
+ /* Ensure apertures are enabled */
+ outr(BUS_CNTL, pATIHW->bus_cntl);
+ outr(CONFIG_CNTL, pATIHW->config_cntl);
+
+ /*
+ * When possible, max out command FIFO size.
+ */
+ if (pATI->Chip >= ATI_CHIP_264VT4)
+
+#ifdef XF86DRI_DEVEL
+
+ /* Changing the FIFO depth seems to interfere with DMA, so use
+ * default of 128 entries (0x01)
+ */
+ pATIHW->gui_cntl = (inm(GUI_CNTL) & ~CMDFIFO_SIZE_MODE) | 0x01;
+
+#else /* XF86DRI_DEVEL */
+
+ pATIHW->gui_cntl = inm(GUI_CNTL) & ~CMDFIFO_SIZE_MODE;
+
+#endif /* XF86DRI_DEVEL */
+
+ /* Initialise destination registers */
+ pATIHW->dst_off_pitch =
+ SetBits((pATI->displayWidth * pATI->XModifier) >> 3, DST_PITCH);
+ pATIHW->dst_cntl = DST_X_DIR | DST_Y_DIR | DST_LAST_PEL;
+
+ /* Initialise source registers */
+ pATIHW->src_off_pitch = pATIHW->dst_off_pitch;
+ pATIHW->src_width1 = pATIHW->src_height1 =
+ pATIHW->src_width2 = pATIHW->src_height2 = 1;
+ pATIHW->src_cntl = SRC_LINE_X_DIR;
+
+ /* Initialise scissor, allowing for offscreen areas */
+#ifdef USE_XAA
+ if (!pATI->useEXA)
+ {
+ int width, height, total;
+
+ pATIHW->sc_right = (pATI->displayWidth * pATI->XModifier) - 1;
+ width = pATI->displayWidth * pATI->bitsPerPixel;
+ total = pScreenInfo->videoRam * (1024 * 8);
+ height = (total + width - 1) / width;
+ if (height > ATIMach64MaxY + 1)
+ height = ATIMach64MaxY + 1;
+ pATIHW->sc_bottom = height - 1;
+ }
+#endif /* USE_XAA */
+
+#ifdef USE_EXA
+ if (pATI->useEXA)
+ {
+ pATIHW->sc_right = ATIMach64MaxX;
+ pATIHW->sc_bottom = ATIMach64MaxY;
+ }
+#endif /* USE_EXA */
+
+ pATI->sc_left_right = SetWord(pATI->NewHW.sc_right, 1) |
+ SetWord(pATI->NewHW.sc_left, 0);
+ pATI->sc_top_bottom = SetWord(pATI->NewHW.sc_bottom, 1) |
+ SetWord(pATI->NewHW.sc_top, 0);
+
+ /* Initialise data path */
+ pATIHW->dp_frgd_clr = (CARD32)(-1);
+ pATIHW->dp_write_mask = (CARD32)(-1);
+
+ switch (pATI->depth)
+ {
+ case 8:
+ pATIHW->dp_chain_mask = DP_CHAIN_8BPP;
+ pATIHW->dp_pix_width =
+ SetBits(PIX_WIDTH_8BPP, DP_DST_PIX_WIDTH) |
+ SetBits(PIX_WIDTH_8BPP, DP_SRC_PIX_WIDTH) |
+ SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH);
+ break;
+
+ case 15:
+ pATIHW->dp_chain_mask = DP_CHAIN_15BPP_1555;
+ pATIHW->dp_pix_width =
+ SetBits(PIX_WIDTH_15BPP, DP_DST_PIX_WIDTH) |
+ SetBits(PIX_WIDTH_15BPP, DP_SRC_PIX_WIDTH) |
+ SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH);
+ break;
+
+ case 16:
+ pATIHW->dp_chain_mask = DP_CHAIN_16BPP_565;
+ pATIHW->dp_pix_width =
+ SetBits(PIX_WIDTH_16BPP, DP_DST_PIX_WIDTH) |
+ SetBits(PIX_WIDTH_16BPP, DP_SRC_PIX_WIDTH) |
+ SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH);
+ break;
+
+ case 24:
+ if (pATI->bitsPerPixel == 24)
+ {
+ pATIHW->dp_chain_mask = DP_CHAIN_24BPP_888;
+ pATIHW->dp_pix_width =
+ SetBits(PIX_WIDTH_8BPP, DP_DST_PIX_WIDTH) |
+ SetBits(PIX_WIDTH_8BPP, DP_SRC_PIX_WIDTH) |
+ SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH);
+ }
+ else
+ {
+ pATIHW->dp_chain_mask = DP_CHAIN_32BPP_8888;
+ pATIHW->dp_pix_width =
+ SetBits(PIX_WIDTH_32BPP, DP_DST_PIX_WIDTH) |
+ SetBits(PIX_WIDTH_32BPP, DP_SRC_PIX_WIDTH) |
+ SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
+
+ pATIHW->dp_pix_width |= DP_BYTE_PIX_ORDER;
+
+#endif /* X_BYTE_ORDER */
+
+ pATIHW->dp_mix = SetBits(MIX_SRC, DP_FRGD_MIX) |
+ SetBits(MIX_DST, DP_BKGD_MIX);
+ pATIHW->dp_src = DP_MONO_SRC_ALLONES |
+ SetBits(SRC_FRGD, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC);
+
+ /* Initialise colour compare */
+ pATIHW->clr_cmp_msk = (1 << pATI->depth) - 1;
+
+ if (pATI->Block1Base)
+ {
+ pATIHW->overlay_y_x_start = SetBits(0, OVERLAY_Y_START) |
+ SetBits(0, OVERLAY_X_START) | OVERLAY_LOCK_START;
+ pATIHW->overlay_y_x_end = SetBits(0, OVERLAY_Y_END) |
+ SetBits(0, OVERLAY_X_END) | OVERLAY_LOCK_END;
+
+ pATIHW->overlay_graphics_key_clr =
+ (3 << ((2 * pATI->depth) / 3)) |
+ (2 << ((1 * pATI->depth) / 3)) |
+ (1 << ((0 * pATI->depth) / 3));
+ pATIHW->overlay_graphics_key_msk = (1 << pATI->depth) - 1;
+
+ pATIHW->overlay_key_cntl =
+ SetBits(OVERLAY_MIX_FALSE, OVERLAY_VIDEO_FN) |
+ SetBits(OVERLAY_MIX_EQUAL, OVERLAY_GRAPHICS_FN);
+
+ pATIHW->overlay_scale_cntl = SCALE_EN;
+
+ pATIHW->video_format = VIDEO_IN_VYUY422 | SCALER_IN_VYUY422;
+
+ if (pATI->Chip >= ATI_CHIP_264GTPRO)
+ {
+ /* These values are documented voodoo */
+ pATIHW->scaler_h_coeff0 = SetByte(0x20U, 1);
+ pATIHW->scaler_h_coeff1 = SetByte(0x0DU, 0) |
+ SetByte(0x20U, 1) | SetByte(0x06U, 2) | SetByte(0x0DU, 3);
+ pATIHW->scaler_h_coeff2 = SetByte(0x0DU, 0) |
+ SetByte(0x1CU, 1) | SetByte(0x0AU, 2) | SetByte(0x0DU, 3);
+ pATIHW->scaler_h_coeff3 = SetByte(0x0CU, 0) |
+ SetByte(0x1AU, 1) | SetByte(0x0EU, 2) | SetByte(0x0CU, 3);
+ pATIHW->scaler_h_coeff4 = SetByte(0x0CU, 0) |
+ SetByte(0x14U, 1) | SetByte(0x14U, 2) | SetByte(0x0CU, 3);
+ }
+ }
+
+ /* Restore aperture enablement */
+ outr(BUS_CNTL, bus_cntl);
+ outr(CONFIG_CNTL, config_cntl);
+ }
+}
+
+/*
+ * ATIMach64Save --
+ *
+ * This function is called to save the Mach64 portion of the current video
+ * state.
+ */
+void
+ATIMach64Save
+(
+ ATIPtr pATI,
+ ATIHWPtr pATIHW
+)
+{
+ pATIHW->crtc_h_total_disp = inr(CRTC_H_TOTAL_DISP);
+ pATIHW->crtc_h_sync_strt_wid = inr(CRTC_H_SYNC_STRT_WID);
+ pATIHW->crtc_v_total_disp = inr(CRTC_V_TOTAL_DISP);
+ pATIHW->crtc_v_sync_strt_wid = inr(CRTC_V_SYNC_STRT_WID);
+
+ pATIHW->crtc_off_pitch = inr(CRTC_OFF_PITCH);
+
+ pATIHW->crtc_gen_cntl = inr(CRTC_GEN_CNTL);
+
+ pATIHW->ovr_clr = inr(OVR_CLR);
+ pATIHW->ovr_wid_left_right = inr(OVR_WID_LEFT_RIGHT);
+ pATIHW->ovr_wid_top_bottom = inr(OVR_WID_TOP_BOTTOM);
+
+ pATIHW->cur_clr0 = inr(CUR_CLR0);
+ pATIHW->cur_clr1 = inr(CUR_CLR1);
+ pATIHW->cur_offset = inr(CUR_OFFSET);
+ pATIHW->cur_horz_vert_posn = inr(CUR_HORZ_VERT_POSN);
+ pATIHW->cur_horz_vert_off = inr(CUR_HORZ_VERT_OFF);
+
+ pATIHW->clock_cntl = inr(CLOCK_CNTL);
+
+ pATIHW->bus_cntl = inr(BUS_CNTL);
+
+ pATIHW->mem_vga_wp_sel = inr(MEM_VGA_WP_SEL);
+ pATIHW->mem_vga_rp_sel = inr(MEM_VGA_RP_SEL);
+
+ pATIHW->dac_cntl = inr(DAC_CNTL);
+
+ pATIHW->config_cntl = inr(CONFIG_CNTL);
+
+ pATIHW->gen_test_cntl = inr(GEN_TEST_CNTL) & ~GEN_CUR_EN;
+
+ if (pATI->Chip >= ATI_CHIP_264VTB)
+ {
+ pATIHW->mem_buf_cntl = inr(MEM_BUF_CNTL) | INVALIDATE_RB_CACHE;
+ pATIHW->mem_cntl = inr(MEM_CNTL);
+ pATIHW->mpp_config = inr(MPP_CONFIG);
+ pATIHW->mpp_strobe_seq = inr(MPP_STROBE_SEQ);
+ pATIHW->tvo_cntl = inr(TVO_CNTL);
+ }
+
+ /* Save draw engine state */
+ if (pATI->Block0Base && (pATIHW == &pATI->OldHW))
+ {
+ /* Ensure apertures are enabled */
+ outr(BUS_CNTL, pATI->NewHW.bus_cntl);
+ outr(CONFIG_CNTL, pATI->NewHW.config_cntl);
+
+ ATIMach64WaitForIdle(pATI);
+
+ /* Save FIFO size */
+ if (pATI->Chip >= ATI_CHIP_264VT4)
+ pATIHW->gui_cntl = inm(GUI_CNTL);
+
+ /* Save destination registers */
+ pATIHW->dst_off_pitch = inm(DST_OFF_PITCH);
+ pATIHW->dst_x = inm(DST_X);
+ pATIHW->dst_y = inm(DST_Y);
+ pATIHW->dst_height = inm(DST_HEIGHT);
+ pATIHW->dst_bres_err = inm(DST_BRES_ERR);
+ pATIHW->dst_bres_inc = inm(DST_BRES_INC);
+ pATIHW->dst_bres_dec = inm(DST_BRES_DEC);
+ pATIHW->dst_cntl = inm(DST_CNTL);
+
+ /* Save source registers */
+ pATIHW->src_off_pitch = inm(SRC_OFF_PITCH);
+ pATIHW->src_x = inm(SRC_X);
+ pATIHW->src_y = inm(SRC_Y);
+ pATIHW->src_width1 = inm(SRC_WIDTH1);
+ pATIHW->src_height1 = inm(SRC_HEIGHT1);
+ pATIHW->src_x_start = inm(SRC_X_START);
+ pATIHW->src_y_start = inm(SRC_Y_START);
+ pATIHW->src_width2 = inm(SRC_WIDTH2);
+ pATIHW->src_height2 = inm(SRC_HEIGHT2);
+ pATIHW->src_cntl = inm(SRC_CNTL);
+
+ if (pATI->Chip >= ATI_CHIP_264GTPRO)
+ {
+ CARD32 offset = TEX_LEVEL(inm(TEX_SIZE_PITCH));
+
+ /* Save 3D control & texture registers */
+ pATIHW->tex_offset = inm(TEX_0_OFF + offset);
+ pATIHW->scale_3d_cntl = inm(SCALE_3D_CNTL);
+ }
+
+ /* Save host data register */
+ pATIHW->host_cntl = inm(HOST_CNTL);
+
+ /* Save pattern registers */
+ pATIHW->pat_reg0 = inm(PAT_REG0);
+ pATIHW->pat_reg1 = inm(PAT_REG1);
+ pATIHW->pat_cntl = inm(PAT_CNTL);
+
+ /* Save scissor registers */
+ pATIHW->sc_left = pATI->sc_left = inm(SC_LEFT);
+ pATIHW->sc_right = pATI->sc_right = inm(SC_RIGHT);
+ pATIHW->sc_top = pATI->sc_top = inm(SC_TOP);
+ pATIHW->sc_bottom = pATI->sc_bottom = inm(SC_BOTTOM);
+
+ /* Save data path registers */
+ pATIHW->dp_bkgd_clr = inm(DP_BKGD_CLR);
+ pATIHW->dp_frgd_clr = inm(DP_FRGD_CLR);
+ pATIHW->dp_write_mask = inm(DP_WRITE_MASK);
+ pATIHW->dp_chain_mask = inm(DP_CHAIN_MASK);
+ pATIHW->dp_pix_width = inm(DP_PIX_WIDTH);
+ pATIHW->dp_mix = inm(DP_MIX);
+ pATIHW->dp_src = inm(DP_SRC);
+
+ /* Save colour compare registers */
+ pATIHW->clr_cmp_clr = inm(CLR_CMP_CLR);
+ pATIHW->clr_cmp_msk = inm(CLR_CMP_MSK);
+ pATIHW->clr_cmp_cntl = inm(CLR_CMP_CNTL);
+
+ /* Save context */
+ pATIHW->context_mask = inm(CONTEXT_MASK);
+
+ if (pATI->Chip >= ATI_CHIP_264GTPRO)
+ {
+ /* Save texture setup registers */
+ pATIHW->tex_size_pitch = inm(TEX_SIZE_PITCH);
+ pATIHW->tex_cntl = inm(TEX_CNTL);
+ }
+
+ if (pATI->Block1Base)
+ {
+ /* Save overlay & scaler registers */
+ pATIHW->overlay_y_x_start = inm(OVERLAY_Y_X_START);
+ pATIHW->overlay_y_x_end = inm(OVERLAY_Y_X_END);
+
+ pATIHW->overlay_graphics_key_clr = inm(OVERLAY_GRAPHICS_KEY_CLR);
+ pATIHW->overlay_graphics_key_msk = inm(OVERLAY_GRAPHICS_KEY_MSK);
+
+ pATIHW->overlay_key_cntl = inm(OVERLAY_KEY_CNTL);
+
+ pATIHW->overlay_scale_inc = inm(OVERLAY_SCALE_INC);
+ pATIHW->overlay_scale_cntl = inm(OVERLAY_SCALE_CNTL);
+
+ pATIHW->scaler_height_width = inm(SCALER_HEIGHT_WIDTH);
+
+ pATIHW->scaler_test = inm(SCALER_TEST);
+
+ pATIHW->video_format = inm(VIDEO_FORMAT);
+
+ if (pATI->Chip < ATI_CHIP_264VTB)
+ {
+ pATIHW->buf0_offset = inm(BUF0_OFFSET);
+ pATIHW->buf0_pitch = inm(BUF0_PITCH);
+ pATIHW->buf1_offset = inm(BUF1_OFFSET);
+ pATIHW->buf1_pitch = inm(BUF1_PITCH);
+ }
+ else
+ {
+ pATIHW->scaler_buf0_offset = inm(SCALER_BUF0_OFFSET);
+ pATIHW->scaler_buf1_offset = inm(SCALER_BUF1_OFFSET);
+ pATIHW->scaler_buf_pitch = inm(SCALER_BUF_PITCH);
+
+ pATIHW->overlay_exclusive_horz = inm(OVERLAY_EXCLUSIVE_HORZ);
+ pATIHW->overlay_exclusive_vert = inm(OVERLAY_EXCLUSIVE_VERT);
+
+ if (pATI->Chip >= ATI_CHIP_264GTPRO)
+ {
+ pATIHW->scaler_colour_cntl = inm(SCALER_COLOUR_CNTL);
+
+ pATIHW->scaler_h_coeff0 = inm(SCALER_H_COEFF0);
+ pATIHW->scaler_h_coeff1 = inm(SCALER_H_COEFF1);
+ pATIHW->scaler_h_coeff2 = inm(SCALER_H_COEFF2);
+ pATIHW->scaler_h_coeff3 = inm(SCALER_H_COEFF3);
+ pATIHW->scaler_h_coeff4 = inm(SCALER_H_COEFF4);
+
+ pATIHW->scaler_buf0_offset_u = inm(SCALER_BUF0_OFFSET_U);
+ pATIHW->scaler_buf0_offset_v = inm(SCALER_BUF0_OFFSET_V);
+ pATIHW->scaler_buf1_offset_u = inm(SCALER_BUF1_OFFSET_U);
+ pATIHW->scaler_buf1_offset_v = inm(SCALER_BUF1_OFFSET_V);
+ }
+ }
+ }
+
+ /* Restore aperture enablement */
+ outr(BUS_CNTL, pATIHW->bus_cntl);
+ outr(CONFIG_CNTL, pATIHW->config_cntl);
+ }
+}
+
+/*
+ * ATIMach64ModeAdjust --
+ *
+ * This function is called to adjust horizontal and vertical timings.
+ */
+static void
+ATIMach64ModeAdjust
+(
+ ATIPtr pATI,
+ ATIHWPtr pATIHW,
+ DisplayModePtr pMode
+)
+{
+ int VDisplay;
+
+ /* Clobber mode timings */
+ if (pATI->OptionPanelDisplay && (pATI->LCDPanelID >= 0))
+ {
+ if (!pMode->CrtcHAdjusted && !pMode->CrtcVAdjusted &&
+ (!pATI->OptionLCDSync || (pMode->type & M_T_BUILTIN)))
+ {
+ int VScan;
+
+ pMode->Clock = pATI->LCDClock;
+ pMode->Flags &= ~(V_DBLSCAN | V_INTERLACE | V_CLKDIV2);
+
+ pMode->VScan = 0;
+
+ /*
+ * Use doublescanning or multiscanning to get around vertical blending
+ * limitations.
+ */
+ VScan = pATI->LCDVertical / pMode->VDisplay;
+ if (VScan > 1)
+ {
+ VScan = 2;
+ pMode->Flags |= V_DBLSCAN;
+ }
+
+ pMode->HSyncStart = pMode->HDisplay + pATI->LCDHSyncStart;
+ pMode->HSyncEnd = pMode->HSyncStart + pATI->LCDHSyncWidth;
+ pMode->HTotal = pMode->HDisplay + pATI->LCDHBlankWidth;
+
+ pMode->VSyncStart = pMode->VDisplay +
+ ATIDivide(pATI->LCDVSyncStart, VScan, 0, 0);
+ pMode->VSyncEnd = pMode->VSyncStart +
+ ATIDivide(pATI->LCDVSyncWidth, VScan, 0, 1);
+ pMode->VTotal = pMode->VDisplay +
+ ATIDivide(pATI->LCDVBlankWidth, VScan, 0, 0);
+ }
+ }
+
+ /* If not already done adjust horizontal timings */
+ if (!pMode->CrtcHAdjusted)
+ {
+ pMode->CrtcHAdjusted = TRUE;
+ /* XXX Deal with Blank Start/End and overscan later */
+ pMode->CrtcHDisplay = (pMode->HDisplay >> 3) - 1;
+ pMode->CrtcHSyncStart = (pMode->HSyncStart >> 3) - 1;
+ pMode->CrtcHSyncEnd = (pMode->HSyncEnd >> 3) - 1;
+ pMode->CrtcHTotal = (pMode->HTotal >> 3) - 1;
+
+ /* Make adjustments if sync pulse width is out-of-bounds */
+ if ((pMode->CrtcHSyncEnd - pMode->CrtcHSyncStart) >
+ (int)MaxBits(CRTC_H_SYNC_WID))
+ {
+ pMode->CrtcHSyncEnd =
+ pMode->CrtcHSyncStart + MaxBits(CRTC_H_SYNC_WID);
+ }
+ else if (pMode->CrtcHSyncStart == pMode->CrtcHSyncEnd)
+ {
+ if (pMode->CrtcHDisplay < pMode->CrtcHSyncStart)
+ pMode->CrtcHSyncStart--;
+ else if (pMode->CrtcHSyncEnd < pMode->CrtcHTotal)
+ pMode->CrtcHSyncEnd++;
+ }
+ }
+
+ /*
+ * Always re-do vertical adjustments.
+ */
+ pMode->CrtcVDisplay = pMode->VDisplay;
+ pMode->CrtcVSyncStart = pMode->VSyncStart;
+ pMode->CrtcVSyncEnd = pMode->VSyncEnd;
+ pMode->CrtcVTotal = pMode->VTotal;
+
+ if ((pATI->Chip >= ATI_CHIP_264CT) &&
+ ((pMode->Flags & V_DBLSCAN) || (pMode->VScan > 1)))
+ {
+ pMode->CrtcVDisplay <<= 1;
+ pMode->CrtcVSyncStart <<= 1;
+ pMode->CrtcVSyncEnd <<= 1;
+ pMode->CrtcVTotal <<= 1;
+ }
+
+ /*
+ * Might as well default to the same as VGA with respect to sync
+ * polarities.
+ */
+ if ((!(pMode->Flags & (V_PHSYNC | V_NHSYNC))) ||
+ (!(pMode->Flags & (V_PVSYNC | V_NVSYNC))))
+ {
+ pMode->Flags &= ~(V_PHSYNC | V_NHSYNC | V_PVSYNC | V_NVSYNC);
+
+ if (pATI->OptionPanelDisplay && (pATI->LCDPanelID >= 0))
+ VDisplay = pATI->LCDVertical;
+ else
+ VDisplay = pMode->CrtcVDisplay;
+
+#ifdef TV_OUT
+ if (pATI->tvActive)
+ VDisplay = pMode->CrtcVDisplay;
+#endif
+
+ if (VDisplay < 400)
+ pMode->Flags |= V_PHSYNC | V_NVSYNC;
+ else if (VDisplay < 480)
+ pMode->Flags |= V_NHSYNC | V_PVSYNC;
+ else if (VDisplay < 768)
+ pMode->Flags |= V_NHSYNC | V_NVSYNC;
+ else
+ pMode->Flags |= V_PHSYNC | V_PVSYNC;
+ }
+
+ pMode->CrtcVDisplay--;
+ pMode->CrtcVSyncStart--;
+ pMode->CrtcVSyncEnd--;
+ pMode->CrtcVTotal--;
+ /* Make sure sync pulse is not too wide */
+ if ((pMode->CrtcVSyncEnd - pMode->CrtcVSyncStart) >
+ (int)MaxBits(CRTC_V_SYNC_WID))
+ pMode->CrtcVSyncEnd = pMode->CrtcVSyncStart + MaxBits(CRTC_V_SYNC_WID);
+ pMode->CrtcVAdjusted = TRUE; /* Redundant */
+}
+
+/*
+ * ATIMach64Calculate --
+ *
+ * This function is called to fill in the Mach64 portion of an ATIHWRec.
+ */
+void
+ATIMach64Calculate
+(
+ ATIPtr pATI,
+ ATIHWPtr pATIHW,
+ DisplayModePtr pMode
+)
+{
+ ATIMach64ModeAdjust(pATI, pATIHW, pMode);
+
+ /* Build register contents */
+ pATIHW->crtc_h_total_disp =
+ SetBits(pMode->CrtcHTotal, CRTC_H_TOTAL) |
+ SetBits(pMode->CrtcHDisplay, CRTC_H_DISP);
+
+ pATIHW->crtc_h_sync_strt_wid =
+ SetBits(pMode->CrtcHSyncStart, CRTC_H_SYNC_STRT) |
+ SetBits(pMode->CrtcHSkew, CRTC_H_SYNC_DLY) | /* ? */
+ SetBits(GetBits(pMode->CrtcHSyncStart, 0x0100U), CRTC_H_SYNC_STRT_HI) |
+ SetBits(pMode->CrtcHSyncEnd - pMode->CrtcHSyncStart, CRTC_H_SYNC_WID);
+ if (pMode->Flags & V_NHSYNC)
+ pATIHW->crtc_h_sync_strt_wid |= CRTC_H_SYNC_POL;
+
+ pATIHW->crtc_v_total_disp =
+ SetBits(pMode->CrtcVTotal, CRTC_V_TOTAL) |
+ SetBits(pMode->CrtcVDisplay, CRTC_V_DISP);
+
+ pATIHW->crtc_v_sync_strt_wid =
+ SetBits(pMode->CrtcVSyncStart, CRTC_V_SYNC_STRT) |
+ SetBits(pMode->CrtcVSyncEnd - pMode->CrtcVSyncStart, CRTC_V_SYNC_WID);
+ if (pMode->Flags & V_NVSYNC)
+ pATIHW->crtc_v_sync_strt_wid |= CRTC_V_SYNC_POL;
+
+ pATIHW->crtc_off_pitch = SetBits(pATI->displayWidth >> 3, CRTC_PITCH);
+
+ pATIHW->crtc_gen_cntl = inr(CRTC_GEN_CNTL) &
+ ~(CRTC_DBL_SCAN_EN | CRTC_INTERLACE_EN |
+ CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_CSYNC_EN |
+ CRTC_PIX_BY_2_EN | CRTC_DISPLAY_DIS | CRTC_VGA_XOVERSCAN |
+ CRTC_PIX_WIDTH | CRTC_BYTE_PIX_ORDER |
+ CRTC_VGA_128KAP_PAGING | CRTC_VFC_SYNC_TRISTATE |
+ CRTC_LOCK_REGS | /* Already off, but ... */
+ CRTC_SYNC_TRISTATE | CRTC_DISP_REQ_EN |
+ CRTC_VGA_TEXT_132 | CRTC_CUR_B_TEST);
+ pATIHW->crtc_gen_cntl |=
+ CRTC_EXT_DISP_EN | CRTC_EN | CRTC_VGA_LINEAR | CRTC_CNT_EN;
+ switch (pATI->depth)
+ {
+ case 8:
+ pATIHW->crtc_gen_cntl |= SetBits(PIX_WIDTH_8BPP, CRTC_PIX_WIDTH);
+ break;
+
+ case 15:
+ pATIHW->crtc_gen_cntl |= SetBits(PIX_WIDTH_15BPP, CRTC_PIX_WIDTH);
+ break;
+
+ case 16:
+ pATIHW->crtc_gen_cntl |= SetBits(PIX_WIDTH_16BPP, CRTC_PIX_WIDTH);
+ break;
+
+ case 24:
+ if (pATI->bitsPerPixel == 24)
+ {
+ pATIHW->crtc_gen_cntl |=
+ SetBits(PIX_WIDTH_24BPP, CRTC_PIX_WIDTH);
+ break;
+ }
+ if (pATI->bitsPerPixel != 32)
+ break;
+ /* Fall through */
+
+ case 32:
+ pATIHW->crtc_gen_cntl |= SetBits(PIX_WIDTH_32BPP, CRTC_PIX_WIDTH);
+ break;
+
+ default:
+ break;
+ }
+ if ((pMode->Flags & V_DBLSCAN) || (pMode->VScan > 1))
+ pATIHW->crtc_gen_cntl |= CRTC_DBL_SCAN_EN;
+ if (pMode->Flags & V_INTERLACE)
+ pATIHW->crtc_gen_cntl |= CRTC_INTERLACE_EN;
+ if (pATI->OptionCSync || (pMode->Flags & (V_CSYNC | V_PCSYNC)))
+ pATIHW->crtc_gen_cntl |= CRTC_CSYNC_EN;
+ /* For now, set display FIFO low water mark as high as possible */
+ if (pATI->Chip < ATI_CHIP_264VTB)
+ pATIHW->crtc_gen_cntl |= CRTC_FIFO_LWM;
+}
+
+/*
+ * ATIMach64Set --
+ *
+ * This function is called to load a Mach64's accelerator CRTC and draw engine.
+ */
+void
+ATIMach64Set
+(
+ ATIPtr pATI,
+ ATIHWPtr pATIHW
+)
+{
+
+#ifndef AVOID_CPIO
+
+ if (pATIHW->crtc == ATI_CRTC_MACH64)
+
+#endif /* AVOID_CPIO */
+
+ {
+ if ((pATIHW->FeedbackDivider > 0))
+ ATIClockSet(pATI, pATIHW); /* Programme clock */
+
+ if (pATI->DAC == ATI_DAC_IBMRGB514)
+ ATIRGB514Set(pATI, pATIHW);
+
+ /* Load Mach64 CRTC registers */
+ outr(CRTC_H_TOTAL_DISP, pATIHW->crtc_h_total_disp);
+ outr(CRTC_H_SYNC_STRT_WID, pATIHW->crtc_h_sync_strt_wid);
+ outr(CRTC_V_TOTAL_DISP, pATIHW->crtc_v_total_disp);
+ outr(CRTC_V_SYNC_STRT_WID, pATIHW->crtc_v_sync_strt_wid);
+
+ outr(CRTC_OFF_PITCH, pATIHW->crtc_off_pitch);
+
+ /* Load overscan registers */
+ outr(OVR_CLR, pATIHW->ovr_clr);
+ outr(OVR_WID_LEFT_RIGHT, pATIHW->ovr_wid_left_right);
+ outr(OVR_WID_TOP_BOTTOM, pATIHW->ovr_wid_top_bottom);
+
+ /* Load hardware cursor registers */
+ outr(CUR_CLR0, pATIHW->cur_clr0);
+ outr(CUR_CLR1, pATIHW->cur_clr1);
+ outr(CUR_OFFSET, pATIHW->cur_offset);
+ outr(CUR_HORZ_VERT_POSN, pATIHW->cur_horz_vert_posn);
+ outr(CUR_HORZ_VERT_OFF, pATIHW->cur_horz_vert_off);
+
+ /* Set pixel clock */
+ outr(CLOCK_CNTL, pATIHW->clock_cntl | CLOCK_STROBE);
+
+ outr(GEN_TEST_CNTL, pATIHW->gen_test_cntl | GEN_GUI_EN);
+ outr(GEN_TEST_CNTL, pATIHW->gen_test_cntl);
+ outr(GEN_TEST_CNTL, pATIHW->gen_test_cntl | GEN_GUI_EN);
+
+ /* Finalise CRTC setup and turn on the screen */
+ outr(CRTC_GEN_CNTL, pATIHW->crtc_gen_cntl);
+ }
+
+ /* Load draw engine */
+ if (pATI->Block0Base)
+ {
+ /* Clobber MMIO cache */
+ (void)memset(pATI->MMIOCached, 0, SizeOf(pATI->MMIOCached));
+
+ /* Ensure apertures are enabled */
+ outr(BUS_CNTL, pATI->NewHW.bus_cntl);
+ outr(CONFIG_CNTL, pATI->NewHW.config_cntl);
+
+ pATI->EngineIsBusy = TRUE; /* Force engine poll */
+ ATIMach64WaitForIdle(pATI);
+
+ /* Load FIFO size */
+ if (pATI->Chip >= ATI_CHIP_264VT4)
+ {
+ outm(GUI_CNTL, pATIHW->gui_cntl);
+ pATI->nAvailableFIFOEntries = 0;
+ ATIMach64PollEngineStatus(pATI);
+ }
+
+ /* Set FIFO depth */
+ pATI->nFIFOEntries = pATI->nAvailableFIFOEntries;
+
+ /* Load destination registers */
+ ATIMach64WaitForFIFO(pATI, 7);
+ outf(DST_OFF_PITCH, pATIHW->dst_off_pitch);
+ outf(DST_Y_X, SetWord(pATIHW->dst_x, 1) | SetWord(pATIHW->dst_y, 0));
+ outf(DST_HEIGHT, pATIHW->dst_height);
+ outf(DST_BRES_ERR, pATIHW->dst_bres_err);
+ outf(DST_BRES_INC, pATIHW->dst_bres_inc);
+ outf(DST_BRES_DEC, pATIHW->dst_bres_dec);
+ outf(DST_CNTL, pATIHW->dst_cntl);
+
+ if (pATI->Chip >= ATI_CHIP_264GTPRO)
+ {
+ /* Load ROP unit registers */
+ ATIMach64WaitForFIFO(pATI, 2);
+ outf(Z_CNTL, 0);
+ outf(ALPHA_TST_CNTL, 0);
+ }
+
+ /* Load source registers */
+ ATIMach64WaitForFIFO(pATI, 6);
+ outf(SRC_OFF_PITCH, pATIHW->src_off_pitch);
+ outf(SRC_Y_X, SetWord(pATIHW->src_x, 1) | SetWord(pATIHW->src_y, 0));
+ outf(SRC_HEIGHT1_WIDTH1,
+ SetWord(pATIHW->src_width1, 1) | SetWord(pATIHW->src_height1, 0));
+ outf(SRC_Y_X_START,
+ SetWord(pATIHW->src_x_start, 1) | SetWord(pATIHW->src_y_start, 0));
+ outf(SRC_HEIGHT2_WIDTH2,
+ SetWord(pATIHW->src_width2, 1) | SetWord(pATIHW->src_height2, 0));
+ outf(SRC_CNTL, pATIHW->src_cntl);
+
+ if (pATI->Chip >= ATI_CHIP_264GTPRO)
+ {
+ CARD32 offset = TEX_LEVEL(pATIHW->tex_size_pitch);
+
+ /* Load 3D control & texture registers */
+ ATIMach64WaitForFIFO(pATI, 2);
+ outf(TEX_0_OFF + offset, pATIHW->tex_offset);
+ outf(SCALE_3D_CNTL, pATIHW->scale_3d_cntl);
+ }
+
+ /* Load host data register */
+ ATIMach64WaitForFIFO(pATI, 1);
+ outf(HOST_CNTL, pATIHW->host_cntl);
+
+ /* Set host transfer window address and size clamp */
+ pATI->pHOST_DATA = ATIHostDataAddr(HOST_DATA_0);
+ pATI->nHostFIFOEntries = pATI->nFIFOEntries >> 1;
+ if (pATI->nHostFIFOEntries > 16)
+ pATI->nHostFIFOEntries = 16;
+
+ /* Load pattern registers */
+ ATIMach64WaitForFIFO(pATI, 3);
+ outf(PAT_REG0, pATIHW->pat_reg0);
+ outf(PAT_REG1, pATIHW->pat_reg1);
+ outf(PAT_CNTL, pATIHW->pat_cntl);
+
+ /* Load scissor registers */
+ ATIMach64WaitForFIFO(pATI, 2);
+ outf(SC_LEFT_RIGHT,
+ SetWord(pATIHW->sc_right, 1) | SetWord(pATIHW->sc_left, 0));
+ outf(SC_TOP_BOTTOM,
+ SetWord(pATIHW->sc_bottom, 1) | SetWord(pATIHW->sc_top, 0));
+ pATI->sc_left = pATIHW->sc_left;
+ pATI->sc_right = pATIHW->sc_right;
+ pATI->sc_top = pATIHW->sc_top;
+ pATI->sc_bottom = pATIHW->sc_bottom;
+
+ /* Load data path registers */
+ ATIMach64WaitForFIFO(pATI, 7);
+ outf(DP_BKGD_CLR, pATIHW->dp_bkgd_clr);
+ outf(DP_FRGD_CLR, pATIHW->dp_frgd_clr);
+ outf(DP_WRITE_MASK, pATIHW->dp_write_mask);
+ outf(DP_CHAIN_MASK, pATIHW->dp_chain_mask);
+ outf(DP_PIX_WIDTH, pATIHW->dp_pix_width);
+ outf(DP_MIX, pATIHW->dp_mix);
+ outf(DP_SRC, pATIHW->dp_src);
+
+ /* Load colour compare registers */
+ ATIMach64WaitForFIFO(pATI, 3);
+ outf(CLR_CMP_CLR, pATIHW->clr_cmp_clr);
+ outf(CLR_CMP_MSK, pATIHW->clr_cmp_msk);
+ outf(CLR_CMP_CNTL, pATIHW->clr_cmp_cntl);
+
+ /* Load context mask */
+ ATIMach64WaitForFIFO(pATI, 1);
+ outf(CONTEXT_MASK, pATIHW->context_mask);
+
+ if (pATI->Chip >= ATI_CHIP_264GTPRO)
+ {
+ /* Load texture setup registers */
+ ATIMach64WaitForFIFO(pATI, 2);
+ outf(TEX_SIZE_PITCH, pATIHW->tex_size_pitch);
+ outf(TEX_CNTL, pATIHW->tex_cntl);
+ }
+
+ if (pATI->Block1Base)
+ {
+ /* Load overlay & scaler registers */
+ ATIMach64WaitForFIFO(pATI, 10);
+ outf(OVERLAY_Y_X_START, pATIHW->overlay_y_x_start);
+ outf(OVERLAY_Y_X_END, pATIHW->overlay_y_x_end);
+
+ outf(OVERLAY_GRAPHICS_KEY_CLR, pATIHW->overlay_graphics_key_clr);
+ outf(OVERLAY_GRAPHICS_KEY_MSK, pATIHW->overlay_graphics_key_msk);
+
+ outf(OVERLAY_KEY_CNTL, pATIHW->overlay_key_cntl);
+
+ outf(OVERLAY_SCALE_INC, pATIHW->overlay_scale_inc);
+ outf(OVERLAY_SCALE_CNTL, pATIHW->overlay_scale_cntl);
+
+ outf(SCALER_HEIGHT_WIDTH, pATIHW->scaler_height_width);
+
+ outf(SCALER_TEST, pATIHW->scaler_test);
+
+ outf(VIDEO_FORMAT, pATIHW->video_format);
+
+ if (pATI->Chip < ATI_CHIP_264VTB)
+ {
+ ATIMach64WaitForFIFO(pATI, 4);
+ outf(BUF0_OFFSET, pATIHW->buf0_offset);
+ outf(BUF0_PITCH, pATIHW->buf0_pitch);
+ outf(BUF1_OFFSET, pATIHW->buf1_offset);
+ outf(BUF1_PITCH, pATIHW->buf1_pitch);
+ }
+ else
+ {
+ ATIMach64WaitForFIFO(pATI, 5);
+ outf(SCALER_BUF0_OFFSET, pATIHW->scaler_buf0_offset);
+ outf(SCALER_BUF1_OFFSET, pATIHW->scaler_buf1_offset);
+ outf(SCALER_BUF_PITCH, pATIHW->scaler_buf_pitch);
+
+ outf(OVERLAY_EXCLUSIVE_HORZ, pATIHW->overlay_exclusive_horz);
+ outf(OVERLAY_EXCLUSIVE_VERT, pATIHW->overlay_exclusive_vert);
+
+ if (pATI->Chip >= ATI_CHIP_264GTPRO)
+ {
+ ATIMach64WaitForFIFO(pATI, 10);
+ outf(SCALER_COLOUR_CNTL, pATIHW->scaler_colour_cntl);
+
+ outf(SCALER_H_COEFF0, pATIHW->scaler_h_coeff0);
+ outf(SCALER_H_COEFF1, pATIHW->scaler_h_coeff1);
+ outf(SCALER_H_COEFF2, pATIHW->scaler_h_coeff2);
+ outf(SCALER_H_COEFF3, pATIHW->scaler_h_coeff3);
+ outf(SCALER_H_COEFF4, pATIHW->scaler_h_coeff4);
+
+ outf(SCALER_BUF0_OFFSET_U, pATIHW->scaler_buf0_offset_u);
+ outf(SCALER_BUF0_OFFSET_V, pATIHW->scaler_buf0_offset_v);
+ outf(SCALER_BUF1_OFFSET_U, pATIHW->scaler_buf1_offset_u);
+ outf(SCALER_BUF1_OFFSET_V, pATIHW->scaler_buf1_offset_v);
+ }
+ }
+ }
+
+ ATIMach64WaitForIdle(pATI);
+
+ if (pATI->OptionMMIOCache)
+ {
+ /*
+ * Enable write caching for selected MMIO registers. This can only
+ * be done for those registers whose value does not change without
+ * driver intervention.
+ */
+
+ CacheRegister(SRC_CNTL);
+
+ if (pATI->Chip >= ATI_CHIP_264GTPRO)
+ {
+ CacheRegister(SCALE_3D_CNTL);
+ }
+
+ CacheRegister(HOST_CNTL);
+
+ CacheRegister(PAT_REG0);
+ CacheRegister(PAT_REG1);
+ CacheRegister(PAT_CNTL);
+
+ CacheRegister(SC_LEFT_RIGHT);
+ CacheRegister(SC_TOP_BOTTOM);
+
+ CacheRegister(DP_BKGD_CLR);
+ CacheRegister(DP_FRGD_CLR);
+ CacheRegister(DP_PIX_WIDTH);
+ CacheRegister(DP_MIX);
+
+ CacheRegister(CLR_CMP_CLR);
+ CacheRegister(CLR_CMP_MSK);
+ CacheRegister(CLR_CMP_CNTL);
+
+ if (pATI->Chip >= ATI_CHIP_264GTPRO)
+ {
+ CacheRegister(TEX_SIZE_PITCH);
+ }
+
+ if (pATI->Block1Base)
+ {
+ CacheRegister(OVERLAY_Y_X_START);
+ CacheRegister(OVERLAY_Y_X_END);
+
+ CacheRegister(OVERLAY_GRAPHICS_KEY_CLR);
+ CacheRegister(OVERLAY_GRAPHICS_KEY_MSK);
+
+ CacheRegister(OVERLAY_KEY_CNTL);
+
+ CacheRegister(OVERLAY_SCALE_INC);
+ CacheRegister(OVERLAY_SCALE_CNTL);
+
+ CacheRegister(SCALER_HEIGHT_WIDTH);
+
+ CacheRegister(SCALER_TEST);
+
+ CacheRegister(VIDEO_FORMAT);
+
+ if (pATI->Chip < ATI_CHIP_264VTB)
+ {
+ CacheRegister(BUF0_OFFSET);
+ CacheRegister(BUF0_PITCH);
+ CacheRegister(BUF1_OFFSET);
+ CacheRegister(BUF1_PITCH);
+ }
+ else
+ {
+ CacheRegister(SCALER_BUF0_OFFSET);
+ CacheRegister(SCALER_BUF1_OFFSET);
+ CacheRegister(SCALER_BUF_PITCH);
+
+ CacheRegister(OVERLAY_EXCLUSIVE_HORZ);
+ CacheRegister(OVERLAY_EXCLUSIVE_VERT);
+
+ if (pATI->Chip >= ATI_CHIP_264GTPRO)
+ {
+ CacheRegister(SCALER_COLOUR_CNTL);
+
+ CacheRegister(SCALER_H_COEFF0);
+ CacheRegister(SCALER_H_COEFF1);
+ CacheRegister(SCALER_H_COEFF2);
+ CacheRegister(SCALER_H_COEFF3);
+ CacheRegister(SCALER_H_COEFF4);
+
+ CacheRegister(SCALER_BUF0_OFFSET_U);
+ CacheRegister(SCALER_BUF0_OFFSET_V);
+ CacheRegister(SCALER_BUF1_OFFSET_U);
+ CacheRegister(SCALER_BUF1_OFFSET_V);
+ }
+ }
+ }
+ }
+ }
+
+#ifndef AVOID_CPIO
+
+ if (pATIHW->crtc == ATI_CRTC_MACH64)
+
+#endif /* AVOID_CPIO */
+
+ {
+ /* Aperture setup */
+ outr(MEM_VGA_WP_SEL, pATIHW->mem_vga_wp_sel);
+ outr(MEM_VGA_RP_SEL, pATIHW->mem_vga_rp_sel);
+
+ outr(DAC_CNTL, pATIHW->dac_cntl);
+
+ outr(CONFIG_CNTL, pATIHW->config_cntl);
+ outr(BUS_CNTL, pATIHW->bus_cntl);
+
+ if (pATI->Chip >= ATI_CHIP_264VTB)
+ {
+ outr(MEM_BUF_CNTL, pATIHW->mem_buf_cntl);
+ outr(MEM_CNTL, pATIHW->mem_cntl);
+ outr(MPP_CONFIG, pATIHW->mpp_config);
+ outr(MPP_STROBE_SEQ, pATIHW->mpp_strobe_seq);
+ outr(TVO_CNTL, pATIHW->tvo_cntl);
+ }
+ }
+}
+
+/*
+ * ATIMach64SaveScreen --
+ *
+ * This function blanks or unblanks a Mach64 screen.
+ */
+void
+ATIMach64SaveScreen
+(
+ ATIPtr pATI,
+ int Mode
+)
+{
+ CARD32 crtc_gen_cntl = inr(CRTC_GEN_CNTL);
+
+ switch (Mode)
+ {
+ case SCREEN_SAVER_OFF:
+ case SCREEN_SAVER_FORCER:
+ outr(CRTC_GEN_CNTL, crtc_gen_cntl & ~CRTC_DISPLAY_DIS);
+ break;
+
+ case SCREEN_SAVER_ON:
+ case SCREEN_SAVER_CYCLE:
+ outr(CRTC_GEN_CNTL, crtc_gen_cntl | CRTC_DISPLAY_DIS);
+ break;
+
+ default:
+ break;
+ }
+}
+
+/*
+ * ATIMach64SetDPMSMode --
+ *
+ * This function sets a Mach64's VESA Display Power Management Signaling mode.
+ */
+void
+ATIMach64SetDPMSMode
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI,
+ int DPMSMode
+)
+{
+ CARD32 crtc_gen_cntl =
+ inr(CRTC_GEN_CNTL) & ~(CRTC_HSYNC_DIS | CRTC_VSYNC_DIS);
+
+ switch (DPMSMode)
+ {
+ case DPMSModeOn: /* HSync on, VSync on */
+ break;
+
+ case DPMSModeStandby: /* HSync off, VSync on */
+ crtc_gen_cntl |= CRTC_HSYNC_DIS;
+ break;
+
+ case DPMSModeSuspend: /* HSync on, VSync off */
+ crtc_gen_cntl |= CRTC_VSYNC_DIS;
+ break;
+
+ case DPMSModeOff: /* HSync off, VSync off */
+ crtc_gen_cntl |= CRTC_HSYNC_DIS | CRTC_VSYNC_DIS;
+ break;
+
+ default: /* Muffle compiler */
+ return;
+ }
+
+#ifdef XF86DRI_DEVEL
+
+ /* XAA Sync requires the DRM lock if DRI enabled */
+ ATIDRILock(pScreenInfo);
+
+#endif /* XF86DRI_DEVEL */
+
+ ATIMach64Sync(pScreenInfo);
+
+ outr(CRTC_GEN_CNTL, crtc_gen_cntl);
+
+ if (pATI->OptionPanelDisplay && (pATI->LCDPanelID >= 0))
+ {
+ CARD32 lcd_index = 0;
+
+ /*
+ * ATI's BIOS simply turns the panel on and off, so do the same by
+ * default, but keep the previous behaviour around for reference.
+ */
+ if (pATI->OptionDevel)
+ {
+ CARD32 power_management;
+
+ if (pATI->Chip == ATI_CHIP_264LT)
+ {
+ power_management = inr(POWER_MANAGEMENT);
+ }
+ else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
+ (pATI->Chip == ATI_CHIP_264XL) ||
+ (pATI->Chip == ATI_CHIP_MOBILITY)) */
+ {
+ lcd_index = inr(LCD_INDEX);
+ power_management = ATIMach64GetLCDReg(LCD_POWER_MANAGEMENT);
+ }
+
+ power_management &= ~(STANDBY_NOW | SUSPEND_NOW);
+
+ switch (DPMSMode)
+ {
+ case DPMSModeOn:
+ break;
+
+ case DPMSModeStandby:
+ power_management |= STANDBY_NOW;
+ break;
+
+ case DPMSModeSuspend:
+ power_management |= SUSPEND_NOW;
+ break;
+
+ case DPMSModeOff:
+ power_management |= STANDBY_NOW | SUSPEND_NOW; /* ? */
+ break;
+
+ default: /* Muffle compiler */
+ return;
+ }
+
+ if (pATI->Chip == ATI_CHIP_264LT)
+ {
+ outr(POWER_MANAGEMENT, power_management);
+ }
+ else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
+ (pATI->Chip == ATI_CHIP_264XL) ||
+ (pATI->Chip == ATI_CHIP_MOBILITY)) */
+ {
+ ATIMach64PutLCDReg(LCD_POWER_MANAGEMENT, power_management);
+ outr(LCD_INDEX, lcd_index);
+ }
+ }
+ else
+ {
+ CARD32 lcd_gen_ctrl;
+
+ if (pATI->Chip == ATI_CHIP_264LT)
+ {
+ lcd_gen_ctrl = inr(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);
+ }
+
+ 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);
+ }
+ }
+ }
+
+#ifdef XF86DRI_DEVEL
+
+ ATIDRIUnlock(pScreenInfo);
+
+#endif /* XF86DRI_DEVEL */
+
+}
diff --git a/driver/xf86-video-mach64/src/atimach64.h b/driver/xf86-video-mach64/src/atimach64.h
new file mode 100644
index 000000000..98b194d00
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atimach64.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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"
+
+extern void ATIMach64PreInit(ScrnInfoPtr, ATIPtr, ATIHWPtr);
+extern void ATIMach64Save(ATIPtr, ATIHWPtr);
+extern void ATIMach64Calculate(ATIPtr, ATIHWPtr, DisplayModePtr);
+extern void ATIMach64Set(ATIPtr, ATIHWPtr);
+
+extern void ATIMach64SaveScreen(ATIPtr, int);
+extern void ATIMach64SetDPMSMode(ScrnInfoPtr, ATIPtr, int);
+
+#endif /* ___ATIMACH64_H___ */
diff --git a/driver/xf86-video-mach64/src/atimach64accel.c b/driver/xf86-video-mach64/src/atimach64accel.c
new file mode 100644
index 000000000..276fc86a6
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atimach64accel.c
@@ -0,0 +1,1068 @@
+/*
+ * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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.
+ */
+/*
+ * DRI support by:
+ * Manuel Teira
+ * Leif Delgass <ldelgass@retinalburn.net>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "ati.h"
+#include "atichip.h"
+#include "atimach64accel.h"
+#include "atimach64io.h"
+#include "atipriv.h"
+#include "atiregs.h"
+
+#ifdef XF86DRI_DEVEL
+#include "mach64_common.h"
+#endif
+
+#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.
+ */
+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.
+ */
+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;
+ }
+}
+
+static __inline__ void TestRegisterCachingDP(ScrnInfoPtr pScreenInfo);
+static __inline__ void TestRegisterCachingXV(ScrnInfoPtr pScreenInfo);
+
+/*
+ * ATIMach64Sync --
+ *
+ * This is called to wait for the draw engine to become idle.
+ */
+void
+ATIMach64Sync
+(
+ ScrnInfoPtr pScreenInfo
+)
+{
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+#ifdef XF86DRI_DEVEL
+
+ if ( pATI->directRenderingEnabled && pATI->NeedDRISync )
+ {
+ ATIHWPtr pATIHW = &pATI->NewHW;
+ CARD32 offset;
+
+ if (pATI->OptionMMIOCache) {
+ /* "Invalidate" the MMIO cache so the cache slots get updated */
+ UncacheRegister(SRC_CNTL);
+ UncacheRegister(SCALE_3D_CNTL);
+ UncacheRegister(HOST_CNTL);
+ UncacheRegister(PAT_CNTL);
+ UncacheRegister(SC_LEFT_RIGHT);
+ UncacheRegister(SC_TOP_BOTTOM);
+ UncacheRegister(DP_BKGD_CLR);
+ UncacheRegister(DP_FRGD_CLR);
+ UncacheRegister(DP_PIX_WIDTH);
+ UncacheRegister(DP_MIX);
+ UncacheRegister(CLR_CMP_CNTL);
+ UncacheRegister(TEX_SIZE_PITCH);
+ }
+
+ ATIDRIWaitForIdle(pATI);
+
+ outr( BUS_CNTL, pATIHW->bus_cntl );
+
+ /* DRI uses GUI_TRAJ_CNTL, which is a composite of
+ * src_cntl, dst_cntl, pat_cntl, and host_cntl
+ */
+ outf( SRC_CNTL, pATIHW->src_cntl );
+ outf( DST_CNTL, pATIHW->dst_cntl );
+ outf( PAT_CNTL, pATIHW->pat_cntl );
+ outf( HOST_CNTL, pATIHW->host_cntl );
+
+ outf( DST_OFF_PITCH, pATIHW->dst_off_pitch );
+ outf( SRC_OFF_PITCH, pATIHW->src_off_pitch );
+ outf( DP_SRC, pATIHW->dp_src );
+ outf( DP_MIX, pATIHW->dp_mix );
+ outf( DP_FRGD_CLR, pATIHW->dp_frgd_clr );
+ outf( DP_WRITE_MASK, pATIHW->dp_write_mask );
+ outf( DP_PIX_WIDTH, pATIHW->dp_pix_width );
+
+ outf( CLR_CMP_CNTL, pATIHW->clr_cmp_cntl );
+
+ offset = TEX_LEVEL(pATIHW->tex_size_pitch);
+
+ ATIMach64WaitForFIFO(pATI, 6);
+ outf( ALPHA_TST_CNTL, 0 );
+ outf( Z_CNTL, 0 );
+ outf( SCALE_3D_CNTL, pATIHW->scale_3d_cntl );
+ outf( TEX_0_OFF + offset, pATIHW->tex_offset );
+ outf( TEX_SIZE_PITCH, pATIHW->tex_size_pitch );
+ outf( TEX_CNTL, pATIHW->tex_cntl );
+
+ ATIMach64WaitForFIFO(pATI, 2);
+ outf( SC_LEFT_RIGHT,
+ SetWord(pATIHW->sc_right, 1) | SetWord(pATIHW->sc_left, 0) );
+ outf( SC_TOP_BOTTOM,
+ SetWord(pATIHW->sc_bottom, 1) | SetWord(pATIHW->sc_top, 0) );
+
+ if (pATI->OptionMMIOCache) {
+ /* Now that the cache slots reflect the register state, re-enable MMIO cache */
+ CacheRegister(SRC_CNTL);
+ CacheRegister(SCALE_3D_CNTL);
+ CacheRegister(HOST_CNTL);
+ CacheRegister(PAT_CNTL);
+ CacheRegister(SC_LEFT_RIGHT);
+ CacheRegister(SC_TOP_BOTTOM);
+ CacheRegister(DP_BKGD_CLR);
+ CacheRegister(DP_FRGD_CLR);
+ CacheRegister(DP_PIX_WIDTH);
+ CacheRegister(DP_MIX);
+ CacheRegister(CLR_CMP_CNTL);
+ CacheRegister(TEX_SIZE_PITCH);
+ }
+
+ ATIMach64WaitForIdle(pATI);
+
+ if (pATI->OptionMMIOCache && pATI->OptionTestMMIOCache) {
+
+ /* Only check registers we didn't restore */
+ TestRegisterCaching(PAT_REG0);
+ TestRegisterCaching(PAT_REG1);
+
+ TestRegisterCaching(CLR_CMP_CLR);
+ TestRegisterCaching(CLR_CMP_MSK);
+
+ TestRegisterCachingXV(pScreenInfo);
+ }
+ pATI->NeedDRISync = FALSE;
+
+ }
+ else
+
+#endif /* XF86DRI_DEVEL */
+ {
+ ATIMach64WaitForIdle(pATI);
+
+ if (pATI->OptionMMIOCache && pATI->OptionTestMMIOCache)
+ {
+ /*
+ * For debugging purposes, attempt to verify that each cached register
+ * should actually be cached.
+ */
+ TestRegisterCachingDP(pScreenInfo);
+
+ TestRegisterCachingXV(pScreenInfo);
+ }
+ }
+
+#ifdef USE_EXA
+ /* EXA sets pEXA->needsSync to FALSE on its own */
+#endif
+
+#ifdef USE_XAA
+ if (pATI->pXAAInfo)
+ pATI->pXAAInfo->NeedToSync = FALSE;
+#endif
+
+ if (pATI->Chip >= ATI_CHIP_264VTB)
+ {
+ /*
+ * Flush the read-back cache (by turning on INVALIDATE_RB_CACHE),
+ * otherwise the host might get stale data when reading through the
+ * aperture.
+ */
+ outr(MEM_BUF_CNTL, pATI->NewHW.mem_buf_cntl);
+ }
+
+ /*
+ * Note:
+ * Before actually invalidating the read-back cache, the mach64 driver
+ * was using the trick below which is buggy. The code is left here for
+ * reference, DRI uses this trick and needs updating.
+ *
+ * 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;
+ */
+}
+
+static __inline__ void
+TestRegisterCachingDP(ScrnInfoPtr pScreenInfo)
+{
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ TestRegisterCaching(SRC_CNTL);
+
+ if (pATI->Chip >= ATI_CHIP_264GTPRO)
+ {
+ TestRegisterCaching(SCALE_3D_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_PIX_WIDTH);
+ TestRegisterCaching(DP_MIX);
+
+ TestRegisterCaching(CLR_CMP_CLR);
+ TestRegisterCaching(CLR_CMP_MSK);
+ TestRegisterCaching(CLR_CMP_CNTL);
+
+ if (pATI->Chip >= ATI_CHIP_264GTPRO)
+ {
+ TestRegisterCaching(TEX_SIZE_PITCH);
+ }
+}
+
+static __inline__ void
+TestRegisterCachingXV(ScrnInfoPtr pScreenInfo)
+{
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ if (!pATI->Block1Base)
+ return;
+
+ 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);
+
+ return;
+ }
+
+ 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)
+ return;
+
+ 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);
+}
+
+#ifdef USE_XAA
+/*
+ * 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);
+
+ ATIDRISync(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;
+
+ ATIDRISync(pScreenInfo);
+
+ /* 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));
+
+ /*
+ * On VTB's and later, the engine will randomly not wait for a copy
+ * operation to commit its results to video memory before starting the next
+ * one. The probability of such occurrences increases with GUI_WB_FLUSH
+ * (or GUI_WB_FLUSH_P) setting, bitsPerPixel and/or CRTC clock. This
+ * would point to some kind of video memory bandwidth problem were it noti
+ * for the fact that the problem occurs less often (but still occurs) when
+ * copying larger rectangles.
+ */
+ if ((pATI->Chip >= ATI_CHIP_264VTB) && !pATI->OptionDevel)
+ ATIMach64Sync(pScreenInfo);
+}
+
+/*
+ * 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);
+
+ ATIDRISync(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);
+
+ ATIDRISync(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);
+
+ ATIDRISync(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);
+
+ ATIDRISync(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;
+
+ ATIDRISync(pScreenInfo);
+
+ 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);
+
+ ATIDRISync(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);
+
+ ATIDRISync(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);
+
+ ATIDRISync(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);
+
+ ATIDRISync(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;
+
+ ATIDRISync(pScreenInfo);
+
+ 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.
+ */
+Bool
+ATIMach64AccelInit
+(
+ ScreenPtr pScreen
+)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ XAAInfoRecPtr pXAAInfo;
+
+ if (!(pATI->pXAAInfo = XAACreateInfoRec()))
+ return FALSE;
+
+ pXAAInfo = pATI->pXAAInfo;
+
+ /* This doesn't seem quite right... */
+ if (pATI->XModifier == 1)
+ {
+ pXAAInfo->Flags = PIXMAP_CACHE | OFFSCREEN_PIXMAPS;
+ 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)
+ goto XAAInit;
+
+ /* Solid lines */
+ pXAAInfo->SetupForSolidLine = ATIMach64SetupForSolidLine;
+ pXAAInfo->SubsequentSolidHorVertLine = ATIMach64SubsequentSolidHorVertLine;
+ pXAAInfo->SubsequentSolidBresenhamLine =
+ ATIMach64SubsequentSolidBresenhamLine;
+
+XAAInit:
+ if (!XAAInit(pScreen, pATI->pXAAInfo)) {
+ XAADestroyInfoRec(pATI->pXAAInfo);
+ pATI->pXAAInfo = NULL;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+#endif /* USE_XAA */
diff --git a/driver/xf86-video-mach64/src/atimach64accel.h b/driver/xf86-video-mach64/src/atimach64accel.h
new file mode 100644
index 000000000..a8585d5d9
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atimach64accel.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 "xaa.h"
+#include "exa.h"
+
+#define ATIMach64MaxX 4095
+#define ATIMach64MaxY 16383
+
+#ifdef USE_EXA
+extern Bool ATIMach64ExaInit(ScreenPtr);
+#endif
+#ifdef USE_XAA
+extern Bool ATIMach64AccelInit(ScreenPtr);
+#endif
+extern void ATIMach64Sync(ScrnInfoPtr);
+
+/* atimach64accel.c */
+extern void ATIMach64ValidateClip(ATIPtr, int, int, int, int);
+
+#ifdef USE_EXA
+/* atimach64render.c */
+extern Bool Mach64CheckComposite(int, PicturePtr, PicturePtr, PicturePtr);
+extern Bool Mach64PrepareComposite(int, PicturePtr, PicturePtr, PicturePtr,
+ PixmapPtr, PixmapPtr, PixmapPtr);
+extern void Mach64Composite(PixmapPtr, int, int, int, int, int, int, int, int);
+extern void Mach64DoneComposite(PixmapPtr);
+#endif
+
+#endif /* ___ATIMACH64ACCEL_H___ */
diff --git a/driver/xf86-video-mach64/src/atimach64cursor.c b/driver/xf86-video-mach64/src/atimach64cursor.c
new file mode 100644
index 000000000..a3488bb13
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atimach64cursor.c
@@ -0,0 +1,426 @@
+/*
+ * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "ati.h"
+#include "aticursor.h"
+#include "atimach64accel.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;
+
+#ifdef XF86DRI_DEVEL
+
+ /* XAA Sync requires the DRM lock if DRI enabled */
+ ATIDRILock(pScreenInfo);
+
+#endif /* XF86DRI_DEVEL */
+
+ /* 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
+
+#ifdef XF86DRI_DEVEL
+
+ ATIDRIUnlock(pScreenInfo);
+
+#endif /* XF86DRI_DEVEL */
+
+}
+
+/*
+ * 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;
+
+ return TRUE;
+}
+
+/*
+ * ATIMach64CursorInit --
+ *
+ * Initialise xf86CursorInfoRec fields with information specific to Mach64
+ * variants.
+ */
+Bool
+ATIMach64CursorInit
+(
+ ScreenPtr pScreen
+)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ xf86CursorInfoPtr pCursorInfo;
+
+ /* Initialise software cursor */
+ if (!miDCInitialize(pScreen, xf86GetPointerScreenFuncs()))
+ return FALSE;
+
+ if (pATI->Cursor == ATI_CURSOR_SOFTWARE)
+ return TRUE;
+
+ /* Initialise hardware cursor */
+ if (!(pATI->pCursorInfo = xf86CreateCursorInfoRec()))
+ return FALSE;
+
+ pCursorInfo = pATI->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;
+
+ if (!xf86InitCursor(pScreen, pATI->pCursorInfo))
+ {
+ xf86DestroyCursorInfoRec(pATI->pCursorInfo);
+ pATI->pCursorInfo = NULL;
+ return FALSE;
+ }
+
+ xf86SetSilkenMouse(pScreen);
+ return TRUE;
+}
diff --git a/driver/xf86-video-mach64/src/atimach64exa.c b/driver/xf86-video-mach64/src/atimach64exa.c
new file mode 100644
index 000000000..67c5f223c
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atimach64exa.c
@@ -0,0 +1,696 @@
+/*
+ * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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.
+ */
+/*
+ * DRI support by:
+ * Manuel Teira
+ * Leif Delgass <ldelgass@retinalburn.net>
+ *
+ * EXA support by:
+ * Jakub Stachowski <qbast@go2.pl>
+ * George Sapountzis <gsap7@yahoo.gr>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include "ati.h"
+#include "atichip.h"
+#include "atidri.h"
+#include "atimach64accel.h"
+#include "atimach64io.h"
+#include "atipriv.h"
+#include "atiregs.h"
+
+#ifdef XF86DRI_DEVEL
+#include "mach64_dri.h"
+#include "mach64_sarea.h"
+#endif
+
+#ifdef USE_EXA
+extern CARD8 ATIMach64ALU[];
+
+extern void
+ATIMach64ValidateClip
+(
+ ATIPtr pATI,
+ int sc_left,
+ int sc_right,
+ int sc_top,
+ int sc_bottom
+);
+
+#if 0
+#define MACH64_TRACE(x) \
+do { \
+ ErrorF("Mach64(%s): ", __FUNCTION__); \
+ ErrorF x; \
+} while(0)
+#else
+#define MACH64_TRACE(x) do { } while(0)
+#endif
+
+#if 0
+#define MACH64_FALLBACK(x) \
+do { \
+ ErrorF("Fallback(%s): ", __FUNCTION__); \
+ ErrorF x; \
+ return FALSE; \
+} while (0)
+#else
+#define MACH64_FALLBACK(x) return FALSE
+#endif
+
+static void
+Mach64WaitMarker(ScreenPtr pScreenInfo, int Marker)
+{
+ ATIMach64Sync(xf86Screens[pScreenInfo->myNum]);
+}
+
+static Bool
+Mach64GetDatatypeBpp(PixmapPtr pPix, CARD32 *pix_width)
+{
+ int bpp = pPix->drawable.bitsPerPixel;
+
+ switch (bpp) {
+ case 8:
+ *pix_width =
+ SetBits(PIX_WIDTH_8BPP, DP_DST_PIX_WIDTH) |
+ SetBits(PIX_WIDTH_8BPP, DP_SRC_PIX_WIDTH) |
+ SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH);
+ break;
+ case 16:
+ *pix_width =
+ SetBits(PIX_WIDTH_16BPP, DP_DST_PIX_WIDTH) |
+ SetBits(PIX_WIDTH_16BPP, DP_SRC_PIX_WIDTH) |
+ SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH);
+ break;
+ case 24:
+ *pix_width =
+ SetBits(PIX_WIDTH_8BPP, DP_DST_PIX_WIDTH) |
+ SetBits(PIX_WIDTH_8BPP, DP_SRC_PIX_WIDTH) |
+ SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH);
+ break;
+ case 32:
+ *pix_width =
+ SetBits(PIX_WIDTH_32BPP, DP_DST_PIX_WIDTH) |
+ SetBits(PIX_WIDTH_32BPP, DP_SRC_PIX_WIDTH) |
+ SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH);
+ break;
+ default:
+ MACH64_FALLBACK(("Unsupported bpp: %d\n", bpp));
+ }
+
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
+
+ *pix_width |= DP_BYTE_PIX_ORDER;
+
+#endif /* X_BYTE_ORDER */
+
+ return TRUE;
+}
+
+static Bool
+Mach64GetOffsetPitch(PixmapPtr pPix, int bpp, CARD32 *pitch_offset,
+ unsigned int offset, unsigned int pitch)
+{
+#if 0
+ ScrnInfoPtr pScreenInfo = xf86Screens[pPix->drawable.pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ if (pitch % pATI->pExa->pixmapPitchAlign != 0)
+ MACH64_FALLBACK(("Bad pitch 0x%08x\n", pitch));
+
+ if (offset % pATI->pExa->pixmapOffsetAlign != 0)
+ MACH64_FALLBACK(("Bad offset 0x%08x\n", offset));
+#endif
+
+ /* pixels / 8 = ((bytes * 8) / bpp) / 8 = bytes / bpp */
+ pitch = pitch / bpp;
+
+ /* bytes / 8 */
+ offset = offset >> 3;
+
+ *pitch_offset = ((pitch << 22) | (offset << 0));
+
+ return TRUE;
+}
+
+static Bool
+Mach64GetPixmapOffsetPitch(PixmapPtr pPix, CARD32 *pitch_offset)
+{
+ CARD32 pitch, offset;
+ int bpp;
+
+ bpp = pPix->drawable.bitsPerPixel;
+ if (bpp == 24)
+ bpp = 8;
+
+ pitch = exaGetPixmapPitch(pPix);
+ offset = exaGetPixmapOffset(pPix);
+
+ return Mach64GetOffsetPitch(pPix, bpp, pitch_offset, offset, pitch);
+}
+
+static Bool
+Mach64PrepareCopy
+(
+ PixmapPtr pSrcPixmap,
+ PixmapPtr pDstPixmap,
+ int xdir,
+ int ydir,
+ int alu,
+ Pixel planemask
+)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ CARD32 src_pitch_offset, dst_pitch_offset, dp_pix_width;
+
+ ATIDRISync(pScreenInfo);
+
+ if (!Mach64GetDatatypeBpp(pDstPixmap, &dp_pix_width))
+ return FALSE;
+ if (!Mach64GetPixmapOffsetPitch(pSrcPixmap, &src_pitch_offset))
+ return FALSE;
+ if (!Mach64GetPixmapOffsetPitch(pDstPixmap, &dst_pitch_offset))
+ return FALSE;
+
+ ATIMach64WaitForFIFO(pATI, 7);
+ outf(DP_WRITE_MASK, planemask);
+ outf(DP_PIX_WIDTH, dp_pix_width);
+ outf(SRC_OFF_PITCH, src_pitch_offset);
+ outf(DST_OFF_PITCH, dst_pitch_offset);
+
+ outf(DP_SRC, DP_MONO_SRC_ALLONES |
+ SetBits(SRC_BLIT, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC));
+ outf(DP_MIX, SetBits(ATIMach64ALU[alu], DP_FRGD_MIX));
+
+ outf(CLR_CMP_CNTL, CLR_CMP_FN_FALSE);
+
+ 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;
+
+ return TRUE;
+}
+
+static void
+Mach64Copy
+(
+ PixmapPtr pDstPixmap,
+ int srcX,
+ int srcY,
+ int dstX,
+ int dstY,
+ int w,
+ int h
+)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ srcX *= pATI->XModifier;
+ dstY *= pATI->XModifier;
+ w *= pATI->XModifier;
+
+ ATIDRISync(pScreenInfo);
+
+ /* Disable clipping if it gets in the way */
+ ATIMach64ValidateClip(pATI, dstX, dstX + w - 1, dstY, dstY + h - 1);
+
+ if (!(pATI->dst_cntl & DST_X_DIR))
+ {
+ srcX += w - 1;
+ dstX += w - 1;
+ }
+
+ if (!(pATI->dst_cntl & DST_Y_DIR))
+ {
+ srcY += h - 1;
+ dstY += h - 1;
+ }
+
+ if (pATI->XModifier != 1)
+ outf(DST_CNTL, pATI->dst_cntl | SetBits((dstX / 4) % 6, DST_24_ROT));
+
+ ATIMach64WaitForFIFO(pATI, 4);
+ outf(SRC_Y_X, SetWord(srcX, 1) | SetWord(srcY, 0));
+ outf(SRC_WIDTH1, w);
+ outf(DST_Y_X, SetWord(dstX, 1) | SetWord(dstY, 0));
+ outf(DST_HEIGHT_WIDTH, SetWord(w, 1) | SetWord(h, 0));
+
+ /*
+ * On VTB's and later, the engine will randomly not wait for a copy
+ * operation to commit its results to video memory before starting the next
+ * one. The probability of such occurrences increases with GUI_WB_FLUSH
+ * (or GUI_WB_FLUSH_P) setting, bitsPerPixel and/or CRTC clock. This
+ * would point to some kind of video memory bandwidth problem were it noti
+ * for the fact that the problem occurs less often (but still occurs) when
+ * copying larger rectangles.
+ */
+ if ((pATI->Chip >= ATI_CHIP_264VTB) && !pATI->OptionDevel)
+ {
+ exaMarkSync(pScreenInfo->pScreen); /* Force sync. */
+ exaWaitSync(pScreenInfo->pScreen); /* Sync and notify EXA. */
+ }
+}
+
+static void Mach64DoneCopy(PixmapPtr pDstPixmap) { }
+
+static Bool
+Mach64PrepareSolid
+(
+ PixmapPtr pPixmap,
+ int alu,
+ Pixel planemask,
+ Pixel fg
+)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pPixmap->drawable.pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ CARD32 dst_pitch_offset, dp_pix_width;
+
+ ATIDRISync(pScreenInfo);
+
+ if (!Mach64GetDatatypeBpp(pPixmap, &dp_pix_width))
+ return FALSE;
+ if (!Mach64GetPixmapOffsetPitch(pPixmap, &dst_pitch_offset))
+ return FALSE;
+
+ ATIMach64WaitForFIFO(pATI, 7);
+ outf(DP_WRITE_MASK, planemask);
+ outf(DP_PIX_WIDTH, dp_pix_width);
+ outf(DST_OFF_PITCH, dst_pitch_offset);
+
+ outf(DP_SRC, DP_MONO_SRC_ALLONES |
+ SetBits(SRC_FRGD, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC));
+ outf(DP_FRGD_CLR, fg);
+ outf(DP_MIX, SetBits(ATIMach64ALU[alu], DP_FRGD_MIX));
+
+ outf(CLR_CMP_CNTL, CLR_CMP_FN_FALSE);
+
+ if (pATI->XModifier == 1)
+ outf(DST_CNTL, DST_X_DIR | DST_Y_DIR);
+
+ return TRUE;
+}
+
+static void
+Mach64Solid
+(
+ PixmapPtr pPixmap,
+ int x1,
+ int y1,
+ int x2,
+ int y2
+)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pPixmap->drawable.pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ int x = x1;
+ int y = y1;
+ int w = x2-x1;
+ int h = y2-y1;
+
+ ATIDRISync(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));
+}
+
+static void Mach64DoneSolid(PixmapPtr pPixmap) { }
+
+/*
+ * Memcpy-based UTS.
+ */
+static Bool
+Mach64UploadToScreen(PixmapPtr pDst, int x, int y, int w, int h,
+ char *src, int src_pitch)
+{
+ char *dst = pDst->devPrivate.ptr;
+ int dst_pitch = exaGetPixmapPitch(pDst);
+
+ int bpp = pDst->drawable.bitsPerPixel;
+ int cpp = (bpp + 7) / 8;
+ int wBytes = w * cpp;
+
+ exaWaitSync(pDst->drawable.pScreen);
+
+ dst += (x * cpp) + (y * dst_pitch);
+
+ while (h--) {
+ memcpy(dst, src, wBytes);
+ src += src_pitch;
+ dst += dst_pitch;
+ }
+
+ return TRUE;
+}
+
+/*
+ * Memcpy-based DFS.
+ */
+static Bool
+Mach64DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h,
+ char *dst, int dst_pitch)
+{
+ char *src = pSrc->devPrivate.ptr;
+ int src_pitch = exaGetPixmapPitch(pSrc);
+
+ int bpp = pSrc->drawable.bitsPerPixel;
+ int cpp = (bpp + 7) / 8;
+ int wBytes = w * cpp;
+
+ exaWaitSync(pSrc->drawable.pScreen);
+
+ src += (x * cpp) + (y * src_pitch);
+
+ while (h--) {
+ memcpy(dst, src, wBytes);
+ src += src_pitch;
+ dst += dst_pitch;
+ }
+
+ return TRUE;
+}
+
+#include "atimach64render.c"
+
+/* Compute log base 2 of val. */
+static __inline__ int Mach64Log2(int val)
+{
+ int bits;
+
+ for (bits = 0; val != 0; val >>= 1, ++bits)
+ ;
+ return bits - 1;
+}
+
+/*
+ * Memory layour for EXA with DRI (no local_textures):
+ * | front | back | depth | textures | pixmaps, xv | c |
+ *
+ * 1024x768@16bpp with 8 MB:
+ * | 1.5 MB | 1.5 MB | 1.5 MB | 0 | ~3.5 MB | c |
+ *
+ * 1024x768@32bpp with 8 MB:
+ * | 3.0 MB | 3.0 MB | 1.5 MB | 0 | ~0.5 MB | c |
+ *
+ * "c" is the hw cursor which occupies 1KB
+ */
+static void
+Mach64SetupMemEXA(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ int cpp = (pScreenInfo->bitsPerPixel + 7) / 8;
+ /* front and back buffer */
+ int bufferSize = pScreenInfo->virtualY * pScreenInfo->displayWidth * cpp;
+ /* always 16-bit z-buffer */
+ int depthSize = pScreenInfo->virtualY * pScreenInfo->displayWidth * 2;
+
+ ExaDriverPtr pExa = pATI->pExa;
+
+ pExa->memoryBase = pATI->pMemory;
+ pExa->memorySize = pScreenInfo->videoRam * 1024;
+ pExa->offScreenBase = bufferSize;
+
+#ifdef XF86DRI_DEVEL
+ if (pATI->directRenderingEnabled)
+ {
+ ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
+ Bool is_pci = pATIDRIServer->IsPCI;
+
+ int textureSize = 0;
+ int pixmapCache = 0;
+ int next = 0;
+
+ /* front buffer */
+ pATIDRIServer->frontOffset = 0;
+ pATIDRIServer->frontPitch = pScreenInfo->displayWidth;
+ next += bufferSize;
+
+ /* back buffer */
+ pATIDRIServer->backOffset = next;
+ pATIDRIServer->backPitch = pScreenInfo->displayWidth;
+ next += bufferSize;
+
+ /* depth buffer */
+ pATIDRIServer->depthOffset = next;
+ pATIDRIServer->depthPitch = pScreenInfo->displayWidth;
+ next += depthSize;
+
+ /* ATIScreenInit does check for the this condition. */
+ if (next > pExa->memorySize)
+ {
+ xf86DrvMsg(pScreen->myNum, X_WARNING,
+ "DRI static buffer allocation failed, disabling DRI --"
+ "need at least %d kB video memory\n", next / 1024 );
+ ATIDRICloseScreen(pScreen);
+ pATI->directRenderingEnabled = FALSE;
+ }
+
+ /* local textures */
+
+ /* Reserve approx. half of offscreen memory for local textures */
+ textureSize = (pExa->memorySize - next) / 2;
+
+ /* In case DRI requires more offscreen memory than available,
+ * should not happen as ATIScreenInit would have not enabled DRI */
+ if (textureSize < 0)
+ textureSize = 0;
+
+ /* Try for enough pixmap cache for a full viewport */
+ pixmapCache = (pExa->memorySize - next) - textureSize;
+ if (pixmapCache < bufferSize)
+ textureSize = 0;
+
+ /* Don't allocate a local texture heap for AGP unless requested */
+ if ( !is_pci && !pATI->OptionLocalTextures )
+ textureSize = 0;
+
+ if (textureSize > 0)
+ {
+ int l = Mach64Log2(textureSize / MACH64_NR_TEX_REGIONS);
+ if (l < MACH64_LOG_TEX_GRANULARITY)
+ l = MACH64_LOG_TEX_GRANULARITY;
+ pATIDRIServer->logTextureGranularity = l;
+
+ /* Round the texture size down to the nearest whole number of
+ * texture regions.
+ */
+ textureSize = (textureSize >> l) << l;
+ }
+
+ /* Set a minimum usable local texture heap size. This will fit
+ * two 256x256 textures. We check this after any rounding of
+ * the texture area.
+ */
+ if (textureSize < 256*256 * cpp * 2)
+ textureSize = 0;
+
+ /* Disable DRI for PCI if cannot allocate a local texture heap */
+ if ( is_pci && textureSize == 0 )
+ {
+ xf86DrvMsg(pScreen->myNum, X_WARNING,
+ "Not enough memory for local textures, disabling DRI\n");
+ ATIDRICloseScreen(pScreen);
+ pATI->directRenderingEnabled = FALSE;
+ }
+
+ pATIDRIServer->textureOffset = next;
+ pATIDRIServer->textureSize = textureSize;
+ next += textureSize;
+
+ /* pExa->offScreenBase is moved to `next' when DRI gets activated */
+ }
+#endif /* XF86DRI_DEVEL */
+
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "EXA memory management initialized\n"
+ "\t base : %10p\n"
+ "\t offscreen: +%10lx\n"
+ "\t size : +%10lx\n"
+ "\t cursor : %10p\n",
+ pExa->memoryBase,
+ pExa->offScreenBase,
+ pExa->memorySize,
+ pATI->pCursorImage);
+
+ if (TRUE || xf86GetVerbosity() > 1)
+ {
+ int offscreen = pExa->memorySize - pExa->offScreenBase;
+ int viewport = bufferSize;
+ int dvdframe = 720*480*cpp; /* enough for single-buffered DVD */
+
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "Will use %d kB of offscreen memory for EXA\n"
+ "\t\t or %5.2f viewports (composite)\n"
+ "\t\t or %5.2f dvdframes (xvideo)\n",
+ offscreen / 1024,
+ 1.0 * offscreen / viewport,
+ 1.0 * offscreen / dvdframe);
+ }
+
+#ifdef XF86DRI_DEVEL
+ if (pATI->directRenderingEnabled)
+ {
+ ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
+
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "Will use back buffer at offset 0x%x\n",
+ pATIDRIServer->backOffset);
+
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "Will use depth buffer at offset 0x%x\n",
+ pATIDRIServer->depthOffset);
+
+ if (pATIDRIServer->textureSize > 0)
+ {
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "Will use %d kB for local textures at offset 0x%x\n",
+ pATIDRIServer->textureSize/1024,
+ pATIDRIServer->textureOffset);
+ }
+ }
+#endif /* XF86DRI_DEVEL */
+
+ pExa->pixmapOffsetAlign = 64;
+ pExa->pixmapPitchAlign = 64;
+
+ pExa->flags = EXA_OFFSCREEN_PIXMAPS;
+
+ pExa->maxX = ATIMach64MaxX;
+ pExa->maxY = ATIMach64MaxY;
+}
+
+Bool ATIMach64ExaInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ ExaDriverPtr pExa;
+
+ pExa = exaDriverAlloc();
+ if (!pExa)
+ return FALSE;
+
+ pATI->pExa = pExa;
+
+ pExa->exa_major = 2;
+ pExa->exa_minor = 0;
+
+ Mach64SetupMemEXA(pScreen);
+
+ pExa->WaitMarker = Mach64WaitMarker;
+
+ pExa->PrepareSolid = Mach64PrepareSolid;
+ pExa->Solid = Mach64Solid;
+ pExa->DoneSolid = Mach64DoneSolid;
+
+ pExa->PrepareCopy = Mach64PrepareCopy;
+ pExa->Copy = Mach64Copy;
+ pExa->DoneCopy = Mach64DoneCopy;
+
+ /* EXA hits more optimized paths when it does not have to fallback because
+ * of missing UTS/DFS, hook memcpy-based UTS/DFS.
+ */
+ pExa->UploadToScreen = Mach64UploadToScreen;
+ pExa->DownloadFromScreen = Mach64DownloadFromScreen;
+
+ if (pATI->RenderAccelEnabled) {
+ if (pATI->Chip >= ATI_CHIP_264GTPRO) {
+ /* 3D Rage Pro does not support NPOT textures. */
+ pExa->flags |= EXA_OFFSCREEN_ALIGN_POT;
+
+ pExa->CheckComposite = Mach64CheckComposite;
+ pExa->PrepareComposite = Mach64PrepareComposite;
+ pExa->Composite = Mach64Composite;
+ pExa->DoneComposite = Mach64DoneComposite;
+ } else {
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "Render acceleration is not supported for ATI chips "
+ "earlier than the ATI 3D Rage Pro.\n");
+ pATI->RenderAccelEnabled = FALSE;
+ }
+ }
+
+ xf86DrvMsg(pScreen->myNum, X_INFO, "Render acceleration %s\n",
+ pATI->RenderAccelEnabled ? "enabled" : "disabled");
+
+ if (!exaDriverInit(pScreen, pATI->pExa)) {
+ xfree(pATI->pExa);
+ pATI->pExa = NULL;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+#endif
diff --git a/driver/xf86-video-mach64/src/atimach64i2c.c b/driver/xf86-video-mach64/src/atimach64i2c.c
new file mode 100644
index 000000000..0f7d797ea
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atimach64i2c.c
@@ -0,0 +1,469 @@
+/*
+ * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#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;
+ }
+}
diff --git a/driver/xf86-video-mach64/src/atimach64i2c.h b/driver/xf86-video-mach64/src/atimach64i2c.h
new file mode 100644
index 000000000..a9f98a9ee
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atimach64i2c.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 "xf86str.h"
+
+extern void ATIMach64I2CPreInit(ScrnInfoPtr, ATIPtr);
+
+#endif /* ___ATIMACH64I2C_H___ */
diff --git a/driver/xf86-video-mach64/src/atimach64io.c b/driver/xf86-video-mach64/src/atimach64io.c
new file mode 100644
index 000000000..bfbdd3d8b
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atimach64io.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#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().
+ */
+ 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;
+}
diff --git a/driver/xf86-video-mach64/src/atimach64io.h b/driver/xf86-video-mach64/src/atimach64io.h
new file mode 100644
index 000000000..d1b14d248
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atimach64io.h
@@ -0,0 +1,421 @@
+/*
+ * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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.
+ *
+ * DRI support by:
+ * Manuel Teira
+ * Leif Delgass <ldelgass@retinalburn.net>
+ */
+
+#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 "atiregs.h"
+#include "atistruct.h"
+
+#include "compiler.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.
+ *
+ * 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).
+ */
+
+/* I/O decoding definitions */
+typedef enum
+{
+ SPARSE_IO,
+ BLOCK_IO
+} ATIIODecodingType;
+
+#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 inl
+#undef outb
+#undef outl
+
+#define inb() /* Nothing */
+#define inl() /* Nothing */
+#define outb() /* 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(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)
+
+#ifdef XF86DRI_DEVEL
+
+/*
+ * DRI Sync and Lock definitions.
+ */
+
+#define ATIDRIWaitForIdle(_pATI) \
+do { \
+ ATIDRIServerInfoPtr pATIDRIServer = _pATI->pDRIServerInfo; \
+ int ret; \
+ \
+ if (pATIDRIServer && pATI->directRenderingEnabled) { \
+ /* Wait for DMA to complete */ \
+ ret = drmCommandNone(_pATI->drmFD, DRM_MACH64_IDLE); \
+ if (ret) { \
+ drmCommandNone(_pATI->drmFD, DRM_MACH64_RESET); \
+ } \
+ \
+ /* Force updating of FIFO entry counters */ \
+ pATI->EngineIsBusy = TRUE; \
+ ATIMach64PollEngineStatus(_pATI); \
+ } else { \
+ ATIMach64WaitForIdle(_pATI); \
+ } \
+} while (0)
+
+/*
+ * Set upon DRISwapContext and when DRI accesses the GPU engine
+ * from within the server, see DRIInitBuffers/DRIMoveBuffers.
+ *
+ * Forces the EXA/XAA software paths to sync before accessing the FB memory.
+ */
+static __inline__ void ATIDRIMarkSyncInt(ScrnInfoPtr _pScrInfo)
+{
+ ATIPtr _pATI=ATIPTR(_pScrInfo);
+#ifdef USE_EXA
+ if (_pATI->useEXA)
+ exaMarkSync(_pScrInfo->pScreen);
+#endif
+#ifdef USE_XAA
+ if (!_pATI->useEXA)
+ SET_SYNC_FLAG(_pATI->pXAAInfo); /* NeedToSync = TRUE */
+#endif
+}
+
+/*
+ * Set upon DRISwapContext and when the server acquires the DRI lock.
+ *
+ * Forces the EXA/XAA accelerated paths to sync before accessing the GPU engine.
+ */
+static __inline__ void ATIDRIMarkSyncExt(ScrnInfoPtr _pScrInfo)
+{
+ ATIPtr _pATI=ATIPTR(_pScrInfo);
+ _pATI->NeedDRISync = TRUE;
+}
+
+static __inline__ void ATIDRISync(ScrnInfoPtr _pScrInfo)
+{
+ ATIPtr _pATI=ATIPTR(_pScrInfo);
+#ifdef USE_EXA
+ if (_pATI->directRenderingEnabled && _pATI->pExa)
+ {
+ if (_pATI->NeedDRISync) exaWaitSync(_pScrInfo->pScreen);
+ }
+#endif
+#ifdef USE_XAA
+ if (_pATI->directRenderingEnabled && _pATI->pXAAInfo)
+ {
+ if (_pATI->NeedDRISync) (*_pATI->pXAAInfo->Sync)(_pScrInfo);
+ }
+#endif
+}
+
+#define ATIDRILock(_pScrInfo) \
+do \
+{ \
+ ATIPtr _pATI=ATIPTR(_pScrInfo); \
+ if (_pATI->directRenderingEnabled) \
+ { \
+ DRILock(_pScrInfo->pScreen, 0); \
+ ATIDRIMarkSyncExt(_pScrInfo); \
+ } \
+} while (0)
+
+#define ATIDRIUnlock(_pScrInfo) \
+do \
+{ \
+ ATIPtr _pATI=ATIPTR(_pScrInfo); \
+ if (_pATI->directRenderingEnabled) \
+ { \
+ DRIUnlock(_pScrInfo->pScreen); \
+ } \
+} while (0)
+
+#else /* XF86DRI_DEVEL */
+
+
+#define ATIDRIWaitForIdle(_pATI)
+#define ATIDRILock(_pScrInfo)
+#define ATIDRIUnlock(_pScrInfo)
+#define ATIDRISync(_pScrInfo)
+
+#endif /* XF86DRI_DEVEL */
+
+
+/*
+ * 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(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
+
+/*
+ * Return the MMIO address of register, used for HOST_DATA_X only.
+ */
+#define ATIHostDataAddr(_Register) \
+ ((CARD8 *)pATI->pBlock[GetBits(_Register, BLOCK_SELECT)] + \
+ ((_Register) & MM_IO_SELECT))
+
+#endif /* ___ATIMACH64IO_H___ */
diff --git a/driver/xf86-video-mach64/src/atimach64probe.c b/driver/xf86-video-mach64/src/atimach64probe.c
new file mode 100644
index 000000000..2d554e16f
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atimach64probe.c
@@ -0,0 +1,289 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "ati.h"
+#include "atichip.h"
+#include "atimach64io.h"
+#include "atimach64probe.h"
+#include "atimach64version.h"
+#include "atioption.h"
+
+/* include headers corresponding to ScrnInfoPtr fields */
+#include "atipreinit.h"
+#include "atiscreen.h"
+#include "aticonsole.h"
+#include "atiadjust.h"
+#include "ativalid.h"
+
+#ifndef XSERVER_LIBPCIACCESS
+static Bool Mach64Probe(DriverPtr pDriver, int flags);
+#endif
+
+SymTabRec
+Mach64Chipsets[] = {
+ {ATI_CHIP_88800GXC, "ATI 88800GX-C"},
+ {ATI_CHIP_88800GXD, "ATI 88800GX-D"},
+ {ATI_CHIP_88800GXE, "ATI 88800GX-E"},
+ {ATI_CHIP_88800GXF, "ATI 88800GX-F"},
+ {ATI_CHIP_88800GX, "ATI 88800GX"},
+ {ATI_CHIP_88800CX, "ATI 88800CX"},
+ {ATI_CHIP_264CT, "ATI 264CT"},
+ {ATI_CHIP_264ET, "ATI 264ET"},
+ {ATI_CHIP_264VT, "ATI 264VT"},
+ {ATI_CHIP_264VTB, "ATI 264VT-B"},
+ {ATI_CHIP_264GT, "ATI 3D Rage"},
+ {ATI_CHIP_264GTB, "ATI 3D Rage II"},
+ {ATI_CHIP_264VT3, "ATI 264VT3"},
+ {ATI_CHIP_264GTDVD, "ATI 3D Rage II+DVD"},
+ {ATI_CHIP_264LT, "ATI 3D Rage LT"},
+ {ATI_CHIP_264VT4, "ATI 264VT4"},
+ {ATI_CHIP_264GT2C, "ATI 3D Rage IIc"},
+ {ATI_CHIP_264GTPRO, "ATI 3D Rage Pro"},
+ {ATI_CHIP_264LTPRO, "ATI 3D Rage LT Pro"},
+ {ATI_CHIP_264XL, "ATI 3D Rage XL or XC"},
+ {ATI_CHIP_MOBILITY, "ATI 3D Rage Mobility"},
+ {-1, NULL }
+};
+
+/*
+ * This table maps a PCI device ID to a chipset family identifier.
+ */
+static PciChipsets
+Mach64PciChipsets[] = {
+ {ATI_CHIP_88800GX, PCI_CHIP_MACH64GX, RES_SHARED_VGA},
+ {ATI_CHIP_88800CX, PCI_CHIP_MACH64CX, RES_SHARED_VGA},
+ {ATI_CHIP_264CT, PCI_CHIP_MACH64CT, RES_SHARED_VGA},
+ {ATI_CHIP_264ET, PCI_CHIP_MACH64ET, RES_SHARED_VGA},
+ {ATI_CHIP_264VT, PCI_CHIP_MACH64VT, RES_SHARED_VGA},
+ {ATI_CHIP_264GT, PCI_CHIP_MACH64GT, RES_SHARED_VGA},
+ {ATI_CHIP_264VT3, PCI_CHIP_MACH64VU, RES_SHARED_VGA},
+ {ATI_CHIP_264GTDVD, PCI_CHIP_MACH64GU, RES_SHARED_VGA},
+ {ATI_CHIP_264LT, PCI_CHIP_MACH64LG, RES_SHARED_VGA},
+ {ATI_CHIP_264VT4, PCI_CHIP_MACH64VV, RES_SHARED_VGA},
+ {ATI_CHIP_264GT2C, PCI_CHIP_MACH64GV, RES_SHARED_VGA},
+ {ATI_CHIP_264GT2C, PCI_CHIP_MACH64GW, RES_SHARED_VGA},
+ {ATI_CHIP_264GT2C, PCI_CHIP_MACH64GY, RES_SHARED_VGA},
+ {ATI_CHIP_264GT2C, PCI_CHIP_MACH64GZ, RES_SHARED_VGA},
+ {ATI_CHIP_264GTPRO, PCI_CHIP_MACH64GB, RES_SHARED_VGA},
+ {ATI_CHIP_264GTPRO, PCI_CHIP_MACH64GD, RES_SHARED_VGA},
+ {ATI_CHIP_264GTPRO, PCI_CHIP_MACH64GI, RES_SHARED_VGA},
+ {ATI_CHIP_264GTPRO, PCI_CHIP_MACH64GP, RES_SHARED_VGA},
+ {ATI_CHIP_264GTPRO, PCI_CHIP_MACH64GQ, RES_SHARED_VGA},
+ {ATI_CHIP_264LTPRO, PCI_CHIP_MACH64LB, RES_SHARED_VGA},
+ {ATI_CHIP_264LTPRO, PCI_CHIP_MACH64LD, RES_SHARED_VGA},
+ {ATI_CHIP_264LTPRO, PCI_CHIP_MACH64LI, RES_SHARED_VGA},
+ {ATI_CHIP_264LTPRO, PCI_CHIP_MACH64LP, RES_SHARED_VGA},
+ {ATI_CHIP_264LTPRO, PCI_CHIP_MACH64LQ, RES_SHARED_VGA},
+ {ATI_CHIP_264XL, PCI_CHIP_MACH64GL, RES_SHARED_VGA},
+ {ATI_CHIP_264XL, PCI_CHIP_MACH64GM, RES_SHARED_VGA},
+ {ATI_CHIP_264XL, PCI_CHIP_MACH64GN, RES_SHARED_VGA},
+ {ATI_CHIP_264XL, PCI_CHIP_MACH64GO, RES_SHARED_VGA},
+ {ATI_CHIP_264XL, PCI_CHIP_MACH64GR, RES_SHARED_VGA},
+ {ATI_CHIP_264XL, PCI_CHIP_MACH64GS, RES_SHARED_VGA},
+ {ATI_CHIP_MOBILITY, PCI_CHIP_MACH64LM, RES_SHARED_VGA},
+ {ATI_CHIP_MOBILITY, PCI_CHIP_MACH64LN, RES_SHARED_VGA},
+ {ATI_CHIP_MOBILITY, PCI_CHIP_MACH64LR, RES_SHARED_VGA},
+ {ATI_CHIP_MOBILITY, PCI_CHIP_MACH64LS, RES_SHARED_VGA},
+ {-1, -1, RES_UNDEFINED}
+};
+
+#ifdef XSERVER_LIBPCIACCESS
+
+static const struct pci_id_match mach64_device_match[] = {
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64GX, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64CX, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64CT, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64ET, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64VT, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64GT, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64VU, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64GU, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64LG, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64VV, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64GV, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64GW, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64GY, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64GZ, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64GB, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64GD, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64GI, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64GP, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64GQ, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64LB, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64LD, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64LI, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64LP, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64LQ, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64GL, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64GM, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64GN, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64GO, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64GR, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64GS, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64LM, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64LN, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64LR, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_MACH64LS, 0 ),
+ { 0, 0, 0 }
+};
+
+#endif /* XSERVER_LIBPCIACCESS */
+
+static const OptionInfoRec *
+Mach64AvailableOptions(int chipid, int busid)
+{
+ return ATIOptionsWeak();
+}
+
+/*
+ * Mach64Identify --
+ *
+ * Print the driver's list of chipset names.
+ */
+static void
+Mach64Identify
+(
+ int flags
+)
+{
+ xf86Msg(X_INFO, "%s: %s\n", MACH64_NAME,
+ "Driver for ATI Mach64 chipsets");
+}
+
+static Bool
+mach64_get_scrninfo(int entity_num)
+{
+ ScrnInfoPtr pScrn;
+
+ pScrn = xf86ConfigPciEntity(NULL, 0, entity_num, Mach64PciChipsets,
+ 0, 0, 0, 0, NULL);
+
+ if (!pScrn)
+ return FALSE;
+
+ pScrn->driverVersion = MACH64_VERSION_CURRENT;
+ pScrn->driverName = MACH64_DRIVER_NAME;
+ pScrn->name = MACH64_NAME;
+#ifdef XSERVER_LIBPCIACCESS
+ pScrn->Probe = NULL;
+#else
+ pScrn->Probe = Mach64Probe;
+#endif
+ pScrn->PreInit = ATIPreInit;
+ pScrn->ScreenInit = ATIScreenInit;
+ pScrn->SwitchMode = ATISwitchMode;
+ pScrn->AdjustFrame = ATIAdjustFrame;
+ pScrn->EnterVT = ATIEnterVT;
+ pScrn->LeaveVT = ATILeaveVT;
+ pScrn->FreeScreen = ATIFreeScreen;
+ pScrn->ValidMode = ATIValidMode;
+
+ return TRUE;
+}
+
+#ifndef XSERVER_LIBPCIACCESS
+
+/*
+ * Mach64Probe --
+ *
+ * This function is called once, at the start of the first server generation to
+ * do a minimal probe for supported hardware.
+ */
+static Bool
+Mach64Probe(DriverPtr pDriver, int flags)
+{
+ GDevPtr *devSections;
+ int *usedChips;
+ int numDevSections;
+ int numUsed;
+ Bool ProbeSuccess = FALSE;
+ int i;
+
+ if (xf86GetPciVideoInfo() == NULL)
+ return FALSE;
+
+ numDevSections = xf86MatchDevice(MACH64_DRIVER_NAME, &devSections);
+
+ if (numDevSections <= 0)
+ return FALSE;
+
+ numUsed = xf86MatchPciInstances(MACH64_NAME, PCI_VENDOR_ATI,
+ Mach64Chipsets, Mach64PciChipsets,
+ devSections, numDevSections,
+ pDriver, &usedChips);
+ xfree(devSections);
+
+ if (numUsed <= 0)
+ return FALSE;
+
+ if (flags & PROBE_DETECT) {
+ ProbeSuccess = TRUE;
+ } else {
+ for (i = 0; i < numUsed; i++) {
+ if (mach64_get_scrninfo(usedChips[i]))
+ ProbeSuccess = TRUE;
+ }
+ }
+
+ xfree(usedChips);
+
+ return ProbeSuccess;
+}
+
+#else /* XSERVER_LIBPCIACCESS */
+
+static Bool
+mach64_pci_probe(
+ DriverPtr pDriver,
+ int entity_num,
+ struct pci_device *device,
+ intptr_t match_data
+)
+{
+ return mach64_get_scrninfo(entity_num);
+}
+
+#endif /* XSERVER_LIBPCIACCESS */
+
+_X_EXPORT DriverRec MACH64 =
+{
+ MACH64_VERSION_CURRENT,
+ MACH64_DRIVER_NAME,
+ Mach64Identify,
+#ifdef XSERVER_LIBPCIACCESS
+ NULL,
+#else
+ Mach64Probe,
+#endif
+ Mach64AvailableOptions,
+ NULL,
+ 0,
+ NULL,
+#ifdef XSERVER_LIBPCIACCESS
+ mach64_device_match,
+ mach64_pci_probe
+#endif
+};
diff --git a/driver/xf86-video-mach64/src/atimach64probe.h b/driver/xf86-video-mach64/src/atimach64probe.h
new file mode 100644
index 000000000..7b0b4b678
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atimach64probe.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 ___ATIMACH64PROBE_H___
+#define ___ATIMACH64PROBE_H___ 1
+
+#include "xf86str.h"
+
+extern DriverRec MACH64;
+
+extern SymTabRec Mach64Chipsets[];
+
+#endif /* ___ATIMACH64PROBE_H___ */
diff --git a/driver/xf86-video-mach64/src/atimach64render.c b/driver/xf86-video-mach64/src/atimach64render.c
new file mode 100644
index 000000000..dda39381d
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atimach64render.c
@@ -0,0 +1,898 @@
+/*
+ * Copyright 2006 George Sapountzis
+ * All Rights Reserved.
+ *
+ * Based on the mach64 DRI and DRM drivers:
+ * Copyright 2000 Gareth Hughes
+ * Copyright 2002-2003 Leif Delgass
+ * All Rights Reserved.
+ *
+ * Based on the ati hw/kdrive driver:
+ * Copyright 2003 Eric Anholt, Anders Carlsson
+ *
+ * Based on the via hw/xfree86 driver:
+ * Copyright 2006 Thomas Hellstrom. 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
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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:
+ * George Sapountzis <gsap7@yahoo.gr>
+ */
+
+/*
+ * Interesting cases for RENDER acceleration:
+ *
+ * cursor : ARGB8888 (24x24) Over
+ * RGB565
+ *
+ * glyph : A8 (9x10) Add
+ * A8 (420x13)
+ * glyph set : ARGB8888 (1x1 R) In
+ * A8 (420x13) Over
+ * RGB565
+ *
+ * shadow : ARGB8888 (1x1 R) In
+ * A8 (670x362) Over
+ * RGB565
+ * translucent : RGB565 (652x344) In
+ * A8 (1x1 R) Over
+ * RGB565
+ *
+ * In all interesting cases one of src/mask is "1x1 R".
+ */
+
+/*
+ * Assumptions and limitations of mach64 RENDER acceleration:
+ *
+ * RENDER acceleration is supported for GTPRO and later chips using the 3D
+ * triangle setup, i.e. the VERTEX_? registers (see the dri driver). According
+ * to atiregs.h, SCALE_3D_CNTL and TEX_?_OFF appear in GT, thus chips as old
+ * as GT should be capable of RENDER acceleration, using the S_?_INC, T_?_INC
+ * registers for texture mapping (see the directfb driver).
+ *
+ * GTPRO added a triangle setup engine and multitexturing. However, it seems
+ * that none of the 8bpp mach64 formats expands the 8bit value to the alpha
+ * channel in texture mapping, RGB8 appears to expand to (I,I,I,0). This makes
+ * GTPRO multitexturing unsuitable for emulating the IN operation. Moreover,
+ * it seems that GT/GTPRO has a muxltiplexer instead of a blender for computing
+ * the final alpha channel which forbids destinations with an alpha channel and
+ * generic two-pass compositing.
+ *
+ * A texture unit combines the fragment color (VERTEX_?_ARGB) coming in from
+ * triangle rasterization with the texel from the texture according to the
+ * texture environment (TEX_LIGHT_FCN_). "1x1 R" textures may come in as frag-
+ * ment colors, eliminating the need for multitexturing in all interesting
+ * cases (via also uses this optimization).
+ *
+ * Texture registers are saved/restored and cached (see atimach64.c). TEX_CNTL
+ * cannot be cached because it flushes the texture cache. TEX_?_OFF are also
+ * not cached because I am not sure whether writing at some offset register
+ * affects the value at another offset.
+ *
+ * Vertex registers are not saved/restored. This shouldn't be a problem though
+ * either for DRI or VT switch because vertex registers are set and used within
+ * a signle acceleration hook. Synchronization between the DDX and DRI is based
+ * on calling ATIDRISync() at the beginning of each DDX acceleration hook,
+ * which suggests the assumption that individual acceleration hooks are not
+ * interrupted.
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+/*
+ * Helper functions copied from exa and via.
+ */
+
+#if 0
+static void
+Mach64ExaCompositePictDesc(PicturePtr pict, char *string, int n)
+{
+ char format[20];
+ char size[20];
+
+ if (!pict) {
+ snprintf(string, n, "None");
+ return;
+ }
+
+ switch (pict->format) {
+ case PICT_x8r8g8b8:
+ snprintf(format, 20, "RGB8888 ");
+ break;
+ case PICT_x8b8g8r8:
+ snprintf(format, 20, "BGR8888 ");
+ break;
+ case PICT_a8r8g8b8:
+ snprintf(format, 20, "ARGB8888");
+ break;
+ case PICT_a8b8g8r8:
+ snprintf(format, 20, "ABGR8888");
+ break;
+ case PICT_r5g6b5:
+ snprintf(format, 20, "RGB565 ");
+ break;
+ case PICT_x1r5g5b5:
+ snprintf(format, 20, "RGB555 ");
+ break;
+ case PICT_a8:
+ snprintf(format, 20, "A8 ");
+ break;
+ case PICT_a1:
+ snprintf(format, 20, "A1 ");
+ break;
+ default:
+ snprintf(format, 20, "0x%x", (int)pict->format);
+ break;
+ }
+
+ snprintf(size, 20, "%dx%d%s%s",
+ pict->pDrawable->width,
+ pict->pDrawable->height,
+ pict->repeat ? " R" : "",
+ pict->componentAlpha ? " C" : ""
+ );
+
+ snprintf(string, n, "%-10p: fmt %s (%s)", (void *)pict->pDrawable, format, size);
+}
+
+static void
+Mach64ExaPrintComposite(CARD8 op,
+ PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, char *string)
+{
+ char sop[20];
+ char srcdesc[40], maskdesc[40], dstdesc[40];
+
+ switch (op) {
+ case PictOpSrc:
+ sprintf(sop, "Src");
+ break;
+ case PictOpOver:
+ sprintf(sop, "Over");
+ break;
+ case PictOpInReverse:
+ sprintf(sop, "InR");
+ break;
+ case PictOpOutReverse:
+ sprintf(sop, "OutR");
+ break;
+ case PictOpAdd:
+ sprintf(sop, "Add");
+ break;
+ default:
+ sprintf(sop, "0x%x", (int)op);
+ break;
+ }
+
+ Mach64ExaCompositePictDesc(pSrc, srcdesc, 40);
+ Mach64ExaCompositePictDesc(pMask, maskdesc, 40);
+ Mach64ExaCompositePictDesc(pDst, dstdesc, 40);
+
+ sprintf(string, "op %s, \n"
+ " src %s\n"
+ " mask %s\n"
+ " dst %s\n", sop, srcdesc, maskdesc, dstdesc);
+}
+#endif
+
+static __inline__ CARD32
+viaBitExpandHelper(CARD32 component, CARD32 bits)
+{
+ CARD32 tmp, mask;
+
+ mask = (1 << (8 - bits)) - 1;
+ tmp = component << (8 - bits);
+ return ((component & 1) ? tmp | mask : tmp);
+}
+
+static __inline__ void
+Mach64PixelARGB(PixmapPtr pPixmap, CARD32 format, CARD32 *argb)
+{
+ CARD32 pixel;
+ CARD8 comp;
+ int bits, shift;
+
+ /* Ensure that texture drawing has completed. */
+ exaWaitSync(pPixmap->drawable.pScreen);
+
+ /* exaGetPixmapFirstPixel() */
+
+ switch (pPixmap->drawable.bitsPerPixel) {
+ case 32:
+ pixel = *(CARD32 *)(pPixmap->devPrivate.ptr);
+ break;
+ case 16:
+ pixel = *(CARD16 *)(pPixmap->devPrivate.ptr);
+ break;
+ default:
+ pixel = *(CARD8 *)(pPixmap->devPrivate.ptr);
+ break;
+ }
+
+ /* exaGetRGBAFromPixel()/viaPixelARGB8888() */
+
+ switch (PICT_FORMAT_TYPE(format)) {
+ case PICT_TYPE_A:
+ shift = 0;
+ bits = PICT_FORMAT_A(format);
+ comp = (pixel >> shift) & ((1 << bits) - 1);
+ comp = viaBitExpandHelper(comp, bits);
+ *argb = comp << 24;
+ break;
+ case PICT_TYPE_ARGB:
+ shift = 0;
+ bits = PICT_FORMAT_B(format);
+ comp = (pixel >> shift) & ((1 << bits) - 1);
+ comp = viaBitExpandHelper(comp, bits);
+ *argb = comp;
+
+ shift += bits;
+ bits = PICT_FORMAT_G(format);
+ comp = (pixel >> shift) & ((1 << bits) - 1);
+ comp = viaBitExpandHelper(comp, bits);
+ *argb |= comp << 8;
+
+ shift += bits;
+ bits = PICT_FORMAT_R(format);
+ comp = (pixel >> shift) & ((1 << bits) - 1);
+ comp = viaBitExpandHelper(comp, bits);
+ *argb |= comp << 16;
+
+ shift += bits;
+ bits = PICT_FORMAT_A(format);
+ if (bits) {
+ comp = (pixel >> shift) & ((1 << bits) - 1);
+ comp = viaBitExpandHelper(comp, bits);
+ } else {
+ comp = 0xff;
+ }
+ *argb |= comp << 24;
+ break;
+ case PICT_TYPE_ABGR:
+ break;
+ default:
+ break;
+ }
+}
+
+/*
+ * RENDER acceleration for mach64
+ */
+
+typedef struct {
+ Bool supported;
+ CARD32 scale_3d_cntl;
+} Mach64BlendOp;
+
+static Mach64BlendOp Mach64BlendOps[] = {
+ /* Clear */
+ {1, MACH64_ALPHA_BLEND_SRC_ZERO | MACH64_ALPHA_BLEND_DST_ZERO},
+ /* Src */
+ {1, MACH64_ALPHA_BLEND_SRC_ONE | MACH64_ALPHA_BLEND_DST_ZERO},
+ /* Dst */
+ {1, MACH64_ALPHA_BLEND_SRC_ZERO | MACH64_ALPHA_BLEND_DST_ONE},
+ /* Over */
+ {1, MACH64_ALPHA_BLEND_SRC_ONE | MACH64_ALPHA_BLEND_DST_INVSRCALPHA},
+ /* OverReverse */
+ {1, MACH64_ALPHA_BLEND_SRC_INVDSTALPHA | MACH64_ALPHA_BLEND_DST_ONE},
+ /* In */
+ {1, MACH64_ALPHA_BLEND_SRC_DSTALPHA | MACH64_ALPHA_BLEND_DST_ZERO},
+ /* InReverse */
+ {1, MACH64_ALPHA_BLEND_SRC_ZERO | MACH64_ALPHA_BLEND_DST_SRCALPHA},
+ /* Out */
+ {1, MACH64_ALPHA_BLEND_SRC_INVDSTALPHA | MACH64_ALPHA_BLEND_DST_ZERO},
+ /* OutReverse */
+ {1, MACH64_ALPHA_BLEND_SRC_ZERO | MACH64_ALPHA_BLEND_DST_INVSRCALPHA},
+ /* Atop */
+ {0, MACH64_ALPHA_BLEND_SRC_DSTALPHA | MACH64_ALPHA_BLEND_DST_INVSRCALPHA},
+ /* AtopReverse */
+ {0, MACH64_ALPHA_BLEND_SRC_INVDSTALPHA | MACH64_ALPHA_BLEND_DST_SRCALPHA},
+ /* Xor */
+ {1, MACH64_ALPHA_BLEND_SRC_INVDSTALPHA | MACH64_ALPHA_BLEND_DST_INVSRCALPHA},
+ /* Add */
+ {1, MACH64_ALPHA_BLEND_SRC_ONE | MACH64_ALPHA_BLEND_DST_ONE}
+};
+
+#define MACH64_NR_BLEND_OPS \
+ (sizeof(Mach64BlendOps) / sizeof(Mach64BlendOps[0]))
+
+typedef struct {
+ CARD32 pictFormat;
+ CARD32 dstFormat;
+ CARD32 texFormat;
+} Mach64TexFormat;
+
+static Mach64TexFormat Mach64TexFormats[] = {
+ {PICT_a8r8g8b8, -1, MACH64_DATATYPE_ARGB8888},
+ {PICT_x8r8g8b8, MACH64_DATATYPE_ARGB8888, MACH64_DATATYPE_ARGB8888},
+ {PICT_a1r5g5b5, -1, MACH64_DATATYPE_ARGB1555},
+ {PICT_x1r5g5b5, MACH64_DATATYPE_ARGB1555, MACH64_DATATYPE_ARGB1555},
+ {PICT_r5g6b5, MACH64_DATATYPE_RGB565, MACH64_DATATYPE_RGB565 },
+ {PICT_a8, MACH64_DATATYPE_RGB8, MACH64_DATATYPE_RGB8 }
+};
+
+#define MACH64_NR_TEX_FORMATS \
+ (sizeof(Mach64TexFormats) / sizeof(Mach64TexFormats[0]))
+
+#define MACH64_PICT_IS_1x1R(_pPict) \
+ ((_pPict) && \
+ (_pPict)->pDrawable->width == 1 && \
+ (_pPict)->pDrawable->height == 1 && \
+ (_pPict)->repeat)
+
+/*
+ * CheckComposite hook helper functions.
+ */
+static __inline__ Bool
+Mach64GetOrder(int val, int *shift)
+{
+ *shift = 0;
+
+ while (val > (1 << *shift))
+ (*shift)++;
+
+ return (val == (1 << *shift));
+}
+
+static Bool
+Mach64CheckTexture(PicturePtr pPict)
+{
+ int w = pPict->pDrawable->width;
+ int h = pPict->pDrawable->height;
+ int l2w, l2h, level, i;
+
+ for (i = 0; i < MACH64_NR_TEX_FORMATS; i++) {
+ if (Mach64TexFormats[i].pictFormat == pPict->format)
+ break;
+ }
+
+ if (i == MACH64_NR_TEX_FORMATS)
+ MACH64_FALLBACK(("Unsupported picture format 0x%x\n",
+ (int)pPict->format));
+
+ /* l2w equals l2p (pitch) for all interesting cases (w >= 64) */
+ Mach64GetOrder(w, &l2w);
+ Mach64GetOrder(h, &l2h);
+
+ level = (l2w > l2h) ? l2w : l2h;
+
+ if (level > 10)
+ MACH64_FALLBACK(("Picture w/h too large (%dx%d)\n", w, h));
+
+ return TRUE;
+}
+
+/*
+ * CheckComposite acceleration hook.
+ */
+Bool
+Mach64CheckComposite
+(
+ int op,
+ PicturePtr pSrcPicture,
+ PicturePtr pMaskPicture,
+ PicturePtr pDstPicture
+)
+{
+ Bool src_solid, mask_solid, mask_comp, op_comp;
+ int i;
+
+ if (op >= MACH64_NR_BLEND_OPS || !Mach64BlendOps[op].supported)
+ return FALSE;
+
+ if (!Mach64CheckTexture(pSrcPicture))
+ return FALSE;
+
+ if (pMaskPicture && !Mach64CheckTexture(pMaskPicture))
+ return FALSE;
+
+ /* Check destination format */
+
+ for (i = 0; i < MACH64_NR_TEX_FORMATS; i++) {
+ if (Mach64TexFormats[i].pictFormat == pDstPicture->format)
+ break;
+ }
+
+ if (i == MACH64_NR_TEX_FORMATS || Mach64TexFormats[i].dstFormat == -1)
+ MACH64_FALLBACK(("Unsupported dst format 0x%x\n",
+ (int)pDstPicture->format));
+
+ /* Check that A8 src/dst appears only as "A8 ADD A8" */
+
+ if (pDstPicture->format == PICT_a8) {
+ if (pMaskPicture || pSrcPicture->format != PICT_a8 || op != PictOpAdd)
+ MACH64_FALLBACK(("A8 dst with mask or non-A8 src.\n"));
+ }
+
+ if (pDstPicture->format != PICT_a8) {
+ if (pSrcPicture->format == PICT_a8)
+ MACH64_FALLBACK(("A8 src with non-A8 dst.\n"));
+ }
+
+ /* Check that one of src/mask can come in as the fragment color. */
+
+ src_solid = MACH64_PICT_IS_1x1R(pSrcPicture);
+
+ mask_solid = MACH64_PICT_IS_1x1R(pMaskPicture);
+
+ mask_comp = pMaskPicture && pMaskPicture->componentAlpha;
+
+ op_comp = op == PictOpAdd ||
+ op == PictOpInReverse ||
+ op == PictOpOutReverse;
+
+ if (mask_solid && src_solid)
+ MACH64_FALLBACK(("Bad one-pixel IN composite operation.\n"));
+
+ if (pMaskPicture) {
+ if (!mask_solid && !src_solid)
+ MACH64_FALLBACK(("Multitexturing required.\n"));
+
+ if (!mask_solid && !op_comp)
+ MACH64_FALLBACK(("Non-solid mask.\n"));
+
+ if (mask_comp && !src_solid)
+ MACH64_FALLBACK(("Component-alpha mask.\n"));
+
+ if (!mask_comp && pMaskPicture->format != PICT_a8)
+ MACH64_FALLBACK(("Non-A8 mask.\n"));
+
+ if (mask_comp && pMaskPicture->format != PICT_a8r8g8b8)
+ MACH64_FALLBACK(("Non-ARGB mask.\n"));
+ }
+
+ return TRUE;
+}
+
+/*
+ * This function setups the fragment color from a solid pixmap in the presence
+ * of a mask.
+ */
+static __inline__ Bool
+Mach64PrepareMask
+(
+ Mach64ContextRegs3D *m3d,
+ int op,
+ PicturePtr pSrcPicture,
+ PicturePtr pMaskPicture,
+ PixmapPtr pSrc,
+ PixmapPtr pMask
+)
+{
+ Bool mask_solid, src_solid;
+ CARD32 argb = 0;
+
+ mask_solid = MACH64_PICT_IS_1x1R(pMaskPicture);
+
+ src_solid = MACH64_PICT_IS_1x1R(pSrcPicture);
+
+ if (mask_solid) {
+ Mach64PixelARGB(pMask, pMaskPicture->format, &argb);
+ argb >>= 24;
+ argb &= 0xff;
+
+ m3d->frag_mask = TRUE;
+ m3d->frag_color = (argb << 24) | (argb << 16) | (argb << 8) | argb;
+ return TRUE;
+ }
+
+ if (src_solid) {
+ /* We can only handle cases where either the src color (e.g. ADD) or
+ * the src alpha (e.g. IN_REV, OUT_REV) is used but not both.
+ *
+ * (ARGB8888 IN A8) OVER RGB565 is implemented as:
+ * (ARGB8888 IN A8) ADD ((ARGB8888 IN A8) OUT_REV RGB565).
+ */
+ if (op == PictOpInReverse || op == PictOpOutReverse) {
+ Mach64PixelARGB(pSrc, pSrcPicture->format, &argb);
+ argb >>= 24;
+ argb &= 0xff;
+
+ m3d->frag_src = TRUE;
+ m3d->frag_color = (argb << 24) | (argb << 16) | (argb << 8) | argb;
+ m3d->color_alpha = TRUE;
+ return TRUE;
+ }
+
+ if (op == PictOpAdd) {
+ Mach64PixelARGB(pSrc, pSrcPicture->format, &argb);
+
+ m3d->frag_src = TRUE;
+ m3d->frag_color = argb;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/*
+ * This function setups the texturing and blending environments. It also
+ * manipulates blend control for non-solid masks.
+ */
+static void __inline__
+Mach64BlendCntl(Mach64ContextRegs3D *m3d, int op)
+{
+ m3d->scale_3d_cntl |= MACH64_SCALE_PIX_EXPAND_DYNAMIC_RANGE |
+ MACH64_SCALE_DITHER_2D_TABLE |
+ MACH64_DITHER_INIT_RESET;
+
+ m3d->scale_3d_cntl |= Mach64BlendOps[op].scale_3d_cntl;
+
+ if (m3d->color_alpha) {
+ /* A8 uses RGB8 which expands to (I,I,I,0). Thus, we use the color
+ * channels instead of the alpha channel as the alpha factor. We also
+ * use the color channels for ARGB8888 masks with component-alpha.
+ */
+ CARD32 Ad = m3d->scale_3d_cntl & MACH64_ALPHA_BLEND_DST_MASK;
+
+ /* InReverse */
+ if (Ad == MACH64_ALPHA_BLEND_DST_SRCALPHA) {
+ m3d->scale_3d_cntl &= ~MACH64_ALPHA_BLEND_DST_MASK;
+ m3d->scale_3d_cntl |= MACH64_ALPHA_BLEND_DST_SRCCOLOR;
+ }
+
+ /* OutReverse */
+ if (Ad == MACH64_ALPHA_BLEND_DST_INVSRCALPHA) {
+ m3d->scale_3d_cntl &= ~MACH64_ALPHA_BLEND_DST_MASK;
+ m3d->scale_3d_cntl |= MACH64_ALPHA_BLEND_DST_INVSRCCOLOR;
+ }
+ }
+
+ /* Can't color mask and blend at the same time */
+ m3d->dp_write_mask = 0xffffffff;
+
+ /* Can't fog and blend at the same time */
+ m3d->scale_3d_cntl |= MACH64_ALPHA_FOG_EN_ALPHA;
+
+ /* Enable texture mapping mode */
+ m3d->scale_3d_cntl |= MACH64_SCALE_3D_FCN_TEXTURE;
+ m3d->scale_3d_cntl |= MACH64_MIP_MAP_DISABLE;
+
+ /* Setup the texture environment */
+ m3d->scale_3d_cntl |= MACH64_TEX_LIGHT_FCN_MODULATE;
+
+ /* Initialize texture unit */
+ m3d->tex_cntl |= MACH64_TEX_ST_DIRECT |
+ MACH64_TEX_SRC_LOCAL |
+ MACH64_TEX_UNCOMPRESSED |
+ MACH64_TEX_CACHE_FLUSH |
+ MACH64_TEX_CACHE_SIZE_4K;
+}
+
+/*
+ * This function setups the texture unit.
+ */
+static Bool
+Mach64PrepareTexture(PicturePtr pPict, PixmapPtr pPix)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pPix->drawable.pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ Mach64ContextRegs3D *m3d = &pATI->m3d;
+
+ CARD32 texFormat;
+
+ int w = pPict->pDrawable->width;
+ int h = pPict->pDrawable->height;
+ int l2w, l2h, l2p, level, pitch, cpp, i;
+
+ /* Prepare picture format */
+ for (i = 0; i < MACH64_NR_TEX_FORMATS; i++) {
+ if (Mach64TexFormats[i].pictFormat == pPict->format)
+ break;
+ }
+ texFormat = Mach64TexFormats[i].texFormat;
+
+ /* Prepare picture size */
+ cpp = PICT_FORMAT_BPP(pPict->format) / 8;
+ pitch = exaGetPixmapPitch(pPix) / cpp;
+
+ Mach64GetOrder(w, &l2w);
+ Mach64GetOrder(h, &l2h);
+ Mach64GetOrder(pitch, &l2p);
+
+ if (pPict->repeat && w == 1 && h == 1)
+ l2p = 0;
+ else if (pPict->repeat)
+ MACH64_FALLBACK(("Repeat not supported for w,h != 1,1\n"));
+
+ l2w = l2p;
+
+ level = (l2w > l2h) ? l2w : l2h;
+
+ m3d->tex_width = (1 << l2w);
+ m3d->tex_height = (1 << l2h);
+
+ /* Update hw state */
+ m3d->dp_pix_width |= SetBits(texFormat, DP_SCALE_PIX_WIDTH);
+
+ m3d->tex_size_pitch = (l2w << 0) |
+ (level << 4) |
+ (l2h << 8);
+
+ m3d->tex_offset = exaGetPixmapOffset(pPix);
+
+ if (PICT_FORMAT_A(pPict->format))
+ m3d->scale_3d_cntl |= MACH64_TEX_MAP_AEN;
+
+ switch (pPict->filter) {
+ case PictFilterNearest:
+ m3d->scale_3d_cntl |= MACH64_TEX_BLEND_FCN_NEAREST;
+ break;
+ case PictFilterBilinear:
+ /* FIXME */
+#if 0
+ m3d->scale_3d_cntl |= MACH64_TEX_BLEND_FCN_LINEAR;
+ m3d->scale_3d_cntl |= MACH64_BILINEAR_TEX_EN;
+#endif
+ MACH64_FALLBACK(("Bilinear filter 0x%x\n", pPict->filter));
+ break;
+ default:
+ MACH64_FALLBACK(("Bad filter 0x%x\n", pPict->filter));
+ }
+
+ m3d->transform = pPict->transform;
+
+ return TRUE;
+}
+
+/*
+ * PrepareComposite acceleration hook.
+ */
+Bool
+Mach64PrepareComposite
+(
+ int op,
+ PicturePtr pSrcPicture,
+ PicturePtr pMaskPicture,
+ PicturePtr pDstPicture,
+ PixmapPtr pSrc,
+ PixmapPtr pMask,
+ PixmapPtr pDst
+)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pDst->drawable.pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ Mach64ContextRegs3D *m3d = &pATI->m3d;
+
+ CARD32 dstFormat;
+ int offset, i;
+
+ ATIDRISync(pScreenInfo);
+
+ /* Initialize state */
+ m3d->dp_mix = SetBits(MIX_SRC, DP_BKGD_MIX) |
+ SetBits(MIX_SRC, DP_FRGD_MIX);
+
+ m3d->dp_src = SetBits(SRC_SCALER_3D, DP_BKGD_SRC) |
+ SetBits(SRC_SCALER_3D, DP_FRGD_SRC) |
+ DP_MONO_SRC_ALLONES;
+
+ Mach64GetPixmapOffsetPitch(pDst, &m3d->dst_pitch_offset);
+
+ m3d->scale_3d_cntl = 0;
+ m3d->tex_cntl = 0;
+
+ m3d->frag_src = FALSE;
+ m3d->frag_mask = FALSE;
+ m3d->frag_color = 0xffffffff;
+
+ m3d->color_alpha = FALSE;
+
+ m3d->transform = NULL;
+
+ /* Compute state */
+ if (pMaskPicture && !Mach64PrepareMask(m3d, op, pSrcPicture, pMaskPicture,
+ pSrc, pMask))
+ return FALSE;
+
+ Mach64BlendCntl(m3d, op);
+
+ for (i = 0; i < MACH64_NR_TEX_FORMATS; i++) {
+ if (Mach64TexFormats[i].pictFormat == pDstPicture->format)
+ break;
+ }
+ dstFormat = Mach64TexFormats[i].dstFormat;
+
+ m3d->dp_pix_width = SetBits(dstFormat, DP_DST_PIX_WIDTH) |
+ SetBits(dstFormat, DP_SRC_PIX_WIDTH) |
+ SetBits(dstFormat, DP_HOST_PIX_WIDTH);
+
+ if (!m3d->frag_src) {
+ if (!Mach64PrepareTexture(pSrcPicture, pSrc))
+ return FALSE;
+ }
+
+ if (pMaskPicture && !m3d->frag_mask) {
+ if (!Mach64PrepareTexture(pMaskPicture, pMask))
+ return FALSE;
+ }
+
+ offset = TEX_LEVEL(m3d->tex_size_pitch);
+
+ /* Emit state */
+ ATIMach64WaitForFIFO(pATI, 12);
+ outf(DP_SRC, m3d->dp_src);
+ outf(DP_MIX, m3d->dp_mix);
+
+ outf(CLR_CMP_CNTL, CLR_CMP_FN_FALSE);
+ outf(DST_CNTL, DST_X_DIR | DST_Y_DIR);
+ outf(DST_OFF_PITCH, m3d->dst_pitch_offset);
+
+ outf(SCALE_3D_CNTL, m3d->scale_3d_cntl);
+ outf(DP_WRITE_MASK, m3d->dp_write_mask);
+ outf(DP_PIX_WIDTH, m3d->dp_pix_width);
+
+ outf(SETUP_CNTL, 0);
+
+ outf(TEX_SIZE_PITCH, m3d->tex_size_pitch);
+ outf(TEX_CNTL, m3d->tex_cntl);
+ outf(TEX_0_OFF + offset, m3d->tex_offset);
+
+ return TRUE;
+}
+
+/*
+ * Vertex format, setup and emission.
+ */
+typedef struct {
+ float s0; /* normalized texture coords */
+ float t0;
+ float x; /* quarter-pixels */
+ float y;
+ CARD32 argb; /* fragment color */
+} Mach64Vertex;
+
+#define VTX_SET(_v, _col, _dstX, _dstY, _srcX, _dx, _srcY, _dy) \
+do { \
+ _v.s0 = ((float)(_srcX) + _dx) / m3d->tex_width; \
+ _v.t0 = ((float)(_srcY) + _dy) / m3d->tex_height; \
+ _v.x = ((float)(_dstX) * 4.0); \
+ _v.y = ((float)(_dstY) * 4.0); \
+ _v.argb = _col; \
+} while (0)
+
+static __inline__ CARD32
+FVAL(float f)
+{
+ union { float f; CARD32 c; } fc;
+
+ fc.f = f;
+ return fc.c;
+}
+
+#define VTX_OUT(_v, n) \
+do { \
+ float w = 1.0; \
+ CARD32 z = 0xffff << 15; \
+ CARD32 x_y = ((CARD16)_v.x << 16) | \
+ ((CARD16)_v.y & 0xffff); \
+ \
+ ATIMach64WaitForFIFO(pATI, 6); \
+ outf(VERTEX_##n##_S, FVAL(_v.s0)); \
+ outf(VERTEX_##n##_T, FVAL(_v.t0)); \
+ outf(VERTEX_##n##_W, FVAL(w)); \
+ \
+ outf(VERTEX_##n##_Z, z); \
+ outf(VERTEX_##n##_ARGB, _v.argb); \
+ outf(VERTEX_##n##_X_Y, x_y); \
+} while (0)
+
+/*
+ * Composite acceleration hook.
+ */
+void
+Mach64Composite
+(
+ PixmapPtr pDst,
+ int srcX,
+ int srcY,
+ int maskX,
+ int maskY,
+ int dstX,
+ int dstY,
+ int w,
+ int h
+)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pDst->drawable.pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ Mach64ContextRegs3D *m3d = &pATI->m3d;
+
+ Mach64Vertex v0, v1, v2, v3;
+ float ooa;
+ CARD32 col;
+ PictVector v;
+ int srcXend, srcYend;
+ float dxy = 0.0, dwh = 0.0;
+
+ ATIDRISync(pScreenInfo);
+
+ /* Disable clipping if it gets in the way */
+ ATIMach64ValidateClip(pATI, dstX, dstX + w - 1, dstY, dstY + h - 1);
+
+ /* Handle solid textures which come in as fragment color */
+ col = m3d->frag_color;
+ if (m3d->frag_src) {
+ srcX = maskX;
+ srcY = maskY;
+ }
+
+ /* Handle transform */
+ srcXend = srcX + w;
+ srcYend = srcY + h;
+ if (m3d->transform) {
+ v.vector[0] = IntToxFixed(srcX);
+ v.vector[1] = IntToxFixed(srcY);
+ v.vector[2] = xFixed1;
+ PictureTransformPoint(m3d->transform, &v);
+ srcX = xFixedToInt(v.vector[0]);
+ srcY = xFixedToInt(v.vector[1]);
+
+ v.vector[0] = IntToxFixed(srcXend);
+ v.vector[1] = IntToxFixed(srcYend);
+ v.vector[2] = xFixed1;
+ PictureTransformPoint(m3d->transform, &v);
+ srcXend = xFixedToInt(v.vector[0]);
+ srcYend = xFixedToInt(v.vector[1]);
+
+#if 0
+ /* Bilinear needs manipulation of texture coordinates */
+ if (m3d->scale_3d_cntl & MACH64_BILINEAR_TEX_EN) {
+ dxy = 0.5;
+ dwh = -1.0;
+ }
+#endif
+ }
+
+ /* Create vertices in clock-wise order */
+ VTX_SET(v0, col, dstX, dstY, srcX, dxy, srcY, dxy);
+ VTX_SET(v1, col, dstX + w, dstY, srcXend, dwh, srcY, dxy);
+ VTX_SET(v2, col, dstX + w, dstY + h, srcXend, dwh, srcYend, dwh);
+ VTX_SET(v3, col, dstX, dstY + h, srcX, dxy, srcYend, dwh);
+
+ /* Setup upper triangle (v0, v1, v3) */
+ VTX_OUT(v0, 1);
+ VTX_OUT(v1, 2);
+ VTX_OUT(v3, 3);
+
+ ooa = 1.0 / (w * h);
+ outf(ONE_OVER_AREA, FVAL(ooa));
+
+ /* Setup lower triangle (v2, v1, v3) */
+ VTX_OUT(v2, 1);
+
+ ooa = -ooa;
+ outf(ONE_OVER_AREA, FVAL(ooa));
+}
+
+/*
+ * DoneComposite acceleration hook.
+ */
+void
+Mach64DoneComposite(PixmapPtr pDst)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pDst->drawable.pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ ATIDRISync(pScreenInfo);
+
+ outf(SCALE_3D_CNTL, 0);
+}
diff --git a/driver/xf86-video-mach64/src/atimach64version.h b/driver/xf86-video-mach64/src/atimach64version.h
new file mode 100644
index 000000000..c1848bde4
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atimach64version.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 _MACH64_VERSION_H_
+#define _MACH64_VERSION_H_ 1
+
+#undef MACH64_NAME
+#undef MACH64_DRIVER_NAME
+#undef MACH64_VERSION_MAJOR
+#undef MACH64_VERSION_MINOR
+#undef MACH64_VERSION_PATCH
+#undef MACH64_VERSION_CURRENT
+#undef MACH64_VERSION_EVALUATE
+#undef MACH64_VERSION_STRINGIFY
+#undef MACH64_VERSION_NAME
+
+#define MACH64_NAME "MACH64"
+#define MACH64_DRIVER_NAME "mach64"
+
+#define MACH64_VERSION_MAJOR 6
+#define MACH64_VERSION_MINOR 7
+#define MACH64_VERSION_PATCH 0
+
+#ifndef MACH64_VERSION_EXTRA
+#define MACH64_VERSION_EXTRA ""
+#endif
+
+#define MACH64_VERSION_CURRENT \
+ ((MACH64_VERSION_MAJOR << 20) | \
+ (MACH64_VERSION_MINOR << 10) | \
+ (MACH64_VERSION_PATCH))
+
+#define MACH64_VERSION_EVALUATE(__x) #__x
+#define MACH64_VERSION_STRINGIFY(_x) MACH64_VERSION_EVALUATE(_x)
+#define MACH64_VERSION_NAME \
+ MACH64_VERSION_STRINGIFY(MACH64_VERSION_MAJOR) "." \
+ MACH64_VERSION_STRINGIFY(MACH64_VERSION_MINOR) "." \
+ MACH64_VERSION_STRINGIFY(MACH64_VERSION_MINOR) MACH64_VERSION_EXTRA
+
+#endif /* _MACH64_VERSION_H_ */
diff --git a/driver/xf86-video-mach64/src/atimach64xv.c b/driver/xf86-video-mach64/src/atimach64xv.c
new file mode 100644
index 000000000..ef17861e7
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atimach64xv.c
@@ -0,0 +1,1686 @@
+/*
+ * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include "ati.h"
+#include "atichip.h"
+#include "atimach64accel.h"
+#include "atimach64io.h"
+#include "atixv.h"
+
+#include <X11/extensions/Xv.h>
+#include "fourcc.h"
+#include "xf86xv.h"
+
+#define MAKE_ATOM(string) MakeAtom(string, strlen(string), TRUE)
+#define MaxScale (CARD32)(CARD16)(-1)
+
+static unsigned long ATIMach64XVAtomGeneration = (unsigned long)(-1);
+
+static XF86VideoEncodingRec ATIMach64VideoEncoding[] =
+{
+ { 0, "XV_IMAGE", 720, 2048, {1, 1} }
+};
+#define nATIMach64VideoEncoding NumberOf(ATIMach64VideoEncoding)
+
+static XF86VideoFormatRec ATIMach64VideoFormat[] =
+{
+ { 8, TrueColor},
+ { 8, DirectColor},
+ { 8, PseudoColor},
+ { 8, GrayScale},
+ { 8, StaticGray},
+ { 8, StaticColor},
+ {15, TrueColor},
+ {16, TrueColor},
+ {24, TrueColor},
+ {15, DirectColor},
+ {16, DirectColor},
+ {24, DirectColor}
+};
+#define nATIMach64VideoFormat NumberOf(ATIMach64VideoFormat)
+
+static XF86AttributeRec ATIMach64Attribute[] =
+{
+ /* These are only supported on the Rage Pro and later ... */
+ {
+ XvSettable | XvGettable,
+ -1000, 1000,
+ "XV_SATURATION"
+ },
+ {
+ XvSettable | XvGettable,
+ -1000, 1000,
+ "XV_BRIGHTNESS"
+ },
+ {
+ XvSettable | XvGettable,
+ -1000, 1000,
+ "XV_COLOUR"
+ },
+ {
+ XvSettable | XvGettable,
+ -1000, 1000,
+ "XV_COLOR"
+ },
+
+ /* Local attributes, odds and ends for compatibility, etc... */
+ {
+ XvSettable | XvGettable,
+ 0, 1,
+ "XV_AUTOPAINT_COLOURKEY"
+ },
+ {
+ XvSettable | XvGettable,
+ 0, 1,
+ "XV_AUTOPAINT_COLORKEY"
+ },
+ {
+ XvSettable | XvGettable,
+ 0, (1 << 24) - 1,
+ "XV_COLOURKEY"
+ },
+ {
+ XvSettable | XvGettable,
+ 0, (1 << 24) - 1,
+ "XV_COLORKEY"
+ },
+ {
+ XvSettable | XvGettable,
+ 0, (1 << 24) - 1,
+ "XV_COLOURKEY_MASK"
+ },
+ {
+ XvSettable | XvGettable,
+ 0, (1 << 24) - 1,
+ "XV_COLORKEY_MASK"
+ },
+ {
+ XvSettable,
+ 0, 0,
+ "XV_SET_DEFAULTS"
+ },
+ { /* Keep last */
+ XvSettable | XvGettable,
+ 0, 1,
+ "XV_DOUBLE_BUFFER"
+ }
+};
+#define nATIMach64Attribute NumberOf(ATIMach64Attribute)
+
+static XF86ImageRec ATIMach64Image[] =
+{
+ XVIMAGE_YUY2,
+ XVIMAGE_UYVY,
+ XVIMAGE_YV12,
+ XVIMAGE_I420
+};
+#define nATIMach64Image NumberOf(ATIMach64Image)
+
+/* A local XVideo adaptor attribute record */
+typedef struct _ATIMach64Attribute
+{
+ Atom AttributeID;
+ INT32 MaxValue; /* ... for the hardware */
+ void (*SetAttribute) (ATIPtr, INT32);
+ INT32 (*GetAttribute) (ATIPtr);
+} ATIMach64AttributeRec, *ATIMach64AttributePtr;
+
+/* Functions to get/set XVideo adaptor attributes */
+
+static void
+ATIMach64SetSaturationAttribute
+(
+ ATIPtr pATI,
+ INT32 Value
+)
+{
+ /* Set the register */
+ pATI->NewHW.scaler_colour_cntl &=
+ ~(SCALE_SATURATION_U | SCALE_SATURATION_V);
+ pATI->NewHW.scaler_colour_cntl |= SetBits(Value, SCALE_SATURATION_U) |
+ SetBits(Value, SCALE_SATURATION_V);
+ outf(SCALER_COLOUR_CNTL, pATI->NewHW.scaler_colour_cntl);
+}
+
+static INT32
+ATIMach64GetSaturationAttribute
+(
+ ATIPtr pATI
+)
+{
+ return (INT32)GetBits(pATI->NewHW.scaler_colour_cntl, SCALE_SATURATION_U);
+}
+
+static void
+ATIMach64SetBrightnessAttribute
+(
+ ATIPtr pATI,
+ INT32 Value
+)
+{
+ /* Set the register */
+ pATI->NewHW.scaler_colour_cntl &= ~SCALE_BRIGHTNESS;
+ pATI->NewHW.scaler_colour_cntl |= SetBits(Value, SCALE_BRIGHTNESS);
+ outf(SCALER_COLOUR_CNTL, pATI->NewHW.scaler_colour_cntl);
+}
+
+static INT32
+ATIMach64GetBrightnessAttribute
+(
+ ATIPtr pATI
+)
+{
+ return (INT32)GetBits(pATI->NewHW.scaler_colour_cntl, SCALE_BRIGHTNESS);
+}
+
+static void
+ATIMach64SetDoubleBufferAttribute
+(
+ ATIPtr pATI,
+ INT32 Value
+)
+{
+ pATI->DoubleBuffer = Value;
+}
+
+static INT32
+ATIMach64GetDoubleBufferAttribute
+(
+ ATIPtr pATI
+)
+{
+ return (int)pATI->DoubleBuffer;
+}
+
+static void
+ATIMach64SetAutoPaintAttribute
+(
+ ATIPtr pATI,
+ INT32 Value
+)
+{
+ pATI->AutoPaint = Value;
+}
+
+static INT32
+ATIMach64GetAutoPaintAttribute
+(
+ ATIPtr pATI
+)
+{
+ return (int)pATI->AutoPaint;
+}
+
+static void
+ATIMach64SetColourKeyAttribute
+(
+ ATIPtr pATI,
+ INT32 Value
+)
+{
+ pATI->NewHW.overlay_graphics_key_clr =
+ (CARD32)(Value & ((1 << pATI->depth) - 1));
+ outf(OVERLAY_GRAPHICS_KEY_CLR, pATI->NewHW.overlay_graphics_key_clr);
+}
+
+static INT32
+ATIMach64GetColourKeyAttribute
+(
+ ATIPtr pATI
+)
+{
+ return (INT32)pATI->NewHW.overlay_graphics_key_clr;
+}
+
+static void
+ATIMach64SetColourKeyMaskAttribute
+(
+ ATIPtr pATI,
+ INT32 Value
+)
+{
+ pATI->NewHW.overlay_graphics_key_msk =
+ (CARD32)(Value & ((1 << pATI->depth) - 1));
+ outf(OVERLAY_GRAPHICS_KEY_MSK, pATI->NewHW.overlay_graphics_key_msk);
+}
+
+static INT32
+ATIMach64GetColourKeyMaskAttribute
+(
+ ATIPtr pATI
+)
+{
+ return (INT32)pATI->NewHW.overlay_graphics_key_msk;
+}
+
+/*
+ * ATIMach64SetDefaultAttributes --
+ *
+ * This function calls other functions to set default values for the various
+ * attributes of an XVideo port.
+ */
+static void
+ATIMach64SetDefaultAttributes
+(
+ ATIPtr pATI,
+ INT32 Value
+)
+{
+ ATIMach64SetAutoPaintAttribute(pATI, TRUE);
+ ATIMach64SetDoubleBufferAttribute(pATI, FALSE);
+ ATIMach64SetColourKeyMaskAttribute(pATI, (1 << pATI->depth) - 1);
+ ATIMach64SetColourKeyAttribute(pATI, (3 << ((2 * pATI->depth) / 3)) |
+ (2 << ((1 * pATI->depth) / 3)) |
+ (1 << ((0 * pATI->depth) / 3)));
+
+ if (pATI->Chip < ATI_CHIP_264GTPRO)
+ return;
+
+ ATIMach64SetBrightnessAttribute(pATI, 32);
+ ATIMach64SetSaturationAttribute(pATI, 16);
+}
+
+/*
+ * There is a one-to-one correspondance between elements of the following array
+ * and those of ATIMach64Attribute.
+ */
+static ATIMach64AttributeRec ATIMach64AttributeInfo[nATIMach64Attribute] =
+{
+ { /* SATURATION */
+ 0, 23,
+ ATIMach64SetSaturationAttribute,
+ ATIMach64GetSaturationAttribute
+ },
+ { /* BRIGHTNESS */
+ 0, 63,
+ ATIMach64SetBrightnessAttribute,
+ ATIMach64GetBrightnessAttribute
+ },
+ { /* COLOUR */
+ 0, 23,
+ ATIMach64SetSaturationAttribute,
+ ATIMach64GetSaturationAttribute
+ },
+ { /* COLOR */
+ 0, 23,
+ ATIMach64SetSaturationAttribute,
+ ATIMach64GetSaturationAttribute
+ },
+ { /* AUTOPAINT_COLOURKEY */
+ 0, 1,
+ ATIMach64SetAutoPaintAttribute,
+ ATIMach64GetAutoPaintAttribute
+ },
+ { /* AUTOPAINT_COLORKEY */
+ 0, 1,
+ ATIMach64SetAutoPaintAttribute,
+ ATIMach64GetAutoPaintAttribute
+ },
+ { /* COLOURKEY */
+ 0, (1 << 24) - 1,
+ ATIMach64SetColourKeyAttribute,
+ ATIMach64GetColourKeyAttribute
+ },
+ { /* COLORKEY */
+ 0, (1 << 24) - 1,
+ ATIMach64SetColourKeyAttribute,
+ ATIMach64GetColourKeyAttribute
+ },
+ { /* COLOURKEY_MASK */
+ 0, (1 << 24) - 1,
+ ATIMach64SetColourKeyMaskAttribute,
+ ATIMach64GetColourKeyMaskAttribute
+ },
+ { /* COLORKEY_MASK */
+ 0, (1 << 24) - 1,
+ ATIMach64SetColourKeyMaskAttribute,
+ ATIMach64GetColourKeyMaskAttribute
+ },
+ { /* SET_DEFAULTS */
+ 0, 0,
+ ATIMach64SetDefaultAttributes,
+ NULL
+ },
+ { /* DOUBLE_BUFFER */
+ 0, 1,
+ ATIMach64SetDoubleBufferAttribute,
+ ATIMach64GetDoubleBufferAttribute
+ }
+};
+
+/*
+ * ATIMach64FindAttribute --
+ *
+ * This function is called to locate an Xv attribute's table entry.
+ */
+static int
+ATIMach64FindPortAttribute
+(
+ ATIPtr pATI,
+ Atom AttributeID
+)
+{
+ int iAttribute;
+
+ if (pATI->Chip < ATI_CHIP_264GTPRO)
+ iAttribute = 4;
+ else
+ iAttribute = 0;
+
+ for (; iAttribute < nATIMach64Attribute; iAttribute++)
+ if (AttributeID == ATIMach64AttributeInfo[iAttribute].AttributeID)
+ return iAttribute;
+
+ return -1;
+}
+
+/*
+ * ATIMach64SetPortAttribute --
+ *
+ * This function sets the value of a particular port's attribute.
+ */
+static int
+ATIMach64SetPortAttribute
+(
+ ScrnInfoPtr pScreenInfo,
+ Atom AttributeID,
+ INT32 Value,
+ pointer pATI
+)
+{
+ INT32 Range;
+ int iAttribute;
+
+ if (((iAttribute = ATIMach64FindPortAttribute(pATI, AttributeID)) < 0) ||
+ !ATIMach64AttributeInfo[iAttribute].SetAttribute)
+ return BadMatch;
+
+ Range = ATIMach64Attribute[iAttribute].max_value -
+ ATIMach64Attribute[iAttribute].min_value;
+
+ if (Range >= 0)
+ {
+ /* Limit and scale the value */
+ Value -= ATIMach64Attribute[iAttribute].min_value;
+
+ if (Value < 0)
+ Value = 0;
+ else if (Value > Range)
+ Value = Range;
+
+ if (Range != ATIMach64AttributeInfo[iAttribute].MaxValue)
+ {
+ if (ATIMach64AttributeInfo[iAttribute].MaxValue > 0)
+ Value *= ATIMach64AttributeInfo[iAttribute].MaxValue;
+ if (Range > 0)
+ Value /= Range;
+ }
+ }
+
+ (*ATIMach64AttributeInfo[iAttribute].SetAttribute)(pATI, Value);
+
+ return Success;
+}
+
+/*
+ * ATIMach64SetPortAttribute --
+ *
+ * This function retrieves the value of a particular port's attribute.
+ */
+static int
+ATIMach64GetPortAttribute
+(
+ ScrnInfoPtr pScreenInfo,
+ Atom AttributeID,
+ INT32 *Value,
+ pointer pATI
+)
+{
+ INT32 Range;
+ int iAttribute;
+
+ if (!Value ||
+ ((iAttribute = ATIMach64FindPortAttribute(pATI, AttributeID)) < 0) ||
+ !ATIMach64AttributeInfo[iAttribute].GetAttribute)
+ return BadMatch;
+
+ *Value = (*ATIMach64AttributeInfo[iAttribute].GetAttribute)(pATI);
+
+ Range = ATIMach64Attribute[iAttribute].max_value -
+ ATIMach64Attribute[iAttribute].min_value;
+
+ if (Range >= 0)
+ {
+ if (Range != ATIMach64AttributeInfo[iAttribute].MaxValue)
+ {
+ /* (Un-)scale the value */
+ if (Range > 0)
+ *Value *= Range;
+ if (ATIMach64AttributeInfo[iAttribute].MaxValue > 0)
+ *Value /= ATIMach64AttributeInfo[iAttribute].MaxValue;
+ }
+
+ *Value += ATIMach64Attribute[iAttribute].min_value;
+ }
+
+ return Success;
+}
+
+static pointer
+ATIMach64XVMemAlloc
+(
+ ScreenPtr pScreen,
+ pointer pVideo,
+ int size,
+ int *offset,
+ ATIPtr pATI
+);
+
+static void
+ATIMach64XVMemFree
+(
+ ScreenPtr pScreen,
+ pointer pVideo,
+ ATIPtr pATI
+);
+
+#ifdef USE_XAA
+/*
+ * ATIMach64RemoveLinearCallback --
+ *
+ * This is called by the framebuffer manager to release the offscreen XVideo
+ * buffer after the video has been temporarily disabled due to its window being
+ * iconified or completely occluded.
+ */
+static void
+ATIMach64RemoveLinearCallback
+(
+ FBLinearPtr pLinear
+)
+{
+ ATIPtr pATI = ATIPTR(xf86Screens[pLinear->pScreen->myNum]);
+
+ pATI->pXVBuffer = NULL;
+ outf(OVERLAY_SCALE_CNTL, SCALE_EN);
+}
+#endif /* USE_XAA */
+
+/*
+ * ATIMach64StopVideo --
+ *
+ * This is called to stop displaying a video. Note that, to prevent jittering
+ * this doesn't actually turn off the overlay unless 'Cleanup' is TRUE, i.e.
+ * when the video is to be actually stopped rather than temporarily disabled.
+ */
+static void
+ATIMach64StopVideo
+(
+ ScrnInfoPtr pScreenInfo,
+ pointer Data,
+ Bool Cleanup
+)
+{
+ ScreenPtr pScreen = pScreenInfo->pScreen;
+ ATIPtr pATI = Data;
+
+ if (pATI->ActiveSurface)
+ return;
+
+ REGION_EMPTY(pScreen, &pATI->VideoClip);
+
+#ifdef USE_XAA
+ if (!pATI->useEXA && !Cleanup)
+ {
+ /*
+ * Free offscreen buffer if/when its allocation is needed by XAA's
+ * pixmap cache.
+ */
+ FBLinearPtr linear = (FBLinearPtr)pATI->pXVBuffer;
+ if (linear)
+ linear->RemoveLinearCallback =
+ ATIMach64RemoveLinearCallback;
+ return;
+ }
+#endif /* USE_XAA */
+
+ ATIMach64XVMemFree(pScreen, pATI->pXVBuffer, pATI);
+ pATI->pXVBuffer = NULL;
+ outf(OVERLAY_SCALE_CNTL, SCALE_EN);
+}
+
+/*
+ * ATIMach64QueryBestSize --
+ *
+ * Quoting XVideo docs:
+ *
+ * This function provides the client with a way to query what the destination
+ * dimensions would end up being if they were to request that an area
+ * VideoWidth by VideoHeight from the video stream be scaled to rectangle of
+ * DrawableWidth by DrawableHeight on the screen. Since it is not expected
+ * that all hardware will be able to get the target dimensions exactly, it is
+ * important that the driver provide this function.
+ */
+static void
+ATIMach64QueryBestSize
+(
+ ScrnInfoPtr pScreenInfo,
+ Bool Motion,
+ short VideoWidth,
+ short VideoHeight,
+ short DrawableWidth,
+ short DrawableHeight,
+ unsigned int *Width,
+ unsigned int *Height,
+ pointer pATI
+)
+{
+ *Width = DrawableWidth;
+ *Height = DrawableHeight;
+}
+
+/*
+ * ATIMach64QueryImageAttributes --
+ *
+ * Quoting XVideo docs:
+ *
+ * This function is called to let the driver specify how data for a particular
+ * image of size Width by Height should be stored. Sometimes only the size and
+ * corrected width and height are needed. In that case pitches and offsets are
+ * NULL. The size of the memory required for the image is returned by this
+ * function. The width and height of the requested image can be altered by the
+ * driver to reflect format limitations (such as component sampling periods
+ * that are larger than one). If pPitch and pOffset are not NULL, these will
+ * be arrays with as many elements in them as there are planes in the image
+ * format. The driver should specify the pitch (in bytes) of each scanline in
+ * the particular plane as well as the offset to that plane (in bytes) from the
+ * beginning of the image.
+ */
+static int
+ATIMach64QueryImageAttributes
+(
+ ScrnInfoPtr pScreenInfo,
+ int ImageID,
+ unsigned short *Width,
+ unsigned short *Height,
+ int *pPitch,
+ int *pOffset
+)
+{
+ int Size, tmp;
+
+ if (!Width || !Height)
+ return 0;
+
+ if (*Width > 2048)
+ *Width = 2048;
+ else
+ *Width = (*Width + 1) & ~1;
+
+ if (*Height > 2048)
+ *Height = 2048;
+
+ if (pOffset)
+ pOffset[0] = 0;
+
+ switch (ImageID)
+ {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ *Height = (*Height + 1) & ~1;
+ Size = (*Width + 3) & ~3;
+ if (pPitch)
+ pPitch[0] = Size;
+ Size *= *Height;
+ if (pOffset)
+ pOffset[1] = Size;
+ tmp = ((*Width >> 1) + 3) & ~3;
+ if (pPitch)
+ pPitch[1] = pPitch[2] = tmp;
+ tmp *= (*Height >> 1);
+ Size += tmp;
+ if (pOffset)
+ pOffset[2] = Size;
+ Size += tmp;
+ break;
+
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ Size = *Width << 1;
+ if (pPitch)
+ pPitch[0] = Size;
+ Size *= *Height;
+ break;
+
+ default:
+ Size = 0;
+ break;
+ }
+
+ return Size;
+}
+
+/*
+ * ATIMach64ScaleVideo --
+ *
+ * This function is called to calculate overlay scaling factors.
+ */
+static void
+ATIMach64ScaleVideo
+(
+ ATIPtr pATI,
+ DisplayModePtr pMode,
+ int SrcW,
+ int SrcH,
+ int DstW,
+ int DstH,
+ CARD32 *pHScale,
+ CARD32 *pVScale
+)
+{
+ int Shift;
+
+ *pHScale = ATIDivide(SrcW, DstW,
+ GetBits(pATI->NewHW.pll_vclk_cntl, PLL_ECP_DIV) + 12, 0);
+
+ Shift = 12;
+ if (pMode->Flags & V_INTERLACE)
+ Shift++;
+
+ if (pATI->OptionPanelDisplay && (pATI->LCDPanelID >= 0))
+ {
+ if (pMode->VDisplay < pATI->LCDVertical)
+ {
+ SrcH *= pMode->VDisplay;
+ DstH *= pATI->LCDVertical;
+ }
+ }
+ else
+ {
+ if (pMode->Flags & V_DBLSCAN)
+ Shift--;
+ if (pMode->VScan > 1)
+ DstH *= pMode->VScan;
+ }
+
+ *pVScale = ATIDivide(SrcH, DstH, Shift, 0);
+}
+
+/*
+ * ATIMach64ClipVideo --
+ *
+ * Clip the video (both source and destination) and make various other
+ * adjustments.
+ */
+static Bool
+ATIMach64ClipVideo
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI,
+ int ImageID,
+ short SrcX,
+ short SrcY,
+ short SrcW,
+ short SrcH,
+ short DstX,
+ short DstY,
+ short *DstW,
+ short *DstH,
+ short Width,
+ short Height,
+ RegionPtr pClip,
+ BoxPtr pDstBox,
+ INT32 *SrcX1,
+ INT32 *SrcX2,
+ INT32 *SrcY1,
+ INT32 *SrcY2,
+ int *SrcLeft,
+ int *SrcTop
+)
+{
+ CARD32 HScale, VScale;
+
+ /* Check hardware limits */
+ if ((Height <= 0) || (Height > 2048) || (Width <= 0) || (Width > 768) ||
+ ((Width > 384) && (pATI->Chip < ATI_CHIP_264VTB)) ||
+ ((Width > 720) && (pATI->Chip < ATI_CHIP_264GTPRO ||
+ pATI->Chip > ATI_CHIP_264LTPRO)))
+ return FALSE;
+
+ ATIMach64ScaleVideo(pATI, pScreenInfo->currentMode,
+ SrcW, SrcH, *DstW, *DstH, &HScale, &VScale);
+ if (!HScale || !VScale)
+ return FALSE;
+ if (HScale > MaxScale)
+ *DstW = (*DstW * HScale) / MaxScale;
+ if (VScale > MaxScale)
+ *DstH = (*DstH * HScale) / MaxScale;
+
+ /* Clip both the source and the destination */
+ *SrcX1 = SrcX;
+ *SrcX2 = SrcX + SrcW;
+ *SrcY1 = SrcY;
+ *SrcY2 = SrcY + SrcH;
+
+ pDstBox->x1 = DstX;
+ pDstBox->x2 = DstX + *DstW;
+ pDstBox->y1 = DstY;
+ pDstBox->y2 = DstY + *DstH;
+
+ if (!xf86XVClipVideoHelper(pDstBox, SrcX1, SrcX2, SrcY1, SrcY2,
+ pClip, Width, Height))
+ return FALSE;
+
+ /*
+ * Reset overlay scaler origin. This prevents jittering during
+ * viewport panning or while the video is being moved or gradually
+ * obscured/unobscured.
+ */
+ pDstBox->x1 = DstX;
+ pDstBox->y1 = DstY;
+
+ /* Translate to the current viewport */
+ pDstBox->x1 -= pScreenInfo->frameX0;
+ pDstBox->x2 -= pScreenInfo->frameX0;
+ pDstBox->y1 -= pScreenInfo->frameY0;
+ pDstBox->y2 -= pScreenInfo->frameY0;
+
+ *SrcLeft = *SrcTop = 0;
+
+ /*
+ * If the overlay scaler origin ends up outside the current viewport, move
+ * it to the viewport's top left corner. This unavoidably causes a slight
+ * jittering in the image (even with double-buffering).
+ */
+ if (pDstBox->x1 < 0)
+ {
+ *SrcLeft = ((-pDstBox->x1 * SrcW) / *DstW) & ~1;
+ pDstBox->x1 = 0;
+ }
+
+ if (pDstBox->y1 < 0)
+ {
+ *SrcTop = (-pDstBox->y1 * SrcH) / *DstH;
+ pDstBox->y1 = 0;
+
+ switch (ImageID)
+ {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ *SrcTop = (*SrcTop + 1) & ~1;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+#ifdef ATIMove32
+
+/* A faster intercept */
+#undef xf86XVCopyPacked
+#define xf86XVCopyPacked ATIMach64XVCopyPacked
+
+static void
+ATIMach64XVCopyPacked
+(
+ const CARD8 *pSrc,
+ CARD8 *pDst,
+ int SrcPitch,
+ int DstPitch,
+ int Height,
+ int Width
+)
+{
+ Width >>= 1;
+ while (--Height >= 0)
+ {
+ ATIMove32(pDst, pSrc, Width);
+ pSrc += SrcPitch;
+ pDst += DstPitch;
+ }
+}
+
+#endif
+
+/*
+ * ATIMach64DisplayVideo --
+ *
+ * This function programmes Mach64 registers needed to display a video.
+ */
+static void
+ATIMach64DisplayVideo
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI,
+ BoxPtr pDstBox,
+ int ImageID,
+ int Offset,
+ int Pitch,
+ short SrcW,
+ short SrcH,
+ short DstW,
+ short DstH,
+ short Width,
+ short Height
+)
+{
+ DisplayModePtr pMode = pScreenInfo->currentMode;
+ CARD32 HScale, VScale;
+
+ if (pMode->VScan > 1)
+ {
+ pDstBox->y1 *= pMode->VScan;
+ pDstBox->y2 *= pMode->VScan;
+ }
+ if (pMode->Flags & V_DBLSCAN)
+ {
+ pDstBox->y1 <<= 1;
+ pDstBox->y2 <<= 1;
+ }
+
+ /* Recalculate overlay scale factors */
+ ATIMach64ScaleVideo(pATI, pMode, SrcW, SrcH, DstW, DstH, &HScale, &VScale);
+
+ pATI->NewHW.video_format &= ~SCALER_IN;
+ if (ImageID == FOURCC_UYVY)
+ pATI->NewHW.video_format |= SCALER_IN_YVYU422;
+ else
+ pATI->NewHW.video_format |= SCALER_IN_VYUY422;
+
+ ATIMach64WaitForFIFO(pATI, 8);
+ outq(OVERLAY_Y_X_START, OVERLAY_Y_X_END, OVERLAY_LOCK_START |
+ SetWord(pDstBox->x1, 1) | SetWord(pDstBox->y1, 0),
+ SetWord(pDstBox->x2 - 1, 1) | SetWord(pDstBox->y2 - 1, 0));
+ outf(OVERLAY_SCALE_INC, SetWord(HScale, 1) | SetWord(VScale, 0));
+ outf(SCALER_HEIGHT_WIDTH, SetWord(Width, 1) | SetWord(Height, 0));
+ outf(VIDEO_FORMAT, pATI->NewHW.video_format);
+
+ if (pATI->Chip < ATI_CHIP_264VTB)
+ {
+ outf(BUF0_OFFSET, Offset);
+ outf(BUF0_PITCH, Pitch);
+ }
+ else
+ {
+ outf(SCALER_BUF0_OFFSET, Offset);
+ outf(SCALER_BUF_PITCH, Pitch);
+ }
+
+ outf(OVERLAY_SCALE_CNTL, SCALE_PIX_EXPAND | OVERLAY_EN | SCALE_EN);
+}
+
+/*
+ * ATIMach64PutImage --
+ *
+ * This function is called to put a video image on the screen.
+ */
+static int
+ATIMach64PutImage
+(
+ ScrnInfoPtr pScreenInfo,
+ short SrcX,
+ short SrcY,
+ short DstX,
+ short DstY,
+ short SrcW,
+ short SrcH,
+ short DstW,
+ short DstH,
+ int ImageID,
+ unsigned char *Buffer,
+ short Width,
+ short Height,
+ Bool Synchronise,
+ RegionPtr pClip,
+ pointer Data,
+ DrawablePtr pDraw
+)
+{
+ ATIPtr pATI = Data;
+ ScreenPtr pScreen;
+ INT32 SrcX1, SrcX2, SrcY1, SrcY2;
+ BoxRec DstBox;
+ int SrcPitch, SrcPitchUV, DstPitch, DstSize;
+ int SrcTop, SrcLeft, DstWidth, DstHeight;
+ int Top, Bottom, Left, Right, nLine, nPixel, Offset;
+ int OffsetV, OffsetU;
+ int XVOffset;
+ int tmp;
+ CARD8 *pDst;
+
+ if (pATI->ActiveSurface)
+ return Success;
+
+ if (DstH < 16)
+ return Success;
+
+ if (!ATIMach64ClipVideo(pScreenInfo, pATI, ImageID,
+ SrcX, SrcY, SrcW, SrcH,
+ DstX, DstY, &DstW, &DstH,
+ Width, Height, pClip, &DstBox,
+ &SrcX1, &SrcX2, &SrcY1, &SrcY2,
+ &SrcLeft, &SrcTop))
+ return Success;
+
+ pScreen = pScreenInfo->pScreen;
+
+ DstWidth = Width - SrcLeft;
+ DstHeight = Height - SrcTop;
+
+ /*
+ * Allocate an offscreen buffer for the entire source, even though only a
+ * subset of the source will be copied into it.
+ */
+ DstPitch = /* bytes */
+ (DstWidth + DstWidth + 15) & ~15;
+ DstSize = /* bytes */
+ (DstPitch * DstHeight);
+
+ pATI->pXVBuffer = ATIMach64XVMemAlloc(pScreen, pATI->pXVBuffer,
+ (pATI->DoubleBuffer + 1) * DstSize, &XVOffset, pATI);
+
+ if (!pATI->pXVBuffer)
+ {
+ if (!pATI->DoubleBuffer)
+ return BadAlloc;
+
+ pATI->pXVBuffer =
+ ATIMach64XVMemAlloc(pScreen, pATI->pXVBuffer, DstSize, &XVOffset, pATI);
+
+ if (!pATI->pXVBuffer)
+ return BadAlloc;
+
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Video image double-buffering downgraded to single-buffering\n due"
+ " to insufficient video memory.\n");
+ pATI->DoubleBuffer = pATI->CurrentBuffer = 0;
+ }
+ else
+ {
+ /* Possibly switch buffers */
+ pATI->CurrentBuffer = pATI->DoubleBuffer - pATI->CurrentBuffer;
+ }
+
+ /* Synchronise video memory accesses */
+ ATIMach64Sync(pScreenInfo);
+
+ Offset = XVOffset + pATI->CurrentBuffer * DstSize;
+ pDst = pATI->pMemoryLE;
+ pDst += Offset;
+
+ switch (ImageID)
+ {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ Left = (SrcX1 >> 16) & ~1;
+ Right = ((SrcX2 + 0x1FFFF) >> 16) & ~1;
+ Top = (SrcY1 >> 16) & ~1;
+ Bottom = ((SrcY2 + 0x1FFFF) >> 16) & ~1;
+
+ if ((Right < Width) && ((SrcX1 & 0x1FFFF) <= (SrcX2 & 0x1FFFF)))
+ Right += 2;
+ if ((Bottom < Height) && ((SrcY1 & 0x1FFFF) <= (SrcY2 & 0x1FFFF)))
+ Bottom += 2;
+
+ nPixel = Right - Left;
+ nLine = Bottom - Top;
+
+ SrcPitch = (Width + 3) & ~3;
+ OffsetV = SrcPitch * Height;
+ SrcPitchUV = ((Width >> 1) + 3) & ~3;
+ OffsetU = ((Height >> 1) * SrcPitchUV) + OffsetV;
+
+ tmp = ((Top >> 1) * SrcPitchUV) + (Left >> 1);
+ OffsetV += tmp;
+ OffsetU += tmp;
+
+ if (ImageID == FOURCC_I420)
+ {
+ tmp = OffsetV;
+ OffsetV = OffsetU;
+ OffsetU = tmp;
+ }
+
+ pDst += ((Top - SrcTop) * DstPitch) + ((Left - SrcLeft) << 1);
+
+ xf86XVCopyYUV12ToPacked(Buffer + (Top * SrcPitch) + Left,
+ Buffer + OffsetV, Buffer + OffsetU, pDst, SrcPitch, SrcPitchUV,
+ DstPitch, nLine, nPixel);
+ break;
+
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ default:
+ Left = (SrcX1 >> 16) & ~1;
+ Right = ((SrcX2 + 0x1FFFF) >> 16) & ~1;
+ Top = SrcY1 >> 16;
+ Bottom = (SrcY2 + 0x0FFFF) >> 16;
+
+ if ((Right < Width) && ((SrcX1 & 0x1FFFF) <= (SrcX2 & 0x1FFFF)))
+ Right += 2;
+ if ((Bottom < Height) && ((SrcY1 & 0x0FFFF) <= (SrcY2 & 0x0FFFF)))
+ Bottom++;
+
+ nPixel = Right - Left;
+ nLine = Bottom - Top;
+
+ SrcPitch = Width << 1;
+ Buffer += (Top * SrcPitch) + (Left << 1);
+ pDst += ((Top - SrcTop) * DstPitch) + ((Left - SrcLeft) << 1);
+
+ xf86XVCopyPacked(Buffer, pDst, SrcPitch, DstPitch, nLine, nPixel);
+ break;
+ }
+
+ if (!REGION_EQUAL(pScreen, &pATI->VideoClip, pClip))
+ {
+ REGION_COPY(pScreen, &pATI->VideoClip, pClip);
+ if (pATI->AutoPaint)
+ xf86XVFillKeyHelper(pScreen, pATI->NewHW.overlay_graphics_key_clr,
+ pClip);
+ }
+
+ ATIMach64DisplayVideo(pScreenInfo, pATI, &DstBox, ImageID,
+ Offset, DstPitch / 2, SrcW, SrcH, DstW, DstH, DstWidth, DstHeight);
+
+ return Success;
+}
+
+/*
+ * ATIMach64AllocateSurface --
+ *
+ * This function allocates an offscreen buffer (called a "surface") for use by
+ * an external driver such as 'v4l'.
+ */
+static int
+ATIMach64AllocateSurface
+(
+ ScrnInfoPtr pScreenInfo,
+ int ImageID,
+ unsigned short Width,
+ unsigned short Height,
+ XF86SurfacePtr pSurface
+)
+{
+ ScreenPtr pScreen;
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ int XVOffset;
+
+ if (pATI->ActiveSurface)
+ return BadAlloc;
+
+ if ((Height <= 0) || (Height > 2048) || (Width <= 0) || (Width > 768) ||
+ ((Width > 384) && (pATI->Chip < ATI_CHIP_264VTB)) ||
+ ((Width > 720) && (pATI->Chip < ATI_CHIP_264GTPRO ||
+ pATI->Chip > ATI_CHIP_264LTPRO)))
+ return BadValue;
+
+ Width = (Width + 1) & ~1;
+ pATI->SurfacePitch = ((Width << 1) + 15) & ~15;
+
+ pScreen = pScreenInfo->pScreen;
+
+ pATI->pXVBuffer = ATIMach64XVMemAlloc(pScreen, pATI->pXVBuffer,
+ Height * pATI->SurfacePitch, &XVOffset, pATI);
+ if (!pATI->pXVBuffer)
+ return BadAlloc;
+
+ pATI->SurfaceOffset = XVOffset;
+
+ pSurface->pScrn = pScreenInfo;
+ pSurface->id = ImageID;
+ pSurface->width = Width;
+ pSurface->height = Height;
+ pSurface->pitches = &pATI->SurfacePitch;
+ pSurface->offsets = &pATI->SurfaceOffset;
+ pSurface->devPrivate.ptr = pATI;
+
+ /* Stop the video */
+ outf(OVERLAY_SCALE_CNTL, SCALE_EN);
+ REGION_EMPTY(pScreen, &pATI->VideoClip);
+ pATI->ActiveSurface = TRUE;
+
+ return Success;
+}
+
+/*
+ * ATIMach64FreeSurface --
+ *
+ * This function called to free a surface's offscreen buffer.
+ */
+static int
+ATIMach64FreeSurface
+(
+ XF86SurfacePtr pSurface
+)
+{
+ ATIPtr pATI = pSurface->devPrivate.ptr;
+
+ if (!pATI->ActiveSurface)
+ return Success;
+
+ outf(OVERLAY_SCALE_CNTL, SCALE_EN);
+ ATIMach64XVMemFree(pSurface->pScrn->pScreen, pATI->pXVBuffer, pATI);
+ pATI->pXVBuffer = NULL;
+ pATI->ActiveSurface = FALSE;
+
+ return Success;
+}
+
+/*
+ * ATIMach64DisplaySurface --
+ *
+ * This function is called to display a video surface.
+ */
+static int
+ATIMach64DisplaySurface
+(
+ XF86SurfacePtr pSurface,
+ short SrcX,
+ short SrcY,
+ short DstX,
+ short DstY,
+ short SrcW,
+ short SrcH,
+ short DstW,
+ short DstH,
+ RegionPtr pClip
+)
+{
+ ATIPtr pATI = pSurface->devPrivate.ptr;
+ ScrnInfoPtr pScreenInfo;
+ int ImageID;
+ short Width, Height;
+ BoxRec DstBox;
+ INT32 SrcX1, SrcX2, SrcY1, SrcY2;
+ int SrcLeft, SrcTop, SrcPitch, Offset;
+
+ if (!pATI->ActiveSurface)
+ return Success;
+
+ pScreenInfo = pSurface->pScrn;
+ ImageID = pSurface->id;
+ Width = pSurface->width;
+ Height = pSurface->height;
+
+ if (!ATIMach64ClipVideo(pScreenInfo, pATI, ImageID,
+ SrcX, SrcY, SrcW, SrcH,
+ DstX, DstY, &DstW, &DstH,
+ Width, Height, pClip, &DstBox,
+ &SrcX1, &SrcX2, &SrcY1, &SrcY2,
+ &SrcLeft, &SrcTop))
+ return Success;
+
+ xf86XVFillKeyHelper(pScreenInfo->pScreen,
+ pATI->NewHW.overlay_graphics_key_clr, pClip);
+
+ SrcPitch = pSurface->pitches[0];
+ Offset = pSurface->offsets[0] + (SrcTop * SrcPitch) + (SrcLeft << 1);
+ ATIMach64DisplayVideo(pScreenInfo, pATI, &DstBox, ImageID,
+ Offset, SrcPitch, SrcW, SrcH, DstW, DstH, Width, Height);
+
+ return Success;
+}
+
+/*
+ * ATIMach64StopSurface --
+ *
+ * This function is called to stop the overlaid display of a video surface.
+ */
+static int
+ATIMach64StopSurface
+(
+ XF86SurfacePtr pSurface
+)
+{
+ ATIPtr pATI = pSurface->devPrivate.ptr;
+
+ if (pATI->ActiveSurface)
+ outf(OVERLAY_SCALE_CNTL, SCALE_EN);
+
+ return Success;
+}
+
+/*
+ * ATIMach64GetSurfaceAttribute --
+ *
+ * Retrieve the value of an XVideo attribute.
+ */
+static int
+ATIMach64GetSurfaceAttribute
+(
+ ScrnInfoPtr pScreenInfo,
+ Atom AttributeID,
+ INT32 *Value
+)
+{
+ return ATIMach64GetPortAttribute(pScreenInfo, AttributeID, Value,
+ ATIPTR(pScreenInfo));
+}
+
+/*
+ * ATIMach64SetSurfaceAttribute
+ *
+ * Set the value of an XVideo attribute.
+ */
+static int
+ATIMach64SetSurfaceAttribute
+(
+ ScrnInfoPtr pScreenInfo,
+ Atom AttributeID,
+ INT32 Value
+)
+{
+ return ATIMach64SetPortAttribute(pScreenInfo, AttributeID, Value,
+ ATIPTR(pScreenInfo));
+}
+
+/* XVideo surface registration data */
+static XF86OffscreenImageRec ATIMach64Surface[] =
+{
+ {
+ &ATIMach64Image[0], /* YUY2 */
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT,
+ ATIMach64AllocateSurface,
+ ATIMach64FreeSurface,
+ ATIMach64DisplaySurface,
+ ATIMach64StopSurface,
+ ATIMach64GetSurfaceAttribute,
+ ATIMach64SetSurfaceAttribute,
+ 720, 2048,
+ nATIMach64Attribute - 1, /* No double-buffering */
+ ATIMach64Attribute
+ },
+ {
+ &ATIMach64Image[1], /* UYVY */
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT,
+ ATIMach64AllocateSurface,
+ ATIMach64FreeSurface,
+ ATIMach64DisplaySurface,
+ ATIMach64StopSurface,
+ ATIMach64GetSurfaceAttribute,
+ ATIMach64SetSurfaceAttribute,
+ 720, 2048,
+ nATIMach64Attribute - 1, /* No double-buffering */
+ ATIMach64Attribute
+ }
+};
+#define nATIMach64Surface NumberOf(ATIMach64Surface)
+
+/*
+ * ATIMach64XVInitialiseAdaptor --
+ *
+ * This function is called to make a Mach64's hardware overlay support
+ * available as an XVideo adaptor.
+ */
+static int
+ATIMach64XVInitialiseAdaptor
+(
+ ScrnInfoPtr pScreenInfo,
+ XF86VideoAdaptorPtr **pppAdaptor
+)
+{
+ ScreenPtr pScreen = screenInfo.screens[pScreenInfo->scrnIndex];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ XF86VideoAdaptorPtr *ppAdaptor = NULL;
+ XF86VideoAdaptorPtr pAdaptor;
+ int Index;
+
+ XF86VideoEncodingPtr enc = &(ATIMach64VideoEncoding[0]);
+ XF86OffscreenImagePtr surf0 = &(ATIMach64Surface[0]);
+ XF86OffscreenImagePtr surf1 = &(ATIMach64Surface[1]);
+
+ if (pppAdaptor)
+ *pppAdaptor = NULL;
+
+ if (!pATI->Block1Base)
+ return 0;
+
+ if (!(pAdaptor = xf86XVAllocateVideoAdaptorRec(pScreenInfo)))
+ return 0;
+
+ ppAdaptor = xnfalloc(sizeof(pAdaptor));
+ ppAdaptor[0] = pAdaptor;
+
+ pAdaptor->nPorts = 1;
+ pAdaptor->pPortPrivates = pATI->XVPortPrivate;
+ pATI->XVPortPrivate[0].ptr = pATI;
+
+ pAdaptor->type = XvInputMask | XvImageMask | XvWindowMask;
+ pAdaptor->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+ pAdaptor->name = "ATI Mach64 Back-end Overlay Scaler";
+
+ if (pATI->Chip < ATI_CHIP_264VTB)
+ {
+ enc->width = 384;
+ }
+ else if (pATI->Chip < ATI_CHIP_264GTPRO ||
+ pATI->Chip > ATI_CHIP_264LTPRO)
+ {
+ enc->width = 720; /* default */
+ }
+ else
+ {
+ enc->width = 768;
+ }
+ pAdaptor->nEncodings = nATIMach64VideoEncoding;
+ pAdaptor->pEncodings = ATIMach64VideoEncoding;
+
+ pAdaptor->nFormats = nATIMach64VideoFormat;
+ pAdaptor->pFormats = ATIMach64VideoFormat;
+
+ pAdaptor->nAttributes = nATIMach64Attribute;
+ pAdaptor->pAttributes = ATIMach64Attribute;
+
+ if (pATI->Chip < ATI_CHIP_264GTPRO)
+ {
+ /* Older controllers don't have brightness or saturation controls */
+ pAdaptor->nAttributes -= 4;
+ pAdaptor->pAttributes += 4;
+ }
+
+ pAdaptor->nImages = nATIMach64Image;
+ pAdaptor->pImages = ATIMach64Image;
+
+ pAdaptor->StopVideo = ATIMach64StopVideo;
+ pAdaptor->SetPortAttribute = ATIMach64SetPortAttribute;
+ pAdaptor->GetPortAttribute = ATIMach64GetPortAttribute;
+ pAdaptor->QueryBestSize = ATIMach64QueryBestSize;
+ pAdaptor->PutImage = ATIMach64PutImage;
+ pAdaptor->QueryImageAttributes = ATIMach64QueryImageAttributes;
+
+ REGION_NULL(pScreen, &pATI->VideoClip);
+ pATI->ActiveSurface = FALSE;
+
+ if (ATIMach64XVAtomGeneration != serverGeneration)
+ {
+ /* Refresh static data */
+ ATIMach64XVAtomGeneration = serverGeneration;
+
+ Index = nATIMach64Attribute - pAdaptor->nAttributes;
+ for (; Index < nATIMach64Attribute; Index++)
+ ATIMach64AttributeInfo[Index].AttributeID =
+ MAKE_ATOM(ATIMach64Attribute[Index].name);
+ }
+
+ ATIMach64SetDefaultAttributes(pATI, 0);
+
+ if (pATI->Chip < ATI_CHIP_264VTB)
+ {
+ surf0->max_width = 384;
+ surf1->max_width = 384;
+ }
+ else if (pATI->Chip < ATI_CHIP_264GTPRO ||
+ pATI->Chip > ATI_CHIP_264LTPRO)
+ {
+ surf0->max_width = 720; /* default */
+ surf1->max_width = 720;
+ }
+ else
+ {
+ surf0->max_width = 768;
+ surf1->max_width = 768;
+ }
+
+ if (pATI->Chip < ATI_CHIP_264GTPRO)
+ {
+ /* No saturation nor brightness */
+ surf0->num_attributes -= 4;
+ surf1->num_attributes -= 4;
+ surf0->attributes += 4;
+ surf1->attributes += 4;
+ }
+ xf86XVRegisterOffscreenImages(pScreen, ATIMach64Surface, nATIMach64Surface);
+
+ if (pppAdaptor)
+ *pppAdaptor = ppAdaptor;
+ else {
+ xfree(ppAdaptor[0]);
+ xfree(ppAdaptor);
+ }
+
+ return 1;
+}
+
+/*
+ * ATIXVPreInit --
+ *
+ * This function is called by ATIPreInit() to set up the environment required
+ * to support the XVideo extension.
+ */
+void
+ATIXVPreInit
+(
+ ATIPtr pATI
+)
+{
+ (void)xf86XVRegisterGenericAdaptorDriver(ATIMach64XVInitialiseAdaptor);
+}
+
+/*
+ * ATIXVFreeAdaptorInfo --
+ *
+ * Free XVideo adaptor information.
+ */
+static void
+ATIXVFreeAdaptorInfo
+(
+ XF86VideoAdaptorPtr *ppAdaptor,
+ int nAdaptor
+)
+{
+ if (!ppAdaptor)
+ return;
+
+ while (nAdaptor > 0)
+ xfree(ppAdaptor[--nAdaptor]);
+
+ xfree(ppAdaptor);
+}
+
+/*
+ * 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;
+
+ pScreenInfo->memPhysBase = pATI->LinearBase;
+ pScreenInfo->fbOffset = 0;
+
+ nAdaptor = xf86XVListGenericAdaptors(pScreenInfo, &ppAdaptor);
+ result = xf86XVScreenInit(pScreen, ppAdaptor, nAdaptor);
+
+ ATIXVFreeAdaptorInfo(ppAdaptor, nAdaptor);
+
+ return result;
+}
+
+/*
+ * ATIMach64CloseXVideo --
+ *
+ * This function is called during screen termination to clean up after
+ * initialisation of Mach64 XVideo support.
+ */
+void
+ATICloseXVideo
+(
+ ScreenPtr pScreen,
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI
+)
+{
+ ATIMach64StopVideo(pScreenInfo, pATI, TRUE);
+
+ REGION_UNINIT(pScreen, &pATI->VideoClip);
+}
+
+/* Functions for offscreen memory management */
+
+#ifdef USE_XAA
+static 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;
+}
+#endif /* USE_XAA */
+
+static pointer
+ATIMach64XVMemAlloc
+(
+ ScreenPtr pScreen,
+ pointer pVideo,
+ int size,
+ int *offset,
+ ATIPtr pATI
+)
+{
+#ifdef USE_EXA
+ if (pATI->useEXA) {
+ ExaOffscreenArea *area = (ExaOffscreenArea *)pVideo;
+
+ if (area != NULL) {
+ if (area->size >= size) {
+ *offset = area->offset;
+ return area;
+ }
+
+ exaOffscreenFree(pScreen, area);
+ }
+
+ area = exaOffscreenAlloc(pScreen, size, 64, TRUE, NULL, NULL);
+ if (area != NULL) {
+ *offset = area->offset;
+ return area;
+ }
+ }
+#endif /* USE_EXA */
+
+#ifdef USE_XAA
+ if (!pATI->useEXA) {
+ FBLinearPtr linear = (FBLinearPtr)pVideo;
+ int cpp = pATI->AdjustDepth;
+
+ /* XAA allocates in units of pixels at the screen bpp, so adjust size
+ * appropriately.
+ */
+ size = (size + cpp - 1) / cpp;
+
+ linear = ATIResizeOffscreenLinear(pScreen, linear, size);
+ if (linear != NULL) {
+ *offset = linear->offset * cpp;
+ return linear;
+ }
+ }
+#endif /* USE_XAA */
+
+ *offset = 0;
+ return NULL;
+}
+
+static void
+ATIMach64XVMemFree
+(
+ ScreenPtr pScreen,
+ pointer pVideo,
+ ATIPtr pATI
+)
+{
+#ifdef USE_EXA
+ if (pATI->useEXA) {
+ ExaOffscreenArea *area = (ExaOffscreenArea *)pVideo;
+
+ if (area != NULL)
+ exaOffscreenFree(pScreen, area);
+ }
+#endif /* USE_EXA */
+
+#ifdef USE_XAA
+ if (!pATI->useEXA) {
+ FBLinearPtr linear = (FBLinearPtr)pVideo;
+
+ if (linear != NULL)
+ ATIResizeOffscreenLinear(pScreen, linear, 0);
+ }
+#endif /* USE_XAA */
+}
+
diff --git a/driver/xf86-video-mach64/src/atimisc.c b/driver/xf86-video-mach64/src/atimisc.c
new file mode 100644
index 000000000..24897c318
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atimisc.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "ati.h"
+#include "atimach64probe.h"
+#include "atimach64version.h"
+
+/* Module loader interface for subsidiary driver module */
+
+static XF86ModuleVersionInfo ATIVersionRec =
+{
+ MACH64_DRIVER_NAME,
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XORG_VERSION_CURRENT,
+ PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
+ 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(&MACH64, Module, HaveDriverFuncs);
+ }
+
+ return (pointer)TRUE;
+}
+
+/* The following record must be called mach64ModuleData */
+_X_EXPORT XF86ModuleData mach64ModuleData =
+{
+ &ATIVersionRec,
+ ATISetup,
+ NULL
+};
diff --git a/driver/xf86-video-mach64/src/atimode.c b/driver/xf86-video-mach64/src/atimode.c
new file mode 100644
index 000000000..d1b319815
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atimode.c
@@ -0,0 +1,1084 @@
+/*
+ * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include "ati.h"
+#include "atichip.h"
+#include "atidac.h"
+#include "atidsp.h"
+#include "atimach64.h"
+#include "atimach64io.h"
+#include "atimode.h"
+#include "atiprint.h"
+#include "atirgb514.h"
+#include "ativga.h"
+#include "atiwonder.h"
+#include "atiwonderio.h"
+
+#ifdef TV_OUT
+
+#include "vbe.h"
+
+#endif /* TV_OUT */
+
+#ifndef AVOID_CPIO
+
+/*
+ * ATICopyVGAMemory --
+ *
+ * This function is called to copy one or all banks of a VGA plane.
+ */
+static void
+ATICopyVGAMemory
+(
+ ATIPtr pATI,
+ ATIHWPtr pATIHW,
+ pointer *saveptr,
+ pointer *from,
+ pointer *to
+)
+{
+ unsigned int iBank;
+
+ for (iBank = 0; iBank < pATIHW->nBank; iBank++)
+ {
+ (*pATIHW->SetBank)(pATI, iBank);
+ (void)memcpy(*to, *from, 0x00010000U);
+ *saveptr = (char *)(*saveptr) + 0x00010000U;
+ }
+}
+
+/*
+ * ATISwap --
+ *
+ * This function saves/restores video memory contents during video mode
+ * switches.
+ */
+static void
+ATISwap
+(
+ int iScreen,
+ ATIPtr pATI,
+ ATIHWPtr pATIHW,
+ Bool ToFB
+)
+{
+ pointer save, *from, *to;
+ unsigned int iPlane = 0, PlaneMask = 1;
+ CARD8 seq2, seq4, gra1, gra3, gra4, gra5, gra6, gra8;
+
+ /*
+ * This is only done for non-accelerator modes. If the video state on
+ * server entry was an accelerator mode, the application that relinquished
+ * the console had better do the Right Thing (tm) anyway by saving and
+ * restoring its own video memory contents.
+ */
+ if (pATIHW->crtc != ATI_CRTC_VGA)
+ return;
+
+ if (ToFB)
+ {
+ if (!pATIHW->frame_buffer)
+ return;
+
+ from = &save;
+ to = &pATI->pBank;
+ }
+ else
+ {
+ /* Allocate the memory */
+ if (!pATIHW->frame_buffer)
+ {
+ pATIHW->frame_buffer =
+ (pointer)xalloc(pATIHW->nBank * pATIHW->nPlane * 0x00010000U);
+ if (!pATIHW->frame_buffer)
+ {
+ xf86DrvMsg(iScreen, X_WARNING,
+ "Temporary frame buffer could not be allocated.\n");
+ return;
+ }
+ }
+
+ from = &pATI->pBank;
+ to = &save;
+ }
+
+ /* Turn off screen */
+ ATIVGASaveScreen(pATI, SCREEN_SAVER_ON);
+
+ /* Save register values to be modified */
+ seq2 = GetReg(SEQX, 0x02U);
+ seq4 = GetReg(SEQX, 0x04U);
+ gra1 = GetReg(GRAX, 0x01U);
+ gra3 = GetReg(GRAX, 0x03U);
+ gra5 = GetReg(GRAX, 0x05U);
+ gra6 = GetReg(GRAX, 0x06U);
+ gra8 = GetReg(GRAX, 0x08U);
+
+ save = pATIHW->frame_buffer;
+
+ /* Temporarily normalise the mode */
+ if (gra1 != 0x00U)
+ PutReg(GRAX, 0x01U, 0x00U);
+ if (gra3 != 0x00U)
+ PutReg(GRAX, 0x03U, 0x00U);
+ if (gra6 != 0x05U)
+ PutReg(GRAX, 0x06U, 0x05U);
+ if (gra8 != 0xFFU)
+ PutReg(GRAX, 0x08U, 0xFFU);
+
+ if (seq4 & 0x08U)
+ {
+ /* Setup packed mode memory */
+ if (seq2 != 0x0FU)
+ PutReg(SEQX, 0x02U, 0x0FU);
+ if (seq4 != 0x0AU)
+ PutReg(SEQX, 0x04U, 0x0AU);
+ if (pATI->Chip < ATI_CHIP_264CT)
+ {
+ if (gra5 != 0x00U)
+ PutReg(GRAX, 0x05U, 0x00U);
+ }
+ else
+ {
+ if (gra5 != 0x40U)
+ PutReg(GRAX, 0x05U, 0x40U);
+ }
+
+ ATICopyVGAMemory(pATI, pATIHW, &save, from, to);
+
+ if (seq2 != 0x0FU)
+ PutReg(SEQX, 0x02U, seq2);
+ if (seq4 != 0x0AU)
+ PutReg(SEQX, 0x04U, seq4);
+ if (pATI->Chip < ATI_CHIP_264CT)
+ {
+ if (gra5 != 0x00U)
+ PutReg(GRAX, 0x05U, gra5);
+ }
+ else
+ {
+ if (gra5 != 0x40U)
+ PutReg(GRAX, 0x05U, gra5);
+ }
+ }
+ else
+ {
+ gra4 = GetReg(GRAX, 0x04U);
+
+ /* Setup planar mode memory */
+ if (seq4 != 0x06U)
+ PutReg(SEQX, 0x04U, 0x06U);
+ if (gra5 != 0x00U)
+ PutReg(GRAX, 0x05U, 0x00U);
+
+ for (; iPlane < pATIHW->nPlane; iPlane++)
+ {
+ PutReg(SEQX, 0x02U, PlaneMask);
+ PutReg(GRAX, 0x04U, iPlane);
+ ATICopyVGAMemory(pATI, pATIHW, &save, from, to);
+ PlaneMask <<= 1;
+ }
+
+ PutReg(SEQX, 0x02U, seq2);
+ if (seq4 != 0x06U)
+ PutReg(SEQX, 0x04U, seq4);
+ PutReg(GRAX, 0x04U, gra4);
+ if (gra5 != 0x00U)
+ PutReg(GRAX, 0x05U, gra5);
+ }
+
+ /* Restore registers */
+ if (gra1 != 0x00U)
+ PutReg(GRAX, 0x01U, gra1);
+ if (gra3 != 0x00U)
+ PutReg(GRAX, 0x03U, gra3);
+ if (gra6 != 0x05U)
+ PutReg(GRAX, 0x06U, gra6);
+ if (gra8 != 0xFFU)
+ PutReg(GRAX, 0x08U, gra8);
+
+ /* Back to bank 0 */
+ (*pATIHW->SetBank)(pATI, 0);
+}
+
+#endif /* AVOID_CPIO */
+
+/*
+ * ATIModePreInit --
+ *
+ * This function initialises an ATIHWRec with information common to all video
+ * states generated by the driver.
+ */
+void
+ATIModePreInit
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI,
+ ATIHWPtr pATIHW
+)
+{
+ CARD32 lcd_index;
+
+#ifndef AVOID_CPIO
+
+ if (pATI->VGAAdapter)
+ {
+ /* Fill in VGA data */
+ ATIVGAPreInit(pATI, pATIHW);
+
+ /* Fill in VGA Wonder data */
+ if (pATI->CPIO_VGAWonder)
+ ATIVGAWonderPreInit(pATI, pATIHW);
+ }
+
+#endif /* AVOID_CPIO */
+
+ {
+ /* Fill in Mach64 data */
+ ATIMach64PreInit(pScreenInfo, pATI, pATIHW);
+
+ if (pATI->Chip >= ATI_CHIP_264CT)
+ {
+ /* Ensure proper VCLK source */
+ pATIHW->pll_vclk_cntl = ATIMach64GetPLLReg(PLL_VCLK_CNTL) |
+ (PLL_VCLK_SRC_SEL | PLL_VCLK_RESET);
+
+ /* Set provisional values for other PLL registers */
+ pATIHW->pll_vclk_post_div = ATIMach64GetPLLReg(PLL_VCLK_POST_DIV);
+ pATIHW->pll_vclk0_fb_div = ATIMach64GetPLLReg(PLL_VCLK0_FB_DIV);
+ pATIHW->pll_vclk1_fb_div = ATIMach64GetPLLReg(PLL_VCLK1_FB_DIV);
+ pATIHW->pll_vclk2_fb_div = ATIMach64GetPLLReg(PLL_VCLK2_FB_DIV);
+ pATIHW->pll_vclk3_fb_div = ATIMach64GetPLLReg(PLL_VCLK3_FB_DIV);
+ pATIHW->pll_xclk_cntl = ATIMach64GetPLLReg(PLL_XCLK_CNTL);
+
+ /* For now disable extended reference and feedback dividers */
+ if (pATI->Chip >= ATI_CHIP_264LT)
+ pATIHW->pll_ext_vpll_cntl =
+ ATIMach64GetPLLReg(PLL_EXT_VPLL_CNTL) &
+ ~(PLL_EXT_VPLL_EN | PLL_EXT_VPLL_VGA_EN |
+ PLL_EXT_VPLL_INSYNC);
+
+ /* Initialise CRTC data for LCD panels */
+ if (pATI->LCDPanelID >= 0)
+ {
+ if (pATI->Chip == ATI_CHIP_264LT)
+ {
+ pATIHW->lcd_gen_ctrl = inr(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);
+ pATIHW->lcd_index = lcd_index &
+ ~(LCD_REG_INDEX | LCD_DISPLAY_DIS | LCD_SRC_SEL |
+ LCD_CRTC2_DISPLAY_DIS);
+ if (pATI->Chip != ATI_CHIP_264XL)
+ pATIHW->lcd_index |= LCD_CRTC2_DISPLAY_DIS;
+ pATIHW->config_panel =
+ ATIMach64GetLCDReg(LCD_CONFIG_PANEL) |
+ DONT_SHADOW_HEND;
+ pATIHW->lcd_gen_ctrl =
+ ATIMach64GetLCDReg(LCD_GEN_CNTL) & ~CRTC_RW_SELECT;
+ outr(LCD_INDEX, lcd_index);
+ }
+
+ pATIHW->lcd_gen_ctrl &=
+ ~(HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 | MCLK_PM_EN |
+ VCLK_DAC_PM_EN | USE_SHADOWED_VEND |
+ USE_SHADOWED_ROWCUR | SHADOW_EN | SHADOW_RW_EN);
+ pATIHW->lcd_gen_ctrl |= DONT_SHADOW_VPAR | LOCK_8DOT;
+
+ if (!pATI->OptionPanelDisplay)
+ {
+ /*
+ * Use primary CRTC to drive the CRT. Turn off panel
+ * interface.
+ */
+ pATIHW->lcd_gen_ctrl &= ~LCD_ON;
+ pATIHW->lcd_gen_ctrl |= CRT_ON;
+ }
+ else
+ {
+ /* Use primary CRTC to drive the panel */
+ pATIHW->lcd_gen_ctrl |= LCD_ON;
+
+ /* If requested, also force CRT on */
+ if (pATI->OptionCRTDisplay)
+ pATIHW->lcd_gen_ctrl |= CRT_ON;
+ }
+ }
+ }
+ else if (pATI->DAC == ATI_DAC_IBMRGB514)
+ {
+ ATIRGB514PreInit(pATI, pATIHW);
+ }
+ }
+
+ /* Set RAMDAC data */
+ ATIDACPreInit(pScreenInfo, pATI, pATIHW);
+}
+
+/*
+ * ATIModeSave --
+ *
+ * This function saves the current video state.
+ */
+void
+ATIModeSave
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI,
+ ATIHWPtr pATIHW
+)
+{
+
+#ifndef AVOID_CPIO
+
+ int Index;
+
+ /* Get back to bank 0 */
+ (*pATIHW->SetBank)(pATI, 0);
+
+#endif /* AVOID_CPIO */
+
+ if (pATI->Chip >= ATI_CHIP_264CT)
+ {
+ pATIHW->pll_vclk_cntl = ATIMach64GetPLLReg(PLL_VCLK_CNTL) |
+ PLL_VCLK_RESET;
+ pATIHW->pll_vclk_post_div = ATIMach64GetPLLReg(PLL_VCLK_POST_DIV);
+ pATIHW->pll_vclk0_fb_div = ATIMach64GetPLLReg(PLL_VCLK0_FB_DIV);
+ pATIHW->pll_vclk1_fb_div = ATIMach64GetPLLReg(PLL_VCLK1_FB_DIV);
+ pATIHW->pll_vclk2_fb_div = ATIMach64GetPLLReg(PLL_VCLK2_FB_DIV);
+ pATIHW->pll_vclk3_fb_div = ATIMach64GetPLLReg(PLL_VCLK3_FB_DIV);
+ pATIHW->pll_xclk_cntl = ATIMach64GetPLLReg(PLL_XCLK_CNTL);
+ if (pATI->Chip >= ATI_CHIP_264LT)
+ pATIHW->pll_ext_vpll_cntl = ATIMach64GetPLLReg(PLL_EXT_VPLL_CNTL);
+
+ /* Save LCD registers */
+ if (pATI->LCDPanelID >= 0)
+ {
+ if (pATI->Chip == ATI_CHIP_264LT)
+ {
+ pATIHW->horz_stretching = inr(HORZ_STRETCHING);
+ pATIHW->vert_stretching = inr(VERT_STRETCHING);
+ pATIHW->lcd_gen_ctrl = inr(LCD_GEN_CTRL);
+
+ /* Set up to save non-shadow registers */
+ outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl & ~SHADOW_RW_EN);
+ }
+ else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
+ (pATI->Chip == ATI_CHIP_264XL) ||
+ (pATI->Chip == ATI_CHIP_MOBILITY)) */
+ {
+ pATIHW->lcd_index = inr(LCD_INDEX);
+ pATIHW->config_panel = ATIMach64GetLCDReg(LCD_CONFIG_PANEL);
+ pATIHW->lcd_gen_ctrl = ATIMach64GetLCDReg(LCD_GEN_CNTL);
+ pATIHW->horz_stretching =
+ ATIMach64GetLCDReg(LCD_HORZ_STRETCHING);
+ pATIHW->vert_stretching =
+ ATIMach64GetLCDReg(LCD_VERT_STRETCHING);
+ pATIHW->ext_vert_stretch =
+ ATIMach64GetLCDReg(LCD_EXT_VERT_STRETCH);
+
+ /* Set up to save non-shadow registers */
+ ATIMach64PutLCDReg(LCD_GEN_CNTL,
+ pATIHW->lcd_gen_ctrl & ~(CRTC_RW_SELECT | SHADOW_RW_EN));
+ }
+ }
+ }
+
+#ifndef AVOID_CPIO
+
+ if (pATI->VGAAdapter)
+ {
+ /* Save VGA data */
+ ATIVGASave(pATI, pATIHW);
+
+ /* Save VGA Wonder data */
+ if (pATI->CPIO_VGAWonder)
+ ATIVGAWonderSave(pATI, pATIHW);
+ }
+
+#endif /* AVOID_CPIO */
+
+ {
+ /* Save Mach64 data */
+ ATIMach64Save(pATI, pATIHW);
+
+ if (pATI->Chip >= ATI_CHIP_264VTB)
+ {
+ /* Save DSP data */
+ ATIDSPSave(pATI, pATIHW);
+
+ if (pATI->LCDPanelID >= 0)
+ {
+ /* Switch to shadow registers */
+ if (pATI->Chip == ATI_CHIP_264LT)
+ outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl | SHADOW_RW_EN);
+ else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
+ (pATI->Chip == ATI_CHIP_264XL) ||
+ (pATI->Chip == ATI_CHIP_MOBILITY)) */
+ ATIMach64PutLCDReg(LCD_GEN_CNTL,
+ (pATIHW->lcd_gen_ctrl & ~CRTC_RW_SELECT) |
+ SHADOW_RW_EN);
+
+#ifndef AVOID_CPIO
+
+ /* Save shadow VGA CRTC registers */
+ for (Index = 0;
+ Index < NumberOf(pATIHW->shadow_vga);
+ Index++)
+ pATIHW->shadow_vga[Index] =
+ GetReg(CRTX(pATI->CPIO_VGABase), Index);
+
+#endif /* AVOID_CPIO */
+
+ /* Save shadow Mach64 CRTC registers */
+ pATIHW->shadow_h_total_disp = inr(CRTC_H_TOTAL_DISP);
+ pATIHW->shadow_h_sync_strt_wid = inr(CRTC_H_SYNC_STRT_WID);
+ pATIHW->shadow_v_total_disp = inr(CRTC_V_TOTAL_DISP);
+ pATIHW->shadow_v_sync_strt_wid = inr(CRTC_V_SYNC_STRT_WID);
+
+ /* Restore CRTC selection and shadow state */
+ if (pATI->Chip == ATI_CHIP_264LT)
+ {
+ outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl);
+ }
+ else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
+ (pATI->Chip == ATI_CHIP_264XL) ||
+ (pATI->Chip == ATI_CHIP_MOBILITY)) */
+ {
+ ATIMach64PutLCDReg(LCD_GEN_CNTL, pATIHW->lcd_gen_ctrl);
+ outr(LCD_INDEX, pATIHW->lcd_index);
+ }
+ }
+ }
+ else if (pATI->DAC == ATI_DAC_IBMRGB514)
+ ATIRGB514Save(pATI, pATIHW);
+ }
+
+ /* Save RAMDAC state */
+ ATIDACSave(pATI, pATIHW);
+
+ if (pATIHW != &pATI->NewHW)
+ {
+ pATIHW->FeedbackDivider = 0; /* Don't programme clock */
+ }
+
+#ifndef AVOID_CPIO
+
+ /* Save video memory */
+ ATISwap(pScreenInfo->scrnIndex, pATI, pATIHW, FALSE);
+
+ if (pATI->VGAAdapter)
+ ATIVGASaveScreen(pATI, SCREEN_SAVER_OFF); /* Turn on screen */
+
+#endif /* AVOID_CPIO */
+
+}
+
+/*
+ * ATIModeCalculate --
+ *
+ * This function fills in an ATIHWRec with all register values needed to enable
+ * a video state. It's important that this be done without modifying the
+ * current video state.
+ */
+Bool
+ATIModeCalculate
+(
+ int iScreen,
+ ATIPtr pATI,
+ ATIHWPtr pATIHW,
+ DisplayModePtr pMode
+)
+{
+ CARD32 lcd_index;
+ int Index, ECPClock, MaxScalerClock;
+
+ /* Fill in Mach64 data */
+ ATIMach64Calculate(pATI, pATIHW, pMode);
+
+ /* Set up LCD register values */
+ if (pATI->LCDPanelID >= 0)
+ {
+ int VDisplay = pMode->VDisplay;
+
+ if (pMode->Flags & V_DBLSCAN)
+ VDisplay <<= 1;
+ if (pMode->VScan > 1)
+ VDisplay *= pMode->VScan;
+ if (pMode->Flags & V_INTERLACE)
+ VDisplay >>= 1;
+
+ /* Ensure secondary CRTC is completely disabled */
+ pATIHW->crtc_gen_cntl &= ~(CRTC2_EN | CRTC2_PIX_WIDTH);
+
+ if (pATI->Chip == ATI_CHIP_264LT)
+ {
+ pATIHW->horz_stretching = inr(HORZ_STRETCHING);
+ }
+ else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
+ (pATI->Chip == ATI_CHIP_264XL) ||
+ (pATI->Chip == ATI_CHIP_MOBILITY)) */
+ {
+ lcd_index = inr(LCD_INDEX);
+ pATIHW->horz_stretching = ATIMach64GetLCDReg(LCD_HORZ_STRETCHING);
+ pATIHW->ext_vert_stretch =
+ ATIMach64GetLCDReg(LCD_EXT_VERT_STRETCH) &
+ ~(AUTO_VERT_RATIO | VERT_STRETCH_MODE | VERT_STRETCH_RATIO3);
+
+ /*
+ * Don't use vertical blending if the mode is too wide or not
+ * vertically stretched.
+ */
+ if (pATI->OptionPanelDisplay &&
+ (pMode->HDisplay <= pATI->LCDVBlendFIFOSize) &&
+ (VDisplay < pATI->LCDVertical))
+ pATIHW->ext_vert_stretch |= VERT_STRETCH_MODE;
+
+ outr(LCD_INDEX, lcd_index);
+ }
+
+ pATIHW->horz_stretching &=
+ ~(HORZ_STRETCH_RATIO | HORZ_STRETCH_LOOP | AUTO_HORZ_RATIO |
+ HORZ_STRETCH_MODE | HORZ_STRETCH_EN);
+ if (pATI->OptionPanelDisplay &&
+ (pMode->HDisplay < pATI->LCDHorizontal))
+ do
+ {
+ /*
+ * The horizontal blender misbehaves when HDisplay is less than a
+ * a certain threshold (440 for a 1024-wide panel). It doesn't
+ * stretch such modes enough. Use pixel replication instead of
+ * blending to stretch modes that can be made to exactly fit the
+ * panel width. The undocumented "NoLCDBlend" option allows the
+ * pixel-replicated mode to be slightly wider or narrower than the
+ * panel width. It also causes a mode that is exactly half as wide
+ * as the panel to be pixel-replicated, rather than blended.
+ */
+ int HDisplay = pMode->HDisplay & ~7;
+ int nStretch = pATI->LCDHorizontal / HDisplay;
+ int Remainder = pATI->LCDHorizontal % HDisplay;
+
+ if ((!Remainder && ((nStretch > 2) || !pATI->OptionBlend)) ||
+ (((HDisplay * 16) / pATI->LCDHorizontal) < 7))
+ {
+ static const char StretchLoops[] = {10, 12, 13, 15, 16};
+ int horz_stretch_loop = -1, BestRemainder;
+ int Numerator = HDisplay, Denominator = pATI->LCDHorizontal;
+
+ ATIReduceRatio(&Numerator, &Denominator);
+
+ BestRemainder = (Numerator * 16) / Denominator;
+ Index = NumberOf(StretchLoops);
+ while (--Index >= 0)
+ {
+ Remainder =
+ ((Denominator - Numerator) * StretchLoops[Index]) %
+ Denominator;
+ if (Remainder < BestRemainder)
+ {
+ horz_stretch_loop = Index;
+ if (!(BestRemainder = Remainder))
+ break;
+ }
+#if 0
+ /*
+ * Enabling this code allows the pixel-replicated mode to
+ * be slightly wider than the panel width.
+ */
+ Remainder = Denominator - Remainder;
+ if (Remainder < BestRemainder)
+ {
+ horz_stretch_loop = Index;
+ BestRemainder = Remainder;
+ }
+#endif
+ }
+
+ if ((horz_stretch_loop >= 0) &&
+ (!BestRemainder || !pATI->OptionBlend))
+ {
+ int horz_stretch_ratio = 0, Accumulator = 0;
+ int reuse_previous = 1;
+
+ Index = StretchLoops[horz_stretch_loop];
+
+ while (--Index >= 0)
+ {
+ if (Accumulator > 0)
+ horz_stretch_ratio |= reuse_previous;
+ else
+ Accumulator += Denominator;
+ Accumulator -= Numerator;
+ reuse_previous <<= 1;
+ }
+
+ pATIHW->horz_stretching |= HORZ_STRETCH_EN |
+ SetBits(horz_stretch_loop, HORZ_STRETCH_LOOP) |
+ SetBits(horz_stretch_ratio, HORZ_STRETCH_RATIO);
+ break; /* Out of the do { ... } while (0) */
+ }
+ }
+
+ pATIHW->horz_stretching |= (HORZ_STRETCH_MODE | HORZ_STRETCH_EN) |
+ SetBits((HDisplay * (MaxBits(HORZ_STRETCH_BLEND) + 1)) /
+ pATI->LCDHorizontal, HORZ_STRETCH_BLEND);
+ } while (0);
+
+ if (!pATI->OptionPanelDisplay || (VDisplay >= pATI->LCDVertical))
+ {
+ pATIHW->vert_stretching = 0;
+ }
+ else
+ {
+ pATIHW->vert_stretching = (VERT_STRETCH_USE0 | VERT_STRETCH_EN) |
+ SetBits((VDisplay * (MaxBits(VERT_STRETCH_RATIO0) + 1)) /
+ pATI->LCDVertical, VERT_STRETCH_RATIO0);
+ }
+
+#ifndef AVOID_CPIO
+
+ /* Copy non-shadow CRTC register values to the shadow set */
+ for (Index = 0; Index < NumberOf(pATIHW->shadow_vga); Index++)
+ pATIHW->shadow_vga[Index] = pATIHW->crt[Index];
+
+#endif /* AVOID_CPIO */
+
+ pATIHW->shadow_h_total_disp = pATIHW->crtc_h_total_disp;
+ pATIHW->shadow_h_sync_strt_wid = pATIHW->crtc_h_sync_strt_wid;
+ pATIHW->shadow_v_total_disp = pATIHW->crtc_v_total_disp;
+ pATIHW->shadow_v_sync_strt_wid = pATIHW->crtc_v_sync_strt_wid;
+ }
+
+ /* Fill in clock data */
+ if (!ATIClockCalculate(iScreen, pATI, pATIHW, pMode))
+ return FALSE;
+
+ /* Setup ECP clock divider */
+ if (pATI->Chip >= ATI_CHIP_264VT)
+ {
+ if (pATI->Chip <= ATI_CHIP_264VT3)
+ MaxScalerClock = 80000;
+ else if (pATI->Chip <= ATI_CHIP_264GT2C)
+ MaxScalerClock = 100000;
+ else if (pATI->Chip == ATI_CHIP_264GTPRO)
+ MaxScalerClock = 125000;
+ else if (pATI->Chip <= ATI_CHIP_MOBILITY)
+ MaxScalerClock = 135000;
+ else
+ MaxScalerClock = 80000; /* Conservative */
+ pATIHW->pll_vclk_cntl &= ~PLL_ECP_DIV;
+#ifdef TV_OUT
+ if (pATI->OptionTvOut) {
+ /* XXX Don't do this for TVOut! */
+ }
+ else
+#endif /* TV_OUT */
+ {
+ ECPClock = pMode->SynthClock;
+ for (Index = 0; (ECPClock > MaxScalerClock) && (Index < 2); Index++)
+ ECPClock >>= 1;
+ pATIHW->pll_vclk_cntl |= SetBits(Index, PLL_ECP_DIV);
+ }
+ }
+ else if (pATI->DAC == ATI_DAC_IBMRGB514)
+ {
+ ATIRGB514Calculate(pATI, pATIHW, pMode);
+ }
+
+ return TRUE;
+}
+
+#ifdef TV_OUT
+
+static void
+ATISetVBEMode
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI,
+ ATIHWPtr pATIHW
+)
+{
+ if (pATIHW->crtc == ATI_CRTC_MACH64) {
+ int vbemode, modekey;
+
+ /* Find a suitable VESA VBE mode, if one exists */
+ modekey = (pScreenInfo->depth << 16) |
+ (pScreenInfo->currentMode->HDisplay);
+
+ switch (modekey) {
+ case (15<<16)|(640):
+ vbemode = 0x110;
+ break;
+ case (16<<16)|(640):
+ vbemode = 0x111;
+ break;
+#if 0
+ case (24<<16)|(640):
+ vbemode = 0x112;
+ break;
+#endif
+ case (15<<16)|(800):
+ vbemode = 0x113;
+ break;
+ case (16<<16)|(800):
+ vbemode = 0x114;
+ break;
+#if 0
+ case (24<<16)|(800):
+ vbemode = 0x115;
+ break;
+#endif
+ case (15<<16)|(1024):
+ vbemode = 0x116;
+ break;
+ case (16<<16)|(1024):
+ vbemode = 0x117;
+ break;
+#if 0
+ case (24<<16)|(1024):
+ vbemode = 0x118;
+ break;
+#endif
+ default:
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "Mode not supported for TV-Out: depth: %d HDisplay: %d\n",
+ modekey>>16, modekey & 0xffff);
+ return;
+ }
+
+ if (pATI->pVBE) {
+
+ /* Preserve video memory contents */
+ vbemode |= (1<<15);
+
+ if (VBESetVBEMode(pATI->pVBE, vbemode, NULL)) {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "VBESetMode: 0x%X (width: %d, pitch: %d, depth: %d)\n",
+ vbemode,
+ pScreenInfo->currentMode->HDisplay,
+ pScreenInfo->displayWidth,
+ pScreenInfo->depth);
+ outr(CRTC_OFF_PITCH,
+ SetBits(pScreenInfo->displayWidth>>3, CRTC_PITCH));
+ } else {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, "VBESetMode failed.\n");
+ }
+ } else {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, "VBE module not loaded.\n");
+ }
+ } else {
+ /* restore text mode with VBESetMode */
+ if (pATI->pVBE) {
+ if (VBESetVBEMode(pATI->pVBE, pATI->vbemode, NULL)) {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, "Restoring VESA mode: 0x%x\n",
+ pATI->vbemode);
+ } else {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, "VBESetMode failed.\n");
+ }
+ } else {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, "VBE module not loaded.\n");
+ }
+ }
+ if (xf86ServerIsExiting()) {
+ if (pATI->pVBE) vbeFree(pATI->pVBE);
+ if (pATI->pInt10) xf86FreeInt10(pATI->pInt10);
+ }
+}
+
+#endif /* TV_OUT */
+
+/*
+ * ATIModeSet --
+ *
+ * This function sets a video mode. It writes out all video state data that
+ * has been previously calculated or saved.
+ */
+void
+ATIModeSet
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI,
+ ATIHWPtr pATIHW
+)
+{
+
+#ifndef AVOID_CPIO
+
+ int Index;
+
+ /* Get back to bank 0 */
+ (*pATIHW->SetBank)(pATI, 0);
+
+#endif /* AVOID_CPIO */
+
+ {
+ /* Stop CRTC */
+ outr(CRTC_GEN_CNTL,
+ pATIHW->crtc_gen_cntl & ~(CRTC_EXT_DISP_EN | CRTC_EN));
+
+ if (pATI->Chip >= ATI_CHIP_264CT)
+ {
+ ATIMach64PutPLLReg(PLL_VCLK_CNTL, pATIHW->pll_vclk_cntl);
+ ATIMach64PutPLLReg(PLL_VCLK_POST_DIV, pATIHW->pll_vclk_post_div);
+ ATIMach64PutPLLReg(PLL_VCLK0_FB_DIV, pATIHW->pll_vclk0_fb_div);
+ ATIMach64PutPLLReg(PLL_VCLK1_FB_DIV, pATIHW->pll_vclk1_fb_div);
+ ATIMach64PutPLLReg(PLL_VCLK2_FB_DIV, pATIHW->pll_vclk2_fb_div);
+ ATIMach64PutPLLReg(PLL_VCLK3_FB_DIV, pATIHW->pll_vclk3_fb_div);
+ ATIMach64PutPLLReg(PLL_XCLK_CNTL, pATIHW->pll_xclk_cntl);
+ if (pATI->Chip >= ATI_CHIP_264LT)
+ ATIMach64PutPLLReg(PLL_EXT_VPLL_CNTL,
+ pATIHW->pll_ext_vpll_cntl);
+ ATIMach64PutPLLReg(PLL_VCLK_CNTL,
+ pATIHW->pll_vclk_cntl & ~PLL_VCLK_RESET);
+
+ /* Load LCD registers */
+ if (pATI->LCDPanelID >= 0)
+ {
+ if (pATI->Chip == ATI_CHIP_264LT)
+ {
+ /* Update non-shadow registers first */
+ outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl & ~SHADOW_RW_EN);
+
+ /* Temporarily disable stretching */
+ outr(HORZ_STRETCHING, pATIHW->horz_stretching &
+ ~(HORZ_STRETCH_MODE | HORZ_STRETCH_EN));
+ outr(VERT_STRETCHING, pATIHW->vert_stretching &
+ ~(VERT_STRETCH_RATIO1 | VERT_STRETCH_RATIO2 |
+ VERT_STRETCH_USE0 | VERT_STRETCH_EN));
+ }
+ else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
+ (pATI->Chip == ATI_CHIP_264XL) ||
+ (pATI->Chip == ATI_CHIP_MOBILITY)) */
+ {
+ /* Update non-shadow registers first */
+ ATIMach64PutLCDReg(LCD_CONFIG_PANEL, pATIHW->config_panel);
+ ATIMach64PutLCDReg(LCD_GEN_CNTL, pATIHW->lcd_gen_ctrl &
+ ~(CRTC_RW_SELECT | SHADOW_RW_EN));
+
+ /* Temporarily disable stretching */
+ ATIMach64PutLCDReg(LCD_HORZ_STRETCHING,
+ pATIHW->horz_stretching &
+ ~(HORZ_STRETCH_MODE | HORZ_STRETCH_EN));
+ ATIMach64PutLCDReg(LCD_VERT_STRETCHING,
+ pATIHW->vert_stretching &
+ ~(VERT_STRETCH_RATIO1 | VERT_STRETCH_RATIO2 |
+ VERT_STRETCH_USE0 | VERT_STRETCH_EN));
+ }
+ }
+ }
+ }
+
+ switch (pATIHW->crtc)
+ {
+
+#ifndef AVOID_CPIO
+
+ case ATI_CRTC_VGA:
+ /* Start sequencer reset */
+ PutReg(SEQX, 0x00U, 0x00U);
+
+ /* Set pixel clock */
+ if ((pATIHW->FeedbackDivider > 0))
+ ATIClockSet(pATI, pATIHW);
+
+ /* Set up RAMDAC */
+ if (pATI->DAC == ATI_DAC_IBMRGB514)
+ ATIRGB514Set(pATI, pATIHW);
+
+ /* Load VGA Wonder */
+ if (pATI->CPIO_VGAWonder)
+ ATIVGAWonderSet(pATI, pATIHW);
+
+ /* Load VGA device */
+ ATIVGASet(pATI, pATIHW);
+
+ /* Load Mach64 registers */
+ {
+ /* Load MMIO registers */
+ if (pATI->Block0Base)
+ ATIMach64Set(pATI, pATIHW);
+
+ outr(CRTC_GEN_CNTL, pATIHW->crtc_gen_cntl);
+ outr(CUR_CLR0, pATIHW->cur_clr0);
+ outr(CUR_CLR1, pATIHW->cur_clr1);
+ outr(CUR_OFFSET, pATIHW->cur_offset);
+ outr(CUR_HORZ_VERT_POSN, pATIHW->cur_horz_vert_posn);
+ outr(CUR_HORZ_VERT_OFF, pATIHW->cur_horz_vert_off);
+ outr(BUS_CNTL, pATIHW->bus_cntl);
+ outr(MEM_VGA_WP_SEL, pATIHW->mem_vga_wp_sel);
+ outr(MEM_VGA_RP_SEL, pATIHW->mem_vga_rp_sel);
+ outr(DAC_CNTL, pATIHW->dac_cntl);
+ outr(GEN_TEST_CNTL, pATIHW->gen_test_cntl | GEN_GUI_EN);
+ outr(GEN_TEST_CNTL, pATIHW->gen_test_cntl);
+ outr(GEN_TEST_CNTL, pATIHW->gen_test_cntl | GEN_GUI_EN);
+ outr(CONFIG_CNTL, pATIHW->config_cntl);
+ if (pATI->Chip >= ATI_CHIP_264CT)
+ {
+ outr(CRTC_H_TOTAL_DISP, pATIHW->crtc_h_total_disp);
+ outr(CRTC_H_SYNC_STRT_WID, pATIHW->crtc_h_sync_strt_wid);
+ outr(CRTC_V_TOTAL_DISP, pATIHW->crtc_v_total_disp);
+ outr(CRTC_V_SYNC_STRT_WID, pATIHW->crtc_v_sync_strt_wid);
+ outr(CRTC_OFF_PITCH, pATIHW->crtc_off_pitch);
+ if (pATI->Chip >= ATI_CHIP_264VTB)
+ {
+ outr(MEM_CNTL, pATIHW->mem_cntl);
+ outr(MPP_CONFIG, pATIHW->mpp_config);
+ outr(MPP_STROBE_SEQ, pATIHW->mpp_strobe_seq);
+ outr(TVO_CNTL, pATIHW->tvo_cntl);
+ }
+ }
+ }
+
+ break;
+
+#endif /* AVOID_CPIO */
+
+ case ATI_CRTC_MACH64:
+ /* Load Mach64 CRTC registers */
+ ATIMach64Set(pATI, pATIHW);
+
+#ifndef AVOID_CPIO
+
+ if (pATI->VGAAdapter)
+ {
+ /* Oddly enough, these need to be set also, maybe others */
+ PutReg(SEQX, 0x02U, pATIHW->seq[2]);
+ PutReg(SEQX, 0x04U, pATIHW->seq[4]);
+ PutReg(GRAX, 0x06U, pATIHW->gra[6]);
+ if (pATI->CPIO_VGAWonder)
+ ATIModifyExtReg(pATI, 0xB6U, -1, 0x00U, pATIHW->b6);
+ }
+
+#endif /* AVOID_CPIO */
+
+ break;
+
+ default:
+ break;
+ }
+
+ if (pATI->LCDPanelID >= 0)
+ {
+ /* Switch to shadow registers */
+ if (pATI->Chip == ATI_CHIP_264LT)
+ outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl | SHADOW_RW_EN);
+ else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
+ (pATI->Chip == ATI_CHIP_264XL) ||
+ (pATI->Chip == ATI_CHIP_MOBILITY)) */
+ ATIMach64PutLCDReg(LCD_GEN_CNTL,
+ (pATIHW->lcd_gen_ctrl & ~CRTC_RW_SELECT) | SHADOW_RW_EN);
+
+ /* Restore shadow registers */
+ switch (pATIHW->crtc)
+ {
+
+#ifndef AVOID_CPIO
+
+ case ATI_CRTC_VGA:
+ for (Index = 0;
+ Index < NumberOf(pATIHW->shadow_vga);
+ Index++)
+ PutReg(CRTX(pATI->CPIO_VGABase), Index,
+ pATIHW->shadow_vga[Index]);
+ /* Fall through */
+
+#endif /* AVOID_CPIO */
+
+ case ATI_CRTC_MACH64:
+ outr(CRTC_H_TOTAL_DISP, pATIHW->shadow_h_total_disp);
+ outr(CRTC_H_SYNC_STRT_WID, pATIHW->shadow_h_sync_strt_wid);
+ outr(CRTC_V_TOTAL_DISP, pATIHW->shadow_v_total_disp);
+ outr(CRTC_V_SYNC_STRT_WID, pATIHW->shadow_v_sync_strt_wid);
+ break;
+
+ default:
+ break;
+ }
+
+ /* Restore CRTC selection & shadow state and enable stretching */
+ if (pATI->Chip == ATI_CHIP_264LT)
+ {
+ outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl);
+ outr(HORZ_STRETCHING, pATIHW->horz_stretching);
+ outr(VERT_STRETCHING, pATIHW->vert_stretching);
+ }
+ else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
+ (pATI->Chip == ATI_CHIP_264XL) ||
+ (pATI->Chip == ATI_CHIP_MOBILITY)) */
+ {
+ ATIMach64PutLCDReg(LCD_GEN_CNTL, pATIHW->lcd_gen_ctrl);
+ ATIMach64PutLCDReg(LCD_HORZ_STRETCHING, pATIHW->horz_stretching);
+ ATIMach64PutLCDReg(LCD_VERT_STRETCHING, pATIHW->vert_stretching);
+ ATIMach64PutLCDReg(LCD_EXT_VERT_STRETCH, pATIHW->ext_vert_stretch);
+ outr(LCD_INDEX, pATIHW->lcd_index);
+ }
+ }
+
+ /*
+ * Set DSP registers. Note that, for some reason, sequencer resets clear
+ * the DSP_CONFIG register on early integrated controllers.
+ */
+ if (pATI->Chip >= ATI_CHIP_264VTB)
+ ATIDSPSet(pATI, pATIHW);
+
+ /* Load RAMDAC */
+ ATIDACSet(pATI, pATIHW);
+
+ /* Reset hardware cursor caching */
+ pATI->CursorXOffset = pATI->CursorYOffset = (CARD16)(-1);
+
+#ifdef TV_OUT
+
+ /* Set VBE mode for TV-Out */
+ if (pATI->OptionTvOut /* && pATI->tvActive */)
+ ATISetVBEMode(pScreenInfo, pATI, pATIHW);
+
+#endif /* TV_OUT */
+
+#ifndef AVOID_CPIO
+
+ /* Restore video memory */
+ ATISwap(pScreenInfo->scrnIndex, pATI, pATIHW, TRUE);
+
+ if (pATI->VGAAdapter)
+ 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);
+ }
+}
diff --git a/driver/xf86-video-mach64/src/atimode.h b/driver/xf86-video-mach64/src/atimode.h
new file mode 100644
index 000000000..8d8f87660
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atimode.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 "xf86str.h"
+
+extern void ATIModePreInit(ScrnInfoPtr, ATIPtr, ATIHWPtr);
+extern void ATIModeSave(ScrnInfoPtr, ATIPtr, ATIHWPtr);
+extern Bool ATIModeCalculate(int, ATIPtr, ATIHWPtr, DisplayModePtr);
+extern void ATIModeSet(ScrnInfoPtr, ATIPtr, ATIHWPtr);
+
+#endif /* ___ATIMODE_H___ */
diff --git a/driver/xf86-video-mach64/src/atioption.h b/driver/xf86-video-mach64/src/atioption.h
new file mode 100644
index 000000000..37303ef07
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atioption.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright 1999 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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.
+ *
+ * DRI support by:
+ * Leif Delgass <ldelgass@retinalburn.net>
+ */
+
+#ifndef ___ATIOPTION_H___
+#define ___ATIOPTION_H___ 1
+
+#include "xf86str.h"
+
+/*
+ * Documented XF86Config options.
+ */
+typedef enum
+{
+ ATI_OPTION_PROBE_SPARSE,
+ ATI_OPTION_ACCEL,
+ ATI_OPTION_CRT_DISPLAY,
+ ATI_OPTION_CSYNC,
+ ATI_OPTION_HWCURSOR,
+
+#ifdef XF86DRI_DEVEL
+
+ ATI_OPTION_IS_PCI,
+ ATI_OPTION_DMA_MODE,
+ ATI_OPTION_AGP_MODE,
+ ATI_OPTION_AGP_SIZE,
+ ATI_OPTION_LOCAL_TEXTURES,
+ ATI_OPTION_BUFFER_SIZE,
+
+#endif /* XF86DRI_DEVEL */
+
+#ifdef TV_OUT
+
+ ATI_OPTION_TV_OUT,
+ ATI_OPTION_TV_STD,
+
+#endif /* TV_OUT */
+
+ ATI_OPTION_MMIO_CACHE,
+ ATI_OPTION_TEST_MMIO_CACHE,
+ ATI_OPTION_PANEL_DISPLAY,
+ ATI_OPTION_REFERENCE_CLOCK,
+ ATI_OPTION_SHADOW_FB,
+ ATI_OPTION_SWCURSOR,
+ ATI_OPTION_ACCELMETHOD,
+ ATI_OPTION_RENDER_ACCEL
+} ATIPublicOptionType;
+
+#ifdef TV_OUT
+
+#define ATI_TV_STDS_MAX_VALID 11
+#define ATI_TV_STDS_NAME_MAXLEN 9
+
+typedef enum {
+ ATI_TV_STD_NTSC = 0,
+ ATI_TV_STD_PAL,
+ ATI_TV_STD_PALM,
+ ATI_TV_STD_PAL60,
+ ATI_TV_STD_NTSCJ,
+ ATI_TV_STD_PALCN,
+ ATI_TV_STD_PALN,
+ ATI_TV_STD_RESERVED1, /* NOT usable */
+ ATI_TV_STD_RESERVED2, /* NOT usable */
+ ATI_TV_STD_SCARTPAL,
+ ATI_TV_STD_NONE, /* OK, means no tv standard change requested */
+ ATI_TV_STD_INVALID /* Invalid tv standard requested */
+} ATITVStandard;
+
+extern const char * ATITVStandardNames[];
+
+#endif /* TV_OUT */
+
+extern const OptionInfoRec * ATIOptionsWeak(void);
+
+extern void ATIProcessOptions(ScrnInfoPtr, ATIPtr);
+
+#endif /* ___ATIOPTION_H___ */
diff --git a/driver/xf86-video-mach64/src/atipcirename.h b/driver/xf86-video-mach64/src/atipcirename.h
new file mode 100644
index 000000000..de8f0a391
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atipcirename.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2007 George Sapountzis
+ *
+ * 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
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ */
+
+/**
+ * Macros for porting drivers from legacy xfree86 PCI code to the pciaccess
+ * library. The main purpose being to facilitate source code compatibility.
+ */
+
+#ifndef ATIPCIRENAME_H
+#define ATIPCIRENAME_H
+
+enum region_type {
+ REGION_MEM,
+ REGION_IO
+};
+
+#ifndef XSERVER_LIBPCIACCESS
+
+/* pciVideoPtr */
+#define PCI_DEV_VENDOR_ID(_pcidev) ((_pcidev)->vendor)
+#define PCI_DEV_DEVICE_ID(_pcidev) ((_pcidev)->chipType)
+#define PCI_DEV_REVISION(_pcidev) ((_pcidev)->chipRev)
+
+#define PCI_SUB_VENDOR_ID(_pcidev) ((_pcidev)->subsysVendor)
+#define PCI_SUB_DEVICE_ID(_pcidev) ((_pcidev)->subsysCard)
+
+#define PCI_DEV_TAG(_pcidev) pciTag((_pcidev)->bus, \
+ (_pcidev)->device, \
+ (_pcidev)->func)
+#define PCI_DEV_BUS(_pcidev) ((_pcidev)->bus)
+#define PCI_DEV_DEV(_pcidev) ((_pcidev)->device)
+#define PCI_DEV_FUNC(_pcidev) ((_pcidev)->func)
+
+/* pciConfigPtr */
+#define PCI_CFG_TAG(_pcidev) (((pciConfigPtr)(_pcidev)->thisCard)->tag)
+#define PCI_CFG_BUS(_pcidev) (((pciConfigPtr)(_pcidev)->thisCard)->busnum)
+#define PCI_CFG_DEV(_pcidev) (((pciConfigPtr)(_pcidev)->thisCard)->devnum)
+#define PCI_CFG_FUNC(_pcidev) (((pciConfigPtr)(_pcidev)->thisCard)->funcnum)
+
+/* region addr: xfree86 uses different fields for memory regions and I/O ports */
+#define PCI_REGION_BASE(_pcidev, _b, _type) \
+ (((_type) == REGION_MEM) ? (_pcidev)->memBase[(_b)] \
+ : (_pcidev)->ioBase[(_b)])
+
+/* region size: xfree86 uses the log2 of the region size,
+ * but with zero meaning no region, not size of one XXX */
+#define PCI_REGION_SIZE(_pcidev, _b) \
+ (((_pcidev)->size[(_b)] > 0) ? (1 << (_pcidev)->size[(_b)]) : 0)
+
+/* read/write PCI configuration space */
+#define PCI_READ_BYTE(_pcidev, _value_ptr, _offset) \
+ *(_value_ptr) = pciReadByte(PCI_CFG_TAG(_pcidev), (_offset))
+
+#define PCI_READ_LONG(_pcidev, _value_ptr, _offset) \
+ *(_value_ptr) = pciReadLong(PCI_CFG_TAG(_pcidev), (_offset))
+
+#define PCI_WRITE_LONG(_pcidev, _value, _offset) \
+ pciWriteLong(PCI_CFG_TAG(_pcidev), (_offset), (_value))
+
+#else /* XSERVER_LIBPCIACCESS */
+
+typedef struct pci_device *pciVideoPtr;
+
+#define PCI_DEV_VENDOR_ID(_pcidev) ((_pcidev)->vendor_id)
+#define PCI_DEV_DEVICE_ID(_pcidev) ((_pcidev)->device_id)
+#define PCI_DEV_REVISION(_pcidev) ((_pcidev)->revision)
+
+#define PCI_SUB_VENDOR_ID(_pcidev) ((_pcidev)->subvendor_id)
+#define PCI_SUB_DEVICE_ID(_pcidev) ((_pcidev)->subdevice_id)
+
+/* pci-rework functions take a 'pci_device' parameter instead of a tag */
+#define PCI_DEV_TAG(_pcidev) (_pcidev)
+
+/* PCI_DEV macros, typically used in printf's, add domain ? XXX */
+#define PCI_DEV_BUS(_pcidev) ((_pcidev)->bus)
+#define PCI_DEV_DEV(_pcidev) ((_pcidev)->dev)
+#define PCI_DEV_FUNC(_pcidev) ((_pcidev)->func)
+
+/* pci-rework functions take a 'pci_device' parameter instead of a tag */
+#define PCI_CFG_TAG(_pcidev) (_pcidev)
+
+/* PCI_CFG macros, typically used in DRI init, contain the domain */
+#define PCI_CFG_BUS(_pcidev) (((_pcidev)->domain << 8) | \
+ (_pcidev)->bus)
+#define PCI_CFG_DEV(_pcidev) ((_pcidev)->dev)
+#define PCI_CFG_FUNC(_pcidev) ((_pcidev)->func)
+
+#define PCI_REGION_BASE(_pcidev, _b, _type) ((_pcidev)->regions[(_b)].base_addr)
+#define PCI_REGION_SIZE(_pcidev, _b) ((_pcidev)->regions[(_b)].size)
+
+#define PCI_READ_BYTE(_pcidev, _value_ptr, _offset) \
+ pci_device_cfg_read_u8((_pcidev), (_value_ptr), (_offset))
+
+#define PCI_READ_LONG(_pcidev, _value_ptr, _offset) \
+ pci_device_cfg_read_u32((_pcidev), (_value_ptr), (_offset))
+
+#define PCI_WRITE_LONG(_pcidev, _value, _offset) \
+ pci_device_cfg_write_u32((_pcidev), (_value), (_offset))
+
+#define ATI_DEVICE_MATCH(d, i) \
+ { PCI_VENDOR_ATI, (d), PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, (i) }
+
+#endif /* XSERVER_LIBPCIACCESS */
+
+#endif /* ATIPCIRENAME_H */
diff --git a/driver/xf86-video-mach64/src/atipreinit.c b/driver/xf86-video-mach64/src/atipreinit.c
new file mode 100644
index 000000000..f89f5b740
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atipreinit.c
@@ -0,0 +1,2509 @@
+/*
+ * Copyright 1999 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <stdio.h>
+
+#include "ati.h"
+#include "atiadjust.h"
+#include "atiaudio.h"
+#include "atibus.h"
+#include "atichip.h"
+#include "aticursor.h"
+#include "atidac.h"
+#include "atidsp.h"
+#include "atii2c.h"
+#include "atiload.h"
+#include "atilock.h"
+#include "atimach64.h"
+#include "atimach64accel.h"
+#include "atimach64io.h"
+#include "atimach64probe.h"
+#include "atimode.h"
+#include "atioption.h"
+#include "atipreinit.h"
+#include "atiprint.h"
+#include "atiprobe.h"
+#include "atividmem.h"
+#include "atiwonderio.h"
+#include "atixv.h"
+
+#include "vbe.h"
+#include "xf86RAC.h"
+
+/*
+ * FreeScreen handles the clean-up.
+ */
+static Bool
+Mach64GetRec(ScrnInfoPtr pScrn)
+{
+ if (!pScrn->driverPrivate) {
+ pScrn->driverPrivate = xnfcalloc(sizeof(ATIRec), 1);
+ memset(pScrn->driverPrivate, 0, sizeof(ATIRec));
+ }
+
+ return TRUE;
+}
+
+/*
+ * ATIReportMemory --
+ *
+ * This function reports on the amount and type of video memory found.
+ */
+static void
+ATIReportMemory
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI,
+ const char *MemoryTypeName
+)
+{
+ char Buffer[128], *Message;
+
+ Message = Buffer +
+ snprintf(Buffer, SizeOf(Buffer), "%d kB of %s detected",
+ pATI->VideoRAM, MemoryTypeName);
+
+ if (pATI->VideoRAM > pScreenInfo->videoRam)
+ {
+ Message += snprintf(Message, Buffer + SizeOf(Buffer) - Message,
+ " (using %d kB)", pScreenInfo->videoRam);
+ }
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED, "%s.\n", Buffer);
+}
+
+static const int videoRamSizes[] =
+ {512, 1024, 2*1024, 4*1024, 6*1024, 8*1024, 12*1024, 16*1024};
+static const rgb defaultWeight = {0, 0, 0};
+static const Gamma defaultGamma = {0.0, 0.0, 0.0};
+
+/*
+ * ATIPrintNoiseIfRequested --
+ *
+ * This function formats debugging information on the server's stderr when
+ * requested by the user through the server's verbosity setting.
+ */
+static void
+ATIPrintNoiseIfRequested
+(
+ ATIPtr pATI,
+ CARD8 *BIOS,
+ unsigned int BIOSSize
+)
+{
+ if (xf86GetVerbosity() <= 3)
+ return;
+
+ if (BIOSSize > 0)
+ ATIPrintBIOS(BIOS, BIOSSize);
+ xf86ErrorFVerb(4, "\n On server entry:\n");
+ ATIPrintRegisters(pATI);
+}
+
+#define BIOS_SIZE 0x00010000U /* 64kB */
+#define BIOSByte(_n) ((CARD8)(BIOS[_n]))
+#define BIOSWord(_n) ((CARD16)(BIOS[_n] | \
+ (BIOS[(_n) + 1] << 8)))
+
+/*
+ * For Mach64 adapters, pick up, from the BIOS, the type of programmable
+ * clock generator (if any), and various information about it.
+ */
+static void
+ati_bios_clock
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI,
+ CARD8 *BIOS,
+ unsigned int ClockTable,
+ GDevPtr pGDev
+)
+{
+ CARD16 ClockDac;
+
+ if (ClockTable > 0)
+ {
+ pATI->ProgrammableClock = BIOSByte(ClockTable);
+ pATI->ClockNumberToProgramme = BIOSByte(ClockTable + 0x06U);
+ pATI->refclk = BIOSWord(ClockTable + 0x08U);
+ pATI->refclk *= 10000;
+ }
+ else
+ {
+ /*
+ * Compensate for BIOS absence. Note that the reference
+ * frequency has already been set by option processing.
+ */
+ if ((pATI->DAC & ~0x0FU) == ATI_DAC_INTERNAL)
+ {
+ pATI->ProgrammableClock = ATI_CLOCK_INTERNAL;
+ }
+ else switch (pATI->DAC)
+ {
+ case ATI_DAC_STG1703:
+ pATI->ProgrammableClock = ATI_CLOCK_STG1703;
+ break;
+
+ case ATI_DAC_CH8398:
+ pATI->ProgrammableClock = ATI_CLOCK_CH8398;
+ break;
+
+ case ATI_DAC_ATT20C408:
+ pATI->ProgrammableClock = ATI_CLOCK_ATT20C408;
+ break;
+
+ case ATI_DAC_IBMRGB514:
+ pATI->ProgrammableClock = ATI_CLOCK_IBMRGB514;
+ break;
+
+ default: /* Provisional */
+ pATI->ProgrammableClock = ATI_CLOCK_ICS2595;
+ break;
+ }
+
+ /* This should be safe for all generators except IBM's RGB514 */
+ pATI->ClockNumberToProgramme = 3;
+ }
+
+ pATI->ClockDescriptor = ATIClockDescriptors[ATI_CLOCK_FIXED];
+
+ if ((pATI->ProgrammableClock > ATI_CLOCK_FIXED) &&
+ (pATI->ProgrammableClock < ATI_CLOCK_MAX))
+ {
+ /*
+ * Graphics PRO TURBO 1600's are unusual in that an ICS2595 is used
+ * to generate clocks for VGA modes, and an IBM RGB514 is used for
+ * accelerator modes.
+ */
+ if ((pATI->ProgrammableClock == ATI_CLOCK_ICS2595) &&
+ (pATI->DAC == ATI_DAC_IBMRGB514))
+ pATI->ProgrammableClock = ATI_CLOCK_IBMRGB514;
+
+ pATI->ClockDescriptor = ATIClockDescriptors[pATI->ProgrammableClock];
+ }
+
+ ClockDac = pATI->DAC;
+ switch (pATI->ProgrammableClock)
+ {
+ case ATI_CLOCK_ICS2595:
+ /*
+ * Pick up reference divider (43 or 46) appropriate to the chip
+ * revision level.
+ */
+ if (ClockTable > 0)
+ pATI->ClockDescriptor.MinM =
+ pATI->ClockDescriptor.MaxM = BIOSWord(ClockTable + 0x0AU);
+ else if (!xf86NameCmp(pGDev->clockchip, "ATI 18818-0"))
+ pATI->ClockDescriptor.MinM =
+ pATI->ClockDescriptor.MaxM = 43;
+ else if (!xf86NameCmp(pGDev->clockchip, "ATI 18818-1"))
+ pATI->ClockDescriptor.MinM =
+ pATI->ClockDescriptor.MaxM = 46;
+ else
+ pATI->ProgrammableClock = ATI_CLOCK_UNKNOWN;
+ break;
+
+ case ATI_CLOCK_STG1703:
+ /* This one's also a RAMDAC */
+ ClockDac = ATI_DAC_STG1703;
+ break;
+
+ case ATI_CLOCK_CH8398:
+ /* This one's also a RAMDAC */
+ ClockDac = ATI_DAC_CH8398;
+ break;
+
+ case ATI_CLOCK_INTERNAL:
+ /*
+ * The reference divider has already been programmed by BIOS
+ * initialisation. Because, there is only one reference
+ * divider for all generated frequencies (including MCLK), it
+ * cannot be changed without reprogramming all clocks every
+ * time one of them needs a different reference divider.
+ *
+ * Besides, it's not a good idea to change the reference
+ * divider. BIOS initialisation sets it to a value that
+ * effectively prevents generating frequencies beyond the
+ * graphics controller's tolerance.
+ */
+ pATI->ClockDescriptor.MinM =
+ pATI->ClockDescriptor.MaxM = ATIMach64GetPLLReg(PLL_REF_DIV);
+
+ /* The DAC is also integrated */
+ if ((pATI->DAC & ~0x0FU) != ATI_DAC_INTERNAL)
+ ClockDac = ATI_DAC_INTERNAL;
+
+ break;
+
+ case ATI_CLOCK_ATT20C408:
+ /* This one's also a RAMDAC */
+ ClockDac = ATI_DAC_ATT20C408;
+ break;
+
+ case ATI_CLOCK_IBMRGB514:
+ /* This one's also a RAMDAC */
+ ClockDac = ATI_DAC_IBMRGB514;
+ pATI->ClockNumberToProgramme = 7;
+ break;
+
+ default:
+ break;
+ }
+
+ /*
+ * We now have up to two indications of what RAMDAC the adapter uses.
+ * They should be the same. The following test and corresponding
+ * action are under construction.
+ */
+ if (pATI->DAC != ClockDac)
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Mach64 RAMDAC probe discrepancy detected:\n"
+ " DAC=0x%02X; ClockDac=0x%02X.\n",
+ pATI->DAC, ClockDac);
+
+ if (pATI->DAC == ATI_DAC_IBMRGB514)
+ {
+ pATI->ProgrammableClock = ATI_CLOCK_IBMRGB514;
+ pATI->ClockDescriptor = ATIClockDescriptors[ATI_CLOCK_IBMRGB514];
+ pATI->ClockNumberToProgramme = 7;
+ }
+ else
+ {
+ pATI->DAC = ClockDac; /* For now */
+ }
+ }
+
+ switch (pATI->refclk / 100000)
+ {
+ case 143:
+ pATI->ReferenceNumerator = 157500;
+ pATI->ReferenceDenominator = 11;
+ break;
+
+ case 286:
+ pATI->ReferenceNumerator = 315000;
+ pATI->ReferenceDenominator = 11;
+ break;
+
+ default:
+ pATI->ReferenceNumerator = pATI->refclk / 1000;
+ pATI->ReferenceDenominator = 1;
+ break;
+ }
+}
+
+/*
+ * Pick up multimedia information, which will be at different
+ * displacements depending on table revision.
+ */
+static void
+ati_bios_mmedia
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI,
+ CARD8 *BIOS,
+ unsigned int VideoTable,
+ unsigned int HardwareTable
+)
+{
+ pATI->Audio = ATI_AUDIO_NONE;
+
+ if (VideoTable > 0)
+ {
+ switch (BIOSByte(VideoTable - 0x02U))
+ {
+ case 0x00U:
+ pATI->Tuner = BIOSByte(VideoTable) & 0x1FU;
+
+ /*
+ * XXX The VideoTable[1] byte is known to have been
+ * omitted in LTPro and Mobility BIOS'es. Any others?
+ */
+ switch (pATI->Chip)
+ {
+ case ATI_CHIP_264LTPRO:
+ case ATI_CHIP_MOBILITY:
+ pATI->Decoder = BIOSByte(VideoTable + 0x01U) & 0x07U;
+ pATI->Audio = BIOSByte(VideoTable + 0x02U) & 0x0FU;
+ break;
+
+ default:
+ pATI->Decoder = BIOSByte(VideoTable + 0x02U) & 0x07U;
+ pATI->Audio = BIOSByte(VideoTable + 0x03U) & 0x0FU;
+ break;
+ }
+
+ break;
+
+ case 0x01U:
+ pATI->Tuner = BIOSByte(VideoTable) & 0x1FU;
+ pATI->Audio = BIOSByte(VideoTable + 0x01U) & 0x0FU;
+ pATI->Decoder = BIOSByte(VideoTable + 0x05U) & 0x0FU;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (HardwareTable > 0)
+ {
+ pATI->I2CType = BIOSByte(HardwareTable + 0x06U) & 0x0FU;
+ }
+}
+
+/*
+ * Determine panel dimensions and model.
+ */
+static void
+ati_bios_panel_info
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI,
+ CARD8 *BIOS,
+ unsigned int BIOSSize,
+ unsigned int LCDTable
+)
+{
+ unsigned int LCDPanelInfo = 0;
+ char Buffer[128];
+ int i, j;
+
+ if (LCDTable > 0)
+ {
+ LCDPanelInfo = BIOSWord(LCDTable + 0x0AU);
+ if (((LCDPanelInfo + 0x1DU) > BIOSSize) ||
+ ((BIOSByte(LCDPanelInfo) != pATI->LCDPanelID) &&
+ (pATI->LCDPanelID || (BIOSByte(LCDPanelInfo) > 0x1FU) ||
+ (pATI->Chip <= ATI_CHIP_264LTPRO))))
+ LCDPanelInfo = 0;
+ }
+
+ if (!LCDPanelInfo)
+ {
+ /*
+ * Scan BIOS for panel info table.
+ */
+ for (i = 0; i <= (int)(BIOSSize - 0x1DU); i++)
+ {
+ /* Look for panel ID ... */
+ if ((BIOSByte(i) != pATI->LCDPanelID) &&
+ (pATI->LCDPanelID || (BIOSByte(i) > 0x1FU) ||
+ (pATI->Chip <= ATI_CHIP_264LTPRO)))
+ continue;
+
+ /* ... followed by 24-byte panel model name ... */
+ for (j = 0; j < 24; j++)
+ {
+ if ((CARD8)(BIOSByte(i + j + 1) - 0x20U) > 0x5FU)
+ {
+ i += j;
+ goto NextBIOSByte;
+ }
+ }
+
+ /* ... verify panel width ... */
+ if (pATI->LCDHorizontal &&
+ (pATI->LCDHorizontal != BIOSWord(i + 0x19U)))
+ continue;
+
+ /* ... and verify panel height */
+ if (pATI->LCDVertical &&
+ (pATI->LCDVertical != BIOSWord(i + 0x1BU)))
+ continue;
+
+ if (LCDPanelInfo)
+ {
+ /*
+ * More than one possibility, but don't care if all
+ * tables describe panels of the same size.
+ */
+ if ((BIOSByte(LCDPanelInfo + 0x19U) ==
+ BIOSByte(i + 0x19U)) &&
+ (BIOSByte(LCDPanelInfo + 0x1AU) ==
+ BIOSByte(i + 0x1AU)) &&
+ (BIOSByte(LCDPanelInfo + 0x1BU) ==
+ BIOSByte(i + 0x1BU)) &&
+ (BIOSByte(LCDPanelInfo + 0x1CU) ==
+ BIOSByte(i + 0x1CU)))
+ continue;
+
+ LCDPanelInfo = 0;
+ break;
+ }
+
+ LCDPanelInfo = i;
+
+ NextBIOSByte: ;
+ }
+ }
+
+ if (LCDPanelInfo > 0)
+ {
+ pATI->LCDPanelID = BIOSByte(LCDPanelInfo);
+ pATI->LCDHorizontal = BIOSWord(LCDPanelInfo + 0x19U);
+ pATI->LCDVertical = BIOSWord(LCDPanelInfo + 0x1BU);
+ }
+
+ if (LCDPanelInfo)
+ {
+ for (i = 0; i < 24; i++)
+ Buffer[i] = BIOSByte(LCDPanelInfo + 1 + i);
+ for (; --i >= 0; )
+ if (Buffer[i] && Buffer[i] != ' ')
+ {
+ Buffer[i + 1] = '\0';
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
+ "Panel model %s.\n", Buffer);
+ break;
+ }
+ }
+}
+
+/*
+ * ATIPreInit --
+ *
+ * This function is only called once per screen at the start of the first
+ * server generation.
+ */
+Bool
+ATIPreInit
+(
+ ScrnInfoPtr pScreenInfo,
+ int flags
+)
+{
+ CARD8 BIOS[BIOS_SIZE];
+ unsigned int BIOSSize = 0;
+ unsigned int ROMTable = 0, ClockTable = 0, FrequencyTable = 0;
+ unsigned int LCDTable = 0, VideoTable = 0;
+ unsigned int HardwareTable = 0;
+
+ char Buffer[128], *Message;
+ ATIPtr pATI;
+ GDevPtr pGDev;
+ EntityInfoPtr pEntity;
+ resPtr pResources;
+ pciVideoPtr pVideo;
+ DisplayModePtr pMode;
+ CARD32 IOValue;
+ int i, j;
+ int Numerator, Denominator;
+ int MinX, MinY;
+ ClockRange ATIClockRange = {NULL, 0, 80000, -1, TRUE, TRUE, 1, 1, 0};
+ int DefaultmaxClock = 0;
+ int minPitch, maxPitch = 0xFFU, pitchInc, maxHeight = 0;
+ int ApertureSize = 0x00010000U;
+ int ModeType = M_T_BUILTIN;
+ LookupModeFlags Strategy = LOOKUP_CLOSEST_CLOCK;
+ int DefaultDepth;
+ Bool PreInitSuccess = FALSE;
+
+# define pATIHW (&pATI->OldHW)
+
+#ifndef AVOID_CPIO
+
+ xf86Int10InfoPtr pInt10Info = NULL;
+ vbeInfoPtr pVBE = NULL;
+ pointer pInt10Module, pDDCModule = NULL, pVBEModule = NULL;
+
+#endif /* AVOID_CPIO */
+
+ if (pScreenInfo->numEntities != 1)
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "Logic error: Number of attached entities not 1.\n");
+ return FALSE;
+ }
+
+ if (!Mach64GetRec(pScreenInfo))
+ return FALSE;
+
+ pATI = ATIPTR(pScreenInfo);
+
+ /* Register resources */
+ pEntity = xf86GetEntityInfo(pScreenInfo->entityList[0]);
+ pGDev = pEntity->device;
+ pResources = pEntity->resources;
+
+ pATI->iEntity = pEntity->index;
+ pATI->Chip = pEntity->chipset;
+ pVideo = xf86GetPciInfoForEntity(pATI->iEntity);
+
+ xfree(pEntity);
+
+ if (!pResources)
+ pResources = xf86RegisterResources(pATI->iEntity, NULL, ResShared);
+ if (pResources)
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "Unable to register the following bus resources:\n");
+ xf86PrintResList(0, pResources);
+ xf86FreeResList(pResources);
+ return FALSE;
+ }
+
+ ConfiguredMonitor = NULL;
+ (void)memset(BIOS, 0, SizeOf(BIOS));
+
+ if (!(flags & PROBE_DETECT))
+ {
+ /* Set monitor */
+ pScreenInfo->monitor = pScreenInfo->confScreen->monitor;
+
+ /* Set depth, bpp, etc. */
+ if ((pATI->Chip < ATI_CHIP_264CT))
+ {
+ i = NoDepth24Support; /* No support for >8bpp either */
+ DefaultDepth = 8;
+ }
+ else
+ {
+ i = Support24bppFb | Support32bppFb;
+ DefaultDepth = 0;
+ }
+
+ if (!xf86SetDepthBpp(pScreenInfo, DefaultDepth, 0, 0, i))
+ return FALSE;
+
+ for (j = 0; ; j++)
+ {
+ static const CARD8 AllowedDepthBpp[][2] =
+ {
+ { 8, 8},
+ {15, 16},
+ {16, 16},
+ {24, 24},
+ {24, 32}
+ };
+
+ if (j < NumberOf(AllowedDepthBpp))
+ {
+ if (pScreenInfo->depth > AllowedDepthBpp[j][0])
+ continue;
+
+ if (pScreenInfo->depth == AllowedDepthBpp[j][0])
+ {
+ if (pScreenInfo->bitsPerPixel > AllowedDepthBpp[j][1])
+ continue;
+
+ if (pScreenInfo->bitsPerPixel == AllowedDepthBpp[j][1])
+ break;
+ }
+ }
+
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "Driver does not support depth %d at fbbpp %d.\n",
+ pScreenInfo->depth, pScreenInfo->bitsPerPixel);
+ return FALSE;
+ }
+
+ xf86PrintDepthBpp(pScreenInfo);
+
+ if ((i == NoDepth24Support) && (pScreenInfo->depth > 8))
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "Depth %d is not supported through this adapter.\n",
+ pScreenInfo->depth);
+ return FALSE;
+ }
+
+ /* Pick up XF86Config options */
+ ATIProcessOptions(pScreenInfo, pATI);
+ }
+
+ if (!ATIMach64ProbeIO(pVideo, pATI))
+ return FALSE;
+
+ ATIClaimBusSlot(pGDev->active, pATI);
+
+#ifndef AVOID_CPIO
+
+#ifdef TV_OUT
+
+ pATI->pVBE = NULL;
+ pATI->pInt10 = NULL;
+
+#endif /* TV_OUT */
+
+ /*
+ * If there is an ix86-style BIOS, ensure its initialisation entry point
+ * has been executed, and retrieve DDC and VBE information from it.
+ */
+ if (!(pInt10Module = xf86LoadSubModule(pScreenInfo, "int10")))
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Unable to load int10 module.\n");
+ }
+ else if (!(pInt10Info = xf86InitInt10(pATI->iEntity)))
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Unable to initialise int10 interface.\n");
+ }
+ else
+ {
+ if (!(pDDCModule = xf86LoadSubModule(pScreenInfo, "ddc")))
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Unable to load ddc module.\n");
+ }
+ else
+ if (!(pVBEModule = xf86LoadSubModule(pScreenInfo, "vbe")))
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Unable to load vbe module.\n");
+ }
+ else
+ {
+ if ((pVBE = VBEInit(pInt10Info, pATI->iEntity)))
+ {
+ ConfiguredMonitor = vbeDoEDID(pVBE, pDDCModule);
+ }
+ }
+
+ if (!(flags & PROBE_DETECT))
+ {
+ /* Validate, then make a private copy of, the initialised BIOS */
+ CARD8 *pBIOS = xf86int10Addr(pInt10Info, pInt10Info->BIOSseg << 4);
+
+ if ((pBIOS[0] != 0x55U) || (pBIOS[1] != 0xAAU) || !pBIOS[2])
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Unable to correctly retrieve adapter BIOS.\n");
+ }
+ else
+ {
+ BIOSSize = pBIOS[2] << 9;
+ if (BIOSSize > BIOS_SIZE)
+ BIOSSize = BIOS_SIZE;
+ (void)memcpy(BIOS, pBIOS, BIOSSize);
+ }
+ }
+ }
+
+#ifndef TV_OUT
+ /* De-activate VBE */
+ vbeFree(pVBE);
+ xf86UnloadSubModule(pVBEModule);
+
+ /* De-activate int10 */
+ xf86FreeInt10(pInt10Info);
+ xf86UnloadSubModule(pInt10Module);
+#else
+ pATI->pInt10 = pInt10Info;
+ pATI->pVBE = pVBE;
+ pVBE = NULL;
+ pInt10Info = NULL;
+#endif /* TV_OUT */
+
+ if (ConfiguredMonitor && !(flags & PROBE_DETECT))
+ {
+ xf86PrintEDID(ConfiguredMonitor);
+ xf86SetDDCproperties(pScreenInfo, ConfiguredMonitor);
+ }
+
+ /* DDC module is no longer needed at this point */
+ xf86UnloadSubModule(pDDCModule);
+
+#endif /* AVOID_CPIO */
+
+ if (flags & PROBE_DETECT)
+ {
+ return TRUE;
+ }
+
+#ifndef AVOID_CPIO
+
+ /* I/O bases might no longer be valid after BIOS initialisation */
+ {
+ if (pATI->CPIODecoding == BLOCK_IO)
+ pATI->CPIOBase = PCI_REGION_BASE(pVideo, 1, REGION_IO);
+
+ pATI->MMIOInLinear = FALSE;
+
+ /* Set MMIO address from PCI configuration space, if available */
+ if ((pATI->Block0Base = PCI_REGION_BASE(pVideo, 2, REGION_MEM)))
+ {
+ pATI->Block0Base += 0x0400U;
+ }
+ }
+
+#endif /* AVOID_CPIO */
+
+#ifdef AVOID_CPIO
+
+ pScreenInfo->racMemFlags =
+ RAC_FB | RAC_COLORMAP | RAC_VIEWPORT | RAC_CURSOR;
+
+#else /* AVOID_CPIO */
+
+ pScreenInfo->racIoFlags =
+ RAC_FB | RAC_COLORMAP | RAC_VIEWPORT | RAC_CURSOR;
+ pScreenInfo->racMemFlags = RAC_FB | RAC_CURSOR;
+
+#endif /* AVOID_CPIO */
+
+ /* Finish private area initialisation */
+ pATI->nFIFOEntries = 16; /* For now */
+
+ /* Finish probing the adapter */
+ {
+ /*
+ * For MMIO register access, the MMIO address is computed when probing
+ * and there are no BIOS calls. This mapping should always succeed.
+ *
+ * For CPIO register access, the MMIO address is computed above in the
+ * presence of an auxiliary aperture. Otherwise, it is set to zero and
+ * gets computed when we read the linear aperture configuration. This
+ * mapping is either irrelevant or a no-op.
+ */
+ if (!ATIMapApertures(pScreenInfo->scrnIndex, pATI))
+ return FALSE;
+
+#ifdef AVOID_CPIO
+
+ if (!pATI->pBlock[0])
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "Unable to mmap() adapter registers.\n");
+ return FALSE;
+ }
+
+#endif /* AVOID_CPIO */
+
+ /*
+ * Verify register access by comparing against the CONFIG_CHIP_ID
+ * value saved by adapter detection.
+ */
+ if (pATI->config_chip_id != inr(CONFIG_CHIP_ID))
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "Adapter registers not mapped correctly.\n");
+ ATIUnmapApertures(pScreenInfo->scrnIndex, pATI);
+ return FALSE;
+ }
+
+ pATIHW->crtc_gen_cntl = inr(CRTC_GEN_CNTL);
+ if (!(pATIHW->crtc_gen_cntl & CRTC_EN) &&
+ (pATI->Chip >= ATI_CHIP_264CT))
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "Adapter has not been initialised.\n");
+ goto bail_locked;
+ }
+
+#ifdef AVOID_CPIO
+
+ if (!(pATIHW->crtc_gen_cntl & CRTC_EXT_DISP_EN))
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "Adapters found to be in VGA mode on server entry are not"
+ " supported by the MMIO-only version of this driver.\n");
+ goto bail_locked;
+ }
+
+#endif /* AVOID_CPIO */
+
+ pATIHW->mem_cntl = inr(MEM_CNTL);
+ if (pATI->Chip < ATI_CHIP_264VTB)
+ {
+ IOValue = GetBits(pATIHW->mem_cntl, CTL_MEM_SIZE);
+ pATI->VideoRAM = videoRamSizes[IOValue];
+ }
+ else
+ {
+ pATI->nFIFOEntries = /* Don't care */
+ (unsigned int)(-1) >> 1;
+
+ IOValue = GetBits(pATIHW->mem_cntl, CTL_MEM_SIZEB);
+ if (IOValue < 8)
+ pATI->VideoRAM = (IOValue + 1) * 512;
+ else if (IOValue < 12)
+ pATI->VideoRAM = (IOValue - 3) * 1024;
+ else
+ pATI->VideoRAM = (IOValue - 7) * 2048;
+ }
+
+ IOValue = inr(CONFIG_STATUS64_0);
+ if (pATI->Chip >= ATI_CHIP_264CT)
+ {
+ pATI->MemoryType = GetBits(IOValue, CFG_MEM_TYPE_T);
+ }
+ else
+ {
+ pATI->MemoryType = GetBits(IOValue, CFG_MEM_TYPE);
+ }
+
+ pATI->LCDPanelID = -1;
+
+ if (pATI->Chip >= ATI_CHIP_264CT)
+ {
+ /* Get LCD panel id */
+ if (pATI->Chip == ATI_CHIP_264LT)
+ {
+ pATI->LCDPanelID = GetBits(IOValue, CFG_PANEL_ID);
+
+ pATIHW->horz_stretching = inr(HORZ_STRETCHING);
+ pATIHW->vert_stretching = inr(VERT_STRETCHING);
+ pATIHW->lcd_gen_ctrl = inr(LCD_GEN_CTRL);
+ }
+ else if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
+ (pATI->Chip == ATI_CHIP_264XL) ||
+ (pATI->Chip == ATI_CHIP_MOBILITY))
+ {
+ pATI->LCDPanelID = GetBits(IOValue, CFG_PANEL_ID);
+
+ pATIHW->lcd_index = inr(LCD_INDEX);
+ pATIHW->horz_stretching =
+ ATIMach64GetLCDReg(LCD_HORZ_STRETCHING);
+ pATI->LCDHorizontal =
+ GetBits(pATIHW->horz_stretching, HORZ_PANEL_SIZE);
+ if (pATI->LCDHorizontal)
+ {
+ if (pATI->LCDHorizontal == MaxBits(HORZ_PANEL_SIZE))
+ pATI->LCDHorizontal = 0;
+ else
+ pATI->LCDHorizontal =
+ (pATI->LCDHorizontal + 1) << 3;
+ }
+ pATIHW->ext_vert_stretch =
+ ATIMach64GetLCDReg(LCD_EXT_VERT_STRETCH);
+ pATI->LCDVertical =
+ GetBits(pATIHW->ext_vert_stretch, VERT_PANEL_SIZE);
+ if (pATI->LCDVertical)
+ {
+ if (pATI->LCDVertical == MaxBits(VERT_PANEL_SIZE))
+ pATI->LCDVertical = 0;
+ else
+ pATI->LCDVertical++;
+ }
+ pATIHW->vert_stretching =
+ ATIMach64GetLCDReg(LCD_VERT_STRETCHING);
+ pATIHW->lcd_gen_ctrl = ATIMach64GetLCDReg(LCD_GEN_CNTL);
+ outr(LCD_INDEX, pATIHW->lcd_index);
+ }
+
+ /*
+ * Don't bother with panel support if it hasn't been previously
+ * enabled.
+ */
+ if ((pATI->LCDPanelID >= 0) &&
+ !(pATIHW->horz_stretching & HORZ_STRETCH_EN) &&
+ !(pATIHW->vert_stretching & VERT_STRETCH_EN) &&
+ !(pATIHW->lcd_gen_ctrl & LCD_ON))
+ {
+ /*
+ * At this point, if an XL or Mobility BIOS hasn't set
+ * panel dimensions, then there is no panel. Otherwise,
+ * keep any panel disabled to allow for modes greater than
+ * the panel's dimensions.
+ */
+ if ((pATI->Chip >= ATI_CHIP_264XL) &&
+ (!pATI->LCDHorizontal || !pATI->LCDVertical))
+ pATI->LCDPanelID = -1;
+ else
+ pATI->OptionPanelDisplay = FALSE;
+ }
+ }
+
+ /* Get DAC type */
+ pATI->DAC = GetBits(inr(DAC_CNTL), DAC_TYPE);
+
+ if (pATI->Chip < ATI_CHIP_264CT)
+ {
+ /* Factor in what the BIOS says the DAC is */
+ pATI->DAC = ATI_DAC(pATI->DAC,
+ GetBits(inr(SCRATCH_REG1), BIOS_INIT_DAC_SUBTYPE));
+ }
+
+ /*
+ * RAMDAC types 0 & 1 for Mach64's are different than those for
+ * Mach32's.
+ */
+ if (pATI->DAC < ATI_DAC_ATI68875)
+ pATI->DAC += ATI_DAC_INTERNAL;
+ }
+
+ {
+ ROMTable = BIOSWord(0x48U);
+ if ((ROMTable < 0x0002U) ||
+ (BIOSWord(ROMTable - 0x02U) < 0x0012U) ||
+ ((ROMTable + BIOSWord(ROMTable - 0x02U)) > BIOSSize))
+ ROMTable = 0;
+
+ if (ROMTable > 0)
+ {
+ ClockTable = BIOSWord(ROMTable + 0x10U);
+ if ((ClockTable + 0x20U) > BIOSSize)
+ ClockTable = 0;
+
+ if (BIOSWord(ROMTable - 0x02U) >= 0x0048U)
+ {
+ VideoTable = BIOSWord(ROMTable + 0x46U);
+ if ((VideoTable < 0x08U) ||
+ (BIOSByte(VideoTable - 0x01U) < 0x08U) ||
+ (BIOSByte(VideoTable - 0x02U) > 0x01U) ||
+ ((VideoTable + BIOSByte(VideoTable - 0x01U)) > BIOSSize))
+ VideoTable = 0;
+ }
+
+ if (BIOSWord(ROMTable - 0x02U) >= 0x004AU)
+ {
+ HardwareTable = BIOSWord(ROMTable + 0x48U);
+ if (((HardwareTable + 0x08U) > BIOSSize) ||
+ (memcmp(BIOS + HardwareTable, "$ATI", 4) != 0))
+ HardwareTable = 0;
+ }
+ }
+
+ ati_bios_clock(pScreenInfo, pATI, BIOS, ClockTable, pGDev);
+
+ ati_bios_mmedia(pScreenInfo, pATI, BIOS, VideoTable, HardwareTable);
+
+ if (pATI->LCDPanelID >= 0)
+ {
+ LCDTable = BIOSWord(0x78U);
+ if ((LCDTable + BIOSByte(LCDTable + 5)) > BIOSSize)
+ LCDTable = 0;
+
+ ati_bios_panel_info(pScreenInfo, pATI, BIOS, BIOSSize, LCDTable);
+ }
+
+ xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_INFO, 3,
+ "BIOS Data: BIOSSize=0x%04X, ROMTable=0x%04X.\n",
+ BIOSSize, ROMTable);
+ xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_INFO, 3,
+ "BIOS Data: ClockTable=0x%04X, FrequencyTable=0x%04X.\n",
+ ClockTable, FrequencyTable);
+ xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_INFO, 3,
+ "BIOS Data: LCDTable=0x%04X.\n",
+ LCDTable);
+ xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_INFO, 3,
+ "BIOS Data: VideoTable=0x%04X, HardwareTable=0x%04X.\n",
+ VideoTable, HardwareTable);
+ xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_INFO, 3,
+ "BIOS Data: I2CType=0x%02X, Tuner=0x%02X, Decoder=0x%02X,"
+ " Audio=0x%02X.\n",
+ pATI->I2CType, pATI->Tuner, pATI->Decoder, pATI->Audio);
+ }
+
+ ATIUnlock(pATI); /* Unlock registers */
+
+ /* Report what was found */
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
+ "%s graphics controller detected.\n",
+ xf86TokenToString(Mach64Chipsets, pATI->Chip));
+
+ {
+ Message = Buffer + snprintf(Buffer, SizeOf(Buffer), "Chip type %04X",
+ pATI->ChipType);
+ if (!(pATI->ChipType & ~(CHIP_CODE_0 | CHIP_CODE_1)))
+ Message += snprintf(Message, Buffer + SizeOf(Buffer) - Message,
+ " (%c%c)",
+ GetBits(pATI->ChipType, CHIP_CODE_1) + 0x41U,
+ GetBits(pATI->ChipType, CHIP_CODE_0) + 0x41U);
+ else if ((pATI->ChipType & 0x4040U) == 0x4040U)
+ Message += snprintf(Message, Buffer + SizeOf(Buffer) - Message,
+ " \"%c%c\"",
+ GetByte(pATI->ChipType, 1), GetByte(pATI->ChipType, 0));
+ if ((pATI->Chip >= ATI_CHIP_264CT) && (pATI->Chip != ATI_CHIP_Mach64))
+ Message += snprintf(Message, Buffer + SizeOf(Buffer) - Message,
+ ", version %d, foundry %s",
+ pATI->ChipVersion, ATIFoundryNames[pATI->ChipFoundry]);
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
+ "%s, class %d, revision 0x%02X.\n",
+ Buffer, pATI->ChipClass, pATI->ChipRevision);
+ }
+
+ {
+ Message = Buffer + snprintf(Buffer, SizeOf(Buffer),
+ "%s bus interface detected", ATIBusNames[pATI->BusType]);
+
+#ifndef AVOID_CPIO
+
+ {
+ Message += snprintf(Message, Buffer + SizeOf(Buffer) - Message,
+ "; %s I/O base is 0x%04lX",
+ (pATI->CPIODecoding == SPARSE_IO) ? "sparse" : "block",
+ pATI->CPIOBase);
+ }
+
+#endif /* AVOID_CPIO */
+
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED, "%s.\n", Buffer);
+ }
+
+#ifndef AVOID_CPIO
+
+ if (pATI->CPIO_VGAWonder)
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
+ "VGA Wonder registers at I/O port 0x%04lX.\n",
+ pATI->CPIO_VGAWonder);
+
+#endif /* AVOID_CPIO */
+
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
+ "ATI Mach64 adapter detected.\n");
+
+ if (pATI->Chip >= ATI_CHIP_264GT)
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_NOTICE,
+ "For information on using the multimedia capabilities\n\tof this"
+ " adapter, please see http://gatos.sf.net.\n");
+
+ if ((pATI->DAC & ~0x0FU) == ATI_DAC_INTERNAL)
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
+ "Internal RAMDAC (subtype %d) detected.\n", pATI->DAC & 0x0FU);
+ }
+ else
+ {
+ const SymTabRec *DAC;
+
+ for (DAC = ATIDACDescriptors; ; DAC++)
+ {
+ if (pATI->DAC == DAC->token)
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
+ "%s RAMDAC detected.\n", DAC->name);
+ break;
+ }
+
+ if (pATI->DAC < DAC->token)
+ {
+ xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_WARNING, 0,
+ "Unknown RAMDAC type 0x%02X detected.\n", pATI->DAC);
+ break;
+ }
+ }
+ }
+
+ if (!xf86LinearVidMem())
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "A linear aperture is not available.\n");
+ goto bail;
+ }
+
+ /*
+ * Set colour weights.
+ */
+
+ if (pATI->Chip < ATI_CHIP_264CT)
+ pScreenInfo->rgbBits = 6;
+ else
+ pScreenInfo->rgbBits = 8;
+ pATI->rgbBits = pScreenInfo->rgbBits;
+ if (!xf86SetWeight(pScreenInfo, defaultWeight, defaultWeight))
+ goto bail;
+
+ if ((pScreenInfo->depth > 8) &&
+ ((pScreenInfo->weight.red != pScreenInfo->weight.blue) ||
+ (pScreenInfo->weight.red != (CARD32)(pScreenInfo->depth / 3)) ||
+ ((CARD32)pScreenInfo->depth != (pScreenInfo->weight.red +
+ pScreenInfo->weight.green +
+ pScreenInfo->weight.blue))))
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "Driver does not support weight %d%d%d for depth %d.\n",
+ (int)pScreenInfo->weight.red, (int)pScreenInfo->weight.green,
+ (int)pScreenInfo->weight.blue, pScreenInfo->depth);
+ goto bail;
+ }
+
+ /*
+ * Set default visual.
+ */
+
+ if (!xf86SetDefaultVisual(pScreenInfo, -1))
+ goto bail;
+
+ if ((pScreenInfo->depth > 8) &&
+ (((pScreenInfo->defaultVisual | DynamicClass) != DirectColor) ||
+ ((pScreenInfo->defaultVisual == DirectColor) &&
+ (pATI->DAC == ATI_DAC_INTERNAL))))
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "Driver does not support default visual %s for depth %d.\n",
+ xf86GetVisualName(pScreenInfo->defaultVisual),
+ pScreenInfo->depth);
+ goto bail;
+ }
+
+ /*
+ * Set colour gamma.
+ */
+
+ if (!xf86SetGamma(pScreenInfo, defaultGamma))
+ goto bail;
+
+ pATI->depth = pScreenInfo->depth;
+ pATI->bitsPerPixel = pScreenInfo->bitsPerPixel;
+ pATI->weight = pScreenInfo->weight;
+ pATI->XModifier = pATI->bitsPerPixel / UnitOf(pATI->bitsPerPixel);
+
+ /*
+ * Determine which CRT controller to use for video modes.
+ */
+
+ {
+ pATI->NewHW.crtc = ATI_CRTC_MACH64;
+
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "Using Mach64 accelerator CRTC.\n");
+
+#ifndef AVOID_CPIO
+
+ if (pATI->VGAAdapter)
+ {
+ /*
+ * No need for VGA I/O resources during operating state (but they
+ * are still decoded).
+ */
+ pResources =
+ xf86SetOperatingState(resVgaIo, pATI->iEntity, ResUnusedOpr);
+ if (pResources)
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Logic error setting operating state for VGA I/O.\n");
+ xf86FreeResList(pResources);
+ }
+
+ if (pATI->CPIO_VGAWonder)
+ {
+ pResources = xf86SetOperatingState(pATI->VGAWonderResources,
+ pATI->iEntity, ResUnusedOpr);
+ if (pResources)
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Logic error setting operating state for"
+ " VGAWonder I/O.\n");
+ xf86FreeResList(pResources);
+ }
+ }
+ }
+
+#endif /* AVOID_CPIO */
+
+ }
+
+ /*
+ * Decide between the CRT and the panel.
+ */
+ if (pATI->LCDPanelID >= 0)
+ {
+ if (!pATI->OptionPanelDisplay)
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_CONFIG,
+ "Using CRT interface and disabling digital flat panel.\n");
+ }
+ else
+ {
+ unsigned HDisplay, VDisplay;
+ CARD8 ClockMask, PostMask;
+
+ /*
+ * Determine porch data. This groks the mode on entry to extract
+ * the width and position of its sync and blanking pulses, and
+ * considers any overscan as part of the displayed area, given that
+ * the overscan is also stretched.
+ *
+ * This also attempts to determine panel dimensions but cannot do
+ * so for one that is "auto-stretched".
+ */
+
+ if (pATI->Chip == ATI_CHIP_264LT)
+ {
+ pATIHW->lcd_gen_ctrl = inr(LCD_GEN_CTRL);
+
+ /* Set up to read non-shadow registers */
+ if (pATIHW->lcd_gen_ctrl & SHADOW_RW_EN)
+ outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl & ~SHADOW_RW_EN);
+ }
+ else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
+ (pATI->Chip == ATI_CHIP_264XL) ||
+ (pATI->Chip == ATI_CHIP_MOBILITY)) */
+ {
+ pATIHW->lcd_index = inr(LCD_INDEX);
+ pATIHW->config_panel = ATIMach64GetLCDReg(LCD_CONFIG_PANEL);
+ pATIHW->lcd_gen_ctrl = ATIMach64GetLCDReg(LCD_GEN_CNTL);
+
+ /* Set up to read non-shadow registers */
+ if (pATIHW->lcd_gen_ctrl & SHADOW_RW_EN)
+ ATIMach64PutLCDReg(LCD_GEN_CNTL,
+ pATIHW->lcd_gen_ctrl & ~SHADOW_RW_EN);
+ }
+
+#ifndef AVOID_CPIO
+
+ if (!(pATIHW->crtc_gen_cntl & CRTC_EXT_DISP_EN))
+ {
+ unsigned HBlankStart, HSyncStart, HSyncEnd, HBlankEnd, HTotal;
+ unsigned VBlankStart, VSyncStart, VSyncEnd, VBlankEnd, VTotal;
+
+ pATIHW->clock = (inb(R_GENMO) & 0x0CU) >> 2;
+
+ pATIHW->crt[2] = GetReg(CRTX(pATI->CPIO_VGABase), 0x02U);
+ pATIHW->crt[3] = GetReg(CRTX(pATI->CPIO_VGABase), 0x03U);
+ pATIHW->crt[5] = GetReg(CRTX(pATI->CPIO_VGABase), 0x05U);
+ pATIHW->crt[7] = GetReg(CRTX(pATI->CPIO_VGABase), 0x07U);
+ pATIHW->crt[9] = GetReg(CRTX(pATI->CPIO_VGABase), 0x09U);
+ pATIHW->crt[21] = GetReg(CRTX(pATI->CPIO_VGABase), 0x15U);
+ pATIHW->crt[22] = GetReg(CRTX(pATI->CPIO_VGABase), 0x16U);
+
+ pATIHW->crtc_h_total_disp = inr(CRTC_H_TOTAL_DISP);
+ pATIHW->crtc_h_sync_strt_wid = inr(CRTC_H_SYNC_STRT_WID);
+ pATIHW->crtc_v_total_disp = inr(CRTC_V_TOTAL_DISP);
+ pATIHW->crtc_v_sync_strt_wid = inr(CRTC_V_SYNC_STRT_WID);
+
+ /* Switch to shadow registers */
+ if (pATI->Chip == ATI_CHIP_264LT)
+ outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl | SHADOW_RW_EN);
+ else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
+ (pATI->Chip == ATI_CHIP_264XL) ||
+ (pATI->Chip == ATI_CHIP_MOBILITY)) */
+ ATIMach64PutLCDReg(LCD_GEN_CNTL,
+ pATIHW->lcd_gen_ctrl | SHADOW_RW_EN);
+
+ pATIHW->shadow_vga[2] =
+ GetReg(CRTX(pATI->CPIO_VGABase), 0x02U);
+ pATIHW->shadow_vga[3] =
+ GetReg(CRTX(pATI->CPIO_VGABase), 0x03U);
+ pATIHW->shadow_vga[5] =
+ GetReg(CRTX(pATI->CPIO_VGABase), 0x05U);
+ pATIHW->shadow_vga[7] =
+ GetReg(CRTX(pATI->CPIO_VGABase), 0x07U);
+ pATIHW->shadow_vga[9] =
+ GetReg(CRTX(pATI->CPIO_VGABase), 0x09U);
+ pATIHW->shadow_vga[21] =
+ GetReg(CRTX(pATI->CPIO_VGABase), 0x15U);
+ pATIHW->shadow_vga[22] =
+ GetReg(CRTX(pATI->CPIO_VGABase), 0x16U);
+
+ pATIHW->shadow_h_total_disp = inr(CRTC_H_TOTAL_DISP);
+ pATIHW->shadow_h_sync_strt_wid = inr(CRTC_H_SYNC_STRT_WID);
+ pATIHW->shadow_v_total_disp = inr(CRTC_V_TOTAL_DISP);
+ pATIHW->shadow_v_sync_strt_wid = inr(CRTC_V_SYNC_STRT_WID);
+
+ /*
+ * HSyncStart and HSyncEnd should equal their shadow
+ * counterparts. Otherwise, due to a chip bug, the panel might
+ * not sync, regardless of which register set is used to drive
+ * the panel. There are certain combinations of register
+ * values where the panel does in fact sync, but it remains
+ * impossible to accurately determine the horizontal sync pulse
+ * timing actually seen by the panel.
+ *
+ * Note that this hardware bug does not affect the CRT output.
+ */
+ if (((pATIHW->crtc_h_sync_strt_wid ^
+ pATIHW->shadow_h_sync_strt_wid) &
+ (CRTC_H_SYNC_STRT | CRTC_H_SYNC_STRT_HI |
+ CRTC_H_SYNC_WID)))
+ {
+ xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_NOTICE, 0,
+ "Invalid horizontal sync pulse timing detected in mode"
+ " on server entry.\n");
+
+ /* Don't trust input timing */
+ pATI->OptionLCDSync = TRUE;
+ ModeType = 0;
+ }
+
+ /* Merge in shadow registers as appropriate */
+ if (pATIHW->lcd_gen_ctrl & SHADOW_EN)
+ {
+ pATIHW->crt[2] = pATIHW->shadow_vga[2];
+ pATIHW->crt[3] = pATIHW->shadow_vga[3];
+ pATIHW->crt[5] = pATIHW->shadow_vga[5];
+
+ /* XXX Does this apply to VGA? If so, what about the LT? */
+ if ((pATI->Chip < ATI_CHIP_264LTPRO) ||
+ !(pATIHW->config_panel & DONT_SHADOW_HEND))
+ {
+ pATIHW->crtc_h_total_disp &= ~CRTC_H_DISP;
+ pATIHW->crtc_h_total_disp |=
+ pATIHW->shadow_h_total_disp & CRTC_H_DISP;
+ }
+
+ pATIHW->crtc_h_total_disp &= ~CRTC_H_TOTAL;
+ pATIHW->crtc_h_total_disp |=
+ pATIHW->shadow_h_total_disp & CRTC_H_TOTAL;
+ pATIHW->crtc_h_sync_strt_wid =
+ pATIHW->shadow_h_sync_strt_wid;
+
+ /* XXX Does this apply to VGA? */
+ if (pATIHW->lcd_gen_ctrl & USE_SHADOWED_VEND)
+ {
+ pATIHW->crtc_v_total_disp &= ~CRTC_V_DISP;
+ pATIHW->crtc_v_total_disp |=
+ pATIHW->shadow_v_total_disp & CRTC_V_DISP;
+ }
+
+ if (!(pATIHW->lcd_gen_ctrl & DONT_SHADOW_VPAR))
+ {
+ pATIHW->crt[7] = pATIHW->shadow_vga[7];
+ pATIHW->crt[9] = pATIHW->shadow_vga[9];
+ pATIHW->crt[21] = pATIHW->shadow_vga[21];
+ pATIHW->crt[22] = pATIHW->shadow_vga[22];
+
+ pATIHW->crtc_v_total_disp &= ~CRTC_V_TOTAL;
+ pATIHW->crtc_v_total_disp |=
+ pATIHW->shadow_v_total_disp & CRTC_V_TOTAL;
+ }
+ }
+
+ if (!(pATIHW->lcd_gen_ctrl & DONT_SHADOW_VPAR))
+ pATIHW->crtc_v_sync_strt_wid =
+ pATIHW->shadow_v_sync_strt_wid;
+
+ /*
+ * Decipher input timing. This is complicated by the fact that
+ * the full width of all timing parameters, except for the
+ * blanking pulses, is only available through the accelerator
+ * registers, not the VGA ones. Blanking pulse boundaries must
+ * then be interpolated.
+ *
+ * Note that, in VGA mode, the accelerator's sync width fields
+ * are actually end positions, not widths.
+ */
+ HDisplay = GetBits(pATIHW->crtc_h_total_disp, CRTC_H_DISP);
+ HSyncStart =
+ (GetBits(pATIHW->crtc_h_sync_strt_wid,
+ CRTC_H_SYNC_STRT_HI) *
+ (MaxBits(CRTC_H_SYNC_STRT) + 1)) |
+ GetBits(pATIHW->crtc_h_sync_strt_wid, CRTC_H_SYNC_STRT);
+ HSyncEnd = (HSyncStart & ~MaxBits(CRTC_H_SYNC_WID)) |
+ GetBits(pATIHW->crtc_h_sync_strt_wid, CRTC_H_SYNC_WID);
+ if (HSyncStart >= HSyncEnd)
+ HSyncEnd += MaxBits(CRTC_H_SYNC_WID) + 1;
+ HTotal = GetBits(pATIHW->crtc_h_total_disp, CRTC_H_TOTAL);
+
+ HBlankStart = (HDisplay & ~0xFFU) | pATIHW->crt[2];
+ if (HDisplay > HBlankStart)
+ HBlankStart += 0x0100U;
+ HBlankEnd = (HSyncEnd & ~0x3FU) |
+ ((pATIHW->crt[5] >> 2) & 0x20U) |
+ (pATIHW->crt[3] & 0x1FU);
+ if (HSyncEnd > (HBlankEnd + 1))
+ HBlankEnd += 0x40U;
+
+ VDisplay = GetBits(pATIHW->crtc_v_total_disp, CRTC_V_DISP);
+ VSyncStart =
+ GetBits(pATIHW->crtc_v_sync_strt_wid, CRTC_V_SYNC_STRT);
+ VSyncEnd = (VSyncStart & ~MaxBits(CRTC_V_SYNC_END_VGA)) |
+ GetBits(pATIHW->crtc_v_sync_strt_wid, CRTC_V_SYNC_END_VGA);
+ if (VSyncStart > VSyncEnd)
+ VSyncEnd += MaxBits(CRTC_V_SYNC_END_VGA) + 1;
+ VTotal = GetBits(pATIHW->crtc_v_total_disp, CRTC_V_TOTAL);
+
+ VBlankStart = (VDisplay & ~0x03FFU) |
+ ((pATIHW->crt[9] << 4) & 0x0200U) |
+ ((pATIHW->crt[7] << 5) & 0x0100U) | pATIHW->crt[21];
+ if (VDisplay > VBlankStart)
+ VBlankStart += 0x0400U;
+ VBlankEnd = (VSyncEnd & ~0x00FFU) | pATIHW->crt[22];
+ if (VSyncEnd > (VBlankEnd + 1))
+ VBlankEnd += 0x0100U;
+
+ pATI->LCDHBlankWidth = HBlankEnd - HBlankStart;
+ pATI->LCDHSyncStart = HSyncStart - HBlankStart;
+ pATI->LCDHSyncWidth = HSyncEnd - HSyncStart;
+
+ pATI->LCDVBlankWidth = VBlankEnd - VBlankStart;
+ pATI->LCDVSyncStart = VSyncStart - VBlankStart;
+ pATI->LCDVSyncWidth = VSyncEnd - VSyncStart;
+
+ HDisplay = HTotal + 5 - pATI->LCDHBlankWidth;
+ VDisplay = VTotal + 2 - pATI->LCDVBlankWidth;
+ }
+ else
+
+#endif /* AVOID_CPIO */
+
+ {
+ pATIHW->clock = inr(CLOCK_CNTL) & 0x03U;
+
+ pATIHW->crtc_h_total_disp = inr(CRTC_H_TOTAL_DISP);
+ pATIHW->crtc_h_sync_strt_wid = inr(CRTC_H_SYNC_STRT_WID);
+ pATIHW->crtc_v_total_disp = inr(CRTC_V_TOTAL_DISP);
+ pATIHW->crtc_v_sync_strt_wid = inr(CRTC_V_SYNC_STRT_WID);
+ pATIHW->ovr_wid_left_right = inr(OVR_WID_LEFT_RIGHT);
+ pATIHW->ovr_wid_top_bottom = inr(OVR_WID_TOP_BOTTOM);
+
+ /* Switch to shadow registers */
+ if (pATI->Chip == ATI_CHIP_264LT)
+ outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl | SHADOW_RW_EN);
+ else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
+ (pATI->Chip == ATI_CHIP_264XL) ||
+ (pATI->Chip == ATI_CHIP_MOBILITY)) */
+ ATIMach64PutLCDReg(LCD_GEN_CNTL,
+ pATIHW->lcd_gen_ctrl | SHADOW_RW_EN);
+
+ /* Oddly enough, there are no shadow overscan registers */
+ pATIHW->shadow_h_total_disp = inr(CRTC_H_TOTAL_DISP);
+ pATIHW->shadow_h_sync_strt_wid = inr(CRTC_H_SYNC_STRT_WID);
+ pATIHW->shadow_v_total_disp = inr(CRTC_V_TOTAL_DISP);
+ pATIHW->shadow_v_sync_strt_wid = inr(CRTC_V_SYNC_STRT_WID);
+
+ /*
+ * HSyncStart and HSyncEnd should equal their shadow
+ * counterparts. Otherwise, due to a chip bug, the panel might
+ * not sync, regardless of which register set is used to drive
+ * the panel. There are certain combinations of register
+ * values where the panel does in fact sync, but it remains
+ * impossible to accurately determine the horizontal sync pulse
+ * timing actually seen by the panel.
+ *
+ * Note that this hardware bug does not affect the CRT output.
+ */
+ if (((pATIHW->crtc_h_sync_strt_wid ^
+ pATIHW->shadow_h_sync_strt_wid) &
+ (CRTC_H_SYNC_STRT | CRTC_H_SYNC_STRT_HI |
+ CRTC_H_SYNC_WID)))
+ {
+ xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_NOTICE, 0,
+ "Invalid horizontal sync pulse timing detected in mode"
+ " on server entry.\n");
+
+ /* Don't trust input timing */
+ pATI->OptionLCDSync = TRUE;
+ ModeType = 0;
+ }
+
+ /* Merge in shadow registers as appropriate */
+ if (pATIHW->lcd_gen_ctrl & SHADOW_EN)
+ {
+ /* XXX What about the LT? */
+ if ((pATI->Chip < ATI_CHIP_264LTPRO) ||
+ !(pATIHW->config_panel & DONT_SHADOW_HEND))
+ {
+ pATIHW->crtc_h_total_disp &= ~CRTC_H_DISP;
+ pATIHW->crtc_h_total_disp |=
+ pATIHW->shadow_h_total_disp & CRTC_H_DISP;
+ }
+
+ pATIHW->crtc_h_total_disp &= ~CRTC_H_TOTAL;
+ pATIHW->crtc_h_total_disp |=
+ pATIHW->shadow_h_total_disp & CRTC_H_TOTAL;
+ pATIHW->crtc_h_sync_strt_wid =
+ pATIHW->shadow_h_sync_strt_wid;
+
+ if (pATIHW->lcd_gen_ctrl & USE_SHADOWED_VEND)
+ {
+ pATIHW->crtc_v_total_disp &= ~CRTC_V_DISP;
+ pATIHW->crtc_v_total_disp |=
+ pATIHW->shadow_v_total_disp & CRTC_V_DISP;
+ }
+
+ if (!(pATIHW->lcd_gen_ctrl & DONT_SHADOW_VPAR))
+ {
+ pATIHW->crtc_v_total_disp &= ~CRTC_V_TOTAL;
+ pATIHW->crtc_v_total_disp |=
+ pATIHW->shadow_v_total_disp & CRTC_V_TOTAL;
+ }
+ }
+
+ if (!(pATIHW->lcd_gen_ctrl & DONT_SHADOW_VPAR))
+ pATIHW->crtc_v_sync_strt_wid =
+ pATIHW->shadow_v_sync_strt_wid;
+
+ /* Decipher input timing */
+ HDisplay = GetBits(pATIHW->crtc_h_total_disp, CRTC_H_DISP) +
+ GetBits(pATIHW->ovr_wid_left_right, OVR_WID_LEFT) +
+ GetBits(pATIHW->ovr_wid_left_right, OVR_WID_RIGHT);
+ VDisplay = GetBits(pATIHW->crtc_v_total_disp, CRTC_V_DISP) +
+ GetBits(pATIHW->ovr_wid_top_bottom, OVR_WID_TOP) +
+ GetBits(pATIHW->ovr_wid_top_bottom, OVR_WID_BOTTOM);
+
+ pATI->LCDHSyncStart =
+ (GetBits(pATIHW->crtc_h_sync_strt_wid,
+ CRTC_H_SYNC_STRT_HI) *
+ (MaxBits(CRTC_H_SYNC_STRT) + 1)) +
+ GetBits(pATIHW->crtc_h_sync_strt_wid, CRTC_H_SYNC_STRT) -
+ HDisplay;
+ pATI->LCDHSyncWidth =
+ GetBits(pATIHW->crtc_h_sync_strt_wid, CRTC_H_SYNC_WID);
+ pATI->LCDHBlankWidth =
+ GetBits(pATIHW->crtc_h_total_disp, CRTC_H_TOTAL) -
+ HDisplay;
+ pATI->LCDVSyncStart =
+ GetBits(pATIHW->crtc_v_sync_strt_wid, CRTC_V_SYNC_STRT) -
+ VDisplay;
+ pATI->LCDVSyncWidth =
+ GetBits(pATIHW->crtc_v_sync_strt_wid, CRTC_V_SYNC_WID);
+ pATI->LCDVBlankWidth =
+ GetBits(pATIHW->crtc_v_total_disp, CRTC_V_TOTAL) -
+ VDisplay;
+
+ HDisplay++;
+ VDisplay++;
+ }
+
+ /* Restore LCD registers */
+ if (pATI->Chip == ATI_CHIP_264LT)
+ {
+ outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl);
+ }
+ else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
+ (pATI->Chip == ATI_CHIP_264XL) ||
+ (pATI->Chip == ATI_CHIP_MOBILITY)) */
+ {
+ ATIMach64PutLCDReg(LCD_GEN_CNTL, pATIHW->lcd_gen_ctrl);
+ outr(LCD_INDEX, pATIHW->lcd_index);
+ }
+
+ HDisplay <<= 3;
+ pATI->LCDHSyncStart <<= 3;
+ pATI->LCDHSyncWidth <<= 3;
+ pATI->LCDHBlankWidth <<= 3;
+
+ /* Calculate panel dimensions implied by the input timing */
+ if ((pATIHW->horz_stretching &
+ (HORZ_STRETCH_EN | AUTO_HORZ_RATIO)) ==
+ HORZ_STRETCH_EN)
+ {
+ if (pATIHW->horz_stretching & HORZ_STRETCH_MODE)
+ {
+ if (pATIHW->horz_stretching & HORZ_STRETCH_BLEND)
+ {
+ HDisplay =
+ (HDisplay * (MaxBits(HORZ_STRETCH_BLEND) + 1)) /
+ GetBits(pATIHW->horz_stretching,
+ HORZ_STRETCH_BLEND);
+ }
+ }
+ else if (((pATIHW->horz_stretching & HORZ_STRETCH_LOOP) >
+ HORZ_STRETCH_LOOP15) ||
+ (pATIHW->horz_stretching &
+ SetBits(1, HORZ_STRETCH_RATIO)))
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Ignoring invalid horizontal stretch ratio in mode on"
+ " server entry.\n");
+ }
+ else
+ {
+ IOValue =
+ GetBits(pATIHW->horz_stretching, HORZ_STRETCH_RATIO);
+
+ switch (GetBits(pATIHW->horz_stretching,
+ HORZ_STRETCH_LOOP))
+ {
+ case GetBits(HORZ_STRETCH_LOOP09, HORZ_STRETCH_LOOP):
+ i = 9;
+ IOValue &= (1 << 9) - 1;
+ break;
+
+ case GetBits(HORZ_STRETCH_LOOP11, HORZ_STRETCH_LOOP):
+ i = 11;
+ IOValue &= (1 << 11) - 1;
+ break;
+
+ case GetBits(HORZ_STRETCH_LOOP12, HORZ_STRETCH_LOOP):
+ i = 12;
+ IOValue &= (1 << 12) - 1;
+ break;
+
+ case GetBits(HORZ_STRETCH_LOOP14, HORZ_STRETCH_LOOP):
+ i = 14;
+ IOValue &= (1 << 14) - 1;
+ break;
+
+ case GetBits(HORZ_STRETCH_LOOP15, HORZ_STRETCH_LOOP):
+ default: /* Muffle compiler */
+ i = 15;
+ IOValue &= (1 << 15) - 1;
+ break;
+ }
+
+ if (IOValue)
+ {
+ /* Count the number of bits in IOValue */
+ j = (IOValue >> 1) & 0x36DBU;
+ j = IOValue - j - ((j >> 1) & 0x36DBU);
+ j = ((j + (j >> 3)) & 0x71C7U) % 0x3FU;
+
+ HDisplay = (HDisplay * i) / j;
+ }
+ }
+ }
+
+ if ((pATIHW->vert_stretching & VERT_STRETCH_EN) &&
+ !(pATIHW->ext_vert_stretch & AUTO_VERT_RATIO))
+ {
+ if ((pATIHW->vert_stretching & VERT_STRETCH_USE0) ||
+ (VDisplay <= 350))
+ IOValue =
+ GetBits(pATIHW->vert_stretching, VERT_STRETCH_RATIO0);
+ else if (VDisplay <= 400)
+ IOValue =
+ GetBits(pATIHW->vert_stretching, VERT_STRETCH_RATIO1);
+ else if ((VDisplay <= 480) ||
+ !(pATIHW->ext_vert_stretch & VERT_STRETCH_RATIO3))
+ IOValue =
+ GetBits(pATIHW->vert_stretching, VERT_STRETCH_RATIO2);
+ else
+ IOValue =
+ GetBits(pATIHW->ext_vert_stretch, VERT_STRETCH_RATIO3);
+
+ if (IOValue)
+ VDisplay =
+ (VDisplay * (MaxBits(VERT_STRETCH_RATIO0) + 1)) /
+ IOValue;
+ }
+
+ /* Match calculated dimensions to probed dimensions */
+ if (!pATI->LCDHorizontal)
+ {
+ if ((pATIHW->horz_stretching &
+ (HORZ_STRETCH_EN | AUTO_HORZ_RATIO)) !=
+ (HORZ_STRETCH_EN | AUTO_HORZ_RATIO))
+ pATI->LCDHorizontal = HDisplay;
+ }
+ else if (pATI->LCDHorizontal != (int)HDisplay)
+ {
+ if ((pATIHW->horz_stretching &
+ (HORZ_STRETCH_EN | AUTO_HORZ_RATIO)) !=
+ (HORZ_STRETCH_EN | AUTO_HORZ_RATIO))
+ xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_WARNING, 4,
+ "Inconsistent panel horizontal dimension:"
+ " %d and %d.\n", pATI->LCDHorizontal, HDisplay);
+ HDisplay = pATI->LCDHorizontal;
+ }
+
+ if (!pATI->LCDVertical)
+ {
+ if (!(pATIHW->vert_stretching & VERT_STRETCH_EN) ||
+ !(pATIHW->ext_vert_stretch & AUTO_VERT_RATIO))
+ pATI->LCDVertical = VDisplay;
+ }
+ else if (pATI->LCDVertical != (int)VDisplay)
+ {
+ if (!(pATIHW->vert_stretching & VERT_STRETCH_EN) ||
+ !(pATIHW->ext_vert_stretch & AUTO_VERT_RATIO))
+ xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_WARNING, 4,
+ "Inconsistent panel vertical dimension: %d and %d.\n",
+ pATI->LCDVertical, VDisplay);
+ VDisplay = pATI->LCDVertical;
+ }
+
+ if (!pATI->LCDHorizontal || !pATI->LCDVertical)
+ {
+ if (pATI->LCDPanelID || (pATI->Chip <= ATI_CHIP_264LTPRO))
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "Unable to determine dimensions of panel (ID %d).\n",
+ pATI->LCDPanelID);
+ else
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "Unable to determine dimensions of panel.\n");
+
+ goto bail;
+ }
+
+ /* If the mode on entry wasn't stretched, adjust timings */
+ if (!(pATIHW->horz_stretching & HORZ_STRETCH_EN) &&
+ (pATI->LCDHorizontal > (int)HDisplay))
+ {
+ HDisplay = pATI->LCDHorizontal - HDisplay;
+ if (pATI->LCDHSyncStart >= HDisplay)
+ pATI->LCDHSyncStart -= HDisplay;
+ else
+ pATI->LCDHSyncStart = 0;
+ pATI->LCDHBlankWidth -= HDisplay;
+ HDisplay = pATI->LCDHSyncStart + pATI->LCDHSyncWidth;
+ if (pATI->LCDHBlankWidth < HDisplay)
+ pATI->LCDHBlankWidth = HDisplay;
+ }
+
+ if (!(pATIHW->vert_stretching & VERT_STRETCH_EN) &&
+ (pATI->LCDVertical > (int)VDisplay))
+ {
+ VDisplay = pATI->LCDVertical - VDisplay;
+ if (pATI->LCDVSyncStart >= VDisplay)
+ pATI->LCDVSyncStart -= VDisplay;
+ else
+ pATI->LCDVSyncStart = 0;
+ pATI->LCDVBlankWidth -= VDisplay;
+ VDisplay = pATI->LCDVSyncStart + pATI->LCDVSyncWidth;
+ if (pATI->LCDVBlankWidth < VDisplay)
+ pATI->LCDVBlankWidth = VDisplay;
+ }
+
+ if (pATI->LCDPanelID || (pATI->Chip <= ATI_CHIP_264LTPRO))
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
+ "%dx%d panel (ID %d) detected.\n",
+ pATI->LCDHorizontal, pATI->LCDVertical, pATI->LCDPanelID);
+ else
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
+ "%dx%d panel detected.\n",
+ pATI->LCDHorizontal, pATI->LCDVertical);
+
+ /*
+ * Determine panel clock. This must be done after option
+ * processing so that the adapter's reference frequency is always
+ * available.
+ *
+ * Get post divider. A GCC bug has caused the following expression
+ * to be broken down into its individual components.
+ */
+ ClockMask = PLL_VCLK0_XDIV << pATIHW->clock;
+ PostMask = PLL_VCLK0_POST_DIV << (pATIHW->clock * 2);
+ i = GetBits(ATIMach64GetPLLReg(PLL_XCLK_CNTL), ClockMask);
+ i *= MaxBits(PLL_VCLK0_POST_DIV) + 1;
+ i |= GetBits(ATIMach64GetPLLReg(PLL_VCLK_POST_DIV), PostMask);
+
+ /* Calculate clock of mode on entry */
+ Numerator = ATIMach64GetPLLReg(PLL_VCLK0_FB_DIV + pATIHW->clock) *
+ pATI->ReferenceNumerator;
+ Denominator = pATI->ClockDescriptor.MinM *
+ pATI->ReferenceDenominator *
+ pATI->ClockDescriptor.PostDividers[i];
+ pATI->LCDClock = ATIDivide(Numerator, Denominator, 1, 0);
+
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
+ "Panel clock is %.3f MHz.\n",
+ (double)(pATI->LCDClock) / 1000.0);
+
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "Using digital flat panel interface%s.\n",
+ pATI->OptionCRTDisplay ?
+ " to display on both CRT and panel" : "");
+ }
+ }
+
+ /*
+ * Finish detecting video RAM size.
+ */
+ pScreenInfo->videoRam = pATI->VideoRAM;
+
+ {
+ {
+ /* Get adapter's linear aperture configuration */
+ pATIHW->config_cntl = inr(CONFIG_CNTL);
+ pATI->LinearBase =
+ GetBits(pATIHW->config_cntl, CFG_MEM_AP_LOC) << 22;
+ if ((pATIHW->config_cntl & CFG_MEM_AP_SIZE) != CFG_MEM_AP_SIZE)
+ {
+ pATI->LinearSize =
+ GetBits(pATIHW->config_cntl, CFG_MEM_AP_SIZE) << 22;
+
+ /*
+ * Linear aperture could have been disabled (but still
+ * assigned) by BIOS initialisation.
+ */
+ if (pATI->LinearBase && !pATI->LinearSize)
+ {
+ if ((pATI->Chip <= ATI_CHIP_88800GXD) &&
+ (pATI->VideoRAM < 4096))
+ pATI->LinearSize = 4 * 1024 * 1024;
+ else
+ pATI->LinearSize = 8 * 1024 * 1024;
+ }
+ }
+
+ if (pATI->LinearBase && pATI->LinearSize)
+ {
+ int AcceleratorVideoRAM = 0, ServerVideoRAM;
+
+#ifndef AVOID_CPIO
+
+ /*
+ * Unless specified in PCI configuration space, set MMIO
+ * address to tail end of linear aperture.
+ */
+ if (!pATI->Block0Base)
+ {
+ pATI->Block0Base =
+ pATI->LinearBase + pATI->LinearSize - 0x00000400U;
+ pATI->MMIOInLinear = TRUE;
+ }
+
+#endif /* AVOID_CPIO */
+
+ AcceleratorVideoRAM = pATI->LinearSize >> 10;
+
+ /*
+ * Account for MMIO area at the tail end of the linear
+ * aperture, if it is needed or if it cannot be disabled.
+ */
+ if (pATI->MMIOInLinear || (pATI->Chip < ATI_CHIP_264VTB))
+ AcceleratorVideoRAM -= 2;
+
+ ServerVideoRAM = pATI->VideoRAM;
+
+ if (pATI->Cursor > ATI_CURSOR_SOFTWARE)
+ {
+ /*
+ * Allocate a 1 kB cursor image area at the top of the
+ * little-endian aperture, just before any MMIO area that
+ * might also be there.
+ */
+ if (ServerVideoRAM > AcceleratorVideoRAM)
+ ServerVideoRAM = AcceleratorVideoRAM;
+
+ ServerVideoRAM--;
+ pATI->CursorOffset = ServerVideoRAM << 10;
+ pATI->CursorBase = pATI->LinearBase + pATI->CursorOffset;
+
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "Storing hardware cursor image at 0x%08lX.\n",
+ pATI->CursorBase);
+ }
+
+ {
+ CARD32 PageSize = getpagesize() >> 10;
+
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
+
+ /*
+ * MMIO areas must be mmap()'ed separately to avoid write
+ * combining them. Thus, they might not end up still
+ * adjacent with the little-endian linear aperture after
+ * mmap()'ing. So, round down the linear aperture size to
+ * avoid an overlap. Any hardware cursor image area might
+ * not end up being write combined, but this seems
+ * preferable to further reducing the video memory size
+ * advertised to the server.
+ *
+ * XXX Ideally this should be dealt with in the os-support
+ * layer, i.e., it should be possible to reset a
+ * subarea's write combining after it has been
+ * mmap()'ed, but doing so currently causes the removal
+ * of write combining for the entire aperture.
+ */
+ if (pATI->MMIOInLinear)
+ AcceleratorVideoRAM -= AcceleratorVideoRAM % PageSize;
+
+#else /* if X_BYTE_ORDER != X_LITTLE_ENDIAN */
+
+ /*
+ * Big-endian apertures are 8 MB higher and don't contain
+ * an MMIO area.
+ */
+ pATI->LinearBase += 0x00800000U;
+ AcceleratorVideoRAM = pATI->LinearSize >> 10;
+
+#endif /* X_BYTE_ORDER */
+
+ if (ServerVideoRAM > AcceleratorVideoRAM)
+ ServerVideoRAM = AcceleratorVideoRAM;
+ else if (AcceleratorVideoRAM > pATI->VideoRAM)
+ AcceleratorVideoRAM = pATI->VideoRAM;
+
+ PageSize--;
+ AcceleratorVideoRAM =
+ (AcceleratorVideoRAM + PageSize) & ~PageSize;
+
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "Using %d MB linear aperture at 0x%08lX.\n",
+ pATI->LinearSize >> 20, pATI->LinearBase);
+
+ /* Only mmap what is needed */
+ ApertureSize = pATI->LinearSize =
+ AcceleratorVideoRAM << 10;
+ }
+
+ if (ServerVideoRAM < pATI->VideoRAM)
+ {
+ pScreenInfo->videoRam = ServerVideoRAM;
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_NOTICE,
+ "Virtual resolutions will be limited to %d kB\n due to"
+ " linear aperture size and/or placement of hardware"
+ " cursor image area.\n",
+ ServerVideoRAM);
+ }
+ }
+ }
+
+ if (!pATI->LinearBase || !pATI->LinearSize)
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "Linear aperture not available.\n");
+ goto bail;
+ }
+
+ if (pATI->Block0Base)
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "Using Block 0 MMIO aperture at 0x%08lX.\n", pATI->Block0Base);
+
+ /* Set Block1 MMIO address if supported */
+ if (pATI->Chip >= ATI_CHIP_264VT)
+ {
+ pATI->Block1Base = pATI->Block0Base - 0x00000400U;
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "Using Block 1 MMIO aperture at 0x%08lX.\n",
+ pATI->Block1Base);
+ }
+ }
+ }
+
+#ifndef AVOID_CPIO
+
+ if (pATI->VGAAdapter)
+ {
+ /*
+ * Free VGA memory aperture during operating state (but it is still
+ * decoded).
+ */
+ pResources = xf86SetOperatingState(resVgaMem, pATI->iEntity,
+ ResUnusedOpr);
+ if (pResources)
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Logic error setting operating state for VGA memory"
+ " aperture.\n");
+ xf86FreeResList(pResources);
+ }
+ }
+
+#endif /* AVOID_CPIO */
+
+ /*
+ * Remap apertures. Must lock and re-unlock around this in case the
+ * remapping fails.
+ */
+ ATILock(pATI);
+ ATIUnmapApertures(pScreenInfo->scrnIndex, pATI);
+ if (!ATIMapApertures(pScreenInfo->scrnIndex, pATI))
+ return FALSE;
+
+ ATIUnlock(pATI);
+
+ if (pATI->OptionAccel)
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "MMIO write caching %sabled.\n",
+ pATI->OptionMMIOCache ? "en" : "dis");
+ }
+
+ {
+ if (pATI->Chip >= ATI_CHIP_264CT)
+ ATIReportMemory(pScreenInfo, pATI,
+ ATIMemoryTypeNames_264xT[pATI->MemoryType]);
+ else if (pATI->Chip == ATI_CHIP_88800CX)
+ ATIReportMemory(pScreenInfo, pATI,
+ ATIMemoryTypeNames_88800CX[pATI->MemoryType]);
+ else
+ ATIReportMemory(pScreenInfo, pATI,
+ ATIMemoryTypeNames_Mach[pATI->MemoryType]);
+ }
+
+ /*
+ * Finish banking setup. This needs to be fixed to not assume the mode on
+ * entry is a VGA mode. XXX
+ */
+
+#ifndef AVOID_CPIO
+
+ if (!pATI->VGAAdapter)
+ {
+ pATI->NewHW.SetBank = ATIx8800SetBank;
+ pATI->NewHW.nPlane = 0;
+
+ pATIHW->crtc = pATI->NewHW.crtc;
+
+ pATIHW->SetBank = (ATIBankProcPtr)NoopDDA;
+ }
+ else
+ {
+ Bool ext_disp_en = (pATI->LockData.crtc_gen_cntl & CRTC_EXT_DISP_EN);
+ Bool vga_ap_en = (pATI->LockData.config_cntl & CFG_MEM_VGA_AP_EN);
+ Bool vga_color_256 = (GetReg(SEQX, 0x04U) & 0x08U);
+
+ pATI->NewHW.SetBank = ATIMach64SetBankPacked;
+ pATI->NewHW.nPlane = 1;
+
+ pATIHW->crtc = ATI_CRTC_VGA;
+
+ if (ext_disp_en)
+ pATIHW->crtc = ATI_CRTC_MACH64;
+
+ if ((pATIHW->crtc != ATI_CRTC_VGA) || vga_color_256)
+ pATIHW->nPlane = 1;
+ else
+ pATIHW->nPlane = 4;
+
+ /* VideoRAM is a multiple of 512kB and BankSize is 64kB */
+ pATIHW->nBank = pATI->VideoRAM / (pATIHW->nPlane * 0x40U);
+
+ if ((pATIHW->crtc == ATI_CRTC_VGA) && !vga_ap_en)
+ {
+ pATIHW->SetBank = (ATIBankProcPtr)NoopDDA;
+ pATIHW->nBank = 1;
+ }
+ else if (pATIHW->nPlane == 1)
+ {
+ pATIHW->SetBank = ATIMach64SetBankPacked;
+ }
+ else
+ {
+ pATIHW->SetBank = ATIMach64SetBankPlanar;
+ }
+ }
+
+#else /* AVOID_CPIO */
+
+ {
+ pATIHW->crtc = pATI->NewHW.crtc;
+ }
+
+#endif /* AVOID_CPIO */
+
+ if (pATI->OptionShadowFB)
+ {
+ /* Until ShadowFB becomes a true screen wrapper, if it ever does... */
+
+ if (pATI->OptionAccel)
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Cannot shadow an accelerated frame buffer.\n");
+ pATI->OptionShadowFB = FALSE;
+ }
+ else
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "Using shadow frame buffer.\n");
+ }
+ }
+
+ /* 264VT-B's and later have DSP registers */
+ if ((pATI->Chip >= ATI_CHIP_264VTB) &&
+ !ATIDSPPreInit(pScreenInfo->scrnIndex, pATI))
+ goto bail;
+
+ /*
+ * Determine minClock and maxClock. For adapters with supported
+ * programmable clock generators, start with an absolute maximum.
+ */
+ if (pATI->ClockDescriptor.MaxN > 0)
+ {
+ Numerator = pATI->ClockDescriptor.MaxN * pATI->ReferenceNumerator;
+ Denominator = pATI->ClockDescriptor.MinM * pATI->ReferenceDenominator *
+ pATI->ClockDescriptor.PostDividers[0];
+
+ /*
+ * An integrated PLL behaves as though the reference frequency were
+ * doubled. It also does not appear to care about the colour depth.
+ */
+ if (pATI->ProgrammableClock == ATI_CLOCK_INTERNAL)
+ Numerator <<= 1;
+
+ ATIClockRange.maxClock = (Numerator / (Denominator * 1000)) * 1000;
+
+ Numerator = pATI->ClockDescriptor.MinN * pATI->ReferenceNumerator;
+ Denominator = pATI->ClockDescriptor.MaxM * pATI->ReferenceDenominator *
+ pATI->ClockDescriptor.PostDividers[pATI->ClockDescriptor.NumD - 1];
+
+ if (pATI->ProgrammableClock == ATI_CLOCK_INTERNAL)
+ Numerator <<= 1;
+
+ ATIClockRange.minClock = (Numerator / (Denominator * 1000)) * 1000;
+
+ if (pATI->XCLKFeedbackDivider)
+ {
+ /* Possibly reduce maxClock due to memory bandwidth */
+ Numerator = pATI->XCLKFeedbackDivider * 2 *
+ pATI->ReferenceNumerator;
+ Denominator = pATI->ClockDescriptor.MinM *
+ pATI->XCLKReferenceDivider * pATI->ReferenceDenominator;
+
+ {
+ Denominator *= pATI->bitsPerPixel / 4;
+ }
+
+ i = (6 - 2) - pATI->XCLKPostDivider;
+
+ i = (ATIDivide(Numerator, Denominator, i, -1) / 1000) * 1000;
+ if (i < ATIClockRange.maxClock)
+ ATIClockRange.maxClock = i;
+ }
+ }
+
+ /*
+ * Assume an internal DAC can handle whatever frequency the internal PLL
+ * can produce (with the reference divider set by BIOS initialisation), but
+ * default maxClock to a lower chip-specific default.
+ */
+ if ((pATI->DAC & ~0x0FU) == ATI_DAC_INTERNAL)
+ {
+ int DacSpeed;
+ switch (pATI->bitsPerPixel)
+ {
+ case 15:
+ case 16:
+ DacSpeed = pGDev->dacSpeeds[DAC_BPP16];
+ break;
+
+ case 24:
+ DacSpeed = pGDev->dacSpeeds[DAC_BPP24];
+ break;
+
+ case 32:
+ DacSpeed = pGDev->dacSpeeds[DAC_BPP32];
+ break;
+
+ default:
+ DacSpeed = 0;
+ break;
+ }
+ if (!DacSpeed)
+ DacSpeed = pGDev->dacSpeeds[DAC_BPP8];
+ if (DacSpeed < ATIClockRange.maxClock)
+ {
+ DefaultmaxClock = 135000;
+
+ if (pATI->depth > 8)
+ DefaultmaxClock = 80000;
+
+ if ((pATI->Chip >= ATI_CHIP_264VTB) &&
+ (pATI->Chip != ATI_CHIP_Mach64))
+ {
+ if ((pATI->Chip >= ATI_CHIP_264VT4) &&
+ (pATI->Chip != ATI_CHIP_264LTPRO))
+ DefaultmaxClock = 230000;
+ else if (pATI->Chip >= ATI_CHIP_264VT3)
+ DefaultmaxClock = 200000;
+ else
+ DefaultmaxClock = 170000;
+ }
+ if (DacSpeed > DefaultmaxClock)
+ ATIClockRange.maxClock = DacSpeed;
+ else if (DefaultmaxClock < ATIClockRange.maxClock)
+ ATIClockRange.maxClock = DefaultmaxClock;
+ }
+ }
+ else
+ {
+ switch(pATI->DAC)
+ {
+ case ATI_DAC_STG1700:
+ case ATI_DAC_STG1702:
+ case ATI_DAC_STG1703:
+ DefaultmaxClock = 110000;
+ break;
+
+ case ATI_DAC_IBMRGB514:
+ pATI->maxClock = 220000;
+ {
+ DefaultmaxClock = 220000;
+ }
+ break;
+
+ default:
+
+#ifndef AVOID_CPIO
+
+ if (pATI->CPIO_VGAWonder && (pATI->VideoRAM < 1024))
+ {
+ DefaultmaxClock =
+ (GetBits(BIOSByte(0x44U), 0x04U) * 5000) + 40000;
+ }
+ else
+
+#endif /* AVOID_CPIO */
+
+ {
+ DefaultmaxClock = 80000;
+ }
+
+ break;
+ }
+
+ if (DefaultmaxClock < ATIClockRange.maxClock)
+ ATIClockRange.maxClock = DefaultmaxClock;
+ }
+
+ /*
+ * Determine available pixel clock frequencies.
+ */
+
+ if ((pATI->ProgrammableClock <= ATI_CLOCK_FIXED) ||
+ (pATI->ProgrammableClock >= ATI_CLOCK_MAX))
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "Unsupported or non-programmable clock generator.\n");
+ goto bail;
+ }
+
+ ATIClockPreInit(pScreenInfo, pATI);
+ Strategy = LOOKUP_BEST_REFRESH;
+
+ /*
+ * Mode validation.
+ */
+
+ if (pATI->Chip >= ATI_CHIP_264CT)
+ {
+ minPitch = 8;
+ }
+ else
+ {
+ minPitch = 16;
+ }
+
+ pitchInc = minPitch * pATI->bitsPerPixel;
+
+ pScreenInfo->maxHValue = (MaxBits(CRTC_H_TOTAL) + 1) << 3;
+
+ if (pATI->Chip < ATI_CHIP_264VT)
+ {
+ /*
+ * ATI finally fixed accelerated doublescanning in the 264VT
+ * and later. On 88800's, the bit is documented to exist, but
+ * only doubles the vertical timings. On the 264CT and 264ET,
+ * the bit is ignored.
+ */
+ ATIClockRange.doubleScanAllowed = FALSE;
+
+ /* CRTC_H_TOTAL is one bit narrower */
+ pScreenInfo->maxHValue >>= 1;
+ }
+
+ pScreenInfo->maxVValue = MaxBits(CRTC_V_TOTAL) + 1;
+
+ maxPitch = minPitch * MaxBits(CRTC_PITCH);
+
+ if (pATI->OptionAccel)
+ {
+ /*
+ * Set engine restrictions on coordinate space. Use maxPitch for the
+ * horizontal and maxHeight for the vertical.
+ */
+ if (maxPitch > (ATIMach64MaxX / pATI->XModifier))
+ maxPitch = ATIMach64MaxX / pATI->XModifier;
+
+ maxHeight = ATIMach64MaxY;
+
+ /*
+ * For SGRAM & WRAM adapters, the display engine limits the pitch to
+ * multiples of 64 bytes.
+ */
+ if ((pATI->Chip >= ATI_CHIP_264CT) &&
+ ((pATI->Chip >= ATI_CHIP_264VTB) ||
+ (pATI->MemoryType >= MEM_264_SGRAM)))
+ pitchInc = pATI->XModifier * (64 * 8);
+ }
+
+ if (pATI->OptionPanelDisplay && (pATI->LCDPanelID >= 0))
+ {
+ /*
+ * Given LCD modes are more tightly controlled than CRT modes, allow
+ * the user the option of not specifying a panel's horizontal sync
+ * and/or vertical refresh tolerances.
+ */
+ Strategy |= LOOKUP_OPTIONAL_TOLERANCES;
+
+ if (ModeType == M_T_BUILTIN)
+ {
+ /*
+ * Add a mode to the end of the monitor's list for the panel's
+ * native resolution.
+ */
+ pMode = (DisplayModePtr)xnfcalloc(1, SizeOf(DisplayModeRec));
+ pMode->name = "Native panel mode";
+ pMode->type = M_T_BUILTIN;
+ pMode->Clock = pATI->LCDClock;
+ pMode->HDisplay = pATI->LCDHorizontal;
+ pMode->VDisplay = pATI->LCDVertical;
+
+ /*
+ * These timings are bogus, but enough to survive sync tolerance
+ * checks.
+ */
+ pMode->HSyncStart = pMode->HDisplay;
+ pMode->HSyncEnd = pMode->HSyncStart + minPitch;
+ pMode->HTotal = pMode->HSyncEnd + minPitch;
+ pMode->VSyncStart = pMode->VDisplay;
+ pMode->VSyncEnd = pMode->VSyncStart + 1;
+ pMode->VTotal = pMode->VSyncEnd + 1;
+
+ pMode->CrtcHDisplay = pMode->HDisplay;
+ pMode->CrtcHBlankStart = pMode->HDisplay;
+ pMode->CrtcHSyncStart = pMode->HSyncStart;
+ pMode->CrtcHSyncEnd = pMode->HSyncEnd;
+ pMode->CrtcHBlankEnd = pMode->HTotal;
+ pMode->CrtcHTotal = pMode->HTotal;
+
+ pMode->CrtcVDisplay = pMode->VDisplay;
+ pMode->CrtcVBlankStart = pMode->VDisplay;
+ pMode->CrtcVSyncStart = pMode->VSyncStart;
+ pMode->CrtcVSyncEnd = pMode->VSyncEnd;
+ pMode->CrtcVBlankEnd = pMode->VTotal;
+ pMode->CrtcVTotal = pMode->VTotal;
+
+ if (!pScreenInfo->monitor->Modes)
+ {
+ pScreenInfo->monitor->Modes = pMode;
+ }
+ else
+ {
+ pScreenInfo->monitor->Last->next = pMode;
+ pMode->prev = pScreenInfo->monitor->Last;
+ }
+
+ pScreenInfo->monitor->Last = pMode;
+ }
+
+ /*
+ * Defeat Xconfigurator brain damage. Ignore all HorizSync and
+ * VertRefresh specifications. For now, this does not take
+ * SYNC_TOLERANCE into account.
+ */
+ if (pScreenInfo->monitor->nHsync > 0)
+ {
+ double hsync = (double)pATI->LCDClock /
+ (pATI->LCDHorizontal + pATI->LCDHBlankWidth);
+
+ for (i = 0; ; i++)
+ {
+ if (i >= pScreenInfo->monitor->nHsync)
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_NOTICE,
+ "Conflicting XF86Config HorizSync specification(s)"
+ " ignored.\n");
+ break;
+ }
+
+ if ((hsync >= pScreenInfo->monitor->hsync[i].lo) &&
+ (hsync <= pScreenInfo->monitor->hsync[i].hi))
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Extraneous XF86Config HorizSync specification(s)"
+ " ignored.\n");
+ break;
+ }
+ }
+
+ pScreenInfo->monitor->nHsync = 0;
+ }
+
+ if (pScreenInfo->monitor->nVrefresh > 0)
+ {
+ double vrefresh = ((double)pATI->LCDClock * 1000.0) /
+ ((pATI->LCDHorizontal + pATI->LCDHBlankWidth) *
+ (pATI->LCDVertical + pATI->LCDVBlankWidth));
+
+ for (i = 0; ; i++)
+ {
+ if (i >= pScreenInfo->monitor->nVrefresh)
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_NOTICE,
+ "Conflicting XF86Config VertRefresh specification(s)"
+ " ignored.\n");
+ break;
+ }
+
+ if ((vrefresh >= pScreenInfo->monitor->vrefresh[i].lo) &&
+ (vrefresh <= pScreenInfo->monitor->vrefresh[i].hi))
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Extraneous XF86Config VertRefresh specification(s)"
+ " ignored.\n");
+ break;
+ }
+ }
+
+ pScreenInfo->monitor->nVrefresh = 0;
+ }
+ }
+
+ i = xf86ValidateModes(pScreenInfo,
+ pScreenInfo->monitor->Modes, pScreenInfo->display->modes,
+ &ATIClockRange, NULL, minPitch, maxPitch,
+ pitchInc, 0, maxHeight,
+ pScreenInfo->display->virtualX, pScreenInfo->display->virtualY,
+ ApertureSize, Strategy);
+ if (i <= 0)
+ goto bail;
+
+ /* Remove invalid modes */
+ xf86PruneDriverModes(pScreenInfo);
+
+ /* Set current mode to the first in the list */
+ pScreenInfo->currentMode = pScreenInfo->modes;
+
+ /* Print mode list */
+ xf86PrintModes(pScreenInfo);
+
+ /* Set display resolution */
+ xf86SetDpi(pScreenInfo, 0, 0);
+
+ /* Load required modules */
+ if (!ATILoadModules(pScreenInfo, pATI))
+ goto bail;
+
+ pATI->displayWidth = pScreenInfo->displayWidth;
+
+ /* Initialise for panning */
+ ATIAdjustPreInit(pATI);
+
+ /*
+ * Warn about modes that are too small, or not aligned, to scroll to the
+ * bottom right corner of the virtual screen.
+ */
+ MinX = pScreenInfo->virtualX - pATI->AdjustMaxX;
+ MinY = pScreenInfo->virtualY - pATI->AdjustMaxY;
+
+ pMode = pScreenInfo->modes;
+ do
+ {
+ if ((pMode->VDisplay <= MinY) &&
+ ((pMode->VDisplay < MinY) || (pMode->HDisplay < MinX)))
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Mode \"%s\" too small to scroll to bottom right corner of"
+ " virtual resolution.\n", pMode->name);
+ else if ((pMode->HDisplay & ~pATI->AdjustMask) / pScreenInfo->xInc)
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Mode \"%s\" cannot scroll to bottom right corner of virtual"
+ " resolution.\n Horizontal dimension not a multiple of %ld.\n",
+ pMode->name, ~pATI->AdjustMask + 1);
+ } 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 = "mach64";
+
+ PreInitSuccess = TRUE;
+
+bail:
+ ATILock(pATI);
+
+bail_locked:
+ ATIPrintNoiseIfRequested(pATI, BIOS, BIOSSize);
+ ATIUnmapApertures(pScreenInfo->scrnIndex, pATI);
+
+ return PreInitSuccess;
+}
diff --git a/driver/xf86-video-mach64/src/atipreinit.h b/driver/xf86-video-mach64/src/atipreinit.h
new file mode 100644
index 000000000..cd150c7cc
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atipreinit.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 1999 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 "xf86str.h"
+
+extern Bool ATIPreInit(ScrnInfoPtr, int);
+
+#endif /* ___ATIPREINIT_H___ */
diff --git a/driver/xf86-video-mach64/src/atiprint.c b/driver/xf86-video-mach64/src/atiprint.c
new file mode 100644
index 000000000..3a1debb40
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atiprint.c
@@ -0,0 +1,784 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <ctype.h>
+#include <stdint.h>
+
+#include "ati.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
+)
+{
+ 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;
+
+ crtc = ATI_CRTC_VGA;
+
+ if (pATI->VGAAdapter)
+ {
+ 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, 0x80U, 0xC0U,
+ "ATI extended VGA", 0);
+ }
+
+#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
+ {
+
+#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);
+
+ 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;
+
+#endif /* AVOID_CPIO */
+
+ {
+ xf86ErrorFVerb(4, "\n\n PCI configuration register values:");
+ for (Index = 0; Index < 256; Index+= 4)
+ {
+ pciVideoPtr pVideo = pATI->PCIInfo;
+ uint32_t data;
+
+ PCI_READ_LONG(pVideo, &data, Index);
+
+ if (!(Index & 15))
+ xf86ErrorFVerb(4, "\n 0x%02X: ", Index);
+ xf86ErrorFVerb(4, " 0x%08X", data);
+ }
+ }
+
+ 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.");
+
+#endif /* AVOID_CPIO */
+
+ if (pATI->pMemory)
+ {
+ 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");
+}
diff --git a/driver/xf86-video-mach64/src/atiprint.h b/driver/xf86-video-mach64/src/atiprint.h
new file mode 100644
index 000000000..0a5a3ce5e
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atiprint.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 "xf86str.h"
+
+extern void ATIPrintBIOS(const CARD8 *, const unsigned int);
+extern void ATIPrintRegisters(ATIPtr);
+extern void ATIPrintMode(DisplayModePtr);
+
+#endif /* ___ATIPRINT_H___ */
diff --git a/driver/xf86-video-mach64/src/atipriv.h b/driver/xf86-video-mach64/src/atipriv.h
new file mode 100644
index 000000000..4a83af171
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atipriv.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 1999 through 2003 by Marc Aurele La France (TSI @ UQV), tsi@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___ */
diff --git a/driver/xf86-video-mach64/src/atiprobe.c b/driver/xf86-video-mach64/src/atiprobe.c
new file mode 100644
index 000000000..50920737a
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atiprobe.c
@@ -0,0 +1,475 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <stdio.h>
+#include <stdint.h>
+
+#include "ati.h"
+#include "atibus.h"
+#include "atichip.h"
+#include "atimach64io.h"
+#include "atimach64version.h"
+#include "atiprobe.h"
+#include "atividmem.h"
+#include "atiwonderio.h"
+
+#ifndef AVOID_CPIO
+
+/*
+ * ATIVGAWonderProbe --
+ *
+ * This function determines if ATI extended VGA registers can be accessed
+ * through the I/O port specified by pATI->CPIO_VGAWonder. If not, the
+ * function resets pATI->CPIO_VGAWonder to zero.
+ */
+static void
+ATIVGAWonderProbe
+(
+ pciVideoPtr pVideo,
+ ATIPtr pATI
+)
+{
+ CARD8 IOValue1, IOValue2, IOValue3, IOValue4, IOValue5, IOValue6;
+
+ if (!pATI->OptionProbeSparse)
+ {
+ xf86Msg(X_WARNING,
+ MACH64_NAME ": Expected VGA Wonder capability at I/O port"
+ " 0x%04lX will not be probed\n"
+ "set option \"probe_sparse\" to force probing.\n",
+ pATI->CPIO_VGAWonder);
+
+ pATI->CPIO_VGAWonder = 0;
+ return;
+ }
+
+ if (pVideo && !xf86IsPrimaryPci(pVideo) &&
+ (pATI->Chip <= ATI_CHIP_88800GXD))
+ {
+ /* Set up extended VGA register addressing */
+ PutReg(GRAX, 0x50U, GetByte(pATI->CPIO_VGAWonder, 0));
+ PutReg(GRAX, 0x51U, GetByte(pATI->CPIO_VGAWonder, 1) | 0x80U);
+ }
+ /*
+ * Register 0xBB is used by the BIOS to keep track of various
+ * things (monitor type, etc.). Except for 18800-x's, register
+ * 0xBC must be zero and causes the adapter to enter a test mode
+ * when written to with a non-zero value.
+ */
+ IOValue1 = inb(pATI->CPIO_VGAWonder);
+ IOValue2 = ATIGetExtReg(IOValue1);
+ IOValue3 = ATIGetExtReg(0xBBU);
+ ATIPutExtReg(0xBBU, IOValue3 ^ 0xAAU);
+ IOValue4 = ATIGetExtReg(0xBBU);
+ ATIPutExtReg(0xBBU, IOValue3 ^ 0x55U);
+ IOValue5 = ATIGetExtReg(0xBBU);
+ ATIPutExtReg(0xBBU, IOValue3);
+ IOValue6 = ATIGetExtReg(0xBCU);
+ ATIPutExtReg(IOValue1, IOValue2);
+
+ if ((IOValue4 == (IOValue3 ^ 0xAAU)) &&
+ (IOValue5 == (IOValue3 ^ 0x55U)) &&
+ (IOValue6 == 0))
+ {
+ xf86MsgVerb(X_INFO, 3,
+ MACH64_NAME ": VGA Wonder at I/O port 0x%04lX detected.\n",
+ pATI->CPIO_VGAWonder);
+ }
+ else
+ {
+ xf86Msg(X_WARNING,
+ MACH64_NAME ": Expected VGA Wonder capability at I/O port"
+ " 0x%04lX was not detected.\n", pATI->CPIO_VGAWonder);
+ pATI->CPIO_VGAWonder = 0;
+ }
+}
+
+#endif /* AVOID_CPIO */
+
+/*
+ * ATIMach64Detect --
+ *
+ * This function determines if a Mach64 is detectable at a particular base
+ * address.
+ */
+static Bool
+ATIMach64Detect
+(
+ ATIPtr pATI,
+ const CARD16 ChipType,
+ const ATIChipType Chip
+)
+{
+ CARD32 IOValue, bus_cntl, gen_test_cntl;
+ Bool DetectSuccess = FALSE;
+
+ (void)ATIMapApertures(-1, pATI); /* Ignore errors */
+
+#ifdef AVOID_CPIO
+
+ if (!pATI->pBlock[0])
+ {
+ ATIUnmapApertures(-1, pATI);
+ return FALSE;
+ }
+
+#endif /* AVOID_CPIO */
+
+ /* Make sure any Mach64 is not in some weird state */
+ bus_cntl = inr(BUS_CNTL);
+ if (Chip < ATI_CHIP_264VTB)
+ outr(BUS_CNTL,
+ (bus_cntl & ~(BUS_HOST_ERR_INT_EN | BUS_FIFO_ERR_INT_EN)) |
+ (BUS_HOST_ERR_INT | BUS_FIFO_ERR_INT));
+ else if (Chip < ATI_CHIP_264VT4)
+ outr(BUS_CNTL, (bus_cntl & ~BUS_HOST_ERR_INT_EN) | BUS_HOST_ERR_INT);
+
+ gen_test_cntl = inr(GEN_TEST_CNTL);
+ IOValue = gen_test_cntl &
+ (GEN_OVR_OUTPUT_EN | GEN_OVR_POLARITY | GEN_CUR_EN | GEN_BLOCK_WR_EN);
+ outr(GEN_TEST_CNTL, IOValue | GEN_GUI_EN);
+ outr(GEN_TEST_CNTL, IOValue);
+ outr(GEN_TEST_CNTL, IOValue | GEN_GUI_EN);
+
+ /* See if a Mach64 answers */
+ IOValue = inr(SCRATCH_REG0);
+
+ /* Test odd bits */
+ outr(SCRATCH_REG0, 0x55555555U);
+ if (inr(SCRATCH_REG0) == 0x55555555U)
+ {
+ /* Test even bits */
+ outr(SCRATCH_REG0, 0xAAAAAAAAU);
+ if (inr(SCRATCH_REG0) == 0xAAAAAAAAU)
+ {
+ /*
+ * *Something* has a R/W 32-bit register at this address. Try to
+ * make sure it's a Mach64. The following assumes that ATI will
+ * not be producing any more adapters that do not register
+ * themselves in PCI configuration space.
+ */
+ ATIMach64ChipID(pATI, ChipType);
+ if ((pATI->Chip != ATI_CHIP_Mach64) ||
+ (pATI->CPIODecoding == BLOCK_IO))
+ DetectSuccess = TRUE;
+ }
+ }
+
+ /* Restore clobbered register value */
+ outr(SCRATCH_REG0, IOValue);
+
+ /* If no Mach64 was detected, return now */
+ if (!DetectSuccess)
+ {
+ outr(GEN_TEST_CNTL, gen_test_cntl);
+ outr(BUS_CNTL, bus_cntl);
+ ATIUnmapApertures(-1, pATI);
+ return FALSE;
+ }
+
+ ATIUnmapApertures(-1, pATI);
+ return TRUE;
+}
+
+#ifdef AVOID_CPIO
+
+/*
+ * ATIMach64Probe --
+ *
+ * This function looks for a Mach64 at a particular MMIO address and returns an
+ * ATIRec if one is found.
+ */
+static ATIPtr
+ATIMach64Probe
+(
+ ATIPtr pATI,
+ pciVideoPtr pVideo,
+ const ATIChipType Chip
+)
+{
+ CARD16 ChipType = PCI_DEV_DEVICE_ID(pVideo);
+
+ pATI->MMIOInLinear = FALSE;
+
+ /*
+ * Probe through auxiliary MMIO aperture if one exists. Because such
+ * apertures can be enabled/disabled only through PCI, this probes no
+ * further.
+ */
+ if ((PCI_REGION_SIZE(pVideo, 2) >= (1 << 12)) &&
+ (pATI->Block0Base = PCI_REGION_BASE(pVideo, 2, REGION_MEM)))
+ {
+ pATI->Block0Base += 0x00000400U;
+ if (ATIMach64Detect(pATI, ChipType, Chip))
+ return pATI;
+
+ return NULL;
+ }
+
+ /*
+ * Probe through the primary MMIO aperture that exists at the tail end
+ * of the linear aperture. Test for both 8MB and 4MB linear apertures.
+ */
+ if ((PCI_REGION_SIZE(pVideo, 0) >= (1 << 22)) &&
+ (pATI->Block0Base = PCI_REGION_BASE(pVideo, 0, REGION_MEM)))
+ {
+ pATI->MMIOInLinear = TRUE;
+
+ pATI->Block0Base += 0x007FFC00U;
+ if ((PCI_REGION_SIZE(pVideo, 0) >= (1 << 23)) &&
+ ATIMach64Detect(pATI, ChipType, Chip))
+ return pATI;
+
+ pATI->Block0Base -= 0x00400000U;
+ if (ATIMach64Detect(pATI, ChipType, Chip))
+ return pATI;
+ }
+
+ return NULL;
+}
+
+#else /* AVOID_CPIO */
+
+/*
+ * ATIMach64Probe --
+ *
+ * This function looks for a Mach64 at a particular PIO address and returns an
+ * ATIRec if one is found.
+ */
+static ATIPtr
+ATIMach64Probe
+(
+ ATIPtr pATI,
+ pciVideoPtr pVideo,
+ const ATIChipType Chip
+)
+{
+ CARD32 IOValue;
+ CARD16 ChipType = PCI_DEV_DEVICE_ID(pVideo);
+
+ if ((pATI->CPIODecoding == BLOCK_IO) &&
+ (PCI_REGION_SIZE(pVideo, 1) < (1 << 8)))
+ return NULL;
+
+ if (!ATIMach64Detect(pATI, ChipType, Chip))
+ {
+ return NULL;
+ }
+
+ /*
+ * Determine VGA capability. VGA can always be enabled on integrated
+ * controllers. For the GX/CX, it's a board strap.
+ */
+ if (pATI->Chip >= ATI_CHIP_264CT)
+ {
+ pATI->VGAAdapter = TRUE;
+ }
+ else
+ {
+ IOValue = inr(CONFIG_STATUS64_0);
+ pATI->BusType = GetBits(IOValue, CFG_BUS_TYPE);
+ IOValue &= (CFG_VGA_EN | CFG_CHIP_EN);
+ if (pATI->Chip == ATI_CHIP_88800CX)
+ IOValue |= CFG_VGA_EN;
+ if (IOValue == (CFG_VGA_EN | CFG_CHIP_EN))
+ {
+ pATI->VGAAdapter = TRUE;
+ pATI->CPIO_VGAWonder = 0x01CEU;
+ }
+ }
+
+ return pATI;
+}
+
+static void
+ATIAssignVGA
+(
+ pciVideoPtr pVideo,
+ ATIPtr pATI
+)
+{
+ if (pATI->CPIO_VGAWonder)
+ {
+ ATIVGAWonderProbe(pVideo, pATI);
+ if (!pATI->CPIO_VGAWonder)
+ {
+ /*
+ * Some adapters are reputed to append ATI extended VGA registers
+ * to the VGA Graphics controller registers. In particular, 0x01CE
+ * cannot, in general, be used in a PCI environment due to routing
+ * of I/O through the bus tree.
+ */
+ pATI->CPIO_VGAWonder = GRAX;
+ ATIVGAWonderProbe(pVideo, pATI);
+ }
+ }
+}
+
+/*
+ * ATIFindVGA --
+ *
+ * This function determines if a VGA associated with an ATI PCI adapter is
+ * shareable.
+ */
+static void
+ATIFindVGA
+(
+ pciVideoPtr pVideo,
+ ATIPtr pATI
+)
+{
+ /*
+ * An ATI PCI adapter has been detected at this point, and its VGA, if
+ * any, is shareable. Ensure the VGA isn't in sleep mode.
+ */
+ outb(GENENA, 0x16U);
+ outb(GENVS, 0x01U);
+ outb(GENENA, 0x0EU);
+
+ ATIAssignVGA(pVideo, pATI);
+}
+
+#endif /* AVOID_CPIO */
+
+/*
+ * ATIMach64ProbeIO --
+ *
+ * This function determines the IO method and IO base of the ATI PCI adapter.
+ */
+Bool
+ATIMach64ProbeIO
+(
+ pciVideoPtr pVideo,
+ ATIPtr pATI
+)
+{
+ /* Next, look for sparse I/O Mach64's */
+ if (!PCI_REGION_SIZE(pVideo, 1))
+ {
+
+#ifndef AVOID_CPIO
+
+ static const IOADDRESS Mach64SparseIOBases[] = {
+ 0x02ECU,
+ 0x01CCU,
+ 0x01C8U
+ };
+ uint32_t PciReg;
+ uint32_t j;
+
+#ifndef XSERVER_LIBPCIACCESS
+ pciConfigPtr pPCI = pVideo->thisCard;
+
+ if (pPCI == NULL)
+ return FALSE;
+#endif
+
+ PCI_READ_LONG(pVideo, &PciReg, PCI_REG_USERCONFIG);
+ j = PciReg & 0x03U;
+
+ if (j == 0x03U)
+ {
+ xf86Msg(X_WARNING, MACH64_NAME ": "
+ "PCI Mach64 in slot %d:%d:%d cannot be enabled\n"
+ "because it has neither a block, nor a sparse, I/O base.\n",
+ PCI_DEV_BUS(pVideo), PCI_DEV_DEV(pVideo), PCI_DEV_FUNC(pVideo));
+
+ return FALSE;
+ }
+
+ /* Possibly fix block I/O indicator */
+ if (PciReg & 0x00000004U)
+ {
+ PciReg &= ~0x00000004U;
+ PCI_WRITE_LONG(pVideo, PciReg, PCI_REG_USERCONFIG);
+ }
+
+ /* FIXME:
+ * Should not probe at sparse I/O bases which have been registered to
+ * other PCI devices. The old ATIProbe() would scan the PCI space and
+ * build a list of registered I/O ports. If there was a conflict
+ * between a mach64 sparse I/O base and a registered I/0 port, probing
+ * that port was not allowed...
+ *
+ * We just add an option and let the user decide, this will not work
+ * with "X -configure" though...
+ */
+ if (!pATI->OptionProbeSparse)
+ {
+ xf86Msg(X_WARNING, MACH64_NAME ": "
+ "PCI Mach64 in slot %d:%d:%d will not be probed\n"
+ "set option \"probe_sparse\" to force sparse I/O probing.\n",
+ PCI_DEV_BUS(pVideo), PCI_DEV_DEV(pVideo), PCI_DEV_FUNC(pVideo));
+
+ return FALSE;
+ }
+
+ pATI->CPIOBase = Mach64SparseIOBases[j];
+ pATI->CPIODecoding = SPARSE_IO;
+ pATI->PCIInfo = pVideo;
+
+#else /* AVOID_CPIO */
+
+ /* The adapter's CPIO base is of little concern here */
+ pATI->CPIOBase = 0;
+ pATI->CPIODecoding = SPARSE_IO;
+ pATI->PCIInfo = pVideo;
+
+#endif /* AVOID_CPIO */
+
+ }
+
+ /* Lastly, look for block I/O devices */
+ if (PCI_REGION_SIZE(pVideo, 1))
+ {
+ pATI->CPIOBase = PCI_REGION_BASE(pVideo, 1, REGION_IO);
+ pATI->CPIODecoding = BLOCK_IO;
+ pATI->PCIInfo = pVideo;
+ }
+
+ if (!ATIMach64Probe(pATI, pVideo, pATI->Chip))
+ {
+ xf86Msg(X_WARNING, MACH64_NAME ": "
+ "Mach64 in slot %d:%d:%d could not be detected!\n",
+ PCI_DEV_BUS(pVideo), PCI_DEV_DEV(pVideo), PCI_DEV_FUNC(pVideo));
+
+ return FALSE;
+ }
+
+ xf86Msg(X_INFO, MACH64_NAME ": "
+ "Mach64 in slot %d:%d:%d detected.\n",
+ PCI_DEV_BUS(pVideo), PCI_DEV_DEV(pVideo), PCI_DEV_FUNC(pVideo));
+
+#ifndef AVOID_CPIO
+
+ if (pATI->VGAAdapter)
+ ATIFindVGA(pVideo, pATI);
+
+#endif /* AVOID_CPIO */
+
+ return TRUE;
+}
diff --git a/driver/xf86-video-mach64/src/atiprobe.h b/driver/xf86-video-mach64/src/atiprobe.h
new file mode 100644
index 000000000..6195eb431
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atiprobe.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 "xf86str.h"
+
+extern Bool ATIMach64ProbeIO(pciVideoPtr, ATIPtr);
+
+#endif /* ___ATIPROBE_H___ */
diff --git a/driver/xf86-video-mach64/src/atiregs.h b/driver/xf86-video-mach64/src/atiregs.h
new file mode 100644
index 000000000..8ab834057
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atiregs.h
@@ -0,0 +1,2882 @@
+/*
+ * Copyright 1994 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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.
+ *
+ * Acknowledgements:
+ * Jake Richter, Panacea Inc., Londonderry, New Hampshire, U.S.A.
+ * Kevin E. Martin, martin@cs.unc.edu
+ * Tiago Gons, tiago@comosjn.hobby.nl
+ * Rickard E. Faith, faith@cs.unc.edu
+ * Scott Laird, lair@kimbark.uchicago.edu
+ *
+ * The intent here is to list all I/O ports for VGA (and its predecessors),
+ * ATI VGA Wonder, 8514/A, ATI Mach8, ATI Mach32 and ATI Mach64 video adapters,
+ * not just the ones in use by the ATI driver.
+ */
+
+#ifndef ___ATIREGS_H___
+#define ___ATIREGS_H___ 1
+
+#include "atiutil.h"
+
+/* I/O decoding definitions */
+#define SPARSE_IO_BASE 0x03fcu
+#define SPARSE_IO_SELECT 0xfc00u
+
+#define BLOCK_IO_BASE 0xff00u
+#define BLOCK_IO_SELECT 0x00fcu
+
+#define MM_IO_SELECT 0x03fcu
+#define BLOCK_SELECT 0x0400u
+#define DWORD_SELECT (BLOCK_SELECT | MM_IO_SELECT)
+
+#define IO_BYTE_SELECT 0x0003u
+
+#define SPARSE_IO_PORT (SPARSE_IO_BASE | IO_BYTE_SELECT)
+#define BLOCK_IO_PORT (BLOCK_IO_BASE | IO_BYTE_SELECT)
+
+#define IOPortTag(_SparseIOSelect, _BlockIOSelect) \
+ (SetBits(_SparseIOSelect, SPARSE_IO_SELECT) | \
+ SetBits(_BlockIOSelect, DWORD_SELECT))
+#define SparseIOTag(_IOSelect) IOPortTag(_IOSelect, 0)
+#define BlockIOTag(_IOSelect) IOPortTag(0, _IOSelect)
+
+/* MDA/[M]CGA/EGA/VGA I/O ports */
+#define GENVS 0x0102u /* Write (and Read on uC only) */
+
+#define R_GENLPS 0x03b9u /* Read */
+
+#define GENHP 0x03bfu
+
+#define ATTRX 0x03c0u
+#define ATTRD 0x03c1u
+#define GENS0 0x03c2u /* Read */
+#define GENMO 0x03c2u /* Write */
+#define GENENB 0x03c3u /* Read */
+#define SEQX 0x03c4u
+#define SEQD 0x03c5u
+#define VGA_DAC_MASK 0x03c6u
+#define VGA_DAC_READ 0x03c7u
+#define VGA_DAC_WRITE 0x03c8u
+#define VGA_DAC_DATA 0x03c9u
+#define R_GENFC 0x03cau /* Read */
+/* ? 0x03cbu */
+#define R_GENMO 0x03ccu /* Read */
+/* ? 0x03cdu */
+#define GRAX 0x03ceu
+#define GRAD 0x03cfu
+
+#define GENB 0x03d9u
+
+#define GENLPS 0x03dcu /* Write */
+#define KCX 0x03ddu
+#define KCD 0x03deu
+
+#define GENENA 0x46e8u /* Write */
+
+/* I/O port base numbers */
+#define MonochromeIOBase 0x03b0u
+#define ColourIOBase 0x03d0u
+
+/* Other MDA/[M]CGA/EGA/VGA I/O ports */
+/* ?(_IOBase) ((_IOBase) + 0x00u) */ /* CRTX synonym */
+/* ?(_IOBase) ((_IOBase) + 0x01u) */ /* CRTD synonym */
+/* ?(_IOBase) ((_IOBase) + 0x02u) */ /* CRTX synonym */
+/* ?(_IOBase) ((_IOBase) + 0x03u) */ /* CRTD synonym */
+#define CRTX(_IOBase) ((_IOBase) + 0x04u)
+#define CRTD(_IOBase) ((_IOBase) + 0x05u)
+/* ?(_IOBase) ((_IOBase) + 0x06u) */
+/* ?(_IOBase) ((_IOBase) + 0x07u) */
+#define GENMC(_IOBase) ((_IOBase) + 0x08u)
+/* ?(_IOBase) ((_IOBase) + 0x09u) */ /* R_GENLPS/GENB */
+#define GENS1(_IOBase) ((_IOBase) + 0x0au) /* Read */
+#define GENFC(_IOBase) ((_IOBase) + 0x0au) /* Write */
+#define GENLPC(_IOBase) ((_IOBase) + 0x0bu)
+/* ?(_IOBase) ((_IOBase) + 0x0cu) */ /* /GENLPS */
+/* ?(_IOBase) ((_IOBase) + 0x0du) */ /* /KCX */
+/* ?(_IOBase) ((_IOBase) + 0x0eu) */ /* /KCD */
+/* ?(_IOBase) ((_IOBase) + 0x0fu) */ /* GENHP/ */
+
+/* 8514/A VESA approved register definitions */
+#define DISP_STAT 0x02e8u /* Read */
+#define SENSE 0x0001u /* Presumably belong here */
+#define VBLANK 0x0002u
+#define HORTOG 0x0004u
+#define H_TOTAL 0x02e8u /* Write */
+#define IBM_DAC_MASK 0x02eau
+#define IBM_DAC_READ 0x02ebu
+#define IBM_DAC_WRITE 0x02ecu
+#define IBM_DAC_DATA 0x02edu
+#define H_DISP 0x06e8u /* Write */
+#define H_SYNC_STRT 0x0ae8u /* Write */
+#define H_SYNC_WID 0x0ee8u /* Write */
+#define HSYNCPOL_POS 0x0000u
+#define HSYNCPOL_NEG 0x0020u
+#define H_POLARITY_POS HSYNCPOL_POS /* Sigh */
+#define H_POLARITY_NEG HSYNCPOL_NEG /* Sigh */
+#define V_TOTAL 0x12e8u /* Write */
+#define V_DISP 0x16e8u /* Write */
+#define V_SYNC_STRT 0x1ae8u /* Write */
+#define V_SYNC_WID 0x1ee8u /* Write */
+#define VSYNCPOL_POS 0x0000u
+#define VSYNCPOL_NEG 0x0020u
+#define V_POLARITY_POS VSYNCPOL_POS /* Sigh */
+#define V_POLARITY_NEG VSYNCPOL_NEG /* Sigh */
+#define DISP_CNTL 0x22e8u /* Write */
+#define ODDBNKENAB 0x0001u
+#define MEMCFG_2 0x0000u
+#define MEMCFG_4 0x0002u
+#define MEMCFG_6 0x0004u
+#define MEMCFG_8 0x0006u
+#define DBLSCAN 0x0008u
+#define INTERLACE 0x0010u
+#define DISPEN_NC 0x0000u
+#define DISPEN_ENAB 0x0020u
+#define DISPEN_DISAB 0x0040u
+#define R_H_TOTAL 0x26e8u /* Read */
+/* ? 0x2ae8u */
+/* ? 0x2ee8u */
+/* ? 0x32e8u */
+/* ? 0x36e8u */
+/* ? 0x3ae8u */
+/* ? 0x3ee8u */
+#define SUBSYS_STAT 0x42e8u /* Read */
+#define VBLNKFLG 0x0001u
+#define PICKFLAG 0x0002u
+#define INVALIDIO 0x0004u
+#define GPIDLE 0x0008u
+#define MONITORID_MASK 0x0070u
+/* MONITORID_? 0x0000u */
+#define MONITORID_8507 0x0010u
+#define MONITORID_8514 0x0020u
+/* MONITORID_? 0x0030u */
+/* MONITORID_? 0x0040u */
+#define MONITORID_8503 0x0050u
+#define MONITORID_8512 0x0060u
+#define MONITORID_8513 0x0060u
+#define MONITORID_NONE 0x0070u
+#define _8PLANE 0x0080u
+#define SUBSYS_CNTL 0x42e8u /* Write */
+#define RVBLNKFLG 0x0001u
+#define RPICKFLAG 0x0002u
+#define RINVALIDIO 0x0004u
+#define RGPIDLE 0x0008u
+#define IVBLNKFLG 0x0100u
+#define IPICKFLAG 0x0200u
+#define IINVALIDIO 0x0400u
+#define IGPIDLE 0x0800u
+#define CHPTEST_NC 0x0000u
+#define CHPTEST_NORMAL 0x1000u
+#define CHPTEST_ENAB 0x2000u
+#define GPCTRL_NC 0x0000u
+#define GPCTRL_ENAB 0x4000u
+#define GPCTRL_RESET 0x8000u
+#define ROM_PAGE_SEL 0x46e8u /* Write */
+#define ADVFUNC_CNTL 0x4ae8u /* Write */
+#define DISABPASSTHRU 0x0001u
+#define CLOKSEL 0x0004u
+/* ? 0x4ee8u */
+#define EXT_CONFIG_0 0x52e8u /* C & T 82C480 */
+#define EXT_CONFIG_1 0x56e8u /* C & T 82C480 */
+#define EXT_CONFIG_2 0x5ae8u /* C & T 82C480 */
+#define EXT_CONFIG_3 0x5ee8u /* C & T 82C480 */
+/* ? 0x62e8u */
+/* ? 0x66e8u */
+/* ? 0x6ae8u */
+/* ? 0x6ee8u */
+/* ? 0x72e8u */
+/* ? 0x76e8u */
+/* ? 0x7ae8u */
+/* ? 0x7ee8u */
+#define CUR_Y 0x82e8u
+#define CUR_X 0x86e8u
+#define DESTY_AXSTP 0x8ae8u /* Write */
+#define DESTX_DIASTP 0x8ee8u /* Write */
+#define ERR_TERM 0x92e8u
+#define MAJ_AXIS_PCNT 0x96e8u /* Write */
+#define GP_STAT 0x9ae8u /* Read */
+#define GE_STAT 0x9ae8u /* Alias */
+#define DATARDY 0x0100u
+#define DATA_READY DATARDY /* Alias */
+#define GPBUSY 0x0200u
+#define CMD 0x9ae8u /* Write */
+#define WRTDATA 0x0001u
+#define PLANAR 0x0002u
+#define LASTPIX 0x0004u
+#define LINETYPE 0x0008u
+#define DRAW 0x0010u
+#define INC_X 0x0020u
+#define YMAJAXIS 0x0040u
+#define INC_Y 0x0080u
+#define PCDATA 0x0100u
+#define _16BIT 0x0200u
+#define CMD_NOP 0x0000u
+#define CMD_OP_MSK 0xf000u
+#define BYTSEQ 0x1000u
+#define CMD_LINE 0x2000u
+#define CMD_RECT 0x4000u
+#define CMD_RECTV1 0x6000u
+#define CMD_RECTV2 0x8000u
+#define CMD_LINEAF 0xa000u
+#define CMD_BITBLT 0xc000u
+#define SHORT_STROKE 0x9ee8u /* Write */
+#define SSVDRAW 0x0010u
+#define VECDIR_000 0x0000u
+#define VECDIR_045 0x0020u
+#define VECDIR_090 0x0040u
+#define VECDIR_135 0x0060u
+#define VECDIR_180 0x0080u
+#define VECDIR_225 0x00a0u
+#define VECDIR_270 0x00c0u
+#define VECDIR_315 0x00e0u
+#define BKGD_COLOR 0xa2e8u /* Write */
+#define FRGD_COLOR 0xa6e8u /* Write */
+#define WRT_MASK 0xaae8u /* Write */
+#define RD_MASK 0xaee8u /* Write */
+#define COLOR_CMP 0xb2e8u /* Write */
+#define BKGD_MIX 0xb6e8u /* Write */
+/* 0x001fu See MIX_* definitions below */
+#define BSS_BKGDCOL 0x0000u
+#define BSS_FRGDCOL 0x0020u
+#define BSS_PCDATA 0x0040u
+#define BSS_BITBLT 0x0060u
+#define FRGD_MIX 0xbae8u /* Write */
+/* 0x001fu See MIX_* definitions below */
+#define FSS_BKGDCOL 0x0000u
+#define FSS_FRGDCOL 0x0020u
+#define FSS_PCDATA 0x0040u
+#define FSS_BITBLT 0x0060u
+#define MULTIFUNC_CNTL 0xbee8u /* Write */
+#define MIN_AXIS_PCNT 0x0000u
+#define SCISSORS_T 0x1000u
+#define SCISSORS_L 0x2000u
+#define SCISSORS_B 0x3000u
+#define SCISSORS_R 0x4000u
+#define M32_MEM_CNTL 0x5000u
+#define HORCFG_4 0x0000u
+#define HORCFG_5 0x0001u
+#define HORCFG_8 0x0002u
+#define HORCFG_10 0x0003u
+#define VRTCFG_2 0x0000u
+#define VRTCFG_4 0x0004u
+#define VRTCFG_6 0x0008u
+#define VRTCFG_8 0x000cu
+#define BUFSWP 0x0010u
+#define PATTERN_L 0x8000u
+#define PATTERN_H 0x9000u
+#define PIX_CNTL 0xa000u
+#define PLANEMODE 0x0004u
+#define COLCMPOP_F 0x0000u
+#define COLCMPOP_T 0x0008u
+#define COLCMPOP_GE 0x0010u
+#define COLCMPOP_LT 0x0018u
+#define COLCMPOP_NE 0x0020u
+#define COLCMPOP_EQ 0x0028u
+#define COLCMPOP_LE 0x0030u
+#define COLCMPOP_GT 0x0038u
+#define MIXSEL_FRGDMIX 0x0000u
+#define MIXSEL_PATT 0x0040u
+#define MIXSEL_EXPPC 0x0080u
+#define MIXSEL_EXPBLT 0x00c0u
+/* ? 0xc2e8u */
+/* ? 0xc6e8u */
+/* ? 0xcae8u */
+/* ? 0xcee8u */
+/* ? 0xd2e8u */
+/* ? 0xd6e8u */
+/* ? 0xdae8u */
+/* ? 0xdee8u */
+#define PIX_TRANS 0xe2e8u
+/* ? 0xe6e8u */
+/* ? 0xeae8u */
+/* ? 0xeee8u */
+/* ? 0xf2e8u */
+/* ? 0xf6e8u */
+/* ? 0xfae8u */
+/* ? 0xfee8u */
+
+/* ATI Mach8 & Mach32 register definitions */
+#define OVERSCAN_COLOR_8 0x02eeu /* Write */ /* Mach32 */
+#define OVERSCAN_BLUE_24 0x02efu /* Write */ /* Mach32 */
+#define OVERSCAN_GREEN_24 0x06eeu /* Write */ /* Mach32 */
+#define OVERSCAN_RED_24 0x06efu /* Write */ /* Mach32 */
+#define CURSOR_OFFSET_LO 0x0aeeu /* Write */ /* Mach32 */
+#define CURSOR_OFFSET_HI 0x0eeeu /* Write */ /* Mach32 */
+#define CONFIG_STATUS_1 0x12eeu /* Read */
+#define CLK_MODE 0x0001u /* Mach8 */
+#define BUS_16 0x0002u /* Mach8 */
+#define MC_BUS 0x0004u /* Mach8 */
+#define EEPROM_ENA 0x0008u /* Mach8 */
+#define DRAM_ENA 0x0010u /* Mach8 */
+#define MEM_INSTALLED 0x0060u /* Mach8 */
+#define ROM_ENA 0x0080u /* Mach8 */
+#define ROM_PAGE_ENA 0x0100u /* Mach8 */
+#define ROM_LOCATION 0xfe00u /* Mach8 */
+#define _8514_ONLY 0x0001u /* Mach32 */
+#define BUS_TYPE 0x000eu /* Mach32 */
+#define ISA_16_BIT 0x0000u /* Mach32 */
+#define EISA 0x0002u /* Mach32 */
+#define MICRO_C_16_BIT 0x0004u /* Mach32 */
+#define MICRO_C_8_BIT 0x0006u /* Mach32 */
+#define LOCAL_386SX 0x0008u /* Mach32 */
+#define LOCAL_386DX 0x000au /* Mach32 */
+#define LOCAL_486 0x000cu /* Mach32 */
+#define PCI 0x000eu /* Mach32 */
+#define MEM_TYPE 0x0070u /* Mach32 */
+#define CHIP_DIS 0x0080u /* Mach32 */
+#define TST_VCTR_ENA 0x0100u /* Mach32 */
+#define DACTYPE 0x0e00u /* Mach32 */
+#define MC_ADR_DECODE 0x1000u /* Mach32 */
+#define CARD_ID 0xe000u /* Mach32 */
+#define HORZ_CURSOR_POSN 0x12eeu /* Write */ /* Mach32 */
+#define CONFIG_STATUS_2 0x16eeu /* Read */
+#define SHARE_CLOCK 0x0001u /* Mach8 */
+#define HIRES_BOOT 0x0002u /* Mach8 */
+#define EPROM_16_ENA 0x0004u /* Mach8 */
+#define WRITE_PER_BIT 0x0008u /* Mach8 */
+#define FLASH_ENA 0x0010u /* Mach8 */
+#define SLOW_SEQ_EN 0x0001u /* Mach32 */
+#define MEM_ADDR_DIS 0x0002u /* Mach32 */
+#define ISA_16_ENA 0x0004u /* Mach32 */
+#define KOR_TXT_MODE_ENA 0x0008u /* Mach32 */
+#define LOCAL_BUS_SUPPORT 0x0030u /* Mach32 */
+#define LOCAL_BUS_CONFIG_2 0x0040u /* Mach32 */
+#define LOCAL_BUS_RD_DLY_ENA 0x0080u /* Mach32 */
+#define LOCAL_DAC_EN 0x0100u /* Mach32 */
+#define LOCAL_RDY_EN 0x0200u /* Mach32 */
+#define EEPROM_ADR_SEL 0x0400u /* Mach32 */
+#define GE_STRAP_SEL 0x0800u /* Mach32 */
+#define VESA_RDY 0x1000u /* Mach32 */
+#define Z4GB 0x2000u /* Mach32 */
+#define LOC2_MDRAM 0x4000u /* Mach32 */
+#define VERT_CURSOR_POSN 0x16eeu /* Write */ /* Mach32 */
+#define FIFO_TEST_DATA 0x1aeeu /* Read */ /* Mach32 */
+#define CURSOR_COLOR_0 0x1aeeu /* Write */ /* Mach32 */
+#define CURSOR_COLOR_1 0x1aefu /* Write */ /* Mach32 */
+#define HORZ_CURSOR_OFFSET 0x1eeeu /* Write */ /* Mach32 */
+#define VERT_CURSOR_OFFSET 0x1eefu /* Write */ /* Mach32 */
+#define PCI_CNTL 0x22eeu /* Mach32-PCI */
+#define CRT_PITCH 0x26eeu /* Write */
+#define CRT_OFFSET_LO 0x2aeeu /* Write */
+#define CRT_OFFSET_HI 0x2eeeu /* Write */
+#define LOCAL_CNTL 0x32eeu /* Mach32 */
+#define FIFO_OPT 0x36eeu /* Write */ /* Mach8 */
+#define MISC_OPTIONS 0x36eeu /* Mach32 */
+#define W_STATE_ENA 0x0000u /* Mach32 */
+#define HOST_8_ENA 0x0001u /* Mach32 */
+#define MEM_SIZE_ALIAS 0x000cu /* Mach32 */
+#define MEM_SIZE_512K 0x0000u /* Mach32 */
+#define MEM_SIZE_1M 0x0004u /* Mach32 */
+#define MEM_SIZE_2M 0x0008u /* Mach32 */
+#define MEM_SIZE_4M 0x000cu /* Mach32 */
+#define DISABLE_VGA 0x0010u /* Mach32 */
+#define _16_BIT_IO 0x0020u /* Mach32 */
+#define DISABLE_DAC 0x0040u /* Mach32 */
+#define DLY_LATCH_ENA 0x0080u /* Mach32 */
+#define TEST_MODE 0x0100u /* Mach32 */
+#define BLK_WR_ENA 0x0400u /* Mach32 */
+#define _64_DRAW_ENA 0x0800u /* Mach32 */
+#define FIFO_TEST_TAG 0x3aeeu /* Read */ /* Mach32 */
+#define EXT_CURSOR_COLOR_0 0x3aeeu /* Write */ /* Mach32 */
+#define EXT_CURSOR_COLOR_1 0x3eeeu /* Write */ /* Mach32 */
+#define MEM_BNDRY 0x42eeu /* Mach32 */
+#define MEM_PAGE_BNDRY 0x000fu /* Mach32 */
+#define MEM_BNDRY_ENA 0x0010u /* Mach32 */
+#define SHADOW_CTL 0x46eeu /* Write */
+#define CLOCK_SEL 0x4aeeu
+/* DISABPASSTHRU 0x0001u See ADVFUNC_CNTL */
+#define VFIFO_DEPTH_1 0x0100u /* Mach32 */
+#define VFIFO_DEPTH_2 0x0200u /* Mach32 */
+#define VFIFO_DEPTH_3 0x0300u /* Mach32 */
+#define VFIFO_DEPTH_4 0x0400u /* Mach32 */
+#define VFIFO_DEPTH_5 0x0500u /* Mach32 */
+#define VFIFO_DEPTH_6 0x0600u /* Mach32 */
+#define VFIFO_DEPTH_7 0x0700u /* Mach32 */
+#define VFIFO_DEPTH_8 0x0800u /* Mach32 */
+#define VFIFO_DEPTH_9 0x0900u /* Mach32 */
+#define VFIFO_DEPTH_A 0x0a00u /* Mach32 */
+#define VFIFO_DEPTH_B 0x0b00u /* Mach32 */
+#define VFIFO_DEPTH_C 0x0c00u /* Mach32 */
+#define VFIFO_DEPTH_D 0x0d00u /* Mach32 */
+#define VFIFO_DEPTH_E 0x0e00u /* Mach32 */
+#define VFIFO_DEPTH_F 0x0f00u /* Mach32 */
+#define COMPOSITE_SYNC 0x1000u
+/* ? 0x4eeeu */
+#define ROM_ADDR_1 0x52eeu
+#define BIOS_BASE_SEGMENT 0x007fu /* Mach32 */
+/* ? 0xff80u */ /* Mach32 */
+#define ROM_ADDR_2 0x56eeu /* Sick ... */
+#define SHADOW_SET 0x5aeeu /* Write */
+#define MEM_CFG 0x5eeeu /* Mach32 */
+#define MEM_APERT_SEL 0x0003u /* Mach32 */
+#define MEM_APERT_PAGE 0x000cu /* Mach32 */
+#define MEM_APERT_LOC 0xfff0u /* Mach32 */
+#define EXT_GE_STATUS 0x62eeu /* Read */ /* Mach32 */
+#define HORZ_OVERSCAN 0x62eeu /* Write */ /* Mach32 */
+#define VERT_OVERSCAN 0x66eeu /* Write */ /* Mach32 */
+#define MAX_WAITSTATES 0x6aeeu
+#define GE_OFFSET_LO 0x6eeeu /* Write */
+#define BOUNDS_LEFT 0x72eeu /* Read */
+#define GE_OFFSET_HI 0x72eeu /* Write */
+#define BOUNDS_TOP 0x76eeu /* Read */
+#define GE_PITCH 0x76eeu /* Write */
+#define BOUNDS_RIGHT 0x7aeeu /* Read */
+#define EXT_GE_CONFIG 0x7aeeu /* Write */ /* Mach32 */
+#define MONITOR_ALIAS 0x0007u /* Mach32 */
+/* MONITOR_? 0x0000u */ /* Mach32 */
+#define MONITOR_8507 0x0001u /* Mach32 */
+#define MONITOR_8514 0x0002u /* Mach32 */
+/* MONITOR_? 0x0003u */ /* Mach32 */
+/* MONITOR_? 0x0004u */ /* Mach32 */
+#define MONITOR_8503 0x0005u /* Mach32 */
+#define MONITOR_8512 0x0006u /* Mach32 */
+#define MONITOR_8513 0x0006u /* Mach32 */
+#define MONITOR_NONE 0x0007u /* Mach32 */
+#define ALIAS_ENA 0x0008u /* Mach32 */
+#define PIXEL_WIDTH_4 0x0000u /* Mach32 */
+#define PIXEL_WIDTH_8 0x0010u /* Mach32 */
+#define PIXEL_WIDTH_16 0x0020u /* Mach32 */
+#define PIXEL_WIDTH_24 0x0030u /* Mach32 */
+#define RGB16_555 0x0000u /* Mach32 */
+#define RGB16_565 0x0040u /* Mach32 */
+#define RGB16_655 0x0080u /* Mach32 */
+#define RGB16_664 0x00c0u /* Mach32 */
+#define MULTIPLEX_PIXELS 0x0100u /* Mach32 */
+#define RGB24 0x0000u /* Mach32 */
+#define RGBx24 0x0200u /* Mach32 */
+#define BGR24 0x0400u /* Mach32 */
+#define xBGR24 0x0600u /* Mach32 */
+#define DAC_8_BIT_EN 0x4000u /* Mach32 */
+#define ORDER_16BPP_565 RGB16_565 /* Mach32 */
+#define BOUNDS_BOTTOM 0x7eeeu /* Read */
+#define MISC_CNTL 0x7eeeu /* Write */ /* Mach32 */
+#define PATT_DATA_INDEX 0x82eeu
+/* ? 0x86eeu */
+/* ? 0x8aeeu */
+#define R_EXT_GE_CONFIG 0x8eeeu /* Read */ /* Mach32 */
+#define PATT_DATA 0x8eeeu /* Write */
+#define R_MISC_CNTL 0x92eeu /* Read */ /* Mach32 */
+#define BRES_COUNT 0x96eeu
+#define EXT_FIFO_STATUS 0x9aeeu /* Read */
+#define LINEDRAW_INDEX 0x9aeeu /* Write */
+/* ? 0x9eeeu */
+#define LINEDRAW_OPT 0xa2eeu
+#define BOUNDS_RESET 0x0100u
+#define CLIP_MODE_0 0x0000u /* Clip exception disabled */
+#define CLIP_MODE_1 0x0200u /* Line segments */
+#define CLIP_MODE_2 0x0400u /* Polygon boundary lines */
+#define CLIP_MODE_3 0x0600u /* Patterned lines */
+#define DEST_X_START 0xa6eeu /* Write */
+#define DEST_X_END 0xaaeeu /* Write */
+#define DEST_Y_END 0xaeeeu /* Write */
+#define R_H_TOTAL_DISP 0xb2eeu /* Read */ /* Mach32 */
+#define SRC_X_STRT 0xb2eeu /* Write */
+#define R_H_SYNC_STRT 0xb6eeu /* Read */ /* Mach32 */
+#define ALU_BG_FN 0xb6eeu /* Write */
+#define R_H_SYNC_WID 0xbaeeu /* Read */ /* Mach32 */
+#define ALU_FG_FN 0xbaeeu /* Write */
+#define SRC_X_END 0xbeeeu /* Write */
+#define R_V_TOTAL 0xc2eeu /* Read */
+#define SRC_Y_DIR 0xc2eeu /* Write */
+#define R_V_DISP 0xc6eeu /* Read */ /* Mach32 */
+#define EXT_SHORT_STROKE 0xc6eeu /* Write */
+#define R_V_SYNC_STRT 0xcaeeu /* Read */ /* Mach32 */
+#define SCAN_X 0xcaeeu /* Write */
+#define VERT_LINE_CNTR 0xceeeu /* Read */ /* Mach32 */
+#define DP_CONFIG 0xceeeu /* Write */
+#define READ_WRITE 0x0001u
+#define DATA_WIDTH 0x0200u
+#define DATA_ORDER 0x1000u
+#define FG_COLOR_SRC_FG 0x2000u
+#define FG_COLOR_SRC_BLIT 0x6000u
+#define R_V_SYNC_WID 0xd2eeu /* Read */
+#define PATT_LENGTH 0xd2eeu /* Write */
+#define PATT_INDEX 0xd6eeu /* Write */
+#define READ_SRC_X 0xdaeeu /* Read */ /* Mach32 */
+#define EXT_SCISSOR_L 0xdaeeu /* Write */
+#define READ_SRC_Y 0xdeeeu /* Read */ /* Mach32 */
+#define EXT_SCISSOR_T 0xdeeeu /* Write */
+#define EXT_SCISSOR_R 0xe2eeu /* Write */
+#define EXT_SCISSOR_B 0xe6eeu /* Write */
+/* ? 0xeaeeu */
+#define DEST_COMP_FN 0xeeeeu /* Write */
+#define DEST_COLOR_CMP_MASK 0xf2eeu /* Write */ /* Mach32 */
+/* ? 0xf6eeu */
+#define CHIP_ID 0xfaeeu /* Read */ /* Mach32 */
+#define CHIP_CODE_0 0x001fu /* Mach32 */
+#define CHIP_CODE_1 0x03e0u /* Mach32 */
+#define CHIP_CLASS 0x0c00u /* Mach32 */
+#define CHIP_REV 0xf000u /* Mach32 */
+#define LINEDRAW 0xfeeeu /* Write */
+
+/* ATI Mach64 register definitions */
+#define CRTC_H_TOTAL_DISP IOPortTag(0x00u, 0x00u)
+#define CRTC_H_TOTAL 0x000001fful
+/* ? 0x0000fe00ul */
+#define CRTC_H_DISP 0x01ff0000ul
+/* ? 0xfe000000ul */
+#define CRTC_H_SYNC_STRT_WID IOPortTag(0x01u, 0x01u)
+#define CRTC_H_SYNC_STRT 0x000000fful
+#define CRTC_H_SYNC_DLY 0x00000700ul
+/* ? 0x00000800ul */
+#define CRTC_H_SYNC_STRT_HI 0x00001000ul
+/* ? 0x0000e000ul */
+#define CRTC_H_SYNC_WID 0x001f0000ul
+#define CRTC_H_SYNC_POL 0x00200000ul
+/* ? 0xffc00000ul */
+#define CRTC_V_TOTAL_DISP IOPortTag(0x02u, 0x02u)
+#define CRTC_V_TOTAL 0x000007fful
+/* ? 0x0000f800ul */
+#define CRTC_V_DISP 0x07ff0000ul
+/* ? 0xf8000000ul */
+#define CRTC_V_SYNC_STRT_WID IOPortTag(0x03u, 0x03u)
+#define CRTC_V_SYNC_STRT 0x000007fful
+/* ? 0x0000f800ul */
+#define CRTC_V_SYNC_WID 0x001f0000ul
+#define CRTC_V_SYNC_END_VGA 0x000f0000ul
+#define CRTC_V_SYNC_POL 0x00200000ul
+/* ? 0xffc00000ul */
+#define CRTC_VLINE_CRNT_VLINE IOPortTag(0x04u, 0x04u)
+#define CRTC_VLINE 0x000007fful
+/* ? 0x0000f800ul */
+#define CRTC_CRNT_VLINE 0x07ff0000ul
+/* ? 0xf8000000ul */
+#define CRTC_OFF_PITCH IOPortTag(0x05u, 0x05u)
+#define CRTC_OFFSET 0x000ffffful
+#define CRTC_OFFSET_VGA 0x0003fffful
+#define CRTC_OFFSET_LOCK 0x00100000ul /* XC/XL */
+/* ? 0x00200000ul */
+#define CRTC_PITCH 0xffc00000ul
+#define CRTC_INT_CNTL IOPortTag(0x06u, 0x06u)
+#define CRTC_VBLANK 0x00000001ul
+#define CRTC_VBLANK_INT_EN 0x00000002ul
+#define CRTC_VBLANK_INT 0x00000004ul
+#define CRTC_VLINE_INT_EN 0x00000008ul
+#define CRTC_VLINE_INT 0x00000010ul
+#define CRTC_VLINE_SYNC 0x00000020ul
+#define CRTC_FRAME 0x00000040ul
+#define CRTC_SNAPSHOT_INT_EN 0x00000080ul /* GTPro */
+#define CRTC_SNAPSHOT_INT 0x00000100ul /* GTPro */
+#define CRTC_I2C_INT_EN 0x00000200ul /* GTPro */
+#define CRTC_I2C_INT 0x00000400ul /* GTPro */
+#define CRTC2_VBLANK 0x00000800ul /* LTPro */
+#define CRTC2_VBLANK_INT_EN 0x00001000ul /* LTPro */
+#define CRTC2_VBLANK_INT 0x00002000ul /* LTPro */
+#define CRTC2_VLINE_INT_EN 0x00004000ul /* LTPro */
+#define CRTC2_VLINE_INT 0x00008000ul /* LTPro */
+#define CRTC_CAPBUF0_INT_EN 0x00010000ul /* VT/GT */
+#define CRTC_CAPBUF0_INT 0x00020000ul /* VT/GT */
+#define CRTC_CAPBUF1_INT_EN 0x00040000ul /* VT/GT */
+#define CRTC_CAPBUF1_INT 0x00080000ul /* VT/GT */
+#define CRTC_OVERLAY_EOF_INT_EN 0x00100000ul /* VT/GT */
+#define CRTC_OVERLAY_EOF_INT 0x00200000ul /* VT/GT */
+#define CRTC_ONESHOT_CAP_INT_EN 0x00400000ul /* VT/GT */
+#define CRTC_ONESHOT_CAP_INT 0x00800000ul /* VT/GT */
+#define CRTC_BUSMASTER_EOL_INT_EN 0x01000000ul /* VTB/GTB/LT */
+#define CRTC_BUSMASTER_EOL_INT 0x02000000ul /* VTB/GTB/LT */
+#define CRTC_GP_INT_EN 0x04000000ul /* VTB/GTB/LT */
+#define CRTC_GP_INT 0x08000000ul /* VTB/GTB/LT */
+#define CRTC2_VLINE_SYNC 0x10000000ul /* LTPro */
+#define CRTC_SNAPSHOT2_INT_EN 0x20000000ul /* LTPro */
+#define CRTC_SNAPSHOT2_INT 0x40000000ul /* LTPro */
+#define CRTC_VBLANK_BIT2_INT 0x80000000ul /* GTPro */
+#define CRTC_INT_ENS /* *** UPDATE ME *** */ \
+ ( \
+ CRTC_VBLANK_INT_EN | \
+ CRTC_VLINE_INT_EN | \
+ CRTC_SNAPSHOT_INT_EN | \
+ CRTC_I2C_INT_EN | \
+ CRTC2_VBLANK_INT_EN | \
+ CRTC2_VLINE_INT_EN | \
+ CRTC_CAPBUF0_INT_EN | \
+ CRTC_CAPBUF1_INT_EN | \
+ CRTC_OVERLAY_EOF_INT_EN | \
+ CRTC_ONESHOT_CAP_INT_EN | \
+ CRTC_BUSMASTER_EOL_INT_EN | \
+ CRTC_GP_INT_EN | \
+ CRTC_SNAPSHOT2_INT_EN | \
+ 0 \
+ )
+#define CRTC_INT_ACKS /* *** UPDATE ME *** */ \
+ ( \
+ CRTC_VBLANK_INT | \
+ CRTC_VLINE_INT | \
+ CRTC_SNAPSHOT_INT | \
+ CRTC_I2C_INT | \
+ CRTC2_VBLANK_INT | \
+ CRTC2_VLINE_INT | \
+ CRTC_CAPBUF0_INT | \
+ CRTC_CAPBUF1_INT | \
+ CRTC_OVERLAY_EOF_INT | \
+ CRTC_ONESHOT_CAP_INT | \
+ CRTC_BUSMASTER_EOL_INT | \
+ CRTC_GP_INT | \
+ CRTC_SNAPSHOT2_INT | \
+ CRTC_VBLANK_BIT2_INT | \
+ 0 \
+ )
+#define CRTC_GEN_CNTL IOPortTag(0x07u, 0x07u)
+#define CRTC_DBL_SCAN_EN 0x00000001ul
+#define CRTC_INTERLACE_EN 0x00000002ul
+#define CRTC_HSYNC_DIS 0x00000004ul
+#define CRTC_VSYNC_DIS 0x00000008ul
+#define CRTC_CSYNC_EN 0x00000010ul
+#define CRTC_PIX_BY_2_EN 0x00000020ul
+#define CRTC2_DBL_SCAN_EN 0x00000020ul /* LTPro */
+#define CRTC_DISPLAY_DIS 0x00000040ul
+#define CRTC_VGA_XOVERSCAN 0x00000080ul
+#define CRTC_PIX_WIDTH 0x00000700ul
+#define CRTC_BYTE_PIX_ORDER 0x00000800ul
+#define CRTC_VSYNC_INT_EN 0x00001000ul /* XC/XL */
+#define CRTC_VSYNC_INT 0x00002000ul /* XC/XL */
+#define CRTC_FIFO_OVERFILL 0x0000c000ul /* VT/GT */
+#define CRTC2_VSYNC_INT_EN 0x00004000ul /* XC/XL */
+#define CRTC2_VSYNC_INT 0x00008000ul /* XC/XL */
+#define CRTC_FIFO_LWM 0x000f0000ul
+#define CRTC_HVSYNC_IO_DRIVE 0x00010000ul /* XC/XL */
+#define CRTC2_PIX_WIDTH 0x000e0000ul /* LTPro */
+#define CRTC_VGA_128KAP_PAGING 0x00100000ul /* VT/GT */
+#define CRTC_DISPREQ_ONLY 0x00200000ul /* VT/GT */
+#define CRTC_VFC_SYNC_TRISTATE 0x00200000ul /* VTB/GTB/LT */
+#define CRTC2_EN 0x00200000ul /* LTPro */
+#define CRTC_LOCK_REGS 0x00400000ul /* VT/GT */
+#define CRTC_SYNC_TRISTATE 0x00800000ul /* VT/GT */
+#define CRTC_EXT_DISP_EN 0x01000000ul
+#define CRTC_EN 0x02000000ul
+#define CRTC_DISP_REQ_EN 0x04000000ul
+#define CRTC_VGA_LINEAR 0x08000000ul
+#define CRTC_VSYNC_FALL_EDGE 0x10000000ul
+#define CRTC_VGA_TEXT_132 0x20000000ul
+#define CRTC_CNT_EN 0x40000000ul
+#define CRTC_CUR_B_TEST 0x80000000ul
+#define CRTC_INT_ENS_X /* *** UPDATE ME *** */ \
+ ( \
+ CRTC_VSYNC_INT_EN | \
+ CRTC2_VSYNC_INT_EN | \
+ 0 \
+ )
+#define CRTC_INT_ACKS_X /* *** UPDATE ME *** */ \
+ ( \
+ CRTC_VSYNC_INT | \
+ CRTC2_VSYNC_INT | \
+ 0 \
+ )
+#define DSP_CONFIG BlockIOTag(0x08u) /* VTB/GTB/LT */
+#define DSP_XCLKS_PER_QW 0x00003ffful
+/* ? 0x00004000ul */
+#define DSP_FLUSH_WB 0x00008000ul
+#define DSP_LOOP_LATENCY 0x000f0000ul
+#define DSP_PRECISION 0x00700000ul
+/* ? 0xff800000ul */
+#define DSP_ON_OFF BlockIOTag(0x09u) /* VTB/GTB/LT */
+#define DSP_OFF 0x000007fful
+/* ? 0x0000f800ul */
+#define DSP_ON 0x07ff0000ul
+/* ? 0xf8000000ul */
+#define TIMER_CONFIG BlockIOTag(0x0au) /* VTB/GTB/LT */
+#define MEM_BUF_CNTL BlockIOTag(0x0bu) /* VTB/GTB/LT */
+#define Z_WB_FLUSH 0x00000007ul
+#define Z_WB_FLUSH_P 0x0000000ful /* GTPro */
+#define VID_WB_FLUSH_P 0x000000f0ul /* GTPro */
+#define VID_WB_FLUSH_MSB 0x00000100ul
+#define GUI_WB_FLUSH_P 0x00001f00ul /* GTPro */
+#define HST_WB_FLUSH_P 0x0000e000ul /* GTPro */
+#define SCL_MIN_BURST_LEN 0x001f0000ul
+#define SCL_THRESH 0x003f0000ul /* GTPro */
+/* ? 0x00400000ul */
+#define INVALIDATE_RB_CACHE 0x00800000ul
+#define HST_WB_FLUSH 0x03000000ul
+#define VID_WB_FLUSH 0x1c000000ul
+#define GUI_WB_FLUSH 0xe0000000ul
+#define SHARED_CNTL BlockIOTag(0x0cu) /* VTB/GTB/LT */
+#define SHARED_MEM_CONFIG BlockIOTag(0x0du) /* VTB/GTB/LT */
+#define MEM_ADDR_CONFIG BlockIOTag(0x0du) /* GTPro */
+#define SHARED_CNTL_CTD BlockIOTag(0x0eu) /* CTD */
+/* ? 0x00fffffful */
+#define CTD_FIFO5 0x01000000ul
+/* ? 0xfe000000ul */
+#define CRT_TRAP BlockIOTag(0x0eu) /* VTB/GTB/LT */
+#define DSTN_CONTROL BlockIOTag(0x0fu) /* LT */
+#define I2C_CNTL_0 BlockIOTag(0x0fu) /* GTPro */
+#define I2C_CNTL_STAT 0x0000000ful
+#define I2C_CNTL_DONE 0x00000001ul
+#define I2C_CNTL_NACK 0x00000002ul
+#define I2C_CNTL_HALT 0x00000004ul
+#define I2C_CNTL_FULL 0x00000008ul
+/* ? 0x00000010ul */
+#define I2C_CNTL_HPTR_RST 0x00000020ul
+/* ? 0x000000c0ul */
+#define I2C_CNTL_START 0x00000100ul
+#define I2C_CNTL_STOP 0x00000200ul
+#define I2C_CNTL_GO 0x00000400ul
+#define I2C_CNTL_RECEIVE 0x00000800ul
+#define I2C_CNTL_ABORT 0x00001000ul
+#define I2C_CNTL_INT_EN 0x00002000ul
+#define I2C_CNTL_SCL 0x00004000ul
+#define I2C_CNTL_SDA 0x00008000ul
+#define I2C_CNTL_M_FACTOR 0x00ff0000ul
+#define I2C_CNTL_N_FACTOR 0xff000000ul
+#define OVR_CLR IOPortTag(0x08u, 0x10u)
+#define OVR_CLR_8 0x000000fful
+#define OVR_CLR_B 0x0000ff00ul
+#define OVR_CLR_G 0x00ff0000ul
+#define OVR_CLR_R 0xff000000ul
+#define OVR_WID_LEFT_RIGHT IOPortTag(0x09u, 0x11u)
+#define OVR_WID_LEFT 0x0000003ful /* 0x0f on <LT */
+/* ? 0x0000ffc0ul */
+#define OVR_WID_RIGHT 0x003f0000ul /* 0x0f0000 on <LT */
+/* ? 0xffc00000ul */
+#define OVR_WID_TOP_BOTTOM IOPortTag(0x0au, 0x12u)
+#define OVR_WID_TOP 0x000001fful /* 0x00ff on <LT */
+/* ? 0x0000fe00ul */
+#define OVR_WID_BOTTOM 0x01ff0000ul /* 0x00ff0000 on <LT */
+/* ? 0xfe000000ul */
+#define VGA_DSP_CONFIG BlockIOTag(0x13u) /* VTB/GTB/LT */
+#define VGA_DSP_XCLKS_PER_QW DSP_XCLKS_PER_QW
+/* ? 0x000fc000ul */
+#define VGA_DSP_PREC_PCLKBY2 0x00700000ul
+/* ? 0x00800000ul */
+#define VGA_DSP_PREC_PCLK 0x07000000ul
+/* ? 0xf8000000ul */
+#define VGA_DSP_ON_OFF BlockIOTag(0x14u) /* VTB/GTB/LT */
+#define VGA_DSP_OFF DSP_OFF
+/* ? 0x0000f800ul */
+#define VGA_DSP_ON DSP_ON
+/* ? 0xf8000000ul */
+#define DSP2_CONFIG BlockIOTag(0x15u) /* LTPro */
+#define DSP2_ON_OFF BlockIOTag(0x16u) /* LTPro */
+#define EXT_CRTC_GEN_CNTL BlockIOTag(0x17u) /* VT-A4 (W) */
+#define CRTC2_OFF_PITCH BlockIOTag(0x17u) /* LTPro */
+#define CUR_CLR0 IOPortTag(0x0bu, 0x18u)
+#define CUR_CLR1 IOPortTag(0x0cu, 0x19u)
+/* These are for both CUR_CLR0 and CUR_CLR1 */
+#define CUR_CLR_I 0x000000fful
+#define CUR_CLR_B 0x0000ff00ul
+#define CUR_CLR_G 0x00ff0000ul
+#define CUR_CLR_R 0xff000000ul
+#define CUR_CLR (CUR_CLR_R | CUR_CLR_G | CUR_CLR_B)
+#define CUR_OFFSET IOPortTag(0x0du, 0x1au)
+#define CUR_HORZ_VERT_POSN IOPortTag(0x0eu, 0x1bu)
+#define CUR_HORZ_POSN 0x000007fful
+/* ? 0x0000f800ul */
+#define CUR_VERT_POSN 0x07ff0000ul
+/* ? 0xf8000000ul */
+#define CUR_HORZ_VERT_OFF IOPortTag(0x0fu, 0x1cu)
+#define CUR_HORZ_OFF 0x0000007ful
+/* ? 0x0000ff80ul */
+#define CUR_VERT_OFF 0x007f0000ul
+/* ? 0xff800000ul */
+#define CONFIG_PANEL BlockIOTag(0x1du) /* LT */
+#define PANEL_FORMAT 0x00000007ul
+/* ? 0x00000008ul */
+#define PANEL_TYPE 0x000000f0ul
+#define NO_OF_GREY 0x00000700ul
+#define MOD_GEN 0x00001800ul
+#define EXT_LVDS_CLK 0x00001800ul /* LTPro */
+#define BLINK_RATE 0x00006000ul
+#define BLINK_RATE_PRO 0x00002000ul /* LTPro */
+#define DONT_SHADOW_HEND 0x00004000ul /* LTPro */
+#define DONT_USE_F32KHZ 0x00008000ul
+#define LCD_IO_DRIVE 0x00008000ul /* XC/XL */
+#define FP_POL 0x00010000ul
+#define LP_POL 0x00020000ul
+#define DTMG_POL 0x00040000ul
+#define SCK_POL 0x00080000ul
+#define DITHER_SEL 0x00300000ul
+#define INVERSE_VIDEO_EN 0x00400000ul
+#define BL_CLK_SEL 0x01800000ul
+#define BL_LEVEL 0x0e000000ul
+#define BL_CLK_SEL_PRO 0x00800000ul /* LTPro */
+#define BL_LEVEL_PRO 0x03000000ul /* LTPro */
+#define BIAS_LEVEL_PRO 0x0c000000ul /* LTPro */
+#define HSYNC_DELAY 0xf0000000ul
+#define TV_OUT_INDEX BlockIOTag(0x1du) /* LTPro */
+#define TV_REG_INDEX 0x000000fful
+#define TV_ON 0x00000100ul
+/* ? 0xfffffe00ul */
+#define GP_IO IOPortTag(0x1eu, 0x1eu) /* VT/GT */
+#define GP_IO_0 0x00000001ul
+#define GP_IO_1 0x00000002ul
+#define GP_IO_2 0x00000004ul
+#define GP_IO_3 0x00000008ul
+#define GP_IO_4 0x00000010ul
+#define GP_IO_5 0x00000020ul
+#define GP_IO_6 0x00000040ul
+#define GP_IO_7 0x00000080ul
+#define GP_IO_8 0x00000100ul
+#define GP_IO_9 0x00000200ul
+#define GP_IO_A 0x00000400ul
+#define GP_IO_B 0x00000800ul
+#define GP_IO_C 0x00001000ul
+#define GP_IO_D 0x00002000ul
+#define GP_IO_E 0x00004000ul
+#define GP_IO_F 0x00008000ul
+#define GP_IO_DIR_0 0x00010000ul
+#define GP_IO_DIR_1 0x00020000ul
+#define GP_IO_DIR_2 0x00040000ul
+#define GP_IO_DIR_3 0x00080000ul
+#define GP_IO_DIR_4 0x00100000ul
+#define GP_IO_DIR_5 0x00200000ul
+#define GP_IO_DIR_6 0x00400000ul
+#define GP_IO_DIR_7 0x00800000ul
+#define GP_IO_DIR_8 0x01000000ul
+#define GP_IO_DIR_9 0x02000000ul
+#define GP_IO_DIR_A 0x04000000ul
+#define GP_IO_DIR_B 0x08000000ul
+#define GP_IO_DIR_C 0x10000000ul
+#define GP_IO_DIR_D 0x20000000ul
+#define GP_IO_DIR_E 0x40000000ul
+#define GP_IO_DIR_F 0x80000000ul
+#define GP_IO_CNTL BlockIOTag(0x1fu) /* VT/GT */
+#define GP_IO_MODE 0x0000000ful
+/* ? 0x7ffffff0ul */
+#define GP_IO_EN 0x80000000ul
+#define HW_DEBUG BlockIOTag(0x1fu) /* VTB/GTB/LT */
+#define FAST_SRCCOPY_DIS 0x00000001ul
+#define BYPASS_SUBPIC_DBF 0x00000001ul /* XL/XC */
+#define SRC_AUTONA_FIX_DIS 0x00000002ul
+#define SYNC_PD_EN 0x00000002ul /* Mobility */
+#define DISP_QW_FIX_DIS 0x00000004ul
+#define GUIDST_WB_EXP_DIS 0x00000008ul
+#define CYC_ALL_FIX_DIS 0x00000008ul /* GTPro */
+#define AGPPLL_FIX_EN 0x00000008ul /* Mobility */
+#define SRC_AUTONA_ALWAYS_EN 0x00000010ul
+#define GUI_BEATS_HOST_P 0x00000010ul /* GTPro */
+#define DRV_CNTL_DQMB_WEB 0x00000020ul
+#define FAST_FILL_SCISSOR_DIS 0x00000020ul /* GT2c/VT4 */
+#define INTER_BLIT_FIX_DIS 0x00000020ul /* GTPro */
+#define DRV_CNTL_MA 0x00000040ul
+#define AUTO_BLKWRT_COLOR_DIS 0x00000040ul /* GT2c/VT4 */
+#define INTER_PRIM_DIS 0x00000040ul /* GTPro */
+#define DRV_CNTL_MD 0x00000080ul
+#define CHG_DEV_ID 0x00000100ul
+#define SRC_TRACK_DST_FIX_DIS 0x00000200ul
+#define HCLK_FB_SKEW 0x00000380ul /* GT2c/VT4 */
+#define SRC_TRACK_DST_FIX_DIS_P 0x00000080ul /* GTPro */
+#define AUTO_BLKWRT_COLOR_DIS_P 0x00000100ul /* GTPro */
+#define INTER_LINE_OVERLAP_DIS 0x00000200ul /* GTPro */
+#define MEM_OE_PULLBACK 0x00000400ul
+#define DBL_BUFFER_EN 0x00000400ul /* GTPro */
+#define MEM_WE_FIX_DIS 0x00000800ul
+#define MEM_OE_PULLBACK_B 0x00000800ul /* GT2c/VT4 */
+#define CMDFIFO_SIZE_EN 0x00000800ul /* GTPro */
+#define RD_EN_FIX_DIS 0x00001000ul
+#define MEM_WE_FIX_DIS_B 0x00001000ul
+#define AUTO_FF_DIS 0x00001000ul /* GTPro */
+#define CMDFIFO_SIZE_DIS 0x00002000ul /* GT2c/VT4 */
+#define AUTO_BLKWRT_DIS 0x00002000ul /* GTPro */
+#define GUI_BEATS_HOST 0x00004000ul /* GT2c/VT4 */
+#define ORED_INVLD_RB_CACHE 0x00004000ul /* GTPro */
+#define BLOCK_DBL_BUF 0x00008000ul /* GTPro */
+#define R2W_TURNAROUND_DELAY 0x00020000ul /* GT2c/VT4 */
+#define ENA_32BIT_DATA_BUS 0x00040000ul /* GT2c/VT4 */
+#define HCLK_FB_SKEW_P 0x00070000ul /* GTPro */
+#define ENA_FLASH_ROM 0x00080000ul /* GT2c/VT4 */
+#define DISABLE_SWITCH_FIX 0x00080000ul /* GTPro */
+#define MCLK_START_EN 0x00080000ul /* LTPro */
+#define SEL_VBLANK_BDL_BUF 0x00100000ul /* GTPro */
+#define CMDFIFO_64EN 0x00200000ul /* GTPro */
+#define BM_FIX_DIS 0x00400000ul /* GTPro */
+#define Z_SWITCH_EN 0x00800000ul /* LTPro */
+#define FLUSH_HOST_WB 0x01000000ul /* GTPro */
+#define HW_DEBUG_WRITE_MSK_FIX_DIS 0x02000000ul /* LTPro */
+#define Z_NO_WRITE_EN 0x04000000ul /* LTPro */
+#define DISABLE_PCLK_RESET_P 0x08000000ul /* LTPro */
+#define PM_D3_SUPPORT_ENABLE_P 0x10000000ul /* LTPro */
+#define STARTCYCLE_FIX_ENABLE 0x20000000ul /* LTPro */
+#define DONT_RST_CHAREN 0x20000000ul /* XL/XC */
+#define C3_FIX_ENABLE 0x40000000ul /* LTPro */
+#define BM_HOSTRA_EN 0x40000000ul /* XL/XC */
+#define PKGBGAb 0x80000000ul /* XL/XC */
+#define AUTOEXP_HORZ_FIX 0x80000000ul /* Mobility */
+#define SCRATCH_REG0 IOPortTag(0x10u, 0x20u)
+#define SCRATCH_REG1 IOPortTag(0x11u, 0x21u)
+/* BIOS_BASE_SEGMENT 0x0000007ful */ /* As above */
+/* ? 0x00000f80ul */
+#define BIOS_INIT_DAC_SUBTYPE 0x0000f000ul
+/* ? 0xffff0000ul */
+#define SCRATCH_REG2 BlockIOTag(0x22u) /* LT */
+#define SCRATCH_REG3 BlockIOTag(0x23u) /* GTPro */
+/* Not described here 0x07fffffful */
+#define DISPLAY_SWITCH_DISABLE 0x08000000ul
+/* Not described here 0xf0000000ul */
+#define CLOCK_CNTL IOPortTag(0x12u, 0x24u)
+#define CLOCK_BIT 0x00000004ul /* For ICS2595 */
+#define CLOCK_PULSE 0x00000008ul /* For ICS2595 */
+#define CLOCK_SELECT 0x0000000ful
+#define CLOCK_DIVIDER 0x00000030ul
+#define CLOCK_STROBE 0x00000040ul
+#define CLOCK_DATA 0x00000080ul
+/* ? 0x00000100ul */
+#define PLL_WR_EN 0x00000200ul /* For internal PLL */
+#define PLL_ADDR 0x0000fc00ul /* For internal PLL */
+#define PLL_DATA 0x00ff0000ul /* For internal PLL */
+/* ? 0xff000000ul */
+#define CONFIG_STAT64_1 BlockIOTag(0x25u) /* GTPro */
+#define CFG_SUBSYS_DEV_ID 0x000000fful
+#define CFG_SUBSYS_VEN_ID 0x00ffff00ul
+/* ? 0x1f000000ul */
+#define CFG_DIMM_TYPE 0xe0000000ul
+#define CFG_PCI_SUBSYS_DEV_ID 0x0000fffful /* XC/XL */
+#define CFG_PCI_SUBSYS_VEN_ID 0xffff0000ul /* XC/XL */
+#define CONFIG_STAT64_2 BlockIOTag(0x26u) /* GTPro */
+#define CFG_DIMM_TYPE_3 0x00000001ul
+/* ? 0x0000001eul */
+#define CFG_ROMWRTEN 0x00000020ul
+#define CFG_AGPVCOGAIN 0x000000c0ul
+#define CFG_PCI_TYPE 0x00000100ul
+#define CFG_AGPSKEW 0x00000e00ul
+#define CFG_X1CLKSKEW 0x00007000ul
+#define CFG_PANEL_ID_P 0x000f8000ul /* LTPro */
+/* ? 0x00100000ul */
+#define CFG_PREFETCH_EN 0x00200000ul
+#define CFG_ID_DISABLE 0x00400000ul
+#define CFG_PRE_TESTEN 0x00800000ul
+/* ? 0x01000000ul */
+#define CFG_PCI5VEN 0x02000000ul /* LTPro */
+#define CFG_VGA_DISABLE 0x04000000ul
+#define CFG_ENINTB 0x08000000ul
+/* ? 0x10000000ul */
+#define CFG_ROM_REMAP_2 0x20000000ul
+#define CFG_IDSEL 0x40000000ul
+/* ? 0x80000000ul */
+#define TV_OUT_DATA BlockIOTag(0x27u) /* LTPro */
+#define BUS_CNTL IOPortTag(0x13u, 0x28u)
+#define BUS_WS 0x0000000ful
+#define BUS_DBL_RESYNC 0x00000001ul /* VTB/GTB/LT */
+#define BUS_MSTR_RESET 0x00000002ul /* VTB/GTB/LT */
+#define BUS_FLUSH_BUF 0x00000004ul /* VTB/GTB/LT */
+#define BUS_STOP_REQ_DIS 0x00000008ul /* VTB/GTB/LT */
+#define BUS_ROM_WS 0x000000f0ul
+#define BUS_APER_REG_DIS 0x00000010ul /* VTB/GTB/LT */
+#define BUS_EXTRA_PIPE_DIS 0x00000020ul /* VTB/GTB/LT */
+#define BUS_MASTER_DIS 0x00000040ul /* VTB/GTB/LT */
+#define BUS_ROM_WRT_EN 0x00000080ul /* GTPro */
+#define BUS_ROM_PAGE 0x00000f00ul
+#define BUS_MINOR_REV_ID 0x00000700ul /* LTPro */
+/* First silicom - Prototype (A11) 0x00000000ul */
+/* Metal mask spin (A12 & A13) 0x00000100ul */
+/* All layer spin (A21) 0x00000200ul */
+/* Fast metal spin (A22) - Prod. 0x00000300ul */
+/* All layer spin (A31) 0x00000700ul */
+/* ? 0x00000800ul */ /* LTPro */
+#define BUS_CHIP_HIDDEN_REV 0x00000300ul /* XC/XL */
+/* ? 0x00001c00ul */ /* XC/XL */
+#define BUS_ROM_DIS 0x00001000ul
+#define BUS_IO_16_EN 0x00002000ul /* GX */
+#define BUS_PCI_READ_RETRY_EN 0x00002000ul /* VTB/GTB/LT */
+#define BUS_DAC_SNOOP_EN 0x00004000ul
+#define BUS_PCI_RETRY_EN 0x00008000ul /* VT/GT */
+#define BUS_PCI_WRT_RETRY_EN 0x00008000ul /* VTB/GTB/LT */
+#define BUS_FIFO_WS 0x000f0000ul
+#define BUS_RETRY_WS 0x000f0000ul /* VTB/GTB/LT */
+#define BUS_FIFO_ERR_INT_EN 0x00100000ul
+#define BUS_MSTR_RD_MULT 0x00100000ul /* VTB/GTB/LT */
+#define BUS_FIFO_ERR_INT 0x00200000ul
+#define BUS_MSTR_RD_LINE 0x00200000ul /* VTB/GTB/LT */
+#define BUS_HOST_ERR_INT_EN 0x00400000ul
+#define BUS_SUSPEND 0x00400000ul /* GTPro */
+#define BUS_HOST_ERR_INT 0x00800000ul
+#define BUS_LAT16X 0x00800000ul /* GTPro */
+#define BUS_PCI_DAC_WS 0x07000000ul
+#define BUS_RD_DISCARD_EN 0x01000000ul /* VTB/GTB/LT */
+#define BUS_RD_ABORT_EN 0x02000000ul /* VTB/GTB/LT */
+#define BUS_MSTR_WS 0x04000000ul /* VTB/GTB/LT */
+#define BUS_PCI_DAC_DLY 0x08000000ul
+#define BUS_EXT_REG_EN 0x08000000ul /* VT/GT */
+#define BUS_PCI_MEMW_WS 0x10000000ul
+#define BUS_MSTR_DISCONNECT_EN 0x10000000ul /* VTB/GTB/LT */
+#define BUS_PCI_BURST_DEC 0x20000000ul /* GX/CX */
+#define BUS_BURST 0x20000000ul /* 264xT */
+#define BUS_WRT_BURST 0x20000000ul /* VTB/GTB/LT */
+#define BUS_RDY_READ_DLY 0xc0000000ul
+#define BUS_READ_BURST 0x40000000ul /* VTB/GTB/LT */
+#define BUS_RDY_READ_DLY_B 0x80000000ul /* VTB/GTB/LT */
+#define LCD_INDEX BlockIOTag(0x29u) /* LTPro */
+#define LCD_REG_INDEX 0x0000003ful
+/* ? 0x000000c0ul */
+#define LCD_DISPLAY_DIS 0x00000100ul
+#define LCD_SRC_SEL 0x00000200ul
+#define LCD_SRC_SEL_CRTC1 0x00000000ul
+#define LCD_SRC_SEL_CRTC2 0x00000200ul
+#define LCD_CRTC2_DISPLAY_DIS 0x00000400ul
+#define LCD_GUI_ACTIVE 0x00000800ul /* XC/XL */
+/* ? 0x00fff000ul */
+#define LCD_MONDET_SENSE 0x01000000ul /* XC/XL */
+#define LCD_MONDET_INT_POL 0x02000000ul /* XC/XL */
+#define LCD_MONDET_INT_EN 0x04000000ul /* XC/XL */
+#define LCD_MONDET_INT 0x08000000ul /* XC/XL */
+#define LCD_MONDET_EN 0x10000000ul /* XC/XL */
+#define LCD_EN_PL 0x20000000ul /* XC/XL */
+/* ? 0xc0000000ul */
+#define HFB_PITCH_ADDR BlockIOTag(0x2au) /* LT */
+#define LCD_DATA BlockIOTag(0x2au) /* LTPro */
+#define EXT_MEM_CNTL BlockIOTag(0x2bu) /* VTB/GTB/LT */
+#define MEM_CNTL IOPortTag(0x14u, 0x2cu)
+#define CTL_MEM_SIZE 0x00000007ul
+/* ? 0x00000008ul */
+#define CTL_MEM_REFRESH 0x00000078ul /* VT/GT */
+#define CTL_MEM_SIZEB 0x0000000ful /* VTB/GTB/LT */
+#define CTL_MEM_RD_LATCH_EN 0x00000010ul
+#define CTL_MEM_RD_LATCH_DLY 0x00000020ul
+#define CTL_MEM_LATENCY 0x00000030ul /* VTB/GTB/LT */
+#define CTL_MEM_SD_LATCH_EN 0x00000040ul
+#define CTL_MEM_SD_LATCH_DLY 0x00000080ul
+#define CTL_MEM_LATCH 0x000000c0ul /* VTB/GTB/LT */
+#define CTL_MEM_WDOE_CNTL 0x000000c0ul /* XC/XL */
+#define CTL_MEM_FULL_PLS 0x00000100ul
+#define CTL_MEM_CYC_LNTH_AUX 0x00000180ul /* VT/GT */
+#define CTL_MEM_TRP 0x00000300ul /* VTB/GTB/LT */
+#define CTL_MEM_CYC_LNTH 0x00000600ul
+#define CTL_MEM_REFRESH_RATE 0x00001800ul /* 264xT */
+#define CTL_MEM_TRCD 0x00000c00ul /* VTB/GTB/LT */
+#define CTL_MEM_WR_RDY_SEL 0x00000800ul /* GX/CX */
+#define CTL_MEM_EXT_RMW_CYC_EN 0x00001000ul /* GX/CX */
+#define CTL_MEM_TCRD 0x00001000ul /* VTB/GTB/LT */
+#define CTL_MEM_DLL_RESET 0x00002000ul /* VT/GT */
+#define CTL_MEM_TR2W 0x00002000ul /* GTPro */
+#define CTL_MEM_ACTV_PRE 0x0000c000ul /* VT/GT */
+#define CTL_MEM_CAS_PHASE 0x00004000ul /* GTPro */
+#define CTL_MEM_OE_PULLBACK 0x00008000ul /* GTPro */
+#define CTL_MEM_TWR 0x0000c000ul /* XC/XL */
+#define CTL_MEM_BNDRY 0x00030000ul
+#define CTL_MEM_BNDRY_0K 0x00000000ul
+#define CTL_MEM_BNDRY_256K 0x00010000ul
+#define CTL_MEM_BNDRY_512K 0x00020000ul
+#define CTL_MEM_BNDRY_1024K 0x00030000ul
+#define CTL_MEM_DLL_GAIN_CNTL 0x00030000ul /* VT/GT */
+#define CTL_MEM_BNDRY_EN 0x00040000ul
+#define CTL_MEM_SDRAM_RESET 0x00040000ul /* VT/GT */
+#define CTL_MEM_TRAS 0x00070000ul /* VTB/GTB/LT */
+#define CTL_MEM_TILE_SELECT 0x00180000ul /* VT/GT */
+#define CTL_MEM_REFRESH_DIS 0x00080000ul /* VTB/GTB/LT */
+#define CTL_MEM_LOW_LATENCY_MODE 0x00200000ul /* VT/GT */
+#define CTL_MEM_CDE_PULLBACK 0x00400000ul /* VT/GT */
+#define CTL_MEM_REFRESH_RATE_B 0x00f00000ul /* VTB/GTB/LT */
+#define CTL_MEM_PIX_WIDTH 0x07000000ul
+#define CTL_MEM_LOWER_APER_ENDIAN 0x03000000ul /* VTB/GTB/LT */
+#define CTL_MEM_OE_SELECT 0x18000000ul /* VT/GT */
+#define CTL_MEM_UPPER_APER_ENDIAN 0x0c000000ul /* VTB/GTB/LT */
+/* ? 0xe0000000ul */
+#define CTL_MEM_PAGE_SIZE 0x30000000ul /* VTB/GTB/LT */
+#define MEM_VGA_WP_SEL IOPortTag(0x15u, 0x2du)
+#define MEM_VGA_WPS0 0x0000fffful
+#define MEM_VGA_WPS1 0xffff0000ul
+#define MEM_VGA_RP_SEL IOPortTag(0x16u, 0x2eu)
+#define MEM_VGA_RPS0 0x0000fffful
+#define MEM_VGA_RPS1 0xffff0000ul
+#define LT_GIO BlockIOTag(0x2fu) /* LT */
+#define I2C_CNTL_1 BlockIOTag(0x2fu) /* GTPro */
+#define I2C_DATA_PORT 0x000000fful
+#define I2C_DATA_COUNT 0x0000ff00ul
+#define I2C_ADDR_COUNT 0x00070000ul
+/* ? 0x00380000ul */
+#define I2C_SEL 0x00400000ul
+/* ? 0x00800000ul */
+#define I2C_TIME_LIMIT 0xff000000ul
+#define DAC_REGS IOPortTag(0x17u, 0x30u) /* 4 separate bytes */
+#define M64_DAC_WRITE (DAC_REGS + 0)
+#define M64_DAC_DATA (DAC_REGS + 1)
+#define M64_DAC_MASK (DAC_REGS + 2)
+#define M64_DAC_READ (DAC_REGS + 3)
+#define DAC_CNTL IOPortTag(0x18u, 0x31u)
+#define DAC_EXT_SEL 0x00000003ul
+#define DAC_EXT_SEL_RS2 0x000000001ul
+#define DAC_EXT_SEL_RS3 0x000000002ul
+#define DAC_RANGE_CTL 0x00000003ul /* VTB/GTB/LT */
+#define DAC_BLANKING 0x00000004ul /* 264xT */
+#define DAC_CMP_DIS 0x00000008ul /* 264xT */
+#define DAC1_CLK_SEL 0x00000010ul /* LTPro */
+#define DAC_PALETTE_ACCESS_CNTL 0x00000020ul /* LTPro */
+#define DAC_PALETTE2_SNOOP_EN 0x00000040ul /* LTPro */
+#define DAC_CMP_OUTPUT 0x00000080ul /* 264xT */
+#define DAC_8BIT_EN 0x00000100ul
+#define DAC_PIX_DLY 0x00000600ul
+#define DAC_DIRECT 0x00000400ul /* VTB/GTB/LT */
+#define DAC_BLANK_ADJ 0x00001800ul
+#define DAC_PAL_CLK_SEL 0x00000800ul /* VTB/GTB/LT */
+#define DAC_CRT_SENSE 0x00000800ul /* XC/XL */
+#define DAC_CRT_DETECTION_ON 0x00001000ul /* XC/XL */
+#define DAC_VGA_ADR_EN 0x00002000ul
+#define DAC_FEA_CON_EN 0x00004000ul /* 264xT */
+#define DAC_PDMN 0x00008000ul /* 264xT */
+#define DAC_TYPE 0x00070000ul
+/* ? 0x00f80000ul */
+#define DAC_MON_ID_STATE0 0x01000000ul /* GX-E+/CX */
+#define DAC_GIO_STATE_1 0x01000000ul /* 264xT */
+#define DAC_MON_ID_STATE1 0x02000000ul /* GX-E+/CX */
+#define DAC_GIO_STATE_0 0x02000000ul /* 264xT */
+#define DAC_MON_ID_STATE2 0x04000000ul /* GX-E+/CX */
+#define DAC_GIO_STATE_4 0x04000000ul /* 264xT */
+#define DAC_MON_ID_DIR0 0x08000000ul /* GX-E+/CX */
+#define DAC_GIO_DIR_1 0x08000000ul /* 264xT */
+#define DAC_MON_ID_DIR1 0x10000000ul /* GX-E+/CX */
+#define DAC_GIO_DIR_0 0x10000000ul /* 264xT */
+#define DAC_MON_ID_DIR2 0x20000000ul /* GX-E+/CX */
+#define DAC_GIO_DIR_4 0x20000000ul /* 264xT */
+#define DAC_MAN_CMP_STATE 0x40000000ul /* GX-E+ */
+#define DAC_RW_WS 0x80000000ul /* VT/GT */
+#define HORZ_STRETCHING BlockIOTag(0x32u) /* LT */
+#define HORZ_STRETCH_BLEND 0x00000ffful
+#define HORZ_STRETCH_RATIO 0x0000fffful
+#define HORZ_STRETCH_LOOP 0x00070000ul
+#define HORZ_STRETCH_LOOP09 0x00000000ul
+#define HORZ_STRETCH_LOOP11 0x00010000ul
+#define HORZ_STRETCH_LOOP12 0x00020000ul
+#define HORZ_STRETCH_LOOP14 0x00030000ul
+#define HORZ_STRETCH_LOOP15 0x00040000ul
+/* ? 0x00050000ul */
+/* ? 0x00060000ul */
+/* ? 0x00070000ul */
+/* ? 0x00080000ul */
+#define HORZ_PANEL_SIZE 0x0ff00000ul /* XC/XL */
+/* ? 0x10000000ul */
+#define AUTO_HORZ_RATIO 0x20000000ul /* XC/XL */
+#define HORZ_STRETCH_MODE 0x40000000ul
+#define HORZ_STRETCH_EN 0x80000000ul
+#define EXT_DAC_REGS BlockIOTag(0x32u) /* GTPro */
+#define EXT_DAC_REG_SEL 0x0000000ful
+/* ? 0x000000f0ul */
+#define EXT_DAC_DATA 0x0000ff00ul
+#define EXT_DAC_EN 0x00010000ul
+#define EXT_DAC_WID 0x00020000ul
+/* ? 0xfffc0000ul */
+#define VERT_STRETCHING BlockIOTag(0x33u) /* LT */
+#define VERT_STRETCH_RATIO0 0x000003fful
+#define VERT_STRETCH_RATIO1 0x000ffc00ul
+#define VERT_STRETCH_RATIO2 0x3ff00000ul
+#define VERT_STRETCH_USE0 0x40000000ul
+#define VERT_STRETCH_EN 0x80000000ul
+#define GEN_TEST_CNTL IOPortTag(0x19u, 0x34u)
+#define GEN_EE_DATA_OUT 0x00000001ul /* GX/CX */
+#define GEN_GIO2_DATA_OUT 0x00000001ul /* 264xT */
+#define GEN_EE_CLOCK 0x00000002ul /* GX/CX */
+/* ? 0x00000002ul */ /* 264xT */
+#define GEN_EE_CHIP_SEL 0x00000004ul /* GX/CX */
+#define GEN_GIO3_DATA_OUT 0x00000004ul /* 264xT */
+#define GEN_EE_DATA_IN 0x00000008ul /* GX/CX */
+#define GEN_GIO2_DATA_IN 0x00000008ul /* 264xT */
+#define GEN_EE_EN 0x00000010ul /* GX/CX */
+#define GEN_GIO2_ENABLE 0x00000010ul /* 264xT */
+#define GEN_ICON2_ENABLE 0x00000010ul /* XC/XL */
+#define GEN_OVR_OUTPUT_EN 0x00000020ul /* GX/CX */
+#define GEN_GIO2_WRITE 0x00000020ul /* 264xT */
+#define GEN_CUR2_ENABLE 0x00000020ul /* XC/XL */
+#define GEN_OVR_POLARITY 0x00000040ul /* GX/CX */
+#define GEN_ICON_ENABLE 0x00000040ul /* XC/XL */
+#define GEN_CUR_EN 0x00000080ul
+#define GEN_GUI_EN 0x00000100ul /* GX/CX */
+#define GEN_GUI_RESETB 0x00000100ul /* 264xT */
+#define GEN_BLOCK_WR_EN 0x00000200ul /* GX */
+/* ? 0x00000200ul */ /* CX/264xT */
+#define GEN_SOFT_RESET 0x00000200ul /* VTB/GTB/LT */
+#define GEN_MEM_TRISTATE 0x00000400ul /* GTPro */
+/* ? 0x00000800ul */
+#define GEN_TEST_VECT_MODE 0x00003000ul /* VT/GT */
+/* ? 0x0000c000ul */
+#define GEN_TEST_FIFO_EN 0x00010000ul /* GX/CX */
+#define GEN_TEST_GUI_REGS_EN 0x00020000ul /* GX/CX */
+#define GEN_TEST_VECT_EN 0x00040000ul /* GX/CX */
+#define GEN_TEST_CRC_STR 0x00080000ul /* GX-C/-D */
+/* ? 0x00080000ul */ /* GX-E+/CX */
+#define GEN_TEST_MODE_T 0x000f0000ul /* 264xT */
+#define GEN_TEST_MODE 0x00700000ul /* GX/CX */
+#define GEN_TEST_CNT_EN 0x00100000ul /* 264xT */
+#define GEN_TEST_CRC_EN 0x00200000ul /* 264xT */
+/* ? 0x00400000ul */ /* 264xT */
+/* ? 0x00800000ul */
+#define GEN_TEST_MEM_WR 0x01000000ul /* GX-C/-D */
+#define GEN_TEST_MEM_STROBE 0x02000000ul /* GX-C/-D */
+#define GEN_TEST_DST_SS_EN 0x04000000ul /* GX/CX */
+#define GEN_TEST_DST_SS_STROBE 0x08000000ul /* GX/CX */
+#define GEN_TEST_SRC_SS_EN 0x10000000ul /* GX/CX */
+#define GEN_TEST_SRC_SS_STROBE 0x20000000ul /* GX/CX */
+#define GEN_TEST_CNT_VALUE 0x3f000000ul /* 264xT */
+#define GEN_TEST_CC_EN 0x40000000ul /* GX/CX */
+#define GEN_TEST_CC_STROBE 0x80000000ul /* GX/CX */
+/* ? 0xc0000000ul */ /* 264xT */
+#define GEN_DEBUG_MODE 0xff000000ul /* VTB/GTB/LT */
+#define LCD_GEN_CTRL BlockIOTag(0x35u) /* LT */
+#define CRT_ON 0x00000001ul
+#define LCD_ON 0x00000002ul
+#define HORZ_DIVBY2_EN 0x00000004ul
+#define TRISTATE_MEM_EN 0x00000008ul
+#define DONT_DS_ICON 0x00000008ul /* LTPro */
+#define LOCK_8DOT 0x00000010ul
+#define ICON_ENABLE 0x00000020ul
+#define DONT_SHADOW_VPAR 0x00000040ul
+#define TOGGLE_EN 0x00000080ul
+#define V2CLK_PM_EN 0x00000080ul /* LTPro */
+#define RST_FM 0x00000100ul
+#define DISABLE_PCLK_RESET 0x00000200ul /* XC/XL */
+#define DIS_HOR_CRT_DIVBY2 0x00000400ul
+#define SCLK_SEL 0x00000800ul
+#define SCLK_DELAY 0x0000f000ul
+#define MCLK_PM_EN 0x00010000ul
+#define TVCLK_PM_EN 0x00010000ul /* LTPro */
+#define VCLK_DAC_PM_EN 0x00020000ul
+#define VCLK_LCD_OFF 0x00040000ul
+#define SLOWDOWN_XMCLK 0x00080000ul
+#define SELECT_WAIT_4MS 0x00080000ul /* LTPro */
+#define XTALIN_PM_EN 0x00080000ul /* XC/XL */
+#define LCD_CLK_RATIO 0x00100000ul
+#define V2CLK_DAC_PM_EN 0x00100000ul /* LTPro */
+#define LVDS_EN 0x00200000ul
+#define LVDS_PLL_EN 0x00400000ul
+#define LVDS_PLL_RESET 0x00800000ul
+#define LVDS_RESERVED_BITS 0x07000000ul
+#define CRTC_RW_SELECT 0x08000000ul /* LTPro */
+#define USE_SHADOWED_VEND 0x10000000ul
+#define USE_SHADOWED_ROWCUR 0x20000000ul
+#define SHADOW_EN 0x40000000ul
+#define SHADOW_RW_EN 0x80000000ul
+#define CUSTOM_MACRO_CNTL BlockIOTag(0x35u) /* GTPro */
+#define POWER_MANAGEMENT BlockIOTag(0x36u) /* LT */
+#define PWR_MGT_ON 0x00000001ul
+#define PWR_MGT_MODE 0x00000006ul
+#define AUTO_PWRUP_EN 0x00000008ul
+#define ACTIVITY_PIN_ON 0x00000010ul
+#define STANDBY_POL 0x00000020ul
+#define SUSPEND_POL 0x00000040ul
+#define SELF_REFRESH 0x00000080ul
+#define ACTIVITY_PIN_EN 0x00000100ul
+#define KEYBD_SNOOP 0x00000200ul
+#define USE_F32KHZ 0x00000400ul /* LTPro */
+#define DONT_USE_XTALIN 0x00000400ul /* XC/XL */
+#define TRISTATE_MEM_EN_P 0x00000800ul /* LTPro */
+#define LCDENG_TEST_MODE 0x0000f000ul
+#define STANDBY_COUNT 0x000f0000ul
+#define SUSPEND_COUNT 0x00f00000ul
+#define BAISON 0x01000000ul
+#define BLON 0x02000000ul
+#define DIGON 0x04000000ul
+#define PM_D3_SUPPORT_ENABLE 0x08000000ul /* XC/XL */
+#define STANDBY_NOW 0x10000000ul
+#define SUSPEND_NOW 0x20000000ul
+#define PWR_MGT_STATUS 0xc0000000ul
+#define CONFIG_CNTL IOPortTag(0x1au, 0x37u)
+#define CFG_MEM_AP_SIZE 0x00000003ul
+#define CFG_MEM_VGA_AP_EN 0x00000004ul
+/* ? 0x00000008ul */
+#define CFG_MEM_AP_LOC 0x00003ff0ul
+/* ? 0x0000c000ul */
+#define CFG_CARD_ID 0x00070000ul
+#define CFG_VGA_DIS 0x00080000ul
+/* ? 0x00f00000ul */
+#define CFG_CDE_WINDOW 0x3f000000ul /* VT/GT */
+/* ? 0xc0000000ul */
+#define CONFIG_CHIP_ID IOPortTag(0x1bu, 0x38u) /* Read */
+#define CFG_CHIP_TYPE0 0x000000fful
+#define CFG_CHIP_TYPE1 0x0000ff00ul
+#define CFG_CHIP_TYPE 0x0000fffful
+#define CFG_CHIP_CLASS 0x00ff0000ul
+#define CFG_CHIP_REV 0xff000000ul
+#define CFG_CHIP_VERSION 0x07000000ul /* 264xT */
+#define CFG_CHIP_FOUNDRY 0x38000000ul /* 264xT */
+#define CFG_CHIP_REVISION 0xc0000000ul /* 264xT */
+#define CONFIG_STATUS64_0 IOPortTag(0x1cu, 0x39u) /* Read (R/W (264xT)) */
+#define CFG_BUS_TYPE 0x00000007ul /* GX/CX */
+#define CFG_MEM_TYPE_T 0x00000007ul /* 264xT */
+#define CFG_MEM_TYPE 0x00000038ul /* GX/CX */
+#define CFG_DUAL_CAS_EN_T 0x00000008ul /* 264xT */
+#define CFG_ROM_128K_EN 0x00000008ul /* VTB/GTB/LT */
+#define CFG_ROM_REMAP 0x00000008ul /* GTPro */
+#define CFG_VGA_EN_T 0x00000010ul /* VT/GT */
+#define CFG_CLOCK_EN 0x00000020ul /* 264xT */
+#define CFG_DUAL_CAS_EN 0x00000040ul /* GX/CX */
+#define CFG_VMC_SENSE 0x00000040ul /* VT/GT */
+#define CFG_SHARED_MEM_EN 0x00000040ul /* VTB/GTB/LT */
+#define CFG_LOCAL_BUS_OPTION 0x00000180ul /* GX/CX */
+#define CFG_VFC_SENSE 0x00000080ul /* VT/GT */
+#define CFG_INIT_DAC_TYPE 0x00000e00ul /* GX/CX */
+#define CFG_INIT_CARD_ID 0x00007000ul /* GX-C/-D */
+#define CFG_BLK_WR_SIZE 0x00001000ul /* GX-E+ */
+#define CFG_INT_QSF_EN 0x00002000ul /* GX-E+ */
+/* ? 0x00004000ul */ /* GX-E+ */
+/* ? 0x00007000ul */ /* CX */
+#define CFG_TRI_BUF_DIS 0x00008000ul /* GX/CX */
+#define CFG_BOARD_ID 0x0000ff00ul /* VT/GT */
+#define CFG_EXT_RAM_ADDR 0x003f0000ul /* GX/CX */
+#define CFG_PANEL_ID 0x001f0000ul /* LT */
+#define CFG_MACROVISION_EN 0x00200000ul /* GTPro */
+#define CFG_ROM_DIS 0x00400000ul /* GX/CX */
+#define CFG_PCI33EN 0x00400000ul /* GTPro */
+#define CFG_VGA_EN 0x00800000ul /* GX/CX */
+#define CFG_FULLAGP 0x00800000ul /* GTPro */
+#define CFG_ARITHMOS_ENABLE 0x00800000ul /* XC/XL */
+#define CFG_LOCAL_BUS_CFG 0x01000000ul /* GX/CX */
+#define CFG_CHIP_EN 0x02000000ul /* GX/CX */
+#define CFG_LOCAL_READ_DLY_DIS 0x04000000ul /* GX/CX */
+#define CFG_ROM_OPTION 0x08000000ul /* GX/CX */
+#define CFG_BUS_OPTION 0x10000000ul /* GX/CX */
+#define CFG_LOCAL_DAC_WR_EN 0x20000000ul /* GX/CX */
+#define CFG_VLB_RDY_DIS 0x40000000ul /* GX/CX */
+#define CFG_AP_4GBYTE_DIS 0x80000000ul /* GX/CX */
+#define CONFIG_STATUS64_1 IOPortTag(0x1du, 0x3au) /* Read */
+#define CFG_PCI_DAC_CFG 0x00000001ul /* GX/CX */
+/* ? 0x0000001eul */ /* GX/CX */
+#define CFG_1C8_IO_SEL 0x00000020ul /* GX/CX */
+/* ? 0xffffffc0ul */ /* GX/CX */
+#define CRC_SIG 0xfffffffful /* 264xT */
+#define MPP_CONFIG BlockIOTag(0x3bu) /* VTB/GTB/LT */
+#define MPP_PRESCALE 0x00000007ul
+/* ? 0x00000008ul */
+#define MPP_NSTATES 0x00000030ul
+/* ? 0x00000000ul */
+#define MPP_NSTATES_2 0x00000010ul
+#define MPP_NSTATES_4 0x00000020ul
+#define MPP_NSTATES_8 0x00000030ul
+#define MPP_FORMAT 0x000000c0ul
+#define MPP_FORMAT_DO8 0x00000000ul
+#define MPP_FORMAT_DO16 0x00000040ul
+#define MPP_FORMAT_DA8 0x00000080ul
+#define MPP_FORMAT_DA16 0x000000c0ul
+#define MPP_WAIT_STATE 0x00000700ul
+#define MPP_CHKRDY_EN 0x00000800ul
+#define MPP_INSERT_WAIT 0x00001000ul
+#define MPP_TRISTATE_ADDR 0x00002000ul
+/* ? 0x00004000ul */
+#define MPP_READ_EARLY 0x00008000ul
+#define MPP_RW_MODE 0x00030000ul
+#define MPP_INT_MASK 0x000c0000ul
+#define MPP_AUTO_INC_EN 0x00300000ul
+#define MPP_CHKREQ_EN 0x00400000ul
+#define MPP_CHKREQ_MODE 0x00800000ul
+#define MPP_BUFFER_SIZE 0x03000000ul
+#define MPP_BUFFER_MODE 0x0c000000ul
+#define MPP_BUFFER_MODE_NORMAL 0x00000000ul
+#define MPP_BUFFER_MODE_PREFETCH 0x04000000ul
+#define MPP_BUFFER_MODE_BUS_MASTER 0x08000000ul
+/* ? 0x0c000000ul */
+/* ? 0x30000000ul */
+#define MPP_BUSY 0x40000000ul
+#define MPP_EN 0x80000000ul
+#define MPP_STROBE_SEQ BlockIOTag(0x3cu) /* VTB/GTB/LT */
+#define MPP_STB0_SEQ 0x000000fful
+#define MPP_STB1_SEQ 0x0000ff00ul
+/* ? 0xffff0000ul */
+#define MPP_ADDR BlockIOTag(0x3du) /* VTB/GTB/LT */
+#define MPP_DATA BlockIOTag(0x3eu) /* VTB/GTB/LT */
+#define TVO_CNTL BlockIOTag(0x3fu) /* VTB/GTB/LT */
+#define TVO_H_TOT_PIX 0x00000007ul
+#define TVO_PC_OVR_DIS 0x00000008ul
+#define TVO_H_TOT_EDGE 0x00000010ul
+/* ? 0x00000060ul */
+#define TVO_VBLANK_ONLY 0x00000080ul
+/* ? 0x0000ff00ul */
+#define TVO_MPEG_CLR_SRC 0x00030000ul
+/* ? 0x1ffc0000ul */
+#define TVO_MPEG_CLK_EN 0x20000000ul
+#define TVO_OVERRIDE_EN 0x40000000ul
+#define TVO_EN 0x80000000ul
+/* GP_IO IOPortTag(0x1eu, 0x1eu) */ /* See above */
+/* CRTC_H_TOTAL_DISP IOPortTag(0x1fu, 0x00u) */ /* Duplicate */
+#define DST_OFF_PITCH BlockIOTag(0x40u)
+#define DST_OFFSET 0x000ffffful
+/* ? 0x00300000ul */
+#define DST_PITCH 0xffc00000ul
+#define DST_X BlockIOTag(0x41u)
+#define DST_Y BlockIOTag(0x42u)
+#define DST_Y_X BlockIOTag(0x43u)
+#define DST_WIDTH BlockIOTag(0x44u)
+#define DST_HEIGHT BlockIOTag(0x45u)
+#define DST_HEIGHT_WIDTH BlockIOTag(0x46u)
+#define DST_X_WIDTH BlockIOTag(0x47u)
+#define DST_BRES_LNTH BlockIOTag(0x48u)
+#define DST_BRES_ERR BlockIOTag(0x49u)
+#define DST_BRES_INC BlockIOTag(0x4au)
+#define DST_BRES_DEC BlockIOTag(0x4bu)
+#define DST_CNTL BlockIOTag(0x4cu)
+#define DST_X_DIR 0x00000001ul
+#define DST_Y_DIR 0x00000002ul
+#define DST_Y_MAJOR 0x00000004ul
+#define DST_X_TILE 0x00000008ul
+#define DST_Y_TILE 0x00000010ul
+#define DST_LAST_PEL 0x00000020ul
+#define DST_POLYGON_EN 0x00000040ul
+#define DST_24_ROT_EN 0x00000080ul
+#define DST_24_ROT 0x00000700ul
+#define DST_BRES_SIGN 0x00000800ul /* GX/CX */
+#define DST_BRES_ZERO 0x00000800ul /* CT */
+#define DST_POLYGON_RTEDGE_DIS 0x00001000ul /* CT */
+#define TRAIL_X_DIR 0x00002000ul /* GT */
+#define TRAP_FILL_DIR 0x00004000ul /* GT */
+#define TRAIL_BRES_SIGN 0x00008000ul /* GT */
+/* ? 0x00010000ul */
+#define BRES_SIGN_AUTO 0x00020000ul /* GT */
+/* ? 0x00040000ul */
+#define ALPHA_OVERLAP_ENB 0x00080000ul /* GTPro */
+#define SUB_PIX_ON 0x00100000ul /* GTPro */
+/* ? 0xffe00000ul */
+/* DST_Y_X BlockIOTag(0x4du) */ /* Duplicate */
+#define TRAIL_BRES_ERR BlockIOTag(0x4eu) /* GT */
+#define TRAIL_BRES_INC BlockIOTag(0x4fu) /* GT */
+#define TRAIL_BRES_DEC BlockIOTag(0x50u) /* GT */
+#define LEAD_BRES_LNTH BlockIOTag(0x51u) /* GT */
+#define Z_OFF_PITCH BlockIOTag(0x52u) /* GT */
+#define Z_CNTL BlockIOTag(0x53u) /* GT */
+#define ALPHA_TST_CNTL BlockIOTag(0x54u) /* GTPro */
+/* ? BlockIOTag(0x55u) */
+#define SECONDARY_STW_EXP BlockIOTag(0x56u) /* GTPro */
+#define SECONDARY_S_X_INC BlockIOTag(0x57u) /* GTPro */
+#define SECONDARY_S_Y_INC BlockIOTag(0x58u) /* GTPro */
+#define SECONDARY_S_START BlockIOTag(0x59u) /* GTPro */
+#define SECONDARY_W_X_INC BlockIOTag(0x5au) /* GTPro */
+#define SECONDARY_W_Y_INC BlockIOTag(0x5bu) /* GTPro */
+#define SECONDARY_W_START BlockIOTag(0x5cu) /* GTPro */
+#define SECONDARY_T_X_INC BlockIOTag(0x5du) /* GTPro */
+#define SECONDARY_T_Y_INC BlockIOTag(0x5eu) /* GTPro */
+#define SECONDARY_T_START BlockIOTag(0x5fu) /* GTPro */
+#define SRC_OFF_PITCH BlockIOTag(0x60u)
+#define SRC_OFFSET 0x000ffffful
+/* ? 0x00300000ul */
+#define SRC_PITCH 0xffc00000ul
+#define SRC_X BlockIOTag(0x61u)
+#define SRC_Y BlockIOTag(0x62u)
+#define SRC_Y_X BlockIOTag(0x63u)
+#define SRC_WIDTH1 BlockIOTag(0x64u)
+#define SRC_HEIGHT1 BlockIOTag(0x65u)
+#define SRC_HEIGHT1_WIDTH1 BlockIOTag(0x66u)
+#define SRC_X_START BlockIOTag(0x67u)
+#define SRC_Y_START BlockIOTag(0x68u)
+#define SRC_Y_X_START BlockIOTag(0x69u)
+#define SRC_WIDTH2 BlockIOTag(0x6au)
+#define SRC_HEIGHT2 BlockIOTag(0x6bu)
+#define SRC_HEIGHT2_WIDTH2 BlockIOTag(0x6cu)
+#define SRC_CNTL BlockIOTag(0x6du)
+#define SRC_PATT_EN 0x00000001ul
+#define SRC_PATT_ROT_EN 0x00000002ul
+#define SRC_LINEAR_EN 0x00000004ul
+#define SRC_BYTE_ALIGN 0x00000008ul
+#define SRC_LINE_X_DIR 0x00000010ul
+#define SRC_8X8X8_BRUSH 0x00000020ul /* VTB/GTB */
+#define FAST_FILL_EN 0x00000040ul /* VTB/GTB */
+#define SRC_TRACK_DST 0x00000080ul /* VTB/GTB */
+#define BUS_MASTER_EN 0x00000100ul /* VTB/GTB */
+#define BUS_MASTER_SYNC 0x00000200ul /* VTB/GTB */
+#define BUS_MASTER_OP 0x00000c00ul /* VTB/GTB */
+#define SRC_8X8X8_BRUSH_LOADED 0x00001000ul /* VTB/GTB */
+#define COLOR_REG_WRITE_EN 0x00002000ul /* VTB/GTB */
+#define BLOCK_WRITE_EN 0x00004000ul /* VTB/GTB */
+/* ? 0xffff8000ul */
+/* ? BlockIOTag(0x6eu) */
+/* ? BlockIOTag(0x6fu) */
+#define SCALE_Y_OFF BlockIOTag(0x70u) /* GT */
+#define SCALE_OFF BlockIOTag(0x70u) /* GTPro */
+#define SECONDARY_SCALE_OFF BlockIOTag(0x70u) /* GTPro */
+#define TEX_0_OFF BlockIOTag(0x70u) /* GT */
+#define TEX_1_OFF BlockIOTag(0x71u) /* GT */
+#define TEX_2_OFF BlockIOTag(0x72u) /* GT */
+#define TEX_3_OFF BlockIOTag(0x73u) /* GT */
+#define TEX_4_OFF BlockIOTag(0x74u) /* GT */
+#define TEX_5_OFF BlockIOTag(0x75u) /* GT */
+#define TEX_6_OFF BlockIOTag(0x76u) /* GT */
+#define SCALE_WIDTH BlockIOTag(0x77u) /* GT */
+#define TEX_7_OFF BlockIOTag(0x77u) /* GT */
+#define SCALE_HEIGHT BlockIOTag(0x78u) /* GT */
+#define TEX_8_OFF BlockIOTag(0x78u) /* GT */
+#define TEX_9_OFF BlockIOTag(0x79u) /* GT */
+#define TEX_10_OFF BlockIOTag(0x7au) /* GT */
+#define S_Y_INC BlockIOTag(0x7bu) /* GT */
+#define SCALE_Y_PITCH BlockIOTag(0x7bu) /* GT */
+#define SCALE_X_INC BlockIOTag(0x7cu) /* GT */
+#define RED_X_INC BlockIOTag(0x7cu) /* GT */
+#define GREEN_X_INC BlockIOTag(0x7du) /* GT */
+#define SCALE_Y_INC BlockIOTag(0x7du) /* GT */
+#define SCALE_VACC BlockIOTag(0x7eu) /* GT */
+#define SCALE_3D_CNTL BlockIOTag(0x7fu) /* GT */
+#define HOST_DATA_0 BlockIOTag(0x80u)
+#define HOST_DATA_1 BlockIOTag(0x81u)
+#define HOST_DATA_2 BlockIOTag(0x82u)
+#define HOST_DATA_3 BlockIOTag(0x83u)
+#define HOST_DATA_4 BlockIOTag(0x84u)
+#define HOST_DATA_5 BlockIOTag(0x85u)
+#define HOST_DATA_6 BlockIOTag(0x86u)
+#define HOST_DATA_7 BlockIOTag(0x87u)
+#define HOST_DATA_8 BlockIOTag(0x88u)
+#define HOST_DATA_9 BlockIOTag(0x89u)
+#define HOST_DATA_A BlockIOTag(0x8au)
+#define HOST_DATA_B BlockIOTag(0x8bu)
+#define HOST_DATA_C BlockIOTag(0x8cu)
+#define HOST_DATA_D BlockIOTag(0x8du)
+#define HOST_DATA_E BlockIOTag(0x8eu)
+#define HOST_DATA_F BlockIOTag(0x8fu)
+#define HOST_CNTL BlockIOTag(0x90u)
+#define HOST_BYTE_ALIGN 0x00000001ul
+#define HOST_BIG_ENDIAN_EN 0x00000002ul /* GX-E/CT */
+/* ? 0xfffffffcul */
+#define BM_HOSTDATA BlockIOTag(0x91u) /* VTB/GTB */
+#define BM_ADDR BlockIOTag(0x92u) /* VTB/GTB */
+#define BM_DATA BlockIOTag(0x92u) /* VTB/GTB */
+#define BM_GUI_TABLE_CMD BlockIOTag(0x93u) /* GTPro */
+/* ? BlockIOTag(0x94u) */
+/* ? BlockIOTag(0x95u) */
+/* ? BlockIOTag(0x96u) */
+/* ? BlockIOTag(0x97u) */
+/* ? BlockIOTag(0x98u) */
+/* ? BlockIOTag(0x99u) */
+/* ? BlockIOTag(0x9au) */
+/* ? BlockIOTag(0x9bu) */
+/* ? BlockIOTag(0x9cu) */
+/* ? BlockIOTag(0x9du) */
+/* ? BlockIOTag(0x9eu) */
+/* ? BlockIOTag(0x9fu) */
+#define PAT_REG0 BlockIOTag(0xa0u)
+#define PAT_REG1 BlockIOTag(0xa1u)
+#define PAT_CNTL BlockIOTag(0xa2u)
+#define PAT_MONO_EN 0x00000001ul
+#define PAT_CLR_4x2_EN 0x00000002ul
+#define PAT_CLR_8x1_EN 0x00000004ul
+/* ? 0xfffffff8ul */
+/* ? BlockIOTag(0xa3u) */
+/* ? BlockIOTag(0xa4u) */
+/* ? BlockIOTag(0xa5u) */
+/* ? BlockIOTag(0xa6u) */
+/* ? BlockIOTag(0xa7u) */
+#define SC_LEFT BlockIOTag(0xa8u)
+#define SC_RIGHT BlockIOTag(0xa9u)
+#define SC_LEFT_RIGHT BlockIOTag(0xaau)
+#define SC_TOP BlockIOTag(0xabu)
+#define SC_BOTTOM BlockIOTag(0xacu)
+#define SC_TOP_BOTTOM BlockIOTag(0xadu)
+#define USR1_DST_OFF_PITCH BlockIOTag(0xaeu) /* LTPro */
+#define USR2_DST_OFF_PITCH BlockIOTag(0xafu) /* LTPro */
+#define DP_BKGD_CLR BlockIOTag(0xb0u)
+#define DP_FRGD_CLR BlockIOTag(0xb1u)
+#define DP_WRITE_MASK BlockIOTag(0xb2u)
+#define DP_CHAIN_MASK BlockIOTag(0xb3u)
+#define DP_CHAIN_1BPP 0x00000000ul /* Irrelevant */
+#define DP_CHAIN_4BPP 0x00008888ul
+#define DP_CHAIN_8BPP 0x00008080ul
+#define DP_CHAIN_8BPP_332 0x00009292ul
+#define DP_CHAIN_15BPP_1555 0x00004210ul
+#define DP_CHAIN_16BPP_565 0x00008410ul
+#define DP_CHAIN_24BPP_888 0x00008080ul
+#define DP_CHAIN_32BPP_8888 0x00008080ul
+/* ? 0xffff0000ul */
+#define DP_PIX_WIDTH BlockIOTag(0xb4u)
+#define DP_DST_PIX_WIDTH 0x0000000ful
+#define COMPOSITE_PIX_WIDTH 0x000000f0ul /* GTPro */
+#define DP_SRC_PIX_WIDTH 0x00000f00ul
+/* ? 0x00001000ul */
+#define DP_HOST_TRIPLE_EN 0x00002000ul /* GT2c/VT4 */
+#define DP_SRC_AUTONA_FIX_DIS 0x00004000ul /* GTB */
+#define DP_FAST_SRCCOPY_DIS 0x00008000ul /* GTB */
+#define DP_HOST_PIX_WIDTH 0x000f0000ul
+#define DP_CI4_RGB_INDEX 0x00f00000ul /* GTB */
+#define DP_BYTE_PIX_ORDER 0x01000000ul
+#define DP_CONVERSION_TEMP 0x02000000ul /* GTB */
+#define DP_CI4_RGB_LOW_NIBBLE 0x04000000ul /* GTB */
+#define DP_C14_RGB_HIGH_NIBBLE 0x08000000ul /* GTB */
+#define DP_SCALE_PIX_WIDTH 0xf0000000ul /* GTB */
+#define DP_MIX BlockIOTag(0xb5u)
+#define DP_BKGD_MIX 0x0000001ful
+/* ? 0x0000ffe0ul */
+#define DP_FRGD_MIX 0x001f0000ul
+/* ? 0xffe00000ul */
+#define DP_SRC BlockIOTag(0xb6u)
+#define DP_BKGD_SRC 0x00000007ul
+/* ? 0x000000feul */
+#define DP_FRGD_SRC 0x00000700ul
+/* ? 0x0000fe00ul */
+#define DP_MONO_SRC 0x00030000ul
+#define DP_MONO_SRC_ALLONES 0x00000000ul
+#define DP_MONO_SRC_PATTERN 0x00010000ul
+#define DP_MONO_SRC_HOST 0x00020000ul
+#define DP_MONO_SRC_BLIT 0x00030000ul
+/* ? 0xfffc0000ul */
+#define DP_FRGD_CLR_MIX BlockIOTag(0xb7u) /* VTB/GTB */
+#define DP_FRGD_BKGD_CLR BlockIOTag(0xb8u) /* VTB/GTB */
+/* ? BlockIOTag(0xb9u) */
+#define DST_X_Y BlockIOTag(0xbau) /* VTB/GTB */
+#define DST_WIDTH_HEIGHT BlockIOTag(0xbbu) /* VTB/GTB */
+#define USR_DST_PITCH BlockIOTag(0xbcu) /* GTPro */
+/* ? BlockIOTag(0xbdu) */
+#define DP_SET_GUI_ENGINE2 BlockIOTag(0xbeu) /* GTPro */
+#define DP_SET_GUI_ENGINE BlockIOTag(0xbfu) /* VTB/GTB */
+#define CLR_CMP_CLR BlockIOTag(0xc0u)
+#define CLR_CMP_MSK BlockIOTag(0xc1u)
+#define CLR_CMP_CNTL BlockIOTag(0xc2u)
+#define CLR_CMP_FN 0x00000007ul
+#define CLR_CMP_FN_FALSE 0x00000000ul
+#define CLR_CMP_FN_TRUE 0x00000001ul
+/* ? 0x00000002ul */
+/* ? 0x00000003ul */
+#define CLR_CMP_FN_NOT_EQUAL 0x00000004ul
+#define CLR_CMP_FN_EQUAL 0x00000005ul
+/* ? 0x00000006ul */
+/* ? 0x00000007ul */
+/* ? 0x00fffff8ul */
+#define CLR_CMP_SRC 0x03000000ul
+#define CLR_CMP_SRC_DST 0x00000000ul
+#define CLR_CMP_SRC_2D 0x01000000ul
+#define CLR_CMP_SRC_TEXEL 0x02000000ul
+/* ? 0x03000000ul */
+/* ? 0xfc000000ul */
+/* ? BlockIOTag(0xc3u) */
+#define FIFO_STAT BlockIOTag(0xc4u)
+#define FIFO_STAT_BITS 0x0000fffful
+/* ? 0x7fff0000ul */
+#define FIFO_ERR 0x80000000ul
+/* ? BlockIOTag(0xc5u) */
+/* ? BlockIOTag(0xc6u) */
+/* ? BlockIOTag(0xc7u) */
+#define CONTEXT_MASK BlockIOTag(0xc8u)
+/* ? BlockIOTag(0xc9u) */
+/* ? BlockIOTag(0xcau) */
+#define CONTEXT_LOAD_CNTL BlockIOTag(0xcbu)
+#define CONTEXT_LOAD_PTR 0x00007ffful
+/* ? 0x00008000ul */
+#define CONTEXT_LOAD_CMD 0x00030000ul
+#define CONTEXT_LOAD_NONE 0x00000000ul
+#define CONTEXT_LOAD_ONLY 0x00010000ul
+#define CONTEXT_LOAD_FILL 0x00020000ul
+#define CONTEXT_LOAD_LINE 0x00030000ul
+/* ? 0x7ffc0000ul */
+#define CONTEXT_LOAD_DIS 0x80000000ul
+#define GUI_TRAJ_CNTL BlockIOTag(0xccu)
+/* ? BlockIOTag(0xcdu) */
+#define GUI_STAT BlockIOTag(0xceu)
+#define GUI_ACTIVE 0x00000001ul
+/* ? 0x000000feul */
+#define DSTX_LT_SCISSOR_LEFT 0x00000100ul
+#define DSTX_GT_SCISSOR_RIGHT 0x00000200ul
+#define DSTY_LT_SCISSOR_TOP 0x00000400ul
+#define DSTY_GT_SCISSOR_BOTTOM 0x00000800ul
+/* ? 0x0000f000ul */
+#define GUI_FIFO 0x03ff0000ul /* VTB/GTB */
+/* ? 0xfc000000ul */
+/* ? BlockIOTag(0xcfu) */
+#define S_X_INC2 BlockIOTag(0xd0u) /* GTB */
+#define TEX_PALETTE_INDEX BlockIOTag(0xd0u) /* GTPro */
+#define S_Y_INC2 BlockIOTag(0xd1u) /* GTB */
+#define STW_EXP BlockIOTag(0xd1u) /* GTPro */
+#define S_XY_INC2 BlockIOTag(0xd2u) /* GTB */
+#define LOG_MAX_INC BlockIOTag(0xd2u) /* GTPro */
+#define S_XINC_START BlockIOTag(0xd3u) /* GTB */
+/* S_Y_INC BlockIOTag(0xd4u) */ /* Duplicate */
+/* SCALE_Y_PITCH BlockIOTag(0xd4u) */ /* Duplicate */
+#define S_START BlockIOTag(0xd5u) /* GTB */
+#define T_X_INC2 BlockIOTag(0xd6u) /* GTB */
+#define W_X_INC BlockIOTag(0xd6u) /* GTPro */
+#define T_Y_INC2 BlockIOTag(0xd7u) /* GTB */
+#define W_Y_INC BlockIOTag(0xd7u) /* GTPro */
+#define T_XY_INC2 BlockIOTag(0xd8u) /* GTB */
+#define W_START BlockIOTag(0xd8u) /* GTPro */
+#define T_XINC_START BlockIOTag(0xd9u) /* GTB */
+#define T_Y_INC BlockIOTag(0xdau) /* GTB */
+#define SECONDARY_SCALE_PITCH BlockIOTag(0xdau) /* GTPro */
+#define T_START BlockIOTag(0xdbu) /* GTB */
+#define TEX_SIZE_PITCH BlockIOTag(0xdcu) /* GTB */
+#define TEX_CNTL BlockIOTag(0xddu) /* GTPro */
+#define SECONDARY_TEX_OFFSET BlockIOTag(0xdeu) /* GTPro */
+#define TEX_PAL_WR BlockIOTag(0xdfu) /* GTB */
+#define TEX_PALETTE BlockIOTag(0xdfu) /* GTPro */
+#define SCALE_PITCH_BOTH BlockIOTag(0xe0u) /* GTPro */
+#define SECONDARY_SCALE_OFF_ACC BlockIOTag(0xe1u) /* GTPro */
+#define SCALE_OFF_ACC BlockIOTag(0xe2u) /* GTPro */
+#define SCALE_DST_Y_X BlockIOTag(0xe3u) /* GTPro */
+/* ? BlockIOTag(0xe4u) */
+/* ? BlockIOTag(0xe5u) */
+#define COMPOSITE_SHADOW_ID BlockIOTag(0xe6u) /* GTPro */
+#define SECONDARY_SCALE_X_INC BlockIOTag(0xe7u) /* GTPro */
+#define SPECULAR_RED_X_INC BlockIOTag(0xe7u) /* GTPro */
+#define SPECULAR_RED_Y_INC BlockIOTag(0xe8u) /* GTPro */
+#define SPECULAR_RED_START BlockIOTag(0xe9u) /* GTPro */
+#define SECONDARY_SCALE_HACC BlockIOTag(0xe9u) /* GTPro */
+#define SPECULAR_GREEN_X_INC BlockIOTag(0xeau) /* GTPro */
+#define SPECULAR_GREEN_Y_INC BlockIOTag(0xebu) /* GTPro */
+#define SPECULAR_GREEN_START BlockIOTag(0xecu) /* GTPro */
+#define SPECULAR_BLUE_X_INC BlockIOTag(0xedu) /* GTPro */
+#define SPECULAR_BLUE_Y_INC BlockIOTag(0xeeu) /* GTPro */
+#define SPECULAR_BLUE_START BlockIOTag(0xefu) /* GTPro */
+/* SCALE_X_INC BlockIOTag(0xf0u) */ /* Duplicate */
+/* RED_X_INC BlockIOTag(0xf0u) */ /* Duplicate */
+#define RED_Y_INC BlockIOTag(0xf1u) /* GTB */
+#define SCALE_HACC BlockIOTag(0xf2u) /* GTB */
+#define RED_START BlockIOTag(0xf2u) /* GTB */
+/* GREEN_X_INC BlockIOTag(0xf3u) */ /* Duplicate */
+/* SCALE_Y_INC BlockIOTag(0xf3u) */ /* Duplicate */
+#define GREEN_Y_INC BlockIOTag(0xf4u) /* GTB */
+#define SECONDARY_SCALE_Y_INC BlockIOTag(0xf4u) /* GTPro */
+#define SECONDARY_SCALE_VACC BlockIOTag(0xf5u) /* GTPro */
+#define GREEN_START BlockIOTag(0xf5u) /* GTB */
+#define BLUE_X_INC BlockIOTag(0xf6u) /* GTB */
+#define SCALE_XUV_INC BlockIOTag(0xf6u) /* GTB */
+#define BLUE_Y_INC BlockIOTag(0xf7u) /* GTB */
+#define BLUE_START BlockIOTag(0xf8u) /* GTB */
+#define SCALE_UV_HACC BlockIOTag(0xf8u) /* GTB */
+#define Z_X_INC BlockIOTag(0xf9u) /* GTB */
+#define Z_Y_INC BlockIOTag(0xfau) /* GTB */
+#define Z_START BlockIOTag(0xfbu) /* GTB */
+#define ALPHA_FOG_X_INC BlockIOTag(0xfcu) /* GTB */
+#define ALPHA_FOG_Y_INC BlockIOTag(0xfdu) /* GTB */
+#define ALPHA_FOG_START BlockIOTag(0xfeu) /* GTB */
+/* ? BlockIOTag(0xffu) */
+#define OVERLAY_Y_X_START BlockIOTag(0x100u)
+#define OVERLAY_Y_START 0x000003fful
+/* ? 0x0000fc00ul */
+#define OVERLAY_X_START 0x03ff0000ul
+/* ? 0x7c000000ul */
+#define OVERLAY_LOCK_START 0x80000000ul
+#define OVERLAY_Y_X_END BlockIOTag(0x101u)
+#define OVERLAY_Y_END 0x000003fful
+/* ? 0x0000fc00ul */
+#define OVERLAY_X_END 0x03ff0000ul
+/* ? 0x7c000000ul */
+#define OVERLAY_LOCK_END 0x80000000ul
+#define OVERLAY_VIDEO_KEY_CLR BlockIOTag(0x102u)
+#define OVERLAY_VIDEO_KEY_MSK BlockIOTag(0x103u)
+#define OVERLAY_GRAPHICS_KEY_CLR BlockIOTag(0x104u)
+#define OVERLAY_GRAPHICS_KEY_MSK BlockIOTag(0x105u)
+#define OVERLAY_KEY_CNTL BlockIOTag(0x106u)
+#define OVERLAY_VIDEO_FN 0x00000007ul
+/* ? 0x00000008ul */
+#define OVERLAY_GRAPHICS_FN 0x00000070ul
+/* ? 0x00000080ul */
+#define OVERLAY_CMP_MIX 0x00000100ul
+/* ? 0xfffffe00ul */
+/* ? BlockIOTag(0x107u) */
+#define OVERLAY_SCALE_INC BlockIOTag(0x108u)
+#define OVERLAY_SCALE_CNTL BlockIOTag(0x109u)
+#define SCALE_PIX_EXPAND 0x00000001ul
+#define SCALE_Y2R_TEMP 0x00000002ul
+#define SCALE_HORZ_MODE 0x00000004ul
+#define SCALE_VERT_MODE 0x00000008ul
+#define SCALE_SIGNED_UV 0x00000010ul
+#define SCALE_GAMMA_SEL 0x00000060ul
+/* ? 0x03ffff80ul */
+#define SCALE_BANDWIDTH 0x04000000ul
+#define SCALE_DIS_LIMIT 0x08000000ul
+/* ? 0x10000000ul */
+#define SCALE_CLK_FORCE_ON 0x20000000ul
+#define OVERLAY_EN 0x40000000ul
+#define SCALE_EN 0x80000000ul
+#define SCALER_HEIGHT_WIDTH BlockIOTag(0x10au)
+#define SCALER_TEST BlockIOTag(0x10bu)
+/* ? 0x00000001ul */
+#define SCALE_Y2R_DIS 0x00000002ul
+/* ? 0xfffffffcul */
+#define SCALER_THRESHOLD BlockIOTag(0x10cu)
+#define SCALER_BUF0_OFFSET BlockIOTag(0x10du) /* VTB/GTB */
+#define SCALER_BUF1_OFFSET BlockIOTag(0x10eu) /* VTB/GTB */
+#define SCALER_BUF_PITCH BlockIOTag(0x10fu) /* VTB/GTB */
+#define CAPTURE_Y_X BlockIOTag(0x110u)
+#define CAPTURE_START_END BlockIOTag(0x110u) /* VTB/GTB */
+#define CAPTURE_HEIGHT_WIDTH BlockIOTag(0x111u)
+#define CAPTURE_X_WIDTH BlockIOTag(0x111u) /* VTB/GTB */
+#define VIDEO_FORMAT BlockIOTag(0x112u)
+#define VIDEO_IN 0x0000000ful
+/* ? 0x00000000ul */
+/* ? 0x00000001ul */
+/* ? 0x00000002ul */
+/* ? 0x00000003ul */
+/* ? 0x00000004ul */
+/* ? 0x00000005ul */
+/* ? 0x00000006ul */
+/* ? 0x00000007ul */
+/* ? 0x00000008ul */
+/* ? 0x00000009ul */
+/* ? 0x0000000aul */
+#define VIDEO_IN_VYUY422 0x0000000bul
+#define VIDEO_IN_YVYU422 0x0000000cul
+/* ? 0x0000000dul */
+/* ? 0x0000000eul */
+/* ? 0x0000000ful */
+#define VIDEO_SIGNED_UV 0x00000010ul
+/* ? 0x0000ffe0ul */
+#define SCALER_IN 0x000f0000ul
+/* ? 0x00000000ul */
+/* ? 0x00010000ul */
+/* ? 0x00020000ul */
+#define SCALER_IN_15BPP 0x00030000ul
+#define SCALER_IN_16BPP 0x00040000ul
+/* ? 0x00050000ul */
+#define SCALER_IN_32BPP 0x00060000ul
+/* ? 0x00070000ul */
+/* ? 0x00080000ul */
+#define SCALER_IN_YUV9 0x00090000ul
+#define SCALER_IN_YUV12 0x000a0000ul
+#define SCALER_IN_VYUY422 0x000b0000ul
+#define SCALER_IN_YVYU422 0x000c0000ul
+/* ? 0x000d0000ul */
+/* ? 0x000e0000ul */
+/* ? 0x000f0000ul */
+/* ? 0x0ff00000ul */
+#define HOST_BYTE_SHIFT_EN 0x10000000ul
+#define HOST_YUV_APER 0x20000000ul
+#define HOST_MEM_MODE 0xc0000000ul
+#define HOST_MEM_MODE_NORMAL 0x00000000ul
+#define HOST_MEM_MODE_Y 0x40000000ul
+#define HOST_MEM_MODE_U 0x80000000ul
+#define HOST_MEM_MODE_V 0xc0000000ul
+#define VIDEO_CONFIG BlockIOTag(0x113u)
+#define VBI_START_END BlockIOTag(0x113u) /* VTB/GTB */
+#define CAPTURE_CONFIG BlockIOTag(0x114u)
+#define CAP_INPUT_MODE 0x00000001ul
+#define CAP_START_FIELD 0x00000002ul
+#define CAP_BUF_MODE 0x00000004ul
+#define CAP_START_BUF 0x00000008ul
+#define CAP_BUF_TYPE 0x00000030ul
+#define CAP_BUF_FIELD 0x00000000ul
+#define CAP_BUF_ALTERNATING 0x00000010ul
+#define CAP_BUF_FRAME 0x00000020ul
+/* ? 0x00000030ul */
+#define CAP_FIELD_FLIP 0x00000040ul
+#define CAP_CCIR656_EN 0x00000080ul
+/* ? 0x00000f00ul */
+#define CAP_MIRROR_EN 0x00001000ul
+#define ONESHOT_MIRROR_EN 0x00002000ul
+#define ONESHOT_MODE 0x00004000ul
+/* ? 0x00008000ul */
+#define CAP_HORZ_DOWN 0x00030000ul
+#define CAP_VERT_DOWN 0x000c0000ul
+#define ONESHOT_HORZ_DOWN 0x00300000ul
+#define ONESHOT_VERT_DOWN 0x00c00000ul
+/* ? 0x0f000000ul */
+#define OVL_BUF_MODE 0x10000000ul
+#define OVL_BUF_NEXT 0x20000000ul
+/* ? 0xc0000000ul */
+#define TRIG_CNTL BlockIOTag(0x115u)
+#define CAP_TRIGGER 0x00000003ul
+#define CAP_TRIGGER_NEXT 0x00000001ul
+/* ? 0x0000001cul */
+#define OVL_CUR_BUF 0x00000020ul
+#define OVL_BUF_STATUS 0x00000040ul
+#define CAP_BUF_STATUS 0x00000080ul
+/* ? 0x7fffff00ul */
+#define CAPTURE_EN 0x80000000ul
+#define VIDEO_SYNC_TEST BlockIOTag(0x116u)
+#define OVERLAY_EXCLUSIVE_HORZ BlockIOTag(0x116u) /* VTB/GTB */
+#define EXCLUSIVE_HORZ_START 0x000000fful
+#define EXCLUSIVE_HORZ_END 0x0000ff00ul
+#define EXCLUSIVE_HORZ_PORCH 0x00ff0000ul
+/* ? 0x7f000000ul */
+#define EXCLUSIVE_EN 0x80000000ul
+#define EXT_CRTC_GEN_CNTL_R BlockIOTag(0x117u) /* VT-A4 (R) */
+#define OVERLAY_EXCLUSIVE_VERT BlockIOTag(0x117u) /* VTB/GTB */
+#define EXCLUSIVE_VERT_START 0x000003fful
+/* ? 0x0000fc00ul */
+#define EXCLUSIVE_VERT_END 0x03ff0000ul
+/* ? 0xfc000000ul */
+#define VMC_CONFIG BlockIOTag(0x118u)
+#define VBI_WIDTH BlockIOTag(0x118u) /* VTB/GTB */
+#define VMC_STATUS BlockIOTag(0x119u)
+#define CAPTURE_DEBUG BlockIOTag(0x119u) /* VTB/GTB */
+#define VMC_CMD BlockIOTag(0x11au)
+#define VIDEO_SYNC_TEST_B BlockIOTag(0x11au) /* VTB/GTB */
+#define VMC_ARG0 BlockIOTag(0x11bu)
+#define VMC_ARG1 BlockIOTag(0x11cu)
+#define SNAPSHOT_VH_COUNTS BlockIOTag(0x11cu) /* GTPro */
+#define VMC_SNOOP_ARG0 BlockIOTag(0x11du)
+#define SNAPSHOT_F_COUNT BlockIOTag(0x11du) /* GTPro */
+#define VMC_SNOOP_ARG1 BlockIOTag(0x11eu)
+#define N_VIF_COUNT BlockIOTag(0x11eu) /* GTPro */
+#define SNAPSHOT_VIF_COUNT BlockIOTag(0x11fu) /* GTPro */
+#define BUF0_OFFSET BlockIOTag(0x120u)
+#define CAPTURE_BUF0_OFFSET BlockIOTag(0x120u) /* VTB/GTB */
+#define CAPTURE_BUF1_OFFSET BlockIOTag(0x121u) /* VTB/GTB */
+#define ONESHOT_BUF_OFFSET BlockIOTag(0x122u) /* VTB/GTB */
+#define BUF0_PITCH BlockIOTag(0x123u)
+/* ? BlockIOTag(0x124u) */
+/* ? BlockIOTag(0x125u) */
+#define BUF1_OFFSET BlockIOTag(0x126u)
+/* ? BlockIOTag(0x127u) */
+/* ? BlockIOTag(0x128u) */
+#define BUF1_PITCH BlockIOTag(0x129u)
+/* ? BlockIOTag(0x12au) */
+#define BUF0_CAP_ODD_OFFSET BlockIOTag(0x12bu)
+#define BUF1_CAP_ODD_OFFSET BlockIOTag(0x12cu)
+#define SNAPSHOT2_VH_COUNTS BlockIOTag(0x12cu) /* LTPro */
+#define SNAPSHOT2_F_COUNT BlockIOTag(0x12du) /* LTPro */
+#define N_VIF2_COUNT BlockIOTag(0x12eu) /* LTPro */
+#define SNAPSHOT2_VIF_COUNT BlockIOTag(0x12fu) /* LTPro */
+#define VMC_STRM_DATA_0 BlockIOTag(0x130u)
+/* MPP_CONFIG BlockIOTag(0x130u) */ /* See 0x3bu */
+#define VMC_STRM_DATA_1 BlockIOTag(0x131u)
+/* MPP_STROBE_SEQ BlockIOTag(0x131u) */ /* See 0x3cu */
+#define VMC_STRM_DATA_2 BlockIOTag(0x132u)
+/* MPP_ADDR BlockIOTag(0x132u) */ /* See 0x3du */
+#define VMC_STRM_DATA_3 BlockIOTag(0x133u)
+/* MPP_DATA BlockIOTag(0x133u) */ /* See 0x3eu */
+#define VMC_STRM_DATA_4 BlockIOTag(0x134u)
+#define VMC_STRM_DATA_5 BlockIOTag(0x135u)
+#define VMC_STRM_DATA_6 BlockIOTag(0x136u)
+#define VMC_STRM_DATA_7 BlockIOTag(0x137u)
+#define VMC_STRM_DATA_8 BlockIOTag(0x138u)
+#define VMC_STRM_DATA_9 BlockIOTag(0x139u)
+#define VMC_STRM_DATA_A BlockIOTag(0x13au)
+#define VMC_STRM_DATA_B BlockIOTag(0x13bu)
+#define VMC_STRM_DATA_C BlockIOTag(0x13cu)
+#define VMC_STRM_DATA_D BlockIOTag(0x13du)
+#define VMC_STRM_DATA_E BlockIOTag(0x13eu)
+#define VMC_STRM_DATA_F BlockIOTag(0x13fu)
+/* TVO_CNTL BlockIOTag(0x140u) */ /* See 0x3fu */
+/* ? BlockIOTag(0x141u) */
+/* ? BlockIOTag(0x142u) */
+/* ? BlockIOTag(0x143u) */
+/* ? BlockIOTag(0x144u) */
+/* ? BlockIOTag(0x145u) */
+/* ? BlockIOTag(0x146u) */
+/* ? BlockIOTag(0x147u) */
+/* ? BlockIOTag(0x148u) */
+/* ? BlockIOTag(0x149u) */
+/* ? BlockIOTag(0x14au) */
+/* ? BlockIOTag(0x14bu) */
+/* ? BlockIOTag(0x14cu) */
+/* ? BlockIOTag(0x14du) */
+/* ? BlockIOTag(0x14eu) */
+/* ? BlockIOTag(0x14fu) */
+/* ? BlockIOTag(0x150u) */
+#define CRT_HORZ_VERT_LOAD BlockIOTag(0x151u) /* VTB/GTB */
+#define AGP_BASE BlockIOTag(0x152u) /* GTPro */
+#define AGP_CNTL BlockIOTag(0x153u) /* GTPro */
+#define AGP_MODE_1X 0x00000001ul
+#define AGP_MODE_2X 0x00000002ul
+#define AGP_MODE_MASK 0x00000003ul
+#define AGP_APER_SIZE_MASK 0x0000003ful
+#define AGP_APER_SIZE_4MB 0x0000003ful
+#define AGP_APER_SIZE_8MB 0x0000003eul
+#define AGP_APER_SIZE_16MB 0x0000003cul
+#define AGP_APER_SIZE_32MB 0x00000038ul
+#define AGP_APER_SIZE_64MB 0x00000030ul
+#define AGP_APER_SIZE_128MB 0x00000020ul
+#define AGP_APER_SIZE_256MB 0x00000000ul
+#define HIGH_PRIORITY_READ_EN 0x00010000ul
+#define AGP_TRDY_MODE 0x00020000ul
+#define SCALER_COLOUR_CNTL BlockIOTag(0x154u) /* GTPro */
+#define SCALE_BRIGHTNESS 0x0000007ful
+/* ? 0x00000080ul */
+#define SCALE_SATURATION_U 0x00001f00ul
+/* ? 0x0000e000ul */
+#define SCALE_SATURATION_V 0x001f0000ul
+#define SCALE_VERT_ADJ_UV 0x0fe00000ul
+#define SCALE_HORZ_ADJ_UV 0xf0000000ul
+#define SCALER_H_COEFF0 BlockIOTag(0x155u) /* GTPro */
+#define SCALER_H_COEFF1 BlockIOTag(0x156u) /* GTPro */
+#define SCALER_H_COEFF2 BlockIOTag(0x157u) /* GTPro */
+#define SCALER_H_COEFF3 BlockIOTag(0x158u) /* GTPro */
+#define SCALER_H_COEFF4 BlockIOTag(0x159u) /* GTPro */
+/* ? BlockIOTag(0x15au) */
+/* ? BlockIOTag(0x15bu) */
+#define GUI_CMDFIFO_DEBUG BlockIOTag(0x15cu) /* GT2c/VT4 */
+#define GUI_CMDFIFO_DATA BlockIOTag(0x15du) /* GT2c/VT4 */
+#define GUI_CNTL BlockIOTag(0x15eu) /* GT2c/VT4 */
+#define CMDFIFO_SIZE_MODE 0x00000003ul
+/* ? 0x0000fffcul */
+#define IDCT_PRSR_MODE 0x00010000ul /* XL/XC */
+#define IDCT_BLOCK_GUI_INITIATOR 0x00020000ul /* XL/XC */
+/* ? 0xfffc0000ul */
+/* ? BlockIOTag(0x15fu) */
+#define BM_FRAME_BUF_OFFSET BlockIOTag(0x160u) /* VTB/GTB */
+#define BM_SYSTEM_MEM_ADDR BlockIOTag(0x161u) /* VTB/GTB */
+#define BM_COMMAND BlockIOTag(0x162u) /* VTB/GTB */
+#define BM_STATUS BlockIOTag(0x163u) /* VTB/GTB */
+/* ? BlockIOTag(0x164u) */
+/* ? BlockIOTag(0x165u) */
+/* ? BlockIOTag(0x166u) */
+/* ? BlockIOTag(0x167u) */
+/* ? BlockIOTag(0x168u) */
+/* ? BlockIOTag(0x169u) */
+/* ? BlockIOTag(0x16au) */
+/* ? BlockIOTag(0x16bu) */
+/* ? BlockIOTag(0x16cu) */
+/* ? BlockIOTag(0x16du) */
+#define BM_GUI_TABLE BlockIOTag(0x16eu) /* VTB/GTB */
+#define BM_SYSTEM_TABLE BlockIOTag(0x16fu) /* VTB/GTB */
+/* ? BlockIOTag(0x170u) */
+/* ? BlockIOTag(0x171u) */
+/* ? BlockIOTag(0x172u) */
+/* ? BlockIOTag(0x173u) */
+/* ? BlockIOTag(0x174u) */
+#define SCALER_BUF0_OFFSET_U BlockIOTag(0x175u) /* GTPro */
+#define SCALER_BUF0_OFFSET_V BlockIOTag(0x176u) /* GTPro */
+#define SCALER_BUF1_OFFSET_U BlockIOTag(0x177u) /* GTPro */
+#define SCALER_BUF1_OFFSET_V BlockIOTag(0x178u) /* GTPro */
+/* ? BlockIOTag(0x179u) */
+/* ? BlockIOTag(0x17au) */
+/* ? BlockIOTag(0x17bu) */
+/* ? BlockIOTag(0x17cu) */
+/* ? BlockIOTag(0x17du) */
+/* ? BlockIOTag(0x17eu) */
+/* ? BlockIOTag(0x17fu) */
+/* ? BlockIOTag(0x180u) */
+/* ? BlockIOTag(0x181u) */
+/* ? BlockIOTag(0x182u) */
+/* ? BlockIOTag(0x183u) */
+/* ? BlockIOTag(0x184u) */
+/* ? BlockIOTag(0x185u) */
+/* ? BlockIOTag(0x186u) */
+/* ? BlockIOTag(0x187u) */
+/* ? BlockIOTag(0x188u) */
+/* ? BlockIOTag(0x189u) */
+/* ? BlockIOTag(0x18au) */
+/* ? BlockIOTag(0x18bu) */
+/* ? BlockIOTag(0x18cu) */
+/* ? BlockIOTag(0x18du) */
+/* ? BlockIOTag(0x18eu) */
+/* ? BlockIOTag(0x18fu) */
+#define VERTEX_1_S BlockIOTag(0x190u) /* GTPro */
+#define VERTEX_1_T BlockIOTag(0x191u) /* GTPro */
+#define VERTEX_1_W BlockIOTag(0x192u) /* GTPro */
+#define VERTEX_1_SPEC_ARGB BlockIOTag(0x193u) /* GTPro */
+#define VERTEX_1_Z BlockIOTag(0x194u) /* GTPro */
+#define VERTEX_1_ARGB BlockIOTag(0x195u) /* GTPro */
+#define VERTEX_1_X_Y BlockIOTag(0x196u) /* GTPro */
+#define ONE_OVER_AREA BlockIOTag(0x197u) /* GTPro */
+#define VERTEX_2_S BlockIOTag(0x198u) /* GTPro */
+#define VERTEX_2_T BlockIOTag(0x199u) /* GTPro */
+#define VERTEX_2_W BlockIOTag(0x19au) /* GTPro */
+#define VERTEX_2_SPEC_ARGB BlockIOTag(0x19bu) /* GTPro */
+#define VERTEX_2_Z BlockIOTag(0x19cu) /* GTPro */
+#define VERTEX_2_ARGB BlockIOTag(0x19du) /* GTPro */
+#define VERTEX_2_X_Y BlockIOTag(0x19eu) /* GTPro */
+/* ONE_OVER_AREA BlockIOTag(0x19fu) */ /* Duplicate */
+#define VERTEX_3_S BlockIOTag(0x1a0u) /* GTPro */
+#define VERTEX_3_T BlockIOTag(0x1a1u) /* GTPro */
+#define VERTEX_3_W BlockIOTag(0x1a2u) /* GTPro */
+#define VERTEX_3_SPEC_ARGB BlockIOTag(0x1a3u) /* GTPro */
+#define VERTEX_3_Z BlockIOTag(0x1a4u) /* GTPro */
+#define VERTEX_3_ARGB BlockIOTag(0x1a5u) /* GTPro */
+#define VERTEX_3_X_Y BlockIOTag(0x1a6u) /* GTPro */
+/* ONE_OVER_AREA BlockIOTag(0x1a7u) */ /* Duplicate */
+#define VERTEX_3_SECONDARY_S BlockIOTag(0x1a8u) /* GTPro */
+#define VERTEX_3_SECONDARY_T BlockIOTag(0x1a9u) /* GTPro */
+#define VERTEX_3_SECONDARY_W BlockIOTag(0x1aau) /* GTPro */
+/* VERTEX_1_S BlockIOTag(0x1abu) */ /* Duplicate */
+/* VERTEX_1_T BlockIOTag(0x1acu) */ /* Duplicate */
+/* VERTEX_1_W BlockIOTag(0x1adu) */ /* Duplicate */
+/* VERTEX_2_S BlockIOTag(0x1aeu) */ /* Duplicate */
+/* VERTEX_2_T BlockIOTag(0x1afu) */ /* Duplicate */
+/* VERTEX_2_W BlockIOTag(0x1b0u) */ /* Duplicate */
+/* VERTEX_3_S BlockIOTag(0x1b1u) */ /* Duplicate */
+/* VERTEX_3_T BlockIOTag(0x1b2u) */ /* Duplicate */
+/* VERTEX_3_W BlockIOTag(0x1b3u) */ /* Duplicate */
+/* VERTEX_1_SPEC_ARGB BlockIOTag(0x1b4u) */ /* Duplicate */
+/* VERTEX_2_SPEC_ARGB BlockIOTag(0x1b5u) */ /* Duplicate */
+/* VERTEX_3_SPEC_ARGB BlockIOTag(0x1b6u) */ /* Duplicate */
+/* VERTEX_1_Z BlockIOTag(0x1b7u) */ /* Duplicate */
+/* VERTEX_2_Z BlockIOTag(0x1b8u) */ /* Duplicate */
+/* VERTEX_3_Z BlockIOTag(0x1b9u) */ /* Duplicate */
+/* VERTEX_1_ARGB BlockIOTag(0x1bau) */ /* Duplicate */
+/* VERTEX_2_ARGB BlockIOTag(0x1bbu) */ /* Duplicate */
+/* VERTEX_3_ARGB BlockIOTag(0x1bcu) */ /* Duplicate */
+/* VERTEX_1_X_Y BlockIOTag(0x1bdu) */ /* Duplicate */
+/* VERTEX_2_X_Y BlockIOTag(0x1beu) */ /* Duplicate */
+/* VERTEX_3_X_Y BlockIOTag(0x1bfu) */ /* Duplicate */
+#define ONE_OVER_AREA_UC BlockIOTag(0x1c0u) /* GTPro */
+#define SETUP_CNTL BlockIOTag(0x1c1u) /* GTPro */
+/* ? BlockIOTag(0x1c2u) */
+/* ? BlockIOTag(0x1c3u) */
+/* ? BlockIOTag(0x1c4u) */
+/* ? BlockIOTag(0x1c5u) */
+/* ? BlockIOTag(0x1c6u) */
+/* ? BlockIOTag(0x1c7u) */
+/* ? BlockIOTag(0x1c8u) */
+/* ? BlockIOTag(0x1c9u) */
+#define VERTEX_1_SECONDARY_S BlockIOTag(0x1cau) /* GTPro */
+#define VERTEX_1_SECONDARY_T BlockIOTag(0x1cbu) /* GTPro */
+#define VERTEX_1_SECONDARY_W BlockIOTag(0x1ccu) /* GTPro */
+#define VERTEX_2_SECONDARY_S BlockIOTag(0x1cdu) /* GTPro */
+#define VERTEX_2_SECONDARY_T BlockIOTag(0x1ceu) /* GTPro */
+#define VERTEX_2_SECONDARY_W BlockIOTag(0x1cfu) /* GTPro */
+/* ? BlockIOTag(0x1d0u) */
+/* ? BlockIOTag(0x1d1u) */
+/* ? BlockIOTag(0x1d2u) */
+/* ? BlockIOTag(0x1d3u) */
+/* ? BlockIOTag(0x1d4u) */
+/* ? BlockIOTag(0x1d5u) */
+/* ? BlockIOTag(0x1d6u) */
+/* ? BlockIOTag(0x1d7u) */
+/* ? BlockIOTag(0x1d8u) */
+/* ? BlockIOTag(0x1d9u) */
+/* ? BlockIOTag(0x1dau) */
+/* ? BlockIOTag(0x1dbu) */
+/* ? BlockIOTag(0x1dcu) */
+/* ? BlockIOTag(0x1ddu) */
+/* ? BlockIOTag(0x1deu) */
+/* ? BlockIOTag(0x1dfu) */
+/* ? BlockIOTag(0x1e0u) */
+/* ? BlockIOTag(0x1e1u) */
+/* ? BlockIOTag(0x1e2u) */
+/* ? BlockIOTag(0x1e3u) */
+/* ? BlockIOTag(0x1e4u) */
+/* ? BlockIOTag(0x1e5u) */
+/* ? BlockIOTag(0x1e6u) */
+/* ? BlockIOTag(0x1e7u) */
+/* ? BlockIOTag(0x1e8u) */
+/* ? BlockIOTag(0x1e9u) */
+/* ? BlockIOTag(0x1eau) */
+/* ? BlockIOTag(0x1ebu) */
+/* ? BlockIOTag(0x1ecu) */
+/* ? BlockIOTag(0x1edu) */
+/* ? BlockIOTag(0x1eeu) */
+/* ? BlockIOTag(0x1efu) */
+/* ? BlockIOTag(0x1f0u) */
+/* ? BlockIOTag(0x1f1u) */
+/* ? BlockIOTag(0x1f2u) */
+/* ? BlockIOTag(0x1f3u) */
+/* ? BlockIOTag(0x1f4u) */
+/* ? BlockIOTag(0x1f5u) */
+/* ? BlockIOTag(0x1f6u) */
+/* ? BlockIOTag(0x1f7u) */
+/* ? BlockIOTag(0x1f8u) */
+/* ? BlockIOTag(0x1f9u) */
+/* ? BlockIOTag(0x1fau) */
+/* ? BlockIOTag(0x1fbu) */
+/* ? BlockIOTag(0x1fcu) */
+/* ? BlockIOTag(0x1fdu) */
+/* ? BlockIOTag(0x1feu) */
+/* ? BlockIOTag(0x1ffu) */
+
+/* Definitions for MEM_CNTL's CTL_MEM_?????_APER_ENDIAN fields */
+#define CTL_MEM_APER_BYTE_ENDIAN 0x00u
+#define CTL_MEM_APER_WORD_ENDIAN 0x01u
+#define CTL_MEM_APER_LONG_ENDIAN 0x02u
+/* ? 0x03u */
+
+/* Definitions for an ICS2595's programme word */
+#define ICS2595_CLOCK 0x000001f0ul
+#define ICS2595_FB_DIV 0x0001fe00ul /* Feedback divider */
+#define ICS2595_POST_DIV 0x000c0000ul /* Post-divider */
+#define ICS2595_STOP 0x00300000ul /* Stop bits */
+#define ICS2595_TOGGLE (ICS2595_POST_DIV | ICS2595_STOP)
+
+/* Definitions for internal PLL registers on a 264xT */
+#define PLL_MPLL_CNTL 0x00u
+#define MPLL_PC_GAIN 0x07u
+#define MPLL_VC_GAIN 0x18u
+#define MPLL_D_CYC 0x60u
+#define MPLL_RANGE 0x80u
+#define VPLL_CNTL 0x01u
+#define VPLL_PC_GAIN 0x07u
+#define VPLL_VC_GAIN 0x18u
+#define VPLL_D_CYC 0x60u
+#define VPLL_RANGE 0x80u
+#define PLL_REF_DIV 0x02u
+#define PLL_GEN_CNTL 0x03u
+#define PLL_OVERRIDE 0x01u
+#define PLL_SLEEP 0x01u /* GTPro */
+#define PLL_MCLK_RESET 0x02u
+#define PLL_OSC_EN 0x04u
+#define PLL_EXT_CLK_EN 0x08u
+#define PLL_MCLK_SRC_SEL 0x70u
+#define PLL_EXT_CLK_CNTL 0x80u /* CT/ET */
+#define PLL_DLL_PWDN 0x80u /* VTB/GTB/LT */
+#define PLL_MCLK_FB_DIV 0x04u
+#define PLL_VCLK_CNTL 0x05u
+#define PLL_VCLK_SRC_SEL 0x03u
+#define PLL_VCLK_RESET 0x04u
+#define PLL_VCLK_INVERT 0x08u
+#define PLL_ECP_DIV 0x30u /* VT/GT */
+#define PLL_ERATE_GT_XRATE 0x40u /* VT/GT */
+#define PLL_SCALER_LOCK_EN 0x80u /* VT/GT */
+#define PLL_VCLK_POST_DIV 0x06u
+#define PLL_VCLK0_POST_DIV 0x03u
+#define PLL_VCLK1_POST_DIV 0x0cu
+#define PLL_VCLK2_POST_DIV 0x30u
+#define PLL_VCLK3_POST_DIV 0xc0u
+#define PLL_VCLK0_FB_DIV 0x07u
+#define PLL_VCLK1_FB_DIV 0x08u
+#define PLL_VCLK2_FB_DIV 0x09u
+#define PLL_VCLK3_FB_DIV 0x0au
+#define PLL_XCLK_CNTL 0x0bu /* VT/GT */
+#define PLL_XCLK_MCLK_RATIO 0x03u
+#define PLL_XCLK_SRC_SEL 0x07u /* VTB/GTB/LT */
+#define PLL_MFB_TIMES_4_2B 0x08u
+#define PLL_VCLK0_XDIV 0x10u
+#define PLL_VCLK1_XDIV 0x20u
+#define PLL_VCLK2_XDIV 0x40u
+#define PLL_VCLK3_XDIV 0x80u
+#define PLL_FCP_CNTL 0x0cu /* VT/GT */
+#define PLL_FCP_POST_DIV 0x0fu
+#define PLL_FCP_SRC_SEL 0x70u
+#define PLL_DCLK_BY2_EN 0x80u
+#define PLL_DLL_CNTL 0x0cu /* VTB/GTB/LT */
+#define PLL_DLL_REF_SRC 0x03u
+#define PLL_DLL_FB_SRC 0x0cu
+#define PLL_DLL_GAIN 0x30u
+#define PLL_DLL_RESET 0x40u
+#define PLL_DLL_HCLK_OUT_EN 0x80u
+#define PLL_VFC_CNTL 0x0du /* VT/GT */
+#define PLL_DCLK_INVB 0x01u
+#define PLL_DCLKBY2_EN 0x02u
+#define PLL_VFC_2PHASE 0x04u
+#define PLL_VFC_DELAY 0x18u
+#define PLL_VFC_DCLKBY2_SHIFT 0x20u
+/* ? 0x40u */
+#define PLL_TST_SRC_SEL_BIT5 0x80u /* VTB/GTB/LT */
+#define PLL_TEST_CNTL 0x0eu
+#define PLL_TST_SRC_SEL 0x1fu
+#define PLL_TST_DIVIDERS 0x20u
+#define PLL_TST_MASK_READ 0x40u
+#define PLL_TST_ANALOG_MON_EN 0x80u
+#define PLL_TEST_COUNT 0x0fu
+#define PLL_LVDSPLL_CNTL0 0x10u /* LT */
+#define PLL_FPDI_NS_TIMING 0x01u
+#define PLL_CURR_LEVEL 0x0eu
+#define PLL_LVDS_TEST_MODE 0xf0u
+#define PLL_LVDSPLL_CNTL1 0x11u /* LT */
+#define PLL_LPPL_RANGE 0x01u
+#define PLL_LPLL_DUTY 0x06u
+#define PLL_LPLL_VC_GAIN 0x18u
+#define PLL_LPLL_CP_GAIN 0xe0u
+#define PLL_AGP1_CNTL 0x12u /* GTPro */
+#define PLL_AGP2_CNTL 0x13u /* GTPro */
+#define PLL_DLL2_CNTL 0x14u /* GTPro */
+#define PLL_SCLK_FB_DIV 0x15u /* GTPro */
+#define PLL_SPLL_CNTL1 0x16u /* GTPro */
+#define PLL_SPLL_CNTL2 0x17u /* GTPro */
+#define PLL_APLL_STRAPS 0x18u /* GTPro */
+#define PLL_EXT_VPLL_CNTL 0x19u /* GTPro */
+#define PLL_EXT_VPLL_REF_SRC 0x03u
+#define PLL_EXT_VPLL_EN 0x04u
+#define PLL_EXT_VPLL_VGA_EN 0x08u
+#define PLL_EXT_VPLL_INSYNC 0x10u
+/* ? 0x60u */
+#define PLL_EXT_V2PLL_EN 0x80u
+#define PLL_EXT_VPLL_REF_DIV 0x1au /* GTPro */
+#define PLL_EXT_VPLL_FB_DIV 0x1bu /* GTPro */
+#define PLL_EXT_VPLL_MSB 0x1cu /* GTPro */
+#define PLL_HTOTAL_CNTL 0x1du /* GTPro */
+#define PLL_BYTE_CLK_CNTL 0x1eu /* GTPro */
+#define PLL_TV_REF_DIV 0x1fu /* LTPro */
+#define PLL_TV_FB_DIV 0x20u /* LTPro */
+#define PLL_TV_CNTL 0x21u /* LTPro */
+#define PLL_TV_GEN_CNTL 0x22u /* LTPro */
+#define PLL_V2_CNTL 0x23u /* LTPro */
+#define PLL_V2_GEN_CNTL 0x24u /* LTPro */
+#define PLL_V2_REF_DIV 0x25u /* LTPro */
+#define PLL_V2_FB_DIV 0x26u /* LTPro */
+#define PLL_V2_MSB 0x27u /* LTPro */
+#define PLL_HTOTAL2_CNTL 0x28u /* LTPro */
+#define PLL_YCLK_CNTL 0x29u /* XC/XL */
+#define PM_DYN_CLK_CNTL 0x2au /* XC/XL */
+/* ? 0x2bu */
+/* ? 0x2cu */
+/* ? 0x2du */
+/* ? 0x2eu */
+/* ? 0x2fu */
+/* ? 0x30u */
+/* ? 0x31u */
+/* ? 0x32u */
+/* ? 0x33u */
+/* ? 0x34u */
+/* ? 0x35u */
+/* ? 0x36u */
+/* ? 0x37u */
+/* ? 0x38u */
+/* ? 0x39u */
+/* ? 0x3au */
+/* ? 0x3bu */
+/* ? 0x3cu */
+/* ? 0x3du */
+/* ? 0x3eu */
+/* ? 0x3fu */
+
+/* Definitions for an LTPro's 32-bit LCD registers */
+#define LCD_CONFIG_PANEL 0x00u /* See LT's CONFIG_PANEL (0x1d) */
+#define LCD_GEN_CNTL 0x01u /* See LT's LCD_GEN_CTRL (0x35) */
+#define LCD_DSTN_CONTROL 0x02u /* See LT's DSTN_CONTROL (0x1f) */
+#define LCD_HFB_PITCH_ADDR 0x03u /* See LT's HFB_PITCH_ADDR (0x2a) */
+#define LCD_HORZ_STRETCHING 0x04u /* See LT's HORZ_STRETCHING (0x32) */
+#define LCD_VERT_STRETCHING 0x05u /* See LT's VERT_STRETCHING (0x33) */
+#define LCD_EXT_VERT_STRETCH 0x06u
+#define VERT_STRETCH_RATIO3 0x000003fful
+#define FORCE_DAC_DATA 0x000000fful
+#define FORCE_DAC_DATA_SEL 0x00000300ul
+#define VERT_STRETCH_MODE 0x00000400ul
+#define VERT_PANEL_SIZE 0x003ff800ul
+#define AUTO_VERT_RATIO 0x00400000ul
+#define USE_AUTO_FP_POS 0x00800000ul
+#define USE_AUTO_LCD_VSYNC 0x01000000ul
+/* ? 0xfe000000ul */
+#define LCD_LT_GIO 0x07u /* See LT's LT_GIO (0x2f) */
+#define LCD_POWER_MANAGEMENT 0x08u /* See LT's POWER_MANAGEMENT (0x36) */
+#define LCD_ZVGPIO 0x09u
+#define LCD_ICON_CLR0 0x0au /* Mobility */
+#define LCD_ICON_CLR1 0x0bu /* Mobility */
+#define LCD_ICON_OFFSET 0x0cu /* Mobility */
+#define LCD_ICON_HORZ_VERT_POSN 0x0du /* Mobility */
+#define LCD_ICON_HORZ_VERT_OFF 0x0eu /* Mobility */
+#define LCD_ICON2_CLR0 0x0fu /* Mobility */
+#define LCD_ICON2_CLR1 0x10u /* Mobility */
+#define LCD_ICON2_OFFSET 0x11u /* Mobility */
+#define LCD_ICON2_HORZ_VERT_POSN 0x12u /* Mobility */
+#define LCD_ICON2_HORZ_VERT_OFF 0x13u /* Mobility */
+#define LCD_MISC_CNTL 0x14u /* XC/XL */
+#define BL_MOD_LEVEL 0x000000fful
+#define BIAS_MOD_LEVEL 0x0000ff00ul
+#define BLMOD_EN 0x00010000ul
+#define BIASMOD_EN 0x00020000ul
+/* ? 0x00040000ul */
+#define PWRSEQ_MODE 0x00080000ul
+#define APC_EN 0x00100000ul
+#define MONITOR_DET_EN 0x00200000ul
+#define FORCE_DAC_DATA_SEL_X 0x00c00000ul
+#define FORCE_DAC_DATA_X 0xff000000ul
+#define LCD_TMDS_CNTL 0x15u /* XC/XL */
+#define LCD_SCRATCH_PAD_4M 0x15u /* Mobility */
+#define LCD_TMDS_SYNC_CHAR_SETA 0x16u /* XC/XL */
+#define LCD_SCRATCH_PAD_5M 0x16u /* Mobility */
+#define LCD_TMDS_SYNC_CHAR_SETB 0x17u /* XC/XL */
+#define LCD_SCRATCH_PAD_6M 0x17u /* Mobility */
+#define LCD_TMDS_SRC 0x18u /* XC/XL */
+#define LCD_SCRATCH_PAD_7M 0x18u /* Mobility */
+#define LCD_PLTSTBLK_CNTL 0x19u /* XC/XL */
+#define LCD_SCRATCH_PAD_8M 0x19u /* Mobility */
+#define LCD_SYNC_GEN_CNTL 0x1au /* XC/XL */
+#define LCD_PATTERN_GEN_SEED 0x1bu /* XC/XL */
+#define LCD_APC_CNTL 0x1cu /* XC/XL */
+#define LCD_POWER_MANAGEMENT_2 0x1du /* XC/XL */
+#define LCD_XCLK_DISP_PM_EN 0x00000001ul
+#define LCD_XCLK_DISP2_PM_EN 0x00000002ul /* Mobility */
+#define LCD_XCLK_VID_PM_EN 0x00000004ul
+#define LCD_XCLK_SCL_PM_EN 0x00000008ul
+#define LCD_XCLK_GUI_PM_EN 0x00000010ul
+#define LCD_XCLK_SUB_PM_EN 0x00000020ul
+/* ? 0x000000c0ul */
+#define LCD_MCLK_PM_EN 0x00000100ul
+#define LCD_SS_EN 0x00000200ul
+#define LCD_BLON_DIGON_EN 0x00000400ul
+/* ? 0x00000800ul */
+#define LCD_PM_DYN_XCLK_SYNC 0x00003000ul
+#define LCD_SEL_W4MS 0x00004000ul
+/* ? 0x00008000ul */
+#define LCD_PM_DYN_XCLK_EN 0x00010000ul
+#define LCD_PM_XCLK_ALWAYS 0x00020000ul
+#define LCD_PM_DYN_XCLK_STATUS 0x00040000ul
+#define LCD_PCI_ACC_DIS 0x00080000ul
+#define LCD_PM_DYN_XCLK_DISP 0x00100000ul
+#define LCD_PM_DYN_XCLK_DISP2 0x00200000ul /* Mobility */
+#define LCD_PM_DYN_XCLK_VID 0x00400000ul
+#define LCD_PM_DYN_XCLK_HFB 0x00800000ul
+#define LCD_PM_DYN_XCLK_SCL 0x01000000ul
+#define LCD_PM_DYN_XCLK_SUB 0x02000000ul
+#define LCD_PM_DYN_XCLK_GUI 0x04000000ul
+#define LCD_PM_DYN_XCLK_HOST 0x08000000ul
+/* ? 0xf0000000ul */
+#define LCD_PRI_ERR_PATTERN 0x1eu /* XC/XL */
+#define LCD_CUR_ERR_PATTERN 0x1fu /* XC/XL */
+#define LCD_PLTSTBLK_RPT 0x20u /* XC/XL */
+#define LCD_SYNC_RPT 0x21u /* XC/XL */
+#define LCD_CRC_PATTERN_RPT 0x22u /* XC/XL */
+#define LCD_PL_TRANSMITTER_CNTL 0x23u /* XC/XL */
+#define LCD_PL_PLL_CNTL 0x24u /* XC/XL */
+#define LCD_ALPHA_BLENDING 0x25u /* Mobility */
+#define LCD_PORTRAIT_GEN_CNTL 0x26u /* Mobility */
+#define LCD_APC_CTRL_IO 0x27u /* Mobility */
+#define LCD_TEST_IO 0x28u /* XC/XL */
+/* ? 0x29u */
+#define LCD_DP1_MEM_ACCESS 0x2au /* XC/XL */
+#define LCD_DP0_MEM_ACCESS 0x2bu /* XC/XL */
+#define LCD_DP0_DEBUG_A 0x2cu /* XC/XL */
+#define LCD_DP0_DEBUG_B 0x2du /* XC/XL */
+#define LCD_DP1_DEBUG_A 0x2eu /* XC/XL */
+#define LCD_DP1_DEBUG_B 0x2fu /* XC/XL */
+#define LCD_DPCTRL_DEBUG_A 0x30u /* XC/XL */
+#define LCD_DPCTRL_DEBUG_B 0x31u /* XC/XL */
+#define LCD_MEMBLK_DEBUG 0x32u /* XC/XL */
+#define LCD_APC_LUT_AB 0x33u /* Mobility */
+#define LCD_SCRATCH_PAD_4X 0x33u /* XL/XC */
+#define LCD_APC_LUT_CD 0x34u /* Mobility */
+#define LCD_SCRATCH_PAD_5X 0x34u /* XL/XC */
+#define LCD_APC_LUT_EF 0x35u /* Mobility */
+#define LCD_SCRATCH_PAD_6X 0x35u /* XL/XC */
+#define LCD_APC_LUT_GH 0x36u /* Mobility */
+#define LCD_SCRATCH_PAD_7X 0x36u /* XL/XC */
+#define LCD_APC_LUT_IJ 0x37u /* Mobility */
+#define LCD_SCRATCH_PAD_8X 0x37u /* XL/XC */
+#define LCD_APC_LUT_KL 0x38u /* Mobility */
+#define LCD_APC_LUT_MN 0x39u /* Mobility */
+#define LCD_APC_LUT_OP 0x3au /* Mobility */
+/* ? 0x3bu */
+/* ? 0x3cu */
+/* ? 0x3du */
+/* ? 0x3eu */
+/* ? 0x3fu */
+
+/* Definitions for an LTPro's TV registers */
+/* ? 0x00u */
+/* ? 0x01u */
+/* ? 0x02u */
+/* ? 0x03u */
+/* ? 0x04u */
+/* ? 0x05u */
+/* ? 0x06u */
+/* ? 0x07u */
+/* ? 0x08u */
+/* ? 0x09u */
+/* ? 0x0au */
+/* ? 0x0bu */
+/* ? 0x0cu */
+/* ? 0x0du */
+/* ? 0x0eu */
+/* ? 0x0fu */
+#define TV_MASTER_CNTL 0x10u
+/* ? 0x11u */
+#define TV_RGB_CNTL 0x12u
+/* ? 0x13u */
+#define TV_SYNC_CNTL 0x14u
+/* ? 0x15u */
+/* ? 0x16u */
+/* ? 0x17u */
+/* ? 0x18u */
+/* ? 0x19u */
+/* ? 0x1au */
+/* ? 0x1bu */
+/* ? 0x1cu */
+/* ? 0x1du */
+/* ? 0x1eu */
+/* ? 0x1fu */
+#define TV_HTOTAL 0x20u
+#define TV_HDISP 0x21u
+#define TV_HSIZE 0x22u
+#define TV_HSTART 0x23u
+#define TV_HCOUNT 0x24u
+#define TV_VTOTAL 0x25u
+#define TV_VDISP 0x26u
+#define TV_VCOUNT 0x27u
+#define TV_FTOTAL 0x28u
+#define TV_FCOUNT 0x29u
+#define TV_FRESTART 0x2au
+#define TV_HRESTART 0x2bu
+#define TV_VRESTART 0x2cu
+/* ? 0x2du */
+/* ? 0x2eu */
+/* ? 0x2fu */
+/* ? 0x30u */
+/* ? 0x31u */
+/* ? 0x32u */
+/* ? 0x33u */
+/* ? 0x34u */
+/* ? 0x35u */
+/* ? 0x36u */
+/* ? 0x37u */
+/* ? 0x38u */
+/* ? 0x39u */
+/* ? 0x3au */
+/* ? 0x3bu */
+/* ? 0x3cu */
+/* ? 0x3du */
+/* ? 0x3eu */
+/* ? 0x3fu */
+/* ? 0x40u */
+/* ? 0x41u */
+/* ? 0x42u */
+/* ? 0x43u */
+/* ? 0x44u */
+/* ? 0x45u */
+/* ? 0x46u */
+/* ? 0x47u */
+/* ? 0x48u */
+/* ? 0x49u */
+/* ? 0x4au */
+/* ? 0x4bu */
+/* ? 0x4cu */
+/* ? 0x4du */
+/* ? 0x4eu */
+/* ? 0x4fu */
+/* ? 0x50u */
+/* ? 0x51u */
+/* ? 0x52u */
+/* ? 0x53u */
+/* ? 0x54u */
+/* ? 0x55u */
+/* ? 0x56u */
+/* ? 0x57u */
+/* ? 0x58u */
+/* ? 0x59u */
+/* ? 0x5au */
+/* ? 0x5bu */
+/* ? 0x5cu */
+/* ? 0x5du */
+/* ? 0x5eu */
+/* ? 0x5fu */
+#define TV_HOST_READ_DATA 0x60u
+#define TV_HOST_WRITE_DATA 0x61u
+#define TV_HOST_RD_WT_CNTL 0x62u
+/* ? 0x63u */
+/* ? 0x64u */
+/* ? 0x65u */
+/* ? 0x66u */
+/* ? 0x67u */
+/* ? 0x68u */
+/* ? 0x69u */
+/* ? 0x6au */
+/* ? 0x6bu */
+/* ? 0x6cu */
+/* ? 0x6du */
+/* ? 0x6eu */
+/* ? 0x6fu */
+#define TV_VSCALER_CNTL 0x70u
+#define TV_TIMING_CNTL 0x71u
+#define TV_GAMMA_CNTL 0x72u
+#define TV_Y_FALL_CNTL 0x73u
+#define TV_Y_RISE_CNTL 0x74u
+#define TV_Y_SAW_TOOTH_CNTL 0x75u
+/* ? 0x76u */
+/* ? 0x77u */
+/* ? 0x78u */
+/* ? 0x79u */
+/* ? 0x7au */
+/* ? 0x7bu */
+/* ? 0x7cu */
+/* ? 0x7du */
+/* ? 0x7eu */
+/* ? 0x7fu */
+#define TV_MODULATOR_CNTL1 0x80u
+#define TV_MODULATOR_CNTL2 0x81u
+/* ? 0x82u */
+/* ? 0x83u */
+/* ? 0x84u */
+/* ? 0x85u */
+/* ? 0x86u */
+/* ? 0x87u */
+/* ? 0x88u */
+/* ? 0x89u */
+/* ? 0x8au */
+/* ? 0x8bu */
+/* ? 0x8cu */
+/* ? 0x8du */
+/* ? 0x8eu */
+/* ? 0x8fu */
+#define TV_PRE_DAC_MUX_CNTL 0x90u
+/* ? 0x91u */
+/* ? 0x92u */
+/* ? 0x93u */
+/* ? 0x94u */
+/* ? 0x95u */
+/* ? 0x96u */
+/* ? 0x97u */
+/* ? 0x98u */
+/* ? 0x99u */
+/* ? 0x9au */
+/* ? 0x9bu */
+/* ? 0x9cu */
+/* ? 0x9du */
+/* ? 0x9eu */
+/* ? 0x9fu */
+#define TV_DAC_CNTL 0xa0u
+/* ? 0xa1u */
+/* ? 0xa2u */
+/* ? 0xa3u */
+/* ? 0xa4u */
+/* ? 0xa5u */
+/* ? 0xa6u */
+/* ? 0xa7u */
+/* ? 0xa8u */
+/* ? 0xa9u */
+/* ? 0xaau */
+/* ? 0xabu */
+/* ? 0xacu */
+/* ? 0xadu */
+/* ? 0xaeu */
+/* ? 0xafu */
+#define TV_CRC_CNTL 0xb0u
+#define TV_VIDEO_PORT_SIG 0xb1u
+/* ? 0xb2u */
+/* ? 0xb3u */
+/* ? 0xb4u */
+/* ? 0xb5u */
+/* ? 0xb6u */
+/* ? 0xb7u */
+#define TV_VBI_CC_CNTL 0xb8u
+#define TV_VBI_EDS_CNTL 0xb9u
+#define TV_VBI_20BIT_CNTL 0xbau
+/* ? 0xbbu */
+/* ? 0xbcu */
+#define TV_VBI_DTO_CNTL 0xbdu
+#define TV_VBI_LEVEL_CNTL 0xbeu
+/* ? 0xbfu */
+#define TV_UV_ADR 0xc0u
+#define TV_FIFO_TEST_CNTL 0xc1u
+/* ? 0xc2u */
+/* ? 0xc3u */
+/* ? 0xc4u */
+/* ? 0xc5u */
+/* ? 0xc6u */
+/* ? 0xc7u */
+/* ? 0xc8u */
+/* ? 0xc9u */
+/* ? 0xcau */
+/* ? 0xcbu */
+/* ? 0xccu */
+/* ? 0xcdu */
+/* ? 0xceu */
+/* ? 0xcfu */
+/* ? 0xd0u */
+/* ? 0xd1u */
+/* ? 0xd2u */
+/* ? 0xd3u */
+/* ? 0xd4u */
+/* ? 0xd5u */
+/* ? 0xd6u */
+/* ? 0xd7u */
+/* ? 0xd8u */
+/* ? 0xd9u */
+/* ? 0xdau */
+/* ? 0xdbu */
+/* ? 0xdcu */
+/* ? 0xddu */
+/* ? 0xdeu */
+/* ? 0xdfu */
+/* ? 0xe0u */
+/* ? 0xe1u */
+/* ? 0xe2u */
+/* ? 0xe3u */
+/* ? 0xe4u */
+/* ? 0xe5u */
+/* ? 0xe6u */
+/* ? 0xe7u */
+/* ? 0xe8u */
+/* ? 0xe9u */
+/* ? 0xeau */
+/* ? 0xebu */
+/* ? 0xecu */
+/* ? 0xedu */
+/* ? 0xeeu */
+/* ? 0xefu */
+/* ? 0xf0u */
+/* ? 0xf1u */
+/* ? 0xf2u */
+/* ? 0xf3u */
+/* ? 0xf4u */
+/* ? 0xf5u */
+/* ? 0xf6u */
+/* ? 0xf7u */
+/* ? 0xf8u */
+/* ? 0xf9u */
+/* ? 0xfau */
+/* ? 0xfbu */
+/* ? 0xfcu */
+/* ? 0xfdu */
+/* ? 0xfeu */
+/* ? 0xffu */
+
+/* Some ImpacTV definitions */
+#define IT_SDA_GET 0x40u
+#define IT_SDA_SET 0x20u
+#define IT_SDA_DIR 0x10u
+#define IT_SCL_GET 0x04u
+#define IT_SCL_SET 0x02u
+#define IT_SCL_DIR 0x01u
+
+#define IT_I2C_CNTL 0x0015u
+
+/* Miscellaneous */
+
+/* Current X, Y & Dest X, Y mask */
+#define COORD_MASK 0x07ffu
+
+/* Pixel widths */
+#define PIX_WIDTH_1BPP 0x00u
+#define PIX_WIDTH_4BPP 0x01u /* CRTC2: 8bpp */
+#define PIX_WIDTH_8BPP 0x02u /* CRTC2: Undefined */
+#define PIX_WIDTH_15BPP 0x03u
+#define PIX_WIDTH_16BPP 0x04u
+#define PIX_WIDTH_24BPP 0x05u
+#define PIX_WIDTH_32BPP 0x06u
+#define PIX_WIDTH_YUV422 0x07u /* CRTC2 only */
+
+/* Source definitions */
+#define SRC_BKGD 0x00u
+#define SRC_FRGD 0x01u
+#define SRC_HOST 0x02u
+#define SRC_BLIT 0x03u
+#define SRC_PATTERN 0x04u
+#define SRC_SCALER_3D 0x05u
+/* ? 0x06u */
+/* ? 0x07u */
+
+/* The Mixes */
+#define MIX_MASK 0x001fu
+
+#define MIX_NOT_DST 0x0000u
+#define MIX_0 0x0001u
+#define MIX_1 0x0002u
+#define MIX_DST 0x0003u
+#define MIX_NOT_SRC 0x0004u
+#define MIX_XOR 0x0005u
+#define MIX_XNOR 0x0006u
+#define MIX_SRC 0x0007u
+#define MIX_NAND 0x0008u
+#define MIX_NOT_SRC_OR_DST 0x0009u
+#define MIX_SRC_OR_NOT_DST 0x000au
+#define MIX_OR 0x000bu
+#define MIX_AND 0x000cu
+#define MIX_SRC_AND_NOT_DST 0x000du
+#define MIX_NOT_SRC_AND_DST 0x000eu
+#define MIX_NOR 0x000fu
+
+#define MIX_MIN 0x0010u
+#define MIX_DST_MINUS_SRC 0x0011u
+#define MIX_SRC_MINUS_DST 0x0012u
+#define MIX_PLUS 0x0013u
+#define MIX_MAX 0x0014u
+#define MIX_HALF__DST_MINUS_SRC 0x0015u
+#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 */
+
+/* 3D Engine for render acceleration (from Mach64 DRI driver) */
+
+/* SCALE_3D_CNTL */
+#define MACH64_SCALE_PIX_EXPAND_ZERO_EXTEND (0 << 0)
+#define MACH64_SCALE_PIX_EXPAND_DYNAMIC_RANGE (1 << 0)
+#define MACH64_SCALE_DITHER_ERROR_DIFFUSE (0 << 1)
+#define MACH64_SCALE_DITHER_2D_TABLE (1 << 1)
+#define MACH64_DITHER_EN (1 << 2)
+#define MACH64_DITHER_INIT_CURRENT (O << 3)
+#define MACH64_DITHER_INIT_RESET (1 << 3)
+#define MACH64_ROUND_EN (1 << 4)
+
+#define MACH64_TEX_CACHE_DIS (1 << 5)
+
+#define MACH64_SCALE_3D_FCN_MASK (3 << 6)
+#define MACH64_SCALE_3D_FCN_NOP (0 << 6)
+#define MACH64_SCALE_3D_FCN_SCALE (1 << 6)
+#define MACH64_SCALE_3D_FCN_TEXTURE (2 << 6)
+#define MACH64_SCALE_3D_FCN_SHADE (3 << 6)
+#define MACH64_TEXTURE_DISABLE (1 << 6)
+
+#define MACH64_EDGE_ANTI_ALIAS (1 << 8)
+#define MACH64_TEX_CACHE_SPLIT (1 << 9)
+#define MACH64_APPLE_YUV_MODE (1 << 10)
+
+#define MACH64_ALPHA_FOG_EN_MASK (3 << 11)
+#define MACH64_ALPHA_FOG_DIS (0 << 11)
+#define MACH64_ALPHA_FOG_EN_ALPHA (1 << 11)
+#define MACH64_ALPHA_FOG_EN_FOG (2 << 11)
+
+#define MACH64_ALPHA_BLEND_SAT (1 << 13)
+#define MACH64_RED_DITHER_MAX (1 << 14)
+#define MACH64_SIGNED_DST_CLAMP (1 << 15)
+
+#define MACH64_ALPHA_BLEND_SRC_MASK (7 << 16)
+#define MACH64_ALPHA_BLEND_SRC_ZERO (0 << 16)
+#define MACH64_ALPHA_BLEND_SRC_ONE (1 << 16)
+#define MACH64_ALPHA_BLEND_SRC_DSTCOLOR (2 << 16)
+#define MACH64_ALPHA_BLEND_SRC_INVDSTCOLOR (3 << 16)
+#define MACH64_ALPHA_BLEND_SRC_SRCALPHA (4 << 16)
+#define MACH64_ALPHA_BLEND_SRC_INVSRCALPHA (5 << 16)
+#define MACH64_ALPHA_BLEND_SRC_DSTALPHA (6 << 16)
+#define MACH64_ALPHA_BLEND_SRC_INVDSTALPHA (7 << 16)
+#define MACH64_ALPHA_BLEND_DST_MASK (7 << 19)
+#define MACH64_ALPHA_BLEND_DST_ZERO (0 << 19)
+#define MACH64_ALPHA_BLEND_DST_ONE (1 << 19)
+#define MACH64_ALPHA_BLEND_DST_SRCCOLOR (2 << 19)
+#define MACH64_ALPHA_BLEND_DST_INVSRCCOLOR (3 << 19)
+#define MACH64_ALPHA_BLEND_DST_SRCALPHA (4 << 19)
+#define MACH64_ALPHA_BLEND_DST_INVSRCALPHA (5 << 19)
+#define MACH64_ALPHA_BLEND_DST_DSTALPHA (6 << 19)
+#define MACH64_ALPHA_BLEND_DST_INVDSTALPHA (7 << 19)
+
+#define MACH64_TEX_LIGHT_FCN_MASK (3 << 22)
+#define MACH64_TEX_LIGHT_FCN_REPLACE (0 << 22)
+#define MACH64_TEX_LIGHT_FCN_MODULATE (1 << 22)
+#define MACH64_TEX_LIGHT_FCN_ALPHA_DECAL (2 << 22)
+
+#define MACH64_MIP_MAP_DISABLE (1 << 24)
+
+#define MACH64_BILINEAR_TEX_EN (1 << 25)
+#define MACH64_TEX_BLEND_FCN_MASK (3 << 26)
+#define MACH64_TEX_BLEND_FCN_NEAREST (0 << 26)
+#define MACH64_TEX_BLEND_FCN_LINEAR (2 << 26)
+#define MACH64_TEX_BLEND_FCN_TRILINEAR (3 << 26)
+
+#define MACH64_TEX_AMASK_AEN (1 << 28)
+#define MACH64_TEX_AMASK_BLEND_EDGE (1 << 29)
+#define MACH64_TEX_MAP_AEN (1 << 30)
+#define MACH64_SRC_3D_HOST_FIFO (1 << 31)
+
+/* TEX_CNTL */
+#define MACH64_LOD_BIAS_SHIFT 0
+#define MACH64_LOD_BIAS_MASK (0xf << 0)
+#define MACH64_COMP_FACTOR_SHIFT 4
+#define MACH64_COMP_FACTOR_MASK (0xf << 4)
+
+#define MACH64_TEXTURE_COMPOSITE (1 << 8)
+
+#define MACH64_COMP_COMBINE_BLEND (0 << 9)
+#define MACH64_COMP_COMBINE_MODULATE (1 << 9)
+#define MACH64_COMP_BLEND_NEAREST (0 << 11)
+#define MACH64_COMP_BLEND_BILINEAR (1 << 11)
+#define MACH64_COMP_FILTER_NEAREST (0 << 12)
+#define MACH64_COMP_FILTER_BILINEAR (1 << 12)
+#define MACH64_COMP_ALPHA (1 << 13)
+
+#define MACH64_TEXTURE_TILING (1 << 14)
+#define MACH64_COMPOSITE_TEX_TILING (1 << 15)
+#define MACH64_TEX_COLLISION_DISABLE (1 << 16)
+
+#define MACH64_TEXTURE_CLAMP_S (1 << 17)
+#define MACH64_TEXTURE_CLAMP_T (1 << 18)
+#define MACH64_TEX_ST_MULT_W (0 << 19)
+#define MACH64_TEX_ST_DIRECT (1 << 19)
+#define MACH64_TEX_SRC_LOCAL (0 << 20)
+#define MACH64_TEX_SRC_AGP (1 << 20)
+#define MACH64_TEX_UNCOMPRESSED (0 << 21)
+#define MACH64_TEX_VQ_COMPRESSED (1 << 21)
+#define MACH64_COMP_TEX_UNCOMPRESSED (0 << 22)
+#define MACH64_COMP_TEX_VQ_COMPRESSED (1 << 22)
+#define MACH64_TEX_CACHE_FLUSH (1 << 23)
+#define MACH64_SEC_TEX_CLAMP_S (1 << 24)
+#define MACH64_SEC_TEX_CLAMP_T (1 << 25)
+#define MACH64_TEX_WRAP_S (1 << 28)
+#define MACH64_TEX_WRAP_T (1 << 29)
+#define MACH64_TEX_CACHE_SIZE_4K (1 << 30)
+#define MACH64_TEX_CACHE_SIZE_2K (1 << 30)
+#define MACH64_SECONDARY_STW (1 << 31)
+
+/* DP_PIX_WIDTH (superset of PIX_WIDTH_?BPP) */
+#define MACH64_DATATYPE_CI8 2
+#define MACH64_DATATYPE_ARGB1555 3
+#define MACH64_DATATYPE_RGB565 4
+#define MACH64_DATATYPE_ARGB8888 6
+#define MACH64_DATATYPE_RGB332 7
+#define MACH64_DATATYPE_Y8 8
+#define MACH64_DATATYPE_RGB8 9
+#define MACH64_DATATYPE_VYUY422 11
+#define MACH64_DATATYPE_YVYU422 12
+#define MACH64_DATATYPE_AYUV444 14
+#define MACH64_DATATYPE_ARGB4444 15
+
+/* Extract texture level from TEX_SIZE_PITCH and shift appropriately for
+ * addition to TEX_0_OFF.
+ */
+#define TEX_LEVEL(_tex_size_pitch) (((_tex_size_pitch) & 0xf0) >> 2)
+
+#endif /* ___ATIREGS_H___ */
diff --git a/driver/xf86-video-mach64/src/atirgb514.c b/driver/xf86-video-mach64/src/atirgb514.c
new file mode 100644
index 000000000..cc7c0ea4d
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atirgb514.c
@@ -0,0 +1,283 @@
+/*
+ * Copyright 2001 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#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);
+}
diff --git a/driver/xf86-video-mach64/src/atirgb514.h b/driver/xf86-video-mach64/src/atirgb514.h
new file mode 100644
index 000000000..bd7c09edf
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atirgb514.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2001 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 "xf86str.h"
+
+extern void ATIRGB514PreInit(ATIPtr, ATIHWPtr);
+extern void ATIRGB514Save(ATIPtr, ATIHWPtr);
+extern void ATIRGB514Calculate(ATIPtr, ATIHWPtr, DisplayModePtr);
+extern void ATIRGB514Set(ATIPtr, ATIHWPtr);
+
+#endif /* ___ATIRGB514_H___ */
diff --git a/driver/xf86-video-mach64/src/atiscreen.c b/driver/xf86-video-mach64/src/atiscreen.c
new file mode 100644
index 000000000..bc5793471
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atiscreen.c
@@ -0,0 +1,692 @@
+/*
+ * Copyright 1999 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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.
+ *
+ * DRI support by:
+ * Gareth Hughes <gareth@valinux.com>
+ * José Fonseca <j_r_fonseca@yahoo.co.uk>
+ * Leif Delgass <ldelgass@retinalburn.net>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include "ati.h"
+#include "atibus.h"
+#include "atichip.h"
+#include "aticonsole.h"
+#include "aticursor.h"
+#include "atidac.h"
+#include "atidga.h"
+#include "atidri.h"
+#include "atimach64.h"
+#include "atimode.h"
+#include "atiscreen.h"
+#include "atistruct.h"
+#include "atixv.h"
+#include "atimach64accel.h"
+
+#ifdef XF86DRI_DEVEL
+#include "mach64_dri.h"
+#include "mach64_sarea.h"
+#endif
+
+#ifdef TV_OUT
+
+#include "atichip.h"
+
+#endif /* TV_OUT */
+
+#include "shadowfb.h"
+#include "xf86cmap.h"
+
+#include "fb.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++;
+ }
+}
+
+/*
+ * ATIMinBits --
+ *
+ * Compute log base 2 of val.
+ */
+static int
+ATIMinBits
+(
+ int val
+)
+{
+ int bits;
+
+ if (!val) return 1;
+ for (bits = 0; val; val >>= 1, ++bits);
+ return bits;
+}
+
+#ifdef USE_XAA
+static Bool
+ATIMach64SetupMemXAA_NoDRI
+(
+ int iScreen,
+ ScreenPtr pScreen
+)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[iScreen];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ int maxScanlines = ATIMach64MaxY;
+ int maxPixelArea, PixelArea;
+
+ {
+ /*
+ * 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);
+ }
+
+ return TRUE;
+}
+
+#ifdef XF86DRI_DEVEL
+/*
+ * Memory layour for XAA with DRI (no local_textures):
+ * | front | pixmaps, xv | back | depth | textures | c |
+ *
+ * 1024x768@16bpp with 8 MB:
+ * | 1.5 MB | ~3.5 MB | 1.5 MB | 1.5 MB | 0 | c |
+ *
+ * 1024x768@32bpp with 8 MB:
+ * | 3.0 MB | ~0.5 MB | 3.0 MB | 1.5 MB | 0 | c |
+ *
+ * "c" is the hw cursor which occupies 1KB
+ */
+static Bool
+ATIMach64SetupMemXAA
+(
+ int iScreen,
+ ScreenPtr pScreen
+)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[iScreen];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
+ int cpp = pATI->bitsPerPixel >> 3;
+ int widthBytes = pScreenInfo->displayWidth * cpp;
+ int zWidthBytes = pScreenInfo->displayWidth * 2; /* always 16-bit z-buffer */
+ int fbSize = pScreenInfo->videoRam * 1024;
+ int bufferSize = pScreenInfo->virtualY * widthBytes;
+ int zBufferSize = pScreenInfo->virtualY * zWidthBytes;
+ int offscreenBytes, total, scanlines;
+
+ pATIDRIServer->fbX = 0;
+ pATIDRIServer->fbY = 0;
+ pATIDRIServer->frontOffset = 0;
+ pATIDRIServer->frontPitch = pScreenInfo->displayWidth;
+
+ /* Calculate memory remaining for pixcache and textures after
+ * front, back, and depth buffers
+ */
+ offscreenBytes = fbSize - ( 2 * bufferSize + zBufferSize );
+
+ if ( !pATIDRIServer->IsPCI && !pATI->OptionLocalTextures ) {
+ /* Don't allocate a local texture heap for AGP unless requested */
+ pATIDRIServer->textureSize = 0;
+ } else {
+ int l, maxPixcache;
+
+#ifdef XvExtension
+
+ int xvBytes;
+
+ /* Try for enough pixmap cache for DVD and a full viewport
+ */
+ xvBytes = 720*480*cpp; /* enough for single-buffered DVD */
+ maxPixcache = xvBytes > bufferSize ? xvBytes : bufferSize;
+
+#else /* XvExtension */
+
+ /* Try for one viewport */
+ maxPixcache = bufferSize;
+
+#endif /* XvExtension */
+
+ pATIDRIServer->textureSize = offscreenBytes - maxPixcache;
+
+ /* If that gives us less than half the offscreen mem available for textures, split
+ * the available mem between textures and pixmap cache
+ */
+ if (pATIDRIServer->textureSize < (offscreenBytes/2)) {
+ pATIDRIServer->textureSize = offscreenBytes/2;
+ }
+
+ if (pATIDRIServer->textureSize <= 0)
+ pATIDRIServer->textureSize = 0;
+
+ l = ATIMinBits((pATIDRIServer->textureSize-1) / MACH64_NR_TEX_REGIONS);
+ if (l < MACH64_LOG_TEX_GRANULARITY) l = MACH64_LOG_TEX_GRANULARITY;
+
+ /* Round the texture size up to the nearest whole number of
+ * texture regions. Again, be greedy about this, don't round
+ * down.
+ */
+ pATIDRIServer->logTextureGranularity = l;
+ pATIDRIServer->textureSize =
+ (pATIDRIServer->textureSize >> l) << l;
+ }
+
+ total = fbSize - pATIDRIServer->textureSize;
+ scanlines = total / widthBytes;
+ if (scanlines > ATIMach64MaxY) scanlines = ATIMach64MaxY;
+
+ /* Recalculate the texture offset and size to accomodate any
+ * rounding to a whole number of scanlines.
+ * FIXME: Is this actually needed?
+ */
+ pATIDRIServer->textureOffset = scanlines * widthBytes;
+ pATIDRIServer->textureSize = fbSize - pATIDRIServer->textureOffset;
+
+ /* Set a minimum usable local texture heap size. This will fit
+ * two 256x256 textures. We check this after any rounding of
+ * the texture area.
+ */
+ if (pATIDRIServer->textureSize < 256*256 * cpp * 2) {
+ pATIDRIServer->textureOffset = 0;
+ pATIDRIServer->textureSize = 0;
+ scanlines = fbSize / widthBytes;
+ if (scanlines > ATIMach64MaxY) scanlines = ATIMach64MaxY;
+ }
+
+ pATIDRIServer->depthOffset = scanlines * widthBytes - zBufferSize;
+ pATIDRIServer->depthPitch = pScreenInfo->displayWidth;
+ pATIDRIServer->depthY = pATIDRIServer->depthOffset/widthBytes;
+ pATIDRIServer->depthX = (pATIDRIServer->depthOffset -
+ (pATIDRIServer->depthY * widthBytes)) / cpp;
+
+ pATIDRIServer->backOffset = pATIDRIServer->depthOffset - bufferSize;
+ pATIDRIServer->backPitch = pScreenInfo->displayWidth;
+ pATIDRIServer->backY = pATIDRIServer->backOffset/widthBytes;
+ pATIDRIServer->backX = (pATIDRIServer->backOffset -
+ (pATIDRIServer->backY * widthBytes)) / cpp;
+
+ scanlines = fbSize / widthBytes;
+ if (scanlines > ATIMach64MaxY) scanlines = ATIMach64MaxY;
+
+ if ( pATIDRIServer->IsPCI && pATIDRIServer->textureSize == 0 ) {
+ xf86DrvMsg(iScreen, X_WARNING,
+ "Not enough memory for local textures, disabling DRI\n");
+ ATIDRICloseScreen(pScreen);
+ pATI->directRenderingEnabled = FALSE;
+ } else {
+ BoxRec ScreenArea;
+
+ ScreenArea.x1 = 0;
+ ScreenArea.y1 = 0;
+ ScreenArea.x2 = pATI->displayWidth;
+ ScreenArea.y2 = scanlines;
+
+ if (!xf86InitFBManager(pScreen, &ScreenArea)) {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "Memory manager initialization to (%d,%d) (%d,%d) failed\n",
+ ScreenArea.x1, ScreenArea.y1,
+ ScreenArea.x2, ScreenArea.y2);
+ return FALSE;
+ } else {
+ int width, height;
+
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "Memory manager initialized to (%d,%d) (%d,%d)\n",
+ ScreenArea.x1, ScreenArea.y1, ScreenArea.x2, ScreenArea.y2);
+
+ if (xf86QueryLargestOffscreenArea(pScreen, &width, &height, 0, 0, 0)) {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "Largest offscreen area available: %d x %d\n",
+ width, height);
+
+ /* lines in offscreen area needed for depth buffer and textures */
+ pATI->depthTexLines = scanlines
+ - pATIDRIServer->depthOffset / widthBytes;
+ pATI->backLines = scanlines
+ - pATIDRIServer->backOffset / widthBytes
+ - pATI->depthTexLines;
+ pATI->depthTexArea = NULL;
+ pATI->backArea = NULL;
+ } else {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "Unable to determine largest offscreen area available\n");
+ return FALSE;
+ }
+
+ }
+
+ xf86DrvMsg(iScreen, X_INFO, "Will use %d kB of offscreen memory for XAA\n",
+ (offscreenBytes - pATIDRIServer->textureSize)/1024);
+
+ xf86DrvMsg(iScreen, X_INFO, "Will use back buffer at offset 0x%x\n",
+ pATIDRIServer->backOffset);
+
+ xf86DrvMsg(iScreen, X_INFO, "Will use depth buffer at offset 0x%x\n",
+ pATIDRIServer->depthOffset);
+
+ if (pATIDRIServer->textureSize > 0) {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "Will use %d kB for local textures at offset 0x%x\n",
+ pATIDRIServer->textureSize/1024,
+ pATIDRIServer->textureOffset);
+ }
+ }
+
+ return TRUE;
+}
+#endif /* XF86DRI_DEVEL */
+#endif /* USE_XAA */
+
+/*
+ * 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)
+ {
+ pATI->FBBytesPerPixel = pATI->bitsPerPixel >> 3;
+ pATI->FBPitch = PixmapBytePad(pATI->displayWidth, pATI->depth);
+ 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;
+ }
+ }
+
+#ifdef XF86DRI_DEVEL
+
+ /* Setup DRI after visuals have been established, but before
+ * fbScreenInit is called. fbScreenInit will eventually call the
+ * driver's InitGLXVisuals call back.
+ */
+
+ /* According to atiregs.h, GTPro (3D Rage Pro) is the first chip type with
+ * 3D triangle setup (the VERTEX_* registers)
+ */
+ if (pATI->Chip < ATI_CHIP_264GTPRO) {
+ xf86DrvMsg(iScreen, X_WARNING,
+ "Direct rendering is not supported for ATI chips earlier than "
+ "the ATI 3D Rage Pro.\n");
+ pATI->directRenderingEnabled = FALSE;
+ } else {
+ /* FIXME: When we move to dynamic allocation of back and depth
+ * buffers, we will want to revisit the following check for 3
+ * times the virtual size (or 2.5 times for 24-bit depth) of the screen below.
+ */
+ int cpp = pATI->bitsPerPixel >> 3;
+ int maxY = pScreenInfo->videoRam * 1024 / (pATI->displayWidth * cpp);
+ int requiredY;
+
+ requiredY = pScreenInfo->virtualY * 2 /* front, back buffers */
+ + (pScreenInfo->virtualY * 2 / cpp); /* depth buffer (always 16-bit) */
+
+ if (!pATI->OptionAccel) {
+ xf86DrvMsg(iScreen, X_WARNING,
+ "Acceleration disabled, not initializing the DRI\n");
+ pATI->directRenderingEnabled = FALSE;
+ } else if ( maxY > requiredY ) {
+ pATI->directRenderingEnabled = ATIDRIScreenInit(pScreen);
+ } else {
+ xf86DrvMsg(iScreen, X_WARNING,
+ "DRI static buffer allocation failed -- "
+ "need at least %d kB video memory\n",
+ (pScreenInfo->displayWidth * requiredY * cpp ) / 1024);
+ pATI->directRenderingEnabled = FALSE;
+ }
+ }
+
+#endif /* XF86DRI_DEVEL */
+
+ /* Initialise framebuffer layer */
+ switch (pATI->bitsPerPixel)
+ {
+ 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->OptionShadowFB)
+ {
+ if (serverGeneration == 1)
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "RENDER extension not supported with a shadowed"
+ " framebuffer.\n");
+ }
+ else if (!fbPictureInit(pScreen, NULL, 0) &&
+ (serverGeneration == 1))
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "RENDER extension initialisation failed.\n");
+ }
+ }
+
+ xf86SetBlackWhitePixels(pScreen);
+
+#ifdef USE_XAA
+
+ if (!pATI->useEXA) {
+
+ /* Memory manager setup */
+
+#ifdef XF86DRI_DEVEL
+ if (pATI->directRenderingEnabled)
+ {
+ if (!ATIMach64SetupMemXAA(iScreen, pScreen))
+ return FALSE;
+ }
+ else
+#endif /* XF86DRI_DEVEL */
+ {
+ if (!ATIMach64SetupMemXAA_NoDRI(iScreen, pScreen))
+ return FALSE;
+ }
+
+ /* Setup acceleration */
+
+ if (pATI->OptionAccel && !ATIMach64AccelInit(pScreen))
+ return FALSE;
+
+ }
+
+#endif /* USE_XAA */
+
+#ifdef USE_EXA
+
+ if (pATI->useEXA) {
+ /* EXA setups both memory manager and acceleration here */
+
+ if (pATI->OptionAccel && !ATIMach64ExaInit(pScreen))
+ return FALSE;
+ }
+
+#endif /* USE_EXA */
+
+#ifndef AVOID_DGA
+
+ /* Initialise DGA support */
+ (void)ATIDGAInit(pScreen, pScreenInfo, pATI);
+
+#endif /* AVOID_DGA */
+
+ /* Initialise backing store */
+ miInitializeBackingStore(pScreen);
+ xf86SetBackingStore(pScreen);
+
+ /* Initialise cursor */
+ if (!ATIMach64CursorInit(pScreen))
+ return FALSE;
+
+ /* Create default colourmap */
+ if (!miCreateDefColormap(pScreen))
+ return FALSE;
+
+ if (!xf86HandleColormaps(pScreen, 256, pATI->rgbBits, ATILoadPalette, NULL,
+ CMAP_PALETTED_TRUECOLOR |
+ CMAP_LOAD_EVEN_IF_OFFSCREEN))
+ return FALSE;
+
+ /* 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);
+
+#ifdef TV_OUT
+ /* Fix-up TV out after ImpacTV probe */
+ if (pATI->OptionTvOut && pATI->Chip < ATI_CHIP_264GTPRO)
+ ATISwitchMode(0, pScreenInfo->currentMode, 0);
+#endif /* TV_OUT */
+
+#ifdef XF86DRI_DEVEL
+
+ /* DRI finalization */
+ if (pATI->directRenderingEnabled) {
+ /* Now that mi, fb, drm and others have done their thing,
+ * complete the DRI setup.
+ */
+ pATI->directRenderingEnabled = ATIDRIFinishScreenInit(pScreen);
+ }
+ if (pATI->directRenderingEnabled) {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "Direct rendering enabled\n");
+ } else {
+ /* FIXME: Release unused offscreen mem here? */
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "Direct rendering disabled\n");
+ }
+
+#endif /* XF86DRI_DEVEL */
+
+ 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;
+
+#ifdef XF86DRI_DEVEL
+
+ /* Disable direct rendering */
+ if (pATI->directRenderingEnabled)
+ {
+ ATIDRICloseScreen(pScreen);
+ pATI->directRenderingEnabled = FALSE;
+ }
+
+#endif /* XF86DRI_DEVEL */
+
+ ATICloseXVideo(pScreen, pScreenInfo, pATI);
+
+#ifdef USE_EXA
+ if (pATI->pExa)
+ {
+ exaDriverFini(pScreen);
+ xfree(pATI->pExa);
+ pATI->pExa = NULL;
+ }
+#endif
+#ifdef USE_XAA
+ if (pATI->pXAAInfo)
+ {
+ XAADestroyInfoRec(pATI->pXAAInfo);
+ pATI->pXAAInfo = NULL;
+ }
+#endif
+
+ 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);
+
+#ifdef USE_XAA
+ if (!pATI->useEXA)
+ {
+ xfree(pATI->ExpansionBitmapScanlinePtr[1]);
+ pATI->ExpansionBitmapScanlinePtr[0] = NULL;
+ pATI->ExpansionBitmapScanlinePtr[1] = NULL;
+ }
+#endif
+
+ xfree(pATI->pShadow);
+ pATI->pShadow = NULL;
+ pScreenInfo->pScreen = NULL;
+
+ return Closed;
+}
diff --git a/driver/xf86-video-mach64/src/atiscreen.h b/driver/xf86-video-mach64/src/atiscreen.h
new file mode 100644
index 000000000..cf2b23dba
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atiscreen.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 1999 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 "screenint.h"
+
+extern Bool ATIScreenInit(int, ScreenPtr, int, char **);
+extern Bool ATICloseScreen(int, ScreenPtr);
+
+#endif /* ___ATISCREEN_H___ */
diff --git a/driver/xf86-video-mach64/src/atistruct.h b/driver/xf86-video-mach64/src/atistruct.h
new file mode 100644
index 000000000..b9f4d08b5
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atistruct.h
@@ -0,0 +1,529 @@
+/*
+ * Copyright 1999 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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.
+ *
+ * DRI support by:
+ * Gareth Hughes <gareth@valinux.com>
+ * Leif Delgass <ldelgass@retinalburn.net>
+ */
+
+#ifndef ___ATISTRUCT_H___
+#define ___ATISTRUCT_H___ 1
+
+#include "atibank.h"
+#include "aticlock.h"
+#include "atiregs.h"
+
+#ifdef XF86DRI_DEVEL
+
+/*
+ * DRI support
+ */
+#define _XF86DRI_SERVER_
+#include "atidripriv.h"
+#include "mach64_dri.h"
+#include "sarea.h"
+#include "xf86drm.h"
+#include "dri.h"
+
+#endif /* XF86DRI_DEVEL */
+
+#ifdef TV_OUT
+
+#include "vbe.h"
+
+#endif /* TV_OUT */
+
+#ifdef USE_EXA
+#include "exa.h"
+#endif
+#ifdef USE_XAA
+#include "xaa.h"
+#endif
+#include "xf86Cursor.h"
+#include "xf86Pci.h"
+#include "xf86Resources.h"
+
+#include "atipcirename.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, mem_buf_cntl,
+ 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;
+
+ CARD32 scale_3d_cntl, tex_size_pitch, tex_cntl, tex_offset;
+
+ /* 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 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;
+
+#ifdef USE_EXA
+/*
+ * Card engine state for communication across RENDER acceleration hooks.
+ */
+typedef struct _Mach64ContextRegs3D
+{
+ CARD32 dp_mix;
+ CARD32 dp_src;
+ CARD32 dp_write_mask;
+ CARD32 dp_pix_width;
+ CARD32 dst_pitch_offset;
+
+ CARD32 scale_3d_cntl;
+
+ CARD32 tex_cntl;
+ CARD32 tex_size_pitch;
+ CARD32 tex_offset;
+
+ int tex_width; /* src/mask texture width (pixels) */
+ int tex_height; /* src/mask texture height (pixels) */
+
+ Bool frag_src; /* solid src uses fragment color */
+ Bool frag_mask; /* solid mask uses fragment color */
+ CARD32 frag_color; /* solid src/mask color */
+
+ Bool color_alpha; /* the alpha value is contained in the color
+ channels instead of the alpha channel */
+
+ PictTransform *transform;
+} Mach64ContextRegs3D;
+#endif /* USE_EXA */
+
+/*
+ * This structure defines the driver's private area.
+ */
+typedef struct _ATIRec
+{
+
+#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;
+
+ /*
+ * 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;
+
+#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;
+
+#ifndef AVOID_CPIO
+
+ resRange VGAWonderResources[2];
+
+#endif /* AVOID_CPIO */
+
+ /*
+ * Definitions related to video memory.
+ */
+ CARD8 MemoryType;
+ int VideoRAM;
+
+ /*
+ * BIOS-related definitions.
+ */
+ 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, FBBytesPerPixel;
+
+#ifndef AVOID_CPIO
+
+ /*
+ * Banking interface.
+ */
+ pointer pBank;
+
+#endif /* AVOID_CPIO */
+
+ /*
+ * Definitions related to MMIO register apertures.
+ */
+ pointer pMMIO, pBlock[2];
+ unsigned long Block0Base, Block1Base;
+
+ /*
+ * XAA interface.
+ */
+ Bool useEXA;
+#ifdef USE_EXA
+ ExaDriverPtr pExa;
+#endif
+#ifdef USE_XAA
+ XAAInfoRecPtr pXAAInfo;
+#endif
+ 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 */
+#ifdef USE_XAA
+ CARD32 *ExpansionBitmapScanlinePtr[2];
+ int ExpansionBitmapWidth;
+#endif
+#ifdef USE_EXA
+ Bool RenderAccelEnabled;
+ Mach64ContextRegs3D m3d;
+#endif
+
+ /*
+ * 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 refclk;
+ int ClockNumberToProgramme, ReferenceNumerator, ReferenceDenominator;
+ int ProgrammableClock, maxClock;
+ ClockRec ClockDescriptor;
+
+ /*
+ * 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;
+ 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];
+ pointer pXVBuffer; /* USE_EXA: ExaOffscreenArea*
+ USE_XAA: FBLinearPtr */
+ 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;
+
+ /* 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;
+
+ /*
+ * Resource Access Control entity index.
+ */
+ int iEntity;
+
+ /*
+ * Driver options.
+ */
+ unsigned int OptionProbeSparse:1; /* Force probe for fixed (sparse) I/O */
+ unsigned int OptionAccel:1; /* Use hardware draw engine */
+ unsigned int OptionBIOSDisplay:1; /* Allow BIOS interference */
+ unsigned int OptionBlend:1; /* Force horizontal blending */
+ unsigned int OptionCRTDisplay:1; /* Display on both CRT & DFP */
+ unsigned int OptionCSync:1; /* Use composite sync */
+ unsigned int OptionDevel:1; /* Intentionally undocumented */
+
+#ifdef TV_OUT
+
+ CARD8 OptionTvOut; /* Enable TV out if TV is connected */
+ CARD8 OptionTvStd; /* Requested TV standard - see ATITVStandard enum in atioption.h */
+
+#endif /* TV_OUT */
+
+ unsigned int OptionMMIOCache:1; /* Cache MMIO writes */
+ unsigned int OptionTestMMIOCache:1;/* Test MMIO cache integrity */
+ unsigned int OptionPanelDisplay:1; /* Prefer digital panel over CRT */
+ unsigned int OptionShadowFB:1; /* Use shadow frame buffer */
+ unsigned int OptionLCDSync:1; /* Temporary */
+
+ /*
+ * State flags.
+ */
+ CARD8 Unlocked, Mapped, Closeable;
+ CARD8 MMIOInLinear;
+
+ /*
+ * Wrapped functions.
+ */
+ CloseScreenProcPtr CloseScreen;
+
+#ifdef XF86DRI_DEVEL
+
+ /*
+ * DRI data.
+ */
+ int directRenderingEnabled;
+ DRIInfoPtr pDRIInfo;
+ int drmFD;
+ int irq;
+ int numVisualConfigs;
+ __GLXvisualConfig *pVisualConfigs;
+ ATIConfigPrivPtr pVisualConfigsPriv;
+ ATIDRIServerInfoPtr pDRIServerInfo;
+ Bool NeedDRISync;
+ Bool have3DWindows;
+
+ /* offscreen memory management */
+#ifdef USE_XAA
+ int backLines;
+ FBAreaPtr backArea;
+ int depthTexLines;
+ FBAreaPtr depthTexArea;
+#endif
+ CARD8 OptionIsPCI; /* Force PCI mode */
+ CARD8 OptionDMAMode; /* async, sync, mmio */
+ CARD8 OptionAGPMode; /* AGP mode */
+ CARD8 OptionAGPSize; /* AGP size in MB */
+ CARD8 OptionLocalTextures; /* Use local textures + AGP textures (only valid for AGP) */
+ CARD8 OptionBufferSize; /* Command/dma buffer size in MB */
+
+#endif /* XF86DRI_DEVEL */
+
+#ifdef TV_OUT
+ /* TV out */
+ vbeInfoPtr pVBE;
+ xf86Int10InfoPtr pInt10;
+ int vbemode; /* saved text mode */
+ Bool tvActive;
+#endif /* TV_OUT */
+} ATIRec;
+
+#define ATIPTR(_p) ((ATIPtr)((_p)->driverPrivate))
+
+#endif /* ___ATISTRUCT_H___ */
diff --git a/driver/xf86-video-mach64/src/atituner.c b/driver/xf86-video-mach64/src/atituner.c
new file mode 100644
index 000000000..df2cdc55c
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atituner.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#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)"
+ }
+};
diff --git a/driver/xf86-video-mach64/src/atituner.h b/driver/xf86-video-mach64/src/atituner.h
new file mode 100644
index 000000000..dc4f01609
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atituner.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2003 by Marc Aurele La France (TSI @ UQV), tsi@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___ */
diff --git a/driver/xf86-video-mach64/src/atiutil.c b/driver/xf86-video-mach64/src/atiutil.c
new file mode 100644
index 000000000..06e0cdb35
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atiutil.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#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);
+}
diff --git a/driver/xf86-video-mach64/src/atiutil.h b/driver/xf86-video-mach64/src/atiutil.h
new file mode 100644
index 000000000..caa4b70e2
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atiutil.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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
+
+/*
+ * 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(int *, int *);
+extern int ATIDivide(int, int, int, const int);
+
+#endif /* ___ATIUTIL_H___ */
diff --git a/driver/xf86-video-mach64/src/ativalid.c b/driver/xf86-video-mach64/src/ativalid.c
new file mode 100644
index 000000000..51cf5ae89
--- /dev/null
+++ b/driver/xf86-video-mach64/src/ativalid.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "atichip.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);
+ int HBlankWidth, HAdjust, VScan, VInterlace;
+
+ if (flags & MODECHECK_FINAL)
+ {
+ 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;
+
+ {
+ if (VScan > 2)
+ return MODE_NO_VSCAN;
+ }
+
+ return MODE_OK;
+}
diff --git a/driver/xf86-video-mach64/src/ativalid.h b/driver/xf86-video-mach64/src/ativalid.h
new file mode 100644
index 000000000..608e1b53e
--- /dev/null
+++ b/driver/xf86-video-mach64/src/ativalid.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 "xf86str.h"
+
+extern ModeStatus ATIValidMode(int, DisplayModePtr, Bool, int);
+
+#endif /* ___ATIVALID_H___ */
diff --git a/driver/xf86-video-mach64/src/ativga.c b/driver/xf86-video-mach64/src/ativga.c
new file mode 100644
index 000000000..8f4b0da12
--- /dev/null
+++ b/driver/xf86-video-mach64/src/ativga.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "ati.h"
+#include "atichip.h"
+#include "atistruct.h"
+#include "ativga.h"
+#include "ativgaio.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;
+ pATIHW->seq[2] = 0x0FU;
+ pATIHW->seq[4] = 0x0AU;
+
+ /* Initialise CRTC register values */
+ if (((pATI->Chip >= ATI_CHIP_264CT)))
+ pATIHW->crt[19] = pATI->displayWidth >> 3;
+ else
+ pATIHW->crt[19] = pATI->displayWidth >> 4;
+
+ pATIHW->crt[23] = 0xE3U;
+ pATIHW->crt[24] = 0xFFU;
+
+ /* Initialise attribute controller register values */
+ {
+ for (Index = 0; Index < 16; Index++)
+ pATIHW->attr[Index] = Index;
+
+ pATIHW->attr[16] = 0x01U;
+ pATIHW->attr[17] = 0xFFU;
+ }
+ pATIHW->attr[18] = 0x0FU;
+
+ /* Initialise graphics controller register values */
+ if (pATI->Chip >= ATI_CHIP_264CT)
+ pATIHW->gra[5] = 0x40U;
+ if (pATI->Chip >= ATI_CHIP_264VT)
+ 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);
+}
+
+/*
+ * 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;
+ }
+}
+
+#endif /* AVOID_CPIO */
diff --git a/driver/xf86-video-mach64/src/ativga.h b/driver/xf86-video-mach64/src/ativga.h
new file mode 100644
index 000000000..3dd6f0e25
--- /dev/null
+++ b/driver/xf86-video-mach64/src/ativga.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 "xf86str.h"
+
+#ifndef AVOID_CPIO
+
+extern void ATIVGAPreInit(ATIPtr, ATIHWPtr);
+extern void ATIVGASave(ATIPtr, ATIHWPtr);
+extern void ATIVGASet(ATIPtr, ATIHWPtr);
+
+extern void ATIVGASaveScreen(ATIPtr, int);
+
+#endif /* AVOID_CPIO */
+
+#endif /* ___ATIVGA_H___ */
diff --git a/driver/xf86-video-mach64/src/ativgaio.c b/driver/xf86-video-mach64/src/ativgaio.c
new file mode 100644
index 000000000..3b66ee349
--- /dev/null
+++ b/driver/xf86-video-mach64/src/ativgaio.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#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 */
diff --git a/driver/xf86-video-mach64/src/ativgaio.h b/driver/xf86-video-mach64/src/ativgaio.h
new file mode 100644
index 000000000..c73e8ae1b
--- /dev/null
+++ b/driver/xf86-video-mach64/src/ativgaio.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 "atiregs.h"
+#include "atipriv.h"
+
+#include "compiler.h"
+
+#ifndef AVOID_CPIO
+
+extern void ATISetVGAIOBase(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___ */
diff --git a/driver/xf86-video-mach64/src/atividmem.c b/driver/xf86-video-mach64/src/atividmem.c
new file mode 100644
index 000000000..8950f84cd
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atividmem.c
@@ -0,0 +1,493 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "ati.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 = NULL;
+}
+
+#endif /* AVOID_CPIO */
+
+/*
+ * ATIUnmapLinear --
+ *
+ * Unmap linear aperture.
+ */
+static void
+ATIUnmapLinear
+(
+ int iScreen,
+ ATIPtr pATI
+)
+{
+ if (pATI->pMemory)
+ {
+#ifndef XSERVER_LIBPCIACCESS
+ xf86UnMapVidMem(iScreen, pATI->pMemory, pATI->LinearSize);
+#else
+ pci_device_unmap_range(pATI->PCIInfo, pATI->pMemory, pATI->LinearSize);
+#endif
+
+#if X_BYTE_ORDER != X_LITTLE_ENDIAN
+
+ if (pATI->pMemoryLE)
+ {
+#ifndef XSERVER_LIBPCIACCESS
+ xf86UnMapVidMem(iScreen, pATI->pMemoryLE, pATI->LinearSize);
+#else
+ pci_device_unmap_range(pATI->PCIInfo, pATI->pMemoryLE, pATI->LinearSize);
+#endif
+ }
+
+#endif /* X_BYTE_ORDER */
+
+ }
+
+ pATI->pMemory = pATI->pMemoryLE = NULL;
+}
+
+/*
+ * ATIUnmapMMIO --
+ *
+ * Unmap MMIO registers.
+ */
+static void
+ATIUnmapMMIO
+(
+ int iScreen,
+ ATIPtr pATI
+)
+{
+ if (pATI->pMMIO)
+ {
+#ifndef XSERVER_LIBPCIACCESS
+ xf86UnMapVidMem(iScreen, pATI->pMMIO, getpagesize());
+#else
+ unsigned long size;
+
+ size = PCI_REGION_SIZE(pATI->PCIInfo, 2);
+ if (!size || size > getpagesize())
+ size = getpagesize();
+ pci_device_unmap_range(pATI->PCIInfo, pATI->pMMIO, size);
+#endif
+ }
+
+ 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)
+ {
+#ifndef XSERVER_LIBPCIACCESS
+ xf86UnMapVidMem(iScreen, pATI->pCursorPage, getpagesize());
+#else
+ pci_device_unmap_range(pATI->PCIInfo, pATI->pCursorPage, getpagesize());
+#endif
+ }
+
+ pATI->pCursorPage = pATI->pCursorImage = NULL;
+}
+
+/*
+ * ATIMapApertures --
+ *
+ * This function maps all apertures used by the driver.
+ *
+ * It is called three times:
+ * - to setup MMIO for an MMIO-only driver during Probe
+ * - to setup MMIO for an MMIO-only driver during PreInit
+ * - to setup MMIO (with Block0Base set) and FB (with LinearBase set)
+ */
+Bool
+ATIMapApertures
+(
+ int iScreen,
+ ATIPtr pATI
+)
+{
+ pciVideoPtr pVideo = pATI->PCIInfo;
+#ifndef XSERVER_LIBPCIACCESS
+ PCITAG Tag = PCI_CFG_TAG(pVideo);
+#else
+ pciVideoPtr Tag = pVideo;
+#endif
+ unsigned long PageSize = getpagesize();
+
+ if (pATI->Mapped)
+ return TRUE;
+
+#ifndef AVOID_CPIO
+
+ /* Map VGA aperture */
+ if (pATI->VGAAdapter)
+ {
+ /*
+ * No relocation, resizing, caching or write-combining of this
+ * aperture is supported. Hence, the hard-coded values here...
+ */
+ pATI->pBank = xf86MapDomainMemory(iScreen, VIDMEM_MMIO_32BIT,
+ Tag, 0x000A0000U, 0x00010000U);
+
+ if (!pATI->pBank)
+ return FALSE;
+
+ pATI->Mapped = TRUE;
+ }
+
+#endif /* AVOID_CPIO */
+
+ /* Map linear aperture */
+ if (pATI->LinearBase)
+ {
+
+#ifndef XSERVER_LIBPCIACCESS
+
+ pATI->pMemory = xf86MapPciMem(iScreen, VIDMEM_FRAMEBUFFER,
+ Tag, pATI->LinearBase, pATI->LinearSize);
+
+#else /* XSERVER_LIBPCIACCESS */
+
+ int mode = PCI_DEV_MAP_FLAG_WRITABLE | PCI_DEV_MAP_FLAG_WRITE_COMBINE;
+
+ int err = pci_device_map_range(pVideo,
+ pATI->LinearBase,
+ pATI->LinearSize,
+ mode, &pATI->pMemory);
+
+ if (err)
+ {
+ xf86DrvMsg (iScreen, X_ERROR,
+ "Unable to map linear aperture. %s (%d)\n",
+ strerror (err), err);
+ }
+
+#endif /* XSERVER_LIBPCIACCESS */
+
+ 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.
+ */
+ {
+
+#ifndef XSERVER_LIBPCIACCESS
+
+ pATI->pMemoryLE = xf86MapPciMem(iScreen, VIDMEM_MMIO, Tag,
+ pATI->LinearBase - 0x00800000U, pATI->LinearSize);
+
+
+#else /* XSERVER_LIBPCIACCESS */
+
+ int mode = PCI_DEV_MAP_FLAG_WRITABLE;
+
+ int err = pci_device_map_range(pVideo,
+ pATI->LinearBase - 0x00800000U,
+ pATI->LinearSize,
+ mode, &pATI->pMemoryLE);
+
+ if (err)
+ {
+ xf86DrvMsg (iScreen, X_ERROR,
+ "Unable to map extended linear aperture. %s (%d)\n",
+ strerror (err), err);
+ }
+
+#endif /* XSERVER_LIBPCIACCESS */
+
+ 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);
+
+#ifndef XSERVER_LIBPCIACCESS
+
+ pATI->pMMIO = xf86MapPciMem(iScreen, VIDMEM_MMIO,
+ Tag, MMIOBase, PageSize);
+
+#else /* XSERVER_LIBPCIACCESS */
+
+ int mode = PCI_DEV_MAP_FLAG_WRITABLE;
+
+ int err;
+ int size;
+
+ size = PCI_REGION_SIZE(pVideo, 2);
+ if (!size || size > PageSize)
+ size = PageSize;
+
+ err = pci_device_map_range(pVideo, MMIOBase,
+ size, mode, &pATI->pMMIO);
+
+ if (err)
+ {
+ xf86DrvMsg (iScreen, X_ERROR,
+ "Unable to map mmio aperture. %s (%d)\n",
+ strerror (err), err);
+ }
+
+#endif /* XSERVER_LIBPCIACCESS */
+
+ 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);
+
+#ifndef XSERVER_LIBPCIACCESS
+
+ pATI->pCursorPage = xf86MapPciMem(iScreen, VIDMEM_FRAMEBUFFER,
+ Tag, CursorBase, PageSize);
+
+#else /* XSERVER_LIBPCIACCESS */
+
+ int mode = PCI_DEV_MAP_FLAG_WRITABLE | PCI_DEV_MAP_FLAG_WRITE_COMBINE;
+
+ int err = pci_device_map_range(pVideo,
+ CursorBase,
+ PageSize,
+ mode, &pATI->pCursorPage);
+
+ if (err)
+ {
+ xf86DrvMsg (iScreen, X_ERROR,
+ "Unable to map cursor aperture. %s (%d)\n",
+ strerror (err), err);
+ }
+
+#endif /* XSERVER_LIBPCIACCESS */
+
+ 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 */
+
+}
diff --git a/driver/xf86-video-mach64/src/atividmem.h b/driver/xf86-video-mach64/src/atividmem.h
new file mode 100644
index 000000000..22b1a1d00
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atividmem.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 "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(int, ATIPtr);
+extern void ATIUnmapApertures(int, ATIPtr);
+
+#endif /* ___ATIVIDMEM_H___ */
diff --git a/driver/xf86-video-mach64/src/atiwonder.c b/driver/xf86-video-mach64/src/atiwonder.c
new file mode 100644
index 000000000..371e251a0
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atiwonder.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/*
+ * 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;
+ pATIHW->b6 = 0x04U;
+ 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);
+ {
+ pATIHW->be = ATIGetExtReg(0xBEU);
+ {
+ 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);
+ }
+ }
+}
+
+/*
+ * ATIVGAWonderSet --
+ *
+ * This function loads the VGA Wonder portion of a video state.
+ */
+void
+ATIVGAWonderSet
+(
+ ATIPtr pATI,
+ ATIHWPtr pATIHW
+)
+{
+ {
+ ATIModifyExtReg(pATI, 0xBEU, -1, 0x00U, pATIHW->be);
+ {
+ 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 */
diff --git a/driver/xf86-video-mach64/src/atiwonder.h b/driver/xf86-video-mach64/src/atiwonder.h
new file mode 100644
index 000000000..2fe5e5ea7
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atiwonder.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 "xf86str.h"
+
+#ifndef AVOID_CPIO
+
+extern void ATIVGAWonderPreInit(ATIPtr, ATIHWPtr);
+extern void ATIVGAWonderSave(ATIPtr, ATIHWPtr);
+extern void ATIVGAWonderSet(ATIPtr, ATIHWPtr);
+
+#endif /* AVOID_CPIO */
+
+#endif /* ___ATIWONDER_H___ */
diff --git a/driver/xf86-video-mach64/src/atiwonderio.c b/driver/xf86-video-mach64/src/atiwonderio.c
new file mode 100644
index 000000000..e6c0db78d
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atiwonderio.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#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;
+
+ ATIPutExtReg(Index, NewValue);
+}
+
+#endif /* AVOID_CPIO */
diff --git a/driver/xf86-video-mach64/src/atiwonderio.h b/driver/xf86-video-mach64/src/atiwonderio.h
new file mode 100644
index 000000000..515cd4d62
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atiwonderio.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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(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___ */
diff --git a/driver/xf86-video-mach64/src/atixv.h b/driver/xf86-video-mach64/src/atixv.h
new file mode 100644
index 000000000..a33106f44
--- /dev/null
+++ b/driver/xf86-video-mach64/src/atixv.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2001 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@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 "xf86str.h"
+
+extern void ATIXVPreInit(ATIPtr);
+extern Bool ATIInitializeXVideo(ScreenPtr, ScrnInfoPtr, ATIPtr);
+extern void ATICloseXVideo(ScreenPtr, ScrnInfoPtr, ATIPtr);
+
+#endif /* ___ATIXV_H___ */
diff --git a/driver/xf86-video-mach64/src/mach64_common.h b/driver/xf86-video-mach64/src/mach64_common.h
new file mode 100644
index 000000000..f1f765a4b
--- /dev/null
+++ b/driver/xf86-video-mach64/src/mach64_common.h
@@ -0,0 +1,130 @@
+/* mach64_common.h -- common header definitions for Rage Pro 2D/3D/DRM suite
+ * Created: Sun Dec 03 11:34:16 2000 by gareth@valinux.com
+ *
+ * Copyright 2000 Gareth Hughes
+ * 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
+ * GARETH HUGHES 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@valinux.com>
+ * Leif Delgass <ldelgass@retinalburn.net>
+ */
+
+#ifndef __MACH64_COMMON_H__
+#define __MACH64_COMMON_H__ 1
+
+/* WARNING: If you change any of these defines, make sure to change
+ * the kernel include file as well (mach64_drm.h)
+ */
+
+/* Driver specific DRM command indices
+ * NOTE: these are not OS specific, but they are driver specific
+ */
+#define DRM_MACH64_INIT 0x00
+#define DRM_MACH64_IDLE 0x01
+#define DRM_MACH64_RESET 0x02
+#define DRM_MACH64_SWAP 0x03
+#define DRM_MACH64_CLEAR 0x04
+#define DRM_MACH64_VERTEX 0x05
+#define DRM_MACH64_BLIT 0x06
+#define DRM_MACH64_FLUSH 0x07
+#define DRM_MACH64_GETPARAM 0x08
+
+/* Buffer flags for clears
+ */
+#define MACH64_FRONT 0x1
+#define MACH64_BACK 0x2
+#define MACH64_DEPTH 0x4
+
+/* Primitive types for vertex buffers
+ */
+#define MACH64_PRIM_POINTS 0x00000000
+#define MACH64_PRIM_LINES 0x00000001
+#define MACH64_PRIM_LINE_LOOP 0x00000002
+#define MACH64_PRIM_LINE_STRIP 0x00000003
+#define MACH64_PRIM_TRIANGLES 0x00000004
+#define MACH64_PRIM_TRIANGLE_STRIP 0x00000005
+#define MACH64_PRIM_TRIANGLE_FAN 0x00000006
+#define MACH64_PRIM_QUADS 0x00000007
+#define MACH64_PRIM_QUAD_STRIP 0x00000008
+#define MACH64_PRIM_POLYGON 0x00000009
+
+
+typedef enum _drmMach64DMAMode {
+ MACH64_MODE_DMA_ASYNC,
+ MACH64_MODE_DMA_SYNC,
+ MACH64_MODE_MMIO
+} drmMach64DMAMode;
+
+typedef struct {
+ enum {
+ DRM_MACH64_INIT_DMA = 0x01,
+ DRM_MACH64_CLEANUP_DMA = 0x02
+ } func;
+ unsigned long sarea_priv_offset;
+ int is_pci;
+ drmMach64DMAMode dma_mode;
+
+ 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 buffers_offset;
+ unsigned long agp_textures_offset;
+} drmMach64Init;
+
+typedef struct {
+ unsigned int flags;
+ int x, y, w, h;
+ unsigned int clear_color;
+ unsigned int clear_depth;
+} drmMach64Clear;
+
+typedef struct {
+ int prim;
+ void *buf; /* Address of vertex buffer */
+ unsigned long used; /* Number of bytes in buffer */
+ int discard; /* Client finished with buffer? */
+} drmMach64Vertex;
+
+typedef struct {
+ void *buf;
+ int pitch;
+ int offset;
+ int format;
+ unsigned short x, y;
+ unsigned short width, height;
+} drmMach64Blit;
+
+typedef struct {
+ int param;
+ int *value;
+} drmMach64GetParam;
+
+#define MACH64_PARAM_FRAMES_QUEUED 1
+#define MACH64_PARAM_IRQ_NR 2
+
+#endif /* __MACH64_COMMON_H__ */
diff --git a/driver/xf86-video-mach64/src/mach64_dri.h b/driver/xf86-video-mach64/src/mach64_dri.h
new file mode 100644
index 000000000..7061931cf
--- /dev/null
+++ b/driver/xf86-video-mach64/src/mach64_dri.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2000 Gareth Hughes
+ * 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
+ * GARETH HUGHES 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:
+ * Gareth Hughes <gareth@valinux.com>
+ * Leif Delgass <ldelgass@retinalburn.net>
+ */
+
+#ifndef __MACH64_DRI_H__
+#define __MACH64_DRI_H__ 1
+
+#include "xf86drm.h"
+
+typedef struct {
+ drm_handle_t fbHandle;
+
+ drm_handle_t regsHandle;
+ drmSize regsSize;
+
+ int IsPCI;
+
+ drm_handle_t agpHandle; /* Handle from drmAgpAlloc */
+ unsigned long agpOffset;
+ drmSize agpSize;
+ int agpMode;
+
+ /* DMA descriptor ring */
+ unsigned long ringStart; /* Offset into AGP space */
+ drm_handle_t ringHandle; /* Handle from drmAddMap */
+ drmSize ringMapSize; /* Size of map */
+ int ringSize; /* Size of ring (in kB) */
+ drmAddress ringMap; /* Map */
+
+ /* vertex buffer data */
+ unsigned long bufferStart; /* Offset into AGP space */
+ drm_handle_t bufferHandle; /* Handle from drmAddMap */
+ drmSize bufferMapSize; /* Size of map */
+ int bufferSize; /* Size of buffers (in MB) */
+ drmAddress bufferMap; /* Map */
+
+ drmBufMapPtr drmBuffers; /* Buffer map */
+ int numBuffers; /* Number of buffers */
+
+ /* AGP Texture data */
+ unsigned long agpTexStart; /* Offset into AGP space */
+ drm_handle_t agpTexHandle; /* Handle from drmAddMap */
+ drmSize agpTexMapSize; /* Size of map */
+ int agpTexSize; /* Size of AGP tex space (in MB) */
+ drmAddress agpTexMap; /* Map */
+ int log2AGPTexGran;
+
+ 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 logTextureGranularity;
+} ATIDRIServerInfoRec, *ATIDRIServerInfoPtr;
+
+typedef struct {
+ int chipset;
+ int width;
+ int height;
+ int mem;
+ int cpp;
+
+ int IsPCI;
+ int AGPMode;
+
+ unsigned int frontOffset;
+ unsigned int frontPitch;
+
+ unsigned int backOffset;
+ unsigned int backPitch;
+
+ unsigned int depthOffset;
+ unsigned int depthPitch;
+
+ unsigned int textureOffset;
+ unsigned int textureSize;
+ int logTextureGranularity;
+
+ drm_handle_t regs;
+ drmSize regsSize;
+
+ drm_handle_t agp;
+ drmSize agpSize;
+ unsigned int agpTextureOffset;
+ unsigned int agpTextureSize;
+ int logAgpTextureGranularity;
+} ATIDRIRec, *ATIDRIPtr;
+
+#endif /* __MACH64_DRI_H__ */
diff --git a/driver/xf86-video-mach64/src/mach64_sarea.h b/driver/xf86-video-mach64/src/mach64_sarea.h
new file mode 100644
index 000000000..718b896e7
--- /dev/null
+++ b/driver/xf86-video-mach64/src/mach64_sarea.h
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2000 Gareth Hughes
+ * 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
+ * GARETH HUGHES 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:
+ * Gareth Hughes <gareth@valinux.com>
+ * Leif Delgass <ldelgass@retinalburn.net>
+ */
+
+#ifndef __MACH64_SAREA_H__
+#define __MACH64_SAREA_H__ 1
+
+#include <X11/Xmd.h>
+
+/* WARNING: If you change any of these defines, make sure to change the
+ * defines in the kernel file (mach64_drm.h)
+ */
+#ifndef __MACH64_SAREA_DEFINES__
+#define __MACH64_SAREA_DEFINES__ 1
+
+/* What needs to be changed for the current vertex buffer?
+ * GH: We're going to be pedantic about this. We want the card to do as
+ * little as possible, so let's avoid having it fetch a whole bunch of
+ * register values that don't change all that often, if at all.
+ */
+#define MACH64_UPLOAD_DST_OFF_PITCH 0x0001
+#define MACH64_UPLOAD_Z_OFF_PITCH 0x0002
+#define MACH64_UPLOAD_Z_ALPHA_CNTL 0x0004
+#define MACH64_UPLOAD_SCALE_3D_CNTL 0x0008
+#define MACH64_UPLOAD_DP_FOG_CLR 0x0010
+#define MACH64_UPLOAD_DP_WRITE_MASK 0x0020
+#define MACH64_UPLOAD_DP_PIX_WIDTH 0x0040
+#define MACH64_UPLOAD_SETUP_CNTL 0x0080
+#define MACH64_UPLOAD_MISC 0x0100
+#define MACH64_UPLOAD_TEXTURE 0x0200
+#define MACH64_UPLOAD_TEX0IMAGE 0x0400
+#define MACH64_UPLOAD_TEX1IMAGE 0x0800
+#define MACH64_UPLOAD_CLIPRECTS 0x1000 /* handled client-side */
+#define MACH64_UPLOAD_CONTEXT 0x00ff
+#define MACH64_UPLOAD_ALL 0x1fff
+
+/* DMA buffer size
+ */
+#define MACH64_BUFFER_SIZE 16384
+
+/* Max number of swaps allowed on the ring
+ * before the client must wait
+ */
+#define MACH64_MAX_QUEUED_FRAMES 3
+
+/* Byte offsets for host blit buffer data
+ */
+#define MACH64_HOSTDATA_BLIT_OFFSET 104
+
+/* Keep these small for testing.
+ */
+#define MACH64_NR_SAREA_CLIPRECTS 8
+
+
+#define MACH64_CARD_HEAP 0
+#define MACH64_AGP_HEAP 1
+#define MACH64_NR_TEX_HEAPS 2
+#define MACH64_NR_TEX_REGIONS 64
+#define MACH64_LOG_TEX_GRANULARITY 16
+
+#define MACH64_TEX_MAXLEVELS 1
+
+#define MACH64_NR_CONTEXT_REGS 15
+#define MACH64_NR_TEXTURE_REGS 4
+
+#endif /* __MACH64_SAREA_DEFINES__ */
+
+typedef struct {
+ /* Context state */
+ unsigned int dst_off_pitch; /* 0x500 */
+
+ unsigned int z_off_pitch; /* 0x548 */ /* ****** */
+ unsigned int z_cntl; /* 0x54c */
+ unsigned int alpha_tst_cntl; /* 0x550 */
+
+ unsigned int scale_3d_cntl; /* 0x5fc */
+
+ unsigned int sc_left_right; /* 0x6a8 */
+ unsigned int sc_top_bottom; /* 0x6b4 */
+
+ unsigned int dp_fog_clr; /* 0x6c4 */
+ unsigned int dp_write_mask; /* 0x6c8 */
+ unsigned int dp_pix_width; /* 0x6d0 */
+ unsigned int dp_mix; /* 0x6d4 */ /* ****** */
+ unsigned int dp_src; /* 0x6d8 */ /* ****** */
+
+ unsigned int clr_cmp_cntl; /* 0x708 */ /* ****** */
+ unsigned int gui_traj_cntl; /* 0x730 */ /* ****** */
+
+ unsigned int setup_cntl; /* 0x304 */
+
+ /* Texture state */
+ unsigned int tex_size_pitch; /* 0x770 */
+ unsigned int tex_cntl; /* 0x774 */
+ unsigned int secondary_tex_off; /* 0x778 */
+ unsigned int tex_offset; /* 0x5c0 */
+} mach64_context_regs_t;
+
+typedef struct {
+ /* The channel for communication of state information to the kernel
+ * on firing a vertex buffer.
+ */
+ mach64_context_regs_t ContextState;
+ unsigned int dirty;
+ unsigned int vertsize;
+
+#ifdef XF86DRI
+ /* The current cliprects, or a subset thereof.
+ */
+ drm_clip_rect_t boxes[MACH64_NR_SAREA_CLIPRECTS];
+ unsigned int nbox;
+#endif
+ /* Counter for throttling of rendering clients.
+ */
+ unsigned int frames_queued;
+
+ /* 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.
+ */
+ drmTextureRegion texList[MACH64_NR_TEX_HEAPS][MACH64_NR_TEX_REGIONS+1];
+ unsigned int texAge[MACH64_NR_TEX_HEAPS];
+
+ int ctxOwner; /* last context to upload state */
+} ATISAREAPrivRec, *ATISAREAPrivPtr;
+
+#endif /* __MACH64_SAREA_H__ */