summaryrefslogtreecommitdiff
path: root/driver/xf86-video-sisusb/src
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2006-11-26 20:13:53 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2006-11-26 20:13:53 +0000
commitc72776735fe8203d357dce0bf9cda921a2376dc6 (patch)
treef4468030b9609553848f2baad835fe7643d4b197 /driver/xf86-video-sisusb/src
parent295d62fd7c6366bd5a282cf713a82c06a711e5af (diff)
Importing xf86-video-sisusb 0.8.1
Diffstat (limited to 'driver/xf86-video-sisusb/src')
-rw-r--r--driver/xf86-video-sisusb/src/Makefile.am54
-rw-r--r--driver/xf86-video-sisusb/src/Makefile.in537
-rw-r--r--driver/xf86-video-sisusb/src/sisusb.h808
-rw-r--r--driver/xf86-video-sisusb/src/sisusb_accel.c134
-rw-r--r--driver/xf86-video-sisusb/src/sisusb_accel.h954
-rw-r--r--driver/xf86-video-sisusb/src/sisusb_cursor.c304
-rw-r--r--driver/xf86-video-sisusb/src/sisusb_cursor.h113
-rw-r--r--driver/xf86-video-sisusb/src/sisusb_dac.c1067
-rw-r--r--driver/xf86-video-sisusb/src/sisusb_dac.h52
-rw-r--r--driver/xf86-video-sisusb/src/sisusb_driver.c2815
-rw-r--r--driver/xf86-video-sisusb/src/sisusb_driver.h160
-rw-r--r--driver/xf86-video-sisusb/src/sisusb_init.c1571
-rw-r--r--driver/xf86-video-sisusb/src/sisusb_init.h787
-rw-r--r--driver/xf86-video-sisusb/src/sisusb_opt.c521
-rw-r--r--driver/xf86-video-sisusb/src/sisusb_osdef.h89
-rw-r--r--driver/xf86-video-sisusb/src/sisusb_regs.h370
-rw-r--r--driver/xf86-video-sisusb/src/sisusb_setup.c132
-rw-r--r--driver/xf86-video-sisusb/src/sisusb_shadow.c153
-rw-r--r--driver/xf86-video-sisusb/src/sisusb_struct.h184
-rw-r--r--driver/xf86-video-sisusb/src/sisusb_types.h229
-rw-r--r--driver/xf86-video-sisusb/src/sisusb_utility.c1309
-rw-r--r--driver/xf86-video-sisusb/src/sisusb_vga.c342
-rw-r--r--driver/xf86-video-sisusb/src/sisusb_video.c2054
-rw-r--r--driver/xf86-video-sisusb/src/sisusb_video.h404
-rw-r--r--driver/xf86-video-sisusb/src/sisusb_videostr.h107
25 files changed, 15250 insertions, 0 deletions
diff --git a/driver/xf86-video-sisusb/src/Makefile.am b/driver/xf86-video-sisusb/src/Makefile.am
new file mode 100644
index 000000000..5e1735f9b
--- /dev/null
+++ b/driver/xf86-video-sisusb/src/Makefile.am
@@ -0,0 +1,54 @@
+# 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@
+sisusb_drv_la_LTLIBRARIES = sisusb_drv.la
+sisusb_drv_la_LDFLAGS = -module -avoid-version
+sisusb_drv_ladir = @moduledir@/drivers
+
+sisusb_drv_la_SOURCES = \
+ sisusb_accel.c \
+ sisusb_accel.h \
+ sisusb_cursor.c \
+ sisusb_cursor.h \
+ sisusb_dac.c \
+ sisusb_dac.h \
+ sisusb_driver.c \
+ sisusb_driver.h \
+ sisusb.h \
+ sisusb_init.c \
+ sisusb_init.h \
+ sisusb_opt.c \
+ sisusb_osdef.h \
+ sisusb_regs.h \
+ sisusb_setup.c \
+ sisusb_shadow.c \
+ sisusb_struct.h \
+ sisusb_types.h \
+ sisusb_utility.c \
+ sisusb_vga.c \
+ sisusb_video.c \
+ sisusb_video.h \
+ sisusb_videostr.h
diff --git a/driver/xf86-video-sisusb/src/Makefile.in b/driver/xf86-video-sisusb/src/Makefile.in
new file mode 100644
index 000000000..e9ddecff7
--- /dev/null
+++ b/driver/xf86-video-sisusb/src/Makefile.in
@@ -0,0 +1,537 @@
+# 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)$(sisusb_drv_ladir)"
+sisusb_drv_laLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(sisusb_drv_la_LTLIBRARIES)
+sisusb_drv_la_LIBADD =
+am_sisusb_drv_la_OBJECTS = sisusb_accel.lo sisusb_cursor.lo \
+ sisusb_dac.lo sisusb_driver.lo sisusb_init.lo sisusb_opt.lo \
+ sisusb_setup.lo sisusb_shadow.lo sisusb_utility.lo \
+ sisusb_vga.lo sisusb_video.lo
+sisusb_drv_la_OBJECTS = $(am_sisusb_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 = $(sisusb_drv_la_SOURCES)
+DIST_SOURCES = $(sisusb_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@
+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@
+RAWCPP = @RAWCPP@
+RAWCPPFLAGS = @RAWCPPFLAGS@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+XORG_CFLAGS = @XORG_CFLAGS@
+XORG_LIBS = @XORG_LIBS@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
+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@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+moduledir = @moduledir@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+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@
+sisusb_drv_la_LTLIBRARIES = sisusb_drv.la
+sisusb_drv_la_LDFLAGS = -module -avoid-version
+sisusb_drv_ladir = @moduledir@/drivers
+sisusb_drv_la_SOURCES = \
+ sisusb_accel.c \
+ sisusb_accel.h \
+ sisusb_cursor.c \
+ sisusb_cursor.h \
+ sisusb_dac.c \
+ sisusb_dac.h \
+ sisusb_driver.c \
+ sisusb_driver.h \
+ sisusb.h \
+ sisusb_init.c \
+ sisusb_init.h \
+ sisusb_opt.c \
+ sisusb_osdef.h \
+ sisusb_regs.h \
+ sisusb_setup.c \
+ sisusb_shadow.c \
+ sisusb_struct.h \
+ sisusb_types.h \
+ sisusb_utility.c \
+ sisusb_vga.c \
+ sisusb_video.c \
+ sisusb_video.h \
+ sisusb_videostr.h
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-sisusb_drv_laLTLIBRARIES: $(sisusb_drv_la_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(sisusb_drv_ladir)" || $(mkdir_p) "$(DESTDIR)$(sisusb_drv_ladir)"
+ @list='$(sisusb_drv_la_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) --mode=install $(sisusb_drv_laLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(sisusb_drv_ladir)/$$f'"; \
+ $(LIBTOOL) --mode=install $(sisusb_drv_laLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(sisusb_drv_ladir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-sisusb_drv_laLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @set -x; list='$(sisusb_drv_la_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(sisusb_drv_ladir)/$$p'"; \
+ $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(sisusb_drv_ladir)/$$p"; \
+ done
+
+clean-sisusb_drv_laLTLIBRARIES:
+ -test -z "$(sisusb_drv_la_LTLIBRARIES)" || rm -f $(sisusb_drv_la_LTLIBRARIES)
+ @list='$(sisusb_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
+sisusb_drv.la: $(sisusb_drv_la_OBJECTS) $(sisusb_drv_la_DEPENDENCIES)
+ $(LINK) -rpath $(sisusb_drv_ladir) $(sisusb_drv_la_LDFLAGS) $(sisusb_drv_la_OBJECTS) $(sisusb_drv_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sisusb_accel.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sisusb_cursor.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sisusb_dac.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sisusb_driver.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sisusb_init.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sisusb_opt.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sisusb_setup.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sisusb_shadow.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sisusb_utility.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sisusb_vga.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sisusb_video.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)$(sisusb_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-sisusb_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-sisusb_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-sisusb_drv_laLTLIBRARIES
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-sisusb_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-sisusb_drv_laLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-info-am \
+ uninstall-sisusb_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-sisusb/src/sisusb.h b/driver/xf86-video-sisusb/src/sisusb.h
new file mode 100644
index 000000000..0eb17d006
--- /dev/null
+++ b/driver/xf86-video-sisusb/src/sisusb.h
@@ -0,0 +1,808 @@
+/* $XFree86$ */
+/* $XdotOrg: driver/xf86-video-sisusb/src/sisusb.h,v 1.16 2006/04/07 21:10:49 ajax Exp $ */
+/*
+ * Main global data and definitions
+ *
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1) Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2) Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3) The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
+
+#ifndef _SISUSB_H
+#define _SISUSB_H_
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#define SISUSBDRIVERVERSIONYEAR 5
+#define SISUSBDRIVERVERSIONMONTH 9
+#define SISUSBDRIVERVERSIONDAY 28
+#define SISUSBDRIVERREVISION 1
+
+#define SISUSBDRIVERIVERSION ((SISUSBDRIVERVERSIONYEAR << 16) | \
+ (SISUSBDRIVERVERSIONMONTH << 8) | \
+ SISUSBDRIVERVERSIONDAY | \
+ (SISUSBDRIVERREVISION << 24))
+
+#undef SIS_LINUX /* Try to find out whether platform is Linux */
+#if defined(__GNUC__) && (__GNUC__ >= 4)
+#ifdef __linux__
+#define SIS_LINUX
+#endif
+#else
+#ifdef linux
+#define SIS_LINUX
+#endif
+#endif
+
+#ifndef SIS_LINUX /* USB dongle driver only for Linux */
+#error sisusb driver can only be compiled for Linux
+#endif
+
+#define SISUSB_NAME "SISUSB"
+#define SISUSB_DRIVER_NAME "sisusb"
+
+#define SISUSB_MAJOR_VERSION 0
+#define SISUSB_MINOR_VERSION 8
+#define SISUSB_PATCHLEVEL 1
+#define SISUSB_CURRENT_VERSION ((SISUSB_MAJOR_VERSION << 16) | \
+ (SISUSB_MINOR_VERSION << 8) | \
+ SISUSB_PATCHLEVEL)
+
+#if 0
+#define TWDEBUG /* for debugging */
+#endif
+
+#include "compiler.h"
+#include "xf86Priv.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "xf86.h"
+#include "xf86Cursor.h"
+#include "xf86cmap.h"
+#include "xaa.h"
+
+#define SISUSB_HaveDriverFuncs 0
+
+#ifdef XORG_VERSION_CURRENT
+#include "xorgVersion.h"
+#define SISUSBMYSERVERNAME "X.org"
+#ifndef XF86_VERSION_NUMERIC
+#define XF86_VERSION_NUMERIC(major,minor,patch,snap,dummy) \
+ (((major) * 10000000) + ((minor) * 100000) + ((patch) * 1000) + snap)
+#define XF86_VERSION_CURRENT XF86_VERSION_NUMERIC(4,3,99,902)
+#endif
+#ifdef HaveDriverFuncs
+#define SISUSB_HAVE_DRIVER_FUNC
+#undef SISUSB_HaveDriverFuncs
+#define SISUSB_HaveDriverFuncs HaveDriverFuncs
+#endif
+#else
+#include "xf86Version.h"
+#define SISUSBMYSERVERNAME "XFree86"
+#endif
+
+#if (XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,3,99,0,0)) || (defined(XvExtension))
+#include "xf86xv.h"
+#include <X11/extensions/Xv.h>
+#endif
+
+/* Platform/architecture related definitions: */
+
+#undef SIS_PC_PLATFORM
+#undef SIS_USE_BIOS_SCRATCH
+#undef SIS_NEED_MAP_IOP
+#undef SISUSEDEVPORT
+
+/* Our #includes: Require the arch/platform dependent #defines above */
+
+#include "sisusb_osdef.h"
+#include "sisusb_types.h"
+#include "sisusb_struct.h"
+
+/* Configurable stuff: ------------------------------------- */
+
+#define SIS_ARGB_CURSOR /* Include code for color hardware cursors */
+
+#define SISVRAMQ /* Use VRAM queue mode */
+
+#undef SIS_ENABLEXV /* Enable/Disable Xv overlay support */
+
+#undef XV_SD_DEPRECATED /* Include deprecated Xv interface for SiSCtrl */
+
+/* End of configurable stuff --------------------------------- */
+
+#define UNLOCK_ALWAYS /* Always unlock the registers (should be set!) */
+
+/* Need that for SiSCtrl */
+#define NEED_REPLIES /* ? */
+#define EXTENSION_PROC_ARGS void *
+#include "extnsionst.h" /* required */
+#include <X11/extensions/panoramiXproto.h> /* required */
+
+#undef SISGAMMARAMP
+#ifdef XORG_VERSION_CURRENT
+#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(6,8,99,13,0)
+#define SISGAMMARAMP /* Driver can set gamma ramp; requires additional symbols in xf86sym.h */
+#endif
+#endif
+
+#undef SIS_GLOBAL_ENABLEXV
+#if defined(XV_SD_DEPRECATED) || defined(SIS_ENABLEXV)
+#define SIS_GLOBAL_ENABLEXV
+#endif
+
+#ifdef TWDEBUG
+#define SISUSBVERBLEVEL 3
+#else
+#define SISUSBVERBLEVEL 4
+#endif
+
+#define USB_CHIP_SIS315 0x8325 /* Fake */
+
+#define SIS_VBFlagsVersion 1
+
+/* pSiSUSB->VBFlags - if anything is changed here, increase VBFlagsVersion! */
+#define CRT2_DEFAULT 0x00000001
+#define CRT2_LCD 0x00000002 /* Never change the order of the CRT2_XXX entries */
+#define CRT2_TV 0x00000004
+#define CRT2_VGA 0x00000008
+#define TV_NTSC 0x00000010
+#define TV_PAL 0x00000020
+#define TV_HIVISION 0x00000040
+#define TV_YPBPR 0x00000080
+#define TV_AVIDEO 0x00000100
+#define TV_SVIDEO 0x00000200
+#define TV_SCART 0x00000400
+#define VB_CONEXANT 0x00000800 /* Definition deprecated (now VBFlags2) */
+#define VB_TRUMPION VB_CONEXANT /* Definition deprecated (now VBFlags2) */
+#define TV_PALM 0x00001000
+#define TV_PALN 0x00002000
+#define TV_NTSCJ TV_PALM
+#define OLDVB_302ELV 0x00004000 /* Definition deprecated (now VBFlags2) */
+#define TV_CHSCART 0x00008000
+#define TV_CHYPBPR525I 0x00010000
+#define CRT1_VGA 0x00000000 /* ZERO - no mask! */
+#define CRT1_LCDA 0x00020000
+#define VGA2_CONNECTED 0x00040000
+#define DISPTYPE_CRT1 0x00080000 /* CRT1 connected and used */
+#define OLDVB_301 0x00100000 /* Definition deprecated (now VBFlags2) */
+#define OLDVB_301B 0x00200000 /* Definition deprecated (now VBFlags2) */
+#define OLDVB_302B 0x00400000 /* Definition deprecated (now VBFlags2) */
+#define OLDVB_30xBDH 0x00800000 /* Definition deprecated (now VBFlags2) */
+#define OLDVB_LVDS 0x01000000 /* Definition deprecated (now VBFlags2) */
+#define OLDVB_CHRONTEL 0x02000000 /* Definition deprecated (now VBFlags2) */
+#define OLDVB_301LV 0x04000000 /* Definition deprecated (now VBFlags2) */
+#define OLDVB_302LV 0x08000000 /* Definition deprecated (now VBFlags2) */
+#define OLDVB_301C 0x10000000 /* Definition deprecated (now VBFlags2) */
+#define SINGLE_MODE 0x20000000 /* CRT1 or CRT2; determined by DISPTYPE_CRTx */
+#define MIRROR_MODE 0x40000000 /* CRT1 + CRT2 identical (mirror mode) */
+#define DUALVIEW_MODE 0x80000000 /* CRT1 + CRT2 independent (dual head mode) */
+
+/* Aliases: */
+#define CRT2_ENABLE (CRT2_LCD | CRT2_TV | CRT2_VGA)
+#define TV_STANDARD (TV_NTSC | TV_PAL | TV_PALM | TV_PALN | TV_NTSCJ)
+#define TV_INTERFACE (TV_AVIDEO|TV_SVIDEO|TV_SCART|TV_HIVISION|TV_YPBPR)
+
+/* Only if TV_YPBPR is set: */
+#define TV_YPBPR525I TV_NTSC
+#define TV_YPBPR525P TV_PAL
+#define TV_YPBPR750P TV_PALM
+#define TV_YPBPR1080I TV_PALN
+#define TV_YPBPRALL (TV_YPBPR525I | TV_YPBPR525P | TV_YPBPR750P | TV_YPBPR1080I)
+
+#define TV_YPBPR43LB TV_CHSCART
+#define TV_YPBPR43 TV_CHYPBPR525I
+#define TV_YPBPR169 (TV_CHSCART | TV_CHYPBPR525I)
+#define TV_YPBPRAR (TV_CHSCART | TV_CHYPBPR525I)
+
+#define DISPTYPE_DISP2 CRT2_ENABLE
+#define DISPTYPE_DISP1 DISPTYPE_CRT1
+#define VB_DISPMODE_SINGLE SINGLE_MODE /* alias */
+#define VB_DISPMODE_MIRROR MIRROR_MODE /* alias */
+#define VB_DISPMODE_DUAL DUALVIEW_MODE /* alias */
+#define DISPLAY_MODE (SINGLE_MODE | MIRROR_MODE | DUALVIEW_MODE)
+
+/* pSiSUSB->VBFlags2 (static stuff only!) */
+#define VB2_SISUMC 0x00000001
+#define VB2_301 0x00000002 /* Video bridge type */
+#define VB2_301B 0x00000004
+#define VB2_301C 0x00000008
+#define VB2_307T 0x00000010
+#define VB2_302B 0x00000800
+#define VB2_301LV 0x00001000
+#define VB2_302LV 0x00002000
+#define VB2_302ELV 0x00004000
+#define VB2_307LV 0x00008000
+#define VB2_30xBDH 0x08000000 /* 30xB DH version (w/o LCD support) */
+#define VB2_CONEXANT 0x10000000 /* >=661 series only */
+#define VB2_TRUMPION 0x20000000 /* 300 series only */
+#define VB2_LVDS 0x40000000
+#define VB2_CHRONTEL 0x80000000
+
+#define VB2_SISLVDSBRIDGE (VB2_301LV | VB2_302LV | VB2_302ELV | VB2_307LV)
+#define VB2_SISTMDSBRIDGE (VB2_301 | VB2_301B | VB2_301C | VB2_302B | VB2_307T)
+#define VB2_SISBRIDGE (VB2_SISLVDSBRIDGE | VB2_SISTMDSBRIDGE)
+
+#define VB2_SISTMDSLCDABRIDGE (VB2_301C | VB2_307T)
+#define VB2_SISLCDABRIDGE (VB2_SISTMDSLCDABRIDGE | VB2_301LV | VB2_302LV | VB2_302ELV | VB2_307LV)
+
+#define VB2_SISHIVISIONBRIDGE (VB2_301 | VB2_301B | VB2_302B)
+#define VB2_SISYPBPRBRIDGE (VB2_301C | VB2_307T | VB2_SISLVDSBRIDGE)
+#define VB2_SISYPBPRARBRIDGE (VB2_301C | VB2_307T | VB2_307LV)
+#define VB2_SISTAP4SCALER (VB2_301C | VB2_307T | VB2_302ELV | VB2_307LV)
+#define VB2_SISTVBRIDGE (VB2_SISHIVISIONBRIDGE | VB2_SISYPBPRBRIDGE)
+
+#define VB2_SISVGA2BRIDGE (VB2_301 | VB2_301B | VB2_301C | VB2_302B | VB2_307T)
+
+#define VB2_VIDEOBRIDGE (VB2_SISBRIDGE | VB2_LVDS | VB2_CHRONTEL | VB2_CONEXANT)
+
+#define VB2_30xB (VB2_301B | VB2_301C | VB2_302B | VB2_307T)
+#define VB2_30xBLV (VB2_30xB | VB2_SISLVDSBRIDGE)
+#define VB2_30xC (VB2_301C | VB2_307T)
+#define VB2_30xCLV (VB2_301C | VB2_307T | VB2_302ELV| VB2_307LV)
+#define VB2_SISEMIBRIDGE (VB2_302LV | VB2_302ELV | VB2_307LV)
+#define VB2_LCD162MHZBRIDGE (VB2_301C | VB2_307T)
+#define VB2_LCDOVER1280BRIDGE (VB2_301C | VB2_307T | VB2_302LV | VB2_302ELV | VB2_307LV)
+#define VB2_LCDOVER1600BRIDGE (VB2_307T | VB2_307LV)
+#define VB2_RAMDAC202MHZBRIDGE (VB2_301C | VB2_307T)
+
+/* pSiSUSB->VBLCDFlags */
+#define VB_LCD_320x480 0x00000001 /* DSTN/FSTN for 550 */
+#define VB_LCD_640x480 0x00000002
+#define VB_LCD_800x600 0x00000004
+#define VB_LCD_1024x768 0x00000008
+#define VB_LCD_1280x1024 0x00000010
+#define VB_LCD_1280x960 0x00000020
+#define VB_LCD_1600x1200 0x00000040
+#define VB_LCD_2048x1536 0x00000080
+#define VB_LCD_1400x1050 0x00000100
+#define VB_LCD_1152x864 0x00000200
+#define VB_LCD_1152x768 0x00000400
+#define VB_LCD_1280x768 0x00000800
+#define VB_LCD_1024x600 0x00001000
+#define VB_LCD_640x480_2 0x00002000 /* DSTN/FSTN */
+#define VB_LCD_640x480_3 0x00004000 /* DSTN/FSTN */
+#define VB_LCD_848x480 0x00008000 /* LVDS only, otherwise handled as custom */
+#define VB_LCD_1280x800 0x00010000
+#define VB_LCD_1680x1050 0x00020000
+#define VB_LCD_1280x720 0x00040000
+#define VB_LCD_320x240 0x00080000
+#define VB_LCD_856x480 0x00100000
+#define VB_LCD_1280x854 0x00200000
+#define VB_LCD_1920x1200 0x00400000
+#define VB_LCD_UNKNOWN 0x10000000
+#define VB_LCD_BARCO1366 0x20000000
+#define VB_LCD_CUSTOM 0x40000000
+#define VB_LCD_EXPANDING 0x80000000
+
+#define VB_FORBID_CRT2LCD_OVER_1600 /* CRT2/LCD supports only up to 1600 pixels */
+
+/* PresetMode argument */
+#define SIS_MODE_SIMU 0
+#define SIS_MODE_CRT1 1
+#define SIS_MODE_CRT2 2
+
+/* pSiSUSB->MiscFlags */
+#define MISC_CRT1OVERLAY 0x00000001 /* Current display mode supports overlay (CRT1) */
+#define MISC_PANELLINKSCALER 0x00000002 /* Panel link is currently scaling */
+#define MISC_CRT1OVERLAYGAMMA 0x00000004 /* Current display mode supports overlay gamma corr on CRT1 */
+#define MISC_TVNTSC1024 0x00000008 /* Current display mode is TV NTSC/PALM/YPBPR525I 1024x768 */
+#define MISC_CRT2OVERLAY 0x00000010 /* Current display mode supports overlay (CRT2) */
+#define MISC_SIS760ONEOVERLAY 0x00000020 /* SiS760/761: Only one overlay available currently */
+#define MISC_STNMODE 0x00000040 /* SiS550: xSTN active */
+
+#ifdef DEBUG
+#define PDEBUG(p) p
+#else
+#define PDEBUG(p)
+#endif
+
+#define BITMASK(h,l) (((unsigned)(1U << ((h) - (l) + 1)) - 1) << (l))
+#define GENMASK(mask) BITMASK(1 ? mask, 0 ? mask)
+
+#define GETBITS(var,mask) (((var) & GENMASK(mask)) >> (0 ? mask))
+#define SETBITS(val,mask) ((val) << (0 ? mask))
+#define SETBIT(n) (1 << (n))
+
+#define GETBITSTR(val,from,to) ((GETBITS(val, from)) << (0 ? to))
+#define SETVARBITS(var,val,from,to) (((var) & (~(GENMASK(to)))) | GETBITSTR(val,from,to))
+#define GETVAR8(var) ((var) & 0xFF)
+#define SETVAR8(var,val) (var) = GETVAR8(val)
+
+typedef unsigned long ULong;
+typedef unsigned short UShort;
+typedef unsigned char UChar;
+
+/* pSiSUSB->VGAEngine - VGA engine types */
+#define UNKNOWN_VGA 0
+#define SIS_530_VGA 1
+#define SIS_OLD_VGA 2
+#define SIS_300_VGA 3
+#define SIS_315_VGA 4 /* Includes 330/660/661/741/760 and M versions thereof */
+
+/* pSiSUSB->ChipFlags */
+/* Use only lower 16 bit for chip id! (sisctrl) */
+#define SiSCF_LARGEOVERLAY 0x00000001
+#define SiSCF_Is651 0x00000002
+#define SiSCF_IsM650 0x00000004
+#define SiSCF_IsM652 0x00000008
+#define SiSCF_IsM653 0x00000010
+#define SiSCF_Is652 0x00000020
+#define SiSCF_Is65x (SiSCF_Is651|SiSCF_IsM650|SiSCF_IsM652|SiSCF_IsM653|SiSCF_Is652)
+#define SiSCF_IsM661 0x00000100 /* M661FX */
+#define SiSCF_IsM741 0x00000200
+#define SiSCF_IsM760 0x00000400
+#define SiSCF_IsM661M 0x00000800 /* M661MX */
+#define SiSCF_IsM66x (SiSCF_IsM661 | SiSCF_IsM741 | SiSCF_IsM760 | SiSCF_IsM661M)
+#define SiSCF_Is315USB 0x00001000 /* USB2VGA dongle */
+#define SiSCF_Is315E 0x00002000 /* 315E */
+#define SiSCF_IsXGIV3 SiSCF_Is651 /* Volari V3(XT) (If neither XGI... set, is V8) */
+#define SiSCF_IsXGIV5 SiSCF_IsM650/* Volari V5 */
+#define SiSCF_IsXGIDUO SiSCF_IsM652/* Volari Duo */
+/* ... */
+#define SiSCF_315Core 0x00010000 /* 3D: Real 315 */
+#define SiSCF_Real256ECore 0x00020000 /* 3D: Similar to 315 core, no T&L? (65x, 661, 740, 741) */
+#define SiSCF_XabreCore 0x00040000 /* 3D: Real Xabre */
+#define SiSCF_Ultra256Core 0x00080000 /* 3D: aka "Mirage 2"; similar to Xabre, no T&L?, no P:Shader? (760) */
+#define SiSCF_MMIOPalette 0x00100000 /* HW supports MMIO palette writing/reading */
+#define SiSCF_IsXGI 0x00200000 /* Is XGI chip (Z7, V3, V5, V8) */
+#define SiSCF_UseLCDA 0x01000000
+#define SiSCF_760LFB 0x08000000 /* 760: LFB active (if not set, UMA only) */
+#define SiSCF_760UMA 0x10000000 /* 760: UMA active (if not set, LFB only) */
+#define SiSCF_CRT2HWCKaputt 0x20000000 /* CRT2 Mono HWCursor engine buggy (SiS 330) */
+#define SiSCF_Glamour3 0x40000000
+#define SiSCF_Integrated 0x80000000
+
+/* SiS Direct Xv-API */
+#define SiS_SD_IS300SERIES 0x00000001
+#define SiS_SD_IS315SERIES 0x00000002
+#define SiS_SD_IS330SERIES 0x00000004
+#define SiS_SD_SUPPORTPALMN 0x00000008 /* tv chip supports pal-m, pal-n */
+#define SiS_SD_SUPPORT2OVL 0x00000010 /* set = 2 overlays, clear = support SWITCHCRT xv prop */
+#define SiS_SD_SUPPORTTVPOS 0x00000020 /* supports changing tv position */
+#define SiS_SD_ISDUALHEAD 0x00000040 /* Driver is in dual head mode */
+#define SiS_SD_ISMERGEDFB 0x00000080 /* Driver is in merged fb mode */
+#define SiS_SD_ISDHSECONDHEAD 0x00000100 /* Dual head: This is CRT1 (=second head) */
+#define SiS_SD_ISDHXINERAMA 0x00000200 /* Dual head: We are running Xinerama */
+#define SiS_SD_VBHASSCART 0x00000400 /* videobridge has SCART instead of VGA2 */
+#define SiS_SD_ISDEPTH8 0x00000800 /* Depth is 8, no independent gamma correction */
+#define SiS_SD_SUPPORTSOVER 0x00001000 /* Support for Chrontel Super Overscan */
+#define SiS_SD_ENABLED 0x00002000 /* sisctrl is enabled (by option) */
+#define SiS_SD_PSEUDOXINERAMA 0x00004000 /* pseudo xinerama is active */
+#define SiS_SD_SUPPORTLCDA 0x00008000 /* Support LCD Channel A */
+#define SiS_SD_SUPPORTNTSCJ 0x00010000 /* tv chip supports ntsc-j */
+#define SiS_SD_ADDLSUPFLAG 0x00020000 /* 1 = the following flags are valid */
+#define SiS_SD_SUPPORTVGA2 0x00040000 /* CRT2=VGA supported */
+#define SiS_SD_SUPPORTSCART 0x00080000 /* CRT2=SCART supported */
+#define SiS_SD_SUPPORTOVERSCAN 0x00100000 /* Overscan flag supported */
+#define SiS_SD_SUPPORTXVGAMMA1 0x00200000 /* Xv Gamma correction for CRT1 supported */
+#define SiS_SD_SUPPORTTV 0x00400000 /* CRT2=TV supported */
+#define SiS_SD_SUPPORTYPBPR 0x00800000 /* CRT2=YPbPr (525i, 525p, 750p, 1080i) is supported */
+#define SiS_SD_SUPPORTHIVISION 0x01000000 /* CRT2=HiVision is supported */
+#define SiS_SD_SUPPORTYPBPRAR 0x02000000 /* YPbPr aspect ratio is supported */
+#define SiS_SD_SUPPORTSCALE 0x04000000 /* Scaling of LCD panel supported */
+#define SiS_SD_SUPPORTCENTER 0x08000000 /* If scaling supported: Centering of screen [NOT] supported (TMDS only) */
+#define SiS_SD_SUPPORTREDETECT 0x10000000 /* Support re-detection of CRT2 devices */
+#define SiS_SD_IS340SERIES 0x20000000
+#define SiS_SD_SUPPORTSGRCRT2 0x40000000 /* Separate CRT2 gamma correction supported */
+#define SiS_SD_CANSETGAMMA 0x80000000 /* Driver can set gamma ramp; otherwise: App needs to reset palette */
+ /* after disabling sep CRT2 gamma corr */
+
+#define SiS_SD2_LCDTMDS 0x00000001 /* SiS Bridge supports TMDS (DVI-D) */
+#define SiS_SD2_LCDLVDS 0x00000002 /* SiS Bridge supports LVDS */
+#define SiS_SD2_SUPPORTLCD 0x00000004 /* Bridge supports LCD (LVDS or TMDS, SiS+3rd party) */
+#define SiS_SD2_SUPPORTTVSIZE 0x00000008 /* TV resizing supported (SiS bridges) */
+#define SiS_SD2_SUPPORTTVTYPE 0x00000010 /* TV type selection supported (SiS bridges) */
+#define SiS_SD2_SUPPORTGAMMA2 0x00000020 /* Gamma corr for CRT2 supported (SiS bridges) */
+#define SiS_SD2_SISBRIDGE 0x00000040 /* SiS bridge */
+#define SiS_SD2_SUPPTVSAT 0x00000080 /* TV saturation supported */
+#define SiS_SD2_SUPPTVEDGE 0x00000100 /* TV edge enhancement supported */
+#define SiS_SD2_CHRONTEL 0x00000200 /* Chrontel TV encoder present */
+#define SiS_SD2_VIDEOBRIDGE 0x00000400 /* Any type of video bridge present */
+#define SiS_SD2_THIRDPARTYLVDS 0x00000800 /* Third party LVDS (non-SiS) */
+#define SiS_SD2_ADDLFLAGS 0x00001000 /* Following flags valid */
+#define SiS_SD2_SUPPORT760OO 0x00002000 /* Support dynamic one/two overlay configuration changes */
+ /* (If set, utility must re-read SD2 flags after mode change) */
+#define SiS_SD2_SIS760ONEOVL 0x00004000 /* (76x:) Only one overlay currently */
+#define SiS_SD2_MERGEDUCLOCK 0x00008000 /* Provide VRefresh in mode->Clock field in MergedFB mode */
+#define SiS_SD2_SUPPORTXVHUESAT 0x00010000 /* Xv: Support hue & saturation */
+#define SiS_SD2_NEEDUSESSE 0x00020000 /* Need "UseSSE" option to use SSE (otherwise auto) */
+#define SiS_SD2_NODDCSUPPORT 0x00040000 /* No hardware DDC support (USB) */
+#define SiS_SD2_SUPPORTXVDEINT 0x00080000 /* Xv deinterlacing supported (n/a) */
+#define SiS_SD2_ISXGI 0x00100000 /* Is XGI chip */
+#define SiS_SD2_USEVBFLAGS2 0x00200000 /* Use VBFlags2 for bridge ID */
+#define SiS_SD2_SUPPLTFLAG 0x00400000 /* Driver supports the following 3 flags */
+#define SiS_SD2_ISLAPTOP 0x00800000 /* This machine is (very probably) a laptop */
+#define SiS_SD2_MACHINETYPE2 0x01000000 /* Machine type 2 (for future use) */
+#define SiS_SD2_MACHINETYPE3 0x02000000 /* Machine type 3 (for future use) */
+#define SiS_SD2_SUPPORT625I 0x04000000 /* Support YPbPr 625i */
+#define SiS_SD2_SUPPORT625P 0x08000000 /* Support YPbPr 625p */
+#define SiS_SD2_VBINVB2ONLY 0x10000000 /* VB_* bits in vbflags no longer used for vb type */
+#define SiS_SD2_NEWGAMMABRICON 0x20000000 /* Support new gamma brightness/contrast */
+#define SiS_SD2_HAVESD34 0x40000000 /* Support SD3 and SD4 flags (for future use) */
+#define SiS_SD2_NOOVERLAY 0x80000000 /* No video overlay */
+
+#define SiS_SD3_OLDGAMMAINUSE 0x00000001 /* Old gamma brightness is currently in use */
+
+#define SIS_DIRECTKEY 0x03145792
+
+/* SiSCtrl: Check mode for CRT2 */
+#define SiS_CF2_LCD 0x01
+#define SiS_CF2_TV 0x02
+#define SiS_CF2_VGA2 0x04
+#define SiS_CF2_TVPAL 0x08
+#define SiS_CF2_TVNTSC 0x10 /* + NTSC-J */
+#define SiS_CF2_TVPALM 0x20
+#define SiS_CF2_TVPALN 0x40
+#define SiS_CF2_CRT1LCDA 0x80
+#define SiS_CF2_TYPEMASK (SiS_CF2_LCD | SiS_CF2_TV | SiS_CF2_VGA2 | SiS_CF2_CRT1LCDA)
+#define SiS_CF2_TVSPECIAL (SiS_CF2_LCD | SiS_CF2_TV)
+#define SiS_CF2_TVSPECMASK (SiS_CF2_TVPAL | SiS_CF2_TVNTSC | SiS_CF2_TVPALM | SiS_CF2_TVPALN)
+#define SiS_CF2_TVHIVISION SiS_CF2_TVPAL
+#define SiS_CF2_TVYPBPR525I SiS_CF2_TVNTSC
+#define SiS_CF2_TVYPBPR525P (SiS_CF2_TVPAL | SiS_CF2_TVNTSC)
+#define SiS_CF2_TVYPBPR750P SiS_CF2_TVPALM
+#define SiS_CF2_TVYPBPR1080I (SiS_CF2_TVPALM | SiS_CF2_TVPAL)
+
+/* Defines for our own vgaHW functions */
+#define SISVGA_SR_MODE 0x01
+#define SISVGA_SR_FONTS 0x02
+#define SISVGA_SR_CMAP 0x04
+#define SISVGA_SR_ALL (SISVGA_SR_MODE | SISVGA_SR_FONTS | SISVGA_SR_CMAP)
+
+/* For backup of register contents */
+typedef struct {
+ UChar sisRegMiscOut;
+ UChar sisRegsATTR[22];
+ UChar sisRegsGR[10];
+ UChar sisDAC[768];
+ UChar sisRegs3C4[0x50];
+ UChar sisRegs3D4[0x90];
+ UChar sisRegs3C2;
+ UChar sisCapt[0x60];
+ UChar sisVid[0x50];
+ UChar VBPart1[0x50];
+ ULong sisMMIO85C0;
+ UChar BIOSModeSave;
+} SISUSBRegRec, *SISUSBRegPtr;
+
+typedef struct _sisModeInfoPtr {
+ int width;
+ int height;
+ int bpp;
+ int n;
+ struct _sisModeInfoPtr *next;
+} sisModeInfoRec, *sisModeInfoPtr;
+
+/* SISFBLayout is mainly there because of DGA. It holds the
+ * current layout parameters needed for acceleration and other
+ * stuff. When switching mode using DGA, these are set up
+ * accordingly and not necessarily match pScrn's. Therefore,
+ * driver modules should read these values instead of pScrn's.
+ */
+typedef struct {
+ int bitsPerPixel; /* = pScrn->bitsPerPixel */
+ int depth; /* = pScrn->depth */
+ int displayWidth; /* = pScrn->displayWidth */
+ int displayHeight; /* = imageHeight from DGA mode; ONLY WHEN DGA IS ACTIVE!!! */
+ int DGAViewportX;
+ int DGAViewportY;
+ DisplayModePtr mode; /* = pScrn->currentMode */
+} SISFBLayout;
+
+#define SISUSBPTR(p) ((SISUSBPtr)((p)->driverPrivate))
+
+typedef struct {
+ ScrnInfoPtr pScrn;
+ EntityInfoPtr pEnt;
+ int Chipset; /* PCI ID (pseudo for USB) */
+ int ChipType; /* From sisusb_types.h */
+ int ChipRev;
+
+ int VGAEngine; /* see above */
+ int hasTwoOverlays; /* Chipset supports two video overlays? */
+ SiS_Private *SiS_Pr; /* For new mode switching code */
+ int DSTN; /* For 550 FSTN/DSTN; set by option, no detection */
+ ULong FbAddress; /* VRAM physical address (in DHM: for each Fb!) */
+ ULong realFbAddress; /* For DHM/PCI mem mapping: store global FBAddress */
+ UChar *FbBase; /* VRAM virtual linear address */
+ CARD32 IOAddress; /* MMIO physical address */
+ UChar *IOBase; /* MMIO linear address */
+ SISIOADDRESS RelIO; /* Relocated IO Ports baseaddress */
+ int MemClock;
+ int BusWidth;
+ int MinClock;
+ int MaxClock;
+ int Flags; /* HW config flags */
+ long FbMapSize; /* Used for Mem Mapping - DON'T CHANGE THIS */
+ long availMem; /* Really available Fb mem (minus TQ, HWCursor) */
+ ULong maxxfbmem; /* limit fb memory X is to use to this (KB) */
+ ULong sisfbMem; /* heapstart of sisfb (if running) */
+ UChar OldMode; /* Back old modeNo (if available) */
+ Bool NoAccel;
+ Bool NoXvideo;
+ Bool XvOnCRT2; /* see sis_opt.c */
+ Bool HWCursor;
+ int VESA;
+ int forceCRT1;
+ Bool CRT1changed;
+ UChar oldCR17, oldCR63, oldSR1F;
+ UChar oldCR32, oldCR36, oldCR37;
+ UChar myCR32, myCR36, myCR37, myCR63;
+ UChar newCR32;
+ unsigned int VBFlags; /* Video bridge configuration */
+ unsigned int VBFlags2; /* Video bridge configuration 2 (static flags only) */
+ unsigned int VBFlags_backup; /* Backup for SlaveMode-modes */
+ unsigned int VBLCDFlags; /* Moved LCD panel size bits here */
+ short scrnOffset; /* Screen pitch (data) */
+ short scrnPitch; /* Screen pitch (display; regarding interlace) */
+ unsigned short DstColor;
+ unsigned long SiS310_AccelDepth; /* used in accel for 315 series */
+ int CommandReg;
+ int MaxCMDQueueLen;
+ int CurCMDQueueLen;
+ int MinCMDQueueLen;
+ CARD16 CursorSize; /* Size of HWCursor area (bytes) */
+ CARD32 cursorOffset; /* see sis_driver.c and sis_cursor.c */
+ UChar *USBCursorBuf;
+ SISUSBRegRec SavedReg;
+ SISUSBRegRec ModeReg;
+ xf86CursorInfoPtr CursorInfoPtr;
+ CloseScreenProcPtr CloseScreen;
+ Bool (*ModeInit)(ScrnInfoPtr pScrn, DisplayModePtr mode);
+ void (*SiSSave)(ScrnInfoPtr pScrn, SISUSBRegPtr sisreg);
+ void (*SiSRestore)(ScrnInfoPtr pScrn, SISUSBRegPtr sisreg);
+ int cmdQueueLen; /* Current cmdQueueLength (for 2D and 3D) */
+ ULong cmdQueueLenMax;
+ ULong cmdQueueLenMin;
+ ULong *cmdQueueBase;
+ int *cmdQueueLenPtr; /* Ptr to variable holding the current queue length */
+ int *cmdQueueLenPtrBackup; /* Backup for DRI init/restore */
+ unsigned int cmdQueueOffset;
+ unsigned int cmdQueueSize;
+ ULong cmdQueueSizeMask;
+ ULong cmdQ_SharedWritePort_2D;
+ ULong *cmdQ_SharedWritePort;
+ ULong *cmdQ_SharedWritePortBackup;
+ unsigned int cmdQueueSize_div2;
+ unsigned int cmdQueueSize_div4;
+ unsigned int cmdQueueSize_4_3;
+
+ Bool IsAGPCard;
+ ULong DRIheapstart, DRIheapend;
+ Bool NeedFlush; /* Need to flush cmd buf mem (760) */
+
+ int PerColorExpandBufferSize;
+ int ColorExpandBufferNumber;
+ int ColorExpandBufferCountMask;
+ UChar *ColorExpandBufferAddr[32];
+ CARD32 ColorExpandBufferScreenOffset[32];
+ CARD32 ColorExpandBase;
+
+ /* ShadowFB support */
+ Bool ShadowFB;
+ UChar *ShadowPtr;
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ UChar *ShadowPtrSwap;
+#endif
+ int ShadowPitch;
+ int ShXmin, ShXmax, ShYmin, ShYmax, ShBoxcount, delaycount;
+
+ /* sisusb and sisusbfb communication */
+ CARD32 USBBus, USBDev;
+ Bool sisusbdevopen;
+ int sisusbdev, sisusb_minor, sisusbfbactive, sisusbconactive;
+ int sisusberrorsleepcount;
+ int sisusbfatalerror, timeout;
+ Time errorTime;
+ ULong sisusbmembase, sisusbmmiobase, sisusbioportbase, sisusbpcibase;
+ ULong sisusbvramsize;
+ UChar sisusbversion, sisusbrevision, sisusbpatchlevel, sisusbinit;
+ Bool sisfbfound;
+ ULong sisfbspecialtiming;
+ Bool sisfb_havelock;
+ char sisfbdevname[16];
+
+ /* Xv */
+ XF86VideoAdaptorPtr adaptor;
+ ScreenBlockHandlerProcPtr BlockHandler;
+ void (*VideoTimerCallback)(ScrnInfoPtr, Time);
+ void (*ResetXv)(ScrnInfoPtr);
+ void (*ResetXvGamma)(ScrnInfoPtr);
+
+ /* misc */
+ OptionInfoPtr Options;
+ Bool Blank;
+ UChar BIOSModeSave;
+ int CRT1off; /* 1=CRT1 off, 0=CRT1 on */
+ CARD16 LCDheight; /* Vertical resolution of LCD panel */
+ CARD16 LCDwidth; /* Horizontal resolution of LCD panel */
+ int UseVESA;
+ CARD16 maxBytesPerScanline;
+ CARD32 *pal, *savedPal;
+ int mapPhys, mapOff, mapSize;
+ int statePage, stateSize, stateMode;
+ CARD8 *fonts;
+ CARD8 *state, *pstate;
+ void *base, *VGAbase;
+ SISFBLayout CurrentLayout; /* Current framebuffer layout */
+ UShort SiS_DDC2_Index;
+ UShort SiS_DDC2_Data;
+ UShort SiS_DDC2_Clk;
+ int RealVideoRam; /* 6326 can only address 4MB, but TQ can be above */
+ CARD32 CmdQueLenMask; /* Mask of queue length in MMIO register */
+ CARD32 CmdQueLenFix; /* Fix value to subtract from QueLen (530/620) */
+ CARD32 CmdQueMaxLen; /* (6326/5597/5598) Amount of cmds the queue can hold */
+ CARD32 detectedCRT2Devices; /* detected CRT2 devices before mask-out */
+ Bool noInternalModes; /* Use our own default modes? */
+ Bool SCLogQuiet;
+
+ int EMI;
+ UChar postVBCR32;
+ ULong lockcalls; /* Count unlock calls for debug */
+ ULong sistvccbase;
+ Bool ForceCursorOff;
+ Bool HaveCustomModes;
+ Bool IsCustom;
+ DisplayModePtr backupmodelist;
+#ifdef SIS_GLOBAL_ENABLEXV
+ Atom xvBrightness, xvContrast, xvColorKey, xvHue, xvSaturation;
+ Atom xvAutopaintColorKey, xvSetDefaults, xvSwitchCRT;
+ Atom xvDisableGfx, xvDisableGfxLR, xvTVXPosition, xvTVYPosition;
+ Atom xvDisableColorkey, xvUseChromakey, xvChromaMin, xvChromaMax;
+ Atom xvInsideChromakey, xvYUVChromakey, xvVSync;
+ Atom xvGammaRed, xvGammaGreen, xvGammaBlue;
+ Atom xv_QVF, xv_QVV, xv_USD, xv_SVF, xv_QDD, xv_TAF, xv_TSA, xv_TEE, xv_GSF;
+ Atom xv_TTE, xv_TCO, xv_TCC, xv_TCF, xv_TLF, xv_CMD, xv_CMDR, xv_CT1, xv_SGA;
+ Atom xv_GDV, xv_GHI, xv_OVR, xv_GBI, xv_TXS, xv_TYS, xv_CFI, xv_COC, xv_COF;
+ Atom xv_YFI, xv_GSS, xv_BRR, xv_BRG, xv_BRB, xv_PBR, xv_PBG, xv_PBB, xv_SHC;
+ Atom xv_BRR2, xv_BRG2, xv_BRB2, xv_PBR2, xv_PBG2, xv_PBB2, xv_PMD, xv_RDT;
+ Atom xv_GARC2,xv_GAGC2,xv_GABC2, xv_GSF2;
+ Atom xv_BRRC2, xv_BRGC2, xv_BRBC2, xv_PBRC2, xv_PBGC2, xv_PBBC2;
+#ifdef TWDEBUG
+ Atom xv_STR;
+#endif
+#endif
+ int xv_sisdirectunlocked;
+ ULong xv_sd_result;
+ int CRT1isoff;
+ ULong ChipFlags;
+ ULong SiS_SD_Flags, SiS_SD2_Flags, SiS_SD3_Flags, SiS_SD4_Flags;
+ Bool UseHWARGBCursor;
+ int OptUseColorCursor;
+ UShort cursorBufferNum;
+ int vb;
+ Bool restorebyset;
+ Bool CRT1gamma, CRT1gammaGiven, XvGamma, XvGammaGiven;
+ int XvDefCon, XvDefBri, XvDefHue, XvDefSat;
+ Bool XvDefDisableGfx, XvDefDisableGfxLR, XvDefAdaptorBlit;
+ Bool XvUseChromaKey, XvDisableColorKey;
+ Bool XvInsideChromaKey, XvYUVChromaKey;
+ int XvChromaMin, XvChromaMax;
+ int XvGammaRed, XvGammaGreen, XvGammaBlue;
+ int XvGammaRedDef, XvGammaGreenDef, XvGammaBlueDef;
+ CARD8 XvGammaRampRed[256], XvGammaRampGreen[256], XvGammaRampBlue[256];
+ Bool disablecolorkeycurrent;
+ CARD32 colorKey;
+ CARD32 MiscFlags;
+ float zClearVal;
+ ULong bClrColor, dwColor;
+ Bool enablesisctrl;
+ short Video_MaxWidth, Video_MaxHeight;
+ int FSTN;
+ short scrnPitch2;
+ CARD32 CurFGCol, CurBGCol;
+ UChar * CurMonoSrc;
+ CARD32 * CurARGBDest;
+ int GammaBriR, GammaBriG, GammaBriB;
+ float NewGammaBriR, NewGammaBriG, NewGammaBriB;
+ float NewGammaConR, NewGammaConG, NewGammaConB;
+ Bool HideHWCursor; /* Custom application */
+ Bool HWCursorIsVisible;
+ ULong HWCursorBackup[16];
+ int HWCursorMBufNum, HWCursorCBufNum;
+ ULong mmioSize;
+ Bool skipswitchcheck;
+ ULong VBFlagsInit;
+ DisplayModePtr currentModeLast;
+ IOADDRESS MyPIOOffset;
+
+ char messagebuffer[64];
+ unsigned int VGAMapSize; /* SiSVGA stuff */
+ ULong VGAMapPhys;
+ void *VGAMemBase; /* mapped */
+ Bool VGAPaletteEnabled;
+ Bool VGACMapSaved;
+
+ ExtensionEntry *SiSCtrlExtEntry;
+ char devsectname[32];
+
+ /* accel wrapper */
+#if 0
+ int SiSUSBGCIndex; /* init -1 */
+ CloseScreenProcPtr AWCloseScreen;
+ CreateGCProcPtr AWCreateGC;
+ Bool AccelNeedSync;
+ Bool IgnoreRefresh;
+ int PreAllocSize;
+ void * PreAllocMem;
+#endif
+} SISUSBRec, *SISUSBPtr;
+
+extern void sisusbSaveUnlockExtRegisterLock(SISUSBPtr pSiS, UChar *reg1, UChar *reg2);
+extern void sisusbRestoreExtRegisterLock(SISUSBPtr pSiS, UChar reg1, UChar reg2);
+extern void SiSUSBOptions(ScrnInfoPtr pScrn);
+extern const OptionInfoRec * SISUSBAvailableOptions(int chipid, int busid);
+extern void SiSUSBSetup(ScrnInfoPtr pScrn);
+extern void SISUSBVGAPreInit(ScrnInfoPtr pScrn);
+extern Bool SiSUSBHWCursorInit(ScreenPtr pScreen);
+extern Bool SiSUSBAccelInit(ScreenPtr pScreen);
+#if 0
+extern void SiSUSBSync(ScrnInfoPtr pScrn);
+#endif
+#ifdef SIS_GLOBAL_ENABLEXV
+extern void SISUSBInitVideo(ScreenPtr pScreen);
+#endif
+extern Bool SiSUSBFBInit(ScreenPtr pScreen);
+
+extern void SiSUSBMemCopyToVideoRam(SISUSBPtr pSiSUSB, UChar *to, UChar *from, int size);
+extern UChar inSISREG(SISUSBPtr pSiSUSB, ULong base);
+extern UShort inSISREGW(SISUSBPtr pSiSUSB, ULong base);
+extern ULong inSISREGL(SISUSBPtr pSiSUSB, ULong base);
+extern void outSISREG(SISUSBPtr pSiSUSB, ULong base, UChar val);
+extern void outSISREGW(SISUSBPtr pSiSUSB, ULong base, UShort val);
+extern void outSISREGL(SISUSBPtr pSiSUSB, ULong base, unsigned int val);
+extern void orSISREG(SISUSBPtr pSiSUSB, ULong base, UChar val);
+extern void andSISREG(SISUSBPtr pSiSUSB, ULong base, UChar val);
+extern void outSISIDXREG(SISUSBPtr pSiSUSB, ULong base, UChar idx, UChar val);
+extern UChar __inSISIDXREG(SISUSBPtr pSiSUSB, ULong base, UChar idx);
+extern void orSISIDXREG(SISUSBPtr pSiSUSB, ULong base, UChar idx, UChar val);
+extern void andSISIDXREG(SISUSBPtr pSiSUSB, ULong base, UChar idx, UChar val);
+extern void setSISIDXREG(SISUSBPtr pSiSUSB, ULong base, UChar idx, UChar myand, UChar myor);
+extern void setSISIDXREGmask(SISUSBPtr pSiSUSB, ULong base, UChar idx, UChar data, UChar mask);
+extern void sisclearvram(SISUSBPtr pSiSUSB, UChar *where, unsigned int howmuch);
+extern void sisrestoredestroyconsole(SISUSBPtr pSiSUSB, int what);
+extern void SIS_MMIO_OUT8(SISUSBPtr pSiSUSB, UChar *base, unsigned int offset, CARD8 val);
+extern void SIS_MMIO_OUT16(SISUSBPtr pSiSUSB, UChar *base, unsigned int offset, CARD16 val);
+extern void SIS_MMIO_OUT32(SISUSBPtr pSiSUSB, UChar *base, unsigned int offset, CARD32 val);
+extern CARD8 SIS_MMIO_IN8(SISUSBPtr pSiSUSB, UChar *base, unsigned int offset);
+extern CARD16 SIS_MMIO_IN16(SISUSBPtr pSiSUSB, UChar *base, unsigned int offset);
+extern CARD32 SIS_MMIO_IN32(SISUSBPtr pSiSUSB, UChar *base, unsigned int offset);
+
+#define inSISIDXREG(struct,base,idx,var) var = __inSISIDXREG(struct, base, idx)
+
+#define SIS_USEIOCTL
+
+#endif /* _SISUSB_H_ */
+
+
+
diff --git a/driver/xf86-video-sisusb/src/sisusb_accel.c b/driver/xf86-video-sisusb/src/sisusb_accel.c
new file mode 100644
index 000000000..f5da5c13d
--- /dev/null
+++ b/driver/xf86-video-sisusb/src/sisusb_accel.c
@@ -0,0 +1,134 @@
+/* $XFree86$ */
+/* $XdotOrg: driver/xf86-video-sisusb/src/sisusb_accel.c,v 1.6 2005/07/11 02:30:00 ajax Exp $ */
+/*
+ * 2D Acceleration for SiS 315/USB - not functional!
+ *
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1) Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2) Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3) The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "sisusb.h"
+#include "sisusb_regs.h"
+#include "sisusb_accel.h"
+
+/* VRAM queue acceleration specific */
+
+#define SIS_WQINDEX(i) sis_accel_cmd_buffer[i]
+#define SIS_RQINDEX(i) ((ULong)tt + 1) /* Bullshit, but we don't flush anyway */
+
+static void
+SiSUSBInitializeAccelerator(ScrnInfoPtr pScrn)
+{
+#ifndef SISVRAMQ
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+
+ if(pSiSUSB->ChipFlags & SiSCF_Integrated) {
+ CmdQueLen = 0;
+ } else {
+ CmdQueLen = ((128 * 1024) / 4) - 64;
+ }
+#endif
+}
+
+Bool
+SiSUSBAccelInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ int topFB, reservedFbSize, usableFbSize;
+ BoxRec Avail;
+
+ pSiSUSB->ColorExpandBufferNumber = 0;
+ pSiSUSB->PerColorExpandBufferSize = 0;
+
+ if((pScrn->bitsPerPixel != 8) &&
+ (pScrn->bitsPerPixel != 16) &&
+ (pScrn->bitsPerPixel != 32)) {
+ pSiSUSB->NoAccel = TRUE;
+ }
+
+ if(!pSiSUSB->NoAccel) {
+
+ SiSUSBInitializeAccelerator(pScrn);
+
+ }
+
+ /* Init framebuffer memory manager */
+
+ topFB = pSiSUSB->maxxfbmem;
+
+ reservedFbSize = pSiSUSB->ColorExpandBufferNumber * pSiSUSB->PerColorExpandBufferSize;
+
+ usableFbSize = topFB - reservedFbSize;
+
+ /* Layout:
+ * |--------------++++++++++++++++++++^************==========~~~~~~~~~~~~|
+ * UsableFbSize ColorExpandBuffers | DRI-Heap HWCursor CommandQueue
+ * topFB
+ */
+
+ Avail.x1 = 0;
+ Avail.y1 = 0;
+ Avail.x2 = pScrn->displayWidth;
+ Avail.y2 = (usableFbSize / (pScrn->displayWidth * pScrn->bitsPerPixel/8)) - 1;
+
+ if(Avail.y2 < 0) Avail.y2 = 32767;
+
+ if(Avail.y2 < pScrn->currentMode->VDisplay) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Not enough video RAM for accelerator. At least "
+ "%dKB needed, %ldKB available\n",
+ ((((pScrn->displayWidth * pScrn->bitsPerPixel/8) /* +8 for make it sure */
+ * pScrn->currentMode->VDisplay) + reservedFbSize) / 1024) + 8,
+ pSiSUSB->maxxfbmem/1024);
+ pSiSUSB->NoAccel = TRUE;
+ pSiSUSB->NoXvideo = TRUE;
+ return FALSE; /* Don't even init fb manager */
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Framebuffer from (%d,%d) to (%d,%d)\n",
+ Avail.x1, Avail.y1, Avail.x2 - 1, Avail.y2 - 1);
+
+ xf86InitFBManager(pScreen, &Avail);
+
+ return TRUE;
+}
+
+
+
+
+
+
+
+
+
diff --git a/driver/xf86-video-sisusb/src/sisusb_accel.h b/driver/xf86-video-sisusb/src/sisusb_accel.h
new file mode 100644
index 000000000..d6acd3664
--- /dev/null
+++ b/driver/xf86-video-sisusb/src/sisusb_accel.h
@@ -0,0 +1,954 @@
+/* $XFree86$ */
+/* $XdotOrg: driver/xf86-video-sisusb/src/sisusb_accel.h,v 1.4 2005/07/09 02:50:34 twini Exp $ */
+/*
+ * 2D Acceleration for SiS 315/USB
+ * Definitions for the SIS engine communication.
+ *
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1) Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2) Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3) The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
+
+/* Engine commands */
+#define BITBLT 0x00000000 /* Blit */
+#define COLOREXP 0x00000001 /* Color expand */
+#define ENCOLOREXP 0x00000002 /* Enhanced color expand (315 only?) */
+#define MULTIPLE_SCANLINE 0x00000003 /* 315 only, not 330 */
+#define LINE 0x00000004 /* Draw line */
+#define TRAPAZOID_FILL 0x00000005 /* Fill trapezoid */
+#define TRANSPARENT_BITBLT 0x00000006 /* Transparent Blit */
+#define ALPHA_BLEND 0x00000007 /* Alpha blended BitBlt */
+#define A3D_FUNCTION 0x00000008 /* 3D command ? */
+#define CLEAR_Z_BUFFER 0x00000009 /* ? */
+#define GRADIENT_FILL 0x0000000A /* Gradient fill */
+#define STRETCH_BITBLT 0x0000000B /* Stretched BitBlit */
+
+#define YUVRGB_BLIT_325 0x0000000C
+#define YUVRGB_BLIT_330 0x00000003
+
+/* Command bits */
+
+/* Source selection */
+#define SRCVIDEO 0x00000000 /* source is video RAM */
+#define SRCSYSTEM 0x00000010 /* source is system memory */
+#define SRCCPUBLITBUF SRCSYSTEM /* source is CPU-driven BitBuffer (for color expand) */
+#define SRCAGP 0x00000020 /* source is AGP memory (?) */
+
+/* Pattern source selection */
+#define PATFG 0x00000000 /* foreground color */
+#define PATPATREG 0x00000040 /* pattern in pattern buffer (0x8300) */
+#define PATMONO 0x00000080 /* mono pattern */
+
+/* Clipping flags */
+#define NOCLIP 0x00000000
+#define NOMERGECLIP 0x04000000
+#define CLIPENABLE 0x00040000
+#define CLIPWITHOUTMERGE 0x04040000
+
+/* Subfunctions for BitBlt: Transparency */
+#define OPAQUE 0x00000000
+#define TRANSPARENT 0x00100000
+
+/* Subfunctions for Alpha Blended BitBlt */
+#define A_CONSTANTALPHA 0x00000000
+#define A_PERPIXELALPHA 0x00080000
+#define A_NODESTALPHA 0x00100000
+#define A_3DFULLSCENE 0x00180000
+
+/* Destination */
+#define DSTAGP 0x02000000
+#define DSTVIDEO 0x00000000
+
+/* Subfunctions for Color/Enhanced Color Expansion */
+#define COLOR_TO_MONO 0x00100000
+#define AA_TEXT 0x00200000
+
+/* Line */
+#define LINE_STYLE 0x00800000
+#define NO_RESET_COUNTER 0x00400000
+#define NO_LAST_PIXEL 0x00200000
+
+/* Trapezoid (315 only?) */
+#define T_XISMAJORL 0x00800000 /* X axis is driving axis (left) */
+#define T_XISMAJORR 0x08000000 /* X axis is driving axis (right) */
+#define T_L_Y_INC 0x00000020 /* left edge direction Y */
+#define T_L_X_INC 0x00000010 /* left edge direction X */
+#define T_R_Y_INC 0x00400000 /* right edge direction Y */
+#define T_R_X_INC 0x00200000 /* right edge direction X */
+
+/* YUV to RGB blit */
+#define YUV_FORMAT_YUY2 0x00000000
+#define YUV_FORMAT_YVYU 0x00002000
+#define YUV_FORMAT_UYVY 0x00004000
+#define YUV_FORMAT_VYUY 0x00006000
+#define YUV_FORMAT_NV12 0x00008000 /* Only supported one */
+#define YUV_FORMAT_NV21 0x0000A000
+
+#define YUV_CMD_YUV 0x00800000
+
+/* Scanline trigger (315 only, not 330) */
+#define SCANLINE_TR_CRT1 0x00000000
+#define SCANLINE_TR_CRT2 0x01000000
+#define SCANLINE_TRIGGER_ENABLE 0x80000000
+
+/* Some general registers */
+#define SRC_ADDR 0x8200
+#define SRC_PITCH 0x8204
+#define AGP_BASE 0x8206 /* color-depth dependent value */
+#define SRC_Y 0x8208
+#define SRC_X 0x820A
+#define DST_Y 0x820C
+#define DST_X 0x820E
+#define DST_ADDR 0x8210
+#define DST_PITCH 0x8214
+#define DST_HEIGHT 0x8216
+#define RECT_WIDTH 0x8218
+#define RECT_HEIGHT 0x821A
+#define PAT_FGCOLOR 0x821C
+#define PAT_BGCOLOR 0x8220
+#define SRC_FGCOLOR 0x8224
+#define SRC_BGCOLOR 0x8228
+#define MONO_MASK 0x822C
+#define LEFT_CLIP 0x8234
+#define TOP_CLIP 0x8236
+#define RIGHT_CLIP 0x8238
+#define BOTTOM_CLIP 0x823A
+#define COMMAND_READY 0x823C
+#define FIRE_TRIGGER 0x8240
+
+#define PATTERN_REG 0x8300 /* 384 bytes pattern buffer */
+
+/* Line registers */
+#define LINE_X0 SRC_Y
+#define LINE_X1 DST_Y
+#define LINE_Y0 SRC_X
+#define LINE_Y1 DST_X
+#define LINE_COUNT RECT_WIDTH
+#define LINE_STYLE_PERIOD RECT_HEIGHT
+#define LINE_STYLE_0 MONO_MASK
+#define LINE_STYLE_1 0x8230
+#define LINE_XN PATTERN_REG
+#define LINE_YN PATTERN_REG+2
+
+/* Transparent bitblit registers */
+#define TRANS_DST_KEY_HIGH PAT_FGCOLOR
+#define TRANS_DST_KEY_LOW PAT_BGCOLOR
+#define TRANS_SRC_KEY_HIGH SRC_FGCOLOR
+#define TRANS_SRC_KEY_LOW SRC_BGCOLOR
+
+#define ALPHA_ALPHA PAT_FGCOLOR
+
+/* Trapezoid registers */
+#define TRAP_YH SRC_Y /* 0x8208 */
+#define TRAP_LR DST_Y /* 0x820C */
+#define TRAP_DL 0x8244
+#define TRAP_DR 0x8248
+#define TRAP_EL 0x824C
+#define TRAP_ER 0x8250
+
+/* Queue */
+#define Q_BASE_ADDR 0x85C0 /* Base address of software queue */
+#define Q_WRITE_PTR 0x85C4 /* Current write pointer */
+#define Q_READ_PTR 0x85C8 /* Current read pointer */
+#define Q_STATUS 0x85CC /* queue status */
+
+/* VRAM queue operation command header definitions */
+#define SISUSB_SPKC_HEADER 0x16800000L
+#define SISUSB_BURST_HEADER0 0x568A0000L
+#define SISUSB_BURST_HEADER1 0x62100000L
+#define SISUSB_PACKET_HEARER0 0x968A0000L
+#define SISUSB_PACKET_HEADER1 0x62100000L
+#define SISUSB_NIL_CMD 0x168F0000L
+
+#define SISUSB_PACKET12_HEADER0 0x968A000CL
+#define SISUSB_PACKET12_HEADER1 0x62100010L
+#define SISUSB_PACKET12_LENGTH 80
+
+/* Macros to do useful things with the SiS315/330 BitBLT engine */
+
+/* Q_STATUS:
+ bit 31 = 1: All engines idle and all queues empty
+ bit 30 = 1: Hardware Queue (=HW CQ, 2D queue, 3D queue) empty
+ bit 29 = 1: 2D engine is idle
+ bit 28 = 1: 3D engine is idle
+ bit 27 = 1: HW command queue empty
+ bit 26 = 1: 2D queue empty
+ bit 25 = 1: 3D queue empty
+ bit 24 = 1: SW command queue empty
+ bits 23:16: 2D counter 3
+ bits 15:8: 2D counter 2
+ bits 7:0: 2D counter 1
+*/
+
+/* As sis_dri.c and dual head mode relocate the cmd-q len to the sarea/entity,
+ * don't use it directly here */
+#define CmdQueLen (*(pSiSUSB->cmdQueueLenPtr))
+
+#define SiSUSBQEmpty \
+ { \
+ int watchdog = 300; \
+ while( (((SIS_MMIO_IN16(pSiSUSB->IOBase, Q_STATUS+2)) & 0x0400) != 0x0400) && --watchdog ) {}; \
+ watchdog = 300; \
+ while( (((SIS_MMIO_IN16(pSiSUSB->IOBase, Q_STATUS+2)) & 0x0400) != 0x0400) && --watchdog ) {}; \
+ }
+
+#define SiSUSBResetCmd pSiSUSB->CommandReg = 0;
+
+#define SiSUSBSetupCMDFlag(flags) pSiSUSB->CommandReg |= (flags);
+
+/* --- VRAM mode --- */
+
+#define SiSUSBGetSwWP() (CARD32)(*(pSiSUSB->cmdQ_SharedWritePort))
+#define SiSUSBGetHwRP() (CARD32)(SIS_MMIO_IN32(pSiSUSB->IOBase, Q_READ_PTR))
+
+#define SiSUSBFlushCmdBuf
+
+#define SiSUSBSyncWP \
+ SiSUSBFlushCmdBuf; \
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, Q_WRITE_PTR, (CARD32)(*(pSiSUSB->cmdQ_SharedWritePort)));
+
+#define SiSUSBSetHwWP(p) \
+ *(pSiSUSB->cmdQ_SharedWritePort) = (p); \
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, Q_WRITE_PTR, (p));
+
+#define SiSUSBSetSwWP(p) *(pSiSUSB->cmdQ_SharedWritePort) = (p);
+
+#define SiSUSBCheckQueue(amount)
+
+#if 0
+ { \
+ CARD32 mcurrent, i=0, ttt = SiSUSBGetSwWP(); \
+ if((ttt + amount) >= pSiSUSB->cmdQueueSize) { \
+ do { \
+ mcurrent = SIS_MMIO_IN32(pSiSUSB->IOBase, Q_READ_PTR); \
+ i++; \
+ } while((mcurrent > ttt) || (mcurrent < ((ttt + amount) & pSiSUSB->cmdQueueSizeMask))); \
+ } else { \
+ do { \
+ mcurrent = SIS_MMIO_IN32(pSiSUSB->IOBase, Q_READ_PTR); \
+ i++; \
+ } while((mcurrent > ttt) && (mcurrent < (ttt + amount))); \
+ } \
+ }
+#endif
+
+#define SiSUSBUpdateQueue \
+ SiSUSBWriteQueue(tt); \
+ ttt += 16; \
+ ttt &= pSiSUSB->cmdQueueSizeMask; \
+ if(!ttt) { \
+ while(SIS_MMIO_IN32(pSiSUSB->IOBase, Q_READ_PTR) < pSiSUSB->cmdQueueSize_div4) {} \
+ } else if(ttt == pSiSUSB->cmdQueueSize_div4) { \
+ CARD32 temppp; \
+ do { \
+ temppp = SIS_MMIO_IN32(pSiSUSB->IOBase, Q_READ_PTR); \
+ } while(temppp >= ttt && temppp <= pSiSUSB->cmdQueueSize_div2); \
+ } else if(ttt == pSiSUSB->cmdQueueSize_div2) { \
+ CARD32 temppp; \
+ do { \
+ temppp = SIS_MMIO_IN32(pSiSUSB->IOBase, Q_READ_PTR); \
+ } while(temppp >= ttt && temppp <= pSiSUSB->cmdQueueSize_4_3); \
+ } else if(ttt == pSiSUSB->cmdQueueSize_4_3) { \
+ while(SIS_MMIO_IN32(pSiSUSB->IOBase, Q_READ_PTR) > ttt) {} \
+ }
+
+/* Write-updates MUST be 128bit aligned. */
+#define SiSUSBNILandUpdateSWQueue \
+ SIS_WQINDEX(2) = (CARD32)(SISUSB_NIL_CMD); \
+ SIS_WQINDEX(3) = (CARD32)(SISUSB_NIL_CMD); \
+ SiSUSBUpdateQueue; \
+ SiSUSBSetSwWP(ttt);
+
+#ifdef SISVRAMQ
+
+#define SiSUSBIdle \
+ { \
+ int watchdog = 500; \
+ while( ((SIS_MMIO_IN16(pSiSUSB->IOBase, Q_STATUS+2) & 0x8000) != 0x8000) && --watchdog ) {}; \
+ watchdog = 500; \
+ while( ((SIS_MMIO_IN16(pSiSUSB->IOBase, Q_STATUS+2) & 0x8000) != 0x8000) && --watchdog ) {}; \
+ }
+
+#define SiSUSBSetupSRCDSTBase(srcbase,dstbase) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + SRC_ADDR); \
+ SIS_WQINDEX(1) = (CARD32)(srcbase); \
+ SIS_WQINDEX(2) = (CARD32)(SISUSB_SPKC_HEADER + DST_ADDR); \
+ SIS_WQINDEX(3) = (CARD32)(dstbase); \
+ SiSUSBUpdateQueue \
+ SiSUSBSetSwWP(ttt); \
+ }
+
+#define SiSUSBSetupSRCDSTXY(sx,sy,dx,dy) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + SRC_Y); \
+ SIS_WQINDEX(1) = (CARD32)(((sx)<<16) | (sy)); \
+ SIS_WQINDEX(2) = (CARD32)(SISUSB_SPKC_HEADER + DST_Y); \
+ SIS_WQINDEX(3) = (CARD32)(((dx)<<16) | (dy)); \
+ SiSUSBUpdateQueue \
+ SiSUSBSetSwWP(ttt); \
+ }
+
+#define SiSUSBSetupDSTXYRect(x,y,w,h) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + DST_Y); \
+ SIS_WQINDEX(1) = (CARD32)(((x)<<16) | (y)); \
+ SIS_WQINDEX(2) = (CARD32)(SISUSB_SPKC_HEADER + RECT_WIDTH); \
+ SIS_WQINDEX(3) = (CARD32)(((h)<<16) | (w)); \
+ SiSUSBUpdateQueue \
+ SiSUSBSetSwWP(ttt); \
+ }
+
+#define SiSUSBSetupSRCPitchDSTRect(pitch,x,y) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + SRC_PITCH); \
+ SIS_WQINDEX(1) = (CARD32)(pitch); \
+ SIS_WQINDEX(2) = (CARD32)(SISUSB_SPKC_HEADER + DST_PITCH); \
+ SIS_WQINDEX(3) = (CARD32)(((y)<<16) | (x)); \
+ SiSUSBUpdateQueue \
+ SiSUSBSetSwWP(ttt); \
+ }
+
+#define SiSUSBSetupSRCBase(base) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + SRC_ADDR); \
+ SIS_WQINDEX(1) = (CARD32)(base); \
+ SiSUSBNILandUpdateSWQueue \
+ }
+
+#define SiSUSBSetupSRCPitch(pitch) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + SRC_PITCH); \
+ SIS_WQINDEX(1) = (CARD32)(pitch); \
+ SiSUSBNILandUpdateSWQueue \
+ }
+
+#define SiSUSBSetupSRCXY(x,y) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + SRC_Y); \
+ SIS_WQINDEX(1) = (CARD32)(((x)<<16) | (y)); \
+ SiSUSBNILandUpdateSWQueue \
+ }
+
+#define SiSUSBSetupDSTBase(base) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + DST_ADDR); \
+ SIS_WQINDEX(1) = (CARD32)(base); \
+ SiSUSBNILandUpdateSWQueue \
+ }
+
+#define SiSUSBSetupDSTXY(x,y) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + DST_Y); \
+ SIS_WQINDEX(1) = (CARD32)(((x)<<16) | (y)); \
+ SiSUSBNILandUpdateSWQueue \
+ }
+
+#define SiSUSBSetupDSTRect(x,y) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + DST_PITCH); \
+ SIS_WQINDEX(1) = (CARD32)(((y)<<16) | (x)); \
+ SiSUSBNILandUpdateSWQueue \
+ }
+
+#define SiSUSBSetupDSTRectBurstHeader(x,y,reg,num) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + DST_PITCH); \
+ SIS_WQINDEX(1) = (CARD32)(((y)<<16) | (x)); \
+ SIS_WQINDEX(2) = (CARD32)(SISUSB_BURST_HEADER0 + reg); \
+ SIS_WQINDEX(3) = (CARD32)(SISUSB_BURST_HEADER1 + num); \
+ SiSUSBUpdateQueue \
+ SiSUSBSetSwWP(ttt); \
+ }
+
+#define SiSUSBSetupDSTColorDepth(bpp) \
+ pSiSUSB->CommandReg = (((CARD32)(bpp)) & (GENMASK(17:16)));
+
+#define SiSUSBSetupPATFGDSTRect(color,x,y) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + PAT_FGCOLOR); \
+ SIS_WQINDEX(1) = (CARD32)(color); \
+ SIS_WQINDEX(2) = (CARD32)(SISUSB_SPKC_HEADER + DST_PITCH); \
+ SIS_WQINDEX(3) = (CARD32)(((y)<<16) | (x)); \
+ SiSUSBUpdateQueue \
+ SiSUSBSetSwWP(ttt); \
+ }
+
+#define SiSUSBSetupSRCFGDSTRect(color,x,y) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + SRC_FGCOLOR); \
+ SIS_WQINDEX(1) = (CARD32)(color); \
+ SIS_WQINDEX(2) = (CARD32)(SISUSB_SPKC_HEADER + DST_PITCH); \
+ SIS_WQINDEX(3) = (CARD32)(((y)<<16) | (x)); \
+ SiSUSBUpdateQueue \
+ SiSUSBSetSwWP(ttt); \
+ }
+
+#define SiSUSBSetupRectSRCPitch(w,h,pitch) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + RECT_WIDTH); \
+ SIS_WQINDEX(1) = (CARD32)(((h)<<16) | (w)); \
+ SIS_WQINDEX(2) = (CARD32)(SISUSB_SPKC_HEADER + SRC_PITCH); \
+ SIS_WQINDEX(3) = (CARD32)(pitch); \
+ SiSUSBUpdateQueue \
+ SiSUSBSetSwWP(ttt); \
+ }
+
+#define SiSUSBSetupRect(w,h) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + RECT_WIDTH); \
+ SIS_WQINDEX(1) = (CARD32)(((h)<<16) | (w)); \
+ SiSUSBNILandUpdateSWQueue \
+ }
+
+#define SiSUSBSetupPATFG(color) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + PAT_FGCOLOR); \
+ SIS_WQINDEX(1) = (CARD32)(color); \
+ SiSUSBNILandUpdateSWQueue \
+ }
+
+#define SiSUSBSetupPATBG(color) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + PAT_BGCOLOR); \
+ SIS_WQINDEX(1) = (CARD32)(color); \
+ SiSUSBNILandUpdateSWQueue \
+ }
+
+#define SiSUSBSetupSRCFG(color) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + SRC_FGCOLOR); \
+ SIS_WQINDEX(1) = (CARD32)(color); \
+ SiSUSBNILandUpdateSWQueue \
+ }
+
+#define SiSUSBSetupSRCBG(color) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + SRC_BGCOLOR); \
+ SIS_WQINDEX(1) = (CARD32)(color); \
+ SiSUSBNILandUpdateSWQueue \
+ }
+
+#define SiSUSBSetupSRCTrans(color) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + TRANS_SRC_KEY_HIGH); \
+ SIS_WQINDEX(1) = (CARD32)(color); \
+ SIS_WQINDEX(2) = (CARD32)(SISUSB_SPKC_HEADER + TRANS_SRC_KEY_LOW); \
+ SIS_WQINDEX(3) = (CARD32)(color); \
+ SiSUSBUpdateQueue \
+ SiSUSBSetSwWP(ttt); \
+ }
+
+#define SiSUSBSetupDSTTrans(color) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + TRANS_DST_KEY_HIGH); \
+ SIS_WQINDEX(1) = (CARD32)(color); \
+ SIS_WQINDEX(2) = (CARD32)(SISUSB_SPKC_HEADER + TRANS_DST_KEY_LOW); \
+ SIS_WQINDEX(3) = (CARD32)(color); \
+ SiSUSBUpdateQueue \
+ SiSUSBSetSwWP(ttt); \
+ }
+
+#define SiSUSBSetupMONOPAT(p0,p1) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + MONO_MASK); \
+ SIS_WQINDEX(1) = (CARD32)(p0); \
+ SIS_WQINDEX(2) = (CARD32)(SISUSB_SPKC_HEADER + MONO_MASK + 4); \
+ SIS_WQINDEX(3) = (CARD32)(p1); \
+ SiSUSBUpdateQueue \
+ SiSUSBSetSwWP(ttt); \
+ }
+
+#define SiSUSBSetupClip(left,top,right,bottom) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + LEFT_CLIP); \
+ SIS_WQINDEX(1) = (CARD32)(((left) & 0xFFFF) | ((top)<<16)); \
+ SIS_WQINDEX(2) = (CARD32)(SISUSB_SPKC_HEADER + RIGHT_CLIP); \
+ SIS_WQINDEX(3) = (CARD32)(((right) & 0xFFFF)|((bottom)<<16)); \
+ SiSUSBUpdateQueue \
+ SiSUSBSetSwWP(ttt); \
+ }
+
+#define SiSUSBSetupDSTBaseDoCMD(base) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + DST_ADDR); \
+ SIS_WQINDEX(1) = (CARD32)(base); \
+ SIS_WQINDEX(2) = (CARD32)(SISUSB_SPKC_HEADER + COMMAND_READY); \
+ SIS_WQINDEX(3) = (CARD32)(pSiSUSB->CommandReg); \
+ if(pSiSUSB->NeedFlush) dummybuf = SIS_RQINDEX(3); \
+ SiSUSBUpdateQueue \
+ SiSUSBSetHwWP(ttt); \
+ }
+
+#define SiSUSBSetRectDoCMD(w,h) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + RECT_WIDTH); \
+ SIS_WQINDEX(1) = (CARD32)(((h)<<16) | (w)); \
+ SIS_WQINDEX(2) = (CARD32)(SISUSB_SPKC_HEADER + COMMAND_READY); \
+ SIS_WQINDEX(3) = (CARD32)(pSiSUSB->CommandReg); \
+ if(pSiSUSB->NeedFlush) dummybuf = SIS_RQINDEX(3); \
+ SiSUSBUpdateQueue \
+ SiSUSBSetHwWP(ttt); \
+ }
+
+#define SiSUSBSetupROP(rop) \
+ pSiSUSB->CommandReg |= (rop) << 8;
+
+#define SiSUSBDoCMD \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + COMMAND_READY); \
+ SIS_WQINDEX(1) = (CARD32)(pSiSUSB->CommandReg); \
+ SIS_WQINDEX(2) = (CARD32)(SISUSB_NIL_CMD); \
+ SIS_WQINDEX(3) = (CARD32)(SISUSB_NIL_CMD); \
+ if(pSiSUSB->NeedFlush) dummybuf = SIS_RQINDEX(3); \
+ SiSUSBUpdateQueue \
+ SiSUSBSetHwWP(ttt); \
+ }
+
+/* Line */
+
+#define SiSUSBSetupX0Y0X1Y1(x1,y1,x2,y2) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + LINE_X0); \
+ SIS_WQINDEX(1) = (CARD32)(((y1)<<16) | (x1)); \
+ SIS_WQINDEX(2) = (CARD32)(SISUSB_SPKC_HEADER + LINE_X1); \
+ SIS_WQINDEX(3) = (CARD32)(((y2)<<16) | (x2)); \
+ SiSUSBUpdateQueue \
+ SiSUSBSetSwWP(ttt); \
+ }
+
+#define SiSUSBSetupX0Y0(x,y) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + LINE_X0); \
+ SIS_WQINDEX(1) = (CARD32)(((y)<<16) | (x)); \
+ SiSUSBNILandUpdateSWQueue \
+ }
+
+#define SiSUSBSetupX1Y1(x,y) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + LINE_X1); \
+ SIS_WQINDEX(1) = (CARD32)(((y)<<16) | (x)); \
+ SiSUSBNILandUpdateSWQueue \
+ }
+
+#define SiSUSBSetupLineCountPeriod(c, p) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + LINE_COUNT); \
+ SIS_WQINDEX(1) = (CARD32)(((p) << 16) | (c)); \
+ SiSUSBNILandUpdateSWQueue \
+ }
+
+#define SiSUSBSetupStyle(ls,hs) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + LINE_STYLE_0); \
+ SIS_WQINDEX(1) = (CARD32)(ls); \
+ SIS_WQINDEX(2) = (CARD32)(SISUSB_SPKC_HEADER + LINE_STYLE_1); \
+ SIS_WQINDEX(3) = (CARD32)(hs); \
+ SiSUSBUpdateQueue \
+ SiSUSBSetSwWP(ttt); \
+ }
+
+/* Trapezoid */
+
+#define SiSUSBSetupYHLR(y,h,left,right) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + TRAP_YH); \
+ SIS_WQINDEX(1) = (CARD32)(((y)<<16) | (h)); \
+ SIS_WQINDEX(2) = (CARD32)(SISUSB_SPKC_HEADER + TRAP_LR); \
+ SIS_WQINDEX(3) = (CARD32)(((right)<<16) | (left)); \
+ SiSUSBUpdateQueue \
+ SiSUSBSetSwWP(ttt); \
+ }
+
+
+#define SiSUSBSetupdLdR(dxL,dyL,fxR,dyR) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + TRAP_DL); \
+ SIS_WQINDEX(1) = (CARD32)(((dyL)<<16) | (dxL)); \
+ SIS_WQINDEX(2) = (CARD32)(SISUSB_SPKC_HEADER + TRAP_DR); \
+ SIS_WQINDEX(3) = (CARD32)(((dyR)<<16) | (dxR)); \
+ SiSUSBUpdateQueue \
+ SiSUSBSetSwWP(ttt); \
+ }
+
+#define SiSUSBSetupELER(eL,eR) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + TRAP_EL); \
+ SIS_WQINDEX(1) = (CARD32)(eL); \
+ SIS_WQINDEX(2) = (CARD32)(SISUSB_SPKC_HEADER + TRAP_ER); \
+ SIS_WQINDEX(3) = (CARD32)(eR); \
+ SiSUSBUpdateQueue \
+ SiSUSBSetSwWP(ttt); \
+ }
+
+/* (Constant) Alpha blended BitBlt (alpha = 8 bit) */
+
+#define SiSUSBSetupAlpha(alpha) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + ALPHA_ALPHA); \
+ SIS_WQINDEX(1) = (CARD32)(alpha); \
+ SiSUSBNILandUpdateSWQueue \
+ }
+
+#define SiSUSBSetPattern(num, value) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(SISUSB_SPKC_HEADER + (PATTERN_REG + (num * 4))); \
+ SIS_WQINDEX(1) = (CARD32)(value); \
+ SiSUSBNILandUpdateSWQueue \
+ }
+
+#define SiSUSBSetupPatternRegBurst(pat1, pat2, pat3, pat4) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(pat1); \
+ SIS_WQINDEX(1) = (CARD32)(pat2); \
+ SIS_WQINDEX(2) = (CARD32)(pat3); \
+ SIS_WQINDEX(3) = (CARD32)(pat4); \
+ SiSUSBUpdateQueue \
+ SiSUSBSetSwWP(ttt); \
+ }
+
+typedef struct _SiSUSB_Packet12_YUV {
+ CARD32 P12_Header0;
+ CARD32 P12_Header1;
+ CARD16 P12_UVPitch; /* 8200 UV if planar, Y if packed */
+ CARD16 P12_Unused0; /* 8202 */
+ CARD16 P12_YPitch; /* 8204 Y if planar */
+ CARD16 P12_AGPBase; /* 8206 */
+ CARD16 P12_Unused1; /* 8208 */
+ CARD16 P12_Unused2; /* 820a */
+ CARD16 P12_DstY; /* 820c */
+ CARD16 P12_DstX; /* 820e */
+ CARD32 P12_DstAddr; /* 8210 */
+ CARD16 P12_DstPitch; /* 8214 */
+ CARD16 P12_DstHeight; /* 8216 */
+ CARD16 P12_RectWidth; /* 8218 */
+ CARD16 P12_RectHeight; /* 821a */
+ CARD32 P12_Unused3; /* 821c */
+ CARD32 P12_Unused4; /* 8220 */
+ CARD32 P12_UVSrcAddr; /* 8224 UV if planar, Y if packed */
+ CARD32 P12_YSrcAddr; /* 8228 Y if planar */
+ CARD32 P12_Unused5; /* 822c */
+ CARD32 P12_Unused6; /* 8230 */
+ CARD16 P12_ClipLeft; /* 8234 */
+ CARD16 P12_ClipTop; /* 8236 */
+ CARD16 P12_ClipRight; /* 8238 */
+ CARD16 P12_ClipBottom; /* 823a */
+ CARD32 P12_Command; /* 823c */
+ CARD32 P12_Null1;
+ CARD32 P12_Null2;
+} SiSUSB_Packet12_YUV;
+
+#define SiSUSBWritePacketPart(part1, part2, part3, part4) \
+ { \
+ CARD32 ttt = SiSUSBGetSwWP(); \
+ pointer tt = (char *)pSiSUSB->cmdQueueBase + ttt; \
+ SIS_WQINDEX(0) = (CARD32)(part1); \
+ SIS_WQINDEX(1) = (CARD32)(part2); \
+ SIS_WQINDEX(2) = (CARD32)(part3); \
+ SIS_WQINDEX(3) = (CARD32)(part4); \
+ SiSUSBUpdateQueue \
+ SiSUSBSetSwWP(ttt); \
+ }
+
+#endif /* VRAM mode */
+
+/* ---- MMIO mode ---- */
+
+#ifndef SISVRAMQ
+
+/* We assume a length of 4 bytes per command; since 512K of
+ * of RAM are allocated, the number of commands is easily
+ * calculated (and written to the address pointed to by
+ * CmdQueueLenPtr, since sis_dri.c relocates this)
+ * UPDATE: using the command queue without syncing totally
+ * (ie assuming a QueueLength of 0) decreases system latency
+ * dramatically on the integrated chipsets (sound gets interrupted,
+ * etc.). We now sync every time... this is a little slower,
+ * but it keeps the rest of the box somewhat alive.
+ * This was the reason for switching to VRAM queue mode.
+ */
+#define SiSUSBIdle \
+ { \
+ if(pSiSUSB->ChipFlags & SiSCF_Integrated) { \
+ CmdQueLen = 0; \
+ } else { \
+ CmdQueLen = ((512 * 1024) / 4) - 64; \
+ } \
+ while( (SIS_MMIO_IN16(pSiSUSB->IOBase, Q_STATUS+2) & 0x8000) != 0x8000) {}; \
+ while( (SIS_MMIO_IN16(pSiSUSB->IOBase, Q_STATUS+2) & 0x8000) != 0x8000) {}; \
+ }
+
+#define SiSUSBSetupSRCBase(base) \
+ if (CmdQueLen <= 0) SiSUSBIdle; \
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, SRC_ADDR, base); \
+ CmdQueLen--;
+
+#define SiSUSBSetupSRCPitch(pitch) \
+ if (CmdQueLen <= 0) SiSUSBIdle; \
+ SIS_MMIO_OUT16(pSiSUSB->IOBase, SRC_PITCH, pitch); \
+ CmdQueLen--;
+
+#define SiSUSBSetupSRCXY(x,y) \
+ if (CmdQueLen <= 0) SiSUSBIdle;\
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, SRC_Y, (x)<<16 | (y) );\
+ CmdQueLen--;
+
+#define SiSUSBSetupDSTBase(base) \
+ if (CmdQueLen <= 0) SiSUSBIdle;\
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, DST_ADDR, base);\
+ CmdQueLen--;
+
+#define SiSUSBSetupDSTXY(x,y) \
+ if (CmdQueLen <= 0) SiSUSBIdle;\
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, DST_Y, (x)<<16 | (y) );\
+ CmdQueLen--;
+
+#define SiSUSBSetupDSTRect(x,y) \
+ if (CmdQueLen <= 0) SiSUSBIdle;\
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, DST_PITCH, (y)<<16 | (x) );\
+ CmdQueLen--;
+
+#define SiSUSBSetupDSTColorDepth(bpp) \
+ if (CmdQueLen <= 0) SiSUSBIdle;\
+ SIS_MMIO_OUT16(pSiSUSB->IOBase, AGP_BASE, bpp);\
+ CmdQueLen--;
+
+#define SiSUSBSetupRect(w,h) \
+ if(CmdQueLen <= 0) SiSUSBIdle;\
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, RECT_WIDTH, (h)<<16 | (w) );\
+ CmdQueLen--;
+
+#define SiSUSBSetupPATFG(color) \
+ if(CmdQueLen <= 0) SiSUSBIdle;\
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, PAT_FGCOLOR, color);\
+ CmdQueLen--;
+
+#define SiSUSBSetupPATBG(color) \
+ if(CmdQueLen <= 0) SiSUSBIdle;\
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, PAT_BGCOLOR, color);\
+ CmdQueLen--;
+
+#define SiSUSBSetupSRCFG(color) \
+ if(CmdQueLen <= 0) SiSUSBIdle;\
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, SRC_FGCOLOR, color);\
+ CmdQueLen--;
+
+#define SiSUSBSetupSRCBG(color) \
+ if(CmdQueLen <= 0) SiSUSBIdle; \
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, SRC_BGCOLOR, color); \
+ CmdQueLen--;
+
+#define SiSUSBSetupSRCTrans(color) \
+ if(CmdQueLen <= 1) SiSUSBIdle;\
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, TRANS_SRC_KEY_HIGH, color);\
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, TRANS_SRC_KEY_LOW, color);\
+ CmdQueLen -= 2;
+
+#define SiSUSBSetupDSTTrans(color) \
+ if(CmdQueLen <= 1) SiSUSBIdle;\
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, TRANS_DST_KEY_HIGH, color); \
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, TRANS_DST_KEY_LOW, color); \
+ CmdQueLen -= 2;
+
+#define SiSUSBSetupMONOPAT(p0,p1) \
+ if(CmdQueLen <= 1) SiSUSBIdle;\
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, MONO_MASK, p0);\
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, MONO_MASK+4, p1);\
+ CmdQueLen=CmdQueLen-2;
+
+#define SiSUSBSetupClipLT(left,top) \
+ if(CmdQueLen <= 0) SiSUSBIdle;\
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, LEFT_CLIP, ((left) & 0xFFFF) | (top)<<16); \
+ CmdQueLen--;
+
+#define SiSUSBSetupClipRB(right,bottom) \
+ if(CmdQueLen <= 0) SiSUSBIdle; \
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, RIGHT_CLIP, ((right) & 0xFFFF) | (bottom)<<16); \
+ CmdQueLen--;
+
+#define SiSUSBSetupROP(rop) \
+ pSiSUSB->CommandReg = (rop) << 8;
+
+#define SiSUSBDoCMD \
+ if (CmdQueLen <= 1) SiSUSBIdle;\
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, COMMAND_READY, pSiSUSB->CommandReg); \
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, FIRE_TRIGGER, 0); \
+ CmdQueLen -= 2;
+
+/* Line */
+
+#define SiSUSBSetupX0Y0(x,y) \
+ if (CmdQueLen <= 0) SiSUSBIdle;\
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, LINE_X0, (y)<<16 | (x) );\
+ CmdQueLen--;
+
+#define SiSUSBSetupX1Y1(x,y) \
+ if (CmdQueLen <= 0) SiSUSBIdle;\
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, LINE_X1, (y)<<16 | (x) );\
+ CmdQueLen--;
+
+#define SiSUSBSetupLineCount(c) \
+ if (CmdQueLen <= 0) SiSUSBIdle;\
+ SIS_MMIO_OUT16(pSiSUSB->IOBase, LINE_COUNT, c);\
+ CmdQueLen--;
+
+#define SiSUSBSetupStylePeriod(p) \
+ if (CmdQueLen <= 0) SiSUSBIdle;\
+ SIS_MMIO_OUT16(pSiSUSB->IOBase, LINE_STYLE_PERIOD, p);\
+ CmdQueLen--;
+
+#define SiSUSBSetupStyleLow(ls) \
+ if (CmdQueLen <= 0) SiSUSBIdle;\
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, LINE_STYLE_0, ls);\
+ CmdQueLen--;
+
+#define SiSUSBSetupStyleHigh(ls) \
+ if (CmdQueLen <= 0) SiSUSBIdle;\
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, LINE_STYLE_1, ls);\
+ CmdQueLen--;
+
+/* Trapezoid */
+
+#define SiSUSBSetupYH(y,h) \
+ if (CmdQueLen <= 0) SiSUSBIdle;\
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, TRAP_YH, (y)<<16 | (h) );\
+ CmdQueLen--;
+
+#define SiSUSBSetupLR(left,right) \
+ if (CmdQueLen <= 0) SiSUSBIdle;\
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, TRAP_LR, (right)<<16 | (left) );\
+ CmdQueLen--;
+
+#define SiSUSBSetupdL(dxL,dyL) \
+ if (CmdQueLen <= 0) SiSUSBIdle;\
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, TRAP_DL, (dyL)<<16 | (dxL) );\
+ CmdQueLen--;
+
+#define SiSUSBSetupdR(dxR,dyR) \
+ if (CmdQueLen <= 0) SiSUSBIdle;\
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, TRAP_DR, (dyR)<<16 | (dxR) );\
+ CmdQueLen--;
+
+#define SiSUSBSetupEL(eL) \
+ if (CmdQueLen <= 0) SiSUSBIdle;\
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, TRAP_EL, eL);\
+ CmdQueLen--;
+
+#define SiSUSBSetupER(eR) \
+ if (CmdQueLen <= 0) SiSUSBIdle;\
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, TRAP_ER, eR);\
+ CmdQueLen--;
+
+/* (Constant) alpha blended BitBlt (alpha = 8 bit) */
+
+#define SiSUSBSetupAlpha(alpha) \
+ if (CmdQueLen <= 0) SiSUSBIdle;\
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, ALPHA_ALPHA, alpha);\
+ CmdQueLen--;
+
+/* Set Pattern register */
+
+#define SiSUSBSetPattern(num, value) \
+ if (CmdQueLen <= 0) SiSUSBIdle; \
+ SIS_MMIO_OUT32(pSiSUSB->IOBase, (PATTERN_REG + (num * 4)), value); \
+ CmdQueLen--;
+
+#endif /* MMIO mode */
+
diff --git a/driver/xf86-video-sisusb/src/sisusb_cursor.c b/driver/xf86-video-sisusb/src/sisusb_cursor.c
new file mode 100644
index 000000000..f697a08bf
--- /dev/null
+++ b/driver/xf86-video-sisusb/src/sisusb_cursor.c
@@ -0,0 +1,304 @@
+/* $XFree86$ */
+/* $XdotOrg: driver/xf86-video-sisusb/src/sisusb_cursor.c,v 1.7 2005/09/28 18:59:22 twini Exp $ */
+/*
+ * SiS 315/USB hardware cursor handling
+ *
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1) Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2) Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3) The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "sisusb.h"
+#include "cursorstr.h"
+#include "sisusb_regs.h"
+#include "sisusb_cursor.h"
+
+extern void SISUSBWaitRetraceCRT1(ScrnInfoPtr pScrn);
+
+static void
+SiSUSBHideCursor(ScrnInfoPtr pScrn)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+
+ pSiSUSB->HWCursorIsVisible = FALSE;
+
+ sisusbDisableHWCursor()
+ sisusbSetCursorPositionY(2000, 0)
+}
+
+static void
+SiSUSBShowCursor(ScrnInfoPtr pScrn)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+
+ if(pSiSUSB->HideHWCursor) {
+ SiSUSBHideCursor(pScrn);
+ pSiSUSB->HWCursorIsVisible = TRUE;
+ return;
+ }
+
+ pSiSUSB->HWCursorIsVisible = TRUE;
+
+ if(pSiSUSB->UseHWARGBCursor) {
+ sisusbEnableHWARGBCursor()
+ } else {
+ sisusbEnableHWCursor()
+ }
+}
+
+static void
+SiSUSBSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ DisplayModePtr mode = pSiSUSB->CurrentLayout.mode;
+ UShort x_preset = 0;
+ UShort y_preset = 0;
+
+ if(x < 0) {
+ x_preset = (-x);
+ x = 0;
+ }
+ if(y < 0) {
+ y_preset = (-y);
+ y = 0;
+ }
+
+ if(mode->Flags & V_INTERLACE) y /= 2;
+ else if(mode->Flags & V_DBLSCAN) y *= 2;
+
+ sisusbSetCursorPositionX(x, x_preset)
+ sisusbSetCursorPositionY(y, y_preset)
+}
+
+
+static void
+SiSUSBSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+
+ if(pSiSUSB->UseHWARGBCursor) return;
+
+ sisusbSetCursorBGColor(bg)
+ sisusbSetCursorFGColor(fg)
+}
+
+static void
+SiSUSBLoadCursorImage(ScrnInfoPtr pScrn, UChar *src)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ ULong cursor_addr;
+ CARD32 status1 = 0;
+ UChar *dest = pSiSUSB->FbBase;
+ int bufnum, i;
+
+ pSiSUSB->HWCursorMBufNum ^= 1;
+ bufnum = 1 << pSiSUSB->HWCursorMBufNum;
+
+ cursor_addr = pScrn->videoRam - pSiSUSB->cursorOffset - ((pSiSUSB->CursorSize/1024) * bufnum);
+
+ if(pSiSUSB->CurrentLayout.mode->Flags & V_DBLSCAN) {
+ UChar *mysrc = (UChar *)pSiSUSB->USBCursorBuf +
+ (pSiSUSB->CursorSize * 4) - (pSiSUSB->CursorSize * bufnum);
+ for(i = 0; i < 32; i++) {
+ memcpy(mysrc + (32 * i) , src + (16 * i), 16);
+ memcpy(mysrc + (32 * i) + 16, src + (16 * i), 16);
+ }
+ SiSUSBMemCopyToVideoRam(pSiSUSB, (UChar *)dest + (cursor_addr * 1024), mysrc, 1024);
+ } else {
+ SiSUSBMemCopyToVideoRam(pSiSUSB, (UChar *)dest + (cursor_addr * 1024), src, 1024);
+ }
+
+ if(pSiSUSB->UseHWARGBCursor) {
+
+ status1 = sisusbGetCursorStatus;
+ sisusbDisableHWCursor()
+
+ SISUSBWaitRetraceCRT1(pScrn);
+ sisusbSwitchToMONOCursor();
+
+ } else {
+
+ SISUSBWaitRetraceCRT1(pScrn);
+
+ }
+
+ sisusbSetCursorAddress(cursor_addr);
+ if(status1) sisusbSetCursorStatus(status1)
+
+ pSiSUSB->UseHWARGBCursor = FALSE;
+}
+
+static Bool
+SiSUSBUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ DisplayModePtr mode = pSiSUSB->CurrentLayout.mode;
+
+ if((mode->Flags & V_DBLSCAN) && (pCurs->bits->height > 32))
+ return FALSE;
+
+ return TRUE;
+}
+
+#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0)
+#ifdef ARGB_CURSOR
+#ifdef SIS_ARGB_CURSOR
+static Bool
+SiSUSBUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ DisplayModePtr mode = pSiSUSB->CurrentLayout.mode;
+
+ if((pCurs->bits->height > 64) || (pCurs->bits->width > 64))
+ return FALSE;
+ if((mode->Flags & V_DBLSCAN) && (pCurs->bits->height > 32))
+ return FALSE;
+
+ return TRUE;
+}
+
+static void SiSUSBLoadCursorImageARGB(ScrnInfoPtr pScrn, CursorPtr pCurs)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ int cursor_addr, i, j, maxheight = 64;
+ CARD32 *src = pCurs->bits->argb, *p, *pb, *dest;
+ int srcwidth = pCurs->bits->width;
+ int srcheight = pCurs->bits->height;
+ CARD32 status1 = 0;
+ Bool sizedouble = FALSE;
+ int bufnum;
+ CARD32 *mysrc;
+
+ if(pSiSUSB->CurrentLayout.mode->Flags & V_DBLSCAN) {
+ sizedouble = TRUE;
+ }
+
+ pSiSUSB->HWCursorCBufNum ^= 1;
+ bufnum = 1 << pSiSUSB->HWCursorCBufNum;
+
+ cursor_addr = pScrn->videoRam - pSiSUSB->cursorOffset - ((pSiSUSB->CursorSize/1024) * (2 + bufnum));
+
+ if(srcwidth > 64) srcwidth = 64;
+ if(srcheight > 64) srcheight = 64;
+
+ dest = mysrc = (CARD32 *)((UChar *)pSiSUSB->USBCursorBuf +
+ (pSiSUSB->CursorSize * 4) - (pSiSUSB->CursorSize * (2 + bufnum)));
+
+ if(sizedouble) {
+ if(srcheight > 32) srcheight = 32;
+ maxheight = 32;
+ }
+
+ for(i = 0; i < srcheight; i++) {
+ p = src;
+ pb = dest;
+ src += pCurs->bits->width;
+ for(j = 0; j < srcwidth; j++) sisfbwritelpinc(dest, p); /* *dest++ = *p++; */
+ if(srcwidth < 64) {
+ for(; j < 64; j++) sisfbwritelinc(dest, 0); /* *dest++ = 0; */
+ }
+ if(sizedouble) {
+ for(j = 0; j < 64; j++) {
+ sisfbwritelinc(dest, sisfbreadlinc(pb)); /* *dest++ = *pb++; */
+ }
+ }
+ }
+ if(srcheight < maxheight) {
+ for(; i < maxheight; i++) {
+ for(j = 0; j < 64; j++) sisfbwritelinc(dest, 0); /* *dest++ = 0; */
+ if(sizedouble) {
+ for(j = 0; j < 64; j++) sisfbwritelinc(dest, 0); /* *dest++ = 0; */
+ }
+ }
+ }
+
+ SiSUSBMemCopyToVideoRam(pSiSUSB, (UChar *)pSiSUSB->FbBase + (cursor_addr * 1024),
+ (UChar *)mysrc, pSiSUSB->CursorSize);
+
+ if(!pSiSUSB->UseHWARGBCursor) {
+ status1 = sisusbGetCursorStatus;
+ sisusbDisableHWCursor()
+ SISUSBWaitRetraceCRT1(pScrn);
+ sisusbSwitchToRGBCursor();
+ }
+
+ sisusbSetCursorAddress(cursor_addr);
+ if(status1) sisusbSetCursorStatus(status1)
+
+ pSiSUSB->UseHWARGBCursor = TRUE;
+}
+#endif
+#endif
+#endif
+
+Bool
+SiSUSBHWCursorInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ xf86CursorInfoPtr infoPtr;
+
+ infoPtr = xf86CreateCursorInfoRec();
+ if(!infoPtr) return FALSE;
+
+ pSiSUSB->CursorInfoPtr = infoPtr;
+ pSiSUSB->UseHWARGBCursor = FALSE;
+
+ infoPtr->MaxWidth = 64;
+ infoPtr->MaxHeight = 64;
+ infoPtr->ShowCursor = SiSUSBShowCursor;
+ infoPtr->HideCursor = SiSUSBHideCursor;
+ infoPtr->SetCursorPosition = SiSUSBSetCursorPosition;
+ infoPtr->SetCursorColors = SiSUSBSetCursorColors;
+ infoPtr->LoadCursorImage = SiSUSBLoadCursorImage;
+ infoPtr->UseHWCursor = SiSUSBUseHWCursor;
+#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0)
+#ifdef ARGB_CURSOR
+#ifdef SIS_ARGB_CURSOR
+ if(pSiSUSB->OptUseColorCursor) {
+ infoPtr->UseHWCursorARGB = SiSUSBUseHWCursorARGB;
+ infoPtr->LoadCursorARGB = SiSUSBLoadCursorImageARGB;
+ }
+#endif
+#endif
+#endif
+ infoPtr->Flags =
+ HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+ HARDWARE_CURSOR_INVERT_MASK |
+ HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
+ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
+ HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 |
+ HARDWARE_CURSOR_UPDATE_UNHIDDEN;
+
+ return(xf86InitCursor(pScreen, infoPtr));
+}
diff --git a/driver/xf86-video-sisusb/src/sisusb_cursor.h b/driver/xf86-video-sisusb/src/sisusb_cursor.h
new file mode 100644
index 000000000..a2938dba1
--- /dev/null
+++ b/driver/xf86-video-sisusb/src/sisusb_cursor.h
@@ -0,0 +1,113 @@
+/* $XFree86$ */
+/* $XdotOrg: driver/xf86-video-sisusb/src/sisusb_cursor.h,v 1.3 2005/07/09 02:50:34 twini Exp $ */
+/*
+ * SiSUSB hardware cursor handling definitions
+ *
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1) Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2) Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3) The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
+
+#define CS(x) (0x8500 + (x << 2))
+
+/* 315/330 series CRT1 */
+
+/* 80000000 = RGB(1) - MONO(0)
+ * 40000000 = enable(1) - disable(0)
+ * 20000000 = 32(1) / 16(1) bit RGB
+ * 10000000 = "ghost"(1) - Alpha Blend(0)
+ */
+
+#define sisusbGetCursorStatus \
+ SIS_MMIO_IN32(pSiSUSB, pSiSUSB->IOBase, CS(0)) & 0x40000000;
+
+#define sisusbSetCursorStatus(status) \
+ pSiSUSB->HWCursorBackup[0] &= 0xbfffffff; \
+ pSiSUSB->HWCursorBackup[0] |= status; \
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, CS(0), pSiSUSB->HWCursorBackup[0]); \
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, CS(3), pSiSUSB->HWCursorBackup[3]); \
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, CS(4), pSiSUSB->HWCursorBackup[4]);
+
+#define sisusbEnableHWCursor()\
+ pSiSUSB->HWCursorBackup[0] &= 0x0fffffff; \
+ pSiSUSB->HWCursorBackup[0] |= 0x40000000; \
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, CS(0), pSiSUSB->HWCursorBackup[0]); \
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, CS(3), pSiSUSB->HWCursorBackup[3]); \
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, CS(4), pSiSUSB->HWCursorBackup[4]);
+
+#define sisusbEnableHWARGBCursor()\
+ pSiSUSB->HWCursorBackup[0] &= 0x0FFFFFFF; \
+ pSiSUSB->HWCursorBackup[0] |= 0xE0000000; \
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, CS(0), pSiSUSB->HWCursorBackup[0]); \
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, CS(3), pSiSUSB->HWCursorBackup[3]); \
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, CS(4), pSiSUSB->HWCursorBackup[4]);
+
+#define sisusbSwitchToMONOCursor() \
+ pSiSUSB->HWCursorBackup[0] &= 0x4fffffff; \
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, CS(0), pSiSUSB->HWCursorBackup[0]); \
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, CS(3), pSiSUSB->HWCursorBackup[3]); \
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, CS(4), pSiSUSB->HWCursorBackup[4]);
+
+#define sisusbSwitchToRGBCursor() \
+ pSiSUSB->HWCursorBackup[0] &= 0xBFFFFFFF; \
+ pSiSUSB->HWCursorBackup[0] |= 0xA0000000; \
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, CS(0), pSiSUSB->HWCursorBackup[0]); \
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, CS(3), pSiSUSB->HWCursorBackup[3]); \
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, CS(4), pSiSUSB->HWCursorBackup[4]);
+
+#define sisusbDisableHWCursor()\
+ pSiSUSB->HWCursorBackup[0] &= 0xBFFFFFFF; \
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, CS(0), pSiSUSB->HWCursorBackup[0]); \
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, CS(3), pSiSUSB->HWCursorBackup[3]); \
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, CS(4), pSiSUSB->HWCursorBackup[4]);
+
+#define sisusbSetCursorBGColor(color) \
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, CS(1), (color)); \
+ pSiSUSB->HWCursorBackup[1] = color;
+
+#define sisusbSetCursorFGColor(color)\
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, CS(2), (color)); \
+ pSiSUSB->HWCursorBackup[2] = color;
+
+#define sisusbSetCursorPositionX(x,preset) \
+ pSiSUSB->HWCursorBackup[3] = ((x) | ((preset) << 16)); \
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, CS(3), pSiSUSB->HWCursorBackup[3]);
+
+#define sisusbSetCursorPositionY(y,preset) \
+ pSiSUSB->HWCursorBackup[4] = ((y) | ((preset) << 16)); \
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, CS(4), pSiSUSB->HWCursorBackup[4]);
+
+#define sisusbSetCursorAddress(address)\
+ pSiSUSB->HWCursorBackup[0] &= 0xF0F00000; \
+ pSiSUSB->HWCursorBackup[0] |= address; \
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, CS(0), pSiSUSB->HWCursorBackup[0]); \
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, CS(1), pSiSUSB->HWCursorBackup[1]); \
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, CS(2), pSiSUSB->HWCursorBackup[2]); \
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, CS(3), pSiSUSB->HWCursorBackup[3]); \
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, CS(4), pSiSUSB->HWCursorBackup[4]);
+
+
+
diff --git a/driver/xf86-video-sisusb/src/sisusb_dac.c b/driver/xf86-video-sisusb/src/sisusb_dac.c
new file mode 100644
index 000000000..3cbda84ec
--- /dev/null
+++ b/driver/xf86-video-sisusb/src/sisusb_dac.c
@@ -0,0 +1,1067 @@
+/* $XFree86$ */
+/* $XdotOrg: driver/xf86-video-sisusb/src/sisusb_dac.c,v 1.6 2005/08/15 22:57:51 twini Exp $ */
+/*
+ * DAC helper functions (Save/Restore, MemClk, etc)
+ *
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1) Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2) Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3) The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ * --------------------------------------------------------------------------
+ *
+ * SiS_compute_vclk(), SiSCalcClock() and parts of SiSMclk():
+ *
+ * Copyright (C) 1998, 1999 by Alan Hourihane, Wigan, England
+ * Written by:
+ * Alan Hourihane <alanh@fairlite.demon.co.uk>,
+ * Mike Chapman <mike@paranoia.com>,
+ * Juanjo Santamarta <santamarta@ctv.es>,
+ * Mitani Hiroshi <hmitani@drl.mei.co.jp>,
+ * David Thomas <davtom@dream.org.uk>,
+ * Thomas Winischhofer <thomas@winischhofer.net>.
+ *
+ * Licensed under the following terms:
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appears in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * and that the name of the copyright holder not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holder makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without expressed or implied warranty.
+ *
+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "sisusb.h"
+#define NEED_cpu_to_le16
+#define NEED_cpu_to_le32
+#include "sisusb_regs.h"
+#include "sisusb_dac.h"
+
+#include "dixstruct.h"
+
+#ifdef XFreeXDGA
+#include "dgaproc.h"
+#endif
+
+static void SiSUSBSave(ScrnInfoPtr pScrn, SISUSBRegPtr sisReg);
+static void SiSUSBRestore(ScrnInfoPtr pScrn, SISUSBRegPtr sisReg);
+
+UChar SiSUSBGetCopyROP(int rop);
+UChar SiSUSBGetPatternROP(int rop);
+
+int SiSUSB_compute_vclk(
+ int Clock,
+ int *out_n,
+ int *out_dn,
+ int *out_div,
+ int *out_sbit,
+ int *out_scale)
+{
+ float f,x,y,t, error, min_error;
+ int n, dn, best_n=0, best_dn=0;
+
+ /*
+ * Rules
+ *
+ * VCLK = 14.318 * (Divider/Post Scalar) * (Numerator/DeNumerator)
+ * Factor = (Divider/Post Scalar)
+ * Divider is 1 or 2
+ * Post Scalar is 1, 2, 3, 4, 6 or 8
+ * Numberator ranged from 1 to 128
+ * DeNumerator ranged from 1 to 32
+ * a. VCO = VCLK/Factor, suggest range is 150 to 250 Mhz
+ * b. Post Scalar selected from 1, 2, 4 or 8 first.
+ * c. DeNumerator selected from 2.
+ *
+ * According to rule a and b, the VCO ranges that can be scaled by
+ * rule b are:
+ * 150 - 250 (Factor = 1)
+ * 75 - 125 (Factor = 2)
+ * 37.5 - 62.5 (Factor = 4)
+ * 18.75 - 31.25 (Factor = 8)
+ *
+ * The following ranges use Post Scalar 3 or 6:
+ * 125 - 150 (Factor = 1.5)
+ * 62.5 - 75 (Factor = 3)
+ * 31.25 - 37.5 (Factor = 6)
+ *
+ * Steps:
+ * 1. divide the Clock by 2 until the Clock is less or equal to 31.25.
+ * 2. if the divided Clock is range from 18.25 to 31.25, than
+ * the Factor is 1, 2, 4 or 8.
+ * 3. if the divided Clock is range from 15.625 to 18.25, than
+ * the Factor is 1.5, 3 or 6.
+ * 4. select the Numberator and DeNumberator with minimum deviation.
+ *
+ * ** this function can select VCLK ranged from 18.75 to 250 Mhz
+ */
+
+ f = (float) Clock;
+ f /= 1000.0;
+ if((f > 250.0) || (f < 18.75))
+ return 0;
+
+ min_error = f;
+ y = 1.0;
+ x = f;
+ while(x > 31.25) {
+ y *= 2.0;
+ x /= 2.0;
+ }
+ if(x >= 18.25) {
+ x *= 8.0;
+ y = 8.0 / y;
+ } else if(x >= 15.625) {
+ x *= 12.0;
+ y = 12.0 / y;
+ }
+
+ t = y;
+ if(t == (float) 1.5) {
+ *out_div = 2;
+ t *= 2.0;
+ } else {
+ *out_div = 1;
+ }
+ if(t > (float) 4.0) {
+ *out_sbit = 1;
+ t /= 2.0;
+ } else {
+ *out_sbit = 0;
+ }
+
+ *out_scale = (int) t;
+
+ for(dn = 2; dn <= 32; dn++) {
+ for(n = 1; n <= 128; n++) {
+ error = x;
+ error -= ((float) 14.318 * (float) n / (float) dn);
+ if(error < (float) 0)
+ error = -error;
+ if(error < min_error) {
+ min_error = error;
+ best_n = n;
+ best_dn = dn;
+ }
+ }
+ }
+ *out_n = best_n;
+ *out_dn = best_dn;
+
+ return 1;
+}
+
+void
+SiSUSBCalcClock(ScrnInfoPtr pScrn, int clock, int max_VLD, unsigned int *vclk)
+{
+ int M, N, P , PSN, VLD , PSNx ;
+ int bestM=0, bestN=0, bestP=0, bestPSN=0, bestVLD=0;
+ double abest = 42.0;
+ double target;
+ double Fvco, Fout;
+ double error, aerror;
+
+ /*
+ * fd = fref*(Numerator/Denumerator)*(Divider/PostScaler)
+ *
+ * M = Numerator [1:128]
+ * N = DeNumerator [1:32]
+ * VLD = Divider (Vco Loop Divider) : divide by 1, 2
+ * P = Post Scaler : divide by 1, 2, 3, 4
+ * PSN = Pre Scaler (Reference Divisor Select)
+ *
+ * result in vclk[]
+ */
+#define Midx 0
+#define Nidx 1
+#define VLDidx 2
+#define Pidx 3
+#define PSNidx 4
+#define Fref 14318180
+/* stability constraints for internal VCO -- MAX_VCO also determines
+ * the maximum Video pixel clock */
+#define MIN_VCO Fref
+#define MAX_VCO 135000000
+#define MAX_VCO_5597 353000000
+#define MAX_PSN 0 /* no pre scaler for this chip */
+#define TOLERANCE 0.01 /* search smallest M and N in this tolerance */
+
+ int M_min = 2;
+ int M_max = 128;
+
+ target = clock * 1000;
+
+ for(PSNx = 0; PSNx <= MAX_PSN ; PSNx++) {
+
+ int low_N, high_N;
+ double FrefVLDPSN;
+
+ PSN = !PSNx ? 1 : 4;
+
+ low_N = 2;
+ high_N = 32;
+
+ for(VLD = 1 ; VLD <= max_VLD ; VLD++) {
+
+ FrefVLDPSN = (double)Fref * VLD / PSN;
+
+ for(N = low_N; N <= high_N; N++) {
+ double tmp = FrefVLDPSN / N;
+
+ for(P = 1; P <= 4; P++) {
+ double Fvco_desired = target * ( P );
+ double M_desired = Fvco_desired / tmp;
+
+ /* Which way will M_desired be rounded?
+ * Do all three just to be safe.
+ */
+ int M_low = M_desired - 1;
+ int M_hi = M_desired + 1;
+
+ if(M_hi < M_min || M_low > M_max) continue;
+
+ if(M_low < M_min) M_low = M_min;
+
+ if(M_hi > M_max) M_hi = M_max;
+
+ for(M = M_low; M <= M_hi; M++) {
+ Fvco = tmp * M;
+ if(Fvco <= MIN_VCO) continue;
+ if(Fvco > MAX_VCO) break;
+
+ Fout = Fvco / ( P );
+
+ error = (target - Fout) / target;
+ aerror = (error < 0) ? -error : error;
+ if(aerror < abest) {
+ abest = aerror;
+ bestM = M;
+ bestN = N;
+ bestP = P;
+ bestPSN = PSN;
+ bestVLD = VLD;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ vclk[Midx] = bestM;
+ vclk[Nidx] = bestN;
+ vclk[VLDidx] = bestVLD;
+ vclk[Pidx] = bestP;
+ vclk[PSNidx] = bestPSN;
+}
+
+/* Save register contents */
+static void
+SiSUSBSave(ScrnInfoPtr pScrn, SISUSBRegPtr sisReg)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ int i;
+
+#ifdef UNLOCK_ALWAYS
+ sisusbSaveUnlockExtRegisterLock(pSiSUSB, NULL, NULL);
+#endif
+
+ /* Save SR registers */
+ for(i = 0x00; i <= 0x3F; i++) {
+ inSISIDXREG(pSiSUSB, SISSR, i, sisReg->sisRegs3C4[i]);
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "SR%02X - %02X \n", i,sisReg->sisRegs3C4[i]);
+#endif
+ }
+
+ /* Save command queue location */
+ sisReg->sisMMIO85C0 = SIS_MMIO_IN32(pSiSUSB, pSiSUSB->IOBase, 0x85C0);
+
+ /* Save CR registers */
+ for(i = 0x00; i <= 0x7c; i++) {
+ inSISIDXREG(pSiSUSB, SISCR, i, sisReg->sisRegs3D4[i]);
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "CR%02X Contents - %02X \n", i,sisReg->sisRegs3D4[i]);
+#endif
+ }
+
+ /* Save video capture registers */
+ for(i = 0x00; i <= 0x4f; i++) {
+ inSISIDXREG(pSiSUSB, SISCAP, i, sisReg->sisCapt[i]);
+ }
+
+ /* Save video playback registers */
+ for(i = 0x00; i <= 0x3f; i++) {
+ inSISIDXREG(pSiSUSB, SISVID, i, sisReg->sisVid[i]);
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Vid%02X Contents - %02X \n", i,sisReg->sisVid[i]);
+#endif
+ }
+
+ /* Save Misc register */
+ sisReg->sisRegs3C2 = inSISREG(pSiSUSB, SISMISCR);
+
+ /* Save mode number */
+ sisReg->BIOSModeSave = SiSUSB_GetSetModeID(pScrn,0xFF);
+}
+
+/* Restore register contents */
+static void
+SiSUSBRestore(ScrnInfoPtr pScrn, SISUSBRegPtr sisReg)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ int i,temp;
+
+#ifdef UNLOCK_ALWAYS
+ sisusbSaveUnlockExtRegisterLock(pSiSUSB, NULL, NULL);
+#endif
+
+ /* Wait for accelerator to finish on-going drawing operations. */
+ inSISIDXREG(pSiSUSB, SISSR, 0x1E, temp);
+ if(temp & (0x40|0x10|0x02)) { /* 0x40 = 2D, 0x10 = 3D enabled*/
+ while ( (SIS_MMIO_IN32(pSiSUSB, pSiSUSB->IOBase, 0x85CC) & 0x80000000) != 0x80000000){};
+ while ( (SIS_MMIO_IN32(pSiSUSB, pSiSUSB->IOBase, 0x85CC) & 0x80000000) != 0x80000000){};
+ while ( (SIS_MMIO_IN32(pSiSUSB, pSiSUSB->IOBase, 0x85CC) & 0x80000000) != 0x80000000){};
+ }
+
+ /* We reset the command queue before restoring.
+ * This might be required because we never know what
+ * console driver (like the kernel framebuffer driver)
+ * or application is running and which queue mode it
+ * uses.
+ */
+ andSISIDXREG(pSiSUSB, SISCR, 0x55, 0x33);
+ outSISIDXREG(pSiSUSB, SISSR, 0x26, 0x01);
+ outSISIDXREG(pSiSUSB, SISSR, 0x27, 0x1F);
+
+ /* Restore extended CR registers */
+ for(i = 0x19; i < 0x5C; i++) {
+ outSISIDXREG(pSiSUSB, SISCR, i, sisReg->sisRegs3D4[i]);
+ }
+ outSISIDXREG(pSiSUSB, SISCR, 0x79, sisReg->sisRegs3D4[0x79]);
+
+ outSISIDXREG(pSiSUSB, SISCR, pSiSUSB->myCR63, sisReg->sisRegs3D4[pSiSUSB->myCR63]);
+
+ /* Leave PCI_IO_ENABLE on if accelerators are on (Is this required?) */
+ if(sisReg->sisRegs3C4[0x1e] & 0x50) { /* 0x40=2D, 0x10=3D */
+ sisReg->sisRegs3C4[0x20] |= 0x20;
+ outSISIDXREG(pSiSUSB, SISSR, 0x20, sisReg->sisRegs3C4[0x20]);
+ }
+
+ /* Restore extended SR registers */
+ for(i = 0x06; i <= 0x3F; i++) {
+ if(i == 0x26) {
+ continue;
+ } else if(i == 0x27) {
+ outSISIDXREG(pSiSUSB, SISSR, 0x27, sisReg->sisRegs3C4[0x27]);
+ outSISIDXREG(pSiSUSB, SISSR, 0x26, sisReg->sisRegs3C4[0x26]);
+ } else {
+ outSISIDXREG(pSiSUSB, SISSR, i, sisReg->sisRegs3C4[i]);
+ }
+ }
+
+ /* Restore VCLK and ECLK */
+ andSISIDXREG(pSiSUSB, SISSR,0x31,0xcf);
+ outSISIDXREG(pSiSUSB, SISSR,0x2b,sisReg->sisRegs3C4[0x2b]);
+ outSISIDXREG(pSiSUSB, SISSR,0x2c,sisReg->sisRegs3C4[0x2c]);
+ outSISIDXREG(pSiSUSB, SISSR,0x2d,0x01);
+
+#ifndef SISVRAMQ
+ /* Initialize read/write pointer for command queue */
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, 0x85C4, SIS_MMIO_IN32(pSiSUSB, pSiSUSB->IOBase, 0x85C8));
+#endif
+ /* Restore queue location */
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, 0x85C0, sisReg->sisMMIO85C0);
+
+ /* Restore Misc register */
+ outSISREG(pSiSUSB, SISMISCW, sisReg->sisRegs3C2);
+
+ /* MemClock needs this to take effect */
+ outSISIDXREG(pSiSUSB, SISSR, 0x00, 0x01); /* Synchronous Reset */
+ outSISIDXREG(pSiSUSB, SISSR, 0x00, 0x03); /* End Reset */
+
+ /* Restore Mode number */
+ SiSUSB_GetSetModeID(pScrn,sisReg->BIOSModeSave);
+}
+
+/* Restore output selection registers */
+void
+SiSUSBRestoreBridge(ScrnInfoPtr pScrn, SISUSBRegPtr sisReg)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ int i;
+
+#ifdef UNLOCK_ALWAYS
+ sisusbSaveUnlockExtRegisterLock(pSiSUSB, NULL, NULL);
+#endif
+
+ for(i = 0x30; i <= 0x3b; i++) {
+ if(i == 0x34) continue;
+ outSISIDXREG(pSiSUSB, SISCR, i, sisReg->sisRegs3D4[i]);
+ }
+
+ outSISIDXREG(pSiSUSB, SISCR, pSiSUSB->myCR63, sisReg->sisRegs3D4[pSiSUSB->myCR63]);
+ outSISIDXREG(pSiSUSB, SISCR, 0x79, sisReg->sisRegs3D4[0x79]);
+}
+
+/* Auxiliary function to find real memory clock (in Khz) */
+int
+SiSUSBMclk(SISUSBPtr pSiSUSB)
+{
+ int mclk = 0;
+ UChar Num, Denum;
+
+ /* Numerator */
+ inSISIDXREG(pSiSUSB, SISSR, 0x28, Num);
+ mclk = 14318 * ((Num & 0x7f) + 1);
+
+ /* Denumerator */
+ inSISIDXREG(pSiSUSB, SISSR, 0x29, Denum);
+ mclk = mclk / ((Denum & 0x1f) + 1);
+
+ /* Divider */
+ if((Num & 0x80) != 0) mclk *= 2;
+
+ /* Post-Scaler */
+ if((Denum & 0x80) == 0) {
+ mclk = mclk / (((Denum & 0x60) >> 5) + 1);
+ } else {
+ mclk = mclk / ((((Denum & 0x60) >> 5) + 1) * 2);
+ }
+
+ return(mclk);
+}
+
+/* Calculate the maximum dotclock */
+int SiSUSBMemBandWidth(ScrnInfoPtr pScrn, Bool IsForCRT2)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+
+ int bus = pSiSUSB->BusWidth;
+ int mclk = pSiSUSB->MemClock;
+ int bpp = pSiSUSB->CurrentLayout.bitsPerPixel;
+ int max = 0;
+ float magic = 0.0, total;
+#ifdef __SUNPRO_C
+#define const
+#endif
+ const float magicDED[4] = { 1.2, 1.368421, 2.263158, 1.2};
+#ifdef __SUNPRO_C
+#undef const
+#endif
+
+ magic = magicDED[bus/64];
+ max = 780000;
+
+ total = mclk * bus / bpp;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Memory bandwidth at %d bpp is %g MHz\n", bpp, total/1000);
+
+ total /= magic;
+ if(total > (max / 2)) total = max / 2;
+
+ return(int)(total);
+}
+
+/* Load the palette. We do this for all supported color depths
+ * in order to support gamma correction. We hereby convert the
+ * given colormap to a complete 24bit color palette and enable
+ * the correspoding bit in SR7 to enable the 24bit lookup table.
+ * Gamma correction for CRT2 is only supported on SiS video bridges.
+ * There are there 6-bit-RGB values submitted even if bpp is 16 and
+ * weight is 565, because SetWeight() sets rgbBits to the maximum
+ * (which is 6 in the 565 case).
+ */
+void
+SISUSBLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
+ VisualPtr pVisual)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ int i, j, index;
+ int myshift = 8 - pScrn->rgbBits;
+ UChar backup = 0;
+ Bool dogamma1 = pSiSUSB->CRT1gamma;
+ Bool resetxvgamma = FALSE;
+
+ inSISIDXREG(pSiSUSB, SISSR, 0x1f, backup);
+ andSISIDXREG(pSiSUSB, SISSR, 0x1f, 0xe7);
+ if( (pSiSUSB->XvGamma) &&
+ (pSiSUSB->MiscFlags & MISC_CRT1OVERLAYGAMMA) &&
+ ((pSiSUSB->CurrentLayout.depth == 16) ||
+ (pSiSUSB->CurrentLayout.depth == 24)) ) {
+ orSISIDXREG(pSiSUSB, SISSR, 0x1f, 0x10);
+ resetxvgamma = TRUE;
+ }
+
+ switch(pSiSUSB->CurrentLayout.depth) {
+ case 16:
+ if(dogamma1) {
+ orSISIDXREG(pSiSUSB, SISSR, 0x07, 0x04);
+ for(i=0; i<numColors; i++) {
+ index = indices[i];
+ if(index < 64) { /* Paranoia */
+ for(j=0; j<4; j++) {
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, 0x8570,
+ (colors[index].green << (myshift + 8)) |
+ (colors[index >> 1].blue << (myshift + 16)) |
+ (colors[index >> 1].red << myshift) |
+ (((index << 2) + j) << 24));
+ }
+ }
+ }
+ } else {
+ andSISIDXREG(pSiSUSB, SISSR, 0x07, ~0x04);
+ }
+ break;
+ case 24:
+ if(dogamma1) {
+ orSISIDXREG(pSiSUSB, SISSR, 0x07, 0x04);
+ for(i=0; i<numColors; i++) {
+ index = indices[i];
+ if(index < 256) { /* Paranoia */
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, 0x8570,
+ (colors[index].blue << 16) |
+ (colors[index].green << 8) |
+ (colors[index].red) |
+ (index << 24));
+ }
+ }
+ } else {
+ andSISIDXREG(pSiSUSB, SISSR, 0x07, ~0x04);
+ }
+ break;
+ default:
+ andSISIDXREG(pSiSUSB, SISSR, 0x07, ~0x04);
+ for(i=0; i<numColors; i++) {
+ index = indices[i];
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, 0x8570,
+ ((colors[index].blue) << 16) |
+ ((colors[index].green) << 8) |
+ (colors[index].red) |
+ (index << 24));
+ }
+ }
+
+ outSISIDXREG(pSiSUSB, SISSR, 0x1f, backup);
+ inSISIDXREG(pSiSUSB, SISSR, 0x07, backup);
+ if((backup & 0x04) && (resetxvgamma) && (pSiSUSB->ResetXvGamma)) {
+ (pSiSUSB->ResetXvGamma)(pScrn);
+ }
+
+}
+
+void
+SISUSBDACPreInit(ScrnInfoPtr pScrn)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+
+ pSiSUSB->MaxClock = SiSUSBMemBandWidth(pScrn, FALSE);
+
+ pSiSUSB->SiSSave = SiSUSBSave;
+ pSiSUSB->SiSRestore = SiSUSBRestore;
+}
+
+UChar SiSUSBGetCopyROP(int rop)
+{
+ const UChar sisALUConv[] =
+ {
+ 0x00, /* dest = 0; 0, GXclear, 0 */
+ 0x88, /* dest &= src; DSa, GXand, 0x1 */
+ 0x44, /* dest = src & ~dest; SDna, GXandReverse, 0x2 */
+ 0xCC, /* dest = src; S, GXcopy, 0x3 */
+ 0x22, /* dest &= ~src; DSna, GXandInverted, 0x4 */
+ 0xAA, /* dest = dest; D, GXnoop, 0x5 */
+ 0x66, /* dest = ^src; DSx, GXxor, 0x6 */
+ 0xEE, /* dest |= src; DSo, GXor, 0x7 */
+ 0x11, /* dest = ~src & ~dest; DSon, GXnor, 0x8 */
+ 0x99, /* dest ^= ~src ; DSxn, GXequiv, 0x9 */
+ 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */
+ 0xDD, /* dest = src|~dest ; SDno, GXorReverse, 0xB */
+ 0x33, /* dest = ~src; Sn, GXcopyInverted, 0xC */
+ 0xBB, /* dest |= ~src; DSno, GXorInverted, 0xD */
+ 0x77, /* dest = ~src|~dest; DSan, GXnand, 0xE */
+ 0xFF, /* dest = 0xFF; 1, GXset, 0xF */
+ };
+
+ return(sisALUConv[rop]);
+}
+
+UChar SiSUSBGetPatternROP(int rop)
+{
+ const UChar sisPatALUConv[] =
+ {
+ 0x00, /* dest = 0; 0, GXclear, 0 */
+ 0xA0, /* dest &= src; DPa, GXand, 0x1 */
+ 0x50, /* dest = src & ~dest; PDna, GXandReverse, 0x2 */
+ 0xF0, /* dest = src; P, GXcopy, 0x3 */
+ 0x0A, /* dest &= ~src; DPna, GXandInverted, 0x4 */
+ 0xAA, /* dest = dest; D, GXnoop, 0x5 */
+ 0x5A, /* dest = ^src; DPx, GXxor, 0x6 */
+ 0xFA, /* dest |= src; DPo, GXor, 0x7 */
+ 0x05, /* dest = ~src & ~dest; DPon, GXnor, 0x8 */
+ 0xA5, /* dest ^= ~src ; DPxn, GXequiv, 0x9 */
+ 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */
+ 0xF5, /* dest = src|~dest ; PDno, GXorReverse, 0xB */
+ 0x0F, /* dest = ~src; Pn, GXcopyInverted, 0xC */
+ 0xAF, /* dest |= ~src; DPno, GXorInverted, 0xD */
+ 0x5F, /* dest = ~src|~dest; DPan, GXnand, 0xE */
+ 0xFF, /* dest = 0xFF; 1, GXset, 0xF */
+ };
+
+ return(sisPatALUConv[rop]);
+}
+
+static void SiSLostConnection(SISUSBPtr pSiSUSB)
+{
+ pSiSUSB->sisusberrorsleepcount = 0;
+ pSiSUSB->sisusbfatalerror = 1;
+ UpdateCurrentTime();
+ pSiSUSB->errorTime = currentTime.milliseconds;
+ close(pSiSUSB->sisusbdev);
+ pSiSUSB->sisusbdevopen = FALSE;
+ xf86DrvMsg(pSiSUSB->pScrn->scrnIndex, X_ERROR,
+ "Lost connection to USB device\n");
+ if(pSiSUSB->timeout == -1) {
+#ifdef XFreeXDGA
+ /* DGAShutdown(); - not resolved, not in symlists - ARGH... */
+#endif
+ GiveUp(0);
+ }
+}
+
+void
+SiSUSBMemCopyToVideoRam(SISUSBPtr pSiSUSB, UChar *to, UChar *from, int size)
+{
+ int num, retry = 3;
+ if(pSiSUSB->sisusbfatalerror) return;
+ do {
+ lseek(pSiSUSB->sisusbdev, (int)to, SEEK_SET);
+ num = write(pSiSUSB->sisusbdev, from, size);
+ } while((num != size) && --retry);
+ if(!retry) SiSLostConnection(pSiSUSB);
+}
+
+UChar inSISREG(SISUSBPtr pSiSUSB, ULong base)
+{
+ UChar tmp;
+ int num, retry = 3;
+ if(pSiSUSB->sisusbfatalerror) return 0;
+ do {
+ lseek(pSiSUSB->sisusbdev, base, SEEK_SET);
+ num = read(pSiSUSB->sisusbdev, &tmp, 1);
+ } while((num != 1) && --retry);
+ if(!retry) SiSLostConnection(pSiSUSB);
+ return tmp;
+}
+
+UShort inSISREGW(SISUSBPtr pSiSUSB, ULong base)
+{
+ UShort tmp;
+ int num, retry = 3;
+ if(pSiSUSB->sisusbfatalerror) return 0;
+ do {
+ lseek(pSiSUSB->sisusbdev, base, SEEK_SET);
+ num = read(pSiSUSB->sisusbdev, &tmp, 2);
+ } while((num != 2) && --retry);
+ if(!retry) SiSLostConnection(pSiSUSB);
+ return tmp;
+}
+
+ULong inSISREGL(SISUSBPtr pSiSUSB, ULong base)
+{
+ ULong tmp;
+ int num, retry = 3;
+ if(pSiSUSB->sisusbfatalerror) return 0;
+ do {
+ lseek(pSiSUSB->sisusbdev, base, SEEK_SET);
+ num = read(pSiSUSB->sisusbdev, &tmp, 4);
+ } while((num != 4) && --retry);
+ if(!retry) SiSLostConnection(pSiSUSB);
+ return tmp;
+}
+
+void outSISREG(SISUSBPtr pSiSUSB, ULong base, UChar val)
+{
+ int num, retry = 3;
+ if(pSiSUSB->sisusbfatalerror) return;
+ do {
+ lseek(pSiSUSB->sisusbdev, base, SEEK_SET);
+ num = write(pSiSUSB->sisusbdev, &val, 1);
+ } while((num != 1) && --retry);
+ if(!retry) SiSLostConnection(pSiSUSB);
+}
+
+void outSISREGW(SISUSBPtr pSiSUSB, ULong base, UShort val)
+{
+ int num, retry = 3;
+ if(pSiSUSB->sisusbfatalerror) return;
+ do {
+ lseek(pSiSUSB->sisusbdev, base, SEEK_SET);
+ num = write(pSiSUSB->sisusbdev, &val, 2);
+ } while((num != 2) && --retry);
+ if(!retry) SiSLostConnection(pSiSUSB);
+}
+
+void outSISREGL(SISUSBPtr pSiSUSB, ULong base, unsigned int val)
+{
+ int num, retry = 3;
+ if(pSiSUSB->sisusbfatalerror) return;
+ do {
+ lseek(pSiSUSB->sisusbdev, base, SEEK_SET);
+ num = write(pSiSUSB->sisusbdev, &val, 4);
+ } while((num != 4) && --retry);
+ if(!retry) SiSLostConnection(pSiSUSB);
+}
+
+void orSISREG(SISUSBPtr pSiSUSB, ULong base, UChar val)
+{
+ UChar tmp;
+ int num, retry = 3;
+ if(pSiSUSB->sisusbfatalerror) return;
+ do {
+ lseek(pSiSUSB->sisusbdev, base, SEEK_SET);
+ read(pSiSUSB->sisusbdev, &tmp, 1);
+ tmp |= val;
+ lseek(pSiSUSB->sisusbdev, base, SEEK_SET);
+ num = write(pSiSUSB->sisusbdev, &tmp, 1);
+ } while((num != 1) && --retry);
+ if(!retry) SiSLostConnection(pSiSUSB);
+}
+
+void andSISREG(SISUSBPtr pSiSUSB, ULong base, UChar val)
+{
+ UChar tmp;
+ int num, retry = 3;
+ if(pSiSUSB->sisusbfatalerror) return;
+ do {
+ lseek(pSiSUSB->sisusbdev, base, SEEK_SET);
+ read(pSiSUSB->sisusbdev, &tmp, 1);
+ tmp &= val;
+ lseek(pSiSUSB->sisusbdev, base, SEEK_SET);
+ num = write(pSiSUSB->sisusbdev, &tmp, 1);
+ } while((num != 1) && --retry);
+ if(!retry) SiSLostConnection(pSiSUSB);
+}
+
+void outSISIDXREG(SISUSBPtr pSiSUSB, ULong base, UChar idx, UChar val)
+{
+ int num, retry = 3;
+#ifdef SIS_USEIOCTL
+ sisusb_command x;
+ if(pSiSUSB->sisusbfatalerror) return;
+ do {
+ x.operation = SUCMD_SET;
+ x.data3 = base;
+ x.data0 = idx;
+ x.data1 = val;
+ num = ioctl(pSiSUSB->sisusbdev, SISUSB_COMMAND, &x);
+ } while((num) && --retry);
+#else
+ UShort value = (val << 8) | idx; /* sic! reads/writes wordwise! */
+ if(pSiSUSB->sisusbfatalerror) return;
+ do {
+ lseek(pSiSUSB->sisusbdev, base, SEEK_SET);
+ num = write(pSiSUSB->sisusbdev, &value, 2);
+ } while((num != 2) && --retry);
+#endif
+ if(!retry) SiSLostConnection(pSiSUSB);
+}
+
+UChar __inSISIDXREG(SISUSBPtr pSiSUSB, ULong base, UChar idx)
+{
+ int num, retry = 3;
+#ifdef SIS_USEIOCTL
+ sisusb_command x;
+ if(pSiSUSB->sisusbfatalerror) return 0;
+ do {
+ x.operation = SUCMD_GET;
+ x.data3 = base;
+ x.data0 = idx;
+ num = ioctl(pSiSUSB->sisusbdev, SISUSB_COMMAND, &x);
+ } while((num) && --retry);
+ if(!retry) SiSLostConnection(pSiSUSB);
+ return x.data1;
+#else
+ UChar tmp;
+ if(pSiSUSB->sisusbfatalerror) return 0;
+ do {
+ lseek(pSiSUSB->sisusbdev, base, SEEK_SET);
+ write(pSiSUSB->sisusbdev, &idx, 1);
+ num = read(pSiSUSB->sisusbdev, &tmp, 1);
+ } while((num != 1) && --retry);
+ if(!retry) SiSLostConnection(pSiSUSB);
+ return tmp;
+#endif
+}
+
+void orSISIDXREG(SISUSBPtr pSiSUSB, ULong base, UChar idx, UChar val)
+{
+ int num, retry = 3;
+#ifdef SIS_USEIOCTL
+ sisusb_command x;
+ if(pSiSUSB->sisusbfatalerror) return;
+ do {
+ x.operation = SUCMD_SETOR;
+ x.data3 = base;
+ x.data0 = idx;
+ x.data1 = val;
+ num = ioctl(pSiSUSB->sisusbdev, SISUSB_COMMAND, &x);
+ } while((num) && --retry);
+#else
+ UChar tmp;
+ if(pSiSUSB->sisusbfatalerror) return;
+ do {
+ lseek(pSiSUSB->sisusbdev, base, SEEK_SET);
+ write(pSiSUSB->sisusbdev, &idx, 1);
+ read(pSiSUSB->sisusbdev, &tmp, 1);
+ tmp |= val;
+ lseek(pSiSUSB->sisusbdev, base + 1, SEEK_SET);
+ num = write(pSiSUSB->sisusbdev, &tmp, 1);
+ } while((num != 1) && --retry);
+#endif
+ if(!retry) SiSLostConnection(pSiSUSB);
+}
+
+void andSISIDXREG(SISUSBPtr pSiSUSB, ULong base, UChar idx, UChar val)
+{
+ int num, retry = 3;
+#ifdef SIS_USEIOCTL
+ sisusb_command x;
+ if(pSiSUSB->sisusbfatalerror) return;
+ do {
+ x.operation = SUCMD_SETAND;
+ x.data3 = base;
+ x.data0 = idx;
+ x.data1 = val;
+ num = ioctl(pSiSUSB->sisusbdev, SISUSB_COMMAND, &x);
+ } while((num) && --retry);
+#else
+ UChar tmp;
+ if(pSiSUSB->sisusbfatalerror) return;
+ do {
+ lseek(pSiSUSB->sisusbdev, base, SEEK_SET);
+ write(pSiSUSB->sisusbdev, &idx, 1);
+ read(pSiSUSB->sisusbdev, &tmp, 1);
+ tmp &= val;
+ lseek(pSiSUSB->sisusbdev, base + 1, SEEK_SET);
+ num = write(pSiSUSB->sisusbdev, &tmp, 1);
+ } while((num != 1) && --retry);
+#endif
+ if(!retry) SiSLostConnection(pSiSUSB);
+}
+
+void setSISIDXREG(SISUSBPtr pSiSUSB, ULong base, UChar idx,
+ UChar myand, UChar myor)
+{
+ int num, retry = 3;
+#ifdef SIS_USEIOCTL
+ sisusb_command x;
+ if(pSiSUSB->sisusbfatalerror) return;
+ do {
+ x.operation = SUCMD_SETANDOR;
+ x.data3 = base;
+ x.data0 = idx;
+ x.data1 = myand;
+ x.data2 = myor;
+ num = ioctl(pSiSUSB->sisusbdev, SISUSB_COMMAND, &x);
+ } while((num) && --retry);
+#else
+ UChar tmp;
+ if(pSiSUSB->sisusbfatalerror) return;
+ do {
+ lseek(pSiSUSB->sisusbdev, base, SEEK_SET);
+ write(pSiSUSB->sisusbdev, &idx, 1);
+ read(pSiSUSB->sisusbdev, &tmp, 1);
+ tmp &= myand;
+ tmp |= myor;
+ lseek(pSiSUSB->sisusbdev, base + 1, SEEK_SET);
+ num = write(pSiSUSB->sisusbdev, &tmp, 1);
+ } while((num != 1) && --retry);
+#endif
+ if(!retry) SiSLostConnection(pSiSUSB);
+}
+
+void setSISIDXREGmask(SISUSBPtr pSiSUSB, ULong base, UChar idx,
+ UChar data, UChar mask)
+{
+ int num, retry = 3;
+#ifdef SIS_USEIOCTL
+ sisusb_command x;
+ if(pSiSUSB->sisusbfatalerror) return;
+ do {
+ x.operation = SUCMD_SETMASK;
+ x.data3 = base;
+ x.data0 = idx;
+ x.data1 = data;
+ x.data2 = mask;
+ num = ioctl(pSiSUSB->sisusbdev, SISUSB_COMMAND, &x);
+ } while((num) && --retry);
+#else
+ UChar tmp;
+ if(pSiSUSB->sisusbfatalerror) return;
+ do {
+ lseek(pSiSUSB->sisusbdev, base, SEEK_SET);
+ write(pSiSUSB->sisusbdev, &idx, 1);
+ read(pSiSUSB->sisusbdev, &tmp, 1);
+ tmp &= ~(mask);
+ tmp |= (data & mask);
+ lseek(pSiSUSB->sisusbdev, base + 1, SEEK_SET);
+ num = write(pSiSUSB->sisusbdev, &tmp, 1);
+ } while((num != 1) && --retry);
+#endif
+ if(!retry) SiSLostConnection(pSiSUSB);
+}
+
+/* Video RAM and MMIO access ----- */
+
+void sisclearvram(SISUSBPtr pSiSUSB, UChar *where, unsigned int howmuch)
+{
+ int num, retry = 3;
+ sisusb_command x;
+ if(pSiSUSB->sisusbfatalerror) return;
+ do {
+ x.operation = SUCMD_CLRSCR;
+ x.data3 = (CARD32)where;
+ x.data0 = (howmuch >> 16) & 0xff;
+ x.data1 = (howmuch >> 8) & 0xff;
+ x.data2 = howmuch & 0xff;
+ num = ioctl(pSiSUSB->sisusbdev, SISUSB_COMMAND, &x);
+ } while((num) && --retry);
+ if(!retry) SiSLostConnection(pSiSUSB);
+}
+
+void sisrestoredestroyconsole(SISUSBPtr pSiSUSB, int what)
+{
+ int num, retry = 3;
+ sisusb_command x;
+ if(pSiSUSB->sisusbfatalerror) return;
+ do {
+ x.operation = SUCMD_HANDLETEXTMODE;
+ x.data3 = 0;
+ x.data0 = what;
+ x.data1 = 0;
+ x.data2 = 0;
+ num = ioctl(pSiSUSB->sisusbdev, SISUSB_COMMAND, &x);
+ } while((num) && --retry);
+ if(!retry) SiSLostConnection(pSiSUSB);
+}
+
+/* MMIO */
+
+void SIS_MMIO_OUT8(SISUSBPtr pSiSUSB, UChar *base, unsigned int offset, CARD8 val)
+{
+ int num, retry = 3;
+ if(pSiSUSB->sisusbfatalerror) return;
+ do {
+ lseek(pSiSUSB->sisusbdev, (int)base + offset, SEEK_SET);
+ num = write(pSiSUSB->sisusbdev, &val, 1);
+ } while((num != 1) && --retry);
+ if(!retry) SiSLostConnection(pSiSUSB);
+}
+
+void SIS_MMIO_OUT16(SISUSBPtr pSiSUSB, UChar *base, unsigned int offset, CARD16 val)
+{
+ int num, retry = 3;
+ CARD16 buf = sisusb_cpu_to_le16(val);
+ if(pSiSUSB->sisusbfatalerror) return;
+ do {
+ lseek(pSiSUSB->sisusbdev, (int)base + offset, SEEK_SET);
+ num = write(pSiSUSB->sisusbdev, &buf, 2);
+ } while((num != 2) && --retry);
+ if(!retry) SiSLostConnection(pSiSUSB);
+}
+
+void SIS_MMIO_OUT32(SISUSBPtr pSiSUSB, UChar *base, unsigned int offset, CARD32 val)
+{
+ int num, retry = 3;
+ CARD32 buf = sisusb_cpu_to_le32(val);
+ if(pSiSUSB->sisusbfatalerror) return;
+ do {
+ lseek(pSiSUSB->sisusbdev, (int)base + offset, SEEK_SET);
+ num = write(pSiSUSB->sisusbdev, &buf, 4);
+ } while((num != 4) && --retry);
+ if(!retry) SiSLostConnection(pSiSUSB);
+}
+
+CARD8 SIS_MMIO_IN8(SISUSBPtr pSiSUSB, UChar *base, unsigned int offset)
+{
+ int num, retry = 3;
+ CARD8 tmp;
+ if(pSiSUSB->sisusbfatalerror) return 0;
+ do {
+ lseek(pSiSUSB->sisusbdev, (int)base + offset, SEEK_SET);
+ num = read(pSiSUSB->sisusbdev, &tmp, 1);
+ } while((num != 1) && --retry);
+ if(!retry) SiSLostConnection(pSiSUSB);
+ return tmp;
+}
+
+CARD16 SIS_MMIO_IN16(SISUSBPtr pSiSUSB, UChar *base, unsigned int offset)
+{
+ int num, retry = 3;
+ CARD16 tmp;
+ if(pSiSUSB->sisusbfatalerror) return 0;
+ do {
+ lseek(pSiSUSB->sisusbdev, (int)base + offset, SEEK_SET);
+ num = read(pSiSUSB->sisusbdev, &tmp, 2);
+ } while((num != 2) && --retry);
+ if(!retry) SiSLostConnection(pSiSUSB);
+ return sisusb_le16_to_cpu(tmp);
+}
+
+CARD32 SIS_MMIO_IN32(SISUSBPtr pSiSUSB, UChar *base, unsigned int offset)
+{
+ int num, retry = 3;
+ CARD32 tmp;
+ if(pSiSUSB->sisusbfatalerror) return 0;
+ do {
+ lseek(pSiSUSB->sisusbdev, (int)base + offset, SEEK_SET);
+ num = read(pSiSUSB->sisusbdev, &tmp, 4);
+ } while((num != 4) && --retry);
+ if(!retry) SiSLostConnection(pSiSUSB);
+ return sisusb_le32_to_cpu(tmp);
+}
+
+
+
+
+
diff --git a/driver/xf86-video-sisusb/src/sisusb_dac.h b/driver/xf86-video-sisusb/src/sisusb_dac.h
new file mode 100644
index 000000000..fa796880e
--- /dev/null
+++ b/driver/xf86-video-sisusb/src/sisusb_dac.h
@@ -0,0 +1,52 @@
+/* $XFree86$ */
+/* $XdotOrg: driver/xf86-video-sisusb/src/sisusb_dac.h,v 1.4 2005/07/09 03:02:56 twini Exp $ */
+/*
+ * DAC helper functions (Save/Restore, MemClk, etc)
+ * Definitions and prototypes
+ *
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1) Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2) Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3) The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+int SiSUSB_compute_vclk(int Clock, int *out_n, int *out_dn, int *out_div,
+ int *out_sbit, int *out_scale);
+void SISUSBDACPreInit(ScrnInfoPtr pScrn);
+void SISUSBLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indicies,
+ LOCO *colors, VisualPtr pVisual);
+void SiSUSBCalcClock(ScrnInfoPtr pScrn, int clock, int max_VLD,
+ unsigned int *vclk);
+void SiSUSBIODump(ScrnInfoPtr pScrn);
+int SiSUSBMemBandWidth(ScrnInfoPtr pScrn, Bool IsForCRT2);
+int SiSUSBMclk(SISUSBPtr pSiSUSB);
+void SiSUSBRestoreBridge(ScrnInfoPtr pScrn, SISUSBRegPtr sisReg);
+
+extern int SiSUSBCalcVRate(DisplayModePtr mode);
+
+/* Functions from sisusb_init.c (use its datatypes!) */
+extern void SiSUSB_DisplayOn(SiS_Private *SiS_Pr);
+extern UCHAR SiSUSB_GetSetModeID(ScrnInfoPtr pScrn, UCHAR id);
+extern void SiSUSBRegInit(SiS_Private *SiS_Pr, USHORT BaseAddr);
+
+/* End of init.c/init301.c imports */
diff --git a/driver/xf86-video-sisusb/src/sisusb_driver.c b/driver/xf86-video-sisusb/src/sisusb_driver.c
new file mode 100644
index 000000000..03570b46a
--- /dev/null
+++ b/driver/xf86-video-sisusb/src/sisusb_driver.c
@@ -0,0 +1,2815 @@
+/* $XFree86$ */
+/* $XdotOrg: driver/xf86-video-sisusb/src/sisusb_driver.c,v 1.16 2005/09/28 18:48:30 twini Exp $ */
+/*
+ * SiSUSB driver main code
+ *
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1) Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2) Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3) The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "sisusb.h"
+
+#include "xf86RAC.h"
+#include "dixstruct.h"
+#include "shadowfb.h"
+#include "fb.h"
+#include "micmap.h"
+#include "mibank.h"
+#include "mipointer.h"
+#include "mibstore.h"
+#define _XF86MISC_SERVER_
+#include <X11/extensions/xf86misc.h>
+
+#include "sisusb_regs.h"
+#include "sisusb_dac.h"
+
+#include "sisusb_driver.h"
+
+#include "globals.h"
+
+#define DPMS_SERVER
+#include <X11/extensions/dpms.h>
+
+/*
+ * This is intentionally screen-independent. It indicates the binding
+ * choice made in the first PreInit.
+ */
+static int pix24bpp = 0;
+
+/*
+ * 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.
+ */
+
+#ifdef _X_EXPORT
+_X_EXPORT
+#endif
+DriverRec SISUSB = {
+ SISUSB_CURRENT_VERSION,
+ SISUSB_DRIVER_NAME,
+ SISUSBIdentify,
+ SISUSBProbe,
+ SISUSBAvailableOptions,
+ NULL,
+ 0
+#ifdef SISUSB_HAVE_DRIVER_FUNC
+ ,
+ SISUSBDriverFunc
+#endif
+};
+
+static SymTabRec SISUSBChipsets[] = {
+ { USB_CHIP_SIS315, "SIS315E/PRO USB" },
+ { -1, NULL }
+};
+
+static const char *fbSymbols[] = {
+ "fbPictureInit",
+ "fbScreenInit",
+ NULL
+};
+
+static const char *shadowSymbols[] = {
+ "ShadowFBInit",
+ NULL
+};
+
+static const char *ramdacSymbols[] = {
+ "xf86CreateCursorInfoRec",
+ "xf86DestroyCursorInfoRec",
+ "xf86InitCursor",
+ NULL
+};
+
+#ifdef XFree86LOADER
+
+static MODULESETUPPROTO(sisusbSetup);
+
+static XF86ModuleVersionInfo sisVersRec =
+{
+ SISUSB_DRIVER_NAME,
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+#ifdef XORG_VERSION_CURRENT
+ XORG_VERSION_CURRENT,
+#else
+ XF86_VERSION_CURRENT,
+#endif
+ SISUSB_MAJOR_VERSION, SISUSB_MINOR_VERSION, SISUSB_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV, /* This is a video driver */
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0,0,0,0}
+};
+
+#ifdef _X_EXPORT
+_X_EXPORT
+#endif
+XF86ModuleData sisusbModuleData = { &sisVersRec, sisusbSetup, NULL };
+
+pointer
+sisusbSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ if(!setupDone) {
+ setupDone = TRUE;
+ xf86AddDriver(&SISUSB, module, SISUSB_HaveDriverFuncs);
+ LoaderRefSymLists(fbSymbols, shadowSymbols, ramdacSymbols, NULL);
+ return (pointer)TRUE;
+ }
+
+ if(errmaj) *errmaj = LDR_ONCEONLY;
+ return NULL;
+}
+
+#endif /* XFree86LOADER */
+
+/* Mandatory */
+static void
+SISUSBIdentify(int flags)
+{
+ xf86PrintChipsets(SISUSB_NAME, "driver for SiSUSB chipsets", SISUSBChipsets);
+}
+
+#ifdef SISUSB_HAVE_DRIVER_FUNC
+static Bool
+SISUSBDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer ptr)
+{
+ xorgHWFlags *flag;
+
+ switch(op) {
+ case GET_REQUIRED_HW_INTERFACES:
+ flag = (xorgHWFlags *)ptr;
+ (*flag) = 0;
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+#endif
+
+static Bool
+SISUSBGetRec(ScrnInfoPtr pScrn)
+{
+ /* Allocate an SISUSBRec, 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(SISUSBRec), 1);
+
+ /* Initialise it to 0 */
+ memset(pScrn->driverPrivate, 0, sizeof(SISUSBRec));
+
+ return TRUE;
+}
+
+static void
+SISUSBFreeRec(ScrnInfoPtr pScrn)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+
+ /* Just to make sure... */
+ if(!pSiSUSB) return;
+
+ if(pSiSUSB->pstate) xfree(pSiSUSB->pstate);
+ pSiSUSB->pstate = NULL;
+ if(pSiSUSB->fonts) xfree(pSiSUSB->fonts);
+ pSiSUSB->fonts = NULL;
+
+ if(pSiSUSB->SiS_Pr) xfree(pSiSUSB->SiS_Pr);
+ pSiSUSB->SiS_Pr = NULL;
+
+ if(pSiSUSB->sisusbdevopen) {
+ close(pSiSUSB->sisusbdev);
+ pSiSUSB->sisusbdevopen = FALSE;
+ }
+
+ if(pScrn->chipset) {
+ xfree(pScrn->chipset);
+ pScrn->chipset = NULL;
+ }
+
+ if(pScrn->driverPrivate) {
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+ }
+}
+
+static void
+SISUSBErrorLog(ScrnInfoPtr pScrn, const char *format, ...)
+{
+ va_list ap;
+ static const char *str = "**************************************************\n";
+
+ va_start(ap, format);
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, str);
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ " ERROR:\n");
+ xf86VDrvMsgVerb(pScrn->scrnIndex, X_ERROR, 1, format, ap);
+ va_end(ap);
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ " END OF MESSAGE\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, str);
+}
+
+static int
+SiSUSBFindDuplicate(int myminor, int *minorArray, int numDevSections)
+{
+ int i;
+ for(i = 0; i < numDevSections; i++) {
+ if(minorArray[i] == -1) continue;
+ if(minorArray[i] == myminor) return TRUE;
+ }
+ return FALSE;
+}
+
+static int
+SiSUSBCheckForUSBDongle(char *filename, SISUSBPtr pSiSUSB, int *filehandle)
+{
+ int retval = -1, myfile, dontclose = 0;
+ unsigned int sisusbversion;
+ CARD32 sisusbinfosize;
+ sisusb_info *mysisusbinfo;
+
+ if((myfile = open(filename, O_RDWR, 0)) != -1) {
+ if(!ioctl(myfile, SISUSB_GET_CONFIG_SIZE, &sisusbinfosize)) {
+ if((mysisusbinfo = xalloc(sisusbinfosize))) {
+ if(!ioctl(myfile, (SISUSB_GET_CONFIG | (sisusbinfosize << 16)), mysisusbinfo)) {
+ if(mysisusbinfo->sisusb_id == SISUSB_ID) {
+ sisusbversion = (mysisusbinfo->sisusb_version << 16) |
+ (mysisusbinfo->sisusb_revision << 8) |
+ mysisusbinfo->sisusb_patchlevel;
+ if(pSiSUSB) {
+ pSiSUSB->sisusbmembase = mysisusbinfo->sisusb_vrambase;
+ pSiSUSB->sisusbmmiobase = mysisusbinfo->sisusb_mmiobase;
+ pSiSUSB->sisusbioportbase = mysisusbinfo->sisusb_iobase;
+ pSiSUSB->sisusbpcibase = mysisusbinfo->sisusb_pcibase;
+ pSiSUSB->sisusbvramsize = mysisusbinfo->sisusb_vramsize;
+ pSiSUSB->sisusbinit = mysisusbinfo->sisusb_gfxinit;
+ pSiSUSB->sisusbversion = mysisusbinfo->sisusb_version;
+ pSiSUSB->sisusbrevision = mysisusbinfo->sisusb_revision;
+ pSiSUSB->sisusbpatchlevel = mysisusbinfo->sisusb_patchlevel;
+ pSiSUSB->sisusbfbactive = 0;
+ pSiSUSB->sisusbconactive = 0;
+ if(sisusbversion >= 0x000007) {
+ pSiSUSB->sisusbfbactive = mysisusbinfo->sisusb_fbdevactive;
+ }
+ if(sisusbversion >= 0x000008) {
+ pSiSUSB->sisusbconactive = mysisusbinfo->sisusb_conactive;
+ }
+ }
+ if(filehandle) {
+ (*filehandle) = myfile;
+ dontclose = 1;
+ }
+ retval = mysisusbinfo->sisusb_minor;
+ }
+ }
+ xfree(mysisusbinfo);
+ mysisusbinfo = NULL;
+ }
+ }
+ if(!dontclose) close(myfile);
+ }
+
+ return retval;
+}
+
+static int
+SiSUSBFindUSBDongle(GDevPtr dev, int *minorArray, int numDevSections, char **nameptr)
+{
+ int i, retval = -1, gotdev = 0;
+ char *p;
+
+ *nameptr = NULL;
+
+ if((dev) && (dev->busID) && (*dev->busID)) {
+ if(*dev->busID == 'U' || *dev->busID == 'u') {
+ if((p = strchr(dev->busID, ':'))) p++;
+ else p = dev->busID;
+ } else {
+ p = dev->busID;
+ }
+ if((p) && (*p) && (*p == '/')) {
+ gotdev = 1;
+ *nameptr = xalloc(strlen(p) + 1);
+ strcpy(*nameptr, p);
+ retval = SiSUSBCheckForUSBDongle(*nameptr, NULL, NULL);
+ } else if((p) && (*p) && (sscanf(p, "%d", &i) == 1)) {
+ if(i >= 0 && i <= 31) {
+ gotdev = 1;
+ *nameptr = xalloc(32);
+ sprintf(*nameptr, "/dev/sisusbvga%d", i);
+ retval = SiSUSBCheckForUSBDongle(*nameptr, NULL, NULL);
+ if(retval < 0) {
+ sprintf(*nameptr, "/dev/usb/sisusbvga%d", i);
+ retval = SiSUSBCheckForUSBDongle(*nameptr, NULL, NULL);
+ }
+ }
+ }
+ }
+ if(!gotdev) {
+ *nameptr = xalloc(32);
+ for(i = 0; i < 64; i++) {
+ if(i < 32) sprintf(*nameptr, "/dev/sisusbvga%d", i);
+ else sprintf(*nameptr, "/dev/usb/sisusbvga%d", i);
+ if((retval = SiSUSBCheckForUSBDongle(*nameptr, NULL, NULL)) >= 0) {
+ if(!SiSUSBFindDuplicate(retval, minorArray, numDevSections)) {
+ break;
+ }
+ }
+ }
+ }
+ if(retval >= 0) {
+ xf86Msg(X_INFO, "Found SiSUSB dongle (node %s, minor %d)\n", *nameptr, retval);
+ } else if((*nameptr)) {
+ xfree(*nameptr);
+ *nameptr = NULL;
+ }
+
+ return retval;
+}
+
+/* Mandatory */
+static Bool
+SISUSBProbe(DriverPtr drv, int flags)
+{
+ GDevPtr *devSections;
+ int i, numDevSections, numUsed, myminor;
+ Bool foundScreen = FALSE;
+ int *minorArray;
+ char **devnameArray;
+ char *nameptr;
+
+ /*
+ * The aim here is to find all cards that this driver can handle,
+ * and for the ones not already claimed by another driver, claim the
+ * slot, and allocate a ScrnInfoRec.
+ *
+ * This should be a minimal probe, and it should under no circumstances
+ * change the state of the hardware. Because a device is found, don't
+ * assume that it will be used. Don't do any initialisations other than
+ * the required ScrnInfoRec initialisations. Don't allocate any new
+ * data structures.
+ *
+ */
+
+ /*
+ * Next we check, if there has been a chipset override in the config file.
+ * For this we must find out if there is an active device section which
+ * is relevant, i.e., which has no driver specified or has THIS driver
+ * specified.
+ */
+
+ if((numDevSections = xf86MatchDevice(SISUSB_DRIVER_NAME, &devSections)) <= 0) {
+ /*
+ * There's no matching device section in the config file, so quit
+ * now.
+ */
+ return FALSE;
+ }
+
+ /* This is to avoid referencing a null-ptr; xf86MatchDevice, strangely, returns
+ * 1 sometimes (probe, doconfigure cases) with an empty device list
+ */
+ if(devSections == NULL) return FALSE;
+
+ /*
+ * 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.
+ */
+
+ /*
+ * Probing the USB2VGA dongle amounts to checking whether the required
+ * /dev file is available and can be opened for r/w.
+ */
+
+ /* Allocate and initialize an array of ints for storing the minors */
+ if(!(minorArray = (int *)xalloc(numDevSections * sizeof(int)))) {
+ return FALSE;
+ }
+ for(i = 0; i < numDevSections; i++) minorArray[i] = -1;
+
+ /* Allocate an array of char ptrs for storing the device node names */
+ if(!(devnameArray = (char **)xalloc(numDevSections * sizeof(char *)))) {
+ xfree(minorArray);
+ return FALSE;
+ }
+
+ /* Go through all device sections and look for dongles. Filter out
+ * duplicates, backup the device node name for further reference.
+ */
+ numUsed = 0;
+ for(i = 0; i < numDevSections; i++) {
+ if((myminor = SiSUSBFindUSBDongle(devSections[i], minorArray, numDevSections, &nameptr)) >= 0) {
+ if(!SiSUSBFindDuplicate(myminor, minorArray, numDevSections)) {
+ minorArray[numUsed] = myminor;
+ devnameArray[numUsed] = xalloc(strlen(nameptr) + 1);
+ strcpy(devnameArray[numUsed], nameptr);
+ numUsed++;
+ }
+ xfree(nameptr);
+ }
+ }
+
+ /* Free the minor array, we don't need it anymore */
+ xfree(minorArray);
+
+ if(numUsed <= 0) {
+ xfree(devSections);
+ xfree(devnameArray);
+ return FALSE;
+ }
+
+ if(flags & PROBE_DETECT) {
+
+ foundScreen = TRUE;
+
+ } else for(i = 0; i < numUsed; i++) {
+
+ /* Allocate a ScrnInfoRec and claim the slot */
+ ScrnInfoPtr pScrn = NULL;
+ int entityIndex = xf86ClaimNoSlot(drv, 0, devSections[i], TRUE);
+
+ if((pScrn = xf86AllocateScreen(drv, 0))) {
+ /* Add entity */
+ xf86AddEntityToScreen(pScrn, entityIndex);
+ /* Fill in what we can of the ScrnInfoRec */
+ pScrn->chipset = devnameArray[i];
+ pScrn->driverVersion = SISUSB_CURRENT_VERSION;
+ pScrn->driverName = SISUSB_DRIVER_NAME;
+ pScrn->name = SISUSB_NAME;
+ pScrn->Probe = SISUSBProbe;
+ pScrn->PreInit = SISUSBPreInit;
+ pScrn->ScreenInit = SISUSBScreenInit;
+ pScrn->SwitchMode = SISUSBSwitchMode;
+ pScrn->AdjustFrame = SISUSBAdjustFrame;
+ pScrn->EnterVT = SISUSBEnterVT;
+ pScrn->LeaveVT = SISUSBLeaveVT;
+ pScrn->FreeScreen = SISUSBFreeScreen;
+ pScrn->ValidMode = SISUSBValidMode;
+#ifdef X_XF86MiscPassMessage
+ if(xf86GetVersion() >= XF86_VERSION_NUMERIC(4,3,99,2,0)) {
+ pScrn->HandleMessage = SISUSBHandleMessage;
+ }
+#endif
+ foundScreen = TRUE;
+ }
+
+ }
+
+ xfree(devSections);
+ xfree(devnameArray);
+ return foundScreen;
+}
+
+static void
+SiSUSB_SiSFB_Lock(ScrnInfoPtr pScrn, Bool lock)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ int fd;
+ CARD32 parm;
+
+ if(!pSiSUSB->sisfbfound) return;
+ if(!pSiSUSB->sisfb_havelock) return;
+
+ if((fd = open(pSiSUSB->sisfbdevname, 'r')) != -1) {
+ parm = lock ? 1 : 0;
+ ioctl(fd, SISUSBFB_SET_LOCK, &parm);
+ close(fd);
+ }
+}
+
+static void
+SISUSBDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ UChar sr1=0, cr63=0, pmreg=0, sr7=0;
+ UChar oldpmreg=0;
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4,
+ "SISUSBDisplayPowerManagementSet(%d)\n",PowerManagementMode);
+
+#ifdef UNLOCK_ALWAYS
+ sisusbSaveUnlockExtRegisterLock(pSiSUSB, NULL, NULL);
+#endif
+
+ switch (PowerManagementMode) {
+
+ case DPMSModeOn: /* HSync: On, VSync: On */
+ pSiSUSB->Blank = FALSE;
+ sr1 = 0x00;
+ pmreg = 0x00;
+ cr63 = 0x00;
+ sr7 = 0x10;
+ break;
+
+ case DPMSModeSuspend: /* HSync: On, VSync: Off */
+ pSiSUSB->Blank = TRUE;
+ sr1 = 0x20;
+ pmreg = 0x80;
+ cr63 = 0x40;
+ sr7 = 0x00;
+ break;
+
+ case DPMSModeStandby: /* HSync: Off, VSync: On */
+ pSiSUSB->Blank = TRUE;
+ sr1 = 0x20;
+ pmreg = 0x40;
+ cr63 = 0x40;
+ sr7 = 0x00;
+ break;
+
+ case DPMSModeOff: /* HSync: Off, VSync: Off */
+ pSiSUSB->Blank = TRUE;
+ sr1 = 0x20;
+ pmreg = 0xc0;
+ cr63 = 0x40;
+ sr7 = 0x00;
+ break;
+
+ default:
+ return;
+ }
+
+ if(!pSiSUSB->CRT1off) {
+ setSISIDXREG(pSiSUSB, SISCR, pSiSUSB->myCR63, 0xbf, cr63);
+ setSISIDXREG(pSiSUSB, SISSR, 0x07, 0xef, sr7);
+ }
+ setSISIDXREG(pSiSUSB, SISSR, 0x01, ~0x20, sr1); /* Set/Clear "Display On" bit */
+
+ inSISIDXREG(pSiSUSB,SISSR, 0x1f, oldpmreg);
+ if(!pSiSUSB->CRT1off) {
+ setSISIDXREG(pSiSUSB, SISSR, 0x1f, 0x3f, pmreg);
+ }
+
+ oldpmreg &= 0xc0;
+
+ if(pmreg != oldpmreg) {
+ outSISIDXREG(pSiSUSB,SISSR, 0x00, 0x01); /* Synchronous Reset */
+ usleep(10000);
+ outSISIDXREG(pSiSUSB,SISSR, 0x00, 0x03); /* End Reset */
+ }
+
+}
+
+#ifdef SISGAMMARAMP
+static unsigned short
+calcgammaval(int j, int nramp, float invgamma, float bri, float c)
+{
+ float k = (float)j;
+ float nrm1 = (float)(nramp - 1);
+ float con = c * nrm1 / 3.0;
+ float l, v;
+
+ if(con != 0.0) {
+ l = nrm1 / 2.0;
+ if(con <= 0.0) {
+ k -= l;
+ k *= (l + con) / l;
+ } else {
+ l -= 1.0;
+ k -= l;
+ k *= l / (l - con);
+ }
+ k += l;
+ if(k < 0.0) k = 0.0;
+ }
+
+ if(invgamma == 1.0) {
+ v = k / nrm1 * 65535.0;
+ } else {
+ v = pow(k / nrm1, invgamma) * 65535.0 + 0.5;
+ }
+
+ v += (bri * (65535.0 / 3.0)) ;
+
+ if(v < 0.0) v = 0.0;
+ else if(v > 65535.0) v = 65535.0;
+
+ return (unsigned short)v;
+}
+
+static void
+SISUSBCalculateGammaRamp(ScreenPtr pScreen, ScrnInfoPtr pScrn)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ int i, j, nramp;
+ UShort *ramp[3];
+ float gamma_max[3], framp;
+ Bool newmethod = FALSE;
+
+ if(!(pSiSUSB->SiS_SD3_Flags & SiS_SD3_OLDGAMMAINUSE)) {
+ newmethod = TRUE;
+ } else {
+ gamma_max[0] = (float)pSiSUSB->GammaBriR / 1000;
+ gamma_max[1] = (float)pSiSUSB->GammaBriG / 1000;
+ gamma_max[2] = (float)pSiSUSB->GammaBriB / 1000;
+ }
+
+ if(!(nramp = xf86GetGammaRampSize(pScreen))) return;
+
+ for(i=0; i<3; i++) {
+ ramp[i] = (UShort *)xalloc(nramp * sizeof(UShort));
+ if(!ramp[i]) {
+ if(ramp[0]) { xfree(ramp[0]); ramp[0] = NULL; }
+ if(ramp[1]) { xfree(ramp[1]); ramp[1] = NULL; }
+ return;
+ }
+ }
+
+ if(newmethod) {
+
+ for(i = 0; i < 3; i++) {
+
+ float invgamma = 0.0, bri = 0.0, con = 0.0;
+
+ switch(i) {
+ case 0: invgamma = 1. / pScrn->gamma.red;
+ bri = pSiSUSB->NewGammaBriR;
+ con = pSiSUSB->NewGammaConR;
+ break;
+ case 1: invgamma = 1. / pScrn->gamma.green;
+ bri = pSiSUSB->NewGammaBriG;
+ con = pSiSUSB->NewGammaConG;
+ break;
+ case 2: invgamma = 1. / pScrn->gamma.blue;
+ bri = pSiSUSB->NewGammaBriB;
+ con = pSiSUSB->NewGammaConB;
+ break;
+ }
+
+ for(j = 0; j < nramp; j++) {
+ ramp[i][j] = calcgammaval(j, nramp, invgamma, bri, con);
+ }
+
+ }
+
+ } else {
+
+ for(i = 0; i < 3; i++) {
+ int fullscale = 65535 * gamma_max[i];
+ float dramp = 1. / (nramp - 1);
+ float invgamma = 0.0, v;
+
+ switch(i) {
+ case 0: invgamma = 1. / pScrn->gamma.red; break;
+ case 1: invgamma = 1. / pScrn->gamma.green; break;
+ case 2: invgamma = 1. / pScrn->gamma.blue; break;
+ }
+
+ for(j = 0; j < nramp; j++) {
+ framp = pow(j * dramp, invgamma);
+
+ v = (fullscale < 0) ? (65535 + fullscale * framp) :
+ fullscale * framp;
+ if(v < 0) v = 0;
+ else if(v > 65535) v = 65535;
+ ramp[i][j] = (UShort)v;
+ }
+ }
+
+ }
+
+ xf86ChangeGammaRamp(pScreen, nramp, ramp[0], ramp[1], ramp[2]);
+
+ xfree(ramp[0]);
+ xfree(ramp[1]);
+ xfree(ramp[2]);
+ ramp[0] = ramp[1] = ramp[2] = NULL;
+}
+#endif
+
+static Bool
+SiSUSBMakeOwnModeList(ScrnInfoPtr pScrn, Bool acceptcustommodes, Bool includelcdmodes,
+ Bool isfordvi, Bool *havecustommodes, Bool fakecrt2modes)
+{
+ DisplayModePtr tempmode, delmode, mymodes;
+
+ if((mymodes = SiSUSBBuildBuiltInModeList(pScrn, includelcdmodes, isfordvi, fakecrt2modes))) {
+ if(!acceptcustommodes) {
+ while(pScrn->monitor->Modes)
+ xf86DeleteMode(&pScrn->monitor->Modes, pScrn->monitor->Modes);
+ pScrn->monitor->Modes = mymodes;
+ } else {
+ delmode = pScrn->monitor->Modes;
+ while(delmode) {
+ if(delmode->type & M_T_DEFAULT) {
+ tempmode = delmode->next;
+ xf86DeleteMode(&pScrn->monitor->Modes, delmode);
+ delmode = tempmode;
+ } else {
+ delmode = delmode->next;
+ }
+ }
+ /* Link default modes AFTER user ones */
+ if((tempmode = pScrn->monitor->Modes)) {
+ *havecustommodes = TRUE;
+ while(tempmode) {
+ if(!tempmode->next) break;
+ else tempmode = tempmode->next;
+ }
+ tempmode->next = mymodes;
+ mymodes->prev = tempmode;
+ } else {
+ pScrn->monitor->Modes = mymodes;
+ }
+ }
+ return TRUE;
+ } else
+ return FALSE;
+}
+
+void SISUSBSaveDetectedDevices(ScrnInfoPtr pScrn)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ /* Backup detected CRT2 devices */
+ pSiSUSB->detectedCRT2Devices = pSiSUSB->VBFlags & (CRT2_LCD|CRT2_TV|CRT2_VGA|TV_AVIDEO|TV_SVIDEO|
+ TV_SCART|TV_HIVISION|TV_YPBPR);
+}
+
+/* Mandatory */
+static Bool
+SISUSBPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ SISUSBPtr pSiSUSB;
+ MessageType from;
+ UChar srlockReg, crlockReg;
+ unsigned int i;
+ int pix24flags;
+ ClockRangePtr clockRanges;
+
+ if(flags & PROBE_DETECT) {
+ return TRUE;
+ }
+
+ /*
+ * Note: This function is only called once at server startup, and
+ * not at the start of each server generation. This means that
+ * only things that are persistent across server generations can
+ * be initialised here. xf86Screens[] is the array of all screens,
+ * (pScrn is a pointer to one of these). Privates allocated using
+ * xf86AllocateScrnInfoPrivateIndex() are too, and should be used
+ * for data that must persist across server generations.
+ *
+ * Per-generation data should be allocated with
+ * AllocateScreenPrivateIndex() from the ScreenInit() function.
+ */
+
+ /* Check the number of entities, and fail if it isn't one. */
+ if(pScrn->numEntities != 1) {
+ SISUSBErrorLog(pScrn, "Number of entities is not 1\n");
+ return FALSE;
+ }
+
+ /* Due to the liberal license terms this is needed for
+ * keeping the copyright notice readable and intact in
+ * binary distributions. Removing this is a copyright
+ * infringement. Please read the license terms above.
+ */
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "SiSUSB driver (%d/%02d/%02d-%d, compiled for " SISUSBMYSERVERNAME " %d.%d.%d.%d)\n",
+ SISUSBDRIVERVERSIONYEAR + 2000, SISUSBDRIVERVERSIONMONTH,
+ SISUSBDRIVERVERSIONDAY, SISUSBDRIVERREVISION,
+#ifdef XORG_VERSION_CURRENT
+ XORG_VERSION_MAJOR, XORG_VERSION_MINOR,
+ XORG_VERSION_PATCH, XORG_VERSION_SNAP
+#else
+ XF86_VERSION_MAJOR, XF86_VERSION_MINOR,
+ XF86_VERSION_PATCH, XF86_VERSION_SNAP
+#endif
+ );
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Copyright (C) 2001-2005 Thomas Winischhofer <thomas@winischhofer.net>\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "*** See http://www.winischhofer.at/linuxsisusbvga.shtml\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "*** for documentation and updates.\n");
+
+#ifdef XORG_VERSION_CURRENT
+#if 0 /* no prototype yet */
+ if(xorgGetVersion() != XORG_VERSION_CURRENT) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "This driver binary is not compiled for this version of " SISUSBMYSERVERNAME "\n");
+ }
+#endif
+#else
+#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0)
+ if(xf86GetVersion() != XF86_VERSION_CURRENT) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "This driver binary is not compiled for this version of " SISUSBMYSERVERNAME "\n");
+ }
+#endif
+#endif
+
+ /* Allocate the SISUSBRec driverPrivate */
+ if(!SISUSBGetRec(pScrn)) {
+ SISUSBErrorLog(pScrn, "Could not allocate memory for pSiSUSB private\n");
+ return FALSE;
+ }
+ pSiSUSB = SISUSBPTR(pScrn);
+ pSiSUSB->pScrn = pScrn;
+
+ /* Get the entity */
+ pSiSUSB->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+
+ if(!(pScrn->chipset)) {
+ SISUSBErrorLog(pScrn, "Internal error: dev node name not found!\n");
+ SISUSBFreeRec(pScrn);
+ return FALSE;
+ }
+
+ pSiSUSB->sisusbfatalerror = 0;
+ pSiSUSB->timeout = 0;
+
+ if(SiSUSBCheckForUSBDongle(pScrn->chipset, pSiSUSB, &pSiSUSB->sisusbdev) < 0) {
+ SISUSBErrorLog(pScrn, "Failed to open %d for read/write\n", pScrn->chipset);
+ SISUSBFreeRec(pScrn);
+ return FALSE;
+ }
+ pSiSUSB->sisusbdevopen = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Found USB dongle (device %s, kernel driver %d.%d.%d)\n",
+ pScrn->chipset, pSiSUSB->sisusbversion, pSiSUSB->sisusbrevision,
+ pSiSUSB->sisusbpatchlevel);
+
+ /* Operations for which memory access is required */
+ /* USB2VGA: We never need memory or i/o access */
+ pScrn->racMemFlags = 0;
+ pScrn->racIoFlags = 0;
+
+ /* Load ramdac module */
+ if(!xf86LoadSubModule(pScrn, "ramdac")) {
+ SISUSBErrorLog(pScrn, "Could not load ramdac module\n");
+ SISUSBFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86LoaderReqSymLists(ramdacSymbols, NULL);
+
+ /* Set pScrn->monitor */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ /* Set Chipset type and revision */
+ pSiSUSB->Chipset = USB_CHIP_SIS315;
+ pSiSUSB->ChipRev = 0;
+ pSiSUSB->ChipType = SIS_315PRO;
+
+ /* Always do a ValidMode() inside Switchmode() */
+ pSiSUSB->skipswitchcheck = FALSE;
+
+ /* Determine chipset and VGA engine type */
+ pSiSUSB->ChipFlags = 0;
+ pSiSUSB->SiS_SD_Flags = pSiSUSB->SiS_SD2_Flags = 0;
+ pSiSUSB->SiS_SD3_Flags = pSiSUSB->SiS_SD4_Flags = 0;
+ pSiSUSB->HWCursorMBufNum = pSiSUSB->HWCursorCBufNum = 0;
+ pSiSUSB->NeedFlush = FALSE;
+
+ pSiSUSB->VGAEngine = SIS_315_VGA;
+ pSiSUSB->ChipFlags |= (SiSCF_Is315USB | SiSCF_315Core | SiSCF_MMIOPalette);
+ pSiSUSB->SiS_SD_Flags |= SiS_SD_IS315SERIES;
+ pSiSUSB->SiS_SD2_Flags |= SiS_SD2_SUPPORTXVHUESAT;
+ pSiSUSB->myCR63 = 0x63;
+ pSiSUSB->mmioSize = 128;
+
+ /* Now check if sisusbfb is active */
+
+ pSiSUSB->OldMode = 0;
+ pSiSUSB->sisfbfound = FALSE;
+ pSiSUSB->sisfbdevname[0] = 0;
+ pSiSUSB->sisfb_havelock = FALSE;
+
+ {
+
+ sisusbfb_info *mysisfbinfo = NULL;
+ CARD32 sisfbinfosize = 0, sisfbversion;
+ int fd, i;
+ char name[16];
+
+ i=0;
+ do {
+
+ if(i <= 7) {
+ sprintf(name, "/dev/fb%1d", i);
+ } else {
+ sprintf(name, "/dev/fb/%1d", i-8);
+ }
+
+ if((fd = open(name, 'r')) != -1) {
+
+ Bool gotit = FALSE;
+
+ if(!ioctl(fd, SISUSBFB_GET_INFO_SIZE, &sisfbinfosize)) {
+ if((mysisfbinfo = xalloc(sisfbinfosize))) {
+ if(!ioctl(fd, (SISUSBFB_GET_INFO | (sisfbinfosize << 16)), mysisfbinfo)) {
+ gotit = TRUE;
+ } else {
+ xfree(mysisfbinfo);
+ mysisfbinfo = NULL;
+ }
+ }
+ }
+
+ if(gotit) {
+
+ if(mysisfbinfo->sisusbfb_id == SISUSBFB_ID) {
+
+ sisfbversion = (mysisfbinfo->sisusbfb_version << 16) |
+ (mysisfbinfo->sisusbfb_revision << 8) |
+ (mysisfbinfo->sisusbfb_patchlevel);
+
+
+ if(mysisfbinfo->sisusbfb_minor == pSiSUSB->sisusb_minor) {
+
+ pSiSUSB->sisfbfound = TRUE;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "%s: SiSUSB kernel fb driver (sisusbfb) %d.%d.%d detected\n",
+ &name[5],
+ mysisfbinfo->sisusbfb_version,
+ mysisfbinfo->sisusbfb_revision,
+ mysisfbinfo->sisusbfb_patchlevel);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "sisusbfb: using video mode 0x%02x\n", mysisfbinfo->fbvidmode);
+ pSiSUSB->OldMode = mysisfbinfo->fbvidmode;
+
+ pSiSUSB->sisfb_havelock = TRUE;
+
+ }
+ }
+ xfree(mysisfbinfo);
+ mysisfbinfo = NULL;
+ }
+ close (fd);
+ }
+ i++;
+ } while((i <= 15) && (!pSiSUSB->sisfbfound));
+
+ if(pSiSUSB->sisfbfound) {
+ strncpy(pSiSUSB->sisfbdevname, name, 15);
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "sisusbfb not found\n");
+ }
+ }
+
+ /*
+ * The first thing we should figure out is the depth, bpp, etc.
+ * Additionally, determine the size of the HWCursor memory area.
+ */
+ pSiSUSB->CursorSize = 16384;
+ pix24flags = Support32bppFb;
+
+ /* Save the name of our Device section for SiSCtrl usage */
+ {
+ int ttt = 0;
+ GDevPtr device = xf86GetDevFromEntity(pScrn->entityList[0],
+ pScrn->entityInstanceList[0]);
+ if(device && device->identifier) {
+ if((ttt = strlen(device->identifier)) > 31) ttt = 31;
+ strncpy(&pSiSUSB->devsectname[0], device->identifier, 31);
+ }
+ pSiSUSB->devsectname[ttt] = 0;
+ }
+
+ pSiSUSB->ForceCursorOff = FALSE;
+
+ /* Allocate SiS_Private (for mode switching code) and initialize it */
+
+ if(!(pSiSUSB->SiS_Pr = xnfcalloc(sizeof(SiS_Private), 1))) {
+ SISUSBErrorLog(pScrn, "Could not allocate memory for SiS_Pr structure\n");
+ SISUSBFreeRec(pScrn);
+ return FALSE;
+ }
+ memset(pSiSUSB->SiS_Pr, 0, sizeof(SiS_Private));
+
+ pSiSUSB->SiS_Pr->ChipType = pSiSUSB->ChipType;
+ pSiSUSB->SiS_Pr->ChipRevision = pSiSUSB->ChipRev;
+ pSiSUSB->SiS_Pr->CRT1UsesCustomMode = FALSE;
+ pSiSUSB->SiS_Pr->SiS_MyCR63 = pSiSUSB->myCR63;
+ pSiSUSB->SiS_Pr->pSiSUSB = (void *)pSiSUSB;
+
+ /* Get our relocated IO registers */
+ pSiSUSB->RelIO = (SISIOADDRESS)pSiSUSB->sisusbioportbase;
+ pSiSUSB->SiS_Pr->IOAddress = (SISIOADDRESS)(pSiSUSB->RelIO + 0x30);
+
+ /* Initialize SiS Port Reg definitions for externally used
+ * sisusb_init.c routines.
+ */
+ SiSUSBRegInit(pSiSUSB->SiS_Pr, pSiSUSB->RelIO + 0x30);
+
+ if(!xf86SetDepthBpp(pScrn, 0, 0, 0, pix24flags)) {
+ SISUSBErrorLog(pScrn, "xf86SetDepthBpp() error\n");
+ SISUSBFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Check that the returned depth is one we support */
+ switch(pScrn->depth) {
+ case 8:
+ case 16:
+ case 24:
+ break;
+ default:
+ SISUSBErrorLog(pScrn,
+ "Given color depth (%d) is not supported by this driver/chipset\n",
+ pScrn->depth);
+ SISUSBFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86PrintDepthBpp(pScrn);
+
+ if(pScrn->bitsPerPixel == 24) {
+ SISUSBErrorLog(pScrn,
+ "Framebuffer bpp %d not supported for this chipset\n", pScrn->bitsPerPixel);
+ SISUSBFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Get the depth24 pixmap format */
+ if(pScrn->depth == 24 && pix24bpp == 0) {
+ pix24bpp = xf86GetBppFromDepth(pScrn, 24);
+ }
+
+ /*
+ * 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)) {
+ SISUSBErrorLog(pScrn, "xf86SetWeight() error\n");
+ SISUSBFreeRec(pScrn);
+ return FALSE;
+ } else {
+ Bool ret = FALSE;
+ switch(pScrn->depth) {
+ case 16:
+ if((pScrn->weight.red != 5) ||
+ (pScrn->weight.green != 6) ||
+ (pScrn->weight.blue != 5)) ret = TRUE;
+ break;
+ case 24:
+ if((pScrn->weight.red != 8) ||
+ (pScrn->weight.green != 8) ||
+ (pScrn->weight.blue != 8)) ret = TRUE;
+ break;
+ }
+ if(ret) {
+ SISUSBErrorLog(pScrn,
+ "RGB weight %d%d%d at depth %d not supported by hardware\n",
+ (int)pScrn->weight.red, (int)pScrn->weight.green,
+ (int)pScrn->weight.blue, pScrn->depth);
+ SISUSBFreeRec(pScrn);
+ return FALSE;
+ }
+ }
+ }
+
+ /* Set the current layout parameters */
+ pSiSUSB->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel;
+ pSiSUSB->CurrentLayout.depth = pScrn->depth;
+ /* (Inside this function, we can use pScrn's contents anyway) */
+
+ if(!xf86SetDefaultVisual(pScrn, -1)) {
+ SISUSBErrorLog(pScrn, "xf86SetDefaultVisual() error\n");
+ SISUSBFreeRec(pScrn);
+ return FALSE;
+ } else {
+ /* We don't support DirectColor at > 8bpp */
+ if(pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
+ SISUSBErrorLog(pScrn,
+ "Given default visual (%s) is not supported at depth %d\n",
+ xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
+ SISUSBFreeRec(pScrn);
+ return FALSE;
+ }
+ }
+
+ /* Unlock registers */
+ sisusbSaveUnlockExtRegisterLock(pSiSUSB, &srlockReg, &crlockReg);
+
+ /* Evaluate options */
+ SiSUSBOptions(pScrn);
+
+ /* We use a programamble clock */
+ pScrn->progClock = TRUE;
+
+ /* Set the bits per RGB for 8bpp mode */
+ if(pScrn->depth == 8) pScrn->rgbBits = 8;
+
+ /* Do some HW configuration detection (memory amount & type, clock, etc) */
+ SiSUSBSetup(pScrn);
+
+ /* Get framebuffer address */
+ pSiSUSB->FbAddress = pSiSUSB->sisusbmembase;
+ pSiSUSB->realFbAddress = pSiSUSB->FbAddress;
+
+ /* Get MMIO address */
+ pSiSUSB->IOAddress = pSiSUSB->sisusbmmiobase;
+
+ pSiSUSB->RealVideoRam = pScrn->videoRam;
+
+ pSiSUSB->FbMapSize = pSiSUSB->availMem = pScrn->videoRam * 1024;
+
+ /* Calculate real availMem according to Accel/TurboQueue and
+ * HWCursur setting. Also, initialize some variables used
+ * in other modules.
+ */
+ pSiSUSB->cursorOffset = 0;
+ pSiSUSB->CurARGBDest = NULL;
+ pSiSUSB->CurMonoSrc = NULL;
+ pSiSUSB->CurFGCol = pSiSUSB->CurBGCol = 0;
+
+#ifdef SISVRAMQ
+ pSiSUSB->cmdQueueSizeMask = pSiSUSB->cmdQueueSize - 1; /* VRAM Command Queue is variable (in therory) */
+ pSiSUSB->cmdQueueOffset = (pScrn->videoRam * 1024) - pSiSUSB->cmdQueueSize;
+ pSiSUSB->cmdQueueLen = 0;
+ pSiSUSB->cmdQueueLenMin = 0x200;
+ pSiSUSB->cmdQueueLenMax = pSiSUSB->cmdQueueSize - pSiSUSB->cmdQueueLenMin;
+ pSiSUSB->cmdQueueSize_div2 = pSiSUSB->cmdQueueSize / 2;
+ pSiSUSB->cmdQueueSize_div4 = pSiSUSB->cmdQueueSize / 4;
+ pSiSUSB->cmdQueueSize_4_3 = (pSiSUSB->cmdQueueSize / 4) * 3;
+ pSiSUSB->availMem -= pSiSUSB->cmdQueueSize;
+ pSiSUSB->cursorOffset = (pSiSUSB->cmdQueueSize / 1024);
+#else
+ pSiSUSB->availMem -= (512*1024); /* MMIO Command Queue is 512k (variable in theory) */
+ pSiSUSB->cursorOffset = 512;
+#endif
+
+ if(pSiSUSB->HWCursor) {
+ if(!(pSiSUSB->USBCursorBuf = xcalloc(pSiSUSB->CursorSize * 4, 1))) pSiSUSB->HWCursor = FALSE;
+
+ pSiSUSB->availMem -= (pSiSUSB->CursorSize * 2);
+ if(pSiSUSB->OptUseColorCursor) pSiSUSB->availMem -= (pSiSUSB->CursorSize * 2);
+
+ }
+ pSiSUSB->cursorBufferNum = 0;
+
+ pSiSUSB->maxxfbmem = pSiSUSB->availMem;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using %ldK of framebuffer memory\n",
+ pSiSUSB->maxxfbmem / 1024);
+
+ /* Find out about sub-classes of some chipsets and check
+ * if the chipset supports two video overlays
+ */
+ pSiSUSB->hasTwoOverlays = FALSE;
+ pSiSUSB->ChipFlags |= SiSCF_LARGEOVERLAY;
+
+ /* Backup VB connection and CRT1 on/off register */
+
+ inSISIDXREG(pSiSUSB,SISSR, 0x1f, pSiSUSB->oldSR1F);
+ inSISIDXREG(pSiSUSB,SISCR, 0x17, pSiSUSB->oldCR17);
+ inSISIDXREG(pSiSUSB,SISCR, 0x32, pSiSUSB->oldCR32);
+ inSISIDXREG(pSiSUSB,SISCR, 0x36, pSiSUSB->oldCR36);
+ inSISIDXREG(pSiSUSB,SISCR, 0x37, pSiSUSB->oldCR37);
+ inSISIDXREG(pSiSUSB,SISCR, pSiSUSB->myCR63, pSiSUSB->oldCR63);
+ pSiSUSB->postVBCR32 = pSiSUSB->oldCR32;
+
+ pSiSUSB->CRT1off = 0;
+
+ /* Detect video bridge and sense TV/VGA2 */
+ SISUSBVGAPreInit(pScrn);
+
+ /* Setup SD flags */
+ pSiSUSB->SiS_SD_Flags |= SiS_SD_ADDLSUPFLAG;
+ pSiSUSB->SiS_SD2_Flags |= SiS_SD2_USEVBFLAGS2;
+ pSiSUSB->SiS_SD2_Flags |= SiS_SD2_VBINVB2ONLY;
+ pSiSUSB->SiS_SD2_Flags |= SiS_SD2_HAVESD34;
+ pSiSUSB->SiS_SD2_Flags |= SiS_SD2_NEWGAMMABRICON;
+
+ /* Backup detected CRT2 devices */
+ SISUSBSaveDetectedDevices(pScrn);
+
+ /* Setup gamma (the cmap layer needs this to be initialised) */
+ /* (Do this after evaluating options) */
+ {
+ Gamma zeros = {0.0, 0.0, 0.0};
+ xf86SetGamma(pScrn, zeros);
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, pSiSUSB->CRT1gammaGiven ? X_CONFIG : X_INFO,
+ "Gamma correction is %s\n",
+ pSiSUSB->CRT1gamma ? "enabled" : "disabled");
+
+#ifdef SIS_GLOBAL_ENABLEXV
+ if(!(pSiSUSB->NoXvideo)) {
+ xf86DrvMsg(pScrn->scrnIndex, pSiSUSB->XvGammaGiven ? X_CONFIG : X_INFO,
+ "Separate Xv gamma correction is %s\n",
+ pSiSUSB->XvGamma ? "enabled" : "disabled");
+ if(pSiSUSB->XvGamma) {
+ xf86DrvMsg(pScrn->scrnIndex, pSiSUSB->XvGammaGiven ? X_CONFIG : X_INFO,
+ "Xv gamma correction: %.3f %.3f %.3f\n",
+ (float)((float)pSiSUSB->XvGammaRed / 1000),
+ (float)((float)pSiSUSB->XvGammaGreen / 1000),
+ (float)((float)pSiSUSB->XvGammaBlue / 1000));
+ if(!pSiSUSB->CRT1gamma) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Xv gamma correction requires gamma correction enabled\n");
+ }
+ }
+ }
+#else
+ pSiSUSB->XvGamma = FALSE;
+#endif
+
+ pSiSUSB->CRT1changed = FALSE;
+ pSiSUSB->newCR32 = pSiSUSB->postVBCR32;
+
+ pSiSUSB->CRT1off = 0;
+ pSiSUSB->XvOnCRT2 = FALSE;
+
+ pSiSUSB->VBFlags |= (VB_DISPMODE_SINGLE | DISPTYPE_CRT1);
+
+ /* Init ptrs for Save/Restore functions and calc MaxClock */
+ SISUSBDACPreInit(pScrn);
+
+ /* ********** end of VBFlags setup ********** */
+
+ /* VBFlags are initialized now. Back them up for SlaveMode modes. */
+ pSiSUSB->VBFlags_backup = pSiSUSB->VBFlags;
+
+ /* Backup CR32,36,37 (in order to write them back after a VT switch) */
+ inSISIDXREG(pSiSUSB,SISCR,0x32,pSiSUSB->myCR32);
+ inSISIDXREG(pSiSUSB,SISCR,0x36,pSiSUSB->myCR36);
+ inSISIDXREG(pSiSUSB,SISCR,0x37,pSiSUSB->myCR37);
+
+ /* Note: Do not use availMem for anything from now. Use
+ * maxxfbmem instead. (availMem does not take dual head
+ * mode into account.)
+ */
+
+ pSiSUSB->DRIheapstart = pSiSUSB->DRIheapend = 0;
+
+ /* From here, we mainly deal with clocks and modes */
+
+ /* Set the min pixel clock */
+ pSiSUSB->MinClock = 10000;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
+ pSiSUSB->MinClock / 1000);
+
+ /* If the user has specified ramdac speed in the config
+ * file, we respect that setting.
+ */
+ from = X_PROBED;
+ if(pSiSUSB->pEnt->device->dacSpeeds[0]) {
+ int speed = 0;
+ switch(pScrn->bitsPerPixel) {
+ case 8: speed = pSiSUSB->pEnt->device->dacSpeeds[DAC_BPP8];
+ break;
+ case 16: speed = pSiSUSB->pEnt->device->dacSpeeds[DAC_BPP16];
+ break;
+ case 24: speed = pSiSUSB->pEnt->device->dacSpeeds[DAC_BPP24];
+ break;
+ case 32: speed = pSiSUSB->pEnt->device->dacSpeeds[DAC_BPP32];
+ break;
+ }
+ if(speed == 0) pSiSUSB->MaxClock = pSiSUSB->pEnt->device->dacSpeeds[0];
+ else pSiSUSB->MaxClock = speed;
+ from = X_CONFIG;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
+ pSiSUSB->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;
+ clockRanges->minClock = pSiSUSB->MinClock;
+ clockRanges->maxClock = pSiSUSB->MaxClock;
+ clockRanges->clockIndex = -1; /* programmable */
+ clockRanges->interlaceAllowed = TRUE;
+ clockRanges->doubleScanAllowed = TRUE;
+
+ /*
+ * Since we have lots of built-in modes for 300/315/330/340 series
+ * with vb support, we replace the given default mode list with our
+ * own. In case the video bridge is to be used, we only allow other
+ * modes if
+ * -) vbtype is 301, 301B, 301C or 302B, and
+ * -) crt2 device is not TV, and
+ * -) crt1 is not LCDA, unless bridge is TMDS/LCDA capable (301C)
+ */
+ {
+ if(!(pSiSUSB->noInternalModes)) {
+ Bool acceptcustommodes = TRUE; /* Accept user modelines */
+ Bool includelcdmodes = FALSE; /* Include modes reported by DDC */
+ Bool isfordvi = FALSE; /* Is for digital DVI output */
+
+ pSiSUSB->HaveCustomModes = FALSE;
+ if(SiSUSBMakeOwnModeList(pScrn, acceptcustommodes, includelcdmodes,
+ isfordvi, &pSiSUSB->HaveCustomModes, FALSE)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Replaced %s mode list with built-in modes\n",
+ pSiSUSB->HaveCustomModes ? "default" : "entire");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Building list of built-in modes failed, using server defaults\n");
+ }
+ } else {
+ pSiSUSB->HaveCustomModes = TRUE;
+ }
+ }
+
+
+ /*
+ * 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 SISValidMode() already takes
+ * care of this, we don't worry about setting them here.
+ */
+
+ /* Select valid modes from those available */
+ /*
+ * Assuming min pitch 256, min height 128
+ */
+ {
+ int minpitch, maxpitch, minheight, maxheight;
+
+ minpitch = 256;
+ minheight = 128;
+ maxpitch = 4088;
+ maxheight = 4096;
+
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges, NULL,
+ minpitch, maxpitch,
+ pScrn->bitsPerPixel * 8,
+ minheight, maxheight,
+ pScrn->display->virtualX,
+ pScrn->display->virtualY,
+ pSiSUSB->maxxfbmem,
+ LOOKUP_BEST_REFRESH);
+ }
+
+ if(i == -1) {
+ SISUSBErrorLog(pScrn, "xf86ValidateModes() error\n");
+ sisusbRestoreExtRegisterLock(pSiSUSB,srlockReg,crlockReg);
+ SISUSBFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Check the virtual screen against the available memory */
+ {
+ ULong memreq = (pScrn->virtualX * ((pScrn->bitsPerPixel + 7) / 8)) * pScrn->virtualY;
+
+ if(memreq > pSiSUSB->maxxfbmem) {
+ SISUSBErrorLog(pScrn,
+ "Virtual screen too big for memory; %ldK needed, %ldK available\n",
+ memreq/1024, pSiSUSB->maxxfbmem/1024);
+ sisusbRestoreExtRegisterLock(pSiSUSB,srlockReg,crlockReg);
+ SISUSBFreeRec(pScrn);
+ return FALSE;
+ }
+ }
+
+ /* Prune the modes marked as invalid */
+ xf86PruneDriverModes(pScrn);
+
+ if(i == 0 || pScrn->modes == NULL) {
+ SISUSBErrorLog(pScrn, "No valid modes found - check VertRefresh/HorizSync\n");
+ sisusbRestoreExtRegisterLock(pSiSUSB,srlockReg,crlockReg);
+ SISUSBFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
+
+ /* Set the current mode to the first in the list */
+ pScrn->currentMode = pScrn->modes;
+
+ /* Copy to CurrentLayout */
+ pSiSUSB->CurrentLayout.mode = pScrn->currentMode;
+ pSiSUSB->CurrentLayout.displayWidth = pScrn->displayWidth;
+ pSiSUSB->CurrentLayout.displayHeight = pScrn->virtualY;
+
+ /* Print the list of modes being used */
+ xf86PrintModes(pScrn);
+
+ /* Set display resolution */
+ xf86SetDpi(pScrn, 0, 0);
+
+ /* Load fb module */
+ switch(pScrn->bitsPerPixel) {
+ case 8:
+ case 16:
+ case 24:
+ case 32:
+ if(!xf86LoadSubModule(pScrn, "fb")) {
+ SISUSBErrorLog(pScrn, "Failed to load fb module");
+ sisusbRestoreExtRegisterLock(pSiSUSB,srlockReg,crlockReg);
+ SISUSBFreeRec(pScrn);
+ return FALSE;
+ }
+ break;
+ default:
+ SISUSBErrorLog(pScrn, "Unsupported framebuffer bpp (%d)\n", pScrn->bitsPerPixel);
+ sisusbRestoreExtRegisterLock(pSiSUSB,srlockReg,crlockReg);
+ SISUSBFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(fbSymbols, NULL);
+
+ /* Load shadowfb (if needed) */
+ if(pSiSUSB->ShadowFB) {
+ if(!xf86LoadSubModule(pScrn, "shadowfb")) {
+ SISUSBErrorLog(pScrn, "Could not load shadowfb module\n");
+ sisusbRestoreExtRegisterLock(pSiSUSB,srlockReg,crlockReg);
+ SISUSBFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(shadowSymbols, NULL);
+ }
+
+ pSiSUSB->UseVESA = 0;
+
+ sisusbRestoreExtRegisterLock(pSiSUSB,srlockReg,crlockReg);
+
+ pSiSUSB->SiS_SD_Flags |= SiS_SD_SUPPORTXVGAMMA1;
+
+ if(pSiSUSB->enablesisctrl) pSiSUSB->SiS_SD_Flags |= SiS_SD_ENABLED;
+
+ pSiSUSB->currentModeLast = pScrn->currentMode;
+ pSiSUSB->VBFlagsInit = pSiSUSB->VBFlags;
+
+ return TRUE;
+}
+
+
+/*
+ * Map the framebuffer and MMIO memory
+ */
+
+static Bool
+SISUSBMapMem(ScrnInfoPtr pScrn)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+
+ pSiSUSB->FbBase = (UChar *)pSiSUSB->FbAddress;
+ pSiSUSB->IOBase = (UChar *)pSiSUSB->IOAddress;
+
+ return TRUE;
+}
+
+
+/*
+ * Unmap the framebuffer and MMIO memory.
+ */
+
+static Bool
+SISUSBUnmapMem(ScrnInfoPtr pScrn)
+{
+ return TRUE;
+}
+
+/*
+ * This function saves the video state.
+ */
+static void
+SISUSBSave(ScrnInfoPtr pScrn)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ SISUSBRegPtr sisReg = &pSiSUSB->SavedReg;
+ int flags = SISVGA_SR_CMAP | SISVGA_SR_MODE;
+
+ SiSUSBVGASave(pScrn, sisReg, flags);
+
+ sisusbSaveUnlockExtRegisterLock(pSiSUSB,&sisReg->sisRegs3C4[0x05],&sisReg->sisRegs3D4[0x80]);
+
+ (*pSiSUSB->SiSSave)(pScrn, sisReg);
+
+ /* "Save" these again as they may have been changed prior to SISUSBSave() call */
+
+ sisReg->sisRegs3C4[0x1f] = pSiSUSB->oldSR1F;
+ sisReg->sisRegs3D4[0x17] = pSiSUSB->oldCR17;
+ sisReg->sisRegs3D4[0x32] = pSiSUSB->oldCR32;
+ sisReg->sisRegs3D4[0x36] = pSiSUSB->oldCR36;
+ sisReg->sisRegs3D4[0x37] = pSiSUSB->oldCR37;
+ sisReg->sisRegs3D4[pSiSUSB->myCR63] = pSiSUSB->oldCR63;
+}
+
+/*
+ * Initialise a new mode.
+ */
+static Bool
+SISUSBModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+
+ /* Notify kernel driver that we are about
+ * to destoy the text console
+ */
+ if(pSiSUSB->sisusbconactive) {
+ sisrestoredestroyconsole(pSiSUSB, 1);
+ }
+
+ andSISIDXREG(pSiSUSB,SISCR,0x11,0x7f); /* Unlock CRTC registers */
+
+ SISUSBModifyModeInfo(mode); /* Quick check of the mode parameters */
+
+ SiSUSBRegInit(pSiSUSB->SiS_Pr, pSiSUSB->RelIO+0x30);
+
+ if(!(*pSiSUSB->ModeInit)(pScrn, mode)) {
+ SISUSBErrorLog(pScrn, "ModeInit() failed\n");
+ return FALSE;
+ }
+
+ pScrn->vtSema = TRUE;
+
+ SiSUSBPreSetMode(pScrn, mode, SIS_MODE_SIMU);
+
+ if(!SiSUSBBIOSSetMode(pSiSUSB->SiS_Pr, pScrn, mode, pSiSUSB->IsCustom)) {
+ SISUSBErrorLog(pScrn, "SiSUSBBIOSSetMode() failed\n");
+ return FALSE;
+ }
+
+ SiSUSBPostSetMode(pScrn, &pSiSUSB->ModeReg);
+
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "REAL REGISTER CONTENTS AFTER SETMODE:\n");
+ (*pSiSUSB->ModeInit)(pScrn, mode);
+#endif
+
+ /* Update Currentlayout */
+ pSiSUSB->CurrentLayout.mode = pSiSUSB->currentModeLast = mode;
+
+ return TRUE;
+}
+
+/*
+ * Restore the initial mode. To be used internally only!
+ */
+static void
+SISUSBRestore(ScrnInfoPtr pScrn)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ SISUSBRegPtr sisReg = &pSiSUSB->SavedReg;
+ int flags;
+
+#if 0
+ /* Wait for the accelerators */
+ if(!pSiSUSB->NoAccel) {
+ SiSUSBSync(pScrn);
+ }
+#endif
+
+ /* Clear video RAM if sisusbfb not active */
+ if(!pSiSUSB->sisfbfound && !pSiSUSB->sisusbfbactive) {
+ sisclearvram(pSiSUSB, pSiSUSB->FbBase, pSiSUSB->maxxfbmem);
+ }
+
+ /* Set up restore flags */
+ flags = SISVGA_SR_MODE | SISVGA_SR_CMAP;
+
+ SiSUSBVGAProtect(pScrn, TRUE);
+
+#ifdef UNLOCK_ALWAYS
+ sisusbSaveUnlockExtRegisterLock(pSiSUSB, NULL,NULL);
+#endif
+
+ /* First, restore CRT1 on/off and VB connection registers */
+ outSISIDXREG(pSiSUSB,SISCR, 0x32, pSiSUSB->oldCR32);
+ outSISIDXREG(pSiSUSB,SISCR, 0x17, pSiSUSB->oldCR17);
+ outSISIDXREG(pSiSUSB,SISCR, pSiSUSB->myCR63, pSiSUSB->oldCR63);
+ outSISIDXREG(pSiSUSB,SISSR, 0x1f, pSiSUSB->oldSR1F);
+
+ if(pSiSUSB->sisusbconactive) {
+
+ sisrestoredestroyconsole(pSiSUSB, 0);
+
+ } else if( (pSiSUSB->restorebyset) && (pSiSUSB->OldMode) ) {
+
+ int mymode = pSiSUSB->OldMode;
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "Restoring by setting old mode 0x%02x\n", pSiSUSB->OldMode);
+
+ pSiSUSB->SiS_Pr->UseCustomMode = FALSE;
+ pSiSUSB->SiS_Pr->CRT1UsesCustomMode = FALSE;
+ SiSUSBSetMode(pSiSUSB->SiS_Pr, pScrn, mymode, FALSE);
+
+ SiSUSB_GetSetModeID(pScrn, pSiSUSB->OldMode); /* NOT mymode! */
+
+ /* Restore CRT1 status */
+ outSISIDXREG(pSiSUSB,SISCR, pSiSUSB->myCR63, pSiSUSB->oldCR63);
+ outSISIDXREG(pSiSUSB,SISSR, 0x1f, pSiSUSB->oldSR1F);
+
+#ifdef SISVRAMQ
+ /* Restore queue mode registers on 315/330/340 series */
+ /* (This became necessary due to the switch to VRAM queue) */
+ SiSUSBRestoreQueueMode(pSiSUSB, sisReg);
+#endif
+
+ } else {
+
+ (*pSiSUSB->SiSRestore)(pScrn, sisReg);
+
+ }
+
+ if(!pSiSUSB->sisusbconactive) {
+ SiSUSBVGAProtect(pScrn, TRUE);
+ SiSUSBVGARestore(pScrn, sisReg, flags);
+ SiSUSBVGAProtect(pScrn, FALSE);
+ }
+
+ sisusbRestoreExtRegisterLock(pSiSUSB,sisReg->sisRegs3C4[0x05],sisReg->sisRegs3D4[0x80]);
+}
+
+/* Restore bridge config registers - to be called BEFORE Restore */
+static void
+SISUSBBridgeRestore(ScrnInfoPtr pScrn)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+
+ SiSUSBRestoreBridge(pScrn, &pSiSUSB->SavedReg);
+}
+
+/* Our generic BlockHandler for Xv */
+static void
+SISUSBBlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask)
+{
+ ScreenPtr pScreen = screenInfo.screens[i];
+ ScrnInfoPtr pScrn = xf86Screens[i];
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+
+ if((pSiSUSB->sisusbfatalerror) && (pSiSUSB->timeout != -1)) {
+ pSiSUSB->sisusberrorsleepcount++;
+ if(!(pSiSUSB->sisusberrorsleepcount % 100)) {
+ if(SiSUSBCheckForUSBDongle(pScrn->chipset, pSiSUSB, &pSiSUSB->sisusbdev) >= 0) {
+ pSiSUSB->sisusberrorsleepcount = 0;
+ pSiSUSB->sisusbfatalerror = 0;
+ pSiSUSB->sisusbdevopen = TRUE;
+ (*pScrn->SwitchMode)(pScrn->scrnIndex, pScrn->currentMode, 0);
+ pSiSUSB->ShBoxcount = 1;
+ pSiSUSB->ShXmin = pSiSUSB->ShYmin = 0;
+ pSiSUSB->ShXmax = pScrn->virtualX;
+ pSiSUSB->ShYmax = pScrn->virtualY;
+ }
+ } else if(pSiSUSB->timeout > 0) {
+ if(currentTime.milliseconds >= pSiSUSB->errorTime + (pSiSUSB->timeout * 1000)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Device disconnection timeout exceeded... Aborting...\n");
+ GiveUp(0);
+ }
+ }
+ }
+
+ SISUSBDoRefreshArea(pScrn);
+
+ pScreen->BlockHandler = pSiSUSB->BlockHandler;
+ (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
+ pScreen->BlockHandler = SISUSBBlockHandler;
+
+ if(pSiSUSB->VideoTimerCallback) {
+ (*pSiSUSB->VideoTimerCallback)(pScrn, currentTime.milliseconds);
+ }
+
+}
+
+/* Mandatory
+ * This gets called at the start of each server generation
+ *
+ * We use pScrn and not CurrentLayout here, because the
+ * properties we use have not changed (displayWidth,
+ * depth, bitsPerPixel)
+ */
+static Bool
+SISUSBScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ int ret;
+ VisualPtr visual;
+ ULong OnScreenSize;
+ int height, width, displayWidth;
+ UChar *FBStart;
+
+ /* Map the SiS memory and MMIO areas */
+ if(!SISUSBMapMem(pScrn)) {
+ SISUSBErrorLog(pScrn, "SiSUSBMapMem() failed\n");
+ return FALSE;
+ }
+
+ SiSUSB_SiSFB_Lock(pScrn, TRUE);
+
+#ifdef UNLOCK_ALWAYS
+ sisusbSaveUnlockExtRegisterLock(pSiSUSB, NULL, NULL);
+#endif
+
+ /* Save the current state */
+ SISUSBSave(pScrn);
+
+ {
+
+ if(!pSiSUSB->OldMode) {
+
+ /* Try to find out current (=old) mode number
+ * (Do this only if not sisfb has told us its mode yet)
+ */
+
+ /* Read 0:449 which the BIOS sets to the current mode number
+ * Unfortunately, this not reliable since the int10 emulation
+ * does not change this. So if we call the VBE later, this
+ * byte won't be touched (which is why we set this manually
+ * then).
+ */
+ UChar myoldmode = SiSUSB_GetSetModeID(pScrn,0xFF);
+ UChar cr30, cr31;
+
+ /* Read CR34 which the BIOS sets to the current mode number for CRT2
+ * This is - of course - not reliable if the machine has no video
+ * bridge...
+ */
+ inSISIDXREG(pSiSUSB,SISCR, 0x34, pSiSUSB->OldMode);
+ inSISIDXREG(pSiSUSB,SISCR, 0x30, cr30);
+ inSISIDXREG(pSiSUSB,SISCR, 0x31, cr31);
+
+ /* What if CR34 is different from the BIOS scratch byte? */
+ if(pSiSUSB->OldMode != myoldmode) {
+ /* If no bridge output is active, trust the BIOS scratch byte */
+ if( (!(pSiSUSB->VBFlags2 & VB2_VIDEOBRIDGE)) ||
+ (pSiSUSB->OldMode == 0) ||
+ (!cr31 && !cr30) ||
+ (cr31 & 0x20) ) {
+ pSiSUSB->OldMode = myoldmode;
+ }
+ /* ..else trust CR34 */
+ }
+
+ /* Newer 650 BIOSes set CR34 to 0xff if the mode has been
+ * "patched", for instance for 80x50 text mode. (That mode
+ * has no number of its own, it's 0x03 like 80x25). In this
+ * case, we trust the BIOS scratch byte (provided that any
+ * of these two is valid).
+ */
+ if(pSiSUSB->OldMode > 0x7f) {
+ pSiSUSB->OldMode = myoldmode;
+ }
+ }
+
+ }
+
+ /* RandR resets screen mode and size in CloseScreen(), hence
+ * we need to adapt our VBFlags to the initial state if the
+ * current mode has changed since closescreen() (or Screeninit()
+ * for the first instance)
+ */
+ if(pScrn->currentMode != pSiSUSB->currentModeLast) {
+ pSiSUSB->VBFlags = pSiSUSB->VBFlags_backup = pSiSUSB->VBFlagsInit;
+ }
+
+ /* Initialise the first mode */
+ if(!SISUSBModeInit(pScrn, pScrn->currentMode)) {
+ SISUSBErrorLog(pScrn, "SiSUSBModeInit() failed\n");
+ return FALSE;
+ }
+
+ /* Darken the screen for aesthetic reasons */
+ /* Not using Dual Head variant on purpose; we darken
+ * the screen for both displays, and un-darken
+ * it when the second head is finished
+ */
+ SISUSBSaveScreen(pScreen, SCREEN_SAVER_ON);
+
+ /* Set the viewport */
+ SISUSBAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ /* Reset visual list. */
+ miClearVisualTypes();
+
+ /* Setup the visuals we support. */
+
+ /*
+ * For bpp > 8, the default visuals are not acceptable because we only
+ * support TrueColor and not DirectColor.
+ */
+ if(!miSetVisualTypes(pScrn->depth,
+ (pScrn->bitsPerPixel > 8) ?
+ TrueColorMask : miGetDefaultVisualMask(pScrn->depth),
+ pScrn->rgbBits, pScrn->defaultVisual)) {
+ SISUSBSaveScreen(pScreen, SCREEN_SAVER_OFF);
+ SISUSBErrorLog(pScrn, "miSetVisualTypes() failed (bpp %d)\n",
+ pScrn->bitsPerPixel);
+ return FALSE;
+ }
+
+ width = pScrn->virtualX;
+ height = pScrn->virtualY;
+ displayWidth = pScrn->displayWidth;
+
+ if(pSiSUSB->ShadowFB) {
+ pSiSUSB->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * displayWidth);
+ pSiSUSB->ShadowPtr = xalloc(pSiSUSB->ShadowPitch * height);
+ if(!(FBStart = pSiSUSB->ShadowPtr)) {
+ SISUSBSaveScreen(pScreen, SCREEN_SAVER_OFF);
+ SISUSBErrorLog(pScrn, "Failed to allocate shadow framebuffer\n");
+ return FALSE;
+ }
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ if(pScrn->bitsPerPixel == 16) {
+ /* For 16bpp, we need to swap the bytes in the framebuffer */
+ if(!(pSiSUSB->ShadowPtrSwap = xalloc(pSiSUSB->ShadowPitch * height))) {
+ SISUSBSaveScreen(pScreen, SCREEN_SAVER_OFF);
+ SISUSBErrorLog(pScrn, "Failed to allocate swap buffer for shadow framebuffer\n");
+ return FALSE;
+ }
+ FBStart = pSiSUSB->ShadowPtrSwap;
+ }
+#endif
+ } else {
+ pSiSUSB->ShadowPtr = NULL;
+ FBStart = pSiSUSB->FbBase;
+ }
+
+ if(!miSetPixmapDepths()) {
+ SISUSBSaveScreen(pScreen, SCREEN_SAVER_OFF);
+ SISUSBErrorLog(pScrn, "miSetPixmapDepths() failed\n");
+ return FALSE;
+ }
+
+ /* Point cmdQueuePtr to pSiSEnt for shared usage
+ * (same technique is then eventually used in DRIScreeninit)
+ * For 315/330 series, this is done in EnableTurboQueue
+ * which has already been called during ModeInit().
+ */
+
+ pSiSUSB->cmdQueueLenPtr = &(pSiSUSB->cmdQueueLen);
+
+ pSiSUSB->cmdQueueLen = 0; /* Force an EngineIdle() at start */
+
+ /*
+ * Call the framebuffer layer's ScreenInit function and fill in other
+ * pScreen fields.
+ */
+ switch(pScrn->bitsPerPixel) {
+ case 8:
+ case 16:
+ case 32:
+ ret = fbScreenInit(pScreen, FBStart, width,
+ height, pScrn->xDpi, pScrn->yDpi,
+ displayWidth, pScrn->bitsPerPixel);
+ break;
+ default:
+ ret = FALSE;
+ break;
+ }
+ if(!ret) {
+ SISUSBErrorLog(pScrn, "Unsupported bpp (%d) or fbScreenInit() failed\n",
+ pScrn->bitsPerPixel);
+ SISUSBSaveScreen(pScreen, SCREEN_SAVER_OFF);
+ return FALSE;
+ }
+
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ /* Fixup RGB ordering on BE machines */
+ /* For 24bpp, we just swap the rgb masks and offsets */
+ if(pScrn->bitsPerPixel == 32) {
+ pScrn->offset.red = 8;
+ pScrn->offset.green = 16;
+ pScrn->offset.blue = 24;
+ pScrn->mask.red = 0x0000ff00;
+ pScrn->mask.green = 0x00ff0000;
+ pScrn->mask.blue = 0xff000000;
+ }
+#endif
+
+ 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;
+ }
+ }
+ }
+
+ /* Initialize RENDER ext; must be after RGB ordering fixed */
+ fbPictureInit(pScreen, 0, 0);
+
+ xf86SetBlackWhitePixels(pScreen);
+
+ /* Initialize the accelerators */
+ SiSUSBAccelInit(pScreen);
+
+ miInitializeBackingStore(pScreen);
+ xf86SetBackingStore(pScreen);
+
+ /* NO SilkenMouse. Never. Ever. */
+
+ /* Initialise cursor functions */
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+
+ if(pSiSUSB->HWCursor) {
+ SiSUSBHWCursorInit(pScreen);
+ }
+
+ /* Initialise default colormap */
+ if(!miCreateDefColormap(pScreen)) {
+ SISUSBSaveScreen(pScreen, SCREEN_SAVER_OFF);
+ SISUSBErrorLog(pScrn, "miCreateDefColormap() failed\n");
+ return FALSE;
+ }
+
+ if(!xf86HandleColormaps(pScreen, 256, (pScrn->depth == 8) ? 8 : pScrn->rgbBits,
+ SISUSBLoadPalette, NULL,
+ CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) {
+ SISUSBSaveScreen(pScreen, SCREEN_SAVER_OFF);
+ SISUSBErrorLog(pScrn, "xf86HandleColormaps() failed\n");
+ return FALSE;
+ }
+
+#ifdef SISGAMMARAMP
+ if((pSiSUSB->GammaBriR != 1000) ||
+ (pSiSUSB->GammaBriB != 1000) ||
+ (pSiSUSB->GammaBriG != 1000)) {
+ SISUSBCalculateGammaRamp(pScreen, pScrn);
+ }
+#endif
+
+ pSiSUSB->ShBoxcount = 0;
+ pSiSUSB->delaycount = 0;
+ if(pSiSUSB->ShadowFB) {
+ ShadowFBInit(pScreen, SISUSBRefreshArea);
+#if 0
+ if(!pSiSUSB->NoAccel) {
+ if(!SiSUSBFBInit(pScreen)) {
+ pSiSUSB->NoAccel = TRUE;
+ }
+ }
+#endif
+ }
+
+#if 0
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "2D acceleration %sabled\n", pSiSUSB->NoAccel ? "dis":"en");
+#endif
+
+ xf86DPMSInit(pScreen, (DPMSSetProcPtr)SISUSBDisplayPowerManagementSet, 0);
+
+ /* Init memPhysBase and fbOffset in pScrn */
+ pScrn->memPhysBase = pSiSUSB->FbAddress;
+ pScrn->fbOffset = 0;
+
+ pSiSUSB->ResetXv = pSiSUSB->ResetXvGamma = NULL;
+ pSiSUSB->xv_sisdirectunlocked = 0;
+
+#ifdef SIS_GLOBAL_ENABLEXV
+#if (XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,3,99,0,0)) || (defined(XvExtension))
+ if(!pSiSUSB->NoXvideo) {
+ SISUSBInitVideo(pScreen);
+ }
+#endif
+#endif
+
+ /* Wrap some funcs and setup remaining SD flags */
+
+ pSiSUSB->SiS_SD_Flags &= ~(SiS_SD_PSEUDOXINERAMA);
+
+ pSiSUSB->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = SISUSBCloseScreen;
+
+ pScreen->SaveScreen = SISUSBSaveScreen;
+
+ /* Install BlockHandler */
+ pSiSUSB->BlockHandler = pScreen->BlockHandler;
+ pScreen->BlockHandler = SISUSBBlockHandler;
+
+ /* Report any unused options (only for the first generation) */
+ if(serverGeneration == 1) {
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+ }
+
+ /* Clear frame buffer */
+ /* For CRT2, we don't do that at this point in dual head
+ * mode since the mode isn't switched at this time (it will
+ * be reset when setting the CRT1 mode). Hence, we just
+ * save the necessary data and clear the screen when
+ * going through this for CRT1.
+ */
+
+ OnScreenSize = pScrn->displayWidth * pScrn->currentMode->VDisplay
+ * (pScrn->bitsPerPixel >> 3);
+
+ /* Turn on the screen now */
+
+ SISUSBSaveScreen(pScreen, SCREEN_SAVER_OFF);
+ sisclearvram(pSiSUSB, pSiSUSB->FbBase, OnScreenSize);
+
+ pSiSUSB->SiS_SD_Flags &= ~SiS_SD_SUPPORTSGRCRT2;
+
+ pSiSUSB->SiS_SD_Flags &= ~SiS_SD_ISDEPTH8;
+ if(pSiSUSB->CurrentLayout.bitsPerPixel == 8) {
+ pSiSUSB->SiS_SD_Flags |= SiS_SD_ISDEPTH8;
+ pSiSUSB->SiS_SD_Flags &= ~SiS_SD_SUPPORTXVGAMMA1;
+ pSiSUSB->SiS_SD_Flags &= ~SiS_SD_SUPPORTSGRCRT2;
+ }
+
+#ifdef SISGAMMARAMP
+ pSiSUSB->SiS_SD_Flags |= SiS_SD_CANSETGAMMA;
+#else
+ pSiSUSB->SiS_SD_Flags &= ~SiS_SD_CANSETGAMMA;
+#endif
+
+#ifdef SIS_ENABLEXV
+ pSiSUSB->SiS_SD2_Flags &= ~SiS_SD2_NOOVERLAY;
+#else
+ pSiSUSB->SiS_SD2_Flags |= SiS_SD2_NOOVERLAY;
+#endif
+
+ pSiSUSB->SiS_SD2_Flags |= SiS_SD2_NODDCSUPPORT;
+
+ pSiSUSB->SiS_SD2_Flags |= SiS_SD2_SUPPLTFLAG;
+ pSiSUSB->SiS_SD2_Flags |= SiS_SD2_HAVESD34;
+
+ SiSUSBCtrlExtInit(pScrn);
+
+ return TRUE;
+}
+
+/* Usually mandatory */
+Bool
+SISUSBSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+
+ if(!pSiSUSB->skipswitchcheck) {
+ if(SISUSBValidMode(scrnIndex, mode, TRUE, flags) != MODE_OK) {
+ return FALSE;
+ }
+ }
+
+#if 0
+ if(!pSiSUSB->NoAccel) {
+ SiSUSBSync(pScrn);
+ }
+#endif
+
+ if(!(SISUSBModeInit(xf86Screens[scrnIndex], mode))) return FALSE;
+
+ return TRUE;
+}
+
+static void
+SISUSBSetStartAddressCRT1(SISUSBPtr pSiSUSB, ULong base)
+{
+ UChar cr11backup;
+
+ inSISIDXREG(pSiSUSB,SISCR, 0x11, cr11backup); /* Unlock CRTC registers */
+ andSISIDXREG(pSiSUSB, SISCR, 0x11, 0x7F);
+ outSISIDXREG(pSiSUSB,SISCR, 0x0D, base & 0xFF);
+ outSISIDXREG(pSiSUSB,SISCR, 0x0C, (base >> 8) & 0xFF);
+ outSISIDXREG(pSiSUSB,SISSR, 0x0D, (base >> 16) & 0xFF);
+ setSISIDXREG(pSiSUSB, SISSR, 0x37, 0xFE, (base >> 24) & 0x01);
+
+ /* Eventually lock CRTC registers */
+ setSISIDXREG(pSiSUSB, SISCR, 0x11, 0x7F,(cr11backup & 0x80));
+}
+
+/*
+ * This function is used to initialize the Start Address - the first
+ * displayed location in the video memory.
+ *
+ * Usually mandatory
+ */
+void
+SISUSBAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ ULong base;
+
+ if(pScrn->bitsPerPixel < 8) {
+ base = (y * pSiSUSB->CurrentLayout.displayWidth + x + 3) >> 3;
+ } else {
+ base = y * pSiSUSB->CurrentLayout.displayWidth + x;
+
+ /* calculate base bpp dep. */
+ switch(pSiSUSB->CurrentLayout.bitsPerPixel) {
+ case 16:
+ base >>= 1;
+ break;
+ case 24:
+ base = ((base * 3)) >> 2;
+ base -= base % 6;
+ break;
+ case 32:
+ break;
+ default: /* 8bpp */
+ base >>= 2;
+ break;
+ }
+ }
+
+#ifdef UNLOCK_ALWAYS
+ sisusbSaveUnlockExtRegisterLock(pSiSUSB, NULL, NULL);
+#endif
+
+ SISUSBSetStartAddressCRT1(pSiSUSB, base);
+}
+
+/*
+ * This is called when VT switching back to the X server. Its job is
+ * to reinitialise the video mode.
+ * Mandatory!
+ */
+static Bool
+SISUSBEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+
+ SiSUSB_SiSFB_Lock(pScrn, TRUE);
+
+ sisusbSaveUnlockExtRegisterLock(pSiSUSB, NULL, NULL);
+
+ outSISIDXREG(pSiSUSB,SISCR,0x32,pSiSUSB->myCR32);
+ outSISIDXREG(pSiSUSB,SISCR,0x36,pSiSUSB->myCR36);
+ outSISIDXREG(pSiSUSB,SISCR,0x37,pSiSUSB->myCR37);
+
+ if(!SISUSBModeInit(pScrn, pScrn->currentMode)) {
+ SISUSBErrorLog(pScrn, "SiSUSBEnterVT: SISUSBModeInit() failed\n");
+ return FALSE;
+ }
+
+ SISUSBAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ if(pSiSUSB->ResetXv) {
+ (pSiSUSB->ResetXv)(pScrn);
+ }
+
+ return TRUE;
+}
+
+/*
+ * This is called when VT switching away from the X server. Its job is
+ * to restore the previous (text) mode.
+ * Mandatory!
+ */
+static void
+SISUSBLeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+
+ if(pSiSUSB->CursorInfoPtr) {
+ pSiSUSB->CursorInfoPtr->HideCursor(pScrn);
+ SISUSBWaitVBRetrace(pScrn);
+ }
+
+ SISUSBBridgeRestore(pScrn);
+
+ SISUSBRestore(pScrn);
+
+ /* We use (otherwise unused) bit 7 to indicate that we are running
+ * to keep sisfb to change the displaymode (this would result in
+ * lethal display corruption upon quitting X or changing to a VT
+ * until a reboot)
+ */
+
+ orSISIDXREG(pSiSUSB, SISCR,0x34,0x80);
+
+ SISUSBVGALock(pSiSUSB);
+
+ SiSUSB_SiSFB_Lock(pScrn, FALSE);
+}
+
+
+/*
+ * 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
+SISUSBCloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+
+ if(pSiSUSB->SiSCtrlExtEntry) {
+ SiSUSBCtrlExtUnregister(pSiSUSB, pScrn->scrnIndex);
+ }
+
+ if(pScrn->vtSema) {
+
+ if(pSiSUSB->CursorInfoPtr) {
+ pSiSUSB->CursorInfoPtr->HideCursor(pScrn);
+ SISUSBWaitVBRetrace(pScrn);
+ }
+
+ SISUSBBridgeRestore(pScrn);
+
+ SISUSBRestore(pScrn);
+
+ SISUSBVGALock(pSiSUSB);
+
+ }
+
+ SiSUSB_SiSFB_Lock(pScrn, FALSE);
+
+ /* We should restore the mode number in case vtsema = false as well,
+ * but since we haven't register access then we can't do it. I think
+ * I need to rework the save/restore stuff, like saving the video
+ * status when returning to the X server and by that save me the
+ * trouble if sisfb was started from a textmode VT while X was on.
+ */
+
+ SISUSBUnmapMem(pScrn);
+
+ if(pSiSUSB->CursorInfoPtr) {
+ xf86DestroyCursorInfoRec(pSiSUSB->CursorInfoPtr);
+ pSiSUSB->CursorInfoPtr = NULL;
+ }
+
+ if(pSiSUSB->USBCursorBuf) {
+ xfree(pSiSUSB->USBCursorBuf);
+ pSiSUSB->USBCursorBuf = NULL;
+ }
+
+ if(pSiSUSB->ShadowPtr) {
+ xfree(pSiSUSB->ShadowPtr);
+ pSiSUSB->ShadowPtr = NULL;
+ }
+
+#if 0
+ if(pSiSUSB->PreAllocMem) {
+ xfree(pSiSUSB->PreAllocMem);
+ pSiSUSB->PreAllocMem = NULL;
+ }
+#endif
+
+ if(pSiSUSB->adaptor) {
+ xfree(pSiSUSB->adaptor);
+ pSiSUSB->adaptor = NULL;
+ pSiSUSB->ResetXv = pSiSUSB->ResetXvGamma = NULL;
+ }
+
+ pScrn->vtSema = FALSE;
+
+ /* Restore Blockhandler */
+ pScreen->BlockHandler = pSiSUSB->BlockHandler;
+
+#if 0
+ if(pSiSUSB->AWCreateGC) {
+ pScreen->CreateGC = pSiSUSB->AWCreateGC;
+ }
+#endif
+
+ pScreen->CloseScreen = pSiSUSB->CloseScreen;
+
+ return(*pScreen->CloseScreen)(scrnIndex, pScreen);
+}
+
+
+/* Free up any per-generation data structures */
+
+/* Optional */
+static void
+SISUSBFreeScreen(int scrnIndex, int flags)
+{
+ SISUSBFreeRec(xf86Screens[scrnIndex]);
+}
+
+
+/* Checks if a mode is suitable for the selected chipset. */
+
+static ModeStatus
+SISUSBValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+
+ if(SiSUSB_CheckModeCRT1(pScrn, mode, pSiSUSB->VBFlags, pSiSUSB->HaveCustomModes) < 0x14)
+ return MODE_BAD;
+
+ return MODE_OK;
+}
+
+/* Do screen blanking
+ *
+ * Mandatory
+ */
+static Bool
+SISUSBSaveScreen(ScreenPtr pScreen, int mode)
+{
+ return SiSUSBVGASaveScreen(pScreen, mode);
+}
+
+
+#ifdef DEBUG
+static void
+SiSUSBDumpModeInfo(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Clock : %x\n", mode->Clock);
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Hz Display : %x\n", mode->CrtcHDisplay);
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Hz Blank Start : %x\n", mode->CrtcHBlankStart);
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Hz Sync Start : %x\n", mode->CrtcHSyncStart);
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Hz Sync End : %x\n", mode->CrtcHSyncEnd);
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Hz Blank End : %x\n", mode->CrtcHBlankEnd);
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Hz Total : %x\n", mode->CrtcHTotal);
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Hz Skew : %x\n", mode->CrtcHSkew);
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Hz HAdjusted : %x\n", mode->CrtcHAdjusted);
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Vt Display : %x\n", mode->CrtcVDisplay);
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Vt Blank Start : %x\n", mode->CrtcVBlankStart);
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Vt Sync Start : %x\n", mode->CrtcVSyncStart);
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Vt Sync End : %x\n", mode->CrtcVSyncEnd);
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Vt Blank End : %x\n", mode->CrtcVBlankEnd);
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Vt Total : %x\n", mode->CrtcVTotal);
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Vt VAdjusted : %x\n", mode->CrtcVAdjusted);
+}
+#endif
+
+static void
+SISUSBModifyModeInfo(DisplayModePtr mode)
+{
+ if(mode->CrtcHBlankStart == mode->CrtcHDisplay)
+ mode->CrtcHBlankStart++;
+ if(mode->CrtcHBlankEnd == mode->CrtcHTotal)
+ mode->CrtcHBlankEnd--;
+ if(mode->CrtcVBlankStart == mode->CrtcVDisplay)
+ mode->CrtcVBlankStart++;
+ if(mode->CrtcVBlankEnd == mode->CrtcVTotal)
+ mode->CrtcVBlankEnd--;
+}
+
+/* Enable the Turboqueue/Commandqueue (For 300 and 315/330/340 series only) */
+static void
+SiSUSBEnableTurboQueue(ScrnInfoPtr pScrn)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ UShort SR26;
+ ULong temp;
+
+ if(!pSiSUSB->NoAccel) {
+ /* On 315/330/340 series, there are three queue modes available
+ * which are chosen by setting bits 7:5 in SR26:
+ * 1. MMIO queue mode (bit 5, 0x20). The hardware will keep
+ * track of the queue, the FIFO, command parsing and so
+ * on. This is the one comparable to the 300 series.
+ * 2. VRAM queue mode (bit 6, 0x40). In this case, one will
+ * have to do queue management himself.
+ * 3. AGP queue mode (bit 7, 0x80). Works as 2., but keeps the
+ * queue in AGP memory space.
+ * We go VRAM or MMIO here.
+ * SR26 bit 4 is called "Bypass H/W queue".
+ * SR26 bit 1 is called "Enable Command Queue Auto Correction"
+ * SR26 bit 0 resets the queue
+ * Size of queue memory is encoded in bits 3:2 like this:
+ * 00 (0x00) 512K
+ * 01 (0x04) 1M
+ * 10 (0x08) 2M
+ * 11 (0x0C) 4M
+ * The queue location is to be written to 0x85C0.
+ */
+#ifdef SISVRAMQ
+ /* We use VRAM Cmd Queue, not MMIO or AGP */
+ UChar tempCR55 = 0;
+
+ pSiSUSB->cmdQ_SharedWritePort = &(pSiSUSB->cmdQ_SharedWritePort_2D);
+
+ /* Set Command Queue Threshold to max value 11111b (?) */
+ outSISIDXREG(pSiSUSB, SISSR, 0x27, 0x1F);
+ /* Disable queue flipping */
+ inSISIDXREG(pSiSUSB, SISCR, 0x55, tempCR55) ;
+ andSISIDXREG(pSiSUSB, SISCR, 0x55, 0x33) ;
+ /* Syncronous reset for Command Queue */
+ outSISIDXREG(pSiSUSB, SISSR, 0x26, 0x01);
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, 0x85c4, 0);
+ /* Enable VRAM Command Queue mode */
+ switch(pSiSUSB->cmdQueueSize) {
+ case 1*1024*1024: SR26 = (0x40 | 0x04 | 0x01); break;
+ case 2*1024*1024: SR26 = (0x40 | 0x08 | 0x01); break;
+ case 4*1024*1024: SR26 = (0x40 | 0x0C | 0x01); break;
+ default:
+ pSiSUSB->cmdQueueSize = 512 * 1024;
+ case 512*1024: SR26 = (0x40 | 0x00 | 0x01);
+ }
+ outSISIDXREG(pSiSUSB,SISSR, 0x26, SR26);
+ SR26 &= 0xfe;
+ outSISIDXREG(pSiSUSB,SISSR, 0x26, SR26);
+ pSiSUSB->cmdQ_SharedWritePort_2D = (ULong)(SIS_MMIO_IN32(pSiSUSB, pSiSUSB->IOBase, 0x85c8));
+ *(pSiSUSB->cmdQ_SharedWritePort) = pSiSUSB->cmdQ_SharedWritePort_2D;
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, 0x85c4, pSiSUSB->cmdQ_SharedWritePort_2D);
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, 0x85C0, pSiSUSB->cmdQueueOffset);
+ temp = (ULong)pSiSUSB->FbBase;
+ temp += pSiSUSB->cmdQueueOffset;
+ pSiSUSB->cmdQueueBase = (ULong *)temp;
+ outSISIDXREG(pSiSUSB,SISCR, 0x55, tempCR55);
+#else
+ /* For MMIO */
+ /* Set Command Queue Threshold to max value 11111b */
+ outSISIDXREG(pSiSUSB,SISSR, 0x27, 0x1F);
+ /* Syncronous reset for Command Queue */
+ outSISIDXREG(pSiSUSB,SISSR, 0x26, 0x01);
+ /* Do some magic (cp readport to writeport) */
+ temp = SIS_MMIO_IN32(pSiSUSB, pSiSUSB->IOBase, 0x85C8);
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, 0x85C4, temp);
+ /* Enable MMIO Command Queue mode (0x20),
+ * Enable_command_queue_auto_correction (0x02)
+ * (no idea, but sounds good, so use it)
+ * 512k (0x00) (does this apply to MMIO mode?) */
+ outSISIDXREG(pSiSUSB,SISSR, 0x26, 0x22);
+ /* Calc Command Queue position (Q is always 512k)*/
+ temp = (pScrn->videoRam - 512) * 1024;
+ /* Set Q position */
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, 0x85C0, temp);
+#endif
+ }
+
+}
+
+#ifdef SISVRAMQ
+static void
+SiSUSBRestoreQueueMode(SISUSBPtr pSiSUSB, SISUSBRegPtr sisReg)
+{
+ UChar tempCR55=0;
+
+ inSISIDXREG(pSiSUSB,SISCR,0x55,tempCR55);
+ andSISIDXREG(pSiSUSB, SISCR,0x55,0x33);
+ outSISIDXREG(pSiSUSB,SISSR,0x26,0x01);
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, 0x85c4, 0);
+ outSISIDXREG(pSiSUSB,SISSR,0x27,sisReg->sisRegs3C4[0x27]);
+ outSISIDXREG(pSiSUSB,SISSR,0x26,sisReg->sisRegs3C4[0x26]);
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, 0x85C0, sisReg->sisMMIO85C0);
+ outSISIDXREG(pSiSUSB,SISCR,0x55,tempCR55);
+}
+#endif
+
+/* Things to do before a ModeSwitch.
+ */
+void SiSUSBPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int viewmode)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ UChar CR30, CR31, CR33;
+ int crt1rateindex = 0;
+ unsigned int vbflag = pSiSUSB->VBFlags;
+ Bool hcm = pSiSUSB->HaveCustomModes;
+ DisplayModePtr mymode = mode;
+
+ pSiSUSB->IsCustom = FALSE;
+
+ if(SiSUSB_CheckModeCRT1(pScrn, mymode, vbflag, hcm) == 0xfe) {
+ pSiSUSB->IsCustom = TRUE;
+ }
+
+#ifdef UNLOCK_ALWAYS
+ sisusbSaveUnlockExtRegisterLock(pSiSUSB, NULL, NULL); /* Unlock Registers */
+#endif
+
+ inSISIDXREG(pSiSUSB,SISCR, 0x33, CR33);
+
+ CR30 = 0x00;
+ CR31 = 0x00;
+
+ if(!pSiSUSB->IsCustom) {
+ crt1rateindex = SISUSBSearchCRT1Rate(pScrn, mymode);
+ }
+
+ CR33 &= 0xf0;
+ CR33 |= (crt1rateindex & 0x0f);
+
+ if(pSiSUSB->CRT1off) CR33 &= 0xf0;
+
+ outSISIDXREG(pSiSUSB,SISCR, 0x30, CR30);
+ outSISIDXREG(pSiSUSB,SISCR, 0x31, CR31);
+ outSISIDXREG(pSiSUSB,SISCR, 0x33, CR33);
+}
+
+
+/* Calc dotclock from registers */
+static int
+SiSUSBGetClockFromRegs(UChar sr2b, UChar sr2c)
+{
+ float num, denum, postscalar, divider;
+ int myclock;
+
+ divider = (sr2b & 0x80) ? 2.0 : 1.0;
+ postscalar = (sr2c & 0x80) ?
+ ( (((sr2c >> 5) & 0x03) == 0x02) ? 6.0 : 8.0 ) :
+ ( ((sr2c >> 5) & 0x03) + 1.0 );
+ num = (sr2b & 0x7f) + 1.0;
+ denum = (sr2c & 0x1f) + 1.0;
+ myclock = (int)((14318 * (divider / postscalar) * (num / denum)) / 1000);
+ return myclock;
+}
+
+/* PostSetMode:
+ * -) Disable CRT1 for saving bandwidth. This doesn't work with VESA;
+ * VESA uses the bridge in SlaveMode and switching CRT1 off while
+ * the bridge is in SlaveMode not that clever...
+ * -) Check if overlay can be used (depending on dotclock)
+ * -) Check if Panel Scaler is active on LVDS for overlay re-scaling
+ * -) Save TV registers for further processing
+ * -) Apply TV settings
+ */
+static void
+SiSUSBPostSetMode(ScrnInfoPtr pScrn, SISUSBRegPtr sisReg)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ UChar sr2b, sr2c;
+ int myclock1, myclock2;
+
+ pSiSUSB->CRT1isoff = pSiSUSB->CRT1off;
+
+#ifdef UNLOCK_ALWAYS
+ sisusbSaveUnlockExtRegisterLock(pSiSUSB, NULL, NULL);
+#endif
+
+ andSISIDXREG(pSiSUSB, SISCR,pSiSUSB->myCR63,0xBF);
+ andSISIDXREG(pSiSUSB, SISSR,0x1f,0x3f);
+
+ /* Determine if the video overlay can be used */
+ if(!pSiSUSB->NoXvideo) {
+ int clklimit1=0, clklimit2=0, clklimitg=0;
+ inSISIDXREG(pSiSUSB,SISSR,0x2b,sr2b);
+ inSISIDXREG(pSiSUSB,SISSR,0x2c,sr2c);
+ myclock1 = myclock2 = SiSUSBGetClockFromRegs(sr2b, sr2c);
+
+ pSiSUSB->MiscFlags &= ~(MISC_CRT1OVERLAY | MISC_CRT2OVERLAY | MISC_CRT1OVERLAYGAMMA);
+
+ clklimit1 = clklimit2 = 180; /* ? */
+ clklimitg = 166; /* ? */
+
+ if(myclock1 <= clklimit1) pSiSUSB->MiscFlags |= MISC_CRT1OVERLAY;
+ if(myclock2 <= clklimit2) pSiSUSB->MiscFlags |= MISC_CRT2OVERLAY;
+ if(myclock1 <= clklimitg) pSiSUSB->MiscFlags |= MISC_CRT1OVERLAYGAMMA;
+ if(!(pSiSUSB->MiscFlags & MISC_CRT1OVERLAY)) {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_WARNING, 3,
+ "Current dotclock (%dMhz) too high for video overlay on CRT1\n",
+ myclock1);
+ }
+ }
+
+ /* Determine if the Panel Link scaler is active */
+ pSiSUSB->MiscFlags &= ~MISC_PANELLINKSCALER;
+
+ /* Determine if our very special TV mode is active */
+ pSiSUSB->MiscFlags &= ~MISC_TVNTSC1024;
+
+ {
+ int i;
+#ifdef SISVRAMQ
+ /* Re-Enable command queue */
+ SiSUSBEnableTurboQueue(pScrn);
+#endif
+ /* Get HWCursor register contents for backup */
+ for(i = 0; i < 16; i++) {
+ pSiSUSB->HWCursorBackup[i] = SIS_MMIO_IN32(pSiSUSB, pSiSUSB->IOBase, 0x8500 + (i << 2));
+ }
+ }
+
+ /* Reset XV gamma correction */
+ if(pSiSUSB->ResetXvGamma) {
+ (pSiSUSB->ResetXvGamma)(pScrn);
+ }
+}
+
+
+/* Check if video bridge is in slave mode */
+Bool
+SiSUSBBridgeIsInSlaveMode(ScrnInfoPtr pScrn)
+{
+ return FALSE;
+}
+
+UShort
+SiSUSB_GetModeNumber(ScrnInfoPtr pScrn, DisplayModePtr mode, unsigned int VBFlags)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ UShort i = (pSiSUSB->CurrentLayout.bitsPerPixel+7)/8 - 1;
+
+ return(SiSUSB_GetModeID(pSiSUSB->VGAEngine, VBFlags, mode->HDisplay, mode->VDisplay,
+ i, pSiSUSB->FSTN, pSiSUSB->LCDwidth, pSiSUSB->LCDheight));
+}
+
+static UShort
+SiSUSB_CheckModeCRT1(ScrnInfoPtr pScrn, DisplayModePtr mode, unsigned int VBFlags, Bool havecustommodes)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ UShort i = (pSiSUSB->CurrentLayout.bitsPerPixel+7)/8 - 1;
+
+ if((havecustommodes) && (!(mode->type & M_T_DEFAULT))) {
+ return 0xfe;
+ }
+
+ return (SiSUSB_GetModeID(pSiSUSB->VGAEngine, VBFlags, mode->HDisplay, mode->VDisplay,
+ i, pSiSUSB->FSTN, pSiSUSB->LCDwidth, pSiSUSB->LCDheight));
+}
+
+/* Calculate the vertical refresh rate from a mode */
+int
+SiSUSBCalcVRate(DisplayModePtr mode)
+{
+ float hsync, refresh = 0;
+
+ if(mode->HSync > 0.0)
+ hsync = mode->HSync;
+ else if(mode->HTotal > 0)
+ hsync = (float)mode->Clock / (float)mode->HTotal;
+ else
+ hsync = 0.0;
+
+ if(mode->VTotal > 0)
+ refresh = hsync * 1000.0 / mode->VTotal;
+
+ if(mode->Flags & V_INTERLACE)
+ refresh *= 2.0;
+
+ if(mode->Flags & V_DBLSCAN)
+ refresh /= 2.0;
+
+ if(mode->VScan > 1)
+ refresh /= mode->VScan;
+
+ if(mode->VRefresh > 0.0)
+ refresh = mode->VRefresh;
+
+ if(hsync == 0 || refresh == 0) return(0);
+
+ return((int)(refresh));
+}
+
+/* Calculate CR33 (rate index) for CRT1.
+ * Calculation is done using currentmode, therefore it is
+ * recommended to set VertRefresh and HorizSync to correct
+ * values in config file.
+ */
+UChar
+SISUSBSearchCRT1Rate(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ int i = 0, irefresh;
+ UShort xres = mode->HDisplay;
+ UShort yres = mode->VDisplay;
+ UChar index, defindex;
+
+ defindex = (xres == 800 || xres == 1024 || xres == 1280) ? 0x02 : 0x01;
+
+ irefresh = SiSUSBCalcVRate(mode);
+ if(!irefresh) return defindex;
+
+ /* We need the REAL refresh rate here */
+ if(mode->Flags & V_INTERLACE) irefresh /= 2;
+
+ /* Do not multiply by 2 when DBLSCAN! */
+
+ index = 0;
+ while((sisx_vrate[i].idx != 0) && (sisx_vrate[i].xres <= xres)) {
+ if((sisx_vrate[i].xres == xres) && (sisx_vrate[i].yres == yres)) {
+ if(sisx_vrate[i].refresh == irefresh) {
+ index = sisx_vrate[i].idx;
+ break;
+ } else if(sisx_vrate[i].refresh > irefresh) {
+ if((sisx_vrate[i].refresh - irefresh) <= 3) {
+ index = sisx_vrate[i].idx;
+ } else if( ((irefresh - sisx_vrate[i - 1].refresh) <= 2) &&
+ (sisx_vrate[i].idx != 1) ) {
+ index = sisx_vrate[i - 1].idx;
+ }
+ break;
+ } else if((irefresh - sisx_vrate[i].refresh) <= 2) {
+ index = sisx_vrate[i].idx;
+ break;
+ }
+ }
+ i++;
+ }
+
+ if(index > 0) return index;
+ else return defindex;
+}
+
+#if 0
+static int
+SISUSBGetScanline(SISUSBPtr pSiSUSB)
+{
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase,0x8514,0x00000001);
+ return(((SIS_MMIO_IN32(pSiSUSB, pSiSUSB->IOBase,0x8514)) >> 16) & 0x7ff);
+#if 0
+ inSISIDXREG(pSiSUSB,SISCR,0x20,reg1);
+ inSISIDXREG(pSiSUSB,SISCR,0x1c,reg2);
+ inSISIDXREG(pSiSUSB,SISCR,0x1d,reg3);
+ return (reg2 | ((reg3 & 0x07) << 8));
+#endif
+}
+#endif
+
+void
+SISUSBWaitRetraceCRT1(ScrnInfoPtr pScrn)
+{
+ usleep(10000);
+#if 0
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ int line1, line2;
+ UChar temp;
+
+ inSISIDXREG(pSiSUSB,SISSR,0x1f,temp);
+ if(temp & 0xc0) return;
+#endif
+}
+
+static void
+SISUSBWaitVBRetrace(ScrnInfoPtr pScrn)
+{
+ SISUSBWaitRetraceCRT1(pScrn);
+}
+
+#define MODEID_OFF 0x449
+
+UChar
+SiSUSB_GetSetModeID(ScrnInfoPtr pScrn, UChar id)
+{
+ return(SiSUSB_GetSetBIOSScratch(pScrn, MODEID_OFF, id));
+}
+
+UChar
+SiSUSB_GetSetBIOSScratch(ScrnInfoPtr pScrn, UShort offset, UChar value)
+{
+ return 0;
+}
+
+void
+sisusbSaveUnlockExtRegisterLock(SISUSBPtr pSiSUSB, UChar *reg1, UChar *reg2)
+{
+ register UChar val;
+ ULong mylockcalls;
+
+ pSiSUSB->lockcalls++;
+ mylockcalls = pSiSUSB->lockcalls;
+
+ if(pSiSUSB->sisusbfatalerror) return;
+
+ /* check if already unlocked */
+ inSISIDXREG(pSiSUSB, SISSR, 0x05, val);
+ if(val != 0xa1) {
+ /* save State */
+ if(reg1) *reg1 = val;
+ /* unlock */
+ outSISIDXREG(pSiSUSB, SISSR, 0x05, 0x86);
+ inSISIDXREG(pSiSUSB, SISSR, 0x05, val);
+ if(val != 0xA1) {
+ SISUSBErrorLog(pSiSUSB->pScrn,
+ "Failed to unlock sr registers (%p, %lx, 0x%02x; %ld)\n",
+ (void *)pSiSUSB, (ULong)pSiSUSB->RelIO, val, mylockcalls);
+ }
+ }
+
+}
+
+void
+sisusbRestoreExtRegisterLock(SISUSBPtr pSiSUSB, UChar reg1, UChar reg2)
+{
+ /* restore lock */
+#ifndef UNLOCK_ALWAYS
+ outSISIDXREG(pSiSUSB, SISSR, 0x05, reg1 == 0xA1 ? 0x86 : 0x00);
+#endif
+}
+
diff --git a/driver/xf86-video-sisusb/src/sisusb_driver.h b/driver/xf86-video-sisusb/src/sisusb_driver.h
new file mode 100644
index 000000000..a03c045a1
--- /dev/null
+++ b/driver/xf86-video-sisusb/src/sisusb_driver.h
@@ -0,0 +1,160 @@
+/* $XFree86$ */
+/* $XdotOrg: driver/xf86-video-sisusb/src/sisusb_driver.h,v 1.8 2005/07/09 03:02:56 twini Exp $ */
+/*
+ * Global data and definitions
+ *
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1) Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2) Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3) The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
+
+/* For calculating refresh rate index (CR33) */
+static const struct _sis_vrate {
+ CARD16 idx;
+ CARD16 xres;
+ CARD16 yres;
+ CARD16 refresh;
+} sisx_vrate[] = {
+ {1, 320, 200, 60}, {1, 320, 200, 70},
+ {1, 320, 240, 60},
+ {1, 400, 300, 60},
+ {1, 512, 384, 60},
+ {1, 640, 400, 60}, {1, 640, 400, 72},
+ {1, 640, 480, 60}, {2, 640, 480, 72}, {3, 640, 480, 75},
+ {4, 640, 480, 85}, {5, 640, 480, 100}, {6, 640, 480, 120},
+ {7, 640, 480, 160}, {8, 640, 480, 200},
+ {1, 720, 480, 60},
+ {1, 720, 576, 60},
+ {1, 768, 576, 60},
+ {1, 800, 480, 60}, {2, 800, 480, 75}, {3, 800, 480, 85},
+ {1, 800, 600, 56}, {2, 800, 600, 60}, {3, 800, 600, 72},
+ {4, 800, 600, 75}, {5, 800, 600, 85}, {6, 800, 600, 105},
+ {7, 800, 600, 120}, {8, 800, 600, 160},
+ {1, 848, 480, 39}, {2, 848, 480, 60},
+ {1, 856, 480, 39}, {2, 856, 480, 60},
+ {1, 960, 540, 60},
+ {1, 960, 600, 60},
+ {1, 1024, 576, 60}, {2, 1024, 576, 75}, {3, 1024, 576, 85},
+ {1, 1024, 768, 43}, {2, 1024, 768, 60}, {3, 1024, 768, 70},
+ {4, 1024, 768, 75}, {5, 1024, 768, 85}, {6, 1024, 768, 100},
+ {7, 1024, 768, 120},
+ {1, 1152, 864, 60}, {2, 1152, 864, 75}, {3, 1152, 864, 84},
+ {1, 1280, 720, 60}, {2, 1280, 720, 75}, {3, 1280, 720, 85},
+ {1, 1280, 768, 60},
+ {1, 1280, 1024, 43}, {2, 1280, 1024, 60}, {3, 1280, 1024, 75},
+ {4, 1280, 1024, 85},
+ {0, 0, 0, 0}
+};
+
+/* Mandatory functions */
+static void SISUSBIdentify(int flags);
+static Bool SISUSBProbe(DriverPtr drv, int flags);
+static Bool SISUSBPreInit(ScrnInfoPtr pScrn, int flags);
+static Bool SISUSBScreenInit(int Index, ScreenPtr pScreen, int argc, char **argv);
+static Bool SISUSBEnterVT(int scrnIndex, int flags);
+static void SISUSBLeaveVT(int scrnIndex, int flags);
+static Bool SISUSBCloseScreen(int scrnIndex, ScreenPtr pScreen);
+static Bool SISUSBSaveScreen(ScreenPtr pScreen, int mode);
+static Bool SISUSBSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
+static void SISUSBAdjustFrame(int scrnIndex, int x, int y, int flags);
+#ifdef SISUSB_HAVE_DRIVER_FUNC
+static Bool SISUSBDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer p);
+#endif
+
+/* Optional functions */
+#ifdef X_XF86MiscPassMessage
+extern int SISUSBHandleMessage(int scrnIndex, const char *msgtype,
+ const char *msgval, char **retmsg);
+#endif
+static void SISUSBFreeScreen(int scrnIndex, int flags);
+static ModeStatus SISUSBValidMode(int scrnIndex, DisplayModePtr mode,
+ Bool verbose, int flags);
+
+/* Internally used functions */
+static Bool SISUSBMapMem(ScrnInfoPtr pScrn);
+static Bool SISUSBUnmapMem(ScrnInfoPtr pScrn);
+static void SISUSBSave(ScrnInfoPtr pScrn);
+static void SISUSBRestore(ScrnInfoPtr pScrn);
+static Bool SISUSBModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+static void SISUSBModifyModeInfo(DisplayModePtr mode);
+static void SiSUSBPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int viewmode);
+static void SiSUSBPostSetMode(ScrnInfoPtr pScrn, SISUSBRegPtr sisReg);
+static void SISUSBBridgeRestore(ScrnInfoPtr pScrn);
+static void SiSUSBEnableTurboQueue(ScrnInfoPtr pScrn);
+static void SiSUSBRestoreQueueMode(SISUSBPtr pSiSUSB, SISUSBRegPtr sisReg);
+UChar SISUSBSearchCRT1Rate(ScrnInfoPtr pScrn, DisplayModePtr mode);
+static void SISUSBWaitVBRetrace(ScrnInfoPtr pScrn);
+void SISUSBWaitRetraceCRT1(ScrnInfoPtr pScrn);
+static UShort SiSUSB_CheckModeCRT1(ScrnInfoPtr pScrn, DisplayModePtr mode,
+ unsigned int VBFlags, Bool hcm);
+
+Bool SiSUSBBridgeIsInSlaveMode(ScrnInfoPtr pScrn);
+UShort SiSUSB_GetModeNumber(ScrnInfoPtr pScrn, DisplayModePtr mode, unsigned int VBFlags);
+UChar SiSUSB_GetSetBIOSScratch(ScrnInfoPtr pScrn, UShort offset, UChar value);
+#ifdef DEBUG
+static void SiSUSBDumpModeInfo(ScrnInfoPtr pScrn, DisplayModePtr mode);
+#endif
+void SISUSBSaveDetectedDevices(ScrnInfoPtr pScrn);
+
+/* Our very own vgaHW functions (sisusb_vga.c) */
+extern void SiSUSBVGASave(ScrnInfoPtr pScrn, SISUSBRegPtr save, int flags);
+extern void SiSUSBVGARestore(ScrnInfoPtr pScrn, SISUSBRegPtr restore, int flags);
+extern void SiSUSBVGASaveFonts(ScrnInfoPtr pScrn);
+extern void SiSUSBVGARestoreFonts(ScrnInfoPtr pScrn);
+extern void SISUSBVGALock(SISUSBPtr pSiSUSB);
+extern void SiSUSBVGAUnlock(SISUSBPtr pSiSUSB);
+extern void SiSUSBVGAProtect(ScrnInfoPtr pScrn, Bool on);
+extern Bool SiSUSBVGAMapMem(ScrnInfoPtr pScrn);
+extern void SiSUSBVGAUnmapMem(ScrnInfoPtr pScrn);
+extern Bool SiSUSBVGASaveScreen(ScreenPtr pScreen, int mode);
+
+/* shadow */
+extern void SISUSBRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+extern void SISUSBDoRefreshArea(ScrnInfoPtr pScrn);
+
+/* vb */
+extern void SISUSBCRT1PreInit(ScrnInfoPtr pScrn);
+
+/* utility */
+extern void SiSUSBCtrlExtInit(ScrnInfoPtr pScrn);
+extern void SiSUSBCtrlExtUnregister(SISUSBPtr pSiSUSB, int index);
+
+/* sisusb_init.c ----- (use its data types!) */
+extern USHORT SiSUSB_GetModeID(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay,
+ int Depth, BOOLEAN FSTN, int LCDwith, int LCDheight);
+extern BOOLEAN SiSUSBBIOSSetMode(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, DisplayModePtr mode,
+ BOOLEAN IsCustom);
+extern BOOLEAN SiSUSBSetMode(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, USHORT ModeNo,
+ BOOLEAN dosetpitch);
+extern DisplayModePtr SiSUSBBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes,
+ BOOLEAN isfordvi, BOOLEAN fakecrt2modes);
+/* End of sisusb_init.c ----- */
+
+
+
+
+
+
diff --git a/driver/xf86-video-sisusb/src/sisusb_init.c b/driver/xf86-video-sisusb/src/sisusb_init.c
new file mode 100644
index 000000000..6e8808e29
--- /dev/null
+++ b/driver/xf86-video-sisusb/src/sisusb_init.c
@@ -0,0 +1,1571 @@
+/* $XFree86$ */
+/* $XdotOrg: driver/xf86-video-sisusb/src/sisusb_init.c,v 1.8 2005/07/11 02:30:00 ajax Exp $ */
+/*
+ * Mode initializing code (CRT1 section) for SiS315/USB
+ * (Universal module for Linux kernel framebuffer and X.org/XFree86 4.x)
+ *
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
+ *
+ * * Redistribution and use in source and binary forms, with or without
+ * * modification, are permitted provided that the following conditions
+ * * are met:
+ * * 1) Redistributions of source code must retain the above copyright
+ * * notice, this list of conditions and the following disclaimer.
+ * * 2) Redistributions in binary form must reproduce the above copyright
+ * * notice, this list of conditions and the following disclaimer in the
+ * * documentation and/or other materials provided with the distribution.
+ * * 3) The name of the author may not be used to endorse or promote products
+ * * derived from this software without specific prior written permission.
+ * *
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "sisusb_init.h"
+
+#if defined(ALLOC_PRAGMA)
+#pragma alloc_text(PAGE,SiSUSBSetMode)
+#endif
+
+/*********************************************/
+/* POINTER INITIALIZATION */
+/*********************************************/
+
+static void
+SiSUSB_InitPtr(SiS_Private *SiS_Pr)
+{
+ SiS_Pr->SiS_ModeResInfo = SiS_ModeResInfo;
+ SiS_Pr->SiS_StandTable = SiS_StandTable;
+ SiS_Pr->pSiS_SoftSetting = &SiS_SoftSetting;
+
+ SiS_Pr->SiS_EModeIDTable = SiSUSB_EModeIDTable;
+ SiS_Pr->SiS_RefIndex = SiSUSB_RefIndex;
+ SiS_Pr->SiS_CRT1Table = SiSUSB_CRT1Table;
+
+ SiS_Pr->SiS_VCLKData = SiSUSB_VCLKData;
+}
+
+/*********************************************/
+/* HELPER: Get ModeID */
+/*********************************************/
+
+USHORT
+SiSUSB_GetModeID(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay,
+ int Depth, BOOLEAN FSTN, int LCDwidth, int LCDheight)
+{
+ USHORT ModeIndex = 0;
+
+ switch(HDisplay)
+ {
+ case 320:
+ if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth];
+ else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth];
+ break;
+ case 400:
+ if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
+ break;
+ case 512:
+ if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
+ break;
+ case 640:
+ if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
+ else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
+ break;
+ case 720:
+ if(VDisplay == 480) ModeIndex = ModeIndex_720x480[Depth];
+ else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
+ break;
+ case 768:
+ if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
+ break;
+ case 800:
+ if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
+ else if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
+ break;
+ case 848:
+ if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
+ break;
+ case 856:
+ if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
+ break;
+ case 960:
+ if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth];
+ else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth];
+ break;
+ case 1024:
+ if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
+ else if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
+ break;
+ case 1152:
+ if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
+ break;
+ case 1280:
+ switch(VDisplay) {
+ case 720:
+ ModeIndex = ModeIndex_1280x720[Depth];
+ break;
+ case 768:
+ ModeIndex = ModeIndex_1280x768[Depth];
+ break;
+ case 1024:
+ ModeIndex = ModeIndex_1280x1024[Depth];
+ break;
+ }
+ }
+
+ return(ModeIndex);
+}
+
+/*********************************************/
+/* HELPER: SetReg, GetReg */
+/*********************************************/
+
+static void
+SiS_SetReg(SiS_Private *SiS_Pr, SISIOADDRESS port, USHORT index, USHORT data)
+{
+ outSISIDXREG((SISUSBPtr)SiS_Pr->pSiSUSB, port, index, data);
+}
+
+static void
+SiS_SetRegByte(SiS_Private *SiS_Pr, SISIOADDRESS port, USHORT data)
+{
+ outSISREG((SISUSBPtr)SiS_Pr->pSiSUSB, port, data);
+}
+
+static UCHAR
+SiS_GetReg(SiS_Private *SiS_Pr, SISIOADDRESS port, USHORT index)
+{
+ return(__inSISIDXREG((SISUSBPtr)SiS_Pr->pSiSUSB, port, index));
+}
+
+static UCHAR
+SiS_GetRegByte(SiS_Private *SiS_Pr, SISIOADDRESS port)
+{
+ return(inSISREG((SISUSBPtr)SiS_Pr->pSiSUSB, port));
+}
+
+static void
+SiS_SetRegANDOR(SiS_Private *SiS_Pr, SISIOADDRESS port, USHORT index,
+ USHORT DataAND, USHORT DataOR)
+{
+ setSISIDXREG((SISUSBPtr)SiS_Pr->pSiSUSB, port, index, DataAND, DataOR);
+}
+
+static void
+SiS_SetRegAND(SiS_Private *SiS_Pr, SISIOADDRESS port, USHORT index, USHORT DataAND)
+{
+ andSISIDXREG((SISUSBPtr)SiS_Pr->pSiSUSB, port, index, DataAND);
+}
+
+static void
+SiS_SetRegOR(SiS_Private *SiS_Pr,SISIOADDRESS port, USHORT index, USHORT DataOR)
+{
+ orSISIDXREG((SISUSBPtr)SiS_Pr->pSiSUSB, port, index, DataOR);
+}
+
+/*********************************************/
+/* HELPER: DisplayOn, DisplayOff */
+/*********************************************/
+
+static void
+SiS_DisplayOn(SiS_Private *SiS_Pr)
+{
+ SiS_SetRegAND(SiS_Pr,SiS_Pr->SiS_P3c4,0x01,0xDF);
+}
+
+/*********************************************/
+/* HELPER: Init Port Addresses */
+/*********************************************/
+
+void
+SiSUSBRegInit(SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr)
+{
+ SiS_Pr->SiS_P3c4 = BaseAddr + 0x14;
+ SiS_Pr->SiS_P3d4 = BaseAddr + 0x24;
+ SiS_Pr->SiS_P3c0 = BaseAddr + 0x10;
+ SiS_Pr->SiS_P3ce = BaseAddr + 0x1e;
+ SiS_Pr->SiS_P3c2 = BaseAddr + 0x12;
+ SiS_Pr->SiS_P3ca = BaseAddr + 0x1a;
+ SiS_Pr->SiS_P3c6 = BaseAddr + 0x16;
+ SiS_Pr->SiS_P3c7 = BaseAddr + 0x17;
+ SiS_Pr->SiS_P3c8 = BaseAddr + 0x18;
+ SiS_Pr->SiS_P3c9 = BaseAddr + 0x19;
+ SiS_Pr->SiS_P3cb = BaseAddr + 0x1b;
+ SiS_Pr->SiS_P3cc = BaseAddr + 0x1c;
+ SiS_Pr->SiS_P3cd = BaseAddr + 0x1d;
+ SiS_Pr->SiS_P3da = BaseAddr + 0x2a;
+ SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04; /* Digital video interface registers (LCD) */
+}
+
+/*********************************************/
+/* HELPER: GetSysFlags */
+/*********************************************/
+
+static void
+SiS_GetSysFlags(SiS_Private *SiS_Pr)
+{
+ SiS_Pr->SiS_MyCR63 = 0x63;
+}
+
+/*********************************************/
+/* HELPER: Init PCI & Engines */
+/*********************************************/
+
+static void
+SiSInitPCIetc(SiS_Private *SiS_Pr)
+{
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3c4,0x20,0xa1);
+ /* - Enable 2D (0x40)
+ * - Enable 3D (0x02)
+ * - Enable 3D vertex command fetch (0x10)
+ * - Enable 3D command parser (0x08)
+ * - Enable 3D G/L transformation engine (0x80)
+ */
+ SiS_SetRegOR(SiS_Pr,SiS_Pr->SiS_P3c4,0x1E,0xDA);
+}
+
+/*********************************************/
+/* HELPER: SET SEGMENT REGISTERS */
+/*********************************************/
+
+static void
+SiS_SetSegRegLower(SiS_Private *SiS_Pr, USHORT value)
+{
+ USHORT temp;
+
+ value &= 0x00ff;
+ temp = SiS_GetRegByte(SiS_Pr,SiS_Pr->SiS_P3cb) & 0xf0;
+ temp |= (value >> 4);
+ SiS_SetRegByte(SiS_Pr,SiS_Pr->SiS_P3cb, temp);
+ temp = SiS_GetRegByte(SiS_Pr,SiS_Pr->SiS_P3cd) & 0xf0;
+ temp |= (value & 0x0f);
+ SiS_SetRegByte(SiS_Pr,SiS_Pr->SiS_P3cd, temp);
+}
+
+static void
+SiS_SetSegRegUpper(SiS_Private *SiS_Pr, USHORT value)
+{
+ USHORT temp;
+
+ value &= 0x00ff;
+ temp = SiS_GetRegByte(SiS_Pr,SiS_Pr->SiS_P3cb) & 0x0f;
+ temp |= (value & 0xf0);
+ SiS_SetRegByte(SiS_Pr,SiS_Pr->SiS_P3cb, temp);
+ temp = SiS_GetRegByte(SiS_Pr,SiS_Pr->SiS_P3cd) & 0x0f;
+ temp |= (value << 4);
+ SiS_SetRegByte(SiS_Pr,SiS_Pr->SiS_P3cd, temp);
+}
+
+static void
+SiS_SetSegmentReg(SiS_Private *SiS_Pr, USHORT value)
+{
+ SiS_SetSegRegLower(SiS_Pr, value);
+ SiS_SetSegRegUpper(SiS_Pr, value);
+}
+
+static void
+SiS_ResetSegmentReg(SiS_Private *SiS_Pr)
+{
+ SiS_SetSegmentReg(SiS_Pr, 0);
+}
+
+static void
+SiS_SetSegmentRegOver(SiS_Private *SiS_Pr, USHORT value)
+{
+ USHORT temp = value >> 8;
+
+ temp &= 0x07;
+ temp |= (temp << 4);
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3c4,0x1d,temp);
+ SiS_SetSegmentReg(SiS_Pr, value);
+}
+
+static void
+SiS_ResetSegmentRegOver(SiS_Private *SiS_Pr)
+{
+ SiS_SetSegmentRegOver(SiS_Pr, 0);
+}
+
+static void
+SiS_ResetSegmentRegisters(SiS_Private *SiS_Pr)
+{
+ SiS_ResetSegmentReg(SiS_Pr);
+ SiS_ResetSegmentRegOver(SiS_Pr);
+}
+
+/*********************************************/
+/* HELPER: SearchModeID */
+/*********************************************/
+
+static BOOLEAN
+SiS_SearchModeID(SiS_Private *SiS_Pr, USHORT *ModeNo, USHORT *ModeIdIndex)
+{
+ if((*ModeNo) <= 0x13) {
+
+ return FALSE;
+
+ } else {
+
+ for(*ModeIdIndex = 0; ;(*ModeIdIndex)++) {
+ if(SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == (*ModeNo)) break;
+ if(SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF) return FALSE;
+ }
+
+ }
+ return TRUE;
+}
+
+/*********************************************/
+/* HELPER: ENABLE CRT1 */
+/*********************************************/
+
+static void
+SiS_HandleCRT1(SiS_Private *SiS_Pr)
+{
+ /* Enable CRT1 gating */
+ SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0xbf);
+}
+
+/*********************************************/
+/* HELPER: GetColorDepth */
+/*********************************************/
+
+static USHORT
+SiS_GetColorDepth(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex)
+{
+ USHORT ColorDepth[6] = { 1, 2, 4, 4, 6, 8};
+ SHORT index;
+ USHORT modeflag;
+
+ /* Do NOT check UseCustomMode, will skrew up FIFO */
+ if(ModeNo == 0xfe) {
+ modeflag = SiS_Pr->CModeFlag;
+ } else {
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ }
+
+ index = (modeflag & ModeTypeMask) - ModeEGA;
+ if(index < 0) index = 0;
+ return ColorDepth[index];
+}
+
+/*********************************************/
+/* HELPER: GetOffset */
+/*********************************************/
+
+static USHORT
+SiS_GetOffset(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex)
+{
+ USHORT xres, temp, colordepth, infoflag;
+
+ if(SiS_Pr->UseCustomMode) {
+ infoflag = SiS_Pr->CInfoFlag;
+ xres = SiS_Pr->CHDisplay;
+ } else {
+ infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+ xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
+ }
+
+ colordepth = SiS_GetColorDepth(SiS_Pr,ModeNo,ModeIdIndex);
+
+ temp = xres / 16;
+ if(infoflag & InterlaceMode) temp <<= 1;
+ temp *= colordepth;
+ if(xres % 16) {
+ colordepth >>= 1;
+ temp += colordepth;
+ }
+
+ return(temp);
+}
+
+/*********************************************/
+/* SEQ */
+/*********************************************/
+
+static void
+SiS_SetSeqRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex)
+{
+ UCHAR SRdata;
+ int i;
+
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3c4,0x00,0x03);
+
+ /* "display off" */
+ SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0] | 0x20;
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3c4,0x01,SRdata);
+
+ for(i = 2; i <= 4; i++) {
+ SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i-1];
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3c4,i,SRdata);
+ }
+}
+
+/*********************************************/
+/* MISC */
+/*********************************************/
+
+static void
+SiS_SetMiscRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex)
+{
+ UCHAR Miscdata;
+
+ Miscdata = SiS_Pr->SiS_StandTable[StandTableIndex].MISC;
+ SiS_SetRegByte(SiS_Pr,SiS_Pr->SiS_P3c2,Miscdata);
+}
+
+/*********************************************/
+/* CRTC */
+/*********************************************/
+
+static void
+SiS_SetCRTCRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex)
+{
+ UCHAR CRTCdata;
+ USHORT i;
+
+ SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3d4,0x11,0x7f); /* Unlock CRTC */
+
+ for(i = 0; i <= 0x18; i++) {
+ CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i];
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3d4,i,CRTCdata); /* Set CRTC(3d4) */
+ }
+}
+
+/*********************************************/
+/* ATT */
+/*********************************************/
+
+static void
+SiS_SetATTRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex)
+{
+ UCHAR ARdata;
+ USHORT i;
+
+ for(i = 0; i <= 0x13; i++) {
+ ARdata = SiS_Pr->SiS_StandTable[StandTableIndex].ATTR[i];
+ SiS_GetRegByte(SiS_Pr,SiS_Pr->SiS_P3da); /* reset 3da */
+ SiS_SetRegByte(SiS_Pr,SiS_Pr->SiS_P3c0,i); /* set index */
+ SiS_SetRegByte(SiS_Pr,SiS_Pr->SiS_P3c0,ARdata); /* set data */
+ }
+ SiS_GetRegByte(SiS_Pr,SiS_Pr->SiS_P3da); /* reset 3da */
+ SiS_SetRegByte(SiS_Pr,SiS_Pr->SiS_P3c0,0x14); /* set index */
+ SiS_SetRegByte(SiS_Pr,SiS_Pr->SiS_P3c0,0x00); /* set data */
+
+ SiS_GetRegByte(SiS_Pr,SiS_Pr->SiS_P3da);
+ SiS_SetRegByte(SiS_Pr,SiS_Pr->SiS_P3c0,0x20); /* Enable Attribute */
+ SiS_GetRegByte(SiS_Pr,SiS_Pr->SiS_P3da);
+}
+
+/*********************************************/
+/* GRC */
+/*********************************************/
+
+static void
+SiS_SetGRCRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex)
+{
+ UCHAR GRdata;
+ USHORT i;
+
+ for(i = 0; i <= 0x08; i++) {
+ GRdata = SiS_Pr->SiS_StandTable[StandTableIndex].GRC[i];
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3ce,i,GRdata);
+ }
+
+ if(SiS_Pr->SiS_ModeType > ModeVGA) {
+ /* 256 color disable */
+ SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3ce,0x05,0xBF);
+ }
+}
+
+/*********************************************/
+/* CLEAR EXTENDED REGISTERS */
+/*********************************************/
+
+static void
+SiS_ClearExt1Regs(SiS_Private *SiS_Pr, USHORT ModeNo)
+{
+ USHORT i;
+
+ for(i = 0x0A; i <= 0x0E; i++) {
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3c4,i,0x00);
+ }
+
+ SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4,0x37,0xFE);
+}
+
+/*********************************************/
+/* Get rate index */
+/*********************************************/
+
+static USHORT
+SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex)
+{
+ USHORT RRTI,i,index,temp;
+
+ /* Do NOT check for UseCustomMode here, will skrew up FIFO */
+ if(ModeNo == 0xfe) return 0;
+
+ index = SiS_GetReg(SiS_Pr,SiS_Pr->SiS_P3d4,0x33) & 0x0F;
+ if(index > 0) index--;
+
+ RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
+ ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;
+
+ i = 0;
+ do {
+ if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break;
+ temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag;
+ temp &= ModeTypeMask;
+ if(temp < SiS_Pr->SiS_ModeType) break;
+ i++;
+ index--;
+ } while(index != 0xFFFF);
+
+ i--;
+
+ return(RRTI + i);
+}
+
+/*********************************************/
+/* SYNC */
+/*********************************************/
+
+static void
+SiS_SetCRT1Sync(SiS_Private *SiS_Pr, USHORT RefreshRateTableIndex)
+{
+ USHORT sync;
+
+ if(SiS_Pr->UseCustomMode) {
+ sync = SiS_Pr->CInfoFlag >> 8;
+ } else {
+ sync = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8;
+ }
+
+ sync &= 0xC0;
+ sync |= 0x2f;
+ SiS_SetRegByte(SiS_Pr,SiS_Pr->SiS_P3c2,sync);
+}
+
+/*********************************************/
+/* CRTC/2 */
+/*********************************************/
+
+static void
+SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex)
+{
+ UCHAR index;
+ USHORT temp,i,j,modeflag;
+
+ SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3d4,0x11,0x7f); /* unlock cr0-7 */
+
+ if(SiS_Pr->UseCustomMode) {
+
+ modeflag = SiS_Pr->CModeFlag;
+
+ for(i=0,j=0;i<=7;i++,j++) {
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
+ }
+ for(j=0x10;i<=10;i++,j++) {
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
+ }
+ for(j=0x15;i<=12;i++,j++) {
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
+ }
+ for(j=0x0A;i<=15;i++,j++) {
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3c4,j,SiS_Pr->CCRT1CRTC[i]);
+ }
+
+ temp = SiS_Pr->CCRT1CRTC[16] & 0xE0;
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3c4,0x0E,temp);
+
+ temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
+ if(modeflag & DoubleScanMode) temp |= 0x80;
+ SiS_SetRegANDOR(SiS_Pr,SiS_Pr->SiS_P3d4,0x09,0x5F,temp);
+
+ } else {
+
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+ index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+
+ for(i=0,j=0;i<=7;i++,j++) {
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3d4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
+ }
+ for(j=0x10;i<=10;i++,j++) {
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3d4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
+ }
+ for(j=0x15;i<=12;i++,j++) {
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3d4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
+ }
+ for(j=0x0A;i<=15;i++,j++) {
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3c4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
+ }
+
+ temp = SiS_Pr->SiS_CRT1Table[index].CR[16] & 0xE0;
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3c4,0x0E,temp);
+
+ temp = ((SiS_Pr->SiS_CRT1Table[index].CR[16]) & 0x01) << 5;
+ if(modeflag & DoubleScanMode) temp |= 0x80;
+ SiS_SetRegANDOR(SiS_Pr,SiS_Pr->SiS_P3d4,0x09,0x5F,temp);
+
+ }
+
+ if(SiS_Pr->SiS_ModeType > ModeVGA) SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3d4,0x14,0x4F);
+}
+
+/*********************************************/
+/* OFFSET & PITCH */
+/*********************************************/
+/* (partly overruled by SetPitch() in XF86) */
+/*********************************************/
+
+static void
+SiS_SetCRT1Offset(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex)
+{
+ USHORT temp, DisplayUnit, infoflag;
+
+ if(SiS_Pr->UseCustomMode) {
+ infoflag = SiS_Pr->CInfoFlag;
+ } else {
+ infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+ }
+
+ DisplayUnit = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex, RefreshRateTableIndex);
+
+ temp = (DisplayUnit >> 8) & 0x0f;
+ SiS_SetRegANDOR(SiS_Pr,SiS_Pr->SiS_P3c4,0x0E,0xF0,temp);
+
+ temp = DisplayUnit & 0xFF;
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3d4,0x13,temp);
+
+ if(infoflag & InterlaceMode) DisplayUnit >>= 1;
+
+ DisplayUnit <<= 5;
+ temp = (DisplayUnit & 0xff00) >> 8;
+ if(DisplayUnit & 0xff) temp++;
+ temp++;
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3c4,0x10,temp);
+}
+
+/*********************************************/
+/* VCLK */
+/*********************************************/
+
+static void
+SiS_SetCRT1VCLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex)
+{
+ USHORT index=0, clka, clkb;
+
+ if(SiS_Pr->UseCustomMode) {
+ clka = SiS_Pr->CSR2B;
+ clkb = SiS_Pr->CSR2C;
+ } else {
+ index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+ clka = SiS_Pr->SiS_VCLKData[index].SR2B;
+ clkb = SiS_Pr->SiS_VCLKData[index].SR2C;
+ }
+
+ SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4,0x31,0xCF);
+
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3c4,0x2B,clka);
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3c4,0x2C,clkb);
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3c4,0x2D,0x01);
+
+}
+
+/*********************************************/
+/* FIFO */
+/*********************************************/
+
+static void
+SiS_SetCRT1FIFO_310(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex)
+{
+ USHORT modeflag;
+
+ /* disable auto-threshold */
+ SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4,0x3D,0xFE);
+
+ if(SiS_Pr->UseCustomMode) {
+ modeflag = SiS_Pr->CModeFlag;
+ } else {
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ }
+
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3c4,0x08,0xAE);
+ SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4,0x09,0xF0);
+
+ if((!(modeflag & DoubleScanMode)) || (!(modeflag & HalfDCLK))) {
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3c4,0x08,0x34);
+ SiS_SetRegOR(SiS_Pr,SiS_Pr->SiS_P3c4,0x3D,0x01);
+ }
+}
+
+/*********************************************/
+/* MODE REGISTERS */
+/*********************************************/
+
+static void
+SiS_SetVCLKState(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT RefreshRateTableIndex,
+ USHORT ModeIdIndex)
+{
+ USHORT data=0, VCLK=0, index=0;
+
+ if(SiS_Pr->UseCustomMode) {
+ VCLK = SiS_Pr->CSRClock;
+ } else {
+ index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+ VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
+ }
+
+ if(VCLK >= 166) data |= 0x0c;
+ SiS_SetRegANDOR(SiS_Pr,SiS_Pr->SiS_P3c4,0x32,0xf3,data);
+
+ if(VCLK >= 166) {
+ SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4,0x1f,0xe7);
+ }
+
+ /* DAC speed */
+ data = 0x03;
+ if((VCLK >= 135) && (VCLK < 160)) data = 0x02;
+ else if((VCLK >= 160) && (VCLK < 260)) data = 0x01;
+ else if(VCLK >= 260) data = 0x00;
+ SiS_SetRegANDOR(SiS_Pr,SiS_Pr->SiS_P3c4,0x07,0xF8,data);
+}
+
+static void
+SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex)
+{
+ USHORT data,infoflag=0,modeflag;
+ USHORT resindex,xres;
+
+ if(SiS_Pr->UseCustomMode) {
+ modeflag = SiS_Pr->CModeFlag;
+ infoflag = SiS_Pr->CInfoFlag;
+ xres = SiS_Pr->CHDisplay;
+ } else {
+ resindex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+ xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
+ }
+
+ /* Disable DPMS */
+ SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4,0x1F,0x3F);
+
+ data = 0;
+ if(SiS_Pr->SiS_ModeType > ModeEGA) {
+ data |= 0x02;
+ data |= ((SiS_Pr->SiS_ModeType - ModeVGA) << 2);
+ }
+ if(infoflag & InterlaceMode) data |= 0x20;
+ SiS_SetRegANDOR(SiS_Pr,SiS_Pr->SiS_P3c4,0x06,0xC0,data);
+
+ data = 0;
+ if(infoflag & InterlaceMode) {
+ /* data = (Hsync / 8) - ((Htotal / 8) / 2) + 3 */
+ USHORT hrs = (SiS_GetReg(SiS_Pr,SiS_Pr->SiS_P3d4,0x04) |
+ ((SiS_GetReg(SiS_Pr,SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2)) - 3;
+ USHORT hto = (SiS_GetReg(SiS_Pr,SiS_Pr->SiS_P3d4,0x00) |
+ ((SiS_GetReg(SiS_Pr,SiS_Pr->SiS_P3c4,0x0b) & 0x03) << 8)) + 5;
+ data = hrs - (hto >> 1) + 3;
+#if 0
+ if(xres <= 800) data = 0x0020; /* guessed */
+ else if(xres <= 1024) data = 0x0035; /* 1024x768 */
+ else data = 0x0048; /* 1280x1024 */
+#endif
+ }
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3d4,0x19,(data & 0xFF));
+ SiS_SetRegANDOR(SiS_Pr,SiS_Pr->SiS_P3d4,0x1a,0xFC,(data >> 8));
+
+ if(modeflag & HalfDCLK) {
+ SiS_SetRegOR(SiS_Pr,SiS_Pr->SiS_P3c4,0x01,0x08);
+ }
+
+ data = 0;
+ if(modeflag & LineCompareOff) data = 0x08;
+ SiS_SetRegANDOR(SiS_Pr,SiS_Pr->SiS_P3c4,0x0F,0xB7,data);
+ if(SiS_Pr->SiS_ModeType == ModeEGA) {
+ SiS_SetRegOR(SiS_Pr,SiS_Pr->SiS_P3c4,0x0F,0x40);
+ }
+
+ SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4,0x31,0xfb);
+
+ data = 0x60;
+ if(SiS_Pr->SiS_ModeType != ModeText) {
+ data ^= 0x60;
+ if(SiS_Pr->SiS_ModeType != ModeEGA) {
+ data ^= 0xA0;
+ }
+ }
+ SiS_SetRegANDOR(SiS_Pr,SiS_Pr->SiS_P3c4,0x21,0x1F,data);
+
+ SiS_SetVCLKState(SiS_Pr, ModeNo, RefreshRateTableIndex, ModeIdIndex);
+
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3d4,0x52,0x2c);
+}
+
+/*********************************************/
+/* LOAD DAC */
+/*********************************************/
+
+static void
+SiS_WriteDAC(SiS_Private *SiS_Pr, SISIOADDRESS DACData, USHORT shiftflag,
+ USHORT dl, USHORT ah, USHORT al, USHORT dh)
+{
+ USHORT temp,bh,bl;
+
+ bh = ah;
+ bl = al;
+ if(dl != 0) {
+ temp = bh;
+ bh = dh;
+ dh = temp;
+ if(dl == 1) {
+ temp = bl;
+ bl = dh;
+ dh = temp;
+ } else {
+ temp = bl;
+ bl = bh;
+ bh = temp;
+ }
+ }
+ if(shiftflag) {
+ dh <<= 2;
+ bh <<= 2;
+ bl <<= 2;
+ }
+ SiS_SetRegByte(SiS_Pr,DACData,(USHORT)dh);
+ SiS_SetRegByte(SiS_Pr,DACData,(USHORT)bh);
+ SiS_SetRegByte(SiS_Pr,DACData,(USHORT)bl);
+}
+
+static void
+SiS_LoadDAC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex)
+{
+ USHORT data,data2;
+ USHORT time,i,j,k,m,n,o;
+ USHORT si,di,bx,dl,al,ah,dh;
+ USHORT shiftflag;
+ SISIOADDRESS DACAddr, DACData;
+ const USHORT *table = NULL;
+
+ if(SiS_Pr->UseCustomMode) {
+ data = SiS_Pr->CModeFlag;
+ } else {
+ data = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ }
+
+ data &= DACInfoFlag;
+
+ time = 256;
+ table = SiS_VGA_DAC;
+
+ if(time == 256) j = 16;
+ else j = time;
+
+ DACAddr = SiS_Pr->SiS_P3c8;
+ DACData = SiS_Pr->SiS_P3c9;
+ shiftflag = 0;
+ SiS_SetRegByte(SiS_Pr,SiS_Pr->SiS_P3c6,0xFF);
+
+ SiS_SetRegByte(SiS_Pr,DACAddr,0x00);
+
+ for(i=0; i<j; i++) {
+ data = table[i];
+ for(k=0; k<3; k++) {
+ data2 = 0;
+ if(data & 0x01) data2 = 0x2A;
+ if(data & 0x02) data2 += 0x15;
+ if(shiftflag) data2 <<= 2;
+ SiS_SetRegByte(SiS_Pr,DACData, data2);
+ data >>= 2;
+ }
+ }
+
+ if(time == 256) {
+ for(i = 16; i < 32; i++) {
+ data = table[i];
+ if(shiftflag) data <<= 2;
+ for(k = 0; k < 3; k++) SiS_SetRegByte(SiS_Pr,DACData, data);
+ }
+ si = 32;
+ for(m = 0; m < 9; m++) {
+ di = si;
+ bx = si + 4;
+ dl = 0;
+ for(n = 0; n < 3; n++) {
+ for(o = 0; o < 5; o++) {
+ dh = table[si];
+ ah = table[di];
+ al = table[bx];
+ si++;
+ SiS_WriteDAC(SiS_Pr, DACData, shiftflag, dl, ah, al, dh);
+ }
+ si -= 2;
+ for(o = 0; o < 3; o++) {
+ dh = table[bx];
+ ah = table[di];
+ al = table[si];
+ si--;
+ SiS_WriteDAC(SiS_Pr, DACData, shiftflag, dl, ah, al, dh);
+ }
+ dl++;
+ } /* for n < 3 */
+ si += 5;
+ } /* for m < 9 */
+ }
+}
+
+/*********************************************/
+/* SET CRT1 REGISTER GROUP */
+/*********************************************/
+
+static void
+SiS_SetCRT1Group(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex)
+{
+ USHORT StandTableIndex,RefreshRateTableIndex;
+
+ SiS_Pr->SiS_CRT1Mode = ModeNo;
+ StandTableIndex = 0;
+
+ SiS_ResetSegmentRegisters(SiS_Pr);
+ SiS_SetSeqRegs(SiS_Pr, StandTableIndex);
+ SiS_SetMiscRegs(SiS_Pr, StandTableIndex);
+ SiS_SetCRTCRegs(SiS_Pr, StandTableIndex);
+ SiS_SetATTRegs(SiS_Pr, StandTableIndex);
+ SiS_SetGRCRegs(SiS_Pr, StandTableIndex);
+ SiS_ClearExt1Regs(SiS_Pr, ModeNo);
+
+ RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);
+
+ if(RefreshRateTableIndex != 0xFFFF) {
+ SiS_SetCRT1Sync(SiS_Pr, RefreshRateTableIndex);
+ SiS_SetCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+ SiS_SetCRT1Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+ SiS_SetCRT1VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+ }
+
+ SiS_SetCRT1FIFO_310(SiS_Pr, ModeNo, ModeIdIndex);
+
+ SiS_SetCRT1ModeRegs(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+
+ SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
+
+ SiS_DisplayOn(SiS_Pr);
+}
+
+/*********************************************/
+/* XFree86: SET SCREEN PITCH */
+/*********************************************/
+
+static void
+SiS_SetPitch(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ UShort HDisplay = pSiSUSB->scrnPitch >> 3;
+
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3d4,0x13,(HDisplay & 0xFF));
+ SiS_SetRegANDOR(SiS_Pr,SiS_Pr->SiS_P3c4,0x0E,0xF0,(HDisplay >> 8));
+}
+
+/*********************************************/
+/* SiSSetMode() */
+/*********************************************/
+
+BOOLEAN
+SiSUSBSetMode(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, USHORT ModeNo, BOOLEAN dosetpitch)
+{
+ USHORT ModeIdIndex;
+ SISIOADDRESS BaseAddr = SiS_Pr->IOAddress;
+
+ if(SiS_Pr->UseCustomMode) {
+ ModeNo = 0xfe;
+ }
+
+ SiSUSB_InitPtr(SiS_Pr);
+ SiSUSBRegInit(SiS_Pr, BaseAddr);
+ SiS_GetSysFlags(SiS_Pr);
+
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3c4,0x05,0x86);
+
+ SiSInitPCIetc(SiS_Pr);
+
+ if(!SiS_Pr->UseCustomMode) ModeNo &= 0x7f;
+
+ if(!SiS_Pr->UseCustomMode) {
+ if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE;
+ SiS_Pr->SiS_ModeType = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag & ModeTypeMask;
+ } else {
+ ModeIdIndex = 0;
+ SiS_Pr->SiS_ModeType = SiS_Pr->CModeFlag & ModeTypeMask;
+ }
+
+ SiS_Pr->SiS_SetFlag = LowModeTests;
+
+ /* Set mode on CRT1 */
+ SiS_SetCRT1Group(SiS_Pr, ModeNo, ModeIdIndex);
+
+ SiS_HandleCRT1(SiS_Pr);
+
+ SiS_DisplayOn(SiS_Pr);
+ SiS_SetRegByte(SiS_Pr,SiS_Pr->SiS_P3c6,0xFF);
+
+ if(pScrn) {
+ /* SetPitch: Adapt to virtual size & position */
+ if((ModeNo > 0x13) && (dosetpitch)) {
+ SiS_SetPitch(SiS_Pr, pScrn);
+ }
+ }
+
+ /* Store mode number */
+ SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3d4,0x34,ModeNo);
+
+ return TRUE;
+}
+
+/*********************************************/
+/* XFree86: SiSBIOSSetMode() */
+/* for non-Dual-Head mode */
+/*********************************************/
+
+BOOLEAN
+SiSUSBBIOSSetMode(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
+ DisplayModePtr mode, BOOLEAN IsCustom)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ UShort ModeNo = 0;
+
+ SiS_Pr->UseCustomMode = FALSE;
+
+ if((IsCustom) && (SiSUSB_CheckBuildCustomMode(pScrn, mode, pSiSUSB->VBFlags))) {
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting custom mode %dx%d\n",
+ SiS_Pr->CHDisplay,
+ (mode->Flags & V_INTERLACE ? SiS_Pr->CVDisplay * 2 :
+ (mode->Flags & V_DBLSCAN ? SiS_Pr->CVDisplay / 2 :
+ SiS_Pr->CVDisplay)));
+
+ } else {
+
+ /* Don't need vbflags here; checks done earlier */
+ ModeNo = SiSUSB_GetModeNumber(pScrn, mode, 0);
+ if(!ModeNo) return FALSE;
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting standard mode 0x%x\n", ModeNo);
+
+ }
+
+ return(SiSUSBSetMode(SiS_Pr, pScrn, ModeNo, TRUE));
+}
+
+/* Helper functions */
+
+#ifndef GETBITSTR
+#define BITMASK(h,l) (((unsigned)(1U << ((h)-(l)+1))-1)<<(l))
+#define GENMASK(mask) BITMASK(1?mask,0?mask)
+#define GETBITS(var,mask) (((var) & GENMASK(mask)) >> (0?mask))
+#define GETBITSTR(val,from,to) ((GETBITS(val,from)) << (0?to))
+#endif
+
+static void
+SiSUSB_CalcCRRegisters(SiS_Private *SiS_Pr, int depth)
+{
+ SiS_Pr->CCRT1CRTC[0] = ((SiS_Pr->CHTotal >> 3) - 5) & 0xff; /* CR0 */
+ SiS_Pr->CCRT1CRTC[1] = (SiS_Pr->CHDisplay >> 3) - 1; /* CR1 */
+ SiS_Pr->CCRT1CRTC[2] = (SiS_Pr->CHBlankStart >> 3) - 1; /* CR2 */
+ SiS_Pr->CCRT1CRTC[3] = (((SiS_Pr->CHBlankEnd >> 3) - 1) & 0x1F) | 0x80; /* CR3 */
+ SiS_Pr->CCRT1CRTC[4] = (SiS_Pr->CHSyncStart >> 3) + 3; /* CR4 */
+ SiS_Pr->CCRT1CRTC[5] = ((((SiS_Pr->CHBlankEnd >> 3) - 1) & 0x20) << 2) | /* CR5 */
+ (((SiS_Pr->CHSyncEnd >> 3) + 3) & 0x1F);
+
+ SiS_Pr->CCRT1CRTC[6] = (SiS_Pr->CVTotal - 2) & 0xFF; /* CR6 */
+ SiS_Pr->CCRT1CRTC[7] = (((SiS_Pr->CVTotal - 2) & 0x100) >> 8) /* CR7 */
+ | (((SiS_Pr->CVDisplay - 1) & 0x100) >> 7)
+ | ((SiS_Pr->CVSyncStart & 0x100) >> 6)
+ | (((SiS_Pr->CVBlankStart - 1) & 0x100) >> 5)
+ | 0x10
+ | (((SiS_Pr->CVTotal - 2) & 0x200) >> 4)
+ | (((SiS_Pr->CVDisplay - 1) & 0x200) >> 3)
+ | ((SiS_Pr->CVSyncStart & 0x200) >> 2);
+
+ SiS_Pr->CCRT1CRTC[16] = ((((SiS_Pr->CVBlankStart - 1) & 0x200) >> 4) >> 5); /* CR9 */
+
+ if(depth != 8) {
+ if(SiS_Pr->CHDisplay >= 1600) SiS_Pr->CCRT1CRTC[16] |= 0x60; /* SRE */
+ else if(SiS_Pr->CHDisplay >= 640) SiS_Pr->CCRT1CRTC[16] |= 0x40;
+ }
+
+ SiS_Pr->CCRT1CRTC[8] = (SiS_Pr->CVSyncStart ) & 0xFF; /* CR10 */
+ SiS_Pr->CCRT1CRTC[9] = ((SiS_Pr->CVSyncEnd ) & 0x0F) | 0x80; /* CR11 */
+ SiS_Pr->CCRT1CRTC[10] = (SiS_Pr->CVDisplay - 1) & 0xFF; /* CR12 */
+ SiS_Pr->CCRT1CRTC[11] = (SiS_Pr->CVBlankStart - 1) & 0xFF; /* CR15 */
+ SiS_Pr->CCRT1CRTC[12] = (SiS_Pr->CVBlankEnd - 1) & 0xFF; /* CR16 */
+
+ SiS_Pr->CCRT1CRTC[13] = /* SRA */
+ GETBITSTR((SiS_Pr->CVTotal -2), 10:10, 0:0) |
+ GETBITSTR((SiS_Pr->CVDisplay -1), 10:10, 1:1) |
+ GETBITSTR((SiS_Pr->CVBlankStart-1), 10:10, 2:2) |
+ GETBITSTR((SiS_Pr->CVSyncStart ), 10:10, 3:3) |
+ GETBITSTR((SiS_Pr->CVBlankEnd -1), 8:8, 4:4) |
+ GETBITSTR((SiS_Pr->CVSyncEnd ), 4:4, 5:5) ;
+
+ SiS_Pr->CCRT1CRTC[14] = /* SRB */
+ GETBITSTR((SiS_Pr->CHTotal >> 3) - 5, 9:8, 1:0) |
+ GETBITSTR((SiS_Pr->CHDisplay >> 3) - 1, 9:8, 3:2) |
+ GETBITSTR((SiS_Pr->CHBlankStart >> 3) - 1, 9:8, 5:4) |
+ GETBITSTR((SiS_Pr->CHSyncStart >> 3) + 3, 9:8, 7:6) ;
+
+
+ SiS_Pr->CCRT1CRTC[15] = /* SRC */
+ GETBITSTR((SiS_Pr->CHBlankEnd >> 3) - 1, 7:6, 1:0) |
+ GETBITSTR((SiS_Pr->CHSyncEnd >> 3) + 3, 5:5, 2:2) ;
+}
+
+void
+SiSUSB_MakeClockRegs(ScrnInfoPtr pScrn, int clock, UCHAR *p2b, UCHAR *p2c)
+{
+ int out_n, out_dn, out_div, out_sbit, out_scale;
+ unsigned int vclk[5];
+
+#define Midx 0
+#define Nidx 1
+#define VLDidx 2
+#define Pidx 3
+#define PSNidx 4
+
+ if(SiSUSB_compute_vclk(clock, &out_n, &out_dn, &out_div, &out_sbit, &out_scale)) {
+ (*p2b) = (out_div == 2) ? 0x80 : 0x00;
+ (*p2b) |= ((out_n - 1) & 0x7f);
+ (*p2c) = (out_dn - 1) & 0x1f;
+ (*p2c) |= (((out_scale - 1) & 3) << 5);
+ (*p2c) |= ((out_sbit & 0x01) << 7);
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sb %d sc %d\n",
+ clock, out_n, out_dn, out_div, out_sbit, out_scale);
+#endif
+ } else {
+ SiSUSBCalcClock(pScrn, clock, 2, vclk);
+ (*p2b) = (vclk[VLDidx] == 2) ? 0x80 : 0x00;
+ (*p2b) |= (vclk[Midx] - 1) & 0x7f;
+ (*p2c) = (vclk[Nidx] - 1) & 0x1f;
+ if(vclk[Pidx] <= 4) {
+ /* postscale 1,2,3,4 */
+ (*p2c) |= ((vclk[Pidx] - 1) & 3) << 5;
+ } else {
+ /* postscale 6,8 */
+ (*p2c) |= (((vclk[Pidx] / 2) - 1) & 3) << 5;
+ (*p2c) |= 0x80;
+ }
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sc %d\n",
+ clock, vclk[Midx], vclk[Nidx], vclk[VLDidx], vclk[Pidx]);
+#endif
+ }
+}
+
+USHORT
+SiSUSB_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, unsigned int VBFlags)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ int depth = pSiSUSB->CurrentLayout.bitsPerPixel;
+
+ pSiSUSB->SiS_Pr->CModeFlag = 0;
+
+ pSiSUSB->SiS_Pr->CDClock = mode->Clock;
+
+ pSiSUSB->SiS_Pr->CHDisplay = mode->HDisplay;
+ pSiSUSB->SiS_Pr->CHSyncStart = mode->HSyncStart;
+ pSiSUSB->SiS_Pr->CHSyncEnd = mode->HSyncEnd;
+ pSiSUSB->SiS_Pr->CHTotal = mode->HTotal;
+
+ pSiSUSB->SiS_Pr->CVDisplay = mode->VDisplay;
+ pSiSUSB->SiS_Pr->CVSyncStart = mode->VSyncStart;
+ pSiSUSB->SiS_Pr->CVSyncEnd = mode->VSyncEnd;
+ pSiSUSB->SiS_Pr->CVTotal = mode->VTotal;
+
+ pSiSUSB->SiS_Pr->CFlags = mode->Flags;
+
+ if(pSiSUSB->SiS_Pr->CFlags & V_INTERLACE) {
+ pSiSUSB->SiS_Pr->CVDisplay >>= 1;
+ pSiSUSB->SiS_Pr->CVSyncStart >>= 1;
+ pSiSUSB->SiS_Pr->CVSyncEnd >>= 1;
+ pSiSUSB->SiS_Pr->CVTotal >>= 1;
+ } else if(pSiSUSB->SiS_Pr->CFlags & V_DBLSCAN) {
+ pSiSUSB->SiS_Pr->CVDisplay <<= 1;
+ pSiSUSB->SiS_Pr->CVSyncStart <<= 1;
+ pSiSUSB->SiS_Pr->CVSyncEnd <<= 1;
+ pSiSUSB->SiS_Pr->CVTotal <<= 1;
+ }
+
+ pSiSUSB->SiS_Pr->CHBlankStart = pSiSUSB->SiS_Pr->CHDisplay;
+ pSiSUSB->SiS_Pr->CHBlankEnd = pSiSUSB->SiS_Pr->CHTotal;
+ pSiSUSB->SiS_Pr->CVBlankStart = pSiSUSB->SiS_Pr->CVSyncStart - 1;
+ pSiSUSB->SiS_Pr->CVBlankEnd = pSiSUSB->SiS_Pr->CVTotal;
+
+ if((!(mode->type & M_T_BUILTIN)) && (mode->HDisplay <= 512)) {
+ pSiSUSB->SiS_Pr->CModeFlag |= HalfDCLK;
+ pSiSUSB->SiS_Pr->CDClock <<= 1;
+ }
+
+ /* Note: For CRT2, HDisplay, HSync* and HTotal must be shifted left
+ * in HalfDCLK mode.
+ */
+
+ SiSUSB_MakeClockRegs(pScrn, pSiSUSB->SiS_Pr->CDClock, &pSiSUSB->SiS_Pr->CSR2B, &pSiSUSB->SiS_Pr->CSR2C);
+
+ pSiSUSB->SiS_Pr->CSRClock = (pSiSUSB->SiS_Pr->CDClock / 1000) + 1;
+
+ SiSUSB_CalcCRRegisters(pSiSUSB->SiS_Pr, depth);
+
+ switch(depth) {
+ case 8: pSiSUSB->SiS_Pr->CModeFlag |= 0x223b; break;
+ case 16: pSiSUSB->SiS_Pr->CModeFlag |= 0x227d; break;
+ case 32: pSiSUSB->SiS_Pr->CModeFlag |= 0x22ff; break;
+ default: return 0;
+ }
+
+ if(pSiSUSB->SiS_Pr->CFlags & V_DBLSCAN)
+ pSiSUSB->SiS_Pr->CModeFlag |= DoubleScanMode;
+
+ if((pSiSUSB->SiS_Pr->CVDisplay >= 1024) ||
+ (pSiSUSB->SiS_Pr->CVTotal >= 1024) ||
+ (pSiSUSB->SiS_Pr->CHDisplay >= 1024))
+ pSiSUSB->SiS_Pr->CModeFlag |= LineCompareOff;
+
+ pSiSUSB->SiS_Pr->CInfoFlag = 0x0007;
+
+ if(pSiSUSB->SiS_Pr->CFlags & V_NHSYNC)
+ pSiSUSB->SiS_Pr->CInfoFlag |= 0x4000;
+
+ if(pSiSUSB->SiS_Pr->CFlags & V_NVSYNC)
+ pSiSUSB->SiS_Pr->CInfoFlag |= 0x8000;
+
+ if(pSiSUSB->SiS_Pr->CFlags & V_INTERLACE)
+ pSiSUSB->SiS_Pr->CInfoFlag |= InterlaceMode;
+
+ pSiSUSB->SiS_Pr->UseCustomMode = TRUE;
+ return 1;
+}
+
+/* Build a list of supported modes:
+ * Built-in modes for which we have all data are M_T_DEFAULT,
+ * modes derived from DDC or database data are M_T_BUILTIN
+ */
+DisplayModePtr
+SiSUSBBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes, BOOLEAN isfordvi, BOOLEAN fakecrt2modes)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ unsigned short VRE, VBE, VRS, VBS, VDE, VT;
+ unsigned short HRE, HBE, HRS, HBS, HDE, HT;
+ unsigned char sr_data, cr_data, cr_data2, cr_data3;
+ unsigned char sr2b, sr2c;
+ float num, denum, postscalar, divider;
+ int A, B, C, D, E, F, temp, i, j, index, vclkindex;
+ DisplayModePtr new = NULL, current = NULL, first = NULL;
+ BOOLEAN IsHDCLK;
+#if 0
+ DisplayModePtr backup = NULL;
+#endif
+
+ pSiSUSB->backupmodelist = NULL;
+
+ SiSUSB_InitPtr(pSiSUSB->SiS_Pr);
+
+ i = 0;
+ while(pSiSUSB->SiS_Pr->SiS_RefIndex[i].Ext_InfoFlag != 0xFFFF) {
+
+ index = pSiSUSB->SiS_Pr->SiS_RefIndex[i].Ext_CRT1CRTC;
+ if(fakecrt2modes) {
+ if(pSiSUSB->SiS_Pr->SiS_RefIndex[i].Ext_FakeCRT2CRTC) {
+ index = pSiSUSB->SiS_Pr->SiS_RefIndex[i].Ext_FakeCRT2CRTC;
+ }
+ }
+
+ if(!(new = xalloc(sizeof(DisplayModeRec)))) return first;
+ memset(new, 0, sizeof(DisplayModeRec));
+ if(!(new->name = xalloc(10))) {
+ xfree(new);
+ return first;
+ }
+ if(!first) first = new;
+ if(current) {
+ current->next = new;
+ new->prev = current;
+ }
+
+ current = new;
+
+ sprintf(current->name, "%dx%d", pSiSUSB->SiS_Pr->SiS_RefIndex[i].XRes,
+ pSiSUSB->SiS_Pr->SiS_RefIndex[i].YRes);
+
+ current->status = MODE_OK;
+
+ current->type = M_T_DEFAULT;
+
+ vclkindex = pSiSUSB->SiS_Pr->SiS_RefIndex[i].Ext_CRTVCLK;
+ if(fakecrt2modes) {
+ if(pSiSUSB->SiS_Pr->SiS_RefIndex[i].Ext_FakeCRT2Clk) {
+ vclkindex = pSiSUSB->SiS_Pr->SiS_RefIndex[i].Ext_FakeCRT2Clk;
+ }
+ }
+
+ sr2b = pSiSUSB->SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
+ sr2c = pSiSUSB->SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
+
+ divider = (sr2b & 0x80) ? 2.0 : 1.0;
+ postscalar = (sr2c & 0x80) ?
+ ( (((sr2c >> 5) & 0x03) == 0x02) ? 6.0 : 8.0) : (((sr2c >> 5) & 0x03) + 1.0);
+ num = (sr2b & 0x7f) + 1.0;
+ denum = (sr2c & 0x1f) + 1.0;
+
+ current->Clock = (int)(14318 * (divider / postscalar) * (num / denum));
+
+ sr_data = pSiSUSB->SiS_Pr->SiS_CRT1Table[index].CR[14];
+ /* inSISIDXREG(SISSR, 0x0b, sr_data); */
+
+ cr_data = pSiSUSB->SiS_Pr->SiS_CRT1Table[index].CR[0];
+
+ /* Horizontal total */
+ HT = (cr_data & 0xff) |
+ ((unsigned short) (sr_data & 0x03) << 8);
+ A = HT + 5;
+
+ cr_data = pSiSUSB->SiS_Pr->SiS_CRT1Table[index].CR[1];
+
+ /* Horizontal display enable end */
+ HDE = (cr_data & 0xff) |
+ ((unsigned short) (sr_data & 0x0C) << 6);
+ E = HDE + 1; /* 0x80 0x64 */
+
+ cr_data = pSiSUSB->SiS_Pr->SiS_CRT1Table[index].CR[4];
+
+ /* Horizontal retrace (=sync) start */
+ HRS = (cr_data & 0xff) |
+ ((unsigned short) (sr_data & 0xC0) << 2);
+ F = HRS - E - 3; /* 0x06 0x06 */
+
+ cr_data = pSiSUSB->SiS_Pr->SiS_CRT1Table[index].CR[2];
+
+ /* Horizontal blank start */
+ HBS = (cr_data & 0xff) |
+ ((unsigned short) (sr_data & 0x30) << 4);
+
+ sr_data = pSiSUSB->SiS_Pr->SiS_CRT1Table[index].CR[15];
+
+ cr_data = pSiSUSB->SiS_Pr->SiS_CRT1Table[index].CR[3];
+
+ cr_data2 = pSiSUSB->SiS_Pr->SiS_CRT1Table[index].CR[5];
+
+ /* Horizontal blank end */
+ HBE = (cr_data & 0x1f) |
+ ((unsigned short) (cr_data2 & 0x80) >> 2) |
+ ((unsigned short) (sr_data & 0x03) << 6);
+
+ /* Horizontal retrace (=sync) end */
+ HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
+
+ temp = HBE - ((E - 1) & 255);
+ B = (temp > 0) ? temp : (temp + 256);
+
+ temp = HRE - ((E + F + 3) & 63);
+ C = (temp > 0) ? temp : (temp + 64); /* 0x0b 0x0b */
+
+ D = B - F - C;
+
+ if((pSiSUSB->SiS_Pr->SiS_RefIndex[i].XRes == 320) &&
+ ((pSiSUSB->SiS_Pr->SiS_RefIndex[i].YRes == 200) ||
+ (pSiSUSB->SiS_Pr->SiS_RefIndex[i].YRes == 240))) {
+
+ /* Terrible hack, but correct CRTC data for
+ * these modes only produces a black screen...
+ * (HRE is 0, leading into a too large C and
+ * a negative D. The CRT controller does not
+ * seem to like correcting HRE to 50
+ */
+ current->HDisplay = 320;
+ current->HSyncStart = 328;
+ current->HSyncEnd = 376;
+ current->HTotal = 400;
+
+ } else {
+
+ current->HDisplay = (E * 8);
+ current->HSyncStart = (E * 8) + (F * 8);
+ current->HSyncEnd = (E * 8) + (F * 8) + (C * 8);
+ current->HTotal = (E * 8) + (F * 8) + (C * 8) + (D * 8);
+
+ }
+
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO,
+ "H: A %d B %d C %d D %d E %d F %d HT %d HDE %d HRS %d HBS %d HBE %d HRE %d\n",
+ A, B, C, D, E, F, HT, HDE, HRS, HBS, HBE, HRE);
+#endif
+
+ sr_data = pSiSUSB->SiS_Pr->SiS_CRT1Table[index].CR[13];
+
+ cr_data = pSiSUSB->SiS_Pr->SiS_CRT1Table[index].CR[6];
+
+ cr_data2 = pSiSUSB->SiS_Pr->SiS_CRT1Table[index].CR[7];
+
+ /* Vertical total */
+ VT = (cr_data & 0xFF) |
+ ((unsigned short) (cr_data2 & 0x01) << 8) |
+ ((unsigned short)(cr_data2 & 0x20) << 4) |
+ ((unsigned short) (sr_data & 0x01) << 10);
+ A = VT + 2;
+
+ cr_data = pSiSUSB->SiS_Pr->SiS_CRT1Table[index].CR[10];
+
+ /* Vertical display enable end */
+ VDE = (cr_data & 0xff) |
+ ((unsigned short) (cr_data2 & 0x02) << 7) |
+ ((unsigned short) (cr_data2 & 0x40) << 3) |
+ ((unsigned short) (sr_data & 0x02) << 9);
+ E = VDE + 1;
+
+ cr_data = pSiSUSB->SiS_Pr->SiS_CRT1Table[index].CR[8];
+
+ /* Vertical retrace (=sync) start */
+ VRS = (cr_data & 0xff) |
+ ((unsigned short) (cr_data2 & 0x04) << 6) |
+ ((unsigned short) (cr_data2 & 0x80) << 2) |
+ ((unsigned short) (sr_data & 0x08) << 7);
+ F = VRS + 1 - E;
+
+ cr_data = pSiSUSB->SiS_Pr->SiS_CRT1Table[index].CR[11];
+
+ cr_data3 = (pSiSUSB->SiS_Pr->SiS_CRT1Table[index].CR[16] & 0x01) << 5;
+
+ /* Vertical blank start */
+ VBS = (cr_data & 0xff) |
+ ((unsigned short) (cr_data2 & 0x08) << 5) |
+ ((unsigned short) (cr_data3 & 0x20) << 4) |
+ ((unsigned short) (sr_data & 0x04) << 8);
+
+ cr_data = pSiSUSB->SiS_Pr->SiS_CRT1Table[index].CR[12];
+
+ /* Vertical blank end */
+ VBE = (cr_data & 0xff) |
+ ((unsigned short) (sr_data & 0x10) << 4);
+ temp = VBE - ((E - 1) & 511);
+ B = (temp > 0) ? temp : (temp + 512);
+
+ cr_data = pSiSUSB->SiS_Pr->SiS_CRT1Table[index].CR[9];
+
+ /* Vertical retrace (=sync) end */
+ VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
+ temp = VRE - ((E + F - 1) & 31);
+ C = (temp > 0) ? temp : (temp + 32);
+
+ D = B - F - C;
+
+ current->VDisplay = VDE + 1;
+ current->VSyncStart = VRS + 1;
+ current->VSyncEnd = ((VRS & ~0x1f) | VRE) + 1;
+ if(VRE <= (VRS & 0x1f)) current->VSyncEnd += 32;
+ current->VTotal = E + D + C + F;
+
+#if 0
+ current->VDisplay = E;
+ current->VSyncStart = E + D;
+ current->VSyncEnd = E + D + C;
+ current->VTotal = E + D + C + F;
+#endif
+
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO,
+ "V: A %d B %d C %d D %d E %d F %d VT %d VDE %d VRS %d VBS %d VBE %d VRE %d\n",
+ A, B, C, D, E, F, VT, VDE, VRS, VBS, VBE, VRE);
+#endif
+
+ if(pSiSUSB->SiS_Pr->SiS_RefIndex[i].Ext_InfoFlag & 0x4000)
+ current->Flags |= V_NHSYNC;
+ else
+ current->Flags |= V_PHSYNC;
+
+ if(pSiSUSB->SiS_Pr->SiS_RefIndex[i].Ext_InfoFlag & 0x8000)
+ current->Flags |= V_NVSYNC;
+ else
+ current->Flags |= V_PVSYNC;
+
+ if(pSiSUSB->SiS_Pr->SiS_RefIndex[i].Ext_InfoFlag & 0x0080)
+ current->Flags |= V_INTERLACE;
+
+ j = 0;
+ IsHDCLK = FALSE;
+ while(pSiSUSB->SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID != 0xff) {
+ if(pSiSUSB->SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID ==
+ pSiSUSB->SiS_Pr->SiS_RefIndex[i].ModeID) {
+ if(pSiSUSB->SiS_Pr->SiS_EModeIDTable[j].Ext_ModeFlag & DoubleScanMode) {
+ current->Flags |= V_DBLSCAN;
+ }
+ if(pSiSUSB->SiS_Pr->SiS_EModeIDTable[j].Ext_ModeFlag & HalfDCLK) {
+ IsHDCLK = TRUE;
+ }
+ break;
+ }
+ j++;
+ }
+
+ if(current->Flags & V_INTERLACE) {
+ current->VDisplay <<= 1;
+ current->VSyncStart <<= 1;
+ current->VSyncEnd <<= 1;
+ current->VTotal <<= 1;
+ current->VTotal |= 1;
+ }
+
+ if(IsHDCLK) {
+ current->Clock >>= 1;
+ }
+
+ if(current->Flags & V_DBLSCAN) {
+ current->VDisplay >>= 1;
+ current->VSyncStart >>= 1;
+ current->VSyncEnd >>= 1;
+ current->VTotal >>= 1;
+ }
+
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Built-in: %s %.2f %d %d %d %d %d %d %d %d\n",
+ current->name, (float)current->Clock / 1000,
+ current->HDisplay, current->HSyncStart, current->HSyncEnd, current->HTotal,
+ current->VDisplay, current->VSyncStart, current->VSyncEnd, current->VTotal);
+#else
+ (void)VBS; (void)HBS; (void)A;
+#endif
+
+ i++;
+ }
+
+ return first;
+}
+
+
+
+
+
diff --git a/driver/xf86-video-sisusb/src/sisusb_init.h b/driver/xf86-video-sisusb/src/sisusb_init.h
new file mode 100644
index 000000000..a1e5b27a1
--- /dev/null
+++ b/driver/xf86-video-sisusb/src/sisusb_init.h
@@ -0,0 +1,787 @@
+/* $XFree86$ */
+/* $XdotOrg: driver/xf86-video-sisusb/src/sisusb_init.h,v 1.6 2005/07/09 02:50:34 twini Exp $ */
+/*
+ * Data and prototypes for init.c
+ *
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
+ *
+ * If distributed as part of the Linux kernel, the following license terms
+ * apply:
+ *
+ * * This program is free software; you can redistribute it and/or modify
+ * * it under the terms of the GNU General Public License as published by
+ * * the Free Software Foundation; either version 2 of the named License,
+ * * or any later version.
+ * *
+ * * This program is distributed in the hope that it will be useful,
+ * * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * * GNU General Public License for more details.
+ * *
+ * * You should have received a copy of the GNU General Public License
+ * * along with this program; if not, write to the Free Software
+ * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Otherwise, the following license terms apply:
+ *
+ * * Redistribution and use in source and binary forms, with or without
+ * * modification, are permitted provided that the following conditions
+ * * are met:
+ * * 1) Redistributions of source code must retain the above copyright
+ * * notice, this list of conditions and the following disclaimer.
+ * * 2) Redistributions in binary form must reproduce the above copyright
+ * * notice, this list of conditions and the following disclaimer in the
+ * * documentation and/or other materials provided with the distribution.
+ * * 3) The name of the author may not be used to endorse or promote products
+ * * derived from this software without specific prior written permission.
+ * *
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
+
+#ifndef _USBINIT_
+#define _USBINIT_
+
+#include "sisusb.h"
+#include "sisusb_regs.h"
+
+/* SiS_ModeType */
+#define ModeText 0x00
+#define ModeCGA 0x01
+#define ModeEGA 0x02
+#define ModeVGA 0x03
+#define Mode15Bpp 0x04
+#define Mode16Bpp 0x05
+#define Mode24Bpp 0x06
+#define Mode32Bpp 0x07
+
+#define ModeTypeMask 0x07
+#define IsTextMode 0x07
+
+#define DACInfoFlag 0x0018
+#define MemoryInfoFlag 0x01E0
+#define MemorySizeShift 5
+
+/* modeflag */
+#define Charx8Dot 0x0200
+#define LineCompareOff 0x0400
+#define CRT2Mode 0x0800
+#define HalfDCLK 0x1000
+#define NoSupportSimuTV 0x2000
+#define NoSupportLCDScale 0x4000 /* SiS bridge: No scaling possible (no matter what panel) */
+#define DoubleScanMode 0x8000
+
+/* Infoflag */
+#define SupportTV 0x0008
+#define SupportTV1024 0x0800
+#define SupportCHTV 0x0800
+#define Support64048060Hz 0x0800 /* Special for 640x480 LCD */
+#define SupportHiVision 0x0010
+#define SupportYPbPr750p 0x1000
+#define SupportLCD 0x0020
+#define SupportRAMDAC2 0x0040 /* All (<= 100Mhz) */
+#define SupportRAMDAC2_135 0x0100 /* All except DH (<= 135Mhz) */
+#define SupportRAMDAC2_162 0x0200 /* B, C (<= 162Mhz) */
+#define SupportRAMDAC2_202 0x0400 /* C (<= 202Mhz) */
+#define InterlaceMode 0x0080
+#define SyncPP 0x0000
+#define SyncPN 0x4000
+#define SyncNP 0x8000
+#define SyncNN 0xc000
+
+/* SetFlag */
+#define ProgrammingCRT2 0x0001
+#define LowModeTests 0x0002
+#define LCDVESATiming 0x0008
+#define EnableLVDSDDA 0x0010
+#define SetDispDevSwitchFlag 0x0020
+#define CheckWinDos 0x0040
+#define SetDOSMode 0x0080
+
+/* CR32 (Newer 630, and 315 series)
+
+ [0] VB connected with CVBS
+ [1] VB connected with SVHS
+ [2] VB connected with SCART
+ [3] VB connected with LCD
+ [4] VB connected with CRT2 (secondary VGA)
+ [5] CRT1 monitor is connected
+ [6] VB connected with Hi-Vision TV
+ [7] <= 330: VB connected with DVI combo connector
+ >= 661: VB connected to YPbPr
+*/
+
+
+/* Index in ModeResInfo table */
+#define SIS_RI_320x200 0
+#define SIS_RI_320x240 1
+#define SIS_RI_320x400 2
+#define SIS_RI_400x300 3
+#define SIS_RI_512x384 4
+#define SIS_RI_640x400 5
+#define SIS_RI_640x480 6
+#define SIS_RI_800x600 7
+#define SIS_RI_1024x768 8
+#define SIS_RI_1280x1024 9
+#define SIS_RI_1600x1200 10
+#define SIS_RI_1920x1440 11
+#define SIS_RI_2048x1536 12
+#define SIS_RI_720x480 13
+#define SIS_RI_720x576 14
+#define SIS_RI_1280x960 15
+#define SIS_RI_800x480 16
+#define SIS_RI_1024x576 17
+#define SIS_RI_1280x720 18
+#define SIS_RI_856x480 19
+#define SIS_RI_1280x768 20
+#define SIS_RI_1400x1050 21
+#define SIS_RI_1152x864 22 /* Up to here SiS conforming */
+#define SIS_RI_848x480 23
+#define SIS_RI_1360x768 24
+#define SIS_RI_1024x600 25
+#define SIS_RI_1152x768 26
+#define SIS_RI_768x576 27
+#define SIS_RI_1360x1024 28
+#define SIS_RI_1680x1050 29
+#define SIS_RI_1280x800 30
+#define SIS_RI_1920x1080 31
+#define SIS_RI_960x540 32
+#define SIS_RI_960x600 33
+
+#define SIS_VIDEO_CAPTURE 0x00 - 0x30
+#define SIS_VIDEO_PLAYBACK 0x02 - 0x30
+#define SIS_CRT2_PORT_04 0x04 - 0x30
+#define SIS_CRT2_PORT_10 0x10 - 0x30
+#define SIS_CRT2_PORT_12 0x12 - 0x30
+#define SIS_CRT2_PORT_14 0x14 - 0x30
+
+/* Mode numbers */
+static const USHORT ModeIndex_320x200[] = {0x59, 0x41, 0x00, 0x4f};
+static const USHORT ModeIndex_320x240[] = {0x50, 0x56, 0x00, 0x53};
+static const USHORT ModeIndex_400x300[] = {0x51, 0x57, 0x00, 0x54};
+static const USHORT ModeIndex_512x384[] = {0x52, 0x58, 0x00, 0x5c};
+static const USHORT ModeIndex_640x400[] = {0x2f, 0x5d, 0x00, 0x5e};
+static const USHORT ModeIndex_640x480[] = {0x2e, 0x44, 0x00, 0x62};
+static const USHORT ModeIndex_720x480[] = {0x31, 0x33, 0x00, 0x35};
+static const USHORT ModeIndex_720x576[] = {0x32, 0x34, 0x00, 0x36};
+static const USHORT ModeIndex_768x576[] = {0x5f, 0x60, 0x00, 0x61};
+static const USHORT ModeIndex_800x480[] = {0x70, 0x7a, 0x00, 0x76};
+static const USHORT ModeIndex_800x600[] = {0x30, 0x47, 0x00, 0x63};
+static const USHORT ModeIndex_848x480[] = {0x39, 0x3b, 0x00, 0x3e};
+static const USHORT ModeIndex_856x480[] = {0x3f, 0x42, 0x00, 0x45};
+static const USHORT ModeIndex_960x540[] = {0x1d, 0x1e, 0x00, 0x1f};
+static const USHORT ModeIndex_960x600[] = {0x20, 0x21, 0x00, 0x22};
+static const USHORT ModeIndex_1024x768[] = {0x38, 0x4a, 0x00, 0x64};
+static const USHORT ModeIndex_1024x576[] = {0x71, 0x74, 0x00, 0x77};
+static const USHORT ModeIndex_1152x864[] = {0x29, 0x2a, 0x00, 0x2b};
+static const USHORT ModeIndex_1280x720[] = {0x79, 0x75, 0x00, 0x78};
+static const USHORT ModeIndex_1280x768[] = {0x23, 0x24, 0x00, 0x25};
+static const USHORT ModeIndex_1280x1024[] = {0x3a, 0x4d, 0x00, 0x65};
+
+static const USHORT SiS_VGA_DAC[] =
+{
+ 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
+ 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
+ 0x00,0x05,0x08,0x0B,0x0E,0x11,0x14,0x18,
+ 0x1C,0x20,0x24,0x28,0x2D,0x32,0x38,0x3F,
+ 0x00,0x10,0x1F,0x2F,0x3F,0x1F,0x27,0x2F,
+ 0x37,0x3F,0x2D,0x31,0x36,0x3A,0x3F,0x00,
+ 0x07,0x0E,0x15,0x1C,0x0E,0x11,0x15,0x18,
+ 0x1C,0x14,0x16,0x18,0x1A,0x1C,0x00,0x04,
+ 0x08,0x0C,0x10,0x08,0x0A,0x0C,0x0E,0x10,
+ 0x0B,0x0C,0x0D,0x0F,0x10
+};
+
+static const SiS_ModeResInfoStruct SiS_ModeResInfo[] =
+{
+ { 320, 200, 8, 8}, /* 0x00 */
+ { 320, 240, 8, 8}, /* 0x01 */
+ { 320, 400, 8, 8}, /* 0x02 */
+ { 400, 300, 8, 8}, /* 0x03 */
+ { 512, 384, 8, 8}, /* 0x04 */
+ { 640, 400, 8,16}, /* 0x05 */
+ { 640, 480, 8,16}, /* 0x06 */
+ { 800, 600, 8,16}, /* 0x07 */
+ { 1024, 768, 8,16}, /* 0x08 */
+ { 1280,1024, 8,16}, /* 0x09 */
+ { 1600,1200, 8,16}, /* 0x0a */
+ { 1920,1440, 8,16}, /* 0x0b */
+ { 2048,1536, 8,16}, /* 0x0c */
+ { 720, 480, 8,16}, /* 0x0d */
+ { 720, 576, 8,16}, /* 0x0e */
+ { 1280, 960, 8,16}, /* 0x0f */
+ { 800, 480, 8,16}, /* 0x10 */
+ { 1024, 576, 8,16}, /* 0x11 */
+ { 1280, 720, 8,16}, /* 0x12 */
+ { 856, 480, 8,16}, /* 0x13 */
+ { 1280, 768, 8,16}, /* 0x14 */
+ { 1400,1050, 8,16}, /* 0x15 */
+ { 1152, 864, 8,16}, /* 0x16 */
+ { 848, 480, 8,16}, /* 0x17 */
+ { 1360, 768, 8,16}, /* 0x18 */
+ { 1024, 600, 8,16}, /* 0x19 */
+ { 1152, 768, 8,16}, /* 0x1a */
+ { 768, 576, 8,16}, /* 0x1b */
+ { 1360,1024, 8,16}, /* 0x1c */
+ { 1680,1050, 8,16}, /* 0x1d */
+ { 1280, 800, 8,16}, /* 0x1e */
+ { 1920,1080, 8,16}, /* 0x1f */
+ { 960, 540, 8,16}, /* 0x20 */
+ { 960, 600, 8,16} /* 0x21 */
+};
+
+static const SiS_StandTableStruct SiS_StandTable[]=
+{
+ {
+ 0x00,0x00,0x00,0x0000,
+ {0x01,0x0f,0x00,0x0e},
+ 0x23,
+ {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
+ 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+ 0x01,0x00,0x00,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
+ 0xff}
+ }
+};
+
+static const SiS_ExtStruct SiSUSB_EModeIDTable[]=
+{
+ {0x2e,0x0a1b,0x0101,SIS_RI_640x480, 0x00,0x00,0x05,0x05,0x08, 2}, /* 640x480x8 */
+ {0x2f,0x0a1b,0x0100,SIS_RI_640x400, 0x00,0x00,0x05,0x05,0x10, 0}, /* 640x400x8 */
+ {0x30,0x2a1b,0x0103,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x8 */
+ {0x31,0x4a1b,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x06,0x11,-1}, /* 720x480x8 */
+ {0x32,0x4a1b,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x06,0x12,-1}, /* 720x576x8 */
+ {0x33,0x4a1d,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x06,0x11,-1}, /* 720x480x16 */
+ {0x34,0x6a1d,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x06,0x12,-1}, /* 720x576x16 */
+ {0x35,0x4a1f,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x06,0x11,-1}, /* 720x480x32 */
+ {0x36,0x6a1f,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x06,0x12,-1}, /* 720x576x32 */
+ {0x38,0x0a1b,0x0105,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13, 4}, /* 1024x768x8 */
+ {0x3a,0x0e3b,0x0107,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x2f, 8}, /* 1280x1024x8 */
+ {0x41,0x9a1d,0x010e,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x1a, 0}, /* 320x200x16 */
+ {0x44,0x0a1d,0x0111,SIS_RI_640x480, 0x00,0x00,0x05,0x05,0x08, 2}, /* 640x480x16 */
+ {0x47,0x2a1d,0x0114,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x16 */
+ {0x4a,0x0a3d,0x0117,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13, 4}, /* 1024x768x16 */
+ {0x4d,0x0e7d,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x2f, 8}, /* 1280x1024x16 */
+ {0x50,0x9a1b,0x0132,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x1b, 2}, /* 320x240x8 */
+ {0x51,0xba1b,0x0133,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x1c, 3}, /* 400x300x8 */
+ {0x52,0xba1b,0x0134,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x1d, 4}, /* 512x384x8 */
+ {0x56,0x9a1d,0x0135,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x1b, 2}, /* 320x240x16 */
+ {0x57,0xba1d,0x0136,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x1c, 3}, /* 400x300x16 */
+ {0x58,0xba1d,0x0137,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x1d, 4}, /* 512x384x16 */
+ {0x59,0x9a1b,0x0138,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x1a, 0}, /* 320x200x8 */
+ {0x5c,0xba1f,0x0000,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x1d, 4}, /* 512x384x32 */
+ {0x5d,0x0a1d,0x0139,SIS_RI_640x400, 0x00,0x00,0x05,0x07,0x10, 0}, /* 640x400x16 */
+ {0x5e,0x0a1f,0x0000,SIS_RI_640x400, 0x00,0x00,0x05,0x07,0x10, 0}, /* 640x400x32 */
+ {0x62,0x0a3f,0x013a,SIS_RI_640x480, 0x00,0x00,0x05,0x05,0x08, 2}, /* 640x480x32 */
+ {0x63,0x2a3f,0x013b,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x32 */
+ {0x64,0x0a7f,0x013c,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13, 4}, /* 1024x768x32 */
+ {0x65,0x0eff,0x013d,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x2f, 8}, /* 1280x1024x32 */
+ {0x70,0x6a1b,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x07,0x1e,-1}, /* 800x480x8 */
+ {0x71,0x4a1b,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x21,-1}, /* 1024x576x8 */
+ {0x74,0x4a1d,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x21,-1}, /* 1024x576x16 */
+ {0x75,0x0a3d,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x24, 5}, /* 1280x720x16 */
+ {0x76,0x6a1f,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x07,0x1e,-1}, /* 800x480x32 */
+ {0x77,0x4a1f,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x21,-1}, /* 1024x576x32 */
+ {0x78,0x0a3f,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x24, 5}, /* 1280x720x32 */
+ {0x79,0x0a3b,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x24, 5}, /* 1280x720x8 */
+ {0x7a,0x6a1d,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x07,0x1e,-1}, /* 800x480x16 */
+ {0x23,0x0e3b,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x27, 6}, /* 1280x768x8 */
+ {0x24,0x0e7d,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x27, 6}, /* 1280x768x16 */
+ {0x25,0x0eff,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x27, 6}, /* 1280x768x32 */
+ {0x39,0x6a1b,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x28,-1}, /* 848x480 */
+ {0x3b,0x6a3d,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x28,-1},
+ {0x3e,0x6a7f,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x28,-1},
+ {0x3f,0x6a1b,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x2a,-1}, /* 856x480 */
+ {0x42,0x6a3d,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x2a,-1},
+ {0x45,0x6a7f,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x2a,-1},
+ {0x4f,0x9a1f,0x0000,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x1a, 0}, /* 320x200x32 */
+ {0x53,0x9a1f,0x0000,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x1b, 2}, /* 320x240x32 */
+ {0x54,0xba1f,0x0000,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x1c, 3}, /* 400x300x32 */
+ {0x5f,0x6a1b,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x2c,-1}, /* 768x576 */
+ {0x60,0x6a1d,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x2c,-1},
+ {0x61,0x6a3f,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x2c,-1},
+ {0x1d,0x6a1b,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x2d,-1}, /* 960x540 */
+ {0x1e,0x6a3d,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x2d,-1},
+ {0x1f,0x6a7f,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x2d,-1},
+ {0x20,0x6a1b,0x0000,SIS_RI_960x600, 0x00,0x00,0x00,0x00,0x2e,-1}, /* 960x600 */
+ {0x21,0x6a3d,0x0000,SIS_RI_960x600, 0x00,0x00,0x00,0x00,0x2e,-1},
+ {0x22,0x6a7f,0x0000,SIS_RI_960x600, 0x00,0x00,0x00,0x00,0x2e,-1},
+ {0x29,0x4e1b,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x33,-1}, /* 1152x864 */
+ {0x2a,0x4e3d,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x33,-1},
+ {0x2b,0x4e7f,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x33,-1},
+ {0xff,0x0000,0x0000,0, 0x00,0x00,0x00,0x00,0x00,-1}
+};
+
+static const SiS_Ext2Struct SiSUSB_RefIndex[]=
+{
+ {0x085f,0x0d,0x03,0x05,0x05,0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x0 */
+ {0x0067,0x0e,0x04,0x05,0x05,0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x1 */
+ {0x0067,0x0f,0x08,0x48,0x05,0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x2 */
+ {0x0067,0x10,0x07,0x8b,0x05,0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x3 */
+ {0x0047,0x11,0x0a,0x00,0x05,0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x4 */
+ {0x0047,0x12,0x0d,0x00,0x05,0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x5 */
+ {0x0047,0x13,0x13,0x00,0x05,0x30, 800, 600, 0x20, 0x00, 0x00}, /* 0x6 */
+ {0x0107,0x14,0x1c,0x00,0x05,0x30, 800, 600, 0x20, 0x00, 0x00}, /* 0x7 */
+ {0xc85f,0x05,0x00,0x04,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0x8 */
+ {0xc067,0x06,0x02,0x04,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0x9 */
+ {0xc067,0x07,0x02,0x47,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xa */
+ {0xc067,0x08,0x03,0x8a,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xb */
+ {0xc047,0x09,0x05,0x00,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xc */
+ {0xc047,0x0a,0x09,0x00,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xd */
+ {0xc047,0x0b,0x0e,0x00,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xe */
+ {0xc047,0x0c,0x15,0x00,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xf */
+ {0x487f,0x04,0x00,0x00,0x00,0x2f, 640, 400, 0x30, 0x55, 0x6e}, /* 0x10 */
+ {0xc06f,0x3c,0x01,0x06,0x13,0x31, 720, 480, 0x30, 0x00, 0x00}, /* 0x11 */
+ {0x006f,0x3d,0x6f,0x06,0x14,0x32, 720, 576, 0x30, 0x00, 0x00}, /* 0x12 (6f was 03) */
+ {0x0087,0x15,0x06,0x00,0x06,0x38,1024, 768, 0x30, 0x00, 0x00}, /* 0x13 */
+ {0xc877,0x16,0x0b,0x06,0x06,0x38,1024, 768, 0x20, 0x00, 0x00}, /* 0x14 */
+ {0xc067,0x17,0x0f,0x49,0x06,0x38,1024, 768, 0x20, 0x00, 0x00}, /* 0x15 */
+ {0x0067,0x18,0x11,0x00,0x06,0x38,1024, 768, 0x20, 0x00, 0x00}, /* 0x16 */
+ {0x0047,0x19,0x16,0x8c,0x06,0x38,1024, 768, 0x20, 0x00, 0x00}, /* 0x17 */
+ {0x0107,0x1a,0x1b,0x00,0x06,0x38,1024, 768, 0x10, 0x00, 0x00}, /* 0x18 */
+ {0x0107,0x1b,0x1f,0x00,0x06,0x38,1024, 768, 0x10, 0x00, 0x00}, /* 0x19 */
+ {0x407f,0x00,0x00,0x00,0x00,0x41, 320, 200, 0x30, 0x56, 0x4e}, /* 0x1a */
+ {0xc07f,0x01,0x00,0x04,0x04,0x50, 320, 240, 0x30, 0x00, 0x00}, /* 0x1b */
+ {0x007f,0x02,0x04,0x05,0x05,0x51, 400, 300, 0x30, 0x00, 0x00}, /* 0x1c */
+ {0xc077,0x03,0x0b,0x06,0x06,0x52, 512, 384, 0x30, 0x00, 0x00}, /* 0x1d */
+ {0x0077,0x32,0x40,0x08,0x18,0x70, 800, 480, 0x30, 0x00, 0x00}, /* 0x1e */
+ {0x0047,0x33,0x07,0x08,0x18,0x70, 800, 480, 0x30, 0x00, 0x00}, /* 0x1f */
+ {0x0047,0x34,0x0a,0x08,0x18,0x70, 800, 480, 0x30, 0x00, 0x00}, /* 0x20 */
+ {0x0077,0x35,0x0b,0x09,0x19,0x71,1024, 576, 0x30, 0x00, 0x00}, /* 0x21 */
+ {0x0047,0x36,0x11,0x09,0x19,0x71,1024, 576, 0x30, 0x00, 0x00}, /* 0x22 */
+ {0x0047,0x37,0x16,0x09,0x19,0x71,1024, 576, 0x30, 0x00, 0x00}, /* 0x23 */
+ {0x1137,0x38,0x19,0x0a,0x0c,0x75,1280, 720, 0x30, 0x00, 0x00}, /* 0x24 */
+ {0x1107,0x39,0x1e,0x0a,0x0c,0x75,1280, 720, 0x30, 0x00, 0x00}, /* 0x25 */
+ {0x1307,0x3a,0x20,0x0a,0x0c,0x75,1280, 720, 0x30, 0x00, 0x00}, /* 0x26 */
+ {0x0077,0x42,0x5b,0x08,0x11,0x23,1280, 768, 0x30, 0x00, 0x00}, /* 0x27 */
+ {0x0087,0x45,0x57,0x00,0x16,0x39, 848, 480, 0x30, 0x00, 0x00}, /* 0x28 848x480-38Hzi */
+ {0xc067,0x46,0x55,0x0b,0x16,0x39, 848, 480, 0x30, 0x00, 0x00}, /* 0x29 848x480-60Hz */
+ {0x0087,0x47,0x57,0x00,0x17,0x3f, 856, 480, 0x30, 0x00, 0x00}, /* 0x2a 856x480-38Hzi */
+ {0xc067,0x48,0x57,0x00,0x17,0x3f, 856, 480, 0x30, 0x00, 0x00}, /* 0x2b 856x480-60Hz */
+ {0x006f,0x4d,0x71,0x06,0x15,0x5f, 768, 576, 0x30, 0x00, 0x00}, /* 0x2c 768x576-56Hz */
+ {0x0067,0x52,0x6a,0x00,0x1c,0x1d, 960, 540, 0x30, 0x00, 0x00}, /* 0x2d 960x540 60Hz */
+ {0x0077,0x53,0x6b,0x0b,0x1d,0x20, 960, 600, 0x30, 0x00, 0x00}, /* 0x2e 960x600 60Hz */
+ {0x0087,0x1c,0x11,0x00,0x07,0x3a,1280,1024, 0x30, 0x00, 0x00}, /* 0x2f */
+ {0x0137,0x1d,0x19,0x07,0x07,0x3a,1280,1024, 0x00, 0x00, 0x00}, /* 0x30 */
+ {0x0107,0x1e,0x1e,0x00,0x07,0x3a,1280,1024, 0x00, 0x00, 0x00}, /* 0x31 */
+ {0x0207,0x1f,0x20,0x00,0x07,0x3a,1280,1024, 0x00, 0x00, 0x00}, /* 0x32 */
+ {0x0127,0x54,0x6d,0x00,0x1a,0x29,1152, 864, 0x30, 0x00, 0x00}, /* 0x33 1152x864-60Hz */
+ {0x0127,0x44,0x19,0x00,0x1a,0x29,1152, 864, 0x30, 0x00, 0x00}, /* 0x34 1152x864-75Hz */
+ {0x0127,0x4a,0x1e,0x00,0x1a,0x29,1152, 864, 0x30, 0x00, 0x00}, /* 0x35 1152x864-85Hz */
+ {0xffff,0x00,0x00,0x00,0x00,0x00, 0, 0, 0, 0x00, 0x00}
+};
+
+static const SiS_CRT1TableStruct SiSUSB_CRT1Table[]=
+{
+ {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
+ 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00,
+ 0x00}}, /* 0x0 */
+ {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e,
+ 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
+ 0x00}}, /* 0x1 */
+ {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0,
+ 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
+ 0x01}}, /* 0x2 */
+ {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+ 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
+ 0x01}}, /* 0x3 */
+ {{0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+ 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05,
+ 0x00}}, /* 0x4 */
+ {{0x5f,0x4f,0x4f,0x83,0x55,0x81,0x0b,0x3e, /* 0x05 - corrected 640x480-60 */
+ 0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05,
+ 0x00}},
+ {{0x63,0x4f,0x4f,0x87,0x56,0x9b,0x06,0x3e, /* 0x06 - corrected 640x480-72 */
+ 0xe8,0x8a,0xdf,0xe7,0x07,0x00,0x00,0x01,
+ 0x00}},
+ {{0x64,0x4f,0x4f,0x88,0x55,0x9d,0xf2,0x1f,
+ 0xe0,0x83,0xdf,0xdf,0xf3,0x10,0x00,0x01,
+ 0x00}}, /* 0x7 */
+ {{0x63,0x4f,0x4f,0x87,0x5a,0x81,0xfb,0x1f,
+ 0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05,
+ 0x00}}, /* 0x8 */
+ {{0x65,0x4f,0x4f,0x89,0x58,0x80,0xfb,0x1f,
+ 0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05, /* Corrected VBE */
+ 0x61}}, /* 0x9 */
+ {{0x65,0x4f,0x4f,0x89,0x58,0x80,0x01,0x3e,
+ 0xe0,0x83,0xdf,0xdf,0x02,0x00,0x00,0x05,
+ 0x61}}, /* 0xa */
+ {{0x67,0x4f,0x4f,0x8b,0x58,0x81,0x0d,0x3e,
+ 0xe0,0x83,0xdf,0xdf,0x0e,0x00,0x00,0x05, /* Corrected VBE */
+ 0x61}}, /* 0xb */
+ {{0x65,0x4f,0x4f,0x89,0x57,0x9f,0xfb,0x1f,
+ 0xe6,0x8a,0xdf,0xdf,0xfc,0x10,0x00,0x01, /* Corrected VDE, VBE */
+ 0x00}}, /* 0xc */
+ {{0x7b,0x63,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
+ 0x58,0x8a,0x57,0x57,0x70,0x20,0x00,0x05,
+ 0x01}}, /* 0xd */
+ {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+ 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x06,
+ 0x01}}, /* 0xe */
+ {{0x7d,0x63,0x63,0x81,0x6e,0x1d,0x98,0xf0,
+ 0x7c,0x82,0x57,0x57,0x99,0x00,0x00,0x06,
+ 0x01}}, /* 0xf */
+ {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xf0,
+ 0x58,0x8b,0x57,0x57,0x70,0x20,0x00,0x06,
+ 0x01}}, /* 0x10 */
+ {{0x7e,0x63,0x63,0x82,0x6b,0x13,0x75,0xf0,
+ 0x58,0x8b,0x57,0x57,0x76,0x20,0x00,0x06,
+ 0x01}}, /* 0x11 */
+ {{0x81,0x63,0x63,0x85,0x6d,0x18,0x7a,0xf0,
+ 0x58,0x8b,0x57,0x57,0x7b,0x20,0x00,0x06,
+ 0x61}}, /* 0x12 */
+ {{0x83,0x63,0x63,0x87,0x6e,0x19,0x81,0xf0,
+ 0x58,0x8b,0x57,0x57,0x82,0x20,0x00,0x06,
+ 0x61}}, /* 0x13 */
+ {{0x85,0x63,0x63,0x89,0x6f,0x1a,0x91,0xf0,
+ 0x58,0x8b,0x57,0x57,0x92,0x20,0x00,0x06,
+ 0x61}}, /* 0x14 */
+ {{0x99,0x7f,0x7f,0x9d,0x84,0x1a,0x96,0x1f,
+ 0x7f,0x83,0x7f,0x7f,0x97,0x10,0x00,0x02,
+ 0x00}}, /* 0x15 */
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
+ 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+ 0x01}}, /* 0x16 */
+ {{0xa1,0x7f,0x7f,0x85,0x86,0x97,0x24,0xf5,
+ 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+ 0x01}}, /* 0x17 */
+ {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf5,
+ 0x00,0x83,0xff,0xff,0x1f,0x10,0x00,0x02,
+ 0x01}}, /* 0x18 */
+ {{0xa7,0x7f,0x7f,0x8b,0x89,0x95,0x26,0xf5,
+ 0x00,0x83,0xff,0xff,0x27,0x10,0x00,0x02,
+ 0x01}}, /* 0x19 */
+ {{0xa9,0x7f,0x7f,0x8d,0x8c,0x9a,0x2c,0xf5,
+ 0x00,0x83,0xff,0xff,0x2d,0x14,0x00,0x02,
+ 0x62}}, /* 0x1a */
+ {{0xab,0x7f,0x7f,0x8f,0x8d,0x9b,0x35,0xf5,
+ 0x00,0x83,0xff,0xff,0x36,0x14,0x00,0x02,
+ 0x62}}, /* 0x1b */
+ {{0xcf,0x9f,0x9f,0x93,0xb2,0x01,0x14,0xba,
+ 0x00,0x83,0xff,0xff,0x15,0x00,0x00,0x03,
+ 0x00}}, /* 0x1c */
+ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0x5a,
+ 0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
+ 0x01}}, /* 0x1d */
+ {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0x5a,
+ 0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
+ 0x01}}, /* 0x1e */
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0x5a,
+ 0x00,0x83,0xff,0xff,0x2f,0x09,0x00,0x07,
+ 0x01}}, /* 0x1f */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+ 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+ 0x00}}, /* 0x20 */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+ 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+ 0x00}}, /* 0x21 @ 4084 */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+ 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+ 0x00}}, /* 0x22 */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+ 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+ 0x00}}, /* 0x23 */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+ 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+ 0x00}}, /* 0x24 */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+ 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+ 0x00}}, /* 0x25 */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+ 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+ 0x00}}, /* 0x26 */
+ {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
+ 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
+ 0x00}}, /* 0x27 */
+ {{0x43,0xef,0xef,0x87,0x06,0x00,0xd4,0x1f,
+ 0xa0,0x83,0x9f,0x9f,0xd5,0x1f,0x41,0x05,
+ 0x63}}, /* 0x28 */
+ {{0x45,0xef,0xef,0x89,0x07,0x01,0xd9,0x1f,
+ 0xa0,0x83,0x9f,0x9f,0xda,0x1f,0x41,0x05,
+ 0x63}}, /* 0x29 */
+ {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
+ 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
+ 0x00}}, /* 0x2a */
+ {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
+ 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
+ 0x00}}, /* 0x2b */
+ {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
+ 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
+ 0x00}}, /* 0x2c */
+ {{0x59,0xff,0xff,0x9d,0x17,0x13,0x33,0xba,
+ 0x00,0x83,0xff,0xff,0x34,0x0f,0x41,0x05,
+ 0x44}}, /* 0x2d */
+ {{0x5b,0xff,0xff,0x9f,0x18,0x14,0x38,0xba,
+ 0x00,0x83,0xff,0xff,0x39,0x0f,0x41,0x05,
+ 0x44}}, /* 0x2e */
+ {{0x5b,0xff,0xff,0x9f,0x18,0x14,0x3d,0xba,
+ 0x00,0x83,0xff,0xff,0x3e,0x0f,0x41,0x05,
+ 0x44}}, /* 0x2f */
+ {{0x5d,0xff,0xff,0x81,0x19,0x95,0x41,0xba,
+ 0x00,0x84,0xff,0xff,0x42,0x0f,0x41,0x05,
+ 0x44}}, /* 0x30 */
+ {{0x55,0xff,0xff,0x99,0x0d,0x0c,0x3e,0xba,
+ 0x00,0x84,0xff,0xff,0x3f,0x0f,0x41,0x05,
+ 0x00}}, /* 0x31 */
+ {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba,
+ 0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06,
+ 0x01}}, /* 0x32 */
+ {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba,
+ 0x26,0x89,0xdf,0xdf,0x6f,0x00,0x00,0x06,
+ 0x01}}, /* 0x33 */
+ {{0x7f,0x63,0x63,0x82,0x6b,0x13,0x75,0xba,
+ 0x29,0x8c,0xdf,0xdf,0x75,0x00,0x00,0x06,
+ 0x01}}, /* 0x34 */
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf1,
+ 0xaf,0x85,0x3f,0x3f,0x25,0x30,0x00,0x02,
+ 0x01}}, /* 0x35 */
+ {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1,
+ 0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02,
+ 0x01}}, /* 0x36 */
+ {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1, /* 95 was 15 - illegal HBE! */
+ 0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02,
+ 0x01}}, /* 0x37 */
+ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4,
+ 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
+ 0x01}}, /* 0x38 */
+ {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xd4,
+ 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
+ 0x01}}, /* 0x39 */
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4,
+ 0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07,
+ 0x01}}, /* 0x3a */
+ {{0xdc,0x9f,0x9f,0x80,0xaf,0x9d,0xe6,0xff, /* 1280x960-60 - corrected */
+ 0xc0,0x83,0xbf,0xbf,0xe7,0x10,0x00,0x07,
+ 0x01}}, /* 0x3b */
+ {{0x6b,0x59,0x59,0x8f,0x5e,0x8c,0x0b,0x3e,
+ 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
+ 0x00}}, /* 0x3c */
+ {{0x6d,0x59,0x59,0x91,0x60,0x89,0x53,0xf0, /* 720x576, corrected to 60Hz */
+ 0x41,0x84,0x3f,0x3f,0x54,0x00,0x00,0x05,
+ 0x41}}, /* 0x3d */
+ {{0x86,0x6a,0x6a,0x8a,0x74,0x06,0x8c,0x15,
+ 0x4f,0x83,0xef,0xef,0x8d,0x30,0x00,0x02,
+ 0x00}}, /* 0x3e */
+ {{0x81,0x6a,0x6a,0x85,0x70,0x00,0x0f,0x3e,
+ 0xeb,0x8e,0xdf,0xdf,0x10,0x00,0x00,0x02,
+ 0x00}}, /* 0x3f */
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1,
+ 0xae,0x85,0x57,0x57,0x1f,0x30,0x00,0x02,
+ 0x01}}, /* 0x40 */
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
+ 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+ 0x01}}, /* 0x41 */
+ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x20,0xf5,
+ 0x03,0x88,0xff,0xff,0x21,0x10,0x00,0x07,
+ 0x01}}, /* 0x42 */
+ {{0xe6,0xae,0xae,0x8a,0xbd,0x90,0x3d,0x10,
+ 0x1a,0x8d,0x19,0x19,0x3e,0x2f,0x00,0x03,
+ 0x00}}, /* 0x43 */
+ {{0xc3,0x8f,0x8f,0x87,0x9b,0x0b,0x82,0xef, /* 1152x864-75 */
+ 0x60,0x83,0x5f,0x5f,0x83,0x10,0x00,0x07,
+ 0x01}}, /* 0x44 */
+ {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15, /* 848x480-38i */
+ 0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
+ 0x00}}, /* 0x45 */
+ {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E, /* 848x480-60 */
+ 0xE5,0x8d,0xDF,0xe4,0x04,0x00,0x00,0x06,
+ 0x00}}, /* 0x46 */
+ {{0x86,0x6A,0x6A,0x8A,0x74,0x06,0x8C,0x15, /* 856x480-38i */
+ 0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
+ 0x00}}, /* 0x47 */
+ {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E, /* 856x480-60 */
+ 0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02,
+ 0x00}}, /* 0x48 */
+ {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd, /* 1360x768-60 */
+ 0x01,0x8d,0xff,0x00,0x27,0x10,0x00,0x03,
+ 0x01}}, /* 0x49 */
+ {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff, /* 1152x864-84 */
+ 0x60,0x8b,0x5f,0x5f,0x8b,0x10,0x00,0x03,
+ 0x01}}, /* 0x4a */
+ {{0xea,0xae,0xae,0x8e,0xba,0x82,0x40,0x10, /* 1400x1050-75 */
+ 0x1b,0x87,0x19,0x1a,0x41,0x0f,0x00,0x03,
+ 0x00}}, /* 0x4b */
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff, /* 1280x960-85 */
+ 0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07,
+ 0x01}}, /* 0x4c */
+ {{0x75,0x5f,0x5f,0x99,0x66,0x90,0x53,0xf0, /* 768x576, corrected to 60Hz */
+ 0x41,0x84,0x3f,0x3f,0x54,0x00,0x00,0x05,
+ 0x41}},
+ {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e, /* FSTN 320x480, TEMP - possibly invalid */
+ 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
+ 0x00}}, /* 0x4e */
+ {{0xcd,0x9f,0x9f,0x91,0xab,0x1c,0x3a,0xff, /* 1280x800-60 */
+ 0x20,0x83,0x1f,0x1f,0x3b,0x10,0x00,0x07,
+ 0x21}}, /* 0x4f */
+ {{0x15,0xd1,0xd1,0x99,0xe2,0x19,0x3d,0x10, /* 1680x1050-60 */
+ 0x1a,0x8d,0x19,0x19,0x3e,0x2f,0x01,0x0c,
+ 0x20}}, /* 0x50 */
+ {{0x0e,0xef,0xef,0x92,0xfe,0x03,0x30,0xf0, /* 1920x1080-60i */
+ 0x1e,0x83,0x1b,0x1c,0x31,0x00,0x01,0x00,
+ 0x61}}, /* 0x51 */
+ {{0x85,0x77,0x77,0x89,0x7d,0x01,0x31,0xf0, /* 960x540-60 */
+ 0x1e,0x84,0x1b,0x1c,0x32,0x00,0x00,0x02,
+ 0x41}}, /* 0x52 */
+ {{0x87,0x77,0x77,0x8b,0x81,0x0b,0x68,0xf0, /* 960x600-60 */
+ 0x5a,0x80,0x57,0x57,0x69,0x00,0x00,0x02,
+ 0x01}}, /* 0x53 */
+ {{0xcd,0x8f,0x8f,0x91,0x9b,0x1b,0x7a,0xff, /* 1152x864-60 */
+ 0x64,0x8c,0x5f,0x62,0x7b,0x10,0x00,0x07,
+ 0x41}} /* 0x54 */
+};
+
+static SiS_VCLKDataStruct SiSUSB_VCLKData[]=
+{
+ { 0x1b,0xe1, 25}, /* 0x00 */
+ { 0x4e,0xe4, 28}, /* 0x01 */
+ { 0x57,0xe4, 31}, /* 0x02 */
+ { 0xc3,0xc8, 36}, /* 0x03 */
+ { 0x42,0xe2, 40}, /* 0x04 */
+ { 0xfe,0xcd, 43}, /* 0x05 */
+ { 0x5d,0xc4, 44}, /* 0x06 */
+ { 0x52,0xe2, 49}, /* 0x07 */
+ { 0x53,0xe2, 50}, /* 0x08 */
+ { 0x74,0x67, 52}, /* 0x09 */
+ { 0x6d,0x66, 56}, /* 0x0a */
+ { 0x5a,0x64, 65}, /* 0x0b */
+ { 0x46,0x44, 67}, /* 0x0c */
+ { 0xb1,0x46, 68}, /* 0x0d */
+ { 0xd3,0x4a, 72}, /* 0x0e */
+ { 0x29,0x61, 75}, /* 0x0f */
+ { 0x6e,0x46, 76}, /* 0x10 */
+ { 0x2b,0x61, 78}, /* 0x11 */
+ { 0x31,0x42, 79}, /* 0x12 */
+ { 0xab,0x44, 83}, /* 0x13 */
+ { 0x46,0x25, 84}, /* 0x14 */
+ { 0x78,0x29, 86}, /* 0x15 */
+ { 0x62,0x44, 94}, /* 0x16 */
+ { 0x2b,0x41,104}, /* 0x17 */
+ { 0x3a,0x23,105}, /* 0x18 */
+ { 0x70,0x44,108}, /* 0x19 */
+ { 0x3c,0x23,109}, /* 0x1a */
+ { 0x5e,0x43,113}, /* 0x1b */
+ { 0xbc,0x44,116}, /* 0x1c */
+ { 0xe0,0x46,132}, /* 0x1d */
+ { 0x54,0x42,135}, /* 0x1e */
+ { 0xea,0x2a,139}, /* 0x1f */
+ { 0x41,0x22,157}, /* 0x20 */
+ { 0x70,0x24,162}, /* 0x21 */
+ { 0x30,0x21,175}, /* 0x22 */
+ { 0x4e,0x22,189}, /* 0x23 */
+ { 0xde,0x26,194}, /* 0x24 */
+ { 0x62,0x06,202}, /* 0x25 */
+ { 0x3f,0x03,229}, /* 0x26 */
+ { 0xb8,0x06,234}, /* 0x27 */
+ { 0x34,0x02,253}, /* 0x28 */
+ { 0x58,0x04,255}, /* 0x29 */
+ { 0x24,0x01,265}, /* 0x2a */
+ { 0x9b,0x02,267}, /* 0x2b */
+ { 0x70,0x05,270}, /* 0x2c */
+ { 0x25,0x01,272}, /* 0x2d */
+ { 0x9c,0x02,277}, /* 0x2e */
+ { 0x27,0x01,286}, /* 0x2f */
+ { 0x3c,0x02,291}, /* 0x30 */
+ { 0xef,0x0a,292}, /* 0x31 */
+ { 0xf6,0x0a,310}, /* 0x32 */
+ { 0x95,0x01,315}, /* 0x33 */
+ { 0xf0,0x09,324}, /* 0x34 */
+ { 0xfe,0x0a,331}, /* 0x35 */
+ { 0xf3,0x09,332}, /* 0x36 */
+ { 0xea,0x08,340}, /* 0x37 */
+ { 0xe8,0x07,376}, /* 0x38 */
+ { 0xde,0x06,389}, /* 0x39 */
+ { 0x52,0x2a, 54}, /* 0x3a 301 TV */
+ { 0x52,0x6a, 27}, /* 0x3b 301 TV */
+ { 0x62,0x24, 70}, /* 0x3c 301 TV */
+ { 0x62,0x64, 70}, /* 0x3d 301 TV */
+ { 0xa8,0x4c, 30}, /* 0x3e 301 TV */
+ { 0x20,0x26, 33}, /* 0x3f 301 TV */
+ { 0x31,0xc2, 39}, /* 0x40 */
+ { 0x60,0x36, 30}, /* 0x41 Chrontel */
+ { 0x40,0x4a, 28}, /* 0x42 Chrontel */
+ { 0x9f,0x46, 44}, /* 0x43 Chrontel */
+ { 0x97,0x2c, 26}, /* 0x44 */
+ { 0x44,0xe4, 25}, /* 0x45 Chrontel */
+ { 0x7e,0x32, 47}, /* 0x46 Chrontel */
+ { 0x8a,0x24, 31}, /* 0x47 Chrontel */
+ { 0x97,0x2c, 26}, /* 0x48 Chrontel */
+ { 0xce,0x3c, 39}, /* 0x49 */
+ { 0x52,0x4a, 36}, /* 0x4a Chrontel */
+ { 0x34,0x61, 95}, /* 0x4b */
+ { 0x78,0x27,108}, /* 0x4c - was 102 */
+ { 0x66,0x43,123}, /* 0x4d Modes 0x26-0x28 (1400x1050) */
+ { 0x41,0x4e, 21}, /* 0x4e */
+ { 0xa1,0x4a, 29}, /* 0x4f Chrontel */
+ { 0x19,0x42, 42}, /* 0x50 */
+ { 0x54,0x46, 58}, /* 0x51 Chrontel */
+ { 0x25,0x42, 61}, /* 0x52 */
+ { 0x44,0x44, 66}, /* 0x53 Chrontel */
+ { 0x3a,0x62, 70}, /* 0x54 Chrontel */
+ { 0x62,0xc6, 34}, /* 0x55 848x480-60 */
+ { 0x6a,0xc6, 37}, /* 0x56 848x480-75 - TEMP */
+ { 0xbf,0xc8, 35}, /* 0x57 856x480-38i,60 */
+ { 0x30,0x23, 88}, /* 0x58 1360x768-62 (is 60Hz!) */
+ { 0x52,0x07,149}, /* 0x59 1280x960-85 */
+ { 0x56,0x07,156}, /* 0x5a 1400x1050-75 */
+ { 0x70,0x29, 81}, /* 0x5b 1280x768 LCD */
+ { 0x45,0x25, 83}, /* 0x5c 1280x800 */
+ { 0x70,0x0a,147}, /* 0x5d 1680x1050 */
+ { 0x70,0x24,162}, /* 0x5e 1600x1200 */
+ { 0x5a,0x64, 65}, /* 0x5f 1280x720 - temp */
+ { 0x63,0x46, 68}, /* 0x60 1280x768_2 */
+ { 0x31,0x42, 79}, /* 0x61 1280x768_3 - temp */
+ { 0, 0, 0}, /* 0x62 - custom (will be filled out at run-time) */
+ { 0x5a,0x64, 65}, /* 0x63 1280x720 (LCD LVDS) */
+ { 0x70,0x28, 90}, /* 0x64 1152x864@60 */
+ { 0x41,0xc4, 32}, /* 0x65 848x480@60 */
+ { 0x5c,0xc6, 32}, /* 0x66 856x480@60 */
+ { 0x76,0xe7, 27}, /* 0x67 720x480@60 */
+ { 0x5f,0xc6, 33}, /* 0x68 720/768x576@60 */
+ { 0x52,0x27, 75}, /* 0x69 1920x1080i 60Hz interlaced */
+ { 0x7c,0x6b, 38}, /* 0x6a 960x540@60 */
+ { 0xe3,0x56, 41}, /* 0x6b 960x600@60 */
+ { 0x45,0x25, 83}, /* 0x6c 1280x800 */
+ { 0x70,0x28, 90}, /* 0x6d 1152x864@60 */
+ { 0x15,0xe1, 20}, /* 0x6e 640x400@60 (fake, not actually used) */
+ { 0x5f,0xc6, 33}, /* 0x6f 720x576@60 */
+ { 0x37,0x5a, 10}, /* 0x70 320x200@60 (fake, not actually used) */
+ { 0x2b,0xc2, 35} /* 0x71 768@576@60 */
+};
+
+static const UCHAR SiS_SoftSetting = 0x30; /* RAM setting */
+
+void SiSUSBRegInit(SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr);
+
+USHORT SiSUSB_GetModeID(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay,
+ int Depth, BOOLEAN FSTN, int LCDwith, int LCDheight);
+BOOLEAN SiSUSBSetMode(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, USHORT ModeNo, BOOLEAN dosetpitch);
+BOOLEAN SiSUSBBIOSSetMode(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom);
+USHORT SiSUSB_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, unsigned int VBFlags);
+DisplayModePtr SiSUSBBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes,
+ BOOLEAN isfordvi, BOOLEAN f2);
+void SiSUSB_MakeClockRegs(ScrnInfoPtr pScrn, int clock, UCHAR *p2b, UCHAR *p2c);
+UShort SiSUSB_GetModeNumber(ScrnInfoPtr pScrn, DisplayModePtr mode, unsigned int VBFlags);
+
+/* From other sis driver modules: */
+extern int SiSUSB_compute_vclk(int Clock, int *out_n, int *out_dn, int *out_div,
+ int *out_sbit, int *out_scale);
+extern void SiSUSBCalcClock(ScrnInfoPtr pScrn, int clock, int max_VLD,
+ unsigned int *vclk);
+
+#endif
+
diff --git a/driver/xf86-video-sisusb/src/sisusb_opt.c b/driver/xf86-video-sisusb/src/sisusb_opt.c
new file mode 100644
index 000000000..8ed42a5d8
--- /dev/null
+++ b/driver/xf86-video-sisusb/src/sisusb_opt.c
@@ -0,0 +1,521 @@
+/* $XFree86$ */
+/* $XdotOrg: driver/xf86-video-sisusb/src/sisusb_opt.c,v 1.7 2005/10/27 18:27:19 twini Exp $ */
+/*
+ * SiSUSB driver option evaluation
+ *
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1) Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2) Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3) The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "sisusb.h"
+
+#include "xf86str.h"
+#include "xf86Cursor.h"
+
+typedef enum {
+ OPTION_NOACCEL,
+ OPTION_SW_CURSOR,
+ OPTION_HW_CURSOR,
+ OPTION_NOXVIDEO,
+ OPTION_NOINTERNALMODES,
+ OPTION_USERGBCURSOR,
+ OPTION_RESTOREBYSET,
+ OPTION_CRT1GAMMA,
+ OPTION_XVGAMMA,
+ OPTION_XVDEFCONTRAST,
+ OPTION_XVDEFBRIGHTNESS,
+ OPTION_XVDEFHUE,
+ OPTION_XVDEFSATURATION,
+ OPTION_XVDEFDISABLEGFX,
+ OPTION_XVDEFDISABLEGFXLR,
+ OPTION_XVUSECHROMAKEY,
+ OPTION_XVCHROMAMIN,
+ OPTION_XVCHROMAMAX,
+ OPTION_XVDISABLECOLORKEY,
+ OPTION_XVINSIDECHROMAKEY,
+ OPTION_XVYUVCHROMAKEY,
+ OPTION_ENABLESISCTRL,
+ OPTION_STOREDBRI,
+ OPTION_NEWSTOREDBRI,
+ OPTION_NEWSTOREDCON,
+ OPTION_DISCONNTIMEOUT,
+ OPTION_PSEUDO
+} SISUSBOpts;
+
+static const OptionInfoRec SISUSBOptions[] = {
+ { OPTION_DISCONNTIMEOUT, "DisconnectTimeout", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_ENABLESISCTRL, "EnableSiSCtrl", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SW_CURSOR, "SWCursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_HW_CURSOR, "HWCursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_USERGBCURSOR, "UseColorHWCursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_NOINTERNALMODES, "NoInternalModes", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_RESTOREBYSET, "RestoreBySetMode", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_CRT1GAMMA, "CRT1Gamma", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_STOREDBRI, "GammaBrightness", OPTV_STRING, {0}, FALSE },
+ { OPTION_STOREDBRI, "StoredGammaBrightness", OPTV_STRING, {0}, FALSE },
+ { OPTION_NEWSTOREDBRI, "Brightness", OPTV_STRING, {0}, FALSE },
+ { OPTION_NEWSTOREDBRI, "NewGammaBrightness", OPTV_STRING, {0}, FALSE },
+ { OPTION_NEWSTOREDCON, "Contrast", OPTV_STRING, {0}, FALSE },
+ { OPTION_NEWSTOREDCON, "NewGammaContrast", OPTV_STRING, {0}, FALSE },
+#ifdef SIS_GLOBAL_ENABLEXV
+ { OPTION_NOXVIDEO, "NoXvideo", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_XVGAMMA, "XvGamma", OPTV_STRING, {0}, FALSE },
+ { OPTION_XVDEFCONTRAST, "XvDefaultContrast", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_XVDEFBRIGHTNESS, "XvDefaultBrightness", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_XVDEFHUE, "XvDefaultHue", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_XVDEFSATURATION, "XvDefaultSaturation", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_XVDEFDISABLEGFX, "XvDefaultDisableGfx", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_XVDEFDISABLEGFXLR, "XvDefaultDisableGfxLR", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_XVCHROMAMIN, "XvChromaMin", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_XVCHROMAMAX, "XvChromaMax", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_XVUSECHROMAKEY, "XvUseChromaKey", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_XVINSIDECHROMAKEY, "XvInsideChromaKey", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_XVYUVCHROMAKEY, "XvYUVChromaKey", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_XVDISABLECOLORKEY, "XvDisableColorKey", OPTV_BOOLEAN, {0}, FALSE },
+#endif
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+static int
+SiSUSB_FIFT(const OptionInfoRec *options, int token)
+{
+ /* Find index from token */
+ int i = 0;
+ while(options[i].token >= 0) {
+ if(options[i].token == token) return i;
+ i++;
+ }
+ return 0; /* Should not happen */
+}
+
+#ifdef SIS_GLOBAL_ENABLEXV
+static void
+SiSUSB_PrintIlRange(ScrnInfoPtr pScrn, int token, int min, int max, UChar showhex)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ static const char *ilparmd = "Invalid parameter for \"%s\". Valid range is %d - %d\n";
+ static const char *ilparmh = "Invalid parameter for \"%s\". Valid range is 0x%x - 0x%x\n";
+
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ showhex ? ilparmh : ilparmd,
+ pSiSUSB->Options[SiSUSB_FIFT(pSiSUSB->Options, token)].name, min, max);
+}
+
+static Bool
+SiSUSB_StrIsBoolOff(char *strptr)
+{
+ if( (!xf86NameCmp(strptr,"off")) ||
+ (!xf86NameCmp(strptr,"false")) ||
+ (!xf86NameCmp(strptr,"no")) ||
+ (!xf86NameCmp(strptr,"0")) ) return TRUE;
+ return FALSE;
+}
+
+static Bool
+SiSUSB_StrIsBoolOn(char *strptr)
+{
+ if( (!xf86NameCmp(strptr,"on")) ||
+ (!xf86NameCmp(strptr,"true")) ||
+ (!xf86NameCmp(strptr,"yes")) ||
+ (!xf86NameCmp(strptr,"1")) ) return TRUE;
+ return FALSE;
+}
+#endif
+
+static Bool
+SiSUSB_EvalOneOrThreeFloats(ScrnInfoPtr pScrn, int token, const char *myerror,
+ char *strptr, int *v1, int *v2, int *v3)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ float val1 = 0.0, val2 = 0.0, val3 = 0.0;
+ Bool valid = FALSE;
+ int result = sscanf(strptr, "%f %f %f", &val1, &val2, &val3);
+ if(result == 1) {
+ if((val1 >= 0.1) && (val1 <= 10.0)) {
+ valid = TRUE;
+ *v1 = *v2 = *v3 = (int)(val1 * 1000);
+ }
+ } else if(result == 3) {
+ if((val1 >= 0.1) && (val1 <= 10.0) &&
+ (val2 >= 0.1) && (val2 <= 10.0) &&
+ (val3 >= 0.1) && (val3 <= 10.0)) {
+ valid = TRUE;
+ *v1 = (int)(val1 * 1000);
+ *v2 = (int)(val2 * 1000);
+ *v3 = (int)(val3 * 1000);
+ }
+ }
+ if(!valid) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, myerror,
+ pSiSUSB->Options[SiSUSB_FIFT(pSiSUSB->Options, token)].name);
+ }
+ return (valid);
+}
+
+static Bool
+SiSUSB_EvalOneOrThreeFloats2(ScrnInfoPtr pScrn, int token, const char *myerror,
+ char *strptr, float *v1, float *v2, float *v3)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ float val1 = 0.0, val2 = 0.0, val3 = 0.0;
+ Bool valid = FALSE;
+ int result = sscanf(strptr, "%f %f %f", &val1, &val2, &val3);
+ if(result == 1) {
+ if((val1 >= -1.0) && (val1 <= 1.0)) {
+ valid = TRUE;
+ *v1 = *v2 = *v3 = val1;
+ }
+ } else if(result == 3) {
+ if((val1 >= -1.0) && (val1 <= 1.0) &&
+ (val2 >= -1.0) && (val2 <= 1.0) &&
+ (val3 >= -1.0) && (val3 <= 1.0)) {
+ valid = TRUE;
+ *v1 = val1;
+ *v2 = val2;
+ *v3 = val3;
+ }
+ }
+ if(!valid) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, myerror,
+ pSiSUSB->Options[SiSUSB_FIFT(pSiSUSB->Options, token)].name);
+ }
+ return (valid);
+}
+
+void
+SiSUSBOptions(ScrnInfoPtr pScrn)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ MessageType from;
+ char *strptr;
+ int ival;
+ static const char *disabledstr= "disabled";
+ static const char *enabledstr = "enabled";
+#ifdef SIS_GLOBAL_ENABLEXV
+ static const char *gammaopt = "%s expects either a boolean, or 1 or 3 real numbers (0.1 - 10.0)\n";
+#endif
+ static const char *briopt = "%s expects one or three real numbers (0.1 - 10.0)\n";
+ static const char *newbriopt = "%s expects one or three real numbers (-1.0 - 1.0)\n";
+ Bool val;
+
+ /* Collect all of the relevant option flags (fill in pScrn->options) */
+ xf86CollectOptions(pScrn, NULL);
+
+ /* Process the options */
+ if(!(pSiSUSB->Options = xalloc(sizeof(SISUSBOptions)))) return;
+
+ memcpy(pSiSUSB->Options, SISUSBOptions, sizeof(SISUSBOptions));
+
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pSiSUSB->Options);
+
+ /* Set defaults */
+
+#ifdef SISVRAMQ
+ /* TODO: Option (315 series VRAM command queue) */
+ /* But beware: sisusbfb does not know about this!!! */
+ pSiSUSB->cmdQueueSize = 512*1024;
+#endif
+ pSiSUSB->HWCursor = TRUE;
+
+ pSiSUSB->NoAccel = TRUE; /* ! */
+ pSiSUSB->ShadowFB = TRUE; /* ! */
+
+ pSiSUSB->timeout = 0;
+
+ pSiSUSB->VESA = -1;
+#ifdef SIS_GLOBAL_ENABLEXV
+ pSiSUSB->NoXvideo = FALSE;
+#else
+ pSiSUSB->NoXvideo = TRUE;
+#endif
+ pSiSUSB->maxxfbmem = 0;
+ pSiSUSB->DSTN = FALSE;
+ pSiSUSB->FSTN = FALSE;
+ pSiSUSB->XvOnCRT2 = FALSE;
+ pSiSUSB->noInternalModes = FALSE;
+ pSiSUSB->restorebyset = TRUE;
+ pSiSUSB->CRT1gamma = TRUE;
+ pSiSUSB->CRT1gammaGiven = FALSE;
+
+ pSiSUSB->XvGamma = FALSE;
+ pSiSUSB->XvGammaGiven = FALSE;
+ pSiSUSB->enablesisctrl = FALSE;
+ pSiSUSB->XvDefBri = 10;
+ pSiSUSB->XvDefCon = 2;
+ pSiSUSB->XvDefHue = 0;
+ pSiSUSB->XvDefSat = 0;
+ pSiSUSB->XvDefDisableGfx = FALSE;
+ pSiSUSB->XvDefDisableGfxLR = FALSE;
+ pSiSUSB->XvUseChromaKey = FALSE;
+ pSiSUSB->XvDisableColorKey = FALSE;
+ pSiSUSB->XvInsideChromaKey = FALSE;
+ pSiSUSB->XvYUVChromaKey = FALSE;
+ pSiSUSB->XvChromaMin = 0x000101fe;
+ pSiSUSB->XvChromaMax = 0x000101ff;
+ pSiSUSB->XvGammaRed = pSiSUSB->XvGammaGreen = pSiSUSB->XvGammaBlue =
+ pSiSUSB->XvGammaRedDef = pSiSUSB->XvGammaGreenDef = pSiSUSB->XvGammaBlueDef = 1000;
+ pSiSUSB->GammaBriR = pSiSUSB->GammaBriG = pSiSUSB->GammaBriB = 1000;
+ pSiSUSB->NewGammaBriR = pSiSUSB->NewGammaBriG = pSiSUSB->NewGammaBriB = 0.0;
+ pSiSUSB->NewGammaConR = pSiSUSB->NewGammaConG = pSiSUSB->NewGammaConB = 0.0;
+
+ pSiSUSB->HideHWCursor = FALSE;
+ pSiSUSB->HWCursorIsVisible = FALSE;
+
+#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0)
+ pSiSUSB->OptUseColorCursor = 0;
+#else
+ pSiSUSB->OptUseColorCursor = 1;
+#endif
+
+ /* Collect the options */
+
+ /* DisconnectTimeout
+ *
+ * 0 = forever, -1 = abort server immediately
+ * otherwise: re-probe for n seconds
+ *
+ */
+ from = X_DEFAULT;
+ if(xf86GetOptValInteger(pSiSUSB->Options, OPTION_DISCONNTIMEOUT, &ival)) {
+ if(ival < 0) pSiSUSB->timeout = -1;
+ else pSiSUSB->timeout = (ival > 32768) ? 32768 : ival;
+ from = X_CONFIG;
+ }
+ switch(pSiSUSB->timeout) {
+ case -1:
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Device disconnection will abort X server\n");
+ break;
+ case 0:
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Device will be re-probed forever after disconnection\n");
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Device will be re-probed for %d seconds after disconnection\n",
+ pSiSUSB->timeout);
+ break;
+ }
+
+ /* SWCursor, HWCursor
+ * Chooses whether to use the hardware or software cursor
+ */
+ from = X_DEFAULT;
+ if(xf86GetOptValBool(pSiSUSB->Options, OPTION_HW_CURSOR, &pSiSUSB->HWCursor)) {
+ from = X_CONFIG;
+ }
+ if(xf86ReturnOptValBool(pSiSUSB->Options, OPTION_SW_CURSOR, FALSE)) {
+ from = X_CONFIG;
+ pSiSUSB->HWCursor = FALSE;
+ pSiSUSB->OptUseColorCursor = 0;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
+ pSiSUSB->HWCursor ? "HW" : "SW");
+
+ /*
+ * UseColorHWCursor
+ * Enable/disable color hardware cursor
+ *
+ */
+#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0)
+#ifdef ARGB_CURSOR
+#ifdef SIS_ARGB_CURSOR
+ if(pSiSUSB->HWCursor) {
+ from = X_DEFAULT;
+ if(xf86GetOptValBool(pSiSUSB->Options, OPTION_USERGBCURSOR, &pSiSUSB->OptUseColorCursor)) {
+ from = X_CONFIG;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Color HW cursor is %s\n",
+ pSiSUSB->OptUseColorCursor ? enabledstr : disabledstr);
+ }
+#endif
+#endif
+#endif
+
+ /* RestoreBySetMode
+ * Set this to force the driver to set the old mode instead of restoring
+ * the register contents. This can be used to overcome problems with
+ * LCD panels and video bridges.
+ */
+ if(xf86GetOptValBool(pSiSUSB->Options, OPTION_RESTOREBYSET, &val)) {
+ pSiSUSB->restorebyset = val ? TRUE : FALSE;
+ }
+
+ /* EnableSiSCtrl */
+ /* Allow sisctrl tool to change driver settings */
+ from = X_DEFAULT;
+ if(xf86GetOptValBool(pSiSUSB->Options, OPTION_ENABLESISCTRL, &val)) {
+ if(val) pSiSUSB->enablesisctrl = TRUE;
+ from = X_CONFIG;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "SiSCtrl utility interface is %s\n",
+ pSiSUSB->enablesisctrl ? enabledstr : disabledstr);
+
+
+ /* CRT1Gamma - enable/disable gamma correction for CRT1
+ */
+ if(xf86GetOptValBool(pSiSUSB->Options, OPTION_CRT1GAMMA, &val)) {
+ pSiSUSB->CRT1gamma = val;
+ pSiSUSB->CRT1gammaGiven = TRUE;
+ }
+
+ /* NoInternalModes (300/315/330 series only)
+ * Don't use that.
+ */
+ if(xf86GetOptValBool(pSiSUSB->Options, OPTION_NOINTERNALMODES, &pSiSUSB->noInternalModes)) {
+ if(pSiSUSB->noInternalModes) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Usage of built-in modes is %s\n", disabledstr);
+ }
+ }
+
+ /* NoXVideo
+ * Set this to TRUE to disable Xv hardware video acceleration
+ */
+#ifdef SIS_GLOBAL_ENABLEXV
+ if(!pSiSUSB->NoXvideo) {
+ if(xf86ReturnOptValBool(pSiSUSB->Options, OPTION_NOXVIDEO, FALSE)) {
+ pSiSUSB->NoXvideo = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "XVideo extension (Xv) disabled\n");
+ }
+
+ if(!pSiSUSB->NoXvideo) {
+
+ /* Some Xv properties' defaults can be set by options */
+ if(xf86GetOptValInteger(pSiSUSB->Options, OPTION_XVDEFCONTRAST, &ival)) {
+ if((ival >= 0) && (ival <= 7)) pSiSUSB->XvDefCon = ival;
+ else SiSUSB_PrintIlRange(pScrn, OPTION_XVDEFCONTRAST, 0, 7, 0);
+ }
+ if(xf86GetOptValInteger(pSiSUSB->Options, OPTION_XVDEFBRIGHTNESS, &ival)) {
+ if((ival >= -128) && (ival <= 127)) pSiSUSB->XvDefBri = ival;
+ else SiSUSB_PrintIlRange(pScrn, OPTION_XVDEFBRIGHTNESS, -128, 127, 0);
+ }
+
+ if(xf86GetOptValInteger(pSiSUSB->Options, OPTION_XVDEFHUE, &ival)) {
+ if((ival >= -8) && (ival <= 7)) pSiSUSB->XvDefHue = ival;
+ else SiSUSB_PrintIlRange(pScrn, OPTION_XVDEFHUE, -8, 7, 0);
+ }
+ if(xf86GetOptValInteger(pSiSUSB->Options, OPTION_XVDEFSATURATION, &ival)) {
+ if((ival >= -7) && (ival <= 7)) pSiSUSB->XvDefSat = ival;
+ else SiSUSB_PrintIlRange(pScrn, OPTION_XVDEFSATURATION, -7, 7, 0);
+ }
+
+ if(xf86GetOptValBool(pSiSUSB->Options, OPTION_XVDEFDISABLEGFX, &val)) {
+ if(val) pSiSUSB->XvDefDisableGfx = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Graphics display will be %s during Xv usage\n",
+ val ? disabledstr : enabledstr);
+ }
+
+ if(xf86GetOptValBool(pSiSUSB->Options, OPTION_XVDEFDISABLEGFXLR, &val)) {
+ if(val) pSiSUSB->XvDefDisableGfxLR = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Graphics display left/right of overlay will be %s during Xv usage\n",
+ val ? disabledstr : enabledstr);
+ }
+ if(xf86GetOptValBool(pSiSUSB->Options, OPTION_XVDISABLECOLORKEY, &val)) {
+ if(val) pSiSUSB->XvDisableColorKey = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Xv Color key is %s\n",
+ val ? disabledstr : enabledstr);
+ }
+ if(xf86GetOptValBool(pSiSUSB->Options, OPTION_XVUSECHROMAKEY, &val)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Xv Chroma-keying is %s\n",
+ val ? enabledstr : disabledstr);
+ if(val) pSiSUSB->XvUseChromaKey = TRUE;
+ }
+ if(xf86GetOptValBool(pSiSUSB->Options, OPTION_XVINSIDECHROMAKEY, &val)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Xv: Video is transparent if %s chroma key range\n",
+ val ? "inside" : "outside");
+ if(val) pSiSUSB->XvInsideChromaKey = TRUE;
+ }
+ if(xf86GetOptValInteger(pSiSUSB->Options, OPTION_XVCHROMAMIN, &ival)) {
+ if((ival >= 0) && (ival <= 0xffffff)) pSiSUSB->XvChromaMin = ival;
+ else SiSUSB_PrintIlRange(pScrn, OPTION_XVCHROMAMIN, 0, 0xffffff, 1);
+ }
+ if(xf86GetOptValInteger(pSiSUSB->Options, OPTION_XVCHROMAMAX, &ival)) {
+ if((ival >= 0) && (ival <= 0xffffff)) pSiSUSB->XvChromaMax = ival;
+ else SiSUSB_PrintIlRange(pScrn, OPTION_XVCHROMAMAX, 0, 0xffffff, 1);
+ }
+
+ /* XvGamma - enable/disable gamma correction for Xv
+ * Supported for CRT1 only
+ */
+ if((strptr = (char *)xf86GetOptValString(pSiSUSB->Options, OPTION_XVGAMMA))) {
+ if(SiSUSB_StrIsBoolOff(strptr)) {
+ pSiSUSB->XvGamma = FALSE;
+ pSiSUSB->XvGammaGiven = TRUE;
+ } else if(SiSUSB_StrIsBoolOn(strptr)) {
+ pSiSUSB->XvGamma = pSiSUSB->XvGammaGiven = TRUE;
+ } else {
+ if(SiSUSB_EvalOneOrThreeFloats(pScrn, OPTION_XVGAMMA, gammaopt, strptr,
+ &pSiSUSB->XvGammaRed, &pSiSUSB->XvGammaGreen, &pSiSUSB->XvGammaBlue)) {
+ pSiSUSB->XvGamma = pSiSUSB->XvGammaGiven = TRUE;
+ pSiSUSB->XvGammaRedDef = pSiSUSB->XvGammaRed;
+ pSiSUSB->XvGammaGreenDef = pSiSUSB->XvGammaGreen;
+ pSiSUSB->XvGammaBlue = pSiSUSB->XvGammaBlue;
+ }
+ }
+ }
+
+ }
+ }
+#endif
+
+ {
+ Bool GotNewBri = FALSE;
+ if((strptr = (char *)xf86GetOptValString(pSiSUSB->Options, OPTION_NEWSTOREDCON))) {
+ SiSUSB_EvalOneOrThreeFloats2(pScrn, OPTION_NEWSTOREDCON, newbriopt, strptr,
+ &pSiSUSB->NewGammaConR, &pSiSUSB->NewGammaConG, &pSiSUSB->NewGammaConB);
+ GotNewBri = TRUE;
+ }
+ if((strptr = (char *)xf86GetOptValString(pSiSUSB->Options, OPTION_NEWSTOREDBRI))) {
+ SiSUSB_EvalOneOrThreeFloats2(pScrn, OPTION_NEWSTOREDBRI, newbriopt, strptr,
+ &pSiSUSB->NewGammaBriR, &pSiSUSB->NewGammaBriG, &pSiSUSB->NewGammaBriB);
+ GotNewBri = TRUE;
+ }
+ if(!GotNewBri) {
+ if((strptr = (char *)xf86GetOptValString(pSiSUSB->Options, OPTION_STOREDBRI))) {
+ SiSUSB_EvalOneOrThreeFloats(pScrn, OPTION_STOREDBRI, briopt, strptr,
+ &pSiSUSB->GammaBriR, &pSiSUSB->GammaBriG, &pSiSUSB->GammaBriB);
+ pSiSUSB->SiS_SD3_Flags |= SiS_SD3_OLDGAMMAINUSE;
+ }
+ }
+ }
+
+}
+
+const OptionInfoRec *
+SISUSBAvailableOptions(int chipid, int busid)
+{
+ return SISUSBOptions;
+}
diff --git a/driver/xf86-video-sisusb/src/sisusb_osdef.h b/driver/xf86-video-sisusb/src/sisusb_osdef.h
new file mode 100644
index 000000000..23b4e014c
--- /dev/null
+++ b/driver/xf86-video-sisusb/src/sisusb_osdef.h
@@ -0,0 +1,89 @@
+/* $XFree86$ */
+/* $XdotOrg: driver/xf86-video-sisusb/src/sisusb_osdef.h,v 1.5 2005/07/09 02:50:34 twini Exp $ */
+/*
+ * OS depending defines
+ *
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
+ *
+ * If distributed as part of the Linux kernel, the following license terms
+ * apply:
+ *
+ * * This program is free software; you can redistribute it and/or modify
+ * * it under the terms of the GNU General Public License as published by
+ * * the Free Software Foundation; either version 2 of the named License,
+ * * or any later version.
+ * *
+ * * This program is distributed in the hope that it will be useful,
+ * * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * * GNU General Public License for more details.
+ * *
+ * * You should have received a copy of the GNU General Public License
+ * * along with this program; if not, write to the Free Software
+ * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Otherwise, the following license terms apply:
+ *
+ * * Redistribution and use in source and binary forms, with or without
+ * * modification, are permitted provided that the following conditions
+ * * are met:
+ * * 1) Redistributions of source code must retain the above copyright
+ * * notice, this list of conditions and the following disclaimer.
+ * * 2) Redistributions in binary form must reproduce the above copyright
+ * * notice, this list of conditions and the following disclaimer in the
+ * * documentation and/or other materials provided with the distribution.
+ * * 3) The name of the author may not be used to endorse or promote products
+ * * derived from this software without specific prior written permission.
+ * *
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
+
+#ifndef _SISUSB_OSDEF_H_
+#define _SISUSB_OSDEF_H_
+
+#ifdef OutPortByte
+#undef OutPortByte
+#endif
+
+#ifdef OutPortWord
+#undef OutPortWord
+#endif
+
+#ifdef OutPortLong
+#undef OutPortLong
+#endif
+
+#ifdef InPortByte
+#undef InPortByte
+#endif
+
+#ifdef InPortWord
+#undef InPortWord
+#endif
+
+#ifdef InPortLong
+#undef InPortLong
+#endif
+
+#define SIS315H
+
+#define OutPortByte(p,v) outSISREG((IOADDRESS)(p),(CARD8)(v))
+#define OutPortWord(p,v) outSISREGW((IOADDRESS)(p),(CARD16)(v))
+#define OutPortLong(p,v) outSISREGL((IOADDRESS)(p),(CARD32)(v))
+#define InPortByte(p) inSISREG((IOADDRESS)(p))
+#define InPortWord(p) inSISREGW((IOADDRESS)(p))
+#define InPortLong(p) inSISREGL((IOADDRESS)(p))
+
+#endif /* _SISUSB_OSDEF_H_ */
diff --git a/driver/xf86-video-sisusb/src/sisusb_regs.h b/driver/xf86-video-sisusb/src/sisusb_regs.h
new file mode 100644
index 000000000..4dc4f9102
--- /dev/null
+++ b/driver/xf86-video-sisusb/src/sisusb_regs.h
@@ -0,0 +1,370 @@
+/* $XFree86$ */
+/* $XdotOrg: driver/xf86-video-sisusb/src/sisusb_regs.h,v 1.5 2005/07/09 02:50:34 twini Exp $ */
+/*
+ * Register access macros and register definitions
+ *
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1) Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2) Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3) The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
+
+#ifndef _SISUSB_REGS_H_
+#define _SISUSB_REGS_H_
+
+/* Endian related macros */
+
+/* About endianness:
+ * 1) I/O ports, PCI config registers
+ * The kernel driver handles swapping. Data written or read
+ * back is in machine endianness.
+ * 2) Video memory
+ * Data is copied 1:1. Command queue, HW cursor and the like
+ * needs to be swapped.
+ * 3) MMIO
+ * Data is copied 1:1. MMIO macros need to handle the swapping.
+ *
+ */
+
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+
+#ifdef NEED_cpu_to_le32
+static __inline CARD32 sisusb_cpu_to_le32(CARD32 v)
+{
+ return( (((CARD32)(v) & (CARD32)0x000000ffUL) << 24) | \
+ (((CARD32)(v) & (CARD32)0x0000ff00UL) << 8) | \
+ (((CARD32)(v) & (CARD32)0x00ff0000UL) >> 8) | \
+ (((CARD32)(v) & (CARD32)0xff000000UL) >> 24) );
+}
+
+#define sisusb_le32_to_cpu(v) sisusb_cpu_to_le32((v))
+#endif
+
+#ifdef NEED_cpu_to_le16
+static __inline CARD16 sisusb_cpu_to_le16(CARD16 v)
+{
+ return( (((CARD16)(v) & (CARD16)0x00ffU) << 8) |
+ (((CARD16)(v) & (CARD16)0xff00U) >> 8) );
+}
+
+#define sisusb_le16_to_cpu(v) sisusb_cpu_to_le16((v))
+#endif
+
+#else
+
+#define sisusb_cpu_to_le32(v) (v)
+#define sisusb_cpu_to_le16(v) (v)
+#define sisusb_le32_to_cpu(v) (v)
+#define sisusb_le16_to_cpu(v) (v)
+
+#endif
+
+/* Video RAM access macros */
+
+/* (Currently, these are use on all platforms; USB2VGA is handled
+ * specially in the code)
+ */
+
+/* dest is video RAM, src is system RAM */
+#define sisfbwritel(dest, data) *(dest) = (data)
+#define sisfbwritelinc(dest, data) *((dest)++) = (data)
+#define sisfbwritelp(dest, dataptr) *(dest) = *(dataptr)
+#define sisfbwritelpinc(dest, dataptr) *((dest)++) = *((dataptr)++)
+
+#define sisfbwritew(dest, data) *(dest) = (data)
+#define sisfbwritewinc(dest, data) *((dest)++) = (data)
+#define sisfbwritewp(dest, dataptr) *(dest) = *(dataptr)
+#define sisfbwritewpinc(dest, dataptr) *((dest)++) = *((dataptr)++)
+
+#define sisfbwriteb(dest, data) *(dest) = (data)
+#define sisfbwritebinc(dest, data) *((dest)++) = (data)
+#define sisfbwritebp(dest, dataptr) *(dest) = *(dataptr)
+#define sisfbwritebpinc(dest, dataptr) *((dest)++) = *((dataptr)++)
+
+/* Source is video RAM */
+#define sisfbreadl(src) *(src)
+#define sisfbreadlinc(src) *((src)++)
+
+#define sisfbreadw(src) *(src)
+#define sisfbreadwinc(src) *((src)++)
+
+#define sisfbreadb(src) *(src)
+#define sisfbreadbinc(src) *((src)++)
+
+/* Port offsets --------------- */
+
+#define AROFFSET 0x40
+#define ARROFFSET 0x41
+#define GROFFSET 0x4e
+#define SROFFSET 0x44
+#define CROFFSET 0x54
+#define MISCROFFSET 0x4c
+#define MISCWOFFSET 0x42
+#define INPUTSTATOFFSET 0x5A
+#define PART1OFFSET 0x04
+#define PART2OFFSET 0x10
+#define PART3OFFSET 0x12
+#define PART4OFFSET 0x14
+#define PART5OFFSET 0x16
+#define CAPTUREOFFSET 0x00
+#define VIDEOOFFSET 0x02
+#define COLREGOFFSET 0x48
+#define PELMASKOFFSET 0x46
+
+#define SISAR pSiSUSB->RelIO + AROFFSET
+#define SISARR pSiSUSB->RelIO + ARROFFSET
+#define SISGR pSiSUSB->RelIO + GROFFSET
+#define SISSR pSiSUSB->RelIO + SROFFSET
+#define SISCR pSiSUSB->RelIO + CROFFSET
+#define SISMISCR pSiSUSB->RelIO + MISCROFFSET
+#define SISMISCW pSiSUSB->RelIO + MISCWOFFSET
+#define SISINPSTAT pSiSUSB->RelIO + INPUTSTATOFFSET
+#define SISPART1 pSiSUSB->RelIO + PART1OFFSET
+#define SISPART2 pSiSUSB->RelIO + PART2OFFSET
+#define SISPART3 pSiSUSB->RelIO + PART3OFFSET
+#define SISPART4 pSiSUSB->RelIO + PART4OFFSET
+#define SISPART5 pSiSUSB->RelIO + PART5OFFSET
+#define SISCAP pSiSUSB->RelIO + CAPTUREOFFSET
+#define SISVID pSiSUSB->RelIO + VIDEOOFFSET
+#define SISCOLIDXR pSiSUSB->RelIO + COLREGOFFSET - 1
+#define SISCOLIDX pSiSUSB->RelIO + COLREGOFFSET
+#define SISCOLDATA pSiSUSB->RelIO + COLREGOFFSET + 1
+#define SISCOL2IDX SISPART5
+#define SISCOL2DATA SISPART5 + 1
+#define SISPEL pSiSUSB->RelIO + PELMASKOFFSET
+
+/* Video registers (300/315/330/340 series only) --------------- */
+#define Index_VI_Passwd 0x00
+
+/* Video overlay horizontal start/end, unit=screen pixels */
+#define Index_VI_Win_Hor_Disp_Start_Low 0x01
+#define Index_VI_Win_Hor_Disp_End_Low 0x02
+#define Index_VI_Win_Hor_Over 0x03 /* Overflow */
+
+/* Video overlay vertical start/end, unit=screen pixels */
+#define Index_VI_Win_Ver_Disp_Start_Low 0x04
+#define Index_VI_Win_Ver_Disp_End_Low 0x05
+#define Index_VI_Win_Ver_Over 0x06 /* Overflow */
+
+/* Y Plane (4:2:0) or YUV (4:2:2) buffer start address, unit=word */
+#define Index_VI_Disp_Y_Buf_Start_Low 0x07
+#define Index_VI_Disp_Y_Buf_Start_Middle 0x08
+#define Index_VI_Disp_Y_Buf_Start_High 0x09
+
+/* U Plane (4:2:0) buffer start address, unit=word */
+#define Index_VI_U_Buf_Start_Low 0x0A
+#define Index_VI_U_Buf_Start_Middle 0x0B
+#define Index_VI_U_Buf_Start_High 0x0C
+
+/* V Plane (4:2:0) buffer start address, unit=word */
+#define Index_VI_V_Buf_Start_Low 0x0D
+#define Index_VI_V_Buf_Start_Middle 0x0E
+#define Index_VI_V_Buf_Start_High 0x0F
+
+/* Pitch for Y, UV Planes, unit=word */
+#define Index_VI_Disp_Y_Buf_Pitch_Low 0x10
+#define Index_VI_Disp_UV_Buf_Pitch_Low 0x11
+#define Index_VI_Disp_Y_UV_Buf_Pitch_Middle 0x12
+
+/* What is this ? */
+#define Index_VI_Disp_Y_Buf_Preset_Low 0x13
+#define Index_VI_Disp_Y_Buf_Preset_Middle 0x14
+
+#define Index_VI_UV_Buf_Preset_Low 0x15
+#define Index_VI_UV_Buf_Preset_Middle 0x16
+#define Index_VI_Disp_Y_UV_Buf_Preset_High 0x17
+
+/* Scaling control registers */
+#define Index_VI_Hor_Post_Up_Scale_Low 0x18
+#define Index_VI_Hor_Post_Up_Scale_High 0x19
+#define Index_VI_Ver_Up_Scale_Low 0x1A
+#define Index_VI_Ver_Up_Scale_High 0x1B
+#define Index_VI_Scale_Control 0x1C
+
+/* Playback line buffer control */
+#define Index_VI_Play_Threshold_Low 0x1D
+#define Index_VI_Play_Threshold_High 0x1E
+#define Index_VI_Line_Buffer_Size 0x1F
+
+/* Destination color key */
+#define Index_VI_Overlay_ColorKey_Red_Min 0x20
+#define Index_VI_Overlay_ColorKey_Green_Min 0x21
+#define Index_VI_Overlay_ColorKey_Blue_Min 0x22
+#define Index_VI_Overlay_ColorKey_Red_Max 0x23
+#define Index_VI_Overlay_ColorKey_Green_Max 0x24
+#define Index_VI_Overlay_ColorKey_Blue_Max 0x25
+
+/* Source color key, YUV color space */
+#define Index_VI_Overlay_ChromaKey_Red_Y_Min 0x26
+#define Index_VI_Overlay_ChromaKey_Green_U_Min 0x27
+#define Index_VI_Overlay_ChromaKey_Blue_V_Min 0x28
+#define Index_VI_Overlay_ChromaKey_Red_Y_Max 0x29
+#define Index_VI_Overlay_ChromaKey_Green_U_Max 0x2A
+#define Index_VI_Overlay_ChromaKey_Blue_V_Max 0x2B
+
+/* Contrast enhancement and brightness control */
+#define Index_VI_Contrast_Factor 0x2C /* obviously unused/undefined */
+#define Index_VI_Brightness 0x2D
+#define Index_VI_Contrast_Enh_Ctrl 0x2E
+
+#define Index_VI_Key_Overlay_OP 0x2F
+
+#define Index_VI_Control_Misc0 0x30
+#define Index_VI_Control_Misc1 0x31
+#define Index_VI_Control_Misc2 0x32
+
+/* Subpicture registers */
+#define Index_VI_SubPict_Buf_Start_Low 0x33
+#define Index_VI_SubPict_Buf_Start_Middle 0x34
+#define Index_VI_SubPict_Buf_Start_High 0x35
+
+/* What is this ? */
+#define Index_VI_SubPict_Buf_Preset_Low 0x36
+#define Index_VI_SubPict_Buf_Preset_Middle 0x37
+
+/* Subpicture pitch, unit=16 bytes */
+#define Index_VI_SubPict_Buf_Pitch 0x38
+
+/* Subpicture scaling control */
+#define Index_VI_SubPict_Hor_Scale_Low 0x39
+#define Index_VI_SubPict_Hor_Scale_High 0x3A
+#define Index_VI_SubPict_Vert_Scale_Low 0x3B
+#define Index_VI_SubPict_Vert_Scale_High 0x3C
+
+#define Index_VI_SubPict_Scale_Control 0x3D
+/* (0x40 = enable/disable subpicture) */
+
+/* Subpicture line buffer control */
+#define Index_VI_SubPict_Threshold 0x3E
+
+/* What is this? */
+#define Index_VI_FIFO_Max 0x3F
+
+/* Subpicture palette; 16 colors, total 32 bytes address space */
+#define Index_VI_SubPict_Pal_Base_Low 0x40
+#define Index_VI_SubPict_Pal_Base_High 0x41
+
+/* I wish I knew how to use these ... */
+#define Index_MPEG_Read_Ctrl0 0x60 /* MPEG auto flip */
+#define Index_MPEG_Read_Ctrl1 0x61 /* MPEG auto flip */
+#define Index_MPEG_Read_Ctrl2 0x62 /* MPEG auto flip */
+#define Index_MPEG_Read_Ctrl3 0x63 /* MPEG auto flip */
+
+/* MPEG AutoFlip scale */
+#define Index_MPEG_Ver_Up_Scale_Low 0x64
+#define Index_MPEG_Ver_Up_Scale_High 0x65
+
+#define Index_MPEG_Y_Buf_Preset_Low 0x66
+#define Index_MPEG_Y_Buf_Preset_Middle 0x67
+#define Index_MPEG_UV_Buf_Preset_Low 0x68
+#define Index_MPEG_UV_Buf_Preset_Middle 0x69
+#define Index_MPEG_Y_UV_Buf_Preset_High 0x6A
+
+/* The following registers only exist on the 315/330/340 series */
+
+/* Bit 16:24 of Y_U_V buf start address */
+#define Index_VI_Y_Buf_Start_Over 0x6B
+#define Index_VI_U_Buf_Start_Over 0x6C
+#define Index_VI_V_Buf_Start_Over 0x6D
+
+#define Index_VI_Disp_Y_Buf_Pitch_High 0x6E
+#define Index_VI_Disp_UV_Buf_Pitch_High 0x6F
+
+/* Hue and saturation */
+#define Index_VI_Hue 0x70
+#define Index_VI_Saturation 0x71
+
+#define Index_VI_SubPict_Start_Over 0x72
+#define Index_VI_SubPict_Buf_Pitch_High 0x73
+
+#define Index_VI_Control_Misc3 0x74
+
+/* 340 and later: */
+/* DDA registers 0x75 - 0xb4 */
+/* threshold high 0xb5, 0xb6 */
+#define Index_VI_Line_Buffer_Size_High 0xb7
+
+
+/* Bits in Scale control (0x1c) */
+#define VI_Scale_Ctrl_Horiz_DDA 0x20
+#define VI_Scale_Ctrl_Vert_DDA 0x40
+
+/* Bits (and helpers) for Index_VI_Control_Misc0 */
+#define VI_Misc0_Enable_Capture_AutoFlip 0x01 /* 340 only? */
+#define VI_Misc0_Enable_Overlay 0x02
+#define VI_Misc0_420_Plane_Enable 0x04 /* Select Plane or Packed mode */
+#define VI_Misc0_422_Enable 0x20 /* Select 422 or 411 mode */
+#define VI_Misc0_Fmt_YVU420P 0x0C /* YUV420 Planar (I420, YV12) */
+#define VI_Misc0_Fmt_YUYV 0x28 /* YUYV Packed (=YUY2) */
+#define VI_Misc0_Fmt_UYVY 0x08 /* (UYVY) */
+#define VI_Misc0_Fmt_YVYU 0x38 /* (YVYU) (315 series only?) */
+#define VI_Misc0_Fmt_NV21 0x5c /* (330 series only?) */
+#define VI_Misc0_Fmt_NV12 0x4c /* (330 series only?) */
+#define VI_Misc0_ChromaKeyRGBYUV 0x40 /* 300 series only: 0 = RGB, 1 = YUV */
+
+/* Bits for Index_VI_Control_Misc1 */
+#define VI_Misc1_DisableGraphicsAtOverlay 0x01 /* Disables graphics display in overlay area */
+#define VI_Misc1_BOB_Enable 0x02 /* Enable BOB de-interlacer */
+#define VI_Misc1_Line_Merge 0x04
+#define VI_Misc1_Field_Mode 0x08 /* ? Assume even/odd fields interleaved in memory ? */
+#define VI_Misc1_Non_Interleave 0x10 /* ? Odd and Even fields are not interleaved ? */
+#define VI_Misc1_Buf_Addr_Lock 0x20 /* 315 series only? */
+/* #define VI_Misc1_? 0x40 */
+/* #define VI_Misc1_? 0x80 */
+
+/* Bits for Index_VI_Control_Misc2 */
+#define VI_Misc2_Select_Video2 0x01
+#define VI_Misc2_Video2_On_Top 0x02
+#define VI_Misc2_DisableGraphics 0x04 /* Disable graphics display entirely (<= 650 only, not >= M650, 651) */
+#define VI_Misc2_Vertical_Interpol 0x08
+#define VI_Misc2_Dual_Line_Merge 0x10 /* dual-overlay chips only; "dual video windows relative line buffer merge" */
+#define VI_Misc2_All_Line_Merge 0x20 /* > 315 only */
+#define VI_Misc2_Auto_Flip_Enable 0x40
+#define VI_Misc2_Video_Reg_Write_Enable 0x80 /* 315 series only? */
+
+/* Bits for Index_VI_Control_Misc3 */
+#define VI_Misc3_Submit_Video_1 0x01 /* AKA "address ready" */
+#define VI_Misc3_Submit_Video_2 0x02 /* AKA "address ready" */
+#define VI_Misc3_Submit_SubPict 0x04 /* AKA "address ready" */
+
+/* Values for Index_VI_Key_Overlay_OP (0x2F) */
+#define VI_ROP_Never 0x00
+#define VI_ROP_DestKey 0x03
+#define VI_ROP_ChromaKey 0x05
+#define VI_ROP_NotChromaKey 0x0A
+#define VI_ROP_Always 0x0F
+
+
+/* mmio registers for video */
+#define REG_PRIM_CRT_COUNTER 0x8514
+
+/* MPEG MMIO registers (630 and later) ----------------------------------------- */
+
+/* Not public (yet?) */
+
+
+#endif /* SIS_REGS_H_ */
+
+
diff --git a/driver/xf86-video-sisusb/src/sisusb_setup.c b/driver/xf86-video-sisusb/src/sisusb_setup.c
new file mode 100644
index 000000000..2b12f9d0f
--- /dev/null
+++ b/driver/xf86-video-sisusb/src/sisusb_setup.c
@@ -0,0 +1,132 @@
+/* $XFree86$ */
+/* $XdotOrg: driver/xf86-video-sisusb/src/sisusb_setup.c,v 1.4 2005/07/11 02:30:00 ajax Exp $ */
+/*
+ * Basic hardware and memory detection
+ *
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1) Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2) Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3) The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "sisusb.h"
+#include "sisusb_regs.h"
+
+extern int SiSUSBMclk(SISUSBPtr pSiSUSB);
+
+static void
+sis315USBSetup(ScrnInfoPtr pScrn)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ int busSDR[4] = {64, 64, 128, 128};
+ int busDDR[4] = {32, 32, 64, 64};
+ int busDDRA[4] = {64+32, 64+32 , (64+32)*2, (64+32)*2};
+ unsigned int config, config1, config2, sr3a, cr5f;
+ char *dramTypeStr315[] = {
+ "Single channel 1 rank SDR SDRAM",
+ "Single channel 1 rank SDR SGRAM",
+ "Single channel 1 rank DDR SDRAM",
+ "Single channel 1 rank DDR SGRAM",
+ "Single channel 2 rank SDR SDRAM",
+ "Single channel 2 rank SDR SGRAM",
+ "Single channel 2 rank DDR SDRAM",
+ "Single channel 2 rank DDR SGRAM",
+ "Asymmetric SDR SDRAM",
+ "Asymmetric SDR SGRAM",
+ "Asymmetric DDR SDRAM",
+ "Asymmetric DDR SGRAM",
+ "Dual channel SDR SDRAM",
+ "Dual channel SDR SGRAM",
+ "Dual channel DDR SDRAM",
+ "Dual channel DDR SGRAM"
+ };
+
+ inSISIDXREG(pSiSUSB, SISSR, 0x14, config);
+ config1 = (config & 0x0C) >> 2;
+
+ inSISIDXREG(pSiSUSB, SISSR, 0x3A, sr3a);
+ config2 = sr3a & 0x03;
+
+ inSISIDXREG(pSiSUSB, SISCR,0x5f,cr5f);
+
+ pScrn->videoRam = (1 << ((config & 0xF0) >> 4)) * 1024;
+
+ pSiSUSB->IsAGPCard = FALSE;
+
+ if(cr5f & 0x10) pSiSUSB->ChipFlags |= SiSCF_Is315E;
+
+ /* If SINGLE_CHANNEL_2_RANK or DUAL_CHANNEL_1_RANK -> mem * 2 */
+ if((config1 == 0x01) || (config1 == 0x03)) {
+ pScrn->videoRam <<= 1;
+ }
+
+ /* If DDR asymetric -> mem * 1,5 */
+ if(config1 == 0x02) pScrn->videoRam += pScrn->videoRam/2;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "DRAM type: %s\n", dramTypeStr315[(config1 * 4) + config2]);
+
+ pSiSUSB->MemClock = SiSUSBMclk(pSiSUSB);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Memory clock: %3.3f MHz\n",
+ pSiSUSB->MemClock/1000.0);
+
+ /* DDR -> mclk * 2 - needed for bandwidth calculation */
+ if(config2 & 0x02) pSiSUSB->MemClock *= 2;
+
+ if(config1 == 0x02)
+ pSiSUSB->BusWidth = busDDRA[(config & 0x03)];
+ else if(config2 & 0x02)
+ pSiSUSB->BusWidth = busDDR[(config & 0x03)];
+ else
+ pSiSUSB->BusWidth = busSDR[(config & 0x03)];
+
+ if(pSiSUSB->ChipFlags & SiSCF_Is315E) {
+ inSISIDXREG(pSiSUSB, SISSR,0x15,config);
+ if(config & 0x10) pSiSUSB->BusWidth = 32;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "DRAM bus width: %d bit\n",
+ pSiSUSB->BusWidth);
+}
+
+void
+SiSUSBSetup(ScrnInfoPtr pScrn)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+
+ pSiSUSB->VBFlags = 0;
+ pSiSUSB->VBFlags2 = 0;
+
+ sis315USBSetup(pScrn);
+}
+
+
diff --git a/driver/xf86-video-sisusb/src/sisusb_shadow.c b/driver/xf86-video-sisusb/src/sisusb_shadow.c
new file mode 100644
index 000000000..982a6683c
--- /dev/null
+++ b/driver/xf86-video-sisusb/src/sisusb_shadow.c
@@ -0,0 +1,153 @@
+/* $XFree86$ */
+/* $XdotOrg: driver/xf86-video-sisusb/src/sisusb_shadow.c,v 1.5 2005/07/11 02:30:00 ajax Exp $ */
+/*
+ * SiS USB driver shadow framebuffer handling
+ *
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1) Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2) Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3) The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "sisusb.h"
+#define NEED_cpu_to_le16
+#include "sisusb_regs.h"
+
+#include "servermd.h"
+
+#if 0
+extern void SiSUSBSync(ScrnInfoPtr pScrn);
+#endif
+
+void SISUSBRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+void SISUSBDoRefreshArea(ScrnInfoPtr pScrn);
+
+void
+SISUSBRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+
+#if 0
+ if(pSiSUSB->IgnoreRefresh) return;
+#endif
+
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ if(pScrn->bitsPerPixel == 16) {
+
+ int FBPitch = pSiSUSB->ShadowPitch >> 1;
+ int w, wb, h, i, offset;
+ int count = num;
+ CARD16 *src16, *dst16;
+ BoxPtr mbox = pbox;
+
+ while(count--) {
+
+ w = mbox->x2 - mbox->x1;
+ h = mbox->y2 - mbox->y1;
+ i = FBPitch - w;
+ offset = (mbox->y1 * FBPitch) + mbox->x1;
+ src16 = (CARD16 *)pSiSUSB->ShadowPtrSwap + offset;
+ dst16 = (CARD16 *)pSiSUSB->ShadowPtr + offset;
+
+ while(h--) {
+ wb = w;
+ while(wb--) {
+ *dst16++ = sisusb_cpu_to_le16(*src16++);
+ }
+ dst16 += i;
+ src16 += i;
+ }
+
+ mbox++;
+ }
+
+ }
+#endif
+
+ if(!pSiSUSB->ShBoxcount) {
+ pSiSUSB->ShXmin = pbox->x1;
+ pSiSUSB->ShXmax = pbox->x2;
+ pSiSUSB->ShYmin = pbox->y1;
+ pSiSUSB->ShYmax = pbox->y2;
+ pbox++;
+ pSiSUSB->ShBoxcount++;
+ num--;
+ }
+
+ while(num--) {
+ if(pbox->y1 < pSiSUSB->ShYmin) {
+ pSiSUSB->ShYmin = pbox->y1;
+ pSiSUSB->ShXmin = pbox->x1;
+ } else if(pbox->y1 == pSiSUSB->ShYmin) {
+ if(pbox->x1 < pSiSUSB->ShXmin) pSiSUSB->ShXmin = pbox->x1;
+ }
+ if(pbox->y2 > pSiSUSB->ShYmax) {
+ pSiSUSB->ShYmax = pbox->y2;
+ pSiSUSB->ShXmax = pbox->x2;
+ } else if(pbox->y2 == pSiSUSB->ShYmax) {
+ if(pbox->x2 > pSiSUSB->ShXmax) pSiSUSB->ShXmax = pbox->x2;
+ }
+ pSiSUSB->ShBoxcount++;
+ pbox++;
+ }
+}
+
+void
+SISUSBDoRefreshArea(ScrnInfoPtr pScrn)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ CARD8 *src, *dst;
+ int width, height, Bpp, FBPitch;
+ int xmin = pSiSUSB->ShXmin;
+ int xmax = pSiSUSB->ShXmax;
+ int ymin = pSiSUSB->ShYmin;
+ int ymax = pSiSUSB->ShYmax;
+
+ if(pSiSUSB->delaycount++ < 3) return;
+ pSiSUSB->delaycount = 0;
+
+ if(!pSiSUSB->ShBoxcount) return;
+
+ Bpp = pScrn->bitsPerPixel >> 3;
+ FBPitch = pSiSUSB->ShadowPitch;
+
+#if 0
+ if(pSiSUSB->AccelNeedSync) {
+ SiSUSBSync(pScrn);
+ }
+#endif
+
+ src = pSiSUSB->ShadowPtr + (ymin * FBPitch) + (xmin * Bpp);
+ dst = pSiSUSB->FbBase + (ymin * FBPitch) + (xmin * Bpp);
+ height = ymax - ymin;
+ width = ((height - 1) * FBPitch) - (xmin * Bpp) + (xmax * Bpp);
+ SiSUSBMemCopyToVideoRam(pSiSUSB, dst, src, width);
+
+ pSiSUSB->ShBoxcount = 0;
+}
diff --git a/driver/xf86-video-sisusb/src/sisusb_struct.h b/driver/xf86-video-sisusb/src/sisusb_struct.h
new file mode 100644
index 000000000..86a180c4d
--- /dev/null
+++ b/driver/xf86-video-sisusb/src/sisusb_struct.h
@@ -0,0 +1,184 @@
+/* $XFree86$ */
+/* $XdotOrg: driver/xf86-video-sisusb/src/sisusb_struct.h,v 1.4 2005/07/09 02:50:34 twini Exp $ */
+/*
+ * General structure definitions for universal mode switching modules
+ *
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
+ *
+ * If distributed as part of the Linux kernel, the following license terms
+ * apply:
+ *
+ * * This program is free software; you can redistribute it and/or modify
+ * * it under the terms of the GNU General Public License as published by
+ * * the Free Software Foundation; either version 2 of the named License,
+ * * or any later version.
+ * *
+ * * This program is distributed in the hope that it will be useful,
+ * * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * * GNU General Public License for more details.
+ * *
+ * * You should have received a copy of the GNU General Public License
+ * * along with this program; if not, write to the Free Software
+ * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Otherwise, the following license terms apply:
+ *
+ * * Redistribution and use in source and binary forms, with or without
+ * * modification, are permitted provided that the following conditions
+ * * are met:
+ * * 1) Redistributions of source code must retain the above copyright
+ * * notice, this list of conditions and the following disclaimer.
+ * * 2) Redistributions in binary form must reproduce the above copyright
+ * * notice, this list of conditions and the following disclaimer in the
+ * * documentation and/or other materials provided with the distribution.
+ * * 3) The name of the author may not be used to endorse or promote products
+ * * derived from this software without specific prior written permission.
+ * *
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
+
+#ifndef _VSTRUCT_
+#define _VSTRUCT_
+
+typedef struct _SiS_StandTableStruct
+{
+ UCHAR CRT_COLS;
+ UCHAR ROWS;
+ UCHAR CHAR_HEIGHT;
+ USHORT CRT_LEN;
+ UCHAR SR[4];
+ UCHAR MISC;
+ UCHAR CRTC[0x19];
+ UCHAR ATTR[0x14];
+ UCHAR GRC[9];
+} SiS_StandTableStruct;
+
+typedef struct _SiS_ExtStruct
+{
+ UCHAR Ext_ModeID;
+ USHORT Ext_ModeFlag;
+ USHORT Ext_VESAID;
+ UCHAR Ext_RESINFO;
+ UCHAR VB_ExtTVFlickerIndex;
+ UCHAR VB_ExtTVEdgeIndex;
+ UCHAR VB_ExtTVYFilterIndex;
+ UCHAR VB_ExtTVYFilterIndexROM661;
+ UCHAR REFindex;
+ CHAR ROMMODEIDX661;
+} SiS_ExtStruct;
+
+typedef struct _SiS_Ext2Struct
+{
+ USHORT Ext_InfoFlag;
+ UCHAR Ext_CRT1CRTC;
+ UCHAR Ext_CRTVCLK;
+ UCHAR Ext_CRT2CRTC;
+ UCHAR Ext_CRT2CRTC_NS;
+ UCHAR ModeID;
+ USHORT XRes;
+ USHORT YRes;
+ UCHAR Ext_PDC;
+ UCHAR Ext_FakeCRT2CRTC;
+ UCHAR Ext_FakeCRT2Clk;
+} SiS_Ext2Struct;
+
+typedef struct _SiS_CRT1TableStruct
+{
+ UCHAR CR[17];
+} SiS_CRT1TableStruct;
+
+typedef struct _SiS_VCLKDataStruct
+{
+ UCHAR SR2B,SR2C;
+ USHORT CLOCK;
+} SiS_VCLKDataStruct;
+
+typedef struct _SiS_ModeResInfoStruct
+{
+ USHORT HTotal;
+ USHORT VTotal;
+ UCHAR XChar;
+ UCHAR YChar;
+} SiS_ModeResInfoStruct;
+
+typedef struct _SiS_Private
+{
+ unsigned char ChipType;
+ unsigned char ChipRevision;
+
+ void *pSiSUSB;
+ SISIOADDRESS IOAddress;
+
+ SISIOADDRESS SiS_P3c4;
+ SISIOADDRESS SiS_P3d4;
+ SISIOADDRESS SiS_P3c0;
+ SISIOADDRESS SiS_P3ce;
+ SISIOADDRESS SiS_P3c2;
+ SISIOADDRESS SiS_P3ca;
+ SISIOADDRESS SiS_P3c6;
+ SISIOADDRESS SiS_P3c7;
+ SISIOADDRESS SiS_P3c8;
+ SISIOADDRESS SiS_P3c9;
+ SISIOADDRESS SiS_P3cb;
+ SISIOADDRESS SiS_P3cc;
+ SISIOADDRESS SiS_P3cd;
+ SISIOADDRESS SiS_P3da;
+ SISIOADDRESS SiS_Part1Port;
+
+ UCHAR SiS_MyCR63;
+ USHORT SiS_CRT1Mode;
+ int SiS_RAMType;
+ UCHAR SiS_ChannelAB;
+ UCHAR SiS_DataBusWidth;
+ USHORT SiS_ModeType;
+ USHORT SiS_SetFlag;
+
+ const SiS_StandTableStruct *SiS_StandTable;
+ const SiS_ExtStruct *SiS_EModeIDTable;
+ const SiS_Ext2Struct *SiS_RefIndex;
+ const SiS_CRT1TableStruct *SiS_CRT1Table;
+ SiS_VCLKDataStruct *SiS_VCLKData;
+ const SiS_ModeResInfoStruct *SiS_ModeResInfo;
+ const UCHAR *pSiS_SoftSetting;
+ BOOLEAN UseCustomMode;
+ BOOLEAN CRT1UsesCustomMode;
+ USHORT CHDisplay;
+ USHORT CHSyncStart;
+ USHORT CHSyncEnd;
+ USHORT CHTotal;
+ USHORT CHBlankStart;
+ USHORT CHBlankEnd;
+ USHORT CVDisplay;
+ USHORT CVSyncStart;
+ USHORT CVSyncEnd;
+ USHORT CVTotal;
+ USHORT CVBlankStart;
+ USHORT CVBlankEnd;
+ ULONG CDClock;
+ ULONG CFlags;
+ UCHAR CCRT1CRTC[17];
+ UCHAR CSR2B;
+ UCHAR CSR2C;
+ USHORT CSRClock;
+ USHORT CSRClock_CRT1;
+ USHORT CModeFlag;
+ USHORT CModeFlag_CRT1;
+ USHORT CInfoFlag;
+
+} SiS_Private;
+
+#endif
+
diff --git a/driver/xf86-video-sisusb/src/sisusb_types.h b/driver/xf86-video-sisusb/src/sisusb_types.h
new file mode 100644
index 000000000..6ee413fbb
--- /dev/null
+++ b/driver/xf86-video-sisusb/src/sisusb_types.h
@@ -0,0 +1,229 @@
+/* $XFree86$ */
+/* $XdotOrg: driver/xf86-video-sisusb/src/sisusb_types.h,v 1.7 2005/08/15 22:57:51 twini Exp $ */
+/*
+ * General type definitions for universal mode switching modules
+ *
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
+ *
+ * If distributed as part of the Linux kernel, the following license terms
+ * apply:
+ *
+ * * This program is free software; you can redistribute it and/or modify
+ * * it under the terms of the GNU General Public License as published by
+ * * the Free Software Foundation; either version 2 of the named License,
+ * * or any later version.
+ * *
+ * * This program is distributed in the hope that it will be useful,
+ * * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * * GNU General Public License for more details.
+ * *
+ * * You should have received a copy of the GNU General Public License
+ * * along with this program; if not, write to the Free Software
+ * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Otherwise, the following license terms apply:
+ *
+ * * Redistribution and use in source and binary forms, with or without
+ * * modification, are permitted provided that the following conditions
+ * * are met:
+ * * 1) Redistributions of source code must retain the above copyright
+ * * notice, this list of conditions and the following disclaimer.
+ * * 2) Redistributions in binary form must reproduce the above copyright
+ * * notice, this list of conditions and the following disclaimer in the
+ * * documentation and/or other materials provided with the distribution.
+ * * 3) The name of the author may not be used to endorse or promote products
+ * * derived from this software without specific prior written permission.
+ * *
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
+
+#ifndef _VGATYPES_
+#define _VGATYPES_
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#ifndef CHAR
+typedef char CHAR;
+#endif
+
+#ifndef SHORT
+typedef short SHORT;
+#endif
+
+#ifndef LONG
+typedef long LONG;
+#endif
+
+#ifndef UCHAR
+typedef unsigned char UCHAR;
+#endif
+
+#ifndef USHORT
+typedef unsigned short USHORT;
+#endif
+
+#ifndef ULONG
+typedef unsigned long ULONG;
+#endif
+
+#ifndef BOOLEAN
+typedef unsigned char BOOLEAN;
+#endif
+
+#define SISIOMEMTYPE
+
+#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,0,0,0)
+typedef unsigned long IOADDRESS;
+typedef unsigned long SISIOADDRESS;
+#else
+typedef IOADDRESS SISIOADDRESS;
+#endif
+
+typedef enum _SIS_CHIP_TYPE {
+ SIS_VGALegacy = 0,
+ SIS_530,
+ SIS_OLD,
+ SIS_300,
+ SIS_630,
+ SIS_730,
+ SIS_540,
+ SIS_315H, /* SiS 310 */
+ SIS_315,
+ SIS_315PRO, /* SiS 325 */
+ SIS_550,
+ SIS_650,
+ SIS_740,
+ SIS_330,
+ SIS_661,
+ SIS_741,
+ SIS_670,
+ SIS_660 = 35,
+ SIS_760,
+ SIS_761,
+ SIS_762,
+ SIS_770,
+ SIS_340 = 55,
+ SIS_341,
+ SIS_342,
+ XGI_20 = 75,
+ XGI_40,
+ MAX_SIS_CHIP
+} SIS_CHIP_TYPE;
+
+/* Addtional IOCTLs for communication sisfb <> X driver */
+/* If changing this, sisfb.h must also be changed (for sisfb) */
+
+/* ioctl for identifying and giving some info (esp. memory heap start) */
+#define SISUSBFB_GET_INFO_SIZE 0x8004f33c
+#define SISUSBFB_GET_INFO 0x8000f33b /* Must be patched with result from ..._SIZE at D[29:16] */
+
+/* lock sisfb from register access */
+#define SISUSBFB_SET_LOCK 0x4004f33a
+
+/* Structure argument for SISUSBFB_GET_INFO ioctl */
+typedef struct _SISUSBFB_INFO sisusbfb_info, *psisusbfb_info;
+
+struct _SISUSBFB_INFO {
+ CARD32 sisusbfb_id; /* for identifying sisusbfb */
+#define SISUSBFB_ID 0x53495546 /* Identify myself with 'SIUF' */
+ CARD32 chip_id; /* PCI ID of detected chip */
+ CARD32 memory; /* video memory in KB which sisusbfb manages */
+ CARD32 heapstart; /* heap start in KB */
+ CARD8 fbvidmode; /* current sisfb mode */
+
+ CARD8 sisusbfb_version;
+ CARD8 sisusbfb_revision;
+ CARD8 sisusbfb_patchlevel;
+
+ CARD8 sisusbfb_caps; /* sisfb's capabilities */
+
+ CARD32 sisusbfb_tqlen; /* turbo/cmd queue length (in KB) */
+
+ CARD32 sisusbfb_minor; /* minor device number of USB device */
+
+ CARD32 reserved[32]; /* for future use */
+};
+
+/* Structure argument for SISUSB_GET_INFO ioctl */
+typedef struct _SISUSB_INFO sisusb_info, *psisusb_info;
+
+struct _SISUSB_INFO {
+ CARD32 sisusb_id; /* for identifying sisusb */
+#define SISUSB_ID 0x53495355 /* Identify myself with 'SISU' */
+ CARD8 sisusb_version;
+ CARD8 sisusb_revision;
+ CARD8 sisusb_patchlevel;
+ CARD8 sisusb_gfxinit; /* graphics core initialized? */
+
+ CARD32 sisusb_vrambase;
+ CARD32 sisusb_mmiobase;
+ CARD32 sisusb_iobase;
+ CARD32 sisusb_pcibase;
+
+ CARD32 sisusb_vramsize;
+
+ CARD32 sisusb_minor;
+
+ CARD32 sisusb_fbdevactive; /* != 0 if framebuffer device active */
+
+ CARD32 sisusb_conactive; /* != 0 if console driver active */
+
+ CARD8 sisusb_reserved[28]; /* for future use */
+};
+
+typedef struct _SISUSB_COMMAND sisusb_command, *psisusb_command;
+
+struct _SISUSB_COMMAND {
+ CARD8 operation; /* see below */
+ CARD8 data0; /* operation dependent */
+ CARD8 data1; /* operation dependent */
+ CARD8 data2; /* operation dependent */
+ CARD32 data3; /* operation dependent */
+ CARD32 data4; /* for future use */
+};
+
+/* quick routines to handle index registers */
+#define SUCMD_GET 0x01 /* for all: data0 = index, data3 = port */
+#define SUCMD_SET 0x02 /* data1 = value */
+#define SUCMD_SETOR 0x03 /* data1 = or */
+#define SUCMD_SETAND 0x04 /* data1 = and */
+#define SUCMD_SETANDOR 0x05 /* data1 = and, data2 = or */
+#define SUCMD_SETMASK 0x06 /* data1 = data, data2 = mask */
+
+/* Clear video RAM */
+#define SUCMD_CLRSCR 0x07 /* data0:1:2 = length, data3 = address */
+
+/* Restore text mode & fonts (console driver); destroy text mode */
+#define SUCMD_HANDLETEXTMODE 0x08
+
+/* ioctl numbers */
+#define SISUSB_GET_CONFIG_SIZE 0x8004f33e /* _IOR(0xF3,0x3E,__u32) */
+#define SISUSB_GET_CONFIG 0x8000f33f /* _IOR(0xF3,0x3F,__u32) */
+ /* Must be patched with result from ..._SIZE at D[29:16] */
+#define SISUSB_COMMAND 0xc00cf33d /* _IORW(0xF3,0x3D,struct _SISUSB_COMMAND) */
+
+#endif
+
diff --git a/driver/xf86-video-sisusb/src/sisusb_utility.c b/driver/xf86-video-sisusb/src/sisusb_utility.c
new file mode 100644
index 000000000..7df9da277
--- /dev/null
+++ b/driver/xf86-video-sisusb/src/sisusb_utility.c
@@ -0,0 +1,1309 @@
+/* $XFree86$ */
+/* $XdotOrg: driver/xf86-video-sisusb/src/sisusb_utility.c,v 1.8 2005/09/16 13:52:16 twini Exp $ */
+/*
+ * SiSUSB driver utility interface & routines
+ *
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1) Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2) Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3) The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "sisusb.h"
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include <X11/X.h>
+#include "dixstruct.h"
+#define _XF86MISC_SERVER_
+#include <X11/extensions/xf86misc.h>
+
+#include "sisusb_videostr.h"
+
+/* Definitions for SISCTRL extension */
+
+#define SISCTRL_PROTOCOL_NAME "SISCTRL"
+
+#define SISCTRL_MAJOR_VERSION 0 /* current version numbers */
+#define SISCTRL_MINOR_VERSION 1
+
+#define SISCTRL_MAX_SCREENS 32 /* number of screens the ext can handle */
+
+#define X_SiSCtrlQueryVersion 0
+#define X_SiSCtrlCommand 1
+
+#define SDC_ID 0x53495321
+
+#define SDC_VERSION 1
+
+#define SDC_NUM_PARM_RESULT 20
+
+/* sdc_command */
+#define SDC_CMD_GETVERSION 0x98980001
+#define SDC_CMD_GETHWINFO 0x98980002
+#define SDC_CMD_GETALLFLAGS 0x98980003
+#define SDC_CMD_GETVBFLAGSVERSION 0x98980004
+#define SDC_CMD_GETVBFLAGS 0x98980005
+#define SDC_CMD_CHECKMODEFORCRT2 0x98980006
+#define SDC_CMD_SETVBFLAGS 0x98980007
+#define SDC_CMD_GETDETECTEDDEVICES 0x98980008
+#define SDC_CMD_REDETECTCRT2DEVICES 0x98980009
+#define SDC_CMD_GETCRT1STATUS 0x9898000a
+#define SDC_CMD_SETCRT1STATUS 0x9898000b
+#define SDC_CMD_GETSDFLAGS 0x9898000c
+#define SDC_CMD_GETSD2FLAGS 0x9898000d
+#define SDC_CMD_GETLOCKSTATUS 0x9898000e
+#define SDC_CMD_SETLOCKSTATUS 0x9898000f
+#define SDC_CMD_GETTVANTIFLICKER 0x98980010
+#define SDC_CMD_SETTVANTIFLICKER 0x98980011
+#define SDC_CMD_GETTVSATURATION 0x98980012
+#define SDC_CMD_SETTVSATURATION 0x98980013
+#define SDC_CMD_GETTVEDGEENHANCE 0x98980014
+#define SDC_CMD_SETTVEDGEENHANCE 0x98980015
+#define SDC_CMD_GETTVCFILTER 0x98980016
+#define SDC_CMD_SETTVCFILTER 0x98980017
+#define SDC_CMD_GETTVYFILTER 0x98980018
+#define SDC_CMD_SETTVYFILTER 0x98980019
+#define SDC_CMD_GETTVCOLORCALIB 0x9898001a
+#define SDC_CMD_SETTVCOLORCALIB 0x9898001b
+#define SDC_CMD_GETTVCHCONTRAST 0x9898001c
+#define SDC_CMD_SETTVCHCONTRAST 0x9898001d
+#define SDC_CMD_GETTVCHTEXTENHANCE 0x9898001e
+#define SDC_CMD_SETTVCHTEXTENHANCE 0x9898001f
+#define SDC_CMD_GETTVCHCHROMAFLICKERFILTER 0x98980020
+#define SDC_CMD_SETTVCHCHROMAFLICKERFILTER 0x98980021
+#define SDC_CMD_GETTVCHLUMAFLICKERFILTER 0x98980022
+#define SDC_CMD_SETTVCHLUMAFLICKERFILTER 0x98980023
+#define SDC_CMD_GETTVCHCVBSCOLOR 0x98980024
+#define SDC_CMD_SETTVCHCVBSCOLOR 0x98980025
+#define SDC_CMD_GETCHTVOVERSCAN 0x98980026
+#define SDC_CMD_SETCHTVOVERSCAN 0x98980027
+#define SDC_CMD_GETGAMMASTATUS 0x98980028
+#define SDC_CMD_SETGAMMASTATUS 0x98980029
+#define SDC_CMD_GETTVXSCALE 0x9898002a
+#define SDC_CMD_SETTVXSCALE 0x9898002b
+#define SDC_CMD_GETTVYSCALE 0x9898002c
+#define SDC_CMD_SETTVYSCALE 0x9898002d
+#define SDC_CMD_GETSCREENSIZE 0x9898002e
+#define SDC_CMD_GETGAMMABRIGHTNESS 0x9898002f
+#define SDC_CMD_SETGAMMABRIGHTNESS 0x98980030
+#define SDC_CMD_GETGAMMABRIGHTNESS2 0x98980031
+#define SDC_CMD_SETGAMMABRIGHTNESS2 0x98980032
+#define SDC_CMD_GETGETGAMMACRT2 0x98980033
+#define SDC_CMD_SETGETGAMMACRT2 0x98980034
+#define SDC_CMD_GETHWCURSORSTATUS 0x98980035
+#define SDC_CMD_SETHWCURSORSTATUS 0x98980036
+#define SDC_CMD_GETPANELMODE 0x98980037
+#define SDC_CMD_SETPANELMODE 0x98980038
+#define SDC_CMD_GETMERGEDMODEDETAILS 0x98980039
+#define SDC_CMD_GETDEVICENAME 0x9898003a
+#define SDC_CMD_GETMONITORNAME 0x9898003b
+#define SDC_CMD_GETDEVICENAME2 0x9898003c
+#define SDC_CMD_GETMONITORNAME2 0x9898003d
+#define SDC_CMD_SETXVBRIGHTNESS 0x9898003e
+#define SDC_CMD_GETXVBRIGHTNESS 0x9898003f
+#define SDC_CMD_SETXVCONTRAST 0x98980040
+#define SDC_CMD_GETXVCONTRAST 0x98980041
+#define SDC_CMD_SETXVHUE 0x98980042
+#define SDC_CMD_GETXVHUE 0x98980043
+#define SDC_CMD_SETXVSATURATION 0x98980044
+#define SDC_CMD_GETXVSATURATION 0x98980045
+#define SDC_CMD_SETXVGAMMA 0x98980046
+#define SDC_CMD_GETXVGAMMA 0x98980047
+#define SDC_CMD_SETXVCOLORKEY 0x98980048
+#define SDC_CMD_GETXVCOLORKEY 0x98980049
+#define SDC_CMD_SETXVAUTOPAINTCOLORKEY 0x9898004a
+#define SDC_CMD_GETXVAUTOPAINTCOLORKEY 0x9898004b
+#define SDC_CMD_SETXVDEFAULTS 0x9898004c
+#define SDC_CMD_SETXVDISABLEGFX 0x9898004d
+#define SDC_CMD_GETXVDISABLEGFX 0x9898004e
+#define SDC_CMD_SETXVDISABLEGFXLR 0x9898004f
+#define SDC_CMD_GETXVDISABLEGFXLR 0x98980050
+#define SDC_CMD_SETXVSWITCHCRT 0x98980051
+#define SDC_CMD_GETXVSWITCHCRT 0x98980052
+#define SDC_CMD_GETTVXPOS 0x98980053
+#define SDC_CMD_SETTVXPOS 0x98980054
+#define SDC_CMD_GETTVYPOS 0x98980055
+#define SDC_CMD_SETTVYPOS 0x98980056
+#define SDC_CMD_SETXVDEINT 0x98980057
+#define SDC_CMD_GETXVDEINT 0x98980058
+#define SDC_CMD_GETMONGAMMACRT1 0x98980059
+#define SDC_CMD_GETMONGAMMACRT2 0x9898005a
+#define SDC_CMD_LOGQUIET 0x9898005b
+#define SDC_CMD_GETNEWGAMMABRICON 0x9898005c
+#define SDC_CMD_SETNEWGAMMABRICON 0x9898005d
+#define SDC_CMD_GETNEWGAMMABRICON2 0x9898005e
+#define SDC_CMD_SETNEWGAMMABRICON2 0x9898005f
+#define SDC_CMD_GETGETNEWGAMMACRT2 0x98980060
+#define SDC_CMD_SETGETNEWGAMMACRT2 0x98980061
+/* more to come, adapt MAXCOMMAND! */
+#define SDC_MAXCOMMAND SDC_CMD_SETGETNEWGAMMACRT2
+
+/* in result_header */
+#define SDC_RESULT_OK 0x66670000
+#define SDC_RESULT_UNDEFCMD 0x66670001
+#define SDC_RESULT_NOPERM 0x66670002
+#define SDC_RESULT_INVAL 0x66670003
+#define SDC_RESULT_MESSAGEERROR 0x66670004 /* Client side only */
+#define SDC_RESULT_NOEXTENSION 0x66670005 /* Client side only */
+
+/* For SDC_CMD_GETHWINFO */
+#define SDC_BUS_TYPE_PCI 0
+#define SDC_BUS_TYPE_AGP 1
+#define SDC_BUS_TYPE_PCIE 2
+#define SDC_BUS_TYPE_USB 3
+
+/* For SDC_CMD_GETMERGEDMODEDETAILS */
+#define SDC_MMODE_POS_ERROR 0
+#define SDC_MMODE_POS_LEFTOF 1
+#define SDC_MMODE_POS_RIGHTOF 2
+#define SDC_MMODE_POS_ABOVE 3
+#define SDC_MMODE_POS_BELOW 4
+#define SDC_MMODE_POS_CLONE 5
+
+typedef struct _SiSCtrlQueryVersion {
+ CARD8 reqType; /* always SiSCtrlReqCode */
+ CARD8 SiSCtrlReqType; /* always X_SiSCtrlQueryVersion */
+ CARD16 length B16;
+} xSiSCtrlQueryVersionReq;
+#define sz_xSiSCtrlQueryVersionReq 4
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD16 majorVersion B16; /* major version of SISCTRL */
+ CARD16 minorVersion B16; /* minor version of SISCTRL */
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+ CARD32 pad6 B32;
+} xSiSCtrlQueryVersionReply;
+#define sz_xSiSCtrlQueryVersionReply 32
+
+typedef struct {
+ CARD8 reqType; /* always SiSCtrlReqCode */
+ CARD8 SiSCtrlReqType; /* always SiSCtrl_SiSCtrlCommand */
+ CARD16 length B16;
+ CARD32 pad1 B32;
+ CARD32 screen;
+ CARD32 sdc_id;
+ CARD32 sdc_chksum;
+ CARD32 sdc_command;
+ CARD32 sdc_parm[SDC_NUM_PARM_RESULT];
+ CARD32 sdc_result_header;
+ CARD32 sdc_result[SDC_NUM_PARM_RESULT];
+ char sdc_buffer[32];
+} xSiSCtrlCommandReq;
+#define sz_xSiSCtrlCommandReq (28 + (SDC_NUM_PARM_RESULT * 4 * 2) + 32)
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 screen;
+ CARD32 sdc_id;
+ CARD32 sdc_chksum;
+ CARD32 sdc_command;
+ CARD32 sdc_parm[SDC_NUM_PARM_RESULT];
+ CARD32 sdc_result_header;
+ CARD32 sdc_result[SDC_NUM_PARM_RESULT];
+ char sdc_buffer[32];
+} xSiSCtrlCommandReply;
+#define sz_xSiSCtrlCommandReply (28 + (SDC_NUM_PARM_RESULT * 4 * 2) + 32)
+
+typedef struct {
+ unsigned int maxscreens; /* Max number of entries = SISCTRL_MAX_SCREENS*/
+ unsigned int version_major; /* Extension major version */
+ unsigned int version_minor; /* Extension minor version */
+ int (*HandleSiSDirectCommand[SISCTRL_MAX_SCREENS])(xSiSCtrlCommandReply *);
+} xSiSCtrlScreenTable;
+
+#ifdef X_XF86MiscPassMessage
+int SISUSBHandleMessage(int scrnIndex, const char *msgtype,
+ const char *msgval, char **retmsg);
+#endif
+void SiSUSBCtrlExtInit(ScrnInfoPtr pScrn);
+void SiSUSBCtrlExtUnregister(SISUSBPtr pSiSUSB, int index);
+
+#ifdef SIS_GLOBAL_ENABLEXV
+#ifdef XV_SD_DEPRECATED
+int SISUSBSetPortUtilAttribute(ScrnInfoPtr pScrn, Atom attribute,
+ INT32 value, SISUSBPortPrivPtr pPriv);
+int SISUSBGetPortUtilAttribute(ScrnInfoPtr pScrn, Atom attribute,
+ INT32 *value, SISUSBPortPrivPtr pPriv);
+#endif
+#ifdef SIS_ENABLEXV
+extern void SiSUSBUpdateXvGamma(SISUSBPtr pSiSUSB, SISUSBPortPrivPtr pPriv);
+#endif
+extern void SISUSBSetPortDefaults(ScrnInfoPtr pScrn, SISUSBPortPrivPtr pPriv);
+#endif /* SIS_GLOBAL_ENABLEXV */
+
+/***********************************
+ * MessageHandler interface *
+ * (unused now; use extension) *
+ ***********************************/
+
+#ifdef X_XF86MiscPassMessage
+int
+SISUSBHandleMessage(int scrnIndex, const char *msgtype, const char *msgval, char **retmsg)
+{
+ return BadMatch;
+}
+#endif
+
+/***********************************
+ * SiSCtrl extension interface *
+ ***********************************/
+
+static void
+sisutil_prepare_string(xSiSCtrlCommandReply *sdcbuf, char *mystring)
+{
+ int slen = 0;
+ sdcbuf->sdc_buffer[0] = 0;
+ if(mystring) {
+ slen = strlen(mystring);
+ if(slen > 31) slen = 31;
+ strncpy(&sdcbuf->sdc_buffer[0], mystring, slen);
+ sdcbuf->sdc_buffer[slen] = 0;
+ }
+ sdcbuf->sdc_result[0] = slen;
+}
+
+static int
+SiSHandleSiSDirectCommand(xSiSCtrlCommandReply *sdcbuf)
+{
+ ScrnInfoPtr pScrn = xf86Screens[sdcbuf->screen];
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ SISUSBPortPrivPtr pPriv = NULL;
+ int i;
+ ULong j;
+
+ if(sdcbuf->sdc_id != SDC_ID) return BadMatch;
+
+ if(pSiSUSB->adaptor) {
+ pPriv = GET_PORT_PRIVATE(pScrn);
+ }
+
+ j = sdcbuf->sdc_command;
+ for(i = 0; i < SDC_NUM_PARM_RESULT; i++) {
+ j += sdcbuf->sdc_parm[i];
+ }
+
+ if(j != sdcbuf->sdc_chksum) return BadMatch;
+
+ sdcbuf->sdc_result_header = SDC_RESULT_OK;
+
+ switch(sdcbuf->sdc_command) {
+
+ case SDC_CMD_GETVERSION:
+ sdcbuf->sdc_result[0] = SDC_VERSION;
+ sdcbuf->sdc_result[1] = SDC_MAXCOMMAND;
+ break;
+
+ case SDC_CMD_GETHWINFO:
+ sdcbuf->sdc_result[0] = SDC_BUS_TYPE_USB;
+ sdcbuf->sdc_result[1] = pSiSUSB->USBBus; /* not set! */
+ sdcbuf->sdc_result[2] = pSiSUSB->USBDev; /* not set! */
+ sdcbuf->sdc_result[3] = 0;
+ sdcbuf->sdc_result[4] = 0;
+ sdcbuf->sdc_result[5] = pSiSUSB->ChipFlags;
+ sdcbuf->sdc_result[6] = pSiSUSB->ChipType;
+ sdcbuf->sdc_result[7] = pSiSUSB->ChipRev;
+ sdcbuf->sdc_result[8] = SISUSBDRIVERVERSIONYEAR;
+ sdcbuf->sdc_result[9] = SISUSBDRIVERVERSIONMONTH;
+ sdcbuf->sdc_result[10] = SISUSBDRIVERVERSIONDAY;
+ sdcbuf->sdc_result[11] = SISUSBDRIVERREVISION;
+ sdcbuf->sdc_result[12] = pScrn->videoRam;
+ sdcbuf->sdc_result[13] = 0; /* No UMA */
+ sdcbuf->sdc_result[14] = pScrn->videoRam; /* All LFB */
+ sdcbuf->sdc_buffer[0] = 0;
+ break;
+
+ case SDC_CMD_GETALLFLAGS:
+ sdcbuf->sdc_result[0] = SIS_VBFlagsVersion;
+ sdcbuf->sdc_result[1] = pSiSUSB->VBFlags;
+ sdcbuf->sdc_result[2] = pSiSUSB->SiS_SD_Flags;
+ sdcbuf->sdc_result[3] = pSiSUSB->SiS_SD2_Flags;
+ sdcbuf->sdc_result[4] = 0; /* No CRT2 devices */
+ sdcbuf->sdc_result[5] = pSiSUSB->VBFlags2;
+ sdcbuf->sdc_result[6] = pSiSUSB->SiS_SD3_Flags;
+ sdcbuf->sdc_result[7] = pSiSUSB->SiS_SD4_Flags;
+ break;
+
+ case SDC_CMD_GETVBFLAGSVERSION:
+ sdcbuf->sdc_result[0] = SIS_VBFlagsVersion;
+ break;
+
+ case SDC_CMD_GETVBFLAGS:
+ sdcbuf->sdc_result[0] = pSiSUSB->VBFlags;
+ sdcbuf->sdc_result[1] = pSiSUSB->VBFlags2;
+ break;
+
+ case SDC_CMD_CHECKMODEFORCRT2:
+ sdcbuf->sdc_result[0] = 0;
+ break;
+
+ case SDC_CMD_SETVBFLAGS:
+ case SDC_CMD_SETCRT1STATUS:
+ case SDC_CMD_REDETECTCRT2DEVICES:
+ if(!pSiSUSB->xv_sisdirectunlocked) {
+ sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
+ }
+ break;
+
+ case SDC_CMD_GETDETECTEDDEVICES:
+ sdcbuf->sdc_result[0] = 0;
+ break;
+
+ case SDC_CMD_GETCRT1STATUS:
+ sdcbuf->sdc_result[0] = 1;
+ break;
+
+ case SDC_CMD_GETSDFLAGS:
+ sdcbuf->sdc_result[0] = pSiSUSB->SiS_SD_Flags;
+ break;
+
+ case SDC_CMD_GETSD2FLAGS:
+ sdcbuf->sdc_result[0] = pSiSUSB->SiS_SD2_Flags;
+ break;
+
+ case SDC_CMD_GETLOCKSTATUS:
+ sdcbuf->sdc_result[0] = pSiSUSB->xv_sisdirectunlocked;
+ break;
+
+ case SDC_CMD_SETLOCKSTATUS:
+ if(pSiSUSB->enablesisctrl) {
+ if(sdcbuf->sdc_parm[0] == SIS_DIRECTKEY) {
+ pSiSUSB->xv_sisdirectunlocked++;
+ } else if(pSiSUSB->xv_sisdirectunlocked) {
+ pSiSUSB->xv_sisdirectunlocked--;
+ }
+ } else {
+ pSiSUSB->xv_sisdirectunlocked = 0;
+ sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
+ }
+ break;
+
+ case SDC_CMD_GETTVANTIFLICKER:
+ case SDC_CMD_GETTVSATURATION:
+ case SDC_CMD_GETTVEDGEENHANCE:
+ case SDC_CMD_GETTVCFILTER:
+ case SDC_CMD_GETTVYFILTER:
+ case SDC_CMD_GETTVCHCONTRAST:
+ case SDC_CMD_GETTVCHTEXTENHANCE:
+ case SDC_CMD_GETTVCHCHROMAFLICKERFILTER:
+ case SDC_CMD_GETTVCHLUMAFLICKERFILTER:
+ case SDC_CMD_GETTVCHCVBSCOLOR:
+ case SDC_CMD_GETCHTVOVERSCAN:
+ sdcbuf->sdc_result[0] = 0;
+ break;
+
+ case SDC_CMD_SETTVANTIFLICKER:
+ case SDC_CMD_SETTVSATURATION:
+ case SDC_CMD_SETTVEDGEENHANCE:
+ case SDC_CMD_SETTVCFILTER:
+ case SDC_CMD_SETTVYFILTER:
+ case SDC_CMD_SETTVCHCONTRAST:
+ case SDC_CMD_SETTVCHTEXTENHANCE:
+ case SDC_CMD_SETTVCHCHROMAFLICKERFILTER:
+ case SDC_CMD_SETTVCHLUMAFLICKERFILTER:
+ case SDC_CMD_SETTVCHCVBSCOLOR:
+ case SDC_CMD_SETCHTVOVERSCAN:
+ case SDC_CMD_SETTVCOLORCALIB:
+ if(!pSiSUSB->xv_sisdirectunlocked) {
+ sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
+ }
+ break;
+
+ case SDC_CMD_GETTVCOLORCALIB:
+ sdcbuf->sdc_result[0] = 32768;
+ sdcbuf->sdc_result[1] = 32768;
+ break;
+
+ case SDC_CMD_GETGAMMASTATUS:
+ {
+ int i = 0;
+ if(pSiSUSB->CRT1gamma) i |= 0x01;
+ if(pSiSUSB->XvGamma) i |= 0x04;
+ sdcbuf->sdc_result[0] = i;
+ }
+ break;
+
+ case SDC_CMD_SETGAMMASTATUS:
+ if(pSiSUSB->xv_sisdirectunlocked) {
+ int value = sdcbuf->sdc_parm[0];
+#ifdef SIS_ENABLEXV
+ Bool backup = pSiSUSB->XvGamma;
+#endif
+ pSiSUSB->CRT1gamma = (value & 0x01) ? TRUE : FALSE;
+ pSiSUSB->XvGamma = (value & 0x04) ? TRUE : FALSE;
+#ifdef SIS_ENABLEXV
+ if(backup != pSiSUSB->XvGamma) {
+ if(pPriv) SiSUSBUpdateXvGamma(pSiSUSB, pPriv);
+ }
+#endif
+ } else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
+ break;
+
+ case SDC_CMD_GETTVXSCALE:
+ case SDC_CMD_GETTVYSCALE:
+ sdcbuf->sdc_result[0] = 32768;
+ break;
+
+ case SDC_CMD_SETTVXSCALE:
+ case SDC_CMD_SETTVYSCALE:
+ if(!pSiSUSB->xv_sisdirectunlocked) {
+ sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
+ }
+ break;
+
+ case SDC_CMD_GETSCREENSIZE:
+ sdcbuf->sdc_result[0] = (pScrn->virtualX << 16) | pScrn->virtualY;
+ break;
+
+ case SDC_CMD_GETGAMMABRIGHTNESS: /* xv_BRx, xv_PBx */
+ case SDC_CMD_GETGAMMABRIGHTNESS2: /* xv_BRx2, xv_PBx2 */
+ sdcbuf->sdc_result[0] = pSiSUSB->GammaBriR;
+ sdcbuf->sdc_result[1] = pSiSUSB->GammaBriG;
+ sdcbuf->sdc_result[2] = pSiSUSB->GammaBriB;
+ break;
+
+ case SDC_CMD_GETNEWGAMMABRICON: /* no xv pendant */
+ case SDC_CMD_GETNEWGAMMABRICON2: /* no xv pendant */
+ sdcbuf->sdc_result[0] = (CARD32)(((int)(pSiSUSB->NewGammaBriR * 1000.0)) + 1000);
+ sdcbuf->sdc_result[1] = (CARD32)(((int)(pSiSUSB->NewGammaBriG * 1000.0)) + 1000);
+ sdcbuf->sdc_result[2] = (CARD32)(((int)(pSiSUSB->NewGammaBriB * 1000.0)) + 1000);
+ sdcbuf->sdc_result[3] = (CARD32)(((int)(pSiSUSB->NewGammaConR * 1000.0)) + 1000);
+ sdcbuf->sdc_result[4] = (CARD32)(((int)(pSiSUSB->NewGammaConG * 1000.0)) + 1000);
+ sdcbuf->sdc_result[5] = (CARD32)(((int)(pSiSUSB->NewGammaConB * 1000.0)) + 1000);
+ break;
+
+ case SDC_CMD_SETGAMMABRIGHTNESS: /* xv_BRx, xv_PBx */
+ case SDC_CMD_SETGAMMABRIGHTNESS2: /* xv_BRx2, xv_PBx2 */
+ if(sdcbuf->sdc_parm[0] < 100 || sdcbuf->sdc_parm[0] > 10000 ||
+ sdcbuf->sdc_parm[1] < 100 || sdcbuf->sdc_parm[1] > 10000 ||
+ sdcbuf->sdc_parm[2] < 100 || sdcbuf->sdc_parm[2] > 10000) {
+ sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
+ } else if(pSiSUSB->xv_sisdirectunlocked) {
+ pSiSUSB->GammaBriR = sdcbuf->sdc_parm[0];
+ pSiSUSB->GammaBriG = sdcbuf->sdc_parm[1];
+ pSiSUSB->GammaBriB = sdcbuf->sdc_parm[2];
+ pSiSUSB->NewGammaBriR = pSiSUSB->NewGammaBriG = pSiSUSB->NewGammaBriB = 0.0;
+ pSiSUSB->NewGammaConR = pSiSUSB->NewGammaConG = pSiSUSB->NewGammaConB = 0.0;
+ pSiSUSB->SiS_SD3_Flags |= SiS_SD3_OLDGAMMAINUSE;
+ } else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
+ break;
+
+ case SDC_CMD_SETNEWGAMMABRICON: /* no xv pendant */
+ case SDC_CMD_SETNEWGAMMABRICON2: /* no xv pendant */
+ if(sdcbuf->sdc_parm[0] > 2000 || sdcbuf->sdc_parm[1] > 2000 ||
+ sdcbuf->sdc_parm[2] > 2000 || sdcbuf->sdc_parm[3] > 2000 ||
+ sdcbuf->sdc_parm[4] > 2000 || sdcbuf->sdc_parm[5] > 2000) {
+ sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
+ } else if(pSiSUSB->xv_sisdirectunlocked) {
+ pSiSUSB->NewGammaBriR = ((float)((int)sdcbuf->sdc_parm[0] - 1000)) / 1000.0;
+ pSiSUSB->NewGammaBriG = ((float)((int)sdcbuf->sdc_parm[1] - 1000)) / 1000.0;
+ pSiSUSB->NewGammaBriB = ((float)((int)sdcbuf->sdc_parm[2] - 1000)) / 1000.0;
+ pSiSUSB->NewGammaConR = ((float)((int)sdcbuf->sdc_parm[3] - 1000)) / 1000.0;
+ pSiSUSB->NewGammaConG = ((float)((int)sdcbuf->sdc_parm[4] - 1000)) / 1000.0;
+ pSiSUSB->NewGammaConB = ((float)((int)sdcbuf->sdc_parm[5] - 1000)) / 1000.0;
+ pSiSUSB->GammaBriR = pSiSUSB->GammaBriG = pSiSUSB->GammaBriB = 1000;
+ pSiSUSB->SiS_SD3_Flags &= ~SiS_SD3_OLDGAMMAINUSE;
+ } else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
+ break;
+
+ case SDC_CMD_SETGETGAMMACRT2:
+ case SDC_CMD_SETGETNEWGAMMACRT2:
+ if(!pSiSUSB->xv_sisdirectunlocked) {
+ sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
+ }
+ break;
+
+ case SDC_CMD_GETGETGAMMACRT2:
+ sdcbuf->sdc_result[0] =
+ sdcbuf->sdc_result[1] =
+ sdcbuf->sdc_result[2] =
+ sdcbuf->sdc_result[3] =
+ sdcbuf->sdc_result[4] =
+ sdcbuf->sdc_result[5] = 1000;
+ break;
+
+ case SDC_CMD_GETGETNEWGAMMACRT2:
+ sdcbuf->sdc_result[0] =
+ sdcbuf->sdc_result[1] =
+ sdcbuf->sdc_result[2] =
+ sdcbuf->sdc_result[3] =
+ sdcbuf->sdc_result[4] =
+ sdcbuf->sdc_result[5] =
+ sdcbuf->sdc_result[6] =
+ sdcbuf->sdc_result[7] =
+ sdcbuf->sdc_result[8] = 1000;
+ break;
+
+ case SDC_CMD_GETHWCURSORSTATUS:
+ sdcbuf->sdc_result[0] = pSiSUSB->HideHWCursor ? 1 : 0;
+ break;
+
+ case SDC_CMD_SETHWCURSORSTATUS:
+ if(pSiSUSB->xv_sisdirectunlocked) {
+ Bool VisibleBackup = pSiSUSB->HWCursorIsVisible;
+ pSiSUSB->HideHWCursor = sdcbuf->sdc_parm[0] ? TRUE : FALSE;
+ if(pSiSUSB->CursorInfoPtr) {
+ if(VisibleBackup) {
+ if(sdcbuf->sdc_parm[0]) {
+ (pSiSUSB->CursorInfoPtr->HideCursor)(pScrn);
+ } else {
+ (pSiSUSB->CursorInfoPtr->ShowCursor)(pScrn);
+ }
+ }
+ pSiSUSB->HWCursorIsVisible = VisibleBackup;
+ }
+ } else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
+ break;
+
+ case SDC_CMD_GETPANELMODE:
+ sdcbuf->sdc_result[0] = 0;
+ break;
+
+ case SDC_CMD_SETPANELMODE:
+ if(!pSiSUSB->xv_sisdirectunlocked) {
+ sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
+ }
+ break;
+
+ case SDC_CMD_GETMERGEDMODEDETAILS:
+ sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
+ break;
+
+ case SDC_CMD_GETDEVICENAME: /* In DualHead mode, this returns CRT1 data */
+ sdcbuf->sdc_result[0] = 0;
+ sisutil_prepare_string(sdcbuf, pSiSUSB->devsectname);
+ break;
+
+ case SDC_CMD_GETMONITORNAME: /* In DualHead mode, this returns CRT1 data */
+ sdcbuf->sdc_result[0] = 0;
+ if(pScrn->monitor) {
+ sisutil_prepare_string(sdcbuf, pScrn->monitor->id);
+ }
+ break;
+
+ case SDC_CMD_GETDEVICENAME2: /* In DualHead mode, this returns CRT2 data */
+ sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
+ break;
+
+ case SDC_CMD_GETMONITORNAME2: /* In DualHead mode, this returns CRT2 data */
+ sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
+ break;
+
+ case SDC_CMD_SETXVBRIGHTNESS:
+ if(pPriv) {
+ int val = sdcbuf->sdc_parm[0] - 32768;
+ if(val >= -128 && val <= 127) pPriv->brightness = val;
+ else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
+ } else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
+ break;
+
+ case SDC_CMD_GETXVBRIGHTNESS:
+ if(pPriv) {
+ sdcbuf->sdc_result[0] = pPriv->brightness + 32768;
+ } else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
+ break;
+
+ case SDC_CMD_SETXVCONTRAST:
+ if(pPriv) {
+ int val = sdcbuf->sdc_parm[0] - 32768;
+ if(val >= 0 && val <= 7) pPriv->contrast = val;
+ else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
+ } else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
+ break;
+
+ case SDC_CMD_GETXVCONTRAST:
+ if(pPriv) {
+ sdcbuf->sdc_result[0] = pPriv->contrast + 32768;
+ } else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
+ break;
+
+ case SDC_CMD_SETXVHUE:
+ if(pPriv) {
+ int val = sdcbuf->sdc_parm[0] - 32768;
+ if(val >= -8 && val <= 7) pPriv->hue = val;
+ else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
+ } else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
+ break;
+
+ case SDC_CMD_GETXVHUE:
+ if(pPriv) {
+ sdcbuf->sdc_result[0] = pPriv->hue + 32768;
+ } else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
+ break;
+
+ case SDC_CMD_SETXVSATURATION:
+ if(pPriv) {
+ int val = sdcbuf->sdc_parm[0] - 32768;
+ if(val >= -7 && val <= 7) pPriv->saturation = val;
+ else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
+ } else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
+ break;
+
+ case SDC_CMD_GETXVSATURATION:
+ if(pPriv) {
+ sdcbuf->sdc_result[0] = pPriv->saturation + 32768;
+ } else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
+ break;
+
+ case SDC_CMD_SETXVGAMMA:
+ if(pPriv) {
+ if(sdcbuf->sdc_parm[0] < 100 || sdcbuf->sdc_parm[0] > 10000 ||
+ sdcbuf->sdc_parm[1] < 100 || sdcbuf->sdc_parm[1] > 10000 ||
+ sdcbuf->sdc_parm[2] < 100 || sdcbuf->sdc_parm[2] > 10000) {
+ sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
+ } else {
+ pSiSUSB->XvGammaRed = sdcbuf->sdc_parm[0];
+ pSiSUSB->XvGammaGreen = sdcbuf->sdc_parm[1];
+ pSiSUSB->XvGammaBlue = sdcbuf->sdc_parm[2];
+#ifdef SIS_ENABLEXV
+ SiSUSBUpdateXvGamma(pSiSUSB, pPriv);
+#endif
+ }
+ } else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
+ break;
+
+ case SDC_CMD_GETXVGAMMA:
+ if(pPriv) {
+ sdcbuf->sdc_result[0] = pSiSUSB->XvGammaRed;
+ sdcbuf->sdc_result[1] = pSiSUSB->XvGammaGreen;
+ sdcbuf->sdc_result[2] = pSiSUSB->XvGammaBlue;
+ } else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
+ break;
+
+ case SDC_CMD_SETXVCOLORKEY:
+ if(pPriv) {
+ pPriv->colorKey = pSiSUSB->colorKey = sdcbuf->sdc_parm[0];
+ } else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
+ break;
+
+ case SDC_CMD_GETXVCOLORKEY:
+ if(pPriv) {
+ sdcbuf->sdc_result[0] = pPriv->colorKey;
+ } else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
+ break;
+
+ case SDC_CMD_SETXVAUTOPAINTCOLORKEY:
+ if(pPriv) {
+ pPriv->autopaintColorKey = sdcbuf->sdc_parm[0] ? 1 : 0;
+ } else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
+ break;
+
+ case SDC_CMD_GETXVAUTOPAINTCOLORKEY:
+ if(pPriv) {
+ sdcbuf->sdc_result[0] = pPriv->autopaintColorKey ? 1 : 0;
+ } else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
+ break;
+
+ case SDC_CMD_SETXVDEFAULTS:
+ if(pPriv) {
+#ifdef SIS_GLOBAL_ENABLEXV
+ SISUSBSetPortDefaults(pScrn, pPriv);
+#endif
+ } else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
+ break;
+
+ case SDC_CMD_SETXVDISABLEGFX:
+ if(pPriv) {
+ pPriv->disablegfx = sdcbuf->sdc_parm[0] ? 1 : 0;
+ } else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
+ break;
+
+ case SDC_CMD_GETXVDISABLEGFX:
+ if(pPriv) {
+ sdcbuf->sdc_result[0] = pPriv->disablegfx ? 1 : 0;
+ } else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
+ break;
+
+ case SDC_CMD_SETXVDISABLEGFXLR:
+ if(pPriv) {
+ pPriv->disablegfxlr = sdcbuf->sdc_parm[0] ? 1 : 0;
+ } else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
+ break;
+
+ case SDC_CMD_GETXVDISABLEGFXLR:
+ if(pPriv) {
+ sdcbuf->sdc_result[0] = pPriv->disablegfxlr ? 1 : 0;
+ } else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
+ break;
+
+ case SDC_CMD_SETXVSWITCHCRT:
+ break;
+
+ case SDC_CMD_GETXVSWITCHCRT:
+ case SDC_CMD_GETMONGAMMACRT1:
+ case SDC_CMD_GETMONGAMMACRT2:
+ sdcbuf->sdc_result[0] = 0;
+ break;
+
+ case SDC_CMD_SETTVXPOS:
+ case SDC_CMD_SETTVYPOS:
+ break;
+
+ case SDC_CMD_GETTVXPOS:
+ case SDC_CMD_GETTVYPOS:
+ sdcbuf->sdc_result[0] = 32768;
+ break;
+
+ case SDC_CMD_SETXVDEINT:
+ case SDC_CMD_GETXVDEINT:
+ sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
+ break;
+
+ case SDC_CMD_LOGQUIET:
+ pSiSUSB->SCLogQuiet = sdcbuf->sdc_parm[0] ? TRUE : FALSE;
+ break;
+
+ default:
+ sdcbuf->sdc_result_header = SDC_RESULT_UNDEFCMD;
+ }
+
+ return Success;
+}
+
+/* Proc */
+
+static int
+SiSUSBProcSiSCtrlQueryVersion(ClientPtr client)
+{
+ xSiSCtrlQueryVersionReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xSiSCtrlQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = SISCTRL_MAJOR_VERSION;
+ rep.minorVersion = SISCTRL_MINOR_VERSION;
+ if(client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.majorVersion, n);
+ swaps(&rep.minorVersion, n);
+ }
+ WriteToClient(client, sizeof(xSiSCtrlQueryVersionReply), (char *)&rep);
+ return (client->noClientException);
+}
+
+static int
+SiSUSBProcSiSCtrlCommand(ClientPtr client)
+{
+ REQUEST(xSiSCtrlCommandReq);
+ xSiSCtrlCommandReply rep;
+ ExtensionEntry *myext;
+ xSiSCtrlScreenTable *myctrl;
+ register int n;
+ int i, ret;
+
+ REQUEST_SIZE_MATCH(xSiSCtrlCommandReq);
+
+ memcpy(&rep, stuff, sizeof(xSiSCtrlCommandReply));
+
+ /* Get pointer to ExtensionEntry */
+ if(!(myext = CheckExtension(SISCTRL_PROTOCOL_NAME))) return BadMatch;
+
+ /* Get pointer to our private */
+ if(!(myctrl = (xSiSCtrlScreenTable *)myext->extPrivate)) return BadMatch;
+
+ /* Check if screen index is within out limits */
+ if(rep.screen > myctrl->maxscreens) return BadMatch;
+
+ /* Check if this screen has added itself */
+ if(!(myctrl->HandleSiSDirectCommand[rep.screen])) return BadMatch;
+
+ /* Finally, execute the command */
+ if((ret = (myctrl->HandleSiSDirectCommand[rep.screen])(&rep)) != Success) {
+ return ret;
+ }
+
+ rep.type = X_Reply;
+ rep.length = (sizeof(xSiSCtrlCommandReply) - sizeof(xGenericReply)) >> 2;
+ rep.sequenceNumber = client->sequence;
+
+ if(client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.screen, n);
+ swapl(&rep.sdc_id, n);
+ swapl(&rep.sdc_command, n);
+ swapl(&rep.sdc_result_header, n);
+ for(i = 0; i < SDC_NUM_PARM_RESULT; i++) {
+ swapl(&rep.sdc_parm[i], n);
+ swapl(&rep.sdc_result[i], n);
+ }
+ }
+ WriteToClient(client, sizeof(xSiSCtrlCommandReply), (char *)&rep);
+ return client->noClientException;
+}
+
+static int
+SiSUSBProcSiSCtrlDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+ switch(stuff->data) {
+ case X_SiSCtrlQueryVersion:
+ return SiSUSBProcSiSCtrlQueryVersion(client);
+ case X_SiSCtrlCommand:
+ return SiSUSBProcSiSCtrlCommand(client);
+ }
+ return BadRequest;
+}
+
+/* SProc */
+
+static int
+SiSUSBSProcSiSCtrlQueryVersion(ClientPtr client)
+{
+ REQUEST(xSiSCtrlQueryVersionReq);
+ register int n;
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xSiSCtrlQueryVersionReq);
+ return SiSUSBProcSiSCtrlQueryVersion(client);
+}
+
+static int
+SiSUSBSProcSiSCtrlCommand(ClientPtr client)
+{
+ REQUEST(xSiSCtrlCommandReq);
+ register int n;
+ int i;
+ swaps(&stuff->length, n);
+ swapl(&stuff->screen, n);
+ swapl(&stuff->sdc_id, n);
+ swapl(&stuff->sdc_command, n);
+ swapl(&stuff->sdc_result_header, n);
+ for(i = 0; i < SDC_NUM_PARM_RESULT; i++) {
+ swapl(&stuff->sdc_parm[i], n);
+ swapl(&stuff->sdc_result[i], n);
+ }
+ REQUEST_SIZE_MATCH(xSiSCtrlCommandReq);
+ return SiSUSBProcSiSCtrlCommand(client);
+}
+
+static int
+SiSUSBSProcSiSCtrlDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+ switch(stuff->data) {
+ case X_SiSCtrlQueryVersion:
+ return SiSUSBSProcSiSCtrlQueryVersion(client);
+ case X_SiSCtrlCommand:
+ return SiSUSBSProcSiSCtrlCommand(client);
+ }
+ return BadRequest;
+}
+
+static void
+SiSUSBCtrlResetProc(ExtensionEntry* extEntry)
+{
+ /* Called by CloseDownExtensions() */
+ if(extEntry->extPrivate) {
+ xfree(extEntry->extPrivate);
+ extEntry->extPrivate = NULL;
+ }
+}
+
+void
+SiSUSBCtrlExtInit(ScrnInfoPtr pScrn)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ ExtensionEntry *myext;
+ xSiSCtrlScreenTable *myctrl;
+ unsigned int version, revision;
+
+ pSiSUSB->SCLogQuiet = FALSE;
+
+ if(!(myext = CheckExtension(SISCTRL_PROTOCOL_NAME))) {
+
+ if(!(myctrl = xcalloc(sizeof(xSiSCtrlScreenTable), 1)))
+ return;
+
+ if(!(myext = AddExtension(SISCTRL_PROTOCOL_NAME, 0, 0,
+ SiSUSBProcSiSCtrlDispatch,
+ SiSUSBSProcSiSCtrlDispatch,
+ SiSUSBCtrlResetProc,
+ StandardMinorOpcode))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to add SISCTRL extension\n");
+ xfree(myctrl);
+ return;
+ }
+
+ myext->extPrivate = (pointer)myctrl;
+
+ myctrl->maxscreens = SISCTRL_MAX_SCREENS;
+ myctrl->version_major = version = SISCTRL_MAJOR_VERSION;
+ myctrl->version_minor = revision = SISCTRL_MINOR_VERSION;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Initialized SISCTRL extension version %d.%d\n",
+ version, revision);
+
+ } else {
+
+ if(!(myctrl = (xSiSCtrlScreenTable *)myext->extPrivate)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Internal error: Found SISCTRL extension with NULL-private!\n");
+ return;
+ }
+
+ version = myctrl->version_major;
+ revision = myctrl->version_minor;
+ }
+
+ if(pScrn->scrnIndex < myctrl->maxscreens) {
+
+ myctrl->HandleSiSDirectCommand[pScrn->scrnIndex] = SiSHandleSiSDirectCommand;
+
+ pSiSUSB->SiSCtrlExtEntry = myext;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Registered screen %d with SISCTRL extension version %d.%d\n",
+ pScrn->scrnIndex, version, revision);
+ } else {
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Screen number (%d) too high for SISCTRL extension %d.%d\n",
+ pScrn->scrnIndex, version, revision);
+
+ }
+
+}
+
+void
+SiSUSBCtrlExtUnregister(SISUSBPtr pSiSUSB, int index)
+{
+ ExtensionEntry *myext;
+ xSiSCtrlScreenTable *myctrl;
+
+ if(!pSiSUSB->SiSCtrlExtEntry) return;
+
+ /* Since CloseDownExtensions() is called before
+ * our CloseScreen(), we must not use the saved
+ * ptr here, but instead check for the extension.
+ */
+
+ if((myext = CheckExtension(SISCTRL_PROTOCOL_NAME))) {
+ if((myctrl = (xSiSCtrlScreenTable *)pSiSUSB->SiSCtrlExtEntry->extPrivate)) {
+ myctrl->HandleSiSDirectCommand[index] = NULL;
+ }
+ }
+}
+
+/***********************************
+ * Xv attribute interface *
+ ***********************************/
+
+#ifdef XV_SD_DEPRECATED
+
+int
+SISUSBSetPortUtilAttribute(ScrnInfoPtr pScrn, Atom attribute,
+ INT32 value, SISUSBPortPrivPtr pPriv)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+
+ if(attribute == pSiSUSB->xv_USD) {
+ if(pSiSUSB->enablesisctrl) {
+ if(value == SIS_DIRECTKEY) {
+ pSiSUSB->xv_sisdirectunlocked++;
+ } else if(pSiSUSB->xv_sisdirectunlocked) {
+ pSiSUSB->xv_sisdirectunlocked--;
+ }
+ } else {
+ pSiSUSB->xv_sisdirectunlocked = 0;
+ }
+ } else if(attribute == pSiSUSB->xv_SVF) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_CT1) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_RDT) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_TAF) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_TSA) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_TEE) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_CFI) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_YFI) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_COC) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_COF) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_TCO) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_TTE) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_TCF) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_TLF) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_TCC) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_OVR) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_CMD) {
+ if(pSiSUSB->xv_sisdirectunlocked) {
+ pSiSUSB->xv_sd_result = (value & 0xffffff00);
+ }
+ } else if(attribute == pSiSUSB->xv_SGA) {
+ if(pSiSUSB->xv_sisdirectunlocked) {
+#ifdef SIS_ENABLEXV
+ Bool backup = pSiSUSB->XvGamma;
+#endif
+ pSiSUSB->CRT1gamma = (value & 0x01) ? TRUE : FALSE;
+ pSiSUSB->XvGamma = (value & 0x04) ? TRUE : FALSE;
+#ifdef SIS_ENABLEXV
+ if(backup != pSiSUSB->XvGamma) {
+ SiSUSBUpdateXvGamma(pSiSUSB, pPriv);
+ }
+#endif
+ }
+ } else if(attribute == pSiSUSB->xv_TXS) {
+ if((value < -16) || (value > 16)) return BadValue;
+ } else if(attribute == pSiSUSB->xv_TYS) {
+ if((value < -4) || (value > 3)) return BadValue;
+ } else if(attribute == pSiSUSB->xv_BRR) {
+ if((value < 100) || (value > 10000)) return BadValue;
+ if(pSiSUSB->xv_sisdirectunlocked) {
+ pSiSUSB->GammaBriR = value;
+ }
+ } else if(attribute == pSiSUSB->xv_BRG) {
+ if((value < 100) || (value > 10000)) return BadValue;
+ if(pSiSUSB->xv_sisdirectunlocked) {
+ pSiSUSB->GammaBriG = value;
+ }
+ } else if(attribute == pSiSUSB->xv_BRB) {
+ if((value < 100) || (value > 10000)) return BadValue;
+ if(pSiSUSB->xv_sisdirectunlocked) {
+ pSiSUSB->GammaBriB = value;
+ }
+ } else if(attribute == pSiSUSB->xv_PBR) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_PBG) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_PBB) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_BRR2) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_BRG2) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_BRB2) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_PBR2) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_PBG2) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_PBB2) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_GARC2) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_GAGC2) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_GABC2) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_BRRC2) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_BRGC2) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_BRBC2) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_PBRC2) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_PBGC2) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_PBBC2) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xv_SHC) {
+ if(pSiSUSB->xv_sisdirectunlocked) {
+ Bool VisibleBackup = pSiSUSB->HWCursorIsVisible;
+ pSiSUSB->HideHWCursor = value ? TRUE : FALSE;
+ if(pSiSUSB->CursorInfoPtr) {
+ if(VisibleBackup) {
+ if(value) {
+ (pSiSUSB->CursorInfoPtr->HideCursor)(pScrn);
+ } else {
+ (pSiSUSB->CursorInfoPtr->ShowCursor)(pScrn);
+ }
+ }
+ pSiSUSB->HWCursorIsVisible = VisibleBackup;
+ }
+ }
+ } else if(attribute == pSiSUSB->xv_PMD) {
+ /* Nop */
+#ifdef TWDEBUG
+ } else if(attribute == pSiSUSB->xv_STR) {
+ ULong port;
+ switch((value & 0xff000000) >> 24) {
+ case 0x00: port = SISSR; break;
+ case 0x01: port = SISPART1; break;
+ case 0x05: port = SISCR; break;
+ case 0x06: port = SISVID; break;
+ default: return BadValue;
+ }
+ outSISIDXREG(pSiSUSB,port,((value & 0x00ff0000) >> 16), ((value & 0x0000ff00) >> 8));
+#endif
+ } else {
+ return BadMatch;
+ }
+
+ return Success;
+}
+
+int
+SISUSBGetPortUtilAttribute(ScrnInfoPtr pScrn, Atom attribute,
+ INT32 *value, SISUSBPortPrivPtr pPriv)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+
+ if(attribute == pSiSUSB->xv_QVF) {
+ *value = pSiSUSB->VBFlags;
+ } else if(attribute == pSiSUSB->xv_GDV) {
+ *value = SISUSBDRIVERIVERSION;
+ } else if(attribute == pSiSUSB->xv_GHI) {
+ *value = (pSiSUSB->ChipFlags & 0xffff) | (pSiSUSB->ChipType << 16) | (pSiSUSB->ChipRev << 24);
+ } else if(attribute == pSiSUSB->xv_GBI) {
+ *value = ((pSiSUSB->USBBus & 0xff) << 8) | (pSiSUSB->USBDev & 0xff);
+ } else if(attribute == pSiSUSB->xv_QVV) {
+ *value = SIS_VBFlagsVersion;
+ } else if(attribute == pSiSUSB->xv_QDD) {
+ *value = 0;
+ } else if(attribute == pSiSUSB->xv_CT1) {
+ *value = 1;
+ } else if(attribute == pSiSUSB->xv_GSF) {
+ *value = pSiSUSB->SiS_SD_Flags;
+ } else if(attribute == pSiSUSB->xv_GSF2) {
+ *value = pSiSUSB->SiS_SD2_Flags;
+ } else if(attribute == pSiSUSB->xv_USD) {
+ *value = pSiSUSB->xv_sisdirectunlocked;
+ } else if(attribute == pSiSUSB->xv_TAF) {
+ *value = 0;
+ } else if(attribute == pSiSUSB->xv_TSA) {
+ *value = 0;
+ } else if(attribute == pSiSUSB->xv_TEE) {
+ *value = 0;
+ } else if(attribute == pSiSUSB->xv_CFI) {
+ *value = 0;
+ } else if(attribute == pSiSUSB->xv_YFI) {
+ *value = 0;
+ } else if(attribute == pSiSUSB->xv_COC) {
+ *value = 0;
+ } else if(attribute == pSiSUSB->xv_COF) {
+ *value = 0;
+ } else if(attribute == pSiSUSB->xv_TCO) {
+ *value = 0;
+ } else if(attribute == pSiSUSB->xv_TTE) {
+ *value = 0;
+ } else if(attribute == pSiSUSB->xv_TCF) {
+ *value = 0;
+ } else if(attribute == pSiSUSB->xv_TLF) {
+ *value = 0;
+ } else if(attribute == pSiSUSB->xv_TCC) {
+ *value = 0;
+ } else if(attribute == pSiSUSB->xv_CMDR) {
+ *value = pSiSUSB->xv_sd_result;
+ } else if(attribute == pSiSUSB->xv_OVR) {
+ /* Changing of CRT2 settings not supported in DHM! */
+ *value = 0;
+ } else if(attribute == pSiSUSB->xv_SGA) {
+ *value = 0;
+ if(pSiSUSB->CRT1gamma) *value |= 0x01;
+ if(pSiSUSB->XvGamma) *value |= 0x04;
+ } else if(attribute == pSiSUSB->xv_TXS) {
+ *value = 0;
+ } else if(attribute == pSiSUSB->xv_TYS) {
+ *value = 0;
+ } else if(attribute == pSiSUSB->xv_GSS) {
+ *value = (pScrn->virtualX << 16) | pScrn->virtualY;
+ } else if(attribute == pSiSUSB->xv_BRR) {
+ *value = pSiSUSB->GammaBriR;
+ } else if(attribute == pSiSUSB->xv_BRG) {
+ *value = pSiSUSB->GammaBriG;
+ } else if(attribute == pSiSUSB->xv_BRB) {
+ *value = pSiSUSB->GammaBriB;
+ } else if(attribute == pSiSUSB->xv_PBR) {
+ *value = 1000;
+ } else if(attribute == pSiSUSB->xv_PBG) {
+ *value = 1000;
+ } else if(attribute == pSiSUSB->xv_PBB) {
+ *value = 1000;
+ } else if(attribute == pSiSUSB->xv_BRR2) {
+ *value = pSiSUSB->GammaBriR;
+ } else if(attribute == pSiSUSB->xv_BRG2) {
+ *value = pSiSUSB->GammaBriG;
+ } else if(attribute == pSiSUSB->xv_BRB2) {
+ *value = pSiSUSB->GammaBriB;
+ } else if(attribute == pSiSUSB->xv_PBR2) {
+ *value = 1000;
+ } else if(attribute == pSiSUSB->xv_PBG2) {
+ *value = 1000;
+ } else if(attribute == pSiSUSB->xv_PBB2) {
+ *value = 1000;
+ } else if(attribute == pSiSUSB->xv_GARC2) {
+ *value = 1000;
+ } else if(attribute == pSiSUSB->xv_GAGC2) {
+ *value = 1000;
+ } else if(attribute == pSiSUSB->xv_GABC2) {
+ *value = 1000;
+ } else if(attribute == pSiSUSB->xv_BRRC2) {
+ *value = 1000;
+ } else if(attribute == pSiSUSB->xv_BRGC2) {
+ *value = 1000;
+ } else if(attribute == pSiSUSB->xv_BRBC2) {
+ *value = 1000;
+ } else if(attribute == pSiSUSB->xv_PBRC2) {
+ *value = 1000;
+ } else if(attribute == pSiSUSB->xv_PBGC2) {
+ *value = 1000;
+ } else if(attribute == pSiSUSB->xv_PBBC2) {
+ *value = 1000;
+ } else if(attribute == pSiSUSB->xv_SHC) {
+ *value = pSiSUSB->HideHWCursor ? 1 : 0;
+ } else if(attribute == pSiSUSB->xv_PMD) {
+ *value = 0;
+ } else {
+ return BadMatch;
+ }
+
+ return Success;
+}
+
+#endif /* XV_SD_DEPRECATED */
+
+
diff --git a/driver/xf86-video-sisusb/src/sisusb_vga.c b/driver/xf86-video-sisusb/src/sisusb_vga.c
new file mode 100644
index 000000000..64b984328
--- /dev/null
+++ b/driver/xf86-video-sisusb/src/sisusb_vga.c
@@ -0,0 +1,342 @@
+/* $XFree86$ */
+/* $XdotOrg: driver/xf86-video-sisusb/src/sisusb_vga.c,v 1.5 2005/07/11 02:30:00 ajax Exp $ */
+/*
+ * Mode setup and basic video bridge detection
+ *
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1) Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2) Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3) The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "sisusb.h"
+#include "sisusb_regs.h"
+#include "sisusb_dac.h"
+
+/* Our very own vgaHW functions */
+void SiSUSBVGASave(ScrnInfoPtr pScrn, SISUSBRegPtr save, int flags);
+void SiSUSBVGARestore(ScrnInfoPtr pScrn, SISUSBRegPtr restore, int flags);
+void SISUSBVGALock(SISUSBPtr pSiSUSB);
+void SiSUSBVGAUnlock(SISUSBPtr pSiSUSB);
+void SiSUSBVGAProtect(ScrnInfoPtr pScrn, Bool on);
+Bool SiSUSBVGASaveScreen(ScreenPtr pScreen, int mode);
+
+/* Init a mode.
+ * This function is now only used for setting up some
+ * variables (eg. scrnOffset).
+ */
+static Bool
+SISUSB300Init(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ SISUSBRegPtr pReg = &pSiSUSB->ModeReg;
+ DisplayModePtr realmode = mode;
+
+ /* Copy current register settings to structure */
+ (*pSiSUSB->SiSSave)(pScrn, pReg);
+
+ /* Calculate Offset/Display Pitch */
+ pSiSUSB->scrnOffset = pSiSUSB->CurrentLayout.displayWidth *
+ ((pSiSUSB->CurrentLayout.bitsPerPixel + 7) / 8);
+
+ pSiSUSB->scrnPitch = pSiSUSB->scrnPitch2 = pSiSUSB->scrnOffset;
+ if(realmode->Flags & V_INTERLACE) pSiSUSB->scrnPitch <<= 1;
+
+#ifdef UNLOCK_ALWAYS
+ outSISIDXREG(pSiSUSB, SISSR, 0x05, 0x86);
+#endif
+
+ switch(pSiSUSB->CurrentLayout.bitsPerPixel) {
+ case 8:
+ pSiSUSB->DstColor = 0x0000;
+ pSiSUSB->SiS310_AccelDepth = 0x00000000;
+ break;
+ case 16:
+ pSiSUSB->DstColor = 0x8000;
+ pSiSUSB->SiS310_AccelDepth = 0x00010000;
+ break;
+ case 24:
+ break;
+ case 32:
+ pSiSUSB->DstColor = 0xC000;
+ pSiSUSB->SiS310_AccelDepth = 0x00020000;
+ break;
+ }
+
+ /* Enable PCI LINEAR ADDRESSING (0x80), MMIO (0x01), PCI_IO (0x20) */
+ pReg->sisRegs3C4[0x20] = 0xA1;
+
+ if(!pSiSUSB->NoAccel) {
+ pReg->sisRegs3C4[0x1E] |= 0x42; /* Enable 2D accelerator */
+ pReg->sisRegs3C4[0x1E] |= 0x18; /* Enable 3D accelerator */
+#ifndef SISVRAMQ
+ /* See comments in sis_driver.c */
+ pReg->sisRegs3C4[0x27] = 0x1F;
+ pReg->sisRegs3C4[0x26] = 0x22;
+ pReg->sisMMIO85C0 = (pScrn->videoRam - 512) * 1024;
+#endif
+ }
+
+ return TRUE;
+}
+
+/* Detect video bridge and set VBFlags accordingly */
+void SISUSBVGAPreInit(ScrnInfoPtr pScrn)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+
+ pSiSUSB->ModeInit = SISUSB300Init;
+
+ pSiSUSB->VBFlags = pSiSUSB->VBFlags2 = 0; /* reset VBFlags */
+}
+
+static void
+SiSUSB_WriteAttr(SISUSBPtr pSiSUSB, int index, int value)
+{
+ (void)inSISREG(pSiSUSB, SISINPSTAT);
+ index |= 0x20;
+ outSISREG(pSiSUSB, SISAR, index);
+ outSISREG(pSiSUSB, SISAR, value);
+}
+
+static int
+SiSUSB_ReadAttr(SISUSBPtr pSiSUSB, int index)
+{
+ (void)inSISREG(pSiSUSB, SISINPSTAT);
+ index |= 0x20;
+ outSISREG(pSiSUSB, SISAR, index);
+ return(inSISREG(pSiSUSB, SISARR));
+}
+
+static void
+SiSUSB_EnablePalette(SISUSBPtr pSiSUSB)
+{
+ (void)inSISREG(pSiSUSB, SISINPSTAT);
+ outSISREG(pSiSUSB, SISAR, 0x00);
+ pSiSUSB->VGAPaletteEnabled = TRUE;
+}
+
+static void
+SiSUSB_DisablePalette(SISUSBPtr pSiSUSB)
+{
+ (void)inSISREG(pSiSUSB, SISINPSTAT);
+ outSISREG(pSiSUSB, SISAR, 0x20);
+ pSiSUSB->VGAPaletteEnabled = FALSE;
+}
+
+void
+SISUSBVGALock(SISUSBPtr pSiSUSB)
+{
+ orSISIDXREG(pSiSUSB, SISCR, 0x11, 0x80); /* Protect CRTC[0-7] */
+}
+
+void
+SiSUSBVGAUnlock(SISUSBPtr pSiSUSB)
+{
+ andSISIDXREG(pSiSUSB, SISCR, 0x11, 0x7f); /* Unprotect CRTC[0-7] */
+}
+
+static void
+SiSUSBVGASaveMode(ScrnInfoPtr pScrn, SISUSBRegPtr save)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ int i;
+
+ save->sisRegMiscOut = inSISREG(pSiSUSB, SISMISCR);
+
+ for(i = 0; i < 25; i++) {
+ inSISIDXREG(pSiSUSB, SISCR, i, save->sisRegs3D4[i]);
+ }
+
+ SiSUSB_EnablePalette(pSiSUSB);
+ for(i = 0; i < 21; i++) {
+ save->sisRegsATTR[i] = SiSUSB_ReadAttr(pSiSUSB, i);
+ }
+ SiSUSB_DisablePalette(pSiSUSB);
+
+ for(i = 0; i < 9; i++) {
+ inSISIDXREG(pSiSUSB, SISGR, i, save->sisRegsGR[i]);
+ }
+
+ for(i = 1; i < 5; i++) {
+ inSISIDXREG(pSiSUSB, SISSR, i, save->sisRegs3C4[i]);
+ }
+}
+
+static void
+SiSUSBVGASaveColormap(ScrnInfoPtr pScrn, SISUSBRegPtr save)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ int i;
+
+ if(pSiSUSB->VGACMapSaved) return;
+
+ outSISREG(pSiSUSB, SISPEL, 0xff);
+
+ outSISREG(pSiSUSB, SISCOLIDXR, 0x00);
+ for(i = 0; i < 768; i++) {
+ save->sisDAC[i] = inSISREG(pSiSUSB, SISCOLDATA);
+ (void)inSISREG(pSiSUSB, SISINPSTAT);
+ (void)inSISREG(pSiSUSB, SISINPSTAT);
+ }
+
+ SiSUSB_DisablePalette(pSiSUSB);
+ pSiSUSB->VGACMapSaved = TRUE;
+}
+
+void
+SiSUSBVGASave(ScrnInfoPtr pScrn, SISUSBRegPtr save, int flags)
+{
+ if(save == NULL) return;
+
+ if(flags & SISVGA_SR_CMAP) SiSUSBVGASaveColormap(pScrn, save);
+ if(flags & SISVGA_SR_MODE) SiSUSBVGASaveMode(pScrn, save);
+}
+
+static void
+SiSUSBVGARestoreMode(ScrnInfoPtr pScrn, SISUSBRegPtr restore)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ int i;
+
+ outSISREG(pSiSUSB, SISMISCW, restore->sisRegMiscOut);
+
+ for(i = 1; i < 5; i++) {
+ outSISIDXREG(pSiSUSB, SISSR, i, restore->sisRegs3C4[i]);
+ }
+
+ outSISIDXREG(pSiSUSB, SISCR, 17, restore->sisRegs3D4[17] & ~0x80);
+
+ for(i = 0; i < 25; i++) {
+ outSISIDXREG(pSiSUSB, SISCR, i, restore->sisRegs3D4[i]);
+ }
+
+ for(i = 0; i < 9; i++) {
+ outSISIDXREG(pSiSUSB, SISGR, i, restore->sisRegsGR[i]);
+ }
+
+ SiSUSB_EnablePalette(pSiSUSB);
+ for(i = 0; i < 21; i++) {
+ SiSUSB_WriteAttr(pSiSUSB, i, restore->sisRegsATTR[i]);
+ }
+ SiSUSB_DisablePalette(pSiSUSB);
+}
+
+static void
+SiSUSBVGARestoreColormap(ScrnInfoPtr pScrn, SISUSBRegPtr restore)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ int i;
+
+ if(!pSiSUSB->VGACMapSaved) return;
+
+ outSISREG(pSiSUSB, SISPEL, 0xff);
+
+ outSISREG(pSiSUSB, SISCOLIDX, 0x00);
+ for(i = 0; i < 768; i++) {
+ outSISREG(pSiSUSB, SISCOLDATA, restore->sisDAC[i]);
+ (void)inSISREG(pSiSUSB, SISINPSTAT);
+ (void)inSISREG(pSiSUSB, SISINPSTAT);
+ }
+
+ SiSUSB_DisablePalette(pSiSUSB);
+}
+
+void
+SiSUSBVGARestore(ScrnInfoPtr pScrn, SISUSBRegPtr restore, int flags)
+{
+ if(restore == NULL) return;
+
+ if(flags & SISVGA_SR_MODE) SiSUSBVGARestoreMode(pScrn, restore);
+ if(flags & SISVGA_SR_CMAP) SiSUSBVGARestoreColormap(pScrn, restore);
+}
+
+static void
+SiSUSB_SeqReset(SISUSBPtr pSiSUSB, Bool start)
+{
+ if(start) {
+ outSISIDXREG(pSiSUSB, SISSR, 0x00, 0x01); /* Synchronous Reset */
+ } else {
+ outSISIDXREG(pSiSUSB, SISSR, 0x00, 0x03); /* End Reset */
+ }
+}
+
+void
+SiSUSBVGAProtect(ScrnInfoPtr pScrn, Bool on)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ UChar tmp;
+
+ if(!pScrn->vtSema) return;
+
+ if(on) {
+ inSISIDXREG(pSiSUSB, SISSR, 0x01, tmp);
+ SiSUSB_SeqReset(pSiSUSB, TRUE); /* start synchronous reset */
+ outSISIDXREG(pSiSUSB, SISSR, 0x01, tmp | 0x20); /* disable display */
+ SiSUSB_EnablePalette(pSiSUSB);
+ } else {
+ andSISIDXREG(pSiSUSB, SISSR, 0x01, ~0x20); /* enable display */
+ SiSUSB_SeqReset(pSiSUSB, FALSE); /* clear synchronous reset */
+ SiSUSB_DisablePalette(pSiSUSB);
+ }
+}
+
+static void
+SISUSBVGABlankScreen(ScrnInfoPtr pScrn, Bool on)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ UChar tmp;
+
+ inSISIDXREG(pSiSUSB, SISSR, 0x01, tmp);
+ if(on) tmp &= ~0x20;
+ else tmp |= 0x20;
+ SiSUSB_SeqReset(pSiSUSB, TRUE);
+ outSISIDXREG(pSiSUSB, SISSR, 0x01, tmp);
+ SiSUSB_SeqReset(pSiSUSB, FALSE);
+}
+
+Bool
+SiSUSBVGASaveScreen(ScreenPtr pScreen, int mode)
+{
+ ScrnInfoPtr pScrn = NULL;
+ Bool on = xf86IsUnblank(mode);
+
+ if(pScreen == NULL) return FALSE;
+
+ pScrn = xf86Screens[pScreen->myNum];
+
+ if(pScrn->vtSema) {
+ SISUSBVGABlankScreen(pScrn, on);
+ }
+ return TRUE;
+}
+
+
+
+
diff --git a/driver/xf86-video-sisusb/src/sisusb_video.c b/driver/xf86-video-sisusb/src/sisusb_video.c
new file mode 100644
index 000000000..e0d05a530
--- /dev/null
+++ b/driver/xf86-video-sisusb/src/sisusb_video.c
@@ -0,0 +1,2054 @@
+/* $XFree86$ */
+/* $XdotOrg: driver/xf86-video-sisusb/src/sisusb_video.c,v 1.9 2006/04/07 23:15:17 aplattner Exp $ */
+/*
+ * Xv driver for SiS 315 USB
+ *
+ * Note: The version of the 315 used in my dongle does not seem
+ * to support Xv at all. The overlay just won't show up. However,
+ * Xv is left enabled since I don't know if other versions of the
+ * dongle support the overlay.
+ *
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1) Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2) Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3) The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "sisusb.h"
+
+#ifdef SIS_GLOBAL_ENABLEXV
+
+#include "xf86fbman.h"
+#include "regionstr.h"
+
+#include "xf86xv.h"
+#include <X11/extensions/Xv.h>
+#include "dixstruct.h"
+#include "fourcc.h"
+
+#include "sisusb_regs.h"
+
+#include "sisusb_video.h"
+
+/****************************************************************************
+ * Raw register access : These routines directly interact with the sis's
+ * control aperature. Must not be called until after
+ * the board's pci memory has been mapped.
+ ****************************************************************************/
+
+#ifdef SIS_ENABLEXV
+#if 0
+static CARD32 _sisread(SISUSBPtr pSiSUSB, CARD32 reg)
+{
+ return *(pSiSUSB->IOBase + reg);
+}
+
+static void _siswrite(SISUSBPtr pSiSUSB, CARD32 reg, CARD32 data)
+{
+ *(pSiSUSB->IOBase + reg) = data;
+}
+#endif
+
+static CARD8 getsrreg(SISUSBPtr pSiSUSB, CARD8 reg)
+{
+ CARD8 ret;
+ inSISIDXREG(pSiSUSB, SISSR, reg, ret);
+ return(ret);
+}
+
+static CARD8 getvideoreg(SISUSBPtr pSiSUSB, CARD8 reg)
+{
+ CARD8 ret;
+ inSISIDXREG(pSiSUSB, SISVID, reg, ret);
+ return(ret);
+}
+
+static __inline void setvideoreg(SISUSBPtr pSiSUSB, CARD8 reg, CARD8 data)
+{
+ outSISIDXREG(pSiSUSB, SISVID, reg, data);
+}
+
+static __inline void setvideoregmask(SISUSBPtr pSiSUSB, CARD8 reg, CARD8 data, CARD8 mask)
+{
+ setSISIDXREGmask(pSiSUSB, SISVID, reg, data, mask);
+}
+
+static void setsrregmask(SISUSBPtr pSiSUSB, CARD8 reg, CARD8 data, CARD8 mask)
+{
+ setSISIDXREGmask(pSiSUSB, SISSR, reg, data, mask);
+}
+
+/* VBlank */
+static CARD8 vblank_active_CRT1(SISUSBPtr pSiSUSB, SISUSBPortPrivPtr pPriv)
+{
+ return(inSISREG(pSiSUSB, SISINPSTAT) & 0x08); /* Verified */
+}
+
+/* Scanline - unused */
+#if 0
+static CARD16 get_scanline_CRT1(SISUSBPtr pSiSUSB)
+{
+ CARD32 line;
+
+ _siswrite(pSiSUSB, REG_PRIM_CRT_COUNTER, 0x00000001);
+ line = _sisread(pSiSUSB, REG_PRIM_CRT_COUNTER);
+
+ return((CARD16)((line >> 16) & 0x07FF));
+}
+#endif
+#endif /* SIS_ENABLEXV */
+
+/* Helper: Count attributes */
+static int
+SiSUSBCountAttributes(XF86AttributeRec *attrs)
+{
+ int num = 0;
+
+ while(attrs[num].name) num++;
+
+ return num;
+}
+
+#ifdef SIS_ENABLEXV
+static void
+SiSUSBComputeXvGamma(SISUSBPtr pSiSUSB)
+{
+ int num = 255, i;
+ double red = 1.0 / (double)((double)pSiSUSB->XvGammaRed / 1000);
+ double green = 1.0 / (double)((double)pSiSUSB->XvGammaGreen / 1000);
+ double blue = 1.0 / (double)((double)pSiSUSB->XvGammaBlue / 1000);
+
+ for(i = 0; i <= num; i++) {
+ pSiSUSB->XvGammaRampRed[i] =
+ (red == 1.0) ? i : (CARD8)(pow((double)i / (double)num, red) * (double)num + 0.5);
+
+ pSiSUSB->XvGammaRampGreen[i] =
+ (green == 1.0) ? i : (CARD8)(pow((double)i / (double)num, green) * (double)num + 0.5);
+
+ pSiSUSB->XvGammaRampBlue[i] =
+ (blue == 1.0) ? i : (CARD8)(pow((double)i / (double)num, blue) * (double)num + 0.5);
+ }
+}
+
+static void
+SiSUSBSetXvGamma(SISUSBPtr pSiSUSB)
+{
+ int i;
+ UChar backup = getsrreg(pSiSUSB, 0x1f);
+ setsrregmask(pSiSUSB, 0x1f, 0x08, 0x18);
+ for(i = 0; i <= 255; i++) {
+ SIS_MMIO_OUT32(pSiSUSB, pSiSUSB->IOBase, 0x8570,
+ (i << 24) |
+ (pSiSUSB->XvGammaRampBlue[i] << 16) |
+ (pSiSUSB->XvGammaRampGreen[i] << 8) |
+ pSiSUSB->XvGammaRampRed[i]);
+ }
+ setsrregmask(pSiSUSB, 0x1f, backup, 0xff);
+}
+
+static void
+SiSUSBUpdateXvGamma(SISUSBPtr pSiSUSB, SISUSBPortPrivPtr pPriv)
+{
+ UChar sr7 = getsrreg(pSiSUSB, 0x07);
+
+ if(!pSiSUSB->XvGamma) return;
+ if(!(pSiSUSB->MiscFlags & MISC_CRT1OVERLAYGAMMA)) return;
+
+ if(!(sr7 & 0x04)) return;
+
+ SiSUSBComputeXvGamma(pSiSUSB);
+ SiSUSBSetXvGamma(pSiSUSB);
+}
+
+static void
+SISUSBResetXvGamma(ScrnInfoPtr pScrn)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ SISUSBPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn);
+
+ SiSUSBUpdateXvGamma(pSiSUSB, pPriv);
+}
+#endif
+
+void SISUSBInitVideo(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL;
+ XF86VideoAdaptorPtr newAdaptor = NULL;
+ int num_adaptors;
+
+ newAdaptor = SISUSBSetupImageVideo(pScreen);
+
+#ifdef SIS_ENABLEXV
+ if(newAdaptor) {
+ SISUSBInitOffscreenImages(pScreen);
+ }
+#endif
+
+ num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
+
+ if(newAdaptor) {
+ int size = num_adaptors;
+
+ if(newAdaptor) size++;
+
+ newAdaptors = xalloc(size * sizeof(XF86VideoAdaptorPtr*));
+ if(newAdaptors) {
+ if(num_adaptors) {
+ memcpy(newAdaptors, adaptors, num_adaptors * sizeof(XF86VideoAdaptorPtr));
+ }
+ if(newAdaptor) {
+ newAdaptors[num_adaptors] = newAdaptor;
+ num_adaptors++;
+ }
+ adaptors = newAdaptors;
+ }
+ }
+
+ if(num_adaptors) {
+ xf86XVScreenInit(pScreen, adaptors, num_adaptors);
+ }
+
+ if(newAdaptors) {
+ xfree(newAdaptors);
+ }
+}
+
+void
+SISUSBSetPortDefaults(ScrnInfoPtr pScrn, SISUSBPortPrivPtr pPriv)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+
+ pPriv->colorKey = pSiSUSB->colorKey = 0x000101fe;
+ pPriv->brightness = pSiSUSB->XvDefBri;
+ pPriv->contrast = pSiSUSB->XvDefCon;
+ pPriv->hue = pSiSUSB->XvDefHue;
+ pPriv->saturation = pSiSUSB->XvDefSat;
+ pPriv->autopaintColorKey = TRUE;
+ pPriv->disablegfx = pSiSUSB->XvDefDisableGfx;
+ pPriv->disablegfxlr= pSiSUSB->XvDefDisableGfxLR;
+ pSiSUSB->disablecolorkeycurrent = pSiSUSB->XvDisableColorKey;
+ pPriv->usechromakey = pSiSUSB->XvUseChromaKey;
+ pPriv->insidechromakey = pSiSUSB->XvInsideChromaKey;
+ pPriv->yuvchromakey = pSiSUSB->XvYUVChromaKey;
+ pPriv->chromamin = pSiSUSB->XvChromaMin;
+ pPriv->chromamax = pSiSUSB->XvChromaMax;
+ pPriv->crtnum = 0;
+
+ pSiSUSB->XvGammaRed = pSiSUSB->XvGammaRedDef;
+ pSiSUSB->XvGammaGreen = pSiSUSB->XvGammaGreenDef;
+ pSiSUSB->XvGammaBlue = pSiSUSB->XvGammaBlueDef;
+#ifdef SIS_ENABLEXV
+ SiSUSBUpdateXvGamma(pSiSUSB, pPriv);
+#endif
+}
+
+#ifdef SIS_ENABLEXV
+static void
+SISUSBResetVideo(ScrnInfoPtr pScrn)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ SISUSBPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn);
+
+ /* Unlock registers */
+#ifdef UNLOCK_ALWAYS
+ sisusbSaveUnlockExtRegisterLock(pSiSUSB, NULL, NULL);
+#endif
+ if(getvideoreg(pSiSUSB, Index_VI_Passwd) != 0xa1) {
+ setvideoreg(pSiSUSB, Index_VI_Passwd, 0x86);
+ if(getvideoreg(pSiSUSB, Index_VI_Passwd) != 0xa1)
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Xv: Video password could not unlock registers\n");
+ }
+
+ /* Initialize first overlay (CRT1) ------------------------------- */
+
+ /* This bit has obviously a different meaning on 315 series (linebuffer-related) */
+
+ /* Select overlay 2, clear all linebuffer related bits */
+ setvideoregmask(pSiSUSB, Index_VI_Control_Misc2, 0x00, 0xb1);
+
+ /* Disable overlay */
+ setvideoregmask(pSiSUSB, Index_VI_Control_Misc0, 0x00, 0x02);
+
+ /* Disable bob de-interlacer and some strange bit */
+ setvideoregmask(pSiSUSB, Index_VI_Control_Misc1, 0x00, 0x82);
+
+ /* Reset scale control and contrast */
+ /* (Enable DDA (interpolation)) */
+ setvideoregmask(pSiSUSB, Index_VI_Scale_Control, 0x60, 0x60);
+ setvideoregmask(pSiSUSB, Index_VI_Contrast_Enh_Ctrl, 0x04, 0x1F);
+
+ setvideoreg(pSiSUSB, Index_VI_Disp_Y_Buf_Preset_Low, 0x00);
+ setvideoreg(pSiSUSB, Index_VI_Disp_Y_Buf_Preset_Middle, 0x00);
+ setvideoreg(pSiSUSB, Index_VI_UV_Buf_Preset_Low, 0x00);
+ setvideoreg(pSiSUSB, Index_VI_UV_Buf_Preset_Middle, 0x00);
+ setvideoreg(pSiSUSB, Index_VI_Disp_Y_UV_Buf_Preset_High, 0x00);
+ setvideoreg(pSiSUSB, Index_VI_Play_Threshold_Low, 0x00);
+ setvideoreg(pSiSUSB, Index_VI_Play_Threshold_High, 0x00);
+
+ /* Reset top window position for scanline check */
+ setvideoreg(pSiSUSB, Index_VI_Win_Ver_Disp_Start_Low, 0x00);
+ setvideoreg(pSiSUSB, Index_VI_Win_Ver_Over, 0x00);
+
+ /* set default properties for overlay 1 (CRT1) -------------------------- */
+ setvideoregmask(pSiSUSB, Index_VI_Control_Misc2, 0x00, 0x01);
+ setvideoregmask(pSiSUSB, Index_VI_Contrast_Enh_Ctrl, 0x04, 0x07);
+ setvideoreg(pSiSUSB, Index_VI_Brightness, 0x20);
+ setvideoreg(pSiSUSB, Index_VI_Hue, 0x00);
+ setvideoreg(pSiSUSB, Index_VI_Saturation, 0x00);
+
+ /* Reset Xv gamma correction */
+ SiSUSBUpdateXvGamma(pSiSUSB, pPriv);
+}
+#endif
+
+/* Set display mode (single CRT1/CRT2, mirror).
+ * MIRROR mode is only available on chipsets with two overlays.
+ * On the other chipsets, if only CRT1 or only CRT2 are used,
+ * the correct display CRT is chosen automatically. If both
+ * CRT1 and CRT2 are connected, the user can choose between CRT1 and
+ * CRT2 by using the option XvOnCRT2.
+ */
+#ifdef SIS_ENABLEXV
+static void
+set_dispmode(ScrnInfoPtr pScrn, SISUSBPortPrivPtr pPriv)
+{
+ pPriv->dualHeadMode = pPriv->bridgeIsSlave = FALSE;
+ pPriv->displayMode = DISPMODE_SINGLE1; /* CRT1 only */
+}
+
+static void
+set_disptype_regs(ScrnInfoPtr pScrn, SISUSBPortPrivPtr pPriv)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+
+#ifdef UNLOCK_ALWAYS
+ sisusbSaveUnlockExtRegisterLock(pSiSUSB, NULL, NULL);
+#endif
+
+ setsrregmask(pSiSUSB, 0x06, 0x00, 0xc0); /* only overlay -> CRT1 */
+ setsrregmask(pSiSUSB, 0x32, 0x00, 0xc0);
+}
+#endif
+
+static void
+set_allowswitchcrt(SISUSBPtr pSiSUSB, SISUSBPortPrivPtr pPriv)
+{
+ pPriv->AllowSwitchCRT = FALSE;
+}
+
+static void
+set_maxencoding(SISUSBPtr pSiSUSB, SISUSBPortPrivPtr pPriv)
+{
+ DummyEncoding.width = IMAGE_MAX_WIDTH_315;
+ DummyEncoding.height = IMAGE_MAX_HEIGHT_315;
+}
+
+static XF86VideoAdaptorPtr
+SISUSBSetupImageVideo(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ XF86VideoAdaptorPtr adapt;
+ SISUSBPortPrivPtr pPriv;
+
+ if(!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) +
+ sizeof(SISUSBPortPrivRec) +
+ sizeof(DevUnion))))
+ return NULL;
+
+ adapt->type = XvWindowMask | XvInputMask | XvImageMask;
+ adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+ adapt->name = "SIS 300/315/330 series Video Overlay";
+ adapt->nEncodings = 1;
+ adapt->pEncodings = &DummyEncoding;
+
+ adapt->nFormats = NUM_FORMATS;
+ adapt->pFormats = SISUSBFormats;
+ adapt->nPorts = 1;
+ adapt->pPortPrivates = (DevUnion*)(&adapt[1]);
+
+ pPriv = (SISUSBPortPrivPtr)(&adapt->pPortPrivates[1]);
+
+ /* Setup chipset type helpers */
+
+ pPriv->hasTwoOverlays = FALSE;
+ pPriv->AllowSwitchCRT = FALSE;
+
+ set_allowswitchcrt(pSiSUSB, pPriv);
+
+ adapt->pPortPrivates[0].ptr = (pointer)(pPriv);
+
+ adapt->nImages = NUM_IMAGES_315;
+ adapt->pAttributes = SISUSBAttributes_315;
+ adapt->nAttributes = SiSUSBCountAttributes(&SISUSBAttributes_315[0]);
+ if(pPriv->hasTwoOverlays) adapt->nAttributes--;
+
+ adapt->pImages = SISUSBImages;
+ adapt->PutVideo = NULL;
+ adapt->PutStill = NULL;
+ adapt->GetVideo = NULL;
+ adapt->GetStill = NULL;
+ adapt->StopVideo = SISUSBStopVideo;
+#ifdef SIS_ENABLEXV
+ adapt->PutImage = SISUSBPutImage;
+#else
+ adapt->PutImage = NULL;
+#endif
+ adapt->SetPortAttribute = SISUSBSetPortAttribute;
+ adapt->GetPortAttribute = SISUSBGetPortAttribute;
+ adapt->QueryBestSize = SISUSBQueryBestSize;
+ adapt->QueryImageAttributes = SISUSBQueryImageAttributes;
+
+ pPriv->videoStatus = 0;
+ pPriv->currentBuf = 0;
+ pPriv->linear = NULL;
+ pPriv->grabbedByV4L= FALSE;
+ pPriv->NoOverlay = FALSE;
+ pPriv->PrevOverlay = FALSE;
+ pPriv->is340 = FALSE;
+
+ /* gotta uninit this someplace */
+#if defined(REGION_NULL)
+ REGION_NULL(pScreen, &pPriv->clip);
+#else
+ REGION_INIT(pScreen, &pPriv->clip, NullBox, 0);
+#endif
+
+ pSiSUSB->adaptor = adapt;
+
+ pSiSUSB->xvBrightness = MAKE_ATOM(sisxvbrightness);
+ pSiSUSB->xvContrast = MAKE_ATOM(sisxvcontrast);
+ pSiSUSB->xvColorKey = MAKE_ATOM(sisxvcolorkey);
+ pSiSUSB->xvSaturation = MAKE_ATOM(sisxvsaturation);
+ pSiSUSB->xvHue = MAKE_ATOM(sisxvhue);
+ pSiSUSB->xvSwitchCRT = MAKE_ATOM(sisxvswitchcrt);
+ pSiSUSB->xvAutopaintColorKey = MAKE_ATOM(sisxvautopaintcolorkey);
+ pSiSUSB->xvSetDefaults = MAKE_ATOM(sisxvsetdefaults);
+ pSiSUSB->xvDisableGfx = MAKE_ATOM(sisxvdisablegfx);
+ pSiSUSB->xvDisableGfxLR = MAKE_ATOM(sisxvdisablegfxlr);
+ pSiSUSB->xvTVXPosition = MAKE_ATOM(sisxvtvxposition);
+ pSiSUSB->xvTVYPosition = MAKE_ATOM(sisxvtvyposition);
+ pSiSUSB->xvGammaRed = MAKE_ATOM(sisxvgammared);
+ pSiSUSB->xvGammaGreen = MAKE_ATOM(sisxvgammagreen);
+ pSiSUSB->xvGammaBlue = MAKE_ATOM(sisxvgammablue);
+ pSiSUSB->xvDisableColorkey = MAKE_ATOM(sisxvdisablecolorkey);
+ pSiSUSB->xvUseChromakey = MAKE_ATOM(sisxvusechromakey);
+ pSiSUSB->xvInsideChromakey = MAKE_ATOM(sisxvinsidechromakey);
+ pSiSUSB->xvYUVChromakey = MAKE_ATOM(sisxvyuvchromakey);
+ pSiSUSB->xvChromaMin = MAKE_ATOM(sisxvchromamin);
+ pSiSUSB->xvChromaMax = MAKE_ATOM(sisxvchromamax);
+#ifdef XV_SD_DEPRECATED
+ pSiSUSB->xv_QVF = MAKE_ATOM(sisxvqueryvbflags);
+ pSiSUSB->xv_GDV = MAKE_ATOM(sisxvsdgetdriverversion);
+ pSiSUSB->xv_GHI = MAKE_ATOM(sisxvsdgethardwareinfo);
+ pSiSUSB->xv_GBI = MAKE_ATOM(sisxvsdgetbusid);
+ pSiSUSB->xv_QVV = MAKE_ATOM(sisxvsdqueryvbflagsversion);
+ pSiSUSB->xv_GSF = MAKE_ATOM(sisxvsdgetsdflags);
+ pSiSUSB->xv_GSF2 = MAKE_ATOM(sisxvsdgetsdflags2);
+ pSiSUSB->xv_USD = MAKE_ATOM(sisxvsdunlocksisdirect);
+ pSiSUSB->xv_SVF = MAKE_ATOM(sisxvsdsetvbflags);
+ pSiSUSB->xv_QDD = MAKE_ATOM(sisxvsdquerydetecteddevices);
+ pSiSUSB->xv_CT1 = MAKE_ATOM(sisxvsdcrt1status);
+ pSiSUSB->xv_CMD = MAKE_ATOM(sisxvsdcheckmodeindexforcrt2);
+ pSiSUSB->xv_CMDR = MAKE_ATOM(sisxvsdresultcheckmodeindexforcrt2);
+ pSiSUSB->xv_RDT = MAKE_ATOM(sisxvsdredetectcrt2);
+ pSiSUSB->xv_TAF = MAKE_ATOM(sisxvsdsisantiflicker);
+ pSiSUSB->xv_TSA = MAKE_ATOM(sisxvsdsissaturation);
+ pSiSUSB->xv_TEE = MAKE_ATOM(sisxvsdsisedgeenhance);
+ pSiSUSB->xv_COC = MAKE_ATOM(sisxvsdsiscolcalibc);
+ pSiSUSB->xv_COF = MAKE_ATOM(sisxvsdsiscolcalibf);
+ pSiSUSB->xv_CFI = MAKE_ATOM(sisxvsdsiscfilter);
+ pSiSUSB->xv_YFI = MAKE_ATOM(sisxvsdsisyfilter);
+ pSiSUSB->xv_TCO = MAKE_ATOM(sisxvsdchcontrast);
+ pSiSUSB->xv_TTE = MAKE_ATOM(sisxvsdchtextenhance);
+ pSiSUSB->xv_TCF = MAKE_ATOM(sisxvsdchchromaflickerfilter);
+ pSiSUSB->xv_TLF = MAKE_ATOM(sisxvsdchlumaflickerfilter);
+ pSiSUSB->xv_TCC = MAKE_ATOM(sisxvsdchcvbscolor);
+ pSiSUSB->xv_OVR = MAKE_ATOM(sisxvsdchoverscan);
+ pSiSUSB->xv_SGA = MAKE_ATOM(sisxvsdenablegamma);
+ pSiSUSB->xv_TXS = MAKE_ATOM(sisxvsdtvxscale);
+ pSiSUSB->xv_TYS = MAKE_ATOM(sisxvsdtvyscale);
+ pSiSUSB->xv_GSS = MAKE_ATOM(sisxvsdgetscreensize);
+ pSiSUSB->xv_BRR = MAKE_ATOM(sisxvsdstorebrir);
+ pSiSUSB->xv_BRG = MAKE_ATOM(sisxvsdstorebrig);
+ pSiSUSB->xv_BRB = MAKE_ATOM(sisxvsdstorebrib);
+ pSiSUSB->xv_PBR = MAKE_ATOM(sisxvsdstorepbrir);
+ pSiSUSB->xv_PBG = MAKE_ATOM(sisxvsdstorepbrig);
+ pSiSUSB->xv_PBB = MAKE_ATOM(sisxvsdstorepbrib);
+ pSiSUSB->xv_BRR2 = MAKE_ATOM(sisxvsdstorebrir2);
+ pSiSUSB->xv_BRG2 = MAKE_ATOM(sisxvsdstorebrig2);
+ pSiSUSB->xv_BRB2 = MAKE_ATOM(sisxvsdstorebrib2);
+ pSiSUSB->xv_PBR2 = MAKE_ATOM(sisxvsdstorepbrir2);
+ pSiSUSB->xv_PBG2 = MAKE_ATOM(sisxvsdstorepbrig2);
+ pSiSUSB->xv_PBB2 = MAKE_ATOM(sisxvsdstorepbrib2);
+ pSiSUSB->xv_GARC2 = MAKE_ATOM(sisxvsdstoregarc2);
+ pSiSUSB->xv_GAGC2 = MAKE_ATOM(sisxvsdstoregagc2);
+ pSiSUSB->xv_GABC2 = MAKE_ATOM(sisxvsdstoregabc2);
+ pSiSUSB->xv_BRRC2 = MAKE_ATOM(sisxvsdstorebrirc2);
+ pSiSUSB->xv_BRGC2 = MAKE_ATOM(sisxvsdstorebrigc2);
+ pSiSUSB->xv_BRBC2 = MAKE_ATOM(sisxvsdstorebribc2);
+ pSiSUSB->xv_PBRC2 = MAKE_ATOM(sisxvsdstorepbrirc2);
+ pSiSUSB->xv_PBGC2 = MAKE_ATOM(sisxvsdstorepbrigc2);
+ pSiSUSB->xv_PBBC2 = MAKE_ATOM(sisxvsdstorepbribc2);
+ pSiSUSB->xv_SHC = MAKE_ATOM(sisxvsdhidehwcursor);
+ pSiSUSB->xv_PMD = MAKE_ATOM(sisxvsdpanelmode);
+#ifdef TWDEBUG
+ pSiSUSB->xv_STR = MAKE_ATOM(sisxvsetreg);
+#endif
+#endif
+
+ pSiSUSB->xv_sisdirectunlocked = 0;
+ pSiSUSB->xv_sd_result = 0;
+
+ pPriv->shiftValue = 1;
+
+ /* Set displayMode according to VBFlags */
+#ifdef SIS_ENABLEXV
+ set_dispmode(pScrn, pPriv);
+#endif
+
+ pPriv->linebufMergeLimit = LINEBUFLIMIT1;
+
+ set_maxencoding(pSiSUSB, pPriv);
+
+ pPriv->linebufmask = 0xb1;
+ if(!(pPriv->hasTwoOverlays)) {
+ /* On machines with only one overlay, the linebuffers are
+ * generally larger, so our merging-limit is higher, too.
+ */
+ pPriv->linebufMergeLimit = LINEBUFLIMIT2;
+ }
+
+ /* Reset the properties to their defaults */
+ SISUSBSetPortDefaults(pScrn, pPriv);
+
+#ifdef SIS_ENABLEXV
+ /* Set SR(06, 32) registers according to DISPMODE */
+ set_disptype_regs(pScrn, pPriv);
+
+ SISUSBResetVideo(pScrn);
+ pSiSUSB->ResetXv = SISUSBResetVideo;
+ pSiSUSB->ResetXvGamma = SISUSBResetXvGamma;
+#endif
+
+ return adapt;
+}
+
+#ifdef SIS_ENABLEXV
+#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,3,0)
+static Bool
+RegionsEqual(RegionPtr A, RegionPtr B)
+{
+ int *dataA, *dataB;
+ int num;
+
+ num = REGION_NUM_RECTS(A);
+ if(num != REGION_NUM_RECTS(B))
+ return FALSE;
+
+ if((A->extents.x1 != B->extents.x1) ||
+ (A->extents.x2 != B->extents.x2) ||
+ (A->extents.y1 != B->extents.y1) ||
+ (A->extents.y2 != B->extents.y2))
+ return FALSE;
+
+ dataA = (int*)REGION_RECTS(A);
+ dataB = (int*)REGION_RECTS(B);
+
+ while(num--) {
+ if((dataA[0] != dataB[0]) || (dataA[1] != dataB[1]))
+ return FALSE;
+ dataA += 2;
+ dataB += 2;
+ }
+
+ return TRUE;
+}
+#endif
+#endif
+
+#if 0
+void
+SISUSBUpdateVideoParms(SISUSBPtr pSiSUSB, SISUSBPortPrivPtr pPriv)
+{
+ set_allowswitchcrt(pSiSUSB, pPriv);
+#ifdef SIS_ENABLEXV
+ set_dispmode(pSiSUSB->pScrn, pPriv);
+#endif
+ set_maxencoding(pSiSUSB, pPriv);
+}
+#endif
+
+static int
+SISUSBSetPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
+ INT32 value, pointer data)
+{
+ SISUSBPortPrivPtr pPriv = (SISUSBPortPrivPtr)data;
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+
+ if(attribute == pSiSUSB->xvBrightness) {
+ if((value < -128) || (value > 127))
+ return BadValue;
+ pPriv->brightness = value;
+ } else if(attribute == pSiSUSB->xvContrast) {
+ if((value < 0) || (value > 7))
+ return BadValue;
+ pPriv->contrast = value;
+ } else if(attribute == pSiSUSB->xvColorKey) {
+ pPriv->colorKey = pSiSUSB->colorKey = value;
+ REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
+ } else if(attribute == pSiSUSB->xvAutopaintColorKey) {
+ if((value < 0) || (value > 1))
+ return BadValue;
+ pPriv->autopaintColorKey = value;
+ } else if(attribute == pSiSUSB->xvSetDefaults) {
+ SISUSBSetPortDefaults(pScrn, pPriv);
+ } else if(attribute == pSiSUSB->xvDisableGfx) {
+ if((value < 0) || (value > 1))
+ return BadValue;
+ pPriv->disablegfx = value;
+ } else if(attribute == pSiSUSB->xvDisableGfxLR) {
+ if((value < 0) || (value > 1))
+ return BadValue;
+ pPriv->disablegfxlr = value;
+ } else if(attribute == pSiSUSB->xvTVXPosition) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xvTVYPosition) {
+ /* Nop */
+ } else if(attribute == pSiSUSB->xvDisableColorkey) {
+ if((value < 0) || (value > 1))
+ return BadValue;
+ pSiSUSB->disablecolorkeycurrent = value;
+ } else if(attribute == pSiSUSB->xvUseChromakey) {
+ if((value < 0) || (value > 1))
+ return BadValue;
+ pPriv->usechromakey = value;
+ } else if(attribute == pSiSUSB->xvInsideChromakey) {
+ if((value < 0) || (value > 1))
+ return BadValue;
+ pPriv->insidechromakey = value;
+ } else if(attribute == pSiSUSB->xvYUVChromakey) {
+ if((value < 0) || (value > 1))
+ return BadValue;
+ pPriv->yuvchromakey = value;
+ } else if(attribute == pSiSUSB->xvChromaMin) {
+ pPriv->chromamin = value;
+ } else if(attribute == pSiSUSB->xvChromaMax) {
+ pPriv->chromamax = value;
+ } else if(attribute == pSiSUSB->xvHue) {
+ if((value < -8) || (value > 7))
+ return BadValue;
+ pPriv->hue = value;
+ } else if(attribute == pSiSUSB->xvSaturation) {
+ if((value < -7) || (value > 7))
+ return BadValue;
+ pPriv->saturation = value;
+ } else if(attribute == pSiSUSB->xvGammaRed) {
+ if((value < 100) || (value > 10000))
+ return BadValue;
+ pSiSUSB->XvGammaRed = value;
+#ifdef SIS_ENABLEXV
+ SiSUSBUpdateXvGamma(pSiSUSB, pPriv);
+#endif
+ } else if(attribute == pSiSUSB->xvGammaGreen) {
+ if((value < 100) || (value > 10000))
+ return BadValue;
+ pSiSUSB->XvGammaGreen = value;
+#ifdef SIS_ENABLEXV
+ SiSUSBUpdateXvGamma(pSiSUSB, pPriv);
+#endif
+ } else if(attribute == pSiSUSB->xvGammaBlue) {
+ if((value < 100) || (value > 10000))
+ return BadValue;
+ pSiSUSB->XvGammaBlue = value;
+#ifdef SIS_ENABLEXV
+ SiSUSBUpdateXvGamma(pSiSUSB, pPriv);
+#endif
+ } else if(attribute == pSiSUSB->xvSwitchCRT) {
+ if(pPriv->AllowSwitchCRT) {
+ if((value < 0) || (value > 1))
+ return BadValue;
+ pPriv->crtnum = value;
+ }
+ } else {
+#ifdef XV_SD_DEPRECATED
+ return(SISUSBSetPortUtilAttribute(pScrn, attribute, value, pPriv));
+#else
+ return BadMatch;
+#endif
+ }
+ return Success;
+}
+
+static int
+SISUSBGetPortAttribute(
+ ScrnInfoPtr pScrn,
+ Atom attribute,
+ INT32 *value,
+ pointer data
+){
+ SISUSBPortPrivPtr pPriv = (SISUSBPortPrivPtr)data;
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+
+ if(attribute == pSiSUSB->xvBrightness) {
+ *value = pPriv->brightness;
+ } else if(attribute == pSiSUSB->xvContrast) {
+ *value = pPriv->contrast;
+ } else if(attribute == pSiSUSB->xvColorKey) {
+ *value = pPriv->colorKey;
+ } else if(attribute == pSiSUSB->xvAutopaintColorKey) {
+ *value = (pPriv->autopaintColorKey) ? 1 : 0;
+ } else if(attribute == pSiSUSB->xvDisableGfx) {
+ *value = (pPriv->disablegfx) ? 1 : 0;
+ } else if(attribute == pSiSUSB->xvDisableGfxLR) {
+ *value = (pPriv->disablegfxlr) ? 1 : 0;
+ } else if(attribute == pSiSUSB->xvTVXPosition) {
+ *value = 0;
+ } else if(attribute == pSiSUSB->xvTVYPosition) {
+ *value = 0;
+ } else if(attribute == pSiSUSB->xvDisableColorkey) {
+ *value = (pSiSUSB->disablecolorkeycurrent) ? 1 : 0;
+ } else if(attribute == pSiSUSB->xvUseChromakey) {
+ *value = (pPriv->usechromakey) ? 1 : 0;
+ } else if(attribute == pSiSUSB->xvInsideChromakey) {
+ *value = (pPriv->insidechromakey) ? 1 : 0;
+ } else if(attribute == pSiSUSB->xvYUVChromakey) {
+ *value = (pPriv->yuvchromakey) ? 1 : 0;
+ } else if(attribute == pSiSUSB->xvChromaMin) {
+ *value = pPriv->chromamin;
+ } else if(attribute == pSiSUSB->xvChromaMax) {
+ *value = pPriv->chromamax;
+ } else if(attribute == pSiSUSB->xvHue) {
+ *value = pPriv->hue;
+ } else if(attribute == pSiSUSB->xvSaturation) {
+ *value = pPriv->saturation;
+ } else if(attribute == pSiSUSB->xvGammaRed) {
+ *value = pSiSUSB->XvGammaRed;
+ } else if(attribute == pSiSUSB->xvGammaGreen) {
+ *value = pSiSUSB->XvGammaGreen;
+ } else if(attribute == pSiSUSB->xvGammaBlue) {
+ *value = pSiSUSB->XvGammaBlue;
+ } else if(attribute == pSiSUSB->xvSwitchCRT) {
+ *value = 0;
+ } else {
+#ifdef XV_SD_DEPRECATED
+ return(SISUSBGetPortUtilAttribute(pScrn, attribute, value, pPriv));
+#else
+ return BadMatch;
+#endif
+ }
+ return Success;
+}
+
+static void
+SISUSBQueryBestSize(
+ 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;
+}
+
+#ifdef SIS_ENABLEXV
+static void
+calc_scale_factor(SISUSBOverlayPtr pOverlay, ScrnInfoPtr pScrn,
+ SISUSBPortPrivPtr pPriv, int index, int iscrt2)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ CARD32 I=0,mult=0;
+ int flag=0;
+
+ int dstW = pOverlay->dstBox.x2 - pOverlay->dstBox.x1;
+ int dstH = pOverlay->dstBox.y2 - pOverlay->dstBox.y1;
+ int srcW = pOverlay->srcW;
+ int srcH = pOverlay->srcH;
+ int srcPitch = pOverlay->origPitch;
+ int origdstH = dstH;
+ int modeflags = pOverlay->currentmode->Flags;
+
+ /* For double scan modes, we need to double the height
+ * On 315 and 550 (?), we need to double the width as well.
+ * Interlace mode vice versa.
+ */
+ if(modeflags & V_DBLSCAN) {
+ dstH = origdstH << 1;
+ flag = 0;
+ if((pSiSUSB->ChipType >= SIS_315H) &&
+ (pSiSUSB->ChipType <= SIS_550)) {
+ dstW <<= 1;
+ }
+ }
+ if(modeflags & V_INTERLACE) {
+ dstH = origdstH >> 1;
+ flag = 0;
+ }
+
+ if(dstW < OVERLAY_MIN_WIDTH) dstW = OVERLAY_MIN_WIDTH;
+ if(dstW == srcW) {
+ pOverlay->HUSF = 0x00;
+ pOverlay->IntBit = 0x05;
+ pOverlay->wHPre = 0;
+ } else if(dstW > srcW) {
+ dstW += 2;
+ pOverlay->HUSF = (srcW << 16) / dstW;
+ pOverlay->IntBit = 0x04;
+ pOverlay->wHPre = 0;
+ } else {
+ int tmpW = dstW;
+
+ /* It seems, the hardware can't scale below factor .125 (=1/8) if the
+ pitch isn't a multiple of 256.
+ TODO: Test this on the 315 series!
+ */
+ if((srcPitch % 256) || (srcPitch < 256)) {
+ if(((dstW * 1000) / srcW) < 125) dstW = tmpW = ((srcW * 125) / 1000) + 1;
+ }
+
+ I = 0;
+ pOverlay->IntBit = 0x01;
+ while(srcW >= tmpW) {
+ tmpW <<= 1;
+ I++;
+ }
+ pOverlay->wHPre = (CARD8)(I - 1);
+ dstW <<= (I - 1);
+ if((srcW % dstW))
+ pOverlay->HUSF = ((srcW - dstW) << 16) / dstW;
+ else
+ pOverlay->HUSF = 0x00;
+ }
+
+ if(dstH < OVERLAY_MIN_HEIGHT) dstH = OVERLAY_MIN_HEIGHT;
+ if(dstH == srcH) {
+ pOverlay->VUSF = 0x00;
+ pOverlay->IntBit |= 0x0A;
+ } else if(dstH > srcH) {
+ dstH += 0x02;
+ pOverlay->VUSF = (srcH << 16) / dstH;
+ pOverlay->IntBit |= 0x08;
+ } else {
+
+ I = srcH / dstH;
+ pOverlay->IntBit |= 0x02;
+
+ if(I < 2) {
+ pOverlay->VUSF = ((srcH - dstH) << 16) / dstH;
+ /* Needed for LCD-scaling modes */
+ if((flag) && (mult = (srcH / origdstH)) >= 2) {
+ pOverlay->pitch /= mult;
+ }
+ } else {
+#if 0
+ if(((pOverlay->bobEnable & 0x08) == 0x00) &&
+ (((srcPitch * I) >> 2) > 0xFFF)){
+ pOverlay->bobEnable |= 0x08;
+ srcPitch >>= 1;
+ }
+#endif
+ if(((srcPitch * I) >> 2) > 0xFFF) {
+ I = (0xFFF * 2 / srcPitch);
+ pOverlay->VUSF = 0xFFFF;
+ } else {
+ dstH = I * dstH;
+ if(srcH % dstH)
+ pOverlay->VUSF = ((srcH - dstH) << 16) / dstH;
+ else
+ pOverlay->VUSF = 0x00;
+ }
+ /* set video frame buffer offset */
+ pOverlay->pitch = (CARD16)(srcPitch * I);
+ }
+ }
+}
+
+static CARD16
+calc_line_buf_size(CARD32 srcW, CARD8 wHPre, CARD8 planar, SISUSBPortPrivPtr pPriv)
+{
+ CARD32 I;
+
+ if(planar) {
+
+ switch(wHPre & 0x07) {
+ case 3:
+ I = (srcW >> 8);
+ if(srcW & 0xff) I++;
+ I <<= 5;
+ break;
+ case 4:
+ I = (srcW >> 9);
+ if(srcW & 0x1ff) I++;
+ I <<= 6;
+ break;
+ case 5:
+ I = (srcW >> 10);
+ if(srcW & 0x3ff) I++;
+ I <<= 7;
+ break;
+ case 6:
+ if(pPriv->is340) {
+ I = (srcW >> 11);
+ if(srcW & 0x7ff) I++;
+ I <<= 8;
+ break;
+ } else {
+ return((CARD16)(255));
+ }
+ default:
+ I = (srcW >> 7);
+ if(srcW & 0x7f) I++;
+ I <<= 4;
+ break;
+ }
+
+ } else { /* packed */
+
+ I = (srcW >> 3);
+ if(srcW & 0x07) I++;
+
+ }
+
+ if(I <= 3) I = 4;
+
+ return((CARD16)(I - 1));
+}
+
+static __inline void
+calc_line_buf_size_1(SISUSBOverlayPtr pOverlay, SISUSBPortPrivPtr pPriv)
+{
+ pOverlay->lineBufSize =
+ calc_line_buf_size(pOverlay->srcW, pOverlay->wHPre, pOverlay->planar, pPriv);
+}
+
+static void
+merge_line_buf(SISUSBPtr pSiSUSB, SISUSBPortPrivPtr pPriv, Bool enable, short width, short limit)
+{
+ UChar misc1, misc2, mask = pPriv->linebufmask;
+
+ if(enable) { /* ----- enable linebuffer merge */
+
+ misc2 = 0x00;
+ misc1 = 0x04;
+ setvideoregmask(pSiSUSB, Index_VI_Control_Misc2, misc2, mask);
+ setvideoregmask(pSiSUSB, Index_VI_Control_Misc1, misc1, 0x04);
+
+ } else { /* ----- disable linebuffer merge */
+
+ setvideoregmask(pSiSUSB, Index_VI_Control_Misc2, 0x00, mask);
+ setvideoregmask(pSiSUSB, Index_VI_Control_Misc1, 0x00, 0x04);
+
+ }
+}
+
+static __inline void
+set_format(SISUSBPtr pSiSUSB, SISUSBOverlayPtr pOverlay)
+{
+ CARD8 fmt;
+
+ switch (pOverlay->pixelFormat){
+ case PIXEL_FMT_YV12:
+ case PIXEL_FMT_I420:
+ fmt = 0x0c;
+ break;
+ case PIXEL_FMT_YUY2:
+ fmt = 0x28;
+ break;
+ case PIXEL_FMT_UYVY:
+ fmt = 0x08;
+ break;
+ case PIXEL_FMT_YVYU:
+ fmt = 0x38;
+ break;
+ case PIXEL_FMT_NV12:
+ fmt = 0x4c;
+ break;
+ case PIXEL_FMT_NV21:
+ fmt = 0x5c;
+ break;
+ case PIXEL_FMT_RGB5: /* D[5:4] : 00 RGB555, 01 RGB 565 */
+ fmt = 0x00;
+ break;
+ case PIXEL_FMT_RGB6:
+ fmt = 0x10;
+ break;
+ default:
+ fmt = 0x00;
+ break;
+ }
+ setvideoregmask(pSiSUSB, Index_VI_Control_Misc0, fmt, 0xfc);
+}
+
+static __inline void
+set_colorkey(SISUSBPtr pSiSUSB, CARD32 colorkey)
+{
+ CARD8 r, g, b;
+
+ b = (CARD8)(colorkey & 0xFF);
+ g = (CARD8)((colorkey>>8) & 0xFF);
+ r = (CARD8)((colorkey>>16) & 0xFF);
+
+ setvideoreg(pSiSUSB, Index_VI_Overlay_ColorKey_Blue_Min ,(CARD8)b);
+ setvideoreg(pSiSUSB, Index_VI_Overlay_ColorKey_Green_Min ,(CARD8)g);
+ setvideoreg(pSiSUSB, Index_VI_Overlay_ColorKey_Red_Min ,(CARD8)r);
+
+ setvideoreg(pSiSUSB, Index_VI_Overlay_ColorKey_Blue_Max ,(CARD8)b);
+ setvideoreg(pSiSUSB, Index_VI_Overlay_ColorKey_Green_Max ,(CARD8)g);
+ setvideoreg(pSiSUSB, Index_VI_Overlay_ColorKey_Red_Max ,(CARD8)r);
+}
+
+static __inline void
+set_chromakey(SISUSBPtr pSiSUSB, CARD32 chromamin, CARD32 chromamax)
+{
+ CARD8 r1, g1, b1;
+ CARD8 r2, g2, b2;
+
+ b1 = (CARD8)(chromamin & 0xFF);
+ g1 = (CARD8)((chromamin>>8) & 0xFF);
+ r1 = (CARD8)((chromamin>>16) & 0xFF);
+ b2 = (CARD8)(chromamax & 0xFF);
+ g2 = (CARD8)((chromamax>>8) & 0xFF);
+ r2 = (CARD8)((chromamax>>16) & 0xFF);
+
+ setvideoreg(pSiSUSB, Index_VI_Overlay_ChromaKey_Blue_V_Min ,(CARD8)b1);
+ setvideoreg(pSiSUSB, Index_VI_Overlay_ChromaKey_Green_U_Min ,(CARD8)g1);
+ setvideoreg(pSiSUSB, Index_VI_Overlay_ChromaKey_Red_Y_Min ,(CARD8)r1);
+
+ setvideoreg(pSiSUSB, Index_VI_Overlay_ChromaKey_Blue_V_Max ,(CARD8)b2);
+ setvideoreg(pSiSUSB, Index_VI_Overlay_ChromaKey_Green_U_Max ,(CARD8)g2);
+ setvideoreg(pSiSUSB, Index_VI_Overlay_ChromaKey_Red_Y_Max ,(CARD8)r2);
+}
+
+static __inline void
+set_brightness(SISUSBPtr pSiSUSB, CARD8 brightness)
+{
+ setvideoreg(pSiSUSB, Index_VI_Brightness, brightness);
+}
+
+static __inline void
+set_contrast(SISUSBPtr pSiSUSB, CARD8 contrast)
+{
+ setvideoregmask(pSiSUSB, Index_VI_Contrast_Enh_Ctrl, contrast, 0x07);
+}
+
+/* 315 series and later only */
+static __inline void
+set_saturation(SISUSBPtr pSiSUSB, short saturation)
+{
+ CARD8 temp = 0;
+
+ if(saturation < 0) {
+ temp |= 0x88;
+ saturation = -saturation;
+ }
+ temp |= (saturation & 0x07);
+ temp |= ((saturation & 0x07) << 4);
+
+ setvideoreg(pSiSUSB, Index_VI_Saturation, temp);
+}
+
+/* 315 series and later only */
+static __inline void
+set_hue(SISUSBPtr pSiSUSB, CARD8 hue)
+{
+ setvideoregmask(pSiSUSB, Index_VI_Hue, (hue & 0x08) ? (hue ^ 0x07) : hue, 0x0F);
+}
+
+static __inline void
+set_disablegfx(SISUSBPtr pSiSUSB, Bool mybool, SISUSBOverlayPtr pOverlay)
+{
+ /* This is not supported on M65x, 65x (x>0) or later */
+ /* For CRT1 ONLY!!! */
+ setvideoregmask(pSiSUSB, Index_VI_Control_Misc2, mybool ? 0x04 : 0x00, 0x04);
+ if(mybool) pOverlay->keyOP = VI_ROP_Always;
+}
+
+static __inline void
+set_disablegfxlr(SISUSBPtr pSiSUSB, Bool mybool, SISUSBOverlayPtr pOverlay)
+{
+ setvideoregmask(pSiSUSB, Index_VI_Control_Misc1, mybool ? 0x01 : 0x00, 0x01);
+ if(mybool) pOverlay->keyOP = VI_ROP_Always;
+}
+
+static void
+set_overlay(SISUSBPtr pSiSUSB, SISUSBOverlayPtr pOverlay, SISUSBPortPrivPtr pPriv, int index, int iscrt2)
+{
+ CARD8 h_over=0, v_over=0;
+ CARD16 top, bottom, left, right, pitch=0;
+ CARD16 screenX, screenY;
+ CARD32 PSY;
+ int modeflags;
+
+ screenX = pOverlay->currentmode->HDisplay;
+ screenY = pOverlay->currentmode->VDisplay;
+ modeflags = pOverlay->currentmode->Flags;
+ top = pOverlay->dstBox.y1;
+ bottom = pOverlay->dstBox.y2;
+ left = pOverlay->dstBox.x1;
+ right = pOverlay->dstBox.x2;
+ pitch = pOverlay->pitch >> pPriv->shiftValue;
+
+ if(bottom > screenY) {
+ bottom = screenY;
+ }
+ if(right > screenX) {
+ right = screenX;
+ }
+
+ /* DoubleScan modes require Y coordinates * 2 */
+ if(modeflags & V_DBLSCAN) {
+ top <<= 1;
+ bottom <<= 1;
+ }
+ /* Interlace modes require Y coordinates / 2 */
+ if(modeflags & V_INTERLACE) {
+ top >>= 1;
+ bottom >>= 1;
+ }
+
+ h_over = (((left>>8) & 0x0f) | ((right>>4) & 0xf0));
+ v_over = (((top>>8) & 0x0f) | ((bottom>>4) & 0xf0));
+
+ /* set line buffer size */
+
+ setvideoreg(pSiSUSB, Index_VI_Line_Buffer_Size, (CARD8)pOverlay->lineBufSize);
+
+ /* set color key mode */
+ setvideoregmask(pSiSUSB, Index_VI_Key_Overlay_OP, pOverlay->keyOP, 0x0f);
+
+ /* Unlock address registers */
+ setvideoregmask(pSiSUSB, Index_VI_Control_Misc1, 0x20, 0x20);
+
+ /* set destination window position */
+ setvideoreg(pSiSUSB, Index_VI_Win_Hor_Disp_Start_Low, (CARD8)left);
+ setvideoreg(pSiSUSB, Index_VI_Win_Hor_Disp_End_Low, (CARD8)right);
+ setvideoreg(pSiSUSB, Index_VI_Win_Hor_Over, (CARD8)h_over);
+
+ setvideoreg(pSiSUSB, Index_VI_Win_Ver_Disp_Start_Low, (CARD8)top);
+ setvideoreg(pSiSUSB, Index_VI_Win_Ver_Disp_End_Low, (CARD8)bottom);
+ setvideoreg(pSiSUSB, Index_VI_Win_Ver_Over, (CARD8)v_over);
+
+ /* Set Y buf pitch */
+ setvideoreg(pSiSUSB, Index_VI_Disp_Y_Buf_Pitch_Low, (CARD8)(pitch));
+ setvideoregmask(pSiSUSB, Index_VI_Disp_Y_UV_Buf_Pitch_Middle, (CARD8)(pitch >> 8), 0x0f);
+
+ /* Set Y start address */
+ PSY = pOverlay->PSY;
+
+ setvideoreg(pSiSUSB, Index_VI_Disp_Y_Buf_Start_Low, (CARD8)(PSY));
+ setvideoreg(pSiSUSB, Index_VI_Disp_Y_Buf_Start_Middle, (CARD8)(PSY >> 8));
+ setvideoreg(pSiSUSB, Index_VI_Disp_Y_Buf_Start_High, (CARD8)(PSY >> 16));
+
+ /* overflow bits for Y plane */
+ setvideoreg(pSiSUSB, Index_VI_Disp_Y_Buf_Pitch_High, (CARD8)(pitch >> 12));
+ setvideoreg(pSiSUSB, Index_VI_Y_Buf_Start_Over, ((CARD8)(PSY >> 24) & 0x03));
+
+ /* Set U/V data if using planar formats */
+ if(pOverlay->planar) {
+
+ CARD32 PSU = pOverlay->PSU;
+ CARD32 PSV = pOverlay->PSV;
+
+ if(pOverlay->planar_shiftpitch) pitch >>= 1;
+
+ /* Set U/V pitch */
+ setvideoreg(pSiSUSB, Index_VI_Disp_UV_Buf_Pitch_Low, (CARD8)pitch);
+ setvideoregmask(pSiSUSB, Index_VI_Disp_Y_UV_Buf_Pitch_Middle, (CARD8)(pitch >> 4), 0xf0);
+
+ /* set U/V start address */
+ setvideoreg(pSiSUSB, Index_VI_U_Buf_Start_Low, (CARD8)PSU);
+ setvideoreg(pSiSUSB, Index_VI_U_Buf_Start_Middle,(CARD8)(PSU >> 8));
+ setvideoreg(pSiSUSB, Index_VI_U_Buf_Start_High, (CARD8)(PSU >> 16));
+
+ setvideoreg(pSiSUSB, Index_VI_V_Buf_Start_Low, (CARD8)PSV);
+ setvideoreg(pSiSUSB, Index_VI_V_Buf_Start_Middle,(CARD8)(PSV >> 8));
+ setvideoreg(pSiSUSB, Index_VI_V_Buf_Start_High, (CARD8)(PSV >> 16));
+
+ /* overflow bits */
+ setvideoreg(pSiSUSB, Index_VI_Disp_UV_Buf_Pitch_High, (CARD8)(pitch >> 12));
+ setvideoreg(pSiSUSB, Index_VI_U_Buf_Start_Over, ((CARD8)(PSU >> 24) & 0x03));
+ setvideoreg(pSiSUSB, Index_VI_V_Buf_Start_Over, ((CARD8)(PSV >> 24) & 0x03));
+
+
+ }
+
+ setvideoregmask(pSiSUSB, Index_VI_Control_Misc1, pOverlay->bobEnable, 0x1a);
+
+ /* Lock the address registers */
+ setvideoregmask(pSiSUSB, Index_VI_Control_Misc1, 0x00, 0x20);
+
+ /* set scale factor */
+ setvideoreg(pSiSUSB, Index_VI_Hor_Post_Up_Scale_Low, (CARD8)(pOverlay->HUSF));
+ setvideoreg(pSiSUSB, Index_VI_Hor_Post_Up_Scale_High,(CARD8)((pOverlay->HUSF) >> 8));
+ setvideoreg(pSiSUSB, Index_VI_Ver_Up_Scale_Low, (CARD8)(pOverlay->VUSF));
+ setvideoreg(pSiSUSB, Index_VI_Ver_Up_Scale_High, (CARD8)((pOverlay->VUSF) >> 8));
+
+ setvideoregmask(pSiSUSB, Index_VI_Scale_Control, (pOverlay->IntBit << 3) |
+ (pOverlay->wHPre), 0x7f);
+
+}
+#endif /* SIS_ENABLEXV */
+
+/* Overlay MUST NOT be switched off while beam is over it */
+#ifdef SIS_ENABLEXV
+static void
+close_overlay(SISUSBPtr pSiSUSB, SISUSBPortPrivPtr pPriv)
+{
+#if 0
+ int watchdog;
+#endif
+
+ if(!(pPriv->overlayStatus)) return;
+ pPriv->overlayStatus = FALSE;
+
+ setvideoregmask(pSiSUSB, Index_VI_Control_Misc2, 0x00, 0x05);
+ setvideoregmask(pSiSUSB, Index_VI_Control_Misc1, 0x00, 0x01);
+
+#if 0
+ watchdog = WATCHDOG_DELAY;
+ while((!vblank_active_CRT1(pSiSUSB, pPriv)) && --watchdog);
+ watchdog = WATCHDOG_DELAY;
+ while(vblank_active_CRT1(pSiSUSB, pPriv) && --watchdog);
+#endif
+ setvideoregmask(pSiSUSB, Index_VI_Control_Misc0, 0x00, 0x02);
+#if 0
+ watchdog = WATCHDOG_DELAY;
+ while((!vblank_active_CRT1(pSiSUSB, pPriv)) && --watchdog);
+ watchdog = WATCHDOG_DELAY;
+ while(vblank_active_CRT1(pSiSUSB, pPriv) && --watchdog);
+#endif
+
+}
+#endif
+
+#ifdef SIS_ENABLEXV
+static void
+SISUSBDisplayVideo(ScrnInfoPtr pScrn, SISUSBPortPrivPtr pPriv)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ short srcPitch = pPriv->srcPitch;
+ short height = pPriv->height;
+ UShort screenwidth;
+ SISUSBOverlayRec overlay;
+ int srcOffsetX = 0, srcOffsetY = 0;
+ int sx = 0, sy = 0;
+ int index = 0, iscrt2 = 0;
+
+ pPriv->NoOverlay = FALSE;
+
+ /* setup dispmode (MIRROR, SINGLEx) */
+ set_dispmode(pScrn, pPriv);
+
+ /* Check if overlay is supported with current mode */
+ if(!(pSiSUSB->MiscFlags & MISC_CRT1OVERLAY)) {
+ if(pPriv->overlayStatus) {
+ close_overlay(pSiSUSB, pPriv);
+ }
+ pPriv->NoOverlay = TRUE;
+ return;
+ }
+
+ memset(&overlay, 0, sizeof(overlay));
+
+ overlay.pixelFormat = pPriv->id;
+ overlay.pitch = overlay.origPitch = srcPitch;
+ if(pPriv->usechromakey) {
+ overlay.keyOP = (pPriv->insidechromakey) ? VI_ROP_ChromaKey : VI_ROP_NotChromaKey;
+ } else {
+ overlay.keyOP = VI_ROP_DestKey;
+ }
+
+ overlay.bobEnable = 0x00; /* Disable BOB de-interlacer */
+
+ overlay.currentmode = pSiSUSB->CurrentLayout.mode;
+ overlay.SCREENheight = overlay.currentmode->VDisplay;
+ screenwidth = overlay.currentmode->HDisplay;
+ overlay.dstBox.x1 = pPriv->drw_x - pScrn->frameX0;
+ overlay.dstBox.x2 = pPriv->drw_x + pPriv->drw_w - pScrn->frameX0;
+ overlay.dstBox.y1 = pPriv->drw_y - pScrn->frameY0;
+ overlay.dstBox.y2 = pPriv->drw_y + pPriv->drw_h - pScrn->frameY0;
+
+ /* Note: x2/y2 is actually real coordinate + 1 */
+
+ if((overlay.dstBox.x1 >= overlay.dstBox.x2) ||
+ (overlay.dstBox.y1 >= overlay.dstBox.y2)) {
+ return;
+ }
+
+ if((overlay.dstBox.x2 <= 0) || (overlay.dstBox.y2 <= 0)) {
+ return;
+ }
+
+ if((overlay.dstBox.x1 >= screenwidth) || (overlay.dstBox.y1 >= overlay.SCREENheight)) {
+ return;
+ }
+
+ if(overlay.dstBox.x1 < 0) {
+ srcOffsetX = pPriv->src_w * (-overlay.dstBox.x1) / pPriv->drw_w;
+ overlay.dstBox.x1 = 0;
+ }
+ if(overlay.dstBox.y1 < 0) {
+ srcOffsetY = pPriv->src_h * (-overlay.dstBox.y1) / pPriv->drw_h;
+ overlay.dstBox.y1 = 0;
+ }
+
+ if((overlay.dstBox.x1 >= overlay.dstBox.x2 - 2) ||
+ (overlay.dstBox.x1 >= screenwidth - 2) ||
+ (overlay.dstBox.y1 >= overlay.dstBox.y2)) {
+ return;
+ }
+
+ switch(pPriv->id) {
+
+ case PIXEL_FMT_YV12:
+ overlay.planar = 1;
+ overlay.planar_shiftpitch = 1;
+ sx = (pPriv->src_x + srcOffsetX) & ~7;
+ sy = (pPriv->src_y + srcOffsetY) & ~1;
+ overlay.PSY = pPriv->bufAddr[pPriv->currentBuf] + sx + sy*srcPitch;
+ overlay.PSV = pPriv->bufAddr[pPriv->currentBuf] + height*srcPitch + ((sx + sy*srcPitch/2) >> 1);
+ overlay.PSU = pPriv->bufAddr[pPriv->currentBuf] + height*srcPitch*5/4 + ((sx + sy*srcPitch/2) >> 1);
+ overlay.PSY >>= pPriv->shiftValue;
+ overlay.PSV >>= pPriv->shiftValue;
+ overlay.PSU >>= pPriv->shiftValue;
+ break;
+
+ case PIXEL_FMT_I420:
+ overlay.planar = 1;
+ overlay.planar_shiftpitch = 1;
+ sx = (pPriv->src_x + srcOffsetX) & ~7;
+ sy = (pPriv->src_y + srcOffsetY) & ~1;
+ overlay.PSY = pPriv->bufAddr[pPriv->currentBuf] + sx + sy*srcPitch;
+ overlay.PSV = pPriv->bufAddr[pPriv->currentBuf] + height*srcPitch*5/4 + ((sx + sy*srcPitch/2) >> 1);
+ overlay.PSU = pPriv->bufAddr[pPriv->currentBuf] + height*srcPitch + ((sx + sy*srcPitch/2) >> 1);
+ overlay.PSY >>= pPriv->shiftValue;
+ overlay.PSV >>= pPriv->shiftValue;
+ overlay.PSU >>= pPriv->shiftValue;
+ break;
+
+ case PIXEL_FMT_NV12:
+ case PIXEL_FMT_NV21:
+ overlay.planar = 1;
+ overlay.planar_shiftpitch = 0;
+ sx = (pPriv->src_x + srcOffsetX) & ~7;
+ sy = (pPriv->src_y + srcOffsetY) & ~1;
+ overlay.PSY = pPriv->bufAddr[pPriv->currentBuf] + sx + sy*srcPitch;
+ overlay.PSV = pPriv->bufAddr[pPriv->currentBuf] + height*srcPitch + ((sx + sy*srcPitch/2) >> 1);
+ overlay.PSY >>= pPriv->shiftValue;
+ overlay.PSV >>= pPriv->shiftValue;
+ overlay.PSU = overlay.PSV;
+ break;
+
+ case PIXEL_FMT_YUY2:
+ case PIXEL_FMT_UYVY:
+ case PIXEL_FMT_YVYU:
+ case PIXEL_FMT_RGB6:
+ case PIXEL_FMT_RGB5:
+ default:
+ overlay.planar = 0;
+ sx = (pPriv->src_x + srcOffsetX) & ~1;
+ sy = (pPriv->src_y + srcOffsetY);
+ overlay.PSY = (pPriv->bufAddr[pPriv->currentBuf] + sx*2 + sy*srcPitch);
+ overlay.PSY >>= pPriv->shiftValue;
+ break;
+ }
+
+ /* Some clipping checks */
+ overlay.srcW = pPriv->src_w - (sx - pPriv->src_x);
+ overlay.srcH = pPriv->src_h - (sy - pPriv->src_y);
+ if( (pPriv->oldx1 != overlay.dstBox.x1) ||
+ (pPriv->oldx2 != overlay.dstBox.x2) ||
+ (pPriv->oldy1 != overlay.dstBox.y1) ||
+ (pPriv->oldy2 != overlay.dstBox.y2) ) {
+ pPriv->mustwait = 1;
+ pPriv->oldx1 = overlay.dstBox.x1; pPriv->oldx2 = overlay.dstBox.x2;
+ pPriv->oldy1 = overlay.dstBox.y1; pPriv->oldy2 = overlay.dstBox.y2;
+ }
+
+ /* Loop head */
+ /* Note: index can only be 1 for CRT2, ie overlay 1
+ * is only used for CRT2.
+ */
+
+ index = 0; iscrt2 = 0;
+ overlay.VBlankActiveFunc = vblank_active_CRT1;
+
+ /* set display mode SR06,32 (CRT1, CRT2 or mirror) */
+ set_disptype_regs(pScrn, pPriv);
+
+ /* set (not only calc) merge line buffer */
+ merge_line_buf(pSiSUSB, pPriv, (overlay.srcW > pPriv->linebufMergeLimit), overlay.srcW,
+ pPriv->linebufMergeLimit);
+
+ /* calculate (not set!) line buffer length */
+ calc_line_buf_size_1(&overlay, pPriv);
+
+ setvideoregmask(pSiSUSB, Index_VI_Control_Misc3, 0x03, 0x03);
+
+ /* calculate scale factor */
+ calc_scale_factor(&overlay, pScrn, pPriv, index, iscrt2);
+
+ /* Select overlay 0 (used for CRT1/or CRT2) or overlay 1 (used for CRT2 only) */
+ setvideoregmask(pSiSUSB, Index_VI_Control_Misc2, index, 0x01);
+
+ /* set format (before color and chroma keys) */
+ set_format(pSiSUSB, &overlay);
+
+ /* set color key */
+ set_colorkey(pSiSUSB, pPriv->colorKey);
+
+ if(pPriv->usechromakey) {
+ set_chromakey(pSiSUSB, pPriv->chromamin, pPriv->chromamax);
+ }
+
+ /* set brightness, contrast, hue, saturation */
+ set_brightness(pSiSUSB, pPriv->brightness);
+ set_contrast(pSiSUSB, pPriv->contrast);
+ set_hue(pSiSUSB, pPriv->hue);
+ set_saturation(pSiSUSB, pPriv->saturation);
+
+ /* enable/disable graphics display around overlay
+ * (Since disabled overlays don't get treated in this
+ * loop, we omit respective checks here)
+ */
+ if(!iscrt2) set_disablegfx(pSiSUSB, pPriv->disablegfx, &overlay);
+ else if(!pPriv->hasTwoOverlays) {
+ set_disablegfx(pSiSUSB, FALSE, &overlay);
+ }
+ set_disablegfxlr(pSiSUSB, pPriv->disablegfxlr, &overlay);
+
+ /* set remaining overlay parameters */
+ set_overlay(pSiSUSB, &overlay, pPriv, index, iscrt2);
+
+ /* enable overlay */
+ setvideoregmask (pSiSUSB, Index_VI_Control_Misc0, 0x02, 0x02);
+
+ /* Trigger register copy */
+ setvideoregmask(pSiSUSB, Index_VI_Control_Misc3, 0x03, 0x03);
+
+ pPriv->mustwait = 0;
+ pPriv->overlayStatus = TRUE;
+}
+#endif
+
+#ifdef SIS_ENABLEXV
+static FBLinearPtr
+SISUSBAllocateOverlayMemory(
+ 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, 8,
+ NULL, NULL, NULL);
+
+ if(!new_linear) {
+ int max_size;
+
+ xf86QueryLargestOffscreenLinear(pScreen, &max_size, 8,
+ PRIORITY_EXTREME);
+
+ if(max_size < size) return NULL;
+
+ xf86PurgeUnlockedOffscreenAreas(pScreen);
+ new_linear = xf86AllocateOffscreenLinear(pScreen, size, 8,
+ NULL, NULL, NULL);
+ }
+ if(!new_linear)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Xv: Failed to allocate %d pixels of linear video memory\n", size);
+#ifdef TWDEBUG
+ else
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Xv: Allocated %d pixels of linear video memory\n", size);
+#endif
+
+ return new_linear;
+}
+
+static void
+SISUSBFreeOverlayMemory(ScrnInfoPtr pScrn)
+{
+ SISUSBPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn);
+
+ if(pPriv->linear) {
+ xf86FreeOffscreenLinear(pPriv->linear);
+ pPriv->linear = NULL;
+ }
+}
+#endif
+
+static void
+SISUSBStopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown)
+{
+#ifdef SIS_ENABLEXV
+ SISUSBPortPrivPtr pPriv = (SISUSBPortPrivPtr)data;
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+
+ if(pPriv->grabbedByV4L) return;
+
+ REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
+
+ if(shutdown) {
+ if(pPriv->videoStatus & CLIENT_VIDEO_ON) {
+ close_overlay(pSiSUSB, pPriv);
+ pPriv->mustwait = 1;
+ }
+ SISUSBFreeOverlayMemory(pScrn);
+ pPriv->videoStatus = 0;
+ } else {
+ if(pPriv->videoStatus & CLIENT_VIDEO_ON) {
+ UpdateCurrentTime();
+ pPriv->offTime = currentTime.milliseconds + OFF_DELAY;
+ pPriv->videoStatus = OFF_TIMER | CLIENT_VIDEO_ON;
+ pSiSUSB->VideoTimerCallback = SISUSBVideoTimerCallback;
+ }
+ }
+#endif
+}
+
+#ifdef SIS_ENABLEXV
+static int
+SISUSBPutImage(
+ 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, UChar *buf,
+ short width, short height,
+ Bool sync,
+ RegionPtr clipBoxes, pointer data,
+ DrawablePtr pDraw
+){
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ SISUSBPortPrivPtr pPriv = (SISUSBPortPrivPtr)data;
+ int totalSize = 0, depth = pSiSUSB->CurrentLayout.bitsPerPixel >> 3;
+
+ if(pPriv->grabbedByV4L) return Success;
+
+ pPriv->drw_x = drw_x;
+ pPriv->drw_y = drw_y;
+ pPriv->drw_w = drw_w;
+ pPriv->drw_h = drw_h;
+ pPriv->src_x = src_x;
+ pPriv->src_y = src_y;
+ pPriv->src_w = src_w;
+ pPriv->src_h = src_h;
+ pPriv->id = id;
+ pPriv->height = height;
+
+ /* Pixel formats:
+ 1. YU12: 3 planes: H V
+ Y sample period 1 1 (8 bit per pixel)
+ V sample period 2 2 (8 bit per pixel, subsampled)
+ U sample period 2 2 (8 bit per pixel, subsampled)
+
+ Y plane is fully sampled (width*height), U and V planes
+ are sampled in 2x2 blocks, hence a group of 4 pixels requires
+ 4 + 1 + 1 = 6 bytes. The data is planar, ie in single planes
+ for Y, U and V.
+ 2. UYVY: 3 planes: H V
+ Y sample period 1 1 (8 bit per pixel)
+ V sample period 2 1 (8 bit per pixel, subsampled)
+ U sample period 2 1 (8 bit per pixel, subsampled)
+ Y plane is fully sampled (width*height), U and V planes
+ are sampled in 2x1 blocks, hence a group of 4 pixels requires
+ 4 + 2 + 2 = 8 bytes. The data is bit packed, there are no separate
+ Y, U or V planes.
+ Bit order: U0 Y0 V0 Y1 U2 Y2 V2 Y3 ...
+ 3. I420: Like YU12, but planes U and V are in reverse order.
+ 4. YUY2: Like UYVY, but order is
+ Y0 U0 Y1 V0 Y2 U2 Y3 V2 ...
+ 5. YVYU: Like YUY2, but order is
+ Y0 V0 Y1 U0 Y2 V2 Y3 U2 ...
+ 6. NV12, NV21: 2 planes H V
+ Y sample period 1 1 (8 bit per pixel)
+ V sample period 2 1 (8 bit per pixel, subsampled)
+ U sample period 2 1 (8 bit per pixel, subsampled)
+ Y plane is fully samples (width*height), U and V planes are
+ interleaved in memory (one byte U, one byte V for NV12, NV21
+ other way round) and sampled in 2x1 blocks. Otherwise such
+ as all other planar formats.
+ */
+
+ switch(id){
+ case PIXEL_FMT_YV12:
+ case PIXEL_FMT_I420:
+ case PIXEL_FMT_NV12:
+ case PIXEL_FMT_NV21:
+ pPriv->srcPitch = (width + 7) & ~7;
+ /* Size = width * height * 3 / 2 */
+ totalSize = (pPriv->srcPitch * height * 3) >> 1; /* Verified */
+ break;
+ case PIXEL_FMT_YUY2:
+ case PIXEL_FMT_UYVY:
+ case PIXEL_FMT_YVYU:
+ case PIXEL_FMT_RGB6:
+ case PIXEL_FMT_RGB5:
+ default:
+ pPriv->srcPitch = ((width << 1) + 3) & ~3; /* Verified */
+ /* Size = width * 2 * height */
+ totalSize = pPriv->srcPitch * height;
+ }
+
+ /* make it a multiple of 16 to simplify to copy loop */
+ totalSize += 15;
+ totalSize &= ~15; /* in bytes */
+
+ /* allocate memory (we do doublebuffering) - size is in pixels! */
+ if(!(pPriv->linear = SISUSBAllocateOverlayMemory(pScrn, pPriv->linear,
+ ((totalSize + depth - 1) / depth) << 1)))
+ return BadAlloc;
+
+ /* fixup pointers */
+ pPriv->bufAddr[0] = (pPriv->linear->offset * depth);
+
+ pPriv->bufAddr[1] = pPriv->bufAddr[0] + totalSize;
+
+ /* copy data */
+ SiSUSBMemCopyToVideoRam(pSiSUSB, pSiSUSB->FbBase + pPriv->bufAddr[pPriv->currentBuf], buf, totalSize);
+
+ SISUSBDisplayVideo(pScrn, pPriv);
+
+ /* update cliplist */
+ if(pPriv->autopaintColorKey &&
+ (pPriv->grabbedByV4L ||
+#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,3,0)
+ (!RegionsEqual(&pPriv->clip, clipBoxes)) ||
+#else
+ (!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) ||
+#endif
+ (pPriv->PrevOverlay != pPriv->NoOverlay))) {
+ /* We always paint the colorkey for V4L */
+ if(!pPriv->grabbedByV4L) {
+ REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
+ }
+ /* draw these */
+ pPriv->PrevOverlay = pPriv->NoOverlay;
+
+ if(!pSiSUSB->disablecolorkeycurrent) {
+ xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes);
+ }
+
+ }
+
+ pPriv->currentBuf ^= 1;
+
+ pPriv->videoStatus = CLIENT_VIDEO_ON;
+
+ pSiSUSB->VideoTimerCallback = SISUSBVideoTimerCallback;
+
+ return Success;
+}
+#endif
+
+static int
+SISUSBQueryImageAttributes(
+ ScrnInfoPtr pScrn,
+ int id,
+ UShort *w, UShort *h,
+ int *pitches, int *offsets
+){
+ int pitchY, pitchUV;
+ int size, sizeY, sizeUV;
+
+ if(*w < IMAGE_MIN_WIDTH) *w = IMAGE_MIN_WIDTH;
+ if(*h < IMAGE_MIN_HEIGHT) *h = IMAGE_MIN_HEIGHT;
+
+ if(*w > DummyEncoding.width) *w = DummyEncoding.width;
+ if(*h > DummyEncoding.height) *h = DummyEncoding.height;
+
+ switch(id) {
+ case PIXEL_FMT_YV12:
+ case PIXEL_FMT_I420:
+ *w = (*w + 7) & ~7;
+ *h = (*h + 1) & ~1;
+ pitchY = *w;
+ pitchUV = *w >> 1;
+ if(pitches) {
+ pitches[0] = pitchY;
+ pitches[1] = pitches[2] = pitchUV;
+ }
+ sizeY = pitchY * (*h);
+ sizeUV = pitchUV * ((*h) >> 1);
+ if(offsets) {
+ offsets[0] = 0;
+ offsets[1] = sizeY;
+ offsets[2] = sizeY + sizeUV;
+ }
+ size = sizeY + (sizeUV << 1);
+ break;
+ case PIXEL_FMT_NV12:
+ case PIXEL_FMT_NV21:
+ *w = (*w + 7) & ~7;
+ *h = (*h + 1) & ~1;
+ pitchY = *w;
+ pitchUV = *w;
+ if(pitches) {
+ pitches[0] = pitchY;
+ pitches[1] = pitchUV;
+ }
+ sizeY = pitchY * (*h);
+ sizeUV = pitchUV * ((*h) >> 1);
+ if(offsets) {
+ offsets[0] = 0;
+ offsets[1] = sizeY;
+ }
+ size = sizeY + (sizeUV << 1);
+ break;
+ case PIXEL_FMT_YUY2:
+ case PIXEL_FMT_UYVY:
+ case PIXEL_FMT_YVYU:
+ case PIXEL_FMT_RGB6:
+ case PIXEL_FMT_RGB5:
+ default:
+ *w = (*w + 1) & ~1;
+ pitchY = *w << 1;
+ if(pitches) pitches[0] = pitchY;
+ if(offsets) offsets[0] = 0;
+ size = pitchY * (*h);
+ break;
+ }
+
+ return size;
+}
+
+/*****************************************************************/
+/* OFFSCREEN SURFACES */
+/*****************************************************************/
+
+#ifdef SIS_ENABLEXV
+static int
+SISUSBAllocSurface(
+ ScrnInfoPtr pScrn,
+ int id,
+ UShort w,
+ UShort h,
+ XF86SurfacePtr surface
+)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ SISUSBPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn);
+ int size, depth;
+
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Xv: SISUSBAllocSurface called\n");
+#endif
+
+ if((w < IMAGE_MIN_WIDTH) || (h < IMAGE_MIN_HEIGHT))
+ return BadValue;
+ if((w > DummyEncoding.width) || (h > DummyEncoding.height))
+ return BadValue;
+
+ if(pPriv->grabbedByV4L)
+ return BadAlloc;
+
+ depth = pSiSUSB->CurrentLayout.bitsPerPixel >> 3;
+ w = (w + 1) & ~1;
+ pPriv->pitch = ((w << 1) + 63) & ~63; /* Only packed pixel modes supported */
+ size = h * pPriv->pitch;
+ pPriv->linear = SISUSBAllocateOverlayMemory(pScrn, pPriv->linear, ((size + depth - 1) / depth));
+
+ if(!pPriv->linear)
+ return BadAlloc;
+
+ pPriv->offset = pPriv->linear->offset * depth;
+
+ surface->width = w;
+ surface->height = h;
+ surface->pScrn = pScrn;
+ surface->id = id;
+ surface->pitches = &pPriv->pitch;
+ surface->offsets = &pPriv->offset;
+ surface->devPrivate.ptr = (pointer)pPriv;
+
+ close_overlay(pSiSUSB, pPriv);
+ pPriv->videoStatus = 0;
+ REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
+ pSiSUSB->VideoTimerCallback = NULL;
+ pPriv->grabbedByV4L = TRUE;
+ return Success;
+}
+
+static int
+SISUSBStopSurface(XF86SurfacePtr surface)
+{
+ SISUSBPortPrivPtr pPriv = (SISUSBPortPrivPtr)(surface->devPrivate.ptr);
+ SISUSBPtr pSiSUSB = SISUSBPTR(surface->pScrn);
+
+ if(pPriv->grabbedByV4L && pPriv->videoStatus) {
+ close_overlay(pSiSUSB, pPriv);
+ pPriv->mustwait = 1;
+ pPriv->videoStatus = 0;
+ }
+ return Success;
+}
+
+static int
+SISUSBFreeSurface(XF86SurfacePtr surface)
+{
+ SISUSBPortPrivPtr pPriv = (SISUSBPortPrivPtr)(surface->devPrivate.ptr);
+
+ if(pPriv->grabbedByV4L) {
+ SISUSBStopSurface(surface);
+ SISUSBFreeOverlayMemory(surface->pScrn);
+ pPriv->grabbedByV4L = FALSE;
+ }
+ return Success;
+}
+
+static int
+SISUSBGetSurfaceAttribute(
+ ScrnInfoPtr pScrn,
+ Atom attribute,
+ INT32 *value
+)
+{
+ SISUSBPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn);
+
+ return SISUSBGetPortAttribute(pScrn, attribute, value, (pointer)pPriv);
+}
+
+static int
+SISUSBSetSurfaceAttribute(
+ ScrnInfoPtr pScrn,
+ Atom attribute,
+ INT32 value
+)
+{
+ SISUSBPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn);;
+
+ return SISUSBSetPortAttribute(pScrn, attribute, value, (pointer)pPriv);
+}
+
+static int
+SISUSBDisplaySurface(
+ 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
+)
+{
+ ScrnInfoPtr pScrn = surface->pScrn;
+ SISUSBPortPrivPtr pPriv = (SISUSBPortPrivPtr)(surface->devPrivate.ptr);
+
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Xv: DisplaySurface called\n");
+#endif
+
+ if(!pPriv->grabbedByV4L) return Success;
+
+ pPriv->drw_x = drw_x;
+ pPriv->drw_y = drw_y;
+ pPriv->drw_w = drw_w;
+ pPriv->drw_h = drw_h;
+ pPriv->src_x = src_x;
+ pPriv->src_y = src_y;
+ pPriv->src_w = src_w;
+ pPriv->src_h = src_h;
+ pPriv->id = surface->id;
+ pPriv->height = surface->height;
+ pPriv->bufAddr[0] = surface->offsets[0];
+ pPriv->currentBuf = 0;
+ pPriv->srcPitch = surface->pitches[0];
+
+ SISUSBDisplayVideo(pScrn, pPriv);
+
+ if(pPriv->autopaintColorKey) {
+ xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes);
+ }
+
+ pPriv->videoStatus = CLIENT_VIDEO_ON;
+
+ return Success;
+}
+
+#define NUMOFFSCRIMAGES_300 4
+#define NUMOFFSCRIMAGES_315 5
+
+static XF86OffscreenImageRec SISUSBOffscreenImages[NUMOFFSCRIMAGES_315] =
+{
+ {
+ &SISUSBImages[0], /* YUV2 */
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT,
+ SISUSBAllocSurface,
+ SISUSBFreeSurface,
+ SISUSBDisplaySurface,
+ SISUSBStopSurface,
+ SISUSBGetSurfaceAttribute,
+ SISUSBSetSurfaceAttribute,
+ 0, 0, /* Rest will be filled in */
+ 0,
+ NULL
+ },
+ {
+ &SISUSBImages[2], /* UYVY */
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT,
+ SISUSBAllocSurface,
+ SISUSBFreeSurface,
+ SISUSBDisplaySurface,
+ SISUSBStopSurface,
+ SISUSBGetSurfaceAttribute,
+ SISUSBSetSurfaceAttribute,
+ 0, 0, /* Rest will be filled in */
+ 0,
+ NULL
+ }
+ ,
+ {
+ &SISUSBImages[4], /* RV15 */
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT,
+ SISUSBAllocSurface,
+ SISUSBFreeSurface,
+ SISUSBDisplaySurface,
+ SISUSBStopSurface,
+ SISUSBGetSurfaceAttribute,
+ SISUSBSetSurfaceAttribute,
+ 0, 0, /* Rest will be filled in */
+ 0,
+ NULL
+ },
+ {
+ &SISUSBImages[5], /* RV16 */
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT,
+ SISUSBAllocSurface,
+ SISUSBFreeSurface,
+ SISUSBDisplaySurface,
+ SISUSBStopSurface,
+ SISUSBGetSurfaceAttribute,
+ SISUSBSetSurfaceAttribute,
+ 0, 0, /* Rest will be filled in */
+ 0,
+ NULL
+ },
+ {
+ &SISUSBImages[6], /* YVYU */
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT,
+ SISUSBAllocSurface,
+ SISUSBFreeSurface,
+ SISUSBDisplaySurface,
+ SISUSBStopSurface,
+ SISUSBGetSurfaceAttribute,
+ SISUSBSetSurfaceAttribute,
+ 0, 0, /* Rest will be filled in */
+ 0,
+ NULL
+ }
+};
+
+static void
+SISUSBInitOffscreenImages(ScreenPtr pScreen)
+{
+ int i, num;
+
+ num = NUMOFFSCRIMAGES_315;
+
+ for(i = 0; i < num; i++) {
+ SISUSBOffscreenImages[i].max_width = DummyEncoding.width;
+ SISUSBOffscreenImages[i].max_height = DummyEncoding.height;
+ SISUSBOffscreenImages[i].attributes = &SISUSBAttributes_315[0];
+ SISUSBOffscreenImages[i].num_attributes = SiSUSBCountAttributes(&SISUSBAttributes_315[0]);
+ }
+ xf86XVRegisterOffscreenImages(pScreen, SISUSBOffscreenImages, num);
+}
+#endif
+
+/*****************************************/
+/* TIMER CALLBACK */
+/*****************************************/
+
+#ifdef SIS_ENABLEXV
+static void
+SISUSBVideoTimerCallback(ScrnInfoPtr pScrn, Time now)
+{
+ SISUSBPtr pSiSUSB = SISUSBPTR(pScrn);
+ SISUSBPortPrivPtr pPriv = NULL;
+ UChar sridx, cridx;
+ Bool setcallback = FALSE;
+
+ if(!pScrn->vtSema) return;
+
+ if(pSiSUSB->adaptor) {
+ pPriv = GET_PORT_PRIVATE(pScrn);
+ if(!pPriv->videoStatus) pPriv = NULL;
+ }
+
+ if(pPriv) {
+ if(pPriv->videoStatus & TIMER_MASK) {
+ if(pPriv->videoStatus & OFF_TIMER) {
+ setcallback = TRUE;
+ if(pPriv->offTime < now) {
+ /* Turn off the overlay */
+ sridx = inSISREG(pSiSUSB, SISSR); cridx = inSISREG(pSiSUSB, SISCR);
+ close_overlay(pSiSUSB, pPriv);
+ outSISREG(pSiSUSB, SISSR, sridx); outSISREG(pSiSUSB, SISCR, cridx);
+ pPriv->mustwait = 1;
+ pPriv->videoStatus = FREE_TIMER;
+ pPriv->freeTime = now + FREE_DELAY;
+ }
+ } else if(pPriv->videoStatus & FREE_TIMER) {
+ if(pPriv->freeTime < now) {
+ SISUSBFreeOverlayMemory(pScrn);
+ pPriv->mustwait = 1;
+ pPriv->videoStatus = 0;
+ } else {
+ setcallback = TRUE;
+ }
+ }
+ }
+ }
+
+ pSiSUSB->VideoTimerCallback = (setcallback) ? SISUSBVideoTimerCallback : NULL;
+}
+#endif
+
+#else /* SIS_GLOBAL_ENABLEXV */
+
+ int i;
+
+#endif /* SIS_GLOBAL_ENABLEXV */
diff --git a/driver/xf86-video-sisusb/src/sisusb_video.h b/driver/xf86-video-sisusb/src/sisusb_video.h
new file mode 100644
index 000000000..90b09b42f
--- /dev/null
+++ b/driver/xf86-video-sisusb/src/sisusb_video.h
@@ -0,0 +1,404 @@
+/* $XFree86$ */
+/* $XdotOrg: driver/xf86-video-sisusb/src/sisusb_video.h,v 1.3 2005/07/09 02:50:34 twini Exp $ */
+/*
+ * Xv driver for SiS 315 USB
+ *
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1) Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2) Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3) The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
+
+#ifndef _SISUSB_VIDEO_H_
+#define _SISUSB_VIDEO_H_
+
+#include "sisusb_videostr.h"
+
+static XF86VideoAdaptorPtr SISUSBSetupImageVideo(ScreenPtr);
+static int SISUSBSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer);
+static int SISUSBGetPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer);
+static void SISUSBQueryBestSize(ScrnInfoPtr, Bool, short, short, short,
+ short, unsigned int *,unsigned int *, pointer);
+static int SISUSBQueryImageAttributes(ScrnInfoPtr,
+ int, UShort *, UShort *, int *, int *);
+static void SISUSBStopVideo(ScrnInfoPtr, pointer, Bool);
+void SISUSBSetPortDefaults(ScrnInfoPtr pScrn, SISUSBPortPrivPtr pPriv);
+#ifdef SIS_ENABLEXV
+static int SISUSBPutImage( ScrnInfoPtr,
+ short, short, short, short, short, short, short, short,
+ int, UChar *, short, short, Bool, RegionPtr, pointer);
+static void SISUSBVideoTimerCallback(ScrnInfoPtr pScrn, Time now);
+static void SISUSBInitOffscreenImages(ScreenPtr pScrn);
+static FBLinearPtr SISUSBAllocateOverlayMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, int size);
+void SiSUSBUpdateXvGamma(SISUSBPtr pSiSUSB, SISUSBPortPrivPtr pPriv);
+#endif
+
+#ifdef XV_SD_DEPRECATED
+extern int SISUSBSetPortUtilAttribute(ScrnInfoPtr pScrn, Atom attribute,
+ INT32 value, SISUSBPortPrivPtr pPriv);
+extern int SISUSBGetPortUtilAttribute(ScrnInfoPtr pScrn, Atom attribute,
+ INT32 *value, SISUSBPortPrivPtr pPriv);
+#endif
+
+#define OFF_DELAY 200 /* milliseconds */
+#define FREE_DELAY 30000
+
+#define OFF_TIMER 0x01
+#define FREE_TIMER 0x02
+#define CLIENT_VIDEO_ON 0x04
+
+#define TIMER_MASK (OFF_TIMER | FREE_TIMER)
+
+#define WATCHDOG_DELAY 200000 /* Watchdog counter for Vertical Restrace waiting */
+
+#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
+
+#define IMAGE_MIN_WIDTH 32 /* Minimum and maximum source image sizes */
+#define IMAGE_MIN_HEIGHT 24
+#define IMAGE_MAX_WIDTH_315 1920
+#define IMAGE_MAX_HEIGHT_315 1080
+#define IMAGE_MAX_WIDTH_340 1920 /* ? */
+
+#define OVERLAY_MIN_WIDTH 32 /* Minimum overlay sizes */
+#define OVERLAY_MIN_HEIGHT 24
+
+#define DISPMODE_SINGLE1 0x1 /* CRT1 only */
+#define DISPMODE_SINGLE2 0x2 /* CRT2 only */
+#define DISPMODE_MIRROR 0x4 /* CRT1 + CRT2 MIRROR (see note below) */
+
+#define LINEBUFLIMIT1 384 /* Limits at which line buffers must be merged */
+#define LINEBUFLIMIT2 720
+#define LINEBUFLIMIT3 576
+#define LINEBUFLIMIT4 1280 /* 340 */
+
+#define NUM_FORMATS 3
+
+static XF86VideoFormatRec SISUSBFormats[NUM_FORMATS] =
+{
+ { 8, PseudoColor},
+ {16, TrueColor},
+ {24, TrueColor}
+};
+
+static char sisxvcolorkey[] = "XV_COLORKEY";
+static char sisxvbrightness[] = "XV_BRIGHTNESS";
+static char sisxvcontrast[] = "XV_CONTRAST";
+static char sisxvsaturation[] = "XV_SATURATION";
+static char sisxvhue[] = "XV_HUE";
+static char sisxvautopaintcolorkey[] = "XV_AUTOPAINT_COLORKEY";
+static char sisxvsetdefaults[] = "XV_SET_DEFAULTS";
+static char sisxvswitchcrt[] = "XV_SWITCHCRT";
+static char sisxvtvxposition[] = "XV_TVXPOSITION";
+static char sisxvtvyposition[] = "XV_TVYPOSITION";
+static char sisxvgammared[] = "XV_GAMMA_RED";
+static char sisxvgammagreen[] = "XV_GAMMA_GREEN";
+static char sisxvgammablue[] = "XV_GAMMA_BLUE";
+static char sisxvdisablegfx[] = "XV_DISABLE_GRAPHICS";
+static char sisxvdisablegfxlr[] = "XV_DISABLE_GRAPHICS_LR";
+static char sisxvdisablecolorkey[] = "XV_DISABLE_COLORKEY";
+static char sisxvusechromakey[] = "XV_USE_CHROMAKEY";
+static char sisxvinsidechromakey[] = "XV_INSIDE_CHROMAKEY";
+static char sisxvyuvchromakey[] = "XV_YUV_CHROMAKEY";
+static char sisxvchromamin[] = "XV_CHROMAMIN";
+static char sisxvchromamax[] = "XV_CHROMAMAX";
+#ifdef XV_SD_DEPRECATED
+static char sisxvqueryvbflags[] = "XV_QUERYVBFLAGS";
+static char sisxvsdgetdriverversion[] = "XV_SD_GETDRIVERVERSION";
+static char sisxvsdgethardwareinfo[] = "XV_SD_GETHARDWAREINFO";
+static char sisxvsdgetbusid[] = "XV_SD_GETBUSID";
+static char sisxvsdqueryvbflagsversion[] = "XV_SD_QUERYVBFLAGSVERSION";
+static char sisxvsdgetsdflags[] = "XV_SD_GETSDFLAGS";
+static char sisxvsdgetsdflags2[] = "XV_SD_GETSDFLAGS2";
+static char sisxvsdunlocksisdirect[] = "XV_SD_UNLOCKSISDIRECT";
+static char sisxvsdsetvbflags[] = "XV_SD_SETVBFLAGS";
+static char sisxvsdquerydetecteddevices[] = "XV_SD_QUERYDETECTEDDEVICES";
+static char sisxvsdcrt1status[] = "XV_SD_CRT1STATUS";
+static char sisxvsdcheckmodeindexforcrt2[] = "XV_SD_CHECKMODEINDEXFORCRT2";
+static char sisxvsdresultcheckmodeindexforcrt2[] = "XV_SD_RESULTCHECKMODEINDEXFORCRT2";
+static char sisxvsdredetectcrt2[] = "XV_SD_REDETECTCRT2DEVICES";
+static char sisxvsdsisantiflicker[] = "XV_SD_SISANTIFLICKER";
+static char sisxvsdsissaturation[] = "XV_SD_SISSATURATION";
+static char sisxvsdsisedgeenhance[] = "XV_SD_SISEDGEENHANCE";
+static char sisxvsdsiscolcalibf[] = "XV_SD_SISCOLCALIBF";
+static char sisxvsdsiscolcalibc[] = "XV_SD_SISCOLCALIBC";
+static char sisxvsdsiscfilter[] = "XV_SD_SISCFILTER";
+static char sisxvsdsisyfilter[] = "XV_SD_SISYFILTER";
+static char sisxvsdchcontrast[] = "XV_SD_CHCONTRAST";
+static char sisxvsdchtextenhance[] = "XV_SD_CHTEXTENHANCE";
+static char sisxvsdchchromaflickerfilter[] = "XV_SD_CHCHROMAFLICKERFILTER";
+static char sisxvsdchlumaflickerfilter[] = "XV_SD_CHLUMAFLICKERFILTER";
+static char sisxvsdchcvbscolor[] = "XV_SD_CHCVBSCOLOR";
+static char sisxvsdchoverscan[] = "XV_SD_CHOVERSCAN";
+static char sisxvsdenablegamma[] = "XV_SD_ENABLEGAMMA";
+static char sisxvsdtvxscale[] = "XV_SD_TVXSCALE";
+static char sisxvsdtvyscale[] = "XV_SD_TVYSCALE";
+static char sisxvsdgetscreensize[] = "XV_SD_GETSCREENSIZE";
+static char sisxvsdstorebrir[] = "XV_SD_STOREDGAMMABRIR";
+static char sisxvsdstorebrig[] = "XV_SD_STOREDGAMMABRIG";
+static char sisxvsdstorebrib[] = "XV_SD_STOREDGAMMABRIB";
+static char sisxvsdstorepbrir[] = "XV_SD_STOREDGAMMAPBRIR";
+static char sisxvsdstorepbrig[] = "XV_SD_STOREDGAMMAPBRIG";
+static char sisxvsdstorepbrib[] = "XV_SD_STOREDGAMMAPBRIB";
+static char sisxvsdstorebrir2[] = "XV_SD_STOREDGAMMABRIR2";
+static char sisxvsdstorebrig2[] = "XV_SD_STOREDGAMMABRIG2";
+static char sisxvsdstorebrib2[] = "XV_SD_STOREDGAMMABRIB2";
+static char sisxvsdstorepbrir2[] = "XV_SD_STOREDGAMMAPBRIR2";
+static char sisxvsdstorepbrig2[] = "XV_SD_STOREDGAMMAPBRIG2";
+static char sisxvsdstorepbrib2[] = "XV_SD_STOREDGAMMAPBRIB2";
+static char sisxvsdstoregarc2[] = "XV_SD_GAMMACRT2R";
+static char sisxvsdstoregagc2[] = "XV_SD_GAMMACRT2G";
+static char sisxvsdstoregabc2[] = "XV_SD_GAMMACRT2B";
+static char sisxvsdstorebrirc2[] = "XV_SD_STOREDGAMMABRIRC2";
+static char sisxvsdstorebrigc2[] = "XV_SD_STOREDGAMMABRIGC2";
+static char sisxvsdstorebribc2[] = "XV_SD_STOREDGAMMABRIBC2";
+static char sisxvsdstorepbrirc2[] = "XV_SD_STOREDGAMMAPBRIRC2";
+static char sisxvsdstorepbrigc2[] = "XV_SD_STOREDGAMMAPBRIGC2";
+static char sisxvsdstorepbribc2[] = "XV_SD_STOREDGAMMAPBRIBC2";
+static char sisxvsdhidehwcursor[] = "XV_SD_HIDEHWCURSOR";
+static char sisxvsdpanelmode[] = "XV_SD_PANELMODE";
+#ifdef TWDEBUG
+static char sisxvsetreg[] = "XV_SD_SETREG";
+#endif
+#endif
+
+/***********************************************/
+/* OVERLAY ADAPTOR */
+/***********************************************/
+
+/* client libraries expect an encoding */
+static XF86VideoEncodingRec DummyEncoding =
+{
+ 0,
+ "XV_IMAGE",
+ 0, 0, /* Will be filled in */
+ {1, 1}
+};
+
+static XF86AttributeRec SISUSBAttributes_315[] =
+{
+ {XvSettable | XvGettable, 0, (1 << 24) - 1, sisxvcolorkey},
+ {XvSettable | XvGettable, -128, 127, sisxvbrightness},
+ {XvSettable | XvGettable, 0, 7, sisxvcontrast},
+ {XvSettable | XvGettable, -7, 7, sisxvsaturation},
+ {XvSettable | XvGettable, -8, 7, sisxvhue},
+ {XvSettable | XvGettable, 0, 1, sisxvautopaintcolorkey},
+ {XvSettable , 0, 0, sisxvsetdefaults},
+ {XvSettable | XvGettable, -32, 32, sisxvtvxposition},
+ {XvSettable | XvGettable, -32, 32, sisxvtvyposition},
+ {XvSettable | XvGettable, 100, 10000, sisxvgammared},
+ {XvSettable | XvGettable, 100, 10000, sisxvgammagreen},
+ {XvSettable | XvGettable, 100, 10000, sisxvgammablue},
+ {XvSettable | XvGettable, 0, 1, sisxvdisablegfx},
+ {XvSettable | XvGettable, 0, 1, sisxvdisablegfxlr},
+ {XvSettable | XvGettable, 0, 1, sisxvdisablecolorkey},
+ {XvSettable | XvGettable, 0, 1, sisxvusechromakey},
+ {XvSettable | XvGettable, 0, 1, sisxvinsidechromakey},
+ {XvSettable | XvGettable, 0, (1 << 24) - 1, sisxvchromamin},
+ {XvSettable | XvGettable, 0, (1 << 24) - 1, sisxvchromamax},
+#ifdef XV_SD_DEPRECATED
+ { XvGettable, 0, -1, sisxvqueryvbflags},
+ { XvGettable, 0, -1, sisxvsdgetdriverversion},
+ { XvGettable, 0, -1, sisxvsdgethardwareinfo},
+ { XvGettable, 0, -1, sisxvsdgetbusid},
+ { XvGettable, 0, -1, sisxvsdqueryvbflagsversion},
+ { XvGettable, 0, -1, sisxvsdgetsdflags},
+ { XvGettable, 0, -1, sisxvsdgetsdflags2},
+ {XvSettable | XvGettable, 0, -1, sisxvsdunlocksisdirect},
+ {XvSettable , 0, -1, sisxvsdsetvbflags},
+ { XvGettable, 0, -1, sisxvsdquerydetecteddevices},
+ {XvSettable | XvGettable, 0, 1, sisxvsdcrt1status},
+ {XvSettable , 0, -1, sisxvsdcheckmodeindexforcrt2},
+ { XvGettable, 0, -1, sisxvsdresultcheckmodeindexforcrt2},
+ {XvSettable , 0, 0, sisxvsdredetectcrt2},
+ {XvSettable | XvGettable, 0, 4, sisxvsdsisantiflicker},
+ {XvSettable | XvGettable, 0, 15, sisxvsdsissaturation},
+ {XvSettable | XvGettable, 0, 15, sisxvsdsisedgeenhance},
+ {XvSettable | XvGettable, -128, 127, sisxvsdsiscolcalibf},
+ {XvSettable | XvGettable, -120, 120, sisxvsdsiscolcalibc},
+ {XvSettable | XvGettable, 0, 1, sisxvsdsiscfilter},
+ {XvSettable | XvGettable, 0, 8, sisxvsdsisyfilter},
+ {XvSettable | XvGettable, 0, 15, sisxvsdchcontrast},
+ {XvSettable | XvGettable, 0, 15, sisxvsdchtextenhance},
+ {XvSettable | XvGettable, 0, 15, sisxvsdchchromaflickerfilter},
+ {XvSettable | XvGettable, 0, 15, sisxvsdchlumaflickerfilter},
+ {XvSettable | XvGettable, 0, 1, sisxvsdchcvbscolor},
+ {XvSettable | XvGettable, 0, 3, sisxvsdchoverscan},
+ {XvSettable | XvGettable, 0, 7, sisxvsdenablegamma},
+ {XvSettable | XvGettable, -16, 16, sisxvsdtvxscale},
+ {XvSettable | XvGettable, -4, 3, sisxvsdtvyscale},
+ { XvGettable, 0, -1, sisxvsdgetscreensize},
+ {XvSettable | XvGettable, 100, 10000, sisxvsdstorebrir},
+ {XvSettable | XvGettable, 100, 10000, sisxvsdstorebrig},
+ {XvSettable | XvGettable, 100, 10000, sisxvsdstorebrib},
+ {XvSettable | XvGettable, 100, 10000, sisxvsdstorepbrir},
+ {XvSettable | XvGettable, 100, 10000, sisxvsdstorepbrig},
+ {XvSettable | XvGettable, 100, 10000, sisxvsdstorepbrib},
+ {XvSettable | XvGettable, 100, 10000, sisxvsdstorebrir2},
+ {XvSettable | XvGettable, 100, 10000, sisxvsdstorebrig2},
+ {XvSettable | XvGettable, 100, 10000, sisxvsdstorebrib2},
+ {XvSettable | XvGettable, 100, 10000, sisxvsdstorepbrir2},
+ {XvSettable | XvGettable, 100, 10000, sisxvsdstorepbrig2},
+ {XvSettable | XvGettable, 100, 10000, sisxvsdstorepbrib2},
+ {XvSettable | XvGettable, 100, 10000, sisxvsdstoregarc2},
+ {XvSettable | XvGettable, 100, 10000, sisxvsdstoregagc2},
+ {XvSettable | XvGettable, 100, 10000, sisxvsdstoregabc2},
+ {XvSettable | XvGettable, 100, 10000, sisxvsdstorebrirc2},
+ {XvSettable | XvGettable, 100, 10000, sisxvsdstorebrigc2},
+ {XvSettable | XvGettable, 100, 10000, sisxvsdstorebribc2},
+ {XvSettable | XvGettable, 100, 10000, sisxvsdstorepbrirc2},
+ {XvSettable | XvGettable, 100, 10000, sisxvsdstorepbrigc2},
+ {XvSettable | XvGettable, 100, 10000, sisxvsdstorepbribc2},
+ {XvSettable | XvGettable, 0, 1, sisxvsdhidehwcursor},
+ {XvSettable | XvGettable, 0, 15, sisxvsdpanelmode},
+#ifdef TWDEBUG
+ {XvSettable , 0, -1, sisxvsetreg},
+#endif
+#endif /* XV_SD_DEPRECATED */
+ {XvSettable | XvGettable, 0, 1, sisxvswitchcrt},
+ {0 , 0, 0, NULL}
+};
+
+#define NUM_IMAGES_315 7 /* basically NV12 only - but does not work */
+
+#define PIXEL_FMT_YV12 FOURCC_YV12 /* 0x32315659 */
+#define PIXEL_FMT_UYVY FOURCC_UYVY /* 0x59565955 */
+#define PIXEL_FMT_YUY2 FOURCC_YUY2 /* 0x32595559 */
+#define PIXEL_FMT_I420 FOURCC_I420 /* 0x30323449 */
+#define PIXEL_FMT_RGB5 0x35315652
+#define PIXEL_FMT_RGB6 0x36315652
+#define PIXEL_FMT_YVYU 0x55595659 /* 315/330+ only */
+#define PIXEL_FMT_NV12 0x3231564e /* 330+ only */
+#define PIXEL_FMT_NV21 0x3132564e /* 330+ only */
+
+/* TODO: */
+#define PIXEL_FMT_RAW8 0x38574152
+
+static XF86ImageRec SISUSBImages[NUM_IMAGES_315] =
+{
+ XVIMAGE_YUY2, /* If order is changed, SISOffscreenImages must be adapted */
+ XVIMAGE_YV12,
+ XVIMAGE_UYVY,
+ XVIMAGE_I420
+ ,
+ { /* RGB 555 */
+ PIXEL_FMT_RGB5,
+ XvRGB,
+ LSBFirst,
+ {'R','V','1','5',
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ 16,
+ XvPacked,
+ 1,
+ 15, 0x7C00, 0x03E0, 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
+ },
+ { /* RGB 565 */
+ PIXEL_FMT_RGB6,
+ 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
+ },
+ { /* YVYU */
+ PIXEL_FMT_YVYU, \
+ XvYUV, \
+ LSBFirst, \
+ {'Y','V','Y','U',
+ 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71},
+ 16,
+ XvPacked,
+ 1,
+ 0, 0, 0, 0,
+ 8, 8, 8,
+ 1, 2, 2,
+ 1, 1, 1,
+ {'Y','V','Y','U',
+ 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
+ }
+};
+
+typedef struct {
+ int pixelFormat;
+
+ CARD16 pitch;
+ CARD16 origPitch;
+
+ CARD8 keyOP;
+ CARD16 HUSF;
+ CARD16 VUSF;
+ CARD8 IntBit;
+ CARD8 wHPre;
+
+ CARD16 srcW;
+ CARD16 srcH;
+
+ BoxRec dstBox;
+
+ CARD32 PSY;
+ CARD32 PSV;
+ CARD32 PSU;
+
+ CARD16 SCREENheight;
+
+ CARD16 lineBufSize;
+
+ DisplayModePtr currentmode;
+
+ CARD8 bobEnable;
+
+ CARD8 planar;
+ CARD8 planar_shiftpitch;
+
+ CARD8 contrastCtrl;
+ CARD8 contrastFactor;
+
+ CARD16 oldLine, oldtop;
+
+ CARD8 (*VBlankActiveFunc)(SISUSBPtr, SISUSBPortPrivPtr);
+#if 0
+ CARD32 (*GetScanLineFunc)(SISUSBPtr pSiSUSB);
+#endif
+
+} SISUSBOverlayRec, *SISUSBOverlayPtr;
+
+#endif
+
+
diff --git a/driver/xf86-video-sisusb/src/sisusb_videostr.h b/driver/xf86-video-sisusb/src/sisusb_videostr.h
new file mode 100644
index 000000000..3eb165c7e
--- /dev/null
+++ b/driver/xf86-video-sisusb/src/sisusb_videostr.h
@@ -0,0 +1,107 @@
+/* $XFree86$ */
+/* $XdotOrg: driver/xf86-video-sisusb/src/sisusb_videostr.h,v 1.3 2005/07/09 02:50:34 twini Exp $ */
+/*
+ * Xv driver for SiS 315 USB
+ *
+ * Overlay port private structure
+ *
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1) Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2) Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3) The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
+
+#ifndef _SISUSB_VIDEOSTR_H_
+#define _SISUSB_VIDEOSTR_H_
+
+#define GET_PORT_PRIVATE(pScrn) \
+ (SISUSBPortPrivPtr)((SISUSBPTR(pScrn))->adaptor->pPortPrivates[0].ptr)
+
+typedef struct {
+ FBLinearPtr linear;
+ CARD32 bufAddr[2];
+
+ UChar currentBuf;
+
+ short drw_x, drw_y, drw_w, drw_h;
+ short src_x, src_y, src_w, src_h;
+ int id;
+ short srcPitch, height;
+
+ char brightness;
+ UChar contrast;
+ char hue;
+ short saturation;
+
+ RegionRec clip;
+ CARD32 colorKey;
+ Bool autopaintColorKey;
+
+ Bool disablegfx;
+ Bool disablegfxlr;
+
+ Bool usechromakey;
+ Bool insidechromakey, yuvchromakey;
+ CARD32 chromamin, chromamax;
+
+ CARD32 videoStatus;
+ Bool overlayStatus;
+ Time offTime;
+ Time freeTime;
+
+ CARD32 displayMode;
+ Bool bridgeIsSlave;
+
+ Bool hasTwoOverlays; /* Chipset has two overlays */
+ Bool dualHeadMode; /* We're running in DHM */
+
+ Bool NoOverlay;
+ Bool PrevOverlay;
+
+ Bool AllowSwitchCRT;
+ int crtnum; /* 0=CRT1, 1=CRT2 */
+
+ Bool needToScale; /* Need to scale video */
+
+ int shiftValue; /* 315/330 series need word addr/pitch, 300 series double word */
+
+ short linebufMergeLimit;
+ CARD8 linebufmask;
+
+ short oldx1, oldx2, oldy1, oldy2;
+ int mustwait;
+
+ Bool grabbedByV4L; /* V4L stuff */
+ int pitch;
+ int offset;
+
+ int modeflags; /* Flags field of current display mode */
+
+ Bool is340;
+
+} SISUSBPortPrivRec, *SISUSBPortPrivPtr;
+
+#endif
+