diff options
author | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2006-11-26 20:13:53 +0000 |
---|---|---|
committer | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2006-11-26 20:13:53 +0000 |
commit | c72776735fe8203d357dce0bf9cda921a2376dc6 (patch) | |
tree | f4468030b9609553848f2baad835fe7643d4b197 /driver/xf86-video-sisusb/src | |
parent | 295d62fd7c6366bd5a282cf713a82c06a711e5af (diff) |
Importing xf86-video-sisusb 0.8.1
Diffstat (limited to 'driver/xf86-video-sisusb/src')
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 + |