diff options
author | Owain Ainsworth <oga@cvs.openbsd.org> | 2008-07-12 15:43:43 +0000 |
---|---|---|
committer | Owain Ainsworth <oga@cvs.openbsd.org> | 2008-07-12 15:43:43 +0000 |
commit | 6be08682fffb33fb738ea68a2d49333fa547d3ac (patch) | |
tree | ea65f842b95b23c12f72c8dd6002c85d5f130e0b /driver/xf86-video-mach64/src | |
parent | 6349dabddf7e186738c7f643a3aa94d79c945330 (diff) |
Import xf86-video-mach64, version 6.8.0. In the correct directory.
ok matthieu@.
Diffstat (limited to 'driver/xf86-video-mach64/src')
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__ */ |