diff options
author | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2006-11-26 20:18:23 +0000 |
---|---|---|
committer | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2006-11-26 20:18:23 +0000 |
commit | c7c4f4e6004ac4b08f8b3b781337c90e2618acc0 (patch) | |
tree | c7e0100293b07ff8b88574d4e40b47eabbb680a9 /driver/xf86-video-trident/src | |
parent | 6d2232c8c34f073b89dd6ffc7d3fc8271b54c1af (diff) |
Importing xf86-video-trident 1.2.3
Diffstat (limited to 'driver/xf86-video-trident/src')
22 files changed, 13655 insertions, 0 deletions
diff --git a/driver/xf86-video-trident/src/Makefile.am b/driver/xf86-video-trident/src/Makefile.am new file mode 100644 index 000000000..730fe2fa0 --- /dev/null +++ b/driver/xf86-video-trident/src/Makefile.am @@ -0,0 +1,51 @@ +# Copyright 2005 Adam Jackson. +# +# 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. +AM_CFLAGS = @XORG_CFLAGS@ +trident_drv_la_LTLIBRARIES = trident_drv.la +trident_drv_la_LDFLAGS = -module -avoid-version +trident_drv_ladir = @moduledir@/drivers + +trident_drv_la_SOURCES = \ + blade_accel.c \ + blade_accel_exa.c \ + image_accel.c \ + trident_accel.c \ + trident_bank.c \ + trident_dac.c \ + trident_dga.c \ + trident_driver.c \ + trident.h \ + tridenthelper.c \ + trident_i2c.c \ + tridentramdac.c \ + trident_regs.h \ + trident_shadow.c \ + trident_tv.c \ + trident_video.c \ + tvga_dac.c \ + xp_accel.c \ + xp4_accel.c \ + xp4_accel_exa.c diff --git a/driver/xf86-video-trident/src/Makefile.in b/driver/xf86-video-trident/src/Makefile.in new file mode 100644 index 000000000..ed80f80d6 --- /dev/null +++ b/driver/xf86-video-trident/src/Makefile.in @@ -0,0 +1,545 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 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. +# +# 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. + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +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)$(trident_drv_ladir)" +trident_drv_laLTLIBRARIES_INSTALL = $(INSTALL) +LTLIBRARIES = $(trident_drv_la_LTLIBRARIES) +trident_drv_la_LIBADD = +am_trident_drv_la_OBJECTS = blade_accel.lo blade_accel_exa.lo \ + image_accel.lo trident_accel.lo trident_bank.lo trident_dac.lo \ + trident_dga.lo trident_driver.lo tridenthelper.lo \ + trident_i2c.lo tridentramdac.lo trident_shadow.lo \ + trident_tv.lo trident_video.lo tvga_dac.lo xp_accel.lo \ + xp4_accel.lo xp4_accel_exa.lo +trident_drv_la_OBJECTS = $(am_trident_drv_la_OBJECTS) +DEFAULT_INCLUDES = -I. -I$(srcdir) -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 --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(trident_drv_la_SOURCES) +DIST_SOURCES = $(trident_drv_la_SOURCES) +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@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +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@ +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_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@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +MISC_MAN_DIR = @MISC_MAN_DIR@ +MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@ +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@ +PKG_CONFIG = @PKG_CONFIG@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +XORG_CFLAGS = @XORG_CFLAGS@ +XORG_LIBS = @XORG_LIBS@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +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@ +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@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ + +# 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. +AM_CFLAGS = @XORG_CFLAGS@ +trident_drv_la_LTLIBRARIES = trident_drv.la +trident_drv_la_LDFLAGS = -module -avoid-version +trident_drv_ladir = @moduledir@/drivers +trident_drv_la_SOURCES = \ + blade_accel.c \ + blade_accel_exa.c \ + image_accel.c \ + trident_accel.c \ + trident_bank.c \ + trident_dac.c \ + trident_dga.c \ + trident_driver.c \ + trident.h \ + tridenthelper.c \ + trident_i2c.c \ + tridentramdac.c \ + trident_regs.h \ + trident_shadow.c \ + trident_tv.c \ + trident_video.c \ + tvga_dac.c \ + xp_accel.c \ + xp4_accel.c \ + xp4_accel_exa.c + +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-trident_drv_laLTLIBRARIES: $(trident_drv_la_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(trident_drv_ladir)" || $(mkdir_p) "$(DESTDIR)$(trident_drv_ladir)" + @list='$(trident_drv_la_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=install $(trident_drv_laLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(trident_drv_ladir)/$$f'"; \ + $(LIBTOOL) --mode=install $(trident_drv_laLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(trident_drv_ladir)/$$f"; \ + else :; fi; \ + done + +uninstall-trident_drv_laLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @set -x; list='$(trident_drv_la_LTLIBRARIES)'; for p in $$list; do \ + p=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(trident_drv_ladir)/$$p'"; \ + $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(trident_drv_ladir)/$$p"; \ + done + +clean-trident_drv_laLTLIBRARIES: + -test -z "$(trident_drv_la_LTLIBRARIES)" || rm -f $(trident_drv_la_LTLIBRARIES) + @list='$(trident_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 +trident_drv.la: $(trident_drv_la_OBJECTS) $(trident_drv_la_DEPENDENCIES) + $(LINK) -rpath $(trident_drv_ladir) $(trident_drv_la_LDFLAGS) $(trident_drv_la_OBJECTS) $(trident_drv_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blade_accel.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blade_accel_exa.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/image_accel.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trident_accel.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trident_bank.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trident_dac.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trident_dga.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trident_driver.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trident_i2c.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trident_shadow.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trident_tv.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trident_video.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tridenthelper.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tridentramdac.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tvga_dac.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xp4_accel.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xp4_accel_exa.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xp_accel.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@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@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@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@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@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 + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +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; } \ + END { 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; } \ + END { 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=; \ + 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; } \ + END { 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)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + 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)$(trident_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-trident_drv_laLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-trident_drv_laLTLIBRARIES + +install-exec-am: + +install-info: install-info-am + +install-man: + +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-info-am uninstall-trident_drv_laLTLIBRARIES + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-trident_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-exec \ + install-exec-am install-info install-info-am install-man \ + install-strip install-trident_drv_laLTLIBRARIES 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-info-am \ + uninstall-trident_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-trident/src/blade_accel.c b/driver/xf86-video-trident/src/blade_accel.c new file mode 100644 index 000000000..a2725d388 --- /dev/null +++ b/driver/xf86-video-trident/src/blade_accel.c @@ -0,0 +1,705 @@ +/* + * Copyright 1997-2003 by Alan Hourihane, North Wales, UK. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * + * Trident Blade3D accelerated options. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/blade_accel.c,v 1.21 2003/10/30 13:38:01 alanh Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "xf86_OSproc.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#include "miline.h" + +#include "trident.h" +#include "trident_regs.h" + +#include "xaarop.h" +#include "xaalocal.h" + +static void BladeSync(ScrnInfoPtr pScrn); +#if 0 +static void BladeSetupForSolidLine(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask); +static void BladeSubsequentSolidBresenhamLine(ScrnInfoPtr pScrn, + int x, int y, int dmaj, int dmin, int e, + int len, int octant); +static void BladeSubsequentSolidTwoPointLine( ScrnInfoPtr pScrn, + int x1, int y1, int x2, int y2, int flags); +static void BladeSetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, + int rop, unsigned int planemask, int length, + unsigned char *pattern); +static void BladeSubsequentDashedTwoPointLine( ScrnInfoPtr pScrn, + int x1, int y1, int x2, int y2, int flags, + int phase); +#endif +static void BladeSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask); +static void BladeSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, + int y, int w, int h); +static void BladeSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, + int x1, int y1, int x2, + int y2, int w, int h); +static void BladeSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, + int xdir, int ydir, int rop, + unsigned int planemask, + int transparency_color); +#if 0 +static void BladeSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn, + int fg, int bg, int rop, + unsigned int planemask); +static void BladeSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn, + int x, int y, int w, int h, int srcx, int srcy, + int offset); +#endif +static void BladeSetupForCPUToScreenColorExpand(ScrnInfoPtr pScrn, + int fg, int bg, int rop, + unsigned int planemask); +static void BladeSubsequentCPUToScreenColorExpand(ScrnInfoPtr pScrn, + int x, int y, int w, int h, int skipleft); +static void BladeSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, + int x2, int y2); +static void BladeDisableClipping(ScrnInfoPtr pScrn); +static void BladeSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, + int patternx, int patterny, int fg, int bg, + int rop, unsigned int planemask); +static void BladeSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, + int patternx, int patterny, int x, int y, + int w, int h); +#if 0 +static void BladeSetupForColor8x8PatternFill(ScrnInfoPtr pScrn, + int patternx, int patterny, + int rop, unsigned int planemask, int trans_col); +static void BladeSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn, + int patternx, int patterny, int x, int y, + int w, int h); +#endif +static void BladeSetupForImageWrite(ScrnInfoPtr pScrn, int rop, + unsigned int planemask, int transparency_color, + int bpp, int depth); +static void BladeSubsequentImageWriteRect(ScrnInfoPtr pScrn, int x, + int y, int w, int h, int skipleft); + +static void +BladeInitializeAccelerator(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + CARD32 stride; + + stride = (pScrn->displayWidth >> 3) << 20; + + BLADE_OUT(0x21C8, stride); + BLADE_OUT(0x21CC, stride); + BLADE_OUT(0x21D0, stride); + BLADE_OUT(0x21D4, stride); + switch (pScrn->depth) { + case 8: + stride |= 0<<29; + break; + case 15: + stride |= 5<<29; + break; + case 16: + stride |= 1<<29; + break; + case 24: + stride |= 2<<29; + break; + } + BLADE_OUT(0x21B8, 0); + BLADE_OUT(0x21B8, stride); + BLADE_OUT(0x21BC, stride); + BLADE_OUT(0x21C0, stride); + BLADE_OUT(0x21C4, stride); +#if 0 + /* It appears that the driver sometimes misdetects the RAM type, so we + * don't force this for now */ + if (pTrident->HasSGRAM) + BLADE_OUT(0x2168, 1<<26); /* Enables Block Write if available (SGRAM) */ + else + BLADE_OUT(0x2168, 0); +#endif + BLADE_OUT(0x216C, 0); +} + +Bool +BladeXaaInit(ScreenPtr pScreen) +{ + XAAInfoRecPtr infoPtr; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + if (pTrident->NoAccel) + return FALSE; + + pTrident->AccelInfoRec = infoPtr = XAACreateInfoRec(); + if (!infoPtr) return FALSE; + + pTrident->InitializeAccelerator = BladeInitializeAccelerator; + BladeInitializeAccelerator(pScrn); + + infoPtr->Flags = PIXMAP_CACHE | + LINEAR_FRAMEBUFFER | + OFFSCREEN_PIXMAPS; + + infoPtr->Sync = BladeSync; + + infoPtr->SetClippingRectangle = BladeSetClippingRectangle; + infoPtr->DisableClipping = BladeDisableClipping; + +#if 0 + infoPtr->SolidLineFlags = 0; + infoPtr->SetupForSolidLine = BladeSetupForSolidLine; + infoPtr->SubsequentSolidTwoPointLine = BladeSubsequentSolidTwoPointLine; + infoPtr->SetupForDashedLine = BladeSetupForDashedLine; + infoPtr->SubsequentDashedTwoPointLine = BladeSubsequentDashedTwoPointLine; + infoPtr->DashPatternMaxLength = 16; + infoPtr->DashedLineFlags = LINE_PATTERN_LSBFIRST_LSBJUSTIFIED | + LINE_PATTERN_POWER_OF_2_ONLY; +#endif + + infoPtr->SolidFillFlags = NO_PLANEMASK; + infoPtr->SetupForSolidFill = BladeSetupForFillRectSolid; + infoPtr->SubsequentSolidFillRect = BladeSubsequentFillRectSolid; + + infoPtr->ScreenToScreenCopyFlags = ONLY_TWO_BITBLT_DIRECTIONS | + NO_PLANEMASK | + NO_TRANSPARENCY; + + infoPtr->SetupForScreenToScreenCopy = + BladeSetupForScreenToScreenCopy; + infoPtr->SubsequentScreenToScreenCopy = + BladeSubsequentScreenToScreenCopy; + + infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK | NO_TRANSPARENCY | + BIT_ORDER_IN_BYTE_MSBFIRST | + HARDWARE_PATTERN_SCREEN_ORIGIN | + HARDWARE_PATTERN_PROGRAMMED_BITS; + + infoPtr->SetupForMono8x8PatternFill = + BladeSetupForMono8x8PatternFill; + infoPtr->SubsequentMono8x8PatternFillRect = + BladeSubsequentMono8x8PatternFillRect; + +#if 0 + infoPtr->Color8x8PatternFillFlags = + HARDWARE_PATTERN_SCREEN_ORIGIN | + BIT_ORDER_IN_BYTE_MSBFIRST; + + infoPtr->SetupForColor8x8PatternFill = + TridentSetupForColor8x8PatternFill; + infoPtr->SubsequentColor8x8PatternFillRect = + TridentSubsequentColor8x8PatternFillRect; + + infoPtr->ScreenToScreenColorExpandFillFlags = 0; + + infoPtr->SetupForScreenToScreenColorExpandFill = + BladeSetupForScreenToScreenColorExpand; + infoPtr->SubsequentScreenToScreenColorExpandFill = + BladeSubsequentScreenToScreenColorExpand; +#endif + + infoPtr->CPUToScreenColorExpandFillFlags = CPU_TRANSFER_PAD_DWORD | + LEFT_EDGE_CLIPPING | + SYNC_AFTER_COLOR_EXPAND | + NO_PLANEMASK | + BIT_ORDER_IN_BYTE_MSBFIRST | + SCANLINE_PAD_DWORD; + infoPtr->ColorExpandRange = 0x10000; + infoPtr->ColorExpandBase = pTrident->IOBase + 0x10000; + infoPtr->SetupForCPUToScreenColorExpandFill = + BladeSetupForCPUToScreenColorExpand; + infoPtr->SubsequentCPUToScreenColorExpandFill = + BladeSubsequentCPUToScreenColorExpand; + + infoPtr->SetupForImageWrite = BladeSetupForImageWrite; + infoPtr->SubsequentImageWriteRect = + BladeSubsequentImageWriteRect; + infoPtr->ImageWriteFlags = NO_PLANEMASK | + LEFT_EDGE_CLIPPING | + CPU_TRANSFER_PAD_DWORD | + SYNC_AFTER_IMAGE_WRITE; + infoPtr->ImageWriteBase = pTrident->IOBase + 0x10000; + infoPtr->ImageWriteRange = 0x10000; + + return(XAAInit(pScreen, infoPtr)); +} + +static void +BladeSync(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int busy; + int cnt = 10000000; + + if (pTrident->Clipping) BladeDisableClipping(pScrn); + BLADE_OUT(0x216C, 0); + + BLADEBUSY(busy); + while (busy != 0) { + if (--cnt < 0) { + ErrorF("GE timeout\n"); + BLADE_OUT(0x2124, 1<<7); + BLADE_OUT(0x2124, 0); + break; + } + BLADEBUSY(busy); + } +} + +static void +BladeSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, + int xdir, int ydir, int rop, + unsigned int planemask, int transparency_color) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + pTrident->BltScanDirection = 0; + if ((xdir < 0) || (ydir < 0)) pTrident->BltScanDirection |= 1<<1; + +#if 0 + if (transparency_color != -1) { + BLADE_OUT(0x2168, transparency_color & 0xffffff); + pTrident->BltScanDirection |= 1<<6; + } + + REPLICATE(planemask); + if (planemask != (unsigned int)-1) { + BLADE_OUT(0x2184, ~planemask); + pTrident->BltScanDirection |= 1<<5; + } +#endif + BLADE_OUT(0x2148, XAAGetCopyROP(rop)); +} + +static void +BladeSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, + int x2, int y2, int w, int h) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int clip = 0; + + if (pTrident->Clipping) clip = 1; + + BLADE_OUT(0x2144, 0xE0000000 | 1<<19 | 1<<4 | 1<<2 | pTrident->BltScanDirection | clip); + + if (pTrident->BltScanDirection) { + BLADE_OUT(0x2100, (y1+h-1)<<16 | (x1+w-1)); + BLADE_OUT(0x2104, y1<<16 | x1); + BLADE_OUT(0x2108, (y2+h-1)<<16 | (x2+w-1)); + BLADE_OUT(0x210C, (y2&0xfff)<<16 | (x2&0xfff)); + } else { + BLADE_OUT(0x2100, y1<<16 | x1); + BLADE_OUT(0x2104, (y1+h-1)<<16 | (x1+w-1)); + BLADE_OUT(0x2108, y2<<16 | x2); + BLADE_OUT(0x210C, ((y2+h-1)&0xfff)<<16 | ((x2+w-1)&0xfff)); + } +} + +static void +BladeSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + BLADE_OUT(0x2154, (y1&0x0fff)<<16 | (x1&0x0fff)); + BLADE_OUT(0x2158, (y2&0x0fff)<<16 | (x2&0x0fff)); + pTrident->Clipping = TRUE; +} + +static void +BladeDisableClipping(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + pTrident->Clipping = FALSE; +} + +#if 0 +static void +BladeSetupForSolidLine(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + REPLICATE(color); + BLADE_OUT(0x2160, color); + BLADE_OUT(0x2148, XAAGetCopyROP(rop)); + pTrident->BltScanDirection = 0; + REPLICATE(planemask); + if (planemask != -1) { + BLADE_OUT(0x2184, ~planemask); + pTrident->BltScanDirection |= 1<<5; + } +} + +static void +BladeSubsequentSolidBresenhamLine( ScrnInfoPtr pScrn, + int x, int y, int dmaj, int dmin, int e, int len, int octant) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int tmp; + int D = 0, E = 0, ymajor = 0; + + + BLADE_OUT(0x2144, 0x20000000 | 3<<19 | 1<<4 | 2<<2 | (pTrident->Clipping ? 1: 0)); + + if (!(octant & YMAJOR)) { + if ((!(octant&XDECREASING)) && (!(octant&YDECREASING))) {E = 1; D = 0;} + if ((!(octant&XDECREASING)) && ( (octant&YDECREASING))) {E = 1; D = 1;} + if (( (octant&XDECREASING)) && (!(octant&YDECREASING))) {E = 1; D = 2;} + if (( (octant&XDECREASING)) && ( (octant&YDECREASING))) {E = 1; D = 3;} + ymajor = 0; + } else { + if ((!(octant&XDECREASING)) && (!(octant&YDECREASING))) {E = 0; D = 0;} + if ((!(octant&XDECREASING)) && ( (octant&YDECREASING))) {E = 0; D = 2;} + if (( (octant&XDECREASING)) && (!(octant&YDECREASING))) {E = 0; D = 1;} + if (( (octant&XDECREASING)) && ( (octant&YDECREASING))) {E = 0; D = 3;} + ymajor = 1<<21; + } + + if (E) { + tmp = x; x = y; y = tmp; + } + BLADE_OUT(0x2130, 0x00000001); + if (D&0x02) { + BLADE_OUT(0x213C, 0x10000000 | 1<<25 | 1<<19 | 1<<17 | ymajor | ((x+len-1)<<4)); + } else { + BLADE_OUT(0x213C, 0x10000000 | 1<<25 | 1<<19 | 1<<17 | ymajor | ((y+len-1)<<4)); + } + BLADE_OUT(0x2140, E<<30 | (y&0xfff)<<20 | ((x&0xfff)<<4)); + BLADE_OUT(0x2144, D<<30 | (((dmaj-dmin)&0xfff) << 16) | (-dmin&0xfff)); + BLADE_OUT(0x2148, ((-(dmin+e)&0xfff) << 16)); +} + +static void +BladeSubsequentSolidTwoPointLine( ScrnInfoPtr pScrn, + int x1, int y1, int x2, int y2, int flags) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + +#if 0 + if (flags & OMIT_LAST) + BladeSetClippingRectangle(pScrn,x1,y1,x2-1,y2-1); +#endif + + BLADE_OUT(0x2144, 0x20000000 | pTrident->BltScanDirection | 1<<19 | 1<<4 | 2<<2); + BLADE_OUT(0x2130, 0x3); + BLADE_OUT(0x2108, y1<<16 | x1); + BLADE_OUT(0x210C, (y2&0xfff)<<16 | (x2&0xfff)); + +#if 0 + if (flags & OMIT_LAST) + BladeDisableClipping(pScrn); +#endif +} + +static void +BladeSetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop, + unsigned int planemask, int length, unsigned char *pattern) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + pTrident->LinePattern = *((CARD16 *)pattern) & ((1<<length) - 1); + switch (length) { + case 2: + pTrident->LinePattern = pTrident->LinePattern | (pTrident->LinePattern << 2); + case 4: + pTrident->LinePattern = pTrident->LinePattern | (pTrident->LinePattern << 4); + case 8: + pTrident->LinePattern = pTrident->LinePattern | (pTrident->LinePattern << 8); + } + + REPLICATE(fg); + REPLICATE(bg); + BLADE_OUT(0x2160, fg); + BLADE_OUT(0x2164, bg); + BLADE_OUT(0x2148, XAAGetCopyROP(rop)); + pTrident->BltScanDirection = 0; + REPLICATE(planemask); + if (planemask != -1) { + BLADE_OUT(0x2184, ~planemask); + pTrident->BltScanDirection |= 1<<5; + } +} + +static void +BladeSubsequentDashedTwoPointLine( ScrnInfoPtr pScrn, + int x1, int y1, int x2, int y2, int flags, int phase) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + if (flags & OMIT_LAST) + BladeSetClippingRectangle(pScrn,x1,y1,x2-1,y2-1); + + BLADE_OUT(0x216C, (pTrident->LinePattern >> phase) | (pTrident->LinePattern << (16-phase))); + BLADE_OUT(0x2144, 0x20000000 | pTrident->BltScanDirection | 1<<27 | 1<<19 | 1<<4 | 2<<2); + BLADE_OUT(0x2108, y1<<16 | x1); + BLADE_OUT(0x210C, (y2&0xfff)<<16 | (x2&0xfff)); + + if (flags & OMIT_LAST) + BladeDisableClipping(pScrn); +} +#endif + +static void +BladeSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + REPLICATE(color); + BLADE_OUT(0x2160, color); + BLADE_OUT(0x2148, XAAGetCopyROP(rop)); + pTrident->BltScanDirection = 0; +#if 0 + REPLICATE(planemask); + if (planemask != -1) { + BLADE_OUT(0x2184, ~planemask); + pTrident->BltScanDirection |= 1<<5; + } +#endif +} + +static void +BladeSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + BLADE_OUT(0x2144, 0x20000000 | pTrident->BltScanDirection | 1<<19 | 1<<4 | 2<<2 | (pTrident->Clipping ? 1:0)); + BLADE_OUT(0x2108, y<<16 | x); + BLADE_OUT(0x210C, ((y+h-1)&0xfff)<<16 | ((x+w-1)&0xfff)); +} + +#if 0 +static void +BladeSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn, + int fg, int bg, int rop, + unsigned int planemask) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + pTrident->ROP = rop; + + REPLICATE(bg); + REPLICATE(fg); + IMAGE_OUT(0x44, fg); + IMAGE_OUT(0x48, bg); + IMAGE_OUT(0x20, 0x90000000 | XAAGetCopyROP(rop)); + pTrident->BltScanDirection = 0; + REPLICATE(planemask); + if (planemask != -1) { + BLADE_OUT(0x2184, ~planemask); + pTrident->BltScanDirection |= 1<<5; + } +} + +static void +BladeSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn, + int x, int y, int w, int h, int srcx, int srcy, int offset) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + IMAGE_OUT(0x00, srcy<<16 | srcx); + IMAGE_OUT(0x04, (srcy+h-1)<<16 | (srcx+w-1)); + IMAGE_OUT(0x08, y<<16 | x); + IMAGE_OUT(0x0C, (y+h-1)<<16 | (x+w-1)); + + IMAGE_OUT(0x24, 0x80000000 | 3<<22 | 1<<7 | pTrident->BltScanDirection | (pTrident->ROP == GXcopy ? 0 : 1<<10) | offset<<25); +} +#endif + +static void +BladeSetupForCPUToScreenColorExpand(ScrnInfoPtr pScrn, + int fg, int bg, int rop, + unsigned int planemask) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + pTrident->BltScanDirection = 0; + BLADE_OUT(0x2148, XAAGetCopyROP(rop)); + if (bg == -1) { + pTrident->BltScanDirection |= 2<<19; + REPLICATE(fg); + BLADE_OUT(0x2160, fg); + BLADE_OUT(0x2164, ~fg); + } else { + pTrident->BltScanDirection |= 3<<19; + REPLICATE(fg); + REPLICATE(bg); + BLADE_OUT(0x2160, fg); + BLADE_OUT(0x2164, bg); + } +#if 0 + REPLICATE(planemask); + if (planemask != -1) { + BLADE_OUT(0x2184, ~planemask); + pTrident->BltScanDirection |= 1<<5; + } +#endif +} + +static void +BladeSubsequentCPUToScreenColorExpand(ScrnInfoPtr pScrn, + int x, int y, int w, int h, int skipleft) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + if (skipleft) BladeSetClippingRectangle(pScrn,x+skipleft,y,(x+w-1),(y+h-1)); + BLADE_OUT(0x2144, 0xE0000000 | pTrident->BltScanDirection | 1<<4 | (skipleft ? 1 : 0)); + BLADE_OUT(0x2108, (y&0xfff)<<16 | (x&0xfff)); + BLADE_OUT(0x210C, ((y+h-1)&0xfff)<<16 | ((x+w-1)&0xfff)); +} + +static void +BladeSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, + int patternx, int patterny, + int fg, int bg, int rop, + unsigned int planemask) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + BladeSync(pScrn); + BLADE_OUT(0x2148, XAAGetPatternROP(rop)); + + if (bg == -1) { + REPLICATE(fg); + BLADE_OUT(0x216C, 0x80000000 | 1<<30); + BLADE_OUT(0x216C, 0x80000000 | 1<<28 | 1<<30); + BLADE_OUT(0x2170, patternx); + BLADE_OUT(0x2170, patterny); + BLADE_OUT(0x2174, fg); +#if 0 + BLADE_OUT(0x2178, ~fg); +#endif + } else { + REPLICATE(fg); + REPLICATE(bg); + BLADE_OUT(0x216C, 0x80000000); + BLADE_OUT(0x216C, 0x80000000 | 1<<28); + BLADE_OUT(0x2170, patternx); + BLADE_OUT(0x2170, patterny); + BLADE_OUT(0x2174, fg); + BLADE_OUT(0x2178, bg); + } + pTrident->BltScanDirection = 0; +#if 0 + REPLICATE(planemask); + if (planemask != -1) { + BLADE_OUT(0x2184, ~planemask); + pTrident->BltScanDirection |= 1<<5; + } +#endif +} + +static void +BladeSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, + int patternx, int patterny, + int x, int y, + int w, int h) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int clip = 0; + + if (pTrident->Clipping) clip = 1; + BLADE_OUT(0x2144, 0x20000000 | pTrident->BltScanDirection | 7<<12 | 1<<4 | 1<<19 | 2<<2 | clip); + BLADE_OUT(0x2108, y<<16 | x); + BLADE_OUT(0x210C, ((y+h-1)&0xfff)<<16 | ((x+w-1)&0xfff)); +} + +#if 0 +static void +BladeSetupForColor8x8PatternFill(ScrnInfoPtr pScrn, + int patternx, int patterny, + int rop, + unsigned int planemask, + int transparency_color) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + TGUI_PATLOC(((patterny * pScrn->displayWidth * pScrn->bitsPerPixel / 8) + + (patternx * pScrn->bitsPerPixel / 8)) >> 6); + pTrident->BltScanDirection = 0; + if (transparency_color != -1) { + BLADE_OUT(0x2168, transparency_color & 0xffffff); + pTrident->BltScanDirection |= 1<<6; + } + TGUI_FMIX(XAAGetPatternROP(rop)); + REPLICATE(planemask); + if (planemask != -1) { + BLADE_OUT(0x2184, ~planemask); + pTrident->BltScanDirection |= 1<<5; + } +} + +static void +BladeSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn, + int patternx, int patterny, + int x, int y, + int w, int h) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + TGUI_DEST_XY(x,y); + TGUI_DIM_XY(w,h); + TGUI_COMMAND(GE_BLT); + CHECKCLIPPING; +} +#endif + +static void BladeSetupForImageWrite( + ScrnInfoPtr pScrn, + int rop, + unsigned int planemask, + int transparency_color, + int bpp, int depth +){ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + BLADE_OUT(0x2148, XAAGetCopyROP(rop)); + pTrident->BltScanDirection = 0; +#if 0 + REPLICATE(planemask); + if (planemask != -1) { + BLADE_OUT(0x2184, ~planemask); + pTrident->BltScanDirection |= 1<<5; + } +#endif +} + +static void BladeSubsequentImageWriteRect( + ScrnInfoPtr pScrn, + int x, int y, int w, int h, + int skipleft +){ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + if (skipleft) BladeSetClippingRectangle(pScrn,x+skipleft,y,(x+w-1),(y+h-1)); + BLADE_OUT(0x2144, 0xE0000000 | 1<<19 | 1<<4 | pTrident->BltScanDirection | (skipleft ? 1 : 0)); + BLADE_OUT(0x2108, y<<16 | (x&0xfff)); + BLADE_OUT(0x210C, ((y+h-1)&0xfff)<<16 | ((x+w-1)&0xfff)); +} diff --git a/driver/xf86-video-trident/src/blade_accel_exa.c b/driver/xf86-video-trident/src/blade_accel_exa.c new file mode 100644 index 000000000..80e3f2316 --- /dev/null +++ b/driver/xf86-video-trident/src/blade_accel_exa.c @@ -0,0 +1,334 @@ +/* + * Copyright 1997-2003 by Alan Hourihane, North Wales, UK. + * Copyright (c) 2006, Jesse Barnes <jbarnes@virtuousgeek.org> + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the authors not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The authors make no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * Jesse Barnes <jbarnes@virtuousgeek.org> + * + * Trident Blade3D EXA support. + * TODO: + * Composite hooks (some ops/arg. combos may not be supported) + * Upload/Download from screen (is this even possible with this chip?) + * Fast mixed directoion Blts + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "xf86_OSproc.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#include "exa.h" + +#include "trident.h" +#include "trident_regs.h" + +#include "xaarop.h" + +#undef REPLICATE +#define REPLICATE(r, bpp) \ +{ \ + if (bpp == 16) { \ + r = ((r & 0xFFFF) << 16) | (r & 0xFFFF); \ + } else \ + if (bpp == 8) { \ + r &= 0xFF; \ + r |= (r<<8); \ + r |= (r<<16); \ + } \ +} + +static int rop_table[16] = +{ + ROP_0, /* GXclear */ + ROP_DSa, /* GXand */ + ROP_SDna, /* GXandReverse */ + ROP_S, /* GXcopy */ + ROP_DSna, /* GXandInverted */ + ROP_D, /* GXnoop */ + ROP_DSx, /* GXxor */ + ROP_DSo, /* GXor */ + ROP_DSon, /* GXnor */ + ROP_DSxn, /* GXequiv */ + ROP_Dn, /* GXinvert*/ + ROP_SDno, /* GXorReverse */ + ROP_Sn, /* GXcopyInverted */ + ROP_DSno, /* GXorInverted */ + ROP_DSan, /* GXnand */ + ROP_1 /* GXset */ +}; + +static int GetCopyROP(int rop) +{ + return rop_table[rop]; +} + +static unsigned long GetDepth(int depth) +{ + unsigned long ret; + + switch (depth) { + case 8: + ret = 0; + break; + case 15: + ret = 5UL << 29; /* 555 */ + case 16: + ret = 1UL << 29; /* 565 */ + break; + case 32: + ret = 2UL << 29; + break; + default: + ret = 0; + break; + } + return ret; +} + +static Bool PrepareSolid(PixmapPtr pPixmap, int rop, Pixel planemask, + Pixel color) +{ + TRIDENTPtr pTrident = + TRIDENTPTR(xf86Screens[pPixmap->drawable.pScreen->myNum]); + + REPLICATE(color, pPixmap->drawable.bitsPerPixel); + BLADE_OUT(GER_FGCOLOR, color); + BLADE_OUT(GER_ROP, GetCopyROP(rop)); + pTrident->BltScanDirection = 0; + + return TRUE; +} + +static void Solid(PixmapPtr pPixmap, int x, int y, int x2, int y2) +{ + TRIDENTPtr pTrident = + TRIDENTPTR(xf86Screens[pPixmap->drawable.pScreen->myNum]); + int dst_stride = (pPixmap->drawable.width + 7) / 8; + int dst_off = exaGetPixmapOffset(pPixmap) / 8; + + BLADE_OUT(GER_DSTBASE0, GetDepth(pPixmap->drawable.bitsPerPixel) | + dst_stride << 20 | dst_off); + + BLADE_OUT(GER_DRAW_CMD, GER_OP_LINE | pTrident->BltScanDirection | + GER_DRAW_SRC_COLOR | GER_ROP_ENABLE | GER_SRC_CONST); + + BLADE_OUT(GER_DST1, y << 16 | x); + BLADE_OUT(GER_DST2, ((y2 - 1) & 0xfff) << 16 | ((x2 - 1) & 0xfff)); +} + +static void DoneSolid(PixmapPtr pPixmap) +{ +} + +static Bool PrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, + int xdir, int ydir, int alu, Pixel planemask) +{ + TRIDENTPtr pTrident = + TRIDENTPTR(xf86Screens[pSrcPixmap->drawable.pScreen->myNum]); + int src_stride = (pSrcPixmap->drawable.width + 7) / 8; + int src_off = exaGetPixmapOffset(pSrcPixmap) / 8; + int dst_stride = (pDstPixmap->drawable.width + 7) / 8; + int dst_off = exaGetPixmapOffset(pDstPixmap) / 8; + + pTrident->BltScanDirection = 0; + + REPLICATE(planemask, pSrcPixmap->drawable.bitsPerPixel); + if (planemask != (unsigned int)-1) { + BLADE_OUT(GER_BITMASK, ~planemask); + pTrident->BltScanDirection |= 1 << 5; + } + + BLADE_OUT(GER_SRCBASE0, GetDepth(pSrcPixmap->drawable.bitsPerPixel) | + src_stride << 20 | src_off); + + BLADE_OUT(GER_DSTBASE0, GetDepth(pDstPixmap->drawable.bitsPerPixel) | + dst_stride << 20 | dst_off); + + if ((xdir < 0) || (ydir < 0)) + pTrident->BltScanDirection |= 1 << 1; + + BLADE_OUT(GER_ROP, GetCopyROP(alu)); + + return TRUE; +} + +static void Copy(PixmapPtr pDstPixmap, int x1, int y1, int x2, + int y2, int w, int h) +{ + TRIDENTPtr pTrident = + TRIDENTPTR(xf86Screens[pDstPixmap->drawable.pScreen->myNum]); + + BLADE_OUT(GER_DRAW_CMD, GER_OP_BLT_HOST | GER_DRAW_SRC_COLOR | + GER_ROP_ENABLE | GER_BLT_SRC_FB | pTrident->BltScanDirection); + + if (pTrident->BltScanDirection) { + BLADE_OUT(GER_SRC1, (y1 + h - 1) << 16 | (x1 + w - 1)); + BLADE_OUT(GER_SRC2, y1 << 16 | x1); + BLADE_OUT(GER_DST1, (y2 + h - 1) << 16 | (x2 + w - 1)); + BLADE_OUT(GER_DST2, (y2 & 0xfff) << 16 | (x2 & 0xfff)); + } else { + BLADE_OUT(GER_SRC1, y1 << 16 | x1); + BLADE_OUT(GER_SRC2, (y1 + h - 1) << 16 | (x1 + w - 1)); + BLADE_OUT(GER_DST1, y2 << 16 | x2); + BLADE_OUT(GER_DST2, (((y2 + h - 1) & 0xfff) << 16 | + ((x2 +w - 1) & 0xfff))); + } +} + +static void DoneCopy(PixmapPtr pDstPixmap) +{ +} + +/* Composite comes later (if at all) */ +static Bool CheckComposite(int op, PicturePtr pSrcPicture, + PicturePtr pMaskPicture, PicturePtr pDstPicture) +{ + return 0; +} + +static Bool PrepareComposite(int op, PicturePtr pSrcPicture, + PicturePtr pMaskPicture, PicturePtr pDstPicture, + PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst) +{ + return 0; +} + +static void Composite(PixmapPtr pDst, int srcX, int srcY, int maskX, + int maskY, int dstX, int dstY, int width, + int height) +{ +} + +static void DoneComposite(PixmapPtr pDst) +{ +} + +static int MarkSync(ScreenPtr pScreen) +{ + return 0; +} + +static void WaitMarker(ScreenPtr pScreen, int marker) +{ + TRIDENTPtr pTrident = TRIDENTPTR(xf86Screens[pScreen->myNum]); + int busy; + int cnt = 10000000; + + BLADE_OUT(GER_PATSTYLE, 0); /* Clear pattern & style first? */ + + BLADEBUSY(busy); + while (busy != 0) { + if (--cnt < 0) { + ErrorF("GE timeout\n"); + BLADE_OUT(GER_CONTROL, GER_CTL_RESET); + BLADE_OUT(GER_CONTROL, GER_CTL_RESUME); + break; + } + BLADEBUSY(busy); + } +} + +static Bool PrepareAccess(PixmapPtr pPix, int index) +{ +} + +static void FinishAccess(PixmapPtr pPix, int index) +{ +} + +static void BladeInitializeAccelerator(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + BLADE_OUT(GER_DSTBASE0, 0); + BLADE_OUT(GER_DSTBASE1, 0); + BLADE_OUT(GER_DSTBASE2, 0); + BLADE_OUT(GER_DSTBASE3, 0); + BLADE_OUT(GER_SRCBASE0, 0); + BLADE_OUT(GER_SRCBASE1, 0); + BLADE_OUT(GER_SRCBASE2, 0); + BLADE_OUT(GER_SRCBASE3, 0); + BLADE_OUT(GER_PATSTYLE, 0); +} + +Bool BladeExaInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + ExaDriverPtr ExaDriver; + + if (pTrident->NoAccel) + return FALSE; + + if (!(ExaDriver = exaDriverAlloc())) { + pTrident->NoAccel = TRUE; + return FALSE; + } + + ExaDriver->exa_major = 2; + ExaDriver->exa_minor = 0; + + pTrident->EXADriverPtr = ExaDriver; + + pTrident->InitializeAccelerator = BladeInitializeAccelerator; + BladeInitializeAccelerator(pScrn); + + ExaDriver->memoryBase = pTrident->FbBase; + ExaDriver->memorySize = pScrn->videoRam * 1024; + + ExaDriver->offScreenBase = pScrn->displayWidth * pScrn->virtualY * + ((pScrn->bitsPerPixel + 7) / 8); + + if(ExaDriver->memorySize > ExaDriver->offScreenBase) + ExaDriver->flags |= EXA_OFFSCREEN_PIXMAPS; + else { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Not enough video RAM for " + "offscreen memory manager. Xv disabled\n"); + /* disable Xv here... */ + } + + ExaDriver->pixmapOffsetAlign = 32; + ExaDriver->pixmapPitchAlign = 32; + ExaDriver->maxX = 2047; + ExaDriver->maxY = 2047; + + ExaDriver->flags |= EXA_TWO_BITBLT_DIRECTIONS; + + ExaDriver->MarkSync = MarkSync; + ExaDriver->WaitMarker = WaitMarker; + + /* Solid fill & copy, the bare minimum */ + ExaDriver->PrepareSolid = PrepareSolid; + ExaDriver->Solid = Solid; + ExaDriver->DoneSolid = DoneSolid; + ExaDriver->PrepareCopy = PrepareCopy; + ExaDriver->Copy = Copy; + ExaDriver->DoneCopy = DoneCopy; + + /* Composite not done yet */ + + return exaDriverInit(pScreen, ExaDriver); +} diff --git a/driver/xf86-video-trident/src/image_accel.c b/driver/xf86-video-trident/src/image_accel.c new file mode 100644 index 000000000..479de5ea2 --- /dev/null +++ b/driver/xf86-video-trident/src/image_accel.c @@ -0,0 +1,640 @@ +/* + * Copyright 1997-2003 by Alan Hourihane, North Wales, UK. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * + * Trident 3DImage' accelerated options. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/image_accel.c,v 1.26 2003/10/30 13:38:01 alanh Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "xf86_OSproc.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#include "miline.h" + +#include "trident.h" +#include "trident_regs.h" + +#include "xaarop.h" +#include "xaalocal.h" + +static void ImageSync(ScrnInfoPtr pScrn); +static void ImageSyncClip(ScrnInfoPtr pScrn); +#if 0 +static void ImageSetupForSolidLine(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask); +static void ImageSubsequentSolidBresenhamLine(ScrnInfoPtr pScrn, + int x, int y, int dmaj, int dmin, int e, + int len, int octant); +#endif +static void ImageSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask); +static void ImageSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, + int y, int w, int h); +static void ImageSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, + int x1, int y1, int x2, + int y2, int w, int h); +static void ImageSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, + int xdir, int ydir, int rop, + unsigned int planemask, + int transparency_color); +static void ImageSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, + int x2, int y2); +static void ImageDisableClipping(ScrnInfoPtr pScrn); +static void ImageSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, + int patternx, int patterny, int fg, int bg, + int rop, unsigned int planemask); +static void ImageSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, + int patternx, int patterny, int x, int y, + int w, int h); +#if 0 +static void ImageSetupForColor8x8PatternFill(ScrnInfoPtr pScrn, + int patternx, int patterny, + int rop, unsigned int planemask, int trans_col); +static void ImageSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn, + int patternx, int patterny, int x, int y, + int w, int h); +#endif +static void ImageSetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop, + unsigned int planemask, int transparency_color, + int bpp, int depth); +static void ImageSubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn, int x, + int y, int w, int h, int skipleft); +static void ImageSubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno); +static void ImageSetupForScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int fg, int bg, int rop, + unsigned int planemask); +static void ImageSubsequentScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, int x, + int y, int w, int h, int skipleft); +static void ImageSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno); + +static void +ImageInitializeAccelerator(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + switch (pScrn->depth) { + case 8: + pTrident->EngineOperation = 0; + break; + case 15: + pTrident->EngineOperation = 5; + break; + case 16: + pTrident->EngineOperation = 1; + break; + case 24: + pTrident->EngineOperation = 2; + break; + } + IMAGE_OUT(0x2120, 0xF0000000); + IMAGE_OUT(0x2120, 0x40000000 | pTrident->EngineOperation); + IMAGE_OUT(0x2120, 0x80000000); + IMAGE_OUT(0x2144, 0x00000000); + IMAGE_OUT(0x2148, 0x00000000); + IMAGE_OUT(0x2150, 0x00000000); + IMAGE_OUT(0x2154, 0x00000000); + IMAGE_OUT(0x2120, 0x60000000 |pScrn->displayWidth<<16 |pScrn->displayWidth); + IMAGE_OUT(0x216C, 0x00000000); + IMAGE_OUT(0x2170, 0x00000000); + IMAGE_OUT(0x217C, 0x00000000); + IMAGE_OUT(0x2120, 0x10000000); + IMAGE_OUT(0x2130, 2047 << 16 | 2047); + pTrident->Clipping = FALSE; + pTrident->DstEnable = FALSE; +} + +Bool +ImageAccelInit(ScreenPtr pScreen) +{ + XAAInfoRecPtr infoPtr; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + if (pTrident->NoAccel) + return FALSE; + + pTrident->AccelInfoRec = infoPtr = XAACreateInfoRec(); + if (!infoPtr) return FALSE; + + pTrident->InitializeAccelerator = ImageInitializeAccelerator; + ImageInitializeAccelerator(pScrn); + + infoPtr->Flags = PIXMAP_CACHE | + LINEAR_FRAMEBUFFER | + OFFSCREEN_PIXMAPS; + + infoPtr->Sync = ImageSync; + +#if 0 + infoPtr->SetClippingRectangle = ImageSetClippingRectangle; + infoPtr->DisableClipping = ImageDisableClipping; + infoPtr->ClippingFlags = HARDWARE_CLIP_SOLID_FILL | + HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY | + HARDWARE_CLIP_MONO_8x8_FILL; +#endif + +#if 0 + infoPtr->SolidLineFlags = NO_PLANEMASK; + infoPtr->SetupForSolidLine = ImageSetupForSolidLine; + infoPtr->SolidBresenhamLineErrorTermBits = 13; + infoPtr->SubsequentSolidBresenhamLine = ImageSubsequentSolidBresenhamLine; + infoPtr->ClippingFlags |= HARDWARE_CLIP_SOLID_LINE; +#endif + + infoPtr->SolidFillFlags = NO_PLANEMASK; + infoPtr->SetupForSolidFill = ImageSetupForFillRectSolid; + infoPtr->SubsequentSolidFillRect = ImageSubsequentFillRectSolid; + + infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK | + NO_TRANSPARENCY | + ONLY_TWO_BITBLT_DIRECTIONS; + + infoPtr->SetupForScreenToScreenCopy = + ImageSetupForScreenToScreenCopy; + infoPtr->SubsequentScreenToScreenCopy = + ImageSubsequentScreenToScreenCopy; + + infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK | + BIT_ORDER_IN_BYTE_MSBFIRST | + HARDWARE_PATTERN_SCREEN_ORIGIN | + HARDWARE_PATTERN_PROGRAMMED_BITS; + + infoPtr->SetupForMono8x8PatternFill = + ImageSetupForMono8x8PatternFill; + infoPtr->SubsequentMono8x8PatternFillRect = + ImageSubsequentMono8x8PatternFillRect; + +#if 0 + infoPtr->Color8x8PatternFillFlags = NO_PLANEMASK | + NO_TRANSPARENCY | + HARDWARE_PATTERN_SCREEN_ORIGIN | + BIT_ORDER_IN_BYTE_MSBFIRST; + + infoPtr->SetupForColor8x8PatternFill = + ImageSetupForColor8x8PatternFill; + infoPtr->SubsequentColor8x8PatternFillRect = + ImageSubsequentColor8x8PatternFillRect; + infoPtr->ClippingFlags |= HARDWARE_CLIP_COLOR_8x8_FILL; +#endif + + if (pTrident->Chipset != CYBER9397DVD) { + /* It seems as though the 9397DVD doesn't like the transfer window */ + /* But then, I've also tried at the two port addresses too, with */ + /* no luck. Disable for this chipset for now. I'd guess there's some */ + /* extra setup needed for this chipset. */ + infoPtr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK | + LEFT_EDGE_CLIPPING | + BIT_ORDER_IN_BYTE_MSBFIRST; + + pTrident->XAAScanlineColorExpandBuffers[0] = + xnfalloc(((pScrn->virtualX + 63)) *4* (pScrn->bitsPerPixel / 8)); + + infoPtr->NumScanlineColorExpandBuffers = 1; + infoPtr->ScanlineColorExpandBuffers = + pTrident->XAAScanlineColorExpandBuffers; + + infoPtr->SetupForScanlineCPUToScreenColorExpandFill = + ImageSetupForScanlineCPUToScreenColorExpandFill; + infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = + ImageSubsequentScanlineCPUToScreenColorExpandFill; + infoPtr->SubsequentColorExpandScanline = + ImageSubsequentColorExpandScanline; + + infoPtr->ScanlineImageWriteFlags = NO_PLANEMASK | + LEFT_EDGE_CLIPPING; + + infoPtr->SetupForScanlineImageWrite = ImageSetupForScanlineImageWrite; + infoPtr->SubsequentScanlineImageWriteRect = + ImageSubsequentScanlineImageWriteRect; + infoPtr->SubsequentImageWriteScanline = ImageSubsequentImageWriteScanline; + + infoPtr->NumScanlineImageWriteBuffers = 1; + infoPtr->ScanlineImageWriteBuffers = pTrident->XAAImageScanlineBuffer; + + pTrident->XAAImageScanlineBuffer[0] = + xnfalloc(pScrn->virtualX * pScrn->bitsPerPixel / 8); + + infoPtr->ImageWriteBase = pTrident->IOBase + 0x10000; + } + + return(XAAInit(pScreen, infoPtr)); +} + +static void +ImageSync(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int busy; + int cnt = 5000000; + + if (pTrident->Clipping) ImageDisableClipping(pScrn); + if (pTrident->DstEnable) { + IMAGE_OUT(0x2120, 0x70000000); + pTrident->DstEnable = FALSE; + } + + IMAGEBUSY(busy); + while (busy != 0) { + if (--cnt < 0) { + ErrorF("GE timeout\n"); + IMAGE_OUT(0x2164, 0x80000000); + } + IMAGEBUSY(busy); + } +} + +static void +ImageSyncClip(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int busy; + int cnt = 5000000; + + IMAGEBUSY(busy); + while (busy != 0) { + if (--cnt < 0) { + ErrorF("GE timeout\n"); + IMAGE_OUT(0x2164, 0x80000000); + } + IMAGEBUSY(busy); + } +} + +static void +ImageSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, + int xdir, int ydir, int rop, + unsigned int planemask, int transparency_color) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + pTrident->BltScanDirection = 0; + if ((xdir < 0) || (ydir < 0)) pTrident->BltScanDirection |= 1<<2; + + IMAGE_OUT(0x2120, 0x80000000); + IMAGE_OUT(0x2120, 0x90000000 | XAAGetCopyROP(rop)); + + if (transparency_color != -1) { + IMAGE_OUT(0x2120, 0x70000000 | 1<<26 | (transparency_color&0xffffff)); + pTrident->DstEnable = TRUE; + } +} + +static void +ImageSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, + int x2, int y2, int w, int h) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + if (pTrident->BltScanDirection) { + IMAGE_OUT(0x2100, (y1+h-1)<<16 | (x1+w-1)); + IMAGE_OUT(0x2104, y1<<16 | x1); + IMAGE_OUT(0x2108, (y2+h-1)<<16 | (x2+w-1)); + IMAGE_OUT(0x210C, y2<<16 | x2); + } else { + IMAGE_OUT(0x2100, y1<<16 | x1); + IMAGE_OUT(0x2104, (y1+h-1)<<16 | (x1+w-1)); + IMAGE_OUT(0x2108, y2<<16 | x2); + IMAGE_OUT(0x210C, (y2+h-1)<<16 | (x2+w-1)); + } + + IMAGE_OUT(0x2124, 0x80000000 | 1<<7 | 1<<22 | 1<<10 | pTrident->BltScanDirection | (pTrident->Clipping ? 1 : 0)); + + if (!pTrident->UsePCIRetry) + ImageSyncClip(pScrn); +} + +static void +ImageSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + IMAGE_OUT(0x2120, 0x10000000 | ((y1&0xfff)<<16) | (x1&0xfff)); + IMAGE_OUT(0x2130, ((y2&0xfff)<<16) | (x2&0xfff)); + pTrident->Clipping = TRUE; +} + +static void +ImageDisableClipping(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + pTrident->Clipping = FALSE; +} + +#if 0 +static void +ImageSetupForSolidLine(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + REPLICATE(color); + IMAGE_OUT(0x2120, 0x84000000); + IMAGE_OUT(0x2120, 0x90000000 | XAAGetCopyROP(rop)); + IMAGE_OUT(0x2144, color); +} + +static void +ImageSubsequentSolidBresenhamLine( ScrnInfoPtr pScrn, + int x, int y, int dmaj, int dmin, int e, int len, int octant) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int tmp; + int D = 0, E = 0, ymajor = 0; + + IMAGE_OUT(0x2124, 0x20000000 | 3<<22 | 1<<10 | 1<<9 | (pTrident->Clipping ? 1:0)); + if (!(octant & YMAJOR)) { + if ((!(octant&XDECREASING)) && (!(octant&YDECREASING))) {E = 1; D = 0;} + if ((!(octant&XDECREASING)) && ( (octant&YDECREASING))) {E = 1; D = 1;} + if (( (octant&XDECREASING)) && (!(octant&YDECREASING))) {E = 1; D = 2;} + if (( (octant&XDECREASING)) && ( (octant&YDECREASING))) {E = 1; D = 3;} + ymajor = 0; + } else { + if ((!(octant&XDECREASING)) && (!(octant&YDECREASING))) {E = 0; D = 0;} + if ((!(octant&XDECREASING)) && ( (octant&YDECREASING))) {E = 0; D = 2;} + if (( (octant&XDECREASING)) && (!(octant&YDECREASING))) {E = 0; D = 1;} + if (( (octant&XDECREASING)) && ( (octant&YDECREASING))) {E = 0; D = 3;} + ymajor = 1<<18; + } + + if (E) { + tmp = x; x = y; y = tmp; + } + if (D&0x02) { + IMAGE_OUT(0x21FC, 0x20000000 | 1<<27 | 1<<19 | 1<<17 | ymajor | (x+len-1)); + } else { + IMAGE_OUT(0x21FC, 0x20000000 | 1<<27 | 1<<19 | 1<<17 | ymajor | (y+len-1)); + } + IMAGE_OUT(0x2100, E<<30 | (y&0xfff)<<16 | (x&0xfff)); + IMAGE_OUT(0x2104, D<<30 | (((dmaj-dmin)&0xfff) << 16) | (-dmin&0xfff)); + IMAGE_OUT(0x2108, ((-e&0xfff) << 16)); + + if (!pTrident->UsePCIRetry) + ImageSyncClip(pScrn); +} +#endif + +static void +ImageSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + REPLICATE(color); + IMAGE_OUT(0x2120, 0x80000000); + IMAGE_OUT(0x2120, 0x90000000 | XAAGetCopyROP(rop)); + IMAGE_OUT(0x2144, color); +} + +static void +ImageSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + if ((w<=0) || (h<=0)) + return; + + IMAGE_OUT(0x2108, ((y&0xfff)<<16) | (x&0xfff)); + IMAGE_OUT(0x210C, (((y+h-1)&0xfff)<<16) | ((x+w-1)&0xfff)); + IMAGE_OUT(0x2124, 0x80000000| 3<<22| 1<<10| 1<<9| (pTrident->Clipping?1:0)); + if (!pTrident->UsePCIRetry) + ImageSyncClip(pScrn); +} + +static +void MoveDWORDS( + register CARD32* dest, + register CARD32* src, + register int dwords ) +{ + Bool extra = FALSE; + if (dwords & 0x01) extra = TRUE; + while(dwords & ~0x03) { + *dest = *src; + *(dest + 1) = *(src + 1); + *(dest + 2) = *(src + 2); + *(dest + 3) = *(src + 3); + src += 4; + dest += 4; + dwords -= 4; + } + if(!dwords) { + if (extra) *dest = 0x00000000; + return; + } + *dest = *src; + if(dwords == 1) { + if (extra) *(dest + 1) = 0x00000000; + return; + } + *(dest + 1) = *(src + 1); + if(dwords == 2) { + if (extra) *(dest + 2) = 0x00000000; + return; + } + *(dest + 2) = *(src + 2); + if (extra) *(dest + 3) = 0x00000000; +} + +static void +ImageSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, + int patternx, int patterny, + int fg, int bg, int rop, + unsigned int planemask) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + IMAGE_OUT(0x2120, 0x90000000 | XAAGetPatternROP(rop)); + if (bg == -1) { + REPLICATE(fg); + IMAGE_OUT(0x2120, 0x80000000 | 1<<27); + IMAGE_OUT(0x2130, patternx); + IMAGE_OUT(0x2134, patterny); + IMAGE_OUT(0x2150, fg); + IMAGE_OUT(0x2154, ~fg); + } else { + REPLICATE(bg); + REPLICATE(fg); + IMAGE_OUT(0x2120, 0x80000000 | 1<<27 | 1<<26); + IMAGE_OUT(0x2130, patternx); + IMAGE_OUT(0x2134, patterny); + IMAGE_OUT(0x2150, fg); + IMAGE_OUT(0x2154, bg); + } +} + +static void +ImageSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, + int patternx, int patterny, + int x, int y, + int w, int h) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + IMAGE_OUT(0x2108, ((y&0xfff)<<16) | (x&0xfff)); + IMAGE_OUT(0x210C, (((y+h-1)&0xfff)<<16) | ((x+w-1)&0xfff)); + IMAGE_OUT(0x2124, 0x80000000 | 7<<18 | 1<<22 | 1<<10 | 1<<9 | (pTrident->Clipping ? 1 : 0)); + if (!pTrident->UsePCIRetry) + ImageSyncClip(pScrn); +} + +#if 0 +static void +ImageSetupForColor8x8PatternFill(ScrnInfoPtr pScrn, + int patternx, int patterny, + int rop, + unsigned int planemask, + int transparency_color) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + IMAGE_OUT(0x2120, 0x90000000 | XAAGetPatternROP(rop)); + IMAGE_OUT(0x2120, 0x80000000 | 1<<26); + if (transparency_color != -1) { + IMAGE_OUT(0x2120, 0x70000000 | 1<<26 | (transparency_color&0xffffff)); + pTrident->DstEnable = TRUE; + } +} + +static void +ImageSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn, + int patternx, int patterny, + int x, int y, + int w, int h) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + IMAGE_OUT(0x2100, (patterny&0xfff)<<16 | (patternx&0xfff)); + IMAGE_OUT(0x2104, (((patterny+h-1)&0xfff)<<16) | ((patternx+w-1)&0xfff)); + IMAGE_OUT(0x2108, (y&0xfff)<<16 | (x&0xfff)); + IMAGE_OUT(0x210C, (((y+h-1)&0xfff)<<16) | ((x+w-1)&0xfff)); + IMAGE_OUT(0x2124, 0x80000000 | 1<<22 | 1<<10 | 1<<7 | (pTrident->Clipping ? 1 : 0)); + if (!pTrident->UsePCIRetry) + ImageSyncClip(pScrn); +} +#endif + +static void +ImageSetupForScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int fg, int bg, + int rop, + unsigned int planemask +){ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + IMAGE_OUT(0x2120, 0x80000000); + IMAGE_OUT(0x2120, 0x90000000 | XAAGetCopyROP(rop)); + if (bg == -1) { + pTrident->ROP = 2<<22; + REPLICATE(fg); + IMAGE_OUT(0x2144, fg); + IMAGE_OUT(0x2148, ~fg); + } else { + pTrident->ROP = 3<<22; + REPLICATE(fg); + IMAGE_OUT(0x2144, fg); + REPLICATE(bg); + IMAGE_OUT(0x2148, bg); + } +} + +static void +ImageSubsequentScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int x, int y, int w, int h, + int skipleft +){ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + ImageSetClippingRectangle(pScrn,(x+skipleft),y,(x+w-1),(y+h-1)); + IMAGE_OUT(0x2108, (y&0xfff)<<16 | (x&0xfff)); + IMAGE_OUT(0x210C, (((y+h-1)&0xfff)<<16) | ((x+w-1)&0xfff)); + IMAGE_OUT(0x2124, 0x80000000 | pTrident->ROP | 1<<10 | 1); + pTrident->dwords = (w + 31) >> 5; + pTrident->h = h; +} + +static void +ImageSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + XAAInfoRecPtr infoRec; + infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + + MoveDWORDS((CARD32*)infoRec->ImageWriteBase, + (CARD32*)pTrident->XAAScanlineColorExpandBuffers[bufno], pTrident->dwords); + + pTrident->h--; + if (!pTrident->h) + ImageSync(pScrn); +} + +static void +ImageSetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop, + unsigned int planemask, int transparency_color, + int bpp, int depth) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + IMAGE_OUT(0x2120, 0x90000000 | XAAGetCopyROP(rop)); + if (transparency_color != -1) { + IMAGE_OUT(0x2120, 0x70000000 | 1<<26 | (transparency_color&0xffffff)); + pTrident->DstEnable = TRUE; + } + IMAGE_OUT(0x2120, 0x80000000); +} + +static void +ImageSubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn, int x, int y, + int w, int h, int skipleft) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + ImageSetClippingRectangle(pScrn,(x+skipleft),y,(x+w-1),(y+h-1)); + IMAGE_OUT(0x2108, ((y&0xfff)<<16) | (x&0xfff)); + IMAGE_OUT(0x210C, (((y+h-1)&0xfff)<<16) | ((x+w-1)&0xfff)); + IMAGE_OUT(0x2124, 0x80000000 | 1<<22 | 1<<10 | 1); + pTrident->dwords = ((w * (pScrn->bitsPerPixel/8)) + 3) >> 2; + pTrident->h = h; +} + + +static void +ImageSubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + XAAInfoRecPtr infoRec; + infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + + MoveDWORDS((CARD32*)infoRec->ImageWriteBase, + (CARD32*)pTrident->XAAImageScanlineBuffer[bufno], pTrident->dwords); + + pTrident->h--; + if (!pTrident->h) + ImageSync(pScrn); +} diff --git a/driver/xf86-video-trident/src/trident.h b/driver/xf86-video-trident/src/trident.h new file mode 100644 index 000000000..965bf7692 --- /dev/null +++ b/driver/xf86-video-trident/src/trident.h @@ -0,0 +1,372 @@ +/* + * Copyright 1992-2003 by Alan Hourihane, North Wales, UK. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident.h,v 1.59 2003/09/05 22:07:28 alanh Exp $ */ +/*#define VBE_INFO*/ + +#ifndef _TRIDENT_H_ +#define _TRIDENT_H_ + +#include <stdio.h> +#include <string.h> +#include <math.h> + +#include "exa.h" +#include "xf86Cursor.h" +#include "xaa.h" +#include "xf86RamDac.h" +#include "compiler.h" +#include "vgaHW.h" +#include "xf86i2c.h" +#include "xf86int10.h" +#include "shadowfb.h" +#include "shadow.h" +#include "xf86xv.h" +#include "xf86Pci.h" +#include "vbe.h" + +#define PCI_CHIP_2200 0x2200 + +typedef struct { + unsigned char tridentRegs3x4[0x100]; + unsigned char tridentRegs3CE[0x100]; + unsigned char tridentRegs3C4[0x100]; + unsigned char tridentRegsDAC[0x01]; + unsigned char tridentRegsClock[0x05]; + unsigned char DacRegs[0x300]; +} TRIDENTRegRec, *TRIDENTRegPtr; + +#define VGA_REGNUM_ABOUT_TV 19 +#define TRIDENTPTR(p) ((TRIDENTPtr)((p)->driverPrivate)) + +typedef struct { + ScrnInfoPtr pScrn; + pciVideoPtr PciInfo; + PCITAG PciTag; + EntityInfoPtr pEnt; + ExaDriverPtr EXADriverPtr; + int useEXA; + int Chipset; + int DACtype; + int RamDac; + int ChipRev; + int HwBpp; + int BppShift; + CARD32 IOAddress; + unsigned long FbAddress; + unsigned char * IOBase; + unsigned char * FbBase; + long FbMapSize; + IOADDRESS PIOBase; + Bool NoAccel; + Bool HWCursor; + Bool UsePCIRetry; + Bool UsePCIBurst; + Bool NewClockCode; + Bool Clipping; + Bool DstEnable; + Bool ROP; + Bool HasSGRAM; + Bool MUX; + Bool IsCyber; + Bool CyberShadow; + Bool CyberStretch; + Bool NoMMIO; + Bool MMIOonly; + Bool ShadowFB; + Bool Linear; + DGAModePtr DGAModes; + int numDGAModes; + Bool DGAactive; + int DGAViewportStatus; + unsigned char * ShadowPtr; + int ShadowPitch; + RefreshAreaFuncPtr RefreshArea; + void (*PointerMoved)(int index, int x, int y); + int Rotate; + float frequency; + unsigned char REGPCIReg; + unsigned char REGNewMode1; + CARD8 SaveClock1; + CARD8 SaveClock2; + CARD8 SaveClock3; + int MinClock; + int MaxClock; + int MUXThreshold; + int currentClock; + int MCLK; + int dwords; + int h; + int x; + int w; + int y; + int lcdMode; + Bool lcdActive; + Bool doInit; +#ifdef READOUT + Bool DontSetClock; +#endif + TRIDENTRegRec SavedReg; + TRIDENTRegRec ModeReg; + I2CBusPtr DDC; + CARD16 EngineOperation; + CARD32 PatternLocation; + CARD32 BltScanDirection; + CARD32 DrawFlag; + CARD16 LinePattern; + RamDacRecPtr RamDacRec; + int CursorOffset; + xf86CursorInfoPtr CursorInfoRec; + xf86Int10InfoPtr Int10; + vbeInfoPtr pVbe; +#ifdef VBE_INFO + vbeModeInfoPtr vbeModes; +#endif + XAAInfoRecPtr AccelInfoRec; + CloseScreenProcPtr CloseScreen; + ScreenBlockHandlerProcPtr BlockHandler; + int panelWidth; + int panelHeight; + unsigned int (*ddc1Read)(ScrnInfoPtr); + CARD8* XAAScanlineColorExpandBuffers[2]; + CARD8* XAAImageScanlineBuffer[1]; + void (*InitializeAccelerator)(ScrnInfoPtr); + void (*VideoTimerCallback)(ScrnInfoPtr, Time); + XF86VideoAdaptorPtr adaptor; + int videoKey; + int hsync; + int hsync_rskew; + int vsync; + int vsync_bskew; + CARD32 videoFlags; + int keyOffset; + int OverrideHsync; + int OverrideVsync; + int OverrideBskew; + int OverrideRskew; + OptionInfoPtr Options; + Bool shadowNew; + int displaySize; + int dspOverride; + Bool GammaBrightnessOn; + int brightness; + double gamma; + int FPDelay; /* just for debugging - will go away */ + int TVChipset; /* 0: None 1: VT1621 2: CH7005C*/ + int TVSignalMode; /* 0: NTSC 1: PAL */ + Bool TVRegSet; /* 0: User not customer TV Reg, 1: User customer TV Reg */ + unsigned char TVRegUserSet[2][128]; /*[0][128] for Reg Index, [1][128] for Reg Value */ + unsigned char DefaultTVDependVGASetting[VGA_REGNUM_ABOUT_TV+0x62]; /* VGA_REGNUM_ABOUT_TV: VGA Reg, 0x62: TV Reg */ +} TRIDENTRec, *TRIDENTPtr; + +typedef struct { + CARD8 mode; + int display_x; + int display_y; + int clock; + int shadow_0; + int shadow_3; + int shadow_4; + int shadow_5; + int shadow_6; + int shadow_7; + int shadow_10; + int shadow_11; + int shadow_16; + int shadow_HiOrd; +} tridentLCD; + +#define LCD_ACTIVE 0x01 +#define CRT_ACTIVE 0x02 + +extern tridentLCD LCD[]; + +typedef struct { + int x_res; + int y_res; + int mode; +} biosMode; + +typedef struct { + int x_res; + int y_res; + CARD8 GR5a; + CARD8 GR5c; +} newModes; + +/* Prototypes */ + +Bool TRIDENTClockSelect(ScrnInfoPtr pScrn, int no); +Bool TRIDENTSwitchMode(int scrnIndex, DisplayModePtr mode, int flags); +void TRIDENTAdjustFrame(int scrnIndex, int x, int y, int flags); +Bool TRIDENTDGAInit(ScreenPtr pScreen); +Bool TRIDENTI2CInit(ScreenPtr pScreen); +void TRIDENTInitVideo(ScreenPtr pScreen); +void TRIDENTResetVideo(ScrnInfoPtr pScrn); +unsigned int Tridentddc1Read(ScrnInfoPtr pScrn); +void TVGARestore(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg); +void TVGASave(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg); +Bool TVGAInit(ScrnInfoPtr pScrn, DisplayModePtr mode); +void TridentRestore(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg); +void TridentSave(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg); +Bool TridentInit(ScrnInfoPtr pScrn, DisplayModePtr mode); +Bool TridentAccelInit(ScreenPtr pScreen); +Bool XPAccelInit(ScreenPtr pScreen); +Bool XP4XaaInit(ScreenPtr pScreen); +Bool XP4ExaInit(ScreenPtr pScreen); +Bool ImageAccelInit(ScreenPtr pScreen); +Bool BladeXaaInit(ScreenPtr pScreen); +Bool BladeExaInit(ScreenPtr pScreen); +Bool TridentHWCursorInit(ScreenPtr pScreen); +int TridentFindMode(int xres, int yres, int depth); +void TGUISetClock(ScrnInfoPtr pScrn, int clock, unsigned char *a, unsigned char *b); +void TGUISetMCLK(ScrnInfoPtr pScrn, int clock, unsigned char *a, unsigned char *b); +void tridentSetModeBIOS(ScrnInfoPtr pScrn, DisplayModePtr mode); +void TridentOutIndReg(ScrnInfoPtr pScrn, + CARD32 reg, unsigned char mask, unsigned char data); +unsigned char TridentInIndReg(ScrnInfoPtr pScrn, CARD32 reg); +void TridentWriteAddress(ScrnInfoPtr pScrn, CARD32 index); +void TridentReadAddress(ScrnInfoPtr pScrn, CARD32 index); +void TridentWriteData(ScrnInfoPtr pScrn, unsigned char data); +unsigned char TridentReadData(ScrnInfoPtr pScrn); +void TridentLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indicies, LOCO *colors, VisualPtr pVisual); +void TridentSetOverscan(ScrnInfoPtr pScrn, int overscan); +int TGUISetRead(ScreenPtr pScreen, int bank); +int TGUISetWrite(ScreenPtr pScreen, int bank); +int TGUISetReadWrite(ScreenPtr pScreen, int bank); +int TVGA8900SetRead(ScreenPtr pScreen, int bank); +int TVGA8900SetWrite(ScreenPtr pScreen, int bank); +int TVGA8900SetReadWrite(ScreenPtr pScreen, int bank); +void TridentFindClock(ScrnInfoPtr pScrn, int clock); +float CalculateMCLK(ScrnInfoPtr pScrn); +void TRIDENTRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +void TRIDENTShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf); +void TRIDENTPointerMoved(int index, int x, int y); +void TRIDENTRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +void TRIDENTRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +void TRIDENTRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +void TRIDENTRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox); + +void VIA_TVInit(ScrnInfoPtr pScrn); +void VIA_SaveTVDepentVGAReg(ScrnInfoPtr pScrn); +void VIA_RestoreTVDependVGAReg(ScrnInfoPtr pScrn); +void VIA_DumpReg(ScrnInfoPtr pScrn); + +/* + * Trident Chipset Definitions + */ + +/* Supported chipsets */ +typedef enum { + TVGA8200LX, + TVGA8800BR, + TVGA8800CS, + TVGA8900B, + TVGA8900C, + TVGA8900CL, + TVGA8900D, + TVGA9000, + TVGA9000i, + TVGA9100B, + TVGA9200CXr, + TGUI9400CXi, + TGUI9420DGi, + TGUI9430DGi, + TGUI9440AGi, + CYBER9320, + TGUI9660, + TGUI9680, + PROVIDIA9682, + CYBER9382, + CYBER9385, + PROVIDIA9685, + CYBER9388, + CYBER9397, + CYBER9397DVD, + CYBER9520, + CYBER9525DVD, + IMAGE975, + IMAGE985, + BLADE3D, + CYBERBLADEI7, + CYBERBLADEI7D, + CYBERBLADEI1, + CYBERBLADEI1D, + CYBERBLADEAI1, + CYBERBLADEAI1D, + CYBERBLADEE4, + BLADEXP, + CYBERBLADEXPAI1, + CYBERBLADEXP4, + XP5 +} TRIDENTType; + +#define UseMMIO (pTrident->NoMMIO == FALSE) + +#define IsPciCard (pTrident->pEnt->location.type == BUS_PCI) + +#define IsPrimaryCard ((xf86IsPrimaryPci(pTrident->PciInfo)) || \ + (xf86IsPrimaryIsa())) + +#define HAS_DST_TRANS ((pTrident->Chipset == PROVIDIA9682) || \ + (pTrident->Chipset == PROVIDIA9685) || \ + (pTrident->Chipset == BLADEXP) || \ + (pTrident->Chipset == CYBERBLADEXPAI1)) + +#define Is3Dchip ((pTrident->Chipset == CYBER9397) || \ + (pTrident->Chipset == CYBER9397DVD) || \ + (pTrident->Chipset == CYBER9520) || \ + (pTrident->Chipset == CYBER9525DVD) || \ + (pTrident->Chipset == CYBERBLADEE4) || \ + (pTrident->Chipset == IMAGE975) || \ + (pTrident->Chipset == IMAGE985) || \ + (pTrident->Chipset == CYBERBLADEI7) || \ + (pTrident->Chipset == CYBERBLADEI7D) || \ + (pTrident->Chipset == CYBERBLADEI1) || \ + (pTrident->Chipset == CYBERBLADEI1D) || \ + (pTrident->Chipset == CYBERBLADEAI1) || \ + (pTrident->Chipset == CYBERBLADEAI1D) || \ + (pTrident->Chipset == BLADE3D) || \ + (pTrident->Chipset == CYBERBLADEXPAI1) || \ + (pTrident->Chipset == CYBERBLADEXP4) || \ + (pTrident->Chipset == XP5) || \ + (pTrident->Chipset == BLADEXP)) + +/* + * Trident DAC's + */ + +#define TKD8001 0 +#define TGUIDAC 1 + +/* + * Video Flags + */ + +#define VID_ZOOM_INV 0x1 +#define VID_ZOOM_MINI 0x2 +#define VID_OFF_SHIFT_4 0x4 +#define VID_ZOOM_NOMINI 0x8 +#define VID_DOUBLE_LINEBUFFER_FOR_WIDE_SRC 0x10 +#endif /* _TRIDENT_H_ */ + diff --git a/driver/xf86-video-trident/src/trident_accel.c b/driver/xf86-video-trident/src/trident_accel.c new file mode 100644 index 000000000..d5d033d19 --- /dev/null +++ b/driver/xf86-video-trident/src/trident_accel.c @@ -0,0 +1,665 @@ +/* + * Copyright 1992-2003 by Alan Hourihane, North Wales, UK. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * + * Trident accelerated options. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_accel.c,v 1.28 2003/10/30 13:38:01 alanh Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "xf86_OSproc.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#include "miline.h" + +#include "trident.h" +#include "trident_regs.h" + +#include "xaalocal.h" +#include "xaarop.h" + +static void TridentSync(ScrnInfoPtr pScrn); +static void TridentSetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, + int rop, unsigned int planemask, int length, + unsigned char *pattern); +static void TridentSubsequentDashedBresenhamLine(ScrnInfoPtr pScrn, + int x, int y, int dmaj, int dmin, int e, + int len, int octant, int phase); +static void TridentSetupForSolidLine(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask); +static void TridentSubsequentSolidBresenhamLine(ScrnInfoPtr pScrn, + int x, int y, int dmaj, int dmin, int e, + int len, int octant); +static void TridentSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, + int len, int dir); +static void TridentSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask); +static void TridentSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, + int y, int w, int h); +static void TridentSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, + int x1, int y1, int x2, + int y2, int w, int h); +static void TridentSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, + int xdir, int ydir, int rop, + unsigned int planemask, + int transparency_color); +static void TridentSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, + int patternx, int patterny, int fg, int bg, + int rop, unsigned int planemask); +static void TridentSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, + int patternx, int patterny, int x, int y, + int w, int h); +#if 0 +static void TridentSetupForColor8x8PatternFill(ScrnInfoPtr pScrn, + int patternx, int patterny, + int rop, unsigned int planemask, int trans_col); +static void TridentSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn, + int patternx, int patterny, int x, int y, + int w, int h); +#endif +#if 0 +static void TridentSetupForScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int fg, int bg, int rop, + unsigned int planemask); +static void TridentSubsequentScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, int x, + int y, int w, int h, int skipleft); +static void TridentSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno); +#endif + + +static void +TridentInitializeAccelerator(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + /* This forces updating the clipper */ + pTrident->Clipping = TRUE; + + CHECKCLIPPING; + + if ( (pTrident->Chipset == PROVIDIA9682) || + (pTrident->Chipset == CYBER9385) || + (pTrident->Chipset == CYBER9382) ) + pTrident->EngineOperation |= 0x100; /* Disable Clipping */ + + TGUI_OPERMODE(pTrident->EngineOperation); + + pTrident->PatternLocation = pScrn->displayWidth*pScrn->bitsPerPixel/8; +} + +Bool +TridentAccelInit(ScreenPtr pScreen) +{ + XAAInfoRecPtr infoPtr; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + if (pTrident->NoAccel) + return FALSE; + + pTrident->AccelInfoRec = infoPtr = XAACreateInfoRec(); + if (!infoPtr) return FALSE; + + if (!(pTrident->Chipset == TGUI9440AGi && pScrn->bitsPerPixel > 8)) + infoPtr->Flags = PIXMAP_CACHE | + OFFSCREEN_PIXMAPS | + LINEAR_FRAMEBUFFER; + + pTrident->InitializeAccelerator = TridentInitializeAccelerator; + TridentInitializeAccelerator(pScrn); + + infoPtr->PixmapCacheFlags = DO_NOT_BLIT_STIPPLES; + + infoPtr->Sync = TridentSync; + + infoPtr->SolidLineFlags = NO_PLANEMASK; + infoPtr->SetupForSolidLine = TridentSetupForSolidLine; + infoPtr->SolidBresenhamLineErrorTermBits = 12; + infoPtr->SubsequentSolidBresenhamLine = TridentSubsequentSolidBresenhamLine; + infoPtr->SubsequentSolidHorVertLine = TridentSubsequentSolidHorVertLine; + + infoPtr->DashedLineFlags = LINE_PATTERN_MSBFIRST_LSBJUSTIFIED | + NO_PLANEMASK | + LINE_PATTERN_POWER_OF_2_ONLY; + infoPtr->SetupForDashedLine = TridentSetupForDashedLine; + infoPtr->DashedBresenhamLineErrorTermBits = 12; + infoPtr->SubsequentDashedBresenhamLine = + TridentSubsequentDashedBresenhamLine; + infoPtr->DashPatternMaxLength = 16; + + infoPtr->SolidFillFlags = NO_PLANEMASK; + infoPtr->SetupForSolidFill = TridentSetupForFillRectSolid; + infoPtr->SubsequentSolidFillRect = TridentSubsequentFillRectSolid; + + infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK; + + if (!HAS_DST_TRANS) infoPtr->ScreenToScreenCopyFlags |= NO_TRANSPARENCY; + + infoPtr->SetupForScreenToScreenCopy = + TridentSetupForScreenToScreenCopy; + infoPtr->SubsequentScreenToScreenCopy = + TridentSubsequentScreenToScreenCopy; + + if (!((pTrident->Chipset == PROVIDIA9685 || + pTrident->Chipset == CYBER9388) && pScrn->bitsPerPixel > 8)) { + infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK | + HARDWARE_PATTERN_SCREEN_ORIGIN | + BIT_ORDER_IN_BYTE_MSBFIRST; + + infoPtr->SetupForMono8x8PatternFill = + TridentSetupForMono8x8PatternFill; + infoPtr->SubsequentMono8x8PatternFillRect = + TridentSubsequentMono8x8PatternFillRect; + } + +#if 0 /* Not convinced this works 100% yet */ + infoPtr->Color8x8PatternFillFlags = NO_PLANEMASK | + HARDWARE_PATTERN_SCREEN_ORIGIN | + BIT_ORDER_IN_BYTE_MSBFIRST; + + if (!HAS_DST_TRANS) infoPtr->Color8x8PatternFillFlags |= NO_TRANSPARENCY; + + infoPtr->SetupForColor8x8PatternFill = + TridentSetupForColor8x8PatternFill; + infoPtr->SubsequentColor8x8PatternFillRect = + TridentSubsequentColor8x8PatternFillRect; +#endif + +#if 0 /* This is buggy, it only seems to work 95% of the time.... */ + { + infoPtr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK | + NO_TRANSPARENCY | + BIT_ORDER_IN_BYTE_MSBFIRST; + + pTrident->XAAScanlineColorExpandBuffers[0] = + xnfalloc(((pScrn->virtualX + 63)) *4* (pScrn->bitsPerPixel / 8)); + + infoPtr->NumScanlineColorExpandBuffers = 1; + infoPtr->ScanlineColorExpandBuffers = + pTrident->XAAScanlineColorExpandBuffers; + + infoPtr->SetupForScanlineCPUToScreenColorExpandFill = + TridentSetupForScanlineCPUToScreenColorExpandFill; + infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = + TridentSubsequentScanlineCPUToScreenColorExpandFill; + infoPtr->SubsequentColorExpandScanline = + TridentSubsequentColorExpandScanline; + } +#endif + + return(XAAInit(pScreen, infoPtr)); +} + +static void +TridentSync(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int count = 0, timeout = 0; + int busy; + + TGUI_OPERMODE(pTrident->EngineOperation); + + for (;;) { + BLTBUSY(busy); + if (busy != GE_BUSY) { + return; + } + count++; + if (count == 10000000) { + ErrorF("Trident: BitBLT engine time-out.\n"); + count = 9990000; + timeout++; + if (timeout == 8) { + /* Reset BitBLT Engine */ + TGUI_STATUS(0x00); + return; + } + } + } +} + +static void +TridentClearSync(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int count = 0, timeout = 0; + int busy; + + for (;;) { + BLTBUSY(busy); + if (busy != GE_BUSY) { + return; + } + count++; + if (count == 10000000) { + ErrorF("Trident: BitBLT engine time-out.\n"); + count = 9990000; + timeout++; + if (timeout == 8) { + /* Reset BitBLT Engine */ + TGUI_STATUS(0x00); + return; + } + } + } +} + +static void +TridentSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, + int xdir, int ydir, int rop, + unsigned int planemask, int transparency_color) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int dst = 0; + + pTrident->BltScanDirection = 0; + if (xdir < 0) pTrident->BltScanDirection |= XNEG; + if (ydir < 0) pTrident->BltScanDirection |= YNEG; + + REPLICATE(transparency_color); + if (transparency_color != -1) { + if (pTrident->Chipset == PROVIDIA9685 || + pTrident->Chipset == CYBER9388) { + dst |= 1<<16; + } else { + TGUI_OPERMODE(pTrident->EngineOperation | DST_ENABLE); + } + TGUI_CKEY(transparency_color); + } + + TGUI_DRAWFLAG(pTrident->DrawFlag | pTrident->BltScanDirection | SCR2SCR | dst); + TGUI_FMIX(XAAGetCopyROP(rop)); +} + +static void +TridentSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, + int x2, int y2, int w, int h) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + if (pTrident->BltScanDirection & YNEG) { + y1 = y1 + h - 1; + y2 = y2 + h - 1; + } + if (pTrident->BltScanDirection & XNEG) { + x1 = x1 + w - 1; + x2 = x2 + w - 1; + } + TGUI_SRC_XY(x1,y1); + TGUI_DEST_XY(x2,y2); + TGUI_DIM_XY(w,h); + TGUI_COMMAND(GE_BLT); + TridentClearSync(pScrn); +} + +static void +TridentSetupForSolidLine(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + pTrident->BltScanDirection = 0; + REPLICATE(color); + TGUI_FMIX(XAAGetPatternROP(rop)); + if (pTrident->Chipset == PROVIDIA9685 || + pTrident->Chipset == CYBER9388) { + TGUI_FPATCOL(color); + } else { + TGUI_FCOLOUR(color); + } +} + +static void +TridentSubsequentSolidBresenhamLine( ScrnInfoPtr pScrn, + int x, int y, int dmaj, int dmin, int e, int len, int octant) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int tmp = pTrident->BltScanDirection; + + if (octant & YMAJOR) tmp |= YMAJ; + if (octant & XDECREASING) tmp |= XNEG; + if (octant & YDECREASING) tmp |= YNEG; + TGUI_DRAWFLAG(pTrident->DrawFlag | SOLIDFILL | STENCIL | tmp); + TGUI_SRC_XY(dmin-dmaj,dmin); + TGUI_DEST_XY(x,y); + TGUI_DIM_XY(dmin+e,len); + TGUI_COMMAND(GE_BRESLINE); + TridentSync(pScrn); +} + +static void +TridentSubsequentSolidHorVertLine( + ScrnInfoPtr pScrn, + int x, int y, + int len, int dir +){ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + TGUI_DRAWFLAG(pTrident->DrawFlag | SOLIDFILL); + if (dir == DEGREES_0) { + TGUI_DIM_XY(len,1); + TGUI_DEST_XY(x,y); + } else { + TGUI_DIM_XY(1,len); + TGUI_DEST_XY(x,y); + } + TGUI_COMMAND(GE_BLT); + TridentSync(pScrn); +} + +void +TridentSetupForDashedLine( + ScrnInfoPtr pScrn, + int fg, int bg, int rop, + unsigned int planemask, + int length, + unsigned char *pattern +){ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + CARD32 *DashPattern = (CARD32*)pattern; + CARD32 NiceDashPattern = DashPattern[0]; + + NiceDashPattern = *((CARD16 *)pattern) & ((1<<length) - 1); + switch(length) { + case 2: NiceDashPattern |= NiceDashPattern << 2; + case 4: NiceDashPattern |= NiceDashPattern << 4; + case 8: NiceDashPattern |= NiceDashPattern << 8; + } + pTrident->BltScanDirection = 0; + REPLICATE(fg); + if (pTrident->Chipset == PROVIDIA9685 || + pTrident->Chipset == CYBER9388) { + TGUI_FPATCOL(fg); + if (bg == -1) { + pTrident->BltScanDirection |= 1<<12; + TGUI_BPATCOL(~fg); + } else { + REPLICATE(bg); + TGUI_BPATCOL(bg); + } + } else { + TGUI_FCOLOUR(fg); + if (bg == -1) { + pTrident->BltScanDirection |= 1<<12; + TGUI_BCOLOUR(~fg); + } else { + REPLICATE(bg); + TGUI_BCOLOUR(bg); + } + } + TGUI_FMIX(XAAGetPatternROP(rop)); + pTrident->LinePattern = NiceDashPattern; +} + + +void +TridentSubsequentDashedBresenhamLine(ScrnInfoPtr pScrn, + int x, int y, int dmaj, int dmin, int e, int len, int octant, int phase) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int tmp = pTrident->BltScanDirection; + + if (octant & YMAJOR) tmp |= YMAJ; + if (octant & XDECREASING) tmp |= XNEG; + if (octant & YDECREASING) tmp |= YNEG; + + TGUI_STYLE(((pTrident->LinePattern >> phase) | + (pTrident->LinePattern << (16-phase))) & 0x0000FFFF); + TGUI_DRAWFLAG(pTrident->DrawFlag | STENCIL | tmp); + TGUI_SRC_XY(dmin-dmaj,dmin); + TGUI_DEST_XY(x,y); + TGUI_DIM_XY(e+dmin,len); + TGUI_COMMAND(GE_BRESLINE); + TridentSync(pScrn); +} + +static void +TridentSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int drawflag = 0; + + REPLICATE(color); + TGUI_FMIX(XAAGetPatternROP(rop)); + if (pTrident->Chipset == PROVIDIA9685 || + pTrident->Chipset == CYBER9388) { + TGUI_FPATCOL(color); + } else { + drawflag |= PATMONO; + TGUI_FCOLOUR(color); + } + TGUI_DRAWFLAG(pTrident->DrawFlag | SOLIDFILL | drawflag); +} + +static void +TridentSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + TGUI_DIM_XY(w,h); + TGUI_DEST_XY(x,y); + TGUI_COMMAND(GE_BLT); + TridentSync(pScrn); +} + +#if 0 +static void MoveDWORDS( + register CARD32* dest, + register CARD32* src, + register int dwords ) +{ + while(dwords & ~0x03) { + *dest = *src; + *(dest + 1) = *(src + 1); + *(dest + 2) = *(src + 2); + *(dest + 3) = *(src + 3); + src += 4; + dest += 4; + dwords -= 4; + } + if (!dwords) return; + *dest = *src; + dest += 1; + src += 1; + if (dwords == 1) return; + *dest = *src; + dest += 1; + src += 1; + if (dwords == 2) return; + *dest = *src; + dest += 1; + src += 1; +} +#endif + +static void +TridentSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, + int patternx, int patterny, + int fg, int bg, int rop, + unsigned int planemask) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int drawflag = 0; + + REPLICATE(fg); + if (pTrident->Chipset == PROVIDIA9685 || + pTrident->Chipset == CYBER9388) + TGUI_FPATCOL(fg); + else + TGUI_FCOLOUR(fg); + + if (bg == -1) { + drawflag |= 1<<12; + if (pTrident->Chipset == PROVIDIA9685 || + pTrident->Chipset == CYBER9388) + TGUI_BPATCOL(~fg); + else + TGUI_BCOLOUR(~fg); + } else { + REPLICATE(bg); + if (pTrident->Chipset == PROVIDIA9685 || + pTrident->Chipset == CYBER9388) + TGUI_BPATCOL(bg); + else + TGUI_BCOLOUR(bg); + } + + if (pTrident->Chipset == PROVIDIA9685 || + pTrident->Chipset == CYBER9388) { + drawflag |= 7<<18; + } + TGUI_DRAWFLAG(pTrident->DrawFlag | PAT2SCR | PATMONO | drawflag); + TGUI_PATLOC(((patterny * pTrident->PatternLocation) + + (patternx * pScrn->bitsPerPixel / 8)) >> 6); + TGUI_FMIX(XAAGetPatternROP(rop)); +} + +static void +TridentSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, + int patternx, int patterny, + int x, int y, + int w, int h) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + TGUI_DEST_XY(x,y); + TGUI_DIM_XY(w,h); + TGUI_COMMAND(GE_BLT); + TridentSync(pScrn); +} + +#if 0 +static void +TridentSetupForColor8x8PatternFill(ScrnInfoPtr pScrn, + int patternx, int patterny, + int rop, + unsigned int planemask, + int transparency_color) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int drawflag = 0; + + REPLICATE(transparency_color); + if (transparency_color != -1) { + if (pTrident->Chipset == PROVIDIA9685 || + pTrident->Chipset == CYBER9388) { + drawflag |= 1<<16; + } else { + TGUI_OPERMODE(pTrident->EngineOperation | DST_ENABLE); + } + TGUI_CKEY(transparency_color); + } + + TGUI_DRAWFLAG(pTrident->DrawFlag | PAT2SCR | drawflag); + TGUI_PATLOC(((patterny * pTrident->PatternLocation) + + (patternx * pScrn->bitsPerPixel / 8)) >> 6); + TGUI_FMIX(XAAGetPatternROP(rop)); +} + +static void +TridentSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn, + int patternx, int patterny, + int x, int y, + int w, int h) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + TGUI_DEST_XY(x,y); + TGUI_DIM_XY(w,h); + TGUI_COMMAND(GE_BLT); + TridentClearSync(pScrn); +} +#endif + +#if 0 +static void +TridentSetupForScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int fg, int bg, + int rop, + unsigned int planemask +){ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int drawflag = SRCMONO; + + REPLICATE(fg); + TGUI_FCOLOUR(fg); + if (bg == -1) { + drawflag |= 1<<12; + TGUI_BCOLOUR(~fg); + } else { + REPLICATE(bg); + TGUI_BCOLOUR(bg); + } + + TGUI_SRC_XY(0,0); + TGUI_DRAWFLAG(drawflag); + TGUI_FMIX(XAAGetCopyROP(rop)); +} + +static void +TridentSubsequentScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int x, int y, int w, int h, + int skipleft +){ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + pTrident->dwords = (w + 31) >> 5; + pTrident->h = h; + pTrident->y = y; + pTrident->x = x; + pTrident->w = w; + + TGUI_DEST_XY(x,pTrident->y++); + TGUI_DIM_XY(w,1); + TGUI_COMMAND(GE_BLT); +} + +static void +TridentSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + XAAInfoRecPtr infoRec; + infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + + MoveDWORDS((CARD32 *)pTrident->FbBase, + (CARD32 *)pTrident->XAAScanlineColorExpandBuffers[0], + pTrident->dwords); + + pTrident->h--; + TridentSync(pScrn); + if (pTrident->h) { + TGUI_DEST_XY(pTrident->x,pTrident->y++); + TGUI_DIM_XY(pTrident->w,1); + TGUI_COMMAND(GE_BLT); + } +} +#endif diff --git a/driver/xf86-video-trident/src/trident_bank.c b/driver/xf86-video-trident/src/trident_bank.c new file mode 100644 index 000000000..be0536aa4 --- /dev/null +++ b/driver/xf86-video-trident/src/trident_bank.c @@ -0,0 +1,98 @@ +/* + * Copyright 1992-2003 by Alan Hourihane, North Wales, UK. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Alan Hourihane, alanh@fairlite.demon.co.uk + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_bank.c,v 1.4 2000/12/07 16:48:04 alanh Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* All drivers should typically include these */ +#include "xf86.h" +#include "xf86_OSproc.h" + +/* Drivers for PCI hardware need this */ +#include "xf86PciInfo.h" + +/* Drivers that need to access the PCI config space directly need this */ +#include "xf86Pci.h" + +#include "compiler.h" +#include "trident.h" +#include "trident_regs.h" + +int TVGA8900SetRead(ScreenPtr pScreen, int bank) +{ + ScrnInfoPtr pScrn; + TRIDENTPtr pTrident; + pScrn = xf86Screens[pScreen->myNum]; + pTrident = TRIDENTPTR(pScrn); + OUTW(0x3c4, 0xC000 | (((bank & 0x3f) ^ 0x02)<<8)|0x0E); + return 0; +} +int TGUISetRead(ScreenPtr pScreen, int bank) +{ + ScrnInfoPtr pScrn; + TRIDENTPtr pTrident; + pScrn = xf86Screens[pScreen->myNum]; + pTrident = TRIDENTPTR(pScrn); + OUTB(0x3d9, bank & 0xff); + return 0; +} +int TVGA8900SetWrite(ScreenPtr pScreen, int bank) +{ + ScrnInfoPtr pScrn; + TRIDENTPtr pTrident; + pScrn = xf86Screens[pScreen->myNum]; + pTrident = TRIDENTPTR(pScrn); + OUTW(0x3c4, 0xC000 | (((bank & 0x3f) ^ 0x02)<<8)|0x0E); + return 0; +} +int TGUISetWrite(ScreenPtr pScreen, int bank) +{ + ScrnInfoPtr pScrn; + TRIDENTPtr pTrident; + pScrn = xf86Screens[pScreen->myNum]; + pTrident = TRIDENTPTR(pScrn); + OUTB(0x3d8, bank & 0xff); + return 0; +} +int TVGA8900SetReadWrite(ScreenPtr pScreen, int bank) +{ + ScrnInfoPtr pScrn; + TRIDENTPtr pTrident; + pScrn = xf86Screens[pScreen->myNum]; + pTrident = TRIDENTPTR(pScrn); + OUTW(0x3c4, 0xC000 | (((bank & 0x3f) ^ 0x02)<<8)|0x0E); + return 0; +} +int TGUISetReadWrite(ScreenPtr pScreen, int bank) +{ + ScrnInfoPtr pScrn; + TRIDENTPtr pTrident; + pScrn = xf86Screens[pScreen->myNum]; + pTrident = TRIDENTPTR(pScrn); + OUTB(0x3d8, bank & 0xff); + OUTB(0x3d9, bank & 0xff); + return 0; +} diff --git a/driver/xf86-video-trident/src/trident_dac.c b/driver/xf86-video-trident/src/trident_dac.c new file mode 100644 index 000000000..1324ddfc1 --- /dev/null +++ b/driver/xf86-video-trident/src/trident_dac.c @@ -0,0 +1,1277 @@ +/* + * Copyright 1992-2003 by Alan Hourihane, North Wales, UK. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Alan Hourihane, alanh@fairlite.demon.co.uk + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_dac.c,v 1.79 2003/11/03 05:11:42 tsi Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Version.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#include "vgaHW.h" + +#include "trident.h" +#include "trident_regs.h" + + +static biosMode bios1[] = { + { 640, 480, 0x11 } +}; + +static biosMode bios4[] = { + { 320, 200, 0xd }, + { 640, 200, 0xe }, + { 640, 350, 0x11 }, + { 640, 480, 0x12 }, + { 800, 600, 0x5b }, + { 1024, 768 , 0x5f }, + { 1280, 1024, 0x63 }, + { 1600, 1200, 0x65 } +}; + +static biosMode bios8[] = { + { 320, 200, 0x13 }, + { 640, 400, 0x5c }, + { 640, 480, 0x5d }, + { 720, 480, 0x60 }, + { 800, 600, 0x5e }, + { 1024, 768, 0x62 }, + { 1280, 1024, 0x64 }, + { 1600, 1200, 0x66 } +}; + +static biosMode bios15[] = { + { 640, 400, 0x72 }, + { 640, 480, 0x74 }, + { 720, 480, 0x70 }, + { 800, 600, 0x76 }, + { 1024, 768, 0x78 }, + { 1280, 1024, 0x7a }, + { 1600, 1200, 0x7c } +}; + +static biosMode bios16[] = { + { 640, 400, 0x73 }, + { 640, 480, 0x75 }, + { 720, 480, 0x71 }, + { 800, 600, 0x77 }, + { 1024, 768, 0x79 }, + { 1280, 1024, 0x7b }, + { 1600, 1200, 0x7d } +}; + +static biosMode bios24[] = { + { 640, 400, 0x6b }, + { 640, 480, 0x6c }, + { 720, 480, 0x61 }, + { 800, 600, 0x6d }, + { 1024, 768, 0x6e } +}; + +static newModes newModeRegs [] = { + { 320, 200, 0x13, 0x30 }, + { 640, 480, 0x13, 0x61 }, + { 800, 600, 0x13, 0x62 }, + { 1024, 768, 0x31, 0x63 }, + { 1280, 1024, 0x7b, 0x64 }, + { 1400, 1050, 0x11, 0x7b } +}; + +int +TridentFindMode(int xres, int yres, int depth) +{ + int xres_s; + int i, size; + biosMode *mode; + + switch (depth) { + case 8: + size = sizeof(bios8) / sizeof(biosMode); + mode = bios8; + break; + case 15: + size = sizeof(bios15) / sizeof(biosMode); + mode = bios15; + break; + case 16: + size = sizeof(bios16) / sizeof(biosMode); + mode = bios16; + break; + case 24: + size = sizeof(bios24) / sizeof(biosMode); + mode = bios24; + break; + default: + return 0; + } + + for (i = 0; i < size; i++) { + if (xres <= mode[i].x_res) { + xres_s = mode[i].x_res; + for (; i < size; i++) { + if (mode[i].x_res != xres_s) + return mode[i-1].mode; + if (yres <= mode[i].y_res) + return mode[i].mode; + } + } + } + return mode[size - 1].mode; +} + +static void +TridentFindNewMode(int xres, int yres, CARD8 *gr5a, CARD8 *gr5c) +{ + int xres_s; + int i, size; + + size = sizeof(newModeRegs) / sizeof(newModes); + + for (i = 0; i < size; i++) { + if (xres <= newModeRegs[i].x_res) { + xres_s = newModeRegs[i].x_res; + for (; i < size; i++) { + if (newModeRegs[i].x_res != xres_s + || yres <= newModeRegs[i].y_res) { + *gr5a = newModeRegs[i].GR5a; + *gr5c = newModeRegs[i].GR5c; + return; + } + } + } + } + *gr5a = newModeRegs[size - 1].GR5a; + *gr5c = newModeRegs[size - 1].GR5c; + return; +} + +static void +tridentSetBrightnessAndGamma(TRIDENTRegPtr tridentReg, + Bool on, double exp,int brightness) +{ + int pivots[] = {0,3,15,63,255}; + + double slope; + double y_0; + double x, x_prev = 0, y, y_prev = 0; + int i; + CARD8 i_slopes[4]; + CARD8 intercepts[4]; + + if (!on) { + tridentReg->tridentRegs3C4[0xB4] &= ~0x80; + return; + } + + for (i = 0; i < 4; i++) { + x = pivots[i + 1] / 255.0; + y = pow(x,exp); + slope = (y - y_prev) / (x - x_prev); + y_0 = y - x * slope; + { +#define RND(x) ((((x) - (int) (x)) < 0.5) ? (int)(x) : (int)(x) + 1) + int val = slope; + if (val > 7) + i_slopes[i] = (3 << 4) | (RND(slope) & 0xf); + else if (val > 3) + i_slopes[i] = (2 << 4) | (RND(slope * 2) & 0xf); + else if (val > 1) + i_slopes[i] = (1 << 4) | (RND(slope * 4) & 0xf); + else + i_slopes[i] = (RND(slope * 8) & 0xf); +#undef RND + } + intercepts[i] = (char)(y_0 * 256 / 4); + x_prev = x; + y_prev = y; + } + + tridentReg->tridentRegs3C4[0xB4] = 0x80 | i_slopes[0]; + tridentReg->tridentRegs3C4[0xB5] = i_slopes[1]; + tridentReg->tridentRegs3C4[0xB6] = i_slopes[2]; + tridentReg->tridentRegs3C4[0xB7] = i_slopes[3]; + tridentReg->tridentRegs3C4[0xB8] = (intercepts[0] + brightness); + tridentReg->tridentRegs3C4[0xB9] = (intercepts[1] + brightness); + tridentReg->tridentRegs3C4[0xBA] = (intercepts[2] + brightness); + tridentReg->tridentRegs3C4[0xBB] = (intercepts[3] + brightness); +} + +Bool +TridentInit(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + TRIDENTRegPtr pReg = &pTrident->ModeReg; + + int vgaIOBase; + int offset = 0; + int clock = pTrident->currentClock; + CARD8 protect = 0; + Bool fullSize = FALSE; + + vgaHWPtr hwp = VGAHWPTR(pScrn); + vgaRegPtr regp = &hwp->ModeReg; + vgaRegPtr vgaReg = &hwp->ModeReg; + vgaIOBase = VGAHWPTR(pScrn)->IOBase; + + /* Unprotect */ + if (pTrident->Chipset > PROVIDIA9685) { + OUTB(0x3C4, Protection); + protect = INB(0x3C5); + OUTB(0x3C5, 0x92); + } + + OUTB(0x3C4, 0x0B); INB(0x3C5); /* Ensure we are in New Mode */ + + pReg->tridentRegs3x4[PixelBusReg] = 0x00; + pReg->tridentRegsDAC[0x00] = 0x00; + pReg->tridentRegs3C4[NewMode2] = 0x20; + OUTB(0x3CE, MiscExtFunc); + pReg->tridentRegs3CE[MiscExtFunc] = INB(0x3CF) & 0xF0; + pReg->tridentRegs3x4[GraphEngReg] = 0x00; + pReg->tridentRegs3x4[PreEndControl] = 0; + pReg->tridentRegs3x4[PreEndFetch] = 0; + + pReg->tridentRegs3x4[CRTHiOrd] = (((mode->CrtcVBlankEnd-1) & 0x400)>>4) | + (((mode->CrtcVTotal - 2) & 0x400) >> 3) | + ((mode->CrtcVSyncStart & 0x400) >> 5) | + (((mode->CrtcVDisplay - 1) & 0x400) >> 6)| + 0x08; + + pReg->tridentRegs3x4[HorizOverflow] = ((mode->CrtcHTotal & 0x800) >> 11) | + ((mode->CrtcHBlankStart & 0x800)>>7); + + if (pTrident->IsCyber) { + Bool LCDActive; +#ifdef READOUT + Bool ShadowModeActive; +#endif + int i = pTrident->lcdMode; +#ifdef READOUT + OUTB(0x3CE, CyberControl); + ShadowModeActive = ((INB(0x3CF) & 0x81) == 0x81); +#endif + OUTB(0x3CE, FPConfig); + pReg->tridentRegs3CE[FPConfig] = INB(0x3CF); + if (pTrident->dspOverride) { + if (pTrident->dspOverride & LCD_ACTIVE) { + pReg->tridentRegs3CE[FPConfig] |= 0x10; + LCDActive = TRUE; + } else { + pReg->tridentRegs3CE[FPConfig] &= ~0x10; + LCDActive = FALSE; + } + if (pTrident->dspOverride & CRT_ACTIVE) + pReg->tridentRegs3CE[FPConfig] |= 0x20; + else + pReg->tridentRegs3CE[FPConfig] &= ~0x20; + } else { + LCDActive = (pReg->tridentRegs3CE[FPConfig] & 0x10); + } + + OUTB(0x3CE, CyberEnhance); +#if 0 + pReg->tridentRegs3CE[CyberEnhance] = INB(0x3CF); +#else + pReg->tridentRegs3CE[CyberEnhance] = INB(0x3CF) & 0x8F; + if (mode->CrtcVDisplay > 1024) + pReg->tridentRegs3CE[CyberEnhance] |= 0x50; + else + if (mode->CrtcVDisplay > 768) + pReg->tridentRegs3CE[CyberEnhance] |= 0x30; + else + if (mode->CrtcVDisplay > 600) + pReg->tridentRegs3CE[CyberEnhance] |= 0x20; + else + if (mode->CrtcVDisplay > 480) + pReg->tridentRegs3CE[CyberEnhance] |= 0x10; +#endif + OUTB(0x3CE, CyberControl); + pReg->tridentRegs3CE[CyberControl] = INB(0x3CF); + + OUTB(0x3CE,HorStretch); + pReg->tridentRegs3CE[HorStretch] = INB(0x3CF); + OUTB(0x3CE,VertStretch); + pReg->tridentRegs3CE[VertStretch] = INB(0x3CF); + +#ifdef READOUT + if ((!((pReg->tridentRegs3CE[VertStretch] & 1) || + (pReg->tridentRegs3CE[HorStretch] & 1))) + && (!LCDActive || ShadowModeActive)) + { + unsigned char tmp; + + SHADOW_ENABLE(tmp); + OUTB(vgaIOBase + 4,0); + pReg->tridentRegs3x4[0x0] = INB(vgaIOBase + 5); + OUTB(vgaIOBase + 4,3); + pReg->tridentRegs3x4[0x3] = INB(vgaIOBase + 5); + OUTB(vgaIOBase + 4,4); + pReg->tridentRegs3x4[0x4] = INB(vgaIOBase + 5); + OUTB(vgaIOBase + 4,5); + pReg->tridentRegs3x4[0x5] = INB(vgaIOBase + 5); + OUTB(vgaIOBase + 4,0x6); + pReg->tridentRegs3x4[0x6] = INB(vgaIOBase + 5); + SHADOW_RESTORE(tmp); + } else +#endif + { + if (i != 0xff) { + pReg->tridentRegs3x4[0x0] = LCD[i].shadow_0; + pReg->tridentRegs3x4[0x1] = regp->CRTC[1]; + pReg->tridentRegs3x4[0x2] = regp->CRTC[2]; + pReg->tridentRegs3x4[0x3] = LCD[i].shadow_3; + pReg->tridentRegs3x4[0x4] = LCD[i].shadow_4; + pReg->tridentRegs3x4[0x5] = LCD[i].shadow_5; + pReg->tridentRegs3x4[0x6] = LCD[i].shadow_6; + xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1, + "Overriding Horizontal timings.\n"); + } + } + + if (i != 0xff) { + pReg->tridentRegs3x4[0x7] = LCD[i].shadow_7; + pReg->tridentRegs3x4[0x10] = LCD[i].shadow_10; + pReg->tridentRegs3x4[0x11] = LCD[i].shadow_11; + pReg->tridentRegs3x4[0x12] = regp->CRTC[0x12]; + pReg->tridentRegs3x4[0x15] = regp->CRTC[0x15]; + pReg->tridentRegs3x4[0x16] = LCD[i].shadow_16; + if (LCDActive) { + /* use current screen size not panel size for display area */ + pReg->tridentRegs3x4[CRTHiOrd] = + (pReg->tridentRegs3x4[CRTHiOrd] & 0x10) + | (LCD[i].shadow_HiOrd & ~0x10); + } + + fullSize = (mode->HDisplay == LCD[i].display_x) + && (mode->VDisplay == LCD[i].display_y); + } + + /* copy over common bits from normal VGA */ + + pReg->tridentRegs3x4[0x7] &= ~0x4A; + pReg->tridentRegs3x4[0x7] |= (vgaReg->CRTC[0x7] & 0x4A); + if (LCDActive && fullSize) { + regp->CRTC[0] = pReg->tridentRegs3x4[0]; + regp->CRTC[3] = pReg->tridentRegs3x4[3]; + regp->CRTC[4] = pReg->tridentRegs3x4[4]; + regp->CRTC[5] = pReg->tridentRegs3x4[5]; + regp->CRTC[6] = pReg->tridentRegs3x4[6]; + regp->CRTC[7] = pReg->tridentRegs3x4[7]; + regp->CRTC[0x10] = pReg->tridentRegs3x4[0x10]; + regp->CRTC[0x11] = pReg->tridentRegs3x4[0x11]; + regp->CRTC[0x16] = pReg->tridentRegs3x4[0x16]; + } + if (LCDActive && !fullSize) { + /* + * Set negative h/vsync polarity to center display nicely + * Seems to work on several systems. + */ + regp->MiscOutReg |= 0xC0; + /* + * If the LCD is active and we don't fill the entire screen + * and the previous mode was stretched we may need help from + * the BIOS to set all registers for the unstreched mode. + */ + pTrident->doInit = ((pReg->tridentRegs3CE[HorStretch] & 1) + || (pReg->tridentRegs3CE[VertStretch] & 1)); + pReg->tridentRegs3CE[CyberControl] |= 0x81; + xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"Shadow on\n"); + } else { + pReg->tridentRegs3CE[CyberControl] &= 0x7E; + xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"Shadow off\n"); + } + if (pTrident->FPDelay < 6) { + pReg->tridentRegs3CE[CyberControl] &= 0xC7; + pReg->tridentRegs3CE[CyberControl] |= (pTrident->FPDelay + 2) << 3; + } + + if (pTrident->CyberShadow) { + pReg->tridentRegs3CE[CyberControl] &= 0x7E; + xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"Forcing Shadow off\n"); + } + + xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"H-timing shadow registers:" + " 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", + pReg->tridentRegs3x4[0], pReg->tridentRegs3x4[3], + pReg->tridentRegs3x4[4], pReg->tridentRegs3x4[5]); + xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"H-timing registers: " + " 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", + regp->CRTC[0], regp->CRTC[1], regp->CRTC[2], + regp->CRTC[3], regp->CRTC[4], regp->CRTC[5]); + xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"V-timing shadow registers: " + "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x" + " 0x%2.2x (0x%2.2x)\n", + pReg->tridentRegs3x4[6], pReg->tridentRegs3x4[7], + pReg->tridentRegs3x4[0x10],pReg->tridentRegs3x4[0x11], + pReg->tridentRegs3x4[0x16], + pReg->tridentRegs3x4[CRTHiOrd]); + xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"V-timing registers: " + "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " + "0x%2.2x 0x%2.2x 0x%2.2x\n", + regp->CRTC[6], regp->CRTC[7], regp->CRTC[0x10], + regp->CRTC[0x11],regp->CRTC[0x12], + regp->CRTC[0x14],regp->CRTC[0x16]); + + + /* disable stretching, enable centering for default sizes */ + pReg->tridentRegs3CE[VertStretch] &= 0x7C; + switch (mode->VDisplay) { + case 768: + case 600: + case 480: + case 240: + pReg->tridentRegs3CE[VertStretch] |= 0x80; + } + pReg->tridentRegs3CE[HorStretch] &= 0x7C; + switch (mode->HDisplay) { + case 1024: + case 800: + case 640: + case 320: + pReg->tridentRegs3CE[HorStretch] |= 0x80; + } +#if 1 + { + int mul = pScrn->bitsPerPixel >> 3; + int val; + + if (!mul) mul = 1; + + /* this is what my BIOS does */ + val = (mode->HDisplay * mul / 8) + 16; + + pReg->tridentRegs3x4[PreEndControl] = ((val >> 8) < 2 ? 2 :0) + | ((val >> 8) & 0x01); + pReg->tridentRegs3x4[PreEndFetch] = val & 0xff; + } +#else + OUTB(vgaIOBase + 4,PreEndControl); + pReg->tridentRegs3x4[PreEndControl] = INB(vgaIOBase + 5); + OUTB(vgaIOBase + 4,PreEndFetch); + pReg->tridentRegs3x4[PreEndFetch] = INB(vgaIOBase + 5); +#endif + /* set mode */ + if (pTrident->Chipset < BLADEXP) { + pReg->tridentRegs3CE[BiosMode] = TridentFindMode( + mode->HDisplay, + mode->VDisplay, + pScrn->depth); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 1, + "Setting BIOS Mode: %x for: %ix%i\n", + pReg->tridentRegs3CE[BiosMode], + mode->HDisplay, + mode->VDisplay); + } else { + TridentFindNewMode(mode->HDisplay, + mode->VDisplay, + &pReg->tridentRegs3CE[BiosNewMode1], + &pReg->tridentRegs3CE[BiosNewMode2]); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 1, + "Setting BIOS Mode Regs: %x %x for: %ix%i\n", + pReg->tridentRegs3CE[BiosNewMode1], + pReg->tridentRegs3CE[BiosNewMode2], + mode->HDisplay, + mode->VDisplay); + }; + + /* no stretch */ + if (pTrident->Chipset == CYBERBLADEXPAI1 + || pTrident->Chipset == BLADEXP) + pReg->tridentRegs3CE[BiosReg] = 8; + else + pReg->tridentRegs3CE[BiosReg] = 0; + + if (pTrident->CyberStretch) { + pReg->tridentRegs3CE[VertStretch] |= 0x01; + pReg->tridentRegs3CE[HorStretch] |= 0x01; + xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"Enabling StretchMode\n"); + } + } + + /* Enable Chipset specific options */ + switch (pTrident->Chipset) { + case XP5: + case CYBERBLADEXP4: + case CYBERBLADEXPAI1: + case BLADEXP: + case CYBERBLADEI7: + case CYBERBLADEI7D: + case CYBERBLADEI1: + case CYBERBLADEI1D: + case CYBERBLADEAI1: + case CYBERBLADEAI1D: + case CYBERBLADEE4: + case BLADE3D: + OUTB(vgaIOBase + 4, RAMDACTiming); + pReg->tridentRegs3x4[RAMDACTiming] = INB(vgaIOBase + 5) | 0x0F; + /* Fall Through */ + case CYBER9520: + case CYBER9525DVD: + case CYBER9397DVD: + case CYBER9397: + case IMAGE975: + case IMAGE985: + case CYBER9388: + pReg->tridentRegs3CE[MiscExtFunc] |= 0x10; + if (!pReg->tridentRegs3x4[PreEndControl]) + pReg->tridentRegs3x4[PreEndControl] = 0x01; + if (!pReg->tridentRegs3x4[PreEndFetch]) + pReg->tridentRegs3x4[PreEndFetch] = 0xFF; + /* Fall Through */ + case PROVIDIA9685: + case CYBER9385: + pReg->tridentRegs3x4[Enhancement0] = 0x40; + /* Fall Through */ + case PROVIDIA9682: + case CYBER9382: + if (pTrident->UsePCIRetry) + pReg->tridentRegs3x4[PCIRetry] = 0xDF; + else + pReg->tridentRegs3x4[PCIRetry] = 0x1F; + /* Fall Through */ + case TGUI9660: + case TGUI9680: + if (pTrident->MUX && pScrn->bitsPerPixel == 8) { + pReg->tridentRegs3x4[PixelBusReg] |= 0x01; /* 16bit bus */ + pReg->tridentRegs3C4[NewMode2] |= 0x02; /* half clock */ + pReg->tridentRegsDAC[0x00] |= 0x20; /* mux mode */ + } + } + + /* Defaults for all trident chipsets follows */ + switch (pScrn->bitsPerPixel) { + case 8: + pReg->tridentRegs3CE[MiscExtFunc] |= 0x02; + offset = pScrn->displayWidth >> 3; + break; + case 16: + pReg->tridentRegs3CE[MiscExtFunc] |= 0x02; + offset = pScrn->displayWidth >> 2; + if (pScrn->depth == 15) + pReg->tridentRegsDAC[0x00] = 0x10; + else + pReg->tridentRegsDAC[0x00] = 0x30; + pReg->tridentRegs3x4[PixelBusReg] = 0x04; + /* Reload with any chipset specific stuff here */ + if (pTrident->Chipset >= TGUI9660) + pReg->tridentRegs3x4[PixelBusReg] |= 0x01; + if (pTrident->Chipset == TGUI9440AGi) { + pReg->tridentRegs3CE[MiscExtFunc] |= 0x08;/*Clock Division / 2*/ + clock *= 2; /* Double the clock */ + } + break; + case 24: + pReg->tridentRegs3CE[MiscExtFunc] |= 0x02; + offset = (pScrn->displayWidth * 3) >> 3; + pReg->tridentRegs3x4[PixelBusReg] = 0x29; + pReg->tridentRegsDAC[0x00] = 0xD0; + if (pTrident->Chipset == CYBERBLADEXP4 || + pTrident->Chipset == XP5 || + pTrident->Chipset == CYBERBLADEE4) { + OUTB(vgaIOBase+ 4, New32); + pReg->tridentRegs3x4[New32] = INB(vgaIOBase + 5) & 0x7F; + } + break; + case 32: + pReg->tridentRegs3CE[MiscExtFunc] |= 0x02; + if (pTrident->Chipset != CYBERBLADEXP4 + && pTrident->Chipset != BLADEXP + && pTrident->Chipset != XP5 + && pTrident->Chipset != CYBERBLADEE4 + && pTrident->Chipset != CYBERBLADEXPAI1) { + /* Clock Division by 2*/ + pReg->tridentRegs3CE[MiscExtFunc] |= 0x08; + clock *= 2; /* Double the clock */ + } + offset = pScrn->displayWidth >> 1; + pReg->tridentRegs3x4[PixelBusReg] = 0x09; + pReg->tridentRegsDAC[0x00] = 0xD0; + if (pTrident->Chipset == CYBERBLADEXP4 + || pTrident->Chipset == BLADEXP + || pTrident->Chipset == XP5 + || pTrident->Chipset == CYBERBLADEE4 + || pTrident->Chipset == CYBERBLADEXPAI1) { + OUTB(vgaIOBase+ 4, New32); + pReg->tridentRegs3x4[New32] = INB(vgaIOBase + 5) | 0x80; + /* With new mode 32bpp we set the packed flag */ + pReg->tridentRegs3x4[PixelBusReg] |= 0x20; + } + break; + } + pReg->tridentRegs3x4[Offset] = offset & 0xFF; + + { + CARD8 a, b; + TGUISetClock(pScrn, clock, &a, &b); + pReg->tridentRegsClock[0x00] = (regp->MiscOutReg & 0xF3) | 0x08; + pReg->tridentRegsClock[0x01] = a; + pReg->tridentRegsClock[0x02] = b; + if (pTrident->MCLK > 0) { + TGUISetMCLK(pScrn, pTrident->MCLK, &a, &b); + pReg->tridentRegsClock[0x03] = a; + pReg->tridentRegsClock[0x04] = b; + } + } + + pReg->tridentRegs3C4[NewMode1] = 0xC0; + pReg->tridentRegs3C4[Protection] = 0x92; + + pReg->tridentRegs3x4[LinearAddReg] = 0; + if (pTrident->Linear) { + /* This is used for VLB, when we support it again in 4.0 */ + if (pTrident->Chipset < CYBER9385) + pReg->tridentRegs3x4[LinearAddReg] |= + ((pTrident->FbAddress >> 24) << 6)| + ((pTrident->FbAddress >> 20) & 0x0F); + /* Turn on linear mapping */ + pReg->tridentRegs3x4[LinearAddReg] |= 0x20; + } else { + pReg->tridentRegs3CE[MiscExtFunc] |= 0x04; + } + + pReg->tridentRegs3x4[CRTCModuleTest] = + (mode->Flags & V_INTERLACE ? 0x84 : 0x80); + + OUTB(vgaIOBase+ 4, InterfaceSel); + pReg->tridentRegs3x4[InterfaceSel] = INB(vgaIOBase + 5) | 0x40; + + OUTB(vgaIOBase+ 4, Performance); + pReg->tridentRegs3x4[Performance] = INB(vgaIOBase + 5); + if (pTrident->Chipset < BLADEXP) + pReg->tridentRegs3x4[Performance] |= 0x10; + + OUTB(vgaIOBase+ 4, DRAMControl); + if (pTrident->Chipset >= CYBER9388) + pReg->tridentRegs3x4[DRAMControl] = INB(vgaIOBase + 5) | 0x10; + + if (pTrident->IsCyber && !pTrident->MMIOonly) + pReg->tridentRegs3x4[DRAMControl] |= 0x20; + + if (pTrident->NewClockCode && pTrident->Chipset <= CYBER9397DVD) { + OUTB(vgaIOBase + 4, ClockControl); + pReg->tridentRegs3x4[ClockControl] = INB(vgaIOBase + 5) | 0x01; + } + + OUTB(vgaIOBase+ 4, AddColReg); + pReg->tridentRegs3x4[AddColReg] = INB(vgaIOBase + 5) & 0xEF; + pReg->tridentRegs3x4[AddColReg] |= (offset & 0x100) >> 4; + + if (pTrident->Chipset >= TGUI9660) { + pReg->tridentRegs3x4[AddColReg] &= 0xDF; + pReg->tridentRegs3x4[AddColReg] |= (offset & 0x200) >> 4; + } + + if (IsPciCard && UseMMIO) { + if (!pTrident->NoAccel) + pReg->tridentRegs3x4[GraphEngReg] |= 0x80; + } else { + if (!pTrident->NoAccel) + pReg->tridentRegs3x4[GraphEngReg] |= 0x82; + } + + OUTB(0x3CE, MiscIntContReg); + pReg->tridentRegs3CE[MiscIntContReg] = INB(0x3CF) | 0x04; + + /* Fix hashing problem in > 8bpp on 9320 chipset */ + if (pTrident->Chipset == CYBER9320 && pScrn->bitsPerPixel > 8) + pReg->tridentRegs3CE[MiscIntContReg] &= ~0x80; + + OUTB(vgaIOBase+ 4, PCIReg); + if (IsPciCard && UseMMIO) + pReg->tridentRegs3x4[PCIReg] = INB(vgaIOBase + 5) & 0xF9; + else + pReg->tridentRegs3x4[PCIReg] = INB(vgaIOBase + 5) & 0xF8; + + /* Enable PCI Bursting on capable chips */ + if (pTrident->Chipset >= TGUI9660) { + if(pTrident->UsePCIBurst) { + pReg->tridentRegs3x4[PCIReg] |= 0x06; + } else { + pReg->tridentRegs3x4[PCIReg] &= 0xF9; + } + } + + if (pTrident->Chipset >= CYBER9388) { + if (pTrident->GammaBrightnessOn) + xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1, + "Setting Gamma: %f Brightness: %i\n", + pTrident->gamma, pTrident->brightness); + tridentSetBrightnessAndGamma(pReg, + pTrident->GammaBrightnessOn, + pTrident->gamma, pTrident->brightness); + } + + /* Video */ + OUTB(0x3C4,0x20); + pReg->tridentRegs3C4[SSetup] = INB(0x3C5) | 0x4; + pReg->tridentRegs3C4[SKey] = 0x00; + pReg->tridentRegs3C4[SPKey] = 0xC0; + OUTB(0x3C4,0x12); + pReg->tridentRegs3C4[Threshold] = INB(0x3C5); + if (pScrn->bitsPerPixel > 16) + pReg->tridentRegs3C4[Threshold] = + (pReg->tridentRegs3C4[Threshold] & 0xf0) | 0x2; + + /* restore */ + if (pTrident->Chipset > PROVIDIA9685) { + OUTB(0x3C4, Protection); + OUTB(0x3C5, protect); + } + + if (pTrident->Chipset == CYBERBLADEXP4 || + pTrident->Chipset == XP5) + pReg->tridentRegs3CE[DisplayEngCont] = 0x08; + + /* Avoid lockup on Blade3D, PCI Retry is permanently on */ + if (pTrident->Chipset == BLADE3D) + pReg->tridentRegs3x4[PCIRetry] = 0x9F; + + return(TRUE); +} + +void +TridentRestore(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int vgaIOBase; + vgaIOBase = VGAHWPTR(pScrn)->IOBase; + + if (pTrident->Chipset > PROVIDIA9685) { + OUTB(0x3C4, Protection); + OUTB(0x3C5, 0x92); + } +#if 0 + if (pTrident->doInit && pTrident->Int10) { + OUTW_3CE(BiosReg); + } +#endif + /* Goto New Mode */ + OUTB(0x3C4, 0x0B); + (void) INB(0x3C5); + + /* Unprotect registers */ + OUTW(0x3C4, ((0xC0 ^ 0x02) << 8) | NewMode1); + + (void) INB(0x3C8); + (void) INB(0x3C6); + (void) INB(0x3C6); + (void) INB(0x3C6); + (void) INB(0x3C6); + OUTB(0x3C6, tridentReg->tridentRegsDAC[0x00]); + (void) INB(0x3C8); + + OUTW_3x4(CRTCModuleTest); + OUTW_3x4(LinearAddReg); + OUTW_3C4(NewMode2); + OUTW_3x4(CursorControl); + OUTW_3x4(CRTHiOrd); + OUTW_3x4(HorizOverflow); + OUTW_3x4(AddColReg); + OUTW_3x4(GraphEngReg); + OUTW_3x4(Performance); + OUTW_3x4(InterfaceSel); + OUTW_3x4(DRAMControl); + OUTW_3x4(PixelBusReg); + OUTW_3x4(PCIReg); + OUTW_3x4(PCIRetry); + OUTW_3CE(MiscIntContReg); + OUTW_3CE(MiscExtFunc); + OUTW_3x4(Offset); + if (pTrident->NewClockCode && pTrident->Chipset <= CYBER9397DVD) + OUTW_3x4(ClockControl); + if (pTrident->Chipset >= CYBER9388) { + OUTW_3C4(Threshold); + OUTW_3C4(SSetup); + OUTW_3C4(SKey); + OUTW_3C4(SPKey); + OUTW_3x4(PreEndControl); + OUTW_3x4(PreEndFetch); + OUTW_3C4(GBslope1); + OUTW_3C4(GBslope2); + OUTW_3C4(GBslope3); + OUTW_3C4(GBslope4); + OUTW_3C4(GBintercept1); + OUTW_3C4(GBintercept2); + OUTW_3C4(GBintercept3); + OUTW_3C4(GBintercept4); + } + if (pTrident->Chipset >= CYBER9385) OUTW_3x4(Enhancement0); + if (pTrident->Chipset >= BLADE3D) OUTW_3x4(RAMDACTiming); + if (pTrident->Chipset == CYBERBLADEXP4 || + pTrident->Chipset == XP5 || + pTrident->Chipset == CYBERBLADEE4) OUTW_3x4(New32); + if (pTrident->Chipset == CYBERBLADEXP4 || + pTrident->Chipset == XP5) OUTW_3CE(DisplayEngCont); + if (pTrident->IsCyber) { + CARD8 tmp; + + OUTW_3CE(VertStretch); + OUTW_3CE(HorStretch); + if (pTrident->Chipset < BLADEXP) { + OUTW_3CE(BiosMode); + } else { + OUTW_3CE(BiosNewMode1); + OUTW_3CE(BiosNewMode2); + }; + OUTW_3CE(BiosReg); + OUTW_3CE(FPConfig); + OUTW_3CE(CyberControl); + OUTW_3CE(CyberEnhance); + SHADOW_ENABLE(tmp); + OUTW_3x4(0x0); + if (pTrident->shadowNew) { + OUTW_3x4(0x1); + OUTW_3x4(0x2); + } + OUTW_3x4(0x3); + OUTW_3x4(0x4); + OUTW_3x4(0x5); + OUTW_3x4(0x6); + OUTW_3x4(0x7); + OUTW_3x4(0x10); + OUTW_3x4(0x11); + if (pTrident->shadowNew) { + OUTW_3x4(0x12); + OUTW_3x4(0x15); + } + OUTW_3x4(0x16); + SHADOW_RESTORE(tmp); + } + + if (Is3Dchip) { +#ifdef READOUT + if (!pTrident->DontSetClock) +#endif + { + OUTW(0x3C4, (tridentReg->tridentRegsClock[0x01])<<8 | ClockLow); + OUTW(0x3C4, (tridentReg->tridentRegsClock[0x02])<<8 | ClockHigh); + } + if (pTrident->MCLK > 0) { + OUTW(0x3C4,(tridentReg->tridentRegsClock[0x03])<<8 | MCLKLow); + OUTW(0x3C4,(tridentReg->tridentRegsClock[0x04])<<8 | MCLKHigh); + } + } else { +#ifdef READOUT + if (!pTrident->DontSetClock) +#endif + { + OUTB(0x43C8, tridentReg->tridentRegsClock[0x01]); + OUTB(0x43C9, tridentReg->tridentRegsClock[0x02]); + } + if (pTrident->MCLK > 0) { + OUTB(0x43C6, tridentReg->tridentRegsClock[0x03]); + OUTB(0x43C7, tridentReg->tridentRegsClock[0x04]); + } + } +#ifdef READOUT + if (!pTrident->DontSetClock) +#endif + { + OUTB(0x3C2, tridentReg->tridentRegsClock[0x00]); + } + + if (pTrident->Chipset > PROVIDIA9685) { + OUTB(0x3C4, Protection); + OUTB(0x3C5, tridentReg->tridentRegs3C4[Protection]); + } + + OUTW(0x3C4, ((tridentReg->tridentRegs3C4[NewMode1] ^ 0x02) << 8)| NewMode1); +} + +void +TridentSave(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int vgaIOBase; + vgaIOBase = VGAHWPTR(pScrn)->IOBase; + + /* Goto New Mode */ + OUTB(0x3C4, 0x0B); + (void) INB(0x3C5); + + INB_3C4(NewMode1); + if (pTrident->Chipset > PROVIDIA9685) + INB_3C4(Protection); + + /* Unprotect registers */ + OUTW(0x3C4, ((0xC0 ^ 0x02) << 8) | NewMode1); + if (pTrident->Chipset > PROVIDIA9685) + OUTW(0x3C4, (0x92 << 8) | Protection); + + INB_3x4(Offset); + INB_3x4(LinearAddReg); + INB_3x4(CRTCModuleTest); + INB_3x4(CRTHiOrd); + INB_3x4(HorizOverflow); + INB_3x4(Performance); + INB_3x4(InterfaceSel); + INB_3x4(DRAMControl); + INB_3x4(AddColReg); + INB_3x4(PixelBusReg); + INB_3x4(GraphEngReg); + INB_3x4(PCIReg); + INB_3x4(PCIRetry); + if (pTrident->NewClockCode && pTrident->Chipset <= CYBER9397DVD) + INB_3x4(ClockControl); + if (pTrident->Chipset >= CYBER9388) { + INB_3C4(Threshold); + INB_3C4(SSetup); + INB_3C4(SKey); + INB_3C4(SPKey); + INB_3x4(PreEndControl); + INB_3x4(PreEndFetch); + INB_3C4(GBslope1); + INB_3C4(GBslope2); + INB_3C4(GBslope3); + INB_3C4(GBslope4); + INB_3C4(GBintercept1); + INB_3C4(GBintercept2); + INB_3C4(GBintercept3); + INB_3C4(GBintercept4); + } + if (pTrident->Chipset >= CYBER9385) INB_3x4(Enhancement0); + if (pTrident->Chipset >= BLADE3D) INB_3x4(RAMDACTiming); + if (pTrident->Chipset == CYBERBLADEXP4 || + pTrident->Chipset == XP5 || + pTrident->Chipset == CYBERBLADEE4) INB_3x4(New32); + if (pTrident->Chipset == CYBERBLADEXP4 || + pTrident->Chipset == XP5) INB_3CE(DisplayEngCont); + if (pTrident->IsCyber) { + CARD8 tmp; + INB_3CE(VertStretch); + INB_3CE(HorStretch); + if (pTrident->Chipset < BLADEXP) { + INB_3CE(BiosMode); + } else { + INB_3CE(BiosNewMode1); + INB_3CE(BiosNewMode2); + } + INB_3CE(BiosReg); + INB_3CE(FPConfig); + INB_3CE(CyberControl); + INB_3CE(CyberEnhance); + SHADOW_ENABLE(tmp); + INB_3x4(0x0); + if (pTrident->shadowNew) { + INB_3x4(0x1); + INB_3x4(0x2); + } + INB_3x4(0x3); + INB_3x4(0x4); + INB_3x4(0x5); + INB_3x4(0x6); + INB_3x4(0x7); + INB_3x4(0x10); + INB_3x4(0x11); + if (pTrident->shadowNew) { + INB_3x4(0x12); + INB_3x4(0x15); + } + INB_3x4(0x16); + SHADOW_RESTORE(tmp); + } + + /* save cursor registers */ + INB_3x4(CursorControl); + + INB_3CE(MiscExtFunc); + INB_3CE(MiscIntContReg); + + (void) INB(0x3C8); + (void) INB(0x3C6); + (void) INB(0x3C6); + (void) INB(0x3C6); + (void) INB(0x3C6); + tridentReg->tridentRegsDAC[0x00] = INB(0x3C6); + (void) INB(0x3C8); + + tridentReg->tridentRegsClock[0x00] = INB(0x3CC); + if (Is3Dchip) { + OUTB(0x3C4, ClockLow); + tridentReg->tridentRegsClock[0x01] = INB(0x3C5); + OUTB(0x3C4, ClockHigh); + tridentReg->tridentRegsClock[0x02] = INB(0x3C5); + if (pTrident->MCLK > 0) { + OUTB(0x3C4, MCLKLow); + tridentReg->tridentRegsClock[0x03] = INB(0x3C5); + OUTB(0x3C4, MCLKHigh); + tridentReg->tridentRegsClock[0x04] = INB(0x3C5); + } + } else { + tridentReg->tridentRegsClock[0x01] = INB(0x43C8); + tridentReg->tridentRegsClock[0x02] = INB(0x43C9); + if (pTrident->MCLK > 0) { + tridentReg->tridentRegsClock[0x03] = INB(0x43C6); + tridentReg->tridentRegsClock[0x04] = INB(0x43C7); + } + } + + INB_3C4(NewMode2); + + /* Protect registers */ + OUTW_3C4(NewMode1); +} + +static void +TridentShowCursor(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int vgaIOBase; + vgaIOBase = VGAHWPTR(pScrn)->IOBase; + + /* 64x64 */ + OUTW(vgaIOBase + 4, 0xC150); +} + +static void +TridentHideCursor(ScrnInfoPtr pScrn) { + int vgaIOBase; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + vgaIOBase = VGAHWPTR(pScrn)->IOBase; + + OUTW(vgaIOBase + 4, 0x4150); +} + +static void +TridentSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) +{ + int vgaIOBase; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + vgaIOBase = VGAHWPTR(pScrn)->IOBase; + + if (x < 0) { + OUTW(vgaIOBase + 4, (-x)<<8 | 0x46); + x = 0; + } else + OUTW(vgaIOBase + 4, 0x0046); + + if (y < 0) { + OUTW(vgaIOBase + 4, (-y)<<8 | 0x47); + y = 0; + } else + OUTW(vgaIOBase + 4, 0x0047); + + OUTW(vgaIOBase + 4, (x&0xFF)<<8 | 0x40); + OUTW(vgaIOBase + 4, (x&0x0F00) | 0x41); + OUTW(vgaIOBase + 4, (y&0xFF)<<8 | 0x42); + OUTW(vgaIOBase + 4, (y&0x0F00) | 0x43); +} + +static void +TridentSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) +{ + int vgaIOBase; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + vgaIOBase = VGAHWPTR(pScrn)->IOBase; + OUTW(vgaIOBase + 4, (fg & 0x000000FF)<<8 | 0x48); + OUTW(vgaIOBase + 4, (fg & 0x0000FF00) | 0x49); + OUTW(vgaIOBase + 4, (fg & 0x00FF0000)>>8 | 0x4A); + OUTW(vgaIOBase + 4, (fg & 0xFF000000)>>16 | 0x4B); + OUTW(vgaIOBase + 4, (bg & 0x000000FF)<<8 | 0x4C); + OUTW(vgaIOBase + 4, (bg & 0x0000FF00) | 0x4D); + OUTW(vgaIOBase + 4, (bg & 0x00FF0000)>>8 | 0x4E); + OUTW(vgaIOBase + 4, (bg & 0xFF000000)>>16 | 0x4F); +} + +static void +TridentLoadCursorImage( + ScrnInfoPtr pScrn, + CARD8 *src +) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int vgaIOBase; + int programmed_offset = pTrident->CursorOffset / 1024; + vgaIOBase = VGAHWPTR(pScrn)->IOBase; + + memcpy((CARD8 *)pTrident->FbBase + pTrident->CursorOffset, + src, pTrident->CursorInfoRec->MaxWidth * + pTrident->CursorInfoRec->MaxHeight / 4); + + OUTW(vgaIOBase + 4, ((programmed_offset & 0xFF) << 8) | 0x44); + OUTW(vgaIOBase + 4, (programmed_offset & 0xFF00) | 0x45); +} + +static Bool +TridentUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + if (pTrident->MUX && pScrn->bitsPerPixel == 8) return FALSE; + + if (!pTrident->HWCursor) return FALSE; + + return TRUE; +} + +#define CURSOR_WIDTH 64 +#define CURSOR_HEIGHT 64 +#define CURSOR_ALIGN(x,bytes) (((x) + ((bytes) - 1)) & ~((bytes) - 1)) + +Bool +TridentHWCursorInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + xf86CursorInfoPtr infoPtr; + FBAreaPtr fbarea; + int width; + int width_bytes; + int height; + int size_bytes; + + size_bytes = CURSOR_WIDTH * 4 * CURSOR_HEIGHT; + width = pScrn->displayWidth; + width_bytes = width * (pScrn->bitsPerPixel / 8); + height = (size_bytes + width_bytes - 1) / width_bytes; + fbarea = xf86AllocateOffscreenArea(pScreen, + width, + height, + 1024, + NULL, + NULL, + NULL); + + if (!fbarea) { + pTrident->CursorOffset = 0; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Hardware cursor disabled" + " due to insufficient offscreen memory\n"); + return FALSE; + } else { + pTrident->CursorOffset = CURSOR_ALIGN((fbarea->box.x1 + + fbarea->box.y1 * width) * + pScrn->bitsPerPixel / 8, + 1024); + } + + if ((pTrident->Chipset != CYBER9397DVD) && + (pTrident->Chipset < CYBERBLADEE4)) { + /* Can't deal with an offset more than 4MB - 4096 bytes */ + if (pTrident->CursorOffset >= ((4096*1024) - 4096)) { + pTrident->CursorOffset = 0; + xf86FreeOffscreenArea(fbarea); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Hardware cursor disabled" + " due to cursor offset constraints.\n"); + return FALSE; + } + } + + infoPtr = xf86CreateCursorInfoRec(); + if(!infoPtr) return FALSE; + + pTrident->CursorInfoRec = infoPtr; + + infoPtr->MaxWidth = 64; + infoPtr->MaxHeight = 64; + infoPtr->Flags = HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | + HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK | + HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 | + ((pTrident->Chipset == CYBERBLADEXP4 || + pTrident->Chipset == BLADEXP || + pTrident->Chipset == XP5 || + pTrident->Chipset == CYBERBLADEE4) ? + HARDWARE_CURSOR_TRUECOLOR_AT_8BPP : 0); + infoPtr->SetCursorColors = TridentSetCursorColors; + infoPtr->SetCursorPosition = TridentSetCursorPosition; + infoPtr->LoadCursorImage = TridentLoadCursorImage; + infoPtr->HideCursor = TridentHideCursor; + infoPtr->ShowCursor = TridentShowCursor; + infoPtr->UseHWCursor = TridentUseHWCursor; + + return(xf86InitCursor(pScreen, infoPtr)); +} + +unsigned int +Tridentddc1Read(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int vgaIOBase = VGAHWPTR(pScrn)->IOBase; + CARD8 temp; + + /* New mode */ + OUTB(0x3C4, 0x0B); temp = INB(0x3C5); + + OUTB(0x3C4, NewMode1); + temp = INB(0x3C5); + OUTB(0x3C5, temp | 0x80); + + /* Define SDA as input */ + OUTW(vgaIOBase + 4, (0x04 << 8) | I2C); + + OUTW(0x3C4, (temp << 8) | NewMode1); + + /* Wait until vertical retrace is in progress. */ + while (INB(vgaIOBase + 0xA) & 0x08); + while (!(INB(vgaIOBase + 0xA) & 0x08)); + + /* Get the result */ + OUTB(vgaIOBase + 4, I2C); + return ( INB(vgaIOBase + 5) & 0x01 ); +} + +void TridentSetOverscan( + ScrnInfoPtr pScrn, + int overscan +){ + vgaHWPtr hwp = VGAHWPTR(pScrn); + + if (overscan < 0 || overscan > 255) + return; + + hwp->enablePalette(hwp); + hwp->writeAttr(hwp, OVERSCAN, overscan); + hwp->disablePalette(hwp); +} + +void TridentLoadPalette( + ScrnInfoPtr pScrn, + int numColors, + int *indicies, + LOCO *colors, + VisualPtr pVisual +){ + vgaHWPtr hwp = VGAHWPTR(pScrn); + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int i, index; + for(i = 0; i < numColors; i++) { + index = indicies[i]; + OUTB(0x3C6, 0xFF); + DACDelay(hwp); + OUTB(0x3c8, index); + DACDelay(hwp); + OUTB(0x3c9, colors[index].red); + DACDelay(hwp); + OUTB(0x3c9, colors[index].green); + DACDelay(hwp); + OUTB(0x3c9, colors[index].blue); + DACDelay(hwp); + } +} diff --git a/driver/xf86-video-trident/src/trident_dga.c b/driver/xf86-video-trident/src/trident_dga.c new file mode 100644 index 000000000..b91ee744a --- /dev/null +++ b/driver/xf86-video-trident/src/trident_dga.c @@ -0,0 +1,301 @@ +/* + * Copyright 1997-2003 by Alan Hourihane, North Wales, UK. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_dga.c,v 1.4 2002/10/08 22:14:11 tsi Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Pci.h" +#include "xf86PciInfo.h" +#include "xaa.h" +#include "xaalocal.h" +#include "trident.h" +#include "trident_regs.h" +#include "dgaproc.h" + + +static Bool TRIDENT_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, + int *, int *, int *); +static Bool TRIDENT_SetMode(ScrnInfoPtr, DGAModePtr); +static void TRIDENT_Sync(ScrnInfoPtr); +static int TRIDENT_GetViewport(ScrnInfoPtr); +static void TRIDENT_SetViewport(ScrnInfoPtr, int, int, int); +static void TRIDENT_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); +static void TRIDENT_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); +#if 0 +static void TRIDENT_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, + unsigned long); +#endif + +static +DGAFunctionRec TRIDENTDGAFuncs = { + TRIDENT_OpenFramebuffer, + NULL, + TRIDENT_SetMode, + TRIDENT_SetViewport, + TRIDENT_GetViewport, + TRIDENT_Sync, + TRIDENT_FillRect, + TRIDENT_BlitRect, +#if 0 + TRIDENT_BlitTransRect +#else + NULL +#endif +}; + +Bool +TRIDENTDGAInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + DGAModePtr modes = NULL, newmodes = NULL, currentMode; + DisplayModePtr pMode, firstMode; + int Bpp = pScrn->bitsPerPixel >> 3; + int num = 0; + Bool oneMore; + + pMode = firstMode = pScrn->modes; + + while(pMode) { + + if(0 /*pScrn->displayWidth != pMode->HDisplay*/) { + newmodes = xrealloc(modes, (num + 2) * sizeof(DGAModeRec)); + oneMore = TRUE; + } else { + newmodes = xrealloc(modes, (num + 1) * sizeof(DGAModeRec)); + oneMore = FALSE; + } + + if(!newmodes) { + xfree(modes); + return FALSE; + } + modes = newmodes; + +SECOND_PASS: + + currentMode = modes + num; + num++; + + currentMode->mode = pMode; + currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; + if(!pTrident->NoAccel) + currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; + if(pMode->Flags & V_DBLSCAN) + currentMode->flags |= DGA_DOUBLESCAN; + if(pMode->Flags & V_INTERLACE) + currentMode->flags |= DGA_INTERLACED; + currentMode->byteOrder = pScrn->imageByteOrder; + currentMode->depth = pScrn->depth; + currentMode->bitsPerPixel = pScrn->bitsPerPixel; + currentMode->red_mask = pScrn->mask.red; + currentMode->green_mask = pScrn->mask.green; + currentMode->blue_mask = pScrn->mask.blue; + currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor; + currentMode->viewportWidth = pMode->HDisplay; + currentMode->viewportHeight = pMode->VDisplay; + currentMode->xViewportStep = 1; + currentMode->yViewportStep = 1; + currentMode->viewportFlags = DGA_FLIP_RETRACE; + currentMode->offset = 0; + currentMode->address = pTrident->FbBase; + + if(oneMore) { /* first one is narrow width */ + currentMode->bytesPerScanline = ((pMode->HDisplay * Bpp) + 3) & ~3L; + currentMode->imageWidth = pMode->HDisplay; + currentMode->imageHeight = pMode->VDisplay; + currentMode->pixmapWidth = currentMode->imageWidth; + currentMode->pixmapHeight = currentMode->imageHeight; + currentMode->maxViewportX = currentMode->imageWidth - + currentMode->viewportWidth; + /* this might need to get clamped to some maximum */ + currentMode->maxViewportY = currentMode->imageHeight - + currentMode->viewportHeight; + oneMore = FALSE; + goto SECOND_PASS; + } else { + currentMode->bytesPerScanline = + ((pScrn->displayWidth * Bpp) + 3) & ~3L; + currentMode->imageWidth = pScrn->displayWidth; + currentMode->imageHeight = pMode->VDisplay; + currentMode->pixmapWidth = currentMode->imageWidth; + currentMode->pixmapHeight = currentMode->imageHeight; + currentMode->maxViewportX = currentMode->imageWidth - + currentMode->viewportWidth; + /* this might need to get clamped to some maximum */ + currentMode->maxViewportY = currentMode->imageHeight - + currentMode->viewportHeight; + } + + pMode = pMode->next; + if(pMode == firstMode) + break; + } + + pTrident->numDGAModes = num; + pTrident->DGAModes = modes; + + return DGAInit(pScreen, &TRIDENTDGAFuncs, modes, num); +} + + +static Bool +TRIDENT_SetMode( + ScrnInfoPtr pScrn, + DGAModePtr pMode +){ + static int OldDisplayWidth[MAXSCREENS]; + int index = pScrn->pScreen->myNum; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + if(!pMode) { /* restore the original mode */ + /* put the ScreenParameters back */ + + pScrn->displayWidth = OldDisplayWidth[index]; + + TRIDENTSwitchMode(index, pScrn->currentMode, 0); + pTrident->DGAactive = FALSE; + } else { + if(!pTrident->DGAactive) { /* save the old parameters */ + OldDisplayWidth[index] = pScrn->displayWidth; + + pTrident->DGAactive = TRUE; + } + + pScrn->displayWidth = pMode->bytesPerScanline / + (pMode->bitsPerPixel >> 3); + + TRIDENTSwitchMode(index, pMode->mode, 0); + } + + return TRUE; +} + + + +static int +TRIDENT_GetViewport( + ScrnInfoPtr pScrn +){ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + return pTrident->DGAViewportStatus; +} + +static void +TRIDENT_SetViewport( + ScrnInfoPtr pScrn, + int x, int y, + int flags +){ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + TRIDENTAdjustFrame(pScrn->pScreen->myNum, x, y, flags); + pTrident->DGAViewportStatus = 0; /* TRIDENTAdjustFrame loops until finished */ +} + +static void +TRIDENT_FillRect ( + ScrnInfoPtr pScrn, + int x, int y, int w, int h, + unsigned long color +){ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + if(pTrident->AccelInfoRec) { + (*pTrident->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0); + (*pTrident->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h); + SET_SYNC_FLAG(pTrident->AccelInfoRec); + } +} + +static void +TRIDENT_Sync( + ScrnInfoPtr pScrn +){ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + if(pTrident->AccelInfoRec) { + (*pTrident->AccelInfoRec->Sync)(pScrn); + } +} + +static void +TRIDENT_BlitRect( + ScrnInfoPtr pScrn, + int srcx, int srcy, + int w, int h, + int dstx, int dsty +){ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + if(pTrident->AccelInfoRec) { + int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; + int ydir = (srcy < dsty) ? -1 : 1; + + (*pTrident->AccelInfoRec->SetupForScreenToScreenCopy)( + pScrn, xdir, ydir, GXcopy, ~0, -1); + (*pTrident->AccelInfoRec->SubsequentScreenToScreenCopy)( + pScrn, srcx, srcy, dstx, dsty, w, h); + SET_SYNC_FLAG(pTrident->AccelInfoRec); + } +} + +#if 0 +static void +TRIDENT_BlitTransRect( + ScrnInfoPtr pScrn, + int srcx, int srcy, + int w, int h, + int dstx, int dsty, + unsigned long color +){ + /* this one should be separate since the XAA function would + prohibit usage of ~0 as the key */ +} +#endif + +static Bool +TRIDENT_OpenFramebuffer( + ScrnInfoPtr pScrn, + char **name, + unsigned char **mem, + int *size, + int *offset, + int *flags +){ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + *name = NULL; /* no special device */ + *mem = (unsigned char*)pTrident->FbAddress; + *size = pTrident->FbMapSize; + *offset = 0; + *flags = DGA_NEED_ROOT; + + return TRUE; +} diff --git a/driver/xf86-video-trident/src/trident_driver.c b/driver/xf86-video-trident/src/trident_driver.c new file mode 100644 index 000000000..f472579a2 --- /dev/null +++ b/driver/xf86-video-trident/src/trident_driver.c @@ -0,0 +1,3763 @@ +/* + * Copyright 1992-2003 by Alan Hourihane, North Wales, UK. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Alan Hourihane, alanh@fairlite.demon.co.uk + * Re-written for XFree86 v4.0 + * + * Previous driver (pre-XFree86 v4.0) by + * Alan Hourihane, alanh@fairlite.demon.co.uk + * David Wexelblat (major contributor) + * Massimiliano Ghilardi, max@Linuz.sns.it, some fixes to the + * clockchip programming code. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_driver.c,v 1.190 2004/01/21 22:31:54 alanh Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "fb.h" + +#include "mibank.h" +#include "micmap.h" +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "xf86Version.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "xf86cmap.h" +#include "vgaHW.h" +#include "xf86RAC.h" +#include "vbe.h" +#include "dixstruct.h" +#include "compiler.h" + +#include "mipointer.h" + +#include "mibstore.h" +#include "shadow.h" +#include "trident.h" +#include "trident_regs.h" + +#ifdef XFreeXDGA +#define _XF86DGA_SERVER_ +#include <X11/extensions/xf86dgastr.h> +#endif + +#include "globals.h" +#define DPMS_SERVER +#include <X11/extensions/dpms.h> + +#include "xf86xv.h" + +static const OptionInfoRec * TRIDENTAvailableOptions(int chipid, int busid); +static void TRIDENTIdentify(int flags); +static Bool TRIDENTProbe(DriverPtr drv, int flags); +static Bool TRIDENTPreInit(ScrnInfoPtr pScrn, int flags); +static Bool TRIDENTScreenInit(int Index, ScreenPtr pScreen, int argc, + char **argv); +static Bool TRIDENTEnterVT(int scrnIndex, int flags); +static void TRIDENTLeaveVT(int scrnIndex, int flags); +static Bool TRIDENTCloseScreen(int scrnIndex, ScreenPtr pScreen); +static Bool TRIDENTSaveScreen(ScreenPtr pScreen, int mode); + +/* Optional functions */ +static void TRIDENTFreeScreen(int scrnIndex, int flags); +static ModeStatus TRIDENTValidMode(int scrnIndex, DisplayModePtr mode, + Bool verbose, int flags); + +/* Internally used functions */ +static Bool TRIDENTMapMem(ScrnInfoPtr pScrn); +static Bool TRIDENTUnmapMem(ScrnInfoPtr pScrn); +static void TRIDENTSave(ScrnInfoPtr pScrn); +static void TRIDENTRestore(ScrnInfoPtr pScrn); +static Bool TRIDENTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); +static void TRIDENTBlockHandler(int, pointer, pointer, pointer); + +static void TRIDENTEnableMMIO(ScrnInfoPtr pScrn); +static void TRIDENTDisableMMIO(ScrnInfoPtr pScrn); +static void PC98TRIDENTInit(ScrnInfoPtr pScrn); +static void PC98TRIDENTEnable(ScrnInfoPtr pScrn); +static void PC98TRIDENTDisable(ScrnInfoPtr pScrn); +static void PC98TRIDENT96xxInit(ScrnInfoPtr pScrn); +static void PC98TRIDENT96xxEnable(ScrnInfoPtr pScrn); +static void PC98TRIDENT96xxDisable(ScrnInfoPtr pScrn); +static void PC98TRIDENT9385Init(ScrnInfoPtr pScrn); +static void PC98TRIDENT9385Enable(ScrnInfoPtr pScrn); +static void PC98TRIDENT9385Disable(ScrnInfoPtr pScrn); +static int TRIDENTLcdDisplaySize (xf86MonPtr pMon); + +/* + * This is intentionally screen-independent. It indicates the binding + * choice made in the first PreInit. + */ +static int pix24bpp = 0; + +#define TRIDENT_VERSION 4000 +#define TRIDENT_NAME "TRIDENT" +#define TRIDENT_DRIVER_NAME "trident" +#define TRIDENT_MAJOR_VERSION 1 +#define TRIDENT_MINOR_VERSION 2 +#define TRIDENT_PATCHLEVEL 3 + +/* + * This contains the functions needed by the server after loading the driver + * module. It must be supplied, and gets passed back by the SetupProc + * function in the dynamic case. In the static case, a reference to this + * is compiled in, and this requires that the name of this DriverRec be + * an upper-case version of the driver name. + */ + +_X_EXPORT DriverRec TRIDENT = { + TRIDENT_VERSION, + TRIDENT_DRIVER_NAME, + TRIDENTIdentify, + TRIDENTProbe, + TRIDENTAvailableOptions, + NULL, + 0 +}; + +static SymTabRec TRIDENTChipsets[] = { + { TVGA9000, "tvga9000" }, + { TVGA9000i, "tvga9000i" }, + { TVGA8900C, "tvga8900c" }, + { TVGA8900D, "tvga8900d" }, + { TVGA9200CXr, "tvga9200cxr" }, + { TGUI9400CXi, "tgui9400cxi" }, + { CYBER9320, "cyber9320" }, + { CYBER9388, "cyber9388" }, + { CYBER9397, "cyber9397" }, + { CYBER9397DVD, "cyber9397dvd" }, + { CYBER9520, "cyber9520" }, + { CYBER9525DVD, "cyber9525dvd" }, + { CYBERBLADEE4, "cyberblade/e4" }, + { TGUI9420DGi, "tgui9420dgi" }, + { TGUI9440AGi, "tgui9440agi" }, + { TGUI9660, "tgui9660" }, + { TGUI9680, "tgui9680" }, + { PROVIDIA9682, "providia9682" }, + { PROVIDIA9685, "providia9685" }, + { CYBER9382, "cyber9382" }, + { CYBER9385, "cyber9385" }, + { IMAGE975, "3dimage975" }, + { IMAGE985, "3dimage985" }, + { BLADE3D, "blade3d" }, + { CYBERBLADEI7, "cyberbladei7" }, + { CYBERBLADEI7D, "cyberbladei7d" }, + { CYBERBLADEI1, "cyberbladei1" }, + { CYBERBLADEI1D, "cyberbladei1d" }, + { CYBERBLADEAI1, "cyberbladeAi1" }, + { CYBERBLADEAI1D, "cyberbladeAi1d" }, + { BLADEXP, "bladeXP" }, + { CYBERBLADEXPAI1, "cyberbladeXPAi1" }, + { CYBERBLADEXP4, "cyberbladeXP4" }, + { XP5, "XP5" }, + { -1, NULL } +}; + +static IsaChipsets TRIDENTISAchipsets[] = { + { TVGA9000, RES_EXCLUSIVE_VGA }, + { TVGA9000i, RES_EXCLUSIVE_VGA }, + { TVGA8900C, RES_EXCLUSIVE_VGA }, + { TVGA8900D, RES_EXCLUSIVE_VGA }, + { TVGA9200CXr, RES_EXCLUSIVE_VGA }, + { TGUI9400CXi, RES_EXCLUSIVE_VGA }, + { CYBER9320, RES_EXCLUSIVE_VGA }, + { TGUI9440AGi, RES_EXCLUSIVE_VGA }, + { -1, RES_UNDEFINED } +}; + +static PciChipsets TRIDENTPciChipsets[] = { + { CYBER9320, PCI_CHIP_9320, RES_SHARED_VGA }, + { CYBER9388, PCI_CHIP_9388, RES_SHARED_VGA }, + { CYBER9397, PCI_CHIP_9397, RES_SHARED_VGA }, + { CYBER9397DVD, PCI_CHIP_939A, RES_SHARED_VGA }, + { CYBER9520, PCI_CHIP_9520, RES_SHARED_VGA }, + { CYBER9525DVD, PCI_CHIP_9525, RES_SHARED_VGA }, + { CYBERBLADEE4, PCI_CHIP_9540, RES_SHARED_VGA }, + { TGUI9420DGi, PCI_CHIP_9420, RES_SHARED_VGA }, + { TGUI9440AGi, PCI_CHIP_9440, RES_SHARED_VGA }, + { TGUI9660, PCI_CHIP_9660, RES_SHARED_VGA }, + { TGUI9680, PCI_CHIP_9660, RES_SHARED_VGA }, + { PROVIDIA9682, PCI_CHIP_9660, RES_SHARED_VGA }, + { PROVIDIA9685, PCI_CHIP_9660, RES_SHARED_VGA }, + { CYBER9382, PCI_CHIP_9660, RES_SHARED_VGA }, + { CYBER9385, PCI_CHIP_9660, RES_SHARED_VGA }, + { IMAGE975, PCI_CHIP_9750, RES_SHARED_VGA }, + { IMAGE985, PCI_CHIP_9850, RES_SHARED_VGA }, + { BLADE3D, PCI_CHIP_9880, RES_SHARED_VGA }, + { CYBERBLADEI7, PCI_CHIP_8400, RES_SHARED_VGA }, + { CYBERBLADEI7D, PCI_CHIP_8420, RES_SHARED_VGA }, + { CYBERBLADEI1, PCI_CHIP_8500, RES_SHARED_VGA }, + { CYBERBLADEI1D, PCI_CHIP_8520, RES_SHARED_VGA }, + { CYBERBLADEAI1, PCI_CHIP_8600, RES_SHARED_VGA }, + { CYBERBLADEAI1D, PCI_CHIP_8620, RES_SHARED_VGA }, + { BLADEXP, PCI_CHIP_9910, RES_SHARED_VGA }, + { CYBERBLADEXPAI1, PCI_CHIP_8820, RES_SHARED_VGA }, + { CYBERBLADEXP4, PCI_CHIP_2100, RES_SHARED_VGA }, + { XP5, PCI_CHIP_2200, RES_SHARED_VGA }, + { -1, -1, RES_UNDEFINED } +}; + +typedef enum { + OPTION_ACCELMETHOD, + OPTION_SW_CURSOR, + OPTION_PCI_RETRY, + OPTION_RGB_BITS, + OPTION_NOACCEL, + OPTION_SETMCLK, + OPTION_MUX_THRESHOLD, + OPTION_SHADOW_FB, + OPTION_ROTATE, + OPTION_MMIO_ONLY, + OPTION_VIDEO_KEY, + OPTION_NOMMIO, + OPTION_NOPCIBURST, + OPTION_CYBER_SHADOW, + OPTION_CYBER_STRETCH, + OPTION_XV_HSYNC, + OPTION_XV_VSYNC, + OPTION_XV_BSKEW, + OPTION_XV_RSKEW, + OPTION_FP_DELAY, + OPTION_1400_DISPLAY, + OPTION_DISPLAY, + OPTION_GB, + OPTION_TV_CHIPSET, + OPTION_TV_SIGNALMODE +} TRIDENTOpts; + +static const OptionInfoRec TRIDENTOptions[] = { + { OPTION_ACCELMETHOD, "AccelMethod", OPTV_ANYSTR, {0}, FALSE }, + { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_PCI_RETRY, "PciRetry", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_SETMCLK, "SetMClk", OPTV_FREQ, {0}, FALSE }, + { OPTION_MUX_THRESHOLD, "MUXThreshold", OPTV_INTEGER, {0}, FALSE }, + { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE }, + { OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE }, + { OPTION_NOMMIO, "NoMMIO", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_NOPCIBURST, "NoPciBurst", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_MMIO_ONLY, "MMIOonly", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_CYBER_SHADOW, "CyberShadow", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_CYBER_STRETCH, "CyberStretch", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_XV_HSYNC, "XvHsync", OPTV_INTEGER, {0}, FALSE }, + { OPTION_XV_VSYNC, "XvVsync", OPTV_INTEGER, {0}, FALSE }, + { OPTION_XV_BSKEW, "XvBskew", OPTV_INTEGER, {0}, FALSE }, + { OPTION_XV_RSKEW, "XvRskew", OPTV_INTEGER, {0}, FALSE }, + { OPTION_FP_DELAY, "FpDelay", OPTV_INTEGER, {0}, FALSE }, + { OPTION_1400_DISPLAY, "Display1400", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_DISPLAY, "Display", OPTV_ANYSTR, {0}, FALSE }, + { OPTION_GB, "GammaBrightness", OPTV_ANYSTR, {0}, FALSE }, + { OPTION_TV_CHIPSET, "TVChipset", OPTV_ANYSTR, {0}, FALSE }, + { OPTION_TV_SIGNALMODE, "TVSignal", OPTV_INTEGER, {0}, FALSE }, + { -1, NULL, OPTV_NONE, {0}, FALSE } +}; + +/* Clock Limits */ +static int ClockLimit[] = { + 80000, + 80000, + 80000, + 80000, + 80000, + 80000, + 80000, + 80000, + 80000, + 80000, + 80000, + 80000, + 80000, + 80000, + 90000, + 90000, + 135000, + 135000, + 170000, + 170000, + 170000, + 170000, + 170000, + 170000, + 170000, + 230000, + 230000, + 230000, + 230000, + 230000, + 230000, + 230000, + 230000, + 230000, + 230000, + 230000, + 230000, + 230000, + 230000, + 230000, + 230000, +}; + +static int ClockLimit16bpp[] = { + 40000, + 40000, + 40000, + 40000, + 40000, + 40000, + 40000, + 40000, + 40000, + 40000, + 40000, + 40000, + 40000, + 40000, + 45000, + 45000, + 90000, + 90000, + 135000, + 135000, + 170000, + 170000, + 170000, + 170000, + 170000, + 230000, + 230000, + 230000, + 230000, + 230000, + 230000, + 230000, + 230000, + 230000, + 230000, + 230000, + 230000, + 230000, + 230000, + 230000, + 230000, +}; + +static int ClockLimit24bpp[] = { + 25180, + 25180, + 25180, + 25180, + 25180, + 25180, + 25180, + 25180, + 25180, + 25180, + 25180, + 25180, + 25180, + 25180, + 25180, + 25180, + 40000, + 40000, + 70000, + 70000, + 70000, + 115000, + 115000, + 115000, + 115000, + 115000, + 115000, + 115000, + 115000, + 115000, + 115000, + 115000, + 115000, + 115000, + 115000, + 115000, + 115000, + 115000, + 115000, + 115000, + 115000, +}; + +static int ClockLimit32bpp[] = { + 25180, + 25180, + 25180, + 25180, + 25180, + 25180, + 25180, + 25180, + 25180, + 25180, + 25180, + 25180, + 25180, + 25180, + 25180, + 25180, + 40000, + 40000, + 70000, + 70000, + 70000, + 115000, + 115000, + 115000, + 115000, + 115000, + 115000, + 115000, + 115000, + 115000, + 115000, + 115000, + 115000, + 115000, + 115000, + 115000, + 115000, + 115000, + 115000, + 115000, + 115000, + 115000, +}; + +/* + * These are fixed modelines for all physical display dimensions the + * chipsets supports on FPs. Most of them are not tested yet. + */ +#if 0 +tridentLCD LCD[] = { /* 0 3 4 5 6 7 10 11 16 */ + { 0,"640x480",25200,0x5f,0x82,0x54,0x80,0xb,0x3e,0xea,0x8c,0xb,0x08}, + { 1,"800x600",40000,0x7f,0x99,0x69,0x99,0x72,0xf0,0x59,0x2d,0x5e,0x08}, + { 2,"1024x768",65000,0xa3,/*0x6*/ 0x98,0x8f,0xa0,0x24,0xf5,0x0f,0x25,0x96,0x08}, + { 3,"1024x768",65000,0xa3,/*0x6*/ 0x98,0x8f,0xa0,0x24,0xf5,0x0f,0x25,0x96,0x08}, /*0x96*/ + { 4,"1280x1024",108000,0xa3,0x6,0x8f,0xa0,0x24,0xf5,0x0f,0x25,0x96,0x08}, + { 5,"1024x600",50500 ,0xa3,0x6,0x8f,0xa0,0xb,0x3e,0xea,0x8c,0xb,0x08}, + { 0xff,"", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } +}; +#else +#if 0 +tridentLCD LCD[] = { + { 1,640,480,25200,0x5f,0x82,0x54,0x80,0xb,0x3e,0xea,0x8c,0xb,0x08}, + { 3,800,600,40000,0x7f,0x82,0x6b,0x1b,0x72,0xf8,0x58,0x8c,0x72,0x08}, + { 2,1024,768,65000,0xa3,/*0x6*/0x98,0x8f,0xa0,0x24,0xf5,0x0f,0x24,0x0a,0x08}, + { 0,1280,1024,108000,0xce,0x81,0xa6,0x9a,0x27,0x50,0x00,0x03,0x26,0xa8}, + { 0xff,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } +}; +#else +tridentLCD LCD[] = { + { 1,640,480,25200,0x5f,0x80,0x52,0x1e,0xb,0x3e,0xea,0x0c,0xb,0x08}, + { 3,800,600,40000,0x7f,0x00,0x69,0x7f,0x72,0xf0,0x59,0x0d,0x00,0x08}, + { 2,1024,768,65000,0xa3,0x00,0x84,0x94,0x24,0xf5,0x03,0x09,0x24,0x08}, + { 0,1280,1024,108000,0xce,0x91,0xa6,0x14,0x28,0x5a,0x01,0x04,0x28,0xa8}, + { 4,1400,1050,122000,0xe6,0x8d,0xba,0x1d,0x38,0x00,0x1c,0x28,0x28,0xf8}, + { 0xff,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } +}; +#endif +#endif + +static const char *xaaSymbols[] = { + "XAAGetCopyROP", + "XAACreateInfoRec", + "XAADestroyInfoRec", + "XAAInit", + "XAAGetPatternROP", + NULL +}; + +const char *exaSymbols[] = { + "exaDriverAlloc", + "exaDriverInit", + "exaDriverFini", + "exaOffscreenAlloc", + "exaOffscreenFree", + NULL +}; + +static const char *vgahwSymbols[] = { + "vgaHWBlankScreenWeak", + "vgaHWFreeHWRec", + "vgaHWGetHWRec", + "vgaHWGetIOBase", + "vgaHWGetIndex", + "vgaHWInit", + "vgaHWLock", + "vgaHWMapMem", + "vgaHWProtectWeak", + "vgaHWRestore", + "vgaHWSave", + "vgaHWSaveScreen", + "vgaHWSetMmioFuncs", + "vgaHWUnlock", + NULL +}; + +static const char *fbSymbols[] = { + "fbPictureInit", + "fbScreenInit", + NULL +}; + +static const char *ramdacSymbols[] = { + "xf86CreateCursorInfoRec", + "xf86DestroyCursorInfoRec", + "xf86InitCursor", + NULL +}; + +static const char *ddcSymbols[] = { + "xf86PrintEDID", + "xf86SetDDCproperties", + NULL +}; + +static const char *i2cSymbols[] = { + "xf86CreateI2CBusRec", + "xf86I2CBusInit", + NULL +}; + +static const char *int10Symbols[] = { + "xf86ExecX86int10", + "xf86FreeInt10", + "xf86InitInt10", + NULL +}; + +static const char *shadowSymbols[] = { + "shadowInit", + NULL +}; + +static const char *vbeSymbols[] = { + "VBEInit", + "vbeDoEDID", + "vbeFree", + NULL +}; + +#ifdef XFree86LOADER + +static MODULESETUPPROTO(tridentSetup); + +static XF86ModuleVersionInfo tridentVersRec = +{ + "trident", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XORG_VERSION_CURRENT, + TRIDENT_MAJOR_VERSION, TRIDENT_MINOR_VERSION, TRIDENT_PATCHLEVEL, + ABI_CLASS_VIDEODRV, /* This is a video driver */ + ABI_VIDEODRV_VERSION, + MOD_CLASS_VIDEODRV, + {0,0,0,0} +}; + +_X_EXPORT XF86ModuleData tridentModuleData = { + &tridentVersRec, + tridentSetup, + NULL +}; + +pointer +tridentSetup(pointer module, pointer opts, int *errmaj, int *errmin) +{ + static Bool setupDone = FALSE; + + if (!setupDone) { + setupDone = TRUE; + xf86AddDriver(&TRIDENT, module, 0); + LoaderRefSymLists(vgahwSymbols, fbSymbols, i2cSymbols, vbeSymbols, + ramdacSymbols, int10Symbols, + xaaSymbols, exaSymbols, shadowSymbols, NULL); + return (pointer)TRUE; + } + + if (errmaj) *errmaj = LDR_ONCEONLY; + return NULL; +} + +#endif /* XFree86LOADER */ + +static Bool +TRIDENTGetRec(ScrnInfoPtr pScrn) +{ + /* + * Allocate an TRIDENTRec, and hook it into pScrn->driverPrivate. + * pScrn->driverPrivate is initialised to NULL, so we can check if + * the allocation has already been done. + */ + if (pScrn->driverPrivate != NULL) + return TRUE; + + pScrn->driverPrivate = xnfcalloc(sizeof(TRIDENTRec), 1); + /* Initialise it */ + + return TRUE; +} + +static void +TRIDENTFreeRec(ScrnInfoPtr pScrn) +{ + if (pScrn->driverPrivate == NULL) + return; + xfree(pScrn->driverPrivate); + pScrn->driverPrivate = NULL; +} + +static void +TRIDENTDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + CARD8 DPMSCont, PMCont, temp; + + if (!pScrn->vtSema) + return; + + OUTB(0x3C4, 0x0E); + temp = INB(0x3C5); + OUTB(0x3C5, 0xC2); + OUTB(0x83C8, 0x04); /* Read DPMS Control */ + PMCont = INB(0x83C6) & 0xFC; + OUTB(0x3CE, 0x23); + DPMSCont = INB(0x3CF) & 0xFC; + switch (PowerManagementMode) + { + case DPMSModeOn: + /* Screen: On, HSync: On, VSync: On */ + PMCont |= 0x03; + DPMSCont |= 0x00; + break; + case DPMSModeStandby: + /* Screen: Off, HSync: Off, VSync: On */ + PMCont |= 0x02; + DPMSCont |= 0x01; + break; + case DPMSModeSuspend: + /* Screen: Off, HSync: On, VSync: Off */ + PMCont |= 0x02; + DPMSCont |= 0x02; + break; + case DPMSModeOff: + /* Screen: Off, HSync: Off, VSync: Off */ + PMCont |= 0x00; + DPMSCont |= 0x03; + break; + } + OUTB(0x3CF, DPMSCont); + OUTB(0x83C8, 0x04); + OUTB(0x83C6, PMCont); + OUTW(0x3C4, (temp<<8) | 0x0E); +} + +static void +TRIDENTBlockHandler ( + int i, + pointer blockData, + pointer pTimeout, + pointer pReadmask +){ + ScreenPtr pScreen = screenInfo.screens[i]; + ScrnInfoPtr pScrn = xf86Screens[i]; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + pScreen->BlockHandler = pTrident->BlockHandler; + (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); + pScreen->BlockHandler = TRIDENTBlockHandler; + + if(pTrident->VideoTimerCallback) { + UpdateCurrentTime(); + (*pTrident->VideoTimerCallback)(pScrn, currentTime.milliseconds); + } +} + +static const OptionInfoRec * +TRIDENTAvailableOptions(int chipid, int busid) +{ + return TRIDENTOptions; +} + +/* Mandatory */ +static void +TRIDENTIdentify(int flags) +{ + xf86PrintChipsets(TRIDENT_NAME, "driver for Trident chipsets", TRIDENTChipsets); +} + +Bool +TRIDENTClockSelect(ScrnInfoPtr pScrn, int no) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + unsigned char temp; + + /* + * CS0 and CS1 are in MiscOutReg + * + * For 8900B, 8900C, 8900CL and 9000, CS2 is bit 0 of + * New Mode Control Register 2. + * + * For 8900CL, CS3 is bit 4 of Old Mode Control Register 1. + * + * For 9000, CS3 is bit 6 of New Mode Control Register 2. + * + * For TGUI, we don't use the ClockSelect function at all. + */ + switch(no) { + case CLK_REG_SAVE: + pTrident->SaveClock1 = INB(0x3CC); + if (pTrident->Chipset != TVGA8800CS) { + if ( (pScrn->numClocks == 16) && + (pTrident->Chipset != TVGA9000) && + (pTrident->Chipset != TVGA9000i) ) + { + OUTW(0x3C4, 0x000B); /* Switch to Old Mode */ + OUTB(0x3C4, 0x0E); pTrident->SaveClock3 = INB(0x3C5); + } + OUTB(0x3C4, 0x0B); + INB(0x3C5); /* Now to New Mode */ + OUTB(0x3C4, 0x0D); pTrident->SaveClock2 = INB(0x3C5); + } + break; + case CLK_REG_RESTORE: + OUTB(0x3C2, pTrident->SaveClock1); + if (pTrident->Chipset != TVGA8800CS) { + if ( (pScrn->numClocks == 16) && + (pTrident->Chipset != TVGA9000) && + (pTrident->Chipset != TVGA9000i) ) + { + OUTW(0x3C4, 0x000B); /* Switch to Old Mode */ + OUTW(0x3C4, (pTrident->SaveClock3 << 8) | 0x0E); + } + OUTB(0x3C4, 0x0B); + INB(0x3C5); /* Now to New Mode */ + OUTW(0x3C4, (pTrident->SaveClock2 << 8) | 0x0D); + } + break; + default: + /* + * Do CS0 and CS1 + */ + temp = INB(0x3CC); + OUTB(0x3C2, (temp & 0xF3) | ((no << 2) & 0x0C)); + if (pTrident->Chipset != TVGA8800CS) { + if ( (pScrn->numClocks == 16) && + (pTrident->Chipset != TVGA9000) && + (pTrident->Chipset != TVGA9000i) ) + { + /* + * Go to Old Mode for CS3. + */ + OUTW(0x3C4, 0x000B); /* Switch to Old Mode */ + OUTB(0x3C4, 0x0E); + temp = INB(0x3C5) & 0xEF; + temp |= (no & 0x08) << 1; + OUTB(0x3C5, temp); + } + /* + * Go to New Mode for CS2 and TVGA9000 CS3. + */ + OUTB(0x3C4, 0x0B); + INB(0x3C5); /* Now to New Mode */ + OUTB(0x3C4, 0x0D); + /* + * Bits 1 & 2 are dividers - set to 0 to get no + * clock division. + */ + temp = INB(0x3C5) & 0xF8; + temp |= (no & 0x04) >> 2; + if ( (pTrident->Chipset == TVGA9000) || + (pTrident->Chipset == TVGA9000i) ) + { + temp &= ~0x40; + temp |= (no & 0x08) << 3; + } + OUTB(0x3C5, temp); + } + } + return(TRUE); +} + +static int +TridentFindIsaDevice(GDevPtr dev) +{ + int found = -1; + unsigned char temp, origVal, newVal; + + /* + * Check first that we have a Trident card. + */ + outb(0x3C4, 0x0B); + temp = inb(0x3C5); /* Save old value */ + outb(0x3C4, 0x0B); /* Switch to Old Mode */ + outb(0x3C5, 0x00); + inb(0x3C5); /* Now to New Mode */ + outb(0x3C4, 0x0E); + origVal = inb(0x3C5); + outb(0x3C5, 0x00); + newVal = inb(0x3C5) & 0x0F; + outb(0x3C5, (origVal ^ 0x02)); + + /* + * Is it a Trident card ?? + */ + if (newVal != 2) { + /* + * Nope, so quit + */ + outb(0x3C4, 0x0B); /* Restore value of 0x0B */ + outb(0x3C5, temp); + outb(0x3C4, 0x0E); + outb(0x3C5, origVal); + return found; + } + + outb(0x3C4, 0x0B); + temp = inb(0x3C5); + switch (temp) { + case 0x01: + found = TVGA8800BR; + break; + case 0x02: + found = TVGA8800CS; + break; + case 0x03: + found = TVGA8900B; + break; + case 0x04: + case 0x13: + found = TVGA8900C; + break; + case 0x23: + found = TVGA9000; + break; + case 0x33: + found = TVGA8900D; + break; + case 0x43: + found = TVGA9000i; + break; + case 0x53: + found = TVGA9200CXr; + break; + case 0x63: + found = TVGA9100B; + break; + case 0x73: + case 0xC3: + found = TGUI9420DGi; + break; + case 0x83: + found = TVGA8200LX; + break; + case 0x93: + found = TGUI9400CXi; + break; + case 0xA3: + found = CYBER9320; + break; + case 0xD3: + found = TGUI9660; + break; + case 0xE3: + found = TGUI9440AGi; + break; + case 0xF3: + found = TGUI9430DGi; + break; + } + return found; +} + + +/* Mandatory */ +static Bool +TRIDENTProbe(DriverPtr drv, int flags) +{ + int i; + GDevPtr *devSections; + int *usedChips = NULL; + int numDevSections; + int numUsed; + Bool foundScreen = FALSE; + + if ((numDevSections = xf86MatchDevice(TRIDENT_DRIVER_NAME, + &devSections)) <= 0) { + /* + * There's no matching device section in the config file, so quit + * now. + */ + return FALSE; + } + + /* + * While we're VGA-dependent, can really only have one such instance, but + * we'll ignore that. + */ + + /* + * We need to probe the hardware first. We then need to see how this + * fits in with what is given in the config file, and allow the config + * file info to override any contradictions. + */ + + /* + * All of the cards this driver supports are PCI, so the "probing" just + * amounts to checking the PCI data that the server has already collected. + */ + if (xf86GetPciVideoInfo()) { + numUsed = xf86MatchPciInstances(TRIDENT_NAME, PCI_VENDOR_TRIDENT, + TRIDENTChipsets, TRIDENTPciChipsets, devSections, + numDevSections, drv, &usedChips); + + if (numUsed > 0) { + if (flags & PROBE_DETECT) + foundScreen = TRUE; + else for (i = 0; i < numUsed; i++) { + ScrnInfoPtr pScrn = NULL; + + if ((pScrn = xf86ConfigPciEntity(pScrn, 0,usedChips[i], + TRIDENTPciChipsets, NULL, + NULL, NULL, NULL, NULL))) { + /* Fill in what we can of the ScrnInfoRec */ + pScrn->driverVersion = TRIDENT_VERSION; + pScrn->driverName = TRIDENT_DRIVER_NAME; + pScrn->name = TRIDENT_NAME; + pScrn->Probe = TRIDENTProbe; + pScrn->PreInit = TRIDENTPreInit; + pScrn->ScreenInit = TRIDENTScreenInit; + pScrn->SwitchMode = TRIDENTSwitchMode; + pScrn->AdjustFrame = TRIDENTAdjustFrame; + pScrn->EnterVT = TRIDENTEnterVT; + pScrn->LeaveVT = TRIDENTLeaveVT; + pScrn->FreeScreen = TRIDENTFreeScreen; + pScrn->ValidMode = TRIDENTValidMode; + foundScreen = TRUE; + } + } + xfree(usedChips); + } + } + + /* Isa Bus */ + numUsed = xf86MatchIsaInstances(TRIDENT_NAME,TRIDENTChipsets, + TRIDENTISAchipsets, + drv,TridentFindIsaDevice,devSections, + numDevSections,&usedChips); + if (numUsed > 0) { + if (flags & PROBE_DETECT) + foundScreen = TRUE; + else for (i = 0; i < numUsed; i++) { + ScrnInfoPtr pScrn = NULL; + if ((pScrn = xf86ConfigIsaEntity(pScrn,0,usedChips[i], + TRIDENTISAchipsets,NULL, + NULL,NULL,NULL,NULL))) { + pScrn->driverVersion = TRIDENT_VERSION; + pScrn->driverName = TRIDENT_DRIVER_NAME; + pScrn->name = TRIDENT_NAME; + pScrn->Probe = TRIDENTProbe; + pScrn->PreInit = TRIDENTPreInit; + pScrn->ScreenInit = TRIDENTScreenInit; + pScrn->SwitchMode = TRIDENTSwitchMode; + pScrn->AdjustFrame = TRIDENTAdjustFrame; + pScrn->EnterVT = TRIDENTEnterVT; + pScrn->LeaveVT = TRIDENTLeaveVT; + pScrn->FreeScreen = TRIDENTFreeScreen; + pScrn->ValidMode = TRIDENTValidMode; + foundScreen = TRUE; + } + } + xfree(usedChips); + } + + xfree(devSections); + return foundScreen; +} + +/* + * GetAccelPitchValues - + * + * This function returns a list of display width (pitch) values that can + * be used in accelerated mode. + */ +static int * +GetAccelPitchValues(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int *linePitches = NULL; + int lines[4] = { 512, 1024, 2048, 4096 }; /* 9440AGi */ + int i, n = 0; + + if (pTrident->Chipset >= BLADEXP) { + lines[0] = 1024; + lines[1] = 2048; + lines[2] = 4096; + lines[3] = 8192; + } + + for (i = 0; i < 4; i++) { + n++; + linePitches = xnfrealloc(linePitches, n * sizeof(int)); + linePitches[n - 1] = lines[i]; + } + + /* Mark the end of the list */ + if (n > 0) { + linePitches = xnfrealloc(linePitches, (n + 1) * sizeof(int)); + linePitches[n] = 0; + } + return linePitches; +} + +static void +TRIDENTProbeDDC(ScrnInfoPtr pScrn, int index) +{ + vbeInfoPtr pVbe; + if (xf86LoadSubModule(pScrn, "vbe")) { + pVbe = VBEInit(NULL,index); + ConfiguredMonitor = vbeDoEDID(pVbe, NULL); + vbeFree(pVbe); + } +} + +/* Mandatory */ +static Bool +TRIDENTPreInit(ScrnInfoPtr pScrn, int flags) +{ + TRIDENTPtr pTrident; + vgaHWPtr hwp; + MessageType from; + CARD8 videoram, videorammask; + char *ramtype = NULL, *chipset = NULL; + Bool Support24bpp; + int vgaIOBase; + float mclk; + double real; + int i, NoClocks = 16; + CARD8 revision; + ClockRangePtr clockRanges; + Bool ddcLoaded = FALSE; + xf86MonPtr pMon = NULL; + char *s; + Bool tmp_bool; + + /* Allocate the TRIDENTRec driverPrivate */ + if (!TRIDENTGetRec(pScrn)) { + return FALSE; + } + pTrident = TRIDENTPTR(pScrn); + pTrident->pScrn = pScrn; + + if (pScrn->numEntities > 1) + return FALSE; + /* This is the general case */ + for (i = 0; i<pScrn->numEntities; i++) { + pTrident->pEnt = xf86GetEntityInfo(pScrn->entityList[i]); + if (pTrident->pEnt->resources) return FALSE; + pTrident->Chipset = pTrident->pEnt->chipset; + pScrn->chipset = (char *)xf86TokenToString(TRIDENTChipsets, + pTrident->pEnt->chipset); + /* This driver can handle ISA and PCI buses */ + if (pTrident->pEnt->location.type == BUS_PCI) { + pTrident->PciInfo = xf86GetPciInfoForEntity(pTrident->pEnt->index); + pTrident->PciTag = pciTag(pTrident->PciInfo->bus, + pTrident->PciInfo->device, + pTrident->PciInfo->func); + pTrident->Linear = TRUE; + } else { + pTrident->Linear = FALSE; + } + } + + if (flags & PROBE_DETECT) { + TRIDENTProbeDDC(pScrn, pTrident->pEnt->index); + return TRUE; + } + + /* Set pScrn->monitor */ + pScrn->monitor = pScrn->confScreen->monitor; + + /* + * The first thing we should figure out is the depth, bpp, etc. + * Our preference for depth 24 is 24bpp, so tell it that too. + */ + if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support24bppFb | Support32bppFb | + SupportConvert32to24 /*| PreferConvert32to24*/)) { + return FALSE; + } else { + /* Check that the returned depth is one we support */ + switch (pScrn->depth) { + case 8: + if (pScrn->bitsPerPixel != pScrn->depth) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given depth (%d)/ fbbpp (%d) is not supported by this driver\n", + pScrn->depth, pScrn->bitsPerPixel); + return FALSE; + } + break; + case 15: + case 16: + if (pScrn->bitsPerPixel != 16) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given depth (%d)/ fbbpp (%d) is not supported by this driver\n", + pScrn->depth, pScrn->bitsPerPixel); + return FALSE; + } + break; + case 24: + if ((pScrn->bitsPerPixel != 24) && (pScrn->bitsPerPixel != 32)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given depth (%d)/ fbbpp (%d) is not supported by this driver\n", + pScrn->depth, pScrn->bitsPerPixel); + return FALSE; + } + /* OK */ + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given depth (%d) is not supported by this driver\n", + pScrn->depth); + return FALSE; + } + } + + xf86PrintDepthBpp(pScrn); + + /* Get the depth24 pixmap format */ + if (pScrn->depth == 24 && pix24bpp == 0) + pix24bpp = xf86GetBppFromDepth(pScrn, 24); + + /* The vgahw module should be loaded here when needed */ + if (!xf86LoadSubModule(pScrn, "vgahw")) + return FALSE; + + xf86LoaderReqSymLists(vgahwSymbols, NULL); + + /* + * Allocate a vgaHWRec + */ + if (!vgaHWGetHWRec(pScrn)) + return FALSE; + + hwp = VGAHWPTR(pScrn); + vgaHWGetIOBase(hwp); + vgaIOBase = hwp->IOBase; + pTrident->PIOBase = hwp->PIOOffset; + + xf86SetOperatingState(resVga, pTrident->pEnt->index, ResUnusedOpr); + + /* The ramdac module should be loaded here when needed */ + if (!xf86LoadSubModule(pScrn, "ramdac")) + return FALSE; + + xf86LoaderReqSymLists(ramdacSymbols, NULL); + + /* + * This must happen after pScrn->display has been set because + * xf86SetWeight references it. + */ + if (pScrn->depth > 8) { + /* The defaults are OK for us */ + rgb zeros = {0, 0, 0}; + + if (!xf86SetWeight(pScrn, zeros, zeros)) { + return FALSE; + } else { + /* XXX check that weight returned is supported */ + ; + } + } + + if (!xf86SetDefaultVisual(pScrn, -1)) { + return FALSE; + } else { + /* We don't currently support DirectColor at > 8bpp */ + if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual" + " (%s) is not supported at depth %d\n", + xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); + return FALSE; + } + } + + /* + * The new cmap layer needs this to be initialised. + */ + + { + Gamma zeros = {0.0, 0.0, 0.0}; + + if (!xf86SetGamma(pScrn, zeros)) { + return FALSE; + } + } + + /* Collect all of the relevant option flags (fill in pScrn->options) */ + xf86CollectOptions(pScrn, NULL); + + /* Process the options */ + if (!(pTrident->Options = xalloc(sizeof(TRIDENTOptions)))) + return FALSE; + memcpy(pTrident->Options, TRIDENTOptions, sizeof(TRIDENTOptions)); + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pTrident->Options); + + /* Set the bits per RGB for 8bpp mode */ + if (pScrn->depth == 8) { + /* XXX This is here just to test options. */ + /* Default to 8 */ + pScrn->rgbBits = 6; +#if 0 + if (xf86GetOptValInteger(pTrident->Options, OPTION_RGB_BITS, + &pScrn->rgbBits)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Bits per RGB set to %d\n", + pScrn->rgbBits); + } +#endif + } + from = X_DEFAULT; + + pTrident->useEXA = FALSE; + if ((s = (char *)xf86GetOptValString(pTrident->Options, + OPTION_ACCELMETHOD))) { + if (!xf86NameCmp(s, "EXA")) { + pTrident->useEXA = TRUE; + from = X_CONFIG; + } + else if (!xf86NameCmp(s, "XAA")) { + pTrident->useEXA = FALSE; + from = X_CONFIG; + } + } + xf86DrvMsg(pScrn->scrnIndex, from, "Using %s for acceleration\n", + pTrident->useEXA ? "EXA" : "XAA"); + + pTrident->HWCursor = TRUE; + if (xf86ReturnOptValBool(pTrident->Options, OPTION_SW_CURSOR, FALSE)) { + from = X_CONFIG; + pTrident->HWCursor = FALSE; + } + if (xf86ReturnOptValBool(pTrident->Options, OPTION_NOACCEL, FALSE)) { + pTrident->NoAccel = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); + } + if (xf86ReturnOptValBool(pTrident->Options, OPTION_PCI_RETRY, FALSE)) { + pTrident->UsePCIRetry = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry enabled\n"); + } + pTrident->UsePCIBurst = TRUE; + if (xf86ReturnOptValBool(pTrident->Options, OPTION_NOPCIBURST, FALSE)) { + pTrident->UsePCIBurst = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI Burst disbled\n"); + } + /* Display Size override moved to DDC section */ + if(xf86GetOptValInteger(pTrident->Options, OPTION_VIDEO_KEY, + &(pTrident->videoKey))) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n", + pTrident->videoKey); + } else { + pTrident->videoKey = (1 << pScrn->offset.red) | + (1 << pScrn->offset.green) | + (((pScrn->mask.blue >> pScrn->offset.blue) - 1) + << pScrn->offset.blue); + } + if (xf86ReturnOptValBool(pTrident->Options, OPTION_NOMMIO, FALSE)) { + pTrident->NoMMIO = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "MMIO Disabled\n"); + } + if (xf86ReturnOptValBool(pTrident->Options, OPTION_MMIO_ONLY, FALSE)) { + if (pTrident->NoMMIO) + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MMIO only cannot be set" + " with NoMMIO\n"); + else { + pTrident->MMIOonly = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "MMIO only enabled\n"); + } + } + + pTrident->dspOverride = 0; + if ((s = xf86GetOptValString(pTrident->Options, OPTION_DISPLAY))) { + if(!xf86NameCmp(s, "CRT")) { + pTrident->dspOverride = CRT_ACTIVE; + xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"LCD off CRT on\n"); + } else if (!xf86NameCmp(s, "LCD")) { + pTrident->dspOverride = LCD_ACTIVE; + xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"LCD on CRT off\n"); + } else if (!xf86NameCmp(s, "Dual")) { + pTrident->dspOverride = LCD_ACTIVE | CRT_ACTIVE; + xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"LCD on CRT on\n"); + } else + xf86DrvMsg(pScrn->scrnIndex,X_ERROR, + "%s is an unknown display option\n",s); + } + if ((s = xf86GetOptValString(pTrident->Options, OPTION_GB))) { + int brightness = -1; + double gamma = -1.0; + Bool error = FALSE; + int i; + + i = sscanf(s,"%lf %i",&gamma,&brightness); + + if (i != 2 || brightness == -1 || gamma == -1.0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Invalid Gamma/Brightness argument: %s\n",s); + error = TRUE; + } else { + if (brightness < 0 || brightness > 128) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "brightness out of range [0,128]: %i\n",brightness); + error = TRUE; + } + if (gamma <= 0.0 || gamma > 10.0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "gamma out of range (0,10.0]: %f\n",gamma); + error = TRUE; + } + } + + if (!error) { + pTrident->GammaBrightnessOn = TRUE; + pTrident->gamma = gamma; + pTrident->brightness = brightness; + xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"Gamma: %f Brightness: %i\n", + gamma,brightness); + } + } + + /* The following is a temporary hack */ + pTrident->FPDelay = 7; /* invalid value */ + if (xf86GetOptValInteger(pTrident->Options, OPTION_FP_DELAY, + &pTrident->FPDelay)) { + if (pTrident->FPDelay < -2 || pTrident->FPDelay > 5) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "FPDelay %i out if range " + "(-2 < FPDelay < 5)\n",pTrident->FPDelay); + pTrident->FPDelay = 7; + } else + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "FP Delay set to %i\n", + pTrident->FPDelay); + } + if (xf86ReturnOptValBool(pTrident->Options, OPTION_CYBER_SHADOW, FALSE)) { + pTrident->CyberShadow = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Cyber Shadow enabled\n"); + } + if (xf86ReturnOptValBool(pTrident->Options, OPTION_CYBER_STRETCH, FALSE)) { + pTrident->CyberStretch = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Cyber Stretch enabled\n"); + } + + pTrident->MUXThreshold = 90000; /* 90MHz */ + if (xf86GetOptValInteger(pTrident->Options, OPTION_MUX_THRESHOLD, + &pTrident->MUXThreshold)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "MUX Threshold set to %d\n", + pTrident->MUXThreshold); + } + pTrident->OverrideHsync = 0; + if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_HSYNC, + &pTrident->OverrideHsync)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Hsync set to %d\n", + pTrident->OverrideHsync); + } + pTrident->OverrideVsync = 0; + if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_VSYNC, + &pTrident->OverrideVsync)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Vsync set to %d\n", + pTrident->OverrideVsync); + } + pTrident->OverrideHsync = 0; + if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_HSYNC, + &pTrident->OverrideHsync)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Hsync set to %d\n", + pTrident->OverrideHsync); + } + pTrident->OverrideVsync = 0; + if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_VSYNC, + &pTrident->OverrideVsync)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Vsync set to %d\n", + pTrident->OverrideVsync); + } + pTrident->OverrideRskew = 0; + if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_RSKEW, + &pTrident->OverrideRskew)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Rskew set to %d\n", + pTrident->OverrideRskew); + } + pTrident->OverrideBskew = 0; + if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_BSKEW, + &pTrident->OverrideBskew)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Bskew set to %d\n", + pTrident->OverrideBskew); + } + if (xf86ReturnOptValBool(pTrident->Options, OPTION_SHADOW_FB, FALSE)) { + if (!pTrident->Linear) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Ignoring Option SHADOW_FB" + " in non-Linear Mode\n"); + else { + pTrident->ShadowFB = TRUE; + pTrident->NoAccel = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Using \"Shadow Framebuffer\" - acceleration disabled\n"); + } + } + pTrident->Rotate = 0; + if ((s = xf86GetOptValString(pTrident->Options, OPTION_ROTATE))) { + if (!pTrident->Linear) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Ignoring Option ROTATE " + "in non-Linear Mode\n"); + else { + if(!xf86NameCmp(s, "CW")) { + /* accel is disabled below for shadowFB */ + pTrident->ShadowFB = TRUE; + pTrident->NoAccel = TRUE; + pTrident->HWCursor = FALSE; + pTrident->Rotate = 1; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Rotating screen clockwise - acceleration disabled\n"); + } else if(!xf86NameCmp(s, "CCW")) { + pTrident->ShadowFB = TRUE; + pTrident->NoAccel = TRUE; + pTrident->HWCursor = FALSE; + pTrident->Rotate = -1; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen" + "counter clockwise - acceleration disabled\n"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid" + "value for Option \"Rotate\"\n", s); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Valid options are \"CW\" or \"CCW\"\n"); + } + } + } + + pTrident->TVChipset = 0; + if ((s = xf86GetOptValString(pTrident->Options, OPTION_TV_CHIPSET))) { + if(!xf86NameCmp(s, "VT1621")) { + pTrident->TVChipset = 1; + xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"Using VIA VT1621 TV chip\n"); + } else if (!xf86NameCmp(s, "CH7005")) { + pTrident->TVChipset = 2; + xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"Using Chrontel CH7005 TV chip\n"); + } else + xf86DrvMsg(pScrn->scrnIndex,X_ERROR, + "%s is an unknown TV chipset option\n",s); + } + /* Default : NTSC */ + pTrident->TVSignalMode=0; + if (xf86GetOptValInteger(pTrident->Options, OPTION_TV_SIGNALMODE, + &pTrident->TVSignalMode)) { + ErrorF("TV SignalMode set to %d\n",pTrident->TVSignalMode); + } + + /* FIXME ACCELERATION */ + if (!UseMMIO) pTrident->NoAccel = TRUE; + + if (pTrident->Linear) { + if (pTrident->pEnt->device->MemBase != 0) { + /* + * XXX Should check that the config file value matches one of the + * PCI base address values. + */ + pTrident->FbAddress = pTrident->pEnt->device->MemBase; + from = X_CONFIG; + } else { + if (IsPciCard) + pTrident->FbAddress = pTrident->PciInfo->memBase[0]& 0xFFFFFFF0; + else + pTrident->FbAddress = 0xA0000; + } + + xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n", + (unsigned long)pTrident->FbAddress); + } + + if (UseMMIO) { + if (pTrident->pEnt->device->IOBase != 0) { + /* + * XXX Should check that the config file value matches one of the + * PCI base address values. + */ + pTrident->IOAddress = pTrident->pEnt->device->IOBase; + from = X_CONFIG; + } else { + if (IsPciCard) + pTrident->IOAddress = pTrident->PciInfo->memBase[1]& 0xFFFFC000; + else + /* FIXME - Multihead UNAWARE */ + pTrident->IOAddress = 0xBF000; + } + + xf86DrvMsg(pScrn->scrnIndex,X_PROBED,"IO registers at 0x%lX\n", + (unsigned long)pTrident->IOAddress); + } + + /* Register the PCI-assigned resources. */ + if (xf86RegisterResources(pTrident->pEnt->index, NULL, ResExclusive)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "xf86RegisterResources() found resource conflicts\n"); + return FALSE; + } + + /* Initialize VBE if possible + * Don't move this past MMIO enable!! + * PIO access will be blocked + * when MMIO is turned on! + */ + + if (xf86LoadSubModule(pScrn, "vbe")) { + vbeInfoPtr pVbe; + + xf86LoaderReqSymLists(vbeSymbols, NULL); + pVbe = VBEInit(NULL,pTrident->pEnt->index); + pMon = vbeDoEDID(pVbe, NULL); +#ifdef VBE_INFO + { + VbeInfoBlock* vbeInfoBlockPtr; + if ((vbeInfoBlockPtr = VBEGetVBEInfo(pVbe))) { + pTrident->vbeModes = VBEBuildVbeModeList(pVbe,vbeInfoBlockPtr); + VBEFreeVBEInfo(vbeInfoBlockPtr); + } + } +#endif + vbeFree(pVbe); + if (pMon) { + if (!xf86LoadSubModule(pScrn, "ddc")) { + TRIDENTFreeRec(pScrn); + return FALSE; + } else { + xf86LoaderReqSymLists(ddcSymbols, NULL); + xf86SetDDCproperties(pScrn,xf86PrintEDID(pMon)); + ddcLoaded = TRUE; + } + } + + } + + if (xf86GetOptValBool(pTrident->Options, OPTION_1400_DISPLAY, &tmp_bool)) { + if (tmp_bool) + pTrident->displaySize = 1400; + } else + pTrident->displaySize = TRIDENTLcdDisplaySize(pMon); + + if (IsPciCard && UseMMIO) { + if (!TRIDENTMapMem(pScrn)) + return FALSE; + + TRIDENTEnableMMIO(pScrn); + } + + OUTB(0x3C4, RevisionID); revision = INB(0x3C5); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Revision is %d\n",revision); + + pScrn->progClock = TRUE; + pTrident->EngineOperation = 0x00; + pTrident->IsCyber = FALSE; + pTrident->HasSGRAM = FALSE; + pTrident->NewClockCode = FALSE; + pTrident->MUX = FALSE; + Support24bpp = FALSE; + + OUTB(vgaIOBase + 4, InterfaceSel); + + switch (pTrident->Chipset) { + case TVGA9000: + case TVGA9000i: + pScrn->progClock = FALSE; + NoClocks = 16; + pTrident->NoMMIO = TRUE; + pTrident->NoAccel = TRUE; + pTrident->HWCursor = FALSE; + chipset = "TVGA9000/9000i"; + ramtype = "Standard DRAM"; + if (pTrident->UsePCIRetry) + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n"); + pTrident->UsePCIRetry = FALSE; /* Not Supported */ + pTrident->frequency = NTSC; + break; + case TVGA9100B: + pScrn->progClock = FALSE; + NoClocks = 8; + pTrident->NoMMIO = TRUE; + pTrident->NoAccel = TRUE; + pTrident->HWCursor = FALSE; + chipset = "TVGA9100B"; + ramtype = "Standard DRAM"; + if (pTrident->UsePCIRetry) + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n"); + pTrident->UsePCIRetry = FALSE; /* Not Supported */ + pTrident->frequency = NTSC; + break; + case TVGA8900B: + pScrn->progClock = FALSE; + NoClocks = 8; + pTrident->NoMMIO = TRUE; + pTrident->NoAccel = TRUE; + pTrident->HWCursor = FALSE; + chipset = "TVGA8900B"; + ramtype = "Standard DRAM"; + if (pTrident->UsePCIRetry) + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n"); + pTrident->UsePCIRetry = FALSE; /* Not Supported */ + pTrident->frequency = NTSC; + break; + case TVGA8900C: + pScrn->progClock = FALSE; + NoClocks = 16; + pTrident->NoMMIO = TRUE; + pTrident->NoAccel = TRUE; + pTrident->HWCursor = FALSE; + chipset = "TVGA8900C"; + ramtype = "Standard DRAM"; + if (pTrident->UsePCIRetry) + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n"); + pTrident->UsePCIRetry = FALSE; /* Not Supported */ + pTrident->frequency = NTSC; + break; + case TVGA8900D: + pScrn->progClock = FALSE; + NoClocks = 16; + pTrident->NoMMIO = TRUE; + pTrident->NoAccel = TRUE; + pTrident->HWCursor = FALSE; + chipset = "TVGA8900D"; + ramtype = "Standard DRAM"; + if (pTrident->UsePCIRetry) + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n"); + pTrident->UsePCIRetry = FALSE; /* Not Supported */ + pTrident->frequency = NTSC; + break; + case TVGA9200CXr: + pScrn->progClock = FALSE; + NoClocks = 16; + pTrident->NoMMIO = TRUE; + pTrident->NoAccel = TRUE; + pTrident->HWCursor = FALSE; + chipset = "TVGA9200CXr"; + ramtype = "Standard DRAM"; + if (pTrident->UsePCIRetry) + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n"); + pTrident->UsePCIRetry = FALSE; /* Not Supported */ + pTrident->frequency = NTSC; + break; + case TGUI9400CXi: + pScrn->progClock = FALSE; + NoClocks = 16; + pTrident->NoMMIO = TRUE; + pTrident->NoAccel = TRUE; + pTrident->HWCursor = FALSE; + chipset = "TVGA9200CXr"; + ramtype = "Standard DRAM"; + if (pTrident->UsePCIRetry) + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n"); + pTrident->UsePCIRetry = FALSE; /* Not Supported */ + pTrident->frequency = NTSC; + break; + case TGUI9440AGi: + pTrident->ddc1Read = Tridentddc1Read; + pTrident->HWCursor = FALSE; + chipset = "TGUI9440AGi"; + ramtype = "Standard DRAM"; + if (pTrident->UsePCIRetry) + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n"); + pTrident->UsePCIRetry = FALSE; /* Not Supported */ + pTrident->frequency = NTSC; + break; + case CYBER9320: + pTrident->ddc1Read = Tridentddc1Read; + chipset = "Cyber9320"; + ramtype = "Standard DRAM"; + if (pTrident->UsePCIRetry) + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n"); + pTrident->UsePCIRetry = FALSE; /* Not Supported */ + break; + /* Trident didn't update the PCI ID's and so we have to detemine + * which chips are right ! Then override pTrident->Chipset to + * correct values */ + case TGUI9660: + pTrident->ddc1Read = Tridentddc1Read; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x04) + ramtype = "EDO Ram"; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) + ramtype = "Standard DRAM"; + switch (revision) { + case 0x00: + chipset = "TGUI9660"; + pTrident->Chipset = TGUI9660; + if (pTrident->UsePCIRetry) + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n"); + pTrident->UsePCIRetry = FALSE; /* Not Supported */ + break; + case 0x01: + chipset = "TGUI9680"; + pTrident->Chipset = TGUI9680; + if (pTrident->UsePCIRetry) + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n"); + pTrident->UsePCIRetry = FALSE; /* Not Supported */ + break; + case 0x10: + chipset = "ProVidia 9682"; + Support24bpp = TRUE; + pTrident->Chipset = PROVIDIA9682; + break; + case 0x21: + chipset = "ProVidia 9685"; + Support24bpp = TRUE; + pTrident->NewClockCode = TRUE; + pTrident->Chipset = PROVIDIA9685; + break; + case 0x22: + case 0x23: + chipset = "Cyber 9397"; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x04) + ramtype = "EDO Ram"; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x08) + ramtype = "SDRAM"; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) { + pTrident->HasSGRAM = TRUE; + ramtype = "SGRAM"; + } + pTrident->NewClockCode = TRUE; + pTrident->Chipset = CYBER9397; + pTrident->IsCyber = TRUE; + break; + case 0x2a: + chipset = "Cyber 9397/DVD"; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x04) + ramtype = "EDO Ram"; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x08) + ramtype = "SDRAM"; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) { + pTrident->HasSGRAM = TRUE; + ramtype = "SGRAM"; + } + pTrident->NewClockCode = TRUE; + pTrident->Chipset = CYBER9397DVD; + pTrident->IsCyber = TRUE; + break; + case 0x30: + case 0x33: + case 0x34: + case 0x35: + case 0xB3: + chipset = "Cyber 9385"; + pTrident->NewClockCode = TRUE; + pTrident->Chipset = CYBER9385; + pTrident->IsCyber = TRUE; + break; + case 0x38: + case 0x3A: + chipset = "Cyber 9385-1"; + pTrident->NewClockCode = TRUE; + pTrident->Chipset = CYBER9385; + pTrident->IsCyber = TRUE; + break; + case 0x40: + case 0x41: + case 0x42: + case 0x43: + chipset = "Cyber 9382"; + pTrident->NewClockCode = TRUE; + pTrident->Chipset = CYBER9382; + pTrident->IsCyber = TRUE; + break; + case 0x4A: + chipset = "Cyber 9388"; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x04) + ramtype = "EDO Ram"; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x08) + ramtype = "SDRAM"; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) { + pTrident->HasSGRAM = TRUE; + ramtype = "SGRAM"; + } + pTrident->NewClockCode = TRUE; + pTrident->Chipset = CYBER9388; + pTrident->IsCyber = TRUE; + break; + default: + chipset = "Unknown"; + pTrident->Chipset = TGUI9660; + break; + } + break; + case CYBER9388: + pTrident->ddc1Read = Tridentddc1Read; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x04) + ramtype = "EDO Ram"; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x08) + ramtype = "SDRAM"; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) { + pTrident->HasSGRAM = TRUE; + ramtype = "SGRAM"; + } + pTrident->IsCyber = TRUE; + Support24bpp = TRUE; + chipset = "Cyber 9388"; + pTrident->NewClockCode = TRUE; + break; + case CYBER9397: + pTrident->ddc1Read = Tridentddc1Read; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x04) + ramtype = "EDO Ram"; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x08) + ramtype = "SDRAM"; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) { + pTrident->HasSGRAM = TRUE; + ramtype = "SGRAM"; + } + pTrident->IsCyber = TRUE; + Support24bpp = TRUE; + chipset = "Cyber 9397"; + pTrident->NewClockCode = TRUE; + break; + case CYBER9397DVD: + pTrident->ddc1Read = Tridentddc1Read; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x04) + ramtype = "EDO Ram"; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x08) + ramtype = "SDRAM"; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) { + pTrident->HasSGRAM = TRUE; + ramtype = "SGRAM"; + } + pTrident->IsCyber = TRUE; + Support24bpp = TRUE; + chipset = "Cyber 9397/DVD"; + pTrident->NewClockCode = TRUE; + break; + case CYBER9520: + pTrident->ddc1Read = Tridentddc1Read; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x04) + ramtype = "EDO Ram"; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x08) + ramtype = "SDRAM"; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) { + pTrident->HasSGRAM = TRUE; + ramtype = "SGRAM"; + } + pTrident->IsCyber = TRUE; + Support24bpp = TRUE; + chipset = "Cyber 9520"; + pTrident->NewClockCode = TRUE; + break; + case CYBER9525DVD: + pTrident->ddc1Read = Tridentddc1Read; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x04) + ramtype = "EDO Ram"; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x08) + ramtype = "SDRAM"; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) { + pTrident->HasSGRAM = TRUE; + ramtype = "SGRAM"; + } + pTrident->IsCyber = TRUE; + Support24bpp = TRUE; + chipset = "Cyber 9525/DVD"; + pTrident->NewClockCode = TRUE; + break; + case CYBERBLADEE4: + pTrident->ddc1Read = Tridentddc1Read; + ramtype = "SDRAM"; + pTrident->IsCyber = TRUE; + Support24bpp = TRUE; + chipset = "CyberBlade e4/128"; + pTrident->NewClockCode = TRUE; + break; + case IMAGE975: + pTrident->ddc1Read = Tridentddc1Read; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x04) + ramtype = "EDO Ram"; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x08) + ramtype = "SDRAM"; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) { + pTrident->HasSGRAM = TRUE; + ramtype = "SGRAM"; + } + Support24bpp = TRUE; + chipset = "3DImage975"; + pTrident->NewClockCode = TRUE; + break; + case IMAGE985: + pTrident->ddc1Read = Tridentddc1Read; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x04) + ramtype = "EDO Ram"; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x08) + ramtype = "SDRAM"; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) { + pTrident->HasSGRAM = TRUE; + ramtype = "SGRAM"; + } + Support24bpp = TRUE; + chipset = "3DImage985"; + pTrident->NewClockCode = TRUE; + break; + case BLADE3D: + pTrident->ddc1Read = Tridentddc1Read; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x08) + ramtype = "SDRAM"; + if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) { + pTrident->HasSGRAM = TRUE; + ramtype = "SGRAM"; + } + Support24bpp = TRUE; + chipset = "Blade3D"; + pTrident->NewClockCode = TRUE; + pTrident->frequency = NTSC; + pTrident->UsePCIRetry = TRUE; /* To avoid lockups */ + break; + case CYBERBLADEI7: + pTrident->ddc1Read = Tridentddc1Read; + ramtype = "SDRAM"; + /* pTrident->IsCyber = TRUE; VIA MVP4 integrated Desktop version */ + Support24bpp = TRUE; + chipset = "CyberBlade/i7/VIA MVP4"; + pTrident->NewClockCode = TRUE; + pTrident->frequency = NTSC; + break; + case CYBERBLADEI7D: + pTrident->ddc1Read = Tridentddc1Read; + ramtype = "SDRAM"; + pTrident->IsCyber = TRUE; + Support24bpp = TRUE; + chipset = "CyberBlade/DSTN/i7"; + pTrident->NewClockCode = TRUE; + pTrident->frequency = NTSC; + break; + case CYBERBLADEI1: + pTrident->ddc1Read = Tridentddc1Read; + ramtype = "SDRAM"; + pTrident->IsCyber = TRUE; + Support24bpp = TRUE; + chipset = "CyberBlade/i1"; + pTrident->NewClockCode = TRUE; + pTrident->frequency = NTSC; + break; + case CYBERBLADEI1D: + pTrident->ddc1Read = Tridentddc1Read; + ramtype = "SDRAM"; + pTrident->IsCyber = TRUE; + Support24bpp = TRUE; + chipset = "CyberBlade/DSTN/i1"; + pTrident->NewClockCode = TRUE; + pTrident->frequency = NTSC; + break; + case CYBERBLADEAI1: + pTrident->ddc1Read = Tridentddc1Read; + ramtype = "SDRAM"; + pTrident->IsCyber = TRUE; + Support24bpp = TRUE; + chipset = "CyberBlade/Ai1"; + pTrident->NewClockCode = TRUE; + pTrident->frequency = NTSC; + break; + case CYBERBLADEAI1D: + pTrident->ddc1Read = Tridentddc1Read; + ramtype = "SDRAM"; + pTrident->IsCyber = TRUE; + Support24bpp = TRUE; + chipset = "CyberBlade/DSTN/Ai1"; + pTrident->NewClockCode = TRUE; + pTrident->frequency = NTSC; + break; + case BLADEXP: /* 0x9910 */ + pTrident->ddc1Read = Tridentddc1Read; + ramtype = "SGRAM"; + pTrident->HasSGRAM = TRUE; + Support24bpp = TRUE; + pTrident->NewClockCode = TRUE; + pTrident->frequency = NTSC; + OUTB(0x3C4, 0x5D); + if (pTrident->PciInfo->subsysVendor != 0x1023) { + chipset = "CyberBladeXP"; + pTrident->IsCyber = TRUE; + } else + if (!(INB(0x3C5) & 0x01)) { + chipset = "BladeXP"; + } else { + CARD8 mem1, mem2; + OUTB(vgaIOBase + 0x04, SPR); + mem1 = INB(vgaIOBase + 5); + OUTB(vgaIOBase + 0x04, 0xC1); + mem2 = INB(vgaIOBase + 5); + if ((mem1 & 0x0e) && (mem2 == 0x11)) { + chipset = "BladeT64"; + } else { + chipset = "BladeT16"; + } + } + break; + case CYBERBLADEXPAI1: + pTrident->ddc1Read = Tridentddc1Read; + ramtype = "SGRAM"; + pTrident->HasSGRAM = TRUE; + pTrident->IsCyber = TRUE; + pTrident->shadowNew = TRUE; + Support24bpp = TRUE; + chipset = "CyberBladeXPAi1"; + pTrident->NewClockCode = TRUE; + pTrident->frequency = NTSC; + break; + case CYBERBLADEXP4: + pTrident->ddc1Read = Tridentddc1Read; + ramtype = "SGRAM"; + pTrident->HasSGRAM = TRUE; + pTrident->IsCyber = TRUE; + pTrident->shadowNew = TRUE; + Support24bpp = TRUE; + chipset = "CyberBladeXP4"; + pTrident->NewClockCode = TRUE; + pTrident->frequency = NTSC; + break; + case XP5: + pTrident->ddc1Read = Tridentddc1Read; + ramtype = "SGRAM"; + pTrident->HasSGRAM = TRUE; + pTrident->IsCyber = TRUE; + pTrident->shadowNew = TRUE; + Support24bpp = TRUE; + chipset = "XP5"; + pTrident->NewClockCode = TRUE; + pTrident->frequency = NTSC; + break; + } + + if (!pScrn->progClock) { + pScrn->numClocks = NoClocks; + xf86GetClocks(pScrn, NoClocks, TRIDENTClockSelect, + vgaHWProtectWeak(), + vgaHWBlankScreenWeak(), + vgaIOBase + 0x0A, 0x08, 1, 28322); + from = X_PROBED; + xf86ShowClocks(pScrn, from); + } + + if (!chipset) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No support for \"%s\"\n", + pScrn->chipset); + if (IsPciCard && UseMMIO) { + TRIDENTDisableMMIO(pScrn); + TRIDENTUnmapMem(pScrn); + } + return FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Found %s chip\n", chipset); + if (ramtype) + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "RAM type is %s\n", ramtype); + + if (pScrn->bitsPerPixel == 24 && !Support24bpp) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "No support for 24bpp on this chipset, use -pixmap32.\n"); + if (IsPciCard && UseMMIO) { + TRIDENTDisableMMIO(pScrn); + TRIDENTUnmapMem(pScrn); + } + return FALSE; + } + + /* HW bpp matches reported bpp */ + pTrident->HwBpp = pScrn->bitsPerPixel; + + /* Due to bugs in the chip, turn it off */ + if (pTrident->Chipset >= CYBERBLADEI7 && pTrident->Chipset <= CYBERBLADEAI1D) + pTrident->HWCursor = FALSE; + + from = X_PROBED; + if (pTrident->pEnt->device->videoRam != 0) { + pScrn->videoRam = pTrident->pEnt->device->videoRam; + from = X_CONFIG; + } else { + if (pTrident->Chipset == XP5) { + OUTB(vgaIOBase + 4, 0x60); + videoram = INB(vgaIOBase + 5); + switch (videoram & 0x7) { + case 0x00: + pScrn->videoRam = 65536 /* 131072 */; + break; + case 0x01: + pScrn->videoRam = 65536; + break; + case 0x02: + pScrn->videoRam = 32768; + break; + case 0x03: + pScrn->videoRam = 16384; + break; + case 0x04: + pScrn->videoRam = 8192; + break; + } + } else + if (pTrident->Chipset == CYBER9525DVD) { + pScrn->videoRam = 2560; + } else + { + OUTB(vgaIOBase + 4, SPR); + videoram = INB(vgaIOBase + 5); + if (pTrident->Chipset < TGUI9440AGi) + videorammask = 0x07; + else + videorammask = 0x0F; + switch (videoram & videorammask) { + case 0x01: + pScrn->videoRam = 512; + break; + case 0x02: /* XP */ + pScrn->videoRam = 6144; + break; + case 0x03: + pScrn->videoRam = 1024; + break; + case 0x04: + pScrn->videoRam = 8192; + break; + case 0x06: /* XP */ + pScrn->videoRam = 10240; + break; + case 0x07: + pScrn->videoRam = 2048; + break; + case 0x08: /* XP */ + pScrn->videoRam = 12288; + break; + case 0x0A: /* XP */ + pScrn->videoRam = 14336; + break; + case 0x0C: /* XP */ + pScrn->videoRam = 16384; + break; + case 0x0E: /* XP */ + OUTB(vgaIOBase + 4, 0xC1); + switch (INB(vgaIOBase + 5) & 0x11) { + case 0x00: + pScrn->videoRam = 20480; + break; + case 0x01: + pScrn->videoRam = 24576; + break; + case 0x10: + pScrn->videoRam = 28672; + break; + case 0x11: + pScrn->videoRam = 32768; + break; + } + break; + case 0x0F: + pScrn->videoRam = 4096; + break; + default: + pScrn->videoRam = 1024; + xf86DrvMsg(pScrn->scrnIndex, from, + "Unable to determine VideoRam, defaulting to 1MB\n"); + break; + } + } + } + + xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", + pTrident->HWCursor ? "HW" : "SW"); + + xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n", + pScrn->videoRam); + + if (pTrident->IsCyber) { + unsigned char mod, dsp, dsp1; + + pTrident->lcdMode = 0xff; + + OUTB(0x3CE,0x42); + dsp = INB(0x3CF); + OUTB(0x3CE,0x43); + dsp1 = INB(0x3CF); + OUTB(0x3CE,0x52); + mod = INB(0x3CF); + /* + * Only allow display size override if 1280x1024 is detected + * Currently 1400x1050 is supported - which is detected as + * 1280x1024 + */ + if (pTrident->displaySize) { + if (((mod >> 4) & 3) == 0) { + for (i = 0; LCD[i].mode != 0xff; i++) { + if (pTrident->displaySize == LCD[i].display_x) + pTrident->lcdMode = LCD[i].mode; + } + xf86DrvMsg(pScrn->scrnIndex, + X_INFO,"%s Panel %ix%i found\n", + (dsp & 0x80) ? "TFT" : + ((dsp1 & 0x20) ? "DSTN" : "STN"), + LCD[i].display_x,LCD[i].display_y); + } else { + xf86DrvMsg(pScrn->scrnIndex,X_WARNING, + "Display size override only for 1280x1024\n"); + pTrident->displaySize = 0; + } + } + + if (!pTrident->displaySize) { + for (i = 0; LCD[i].mode != 0xff; i++) { + if (LCD[i].mode == ((mod >> 4) & 3)) { + pTrident->lcdMode = i; + xf86DrvMsg(pScrn->scrnIndex, + X_PROBED,"%s Panel %ix%i found\n", + (dsp & 0x80) ? "TFT" : + ((dsp1 & 0x20) ? "DSTN" : "STN"), + LCD[i].display_x,LCD[i].display_y); + } + } + } + if (pTrident->dspOverride) { + if (pTrident->dspOverride & LCD_ACTIVE) + pTrident->lcdActive = TRUE; + else + pTrident->lcdActive = FALSE; + } else { + OUTB(0x3CE, FPConfig); + pTrident->lcdActive = (INB(0x3CF) & 0x10); + } + } + + pTrident->MCLK = 0; + mclk = CalculateMCLK(pScrn); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Memory Clock is %3.2f MHz\n", mclk); + if (xf86GetOptValFreq(pTrident->Options, OPTION_SETMCLK, OPTUNITS_MHZ, + &real)) { + pTrident->MCLK = (int)(real * 1000.0); + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Setting new Memory Clock to %3.2f MHz\n", + (float)(pTrident->MCLK / 1000)); + } + + /* Set the min pixel clock */ + pTrident->MinClock = 12000; /* XXX Guess, need to check this */ + xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n", + pTrident->MinClock / 1000); + + /* + * If the user has specified ramdac speed in the XF86Config + * file, we respect that setting. + */ + if (pTrident->pEnt->device->dacSpeeds[0]) { + int speed = 0; + + switch (pScrn->bitsPerPixel) { + case 8: + speed = pTrident->pEnt->device->dacSpeeds[DAC_BPP8]; + break; + case 16: + speed = pTrident->pEnt->device->dacSpeeds[DAC_BPP16]; + break; + case 24: + speed = pTrident->pEnt->device->dacSpeeds[DAC_BPP24]; + break; + case 32: + speed = pTrident->pEnt->device->dacSpeeds[DAC_BPP32]; + break; + } + if (speed == 0) + pTrident->MaxClock = pTrident->pEnt->device->dacSpeeds[0]; + else + pTrident->MaxClock = speed; + from = X_CONFIG; + } else { + switch (pScrn->bitsPerPixel) { + case 16: + pTrident->MaxClock = ClockLimit16bpp[pTrident->Chipset]; + break; + case 24: + pTrident->MaxClock = ClockLimit24bpp[pTrident->Chipset]; + break; + case 32: + pTrident->MaxClock = ClockLimit32bpp[pTrident->Chipset]; + break; + default: + pTrident->MaxClock = ClockLimit[pTrident->Chipset]; + break; + } + } + xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n", + pTrident->MaxClock / 1000); + + /* + * Setup the ClockRanges, which describe what clock ranges are available, + * and what sort of modes they can be used for. + */ + clockRanges = xnfcalloc(sizeof(ClockRange), 1); + clockRanges->next = NULL; + if (!pScrn->progClock) { + if (pScrn->videoRam < 1024) + clockRanges->ClockMulFactor = 2; + if (pScrn->bitsPerPixel == 16) + clockRanges->ClockMulFactor = 2; + } + clockRanges->minClock = pTrident->MinClock; + clockRanges->maxClock = pTrident->MaxClock; + clockRanges->clockIndex = -1; /* programmable */ + clockRanges->interlaceAllowed = TRUE; + clockRanges->doubleScanAllowed = FALSE; /* XXX check this */ + + /* + * xf86ValidateModes will check that the mode HTotal and VTotal values + * don't exceed the chipset's limit if pScrn->maxHValue and + * pScrn->maxVValue are set. Since our TRIDENTValidMode() already takes + * care of this, we don't worry about setting them here. + */ + + if (pScrn->bitsPerPixel == 24) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Disabling Engine due to 24bpp.\n"); + pTrident->NoAccel = TRUE; + } + + /* Select valid modes from those available */ + if (pTrident->NoAccel || Is3Dchip) { + /* + * XXX Assuming min pitch 256, max 4096 + * XXX Assuming min height 128, max 4096 + */ + i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, + pScrn->display->modes, clockRanges, + NULL, 256, 4096, + pScrn->bitsPerPixel, 128, 4096, + pScrn->display->virtualX, + pScrn->display->virtualY, + pTrident->FbMapSize, + LOOKUP_BEST_REFRESH); + } else { + /* + * XXX Assuming min height 128, max 2048 + */ + i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, + pScrn->display->modes, clockRanges, + GetAccelPitchValues(pScrn), 0, 0, + pScrn->bitsPerPixel, 128, 2048, + pScrn->display->virtualX, + pScrn->display->virtualY, + pTrident->FbMapSize, + LOOKUP_BEST_REFRESH); + } + + if (i == -1) { + if (IsPciCard && UseMMIO) { + TRIDENTDisableMMIO(pScrn); + TRIDENTUnmapMem(pScrn); + } + TRIDENTFreeRec(pScrn); + return FALSE; + } + + /* Prune the modes marked as invalid */ + xf86PruneDriverModes(pScrn); + + if (i == 0 || pScrn->modes == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); + if (IsPciCard && UseMMIO) { + TRIDENTDisableMMIO(pScrn); + TRIDENTUnmapMem(pScrn); + } + TRIDENTFreeRec(pScrn); + return FALSE; + } + + xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V); + + /* Set the current mode to the first in the list */ + pScrn->currentMode = pScrn->modes; + + /* Print the list of modes being used */ + xf86PrintModes(pScrn); + + /* Set display resolution */ + xf86SetDpi(pScrn, 0, 0); + + /* Load bpp-specific modules */ + switch (pScrn->bitsPerPixel) { + case 8: + pTrident->EngineOperation |= 0x00; + break; + case 16: + pTrident->EngineOperation |= 0x01; + break; + case 24: + pTrident->EngineOperation |= 0x03; + break; + case 32: + pTrident->EngineOperation |= 0x02; + break; + } + + if (xf86LoadSubModule(pScrn, "fb") == NULL) { + if (IsPciCard && UseMMIO) { + TRIDENTDisableMMIO(pScrn); + TRIDENTUnmapMem(pScrn); + } + TRIDENTFreeRec(pScrn); + return FALSE; + } + + xf86LoaderReqSymLists(fbSymbols, NULL); + + if (!xf86LoadSubModule(pScrn, "i2c")) { + if (IsPciCard && UseMMIO) { + TRIDENTDisableMMIO(pScrn); + TRIDENTUnmapMem(pScrn); + } + TRIDENTFreeRec(pScrn); + return FALSE; + } + + xf86LoaderReqSymLists(i2cSymbols, NULL); + + /* Load shadow if needed */ + if (pTrident->ShadowFB) { + if (!xf86LoadSubModule(pScrn, "shadow")) { + TRIDENTFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymLists(shadowSymbols, NULL); + } + + /* Load XAA if needed */ + if (!pTrident->NoAccel) { + if (!pTrident->useEXA) { + if (!xf86LoadSubModule(pScrn, "xaa")) { + if (IsPciCard && UseMMIO) { + TRIDENTDisableMMIO(pScrn); + TRIDENTUnmapMem(pScrn); + } + TRIDENTFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymLists(xaaSymbols, NULL); + } + + if (pTrident->useEXA) { + XF86ModReqInfo req; + int errmaj, errmin; + + memset(&req, 0, sizeof(req)); + + req.majorversion = 2; + if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, &req, + &errmaj, &errmin)) + { + LoaderErrorMsg(NULL, "exa", errmaj, errmin); + if (IsPciCard && UseMMIO) { + TRIDENTDisableMMIO(pScrn); + TRIDENTUnmapMem(pScrn); + } + TRIDENTFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymLists(exaSymbols, NULL); + } + + switch (pScrn->displayWidth * pScrn->bitsPerPixel / 8) { + case 512: + case 8192: + pTrident->EngineOperation |= 0x00; + break; + case 1024: + pTrident->EngineOperation |= 0x04; + break; + case 2048: + pTrident->EngineOperation |= 0x08; + break; + case 4096: + pTrident->EngineOperation |= 0x0C; + break; + } + } + + /* Load DDC if needed */ + /* This gives us DDC1 - we should be able to get DDC2B using i2c */ + + if (! ddcLoaded) + if (!xf86LoadSubModule(pScrn, "ddc")) { + if (IsPciCard && UseMMIO) { + TRIDENTDisableMMIO(pScrn); + TRIDENTUnmapMem(pScrn); + } + TRIDENTFreeRec(pScrn); + return FALSE; + } + + xf86LoaderReqSymLists(ddcSymbols, NULL); + + if (IsPciCard && UseMMIO) { + TRIDENTDisableMMIO(pScrn); + TRIDENTUnmapMem(pScrn); + } + + pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; + + if (pTrident->IsCyber && pTrident->MMIOonly) + pScrn->racIoFlags = 0; + else + pScrn->racIoFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; + + pTrident->FbMapSize = pScrn->videoRam * 1024; + + return TRUE; +} + +/* + * Map the framebuffer and MMIO memory. + */ + +static Bool +TRIDENTMapMem(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + vgaHWPtr hwp = VGAHWPTR(pScrn); + int mapsize = 0x10000; + + if (Is3Dchip) mapsize = 0x20000; + + if (IsPciCard && UseMMIO) + pTrident->IOBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, + pTrident->PciTag, pTrident->IOAddress, mapsize); + else { + pTrident->IOBase = xf86MapDomainMemory(pScrn->scrnIndex, VIDMEM_MMIO, + pTrident->PciTag, pTrident->IOAddress, 0x1000); + pTrident->IOBase += 0xF00; + } + + if (pTrident->IOBase == NULL) + return FALSE; + + if (pTrident->Linear) { + if (pTrident->FbMapSize != 0) { + pTrident->FbBase = xf86MapPciMem(pScrn->scrnIndex, + VIDMEM_FRAMEBUFFER, + pTrident->PciTag, + (unsigned long)pTrident->FbAddress, + pTrident->FbMapSize); + if (pTrident->FbBase == NULL) + return FALSE; + } + } + else + pTrident->FbBase = hwp->Base; + + return TRUE; +} + +/* + * Unmap the framebuffer and MMIO memory. + */ + +static Bool +TRIDENTUnmapMem(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int mapsize = 0x10000; + + if (Is3Dchip) mapsize = 0x20000; + + /* + * Unmap IO registers to virtual address space + */ + if (IsPciCard && UseMMIO) + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTrident->IOBase, mapsize); + else { + pTrident->IOBase -= 0xF00; + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTrident->IOBase, 0x1000); + } + pTrident->IOBase = NULL; + + if (pTrident->Linear) { + if (pTrident->FbMapSize != 0) { + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTrident->FbBase, + pTrident->FbMapSize); + pTrident->FbBase = NULL; + } + } + + return TRUE; +} + + +/* + * This function saves the video state. + */ +static void +TRIDENTSave(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident; + vgaRegPtr vgaReg; + TRIDENTRegPtr tridentReg; + + pTrident = TRIDENTPTR(pScrn); + vgaReg = &VGAHWPTR(pScrn)->SavedReg; + tridentReg = &pTrident->SavedReg; + + vgaHWSave(pScrn, vgaReg, VGA_SR_MODE | VGA_SR_CMAP | + (IsPrimaryCard ? VGA_SR_FONTS : 0)); + + if (pScrn->progClock) + TridentSave(pScrn, tridentReg); + else + TVGASave(pScrn, tridentReg); + + if (pTrident->TVChipset != 0) + VIA_SaveTVDepentVGAReg(pScrn); +} + + +/* + * Initialise a new mode. This is currently still using the old + * "initialise struct, restore/write struct to HW" model. That could + * be changed. + */ + +static Bool +TRIDENTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + vgaRegPtr vgaReg; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + TRIDENTRegPtr tridentReg; + + WAITFORVSYNC; + + TridentFindClock(pScrn,mode->Clock); + + switch (pTrident->Chipset) { + case TGUI9660: + case TGUI9680: + case PROVIDIA9682: + case PROVIDIA9685: + case IMAGE975: + case IMAGE985: + case BLADE3D: + case CYBERBLADEI7: + case CYBERBLADEI7D: + case CYBERBLADEI1: + case CYBERBLADEI1D: + case CYBERBLADEAI1: + case CYBERBLADEAI1D: + case CYBER9520: + case CYBER9525DVD: + case CYBERBLADEE4: + case CYBER9397: + case CYBER9397DVD: + case BLADEXP: + case CYBERBLADEXPAI1: + case CYBERBLADEXP4: + case XP5: + /* Get ready for MUX mode */ + if (pTrident->MUX && + pScrn->bitsPerPixel == 8 && + !mode->CrtcHAdjusted) { + ErrorF("BARF\n"); + mode->CrtcHDisplay >>= 1; + mode->CrtcHSyncStart >>= 1; + mode->CrtcHSyncEnd >>= 1; + mode->CrtcHBlankStart >>= 1; + mode->CrtcHBlankEnd >>= 1; + mode->CrtcHTotal >>= 1; + mode->CrtcHAdjusted = TRUE; + } + break; + default: + if (pScrn->videoRam < 1024 && + !mode->CrtcHAdjusted) { + mode->CrtcHDisplay <<= 1; + mode->CrtcHSyncStart <<= 1; + mode->CrtcHSyncEnd <<= 1; + mode->CrtcHBlankStart <<= 1; + mode->CrtcHBlankEnd <<= 1; + mode->CrtcHTotal <<= 1; + mode->CrtcHAdjusted = TRUE; + } + break; + } + + vgaHWUnlock(hwp); + /* Initialise the ModeReg values */ + if (!vgaHWInit(pScrn, mode)) + return FALSE; + + pScrn->vtSema = TRUE; + /* + * We used to do this at a later time. + * Now since READOUT isn't defined any more + * we do it here. + * The original NOTE read: + * TridentInit() has to modify registers + * that have already been set by vgaHWRestore(). + * So we call it _after_ vgaHWRestore() has + * programmed these registers. + */ + if (pScrn->progClock) { + if (!TridentInit(pScrn, mode)) + return FALSE; + } else { + if (!TVGAInit(pScrn, mode)) + return FALSE; + } + + /* Program the registers */ + vgaHWProtect(pScrn, TRUE); + vgaReg = &hwp->ModeReg; + tridentReg = &pTrident->ModeReg; + + vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE); + if (pScrn->progClock) + TridentRestore(pScrn, tridentReg); + else + TVGARestore(pScrn, tridentReg); + + vgaHWProtect(pScrn, FALSE); + + if (xf86IsPc98()) + PC98TRIDENTEnable(pScrn); + + if (pTrident->TVChipset != 0) + VIA_TVInit(pScrn); + + return TRUE; +} + +/* + * Restore the initial (text) mode. + */ +static void +TRIDENTRestore(ScrnInfoPtr pScrn) +{ + vgaHWPtr hwp; + vgaRegPtr vgaReg; + TRIDENTPtr pTrident; + TRIDENTRegPtr tridentReg; + + hwp = VGAHWPTR(pScrn); + pTrident = TRIDENTPTR(pScrn); + vgaReg = &hwp->SavedReg; + tridentReg = &pTrident->SavedReg; + + vgaHWProtect(pScrn, TRUE); + + if (pScrn->progClock) + TridentRestore(pScrn, tridentReg); + else + TVGARestore(pScrn, tridentReg); + + vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE | VGA_SR_CMAP | + (IsPrimaryCard ? VGA_SR_FONTS : 0)); + + if (pTrident->TVChipset != 0) + VIA_RestoreTVDependVGAReg(pScrn); + + vgaHWProtect(pScrn, FALSE); +} + + +/* Mandatory */ + +/* This gets called at the start of each server generation */ + +static Bool +TRIDENTScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) +{ + /* The vgaHW references will disappear one day */ + ScrnInfoPtr pScrn; + vgaHWPtr hwp; + TRIDENTPtr pTrident; + int ret; + VisualPtr visual; + unsigned char *FBStart; + int width, height, displayWidth; + + /* + * First get the ScrnInfoRec + */ + pScrn = xf86Screens[pScreen->myNum]; + pTrident = TRIDENTPTR(pScrn); + + if (IsPrimaryCard) { + if (!vgaHWMapMem(pScrn)) + return FALSE; + } + + /* Map the TRIDENT memory and MMIO areas */ + if (!TRIDENTMapMem(pScrn)) + return FALSE; + + if (!xf86IsPc98()) { +#ifdef VBE_INFO + if (pTrident->vbeModes) { + pTrident->pVbe = VBEInit(NULL,pTrident->pEnt->index); + pTrident->Int10 = pTrident->pVbe->pInt10; + } else +#endif + { + if (xf86LoadSubModule(pScrn, "int10")) { + xf86LoaderReqSymLists(int10Symbols, NULL); + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Initializing int10\n"); + pTrident->Int10 = xf86InitInt10(pTrident->pEnt->index); + } + } + } + + hwp = VGAHWPTR(pScrn); + + if (IsPciCard && UseMMIO) { + TRIDENTEnableMMIO(pScrn); + + /* Initialize the MMIO vgahw functions */ + vgaHWSetMmioFuncs(hwp, pTrident->IOBase, 0); + } + + /* Save the current state */ + TRIDENTSave(pScrn); + + /* + * Some Trident chip on PC-9821 needs setup, + * because VGA chip is not initialized by VGA BIOS. + */ + if (IsPciCard && xf86IsPc98()) { + PC98TRIDENTInit(pScrn); + } else tridentSetModeBIOS(pScrn,pScrn->currentMode); + + /* Initialise the first mode */ + if (!TRIDENTModeInit(pScrn, pScrn->currentMode)) + return FALSE; + + /* Darken the screen for aesthetic reasons and set the viewport */ + TRIDENTSaveScreen(pScreen, SCREEN_SAVER_ON); + TRIDENTAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + + /* + * The next step is to setup the screen's visuals, and initialise the + * framebuffer code. In cases where the framebuffer's default + * choices for things like visual layouts and bits per RGB are OK, + * this may be as simple as calling the framebuffer's ScreenInit() + * function. If not, the visuals will need to be setup before calling + * a fb ScreenInit() function and fixed up after. + * + * For most PC hardware at depths >= 8, the defaults that fb uses + * are not appropriate. In this driver, we fixup the visuals after. + */ + + /* + * Reset visual list. + */ + miClearVisualTypes(); + + /* Setup the visuals we support. */ + + if (!miSetVisualTypes(pScrn->depth, + miGetDefaultVisualMask(pScrn->depth), + pScrn->rgbBits, pScrn->defaultVisual)) { + if (pTrident->pVbe) + vbeFree(pTrident->pVbe); + else + xf86FreeInt10(pTrident->Int10); + return FALSE; + } + + miSetPixmapDepths (); + + /* FIXME - we don't do shadowfb for < 4 */ + displayWidth = pScrn->displayWidth; + if (pTrident->Rotate) { + height = pScrn->virtualX; + width = pScrn->virtualY; + } else { + width = pScrn->virtualX; + height = pScrn->virtualY; + } + + if(pTrident->ShadowFB) { + pTrident->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width); + pTrident->ShadowPtr = xalloc(pTrident->ShadowPitch * height); + displayWidth = pTrident->ShadowPitch / (pScrn->bitsPerPixel >> 3); + FBStart = pTrident->ShadowPtr; + } else { + pTrident->ShadowFB = FALSE; + pTrident->ShadowPtr = NULL; + FBStart = pTrident->FbBase; + } + + /* + * Call the framebuffer layer's ScreenInit function, and fill in other + * pScreen fields. + */ + + switch (pScrn->bitsPerPixel) { + case 8: + case 16: + case 24: + case 32: + ret = fbScreenInit(pScreen, FBStart, width, + height, pScrn->xDpi, pScrn->yDpi, + displayWidth, pScrn->bitsPerPixel); + + break; + default: + xf86DrvMsg(scrnIndex, X_ERROR, + "Internal error: invalid bpp (%d) in TRIDENTScrnInit\n", + pScrn->bitsPerPixel); + ret = FALSE; + break; + } + if (!ret) { + if (pTrident->pVbe) + vbeFree(pTrident->pVbe); + else + xf86FreeInt10(pTrident->Int10); + return FALSE; + } + if (pScrn->bitsPerPixel > 8) { + /* Fixup RGB ordering */ + visual = pScreen->visuals + pScreen->numVisuals; + while (--visual >= pScreen->visuals) { + if ((visual->class | DynamicClass) == DirectColor) { + visual->offsetRed = pScrn->offset.red; + visual->offsetGreen = pScrn->offset.green; + visual->offsetBlue = pScrn->offset.blue; + visual->redMask = pScrn->mask.red; + visual->greenMask = pScrn->mask.green; + visual->blueMask = pScrn->mask.blue; + } + } + } + + /* must be after RGB ordering fixed */ + fbPictureInit (pScreen, 0, 0); + + xf86SetBlackWhitePixels(pScreen); + + pTrident->BlockHandler = pScreen->BlockHandler; + pScreen->BlockHandler = TRIDENTBlockHandler; + + if (!pTrident->ShadowFB) + TRIDENTDGAInit(pScreen); + + if (!pTrident->Linear) { + miBankInfoPtr pBankInfo; + + /* Setup the vga banking variables */ + pBankInfo = xnfcalloc(sizeof(miBankInfoRec),1); + if (pBankInfo == NULL) { + if (pTrident->pVbe) + vbeFree(pTrident->pVbe); + else + xf86FreeInt10(pTrident->Int10); + return FALSE; + } + pBankInfo->pBankA = pTrident->FbBase; + pBankInfo->pBankB = pTrident->FbBase; + pBankInfo->BankSize = 0x10000; + pBankInfo->nBankDepth = (pScrn->depth == 4) ? 1 : pScrn->depth; + + pBankInfo->SetSourceBank = + (miBankProcPtr)TVGA8900SetRead; + pBankInfo->SetDestinationBank = + (miBankProcPtr)TVGA8900SetWrite; + pBankInfo->SetSourceAndDestinationBanks = + (miBankProcPtr)TVGA8900SetReadWrite; + if (!miInitializeBanking(pScreen, pScrn->virtualX, pScrn->virtualY, + pScrn->displayWidth, pBankInfo)) { + xfree(pBankInfo); + pBankInfo = NULL; + if (pTrident->pVbe) + vbeFree(pTrident->pVbe); + else + xf86FreeInt10(pTrident->Int10); + return FALSE; + } + } + + { + BoxRec AvailFBArea; + + AvailFBArea.x1 = 0; + AvailFBArea.y1 = 0; + AvailFBArea.x2 = pScrn->displayWidth; + AvailFBArea.y2 = pTrident->FbMapSize / (pScrn->displayWidth * + pScrn->bitsPerPixel / 8); + + if (AvailFBArea.y2 > 2047) AvailFBArea.y2 = 2047; + + if (xf86InitFBManager(pScreen, &AvailFBArea)) { + int cpp = pScrn->bitsPerPixel / 8; + int area = AvailFBArea.y2 * pScrn->displayWidth; + int areaoffset = area * cpp; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %i scanlines of offscreen memory for area's \n", + AvailFBArea.y2 - pScrn->virtualY); + + if (xf86InitFBManagerLinear(pScreen, area, ((pTrident->FbMapSize/cpp) - area))) { + xf86DrvMsg(scrnIndex, X_INFO, + "Using %ld bytes of offscreen memory for linear (offset=0x%x)\n", (pTrident->FbMapSize - areaoffset), areaoffset); + } + } + } + + if (Is3Dchip) { + if ((pTrident->Chipset == CYBERBLADEI7) || + (pTrident->Chipset == CYBERBLADEI7D) || + (pTrident->Chipset == CYBERBLADEI1) || + (pTrident->Chipset == CYBERBLADEI1D) || + (pTrident->Chipset == CYBERBLADEAI1) || + (pTrident->Chipset == CYBERBLADEAI1D) || + (pTrident->Chipset == CYBERBLADEE4) || + (pTrident->Chipset == BLADE3D)) { + if (pTrident->useEXA) + BladeExaInit(pScreen); + else + BladeXaaInit(pScreen); + } else + if ((pTrident->Chipset == CYBERBLADEXP4) || + (pTrident->Chipset == XP5)) { + if (pTrident->useEXA) + XP4ExaInit(pScreen); + else + XP4XaaInit(pScreen); + } else + if ((pTrident->Chipset == BLADEXP) || + (pTrident->Chipset == CYBERBLADEXPAI1)) { + XPAccelInit(pScreen); + } else { + ImageAccelInit(pScreen); + } + } else { + TridentAccelInit(pScreen); + } + + miInitializeBackingStore(pScreen); + xf86SetBackingStore(pScreen); + + /* Initialise cursor functions */ + miDCInitialize (pScreen, xf86GetPointerScreenFuncs()); + + if (pTrident->HWCursor) { + xf86SetSilkenMouse(pScreen); + TridentHWCursorInit(pScreen); + } + + /* Initialise default colourmap */ + if (!miCreateDefColormap(pScreen)) { + if (pTrident->pVbe) + vbeFree(pTrident->pVbe); + else + xf86FreeInt10(pTrident->Int10); + return FALSE; + } + if(!xf86HandleColormaps(pScreen, 256, 6, TridentLoadPalette, + TridentSetOverscan, CMAP_RELOAD_ON_MODE_SWITCH|CMAP_PALETTED_TRUECOLOR)) { + if (pTrident->pVbe) + vbeFree(pTrident->pVbe); + else + xf86FreeInt10(pTrident->Int10); + return FALSE; + } + if(pTrident->ShadowFB) { + if(pTrident->Rotate) { + if (!pTrident->PointerMoved) { + pTrident->PointerMoved = pScrn->PointerMoved; + pScrn->PointerMoved = TRIDENTPointerMoved; + } + switch (pScrn->bitsPerPixel) { + case 8: pTrident->RefreshArea = TRIDENTRefreshArea8; break; + case 16: pTrident->RefreshArea = TRIDENTRefreshArea16; break; + case 24: pTrident->RefreshArea = TRIDENTRefreshArea24; break; + case 32: pTrident->RefreshArea = TRIDENTRefreshArea32; break; + } + } else { + pTrident->RefreshArea = TRIDENTRefreshArea; + } + shadowInit (pScreen, TRIDENTShadowUpdate, 0); + } + + xf86DPMSInit(pScreen, (DPMSSetProcPtr)TRIDENTDisplayPowerManagementSet, 0); + + pScrn->memPhysBase = pTrident->FbAddress; + pScrn->fbOffset = 0; + + if (pTrident->Chipset >= TGUI9660) + TRIDENTInitVideo(pScreen); + + pTrident->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = TRIDENTCloseScreen; + pScreen->SaveScreen = TRIDENTSaveScreen; + + /* Report any unused options (only for the first generation) */ + if (serverGeneration == 1) { + xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); + } + +#if 0 + TRIDENTI2CInit(pScreen); + + xf86PrintEDID(xf86DoEDID_DDC2(pScrn->scrnIndex,pTrident->DDC)); +#endif + + return TRUE; +} + +/* Usually mandatory */ +Bool +TRIDENTSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) +{ + return TRIDENTModeInit(xf86Screens[scrnIndex], mode); +} + + +/* + * This function is used to initialize the Start Address - the first + * displayed location in the video memory. + */ +/* Usually mandatory */ +void +TRIDENTAdjustFrame(int scrnIndex, int x, int y, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + TRIDENTPtr pTrident; + int base = y * pScrn->displayWidth + x; + int vgaIOBase; + CARD8 temp; + + pTrident = TRIDENTPTR(pScrn); + vgaIOBase = VGAHWPTR(pScrn)->IOBase; + + switch (pScrn->bitsPerPixel) { + case 8: + if (pScrn->progClock) + base = (base & 0xFFFFFFF8) >> 2; + else + base = (base & 0xFFFFFFF8) >> 3; + break; + case 16: + base >>= 1; + break; + case 24: + base = (((base + 1) & ~0x03) * 3) >> 2; + break; + case 32: + break; + } + + /* CRT bits 0-15 */ + OUTW(vgaIOBase + 4, (base & 0x00FF00) | 0x0C); + OUTW(vgaIOBase + 4, ((base & 0x00FF) << 8) | 0x0D); + /* CRT bit 16 */ + OUTB(vgaIOBase + 4, CRTCModuleTest); temp = INB(vgaIOBase + 5) & 0xDF; + OUTB(vgaIOBase + 5, temp | ((base & 0x10000) >> 11)); + /* CRT bit 17-19 */ + OUTB(vgaIOBase + 4, CRTHiOrd); temp = INB(vgaIOBase + 5) & 0xF8; + OUTB(vgaIOBase + 5, temp | ((base & 0xE0000) >> 17)); +} + + +/* + * This is called when VT switching back to the X server. Its job is + * to reinitialise the video mode. + */ + +/* Mandatory */ +static Bool +TRIDENTEnterVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + if (IsPciCard && UseMMIO) TRIDENTEnableMMIO(pScrn); + + /* Should we re-save the text mode on each VT enter? */ + if (!TRIDENTModeInit(pScrn, pScrn->currentMode)) + return FALSE; + + if (pTrident->InitializeAccelerator) + pTrident->InitializeAccelerator(pScrn); + + return TRUE; +} + + +/* + * This is called when VT switching away from the X server. Its job is + * to restore the previous (text) mode. + * + * We may wish to remap video/MMIO memory too. + */ + +/* Mandatory */ +static void +TRIDENTLeaveVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + vgaHWPtr hwp = VGAHWPTR(pScrn); + + if (!pTrident->NoAccel && !pTrident->useEXA) + pTrident->AccelInfoRec->Sync(pScrn); + else if (!pTrident->NoAccel && pTrident->useEXA) + pTrident->EXADriverPtr->WaitMarker(pScrn->pScreen, 0); + + TRIDENTRestore(pScrn); + vgaHWLock(hwp); + + if (xf86IsPc98()) + PC98TRIDENTDisable(pScrn); + + if (IsPciCard && UseMMIO) TRIDENTDisableMMIO(pScrn); +} + + +/* + * This is called at the end of each server generation. It restores the + * original (text) mode. It should really also unmap the video memory too. + */ + +/* Mandatory */ +static Bool +TRIDENTCloseScreen(int scrnIndex, ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + vgaHWPtr hwp = VGAHWPTR(pScrn); + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + if (pScrn->vtSema) { + if (!pTrident->NoAccel && !pTrident->useEXA) + pTrident->AccelInfoRec->Sync(pScrn); + else if (!pTrident->NoAccel && pTrident->useEXA) + pTrident->EXADriverPtr->WaitMarker(pScreen, 0); + + if (xf86IsPc98()) + PC98TRIDENTDisable(pScrn); + + TRIDENTRestore(pScrn); + vgaHWLock(hwp); + if (IsPciCard && UseMMIO) TRIDENTDisableMMIO(pScrn); + TRIDENTUnmapMem(pScrn); + } + if (pTrident->AccelInfoRec) + XAADestroyInfoRec(pTrident->AccelInfoRec); + if (pTrident->EXADriverPtr) { + exaDriverFini(pScreen); + xfree(pTrident->EXADriverPtr); + pTrident->EXADriverPtr = NULL; + } + if (pTrident->CursorInfoRec) + xf86DestroyCursorInfoRec(pTrident->CursorInfoRec); + if (pTrident->ShadowPtr) + xfree(pTrident->ShadowPtr); + if (pTrident->DGAModes) + xfree(pTrident->DGAModes); + pScrn->vtSema = FALSE; + + if(pTrident->BlockHandler) + pScreen->BlockHandler = pTrident->BlockHandler; + + if (pTrident->pVbe) + vbeFree(pTrident->pVbe); + else + xf86FreeInt10(pTrident->Int10); + pScreen->CloseScreen = pTrident->CloseScreen; + return (*pScreen->CloseScreen)(scrnIndex, pScreen); +} + + +/* Free up any per-generation data structures */ + +/* Optional */ +static void +TRIDENTFreeScreen(int scrnIndex, int flags) +{ + if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) + vgaHWFreeHWRec(xf86Screens[scrnIndex]); + TRIDENTFreeRec(xf86Screens[scrnIndex]); +} + + +/* Checks if a mode is suitable for the selected chipset. */ + +/* Optional */ +static ModeStatus +TRIDENTValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + if (pTrident->lcdActive && (pTrident->lcdMode != 0xff)){ + if (((mode->HDisplay > LCD[pTrident->lcdMode].display_x) + || (mode->VDisplay > LCD[pTrident->lcdMode].display_y))) { + xf86DrvMsg(scrnIndex,X_INFO, "Removing mode (%dx%d) " + "larger than the LCD panel (%dx%d)\n", + mode->HDisplay, + mode->VDisplay, + LCD[pTrident->lcdMode].display_x, + LCD[pTrident->lcdMode].display_y); + return(MODE_BAD); + } + if (((float)mode->HDisplay/(float)mode->VDisplay) > 2.0) { + xf86DrvMsg(scrnIndex,X_INFO, "Removing mode (%dx%d) " + "unusual aspect ratio\n", + mode->HDisplay, + mode->VDisplay); + return(MODE_BAD); + } + } + return (MODE_OK); +} + +/* Do screen blanking */ + +/* Mandatory */ +static Bool +TRIDENTSaveScreen(ScreenPtr pScreen, int mode) +{ + return vgaHWSaveScreen(pScreen, mode); +} + +static void +TRIDENTEnableMMIO(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + IOADDRESS vgaIOBase = pTrident->PIOBase + VGAHWPTR(pScrn)->IOBase; + CARD8 temp = 0, protect = 0; + + /* + * Skip MMIO Enable in PC-9821 PCI Trident Card!! + * Because of lack of non PCI VGA port + */ + if (IsPciCard && xf86IsPc98()) + return; + + /* Goto New Mode */ + outb(pTrident->PIOBase + 0x3C4, 0x0B); + inb(pTrident->PIOBase + 0x3C5); + + /* Unprotect registers */ + if (pTrident->Chipset > PROVIDIA9685) { + outb(pTrident->PIOBase + 0x3C4, Protection); + protect = inb(pTrident->PIOBase + 0x3C5); + outb(pTrident->PIOBase + 0x3C5, 0x92); + } + outb(pTrident->PIOBase + 0x3C4, NewMode1); + temp = inb(pTrident->PIOBase + 0x3C5); + outb(pTrident->PIOBase + 0x3C5, 0x80); + + /* Enable MMIO */ + outb(vgaIOBase + 4, PCIReg); + pTrident->REGPCIReg = inb(vgaIOBase + 5); + outb(vgaIOBase + 5, pTrident->REGPCIReg | 0x01); /* Enable it */ + + /* Protect registers */ + if (pTrident->Chipset > PROVIDIA9685) { + OUTB(0x3C4, Protection); + OUTB(0x3C5, protect); + } + OUTB(0x3C4, NewMode1); + OUTB(0x3C5, temp); +} + +static void +TRIDENTDisableMMIO(ScrnInfoPtr pScrn) +{ + int vgaIOBase = VGAHWPTR(pScrn)->IOBase; + CARD8 temp = 0, protect = 0; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + /* + * Skip MMIO Disable in PC-9821 PCI Trident Card!! + * Because of lack of non PCI VGA port + */ + if (IsPciCard && xf86IsPc98()) + return; + + /* Goto New Mode */ + OUTB(0x3C4, 0x0B); temp = INB(0x3C5); + + /* Unprotect registers */ + OUTB(0x3C4, NewMode1); temp = INB(0x3C5); + OUTB(0x3C5, 0x80); + if (pTrident->Chipset > PROVIDIA9685) { + OUTB(0x3C4, Protection); + protect = INB(0x3C5); + OUTB(0x3C5, 0x92); + } + + /* Disable MMIO access */ + OUTB(vgaIOBase + 4, PCIReg); + pTrident->REGPCIReg = INB(vgaIOBase + 5); + OUTB(vgaIOBase + 5, pTrident->REGPCIReg & 0xFE); + + /* Protect registers */ + if (pTrident->Chipset > PROVIDIA9685) { + outb(pTrident->PIOBase + 0x3C4, Protection); + outb(pTrident->PIOBase + 0x3C5, protect); + } + outb(pTrident->PIOBase + 0x3C4, NewMode1); + outb(pTrident->PIOBase + 0x3C5, temp); +} + +/* Initialize VGA Block for Trident Chip on PC-98x1 */ +static void +PC98TRIDENTInit(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + switch (pTrident->Chipset) { + case TGUI9660: + case TGUI9680: + case PROVIDIA9682: + PC98TRIDENT96xxInit(pScrn); + break; + case CYBER9320: + case CYBER9385: + PC98TRIDENT9385Init(pScrn); + break; + default: /* Run 96xx code as default */ + PC98TRIDENT96xxInit(pScrn); + break; + } +} + +static void +PC98TRIDENTEnable(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + switch (pTrident->Chipset) { + case TGUI9660: + case TGUI9680: + case PROVIDIA9682: + PC98TRIDENT96xxEnable(pScrn); + break; + case CYBER9320: + case CYBER9385: + PC98TRIDENT9385Enable(pScrn); + break; + default: /* Run 96xx code as default */ + PC98TRIDENT96xxEnable(pScrn); + break; + } +} + +static void +PC98TRIDENTDisable(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + switch (pTrident->Chipset) { + case TGUI9660: + case TGUI9680: + case PROVIDIA9682: + PC98TRIDENT96xxDisable(pScrn); + break; + case CYBER9320: + case CYBER9385: + PC98TRIDENT9385Disable(pScrn); + break; + default: /* Run 96xx code as default */ + PC98TRIDENT96xxDisable(pScrn); + break; + } +} + +/* Initialize VGA Block for Cyber9385 on PC-98x1 */ +static void +PC98TRIDENT9385Init(ScrnInfoPtr pScrn) +{ +/* Nothing to initialize */ +} + +static void +PC98TRIDENT9385Enable(ScrnInfoPtr pScrn) +{ + outb(0xFAC, 0x02); +} + +static void +PC98TRIDENT9385Disable(ScrnInfoPtr pScrn) +{ + outb(0xFAC, 0x00); +} + +/* Initialize VGA Block for Trident96xx on PC-98x1 */ +static void +PC98TRIDENT96xxInit(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + vgaHWPtr hwp = VGAHWPTR(pScrn); + CARD8 temp = 0; + + vgaHWProtect(pScrn, TRUE); + + /* Video SusSystem Enable */ + temp = INB(0x3CC); + OUTB(0x3C2, temp | 0xC3); + /* Switch Old */ + OUTB(0x3C4, 0x0B); temp = INB(0x3C5); + OUTW(0x3C4, 0x0B | (temp << 8)); + /* Select Configuration Port 1 */ + OUTB(0x3C4, 0x0E); temp = INB(0x3C5); + OUTW(0x3C4, 0x0E | ((temp | 0x20) << 8)); + + OUTB(0x3C4, 0x0c); + if((INB(0x3C5) & 0x10) == 0x10) + { + OUTB(0x3C4, 0x0E | (temp << 8)); + OUTB(0x94, 0x00); + OUTB(0x102, 0x01); + OUTB(0x94, 0x20); + temp = INB(0x3C3); + OUTB(0x3C3, temp | 0x01); + } else { + OUTB(0x3C4, 0x0E | (temp << 8)); + OUTB(0x46E8, 0x10); + OUTB(0x102, 0x01); + OUTB(0x46E8, 0x08); + } + + INB(0x3DA); + OUTB(0x3C0,0x10); + OUTB(0x3C0,0x41); + + /* Register Unlock */ + vgaHWUnlock(hwp); + OUTB(0x3C4, 0x0B); temp = INB(0x3C5); /* Switch New */ + OUTB(0x3C4, 0x0E); temp = INB(0x3C5); + OUTW(0x3C4, 0x0E | ((temp | 0x80) << 8)); + + /* For Speed Up [Facoor 2 at Xengine] */ + OUTW(0x3D4, 0x3820); /* Command FIFO Register */ + OUTW(0x3D4, 0x2020); /* Command FIFO Register */ + /* Latency Control Registers 0x30 - 0x32 */ + /* Parameter Range 0x00 - 0x0F */ + /* Tune these parameter to avoid GE Timeout */ + OUTW(0x3D4, 0x0E30); /* Display Queue Latency Control */ + /* 8bpp GE No Timeout Parameter 0x0D - 0x0F for PC-9821Xa7 TGUi9680 */ + OUTW(0x3D4, 0x0031); /* Frame Buffer Latency Control */ + OUTW(0x3D4, 0x0032); /* Display & Frame Buffer Latency Control */ + OUTW(0x3D4, 0x213B); /* Clock and Tuning */ + + /* MCLK Init */ + OUTB(0x43C6, 0xAF); OUTB(0x43C7, 0x00); /* 80.0MHz */ +#if 0 + /* Sample MCLKs */ + OUTB(0x43C6, 0xAF); OUTB(0x43C7, 0x00); /* 80.0MHz */ + OUTB(0x43C6, 0xA7); OUTB(0x43C7, 0x00); /* 77.0MHz */ + OUTB(0x43C6, 0x8E); OUTB(0x43C7, 0x00); /* 75.0MHz */ + OUTB(0x43C6, 0x86); OUTB(0x43C7, 0x00); /* 72.0MHz */ + OUTB(0x43C6, 0x8F); OUTB(0x43C7, 0x00); /* 67.2MHz */ + OUTB(0x43C6, 0xD5); OUTB(0x43C7, 0x02); /* 61.6MHz */ +#endif + + /* Register Lock */ + OUTB(0x3C4, 0x0B); temp = INB(0x3C5); /* Switch New */ + OUTB(0x3C4, 0x0E); temp = INB(0x3C5); + OUTW(0x3C4, 0x0E | ((temp & 0x7F) << 8)); + vgaHWLock(hwp); + + vgaHWProtect(pScrn, FALSE); +} + +static void +PC98TRIDENT96xxEnable(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + CARD8 temp = 0; + + outb(0x68, 0x0E); + outb(0x6A, 0x07); + outb(0x6A, 0x8F); + outb(0x6A, 0x06); + + vgaHWProtect(pScrn, TRUE); + + OUTB(0x3D4, 0x23); temp = INB(0x3D5); + OUTW(0x3D4, 0x23 | ((temp & 0xDF) << 8)); + + OUTB(0x3D4, 0x29); temp = INB(0x3D5); + OUTW(0x3D4, 0x29 | ((temp | 0x04) << 8)); + + OUTB(0x83C8, 0x04); temp = INB(0x83c6); + OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp | 0x06)); + + OUTB(0x83C8, 0x04); temp = INB(0x83c6); + OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp | 0x08)); + + OUTB(0x3CE, 0x23); temp = INB(0x3CF); + OUTW(0x3CE, 0x23 | ((temp & 0xFC) << 8)); + + OUTB(0x83C8, 0x04); temp = INB(0x83c6); + OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp | 0x01)); + + OUTB(0x3C4, 0x01); temp = INB(0x3C5); + OUTW(0x3C4, 0x01 | ((temp & 0xEF) << 8)); + + vgaHWProtect(pScrn, FALSE); + + outb(0xFAC, 0x02); +} + +static void +PC98TRIDENT96xxDisable(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + CARD8 temp = 0; + + outb(0xFAC, 0x00); + + vgaHWProtect(pScrn, TRUE); + + OUTB(0x3C4, 0x01); temp = INB(0x3C5); + OUTW(0x3C4, 0x01 | ((temp | 0x10) << 8)); + + OUTB(0x83C8, 0x04); temp = INB(0x83c6); + OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xFE)); + + OUTB(0x3CE, 0x23); temp = INB(0x3CF); + OUTW(0x3CE, 0x23 | (((temp & 0xFC) | 0x01) << 8)); + + OUTB(0x83C8, 0x04); temp = INB(0x83c6); + OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xFD)); + + OUTB(0x83C8, 0x04); temp = INB(0x83c6); + OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xCF)); + + OUTB(0x83C8, 0x04); temp = INB(0x83c6); + OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xF7)); + + OUTB(0x83C8, 0x04); temp = INB(0x83c6); + OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xFB)); + + OUTB(0x3D4, 0x29); temp = INB(0x3D5); + OUTW(0x3D4, 0x29 | ((temp & 0xFB) << 8)); + + OUTB(0x3D4, 0x23); temp = INB(0x3D5); + OUTW(0x3D4, 0x23 | ((temp | 0x20) << 8)); + + vgaHWProtect(pScrn, FALSE); + + outb(0x6A, 0x07); + outb(0x6A, 0x8E); + outb(0x6A, 0x06); + outb(0x68, 0x0F); +} + + +/* + * This is a terrible hack! If we are on a notebook in a stretched + * mode and don't want full screen we use the BIOS to set an unstreched + * mode. + */ +void +tridentSetModeBIOS(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + +#ifdef VBE_INFO + if (pTrident->vbeModes) { + vbeSaveRestoreRec vbesr; + vbesr.stateMode = VBECalcVbeModeIndex(pTrident->vbeModes, + mode, pScrn->bitsPerPixel); + vbesr.pstate = NULL; + if (vbesr.stateMode) { + if (IsPciCard && UseMMIO) + TRIDENTDisableMMIO(pScrn); + VBEVesaSaveRestore(pTrident->pVbe,&vbesr,MODE_RESTORE); + if (IsPciCard && UseMMIO) + TRIDENTEnableMMIO(pScrn); + return; + } else + xf86DrvMsg(pScrn->scrnIndex,X_WARNING,"No BIOS Mode matches " + "%ix%I@%ibpp\n",mode->HDisplay,mode->VDisplay, + pScrn->bitsPerPixel); + } +#endif + /* This function is only for LCD screens, and also when we have + * int10 available */ + + if (pTrident->IsCyber && pTrident->lcdMode && pTrident->Int10) { + int i = pTrident->lcdMode; + if ((pScrn->currentMode->HDisplay != LCD[i].display_x) /* !fullsize? */ + || (pScrn->currentMode->VDisplay != LCD[i].display_y)) { + if (pTrident->lcdActive) { /* LCD Active ?*/ + int h_str, v_str; + + OUTB(0x3CE,HorStretch); h_str = INB(0x3CF) & 0x01; + OUTB(0x3CE,VertStretch); v_str = INB(0x3CF) & 0x01; + if (h_str || v_str) { + OUTB(0x3C4, 0x11); OUTB(0x3C5, 0x92); + OUTW(0x3CE, BiosReg ); + pTrident->Int10->ax = 0x3; + pTrident->Int10->num = 0x10; + if (IsPciCard && UseMMIO) + TRIDENTDisableMMIO(pScrn); + xf86ExecX86int10(pTrident->Int10); + if (IsPciCard && UseMMIO) + TRIDENTEnableMMIO(pScrn); + } + } + } + } +} + +/* Currently we only test for 1400 */ +static int +TRIDENTLcdDisplaySize (xf86MonPtr pMon) +{ + if (pMon) { + int i,j; + + for (i = 0; i < STD_TIMINGS; i++) { + if (pMon->timings2[i].hsize == 1400) { + return 1400; + } + } + /* + * If not explicitely set try to find out if the display supports + * the 1400 mode. For sanity check if DDC comes from a digital + * display. + */ + if (DIGITAL(pMon->features.input_type)) { + for (i = 0; i < DET_TIMINGS; i++) { + if (pMon->det_mon[i].type == DS_STD_TIMINGS) { + for (j = 0; j < 5; j++) { + if (pMon->det_mon[i].section.std_t[j].hsize == 1400) { + return 1400; + } + } + } else if (pMon->det_mon[i].type == DT) { + if (pMon->det_mon[i].section.d_timings.h_active == 1400) { + return 1400; + } + } + } + } + } + return 0; +} + diff --git a/driver/xf86-video-trident/src/trident_i2c.c b/driver/xf86-video-trident/src/trident_i2c.c new file mode 100644 index 000000000..bf3a27386 --- /dev/null +++ b/driver/xf86-video-trident/src/trident_i2c.c @@ -0,0 +1,80 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_i2c.c,v 1.2 1999/01/23 09:55:59 dawes Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "compiler.h" + +#include "xf86Pci.h" +#include "xf86PciInfo.h" + +#include "vgaHW.h" + +#include "trident.h" +#include "trident_regs.h" + +static void +TRIDENTI2CPutBits(I2CBusPtr b, int clock, int data) { + unsigned int reg = 0x0C; + TRIDENTPtr pTrident = ((TRIDENTPtr)b->DriverPrivate.ptr); + int vgaIOBase = VGAHWPTR(pTrident->pScrn)->IOBase; + +#if 0 + if(!TRIDENTI2CSwitchToBus(b)) + return FALSE; +#endif + + if(clock) reg |= 2; + if(data) reg |= 1; + OUTB(vgaIOBase + 4, I2C); + OUTB(vgaIOBase + 5, reg); +#if 0 + ErrorF("TRIDENTI2CPutBits: %d %d\n", clock, data); +#endif +} + +static void +TRIDENTI2CGetBits(I2CBusPtr b, int *clock, int *data) { + unsigned int reg; + TRIDENTPtr pTrident = ((TRIDENTPtr)b->DriverPrivate.ptr); + int vgaIOBase = VGAHWPTR(pTrident->pScrn)->IOBase; + +#if 0 + if(!TRIDENTI2CSwitchToBus(b)) + return FALSE; +#endif + + OUTB(vgaIOBase + 4, I2C); + reg = INB(vgaIOBase + 5); + *clock = (reg & 0x02) != 0; + *data = (reg & 0x01) != 0; +#if 0 + ErrorF("TRIDENTI2CGetBits: %d %d\n", *clock, *data); +#endif +} + +Bool +TRIDENTI2CInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + I2CBusPtr I2CPtr; + + I2CPtr = xf86CreateI2CBusRec(); + + pTrident->DDC = I2CPtr; + + I2CPtr->BusName = "DDC"; + I2CPtr->scrnIndex = pScrn->scrnIndex; + I2CPtr->I2CPutBits = TRIDENTI2CPutBits; + I2CPtr->I2CGetBits = TRIDENTI2CGetBits; + I2CPtr->DriverPrivate.ptr = pTrident; + + if(!xf86I2CBusInit(I2CPtr)) + return FALSE; + + return TRUE; +} diff --git a/driver/xf86-video-trident/src/trident_regs.h b/driver/xf86-video-trident/src/trident_regs.h new file mode 100644 index 000000000..c0bc99c54 --- /dev/null +++ b/driver/xf86-video-trident/src/trident_regs.h @@ -0,0 +1,454 @@ +/* + * Copyright 1992-2003 by Alan Hourihane, North Wales, UK. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Alan Hourihane, alanh@fairlite.demon.co.uk + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_regs.h,v 1.27 2003/09/05 22:07:29 alanh Exp $ */ + +#define DEBUG 1 + +#define NTSC 14.31818 +#define PAL 17.73448 + +/* General Registers */ +#define SPR 0x1F /* Software Programming Register (videoram) */ + +/* 3C4 */ +#define RevisionID 0x09 +#define ConfPort1 0x0C +#define ConfPort2 0x0C +#define NewMode2 0x0D +#define OldMode2 0x00 /* Should be 0x0D - dealt with in trident_dac.c */ +#define OldMode1 0x0E +#define NewMode1 0x0E +#define Protection 0x11 +#define Threshold 0x12 +#define MCLKLow 0x16 +#define MCLKHigh 0x17 +#define ClockLow 0x18 +#define ClockHigh 0x19 +#define SSetup 0x20 +#define SKey 0x37 +#define SPKey 0x57 +#define GBslope1 0xB4 +#define GBslope2 0xB5 +#define GBslope3 0xB6 +#define GBslope4 0xB7 +#define GBintercept1 0xB8 +#define GBintercept2 0xB9 +#define GBintercept3 0xBA +#define GBintercept4 0xBB + +/* 3x4 */ +#define Offset 0x13 +#define Underline 0x14 +#define CRTCMode 0x17 +#define CRTCModuleTest 0x1E +#define FIFOControl 0x20 +#define LinearAddReg 0x21 +#define DRAMTiming 0x23 +#define New32 0x23 +#define RAMDACTiming 0x25 +#define CRTHiOrd 0x27 +#define AddColReg 0x29 +#define InterfaceSel 0x2A +#define HorizOverflow 0x2B +#define GETest 0x2D +#define Performance 0x2F +#define GraphEngReg 0x36 +#define I2C 0x37 +#define PixelBusReg 0x38 +#define PCIReg 0x39 +#define DRAMControl 0x3A +#define MiscContReg 0x3C +#define CursorXLow 0x40 +#define CursorXHigh 0x41 +#define CursorYLow 0x42 +#define CursorYHigh 0x43 +#define CursorLocLow 0x44 +#define CursorLocHigh 0x45 +#define CursorXOffset 0x46 +#define CursorYOffset 0x47 +#define CursorFG1 0x48 +#define CursorFG2 0x49 +#define CursorFG3 0x4A +#define CursorFG4 0x4B +#define CursorBG1 0x4C +#define CursorBG2 0x4D +#define CursorBG3 0x4E +#define CursorBG4 0x4F +#define CursorControl 0x50 +#define PCIRetry 0x55 +#define PreEndControl 0x56 +#define PreEndFetch 0x57 +#define PCIMaster 0x60 +#define Enhancement0 0x62 +#define NewEDO 0x64 +#define TVinterface 0xC0 +#define TVMode 0xC1 +#define ClockControl 0xCF + + +/* 3CE */ +#define MiscExtFunc 0x0F +#define MiscIntContReg 0x2F +#define CyberControl 0x30 +#define CyberEnhance 0x31 +#define FPConfig 0x33 +#define VertStretch 0x52 +#define HorStretch 0x53 +#define BiosMode 0x5c +#define BiosNewMode1 0x5a +#define BiosNewMode2 0x5c +#define BiosReg 0x5d +#define DisplayEngCont 0xD1 + +/* Graphics Engine for 9420/9430 */ + +#define GER_INDEX 0x210A +#define GER_BYTE0 0x210C +#define GER_BYTE1 0x210D +#define GER_BYTE2 0x210E +#define GER_BYTE3 0x210F +#define MMIOBASE 0x7C +#define OLDGER_STATUS 0x90 +#define OLDGER_MWIDTH 0xB8 +#define OLDGER_MFORMAT 0xBC +#define OLDGER_STYLE 0xC4 +#define OLDGER_FMIX 0xC8 +#define OLDGER_BMIX 0xC8 +#define OLDGER_FCOLOUR 0xD8 +#define OLDGER_BCOLOUR 0xDC +#define OLDGER_DIMXY 0xE0 +#define OLDGER_DESTLINEAR 0xE4 +#define OLDGER_DESTXY 0xF8 +#define OLDGER_COMMAND 0xFC +#define OLDGE_FILL 0x000A0000 /* Area Fill */ + +/* Graphics Engine for 9440/9660/9680 */ + +#define GER_STATUS 0x2120 +#define GE_BUSY 0x80 +#define GER_OPERMODE 0x2122 /* Byte for 9440, Word for 96xx */ +#define DST_ENABLE 0x200 /* Destination Transparency */ +#define GER_COMMAND 0x2124 +#define GE_NOP 0x00 /* No Operation */ +#define GE_BLT 0x01 /* BitBLT ROP3 only */ +#define GE_BLT_ROP4 0x02 /* BitBLT ROP4 (96xx only) */ +#define GE_SCANLINE 0x03 /* Scan Line */ +#define GE_BRESLINE 0x04 /* Bresenham Line */ +#define GE_SHVECTOR 0x05 /* Short Vector */ +#define GE_FASTLINE 0x06 /* Fast Line (96xx only) */ +#define GE_TRAPEZ 0x07 /* Trapezoidal fill (96xx only) */ +#define GE_ELLIPSE 0x08 /* Ellipse (96xx only) (RES) */ +#define GE_ELLIP_FILL 0x09 /* Ellipse Fill (96xx only) (RES)*/ +#define GER_FMIX 0x2127 +#define GER_DRAWFLAG 0x2128 /* long */ +#define FASTMODE 1<<28 +#define STENCIL 0x8000 +#define SOLIDFILL 0x4000 +#define TRANS_ENABLE 0x1000 +#define TRANS_REVERSE 0x2000 +#define YMAJ 0x0400 +#define XNEG 0x0200 +#define YNEG 0x0100 +#define SRCMONO 0x0040 +#define PATMONO 0x0020 +#define SCR2SCR 0x0004 +#define PAT2SCR 0x0002 +#define GER_FCOLOUR 0x212C /* Word for 9440, long for 96xx */ +#define GER_BCOLOUR 0x2130 /* Word for 9440, long for 96xx */ +#define GER_PATLOC 0x2134 /* Word */ +#define GER_DEST_XY 0x2138 +#define GER_DEST_X 0x2138 /* Word */ +#define GER_DEST_Y 0x213A /* Word */ +#define GER_SRC_XY 0x213C +#define GER_SRC_X 0x213C /* Word */ +#define GER_SRC_Y 0x213E /* Word */ +#define GER_DIM_XY 0x2140 +#define GER_DIM_X 0x2140 /* Word */ +#define GER_DIM_Y 0x2142 /* Word */ +#define GER_STYLE 0x2144 /* Long */ +#define GER_CKEY 0x2168 /* Long */ +#define GER_FPATCOL 0x2178 +#define GER_BPATCOL 0x217C +#define GER_PATTERN 0x2180 /* from 0x2180 to 0x21FF */ + +/* Additional - Graphics Engine for 96xx */ +#define GER_SRCCLIP_XY 0x2148 +#define GER_SRCCLIP_X 0x2148 /* Word */ +#define GER_SRCCLIP_Y 0x214A /* Word */ +#define GER_DSTCLIP_XY 0x214C +#define GER_DSTCLIP_X 0x214C /* Word */ +#define GER_DSTCLIP_Y 0x214E /* Word */ + +/* Graphics Engine for Cyberblade/i1 */ +#define GER_SRC1 0x2100 +#define GER_SRC2 0x2104 +#define GER_DST1 0x2108 +#define GER_DST2 0x210C +#define GER_CONTROL 0x2124 +#define GER_CTL_RESET (1 << 7) +#define GER_CTL_RESUME 0 +#define GER_DRAW_CMD 0x2144 +#define GER_OP_NULL 0 +#define GER_OP_RSVD1 (1 << 28) +#define GER_OP_LINE (2 << 28) +#define GER_OP_RSVD2 (3 << 28) +#define GER_OP_RSVD3 (4 << 28) +#define GER_OP_RSVD4 (5 << 28) +#define GER_OP_RSVD5 (6 << 28) +#define GER_OP_RSVD6 (7 << 28) +#define GER_OP_BLT_FB (8 << 28) +#define GER_OP_TXT_FB (9 << 28) +#define GER_OP_BLT_HOST (0xA << 28) +#define GER_OP_TRAP_POLY1 (0xB<< 28) +#define GER_OP_BLT_RE (0xC << 28) +#define GER_OP_TXT_RE (0xD << 28) +#define GER_OP_TRAP_POLY (0xE << 28) +#define GER_OP_RSVD7 (0xF << 28) + +/* Op args */ +#define GER_DRAW_SRC_COLOR (1 << 19) +#define GER_ROP_ENABLE (1 << 4) + +/* Blt, line & poly op operation sources */ +#define GER_BLT_SRC_HOST (0 << 2) +#define GER_BLT_SRC_FB (1 << 2) +#define GER_SRC_CONST (2 << 2) +#define GER_BLK_WRITE (3 << 2) + +#define GER_ROP 0x2148 +#define GER_CLIP0 0x2154 +#define GER_CLIP1 0x2158 +#define GER_FGCOLOR 0x2160 +#define GER_BITMASK 0x2184 +#define GER_PATSTYLE 0x216C +#define GER_DSTBASE0 0x21B8 +#define GER_DSTBASE1 0x21BC +#define GER_DSTBASE2 0x21C0 +#define GER_DSTBASE3 0x21C4 +#define GER_SRCBASE0 0x21C8 +#define GER_SRCBASE1 0x21CC +#define GER_SRCBASE2 0x21D0 +#define GER_SRCBASE3 0x21C4 + +/* Wait for VSync */ +#define WAITFORVSYNC \ + { \ + while (hwp->readST01(hwp)&0x8) {}; \ + while (!(hwp->readST01(hwp)&0x8)) {}; \ + } + +/* Defines for IMAGE Graphics Engine */ +#define IMAGE_GE_STATUS 0x2164 +#define IMAGE_GE_DRAWENV 0x2120 + +/* Defines for BLADE Graphics Engine */ +#define BLADE_GE_STATUS 0x2120 +#define BLADE_XP_GER_OPERMODE 0x2125 + +#define REPLICATE(r) \ +{ \ + if (pScrn->bitsPerPixel == 16) { \ + r = ((r & 0xFFFF) << 16) | (r & 0xFFFF); \ + } else \ + if (pScrn->bitsPerPixel == 8) { \ + r &= 0xFF; \ + r |= (r<<8); \ + r |= (r<<16); \ + } \ +} + +#define CHECKCLIPPING \ + if (pTrident->Clipping) { \ + pTrident->Clipping = FALSE; \ + if (pTrident->Chipset < PROVIDIA9682) { \ + TGUI_SRCCLIP_XY(0,0); \ + TGUI_DSTCLIP_XY(4095,2047); \ + } \ + } + + +/* Merge XY */ +#define XY_MERGE(x,y) \ + ((((CARD32)(y)&0xFFFF) << 16) | ((CARD32)(x) & 0xffff)) +#define XP_XY_MERGE(y,x) \ + ((((CARD32)(y)&0xFFFF) << 16) | ((CARD32)(x) & 0xffff)) + +#define TRIDENT_WRITE_REG(v,r) \ + MMIO_OUT32(pTrident->IOBase,(r),(v)) + +#define TRIDENT_READ_REG(r) \ + MMIO_IN32(pTrident->IOBase,(r)) + +#define OUTB(addr, data) \ +{ \ + if (IsPciCard && UseMMIO) { \ + MMIO_OUT8(pTrident->IOBase, addr, data); \ + } else { \ + outb(pTrident->PIOBase + (addr), data); \ + } \ +} +#define OUTW(addr, data) \ +{ \ + if (IsPciCard && UseMMIO) { \ + MMIO_OUT16(pTrident->IOBase, addr, data); \ + } else { \ + outw(pTrident->PIOBase + (addr), data); \ + } \ +} +#define INB(addr) \ +( \ + (IsPciCard && UseMMIO) ? \ + MMIO_IN8(pTrident->IOBase, addr) : \ + inb(pTrident->PIOBase + (addr)) \ +) + +#define OUTW_3C4(reg) \ + OUTW(0x3C4, (tridentReg->tridentRegs3C4[reg])<<8 | (reg)) +#define OUTW_3CE(reg) \ + OUTW(0x3CE, (tridentReg->tridentRegs3CE[reg])<<8 | (reg)) +#define OUTW_3x4(reg) \ + OUTW(vgaIOBase + 4, (tridentReg->tridentRegs3x4[reg])<<8 | (reg)) +#define INB_3x4(reg) \ + OUTB(vgaIOBase + 4, reg); \ + tridentReg->tridentRegs3x4[reg] = INB(vgaIOBase + 5) +#define INB_3C4(reg) \ + OUTB(0x3C4, reg); \ + tridentReg->tridentRegs3C4[reg] = INB(0x3C5); +#define INB_3CE(reg) \ + OUTB(0x3CE, reg); \ + tridentReg->tridentRegs3CE[reg] = INB(0x3CF); + +#define VIDEOOUT(val,reg) \ + if (pTrident->Chipset >= CYBER9397) { \ + OUTW(0x3C4, (val << 8) | reg); \ + } else { \ + OUTB(0x83C8, reg); \ + OUTB(0x83C6, val); \ + } + + +#define BLTBUSY(b) \ + (b = MMIO_IN8(pTrident->IOBase,GER_STATUS) & GE_BUSY) +#define OLDBLTBUSY(b) \ + (b = MMIO_IN8(pTrident->IOBase,OLDGER_STATUS) & GE_BUSY) +#define IMAGE_STATUS(c) \ + MMIO_OUT32(pTrident->IOBase, IMAGE_GE_STATUS, (c)) +#define TGUI_STATUS(c) \ + MMIO_OUT8(pTrident->IOBase, GER_STATUS, (c)) +#define OLDTGUI_STATUS(c) \ + MMIO_OUT8(pTrident->IOBase, OLDGER_STATUS, (c)) +#define TGUI_OPERMODE(c) \ + MMIO_OUT16(pTrident->IOBase, GER_OPERMODE, (c)) +#define BLADE_XP_OPERMODE(c) \ + MMIO_OUT8(pTrident->IOBase, BLADE_XP_GER_OPERMODE, (c)) +/* XXX */ +#define OLDTGUI_OPERMODE(c) \ + { \ + MMIO_OUT16(pTrident->IOBase, OLDGER_MWIDTH, \ + vga256InfoRec.displayWidth - 1); \ + MMIO_OUT8(pTrident->IOBase, OLDGER_MFORMAT, (c)); \ + } +#define TGUI_FCOLOUR(c) \ + MMIO_OUT32(pTrident->IOBase, GER_FCOLOUR, (c)) +#define TGUI_FPATCOL(c) \ + MMIO_OUT32(pTrident->IOBase, GER_FPATCOL, (c)) +#define OLDTGUI_FCOLOUR(c) \ + MMIO_OUT32(pTrident->IOBase, OLDGER_FCOLOUR, (c)) +#define TGUI_BCOLOUR(c) \ + MMIO_OUT32(pTrident->IOBase, GER_BCOLOUR, (c)) +#define TGUI_BPATCOL(c) \ + MMIO_OUT32(pTrident->IOBase, GER_BPATCOL, (c)) +#define OLDTGUI_BCOLOUR(c) \ + MMIO_OUT32(pTrident->IOBase, OLDGER_BCOLOUR, (c)) +#define IMAGE_DRAWENV(c) \ + MMIO_OUT32(pTrident->IOBase, IMAGE_GE_DRAWENV, (c)) +#define TGUI_DRAWFLAG(c) \ + MMIO_OUT32(pTrident->IOBase, GER_DRAWFLAG, (c)) +#define OLDTGUI_STYLE(c) \ + MMIO_OUT16(pTrident->IOBase, OLDGER_STYLE, (c)) +#define TGUI_FMIX(c) \ + MMIO_OUT8(pTrident->IOBase, GER_FMIX, (c)) +#define OLDTGUI_FMIX(c) \ + MMIO_OUT8(pTrident->IOBase, OLDGER_FMIX, (c)) +#define OLDTGUI_BMIX(c) \ + MMIO_OUT8(pTrident->IOBase, OLDGER_BMIX, (c)) +#define TGUI_DIM_XY(w,h) \ + MMIO_OUT32(pTrident->IOBase, GER_DIM_XY, XY_MERGE((w)-1,(h)-1)) +#define XP_DIM_XY(w,h) \ + MMIO_OUT32(pTrident->IOBase, GER_DIM_XY, XY_MERGE((h),(w))) +#define TGUI_STYLE(c) \ + MMIO_OUT32(pTrident->IOBase, GER_STYLE, (c)) +#define OLDTGUI_DIMXY(w,h) \ + MMIO_OUT32(pTrident->IOBase, OLDGER_DIMXY, XY_MERGE((w)-1,(h)-1)) +#define TGUI_SRC_XY(x,y) \ + MMIO_OUT32(pTrident->IOBase, GER_SRC_XY, XY_MERGE(x,y)) +#define XP_SRC_XY(x,y) \ + MMIO_OUT32(pTrident->IOBase, GER_SRC_XY, XP_XY_MERGE(x,y)) +#define TGUI_DEST_XY(x,y) \ + MMIO_OUT32(pTrident->IOBase, GER_DEST_XY, XY_MERGE(x,y)) +#define XP_DEST_XY(x,y) \ + MMIO_OUT32(pTrident->IOBase, GER_DEST_XY, XP_XY_MERGE(x,y)) +#define OLDTGUI_DESTXY(x,y) \ + MMIO_OUT32(pTrident->IOBase, OLDGER_DESTXY, XY_MERGE(x,y)) +#define OLDTGUI_DESTLINEAR(c) \ + MMIO_OUT32(pTrident->IOBase, OLDGER_DESTLINEAR, (c)) +#define TGUI_SRCCLIP_XY(x,y) \ + MMIO_OUT32(pTrident->IOBase, GER_SRCCLIP_XY, XY_MERGE(x,y)) +#define TGUI_DSTCLIP_XY(x,y) \ + MMIO_OUT32(pTrident->IOBase, GER_DSTCLIP_XY, XY_MERGE(x,y)) +#define TGUI_PATLOC(addr) \ + MMIO_OUT16(pTrident->IOBase, GER_PATLOC, (addr)) +#define TGUI_CKEY(c) \ + MMIO_OUT32(pTrident->IOBase, GER_CKEY, (c)) +#define IMAGEBUSY(b) \ + (b = MMIO_IN32(pTrident->IOBase,IMAGE_GE_STATUS) & 0xF0000000) +#define BLADEBUSY(b) \ + (b = MMIO_IN32(pTrident->IOBase,BLADE_GE_STATUS) & 0xFA800000) +#define IMAGE_OUT(addr, c) \ + MMIO_OUT32(pTrident->IOBase, addr, (c)) +#define BLADE_OUT(addr, c) \ + MMIO_OUT32(pTrident->IOBase, addr, (c)) +#define TGUI_OUTL(addr, c) \ + MMIO_OUT32(pTrident->IOBase, addr, (c)) +#define TGUI_COMMAND(c) \ + MMIO_OUT8(pTrident->IOBase, GER_COMMAND, (c)) +#define OLDTGUI_COMMAND(c) \ + do { \ + OLDTGUI_OPERMODE(GE_OP); \ + OLDTGUISync(); \ + MMIO_OUT32(pTrident->IOBase, OLDGER_COMMAND, (c)); \ + } while (0) + +/* Cyber FP support */ +#define SHADOW_ENABLE(oldval) \ + do {\ + OUTB(0x3CE, CyberControl); \ + oldval = INB(0x3CF);\ + OUTB(0x3CF,oldval | (1 << 6));\ + } while (0) +#define SHADOW_RESTORE(val) \ + do {\ + OUTB(0x3CE, CyberControl); \ + OUTB(0x3CF,val); \ + } while (0); diff --git a/driver/xf86-video-trident/src/trident_shadow.c b/driver/xf86-video-trident/src/trident_shadow.c new file mode 100644 index 000000000..9f56a61c8 --- /dev/null +++ b/driver/xf86-video-trident/src/trident_shadow.c @@ -0,0 +1,263 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_shadow.c,v 1.2 2000/11/16 19:45:01 eich Exp $ */ + +/* + Copyright (c) 1999, 2000 The XFree86 Project Inc. + based on code written by Mark Vojkovich <markv@valinux.com> +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "shadowfb.h" +#include "servermd.h" +#include "trident.h" + +void +TRIDENTRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int width, height, Bpp, FBPitch; + unsigned char *src, *dst; + + Bpp = pScrn->bitsPerPixel >> 3; + FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel); + + while(num--) { + width = (pbox->x2 - pbox->x1) * Bpp; + height = pbox->y2 - pbox->y1; + src = pTrident->ShadowPtr + (pbox->y1 * pTrident->ShadowPitch) + + (pbox->x1 * Bpp); + dst = pTrident->FbBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp); + + while(height--) { + memcpy(dst, src, width); + dst += FBPitch; + src += pTrident->ShadowPitch; + } + + pbox++; + } +} + +void +TRIDENTShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf) +{ + RegionPtr damage = &pBuf->damage; + ScrnInfoPtr pScrn; + pScrn = xf86Screens[pScreen->myNum]; + + (TRIDENTPTR(pScrn))->RefreshArea (pScrn, REGION_NUM_RECTS(damage), + REGION_RECTS(damage)); +} + +void +TRIDENTPointerMoved(int index, int x, int y) +{ + ScrnInfoPtr pScrn = xf86Screens[index]; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int newX, newY; + + if(pTrident->Rotate == 1) { + newX = pScrn->pScreen->height - y - 1; + newY = x; + } else { + newX = y; + newY = pScrn->pScreen->width - x - 1; + } + + (*pTrident->PointerMoved)(index, newX, newY); +} + +void +TRIDENTRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int count, width, height, y1, y2, dstPitch, srcPitch; + CARD8 *dstPtr, *srcPtr, *src; + CARD32 *dst; + + dstPitch = pScrn->displayWidth; + srcPitch = -pTrident->Rotate * pTrident->ShadowPitch; + + while(num--) { + width = pbox->x2 - pbox->x1; + y1 = pbox->y1 & ~3; + y2 = (pbox->y2 + 3) & ~3; + height = (y2 - y1) >> 2; /* in dwords */ + + if(pTrident->Rotate == 1) { + dstPtr = pTrident->FbBase + + (pbox->x1 * dstPitch) + pScrn->virtualX - y2; + srcPtr = pTrident->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1; + } else { + dstPtr = pTrident->FbBase + + ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; + srcPtr = pTrident->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1; + } + + while(width--) { + src = srcPtr; + dst = (CARD32*)dstPtr; + count = height; + while(count--) { + *(dst++) = src[0] | (src[srcPitch] << 8) | + (src[srcPitch * 2] << 16) | + (src[srcPitch * 3] << 24); + src += srcPitch * 4; + } + srcPtr += pTrident->Rotate; + dstPtr += dstPitch; + } + + pbox++; + } +} + + +void +TRIDENTRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int count, width, height, y1, y2, dstPitch, srcPitch; + CARD16 *dstPtr, *srcPtr, *src; + CARD32 *dst; + + dstPitch = pScrn->displayWidth; + srcPitch = -pTrident->Rotate * pTrident->ShadowPitch >> 1; + + while(num--) { + width = pbox->x2 - pbox->x1; + y1 = pbox->y1 & ~1; + y2 = (pbox->y2 + 1) & ~1; + height = (y2 - y1) >> 1; /* in dwords */ + + if(pTrident->Rotate == 1) { + dstPtr = (CARD16*)pTrident->FbBase + + (pbox->x1 * dstPitch) + pScrn->virtualX - y2; + srcPtr = (CARD16*)pTrident->ShadowPtr + + ((1 - y2) * srcPitch) + pbox->x1; + } else { + dstPtr = (CARD16*)pTrident->FbBase + + ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; + srcPtr = (CARD16*)pTrident->ShadowPtr + + (y1 * srcPitch) + pbox->x2 - 1; + } + + while(width--) { + src = srcPtr; + dst = (CARD32*)dstPtr; + count = height; + while(count--) { + *(dst++) = src[0] | (src[srcPitch] << 16); + src += srcPitch * 2; + } + srcPtr += pTrident->Rotate; + dstPtr += dstPitch; + } + + pbox++; + } +} + + +/* this one could be faster */ +void +TRIDENTRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int count, width, height, y1, y2, dstPitch, srcPitch; + CARD8 *dstPtr, *srcPtr, *src; + CARD32 *dst; + + dstPitch = BitmapBytePad(pScrn->displayWidth * 24); + srcPitch = -pTrident->Rotate * pTrident->ShadowPitch; + + while(num--) { + width = pbox->x2 - pbox->x1; + y1 = pbox->y1 & ~3; + y2 = (pbox->y2 + 3) & ~3; + height = (y2 - y1) >> 2; /* blocks of 3 dwords */ + + if(pTrident->Rotate == 1) { + dstPtr = pTrident->FbBase + + (pbox->x1 * dstPitch) + ((pScrn->virtualX - y2) * 3); + srcPtr = pTrident->ShadowPtr + ((1 - y2) * srcPitch) + (pbox->x1 * 3); + } else { + dstPtr = pTrident->FbBase + + ((pScrn->virtualY - pbox->x2) * dstPitch) + (y1 * 3); + srcPtr = pTrident->ShadowPtr + (y1 * srcPitch) + (pbox->x2 * 3) - 3; + } + + while(width--) { + src = srcPtr; + dst = (CARD32*)dstPtr; + count = height; + while(count--) { + dst[0] = src[0] | (src[1] << 8) | (src[2] << 16) | + (src[srcPitch] << 24); + dst[1] = src[srcPitch + 1] | (src[srcPitch + 2] << 8) | + (src[srcPitch * 2] << 16) | + (src[(srcPitch * 2) + 1] << 24); + dst[2] = src[(srcPitch * 2) + 2] | (src[srcPitch * 3] << 8) | + (src[(srcPitch * 3) + 1] << 16) | + (src[(srcPitch * 3) + 2] << 24); + dst += 3; + src += srcPitch * 4; + } + srcPtr += pTrident->Rotate * 3; + dstPtr += dstPitch; + } + + pbox++; + } +} + +void +TRIDENTRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int count, width, height, dstPitch, srcPitch; + CARD32 *dstPtr, *srcPtr, *src, *dst; + + dstPitch = pScrn->displayWidth; + srcPitch = -pTrident->Rotate * pTrident->ShadowPitch >> 2; + + while(num--) { + width = pbox->x2 - pbox->x1; + height = pbox->y2 - pbox->y1; + + if(pTrident->Rotate == 1) { + dstPtr = (CARD32*)pTrident->FbBase + + (pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2; + srcPtr = (CARD32*)pTrident->ShadowPtr + + ((1 - pbox->y2) * srcPitch) + pbox->x1; + } else { + dstPtr = (CARD32*)pTrident->FbBase + + ((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1; + srcPtr = (CARD32*)pTrident->ShadowPtr + + (pbox->y1 * srcPitch) + pbox->x2 - 1; + } + + while(width--) { + src = srcPtr; + dst = dstPtr; + count = height; + while(count--) { + *(dst++) = *src; + src += srcPitch; + } + srcPtr += pTrident->Rotate; + dstPtr += dstPitch; + } + + pbox++; + } +} + + diff --git a/driver/xf86-video-trident/src/trident_tv.c b/driver/xf86-video-trident/src/trident_tv.c new file mode 100644 index 000000000..8086ce3d6 --- /dev/null +++ b/driver/xf86-video-trident/src/trident_tv.c @@ -0,0 +1,708 @@ +/* + * VIA TV additions + */ + +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_tv.c,v 1.1 2003/04/15 22:13:43 alanh Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "trident.h" +#include "trident_regs.h" + +/*************************************************************************** + * + * TV parameters for VT1621 + * + ***************************************************************************/ +#define TV_MODE 8 +#define TVX_MODE_SIZE 0X72 +#define TVX_CRTC_NUM 0x10 +#define TVX_REG_NUM 0x62 +#define TVX_VT1621_PORT 0x40 +#define SMBUS_BASE 0x5000 +unsigned char TVX_VT1621_Table[TV_MODE][TVX_MODE_SIZE] = { +{ +/* NTSC, 640x480, bpp=8,16 */ +0x02, 0x54, 0xE0, 0xFA, 0x11, 0x5D, 0x11, 0x57, 0x5A, 0x56, +0xA0, 0x26, 0x0A, 0x55, 0x37, 0x86, + +0x6A, 0x0B, 0x22, 0x27, 0x43, 0x50, 0x13, 0x50, +0xB0, 0x07, 0xEE, 0x15, 0x90, 0xE4, 0x00, 0xA8, +0x00, 0x00, 0x0E, 0x48, 0x38, 0x38, 0x00, 0x1C, +0x00, 0x40, 0x0C, 0x02, 0x01, 0x80, 0x00, 0x00, +0x0F, 0x06, 0x99, 0x7C, 0x04, 0x5D, 0x36, 0x9B, +0x54, 0x00, 0x00, 0xB4, 0x2F, 0x85, 0xFF, 0x00, +0x00, 0x17, 0x15, 0x21, 0x15, 0x05, 0x05, 0x02, +0x1B, 0x1B, 0x24, 0xF8, 0x07, 0x00, 0x00, 0x0F, +0x0F, 0x60, 0x01, 0x0A, 0x00, 0x05, 0x04, 0xFF, +0x03, 0x01, 0x90, 0x33, 0x00, 0x00, 0x00, 0x00, +0x00, 0x04, 0x47, 0x02, 0x02, 0xFD, 0x06, 0xf8, +0x0B, 0xF3, 0x0F, 0x70, 0x05, 0xF9, 0x0B, 0xF1, +0x11, 0x6E +}, +{ +/* NTSC, 800x600, bpp=8,16 */ +0X02, 0x79, 0XE0, 0x73, 0x02, 0x80, 0x01, 0x7A, 0x7E, 0xEC, +0xA0, 0x8A, 0x0E, 0xEB, 0x8B, 0x89, + +0x8B, 0x0B, 0x6A, 0x27, 0x43, 0x50, 0x12, 0x50, +0xBC, 0x0A, 0XE8, 0x15, 0x88, 0xDC, 0x00, 0x98, +0x00, 0x00, 0x0A, 0x48, 0x1C, 0x28, 0x03, 0x20, +0x00, 0x40, 0x36, 0x02, 0x03, 0x80, 0x00, 0x00, +0x0D, 0x04, 0x04, 0x7B, 0x00, 0x5D, 0xC1, 0x9B, +0x6B, 0x00, 0x00, 0xA1, 0x3F, 0x9D, 0x2F, 0x10, +0x00, 0x17, 0x15, 0x21, 0x15, 0x05, 0x05, 0x02, +0x1B, 0x1B, 0x24, 0xF8, 0x07, 0x00, 0x00, 0x0F, +0x0F, 0x60, 0x01, 0x0A, 0x00, 0x05, 0x04, 0xFF, +0x03, 0x01, 0xD6, 0x80, 0x00, 0x00, 0x00, 0x00, +0x00, 0x0C, 0x46, 0x02, 0x02, 0xFD, 0x06, 0xF8, +0x0B, 0xF3, 0x0F, 0x70, 0x05, 0xF9, 0x0B, 0xF1, +0x11, 0x6E +}, +{ +/* NTSC, 640x480, bpp=32 */ +0X02, 0x54, 0XE0, 0xFA, 0x11, 0x5D, 0x01, 0x57, 0x5A, 0x56, +0xA0, 0x26, 0x0A, 0X55, 0x37, 0x46, + +0x6A, 0x0B, 0x23, 0x33, 0x43, 0x50, 0x13, 0x51, +0xB0, 0x07, 0xAB, 0x15, 0x90, 0xA9, 0x00, 0x98, +0x00, 0x00, 0x0E, 0x48, 0x38, 0x38, 0x03, 0x1C, +0x00, 0x40, 0x0C, 0x02, 0x03, 0x80, 0x00, 0x00, +0x0F, 0x04, 0x99, 0x7A, 0x04, 0x5E, 0xB6, 0x90, +0x5B, 0x00, 0x00, 0x67, 0x2F, 0x88, 0xFA, 0x00, +0x00, 0x17, 0x15, 0x21, 0x15, 0x05, 0x05, 0x02, +0x1B, 0x1B, 0x24, 0xF8, 0x07, 0x00, 0x00, 0x0F, +0x0F, 0x60, 0x01, 0x0A, 0x00, 0x05, 0x04, 0xFF, +0x03, 0x01, 0xA0, 0x33, 0x1B, 0x00, 0X00, 0x00, +0x00, 0x08, 0x47, 0x02, 0x02, 0xFD, 0x06, 0xf8, +0x0B, 0xF3, 0x0F, 0x70, 0x05, 0xF9, 0x0B, 0xF1, +0x11, 0x6E +}, +{ +/* NTSC, 800x600, bpp=32 */ +0X02, 0x79, 0XE0, 0x73, 0x02, 0x80, 0x01, 0x7B, 0x7E, 0xEC, +0xA0, 0x8A, 0x0E, 0xEB, 0x8B, 0x49, + +0x8B, 0x0B, 0x6B, 0x27, 0x43, 0x50, 0x12, 0x2D, +0xBC, 0x0C, 0xED, 0x15, 0x88, 0xEE, 0x00, 0x99, +0x00, 0x00, 0x0A, 0x48, 0x1C, 0x28, 0x03, 0x20, +0x00, 0x40, 0x36, 0x02, 0x03, 0x80, 0x00, 0x00, +0x0D, 0x04, 0x04, 0x7A, 0x00, 0x5D, 0xC1, 0x9B, +0x6B, 0x00, 0x00, 0xA1, 0x3F, 0x9D, 0x2F, 0x10, +0x00, 0x17, 0x15, 0x21, 0x15, 0x05, 0x05, 0x02, +0x1B, 0x1B, 0x24, 0xF8, 0x07, 0x00, 0x00, 0x0F, +0x0F, 0x60, 0x01, 0x0A, 0x00, 0x05, 0x04, 0xFF, +0x03, 0x01, 0xC6, 0x90, 0x00, 0x00, 0x00, 0x00, +0x00, 0x08, 0x46, 0x02, 0x02, 0xFD, 0x06, 0xF8, +0x0B, 0xF3, 0x0F, 0x70, 0x05, 0xF9, 0x0B, 0xF1, +0x11, 0x6E +}, +{ +/* PAL, 640x480, bpp=8,16 */ +0X82, 0x5D, 0XE0, 0x23, 0x02, 0x64, 0x01, 0x56, 0x5A, 0x6F, +0xA0, 0x0D, 0x0F, 0x6E, 0x24, 0xC1, + +0x6B, 0x0B, 0x03, 0x67, 0x40, 0x50, 0x12, 0x96, +0xCE, 0x32, 0xFF, 0x01, 0x7E, 0xF6, 0x00, 0xA8, +0x00, 0x00, 0x07, 0x48, 0x20, 0x1C, 0x44, 0x60, +0x44, 0x4F, 0x1B, 0x02, 0x03, 0x80, 0x00, 0x00, +0x0C, 0x0C, 0xD7, 0x84, 0x04, 0x68, 0x3B, 0x9C, +0x57, 0x63, 0x17, 0xAC, 0x25, 0x80, 0x29, 0x10, +0x00, 0x1A, 0x22, 0x2A, 0x22, 0x05, 0x02, 0x00, +0x1C, 0x3D, 0x14, 0xFE, 0x03, 0x54, 0x01, 0xFE, +0x7E, 0x60, 0x00, 0x08, 0x00, 0x04, 0x07, 0x55, +0x01, 0x01, 0xA0, 0x33, 0x00, 0x00, 0x00, 0x00, +0x00, 0x0C, 0x4E, 0xFE, 0x03, 0xFB, 0x06, 0xF8, +0x0A, 0xF5, 0x0C, 0x73, 0x06, 0xF8, 0x0B, 0xF2, +0x10, 0x6F +}, +{ +/* PAL, 800x600, bpp=8,16 */ +0X82, 0x5B, 0XE0, 0x91, 0x02, 0x73, 0x07, 0x6C, 0x70, 0xEC, +0xA0, 0xA8, 0x0B, 0xEB, 0xAD, 0xC7, + +0x8B, 0x0B, 0x1A, 0x47, 0x40, 0x50, 0x12, 0x56, +0x00, 0x37, 0xF7, 0x00, 0x7D, 0xE2, 0x00, 0xB9, +0x00, 0x00, 0x0E, 0x48, 0x38, 0x38, 0x44, 0x62, +0x44, 0x4F, 0x53, 0x02, 0x07, 0x80, 0x00, 0x00, +0x0A, 0x05, 0xA2, 0x83, 0x08, 0x68, 0x46, 0x99, +0x68, 0x63, 0x17, 0xAC, 0x25, 0x80, 0x6B, 0x10, +0x00, 0x1A, 0x22, 0x2A, 0x22, 0x05, 0x02, 0x00, +0x1C, 0x3D, 0x14, 0xFE, 0x03, 0x54, 0x01, 0xFE, +0x7E, 0x60, 0x00, 0x08, 0x00, 0x04, 0x07, 0x55, +0x01, 0x01, 0xE6, 0x90, 0x00, 0x00, 0x00, 0x00, +0x00, 0x0C, 0x4D, 0xFB, 0x04, 0xFB, 0x07, 0xF8, +0x09, 0xF6, 0x0A, 0x74, 0x06, 0xF8, 0x0B, 0xF2, +0x10, 0x6F +}, +{ +/* PAL, 640x480, bpp=32 */ +0X82, 0x5D, 0XE0, 0x23, 0x02, 0x64, 0x01, 0x56, 0x5A, 0x6F, +0xA0, 0x0D, 0x0F, 0x6E, 0x24, 0x81, + +0x6B, 0x0B, 0x02, 0x67, 0x40, 0x50, 0x12, 0x93, +0xCE, 0x32, 0xF0, 0x01, 0x88, 0xE8, 0x00, 0xA8, +0x00, 0x00, 0x07, 0x48, 0x20, 0x1C, 0x44, 0x60, +0x44, 0x4F, 0x1B, 0x02, 0x03, 0x80, 0x00, 0x00, +0x0C, 0x05, 0xE2, 0x84, 0x00, 0x68, 0x3B, 0x9C, +0x57, 0x63, 0x17, 0xAC, 0x25, 0x80, 0x29, 0x10, +0x00, 0x1A, 0x22, 0x2A, 0x22, 0x05, 0x02, 0x00, +0x1C, 0x3D, 0x14, 0xFE, 0x03, 0x54, 0x01, 0xFE, +0x7E, 0x60, 0x00, 0x08, 0x00, 0x04, 0x07, 0x55, +0x01, 0x01, 0xA0, 0x33, 0x00, 0x00, 0x00, 0x00, +0x00, 0x0C, 0x4E, 0xFE, 0x03, 0xFB, 0x06, 0xF8, +0x0A, 0xF5, 0x0C, 0x73, 0x06, 0xF8, 0x0B, 0xF2, +0x10, 0x6F +}, +{ +/* PAL, 800x600, bpp=32 */ +0X82, 0x5B, 0XE0, 0x91, 0x02, 0x73, 0x07, 0x6C, 0x70, 0xEC, +0xA0, 0xA8, 0x0B, 0xEB, 0xAD, 0x87, + +0x8B, 0x0B, 0x1A, 0x67, 0x40, 0x50, 0x12, 0x53, +0x00, 0x37, 0xEE, 0x00, 0x83, 0xEB, 0x00, 0xB9, +0x00, 0x00, 0x0E, 0x48, 0x38, 0x38, 0x44, 0x62, +0x44, 0x4F, 0x53, 0x02, 0x07, 0x80, 0x00, 0x00, +0x0A, 0x05, 0x5E, 0x83, 0x08, 0x68, 0x46, 0x99, +0x68, 0x63, 0x17, 0xAC, 0x25, 0x80, 0x6B, 0x10, +0x00, 0x1A, 0x22, 0x2A, 0x22, 0x05, 0x02, 0x00, +0x1C, 0x3D, 0x14, 0xFE, 0x03, 0x54, 0x01, 0xFE, +0x7E, 0x60, 0x00, 0x08, 0x00, 0x04, 0x07, 0x55, +0x01, 0x01, 0xA0, 0x22, 0x00, 0x00, 0x00, 0x00, +0x00, 0x0C, 0x4D, 0xFB, 0x04, 0xFB, 0x07, 0xF8, +0x09, 0xF6, 0x0A, 0x74, 0x06, 0xF8, 0x0B, 0xF2, +0x10, 0x6F +} +}; +/* TV Parameters for CH7005C */ +#define TV_CH7005C_MODE_SIZE 45 +#define TV_CH7005C_CRTC_NUM 0x10 +#define TV_CH7005C_TVREG_NUM 29 +#define TV_CH7005C_PORT 0xEA +unsigned char TV_CH7005C_Table[TV_MODE][TV_CH7005C_MODE_SIZE]={ +{ +/* NTSC 640x480 bpp=8,16 */ +0x02, 0x80, 0x20, 0x02, 0x00, 0x5D, 0X80, 0X57, 0X80, 0X56, +0XBA, 0X10, 0X8C, 0X50, 0XF8, 0X7F, + +0X6A, 0X7A, 0X00, 0X09, 0X80, 0X66, 0X00, 0X60, +0X2E, 0XFF, 0X01, 0X0B, 0X0C, 0X03, 0X40, 0X3F, +0X7E, 0X40, 0X02, 0X00, 0X08, 0X00, 0X00, 0X00, +0X00, 0X00, 0X0A, 0X02, 0X05 +}, +{ +/* NTSC 800X600 bpp=8,16 */ +0x02, 0x80, 0x20, 0x02, 0x00, 0x7D, 0X80, 0X6E, 0X1C, 0XBA, +0XF0, 0X70, 0X8C, 0XBA, 0X78, 0X53, + +0X8C, 0X4A, 0X00, 0X09, 0X80, 0XAE, 0X01, 0X80, +0X2E, 0X02, 0X01, 0X0B, 0X7E, 0X7E, 0X7E, 0X7E, +0X7E, 0X40, 0X01, 0X0C, 0X00, 0X00, 0X00, 0X00, +0X00, 0X00, 0X0A, 0X00, 0X05 +}, +{ +/* NTSC 640x480 bpp=32 */ +0x02, 0x80, 0x20, 0x02, 0x00, 0x5D, 0X80, 0X57, 0X80, 0X56, +0XBA, 0X10, 0X8C, 0X50, 0XBD, 0X57, + +0X6A, 0X7A, 0X00, 0X09, 0X80, 0X67, 0X00, 0X60, +0X2E, 0XFF, 0X01, 0X0B, 0X0C, 0X03, 0X40, 0X3F, +0X7E, 0X40, 0X02, 0X00, 0X07, 0X0C, 0X0D, 0X00, +0X00, 0X00, 0X0A, 0X02, 0X05 +}, +{ +/* NTSC 800X600 bpp=32 */ +0x02, 0x80, 0x20, 0x02, 0x00, 0x7D, 0X80, 0X6E, 0X1C, 0XBA, +0XF0, 0X70, 0X8C, 0XBA, 0XF8, 0X53, + +0X8C, 0X4A, 0X00, 0X09, 0X80, 0XAF, 0X01, 0X80, +0X2E, 0X02, 0X01, 0X0B, 0X0C, 0X03, 0X40, 0X3F, +0X7E, 0X40, 0X01, 0X0C, 0X00, 0X00, 0X00, 0X00, +0X00, 0X00, 0X0A, 0X00, 0X05 +}, +{ +/* PAL 640x480 bpp=8,16 */ +0x82, 0x80, 0x20, 0x02, 0x00, 0x71, 0X74, 0X62, 0X84, 0X6F, +0XF0, 0X10, 0X09, 0XEB, 0X80, 0X5F, + +0X81, 0X4A, 0X00, 0X09, 0X80, 0X84, 0X00, 0X70, +0X28, 0X02, 0X01, 0X0B, 0X0C, 0X03, 0X40, 0X3F, +0X7E, 0X40, 0X02, 0X00, 0X08, 0X00, 0X00, 0X00, +0X00, 0X00, 0X0A, 0X01, 0X05 +}, +{ +/* PAL 800x600 bpp=8,16 */ +0x82, 0x80, 0x20, 0x02, 0x00, 0x73, 0X76, 0X6A, 0X8C, 0XEC, +0XF0, 0X7E, 0X09, 0XEB, 0X8F, 0X8D, + +0X83, 0X4A, 0X00, 0X09, 0X80, 0X7E, 0X00, 0X70, +0X3F, 0X02, 0X01, 0X0B, 0X0C, 0X03, 0X40, 0X3F, +0X7E, 0X40, 0X02, 0X00, 0X08, 0X00, 0X00, 0X00, +0X00, 0X00, 0X0A, 0X01, 0X05 +}, +{ +/* PAL 640x480 bpp=32 */ +0x82, 0x80, 0x20, 0x02, 0x00, 0x71, 0X74, 0X62, 0X84, 0X6F, +0XF0, 0X10, 0X09, 0XEB, 0X80, 0X1F, + +0X81, 0X4A, 0X00, 0X09, 0X80, 0X84, 0X00, 0X70, +0X28, 0X02, 0X01, 0X0B, 0X0C, 0X03, 0X40, 0X3F, +0X7E, 0X40, 0X02, 0X00, 0X08, 0X00, 0X00, 0X00, +0X00, 0X00, 0X0A, 0X01, 0X05 +}, +{ +/* PAL 800X600 bpp=32 */ +0x82, 0x80, 0x20, 0x02, 0x00, 0x73, 0X76, 0X6A, 0X8C, 0XEC, +0XF0, 0X7E, 0X09, 0XEB, 0X5D, 0X48, + +0X83, 0X4A, 0X00, 0X09, 0X80, 0X7E, 0X00, 0X70, +0X3F, 0X02, 0X01, 0X0B, 0X0C, 0X03, 0X40, 0X3F, +0X7E, 0X40, 0X02, 0X00, 0X08, 0X00, 0X00, 0X00, +0X00, 0X00, 0X0A, 0X01, 0X05 +} +}; + +static unsigned char smbus_read(ScrnInfoPtr pScrn, unsigned char bIndex, unsigned char devAdr) +{ + TRIDENTPtr pTrident=TRIDENTPTR(pScrn); + unsigned short i; + unsigned char bData; + + /* clear host status */ + OUTB(SMBUS_BASE, 0xFF); + + /* check SMBUS ready */ + for ( i = 0; i < 0xFFFF; i++ ) + if ( (INB(SMBUS_BASE) & 0x01) == 0 ) + break; + + /* set host command */ + OUTB(SMBUS_BASE+3, bIndex); + + /* set slave address */ + OUTB(SMBUS_BASE+4, devAdr | 0x01); + + /* start */ + OUTB(SMBUS_BASE+2, 0x48); + + /* SMBUS Wait Ready */ + for ( i = 0; i < 0xFFFF; i++ ) + if ( (INB(SMBUS_BASE) & 0x01) == 0 ) + break; + bData=INB(SMBUS_BASE+5); + + return bData; + +} + +static void smbus_write(ScrnInfoPtr pScrn, unsigned char bData, unsigned char bIndex, unsigned char devAdr) +{ + TRIDENTPtr pTrident=TRIDENTPTR(pScrn); + unsigned short i; + + /* clear host status */ + OUTB(SMBUS_BASE, 0xFF); + + /* check SMBUS ready */ + for ( i = 0; i < 0xFFFF; i++ ) + if ( (INB(SMBUS_BASE) & 0x01) == 0 ) + break; + + OUTB(SMBUS_BASE+2, 0x08); + + /* set host command */ + OUTB(SMBUS_BASE+3, bIndex); + + /* set slave address */ + OUTB(SMBUS_BASE+4, devAdr & 0xFE); + + OUTB(SMBUS_BASE+5, bData); + + /* start */ + OUTB(SMBUS_BASE+2, 0x48); + + /* SMBUS Wait Ready */ + for ( i = 0; i < 0xFFFF; i++ ) + if ( (INB(SMBUS_BASE) & 0x01) == 0 ) + break; +} +void VIA_SaveTVDepentVGAReg(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident=TRIDENTPTR(pScrn); + unsigned char protect; + unsigned char bTmp; + int i; + unsigned char VGA_RegIdx_about_TV[VGA_REGNUM_ABOUT_TV]={ + 0xD8,0XD9,/* SR */ + 0X33,/* GR */ + 0XC0,0XD0,0XD1,0XD2,0XD3,0XE0,0XE3,0XE4,0XE5,/* CR */ + 0XE6,0XE7,0XF0,0XF1,0XF6,0XFE,0XFF + }; + unsigned char TV_CH7005C_RegIdx[TV_CH7005C_TVREG_NUM]={ + 0X00,0X01,0X03,0X04,0X06,0X07,0X08,0X09, + 0X0A,0X0B,0X0D,0X0E,0X10,0X11,0X13,0X14, + 0X15,0X17,0X18,0X19,0X1A,0X1B,0X1C,0X1D, + 0X1E,0X1F,0X20,0X21,0X3D + }; + + /*ErrorF("VIAB3D: VIA_SaveTVDepentVGAReg:\n");*/ + + /* Unprotect */ + OUTB(0x3C4, 0x11); + protect = INB(0x3C5); + OUTB(0x3C5, 0x92); + + /* Set TV Hw environment */ + OUTB(0x3d4,0xc1); + OUTB(0x3d5,0x41); + + /* SR_d8,SR_d9 */ + for (i=0; i<2; i++) + { + OUTB(0x3c4,VGA_RegIdx_about_TV[i]); + bTmp=INB(0x3c5); + pTrident->DefaultTVDependVGASetting[i]=bTmp; + } + + /* GR_33 */ + OUTB(0x3ce,0x33); + bTmp=INB(0x3cf); + pTrident->DefaultTVDependVGASetting[2]=bTmp; + + /* CR_c0,d0,d1,d2,d3,e0,e3,e4,e5,e6,e7,f0,f1,f6,fe,ff */ + for (i=3; i<VGA_REGNUM_ABOUT_TV; i++) + { + OUTB(0x3d4,VGA_RegIdx_about_TV[i]); + bTmp=INB(0x3d5); + pTrident->DefaultTVDependVGASetting[i]=bTmp; + } + + switch (pTrident->TVChipset) + { + case 1: + for (i=0; i<TVX_REG_NUM; i++) + { + bTmp=smbus_read(pScrn,i,TVX_VT1621_PORT); + pTrident->DefaultTVDependVGASetting[VGA_REGNUM_ABOUT_TV+i]=bTmp; + } + break; + case 2: + for (i=0; i<TV_CH7005C_TVREG_NUM; i++) + { + bTmp=smbus_read(pScrn,TV_CH7005C_RegIdx[i],TV_CH7005C_PORT); + pTrident->DefaultTVDependVGASetting[VGA_REGNUM_ABOUT_TV+i]=bTmp; + } + break; + default: + ErrorF("VIAB3D: VIA_SaveTVDepentVGAReg: Wrong Chipset setting\n"); + break; + + } + /* protect */ + OUTB(0x3C4, 0x11); + OUTB(0x3C5, protect); +} +void VIA_RestoreTVDependVGAReg(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident=TRIDENTPTR(pScrn); + unsigned char protect; + unsigned char bTmp; + int i; + unsigned char VGA_RegIdx_about_TV[VGA_REGNUM_ABOUT_TV]={ + 0xD8,0XD9,/* SR */ + 0X33,/* GR */ + 0XC0,0XD0,0XD1,0XD2,0XD3,0XE0,0XE3,0XE4,0XE5,/* CR */ + 0XE6,0XE7,0XF0,0XF1,0XF6,0XFE,0XFF + }; + unsigned char TV_CH7005C_RegIdx[TV_CH7005C_TVREG_NUM]={ + 0X00,0X01,0X03,0X04,0X06,0X07,0X08,0X09, + 0X0A,0X0B,0X0D,0X0E,0X10,0X11,0X13,0X14, + 0X15,0X17,0X18,0X19,0X1A,0X1B,0X1C,0X1D, + 0X1E,0X1F,0X20,0X21,0X3D + }; + + /*ErrorF("VIAB3D: VIA_RestoreTVDependVGAReg:\n");*/ + + /* Unprotect */ + OUTB(0x3C4, 0x11); + protect = INB(0x3C5); + OUTB(0x3C5, 0x92); + + /* Set TV Hw environment */ + OUTB(0x3d4,0xc1); + OUTB(0x3d5,0x41); + + /* SR_d8,SR_d9 */ + for (i=0; i<2; i++) + { + OUTB(0x3c4,VGA_RegIdx_about_TV[i]); + bTmp=pTrident->DefaultTVDependVGASetting[i]; + OUTB(0x3c5,bTmp); + } + /* GR_33 */ + OUTB(0x3ce,0x33); + bTmp=pTrident->DefaultTVDependVGASetting[2]; + OUTB(0x3cf,bTmp); + + /* CR_c0,d0,d1,d2,d3,e0,e3,e4,e5,e6,e7,f0,f1,f6,fe,ff */ + for (i=3; i<VGA_REGNUM_ABOUT_TV; i++) + { + OUTB(0x3d4,VGA_RegIdx_about_TV[i]); + bTmp=pTrident->DefaultTVDependVGASetting[i]; + OUTB(0x3d5,bTmp); + } + switch (pTrident->TVChipset) + { + case 1: + for (i=0; i<TVX_REG_NUM; i++) + { + bTmp=pTrident->DefaultTVDependVGASetting[VGA_REGNUM_ABOUT_TV+i]; + smbus_write(pScrn,bTmp,i,TVX_VT1621_PORT); + } + break; + case 2: + for (i=0; i<TV_CH7005C_TVREG_NUM; i++) + { + bTmp=pTrident->DefaultTVDependVGASetting[VGA_REGNUM_ABOUT_TV+i]; + smbus_write(pScrn,bTmp,TV_CH7005C_RegIdx[i],TV_CH7005C_PORT); + } + break; + default: + ErrorF("VIAB3D: VIA_SaveTVDepentVGAReg: Wrong Chipset setting\n"); + break; + } + /* protect */ + OUTB(0x3C4, 0x11); + OUTB(0x3C5, protect); +} +void VIA_TVInit(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident=TRIDENTPTR(pScrn); + unsigned char idx=0; + unsigned char i; + unsigned char protect; + unsigned char TV_CRTC[TVX_CRTC_NUM] = + { 0xC0,0xD0,0xD1,0xD2,0xD3,0xE0,0xE3,0xE4,0xE5, + 0xE6,0xE7,0xF0,0xF1,0xF6,0xFE,0xFF }; + unsigned char TV_CH7005C_RegIdx[TV_CH7005C_TVREG_NUM]={ + 0X00,0X01,0X03,0X04,0X06,0X07,0X08,0X09, + 0X0A,0X0B,0X0D,0X0E,0X10,0X11,0X13,0X14, + 0X15,0X17,0X18,0X19,0X1A,0X1B,0X1C,0X1D, + 0X1E,0X1F,0X20,0X21,0X3D + }; + +#ifdef DEBUG_CODE_TRACE + ErrorF("VIAB3D: VIA_TVInit:\n"); +#endif + + if (pScrn->currentMode->HDisplay==640 && pScrn->currentMode->VDisplay==480 && (pScrn->depth==8 || pScrn->depth==16) && pTrident->TVSignalMode == 0) + { + /* Overlay window 1 position OK */ + ErrorF("VIAB3D: VIA_TVInit: TV Params 640x480x8(16) NTSC\n"); + idx=0; + pTrident->OverrideHsync=-71; + pTrident->OverrideVsync=15; + } + else if (pScrn->currentMode->HDisplay==800 && pScrn->currentMode->VDisplay==600 && (pScrn->depth==8 || pScrn->depth==16) && pTrident->TVSignalMode == 0) + { + /* Overlay window 1 position OK */ + ErrorF("VIAB3D: VIA_TVInit: TV Params 800x600x8(16) NTSC\n"); + idx=1; + pTrident->OverrideHsync=-152; + pTrident->OverrideVsync=72; + } + else if (pScrn->currentMode->HDisplay==640 && pScrn->currentMode->VDisplay==480 && pScrn->depth==24 && pTrident->TVSignalMode == 0) + { + ErrorF("VIAB3D: VIA_TVInit: TV Params 640x480x32 NTSC\n"); + idx=2; + pTrident->OverrideHsync=-65; + pTrident->OverrideVsync=14; + } + else if (pScrn->currentMode->HDisplay==800 && pScrn->currentMode->VDisplay==600 && pScrn->depth==24 && pTrident->TVSignalMode == 0) + { + ErrorF("VIAB3D: VIA_TVInit: TV Params 800x600x32 NTSC\n"); + idx=3; + pTrident->OverrideHsync=-158; + pTrident->OverrideVsync=72; + } + else if (pScrn->currentMode->HDisplay==640 && pScrn->currentMode->VDisplay==480 && (pScrn->depth==8 || pScrn->depth==16) && pTrident->TVSignalMode == 1) + { + /* Overlay window 1 position OK */ + ErrorF("VIAB3D: VIA_TVInit: TV Params 640x480x8(16) PAL\n"); + idx=4; + pTrident->OverrideHsync=2; + pTrident->OverrideVsync=65; + } + else if (pScrn->currentMode->HDisplay==800 && pScrn->currentMode->VDisplay==600 && (pScrn->depth==8 || pScrn->depth==16) && pTrident->TVSignalMode == 1) + { + ErrorF("VIAB3D: VIA_TVInit: TV Params 800x600x8(16) PAL\n"); + /* patch TV screen defection */ + idx=5; + /* patch 800x600 screen defect */ + OUTB(0x3d4,0x2f); + OUTB(0x3d5,0xbf); + pTrident->OverrideHsync=-145; + pTrident->OverrideVsync=43; + } + else if (pScrn->currentMode->HDisplay==640 && pScrn->currentMode->VDisplay==480 && pScrn->depth==24 && pTrident->TVSignalMode == 1) + { + ErrorF("VIAB3D: VIA_TVInit: TV Params 640x480x32 PAL\n"); + idx=6; + pTrident->OverrideHsync=0; + pTrident->OverrideVsync=63; + } + else if (pScrn->currentMode->HDisplay==800 && pScrn->currentMode->VDisplay==600 && pScrn->depth==24 && pTrident->TVSignalMode == 1) + { + ErrorF("VIAB3D: VIA_TVInit: TV Params 800x600x32 PAL\n"); + idx=7; + OUTB(0x3d4,0x2f); + OUTB(0x3d5,0xbf); + pTrident->OverrideHsync=-141; + pTrident->OverrideVsync=42; + } + else + { + ErrorF("VIAB3D: VIA_TVInit: TV Params default mode\n"); + return; + } + + /* Unprotect */ + OUTB(0x3C4, 0x11); + protect = INB(0x3C5); + OUTB(0x3C5, 0x92); + + /* Set TV hw environment */ + OUTB(0x3c4,0x24); + OUTB(0x3c5,0x4f); + OUTB(0x3d4,0xc1); + OUTB(0x3d5,0x41); + OUTB(0x3ce,0x23); + OUTB(0x3cf,0x88); + + /* set CRT + TV */ + OUTB(0x3CE,0x33); + OUTB(0x3CF,0x20); + + /* set CRTC */ + for( i = 0; i < TVX_CRTC_NUM; i++ ) + { + OUTB(0x3D4, TV_CRTC[i]); + + if (pTrident->TVChipset==2) { + OUTB(0x3D5, TV_CH7005C_Table[idx][i]); + } + else { + OUTB(0x3D5, TVX_VT1621_Table[idx][i]); + } + } + + + /* Digital TV interface control */ + switch (pTrident->TVChipset) + { + case 1: OUTB(0x3C4,0xD8); + OUTB(0x3C5,0x60); + OUTB(0x3C4,0xD9); + OUTB(0x3C5,0x38); + break; + case 2: OUTB(0x3c4,0xd8); + OUTB(0x3c5,0x24); + OUTB(0x3C4,0xD9); + OUTB(0x3C5,0x18); + break; + } + + switch (pTrident->TVChipset) + { + case 1: + /* set TVX registers */ + for (i=0; i < TVX_REG_NUM; i++ ) + { + smbus_write(pScrn,TVX_VT1621_Table[idx][TVX_CRTC_NUM+i], i, TVX_VT1621_PORT); + } + break; + case 2: + for (i=0; i<TV_CH7005C_TVREG_NUM; i++) + { + smbus_write(pScrn,TV_CH7005C_Table[idx][TV_CH7005C_CRTC_NUM+i], TV_CH7005C_RegIdx[i], TV_CH7005C_PORT); + } + break; + } + + /*VIA_DumpReg(pScrn);*/ + + /* protect */ + OUTB(0x3C4, 0x11); + OUTB(0x3C5, protect); +} +void VIA_DumpReg(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident=TRIDENTPTR(pScrn); + int i,j; + unsigned char bTmp; + unsigned char protect; + + /* Unprotect */ + OUTB(0x3C4, 0x11); + protect = INB(0x3C5); + OUTB(0x3C5, 0x92); + + /* SR */ + for (i=0; i<16; i++) + { + for (j=0; j<16; j++) + { + OUTB(0x3c4,(16*i+j)); + bTmp=INB(0x3c5); + + ErrorF("SR%02x=%02x ",(16*i+j),bTmp); + } + ErrorF("\n"); + } + ErrorF("\n"); + /* CR */ + for (i=0; i<16; i++) + { + for (j=0; j<16; j++) + { + OUTB(0x3d4,(16*i+j)); + bTmp=INB(0x3d5); + + ErrorF("CR%02x=%02x ",(16*i+j),bTmp); + } + ErrorF("\n"); + } + ErrorF("\n"); + /* GR */ + for (i=0; i<16; i++) + { + for (j=0; j<16; j++) + { + OUTB(0x3ce,(16*i+j)); + bTmp=INB(0x3cf); + + ErrorF("GR%02x=%02x ",(16*i+j),bTmp); + } + ErrorF("\n"); + } + ErrorF("\n"); + /* SM */ + for (i=0; i<16; i++) + { + for (j=0; j<16; j++) + { + if (pTrident->TVChipset==2) + bTmp=smbus_read(pScrn,(16*i+j),TV_CH7005C_PORT); + else bTmp=smbus_read(pScrn,(16*i+j),TVX_VT1621_PORT); + ErrorF("SM%02x=%02x ",(16*i+j),bTmp); + } + ErrorF("\n"); + } + ErrorF("\n"); + /* protect */ + OUTB(0x3C4, 0x11); + OUTB(0x3C5, protect); + +} diff --git a/driver/xf86-video-trident/src/trident_video.c b/driver/xf86-video-trident/src/trident_video.c new file mode 100644 index 000000000..c31ce48a9 --- /dev/null +++ b/driver/xf86-video-trident/src/trident_video.c @@ -0,0 +1,1335 @@ +/* + * Copyright 1992-2003 by Alan Hourihane, North Wales, UK. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Alan Hourihane, alanh@fairlite.demon.co.uk + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_video.c,v 1.45 2003/11/10 18:22:34 tsi Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "compiler.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "xf86fbman.h" +#include "regionstr.h" + +#include "trident.h" +#include "trident_regs.h" +#include <X11/extensions/Xv.h> +#include "xaa.h" +#include "xaalocal.h" +#include "dixstruct.h" +#include "fourcc.h" + +#define OFF_DELAY 800 /* milliseconds */ +#define FREE_DELAY 60000 + +#define OFF_TIMER 0x01 +#define FREE_TIMER 0x02 +#define CLIENT_VIDEO_ON 0x04 + +#define TIMER_MASK (OFF_TIMER | FREE_TIMER) + +static XF86VideoAdaptorPtr TRIDENTSetupImageVideo(ScreenPtr); +static void TRIDENTInitOffscreenImages(ScreenPtr); +static void TRIDENTStopVideo(ScrnInfoPtr, pointer, Bool); +static int TRIDENTSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); +static int TRIDENTGetPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer); +static void TRIDENTQueryBestSize(ScrnInfoPtr, Bool, + short, short, short, short, unsigned int *, unsigned int *, pointer); +static int TRIDENTPutImage( ScrnInfoPtr, + short, short, short, short, short, short, short, short, + int, unsigned char*, short, short, Bool, RegionPtr, pointer, + DrawablePtr); +static int TRIDENTQueryImageAttributes(ScrnInfoPtr, + int, unsigned short *, unsigned short *, int *, int *); +static void TRIDENTVideoTimerCallback(ScrnInfoPtr pScrn, Time time); +static void tridentSetVideoContrast(TRIDENTPtr pTrident,int value); +static void tridentSetVideoParameters(TRIDENTPtr pTrident, int brightness, + int saturation, int hue); +void tridentFixFrame(ScrnInfoPtr pScrn, int *fixFrame); +static void WaitForVBlank(ScrnInfoPtr pScrn); + +#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) + +static Atom xvColorKey, xvSaturation, xvBrightness, xvHUE, xvContrast; + +void TRIDENTInitVideo(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; + XF86VideoAdaptorPtr newAdaptor = NULL; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int num_adaptors; + + /* + * The following has been tested on: + * + * 9525 : flags: None + * Image985 : flags: None + * Cyber9397(DVD) : flags: VID_ZOOM_NOMINI + * CyberBlade/i7: flags: VID_ZOOM_INV | VID_ZOOM_MINI + * CyberBlade/i1: flags: VID_ZOOM_INV | VID_ZOOM_MINI + * CyberBlade/Ai1: flags: VID_ZOOM_INV + * Cyber 9540 : flags: VID_ZOOM_INV | VID_SHIFT_4 + * CyberXPm8 : flags: VID_ZOOM_INV | VID_SHIFT_4 + * + * When you make changes make sure not to break these + * Add new chipsets to this list. + */ + if (pTrident->Chipset >= BLADE3D) { + pTrident->videoFlags = VID_ZOOM_INV ; + if (pTrident->Chipset <= CYBERBLADEI1D) + pTrident->videoFlags |= VID_ZOOM_MINI; + else if (pTrident->Chipset < CYBERBLADEAI1 /* verified EE */ + || pTrident->Chipset > CYBERBLADEAI1D) + pTrident->videoFlags |= VID_OFF_SHIFT_4; + } + if (pTrident->Chipset == CYBER9397 || pTrident->Chipset == CYBER9397DVD) + pTrident->videoFlags = VID_ZOOM_NOMINI; + + if (pTrident->Chipset == CYBER9397DVD || + pTrident->Chipset == CYBER9525DVD || + pTrident->Chipset >= BLADE3D) + pTrident->videoFlags |= VID_DOUBLE_LINEBUFFER_FOR_WIDE_SRC; + + newAdaptor = TRIDENTSetupImageVideo(pScreen); + TRIDENTInitOffscreenImages(pScreen); + + num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); + + if(newAdaptor) { + if(!num_adaptors) { + num_adaptors = 1; + adaptors = &newAdaptor; + } else { + newAdaptors = /* need to free this someplace */ + xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr*)); + if(newAdaptors) { + memcpy(newAdaptors, adaptors, num_adaptors * + sizeof(XF86VideoAdaptorPtr)); + newAdaptors[num_adaptors] = newAdaptor; + adaptors = newAdaptors; + num_adaptors++; + } + } + } + + if(num_adaptors) + xf86XVScreenInit(pScreen, adaptors, num_adaptors); + + if(newAdaptors) + xfree(newAdaptors); + + if (pTrident->videoFlags) + xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,3, + "Trident Video Flags: %s %s %s %s\n", + pTrident->videoFlags & VID_ZOOM_INV ? "VID_ZOOM_INV" : "", + pTrident->videoFlags & VID_ZOOM_MINI ? "VID_ZOOM_MINI" : "", pTrident->videoFlags & VID_OFF_SHIFT_4 ? "VID_OFF_SHIFT_4" + : "", + pTrident->videoFlags & VID_ZOOM_NOMINI ? "VID_ZOOM_NOMINI" + : ""); + +} + +/* client libraries expect an encoding */ +static XF86VideoEncodingRec DummyEncoding[1] = +{ + { + 0, + "XV_IMAGE", + 1024, 1024, + {1, 1} + } +}; + +#define NUM_FORMATS 4 + +static XF86VideoFormatRec Formats[NUM_FORMATS] = +{ + {8, PseudoColor}, {15, TrueColor}, {16, TrueColor}, {24, TrueColor} +}; + +#define NUM_ATTRIBUTES 5 + +static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = +{ + {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, + {XvSettable | XvGettable, 0, 187, "XV_SATURATION"}, + {XvSettable | XvGettable, 0, 0x3F, "XV_BRIGHTNESS"}, + {XvSettable | XvGettable, 0, 360 , "XV_HUE"}, + {XvSettable | XvGettable, 0, 7, "XV_CONTRAST"} +}; + +#define NUM_IMAGES 3 + +static XF86ImageRec Images[NUM_IMAGES] = +{ + { + 0x36315652, + XvRGB, + LSBFirst, + {'R','V','1','6', + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + 16, + XvPacked, + 1, + 16, 0xF800, 0x07E0, 0x001F, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + {'R','V','B',0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + XvTopToBottom + }, + XVIMAGE_YV12, + XVIMAGE_YUY2 +}; + +typedef struct { + FBLinearPtr linear; + RegionRec clip; + CARD32 colorKey; + CARD8 Saturation; + CARD8 Brightness; + CARD16 HUE; + INT8 Contrast; + CARD32 videoStatus; + Time offTime; + Time freeTime; + int fixFrame; +} TRIDENTPortPrivRec, *TRIDENTPortPrivPtr; + + +#define GET_PORT_PRIVATE(pScrn) \ + (TRIDENTPortPrivPtr)((TRIDENTPTR(pScrn))->adaptor->pPortPrivates[0].ptr) + +void TRIDENTResetVideo(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + TRIDENTPortPrivPtr pPriv = pTrident->adaptor->pPortPrivates[0].ptr; + int vgaIOBase = VGAHWPTR(pScrn)->IOBase; + int red, green, blue; + int tmp; + + WaitForVBlank(pScrn); + OUTW(vgaIOBase + 4, 0x848E); + + if (pTrident->Chipset >= CYBER9388) { + OUTW(vgaIOBase + 4, 0x80B9); + OUTW(vgaIOBase + 4, 0x00BE); + OUTW(0x3C4, 0xC057); + OUTW(0x3C4, 0x3420); + OUTW(0x3C4, 0x3037); + } else { + if (pTrident->Chipset >= PROVIDIA9682) { + OUTB(0x83C8, 0x57); + OUTB(0x83C6, 0xC0); + OUTW(vgaIOBase + 4, 0x26BE); + } else { + OUTB(0x83C8, 0x37); + OUTB(0x83C6, 0x01); + OUTB(0x83C8, 0x00); + OUTB(0x83C6, 0x00); + } + } + + if (pTrident->Chipset >= BLADEXP) { + OUTW(0x3C4, 0x007A); + OUTW(0x3C4, 0x007D); + } + switch (pScrn->depth) { + case 8: + VIDEOOUT(pPriv->colorKey, pTrident->keyOffset); + VIDEOOUT(0x00, (pTrident->keyOffset + 1)); + VIDEOOUT(0x00, (pTrident->keyOffset + 2)); + VIDEOOUT(0xFF, (pTrident->keyOffset + 4)); + VIDEOOUT(0x00, (pTrident->keyOffset + 5)); + VIDEOOUT(0x00, (pTrident->keyOffset + 6)); + break; + default: + red = (pPriv->colorKey & pScrn->mask.red) >> pScrn->offset.red; + green = (pPriv->colorKey & pScrn->mask.green) >> pScrn->offset.green; + blue = (pPriv->colorKey & pScrn->mask.blue) >> pScrn->offset.blue; + switch (pScrn->depth) { + case 15: + tmp = (red << 10) | (green << 5) | (blue); + VIDEOOUT((tmp & 0xff), pTrident->keyOffset); + VIDEOOUT((tmp & 0xff00)>>8, (pTrident->keyOffset + 1)); + VIDEOOUT(0x00, (pTrident->keyOffset + 2)); + VIDEOOUT(0xFF, (pTrident->keyOffset + 4)); + VIDEOOUT(0xFF, (pTrident->keyOffset + 5)); + VIDEOOUT(0x00, (pTrident->keyOffset + 6)); + break; + case 16: + tmp = (red << 11) | (green << 5) | (blue); + VIDEOOUT((tmp & 0xff), pTrident->keyOffset); + VIDEOOUT((tmp & 0xff00)>>8, (pTrident->keyOffset + 1)); + VIDEOOUT(0x00, (pTrident->keyOffset + 2)); + VIDEOOUT(0xFF, (pTrident->keyOffset + 4)); + VIDEOOUT(0xFF, (pTrident->keyOffset + 5)); + VIDEOOUT(0x00, (pTrident->keyOffset + 6)); + break; + case 24: + VIDEOOUT(blue, pTrident->keyOffset); + VIDEOOUT(green, (pTrident->keyOffset + 1)); + VIDEOOUT(red, (pTrident->keyOffset + 2)); + VIDEOOUT(0xFF, (pTrident->keyOffset + 4)); + VIDEOOUT(0xFF, (pTrident->keyOffset + 5)); + VIDEOOUT(0xFF, (pTrident->keyOffset + 6)); + break; + } + } + + if (pTrident->Chipset >= CYBER9388) { + tridentSetVideoContrast(pTrident,pPriv->Contrast); + tridentSetVideoParameters(pTrident,pPriv->Brightness,pPriv->Saturation, + pPriv->HUE); + } +} + + +static XF86VideoAdaptorPtr +TRIDENTSetupImageVideo(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + XF86VideoAdaptorPtr adapt; + TRIDENTPortPrivPtr pPriv; + + if(!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) + + sizeof(TRIDENTPortPrivRec) + + sizeof(DevUnion)))) + return NULL; + + adapt->type = XvWindowMask | XvInputMask | XvImageMask; + adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; + adapt->name = "Trident Backend Scaler"; + adapt->nEncodings = 1; + adapt->pEncodings = DummyEncoding; + adapt->nFormats = NUM_FORMATS; + adapt->pFormats = Formats; + adapt->nPorts = 1; + adapt->pPortPrivates = (DevUnion*)(&adapt[1]); + pPriv = (TRIDENTPortPrivPtr)(&adapt->pPortPrivates[1]); + adapt->pPortPrivates[0].ptr = (pointer)(pPriv); + adapt->pAttributes = Attributes; + adapt->nImages = NUM_IMAGES; + if (pTrident->Chipset >= CYBER9388) { + adapt->nAttributes = NUM_ATTRIBUTES; + } else { + adapt->nAttributes = 1; /* Just colorkey */ + } + adapt->pImages = Images; + adapt->PutVideo = NULL; + adapt->PutStill = NULL; + adapt->GetVideo = NULL; + adapt->GetStill = NULL; + adapt->StopVideo = TRIDENTStopVideo; + adapt->SetPortAttribute = TRIDENTSetPortAttribute; + adapt->GetPortAttribute = TRIDENTGetPortAttribute; + adapt->QueryBestSize = TRIDENTQueryBestSize; + adapt->PutImage = TRIDENTPutImage; + adapt->QueryImageAttributes = TRIDENTQueryImageAttributes; + + pPriv->colorKey = pTrident->videoKey & ((1 << pScrn->depth) - 1); + pPriv->Brightness = 45; + pPriv->Saturation = 80; + pPriv->Contrast = 4; + pPriv->HUE = 0; + pPriv->videoStatus = 0; + pPriv->fixFrame = 100; + + /* gotta uninit this someplace */ + REGION_NULL(pScreen, &pPriv->clip); + + pTrident->adaptor = adapt; + + xvColorKey = MAKE_ATOM("XV_COLORKEY"); + + if (pTrident->Chipset >= CYBER9388) { + xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); + xvSaturation = MAKE_ATOM("XV_SATURATION"); + xvHUE = MAKE_ATOM("XV_HUE"); + xvContrast = MAKE_ATOM("XV_CONTRAST"); + } + + if (pTrident->Chipset >= PROVIDIA9682) + pTrident->keyOffset = 0x50; + else + pTrident->keyOffset = 0x30; + + TRIDENTResetVideo(pScrn); + + return adapt; +} + + +static void +TRIDENTStopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + TRIDENTPortPrivPtr pPriv = (TRIDENTPortPrivPtr)data; + int vgaIOBase = VGAHWPTR(pScrn)->IOBase; + + REGION_EMPTY(pScrn->pScreen, &pPriv->clip); + + if(shutdown) { + if(pPriv->videoStatus & CLIENT_VIDEO_ON) { + WaitForVBlank(pScrn); + OUTW(vgaIOBase + 4, 0x848E); + OUTW(vgaIOBase + 4, 0x0091); + } + if(pPriv->linear) { + xf86FreeOffscreenLinear(pPriv->linear); + pPriv->linear = NULL; + } + pPriv->videoStatus = 0; + } else { + if(pPriv->videoStatus & CLIENT_VIDEO_ON) { + pPriv->videoStatus |= OFF_TIMER; + pPriv->offTime = currentTime.milliseconds + OFF_DELAY; + pTrident->VideoTimerCallback = TRIDENTVideoTimerCallback; + } + } +} + +#undef PI +#define PI 3.14159265 + +static void +tridentSetVideoContrast(TRIDENTPtr pTrident,int value) +{ + OUTW(0x3C4, (((value & 0x7)|((value & 0x7) << 4)) << 8) | 0xBC); +} + +static void +tridentSetVideoParameters(TRIDENTPtr pTrident, int brightness, + int saturation, int hue) +{ + double dtmp; + CARD8 sign, tmp, tmp1; + + if (brightness >= 0x20) + brightness -= 0x20; + else + brightness += 0x20; + dtmp = sin((double)hue / 180.0 * PI) * saturation / 12.5; + sign = (dtmp < 0) ? 1 << 1 : 0; + tmp1 = ((int)fabs(dtmp) >> 4) & 0x1; + tmp = brightness << 2 | sign | tmp1; + OUTW(0x3C4, tmp << 8 | 0xB1); + + tmp1 = ((int)fabs(dtmp) & 0x7 ) << 5; + dtmp = cos((double)hue / 180.0 * PI) * saturation / 12.5; + sign = (dtmp < 0) ? 1 << 4 : 0; + tmp1 |= (int)fabs(dtmp) & 0xf; + tmp = sign | tmp1; + OUTW(0x3C4, tmp << 8 | 0xB0); +} + +static int +TRIDENTSetPortAttribute( + ScrnInfoPtr pScrn, + Atom attribute, + INT32 value, + pointer data +){ + TRIDENTPortPrivPtr pPriv = (TRIDENTPortPrivPtr)data; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + if(attribute == xvColorKey) { + int red, green, blue; + int tmp; + pPriv->colorKey = value; + switch (pScrn->depth) { + case 8: + VIDEOOUT(pPriv->colorKey, pTrident->keyOffset); + VIDEOOUT(0x00, (pTrident->keyOffset + 1)); + VIDEOOUT(0x00, (pTrident->keyOffset + 2)); + break; + default: + red = (pPriv->colorKey & pScrn->mask.red) >> pScrn->offset.red; + green = (pPriv->colorKey & pScrn->mask.green) >> pScrn->offset.green; + blue = (pPriv->colorKey & pScrn->mask.blue) >> pScrn->offset.blue; + switch (pScrn->depth) { + case 15: + tmp = (red << 10) | (green << 5) | (blue); + VIDEOOUT((tmp&0xff), pTrident->keyOffset); + VIDEOOUT((tmp&0xff00)>>8, (pTrident->keyOffset + 1)); + VIDEOOUT(0x00, (pTrident->keyOffset + 2)); + break; + case 16: + tmp = (red << 11) | (green << 5) | (blue); + VIDEOOUT((tmp&0xff), pTrident->keyOffset); + VIDEOOUT((tmp&0xff00)>>8, (pTrident->keyOffset + 1)); + VIDEOOUT(0x00, (pTrident->keyOffset + 2)); + break; + case 24: + VIDEOOUT(blue, pTrident->keyOffset); + VIDEOOUT(green, (pTrident->keyOffset + 1)); + VIDEOOUT(red, (pTrident->keyOffset + 2)); + break; + } + } + REGION_EMPTY(pScrn->pScreen, &pPriv->clip); + } else if (attribute == xvBrightness) { + if ((value < 0) || (value > 0x3f)) + return BadValue; + pPriv->Brightness = value; + tridentSetVideoParameters(pTrident, pPriv->Brightness, pPriv->Saturation, + pPriv->HUE); + } else if (attribute == xvSaturation) { + if ((value < 0) || (value > 187)) + return BadValue; + pPriv->Saturation = value; + tridentSetVideoParameters(pTrident, pPriv->Brightness, pPriv->Saturation, + pPriv->HUE); + } else if (attribute == xvHUE) { + if ((value < 0) || (value > 360)) + return BadValue; + pPriv->HUE = value; + tridentSetVideoParameters(pTrident, pPriv->Brightness, pPriv->Saturation, + pPriv->HUE); + } else if (attribute == xvContrast) { + if ((value < 0) || (value > 7)) + return BadValue; + pPriv->Contrast = value; + tridentSetVideoContrast(pTrident,value); + } else + return BadMatch; + + return Success; +} + +static int +TRIDENTGetPortAttribute( + ScrnInfoPtr pScrn, + Atom attribute, + INT32 *value, + pointer data +){ + TRIDENTPortPrivPtr pPriv = (TRIDENTPortPrivPtr)data; + + if(attribute == xvColorKey) { + *value = pPriv->colorKey; + } else if(attribute == xvBrightness) { + *value = pPriv->Brightness; + } else if(attribute == xvSaturation) { + *value = pPriv->Saturation; + } else if (attribute == xvHUE) { + *value = pPriv->HUE; + } else if (attribute == xvContrast) { + *value = pPriv->Contrast; + } else + return BadMatch; + + return Success; +} + +static void +TRIDENTQueryBestSize( + ScrnInfoPtr pScrn, + Bool motion, + short vid_w, short vid_h, + short drw_w, short drw_h, + unsigned int *p_w, unsigned int *p_h, + pointer data +){ + *p_w = drw_w; + *p_h = drw_h; + + if(*p_w > 16384) *p_w = 16384; +} + + +static FBLinearPtr +TRIDENTAllocateMemory( + ScrnInfoPtr pScrn, + FBLinearPtr linear, + int size +){ + ScreenPtr pScreen; + FBLinearPtr new_linear; + + if(linear) { + if(linear->size >= size) + return linear; + + if(xf86ResizeOffscreenLinear(linear, size)) + return linear; + + xf86FreeOffscreenLinear(linear); + } + + pScreen = screenInfo.screens[pScrn->scrnIndex]; + + new_linear = xf86AllocateOffscreenLinear(pScreen, size, 16, + NULL, NULL, NULL); + + if(!new_linear) { + int max_size; + + xf86QueryLargestOffscreenLinear(pScreen, &max_size, 16, + PRIORITY_EXTREME); + + if(max_size < size) + return NULL; + + xf86PurgeUnlockedOffscreenAreas(pScreen); + new_linear = xf86AllocateOffscreenLinear(pScreen, size, 16, + NULL, NULL, NULL); + } + + return new_linear; +} + +static void +TRIDENTDisplayVideo( + ScrnInfoPtr pScrn, + int id, + int offset, + short width, short height, + int pitch, + int x1, int y1, int x2, int y2, + BoxPtr dstBox, + short src_w, short src_h, + short drw_w, short drw_h +){ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int vgaIOBase = VGAHWPTR(pScrn)->IOBase; + int zoomx1, zoomx2, zoomy1, zoomy2; + int tx1,tx2; + int ty1,ty2; + + switch(id) { + case 0x35315652: /* RGB15 */ + case 0x36315652: /* RGB16 */ + if (pTrident->Chipset >= CYBER9388) { + OUTW(vgaIOBase + 4, 0x22BF); + OUTW(vgaIOBase + 4, 0x248F); + } else { + OUTW(vgaIOBase + 4, 0x118F); + } + break; + case FOURCC_YV12: /* YV12 */ + case FOURCC_YUY2: /* YUY2 */ + default: + if (pTrident->Chipset >= CYBER9388) { + OUTW(vgaIOBase + 4, 0x00BF); + OUTW(vgaIOBase + 4, 0x208F); + } else { + OUTW(vgaIOBase + 4, 0x108F); + } + break; + } + tx1 = dstBox->x1 + pTrident->hsync; + tx2 = dstBox->x2 + pTrident->hsync + pTrident->hsync_rskew; + ty1 = dstBox->y1 + pTrident->vsync - 2; + ty2 = dstBox->y2 + pTrident->vsync + 2 + pTrident->vsync_bskew; + + OUTW(vgaIOBase + 4, (tx1 & 0xff) <<8 | 0x86); + OUTW(vgaIOBase + 4, (tx1 & 0xff00) | 0x87); + OUTW(vgaIOBase + 4, (ty1 & 0xff) <<8 | 0x88); + OUTW(vgaIOBase + 4, (ty1 & 0xff00) | 0x89); + OUTW(vgaIOBase + 4, (tx2 & 0xff) <<8 | 0x8A); + OUTW(vgaIOBase + 4, (tx2 & 0xff00) | 0x8B); + OUTW(vgaIOBase + 4, (ty2 & 0xff) <<8 | 0x8C); + OUTW(vgaIOBase + 4, (ty2 & 0xff00) | 0x8D); + + offset += (x1 >> 15) & ~0x01; + + if (pTrident->videoFlags & VID_OFF_SHIFT_4) + offset = offset >> 4; + else + offset = offset >> 3; + + OUTW(vgaIOBase + 4, (((width<<1) & 0xff)<<8) | 0x90); + OUTW(vgaIOBase + 4, ((width<<1) & 0xff00) | 0x91); + OUTW(vgaIOBase + 4, ((offset) & 0xff) << 8 | 0x92); + OUTW(vgaIOBase + 4, ((offset) & 0xff00) | 0x93); + if (pTrident->Chipset >= CYBER9397) { + OUTW(vgaIOBase + 4, ((offset) & 0x0f0000) >> 8 | 0x94); + } else { + OUTW(vgaIOBase + 4, ((offset) & 0x070000) >> 8 | 0x94); + } + + /* Horizontal Zoom */ + if (pTrident->videoFlags & VID_ZOOM_INV) { + if ((pTrident->videoFlags & VID_ZOOM_MINI) && src_w > drw_w) + zoomx2 = (int)((float)drw_w/(float)src_w * 1024) + | (((int)((float)src_w/(float)drw_w) - 1)&7)<<10 | 0x8000; + else + zoomx2 = (int)(float)src_w/(float)drw_w * 1024; + + OUTW(vgaIOBase + 4, (zoomx2&0xff)<<8 | 0x80); + OUTW(vgaIOBase + 4, (zoomx2&0x9f00) | 0x81); + } else { + if (drw_w == src_w + || ((pTrident->videoFlags & VID_ZOOM_NOMINI) && (src_w > drw_w))) { + OUTW(vgaIOBase + 4, 0x0080); + OUTW(vgaIOBase + 4, 0x0081); + } else + if (drw_w > src_w) { + float z; + + z = (float)((drw_w)/(float)src_w) - 1.0; + + zoomx1 = z; + zoomx2 = (z - (int)zoomx1 ) * 1024; + + OUTW(vgaIOBase + 4, (zoomx2&0xff)<<8 | 0x80); + OUTW(vgaIOBase + 4, (zoomx1&0x0f)<<10 | (zoomx2&0x0300) |0x81); + } else { + zoomx1 = ((float)drw_w/(float)src_w); + zoomx2 = ( ((float)drw_w/(float)src_w) - (int)zoomx1 ) * 1024; + OUTW(vgaIOBase + 4, (zoomx2&0xff)<<8 | 0x80); + OUTW(vgaIOBase + 4, (zoomx2&0x0300)| + (((int)((float)src_w/(float)drw_w)-1)&7)<<10 | 0x8081); + } + } + + /* Vertical Zoom */ + if (pTrident->videoFlags & VID_ZOOM_INV) { + if ((pTrident->videoFlags & VID_ZOOM_MINI) && src_h > drw_h) + zoomy2 = (int)(( ((float)drw_h/(float)src_h)) * 1024) + | (((int)((float)src_h/(float)drw_h)-1)&7)<<10 + | 0x8000; + else + zoomy2 = ( ((float)src_h/(float)drw_h)) * 1024; + OUTW(vgaIOBase + 4, (zoomy2&0xff)<<8 | 0x82); + OUTW(vgaIOBase + 4, (zoomy2&0x9f00) | 0x0083); + } else { + if (drw_h == src_h + || ((pTrident->videoFlags & VID_ZOOM_NOMINI) && (src_h > drw_h))) { + OUTW(vgaIOBase + 4, 0x0082); + OUTW(vgaIOBase + 4, 0x0083); + } else + if (drw_h > src_h) { + float z; + + z = (float)drw_h/(float)src_h - 1; + zoomy1 = z; + zoomy2 = (z - (int)zoomy1 ) * 1024; + + OUTW(vgaIOBase + 4, (zoomy2&0xff)<<8 | 0x82); + OUTW(vgaIOBase + 4, (zoomy1&0x0f)<<10 | (zoomy2&0x0300) |0x83); + } else { + zoomy1 = ((float)drw_h/(float)src_h); + zoomy2 = ( ((float)drw_h/(float)src_h) - (int)zoomy1 ) * 1024; + OUTW(vgaIOBase + 4, (zoomy2&0xff)<<8 | 0x82); + OUTW(vgaIOBase + 4, (zoomy2&0x0300)| + (((int)((float)src_h/(float)drw_h)-1)&7)<<10 | 0x8083); + } + } + + if (pTrident->Chipset >= CYBER9388) { + int lb = (width+2) >> 2; + + OUTW(vgaIOBase + 4, ((lb & 0x100)>>1) | 0x0895); + OUTW(vgaIOBase + 4, (lb & 0xFF)<<8 | 0x0096); + if ((pTrident->videoFlags & VID_DOUBLE_LINEBUFFER_FOR_WIDE_SRC) + && (src_w > 384)) { + OUTW(0x3C4, 0x0497); /* 2x line buffers */ + } else { + OUTW(0x3C4, 0x0097); /* 1x line buffers */ + } + OUTW(vgaIOBase + 4, 0x0097); + OUTW(vgaIOBase + 4, 0x00BA); + OUTW(vgaIOBase + 4, 0x00BB); + OUTW(vgaIOBase + 4, 0xFFBC); + OUTW(vgaIOBase + 4, 0xFFBD); + OUTW(vgaIOBase + 4, 0x04BE); + OUTW(vgaIOBase + 4, 0x948E); + } else { + + OUTW(vgaIOBase + 4, ((((id == FOURCC_YV12) || (id == FOURCC_YUY2)) + ? (width >> 2) : (width >> 6)) << 8) | 0x95); + OUTW(vgaIOBase + 4, ((((id == FOURCC_YV12) || (id == FOURCC_YUY2)) + ? ((width+2) >> 2) : ((width+2) >> 6)) << 8) |0x96); + + OUTW(vgaIOBase + 4, 0x948E); + OUTB(0x83C8, 0x00); + OUTB(0x83C6, 0x95); + } +} + +static int +TRIDENTPutImage( + ScrnInfoPtr pScrn, + short src_x, short src_y, + short drw_x, short drw_y, + short src_w, short src_h, + short drw_w, short drw_h, + int id, unsigned char* buf, + short width, short height, + Bool sync, + RegionPtr clipBoxes, pointer data, + DrawablePtr pDraw +){ + TRIDENTPortPrivPtr pPriv = (TRIDENTPortPrivPtr)data; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + INT32 x1, x2, y1, y2; + unsigned char *dst_start; + int new_size, offset, offset2 = 0, offset3 = 0; + int srcPitch, srcPitch2 = 0, dstPitch; + int top, left, npixels, nlines, bpp; + BoxRec dstBox; + CARD32 tmp; + + /* Clip */ + x1 = src_x; + x2 = src_x + src_w; + y1 = src_y; + y2 = src_y + src_h; + + dstBox.x1 = drw_x; + dstBox.x2 = drw_x + drw_w; + dstBox.y1 = drw_y; + dstBox.y2 = drw_y + drw_h; + + if(!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2, clipBoxes, + width, height)) + return Success; + + dstBox.x1 -= pScrn->frameX0; + dstBox.x2 -= pScrn->frameX0; + dstBox.y1 -= pScrn->frameY0; + dstBox.y2 -= pScrn->frameY0; + + bpp = pScrn->bitsPerPixel >> 3; + + dstPitch = ((width << 1) + 15) & ~15; + new_size = ((dstPitch * height) + bpp - 1) / bpp; + switch(id) { + case FOURCC_YV12: + case FOURCC_I420: + srcPitch = (width + 3) & ~3; + offset2 = srcPitch * height; + srcPitch2 = ((width >> 1) + 3) & ~3; + offset3 = (srcPitch2 * (height >> 1)) + offset2; + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + default: + srcPitch = (width << 1); + break; + } + + if(!(pPriv->linear = TRIDENTAllocateMemory(pScrn, pPriv->linear, new_size))) + return BadAlloc; + + /* copy data */ + top = y1 >> 16; + left = (x1 >> 16) & ~1; + npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left; + left <<= 1; + + offset = pPriv->linear->offset * bpp; + + dst_start = pTrident->FbBase + offset + left + (top * dstPitch); + + switch(id) { + case FOURCC_YV12: + case FOURCC_I420: + top &= ~1; + tmp = ((top >> 1) * srcPitch2) + (left >> 2); + offset2 += tmp; + offset3 += tmp; + if(id == FOURCC_I420) { + tmp = offset2; + offset2 = offset3; + offset3 = tmp; + } + nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top; + xf86XVCopyYUV12ToPacked(buf + (top * srcPitch) + (left >> 1), + buf + offset2, buf + offset3, dst_start, + srcPitch, srcPitch2, dstPitch, nlines, npixels); + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + default: + buf += (top * srcPitch) + left; + nlines = ((y2 + 0xffff) >> 16) - top; + xf86XVCopyPacked(buf, dst_start, srcPitch, dstPitch, nlines, npixels); + break; + } + + /* update cliplist */ + if(!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) { + /* update cliplist */ + REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes); + xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes); + } + + offset += top * dstPitch; + + tridentFixFrame(pScrn,&pPriv->fixFrame); + TRIDENTDisplayVideo(pScrn, id, offset, width, height, dstPitch, + x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); + + pPriv->videoStatus = CLIENT_VIDEO_ON; + + pTrident->VideoTimerCallback = TRIDENTVideoTimerCallback; + + return Success; +} + +static int +TRIDENTQueryImageAttributes( + ScrnInfoPtr pScrn, + int id, + unsigned short *w, unsigned short *h, + int *pitches, int *offsets +){ + int size, tmp; + + if(*w > 1024) *w = 1024; + if(*h > 1024) *h = 1024; + + *w = (*w + 1) & ~1; + if(offsets) offsets[0] = 0; + + switch(id) { + case FOURCC_YV12: /* YV12 */ + *h = (*h + 1) & ~1; + size = (*w + 3) & ~3; + if(pitches) pitches[0] = size; + size *= *h; + if(offsets) offsets[1] = size; + tmp = ((*w >> 1) + 3) & ~3; + if(pitches) pitches[1] = pitches[2] = tmp; + tmp *= (*h >> 1); + size += tmp; + if(offsets) offsets[2] = size; + size += tmp; + break; + default: /* RGB15, RGB16, YUY2 */ + size = *w << 1; + if(pitches) pitches[0] = size; + size *= *h; + break; + } + + return size; +} + +/****************** Offscreen stuff ***************/ + +typedef struct { + FBLinearPtr linear; + Bool isOn; +} OffscreenPrivRec, * OffscreenPrivPtr; + +static int +TRIDENTAllocateSurface( + ScrnInfoPtr pScrn, + int id, + unsigned short w, + unsigned short h, + XF86SurfacePtr surface +){ + FBLinearPtr linear; + int pitch, size, bpp; + OffscreenPrivPtr pPriv; + + if((w > 1024) || (h > 1024)) + return BadAlloc; + + w = (w + 1) & ~1; + pitch = ((w << 1) + 15) & ~15; + bpp = pScrn->bitsPerPixel >> 3; + size = ((pitch * h) + bpp - 1) / bpp; + + if(!(linear = TRIDENTAllocateMemory(pScrn, NULL, size))) + return BadAlloc; + + surface->width = w; + surface->height = h; + + if(!(surface->pitches = xalloc(sizeof(int)))) { + xf86FreeOffscreenLinear(linear); + return BadAlloc; + } + if(!(surface->offsets = xalloc(sizeof(int)))) { + xfree(surface->pitches); + xf86FreeOffscreenLinear(linear); + return BadAlloc; + } + if(!(pPriv = xalloc(sizeof(OffscreenPrivRec)))) { + xfree(surface->pitches); + xfree(surface->offsets); + xf86FreeOffscreenLinear(linear); + return BadAlloc; + } + + pPriv->linear = linear; + pPriv->isOn = FALSE; + + surface->pScrn = pScrn; + surface->id = id; + surface->pitches[0] = pitch; + surface->offsets[0] = linear->offset * bpp; + surface->devPrivate.ptr = (pointer)pPriv; + + return Success; +} + +static int +TRIDENTStopSurface( + XF86SurfacePtr surface +){ + OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; + + if(pPriv->isOn) { + TRIDENTPtr pTrident = TRIDENTPTR(surface->pScrn); + int vgaIOBase = VGAHWPTR(surface->pScrn)->IOBase; + WaitForVBlank(surface->pScrn); + OUTW(vgaIOBase + 4, 0x848E); + OUTW(vgaIOBase + 4, 0x0091); + pPriv->isOn = FALSE; + } + + return Success; +} + + +static int +TRIDENTFreeSurface( + XF86SurfacePtr surface +){ + OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; + + if(pPriv->isOn) + TRIDENTStopSurface(surface); + xf86FreeOffscreenLinear(pPriv->linear); + xfree(surface->pitches); + xfree(surface->offsets); + xfree(surface->devPrivate.ptr); + + return Success; +} + +static int +TRIDENTGetSurfaceAttribute( + ScrnInfoPtr pScrn, + Atom attribute, + INT32 *value +){ + return TRIDENTGetPortAttribute(pScrn, attribute, value, + (pointer)(GET_PORT_PRIVATE(pScrn))); +} + +static int +TRIDENTSetSurfaceAttribute( + ScrnInfoPtr pScrn, + Atom attribute, + INT32 value +){ + return TRIDENTSetPortAttribute(pScrn, attribute, value, + (pointer)(GET_PORT_PRIVATE(pScrn))); +} + +static int +TRIDENTDisplaySurface( + XF86SurfacePtr surface, + short src_x, short src_y, + short drw_x, short drw_y, + short src_w, short src_h, + short drw_w, short drw_h, + RegionPtr clipBoxes +){ + OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; + ScrnInfoPtr pScrn = surface->pScrn; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + TRIDENTPortPrivPtr portPriv = pTrident->adaptor->pPortPrivates[0].ptr; + INT32 x1, y1, x2, y2; + BoxRec dstBox; + + x1 = src_x; + x2 = src_x + src_w; + y1 = src_y; + y2 = src_y + src_h; + + dstBox.x1 = drw_x; + dstBox.x2 = drw_x + drw_w; + dstBox.y1 = drw_y; + dstBox.y2 = drw_y + drw_h; + + if(!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2, clipBoxes, + surface->width, surface->height)) + { + return Success; + } + + dstBox.x1 -= pScrn->frameX0; + dstBox.x2 -= pScrn->frameX0; + dstBox.y1 -= pScrn->frameY0; + dstBox.y2 -= pScrn->frameY0; + + TRIDENTResetVideo(pScrn); + + tridentFixFrame(pScrn,&portPriv->fixFrame); + TRIDENTDisplayVideo(pScrn, surface->id, surface->offsets[0], + surface->width, surface->height, surface->pitches[0], + x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); + + xf86XVFillKeyHelper(pScrn->pScreen, portPriv->colorKey, clipBoxes); + + pPriv->isOn = TRUE; + /* we've prempted the XvImage stream so set its free timer */ + if(portPriv->videoStatus & CLIENT_VIDEO_ON) { + REGION_EMPTY(pScrn->pScreen, &portPriv->clip); + UpdateCurrentTime(); + portPriv->videoStatus = FREE_TIMER; + portPriv->freeTime = currentTime.milliseconds + FREE_DELAY; + pTrident->VideoTimerCallback = TRIDENTVideoTimerCallback; + } + + return Success; +} + +static void +TRIDENTInitOffscreenImages(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + XF86OffscreenImagePtr offscreenImages; + + /* need to free this someplace */ + if(!(offscreenImages = xalloc(sizeof(XF86OffscreenImageRec)))) + return; + + offscreenImages[0].image = &Images[0]; + offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES | + VIDEO_CLIP_TO_VIEWPORT; + offscreenImages[0].alloc_surface = TRIDENTAllocateSurface; + offscreenImages[0].free_surface = TRIDENTFreeSurface; + offscreenImages[0].display = TRIDENTDisplaySurface; + offscreenImages[0].stop = TRIDENTStopSurface; + offscreenImages[0].setAttribute = TRIDENTSetSurfaceAttribute; + offscreenImages[0].getAttribute = TRIDENTGetSurfaceAttribute; + offscreenImages[0].max_width = 1024; + offscreenImages[0].max_height = 1024; + if (pTrident->Chipset >= CYBER9388) { + offscreenImages[0].num_attributes = NUM_ATTRIBUTES; + } else { + offscreenImages[0].num_attributes = 1; /* just colorkey */ + } + offscreenImages[0].attributes = Attributes; + + xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1); +} + +static void +TRIDENTVideoTimerCallback(ScrnInfoPtr pScrn, Time time) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + TRIDENTPortPrivPtr pPriv = pTrident->adaptor->pPortPrivates[0].ptr; + int vgaIOBase = VGAHWPTR(pScrn)->IOBase; + + if(pPriv->videoStatus & TIMER_MASK) { + if(pPriv->videoStatus & OFF_TIMER) { + if(pPriv->offTime < time) { + WaitForVBlank(pScrn); + OUTW(vgaIOBase + 4, 0x848E); + OUTW(vgaIOBase + 4, 0x0091); + pPriv->videoStatus = FREE_TIMER; + pPriv->freeTime = time + FREE_DELAY; + } + } else { /* FREE_TIMER */ + if(pPriv->freeTime < time) { + if(pPriv->linear) { + xf86FreeOffscreenLinear(pPriv->linear); + pPriv->linear = NULL; + } + pPriv->videoStatus = 0; + pTrident->VideoTimerCallback = NULL; + } + } + } else /* shouldn't get here */ + pTrident->VideoTimerCallback = NULL; +} + + /* Calculate skew offsets for video overlay */ + + +void +tridentFixFrame(ScrnInfoPtr pScrn, int *fixFrame) +{ + + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int vgaIOBase = VGAHWPTR(pScrn)->IOBase; + int HTotal, HSyncStart; + int VTotal, VSyncStart; + int h_off = 0; + int v_off = 0; + unsigned char CRTC[0x11]; + unsigned char hcenter, vcenter; + Bool isShadow; + unsigned char shadow = 0; + + if ((*fixFrame)++ < 100) + return; + + *fixFrame = 0; + + OUTB(0x3CE, CyberControl); + isShadow = ((INB(0x3CF) & 0x81) == 0x81); + + if (isShadow) + SHADOW_ENABLE(shadow); + + OUTB(vgaIOBase + 4, 0x0); + CRTC[0x0] = INB(vgaIOBase + 5); + OUTB(vgaIOBase + 4, 0x4); + CRTC[0x4] = INB(vgaIOBase + 5); + OUTB(vgaIOBase + 4, 0x5); + CRTC[0x5] = INB(vgaIOBase + 5); + OUTB(vgaIOBase + 4, 0x6); + CRTC[0x6] = INB(vgaIOBase + 5); + OUTB(vgaIOBase + 4, 0x7); + CRTC[0x7] = INB(vgaIOBase + 5); + OUTB(vgaIOBase + 4, 0x10); + CRTC[0x10] = INB(vgaIOBase + 5); + OUTB(0x3CE, HorStretch); + hcenter = INB(0x3CF); + OUTB(0x3CE, VertStretch); + vcenter = INB(0x3CF); + + HTotal = CRTC[0] << 3; + VTotal = CRTC[6] + | ((CRTC[7] & (1<<0)) << 8) + | ((CRTC[7] & (1<<5)) << 4); + HSyncStart = (CRTC[4] + + ((CRTC[5] >> 5) & 0x3)) << 3; + VSyncStart = CRTC[0x10] + | ((CRTC[7] & (1<<2)) << 6) + | ((CRTC[7] & (1<<7)) << 2); + + if (isShadow) { + SHADOW_RESTORE(shadow); + if (pTrident->lcdMode != 0xff) { + if (hcenter & 0x80) { + h_off = (LCD[pTrident->lcdMode].display_x + - pScrn->currentMode->HDisplay) >> 1; + switch (pTrident->Chipset) { + case BLADEXP: + h_off -= 5; + } + } + if (vcenter & 0x80) { + v_off = (LCD[pTrident->lcdMode].display_y + - pScrn->currentMode->VDisplay) >> 1; + } + } + } + + pTrident->hsync = HTotal - HSyncStart + 23 + h_off; + pTrident->vsync = VTotal - VSyncStart - 2 + v_off; + pTrident->hsync_rskew = 0; + pTrident->vsync_bskew = 0; + + /* + * HACK !! As awful as this is, it appears to be the only way....Sigh! + * We have XvHsync and XvVsync as options now, which adjust + * at the very end of this function. It'll be helpful for now + * and we can get more data on some of these skew values. + */ + switch (pTrident->Chipset) { + case TGUI9680: + /* Furthur tweaking needed */ + pTrident->hsync -= 84; + pTrident->vsync += 2; + break; + case PROVIDIA9682: + /* Furthur tweaking needed */ + pTrident->hsync += 7; + break; + case PROVIDIA9685: + /* Spot on */ + break; + case BLADEXP: + case CYBERBLADEXPAI1: + pTrident->hsync -= 15; + pTrident->hsync_rskew = 3; + break; + case BLADE3D: + if (pScrn->depth == 24) + pTrident->hsync -= 8; + else + pTrident->hsync -= 6; + break; + case CYBERBLADEI7: + case CYBERBLADEI7D: + case CYBERBLADEI1: + case CYBERBLADEI1D: + if (pScrn->depth == 24) + pTrident->hsync -= 7; + else + pTrident->hsync -= 6; + break; + case CYBERBLADEAI1: + pTrident->hsync -= 7; + break; + case CYBERBLADEAI1D: + pTrident->vsync += 2; + pTrident->vsync_bskew = -4; + pTrident->hsync -= 5; + break; + case CYBERBLADEE4: + pTrident->hsync -= 8; + break; + case CYBER9397: + pTrident->hsync -= 1; + pTrident->vsync -= 0; + pTrident->vsync_bskew = 0; + break; + case CYBER9397DVD: + pTrident->hsync_rskew = -1; + pTrident->vsync_bskew = -1; + break; + } + pTrident->hsync+=pTrident->OverrideHsync; + pTrident->vsync+=pTrident->OverrideVsync; + pTrident->hsync_rskew += pTrident->OverrideRskew; + pTrident->vsync_bskew += pTrident->OverrideBskew; +} + +static void +WaitForVBlank(ScrnInfoPtr pScrn) +{ + register vgaHWPtr hwp = VGAHWPTR(pScrn); + + /* We have to wait for one full VBlank to let the video engine start/stop. + * So the first may be waiting for too short a period as it may already + * be part way through the video frame. So we wait a second time to ensure + * full vblank has passed. + * - Alan. + */ + WAITFORVSYNC; + WAITFORVSYNC; +} diff --git a/driver/xf86-video-trident/src/tridenthelper.c b/driver/xf86-video-trident/src/tridenthelper.c new file mode 100644 index 000000000..b3772066b --- /dev/null +++ b/driver/xf86-video-trident/src/tridenthelper.c @@ -0,0 +1,347 @@ +/* + * Copyright 1992-2003 by Alan Hourihane, North Wales, UK. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Alan Hourihane, alanh@fairlite.demon.co.uk + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/tridenthelper.c,v 1.20 2001/10/28 03:33:52 tsi Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Version.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#include "vgaHW.h" + +#include "trident.h" +#include "trident_regs.h" + +static void IsClearTV(ScrnInfoPtr pScrn); + +void +TGUISetClock(ScrnInfoPtr pScrn, int clock, CARD8 *a, CARD8 *b) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int powerup[4] = { 1,2,4,8 }; + int clock_diff = 750; + int freq, ffreq; + int m, n, k; + int p, q, r, s; + int endn, endm, endk, startk; + + p = q = r = s = 0; + + IsClearTV(pScrn); + + if (pTrident->NewClockCode) + { + endn = 255; + endm = 63; + endk = 2; + if (clock >= 100000) startk = 0; else + if (clock >= 50000) startk = 1; else + startk = 2; + } + else + { + endn = 121; + endm = 31; + endk = 1; + if (clock > 50000) startk = 1; else + startk = 0; + } + + freq = clock; + + for (k=startk;k<=endk;k++) + for (n=0;n<=endn;n++) + for (m=1;m<=endm;m++) + { + ffreq = ( ( ((n + 8) * pTrident->frequency) / ((m + 2) * powerup[k]) ) * 1000); + if ((ffreq > freq - clock_diff) && (ffreq < freq + clock_diff)) + { +/* + * It seems that the 9440 docs have this STRICT limitation, although + * most 9440 boards seem to cope. 96xx/Cyber chips don't need this limit + * so, I'm gonna remove it and it allows lower clocks < 25.175 too ! + */ +#ifdef STRICT + if ( (n+8)*100/(m+2) < 978 && (n+8)*100/(m+2) > 349 ) { +#endif + clock_diff = (freq > ffreq) ? freq - ffreq : ffreq - freq; + p = n; q = m; r = k; s = ffreq; +#ifdef STRICT + } +#endif + } + } + + if (s == 0) + { + FatalError("Unable to set programmable clock.\n" + "Frequency %d is not a valid clock.\n" + "Please modify XF86Config for a new clock.\n", + freq); + } + + if (pTrident->NewClockCode) + { + /* N is all 8bits */ + *a = p; + /* M is first 6bits, with K last 2bits */ + *b = (q & 0x3F) | (r << 6); + } + else + { + /* N is first 7bits, first M bit is 8th bit */ + *a = ((1 & q) << 7) | p; + /* first 4bits are rest of M, 1bit for K value */ + *b = (((q & 0xFE) >> 1) | (r << 4)); + } + xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,3,"Found Clock %6.2f n=%i m=%i" + " k=%i\n",clock/1000.,p,q,r); +} + +static void +IsClearTV(ScrnInfoPtr pScrn) +{ + int vgaIOBase = VGAHWPTR(pScrn)->IOBase; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + CARD8 temp; + + if (pTrident->frequency != 0) return; + + OUTB(vgaIOBase + 4, 0xC0); + temp = INB(vgaIOBase + 5); + if (temp & 0x80) + pTrident->frequency = PAL; + else + pTrident->frequency = NTSC; +} + +void +TridentFindClock(ScrnInfoPtr pScrn, int clock) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + pTrident->MUX = FALSE; +#ifdef READOUT + pTrident->DontSetClock = FALSE; +#endif + pTrident->currentClock = clock; + + if (pTrident->IsCyber) { + Bool LCDActive; +#ifdef READOUT + Bool ShadowModeActive; + Bool HStretch; + Bool VStretch; +#endif + OUTB(0x3CE, FPConfig); + LCDActive = (INB(0x3CF) & 0x10); +#ifdef READOUT + OUTB(0x3CE,HorStretch); + HStretch = (INB(0x3CF) & 0x01); + OUTB(0x3CE,VertStretch); + VStretch = (INB(0x3CF) & 0x01); + + if (!(VStretch || HStretch) && LCDActive) { + CARD8 temp; + temp = INB(0x3C8); + temp = INB(0x3C6); + temp = INB(0x3C6); + temp = INB(0x3C6); + temp = INB(0x3C6); + pTrident->MUX = ((INB(0x3C6) & 0x20) == 0x20); + temp = INB(0x3C8); + pTrident->DontSetClock = TRUE; + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Keeping Clock for LCD Mode\n"); + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"MUX is %s\n",pTrident->MUX? + "on":"off"); + return; + } else +#endif + { + if (pTrident->lcdMode != 0xff && LCDActive) + pTrident->currentClock = clock = LCD[pTrident->lcdMode].clock; + } + + } +#ifndef READOUT + if (pTrident->Chipset != BLADEXP + && clock > pTrident->MUXThreshold) + pTrident->MUX = TRUE; + else + pTrident->MUX = FALSE; +#endif +} + +float +CalculateMCLK(ScrnInfoPtr pScrn) +{ + int vgaIOBase = VGAHWPTR(pScrn)->IOBase; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int a,b; + int m,n,k; + float freq = 0.0; + int powerup[4] = { 1,2,4,8 }; + CARD8 temp; + + if (pTrident->HasSGRAM) { + OUTB(vgaIOBase + 4, 0x28); + switch(INB(vgaIOBase + 5) & 0x07) { + case 0: + freq = 60; + break; + case 1: + freq = 78; + break; + case 2: + freq = 90; + break; + case 3: + freq = 120; + break; + case 4: + freq = 66; + break; + case 5: + freq = 83; + break; + case 6: + freq = 100; + break; + case 7: + freq = 132; + break; + } + } else { + OUTB(0x3C4, NewMode1); + temp = INB(0x3C5); + + OUTB(0x3C5, 0xC2); + if (!Is3Dchip) { + a = INB(0x43C6); + b = INB(0x43C7); + } else { + OUTB(0x3C4, 0x16); + a = INB(0x3C5); + OUTB(0x3C4, 0x17); + b = INB(0x3C5); + } + + OUTB(0x3C4, NewMode1); + OUTB(0x3C5, temp); + + IsClearTV(pScrn); + + if (pTrident->NewClockCode) { + m = b & 0x3F; + n = a; + k = (b & 0xC0) >> 6; + } else { + m = (a & 0x07); + k = (b & 0x02) >> 1; + n = ((a & 0xF8)>>3)|((b&0x01)<<5); + } + + freq = ((n+8)*pTrident->frequency)/((m+2)*powerup[k]); + } + return (freq); +} + +void +TGUISetMCLK(ScrnInfoPtr pScrn, int clock, CARD8 *a, CARD8 *b) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int powerup[4] = { 1,2,4,8 }; + int clock_diff = 750; + int freq, ffreq; + int m,n,k; + int p, q, r, s; + int startn, endn; + int endm, endk; + + p = q = r = s = 0; + + IsClearTV(pScrn); + + if (pTrident->NewClockCode) + { + startn = 64; + endn = 255; + endm = 63; + endk = 3; + } + else + { + startn = 0; + endn = 121; + endm = 31; + endk = 1; + } + + freq = clock; + + if (!pTrident->HasSGRAM) { + for (k=0;k<=endk;k++) + for (n=startn;n<=endn;n++) + for (m=1;m<=endm;m++) { + ffreq = ((((n+8)*pTrident->frequency)/((m+2)*powerup[k]))*1000); + if ((ffreq > freq - clock_diff) && (ffreq < freq + clock_diff)) + { + clock_diff = (freq > ffreq) ? freq - ffreq : ffreq - freq; + p = n; q = m; r = k; s = ffreq; + } + } + + if (s == 0) + { + FatalError("Unable to set memory clock.\n" + "Frequency %d is not a valid clock.\n" + "Please modify XF86Config for a new clock.\n", + freq); + } + + if (pTrident->NewClockCode) + { + /* N is all 8bits */ + *a = p; + /* M is first 6bits, with K last 2bits */ + *b = (q & 0x3F) | (r << 6); + } + else + { + /* N is first 7bits, first M bit is 8th bit */ + *a = ((1 & q) << 7) | p; + /* first 4bits are rest of M, 1bit for K value */ + *b = (((q & 0xFE) >> 1) | (r << 4)); + } + } +} + + + + diff --git a/driver/xf86-video-trident/src/tridentramdac.c b/driver/xf86-video-trident/src/tridentramdac.c new file mode 100644 index 000000000..299e782de --- /dev/null +++ b/driver/xf86-video-trident/src/tridentramdac.c @@ -0,0 +1,70 @@ +/* + * Copyright 1992-2003 by Alan Hourihane, North Wales, UK. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * + * TridentOutIndReg() and TridentInIndReg() are used to access + * the indirect Trident RAMDAC registers only. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/tridentramdac.c,v 1.4 2000/12/07 16:48:06 alanh Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "xf86_OSproc.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#include "trident_regs.h" +#include "trident.h" + +void +TridentWriteAddress(ScrnInfoPtr pScrn, CARD32 index) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + MMIO_OUTB(0x3C6, 0xFF); + MMIO_OUTB(0x3C8, index); +} + +void +TridentWriteData(ScrnInfoPtr pScrn, unsigned char data) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + MMIO_OUTB(0x3C9, data); +} + +void +TridentReadAddress(ScrnInfoPtr pScrn, CARD32 index) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + MMIO_OUTB(0x3C6, 0xFF); + MMIO_OUTB(0x3C7, index); +} + +unsigned char +TridentReadData(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + return(MMIO_INB(0x3C9)); +} diff --git a/driver/xf86-video-trident/src/tvga_dac.c b/driver/xf86-video-trident/src/tvga_dac.c new file mode 100644 index 000000000..442eed8fe --- /dev/null +++ b/driver/xf86-video-trident/src/tvga_dac.c @@ -0,0 +1,222 @@ +/* + * Copyright 1992-2003 by Alan Hourihane, North Wales, UK. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Alan Hourihane, alanh@fairlite.demon.co.uk + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/tvga_dac.c,v 1.7tsi Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Version.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#include "vgaHW.h" + +#include "trident.h" +#include "trident_regs.h" + +Bool +TVGAInit(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + TRIDENTRegPtr pReg = &pTrident->ModeReg; + int vgaIOBase; + int offset = 0; + int clock = mode->Clock; + vgaIOBase = VGAHWPTR(pScrn)->IOBase; + + OUTB(0x3C4, 0x0B); INB(0x3C5); /* Ensure we are in New Mode */ + + pReg->tridentRegsDAC[0x00] = 0x00; + OUTB(0x3C4, ConfPort2); + pReg->tridentRegs3C4[ConfPort2] = INB(0x3C5); + OUTB(0x3CE, MiscExtFunc); + pReg->tridentRegs3CE[MiscExtFunc] = INB(0x3CF) & 0xF0; + OUTB(vgaIOBase + 4, FIFOControl); + pReg->tridentRegs3x4[FIFOControl] = INB(vgaIOBase + 5) | 0x24; + + /* YUK ! here we have to mess with old mode operation */ + OUTB(0x3C4, 0x0B); OUTB(0x3C5, 0x00); /* Goto Old Mode */ + OUTB(0x3C4, OldMode2 + NewMode2); + pReg->tridentRegs3C4[OldMode2] = 0x10; + OUTB(0x3C4, 0x0B); INB(0x3C5); /* Back to New Mode */ + pReg->tridentRegs3x4[Underline] = 0x40; + if (pTrident->Chipset < TGUI9440AGi) + pReg->tridentRegs3x4[CRTCMode] = 0xA3; + + if (pScrn->videoRam > 512) + pReg->tridentRegs3C4[ConfPort2] |= 0x20; + else + pReg->tridentRegs3C4[ConfPort2] &= 0xDF; + + switch (pScrn->bitsPerPixel) { + case 8: + if (pScrn->videoRam < 1024) + offset = pScrn->displayWidth >> 3; + else + offset = pScrn->displayWidth >> 4; + pReg->tridentRegs3CE[MiscExtFunc] |= 0x02; + break; + case 16: + pReg->tridentRegs3CE[MiscExtFunc] |= 0x02; + offset = pScrn->displayWidth >> 3; + /* Reload with any chipset specific stuff here */ + if (pTrident->Chipset == TVGA8900D) { + if (pScrn->depth == 15) + pReg->tridentRegsDAC[0x00] = 0xA0; + else + pReg->tridentRegsDAC[0x00] = 0xE0; + pReg->tridentRegs3CE[MiscExtFunc] |= 0x08; /* Clock Div by 2*/ + clock *= 2; /* Double the clock */ + } + break; + case 24: + pReg->tridentRegs3CE[MiscExtFunc] |= 0x02; + offset = (pScrn->displayWidth * 3) >> 3; + pReg->tridentRegsDAC[0x00] = 0xD0; + break; + case 32: + pReg->tridentRegs3CE[MiscExtFunc] |= 0x02; + pReg->tridentRegs3CE[MiscExtFunc] |= 0x08; /* Clock Division by 2*/ + clock *= 2; /* Double the clock */ + offset = pScrn->displayWidth >> 1; + pReg->tridentRegsDAC[0x00] = 0x42; + break; + } + pReg->tridentRegs3x4[Offset] = offset & 0xFF; + + pReg->tridentRegsClock[0x00] = mode->ClockIndex; + + pReg->tridentRegs3C4[NewMode1] = 0x80; + + if (pTrident->Linear) + pReg->tridentRegs3x4[LinearAddReg] = ((pTrident->FbAddress >> 24) << 6)| + ((pTrident->FbAddress >> 20) & 0x0F)| + 0x20; + else { + pReg->tridentRegs3CE[MiscExtFunc] |= 0x04; + pReg->tridentRegs3x4[LinearAddReg] = 0; + } + + pReg->tridentRegs3x4[CRTCModuleTest] = + (mode->Flags & V_INTERLACE ? 0x84 : 0x80); + OUTB(vgaIOBase+ 4, AddColReg); + pReg->tridentRegs3x4[AddColReg] = (INB(vgaIOBase + 5) & 0xCF) | + ((offset & 0x100) >> 4); + + return(TRUE); +} + +void +TVGARestore(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int vgaIOBase; + vgaIOBase = VGAHWPTR(pScrn)->IOBase; + + /* Goto Old Mode */ + OUTB(0x3C4, 0x0B); + OUTB(0x3C5, 0x00); + OUTB(0x3C4, OldMode2 + NewMode2); + OUTB(0x3C5, tridentReg->tridentRegs3C4[OldMode2]); + + /* Goto New Mode */ + OUTB(0x3C4, 0x0B); + (void) INB(0x3C5); + + /* Unprotect registers */ + OUTW(0x3C4, (0x80 << 8) | NewMode1); + + (void) INB(0x3C8); + (void) INB(0x3C6); + (void) INB(0x3C6); + (void) INB(0x3C6); + (void) INB(0x3C6); + OUTB(0x3C6, tridentReg->tridentRegsDAC[0x00]); + (void) INB(0x3C8); + + OUTW_3x4(CRTCModuleTest); + OUTW_3x4(LinearAddReg); + OUTW_3x4(FIFOControl); + OUTW_3C4(ConfPort2); + OUTW_3x4(Underline); + if (pTrident->Chipset < TGUI9440AGi) + OUTW_3x4(CRTCMode); + OUTW_3x4(AddColReg); + OUTW_3CE(MiscExtFunc); + OUTW_3x4(Offset); + + TRIDENTClockSelect(pScrn, tridentReg->tridentRegsClock[0x00]); + + OUTW(0x3C4, ((tridentReg->tridentRegs3C4[NewMode1]) << 8)| NewMode1); +} + +void +TVGASave(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int vgaIOBase; + vgaIOBase = VGAHWPTR(pScrn)->IOBase; + + (void) INB(0x3C8); + (void) INB(0x3C6); + (void) INB(0x3C6); + (void) INB(0x3C6); + (void) INB(0x3C6); + tridentReg->tridentRegsDAC[0x00] = INB(0x3C6); + (void) INB(0x3C8); + + /* Goto Old Mode */ + OUTB(0x3C4, 0x0B); + OUTB(0x3C5, 0x00); + OUTB(0x3C4, OldMode2 + NewMode2); + tridentReg->tridentRegs3C4[OldMode2] = INB(0x3C5); + + /* Goto New Mode */ + OUTB(0x3C4, 0x0B); + (void) INB(0x3C5); + + INB_3C4(NewMode1); + + /* Unprotect registers */ + OUTW(0x3C4, ((0x80 ^ 0x02) << 8) | NewMode1); + OUTW(vgaIOBase + 4, (0x92 << 8) | NewMode1); + + INB_3x4(Underline); + if (pTrident->Chipset < TGUI9440AGi) + INB_3x4(CRTCMode); + INB_3x4(LinearAddReg); + INB_3x4(FIFOControl); + INB_3x4(CRTCModuleTest); + INB_3x4(AddColReg); + INB_3CE(MiscExtFunc); + INB_3C4(ConfPort2); + + TRIDENTClockSelect(pScrn, CLK_REG_SAVE); + + /* Protect registers */ + OUTW_3C4(NewMode1); +} diff --git a/driver/xf86-video-trident/src/xp4_accel.c b/driver/xf86-video-trident/src/xp4_accel.c new file mode 100644 index 000000000..9ac3e9778 --- /dev/null +++ b/driver/xf86-video-trident/src/xp4_accel.c @@ -0,0 +1,558 @@ +/* + * Copyright 1992-2003 by Alan Hourihane, North Wales, UK. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * + * CyberBladeXP4 accelerated options. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/xp_accel.c,v 1.8tsi Exp $ */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "xf86_OSproc.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#include "miline.h" + +#include "trident.h" +#include "trident_regs.h" + +#include "xaarop.h" + +static void XP4Sync(ScrnInfoPtr pScrn); +#if 0 +static void XP4SetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, + int rop, unsigned int planemask, int length, + unsigned char *pattern); +static void XP4SubsequentDashedBresenhamLine(ScrnInfoPtr pScrn, + int x, int y, int dmaj, int dmin, int e, + int len, int octant, int phase); +static void XP4SetupForSolidLine(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask); +static void XP4SubsequentSolidBresenhamLine(ScrnInfoPtr pScrn, + int x, int y, int dmaj, int dmin, int e, + int len, int octant); +#endif +static void XP4SubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, + int len, int dir); +static void XP4SetupForFillRectSolid(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask); +static void XP4SubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, + int y, int w, int h); +static void XP4SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, + int x1, int y1, int x2, + int y2, int w, int h); +static void XP4SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, + int xdir, int ydir, int rop, + unsigned int planemask, + int transparency_color); +static void XP4SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, + int patternx, int patterny, int fg, int bg, + int rop, unsigned int planemask); +static void XP4SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, + int patternx, int patterny, int x, int y, + int w, int h); +static void XP4SetupForCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int fg, int bg, int rop, + unsigned int planemask); +static void XP4SubsequentCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, int x, + int y, int w, int h, int skipleft); + +static int bpp; +static int ropcode; + +static void +XP4InitializeAccelerator(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int shift; + + /* This forces updating the clipper */ + pTrident->Clipping = TRUE; + + CHECKCLIPPING; + + switch (pScrn->bitsPerPixel) { + case 8: + default: /* Muffle compiler */ + shift = 18; + break; + case 16: + shift = 19; + break; + case 32: + shift = 20; + break; + } + + switch (pScrn->bitsPerPixel) { + case 8: + bpp = 0x40; + break; + case 16: + bpp = 0x41; + break; + case 32: + bpp = 0x42; + break; + } + MMIO_OUT32(pTrident->IOBase, 0x2154, (pScrn->displayWidth) << shift); + MMIO_OUT32(pTrident->IOBase, 0x2150, (pScrn->displayWidth) << shift); +} + +Bool +XP4XaaInit(ScreenPtr pScreen) +{ + XAAInfoRecPtr infoPtr; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + if (pTrident->NoAccel) + return FALSE; + + pTrident->AccelInfoRec = infoPtr = XAACreateInfoRec(); + if (!infoPtr) return FALSE; + + infoPtr->Flags = PIXMAP_CACHE | + OFFSCREEN_PIXMAPS | + LINEAR_FRAMEBUFFER; + + pTrident->InitializeAccelerator = XP4InitializeAccelerator; + XP4InitializeAccelerator(pScrn); + + infoPtr->Sync = XP4Sync; + +#if 0 /* TO DO for the XP */ + infoPtr->SolidLineFlags = NO_PLANEMASK; + infoPtr->SetupForSolidLine = XP4SetupForSolidLine; + infoPtr->SolidBresenhamLineErrorTermBits = 12; + infoPtr->SubsequentSolidBresenhamLine = XP4SubsequentSolidBresenhamLine; + + infoPtr->DashedLineFlags = LINE_PATTERN_MSBFIRST_LSBJUSTIFIED | + NO_PLANEMASK | + LINE_PATTERN_POWER_OF_2_ONLY; + infoPtr->SetupForDashedLine = XP4SetupForDashedLine; + infoPtr->DashedBresenhamLineErrorTermBits = 12; + infoPtr->SubsequentDashedBresenhamLine = + XP4SubsequentDashedBresenhamLine; + infoPtr->DashPatternMaxLength = 16; +#endif + + + infoPtr->SolidFillFlags = NO_PLANEMASK; + infoPtr->SetupForSolidFill = XP4SetupForFillRectSolid; + infoPtr->SubsequentSolidFillRect = XP4SubsequentFillRectSolid; +#if 0 + infoPtr->SubsequentSolidHorVertLine = XP4SubsequentSolidHorVertLine; +#endif + + infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK | NO_TRANSPARENCY; + + infoPtr->SetupForScreenToScreenCopy = + XP4SetupForScreenToScreenCopy; + infoPtr->SubsequentScreenToScreenCopy = + XP4SubsequentScreenToScreenCopy; + + infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK | + HARDWARE_PATTERN_PROGRAMMED_BITS | + HARDWARE_PATTERN_SCREEN_ORIGIN | + BIT_ORDER_IN_BYTE_MSBFIRST; + + infoPtr->SetupForMono8x8PatternFill = + XP4SetupForMono8x8PatternFill; + infoPtr->SubsequentMono8x8PatternFillRect = + XP4SubsequentMono8x8PatternFillRect; + +#if 0 + infoPtr->CPUToScreenColorExpandFillFlags = NO_PLANEMASK | + BIT_ORDER_IN_BYTE_MSBFIRST; + infoPtr->ColorExpandBase = pTrident->D3Base; + infoPtr->ColorExpandRange = pScrn->displayWidth; + + infoPtr->SetupForCPUToScreenColorExpandFill = + XP4SetupForCPUToScreenColorExpandFill; + infoPtr->SubsequentCPUToScreenColorExpandFill = + XP4SubsequentCPUToScreenColorExpandFill; +#endif + + return(XAAInit(pScreen, infoPtr)); +} + +static void +XP4Sync(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int count = 0, timeout = 0; + int busy; + + for (;;) { + BLTBUSY(busy); + if (busy != GE_BUSY) { + return; + } + count++; + if (count == 10000000) { + ErrorF("XP: BitBLT engine time-out.\n"); + count = 9990000; + timeout++; + if (timeout == 4) { + /* Reset BitBLT Engine */ + TGUI_STATUS(0x00); + return; + } + } + } +} + +static void +XP4SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, + int xdir, int ydir, int rop, + unsigned int planemask, int transparency_color) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int dst = 0; + + pTrident->BltScanDirection = 0; + if (xdir < 0) pTrident->BltScanDirection |= XNEG; + if (ydir < 0) pTrident->BltScanDirection |= YNEG; + + REPLICATE(transparency_color); + if (transparency_color != -1) { + dst |= 3<<16; + MMIO_OUT32(pTrident->IOBase, 0x2134, transparency_color); + } + + ropcode = rop; + + MMIO_OUT32(pTrident->IOBase, 0x2128, pTrident->BltScanDirection | SCR2SCR); +} + +static void +XP4SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, + int x2, int y2, int w, int h) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + if (pTrident->BltScanDirection & YNEG) { + y1 = y1 + h - 1; + y2 = y2 + h - 1; + } + if (pTrident->BltScanDirection & XNEG) { + x1 = x1 + w - 1; + x2 = x2 + w - 1; + } + MMIO_OUT32(pTrident->IOBase, 0x2138, x2<<16 | y2); + MMIO_OUT32(pTrident->IOBase, 0x213C, x1<<16 | y1); + MMIO_OUT32(pTrident->IOBase, 0x2140, w<<16 | h); + XP4Sync(pScrn); + MMIO_OUT32(pTrident->IOBase, 0x2124, XAAGetCopyROP(ropcode) << 24 | bpp << 8 | 1); +} + +#if 0 +static void +XP4SetupForSolidLine(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + pTrident->BltScanDirection = 0; + REPLICATE(color); + TGUI_FMIX(XAAPatternROP[rop]); + if (pTrident->Chipset >= PROVIDIA9685) { + TGUI_FPATCOL(color); + } else { + TGUI_FCOLOUR(color); + } +} + +static void +XP4SubsequentSolidBresenhamLine( ScrnInfoPtr pScrn, + int x, int y, int dmaj, int dmin, int e, int len, int octant) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int tmp = pTrident->BltScanDirection; + + if (octant & YMAJOR) tmp |= YMAJ; + if (octant & XDECREASING) tmp |= XNEG; + if (octant & YDECREASING) tmp |= YNEG; + TGUI_DRAWFLAG(SOLIDFILL | STENCIL | tmp); + XP_SRC_XY(dmin-dmaj,dmin); + XP_DEST_XY(x,y); + XP_DIM_XY(dmin+e,len); + TGUI_COMMAND(GE_BRESLINE); + XP4Sync(pScrn); +} +#endif + +static void +XP4SubsequentSolidHorVertLine( + ScrnInfoPtr pScrn, + int x, int y, + int len, int dir +){ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + TGUI_DRAWFLAG(SOLIDFILL); + if (dir == DEGREES_0) { + XP_DIM_XY(len,1); + XP_DEST_XY(x,y); + } else { + XP_DIM_XY(1,len); + XP_DEST_XY(x,y); + } + TGUI_COMMAND(GE_BLT); + XP4Sync(pScrn); +} + +#if 0 +void +XP4SetupForDashedLine( + ScrnInfoPtr pScrn, + int fg, int bg, int rop, + unsigned int planemask, + int length, + unsigned char *pattern +){ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + CARD32 *DashPattern = (CARD32*)pattern; + CARD32 NiceDashPattern = DashPattern[0]; + + NiceDashPattern = *((CARD16 *)pattern) & ((1<<length) - 1); + switch(length) { + case 2: NiceDashPattern |= NiceDashPattern << 2; + case 4: NiceDashPattern |= NiceDashPattern << 4; + case 8: NiceDashPattern |= NiceDashPattern << 8; + } + pTrident->BltScanDirection = 0; + REPLICATE(fg); + if (pTrident->Chipset >= PROVIDIA9685) { + TGUI_FPATCOL(fg); + if (bg == -1) { + pTrident->BltScanDirection |= 1<<12; + TGUI_BPATCOL(~fg); + } else { + REPLICATE(bg); + TGUI_BPATCOL(bg); + } + } else { + TGUI_FCOLOUR(fg); + if (bg == -1) { + pTrident->BltScanDirection |= 1<<12; + TGUI_BCOLOUR(~fg); + } else { + REPLICATE(bg); + TGUI_BCOLOUR(bg); + } + } + TGUI_FMIX(XAAPatternROP[rop]); + pTrident->LinePattern = NiceDashPattern; +} + +void +XP4SubsequentDashedBresenhamLine(ScrnInfoPtr pScrn, + int x, int y, int dmaj, int dmin, int e, int len, int octant, int phase) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int tmp = pTrident->BltScanDirection; + + if (octant & YMAJOR) tmp |= YMAJ; + if (octant & XDECREASING) tmp |= XNEG; + if (octant & YDECREASING) tmp |= YNEG; + + TGUI_STYLE(((pTrident->LinePattern >> phase) | + (pTrident->LinePattern << (16-phase))) & 0x0000FFFF); + TGUI_DRAWFLAG(STENCIL | tmp); + XP_SRC_XY(dmin-dmaj,dmin); + XP_DEST_XY(x,y); + XP_DIM_XY(e+dmin,len); + TGUI_COMMAND(GE_BRESLINE); + XP4Sync(pScrn); +} +#endif + +static void +XP4SetupForFillRectSolid(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + ropcode = rop; + + REPLICATE(color); + MMIO_OUT32(pTrident->IOBase, 0x2158, color); + MMIO_OUT32(pTrident->IOBase, 0x2128, 1<<14); +} + +static void +XP4SubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + MMIO_OUT32(pTrident->IOBase, 0x2138, x<<16 | y); + MMIO_OUT32(pTrident->IOBase, 0x2140, w<<16 | h); + XP4Sync(pScrn); + MMIO_OUT32(pTrident->IOBase, 0x2124, XAAGetPatternROP(ropcode) << 24 | bpp << 8 | 2); +} + +#if 1 +static void MoveDWORDS( + register CARD32* dest, + register CARD32* src, + register int dwords ) +{ + while(dwords & ~0x03) { + *dest = *src; + *(dest + 1) = *(src + 1); + *(dest + 2) = *(src + 2); + *(dest + 3) = *(src + 3); + src += 4; + dest += 4; + dwords -= 4; + } + if (!dwords) return; + *dest = *src; + dest += 1; + src += 1; + if (dwords == 1) return; + *dest = *src; + dest += 1; + src += 1; + if (dwords == 2) return; + *dest = *src; + dest += 1; + src += 1; +} +#endif + +#if 1 +static void MoveDWORDS_FixedBase( + register CARD32* dest, + register CARD32* src, + register int dwords ) +{ + while(dwords & ~0x03) { + *dest = *src; + *dest = *(src + 1); + *dest = *(src + 2); + *dest = *(src + 3); + dwords -= 4; + src += 4; + } + + if(!dwords) return; + *dest = *src; + if(dwords == 1) return; + *dest = *(src + 1); + if(dwords == 2) return; + *dest = *(src + 2); +} +#endif + + +static void +XP4SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, + int patternx, int patterny, + int fg, int bg, int rop, + unsigned int planemask) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int drawflag = 0; + + REPLICATE(fg); + MMIO_OUT32(pTrident->IOBase, 0x2158, fg); + + if (bg == -1) { + drawflag |= 1<<12; + MMIO_OUT32(pTrident->IOBase, 0x215C, ~fg); + } else { + REPLICATE(bg); + MMIO_OUT32(pTrident->IOBase, 0x215C, bg); + } + + ropcode = rop; + + drawflag |= 7<<18; + TGUI_DRAWFLAG(PATMONO | drawflag); +} + +static void +XP4SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, + int patternx, int patterny, + int x, int y, + int w, int h) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + MMIO_OUT32(pTrident->IOBase, 0x2180, patternx); + MMIO_OUT32(pTrident->IOBase, 0x2184, patterny); + MMIO_OUT32(pTrident->IOBase, 0x2138, x<<16 | y); + MMIO_OUT32(pTrident->IOBase, 0x2140, w<<16 | h); + XP4Sync(pScrn); + MMIO_OUT32(pTrident->IOBase, 0x2124, XAAGetPatternROP(ropcode) << 24 | bpp << 8 | 2); +} + +#if 1 +static void +XP4SetupForCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int fg, int bg, + int rop, + unsigned int planemask +){ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + ropcode = XAAGetCopyROP(rop); +#if 0 + TGUI_FMIX(XAACopyROP[rop]); +#endif + if (bg == -1) { + TGUI_DRAWFLAG(SRCMONO | 1<<12); + REPLICATE(fg); + TGUI_FCOLOUR(fg); + } else { + TGUI_DRAWFLAG(SRCMONO); + REPLICATE(fg); + REPLICATE(bg); + TGUI_FCOLOUR(fg); + TGUI_BCOLOUR(bg); + } +} + +static void +XP4SubsequentCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int x, int y, int w, int h, + int skipleft +){ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + MMIO_OUT32(pTrident->IOBase, 0x2138, x<<16 | y); + MMIO_OUT32(pTrident->IOBase, 0x2140, w<<16 | h); + XP4Sync(pScrn); + MMIO_OUT32(pTrident->IOBase, 0x2124, ropcode << 24 | bpp << 8 | 2); +} +#endif diff --git a/driver/xf86-video-trident/src/xp4_accel_exa.c b/driver/xf86-video-trident/src/xp4_accel_exa.c new file mode 100644 index 000000000..75da2a3c6 --- /dev/null +++ b/driver/xf86-video-trident/src/xp4_accel_exa.c @@ -0,0 +1,274 @@ +/* + * Copyright 2006 by Alan Hourihane, North Wales, UK. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the authors not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The authors make no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * + * Trident XP4/XP5 accelerated options. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "exa.h" +#include "picture.h" + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Pci.h" +#include "xf86PciInfo.h" +#include "xaarop.h" + +#include "trident.h" +#include "trident_regs.h" + +static int ropcode; + +static int CopyROP[16] = +{ + ROP_0, /* GXclear */ + ROP_DSa, /* GXand */ + ROP_SDna, /* GXandReverse */ + ROP_S, /* GXcopy */ + ROP_DSna, /* GXandInverted */ + ROP_D, /* GXnoop */ + ROP_DSx, /* GXxor */ + ROP_DSo, /* GXor */ + ROP_DSon, /* GXnor */ + ROP_DSxn, /* GXequiv */ + ROP_Dn, /* GXinvert*/ + ROP_SDno, /* GXorReverse */ + ROP_Sn, /* GXcopyInverted */ + ROP_DSno, /* GXorInverted */ + ROP_DSan, /* GXnand */ + ROP_1 /* GXset */ +}; + +static int PatternROP[16]= +{ + ROP_0, + ROP_DPa, + ROP_PDna, + ROP_P, + ROP_DPna, + ROP_D, + ROP_DPx, + ROP_DPo, + ROP_DPon, + ROP_PDxn, + ROP_Dn, + ROP_PDno, + ROP_Pn, + ROP_DPno, + ROP_DPan, + ROP_1 +}; + +static int GetCopyROP(int i) +{ + return CopyROP[i]; +} + +static int GetPatternROP(int i) +{ + return PatternROP[i]; +} + +static void +XP4WaitMarker(ScreenPtr pScreen, int Marker) +{ + /* Don't need a wait marker as we need to sync on all operations */ +} + +static void +XP4Done(PixmapPtr p) { + ScrnInfoPtr pScrn = xf86Screens[p->drawable.pScreen->myNum]; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int count = 0, timeout = 0; + int busy; + + for (;;) { + BLTBUSY(busy); + if (busy != GE_BUSY) { + return; + } + count++; + if (count == 10000000) { + ErrorF("XP: BitBLT engine time-out.\n"); + count = 9990000; + timeout++; + if (timeout == 4) { + /* Reset BitBLT Engine */ + TGUI_STATUS(0x00); + return; + } + } + } +} + +static Bool +XP4PrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg) +{ + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + unsigned int dorg = exaGetPixmapOffset(pPixmap); + unsigned int dptch = exaGetPixmapPitch(pPixmap); + + if (planemask != -1) + return FALSE; + + ropcode = alu; + + MMIO_OUT32(pTrident->IOBase, 0x2150, (dptch << 18) | (dorg >> 4)); + + REPLICATE(fg); + MMIO_OUT32(pTrident->IOBase, 0x2158, fg); + MMIO_OUT32(pTrident->IOBase, 0x2128, 1<<14); + + return TRUE; +} + +static void +XP4Solid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) +{ + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int bpp; + + switch (pPixmap->drawable.bitsPerPixel) { + case 8: + bpp = 0x40; + break; + case 16: + bpp = 0x41; + break; + case 32: + bpp = 0x42; + break; + } + + MMIO_OUT32(pTrident->IOBase, 0x2138, x1<<16 | y1); + MMIO_OUT32(pTrident->IOBase, 0x2140, (x2-x1)<<16 | (y2-y1)); + MMIO_OUT32(pTrident->IOBase, 0x2124, GetPatternROP(ropcode) << 24 | bpp << 8 | 2); +} + +static Bool +XP4PrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int dx, int dy, + int alu, Pixel planemask) +{ + ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + unsigned int sorg = exaGetPixmapOffset(pSrcPixmap); + unsigned int dorg = exaGetPixmapOffset(pDstPixmap); + unsigned int sptch = exaGetPixmapPitch(pSrcPixmap); + unsigned int dptch = exaGetPixmapPitch(pDstPixmap); + + if (planemask != -1) + return FALSE; + + pTrident->BltScanDirection = 0; + if (dx < 0) pTrident->BltScanDirection |= XNEG; + if (dy < 0) pTrident->BltScanDirection |= YNEG; + + ropcode = alu; + + MMIO_OUT32(pTrident->IOBase, 0x2154, (sptch << 18) | (sorg >> 4)); + MMIO_OUT32(pTrident->IOBase, 0x2150, (dptch << 18) | (dorg >> 4)); + + return TRUE; +} + +static void +XP4Copy(PixmapPtr pDstPixmap, int x1, int y1, int x2, int y2, int w, int h) +{ + ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int bpp; + + switch (pDstPixmap->drawable.bitsPerPixel) { + case 8: + bpp = 0x40; + break; + case 16: + bpp = 0x41; + break; + case 32: + bpp = 0x42; + break; + } + + if (pTrident->BltScanDirection & YNEG) { + y1 = y1 + h - 1; + y2 = y2 + h - 1; + } + if (pTrident->BltScanDirection & XNEG) { + x1 = x1 + w - 1; + x2 = x2 + w - 1; + } + MMIO_OUT32(pTrident->IOBase, 0x2128, pTrident->BltScanDirection | SCR2SCR); + MMIO_OUT32(pTrident->IOBase, 0x2138, x2<<16 | y2); + MMIO_OUT32(pTrident->IOBase, 0x213C, x1<<16 | y1); + MMIO_OUT32(pTrident->IOBase, 0x2140, w<<16 | h); + MMIO_OUT32(pTrident->IOBase, 0x2124, GetCopyROP(ropcode) << 24 | bpp << 8 | 1); +} + +Bool +XP4ExaInit(ScreenPtr pScreen) +{ + ExaDriverPtr pExa; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + if (pTrident->NoAccel) + return FALSE; + + if (!(pExa = pTrident->EXADriverPtr = exaDriverAlloc())) { + pTrident->NoAccel = TRUE; + return FALSE; + } + + pExa->exa_major = 2; + pExa->exa_minor = 0; + + pExa->flags = EXA_OFFSCREEN_PIXMAPS; + pExa->memoryBase = pTrident->FbBase; + pExa->memorySize = pTrident->FbMapSize; + pExa->offScreenBase = pScrn->displayWidth * pScrn->virtualY * + ((pScrn->bitsPerPixel + 7) / 8); + + pExa->pixmapOffsetAlign = 16; + pExa->pixmapPitchAlign = 16; + + pExa->maxX = 4095; + pExa->maxY = 4095; + + pExa->WaitMarker = XP4WaitMarker; + + pExa->PrepareSolid = XP4PrepareSolid; + pExa->Solid = XP4Solid; + pExa->DoneSolid = XP4Done; + + pExa->PrepareCopy = XP4PrepareCopy; + pExa->Copy = XP4Copy; + pExa->DoneCopy = XP4Done; + + return(exaDriverInit(pScreen, pExa)); +} diff --git a/driver/xf86-video-trident/src/xp_accel.c b/driver/xf86-video-trident/src/xp_accel.c new file mode 100644 index 000000000..d7150422e --- /dev/null +++ b/driver/xf86-video-trident/src/xp_accel.c @@ -0,0 +1,593 @@ +/* + * Copyright 1992-2003 by Alan Hourihane, North Wales, UK. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * + * BladeXP accelerated options. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/xp_accel.c,v 1.6 2003/10/30 13:38:02 alanh Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "xf86_OSproc.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#include "miline.h" + +#include "trident.h" +#include "trident_regs.h" + +#include "xaalocal.h" +#include "xaarop.h" + +static void XPSync(ScrnInfoPtr pScrn); +#if 0 +static void XPSetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, + int rop, unsigned int planemask, int length, + unsigned char *pattern); +static void XPSubsequentDashedBresenhamLine(ScrnInfoPtr pScrn, + int x, int y, int dmaj, int dmin, int e, + int len, int octant, int phase); +static void XPSetupForSolidLine(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask); +static void XPSubsequentSolidBresenhamLine(ScrnInfoPtr pScrn, + int x, int y, int dmaj, int dmin, int e, + int len, int octant); +#endif +static void XPSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, + int len, int dir); +static void XPSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask); +static void XPSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, + int y, int w, int h); +static void XPSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, + int x1, int y1, int x2, + int y2, int w, int h); +static void XPSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, + int xdir, int ydir, int rop, + unsigned int planemask, + int transparency_color); +static void XPSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, + int patternx, int patterny, int fg, int bg, + int rop, unsigned int planemask); +static void XPSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, + int patternx, int patterny, int x, int y, + int w, int h); +#if 0 +static void XPSetupForScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int fg, int bg, int rop, + unsigned int planemask); +static void XPSubsequentScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, int x, + int y, int w, int h, int skipleft); +static void XPSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno); +#endif + +static void +XPInitializeAccelerator(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int shift; + + /* This forces updating the clipper */ + pTrident->Clipping = TRUE; + + CHECKCLIPPING; + + BLADE_XP_OPERMODE(pTrident->EngineOperation); + pTrident->EngineOperation |= 0x40; + switch (pScrn->bitsPerPixel) { + case 8: + default: /* Muffle compiler */ + shift = 18; + break; + case 16: + shift = 19; + break; + case 32: + shift = 20; + break; + } + MMIO_OUT32(pTrident->IOBase, 0x2154, (pScrn->displayWidth) << shift); + MMIO_OUT32(pTrident->IOBase, 0x2150, (pScrn->displayWidth) << shift); + MMIO_OUT8(pTrident->IOBase, 0x2126, 3); +} + +Bool +XPAccelInit(ScreenPtr pScreen) +{ + XAAInfoRecPtr infoPtr; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + if (pTrident->NoAccel) + return FALSE; + + pTrident->AccelInfoRec = infoPtr = XAACreateInfoRec(); + if (!infoPtr) return FALSE; + + infoPtr->Flags = PIXMAP_CACHE | + OFFSCREEN_PIXMAPS | + LINEAR_FRAMEBUFFER; + + pTrident->InitializeAccelerator = XPInitializeAccelerator; + XPInitializeAccelerator(pScrn); + + infoPtr->Sync = XPSync; + +#if 0 /* TO DO for the XP */ + infoPtr->SolidLineFlags = NO_PLANEMASK; + infoPtr->SetupForSolidLine = XPSetupForSolidLine; + infoPtr->SolidBresenhamLineErrorTermBits = 12; + infoPtr->SubsequentSolidBresenhamLine = XPSubsequentSolidBresenhamLine; + + infoPtr->DashedLineFlags = LINE_PATTERN_MSBFIRST_LSBJUSTIFIED | + NO_PLANEMASK | + LINE_PATTERN_POWER_OF_2_ONLY; + infoPtr->SetupForDashedLine = XPSetupForDashedLine; + infoPtr->DashedBresenhamLineErrorTermBits = 12; + infoPtr->SubsequentDashedBresenhamLine = + XPSubsequentDashedBresenhamLine; + infoPtr->DashPatternMaxLength = 16; +#endif + + infoPtr->SolidFillFlags = NO_PLANEMASK; + infoPtr->SetupForSolidFill = XPSetupForFillRectSolid; + infoPtr->SubsequentSolidFillRect = XPSubsequentFillRectSolid; + infoPtr->SubsequentSolidHorVertLine = XPSubsequentSolidHorVertLine; + + infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK | NO_TRANSPARENCY; + + infoPtr->SetupForScreenToScreenCopy = + XPSetupForScreenToScreenCopy; + infoPtr->SubsequentScreenToScreenCopy = + XPSubsequentScreenToScreenCopy; + + infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK | + HARDWARE_PATTERN_PROGRAMMED_BITS | + BIT_ORDER_IN_BYTE_MSBFIRST; + + infoPtr->SetupForMono8x8PatternFill = + XPSetupForMono8x8PatternFill; + infoPtr->SubsequentMono8x8PatternFillRect = + XPSubsequentMono8x8PatternFillRect; + +#if 0 /* Needs fixing */ + infoPtr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK | + BIT_ORDER_IN_BYTE_MSBFIRST; + + pTrident->XAAScanlineColorExpandBuffers[0] = + xnfalloc(((pScrn->virtualX + 63)) *4* (pScrn->bitsPerPixel / 8)); + + infoPtr->NumScanlineColorExpandBuffers = 1; + infoPtr->ScanlineColorExpandBuffers = + pTrident->XAAScanlineColorExpandBuffers; + + infoPtr->SetupForScanlineCPUToScreenColorExpandFill = + XPSetupForScanlineCPUToScreenColorExpandFill; + infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = + XPSubsequentScanlineCPUToScreenColorExpandFill; + infoPtr->SubsequentColorExpandScanline = + XPSubsequentColorExpandScanline; +#endif + + return(XAAInit(pScreen, infoPtr)); +} + +static void +XPSync(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int count = 0, timeout = 0; + int busy; + + BLADE_XP_OPERMODE(pTrident->EngineOperation); + + for (;;) { + BLTBUSY(busy); + if (busy != GE_BUSY) { + return; + } + count++; + if (count == 10000000) { + ErrorF("XP: BitBLT engine time-out.\n"); + count = 9990000; + timeout++; + if (timeout == 8) { + /* Reset BitBLT Engine */ + TGUI_STATUS(0x00); + return; + } + } + } +} + +static void +XPClearSync(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int count = 0, timeout = 0; + int busy; + + for (;;) { + BLTBUSY(busy); + if (busy != GE_BUSY) { + return; + } + count++; + if (count == 10000000) { + ErrorF("XP: BitBLT engine time-out.\n"); + count = 9990000; + timeout++; + if (timeout == 8) { + /* Reset BitBLT Engine */ + TGUI_STATUS(0x00); + return; + } + } + } +} + +static void +XPSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, + int xdir, int ydir, int rop, + unsigned int planemask, int transparency_color) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int dst = 0; + + pTrident->BltScanDirection = 0; + if (xdir < 0) pTrident->BltScanDirection |= XNEG; + if (ydir < 0) pTrident->BltScanDirection |= YNEG; + + REPLICATE(transparency_color); + if (transparency_color != -1) { + dst |= 3<<16; + MMIO_OUT32(pTrident->IOBase, 0x2134, transparency_color); + } + + TGUI_DRAWFLAG(pTrident->BltScanDirection | SCR2SCR | dst); + TGUI_FMIX(XAAGetCopyROP(rop)); +} + +static void +XPSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, + int x2, int y2, int w, int h) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + if (pTrident->BltScanDirection & YNEG) { + y1 = y1 + h - 1; + y2 = y2 + h - 1; + } + if (pTrident->BltScanDirection & XNEG) { + x1 = x1 + w - 1; + x2 = x2 + w - 1; + } + XP_SRC_XY(x1,y1); + XP_DEST_XY(x2,y2); + XP_DIM_XY(w,h); + TGUI_COMMAND(GE_BLT); + XPClearSync(pScrn); +} + +#if 0 +static void +XPSetupForSolidLine(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + pTrident->BltScanDirection = 0; + REPLICATE(color); + TGUI_FMIX(XAAGetPatternROP(rop)); + if (pTrident->Chipset >= PROVIDIA9685) { + TGUI_FPATCOL(color); + } else { + TGUI_FCOLOUR(color); + } +} + +static void +XPSubsequentSolidBresenhamLine( ScrnInfoPtr pScrn, + int x, int y, int dmaj, int dmin, int e, int len, int octant) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int tmp = pTrident->BltScanDirection; + + if (octant & YMAJOR) tmp |= YMAJ; + if (octant & XDECREASING) tmp |= XNEG; + if (octant & YDECREASING) tmp |= YNEG; + TGUI_DRAWFLAG(SOLIDFILL | STENCIL | tmp); + XP_SRC_XY(dmin-dmaj,dmin); + XP_DEST_XY(x,y); + XP_DIM_XY(dmin+e,len); + TGUI_COMMAND(GE_BRESLINE); + XPSync(pScrn); +} +#endif + +static void +XPSubsequentSolidHorVertLine( + ScrnInfoPtr pScrn, + int x, int y, + int len, int dir +){ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + TGUI_DRAWFLAG(SOLIDFILL); + if (dir == DEGREES_0) { + XP_DIM_XY(len,1); + XP_DEST_XY(x,y); + } else { + XP_DIM_XY(1,len); + XP_DEST_XY(x,y); + } + TGUI_COMMAND(GE_BLT); + XPSync(pScrn); +} + +#if 0 +void +XPSetupForDashedLine( + ScrnInfoPtr pScrn, + int fg, int bg, int rop, + unsigned int planemask, + int length, + unsigned char *pattern +){ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + CARD32 *DashPattern = (CARD32*)pattern; + CARD32 NiceDashPattern = DashPattern[0]; + + NiceDashPattern = *((CARD16 *)pattern) & ((1<<length) - 1); + switch(length) { + case 2: NiceDashPattern |= NiceDashPattern << 2; + case 4: NiceDashPattern |= NiceDashPattern << 4; + case 8: NiceDashPattern |= NiceDashPattern << 8; + } + pTrident->BltScanDirection = 0; + REPLICATE(fg); + if (pTrident->Chipset >= PROVIDIA9685) { + TGUI_FPATCOL(fg); + if (bg == -1) { + pTrident->BltScanDirection |= 1<<12; + TGUI_BPATCOL(~fg); + } else { + REPLICATE(bg); + TGUI_BPATCOL(bg); + } + } else { + TGUI_FCOLOUR(fg); + if (bg == -1) { + pTrident->BltScanDirection |= 1<<12; + TGUI_BCOLOUR(~fg); + } else { + REPLICATE(bg); + TGUI_BCOLOUR(bg); + } + } + TGUI_FMIX(XAAGetPatternROP(rop)); + pTrident->LinePattern = NiceDashPattern; +} + +void +XPSubsequentDashedBresenhamLine(ScrnInfoPtr pScrn, + int x, int y, int dmaj, int dmin, int e, int len, int octant, int phase) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int tmp = pTrident->BltScanDirection; + + if (octant & YMAJOR) tmp |= YMAJ; + if (octant & XDECREASING) tmp |= XNEG; + if (octant & YDECREASING) tmp |= YNEG; + + TGUI_STYLE(((pTrident->LinePattern >> phase) | + (pTrident->LinePattern << (16-phase))) & 0x0000FFFF); + TGUI_DRAWFLAG(STENCIL | tmp); + XP_SRC_XY(dmin-dmaj,dmin); + XP_DEST_XY(x,y); + XP_DIM_XY(e+dmin,len); + TGUI_COMMAND(GE_BRESLINE); + XPSync(pScrn); +} +#endif + +static void +XPSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + REPLICATE(color); + TGUI_FMIX(XAAGetPatternROP(rop)); + MMIO_OUT32(pTrident->IOBase, 0x2158, color); + TGUI_DRAWFLAG(SOLIDFILL); +} + +static void +XPSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + XP_DIM_XY(w,h); + XP_DEST_XY(x,y); + TGUI_COMMAND(GE_BLT); + XPSync(pScrn); +} + +#if 0 +static void MoveDWORDS( + register CARD32* dest, + register CARD32* src, + register int dwords ) +{ + while(dwords & ~0x03) { + *dest = *src; + *(dest + 1) = *(src + 1); + *(dest + 2) = *(src + 2); + *(dest + 3) = *(src + 3); + src += 4; + dest += 4; + dwords -= 4; + } + if (!dwords) return; + *dest = *src; + dest += 1; + src += 1; + if (dwords == 1) return; + *dest = *src; + dest += 1; + src += 1; + if (dwords == 2) return; + *dest = *src; + dest += 1; + src += 1; +} +#endif + +#if 0 +static void MoveDWORDS_FixedBase( + register CARD32* dest, + register CARD32* src, + register int dwords ) +{ + while(dwords & ~0x03) { + *dest = *src; + *dest = *(src + 1); + *dest = *(src + 2); + *dest = *(src + 3); + dwords -= 4; + src += 4; + } + + if(!dwords) return; + *dest = *src; + if(dwords == 1) return; + *dest = *(src + 1); + if(dwords == 2) return; + *dest = *(src + 2); +} +#endif + + +static void +XPSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, + int patternx, int patterny, + int fg, int bg, int rop, + unsigned int planemask) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int drawflag = 0; + + REPLICATE(fg); + MMIO_OUT32(pTrident->IOBase, 0x2158, fg); + + if (bg == -1) { + drawflag |= 1<<12; + MMIO_OUT32(pTrident->IOBase, 0x215C, ~fg); + } else { + REPLICATE(bg); + MMIO_OUT32(pTrident->IOBase, 0x215C, bg); + } + + drawflag |= 7<<18; + TGUI_DRAWFLAG(PATMONO | drawflag); + MMIO_OUT32(pTrident->IOBase, 0x2180, patternx); + MMIO_OUT32(pTrident->IOBase, 0x2184, patterny); + TGUI_FMIX(XAAGetPatternROP(rop)); +} + +static void +XPSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, + int patternx, int patterny, + int x, int y, + int w, int h) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + XP_DEST_XY(x,y); + XP_DIM_XY(w,h); + TGUI_COMMAND(GE_BLT); + XPSync(pScrn); +} + +#if 0 +static void +XPSetupForScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int fg, int bg, + int rop, + unsigned int planemask +){ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + TGUI_FMIX(XAAGetCopyROP(rop)); + if (bg == -1) { + TGUI_DRAWFLAG(SRCMONO | 1<<12); + REPLICATE(fg); + TGUI_FCOLOUR(fg); + } else { + TGUI_DRAWFLAG(SRCMONO); + REPLICATE(fg); + REPLICATE(bg); + TGUI_FCOLOUR(fg); + TGUI_BCOLOUR(bg); + } +} + +static void +XPSubsequentScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int x, int y, int w, int h, + int skipleft +){ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + pTrident->dwords = (w + 31) >> 5; + pTrident->h = h; + + XP_DEST_XY(x,y); + XP_DIM_XY(w>>1,h); + TGUI_COMMAND(GE_BLT); +} + +static void +XPSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + XAAInfoRecPtr infoRec; + infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + + MoveDWORDS_FixedBase((CARD32 *)pTrident->IOBase + 0x2160, + (CARD32 *)pTrident->XAAScanlineColorExpandBuffers[0], + pTrident->dwords); + + pTrident->h--; + if (pTrident->h) + XPSync(pScrn); +} +#endif |